CFS_FAIL_TIMEOUT(OBD_FAIL_MGS_CONNECT_NET, 3 * cfs_fail_val / 2);
LASSERT(imp->imp_invalid);
- /* Wait forever until inflight == 0. We really can't do it another
- * way because in some cases we need to wait for very long reply
- * unlink. We can't do anything before that because there is really
- * no guarantee that some rdma transfer is not in progress right now. */
- do {
+ /* Wait forever until inflight == 0. We really can't do it another
+ * way because in some cases we need to wait for very long reply
+ * unlink. We can't do anything before that because there is really
+ * no guarantee that some rdma transfer is not in progress right now.
+ */
+ do {
long timeout_jiffies;
- /* Calculate max timeout for waiting on rpcs to error
- * out. Use obd_timeout if calculated value is smaller
+ /* Calculate max timeout for waiting on rpcs to error
+ * out. Use obd_timeout if calculated value is smaller
* than it.
*/
if (!OBD_FAIL_CHECK(OBD_FAIL_PTLRPC_LONG_REPL_UNLINK)) {
timeout_jiffies = max_t(long, cfs_time_seconds(timeout), 1);
lwi = LWI_TIMEOUT_INTERVAL(timeout_jiffies,
(timeout > 1) ? cfs_time_seconds(1) :
- cfs_time_seconds(1) / 2,
- NULL, NULL);
+ cfs_time_seconds(1) / 2,
+ NULL, NULL);
rc = l_wait_event(imp->imp_recovery_waitq,
(atomic_read(&imp->imp_inflight) == 0),
&lwi);
}
CERROR("%s: Unregistering RPCs found (%d). "
- "Network is sluggish? Waiting them "
+ "Network is sluggish? Waiting for them "
"to error out.\n", cli_tgt,
atomic_read(&imp->imp_unregistering));
}
imp->imp_conn_current = imp_conn;
}
+ /* The below message is checked in conf-sanity.sh test_35[ab] */
CDEBUG(D_HA, "%s: import %p using connection %s/%s\n",
imp->imp_obd->obd_name, imp, imp_conn->oic_uuid.uuid,
libcfs_nid2str(imp_conn->oic_conn->c_peer.nid));
req = list_entry(tmp, struct ptlrpc_request, rq_replay_list);
*transno = req->rq_transno;
if (req->rq_transno == 0) {
- DEBUG_REQ(D_ERROR, req, "zero transno in committed_list");
+ DEBUG_REQ(D_ERROR, req,
+ "zero transno in committed_list");
LBUG();
}
return 1;
return 0;
}
+int ptlrpc_connect_import(struct obd_import *imp)
+{
+ spin_lock(&imp->imp_lock);
+ return ptlrpc_connect_import_locked(imp);
+}
+
/**
* Attempt to (re)connect import \a imp. This includes all preparations,
* initializing CONNECT RPC request and passing it to ptlrpcd for
* actual sending.
+ *
+ * Assumes imp->imp_lock is held, and releases it.
+ *
* Returns 0 on success or error code.
*/
-int ptlrpc_connect_import(struct obd_import *imp)
+int ptlrpc_connect_import_locked(struct obd_import *imp)
{
struct obd_device *obd = imp->imp_obd;
int initial_connect = 0;
int rc;
ENTRY;
- spin_lock(&imp->imp_lock);
+ assert_spin_locked(&imp->imp_lock);
+
if (imp->imp_state == LUSTRE_IMP_CLOSED) {
spin_unlock(&imp->imp_lock);
CERROR("can't connect to a closed import\n");
ptlrpc_request_set_replen(request);
request->rq_interpret_reply = ptlrpc_connect_interpret;
- CLASSERT(sizeof(*aa) <= sizeof(request->rq_async_args));
- aa = ptlrpc_req_async_args(request);
+ aa = ptlrpc_req_async_args(aa, request);
memset(aa, 0, sizeof *aa);
aa->pcaa_peer_committed = committed_before_reconnect;
* full state for normal operations of disconnect it due to an error.
*/
static int ptlrpc_connect_interpret(const struct lu_env *env,
- struct ptlrpc_request *request,
- void *data, int rc)
+ struct ptlrpc_request *request,
+ void *data, int rc)
{
- struct ptlrpc_connect_async_args *aa = data;
- struct obd_import *imp = request->rq_import;
- struct lustre_handle old_hdl;
- __u64 old_connect_flags;
- int msg_flags;
+ struct ptlrpc_connect_async_args *aa = data;
+ struct obd_import *imp = request->rq_import;
+ struct lustre_handle old_hdl;
+ __u64 old_connect_flags;
+ int msg_flags;
struct obd_connect_data *ocd;
struct obd_export *exp = NULL;
int ret;
spin_lock(&imp->imp_lock);
- /* All imports are pingable */
- imp->imp_pingable = 1;
- imp->imp_force_reconnect = 0;
- imp->imp_force_verify = 0;
+ /* All imports are pingable */
+ imp->imp_pingable = 1;
+ imp->imp_force_reconnect = 0;
+ imp->imp_force_verify = 0;
imp->imp_connect_data = *ocd;
* because may reflect other routing, etc. */
at_reinit(&imp->imp_at.iat_net_latency, 0, 0);
ptlrpc_at_adj_net_latency(request,
- lustre_msg_get_service_time(request->rq_repmsg));
+ lustre_msg_get_service_time(
+ request->rq_repmsg));
/* Import flags should be updated before waking import at FULL state */
rc = ptlrpc_connect_set_flags(imp, ocd, old_connect_flags, exp,
imp->imp_replayable = 0;
}
- /* if applies, adjust the imp->imp_msg_magic here
- * according to reply flags */
+ /* if applies, adjust the imp->imp_msg_magic here
+ * according to reply flags
+ */
- imp->imp_remote_handle =
- *lustre_msg_get_handle(request->rq_repmsg);
+ imp->imp_remote_handle =
+ *lustre_msg_get_handle(request->rq_repmsg);
- /* Initial connects are allowed for clients with non-random
- * uuids when servers are in recovery. Simply signal the
- * servers replay is complete and wait in REPLAY_WAIT. */
- if (msg_flags & MSG_CONNECT_RECOVERING) {
- CDEBUG(D_HA, "connect to %s during recovery\n",
- obd2cli_tgt(imp->imp_obd));
+ /* Initial connects are allowed for clients with non-random
+ * uuids when servers are in recovery. Simply signal the
+ * servers replay is complete and wait in REPLAY_WAIT.
+ */
+ if (msg_flags & MSG_CONNECT_RECOVERING) {
+ CDEBUG(D_HA, "connect to %s during recovery\n",
+ obd2cli_tgt(imp->imp_obd));
import_set_state_nolock(imp, LUSTRE_IMP_REPLAY_LOCKS);
spin_unlock(&imp->imp_lock);
- } else {
+ } else {
spin_unlock(&imp->imp_lock);
ptlrpc_activate_import(imp, true);
- }
+ }
- GOTO(finish, rc = 0);
- }
+ GOTO(finish, rc = 0);
+ }
- /* Determine what recovery state to move the import to. */
- if (MSG_CONNECT_RECONNECT & msg_flags) {
- memset(&old_hdl, 0, sizeof(old_hdl));
- if (!memcmp(&old_hdl, lustre_msg_get_handle(request->rq_repmsg),
- sizeof (old_hdl))) {
- LCONSOLE_WARN("Reconnect to %s (at @%s) failed due "
+ /* Determine what recovery state to move the import to. */
+ if (MSG_CONNECT_RECONNECT & msg_flags) {
+ memset(&old_hdl, 0, sizeof(old_hdl));
+ if (!memcmp(&old_hdl, lustre_msg_get_handle(request->rq_repmsg),
+ sizeof(old_hdl))) {
+ LCONSOLE_WARN("Reconnect to %s (at @%s) failed due "
"bad handle %#llx\n",
- obd2cli_tgt(imp->imp_obd),
- imp->imp_connection->c_remote_uuid.uuid,
- imp->imp_dlm_handle.cookie);
- GOTO(out, rc = -ENOTCONN);
- }
+ obd2cli_tgt(imp->imp_obd),
+ imp->imp_connection->c_remote_uuid.uuid,
+ imp->imp_dlm_handle.cookie);
+ GOTO(out, rc = -ENOTCONN);
+ }
- if (memcmp(&imp->imp_remote_handle,
- lustre_msg_get_handle(request->rq_repmsg),
- sizeof(imp->imp_remote_handle))) {
- int level = msg_flags & MSG_CONNECT_RECOVERING ?
- D_HA : D_WARNING;
-
- /* Bug 16611/14775: if server handle have changed,
- * that means some sort of disconnection happened.
- * If the server is not in recovery, that also means it
- * already erased all of our state because of previous
- * eviction. If it is in recovery - we are safe to
- * participate since we can reestablish all of our state
- * with server again */
- if ((MSG_CONNECT_RECOVERING & msg_flags)) {
- CDEBUG(level,"%s@%s changed server handle from "
+ if (memcmp(&imp->imp_remote_handle,
+ lustre_msg_get_handle(request->rq_repmsg),
+ sizeof(imp->imp_remote_handle))) {
+ int level = msg_flags & MSG_CONNECT_RECOVERING ?
+ D_HA : D_WARNING;
+
+ /* Bug 16611/14775: if server handle have changed,
+ * that means some sort of disconnection happened.
+ * If the server is not in recovery, that also means it
+ * already erased all of our state because of previous
+ * eviction. If it is in recovery - we are safe to
+ * participate since we can reestablish all of our state
+ * with server again
+ */
+ if ((MSG_CONNECT_RECOVERING & msg_flags)) {
+ CDEBUG(level,
+ "%s@%s changed server handle from "
"%#llx to %#llx"
- " but is still in recovery\n",
- obd2cli_tgt(imp->imp_obd),
- imp->imp_connection->c_remote_uuid.uuid,
- imp->imp_remote_handle.cookie,
- lustre_msg_get_handle(
- request->rq_repmsg)->cookie);
- } else {
- LCONSOLE_WARN("Evicted from %s (at %s) "
- "after server handle changed from "
+ " but is still in recovery\n",
+ obd2cli_tgt(imp->imp_obd),
+ imp->imp_connection->c_remote_uuid.uuid,
+ imp->imp_remote_handle.cookie,
+ lustre_msg_get_handle(
+ request->rq_repmsg)->cookie);
+ } else {
+ LCONSOLE_WARN("Evicted from %s (at %s) "
+ "after server handle changed from "
"%#llx to %#llx\n",
- obd2cli_tgt(imp->imp_obd),
- imp->imp_connection-> \
- c_remote_uuid.uuid,
- imp->imp_remote_handle.cookie,
- lustre_msg_get_handle(
- request->rq_repmsg)->cookie);
- }
-
+ obd2cli_tgt(imp->imp_obd),
+ imp->imp_connection->
+ c_remote_uuid.uuid,
+ imp->imp_remote_handle.cookie,
+ lustre_msg_get_handle(
+ request->rq_repmsg)->cookie);
+ }
- imp->imp_remote_handle =
- *lustre_msg_get_handle(request->rq_repmsg);
+ imp->imp_remote_handle =
+ *lustre_msg_get_handle(request->rq_repmsg);
- if (!(MSG_CONNECT_RECOVERING & msg_flags)) {
+ if (!(MSG_CONNECT_RECOVERING & msg_flags)) {
import_set_state(imp, LUSTRE_IMP_EVICTED);
- GOTO(finish, rc = 0);
- }
-
- } else {
- CDEBUG(D_HA, "reconnected to %s@%s after partition\n",
- obd2cli_tgt(imp->imp_obd),
- imp->imp_connection->c_remote_uuid.uuid);
- }
+ GOTO(finish, rc = 0);
+ }
+ } else {
+ CDEBUG(D_HA, "reconnected to %s@%s after partition\n",
+ obd2cli_tgt(imp->imp_obd),
+ imp->imp_connection->c_remote_uuid.uuid);
+ }
- if (imp->imp_invalid) {
- CDEBUG(D_HA, "%s: reconnected but import is invalid; "
- "marking evicted\n", imp->imp_obd->obd_name);
+ if (imp->imp_invalid) {
+ CDEBUG(D_HA, "%s: reconnected but import is invalid; "
+ "marking evicted\n", imp->imp_obd->obd_name);
import_set_state(imp, LUSTRE_IMP_EVICTED);
- } else if (MSG_CONNECT_RECOVERING & msg_flags) {
- CDEBUG(D_HA, "%s: reconnected to %s during replay\n",
- imp->imp_obd->obd_name,
- obd2cli_tgt(imp->imp_obd));
+ } else if (MSG_CONNECT_RECOVERING & msg_flags) {
+ CDEBUG(D_HA, "%s: reconnected to %s during replay\n",
+ imp->imp_obd->obd_name,
+ obd2cli_tgt(imp->imp_obd));
spin_lock(&imp->imp_lock);
imp->imp_resend_replay = 1;
spin_unlock(&imp->imp_lock);
import_set_state(imp, imp->imp_replay_state);
- } else {
+ } else {
import_set_state(imp, LUSTRE_IMP_RECOVER);
- }
- } else if ((MSG_CONNECT_RECOVERING & msg_flags) && !imp->imp_invalid) {
- LASSERT(imp->imp_replayable);
- imp->imp_remote_handle =
- *lustre_msg_get_handle(request->rq_repmsg);
- imp->imp_last_replay_transno = 0;
+ }
+ } else if ((MSG_CONNECT_RECOVERING & msg_flags) && !imp->imp_invalid) {
+ LASSERT(imp->imp_replayable);
+ imp->imp_remote_handle =
+ *lustre_msg_get_handle(request->rq_repmsg);
+ imp->imp_last_replay_transno = 0;
imp->imp_replay_cursor = &imp->imp_committed_list;
import_set_state(imp, LUSTRE_IMP_REPLAY);
} else if ((ocd->ocd_connect_flags & OBD_CONNECT_LIGHTWEIGHT) != 0 &&
!imp->imp_invalid) {
obd_import_event(imp->imp_obd, imp, IMP_EVENT_INVALIDATE);
+ /* The below message is checked in recovery-small.sh test_106 */
DEBUG_REQ(D_HA, request, "%s: lwp recover",
imp->imp_obd->obd_name);
imp->imp_remote_handle =
*lustre_msg_get_handle(request->rq_repmsg);
import_set_state(imp, LUSTRE_IMP_RECOVER);
} else {
- DEBUG_REQ(D_HA, request, "%s: evicting (reconnect/recover flags"
- " not set: %x)", imp->imp_obd->obd_name, msg_flags);
- imp->imp_remote_handle =
- *lustre_msg_get_handle(request->rq_repmsg);
+ DEBUG_REQ(D_HA, request,
+ "%s: evicting (reconnect/recover flags not set: %x)",
+ imp->imp_obd->obd_name, msg_flags);
+ imp->imp_remote_handle =
+ *lustre_msg_get_handle(request->rq_repmsg);
import_set_state(imp, LUSTRE_IMP_EVICTED);
- }
+ }
- /* Sanity checks for a reconnected import. */
- if (!(imp->imp_replayable) != !(msg_flags & MSG_CONNECT_REPLAYABLE)) {
- CERROR("imp_replayable flag does not match server "
- "after reconnect. We should LBUG right here.\n");
- }
+ /* Sanity checks for a reconnected import. */
+ if (!(imp->imp_replayable) != !(msg_flags & MSG_CONNECT_REPLAYABLE))
+ CERROR("imp_replayable flag does not match server after reconnect. We should LBUG right here.\n");
- if (lustre_msg_get_last_committed(request->rq_repmsg) > 0 &&
- lustre_msg_get_last_committed(request->rq_repmsg) <
- aa->pcaa_peer_committed) {
- CERROR("%s went back in time (transno %lld"
- " was previously committed, server now claims %lld"
- ")! See https://bugzilla.lustre.org/show_bug.cgi?"
- "id=9646\n",
- obd2cli_tgt(imp->imp_obd), aa->pcaa_peer_committed,
+ if (lustre_msg_get_last_committed(request->rq_repmsg) > 0 &&
+ lustre_msg_get_last_committed(request->rq_repmsg) <
+ aa->pcaa_peer_committed) {
+ static bool printed;
+
+ /* The below message is checked in recovery-small.sh test_54 */
+ CERROR("%s: went back in time (transno %lld was previously committed, server now claims %lld)!\n",
+ obd2cli_tgt(imp->imp_obd), aa->pcaa_peer_committed,
lustre_msg_get_last_committed(request->rq_repmsg));
+ if (!printed) {
+ CERROR("For further information, see http://doc.lustre.org/lustre_manual.xhtml#went_back_in_time\n");
+ printed = true;
+ }
}
finish:
if (ocd &&
(ocd->ocd_connect_flags & OBD_CONNECT_VERSION) &&
(ocd->ocd_version != LUSTRE_VERSION_CODE)) {
- LCONSOLE_ERROR_MSG(0x16a, "Server %s version "
- "(%d.%d.%d.%d)"
- " refused connection from this client "
- "with an incompatible version (%s). "
- "Client must be recompiled\n",
- obd2cli_tgt(imp->imp_obd),
- OBD_OCD_VERSION_MAJOR(ocd->ocd_version),
- OBD_OCD_VERSION_MINOR(ocd->ocd_version),
- OBD_OCD_VERSION_PATCH(ocd->ocd_version),
- OBD_OCD_VERSION_FIX(ocd->ocd_version),
- LUSTRE_VERSION_STRING);
+ LCONSOLE_ERROR_MSG(0x16a, "Server %s version "
+ "(%d.%d.%d.%d)"
+ " refused connection from this client "
+ "with an incompatible version (%s). "
+ "Client must be recompiled\n",
+ obd2cli_tgt(imp->imp_obd),
+ OBD_OCD_VERSION_MAJOR(ocd->ocd_version),
+ OBD_OCD_VERSION_MINOR(ocd->ocd_version),
+ OBD_OCD_VERSION_PATCH(ocd->ocd_version),
+ OBD_OCD_VERSION_FIX(ocd->ocd_version),
+ LUSTRE_VERSION_STRING);
ptlrpc_deactivate_import_nolock(imp);
import_set_state_nolock(imp, LUSTRE_IMP_CLOSED);
inact = true;
req = ptlrpc_request_alloc_pack(imp, &RQF_MDS_DISCONNECT,
LUSTRE_OBD_VERSION, rq_opc);
if (req == NULL)
- RETURN(NULL);
+ RETURN(ERR_PTR(-ENOMEM));
/* We are disconnecting, do not retry a failed DISCONNECT rpc if
* it fails. We can get through the above with a down server
rq_list) {
spin_lock(&old->rq_lock);
if (old->rq_import_generation == imp->imp_generation - 1 &&
- !old->rq_no_resend)
+ ((imp->imp_initiated_at == imp->imp_generation) ||
+ !old->rq_no_resend))
old->rq_import_generation = imp->imp_generation;
spin_unlock(&old->rq_lock);
}
struct obd_import *imp = req->rq_import;
int connect = 0;
- DEBUG_REQ(D_HA, req, "inflight=%d, refcount=%d: rc = %d ",
+ DEBUG_REQ(D_HA, req, "inflight=%d, refcount=%d: rc = %d",
atomic_read(&imp->imp_inflight),
atomic_read(&imp->imp_refcount), rc);
connect = 1;
}
}
- spin_unlock(&imp->imp_lock);
if (connect) {
- rc = ptlrpc_connect_import(imp);
+ rc = ptlrpc_connect_import_locked(imp);
if (rc >= 0)
ptlrpc_pinger_add_import(imp);
+ } else {
+ spin_unlock(&imp->imp_lock);
}
return 0;