Whamcloud - gitweb
b=14836 Fail if "lfs setstripe" has positional parameters
[fs/lustre-release.git] / lustre / utils / lfs.c
index bb055c5..20f2d60 100644 (file)
@@ -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"
@@ -162,7 +162,8 @@ command_t cmdlist[] = {
         {"join", lfs_join, 0,
          "join two lustre files into one.\n"
          "obsolete, HEAD does not support it anymore.\n"},
-        {"osts", lfs_osts, 0, "osts"},
+        {"osts", lfs_osts, 0, "list OSTs connected to client "
+         "[for specified path only]\n" "usage: osts [path]"},
         {"df", lfs_df, 0,
          "report filesystem disk space usage or inodes usage"
          "of each MDS and all OSDs or a batch belonging to a specific pool .\n"
@@ -198,9 +199,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 [-q] [-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
@@ -291,18 +292,12 @@ static int lfs_setstripe(int argc, char **argv)
         st_offset = -1;
         st_count = 0;
 
-#if LUSTRE_VERSION < OBD_OCD_VERSION(2,1,0,0)
+#if LUSTRE_VERSION < OBD_OCD_VERSION(2,4,50,0)
         if (argc == 5 && argv[1][0] != '-' &&
             isnumber(argv[2]) && isnumber(argv[3]) && isnumber(argv[4])) {
-                fprintf(stderr, "warning: deprecated usage of setstripe "
+                fprintf(stderr, "error: obsolete usage of setstripe "
                         "positional parameters.  Use -c, -i, -s instead.\n");
-                /* for compatibility with the existing positional parameter
-                 * usage */
-                fname = argv[1];
-                stripe_size_arg = argv[2];
-                stripe_off_arg = argv[3];
-                stripe_count_arg = argv[4];
-                optind = 4;
+                return CMD_HELP;
         } else
 #else
 #warning "remove obsolete positional parameter code"
@@ -371,7 +366,7 @@ static int lfs_setstripe(int argc, char **argv)
         }
         /* get the stripe offset */
         if (stripe_off_arg != NULL) {
-                st_offset = strtoul(stripe_off_arg, &end, 0);
+                st_offset = strtol(stripe_off_arg, &end, 0);
                 if (*end != '\0') {
                         fprintf(stderr, "error: %s: bad stripe offset '%s'\n",
                                 argv[0], stripe_off_arg);
@@ -499,7 +494,6 @@ static int lfs_find(int argc, char **argv)
         int c, ret;
         time_t t;
         struct find_param param = { .maxdepth = -1 };
-        char str[1024];
         struct option long_opts[] = {
                 /* New find options. */
                 {"atime",     required_argument, 0, 'A'},
@@ -581,29 +575,20 @@ static int lfs_find(int argc, char **argv)
                 case 'A':
                         xtime = &param.atime;
                         xsign = &param.asign;
+                        param.exclude_atime = !!neg_opt;
                 case 'C':
                         if (c == 'C') {
                                 xtime = &param.ctime;
                                 xsign = &param.csign;
+                                param.exclude_ctime = !!neg_opt;
                         }
                 case 'M':
                         if (c == 'M') {
                                 xtime = &param.mtime;
                                 xsign = &param.msign;
+                                param.exclude_mtime = !!neg_opt;
                         }
                         new_fashion = 1;
-                        if (neg_opt) {
-                                if (optarg[0] == '-')
-                                        optarg[0] = '+';
-                                else if (optarg[0] == '+')
-                                        optarg[0] = '-';
-                                else {
-                                        str[0] = '-';
-                                        str[1] = '\0';
-                                        strcat(str, optarg);
-                                        optarg = str;
-                                }
-                        }
                         ret = set_time(&t, xtime, optarg);
                         if (ret == INT_MAX)
                                 return -1;
@@ -734,18 +719,6 @@ static int lfs_find(int argc, char **argv)
                         };
                         break;
                 case 's':
-                        if (neg_opt) {
-                                if (optarg[0] == '-')
-                                        optarg[0] = '+';
-                                else if (optarg[0] == '+')
-                                        optarg[0] = '-';
-                                else {
-                                        str[0] = '-';
-                                        str[1] = '\0';
-                                        strcat(str, optarg);
-                                        optarg = str;
-                                }
-                        }
                         if (optarg[0] == '+')
                                 param.size_sign = -1;
                         else if (optarg[0] == '-')
@@ -760,6 +733,8 @@ static int lfs_find(int argc, char **argv)
                                         optarg);
                                 return ret;
                         }
+                        param.check_size = 1;
+                        param.exclude_size = !!neg_opt;
                         break;
                 case 'v':
                         new_fashion = 0;
@@ -879,7 +854,10 @@ static int lfs_getstripe(int argc, char **argv)
                         }
                         break;
                 case 'p':
-                        param.verbose |= VERBOSE_POOL;
+                        if (!(param.verbose & VERBOSE_DETAIL)) {
+                                param.verbose |= VERBOSE_POOL;
+                                param.maxdepth = 0;
+                        }
                         break;
                 case 'M':
                         param.get_mdt_index = 1;
@@ -916,20 +894,33 @@ static int lfs_getstripe(int argc, char **argv)
 
 static int lfs_osts(int argc, char **argv)
 {
-        char mntdir[PATH_MAX] = {'\0'};
+        char mntdir[PATH_MAX] = {'\0'}, path[PATH_MAX] = {'\0'};
         struct find_param param;
         int index = 0, rc=0;
 
-        if (argc != 1)
+        if (argc > 2)
                 return CMD_HELP;
 
-        while (llapi_search_mounts(NULL, index++, mntdir, NULL) == 0) {
+        if (argc == 2 && !realpath(argv[1], path)) {
+                rc = -errno;
+                fprintf(stderr, "error: invalid path '%s': %s\n",
+                        argv[1], strerror(-rc));
+                return rc;
+        }
+
+        while (!llapi_search_mounts(path, index++, mntdir, NULL)) {
+                /* Check if we have a mount point */
+                if (mntdir[0] == '\0')
+                        continue;
+
                 memset(&param, 0, sizeof(param));
                 rc = llapi_ostlist(mntdir, &param);
                 if (rc) {
                         fprintf(stderr, "error: %s: failed on %s\n",
                                 argv[0], mntdir);
                 }
+                if (path[0] != '\0')
+                        break;
                 memset(mntdir, 0, PATH_MAX);
         }
 
@@ -980,8 +971,8 @@ static int showdf(char *mntdir, struct obd_statfs *stat,
                         total = (stat->os_blocks * stat->os_bsize) >> shift;
                 }
 
-                if (total > 0)
-                        ratio = (double)used / (double)total;
+                if ((used + avail) > 0)
+                        ratio = (double)used / (double)(used + avail);
 
                 if (cooked) {
                         int i;
@@ -1013,7 +1004,7 @@ static int showdf(char *mntdir, struct obd_statfs *stat,
                         sprintf(abuf, CDF, avail);
                 }
 
-                sprintf(rbuf, RDF, (int)(ratio * 100));
+                sprintf(rbuf, RDF, (int)(ratio * 100 + 0.5));
                 printf(UUF" "CSF" "CSF" "CSF" "RSF" %-s",
                        uuid, tbuf, ubuf, abuf, rbuf, mntdir);
                 if (type)
@@ -1088,18 +1079,14 @@ static int mntdf(char *mntdir, char *fsname, char *pool, int ishow, int cooked)
                         /* the llapi_obd_statfs() call may have returned with
                          * an error, but if it filled in uuid_buf we will at
                          * lease use that to print out a message for that OBD.
-                         * If we didn't even fill in uuid_buf something is
-                         * definitely incorrect and no point in continuing. */
-                        if (uuid_buf.uuid[0] != '\0') {
-                                showdf(mntdir,&stat_buf,obd_uuid2str(&uuid_buf),
-                                       ishow, cooked, tp->st_name, index, rc);
-                        } else {
-                                char tmp_uuid[12];
+                         * If we didn't get anything in the uuid_buf, then fill
+                         * it in so that we can print an error message. */
+                        if (uuid_buf.uuid[0] == '\0')
+                                sprintf(uuid_buf.uuid, "%s%04x",
+                                       tp->st_name, index);
+                       showdf(mntdir,&stat_buf,obd_uuid2str(&uuid_buf),
+                              ishow, cooked, tp->st_name, index, rc);
 
-                                sprintf(tmp_uuid, "%s%04x", tp->st_name, index);
-                                showdf(mntdir, &stat_buf, tmp_uuid,
-                                       ishow, cooked, tp->st_name, index, rc);
-                        }
                         if (rc == 0) {
                                 if (tp->st_op == LL_STATFS_MDC) {
                                         sum.os_ffree += stat_buf.os_ffree;
@@ -1120,16 +1107,15 @@ static int mntdf(char *mntdir, char *fsname, char *pool, int ishow, int cooked)
 
         printf("\n");
         showdf(mntdir, &sum, "filesystem summary:", ishow, cooked, NULL, 0,0);
-
+        printf("\n");
         return 0;
 }
 
 static int lfs_df(int argc, char **argv)
 {
-        char *path = NULL;
-        char *mntdir = NULL;
+        char mntdir[PATH_MAX] = {'\0'}, path[PATH_MAX] = {'\0'};
         int ishow = 0, cooked = 0;
-        int c, rc = 0;
+        int c, rc = 0, index = 0;
         char fsname[PATH_MAX] = "", *pool_name = NULL;
         struct option long_opts[] = {
                 {"pool", required_argument, 0, 'p'},
@@ -1152,46 +1138,25 @@ static int lfs_df(int argc, char **argv)
                         return CMD_HELP;
                 }
         }
-        if (optind < argc )
-                path = argv[optind];
-
-        if ((mntdir = malloc(PATH_MAX)) == NULL) {
-                fprintf(stderr, "error: cannot allocate %d bytes\n",
-                        PATH_MAX);
-                return -ENOMEM;
+        if (optind < argc && !realpath(argv[optind], path)) {
+                rc = -errno;
+                fprintf(stderr, "error: invalid path '%s': %s\n",
+                        argv[optind], strerror(-rc));
+                return rc;
         }
-        memset(mntdir, 0, PATH_MAX);
-
-        if (path) {
-                char rpath[PATH_MAX] = {'\0'};
 
-                if (!realpath(path, rpath)) {
-                        rc = -errno;
-                        fprintf(stderr, "error: invalid path '%s': %s\n",
-                                        path, strerror(-rc));
-                } else {
-                        rc = llapi_search_mounts(rpath, 0, mntdir, fsname);
-                        if (rc == 0 && mntdir[0] != '\0') {
-                                rc = mntdf(mntdir, fsname, pool_name,
-                                           ishow, cooked);
-                                printf("\n");
-                        }
-                }
-        } else {
-                int index = 0;
+        while (!llapi_search_mounts(path, index++, mntdir, fsname)) {
+                /* Check if we have a mount point */
+                if (mntdir[0] == '\0')
+                        continue;
 
-                while (llapi_search_mounts(NULL, index++, mntdir, fsname)==0) {
-                        rc = mntdf(mntdir, fsname, pool_name,
-                                   ishow, cooked);
-                        if (rc)
-                                break;
-                        printf("\n");
-                        fsname[0] = '\0'; /* avoid matching in next loop */
-                        mntdir[0] = '\0'; /* avoid matching in next loop */
-                }
+                rc = mntdf(mntdir, fsname, pool_name, ishow, cooked);
+                if (rc || path[0] != '\0')
+                        break;
+                fsname[0] = '\0'; /* avoid matching in next loop */
+                mntdir[0] = '\0'; /* avoid matching in next loop */
         }
 
-        free(mntdir);
         return rc;
 }
 
@@ -1854,7 +1819,6 @@ static inline char *type2name(int check_type)
                 return "unknown";
 }
 
-
 /* Converts seconds value into format string
  * result is returned in buf
  * Notes:
@@ -1862,12 +1826,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 +1842,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 +1871,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)
@@ -1999,8 +1979,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);
         }
@@ -2051,7 +2031,8 @@ 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, quiet = 0;
+        int rc, rc1 = 0, rc2 = 0, rc3 = 0,
+            verbose = 0, pass = 0, quiet = 0, inacc;
         char *endptr;
         __u32 valid = QC_GENERAL, idx = 0;
 
@@ -2172,6 +2153,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) {
@@ -2179,7 +2163,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");
@@ -2368,10 +2352,14 @@ static int lfs_changelog(int argc, char **argv)
                 time_t secs;
                 struct tm ts;
 
-                if (endrec && rec->cr_index > endrec)
+                if (endrec && rec->cr_index > endrec) {
+                        llapi_changelog_free(&rec);
                         break;
-                if (rec->cr_index < startrec)
+                }
+                if (rec->cr_index < startrec) {
+                        llapi_changelog_free(&rec);
                         continue;
+                }
 
                 secs = rec->cr_time >> 30;
                 gmtime_r(&secs, &ts);