Whamcloud - gitweb
LU-15653 client: able to cleanup devices manually 59/46859/7
authorMikhail Pershin <mpershin@whamcloud.com>
Tue, 22 Feb 2022 17:34:37 +0000 (20:34 +0300)
committerOleg Drokin <green@whamcloud.com>
Tue, 12 Jul 2022 00:09:27 +0000 (00:09 +0000)
Using 'lctl cleanup/detach' could be needed in situations
with unclean umount. Meanwhile that doesn't work now for
LMV and also could cause panic after all

Patch restores ability to cleanup/detach client devices
manually.
- debugfs and lprocfs cleanup in lmv_precleanup() are moved
  lmv_cleanup() to be not cleared too early. This prevents
  hang on 'lctl cleanup' for LMV device
- test 172 is added in sanity. It skips device cleanup during
  normal umount, keeping device alive without client mount
  then manually cleanups/detaches them
- prevent negative lov_connections in lov_disconnect() and
  handle it gracefully
- remove obd_cleanup_client_import() in mdc_precleanup(),
  it is called already inside osc_precleanup_common()

Signed-off-by: Mikhail Pershin <mpershin@whamcloud.com>
Change-Id: I8a3868fabd1d805e827d04852d1614a3fe57ce35
Reviewed-on: https://review.whamcloud.com/46859
Reviewed-by: John L. Hammond <jhammond@whamcloud.com>
Tested-by: jenkins <devops@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
lustre/include/obd_support.h
lustre/llite/llite_lib.c
lustre/lmv/lmv_obd.c
lustre/lov/lov_obd.c
lustre/mdc/mdc_request.c
lustre/tests/sanity.sh

index 80afed0..f6aea9a 100644 (file)
@@ -479,6 +479,7 @@ extern char obd_jobid_var[];
 #define OBD_FAIL_OBD_ZERO_NLINK_RACE    0x60b
 #define OBD_FAIL_OBD_STOP_MDS_RACE      0x60c
 #define OBD_FAIL_OBD_SETUP              0x60d
+#define OBD_FAIL_OBD_CLEANUP            0x60e
 
 #define OBD_FAIL_TGT_REPLY_NET           0x700
 #define OBD_FAIL_TGT_CONN_RACE           0x701
index 1e33055..9fc44a8 100644 (file)
@@ -1482,10 +1482,15 @@ void ll_put_super(struct super_block *sb)
                client_common_put_super(sb);
        }
 
+       /* imitate failed cleanup */
+       if (OBD_FAIL_CHECK(OBD_FAIL_OBD_CLEANUP))
+               goto skip_cleanup;
+
        next = 0;
        while ((obd = class_devices_in_group(&sbi->ll_sb_uuid, &next)))
                class_manual_cleanup(obd);
 
+skip_cleanup:
        if (test_bit(LL_SBI_VERBOSE, sbi->ll_flags))
                LCONSOLE_WARN("Unmounted %s\n", profilenm ? profilenm : "");
 
index 1431ec4..9de2f12 100644 (file)
@@ -545,10 +545,8 @@ static int lmv_disconnect(struct obd_export *exp)
        if (lmv->lmv_tgts_kobj)
                kobject_put(lmv->lmv_tgts_kobj);
 
-       if (!lmv->connected)
-               class_export_put(exp);
-       rc = class_disconnect(exp);
        lmv->connected = 0;
+       rc = class_disconnect(exp);
 
        RETURN(rc);
 }
@@ -1161,6 +1159,11 @@ static int lmv_cleanup(struct obd_device *obd)
        ENTRY;
 
        fld_client_fini(&lmv->lmv_fld);
+       fld_client_debugfs_fini(&lmv->lmv_fld);
+
+       lprocfs_obd_cleanup(obd);
+       lprocfs_free_md_stats(obd);
+
        lmv_foreach_tgt_safe(lmv, tgt, tmp)
                lmv_del_target(lmv, tgt);
        lu_tgt_descs_fini(&lmv->lmv_mdt_descs);
@@ -3116,9 +3119,6 @@ static int lmv_precleanup(struct obd_device *obd)
 {
        ENTRY;
        libcfs_kkuc_group_rem(&obd->obd_uuid, 0, KUC_GRP_HSM);
-       fld_client_debugfs_fini(&obd->u.lmv.lmv_fld);
-       lprocfs_obd_cleanup(obd);
-       lprocfs_free_md_stats(obd);
        RETURN(0);
 }
 
index 3efba72..b7512bd 100644 (file)
@@ -309,8 +309,14 @@ static int lov_disconnect(struct obd_export *exp)
                goto out;
 
        /* Only disconnect the underlying layers on the final disconnect. */
+       if (lov->lov_connects == 0) {
+               CWARN("%s: was disconnected already #%d\n",
+                     obd->obd_name, lov->lov_connects);
+               RETURN(0);
+       }
+
        lov->lov_connects--;
-       if (lov->lov_connects != 0) {
+       if (lov->lov_connects > 0) {
                /* why should there be more than 1 connect? */
                CWARN("%s: unexpected disconnect #%d\n",
                      obd->obd_name, lov->lov_connects);
index c032849..8f61982 100644 (file)
@@ -2951,12 +2951,12 @@ static int mdc_precleanup(struct obd_device *obd)
        ENTRY;
 
        osc_precleanup_common(obd);
-       mdc_changelog_cdev_finish(obd);
 
-       obd_cleanup_client_import(obd);
-       ptlrpc_lprocfs_unregister_obd(obd);
-       lprocfs_free_md_stats(obd);
+       mdc_changelog_cdev_finish(obd);
        mdc_llog_finish(obd);
+       lprocfs_free_md_stats(obd);
+       ptlrpc_lprocfs_unregister_obd(obd);
+
        RETURN(0);
 }
 
index 4ddad5e..b906786 100755 (executable)
@@ -17857,6 +17857,36 @@ test_171() { # bug20592
 }
 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
 
+test_172() {
+
+       #define OBD_FAIL_OBD_CLEANUP  0x60e
+       $LCTL set_param fail_loc=0x60e
+       umount $MOUNT || error "umount $MOUNT failed"
+       stack_trap "mount_client $MOUNT"
+
+       (( $($LCTL dl | egrep -c " osc | lov | lmv | mdc ") > 0 )) ||
+               error "no client OBDs are remained"
+
+       $LCTL dl | while read devno state type name foo; do
+               case $type in
+               lov|osc|lmv|mdc)
+                       $LCTL --device $name cleanup
+                       $LCTL --device $name detach
+                       ;;
+               *)
+                       # skip server devices
+                       ;;
+               esac
+       done
+
+       if (( $($LCTL dl | egrep -c " osc | lov | lmv | mdc ") > 0 )); then
+               $LCTL dl | egrep " osc | lov | lmv | mdc "
+               error "some client OBDs are still remained"
+       fi
+
+}
+run_test 172 "manual device removal with lctl cleanup/detach ======"
+
 # it would be good to share it with obdfilter-survey/iokit-libecho code
 setup_obdecho_osc () {
         local rc=0