Whamcloud - gitweb
LU-14027 ldlm: Do not hang if recovery restarted during lock replay 24/41224/2
authorOleg Drokin <green@whamcloud.com>
Wed, 14 Oct 2020 03:55:02 +0000 (23:55 -0400)
committerOleg Drokin <green@whamcloud.com>
Thu, 4 Mar 2021 08:36:43 +0000 (08:36 +0000)
LU-13600 introduced lock ratelimiting logic, but it did not take
into account that if there's a disconnection in the REPLAY_LOCKS
phase then yet unsent locks get stuck in the sending queue so
the replay locks thread hangs with imp_replay_inflight elevated
above zero.

The direct consequence from that is recovery state machine never
advances from REPLAY to REPLAY_LOCKS status when imp_replay_inflight
is non zero.

Adjust __ldlm_replay_locks() to check if the import state changed
before attempting to send any more requests.

Add a testcase.

Lustre-change: https://review.whamcloud.com/40238
Lustre-commit: 7ca495ec67f474e10352077fc40123e4818b8e69

Change-Id: Idbaf5461f33d1884088269d67d01071c7e1bf8a5
Signed-off-by: Oleg Drokin <green@whamcloud.com>
Fixes: 3b613a442b ("LU-13600 ptlrpc: limit rate of lock replays")
Reviewed-by: Mike Pershin <mpershin@whamcloud.com>
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
Signed-off-by: Etienne AUJAMES <eaujames@ddn.com>
Fixes: 6b6d9c0911 ("LU-13600 ptlrpc: limit rate of lock replays")
Reviewed-on: https://review.whamcloud.com/41224
Tested-by: jenkins <devops@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
lustre/include/obd_support.h
lustre/ldlm/ldlm_lib.c
lustre/ldlm/ldlm_request.c
lustre/tests/replay-single.sh

index 56dfc54..32121b5 100644 (file)
@@ -394,6 +394,7 @@ extern char obd_jobid_var[];
 
 #define OBD_FAIL_LDLM_GRANT_CHECK        0x32a
 #define OBD_FAIL_LDLM_PROLONG_PAUSE     0x32b
+#define OBD_FAIL_LDLM_LOCK_REPLAY       0x32d
 
 /* LOCKLESS IO */
 #define OBD_FAIL_LDLM_SET_CONTENTION     0x385
index bca75f0..e080e35 100644 (file)
@@ -2589,6 +2589,11 @@ static int target_recovery_thread(void *arg)
                LASSERT(trd->trd_processing_task == current_pid());
                DEBUG_REQ(D_HA, req, "processing lock from %s: ",
                          libcfs_nid2str(req->rq_peer.nid));
+               if (OBD_FAIL_CHECK(OBD_FAIL_LDLM_LOCK_REPLAY)) {
+                       req->rq_status = -ENODEV;
+                       target_request_copy_put(req);
+                       continue;
+               }
                handle_recovery_req(thread, req,
                                    trd->trd_recovery_handler);
                target_request_copy_put(req);
index be0bb8e..8499ecb 100644 (file)
@@ -2450,9 +2450,11 @@ int __ldlm_replay_locks(struct obd_import *imp, bool rate_limit)
 
        list_for_each_entry_safe(lock, next, &list, l_pending_chain) {
                list_del_init(&lock->l_pending_chain);
-               if (rc) {
+               /* If we disconnected in the middle - cleanup and let
+                * reconnection to happen again. LU-14027 */
+               if (rc || (imp->imp_state != LUSTRE_IMP_REPLAY_LOCKS)) {
                        LDLM_LOCK_RELEASE(lock);
-                       continue; /* or try to do the rest? */
+                       continue;
                }
                rc = replay_one_lock(imp, lock);
                LDLM_LOCK_RELEASE(lock);
index 7882652..12bd433 100755 (executable)
@@ -4871,6 +4871,51 @@ test_132a() {
 }
 run_test 132a "PFL new component instantiate replay"
 
+# LU-14027
+test_135() {
+       mkdir $DIR/$tdir || error "mkdir $DIR/$tdir failed"
+
+       # All files to ost1
+       $LFS setstripe -S $((128 * 1024)) -i 0 $DIR/$tdir
+
+       replay_barrier ost1
+
+       # Create 20 files so we have 20 ost locks
+       for i in $(seq 20) ; do
+               echo blah > $DIR/$tdir/file.${i}
+       done
+
+       shutdown_facet ost1
+       reboot_facet ost1
+       change_active ost1
+       wait_for_facet ost1
+
+       #define OBD_FAIL_TGT_REPLAY_RECONNECT     0x32d
+       # Make sure lock replay server side never completes and errors out.
+       do_facet ost1 "$LCTL set_param fail_val=20"
+       do_facet ost1 "$LCTL set_param fail_loc=0x32d"
+
+       mount_facet ost1
+
+       # Now make sure we notice
+       (sync;sync;sync) &
+       local PID=$?
+       sleep 20 # should we do something proactive to make reconnects go?
+       kill -0 $PID || error "Unexpected sync success"
+
+       shutdown_facet ost1
+       reboot_facet ost1
+       change_active ost1
+       wait_for_facet ost1
+
+       do_facet ost1 "$LCTL set_param fail_loc=0"
+       mount_facet ost1
+       echo blah > $DIR/$tdir/file.test2
+
+       rm -rf $DIR/$tdir
+}
+run_test 135 "Server failure in lock replay phase"
+
 complete $SECONDS
 check_and_cleanup_lustre
 exit_status