From: Bruno Faccini Date: Fri, 16 Sep 2016 08:15:06 +0000 (+0200) Subject: LU-6499 obdclass: obdclass module cleanup upon load error X-Git-Tag: 2.9.54~54 X-Git-Url: https://git.whamcloud.com/?p=fs%2Flustre-release.git;a=commitdiff_plain;h=e4761eb1f4d564f111be66a61ac84f9f9be97fc2 LU-6499 obdclass: obdclass module cleanup upon load error Fix obdclass_init() error paths to proceed with cleanup. This will particularly allow to no longer crash upon next load attempt and this due to previous miscdevice not been deregistered and thus still referenced in misc_list when unmapped. conf-sanity/test_102 has been created to verify correct behavior/cleanup. Signed-off-by: Bruno Faccini Change-Id: I6f65cf651251cf92427e2bab3ff6b51ebb98d699 Reviewed-on: https://review.whamcloud.com/22544 Reviewed-by: Patrick Farrell Tested-by: Jenkins Tested-by: Maloo Reviewed-by: James Simmons Reviewed-by: Oleg Drokin --- diff --git a/lustre/include/obd_support.h b/lustre/include/obd_support.h index d1d5b47..4faba88 100644 --- a/lustre/include/obd_support.h +++ b/lustre/include/obd_support.h @@ -434,6 +434,7 @@ extern char obd_jobid_var[]; #define OBD_FAIL_OBD_IDX_READ_NET 0x607 #define OBD_FAIL_OBD_IDX_READ_BREAK 0x608 #define OBD_FAIL_OBD_NO_LRU 0x609 +#define OBD_FAIL_OBDCLASS_MODULE_LOAD 0x60a #define OBD_FAIL_TGT_REPLY_NET 0x700 #define OBD_FAIL_TGT_CONN_RACE 0x701 diff --git a/lustre/obdclass/class_obd.c b/lustre/obdclass/class_obd.c index cf38cde..d70d496 100644 --- a/lustre/obdclass/class_obd.c +++ b/lustre/obdclass/class_obd.c @@ -513,7 +513,8 @@ static int __init obdclass_init(void) LPROCFS_STATS_FLAG_IRQ_SAFE); if (obd_memory == NULL) { CERROR("kmalloc of 'obd_memory' failed\n"); - RETURN(-ENOMEM); + err = -ENOMEM; + goto cleanup_zombie_impexp; } lprocfs_counter_init(obd_memory, OBD_MEMORY_STAT, @@ -522,19 +523,19 @@ static int __init obdclass_init(void) #endif err = obd_init_checks(); if (err == -EOVERFLOW) - return err; + goto cleanup_zombie_impexp; class_init_uuidlist(); err = class_handle_init(); if (err) - return err; + goto cleanup_uuidlist; INIT_LIST_HEAD(&obd_types); err = misc_register(&obd_psdev); if (err) { CERROR("cannot register %d err %d\n", OBD_DEV_MINOR, err); - return err; + goto cleanup_class_handle; } /* This struct is already zeroed for us (static global) */ @@ -551,35 +552,91 @@ static int __init obdclass_init(void) err = obd_init_caches(); if (err) - return err; + goto cleanup_deregister; + err = class_procfs_init(); if (err) - return err; + goto cleanup_caches; err = lu_global_init(); if (err) - return err; + goto cleanup_class_procfs; err = cl_global_init(); if (err != 0) - return err; + goto cleanup_lu_global; #ifdef HAVE_SERVER_SUPPORT err = dt_global_init(); if (err != 0) - return err; + goto cleanup_cl_global; err = lu_ucred_global_init(); if (err != 0) - return err; + goto cleanup_dt_global; #endif /* HAVE_SERVER_SUPPORT */ err = llog_info_init(); if (err) - return err; +#ifdef HAVE_SERVER_SUPPORT + goto cleanup_lu_ucred_global; +#else /* !HAVE_SERVER_SUPPORT */ + goto cleanup_cl_global; +#endif /* HAVE_SERVER_SUPPORT */ err = lustre_register_fs(); + /* simulate a late OOM situation now to require all + * alloc'ed/initialized resources to be freed */ + if (OBD_FAIL_CHECK(OBD_FAIL_OBDCLASS_MODULE_LOAD)) { + /* fake error but filesystem has been registered */ + lustre_unregister_fs(); + /* force error to ensure module will be unloaded/cleaned */ + err = -ENOMEM; + } + + if (err) + goto cleanup_llog_info; + + goto out_success; + +cleanup_llog_info: + llog_info_fini(); + +#ifdef HAVE_SERVER_SUPPORT +cleanup_lu_ucred_global: + lu_ucred_global_fini(); + +cleanup_dt_global: + dt_global_fini(); +#endif /* HAVE_SERVER_SUPPORT */ + +cleanup_cl_global: + cl_global_fini(); + +cleanup_lu_global: + lu_global_fini(); + +cleanup_class_procfs: + obd_sysctl_clean(); + class_procfs_clean(); + +cleanup_caches: + obd_cleanup_caches(); + +cleanup_deregister: + misc_deregister(&obd_psdev); + +cleanup_class_handle: + class_handle_cleanup(); + +cleanup_uuidlist: + class_exit_uuidlist(); + +cleanup_zombie_impexp: + obd_zombie_impexp_stop(); + +out_success: return err; } diff --git a/lustre/tests/conf-sanity.sh b/lustre/tests/conf-sanity.sh index 02e2a61..037a782 100755 --- a/lustre/tests/conf-sanity.sh +++ b/lustre/tests/conf-sanity.sh @@ -7028,6 +7028,43 @@ test_101() { } run_test 101 "Race MDT->OST reconnection with create" +test_102() { + cleanup || error "cleanup failed with $?" + + local mds1dev=$(mdsdevname 1) + local mds1mnt=$(facet_mntpt mds1) + local mds1fstype=$(facet_fstype mds1) + local mds1opts=$MDS_MOUNT_OPTS + + if [ $mds1fstype == ldiskfs ] && + ! do_facet mds1 test -b $mds1dev; then + mds1opts=$(csa_add "$mds1opts" -o loop) + fi + if [[ $mds1fstype == zfs ]]; then + import_zpool mds1 || return ${PIPESTATUS[0]} + fi + + # unload all and only load libcfs to allow fail_loc setting + do_facet mds1 lustre_rmmod || error "unable to unload modules" + do_facet mds1 modprobe libcfs || error "libcfs not loaded" + do_facet mds1 lsmod \| grep libcfs || error "libcfs not loaded" + + #define OBD_FAIL_OBDCLASS_MODULE_LOAD 0x60a + do_facet mds1 "$LCTL set_param fail_loc=0x8000060a" + + do_facet mds1 $MOUNT_CMD $mds1dev $mds1mnt $mds1opts && + error "mdt start must fail" + do_facet mds1 lsmod \| grep obdclass && error "obdclass must not load" + + do_facet mds1 "$LCTL set_param fail_loc=0x0" + + do_facet mds1 $MOUNT_CMD $mds1dev $mds1mnt $mds1opts || + error "mdt start must not fail" + + cleanup || error "cleanup failed with $?" +} +run_test 102 "obdclass module cleanup upon error" + if ! combined_mgs_mds ; then stop mgs fi