Whamcloud - gitweb
LU-7506 lfs: "lfs quota -h" should support petabytes output 41/17441/6
authorEmoly Liu <emoly.liu@intel.com>
Fri, 25 Dec 2015 07:28:01 +0000 (15:28 +0800)
committerOleg Drokin <oleg.drokin@intel.com>
Thu, 7 Jan 2016 00:56:07 +0000 (00:56 +0000)
This patch adds human-readable petabytes output and allows to set
fraction block limit, e.g. 1.5P.
Also, it adds sanity-quota.sh test_27d to verify these new functions,
and replaces some sprintf() with snprintf() to meet the code style
requirement.

Signed-off-by: Emoly Liu <emoly.liu@intel.com>
Change-Id: I1dced352687e8e53988f85d2781396e647b62865
Reviewed-on: http://review.whamcloud.com/17441
Tested-by: Jenkins
Reviewed-by: Bobi Jam <bobijam@hotmail.com>
Tested-by: Maloo <hpdd-maloo@intel.com>
Reviewed-by: Andreas Dilger <andreas.dilger@intel.com>
lustre/tests/sanity-quota.sh
lustre/utils/lfs.c
lustre/utils/liblustreapi.c

index 6d7220d..9d5e75d 100644 (file)
@@ -2042,6 +2042,22 @@ test_27c() {
 }
 run_test 27c "lfs quota should support human-readable output"
 
+test_27d() {
+       local softlimit=1.5
+       local hardlimit=2.3
+       local limit
+
+       $LFS setquota -u $TSTID -b ${softlimit}p -B ${hardlimit}P $DIR ||
+               error "set fraction block limit failed"
+       limit=$($LFS quota -u $TSTID -h $DIR | grep $DIR | awk '{print $3}')
+       [ $limit == ${softlimit}P ] || error "get fraction softlimit failed"
+       limit=$($LFS quota -u $TSTID -h $DIR | grep $DIR | awk '{print $4}')
+       [ $limit == ${hardlimit}P ] || error "get fraction hardlimit failed"
+
+       resetquota -u $TSTUSR
+}
+run_test 27d "lfs setquota should support fraction block limit"
+
 test_30() {
        local LIMIT=4 # 4MB
        local TESTFILE="$DIR/$tdir/$tfile"
index 71952b6..b08bbea 100644 (file)
@@ -2917,22 +2917,29 @@ static void print_quota_title(char *name, struct if_quotactl *qctl,
               "files", "quota", "limit", "grace");
 }
 
-static void kbytes2str(__u64 num, char *buf, bool h)
+static void kbytes2str(__u64 num, char *buf, int buflen, bool h)
 {
        if (!h) {
-               sprintf(buf, LPU64, num);
+               snprintf(buf, buflen, LPU64, num);
        } else {
-               if (num >> 30)
-                       sprintf(buf, "%5.4gT", (double)num / (1 << 30));
+               if (num >> 40)
+                       snprintf(buf, buflen, "%5.4gP",
+                                (double)num / ((__u64)1 << 40));
+               else if (num >> 30)
+                       snprintf(buf, buflen, "%5.4gT",
+                                (double)num / (1 << 30));
                else if (num >> 20)
-                       sprintf(buf, "%5.4gG", (double)num / (1 << 20));
+                       snprintf(buf, buflen, "%5.4gG",
+                                (double)num / (1 << 20));
                else if (num >> 10)
-                       sprintf(buf, "%5.4gM", (double)num / (1 << 10));
+                       snprintf(buf, buflen, "%5.4gM",
+                                (double)num / (1 << 10));
                else
-                       sprintf(buf, LPU64"%s", num, "k");
+                       snprintf(buf, buflen, LPU64"%s", num, "k");
        }
 }
 
+#define STRBUF_LEN     32
 static void print_quota(char *mnt, struct if_quotactl *qctl, int type,
                        int rc, bool h)
 {
@@ -2943,9 +2950,9 @@ static void print_quota(char *mnt, struct if_quotactl *qctl, int type,
         if (qctl->qc_cmd == LUSTRE_Q_GETQUOTA || qctl->qc_cmd == Q_GETOQUOTA) {
                int bover = 0, iover = 0;
                struct obd_dqblk *dqb = &qctl->qc_dqblk;
-               char numbuf[3][32];
+               char numbuf[3][STRBUF_LEN];
                char timebuf[40];
-               char strbuf[32];
+               char strbuf[STRBUF_LEN];
 
                 if (dqb->dqb_bhardlimit &&
                    lustre_stoqb(dqb->dqb_curspace) >= dqb->dqb_bhardlimit) {
@@ -2978,21 +2985,22 @@ static void print_quota(char *mnt, struct if_quotactl *qctl, int type,
                if (bover)
                        diff2str(dqb->dqb_btime, timebuf, now);
 
-               kbytes2str(lustre_stoqb(dqb->dqb_curspace), strbuf, h);
+               kbytes2str(lustre_stoqb(dqb->dqb_curspace),
+                          strbuf, sizeof(strbuf), h);
                if (rc == -EREMOTEIO)
                        sprintf(numbuf[0], "%s*", strbuf);
                else
                        sprintf(numbuf[0], (dqb->dqb_valid & QIF_SPACE) ?
                                "%s" : "[%s]", strbuf);
 
-               kbytes2str(dqb->dqb_bsoftlimit, strbuf, h);
+               kbytes2str(dqb->dqb_bsoftlimit, strbuf, sizeof(strbuf), h);
                if (type == QC_GENERAL)
                        sprintf(numbuf[1], (dqb->dqb_valid & QIF_BLIMITS) ?
                                "%s" : "[%s]", strbuf);
                else
                        sprintf(numbuf[1], "%s", "-");
 
-               kbytes2str(dqb->dqb_bhardlimit, strbuf, h);
+               kbytes2str(dqb->dqb_bhardlimit, strbuf, sizeof(strbuf), h);
                sprintf(numbuf[2], (dqb->dqb_valid & QIF_BLIMITS) ?
                        "%s" : "[%s]", strbuf);
 
@@ -3217,13 +3225,14 @@ ug_output:
 
        if (qctl.qc_valid == QC_GENERAL && qctl.qc_cmd != LUSTRE_Q_GETINFO &&
            verbose) {
-               char strbuf[32];
+               char strbuf[STRBUF_LEN];
 
                rc2 = print_obd_quota(mnt, &qctl, 1, human_readable,
                                      &total_ialloc);
                rc3 = print_obd_quota(mnt, &qctl, 0, human_readable,
                                      &total_balloc);
-               kbytes2str(total_balloc, strbuf, human_readable);
+               kbytes2str(total_balloc, strbuf, sizeof(strbuf),
+                          human_readable);
                printf("Total allocated inode limit: "LPU64", total "
                       "allocated block limit: %s\n", total_ialloc, strbuf);
        }
index fdf0529..094996a 100644 (file)
@@ -187,55 +187,67 @@ llapi_log_callback_t llapi_info_callback_set(llapi_log_callback_t cb)
 int llapi_parse_size(const char *optarg, unsigned long long *size,
                     unsigned long long *size_units, int bytes_spec)
 {
-        char *end;
+       char *end;
+       char *argbuf = (char *)optarg;
+       unsigned long long frac = 0, frac_d = 1;
 
-        if (strncmp(optarg, "-", 1) == 0)
-                return -1;
+       if (strncmp(optarg, "-", 1) == 0)
+               return -1;
 
-        if (*size_units == 0)
-                *size_units = 1;
-
-        *size = strtoull(optarg, &end, 0);
-
-        if (*end != '\0') {
-                if ((*end == 'b') && *(end + 1) == '\0' &&
-                    (*size & (~0ULL << (64 - 9))) == 0 &&
-                    !bytes_spec) {
-                        *size_units = 1 << 9;
-                } else if ((*end == 'b') &&
-                           *(end + 1) == '\0' &&
-                           bytes_spec) {
-                        *size_units = 1;
-                } else if ((*end == 'k' || *end == 'K') &&
-                           *(end + 1) == '\0' &&
-                           (*size & (~0ULL << (64 - 10))) == 0) {
-                        *size_units = 1 << 10;
-                } else if ((*end == 'm' || *end == 'M') &&
-                           *(end + 1) == '\0' &&
-                           (*size & (~0ULL << (64 - 20))) == 0) {
-                        *size_units = 1 << 20;
-                } else if ((*end == 'g' || *end == 'G') &&
-                           *(end + 1) == '\0' &&
-                           (*size & (~0ULL << (64 - 30))) == 0) {
-                        *size_units = 1 << 30;
-                } else if ((*end == 't' || *end == 'T') &&
-                           *(end + 1) == '\0' &&
-                           (*size & (~0ULL << (64 - 40))) == 0) {
-                        *size_units = 1ULL << 40;
-                } else if ((*end == 'p' || *end == 'P') &&
-                           *(end + 1) == '\0' &&
-                           (*size & (~0ULL << (64 - 50))) == 0) {
-                        *size_units = 1ULL << 50;
-                } else if ((*end == 'e' || *end == 'E') &&
-                           *(end + 1) == '\0' &&
-                           (*size & (~0ULL << (64 - 60))) == 0) {
-                        *size_units = 1ULL << 60;
-                } else {
-                        return -1;
-                }
-        }
-        *size *= *size_units;
-        return 0;
+       if (*size_units == 0)
+               *size_units = 1;
+
+       *size = strtoull(argbuf, &end, 0);
+       if (end != NULL && *end == '.') {
+               int i;
+
+               argbuf = end + 1;
+               frac = strtoull(argbuf, &end, 10);
+               /* count decimal places */
+               for (i = 0; i < (end - argbuf); i++)
+                       frac_d *= 10;
+       }
+
+       if (*end != '\0') {
+               if ((*end == 'b') && *(end + 1) == '\0' &&
+                   (*size & (~0ULL << (64 - 9))) == 0 &&
+                   !bytes_spec) {
+                       *size_units = 1 << 9;
+               } else if ((*end == 'b') &&
+                          *(end + 1) == '\0' &&
+                          bytes_spec) {
+                       *size_units = 1;
+               } else if ((*end == 'k' || *end == 'K') &&
+                          *(end + 1) == '\0' &&
+                          (*size & (~0ULL << (64 - 10))) == 0) {
+                       *size_units = 1 << 10;
+               } else if ((*end == 'm' || *end == 'M') &&
+                          *(end + 1) == '\0' &&
+                          (*size & (~0ULL << (64 - 20))) == 0) {
+                       *size_units = 1 << 20;
+               } else if ((*end == 'g' || *end == 'G') &&
+                          *(end + 1) == '\0' &&
+                          (*size & (~0ULL << (64 - 30))) == 0) {
+                       *size_units = 1 << 30;
+               } else if ((*end == 't' || *end == 'T') &&
+                          *(end + 1) == '\0' &&
+                          (*size & (~0ULL << (64 - 40))) == 0) {
+                       *size_units = 1ULL << 40;
+               } else if ((*end == 'p' || *end == 'P') &&
+                          *(end + 1) == '\0' &&
+                          (*size & (~0ULL << (64 - 50))) == 0) {
+                       *size_units = 1ULL << 50;
+               } else if ((*end == 'e' || *end == 'E') &&
+                          *(end + 1) == '\0' &&
+                          (*size & (~0ULL << (64 - 60))) == 0) {
+                       *size_units = 1ULL << 60;
+               } else {
+                       return -1;
+               }
+       }
+       *size = *size * *size_units + frac * *size_units / frac_d;
+
+       return 0;
 }
 
 /* XXX: llapi_xxx() functions return negative values upon failure */