Whamcloud - gitweb
LU-18859 quota: show default quota and root squash 63/58563/4
authorSergey Cheremencev <scherementsev@ddn.com>
Tue, 18 Mar 2025 00:14:37 +0000 (03:14 +0300)
committerOleg Drokin <green@whamcloud.com>
Thu, 10 Apr 2025 06:59:20 +0000 (06:59 +0000)
When show default quotas don't swap ID=0 with squashed ID.
It is not required as default quotas are stored in a ROOT
lqe. Patch is against the following panic:

 (qmt_handler.c:58:qmt_get())
ASSERTION( !is_default || id->qid_uid == 0 ) failed:
 (qmt_handler.c:58:qmt_get()) LBUG
  ...
  dump_stack+0x41/0x60
  lbug_with_loc.cold.8+0x5/0x43 [libcfs]
  qmt_get+0x185/0x3e0 [lquota]
  qmt_quotactl+0x309/0xa10 [lquota]
  mdt_quotactl+0x21f/0x880 [mdt]
  tgt_request_handle+0xc9c/0x1990 [ptlrpc]
  ptlrpc_server_handle_request+0x323/0xbd0 [ptlrpc]
  ptlrpc_main+0xb45/0x13a0 [ptlrpc]
  kthread+0x134/0x150

Cleanup lqes created in sanity-quota_87 "lfs quota -a should
print default quota setting". Without that new default quota
limits are applied to 50 default lqes created in test case 87.
It produces too many useless lustre debug logs.

Add into stack_trap restoring initial nodemap values changed
in tests 1j and 75.

Fixes: 2686838fef ("LU-18240 sec: enforce per-nodemap project quota for root")
Fixes: a4fbe7341b ("LU-14739 quota: nodemap squashed root cannot bypass quota")
Fixes: 115562106b ("LU-18453 quota: show default quota in lfs quota -a")
Signed-off-by: Sergey Cheremencev <scherementsev@ddn.com>
Change-Id: Ieef5f8b99c92d8fef3addcb7d55771c96c82129f
Reviewed-on: https://review.whamcloud.com/c/fs/lustre-release/+/58563
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
Reviewed-by: Sebastien Buisson <sbuisson@ddn.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
Tested-by: jenkins <devops@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
lustre/mdt/mdt_handler.c
lustre/tests/sanity-quota.sh

index b205a45..1187f06 100644 (file)
@@ -3485,6 +3485,17 @@ put:
        return rc;
 }
 
+/* To get default quotas ID needs to be 0, so
+ * no reasons to swap this according to nodemap.
+ */
+static inline bool qmt_need_swap(__u32 cmd)
+{
+       if (cmd == LUSTRE_Q_GETDEFAULT || cmd == LUSTRE_Q_GETDEFAULT_POOL)
+               return false;
+
+       return true;
+}
+
 /*
  * Handle quota control requests to consult current usage/limit, but also
  * to configure quota enforcement
@@ -3588,7 +3599,7 @@ static int mdt_quotactl(struct tgt_session_info *tsi)
        if (oqctl->qc_cmd == Q_SETINFO || oqctl->qc_cmd == Q_SETQUOTA)
                barrier_exit(tsi->tsi_tgt->lut_bottom);
 
-       if (oqctl->qc_id != id)
+       if (oqctl->qc_id != id && qmt_need_swap(oqctl->qc_cmd))
                swap(oqctl->qc_id, id);
 
        if (oqctl->qc_cmd == Q_SETINFO || oqctl->qc_cmd == Q_SETQUOTA) {
@@ -3633,7 +3644,7 @@ static int mdt_quotactl(struct tgt_session_info *tsi)
                GOTO(out_nodemap, rc = -EFAULT);
        }
 
-       if (oqctl->qc_id != id)
+       if (oqctl->qc_id != id && qmt_need_swap(oqctl->qc_cmd))
                swap(oqctl->qc_id, id);
 
        QCTL_COPY_NO_PNAME(repoqc, oqctl);
index 2472933..ffbaeea 100755 (executable)
@@ -1296,10 +1296,19 @@ test_1j() {
                error "disable root quotas for project failed"
 
        if (( $OST1_VERSION >= $(version_code 2.16.50) )); then
+               local cmd="do_facet mgs $LCTL get_param -n "
+               local adm=$($cmd nodemap.default.admin_nodemap)
+               local trs=$($cmd nodemap.default.trusted_nodemap)
+               local act=$($cmd nodemap.active)
+
                do_facet mgs $LCTL nodemap_modify --name default \
                        --property admin --value 1
+               stack_trap "do_facet mgs $LCTL nodemap_modify --name default \
+                       --property admin --value $adm"
                do_facet mgs $LCTL nodemap_modify --name default \
                        --property trusted --value 1
+               stack_trap "do_facet mgs $LCTL nodemap_modify --name default \
+                       --property trusted --value $trs"
                do_facet mgs $LCTL nodemap_add $nm
                stack_trap "do_facet mgs $LCTL nodemap_del $nm || true"
                do_facet mgs $LCTL nodemap_add_range    \
@@ -1312,7 +1321,7 @@ test_1j() {
                do_facet mgs $LCTL nodemap_modify --name $nm --property rbac \
                        --value file_perms,dne_ops,quota_ops,byfid_ops,chlg_ops
                do_facet mgs $LCTL nodemap_activate 1
-               stack_trap "do_facet mgs $LCTL nodemap_activate 0"
+               stack_trap "do_facet mgs $LCTL nodemap_activate $act"
                wait_nm_sync active
                wait_nm_sync default admin_nodemap
                wait_nm_sync default trusted_nodemap
@@ -5726,21 +5735,35 @@ run_test 74 "check quota pools per user"
 function cleanup_quota_test_75()
 {
        do_facet mgs $LCTL nodemap_modify --name default \
-               --property admin --value 1
+               --property admin --value $1
+       do_facet mgs $LCTL nodemap_modify --name default \
+               --property trusted --value $2
        do_facet mgs $LCTL nodemap_modify --name default \
-               --property trusted --value 1
+               --property deny_unknown --value $3
        do_facet mgs $LCTL nodemap_modify --name default \
-               --property squash_uid --value 99
+               --property squash_uid --value $4
        do_facet mgs $LCTL nodemap_modify --name default \
-               --property squash_gid --value 99
+               --property squash_gid --value $5
 
        wait_nm_sync default admin_nodemap
        wait_nm_sync default trusted_nodemap
 
-       do_facet mgs $LCTL nodemap_activate 0
-       wait_nm_sync active
+       do_facet mgs $LCTL nodemap_activate $6
+       wait_nm_sync active $6
+       return 0
+}
 
-       resetquota -u $TSTUSR
+stack_trap_nodemap_cleanup_75()
+{
+       local cmd="do_facet mgs $LCTL get_param -n "
+       local adm=$($cmd nodemap.default.admin_nodemap)
+       local trs=$($cmd nodemap.default.trusted_nodemap)
+       local deny=$($cmd nodemap.default.deny_unknown)
+       local uid=$($cmd nodemap.default.squash_uid)
+       local gid=$($cmd nodemap.default.squash_gid)
+       local act=$($cmd nodemap.active)
+
+       stack_trap "cleanup_quota_test_75 $adm $trs $deny $uid $gid $act"
 }
 
 test_dom_75() {
@@ -5818,7 +5841,6 @@ test_75()
        fi
 
        setup_quota_test || error "setup quota failed with $?"
-       stack_trap cleanup_quota_test_75 EXIT
 
        # enable ost quota
        set_ost_qtype $QTYPE || error "enable ost quota failed"
@@ -5837,6 +5859,7 @@ test_75()
        $LFS setstripe -E 1M -L mdt $DIR/$tdir_dom ||
                error "setstripe $tdir_dom failed"
 
+       stack_trap_nodemap_cleanup_75
        do_facet mgs $LCTL nodemap_activate 1
        wait_nm_sync active
        do_facet mgs $LCTL nodemap_modify --name default \
@@ -6460,6 +6483,24 @@ test_86()
 }
 run_test 86 "Pre-acquired quota should be released if quota is over limit"
 
+cleanup_lqes()
+{
+       for ((i = $1; i < $2; i++)); do
+               $LFS setquota -B0 -b0 -I0 -i0 -u $i $MOUNT ||
+                       error "Can't cleanup user $i"
+               $LFS setquota -B0 -b0 -I0 -i0 -g $i $MOUNT ||
+                       error "Can't cleanup group $i"
+               is_project_quota_supported &&
+                       $LFS setquota -B0 -b0 -I0 -i0 -p $i $MOUNT ||
+                               error "Can't cleanup project $i"
+       done
+       # The only way to remove lqes from the hash table
+       stop mds1 -f || error "MDS umount failed"
+       start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
+       quota_init
+       clients_up || true
+}
+
 test_87()
 {
        (( $MDS1_VERSION >= $(version_code 2.16.50) )) ||
@@ -6497,6 +6538,7 @@ test_87()
 
        #define OBD_FAIL_QUOTA_NOSYNC           0xA09
        do_facet mds1 $LCTL set_param fail_loc=0xa09
+       stack_trap "cleanup_lqes 100 200"
 
        for ((i = 100; i < 150; i++)); do
                $LFS setquota -u $i -b $blimit -B $blimit $MOUNT ||
@@ -6615,6 +6657,38 @@ test_88()
 }
 run_test 88 "Writing over quota should not hang"
 
+test_89()
+{
+       local cmd="do_facet mgs $LCTL get_param -n "
+
+       (( $MDS1_VERSION >= $(version_code 2.16.53) )) ||
+               skip "need MDS >= 2.16.53 to show default quota with squash_uid"
+
+       local act=$($cmd nodemap.active)
+       do_facet mgs $LCTL nodemap_activate 1
+       wait_nm_sync active
+       stack_trap "do_facet mgs $LCTL nodemap_activate $act; \
+                   wait_nm_sync active"
+
+       local suid=$($cmd nodemap.default.squash_uid)
+       do_facet mgs "$LCTL nodemap_modify --name default \
+               --property squash_uid --value $TSTID"
+       wait_nm_sync default squash_uid
+       stack_trap "do_facet mgs $LCTL nodemap_modify --name default \
+               --property squash_uid --value $suid"
+
+       $LFS setquota -P -B100M $MOUNT &&
+               error "Set default quotas with squashed uid"
+       is_project_quota_supported &&
+               $LFS quota -P $MOUNT ||
+                       error "Can't get default prj quota for squashed uid"
+       $LFS quota -U $MOUNT ||
+               error "Can't get default usr quota for squashed uid"
+       $LFS quota -G $MOUNT ||
+               error "Can't get default grp quota for squashed uid"
+}
+run_test 89 "Show default quota with squash_uid"
+
 check_quota_no_mount()
 {
        local opts="$1"