Author: allanjude
Date: Mon Oct 26 17:07:22 2015
New Revision: 290015
URL: https://svnweb.freebsd.org/changeset/base/290015

Log:
  Allow 'zfs holds -r' to recurse over a file system or volume to find holds
  
  Previously, the parameters of 'zfs holds' could only be snapshots
  
  Add -d <depth> flag to limit depth of recursion
  Add -p flag to print literal values, rather than interpreted values
  Add -H flag to suppress header output and use tabs rather than whitespace
  
  Reviewed by:  mahrens, smh, dteske
  Approved by:  bapt (mentor)
  MFC after:    3 weeks
  Relnotes:     yes
  Sponsored by: ScaleEngine Inc.
  Differential Revision:        https://reviews.freebsd.org/D3994

Modified:
  head/cddl/contrib/opensolaris/cmd/zfs/zfs.8
  head/cddl/contrib/opensolaris/cmd/zfs/zfs_main.c

Modified: head/cddl/contrib/opensolaris/cmd/zfs/zfs.8
==============================================================================
--- head/cddl/contrib/opensolaris/cmd/zfs/zfs.8 Mon Oct 26 16:21:56 2015        
(r290014)
+++ head/cddl/contrib/opensolaris/cmd/zfs/zfs.8 Mon Oct 26 17:07:22 2015        
(r290015)
@@ -31,7 +31,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd September 14, 2015
+.Dd October 24, 2015
 .Dt ZFS 8
 .Os
 .Sh NAME
@@ -272,8 +272,10 @@
 .Ar tag snapshot Ns ...
 .Nm
 .Cm holds
-.Op Fl r
-.Ar snapshot Ns ...
+.Op Fl Hp
+.Op Fl r Ns | Ns Fl d Ar depth
+.Ar filesystem Ns | Ns Ar volume Ns | Ns Ar snapshot Ns
+.Ns ...
 .Nm
 .Cm release
 .Op Fl r
@@ -3159,15 +3161,26 @@ snapshots of all descendent file systems
 .It Xo
 .Nm
 .Cm holds
-.Op Fl r
-.Ar snapshot Ns ...
+.Op Fl Hp
+.Op Fl r Ns | Ns Fl d Ar depth
+.Ar filesystem Ns | Ns Ar volume Ns | Ns Ar snapshot Ns
+.Ns ...
 .Xc
 .Pp
-Lists all existing user references for the given snapshot or snapshots.
+Lists all existing user references for the given dataset or datasets.
 .Bl -tag -width indent
+.It Fl H
+Used for scripting mode. Do not print headers and separate fields by a single
+tab instead of arbitrary white space.
+.It Fl p
+Display numbers in parsable (exact) values.
 .It Fl r
-Lists the holds that are set on the named descendent snapshots, in addition to
-listing the holds on the named snapshot.
+Lists the holds that are set on the descendent snapshots of the named datasets
+or snapshots, in addition to listing the holds on the named snapshots, if any.
+.It Fl d Ar depth
+Recursively display any holds on the named snapshots, or descendent snapshots 
of
+the named datasets or snapshots, limiting the recursion to
+.Ar depth .
 .El
 .It Xo
 .Nm

Modified: head/cddl/contrib/opensolaris/cmd/zfs/zfs_main.c
==============================================================================
--- head/cddl/contrib/opensolaris/cmd/zfs/zfs_main.c    Mon Oct 26 16:21:56 
2015        (r290014)
+++ head/cddl/contrib/opensolaris/cmd/zfs/zfs_main.c    Mon Oct 26 17:07:22 
2015        (r290015)
@@ -329,7 +329,8 @@ get_usage(zfs_help_t idx)
        case HELP_HOLD:
                return (gettext("\thold [-r] <tag> <snapshot> ...\n"));
        case HELP_HOLDS:
-               return (gettext("\tholds [-r] <snapshot> ...\n"));
+               return (gettext("\tholds [-Hp] [-r|-d depth] "
+                   "<filesystem|volume|snapshot> ...\n"));
        case HELP_RELEASE:
                return (gettext("\trelease [-r] <tag> <snapshot> ...\n"));
        case HELP_DIFF:
@@ -5543,7 +5544,8 @@ typedef struct holds_cbdata {
  *
  */
 static void
-print_holds(boolean_t scripted, size_t nwidth, size_t tagwidth, nvlist_t *nvl)
+print_holds(boolean_t scripted, boolean_t literal, size_t nwidth,
+    size_t tagwidth, nvlist_t *nvl)
 {
        int i;
        nvpair_t *nvp = NULL;
@@ -5576,10 +5578,14 @@ print_holds(boolean_t scripted, size_t n
                        size_t sepnum = scripted ? 1 : 2;
 
                        (void) nvpair_value_uint64(nvp2, &val);
-                       time = (time_t)val;
-                       (void) localtime_r(&time, &t);
-                       (void) strftime(tsbuf, DATETIME_BUF_LEN,
-                           gettext(STRFTIME_FMT_STR), &t);
+                       if (literal)
+                               snprintf(tsbuf, DATETIME_BUF_LEN, "%llu", val);
+                       else {
+                               time = (time_t)val;
+                               (void) localtime_r(&time, &t);
+                               (void) strftime(tsbuf, DATETIME_BUF_LEN,
+                                   gettext(STRFTIME_FMT_STR), &t);
+                       }
 
                        (void) printf("%-*s%*c%-*s%*c%s\n", nwidth, zname,
                            sepnum, sep, tagwidth, tagname, sepnum, sep, tsbuf);
@@ -5600,7 +5606,7 @@ holds_callback(zfs_handle_t *zhp, void *
        const char *zname = zfs_get_name(zhp);
        size_t znamelen = strnlen(zname, ZFS_MAXNAMELEN);
 
-       if (cbp->cb_recursive) {
+       if (cbp->cb_recursive && cbp->cb_snapname != NULL) {
                const char *snapname;
                char *delim  = strchr(zname, '@');
                if (delim == NULL)
@@ -5628,9 +5634,12 @@ holds_callback(zfs_handle_t *zhp, void *
 }
 
 /*
- * zfs holds [-r] <snap> ...
+ * zfs holds [-Hp] [-r | -d max] <dataset|snap> ...
  *
- *     -r      Recursively hold
+ *     -H      Suppress header output
+ *     -p      Output literal values
+ *     -r      Recursively search for holds
+ *     -d max  Limit depth of recursive search
  */
 static int
 zfs_do_holds(int argc, char **argv)
@@ -5639,8 +5648,9 @@ zfs_do_holds(int argc, char **argv)
        int c;
        int i;
        boolean_t scripted = B_FALSE;
+       boolean_t literal = B_FALSE;
        boolean_t recursive = B_FALSE;
-       const char *opts = "rH";
+       const char *opts = "d:rHp";
        nvlist_t *nvl;
 
        int types = ZFS_TYPE_SNAPSHOT;
@@ -5653,12 +5663,19 @@ zfs_do_holds(int argc, char **argv)
        /* check options */
        while ((c = getopt(argc, argv, opts)) != -1) {
                switch (c) {
+               case 'd':
+                       limit = parse_depth(optarg, &flags);
+                       recursive = B_TRUE;
+                       break;
                case 'r':
                        recursive = B_TRUE;
                        break;
                case 'H':
                        scripted = B_TRUE;
                        break;
+               case 'p':
+                       literal = B_TRUE;
+                       break;
                case '?':
                        (void) fprintf(stderr, gettext("invalid option '%c'\n"),
                            optopt);
@@ -5684,18 +5701,14 @@ zfs_do_holds(int argc, char **argv)
        for (i = 0; i < argc; ++i) {
                char *snapshot = argv[i];
                const char *delim;
-               const char *snapname;
+               const char *snapname = NULL;
 
                delim = strchr(snapshot, '@');
-               if (delim == NULL) {
-                       (void) fprintf(stderr,
-                           gettext("'%s' is not a snapshot\n"), snapshot);
-                       ++errors;
-                       continue;
+               if (delim != NULL) {
+                       snapname = delim + 1;
+                       if (recursive)
+                               snapshot[delim - snapshot] = '\0';
                }
-               snapname = delim + 1;
-               if (recursive)
-                       snapshot[delim - snapshot] = '\0';
 
                cb.cb_recursive = recursive;
                cb.cb_snapname = snapname;
@@ -5713,7 +5726,8 @@ zfs_do_holds(int argc, char **argv)
        /*
         *  2. print holds data
         */
-       print_holds(scripted, cb.cb_max_namelen, cb.cb_max_taglen, nvl);
+       print_holds(scripted, literal, cb.cb_max_namelen, cb.cb_max_taglen,
+           nvl);
 
        if (nvlist_empty(nvl))
                (void) printf(gettext("no datasets available\n"));
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to