1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2 * vim:expandtab:shiftwidth=8:tabstop=8:
4 * Copyright (c) 2002, 2003 Cluster File Systems, Inc.
5 * Author: Mike Shaver <shaver@clusterfs.com>
7 * This file is part of Lustre, http://www.lustre.org.
9 * Lustre is free software; you can redistribute it and/or
10 * modify it under the terms of version 2 of the GNU General Public
11 * License as published by the Free Software Foundation.
13 * Lustre is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with Lustre; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 #define DEBUG_SUBSYSTEM S_RPC
26 # define EXPORT_SYMTAB
30 # include <linux/config.h>
31 # include <linux/module.h>
32 # include <linux/kmod.h>
34 # include <liblustre.h>
37 #include <linux/obd_support.h>
38 #include <linux/lustre_ha.h>
39 #include <linux/lustre_net.h>
40 #include <linux/lustre_import.h>
41 #include <linux/lustre_export.h>
42 #include <linux/obd.h>
43 #include <linux/obd_class.h>
45 #include "ptlrpc_internal.h"
47 struct ptlrpc_connect_async_args {
48 __u64 pcaa_peer_committed;
49 int pcaa_initial_connect;
52 /* A CLOSED import should remain so. */
53 #define IMPORT_SET_STATE_NOLOCK(imp, state) \
55 if (imp->imp_state != LUSTRE_IMP_CLOSED) { \
56 CDEBUG(D_HA, "%p %s: changing import state from %s to %s\n", \
57 imp, imp->imp_target_uuid.uuid, \
58 ptlrpc_import_state_name(imp->imp_state), \
59 ptlrpc_import_state_name(state)); \
60 imp->imp_state = state; \
64 #define IMPORT_SET_STATE(imp, state) \
66 unsigned long flags; \
68 spin_lock_irqsave(&imp->imp_lock, flags); \
69 IMPORT_SET_STATE_NOLOCK(imp, state); \
70 spin_unlock_irqrestore(&imp->imp_lock, flags); \
74 static int ptlrpc_connect_interpret(struct ptlrpc_request *request,
76 int ptlrpc_import_recovery_state_machine(struct obd_import *imp);
78 /* Only this function is allowed to change the import state when it is
79 * CLOSED. I would rather refcount the import and free it after
80 * disconnection like we do with exports. To do that, the client_obd
81 * will need to save the peer info somewhere other than in the import,
83 int ptlrpc_init_import(struct obd_import *imp)
87 spin_lock_irqsave(&imp->imp_lock, flags);
89 imp->imp_generation++;
90 imp->imp_state = LUSTRE_IMP_NEW;
92 spin_unlock_irqrestore(&imp->imp_lock, flags);
96 EXPORT_SYMBOL(ptlrpc_init_import);
98 #define UUID_STR "_UUID"
99 static void deuuidify(char *uuid, const char *prefix, char **uuid_start, int *uuid_len)
101 *uuid_start = !prefix || strncmp(uuid, prefix, strlen(prefix))
102 ? uuid : uuid + strlen(prefix);
104 *uuid_len = strlen(*uuid_start);
106 if (*uuid_len < strlen(UUID_STR))
109 if (!strncmp(*uuid_start + *uuid_len - strlen(UUID_STR),
110 UUID_STR, strlen(UUID_STR)))
111 *uuid_len -= strlen(UUID_STR);
114 /* Returns true if import was FULL, false if import was already not
117 int ptlrpc_set_import_discon(struct obd_import *imp)
122 spin_lock_irqsave(&imp->imp_lock, flags);
124 if (imp->imp_state == LUSTRE_IMP_FULL) {
128 deuuidify(imp->imp_target_uuid.uuid, NULL,
129 &target_start, &target_len);
131 LCONSOLE_ERROR("Connection to service %.*s via nid %s was "
132 "lost; in progress operations using this "
133 "service will %s.\n",
134 target_len, target_start,
135 libcfs_nid2str(imp->imp_connection->c_peer.nid),
137 ? "wait for recovery to complete"
140 CWARN("%s: connection lost to %s@%s\n",
141 imp->imp_obd->obd_name,
142 imp->imp_target_uuid.uuid,
143 imp->imp_connection->c_remote_uuid.uuid);
144 IMPORT_SET_STATE_NOLOCK(imp, LUSTRE_IMP_DISCON);
145 spin_unlock_irqrestore(&imp->imp_lock, flags);
146 obd_import_event(imp->imp_obd, imp, IMP_EVENT_DISCON);
149 spin_unlock_irqrestore(&imp->imp_lock, flags);
150 CDEBUG(D_HA, "%p %s: import already not connected: %s\n",
151 imp,imp->imp_client->cli_name,
152 ptlrpc_import_state_name(imp->imp_state));
159 * This acts as a barrier; all existing requests are rejected, and
160 * no new requests will be accepted until the import is valid again.
162 void ptlrpc_deactivate_import(struct obd_import *imp)
167 spin_lock_irqsave(&imp->imp_lock, flags);
168 CDEBUG(D_HA, "setting import %s INVALID\n", imp->imp_target_uuid.uuid);
169 imp->imp_invalid = 1;
170 imp->imp_generation++;
171 spin_unlock_irqrestore(&imp->imp_lock, flags);
173 ptlrpc_abort_inflight(imp);
174 obd_import_event(imp->imp_obd, imp, IMP_EVENT_INACTIVE);
178 * This function will invalidate the import, if necessary, then block
179 * for all the RPC completions, and finally notify the obd to
180 * invalidate its state (ie cancel locks, clear pending requests,
183 void ptlrpc_invalidate_import(struct obd_import *imp)
185 struct l_wait_info lwi;
188 if (!imp->imp_invalid)
189 ptlrpc_deactivate_import(imp);
191 LASSERT(imp->imp_invalid);
193 /* wait for all requests to error out and call completion callbacks */
194 lwi = LWI_TIMEOUT_INTR(MAX(obd_timeout * HZ, 1), NULL,
196 rc = l_wait_event(imp->imp_recovery_waitq,
197 (atomic_read(&imp->imp_inflight) == 0),
201 CERROR("%s: rc = %d waiting for callback (%d != 0)\n",
202 imp->imp_target_uuid.uuid, rc,
203 atomic_read(&imp->imp_inflight));
205 obd_import_event(imp->imp_obd, imp, IMP_EVENT_INVALIDATE);
208 void ptlrpc_activate_import(struct obd_import *imp)
210 struct obd_device *obd = imp->imp_obd;
213 spin_lock_irqsave(&imp->imp_lock, flags);
214 imp->imp_invalid = 0;
215 spin_unlock_irqrestore(&imp->imp_lock, flags);
217 obd_import_event(obd, imp, IMP_EVENT_ACTIVE);
220 void ptlrpc_fail_import(struct obd_import *imp, int generation)
224 LASSERT (!imp->imp_dlm_fake);
226 if (ptlrpc_set_import_discon(imp)) {
229 if (!imp->imp_replayable) {
230 CDEBUG(D_HA, "import %s@%s for %s not replayable, "
231 "auto-deactivating\n",
232 imp->imp_target_uuid.uuid,
233 imp->imp_connection->c_remote_uuid.uuid,
234 imp->imp_obd->obd_name);
235 ptlrpc_deactivate_import(imp);
238 CDEBUG(D_HA, "%s: waking up pinger\n",
239 imp->imp_target_uuid.uuid);
241 spin_lock_irqsave(&imp->imp_lock, flags);
242 imp->imp_force_verify = 1;
243 spin_unlock_irqrestore(&imp->imp_lock, flags);
245 ptlrpc_pinger_wake_up();
250 static int import_select_connection(struct obd_import *imp)
252 struct obd_import_conn *imp_conn;
253 struct obd_export *dlmexp;
256 spin_lock(&imp->imp_lock);
258 if (list_empty(&imp->imp_conn_list)) {
259 CERROR("%s: no connections available\n",
260 imp->imp_obd->obd_name);
261 spin_unlock(&imp->imp_lock);
265 if (imp->imp_conn_current &&
266 !(imp->imp_conn_current->oic_item.next == &imp->imp_conn_list)) {
267 imp_conn = list_entry(imp->imp_conn_current->oic_item.next,
268 struct obd_import_conn, oic_item);
270 imp_conn = list_entry(imp->imp_conn_list.next,
271 struct obd_import_conn, oic_item);
274 /* switch connection, don't mind if it's same as the current one */
275 if (imp->imp_connection)
276 ptlrpc_put_connection(imp->imp_connection);
277 imp->imp_connection = ptlrpc_connection_addref(imp_conn->oic_conn);
279 dlmexp = class_conn2export(&imp->imp_dlm_handle);
280 LASSERT(dlmexp != NULL);
281 if (dlmexp->exp_connection)
282 ptlrpc_put_connection(dlmexp->exp_connection);
283 dlmexp->exp_connection = ptlrpc_connection_addref(imp_conn->oic_conn);
284 class_export_put(dlmexp);
286 imp->imp_conn_current = imp_conn;
287 CDEBUG(D_HA, "%s: import %p using connection %s\n",
288 imp->imp_obd->obd_name, imp, imp_conn->oic_uuid.uuid);
289 spin_unlock(&imp->imp_lock);
294 int ptlrpc_connect_import(struct obd_import *imp, char * new_uuid)
296 struct obd_device *obd = imp->imp_obd;
297 int initial_connect = 0;
299 __u64 committed_before_reconnect = 0;
300 struct ptlrpc_request *request;
301 int size[] = {sizeof(imp->imp_target_uuid),
302 sizeof(obd->obd_uuid),
303 sizeof(imp->imp_dlm_handle),
304 sizeof(imp->imp_connect_data)};
305 char *tmp[] = {imp->imp_target_uuid.uuid,
307 (char *)&imp->imp_dlm_handle,
308 (char *)&imp->imp_connect_data};
309 struct ptlrpc_connect_async_args *aa;
312 spin_lock_irqsave(&imp->imp_lock, flags);
313 if (imp->imp_state == LUSTRE_IMP_CLOSED) {
314 spin_unlock_irqrestore(&imp->imp_lock, flags);
315 CERROR("can't connect to a closed import\n");
317 } else if (imp->imp_state == LUSTRE_IMP_FULL) {
318 spin_unlock_irqrestore(&imp->imp_lock, flags);
319 CERROR("already connected\n");
321 } else if (imp->imp_state == LUSTRE_IMP_CONNECTING) {
322 spin_unlock_irqrestore(&imp->imp_lock, flags);
323 CERROR("already connecting\n");
327 IMPORT_SET_STATE_NOLOCK(imp, LUSTRE_IMP_CONNECTING);
330 imp->imp_resend_replay = 0;
332 if (imp->imp_remote_handle.cookie == 0) {
335 committed_before_reconnect = imp->imp_peer_committed_transno;
338 spin_unlock_irqrestore(&imp->imp_lock, flags);
341 struct obd_uuid uuid;
343 obd_str2uuid(&uuid, new_uuid);
344 rc = import_set_conn_priority(imp, &uuid);
349 rc = import_select_connection(imp);
353 request = ptlrpc_prep_req(imp, imp->imp_connect_op, 4, size, tmp);
355 GOTO(out, rc = -ENOMEM);
358 lustre_msg_add_op_flags(request->rq_reqmsg, MSG_CONNECT_LIBCLIENT);
361 request->rq_send_state = LUSTRE_IMP_CONNECTING;
362 size[0] = sizeof(struct obd_connect_data);
363 request->rq_replen = lustre_msg_size(1, size);
364 request->rq_interpret_reply = ptlrpc_connect_interpret;
366 LASSERT (sizeof (*aa) <= sizeof (request->rq_async_args));
367 aa = (struct ptlrpc_connect_async_args *)&request->rq_async_args;
368 memset(aa, 0, sizeof *aa);
370 aa->pcaa_peer_committed = committed_before_reconnect;
371 aa->pcaa_initial_connect = initial_connect;
373 if (aa->pcaa_initial_connect)
374 imp->imp_replayable = 1;
376 DEBUG_REQ(D_RPCTRACE, request, "(re)connect request");
377 ptlrpcd_add_req(request);
381 IMPORT_SET_STATE(imp, LUSTRE_IMP_DISCON);
386 EXPORT_SYMBOL(ptlrpc_connect_import);
388 static void ptlrpc_maybe_ping_import_soon(struct obd_import *imp)
390 struct obd_import_conn *imp_conn;
396 spin_lock_irqsave(&imp->imp_lock, flags);
397 if (list_empty(&imp->imp_conn_list))
400 imp_conn = list_entry(imp->imp_conn_list.prev,
401 struct obd_import_conn,
404 if (imp->imp_conn_current != imp_conn) {
405 ptlrpc_ping_import_soon(imp);
410 spin_unlock_irqrestore(&imp->imp_lock, flags);
413 ptlrpc_pinger_wake_up();
418 static int ptlrpc_connect_interpret(struct ptlrpc_request *request,
421 struct ptlrpc_connect_async_args *aa = data;
422 struct obd_import *imp = request->rq_import;
423 struct lustre_handle old_hdl;
428 spin_lock_irqsave(&imp->imp_lock, flags);
429 if (imp->imp_state == LUSTRE_IMP_CLOSED) {
430 spin_unlock_irqrestore(&imp->imp_lock, flags);
433 spin_unlock_irqrestore(&imp->imp_lock, flags);
438 LASSERT(imp->imp_conn_current);
440 msg_flags = lustre_msg_get_op_flags(request->rq_repmsg);
442 /* All imports are pingable */
443 imp->imp_pingable = 1;
445 if (aa->pcaa_initial_connect) {
446 if (msg_flags & MSG_CONNECT_REPLAYABLE) {
447 CDEBUG(D_HA, "connected to replayable target: %s\n",
448 imp->imp_target_uuid.uuid);
449 imp->imp_replayable = 1;
451 imp->imp_replayable = 0;
453 imp->imp_remote_handle = request->rq_repmsg->handle;
455 IMPORT_SET_STATE(imp, LUSTRE_IMP_FULL);
456 GOTO(finish, rc = 0);
459 /* Determine what recovery state to move the import to. */
460 if (MSG_CONNECT_RECONNECT & msg_flags) {
461 memset(&old_hdl, 0, sizeof(old_hdl));
462 if (!memcmp(&old_hdl, &request->rq_repmsg->handle,
464 CERROR("%s@%s didn't like our handle "LPX64
465 ", failed\n", imp->imp_target_uuid.uuid,
466 imp->imp_connection->c_remote_uuid.uuid,
467 imp->imp_dlm_handle.cookie);
468 GOTO(out, rc = -ENOTCONN);
471 if (memcmp(&imp->imp_remote_handle, &request->rq_repmsg->handle,
472 sizeof(imp->imp_remote_handle))) {
473 CERROR("%s@%s changed handle from "LPX64" to "LPX64
474 "; copying, but this may foreshadow disaster\n",
475 imp->imp_target_uuid.uuid,
476 imp->imp_connection->c_remote_uuid.uuid,
477 imp->imp_remote_handle.cookie,
478 request->rq_repmsg->handle.cookie);
479 imp->imp_remote_handle = request->rq_repmsg->handle;
481 CDEBUG(D_HA, "reconnected to %s@%s after partition\n",
482 imp->imp_target_uuid.uuid,
483 imp->imp_connection->c_remote_uuid.uuid);
486 if (imp->imp_invalid) {
487 IMPORT_SET_STATE(imp, LUSTRE_IMP_EVICTED);
488 } else if (MSG_CONNECT_RECOVERING & msg_flags) {
489 CDEBUG(D_HA, "%s: reconnected to %s during replay\n",
490 imp->imp_obd->obd_name,
491 imp->imp_target_uuid.uuid);
492 imp->imp_resend_replay = 1;
493 IMPORT_SET_STATE(imp, LUSTRE_IMP_REPLAY);
495 IMPORT_SET_STATE(imp, LUSTRE_IMP_RECOVER);
497 } else if ((MSG_CONNECT_RECOVERING & msg_flags) && !imp->imp_invalid) {
498 LASSERT(imp->imp_replayable);
499 imp->imp_remote_handle = request->rq_repmsg->handle;
500 imp->imp_last_replay_transno = 0;
501 IMPORT_SET_STATE(imp, LUSTRE_IMP_REPLAY);
503 imp->imp_remote_handle = request->rq_repmsg->handle;
504 IMPORT_SET_STATE(imp, LUSTRE_IMP_EVICTED);
507 /* Sanity checks for a reconnected import. */
508 if (!(imp->imp_replayable) != !(msg_flags & MSG_CONNECT_REPLAYABLE)) {
509 CERROR("imp_replayable flag does not match server "
510 "after reconnect. We should LBUG right here.\n");
513 if (request->rq_repmsg->last_committed < aa->pcaa_peer_committed) {
514 CERROR("%s went back in time (transno "LPD64
515 " was previously committed, server now claims "LPD64
516 ")! is shared storage not coherent?\n",
517 imp->imp_target_uuid.uuid,
518 aa->pcaa_peer_committed,
519 request->rq_repmsg->last_committed);
523 rc = ptlrpc_import_recovery_state_machine(imp);
525 if (rc == -ENOTCONN) {
526 CDEBUG(D_HA, "evicted/aborted by %s@%s during recovery;"
527 "invalidating and reconnecting\n",
528 imp->imp_target_uuid.uuid,
529 imp->imp_connection->c_remote_uuid.uuid);
530 ptlrpc_connect_import(imp, NULL);
534 list_del(&imp->imp_conn_current->oic_item);
535 list_add(&imp->imp_conn_current->oic_item,
536 &imp->imp_conn_list);
537 imp->imp_conn_current = NULL;
542 IMPORT_SET_STATE(imp, LUSTRE_IMP_DISCON);
543 if (aa->pcaa_initial_connect && !imp->imp_initial_recov) {
544 ptlrpc_deactivate_import(imp);
547 ptlrpc_maybe_ping_import_soon(imp);
549 CDEBUG(D_HA, "recovery of %s on %s failed (%d)\n",
550 imp->imp_target_uuid.uuid,
551 (char *)imp->imp_connection->c_remote_uuid.uuid, rc);
554 wake_up(&imp->imp_recovery_waitq);
558 static int completed_replay_interpret(struct ptlrpc_request *req,
561 atomic_dec(&req->rq_import->imp_replay_inflight);
562 if (req->rq_status == 0) {
563 ptlrpc_import_recovery_state_machine(req->rq_import);
565 CDEBUG(D_HA, "%s: LAST_REPLAY message error: %d, "
567 req->rq_import->imp_obd->obd_name, req->rq_status);
568 ptlrpc_connect_import(req->rq_import, NULL);
574 static int signal_completed_replay(struct obd_import *imp)
576 struct ptlrpc_request *req;
579 LASSERT(atomic_read(&imp->imp_replay_inflight) == 0);
580 atomic_inc(&imp->imp_replay_inflight);
582 req = ptlrpc_prep_req(imp, OBD_PING, 0, NULL, NULL);
584 atomic_dec(&imp->imp_replay_inflight);
588 req->rq_replen = lustre_msg_size(0, NULL);
589 req->rq_send_state = LUSTRE_IMP_REPLAY_WAIT;
590 req->rq_reqmsg->flags |= MSG_LAST_REPLAY;
591 req->rq_timeout *= 3;
592 req->rq_interpret_reply = completed_replay_interpret;
594 ptlrpcd_add_req(req);
599 static int ptlrpc_invalidate_import_thread(void *data)
601 struct obd_import *imp = data;
609 SIGNAL_MASK_LOCK(current, flags);
610 sigfillset(¤t->blocked);
612 SIGNAL_MASK_UNLOCK(current, flags);
613 THREAD_NAME(current->comm, sizeof(current->comm), "ll_imp_inval");
616 CDEBUG(D_HA, "thread invalidate import %s to %s@%s\n",
617 imp->imp_obd->obd_name, imp->imp_target_uuid.uuid,
618 imp->imp_connection->c_remote_uuid.uuid);
620 ptlrpc_invalidate_import(imp);
622 IMPORT_SET_STATE(imp, LUSTRE_IMP_RECOVER);
623 ptlrpc_import_recovery_state_machine(imp);
629 int ptlrpc_import_recovery_state_machine(struct obd_import *imp)
636 if (imp->imp_state == LUSTRE_IMP_EVICTED) {
637 deuuidify(imp->imp_target_uuid.uuid, NULL,
638 &target_start, &target_len);
639 LCONSOLE_ERROR("This client was evicted by %.*s; in progress "
640 "operations using this service will fail.\n",
641 target_len, target_start);
642 CDEBUG(D_HA, "evicted from %s@%s; invalidating\n",
643 imp->imp_target_uuid.uuid,
644 imp->imp_connection->c_remote_uuid.uuid);
647 rc = kernel_thread(ptlrpc_invalidate_import_thread, imp,
648 CLONE_VM | CLONE_FILES);
650 CERROR("error starting invalidate thread: %d\n", rc);
655 ptlrpc_invalidate_import(imp);
657 IMPORT_SET_STATE(imp, LUSTRE_IMP_RECOVER);
661 if (imp->imp_state == LUSTRE_IMP_REPLAY) {
662 CDEBUG(D_HA, "replay requested by %s\n",
663 imp->imp_target_uuid.uuid);
664 rc = ptlrpc_replay_next(imp, &inflight);
666 atomic_read(&imp->imp_replay_inflight) == 0) {
667 IMPORT_SET_STATE(imp, LUSTRE_IMP_REPLAY_LOCKS);
668 rc = ldlm_replay_locks(imp);
675 if (imp->imp_state == LUSTRE_IMP_REPLAY_LOCKS) {
676 if (atomic_read(&imp->imp_replay_inflight) == 0) {
677 IMPORT_SET_STATE(imp, LUSTRE_IMP_REPLAY_WAIT);
678 rc = signal_completed_replay(imp);
685 if (imp->imp_state == LUSTRE_IMP_REPLAY_WAIT) {
686 if (atomic_read(&imp->imp_replay_inflight) == 0) {
687 IMPORT_SET_STATE(imp, LUSTRE_IMP_RECOVER);
691 if (imp->imp_state == LUSTRE_IMP_RECOVER) {
694 CDEBUG(D_HA, "reconnected to %s@%s\n",
695 imp->imp_target_uuid.uuid,
696 imp->imp_connection->c_remote_uuid.uuid);
698 rc = ptlrpc_resend(imp);
701 IMPORT_SET_STATE(imp, LUSTRE_IMP_FULL);
702 ptlrpc_activate_import(imp);
704 deuuidify(imp->imp_target_uuid.uuid, NULL,
705 &target_start, &target_len);
706 nidstr = libcfs_nid2str(imp->imp_connection->c_peer.nid);
708 LCONSOLE_INFO("Connection restored to service %.*s using nid "
709 "%s.\n", target_len, target_start, nidstr);
711 CWARN("%s: connection restored to %s@%s\n",
712 imp->imp_obd->obd_name,
713 imp->imp_target_uuid.uuid,
714 imp->imp_connection->c_remote_uuid.uuid);
717 if (imp->imp_state == LUSTRE_IMP_FULL) {
718 wake_up(&imp->imp_recovery_waitq);
719 ptlrpc_wake_delayed(imp);
726 static int back_to_sleep(void *unused)
731 int ptlrpc_disconnect_import(struct obd_import *imp)
733 struct ptlrpc_request *request;
739 switch (imp->imp_connect_op) {
740 case OST_CONNECT: rq_opc = OST_DISCONNECT; break;
741 case MDS_CONNECT: rq_opc = MDS_DISCONNECT; break;
742 case MGMT_CONNECT:rq_opc = MGMT_DISCONNECT;break;
744 CERROR("don't know how to disconnect from %s (connect_op %d)\n",
745 imp->imp_target_uuid.uuid, imp->imp_connect_op);
750 if (ptlrpc_import_in_recovery(imp)) {
751 struct l_wait_info lwi;
752 lwi = LWI_TIMEOUT_INTR(MAX(obd_timeout * HZ, 1), back_to_sleep,
754 rc = l_wait_event(imp->imp_recovery_waitq,
755 !ptlrpc_import_in_recovery(imp), &lwi);
759 spin_lock_irqsave(&imp->imp_lock, flags);
760 if (imp->imp_state != LUSTRE_IMP_FULL) {
763 spin_unlock_irqrestore(&imp->imp_lock, flags);
765 request = ptlrpc_prep_req(imp, rq_opc, 0, NULL, NULL);
767 /* For non-replayable connections, don't attempt
768 reconnect if this fails */
769 if (!imp->imp_replayable) {
770 request->rq_no_resend = 1;
771 IMPORT_SET_STATE(imp, LUSTRE_IMP_CONNECTING);
772 request->rq_send_state = LUSTRE_IMP_CONNECTING;
774 request->rq_replen = lustre_msg_size(0, NULL);
775 rc = ptlrpc_queue_wait(request);
776 ptlrpc_req_finished(request);
779 spin_lock_irqsave(&imp->imp_lock, flags);
781 IMPORT_SET_STATE_NOLOCK(imp, LUSTRE_IMP_CLOSED);
782 memset(&imp->imp_remote_handle, 0, sizeof(imp->imp_remote_handle));
783 spin_unlock_irqrestore(&imp->imp_lock, flags);