Whamcloud - gitweb
LU-14472 quota: skip non-exist or inact tgt for lfs_quota
authorHongchao Zhang <hongchao@whamcloud.com>
Wed, 15 Dec 2021 12:11:17 +0000 (20:11 +0800)
committerAndreas Dilger <adilger@whamcloud.com>
Wed, 10 Aug 2022 01:40:19 +0000 (01:40 +0000)
The nonexistent or inactive targets (MDC or OSC) should be skipped
for "lfs quota".

Lustre-change: https://review.whamcloud.com/41771
Lustre-commit: b54b7ce43929ce7ff6e48cd219623c264ca6b6b3

Change-Id: I25eece413715e4e05dd94ccbfd101220da7477f9
Signed-off-by: Hongchao Zhang <hongchao@whamcloud.com>
Reviewed-on: https://review.whamcloud.com/48171
Tested-by: jenkins <devops@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
lustre/doc/lfs-quota.1
lustre/llite/dir.c
lustre/lmv/lmv_obd.c
lustre/lov/lov_obd.c
lustre/tests/sanity-quota.sh
lustre/utils/lfs.c

index e8abe6b..91443f2 100644 (file)
@@ -49,6 +49,7 @@ column headers will not be printed.
 .B -v
 Verbose. Display per-MDT and per-OST statistics in addition
 to the usual system wide data.
+Inactive target will also be printed but marked as "inact".
 .TP
 .B -u <\fIuname|uid\fR>
 Display user quota information for \fIuname\fR or \fIuid\fR.
index 7a87b9f..cdae535 100644 (file)
@@ -1236,34 +1236,33 @@ int quotactl_ioctl(struct super_block *sb, struct if_quotactl *qctl)
                else
                        RETURN(-EINVAL);
 
-                switch (valid) {
-                case QC_MDTIDX:
-                        rc = obd_iocontrol(OBD_IOC_QUOTACTL, sbi->ll_md_exp,
-                                           sizeof(*qctl), qctl, NULL);
-                        break;
-                case QC_OSTIDX:
-                        rc = obd_iocontrol(OBD_IOC_QUOTACTL, sbi->ll_dt_exp,
-                                           sizeof(*qctl), qctl, NULL);
-                        break;
-                case QC_UUID:
-                        rc = obd_iocontrol(OBD_IOC_QUOTACTL, sbi->ll_md_exp,
-                                           sizeof(*qctl), qctl, NULL);
-                        if (rc == -EAGAIN)
-                                rc = obd_iocontrol(OBD_IOC_QUOTACTL,
-                                                   sbi->ll_dt_exp,
-                                                   sizeof(*qctl), qctl, NULL);
-                        break;
-                default:
-                        rc = -EINVAL;
-                        break;
-                }
-
-                if (rc)
-                        RETURN(rc);
+               switch (valid) {
+               case QC_MDTIDX:
+                       rc = obd_iocontrol(OBD_IOC_QUOTACTL, sbi->ll_md_exp,
+                                          sizeof(*qctl), qctl, NULL);
+                       break;
+               case QC_OSTIDX:
+                       rc = obd_iocontrol(OBD_IOC_QUOTACTL, sbi->ll_dt_exp,
+                                          sizeof(*qctl), qctl, NULL);
+                       break;
+               case QC_UUID:
+                       rc = obd_iocontrol(OBD_IOC_QUOTACTL, sbi->ll_md_exp,
+                                          sizeof(*qctl), qctl, NULL);
+                       if (rc == -EAGAIN)
+                               rc = obd_iocontrol(OBD_IOC_QUOTACTL,
+                                                  sbi->ll_dt_exp,
+                                                  sizeof(*qctl), qctl, NULL);
+                       break;
+               default:
+                       rc = -EINVAL;
+                       break;
+               }
 
-                qctl->qc_cmd = cmd;
-        } else {
-                struct obd_quotactl *oqctl;
+               qctl->qc_cmd = cmd;
+               if (rc)
+                       RETURN(rc);
+       } else {
+               struct obd_quotactl *oqctl;
                int oqctl_len = sizeof(*oqctl);
 
                if (LUSTRE_Q_CMD_IS_POOL(cmd))
@@ -2023,7 +2022,7 @@ out_req:
                }
 
                rc = quotactl_ioctl(inode->i_sb, qctl);
-               if (rc == 0 &&
+               if ((rc == 0 || rc == -ENODATA) &&
                    copy_to_user((void __user *)arg, qctl, sizeof(*qctl)))
                         rc = -EFAULT;
 
index 6a344a2..087dc58 100644 (file)
@@ -878,6 +878,7 @@ static int lmv_iocontrol(unsigned int cmd, struct obd_export *exp,
        case OBD_IOC_QUOTACTL: {
                struct if_quotactl *qctl = karg;
                struct obd_quotactl *oqctl;
+               struct obd_import *imp;
 
                if (qctl->qc_valid == QC_MDTIDX) {
                        tgt = lmv_tgt(lmv, qctl->qc_idx);
@@ -896,9 +897,19 @@ static int lmv_iocontrol(unsigned int cmd, struct obd_export *exp,
                        RETURN(-EINVAL);
                }
 
-               if (!tgt || !tgt->ltd_exp)
+               if (!tgt)
+                       RETURN(-ENODEV);
+
+               if (!tgt->ltd_exp)
                        RETURN(-EINVAL);
 
+               imp = class_exp2cliimp(tgt->ltd_exp);
+               if (!tgt->ltd_active && imp->imp_state != LUSTRE_IMP_IDLE) {
+                       qctl->qc_valid = QC_MDTIDX;
+                       qctl->obd_uuid = tgt->ltd_uuid;
+                       RETURN(-ENODATA);
+               }
+
                OBD_ALLOC_PTR(oqctl);
                if (!oqctl)
                        RETURN(-ENOMEM);
@@ -3191,7 +3202,7 @@ static int lmv_get_info(const struct lu_env *env, struct obd_export *exp,
                        exp->exp_connect_data = *(struct obd_connect_data *)val;
                RETURN(rc);
        } else if (KEY_IS(KEY_TGT_COUNT)) {
-               *((int *)val) = lmv->lmv_mdt_descs.ltd_lmv_desc.ld_tgt_count;
+               *((int *)val) = lmv->lmv_mdt_descs.ltd_tgts_size;
                RETURN(0);
        }
 
index 44a0d8b..5d325c8 100644 (file)
@@ -1058,54 +1058,65 @@ static int lov_iocontrol(unsigned int cmd, struct obd_export *exp, int len,
                         rc = -EFAULT;
                OBD_FREE_LARGE(buf, len);
                 break;
-        }
-        case OBD_IOC_QUOTACTL: {
-                struct if_quotactl *qctl = karg;
-                struct lov_tgt_desc *tgt = NULL;
-                struct obd_quotactl *oqctl;
+       }
+       case OBD_IOC_QUOTACTL: {
+               struct if_quotactl *qctl = karg;
+               struct lov_tgt_desc *tgt = NULL;
+               struct obd_quotactl *oqctl;
+               struct obd_import *imp;
 
                if (qctl->qc_valid == QC_OSTIDX) {
                        if (count <= qctl->qc_idx)
                                RETURN(-EINVAL);
 
                        tgt = lov->lov_tgts[qctl->qc_idx];
-                       if (!tgt || !tgt->ltd_exp)
+                       if (!tgt)
+                               RETURN(-ENODEV);
+
+                       if (!tgt->ltd_exp)
                                RETURN(-EINVAL);
-                } else if (qctl->qc_valid == QC_UUID) {
-                        for (i = 0; i < count; i++) {
-                                tgt = lov->lov_tgts[i];
-                                if (!tgt ||
-                                    !obd_uuid_equals(&tgt->ltd_uuid,
-                                                     &qctl->obd_uuid))
-                                        continue;
-
-                                if (tgt->ltd_exp == NULL)
-                                        RETURN(-EINVAL);
-
-                                break;
-                        }
-                } else {
-                        RETURN(-EINVAL);
-                }
+               } else if (qctl->qc_valid == QC_UUID) {
+                       for (i = 0; i < count; i++) {
+                               tgt = lov->lov_tgts[i];
+                               if (!tgt ||
+                                   !obd_uuid_equals(&tgt->ltd_uuid,
+                                                    &qctl->obd_uuid))
+                                       continue;
+
+                               if (tgt->ltd_exp == NULL)
+                                       RETURN(-EINVAL);
+
+                               break;
+                       }
+               } else {
+                       RETURN(-EINVAL);
+               }
 
-                if (i >= count)
-                        RETURN(-EAGAIN);
+               if (i >= count)
+                       RETURN(-EAGAIN);
 
-                LASSERT(tgt && tgt->ltd_exp);
-                OBD_ALLOC_PTR(oqctl);
-                if (!oqctl)
-                        RETURN(-ENOMEM);
+               LASSERT(tgt && tgt->ltd_exp);
+               imp = class_exp2cliimp(tgt->ltd_exp);
+               if (!tgt->ltd_active && imp->imp_state != LUSTRE_IMP_IDLE) {
+                       qctl->qc_valid = QC_OSTIDX;
+                       qctl->obd_uuid = tgt->ltd_uuid;
+                       RETURN(-ENODATA);
+               }
 
-                QCTL_COPY(oqctl, qctl);
-                rc = obd_quotactl(tgt->ltd_exp, oqctl);
-                if (rc == 0) {
-                        QCTL_COPY(qctl, oqctl);
-                        qctl->qc_valid = QC_OSTIDX;
-                        qctl->obd_uuid = tgt->ltd_uuid;
-                }
-                OBD_FREE_PTR(oqctl);
-                break;
-        }
+               OBD_ALLOC_PTR(oqctl);
+               if (!oqctl)
+                       RETURN(-ENOMEM);
+
+               QCTL_COPY(oqctl, qctl);
+               rc = obd_quotactl(tgt->ltd_exp, oqctl);
+               if (rc == 0) {
+                       QCTL_COPY(qctl, oqctl);
+                       qctl->qc_valid = QC_OSTIDX;
+                       qctl->obd_uuid = tgt->ltd_uuid;
+               }
+               OBD_FREE_PTR(oqctl);
+               break;
+       }
        default: {
                int set = 0;
 
index 4234e04..8d3d8fa 100755 (executable)
@@ -2527,6 +2527,108 @@ test_15(){
 }
 run_test 15 "Set over 4T block quota"
 
+test_16a()
+{
+       (( $CLIENT_VERSION < $(version_code 2.14.55) )) &&
+               skip "Not supported Lustre client before 2.14.55"
+
+       setup_quota_test || error "setup quota failed with $?"
+
+       $LFS setquota -u $TSTUSR -B 500M -I 10K $MOUNT ||
+               error "failed to set quota for user $TSTUSR"
+       $LFS setquota -g $TSTUSR -B 500M -I 10K $MOUNT ||
+               error "failed to set quota for group $TSTUSR"
+
+       $RUNAS $DD of=$DIR/$tdir/$tfile bs=1M count=50 ||
+               quota_error u $TSTUSR "write failure"
+
+       $LFS quota -u $TSTUSR $MOUNT ||
+               quota_error u $TSTUSR "failed to get quota"
+
+       local OSC=$($LCTL dl | grep OST0000-osc-[^M] | awk '{print $4}')
+
+       $LCTL --device %$OSC deactivate
+       stack_trap "$LCTL --device %$OSC activate"
+
+       $LFS quota -v -u $TSTUSR $MOUNT ||
+               quota_error u $TSTUSR "failed to get quota after deactivate OSC"
+       $LFS quota -v -g $TSTUSR $MOUNT ||
+               quota_error g $TSTUSR "failed to get quota after deactivate OSC"
+
+       (( $MDSCOUNT > 1 )) || return 0
+
+       local MDC=$($LCTL dl | grep MDT0001-mdc-[^M] | awk '{print $4}')
+
+       $LCTL --device %$MDC deactivate
+       stack_trap "$LCTL --device %$MDC activate"
+
+       $LFS quota -v -u $TSTUSR $MOUNT ||
+               quota_error u $TSTUSR "failed to get quota after deactivate MDC"
+       $LFS quota -v -g $TSTUSR $MOUNT ||
+               quota_error g $TSTUSR "failed to get quota after deactivate OSC"
+}
+run_test 16a "lfs quota should skip the inactive MDT/OST"
+
+cleanup_16b()
+{
+       stopall
+       formatall
+       setupall
+}
+
+test_16b()
+{
+       (( $CLIENT_VERSION < $(version_code 2.14.55) )) &&
+               skip "Not supported Lustre client before 2.14.55"
+
+       (( $MDSCOUNT >= 3 )) || skip "needs >= 3 MDTs"
+
+       stopall
+       if ! combined_mgs_mds ; then
+               format_mgs
+               start_mgs
+       fi
+
+       add mds1 $(mkfs_opts mds1 $(mdsdevname 1)) --index=0 --reformat \
+               $(mdsdevname 1) $(mdsvdevname 1)
+       add mds2 $(mkfs_opts mds2 $(mdsdevname 2)) --index=1 --reformat \
+               $(mdsdevname 2) $(mdsvdevname 2)
+       add mds3 $(mkfs_opts mds3 $(mdsdevname 3)) --index=100 --reformat \
+               $(mdsdevname 3) $(mdsvdevname 3)
+
+       add ost1 $(mkfs_opts ost1 $(ostdevname 1)) --index=0 --reformat \
+               $(ostdevname 1) $(ostvdevname 1)
+       add ost2 $(mkfs_opts ost2 $(ostdevname 2)) --index=100 --reformat \
+               $(ostdevname 2) $(ostvdevname 2)
+
+       stack_trap cleanup_16b
+
+       start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS || error "MDT1 start failed"
+       start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS || error "MDT2 start failed"
+       start mds3 $(mdsdevname 3) $MDS_MOUNT_OPTS || error "MDT3 start failed"
+       start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "OST1 start failed"
+       start ost2 $(ostdevname 2) $OST_MOUNT_OPTS || error "OST2 start failed"
+
+       mount_client $MOUNT || error "Unable to mount client"
+
+       setup_quota_test || error "setup quota failed with $?"
+       stack_trap cleanup_quota_test EXIT
+
+       $LFS setquota -u $TSTUSR -B 100M -I 10K $MOUNT ||
+               error "failed to set quota for user $TSTUSR"
+       $LFS setquota -g $TSTUSR -B 100M -I 10K $MOUNT ||
+               error "failed to set quota for group $TSTUSR"
+
+       $RUNAS $DD of=$DIR/$tdir/$tfile bs=1M count=10 ||
+               quota_error u $TSTUSR "write failure"
+
+       cnt=$($LFS quota -v -u $TSTUSR $MOUNT | grep -ce "^$FSNAME-[MD|OS]T*")
+       [ $cnt -le 5 ] || quota_error u $TSTUSR "failed to get user quota"
+       cnt=$($LFS quota -v -g $TSTUSR $MOUNT | grep -ce "^$FSNAME-[MD|OS]T*")
+       [ $cnt -le 5 ] || quota_error g $TSTUSR "failed to get group quota"
+}
+run_test 16b "lfs quota should skip the nonexistent MDT/OST"
+
 test_17sub() {
        local err_code=$1
        local BLKS=1    # 1M less than limit
index d1fa15e..48e0c02 100644 (file)
@@ -7974,6 +7974,28 @@ static int print_obd_quota(char *mnt, struct if_quotactl *qctl, int is_mdt,
                                goto out;
                        }
 
+                       /* no target for this index yet */
+                       if (rc == -ENODEV) {
+                               rc = 0;
+                               continue;
+                       }
+
+                       /* inactive target */
+                       if (rc == -ENODATA) {
+                               char name[UUID_MAX+8];
+
+                               snprintf(name, sizeof(name), "%s[inact]",
+                                       obd_uuid2str(&qctl->obd_uuid));
+                               memset(&qctl->qc_dqinfo, 0,
+                                      sizeof(qctl->qc_dqinfo));
+                               memset(&qctl->qc_dqblk, 0,
+                                      sizeof(qctl->qc_dqblk));
+                               print_quota(name, qctl, qctl->qc_valid, 0, h,
+                                           false);
+                               rc = 0;
+                               continue;
+                       }
+
                        if (!rc1)
                                rc1 = rc;
                        fprintf(stderr, "quotactl %s%d failed.\n",