Whamcloud - gitweb
LU-8920 utils: don't print deactivated OSTs in "lfs df" 28/24228/2
authorAndreas Dilger <andreas.dilger@intel.com>
Wed, 7 Dec 2016 23:56:47 +0000 (16:56 -0700)
committerOleg Drokin <oleg.drokin@intel.com>
Sat, 17 Dec 2016 05:49:12 +0000 (05:49 +0000)
Don't print deactivated OSTs or MDTs in "lfs df".  If they have
been deactivated then the sysadmin knows they are inactive so
there isn't much benefit to printing them all the time.  Only
print deactivated OSTs/MDTs if the new "-v" option is given.

Add long options for "-i" and "-h" (--inodes and --human-readable,
respectively) and sort the lfs_df() options to be alphabetical by
short option letter.

Move the "lfs df" manual to a separate "lfs-df.1" man page to
allow better description of the options and examples.

Add a "flags" argument to showdf() and mntdf() instead of adding
an every-growing list of boolean arguments to these functions.

Do space->tab conversion for affected functions.

Signed-off-by: Andreas Dilger <andreas.dilger@intel.com>
Change-Id: I97917f0583373ffe645f68ed3cf8dbfbc48cab07
Reviewed-on: https://review.whamcloud.com/24228
Tested-by: Jenkins
Tested-by: Maloo <hpdd-maloo@intel.com>
Reviewed-by: Steve Guminski <stephenx.guminski@intel.com>
Reviewed-by: Yang Sheng <yang.sheng@intel.com>
Reviewed-by: John L. Hammond <john.hammond@intel.com>
Reviewed-by: Oleg Drokin <oleg.drokin@intel.com>
lustre/doc/lfs-df.1 [new file with mode: 0644]
lustre/doc/lfs.1
lustre/utils/lfs.c

diff --git a/lustre/doc/lfs-df.1 b/lustre/doc/lfs-df.1
new file mode 100644 (file)
index 0000000..cfba73c
--- /dev/null
@@ -0,0 +1,83 @@
+.TH lfs-df 1 "2016 Dec 7" Lustre "user utilities"
+.SH NAME
+lfs df \- report Lustre filesystem disk usage
+.SH SYNOPSIS
+.BR "lfs df" " [" -i "] [" -h "] [" --lazy "] [" --pool | -p
+.IR <fsname> [. <pool> ]]
+.RB [ -v ]
+.RI [ path ]
+.SH DESCRIPTION
+.B lfs df
+displays filesystem usage information by default for each Lustre
+filesystem currently mounted on that node, or for the filesystem
+that contains
+.I path
+if given. It displaying current usage and totals for each MDT and
+OST separately, as well as a per-filesystem summary that matches
+.BR df (1)
+output for each filesystem.
+.SH OPTIONS
+The various options supported by
+.B lfs df
+are listed and explained below:
+.TP
+.BR -h ", " --human-readable
+Print output in a human readable format (e.g. 16.3T, 4.25P).
+Suffixes are SI base-2 units (i.e. 1 GiB = 1024 MiB).
+.TP
+.BR -i ", " --inodes
+Print information about the inode usage and totals for the MDTs and
+OSTs rather than space usage.
+.TP
+.BR -l ", " --lazy
+Do not attempt to contact any OST or MDT not currently connected to
+the client.  This avoids blocking the
+.B lfs df
+output if an OST is down, and only returns the space on the OSTs that
+can currently be accessed.
+.TP
+.BR -p ", " --pool=\fR[\fIfsname\fR.]\fIpool
+Show only OSTs that are in the specified
+.IR pool .
+If multiple filesystems are mounted, list OSTs in
+.I pool
+for every filesystem, or limit the display to only a pool for a
+specific filesystem if
+.I fsname.pool
+is given.  Specifying both the fsname and pool like:
+.br
+.BI "lfs df --pool=" fsname.pool
+.br
+is equivalent to specifying the mountpoint for the given
+.IR fsname :
+.br
+.BI "lfs df --pool=" "pool /mnt/fsname"
+.TP
+.BR -v ", " --verbose
+Show deactivated MDTs and OSTs in the listing.  By default, any
+MDTs and OSTs that are deactivated by the administrator are not shown.
+However, targets that are only temporarily inaccessible are still shown.
+.SH EXAMPLES
+.TP
+.B $ lfs df -h /mnt/testfs
+Lists space usage per OST and MDT for the
+.B testfs
+filesystem in human readable format.
+.TP
+.B $ lfs df -i
+List inode usage per OST and MDT for all mounted Lustre filesystems.
+.TP
+.B $ lfs df --pool ssd /mnt/testfs
+List space usage for only the
+.B ssd
+pool of the
+.B testfs
+filesystem.
+.TP
+.B $ lfs df -v /mnt/testfs
+List all MDTs and OSTs for the
+.B testfs
+filesystem, even if not currently connected.
+.SH SEE ALSO
+.BR lfs (1),
+.BR lustre (7)
index a9eb54e..ba5d462 100644 (file)
@@ -13,7 +13,7 @@ lfs \- Lustre utility to create a file with specific striping pattern, find the
 .br
 .B lfs data_version [-n] \fB<filename>\fR
 .br
-.B lfs df [-i] [-h] [--lazy] [--pool|-p <fsname>[.<pool>] [path]
+.B lfs df [-ihlv] [--pool|-p <fsname>[.<pool>]] [path]
 .br
 .B lfs fid2path [--link <linkno>] <fsname|rootpath> <fid> ...
 .br
@@ -126,16 +126,12 @@ Changelog consumers must be registered on the MDT node using \fBlctl\fR.
 .B check
 Display the status of MDS or OSTs (as specified in the command) or all the servers (MDS and OSTs)
 .TP
-.B df [-i] [-h] [--lazy] [--pool|-p <fsname>[.<pool>] [path]
-Report filesystem disk space usage or inodes usage (with \fB-i\fR) of each
-MDT/OST, or a subset of OSTs if a pool is specified with \fB-p\fR.  By default
-print the usage of all mounted Lustre filesystems, otherwise if \fBpath\fR is
-specified print only the usage of that filesystem.  If \fB-h\fR is given, the
-output is printed in \fIh\fRuman readable format, using SI base-2 suffixes
-for \fBM\fRega-, \fBG\fRiga-, \fBT\fRera-, \fBP\fReta-, or \fBE\fRxabytes.
-The \fB--lazy\fR/\fB-l\fR option skips any OST that is currently disconnected
-from the client.  This avoids blocking the \fBdf\fR output if an OST is down,
-and only returns the space on the OSTs that can currently be accessed.
+.B df
+See
+.BR lfs-df (1)
+for details of
+.B lfs df
+usage.
 .TP
 .B find
 To search the directory tree rooted at the given dir/file name for the files that match the given parameters: \fB--atime\fR (file was last accessed N*24 hours ago), \fB--ctime\fR (file's status was last changed N*24 hours ago), \fB--mtime\fR (file's data was last modified N*24 hours ago), \fB--obd\fR (file has an object on a specific OST or OSTs), \fB--size\fR (file has size in bytes, or \fBk\fRilo-, \fBM\fRega-, \fBG\fRiga-, \fBT\fRera-, \fBP\fReta-, or \fBE\fRxabytes if a suffix is given), \fB--type\fR (file has the type: \fBb\fRlock, \fBc\fRharacter, \fBd\fRirectory, \fBp\fRipe, \fBf\fRile, sym\fBl\fRink, \fBs\fRocket, or \fBD\fRoor (Solaris)), \fB--uid\fR (file has specific numeric user ID), \fB--user\fR (file owned by specific user, numeric user ID allowed), \fB--gid\fR (file has specific group ID), \fB--group\fR (file belongs to specific group, numeric group ID allowed), \fB--layout\fR (file has a raid0 layout or is released). The option \fB--maxdepth\fR limits find to decend at most N levels of directory tree. The options \fB--print\fR and \fB--print0\fR print full file name, followed by a newline or NUL character correspondingly.  Using \fB!\fR before an option negates its meaning (\fIfiles NOT matching the parameter\fR).  Using \fB+\fR before a numeric value means \fIfiles with the parameter OR MORE\fR, while \fB-\fR before a numeric value means \fIfiles with the parameter OR LESS\fR.
@@ -380,15 +376,6 @@ List all the OSTs
 .B $ lfs mdts
 List all the MDTs
 .TP
-.B $ lfs df -h
-Lists space usage per OST and MDT in human readable format.
-.TP
-.B $ lfs df -i
-Lists inode usage per OST and MDT
-.TP
-.B $ lfs df --pool <filesystem>[.<pool>] | <pathname>
-List space or inode usage for a specific OST pool
-.TP
 .B $ lfs quota -u bob /mnt/lustre
 List quotas of user `bob'
 .TP
@@ -418,6 +405,7 @@ The \fBlfs find\fR command isn't as comprehensive as \fBfind\fR(1).
 .SH AUTHOR
 The lfs command is part of the Lustre filesystem.
 .SH SEE ALSO
+.BR lfs-df (1),
 .BR lfs-hsm (1),
 .BR lfs-setdirstripe (1),
 .BR lfs-getdirstripe (1),
index c885e5f..e868c86 100644 (file)
@@ -2258,69 +2258,79 @@ static int lfs_mdts(int argc, char **argv)
 #define RSF     "%4s"
 #define RDF     "%3d%%"
 
+enum mntdf_flags {
+       MNTDF_INODES    = 0x0001,
+       MNTDF_COOKED    = 0x0002,
+       MNTDF_LAZY      = 0x0004,
+       MNTDF_VERBOSE   = 0x0008,
+};
+
 static int showdf(char *mntdir, struct obd_statfs *stat,
-                  char *uuid, int ishow, int cooked,
-                  char *type, int index, int rc)
+                 char *uuid, enum mntdf_flags flags,
+                 char *type, int index, int rc)
 {
-        long long avail, used, total;
-        double ratio = 0;
-        char *suffix = "KMGTPEZY";
-        /* Note if we have >2^64 bytes/fs these buffers will need to be grown */
+       long long avail, used, total;
+       double ratio = 0;
+       char *suffix = "KMGTPEZY";
+       /* Note if we have >2^64 bytes/fs these buffers will need to be grown */
        char tbuf[3 * sizeof(__u64)];
        char ubuf[3 * sizeof(__u64)];
        char abuf[3 * sizeof(__u64)];
        char rbuf[3 * sizeof(__u64)];
 
-        if (!uuid || !stat)
-                return -EINVAL;
+       if (!uuid || !stat)
+               return -EINVAL;
 
-        switch (rc) {
-        case 0:
-                if (ishow) {
-                        avail = stat->os_ffree;
-                        used = stat->os_files - stat->os_ffree;
-                        total = stat->os_files;
-                } else {
-                        int shift = cooked ? 0 : 10;
+       switch (rc) {
+       case 0:
+               if (flags & MNTDF_INODES) {
+                       avail = stat->os_ffree;
+                       used = stat->os_files - stat->os_ffree;
+                       total = stat->os_files;
+               } else {
+                       int shift = flags & MNTDF_COOKED ? 0 : 10;
 
-                        avail = (stat->os_bavail * stat->os_bsize) >> shift;
-                        used  = ((stat->os_blocks - stat->os_bfree) *
-                                 stat->os_bsize) >> shift;
-                        total = (stat->os_blocks * stat->os_bsize) >> shift;
-                }
+                       avail = (stat->os_bavail * stat->os_bsize) >> shift;
+                       used  = ((stat->os_blocks - stat->os_bfree) *
+                                stat->os_bsize) >> shift;
+                       total = (stat->os_blocks * stat->os_bsize) >> shift;
+               }
 
-                if ((used + avail) > 0)
-                        ratio = (double)used / (double)(used + avail);
-
-                if (cooked) {
-                        int i;
-                        double cook_val;
-
-                        cook_val = (double)total;
-                        i = COOK(cook_val);
-                        if (i > 0)
-                                sprintf(tbuf, HDF, cook_val, suffix[i - 1]);
-                        else
-                                sprintf(tbuf, CDF, total);
-
-                        cook_val = (double)used;
-                        i = COOK(cook_val);
-                        if (i > 0)
-                                sprintf(ubuf, HDF, cook_val, suffix[i - 1]);
-                        else
-                                sprintf(ubuf, CDF, used);
-
-                        cook_val = (double)avail;
-                        i = COOK(cook_val);
-                        if (i > 0)
-                                sprintf(abuf, HDF, cook_val, suffix[i - 1]);
-                        else
-                                sprintf(abuf, CDF, avail);
-                } else {
-                        sprintf(tbuf, CDF, total);
-                        sprintf(ubuf, CDF, used);
-                        sprintf(abuf, CDF, avail);
-                }
+               if ((used + avail) > 0)
+                       ratio = (double)used / (double)(used + avail);
+
+               if (flags & MNTDF_COOKED) {
+                       int i;
+                       double cook_val;
+
+                       cook_val = (double)total;
+                       i = COOK(cook_val);
+                       if (i > 0)
+                               snprintf(tbuf, sizeof(tbuf), HDF, cook_val,
+                                        suffix[i - 1]);
+                       else
+                               snprintf(tbuf, sizeof(tbuf), CDF, total);
+
+                       cook_val = (double)used;
+                       i = COOK(cook_val);
+                       if (i > 0)
+                               snprintf(ubuf, sizeof(ubuf), HDF, cook_val,
+                                        suffix[i - 1]);
+                       else
+                               snprintf(ubuf, sizeof(ubuf), CDF, used);
+
+                       cook_val = (double)avail;
+                       i = COOK(cook_val);
+                       if (i > 0)
+                               snprintf(abuf, sizeof(abuf), HDF, cook_val,
+                                        suffix[i - 1]);
+                       else
+                               snprintf(abuf, sizeof(abuf), CDF, avail);
+               } else {
+                       snprintf(tbuf, sizeof(tbuf), CDF, total);
+                       snprintf(ubuf, sizeof(tbuf), CDF, used);
+                       snprintf(abuf, sizeof(tbuf), CDF, avail);
+               }
 
                 sprintf(rbuf, RDF, (int)(ratio * 100 + 0.5));
                 printf(UUF" "CSF" "CSF" "CSF" "RSF" %-s",
@@ -2347,8 +2357,7 @@ struct ll_stat_type {
         char *st_name;
 };
 
-static int mntdf(char *mntdir, char *fsname, char *pool, int ishow,
-               int cooked, int lazy)
+static int mntdf(char *mntdir, char *fsname, char *pool, enum mntdf_flags flags)
 {
        struct obd_statfs stat_buf, sum = { .os_bsize = 1 };
        struct obd_uuid uuid_buf;
@@ -2364,17 +2373,17 @@ static int mntdf(char *mntdir, char *fsname, char *pool, int ishow,
        int rc = 0;
        int rc2;
 
-        if (pool) {
-                poolname = strchr(pool, '.');
-                if (poolname != NULL) {
-                        if (strncmp(fsname, pool, strlen(fsname))) {
-                                fprintf(stderr, "filesystem name incorrect\n");
-                                return -ENODEV;
-                        }
-                        poolname++;
-                } else
-                        poolname = pool;
-        }
+       if (pool) {
+               poolname = strchr(pool, '.');
+               if (poolname != NULL) {
+                       if (strncmp(fsname, pool, strlen(fsname))) {
+                               fprintf(stderr, "filesystem name incorrect\n");
+                               return -ENODEV;
+                       }
+                       poolname++;
+               } else
+                       poolname = pool;
+       }
 
        fd = open(mntdir, O_RDONLY);
        if (fd < 0) {
@@ -2384,52 +2393,55 @@ static int mntdf(char *mntdir, char *fsname, char *pool, int ishow,
                return rc;
        }
 
-        if (ishow)
-                printf(UUF" "CSF" "CSF" "CSF" "RSF" %-s\n",
-                       "UUID", "Inodes", "IUsed", "IFree",
-                       "IUse%", "Mounted on");
-        else
-                printf(UUF" "CSF" "CSF" "CSF" "RSF" %-s\n",
-                       "UUID", cooked ? "bytes" : "1K-blocks",
-                       "Used", "Available", "Use%", "Mounted on");
-
-        for (tp = types; tp->st_name != NULL; tp++) {
-                for (index = 0; ; index++) {
-                        memset(&stat_buf, 0, sizeof(struct obd_statfs));
-                        memset(&uuid_buf, 0, sizeof(struct obd_uuid));
-                       type = lazy ? tp->st_op | LL_STATFS_NODELAY : tp->st_op;
+       if (flags & MNTDF_INODES)
+               printf(UUF" "CSF" "CSF" "CSF" "RSF" %-s\n",
+                      "UUID", "Inodes", "IUsed", "IFree",
+                      "IUse%", "Mounted on");
+       else
+               printf(UUF" "CSF" "CSF" "CSF" "RSF" %-s\n",
+                      "UUID", flags & MNTDF_COOKED ? "bytes" : "1K-blocks",
+                      "Used", "Available", "Use%", "Mounted on");
+
+       for (tp = types; tp->st_name != NULL; tp++) {
+               for (index = 0; ; index++) {
+                       memset(&stat_buf, 0, sizeof(struct obd_statfs));
+                       memset(&uuid_buf, 0, sizeof(struct obd_uuid));
+                       type = flags & MNTDF_LAZY ?
+                               tp->st_op | LL_STATFS_NODELAY : tp->st_op;
                        rc2 = llapi_obd_fstatfs(fd, type, index,
                                               &stat_buf, &uuid_buf);
                        if (rc2 == -ENODEV)
                                break;
-                       else if (rc2 == -EAGAIN)
+                       if (rc2 == -EAGAIN)
                                continue;
-                       else if (rc2 == -ENODATA)
-                               ; /* Inactive device, OK. */
-                       else if (rc2 < 0 && rc == 0)
+                       if (rc2 == -ENODATA) { /* Inactive device, OK. */
+                               if (!(flags & MNTDF_VERBOSE))
+                                       continue;
+                       } else if (rc2 < 0 && rc == 0) {
                                rc = rc2;
+                       }
+
+                       if (poolname && tp->st_op == LL_STATFS_LOV &&
+                           llapi_search_ost(fsname, poolname,
+                                            obd_uuid2str(&uuid_buf)) != 1)
+                               continue;
 
-                        if (poolname && tp->st_op == LL_STATFS_LOV &&
-                            llapi_search_ost(fsname, poolname,
-                                             obd_uuid2str(&uuid_buf)) != 1)
-                                continue;
-
-                        /* 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 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);
+                       /* 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 get anything in the uuid_buf, then fill
+                        * it in so that we can print an error message. */
+                       if (uuid_buf.uuid[0] == '\0')
+                               snprintf(uuid_buf.uuid, sizeof(uuid_buf.uuid),
+                                        "%s%04x", tp->st_name, index);
                        showdf(mntdir, &stat_buf, obd_uuid2str(&uuid_buf),
-                              ishow, cooked, tp->st_name, index, rc2);
+                              flags, tp->st_name, index, rc2);
 
                        if (rc2 == 0) {
-                                if (tp->st_op == LL_STATFS_LMV) {
-                                        sum.os_ffree += stat_buf.os_ffree;
-                                        sum.os_files += stat_buf.os_files;
-                                } else /* if (tp->st_op == LL_STATFS_LOV) */ {
+                               if (tp->st_op == LL_STATFS_LMV) {
+                                       sum.os_ffree += stat_buf.os_ffree;
+                                       sum.os_files += stat_buf.os_files;
+                               } else /* if (tp->st_op == LL_STATFS_LOV) */ {
                                        sum.os_blocks += stat_buf.os_blocks *
                                                stat_buf.os_bsize;
                                        sum.os_bfree  += stat_buf.os_bfree *
@@ -2453,7 +2465,7 @@ static int mntdf(char *mntdir, char *fsname, char *pool, int ishow,
                sum.os_ffree = ost_ffree;
        }
        printf("\n");
-       showdf(mntdir, &sum, "filesystem summary:", ishow, cooked, NULL, 0, 0);
+       showdf(mntdir, &sum, "filesystem_summary:", flags, NULL, 0, 0);
        printf("\n");
 
        return rc;
@@ -2461,55 +2473,60 @@ static int mntdf(char *mntdir, char *fsname, char *pool, int ishow,
 
 static int lfs_df(int argc, char **argv)
 {
-        char mntdir[PATH_MAX] = {'\0'}, path[PATH_MAX] = {'\0'};
-        int ishow = 0, cooked = 0;
-       int lazy = 0;
-        int c, rc = 0, index = 0;
-        char fsname[PATH_MAX] = "", *pool_name = NULL;
-        struct option long_opts[] = {
-                {"pool", required_argument, 0, 'p'},
-                {"lazy", 0, 0, 'l'},
-                {0, 0, 0, 0}
-        };
+       char mntdir[PATH_MAX] = {'\0'}, path[PATH_MAX] = {'\0'};
+       enum mntdf_flags flags = 0;
+       int c, rc = 0, index = 0;
+       char fsname[PATH_MAX] = "", *pool_name = NULL;
+       struct option long_opts[] = {
+               {"human-readable", 0, 0, 'h'},
+               {"inodes", 0, 0, 'i'},
+               {"lazy", 0, 0, 'l'},
+               {"pool", required_argument, 0, 'p'},
+               {"verbose", 0, 0, 'v'},
+               {0, 0, 0, 0}
+       };
 
-       while ((c = getopt_long(argc, argv, "hilp:", long_opts, NULL)) != -1) {
+       while ((c = getopt_long(argc, argv, "hilp:v", long_opts, NULL)) != -1) {
                switch (c) {
-               case 'i':
-                       ishow = 1;
-                       break;
                case 'h':
-                       cooked = 1;
+                       flags |= MNTDF_COOKED;
+                       break;
+               case 'i':
+                       flags |= MNTDF_INODES;
                        break;
                case 'l':
-                       lazy = 1;
+                       flags |= MNTDF_LAZY;
                        break;
                case 'p':
                        pool_name = optarg;
                        break;
+               case 'v':
+                       flags |= MNTDF_VERBOSE;
+                       break;
                default:
                        return CMD_HELP;
                }
        }
-        if (optind < argc && !realpath(argv[optind], path)) {
-                rc = -errno;
-                fprintf(stderr, "error: invalid path '%s': %s\n",
-                        argv[optind], strerror(-rc));
-                return rc;
-        }
+       if (optind < argc && !realpath(argv[optind], path)) {
+               rc = -errno;
+               fprintf(stderr, "error: invalid path '%s': %s\n",
+                       argv[optind], strerror(-rc));
+               return rc;
+       }
 
-        while (!llapi_search_mounts(path, index++, mntdir, fsname)) {
-                /* Check if we have a mount point */
-                if (mntdir[0] == '\0')
-                        continue;
+       while (!llapi_search_mounts(path, index++, mntdir, fsname)) {
+               /* Check if we have a mount point */
+               if (mntdir[0] == '\0')
+                       continue;
 
-               rc = mntdf(mntdir, fsname, pool_name, ishow, cooked, lazy);
-                if (rc || path[0] != '\0')
-                        break;
-                fsname[0] = '\0'; /* avoid matching in next loop */
-                mntdir[0] = '\0'; /* avoid matching in next loop */
-        }
+               rc = mntdf(mntdir, fsname, pool_name, flags);
+               if (rc || path[0] != '\0')
+                       break;
+               fsname[0] = '\0'; /* avoid matching in next loop */
+               mntdir[0] = '\0'; /* avoid matching in next loop */
+       }
 
-        return rc;
+       return rc;
 }
 
 static int lfs_getname(int argc, char **argv)