Whamcloud - gitweb
b=22440 more proper error message for "lfs quota"
[fs/lustre-release.git] / lustre / utils / lfs.c
index 5156dec..f2b1748 100644 (file)
@@ -26,7 +26,7 @@
  * GPL HEADER END
  */
 /*
- * Copyright  2008 Sun Microsystems, Inc. All rights reserved
+ * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  */
 /*
@@ -117,23 +117,23 @@ command_t cmdlist[] = {
          "Create a new file with a specific striping pattern or\n"
          "set the default striping pattern on an existing directory or\n"
          "delete the default striping pattern from an existing directory\n"
-         "usage: setstripe [--size|-s stripe_size] [--offset|-o start_ost]\n"
-         "                 [--count|-c stripe_count] [--pool|-p <pool>]\n"
-         "                 <dir|filename>\n"
+         "usage: setstripe [--size|-s stripe_size] [--count|-c stripe_count]\n"
+         "                 [--index|-i|--offset|-o start_ost_index]\n"
+         "                 [--pool|-p <pool>] <dir|filename>\n"
          "       or \n"
          "       setstripe -d <dir>   (to delete default striping)\n"
          "\tstripe_size:  Number of bytes on each OST (0 filesystem default)\n"
          "\t              Can be specified with k, m or g (in KB, MB and GB\n"
          "\t              respectively)\n"
-         "\tstart_ost:    OST index of first stripe (-1 filesystem default)\n"
+         "\tstart_ost_index: OST index of first stripe (-1 filesystem default)\n"
          "\tstripe_count: Number of OSTs to stripe over (0 default, -1 all)\n"
          "\tpool:         Name of OST pool"},
         {"getstripe", lfs_getstripe, 0,
          "To list the striping info for a given file or files in a\n"
          "directory or recursively for all files in a directory tree.\n"
          "usage: getstripe [--obd|-O <uuid>] [--quiet | -q] [--verbose | -v]\n"
-         "                 [--count | -c ] [--size | -s ] [--index | -i ]\n"
-         "                 [--offset | -o ] [--pool | -p ] [--directory | -d]\n"
+         "                 [--count | -c ] [--index | -i | --offset | -o ]\n"
+         "                 [--size | -s ] [--pool | -p ] [--directory | -d]\n"
          "                 [--mdt | -M] [--recursive | -r] <dir|file> ..."},
         {"pool_list", lfs_poollist, 0,
          "List pools or pool OSTs\n"
@@ -198,9 +198,9 @@ command_t cmdlist[] = {
          "       -i can be used instead of --inode-softlimit/--inode-grace\n"
          "       -I can be used instead of --inode-hardlimit"},
         {"quota", lfs_quota, 0, "Display disk usage and limits.\n"
-         "usage: quota [-v] [-o obd_uuid|-i mdt_idx|-I ost_idx]\n"
+         "usage: quota [-q] [-v] [-o <obd_uuid>|-i <mdt_idx>|-I <ost_idx>]\n"
          "             [<-u|-g> <uname>|<uid>|<gname>|<gid>] <filesystem>\n"
-         "       quota [-o obd_uuid|-i mdt_idx|-I ost_idx] -t <-u|-g> <filesystem>"},
+         "       quota [-o <obd_uuid>|-i <mdt_idx>|-I <ost_idx>] -t <-u|-g> <filesystem>"},
         {"quotainv", lfs_quotainv, 0, "Invalidate quota data.\n"
          "usage: quotainv [-u|-g] <filesystem>"},
 #endif
@@ -1854,7 +1854,6 @@ static inline char *type2name(int check_type)
                 return "unknown";
 }
 
-
 /* Converts seconds value into format string
  * result is returned in buf
  * Notes:
@@ -1862,12 +1861,12 @@ static inline char *type2name(int check_type)
  *        2. zero fields are not filled (except for p. 3): 5d1s
  *        3. zero seconds value is presented as "0s"
  */
-static void sec2str(time_t seconds, char *buf)
+static char * __sec2str(time_t seconds, char *buf)
 {
         const char spec[] = "smhdw";
         const unsigned long mult[] = {1, 60, 60*60, 24*60*60, 7*24*60*60};
         unsigned long c;
-        chartail = buf;
+        char *tail = buf;
         int i;
 
         for (i = sizeof(mult) / sizeof(mult[0]) - 1 ; i >= 0; i--) {
@@ -1878,8 +1877,24 @@ static void sec2str(time_t seconds, char *buf)
 
                 seconds %= mult[i];
         }
+
+        return tail;
 }
 
+static void sec2str(time_t seconds, char *buf, int rc)
+{
+        char *tail = buf;
+
+        if (rc)
+                *tail++ = '[';
+
+        tail = __sec2str(seconds, tail);
+
+        if (rc && tail - buf < 39) {
+                *tail++ = ']';
+                *tail++ = 0;
+        }
+}
 
 static void diff2str(time_t seconds, char *buf, time_t now)
 {
@@ -1891,7 +1906,7 @@ static void diff2str(time_t seconds, char *buf, time_t now)
                 strcpy(buf, "none");
                 return;
         }
-        sec2str(seconds - now, buf);
+        __sec2str(seconds - now, buf);
 }
 
 static void print_quota_title(char *name, struct if_quotactl *qctl)
@@ -1966,12 +1981,12 @@ static void print_quota(char *mnt, struct if_quotactl *qctl, int type, int rc)
                                         ? LPU64 : "["LPU64"]",
                                         dqb->dqb_bsoftlimit);
                         else
-                                sprintf(numbuf[1], "%s", "");
+                                sprintf(numbuf[1], "%s", "-");
                         sprintf(numbuf[2], (dqb->dqb_valid & QIF_BLIMITS)
                                 ? LPU64 : "["LPU64"]", dqb->dqb_bhardlimit);
                         printf(" %7s%c %6s %7s %7s",
                                numbuf[0], bover ? '*' : ' ', numbuf[1],
-                               numbuf[2], bover > 1 ? timebuf : "");
+                               numbuf[2], bover > 1 ? timebuf : "-");
 
                         if (iover)
                                 diff2str(dqb->dqb_itime, timebuf, now);
@@ -1983,13 +1998,15 @@ static void print_quota(char *mnt, struct if_quotactl *qctl, int type, int rc)
                                         ? LPU64 : "["LPU64"]",
                                         dqb->dqb_isoftlimit);
                         else
-                                sprintf(numbuf[1], "%s", "");
+                                sprintf(numbuf[1], "%s", "-");
                         sprintf(numbuf[2], (dqb->dqb_valid & QIF_ILIMITS) ?
                                 LPU64 : "["LPU64"]", dqb->dqb_ihardlimit);
                         if (type != QC_OSTIDX)
                                 printf(" %7s%c %6s %7s %7s",
                                        numbuf[0], iover ? '*' : ' ', numbuf[1],
-                                       numbuf[2], iover > 1 ? timebuf : "");
+                                       numbuf[2], iover > 1 ? timebuf : "-");
+                        else
+                                printf(" %7s %7s %7s %7s", "-", "-", "-", "-");
                         printf("\n");
                 }
         } else if (qctl->qc_cmd == LUSTRE_Q_GETINFO ||
@@ -1997,8 +2014,8 @@ static void print_quota(char *mnt, struct if_quotactl *qctl, int type, int rc)
                 char bgtimebuf[40];
                 char igtimebuf[40];
 
-                sec2str(qctl->qc_dqinfo.dqi_bgrace, bgtimebuf);
-                sec2str(qctl->qc_dqinfo.dqi_igrace, igtimebuf);
+                sec2str(qctl->qc_dqinfo.dqi_bgrace, bgtimebuf, rc);
+                sec2str(qctl->qc_dqinfo.dqi_igrace, igtimebuf, rc);
                 printf("Block grace time: %s; Inode grace time: %s\n",
                        bgtimebuf, igtimebuf);
         }
@@ -2049,12 +2066,13 @@ static int lfs_quota(int argc, char **argv)
                                     .qc_type = UGQUOTA };
         char *obd_type = (char *)qctl.obd_type;
         char *obd_uuid = (char *)qctl.obd_uuid.uuid;
-        int rc, rc1 = 0, rc2 = 0, rc3 = 0, verbose = 0, pass = 0;
+        int rc, rc1 = 0, rc2 = 0, rc3 = 0,
+            verbose = 0, pass = 0, quiet = 0, inacc;
         char *endptr;
         __u32 valid = QC_GENERAL, idx = 0;
 
         optind = 0;
-        while ((c = getopt(argc, argv, "ugto:i:I:v")) != -1) {
+        while ((c = getopt(argc, argv, "ugto:i:I:qv")) != -1) {
                 switch (c) {
                 case 'u':
                         if (qctl.qc_type != UGQUOTA) {
@@ -2088,6 +2106,9 @@ static int lfs_quota(int argc, char **argv)
                 case 'v':
                         verbose = 1;
                         break;
+                case 'q':
+                        quiet = 1;
+                        break;
                 default:
                         fprintf(stderr, "error: %s: option '-%c' "
                                         "unrecognized\n", argv[0], c);
@@ -2141,13 +2162,24 @@ ug_output:
         mnt = argv[optind];
 
         rc1 = llapi_quotactl(mnt, &qctl);
-        if (rc1 == -1 && errno == ESRCH) {
-                fprintf(stderr, "\n%s quotas are not enabled.\n",
-                        qctl.qc_type == USRQUOTA ? "user" : "group");
-                goto out;
+        if (rc1 == -1) {
+                switch (errno) {
+                case ESRCH:
+                        fprintf(stderr, "%s quotas are not enabled.\n",
+                                qctl.qc_type == USRQUOTA ? "user" : "group");
+                        goto out;
+                case EPERM:
+                        fprintf(stderr, "Permission denied.\n");
+                case ENOENT:
+                        /* We already got a "No such file..." message. */
+                        goto out;
+                default:
+                        fprintf(stderr, "Unexpected quotactl error: %s\n",
+                                strerror(errno));
+                }
         }
 
-        if (qctl.qc_cmd == LUSTRE_Q_GETQUOTA)
+        if (qctl.qc_cmd == LUSTRE_Q_GETQUOTA && !quiet)
                 print_quota_title(name, &qctl);
 
         if (rc1 && *obd_type)
@@ -2156,6 +2188,9 @@ ug_output:
         if (qctl.qc_valid != QC_GENERAL)
                 mnt = "";
 
+        inacc = (qctl.qc_cmd == LUSTRE_Q_GETQUOTA) &&
+                ((qctl.qc_dqblk.dqb_valid&(QIF_LIMITS|QIF_USAGE))!=(QIF_LIMITS|QIF_USAGE));
+
         print_quota(mnt, &qctl, QC_GENERAL, rc1);
 
         if (qctl.qc_valid == QC_GENERAL && qctl.qc_cmd != LUSTRE_Q_GETINFO && verbose) {
@@ -2163,7 +2198,7 @@ ug_output:
                 rc3 = print_obd_quota(mnt, &qctl, 0);
         }
 
-        if (rc1 || rc2 || rc3)
+        if (rc1 || rc2 || rc3 || inacc)
                 printf("Some errors happened when getting quota info. "
                        "Some devices may be not working or deactivated. "
                        "The data in \"[]\" is inaccurate.\n");
@@ -2172,7 +2207,7 @@ out:
         if (pass == 1)
                 goto ug_output;
 
-        return 0;
+        return rc1;
 }
 #endif /* HAVE_SYS_QUOTA_H! */