import.c

来自「lustre 1.6.5 source code」· C语言 代码 · 共 1,348 行 · 第 1/4 页

C
1,348
字号
/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- * vim:expandtab:shiftwidth=8:tabstop=8: * *  Copyright (c) 2002, 2003 Cluster File Systems, Inc. *   Author: Mike Shaver <shaver@clusterfs.com> * *   This file is part of the Lustre file system, http://www.lustre.org *   Lustre is a trademark of Cluster File Systems, Inc. * *   You may have signed or agreed to another license before downloading *   this software.  If so, you are bound by the terms and conditions *   of that agreement, and the following does not apply to you.  See the *   LICENSE file included with this distribution for more information. * *   If you did not agree to a different license, then this copy of Lustre *   is open source software; you can redistribute it and/or modify it *   under the terms of version 2 of the GNU General Public License as *   published by the Free Software Foundation. * *   In either case, Lustre is distributed in the hope that it will be *   useful, but WITHOUT ANY WARRANTY; without even the implied warranty *   of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *   license text for more details. */#define DEBUG_SUBSYSTEM S_RPC#ifndef __KERNEL__# include <liblustre.h>#endif#include <obd_support.h>#include <lustre_ha.h>#include <lustre_net.h>#include <lustre_import.h>#include <lustre_export.h>#include <obd.h>#include <obd_class.h>#include "ptlrpc_internal.h"struct ptlrpc_connect_async_args {         __u64 pcaa_peer_committed;        int pcaa_initial_connect;};/* A CLOSED import should remain so. */#define IMPORT_SET_STATE_NOLOCK(imp, state)                                    \do {                                                                           \        if (imp->imp_state != LUSTRE_IMP_CLOSED) {                             \               CDEBUG(D_HA, "%p %s: changing import state from %s to %s\n",    \                      imp, obd2cli_tgt(imp->imp_obd),                          \                      ptlrpc_import_state_name(imp->imp_state),                \                      ptlrpc_import_state_name(state));                        \               imp->imp_state = state;                                         \        }                                                                      \} while(0)#define IMPORT_SET_STATE(imp, state)            \do {                                            \        spin_lock(&imp->imp_lock);              \        IMPORT_SET_STATE_NOLOCK(imp, state);    \        spin_unlock(&imp->imp_lock);            \} while(0)static int ptlrpc_connect_interpret(struct ptlrpc_request *request,                                    void * data, int rc);int ptlrpc_import_recovery_state_machine(struct obd_import *imp);/* Only this function is allowed to change the import state when it is * CLOSED. I would rather refcount the import and free it after * disconnection like we do with exports. To do that, the client_obd * will need to save the peer info somewhere other than in the import, * though. */int ptlrpc_init_import(struct obd_import *imp){        spin_lock(&imp->imp_lock);        imp->imp_generation++;        imp->imp_state =  LUSTRE_IMP_NEW;        spin_unlock(&imp->imp_lock);        return 0;}EXPORT_SYMBOL(ptlrpc_init_import);#define UUID_STR "_UUID"static void deuuidify(char *uuid, const char *prefix, char **uuid_start,                      int *uuid_len){        *uuid_start = !prefix || strncmp(uuid, prefix, strlen(prefix))                ? uuid : uuid + strlen(prefix);        *uuid_len = strlen(*uuid_start);        if (*uuid_len < strlen(UUID_STR))                return;        if (!strncmp(*uuid_start + *uuid_len - strlen(UUID_STR),                    UUID_STR, strlen(UUID_STR)))                *uuid_len -= strlen(UUID_STR);}/* Returns true if import was FULL, false if import was already not * connected. * @imp - import to be disconnected * @conn_cnt - connection count (epoch) of the request that timed out *             and caused the disconnection.  In some cases, multiple *             inflight requests can fail to a single target (e.g. OST *             bulk requests) and if one has already caused a reconnection *             (increasing the import->conn_cnt) the older failure should *             not also cause a reconnection.  If zero it forces a reconnect. */int ptlrpc_set_import_discon(struct obd_import *imp, __u32 conn_cnt){        int rc = 0;        spin_lock(&imp->imp_lock);        if (imp->imp_state == LUSTRE_IMP_FULL &&            (conn_cnt == 0 || conn_cnt == imp->imp_conn_cnt)) {                char *target_start;                int   target_len;                deuuidify(obd2cli_tgt(imp->imp_obd), NULL,                          &target_start, &target_len);                if (imp->imp_replayable) {                        LCONSOLE_WARN("%s: Connection to service %.*s via nid "                               "%s was lost; in progress operations using this "                               "service will wait for recovery to complete.\n",                               imp->imp_obd->obd_name, target_len, target_start,                               libcfs_nid2str(imp->imp_connection->c_peer.nid));                } else {                        LCONSOLE_ERROR_MSG(0x166, "%s: Connection to service "                               "%.*s via nid %s was lost; in progress "                               "operations using this service will fail.\n",                               imp->imp_obd->obd_name, target_len, target_start,                                libcfs_nid2str(imp->imp_connection->c_peer.nid));                }                IMPORT_SET_STATE_NOLOCK(imp, LUSTRE_IMP_DISCON);                spin_unlock(&imp->imp_lock);                    if (obd_dump_on_timeout)                        libcfs_debug_dumplog();                obd_import_event(imp->imp_obd, imp, IMP_EVENT_DISCON);                rc = 1;        } else {                spin_unlock(&imp->imp_lock);                CDEBUG(D_HA, "%s: import %p already %s (conn %u, was %u): %s\n",                       imp->imp_client->cli_name, imp,                       (imp->imp_state == LUSTRE_IMP_FULL &&                        imp->imp_conn_cnt > conn_cnt) ?                       "reconnected" : "not connected", imp->imp_conn_cnt,                       conn_cnt, ptlrpc_import_state_name(imp->imp_state));        }        return rc;}/* Must be called with imp_lock held! */static void ptlrpc_deactivate_and_unlock_import(struct obd_import *imp){        ENTRY;        LASSERT_SPIN_LOCKED(&imp->imp_lock);        CDEBUG(D_HA, "setting import %s INVALID\n", obd2cli_tgt(imp->imp_obd));        imp->imp_invalid = 1;        imp->imp_generation++;        spin_unlock(&imp->imp_lock);        ptlrpc_abort_inflight(imp);        obd_import_event(imp->imp_obd, imp, IMP_EVENT_INACTIVE);}/* * This acts as a barrier; all existing requests are rejected, and * no new requests will be accepted until the import is valid again. */void ptlrpc_deactivate_import(struct obd_import *imp){        spin_lock(&imp->imp_lock);        ptlrpc_deactivate_and_unlock_import(imp);}/* * This function will invalidate the import, if necessary, then block * for all the RPC completions, and finally notify the obd to * invalidate its state (ie cancel locks, clear pending requests, * etc). */void ptlrpc_invalidate_import(struct obd_import *imp){        struct list_head *tmp, *n;        struct ptlrpc_request *req;        struct l_wait_info lwi;        int rc;        atomic_inc(&imp->imp_inval_count);        /*          * If this is an invalid MGC connection, then don't bother         * waiting for imp_inflight to drop to 0.         */        if (imp->imp_invalid && imp->imp_recon_bk && !imp->imp_obd->obd_no_recov)                goto out;        if (!imp->imp_invalid || imp->imp_obd->obd_no_recov)                ptlrpc_deactivate_import(imp);        LASSERT(imp->imp_invalid);        /* wait for all requests to error out and call completion callbacks.           Cap it at obd_timeout -- these should all have been locally           cancelled by ptlrpc_abort_inflight. */        lwi = LWI_TIMEOUT_INTERVAL(                cfs_timeout_cap(cfs_time_seconds(obd_timeout)),                cfs_time_seconds(1), NULL, NULL);        rc = l_wait_event(imp->imp_recovery_waitq,                          (atomic_read(&imp->imp_inflight) == 0), &lwi);        if (rc) {                CERROR("%s: rc = %d waiting for callback (%d != 0)\n",                       obd2cli_tgt(imp->imp_obd), rc,                       atomic_read(&imp->imp_inflight));                spin_lock(&imp->imp_lock);                list_for_each_safe(tmp, n, &imp->imp_sending_list) {                        req = list_entry(tmp, struct ptlrpc_request, rq_list);                        DEBUG_REQ(D_ERROR, req, "still on sending list");                }                list_for_each_safe(tmp, n, &imp->imp_delayed_list) {                        req = list_entry(tmp, struct ptlrpc_request, rq_list);                        DEBUG_REQ(D_ERROR, req, "still on delayed list");                }                spin_unlock(&imp->imp_lock);        }  out:        obd_import_event(imp->imp_obd, imp, IMP_EVENT_INVALIDATE);                atomic_dec(&imp->imp_inval_count);        cfs_waitq_signal(&imp->imp_recovery_waitq);}/* unset imp_invalid */void ptlrpc_activate_import(struct obd_import *imp){        struct obd_device *obd = imp->imp_obd;        spin_lock(&imp->imp_lock);        imp->imp_invalid = 0;        spin_unlock(&imp->imp_lock);        obd_import_event(obd, imp, IMP_EVENT_ACTIVE);}void ptlrpc_fail_import(struct obd_import *imp, __u32 conn_cnt){        ENTRY;        LASSERT(!imp->imp_dlm_fake);        if (ptlrpc_set_import_discon(imp, conn_cnt)) {                if (!imp->imp_replayable) {                        CDEBUG(D_HA, "import %s@%s for %s not replayable, "                               "auto-deactivating\n",                               obd2cli_tgt(imp->imp_obd),                               imp->imp_connection->c_remote_uuid.uuid,                               imp->imp_obd->obd_name);                        ptlrpc_deactivate_import(imp);                }                CDEBUG(D_HA, "%s: waking up pinger\n",                       obd2cli_tgt(imp->imp_obd));                spin_lock(&imp->imp_lock);                imp->imp_force_verify = 1;                spin_unlock(&imp->imp_lock);                ptlrpc_pinger_wake_up();        }        EXIT;}int ptlrpc_reconnect_import(struct obd_import *imp){                ptlrpc_set_import_discon(imp, 0);         /* Force a new connect attempt */        ptlrpc_invalidate_import(imp);        /* Do a fresh connect next time by zeroing the handle */        ptlrpc_disconnect_import(imp, 1);        /* Wait for all invalidate calls to finish */        if (atomic_read(&imp->imp_inval_count) > 0) {                int rc;                struct l_wait_info lwi = LWI_INTR(LWI_ON_SIGNAL_NOOP, NULL);                rc = l_wait_event(imp->imp_recovery_waitq,                                  (atomic_read(&imp->imp_inval_count) == 0),                                  &lwi);                if (rc)                        CERROR("Interrupted, inval=%d\n",                                atomic_read(&imp->imp_inval_count));        }        /*          * Allow reconnect attempts. Note: Currently, the function is         * only called by MGC. So assume this is a recoverable import,         * and force import to be recoverable. fix this if you need to          */                imp->imp_obd->obd_no_recov = 0;        /* Remove 'invalid' flag */        ptlrpc_activate_import(imp);        /* Attempt a new connect */        ptlrpc_recover_import(imp, NULL);        return 0;}EXPORT_SYMBOL(ptlrpc_reconnect_import);static int import_select_connection(struct obd_import *imp){        struct obd_import_conn *imp_conn = NULL, *conn;        struct obd_export *dlmexp;        int tried_all = 1;        ENTRY;        spin_lock(&imp->imp_lock);        if (list_empty(&imp->imp_conn_list)) {                CERROR("%s: no connections available\n",                        imp->imp_obd->obd_name);                spin_unlock(&imp->imp_lock);                RETURN(-EINVAL);        }

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?