Whamcloud - gitweb
LU-15097 quota: stop pool_recalc before killing pool 56/45256/8
authorSergey Cheremencev <sergey.cheremencev@hpe.ccom>
Mon, 20 Sep 2021 12:08:20 +0000 (15:08 +0300)
committerOleg Drokin <green@whamcloud.com>
Thu, 6 Jan 2022 22:02:29 +0000 (22:02 +0000)
qmt_start_pool_recalc holds a refrence on a pool while
it is running. This thread should be stopped before
putting the last pool reference in qmt_pool_free to be
sure that pool can finally freed. Patch helps to avoid
following ASSERTION:
qmt_pool_fini()) ASSERTION( list_empty(&qmt->qmt_pool_list) ) failed

HPE-bug-id: LUS-10294
Change-Id: If72042a620d9ded693fcb669bc9148d1f96126a4
Signed-off-by: Sergey Cheremencev <sergey.cheremencev@hpe.com>
Reviewed-on: https://review.whamcloud.com/45256
Tested-by: jenkins <devops@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: Alexander Boyko <alexander.boyko@hpe.com>
Reviewed-by: Alexey Lyashkov <alexey.lyashkov@hpe.com>
Reviewed-by: Andriy Skulysh <andriy.skulysh@hpe.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
lustre/include/obd_support.h
lustre/quota/qmt_pool.c
lustre/tests/sanity-quota.sh

index d34d0f0..1774f7e 100644 (file)
@@ -536,6 +536,7 @@ extern char obd_jobid_var[];
 #define OBD_FAIL_QUOTA_RECOVERABLE_ERR   0xA04
 #define OBD_FAIL_QUOTA_INIT              0xA05
 #define OBD_FAIL_QUOTA_PREACQ            0xA06
+#define OBD_FAIL_QUOTA_RECALC            0xA07
 
 #define OBD_FAIL_LPROC_REMOVE            0xB00
 
index bf9241c..c4398a5 100644 (file)
@@ -466,6 +466,8 @@ void qmt_pool_fini(const struct lu_env *env, struct qmt_device *qmt)
 
        /* parse list of pool and destroy each element */
        list_for_each_entry_safe(pool, tmp, &qmt->qmt_pool_list, qpi_linkage) {
+               /* stop all recalc threads - it may hold qpi reference */
+               qmt_stop_pool_recalc(pool);
                /* release extra reference taken in qmt_pool_alloc */
                qpi_putref(env, pool);
        }
@@ -1179,6 +1181,7 @@ static int qmt_pool_recalc(void *args)
                while (obd->obd_process_conf)
                        schedule_timeout_uninterruptible(cfs_time_seconds(1));
 
+       OBD_FAIL_TIMEOUT(OBD_FAIL_QUOTA_RECALC, cfs_fail_val);
        sem = qmt_sarr_rwsem(pool);
        LASSERT(sem);
        down_read(sem);
@@ -1364,6 +1367,9 @@ static int qmt_pool_add_rem(struct obd_device *obd, char *poolname,
        int                      rc, idx;
        ENTRY;
 
+       if (qmt->qmt_stopping)
+               RETURN(0);
+
        if (strnlen(poolname, LOV_MAXPOOLNAME + 1) > LOV_MAXPOOLNAME)
                RETURN(-ENAMETOOLONG);
 
index 13837ed..f0e310b 100755 (executable)
@@ -5070,7 +5070,6 @@ test_78()
        check_set_fallocate_or_skip
 
        setup_quota_test || error "setup quota failed with $?"
-       stack_trap cleanup_quota_test
 
        # enable ost quota
        set_ost_qtype $QTYPE || error "enable ost quota failed"
@@ -5193,6 +5192,34 @@ test_80()
 }
 run_test 80 "check for EDQUOT after OST failover"
 
+test_81() {
+       local global_limit=20  # 100M
+       local testfile="$DIR/$tdir/$tfile-0"
+       local qpool="qpool1"
+
+       mds_supports_qp
+       setup_quota_test || error "setup quota failed with $?"
+
+       # enable ost quota
+       set_ost_qtype $QTYPE || error "enable ost quota failed"
+
+       # test for user
+       log "User quota (block hardlimit:$global_limit MB)"
+       $LFS setquota -u $TSTUSR -B 1G $DIR || error "set user quota failed"
+
+       pool_add $qpool || error "pool_add failed"
+       #define OBD_FAIL_QUOTA_RECALC   0xA07
+       do_facet mds1 $LCTL set_param fail_loc=0x80000A07 fail_val=30
+       # added OST casues to start pool recalculation
+       pool_add_targets $qpool 0 0 1
+       stop mds1 -f || error "MDS umount failed"
+
+       #start mds1 back to destroy created pool
+       start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
+       clients_up || true
+}
+run_test 81 "Race qmt_start_pool_recalc with qmt_pool_free"
+
 quota_fini()
 {
        do_nodes $(comma_list $(nodes_list)) \