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 + -
显示快捷键?