- down(&imp->imp_recovery_sem);
- /* If recovery happened while we waited, we're done. */
- if (imp->imp_state == LUSTRE_IMP_FULL)
- GOTO(out, rc = 0);
-
- LASSERT (imp->imp_state == LUSTRE_IMP_DISCON);
-
- if (new_uuid) {
- struct ptlrpc_connection *conn;
- struct obd_uuid uuid;
- struct ptlrpc_peer peer;
- struct obd_export *dlmexp;
-
- obd_str2uuid(&uuid, new_uuid);
- if (ptlrpc_uuid_to_peer(&uuid, &peer)) {
- CERROR("no connection found for UUID %s\n", new_uuid);
- GOTO(out, rc = -EINVAL);
- }
-
- conn = ptlrpc_get_connection(&peer, &uuid);
- if (!conn)
- GOTO(out, rc = -ENOMEM);
-
- CDEBUG(D_HA, "switching import %s/%s from %s to %s\n",
- imp->imp_target_uuid.uuid, imp->imp_obd->obd_name,
- imp->imp_connection->c_remote_uuid.uuid,
- conn->c_remote_uuid.uuid);
-
- /* Switch the import's connection and the DLM export's
- * connection (which are almost certainly the same, but we
- * keep distinct refs just to make things clearer. I think. */
- if (imp->imp_connection)
- ptlrpc_put_connection(imp->imp_connection);
- /* We hand off the ref from ptlrpc_get_connection. */
- imp->imp_connection = conn;
-
- dlmexp = class_conn2export(&imp->imp_dlm_handle);
- if (dlmexp->exp_connection)
- ptlrpc_put_connection(dlmexp->exp_connection);
- dlmexp->exp_connection = ptlrpc_connection_addref(conn);
- class_export_put(dlmexp);
-
- }
-
- connect:
- rc = ptlrpc_connect_import(imp);
-
- if (rc < 0) {
- CERROR("failed to reconnect to %s@%s: %d\n",
- imp->imp_target_uuid.uuid,
- imp->imp_connection->c_remote_uuid.uuid, rc);
- GOTO(out, rc);
- }
-
- if (imp->imp_state == LUSTRE_IMP_EVICTED) {
- CDEBUG(D_HA, "evicted from %s@%s; invalidating\n",
- imp->imp_target_uuid.uuid,
- imp->imp_connection->c_remote_uuid.uuid);
- ptlrpc_set_import_active(imp, 0);
- CDEBUG(D_HA, "%s: new state: RECOVER\n",
- imp->imp_client->cli_name);
- imp->imp_state = LUSTRE_IMP_RECOVER;
- }
-
- if (imp->imp_state == LUSTRE_IMP_REPLAY) {
- CDEBUG(D_HA, "replay requested by %s\n",
- imp->imp_target_uuid.uuid);
- rc = ptlrpc_replay(imp);
- if (rc)
- GOTO(out, rc);
-
- rc = ldlm_replay_locks(imp);
- if (rc)
- GOTO(out, rc);
-
- rc = signal_completed_replay(imp);
- if (rc)
- GOTO(out, rc);
- CDEBUG(D_HA, "%s: new state: RECOVER\n",
- imp->imp_client->cli_name);
- imp->imp_state = LUSTRE_IMP_RECOVER;
- }
-
- if (imp->imp_state == LUSTRE_IMP_RECOVER) {
- CDEBUG(D_HA, "reconnected to %s@%s\n",
- imp->imp_target_uuid.uuid,
- imp->imp_connection->c_remote_uuid.uuid);
-
- ptlrpc_set_import_active(imp, 1);
- ptlrpc_resend(imp);
- spin_lock_irqsave(&imp->imp_lock, flags);
- CDEBUG(D_HA, "%s: new state: FULL\n",
- imp->imp_client->cli_name);
- imp->imp_state = LUSTRE_IMP_FULL;
- spin_unlock_irqrestore(&imp->imp_lock, flags);
- ptlrpc_wake_delayed(imp);
- }