]> xenbits.xensource.com Git - freebsd.git/commitdiff
MFZoL: Add -vnP support to 'zfs send' for bookmarks
authoravg <avg@FreeBSD.org>
Tue, 17 Sep 2019 13:58:15 +0000 (13:58 +0000)
committeravg <avg@FreeBSD.org>
Tue, 17 Sep 2019 13:58:15 +0000 (13:58 +0000)
zfsonlinux/zfs@835db58592d7d947e5818eb7281882e2a46073e0

We have long supported estimating a size of an incremental stream from a
snapshot.  We should do the same for bookmarks as well.

Obtained from: ZoL
Author: loli10K <ezomori.nozomu@gmail.com>
MFC after: 3 days

cddl/contrib/opensolaris/cmd/zfs/zfs.8
cddl/contrib/opensolaris/cmd/zfs/zfs_main.c
cddl/contrib/opensolaris/lib/libzfs/common/libzfs.h
cddl/contrib/opensolaris/lib/libzfs/common/libzfs_sendrecv.c

index 53c144d1db0edbaf88731f7df060f8611bf3c10b..84f13273af2232d38f5485abd2e0a57a26f8d69e 100644 (file)
 .Ar snapshot
 .Nm
 .Cm send
-.Op Fl Lce
-.Op Fl i Ar snapshot Ns | Ns bookmark
+.Op Fl LPcenv
+.Op Fl i Ar snapshot Ns | Ns Ar bookmark
 .Ar filesystem Ns | Ns Ar volume Ns | Ns Ar snapshot
 .Nm
 .Cm send
@@ -2766,7 +2766,7 @@ on future versions of
 .It Xo
 .Nm
 .Cm send
-.Op Fl Lce
+.Op Fl LPcenv
 .Op Fl i Ar snapshot Ns | Ns Ar bookmark
 .Ar filesystem Ns | Ns Ar volume Ns | Ns Ar snapshot
 .Xc
@@ -2780,7 +2780,7 @@ stream generated from a filesystem or volume is received, the default snapshot
 name will be
 .Pq --head-- .
 .Bl -tag -width indent
-.It Fl i Ar snapshot Ns | Ns bookmark
+.It Fl i Ar snapshot Ns | Ns Ar bookmark
 Generate an incremental send stream.
 The incremental source must be an earlier
 snapshot in the destination's history.
@@ -2792,6 +2792,23 @@ specified as the last component of the name
 If the incremental target is a clone, the incremental source can
 be the origin snapshot, or an earlier snapshot in the origin's filesystem,
 or the origin's origin, etc.
+.It Fl n, -dryrun
+Do a dry-run
+.Pq Qq No-op
+send.
+Do not generate any actual send data.
+This is useful in conjunction with the
+.Fl v
+or
+.Fl P
+flags to determine what data will be sent.
+In this case, the verbose output will be written to standard output
+.Po contrast with a non-dry-run, where the stream is written to standard output
+and the verbose output goes to standard error
+.Pc .
+.It Fl v, -verbose
+Print verbose information about the stream package generated.
+This information includes a per-second report of how much data has been sent.
 .It Fl L, -large-block
 Generate a stream which may contain blocks larger than 128KB.
 This flag
@@ -2808,6 +2825,8 @@ See
 for details on ZFS feature flags and the
 .Sy large_blocks
 feature.
+.It Fl P, -parsable
+Print machine-parsable verbose information about the stream package generated.
 .It Fl c, -compressed
 Generate a more compact stream by using compressed WRITE records for blocks
 which are compressed on disk and in memory (see the
index 232181a873454f992c925234550e2d414acf88a4..65dd40e33316c5a3e5e56113cf480d7749da4a8f 100644 (file)
@@ -3928,13 +3928,11 @@ zfs_do_send(int argc, char **argv)
        if (strchr(argv[0], '@') == NULL ||
            (fromname && strchr(fromname, '#') != NULL)) {
                char frombuf[ZFS_MAX_DATASET_NAME_LEN];
-               enum lzc_send_flags lzc_flags = 0;
 
                if (flags.replicate || flags.doall || flags.props ||
-                   flags.dedup || flags.dryrun || flags.verbose ||
-                   flags.progress) {
-                       (void) fprintf(stderr,
-                           gettext("Error: "
+                   flags.dedup || (strchr(argv[0], '@') == NULL &&
+                   (flags.dryrun || flags.verbose || flags.progress))) {
+                       (void) fprintf(stderr, gettext("Error: "
                            "Unsupported flag with filesystem or bookmark.\n"));
                        return (1);
                }
@@ -3943,13 +3941,6 @@ zfs_do_send(int argc, char **argv)
                if (zhp == NULL)
                        return (1);
 
-               if (flags.largeblock)
-                       lzc_flags |= LZC_SEND_FLAG_LARGE_BLOCK;
-               if (flags.embed_data)
-                       lzc_flags |= LZC_SEND_FLAG_EMBED_DATA;
-               if (flags.compress)
-                       lzc_flags |= LZC_SEND_FLAG_COMPRESS;
-
                if (fromname != NULL &&
                    (fromname[0] == '#' || fromname[0] == '@')) {
                        /*
@@ -3963,7 +3954,7 @@ zfs_do_send(int argc, char **argv)
                        (void) strlcat(frombuf, fromname, sizeof (frombuf));
                        fromname = frombuf;
                }
-               err = zfs_send_one(zhp, fromname, STDOUT_FILENO, lzc_flags);
+               err = zfs_send_one(zhp, fromname, STDOUT_FILENO, flags);
                zfs_close(zhp);
                return (err != 0);
        }
index f75effd338fc6e1e04099e6814bb9f9e6e8b5fe9..15b1d54e6341d5f5bd2cd1fb79a093551a43984e 100644 (file)
@@ -660,7 +660,7 @@ typedef boolean_t (snapfilter_cb_t)(zfs_handle_t *, void *);
 
 extern int zfs_send(zfs_handle_t *, const char *, const char *,
     sendflags_t *, int, snapfilter_cb_t, void *, nvlist_t **);
-extern int zfs_send_one(zfs_handle_t *, const char *, int, enum lzc_send_flags);
+extern int zfs_send_one(zfs_handle_t *, const char *, int, sendflags_t flags);
 extern int zfs_send_resume(libzfs_handle_t *, sendflags_t *, int outfd,
     const char *);
 extern nvlist_t *zfs_send_resume_token_to_nvlist(libzfs_handle_t *hdl,
index b7e624e4621c9d04dbd843565b59d03b8ab465ee..cf5aedafca7e739f59ec1519d79d1d0e8b359091 100644 (file)
@@ -1190,16 +1190,14 @@ send_print_verbose(FILE *fout, const char *tosnap, const char *fromsnap,
                }
        }
 
-       if (size != 0) {
-               if (parsable) {
-                       (void) fprintf(fout, "\t%llu",
-                           (longlong_t)size);
-               } else {
-                       char buf[16];
-                       zfs_nicenum(size, buf, sizeof (buf));
-                       (void) fprintf(fout, dgettext(TEXT_DOMAIN,
-                           " estimated size is %s"), buf);
-               }
+       if (parsable) {
+               (void) fprintf(fout, "\t%llu",
+                   (longlong_t)size);
+       } else if (size != 0) {
+               char buf[16];
+               zfs_nicenum(size, buf, sizeof (buf));
+               (void) fprintf(fout, dgettext(TEXT_DOMAIN,
+                   " estimated size is %s"), buf);
        }
        (void) fprintf(fout, "\n");
 }
@@ -2037,17 +2035,40 @@ err_out:
 }
 
 int
-zfs_send_one(zfs_handle_t *zhp, const char *from, int fd,
-    enum lzc_send_flags flags)
+zfs_send_one(zfs_handle_t *zhp, const char *from, int fd, sendflags_t flags)
 {
-       int err;
+       int err = 0;
        libzfs_handle_t *hdl = zhp->zfs_hdl;
-
+       enum lzc_send_flags lzc_flags = 0;
+       FILE *fout = (flags.verbose && flags.dryrun) ? stdout : stderr;
        char errbuf[1024];
+
+       if (flags.largeblock)
+               lzc_flags |= LZC_SEND_FLAG_LARGE_BLOCK;
+       if (flags.embed_data)
+               lzc_flags |= LZC_SEND_FLAG_EMBED_DATA;
+       if (flags.compress)
+               lzc_flags |= LZC_SEND_FLAG_COMPRESS;
+
+       if (flags.verbose) {
+               uint64_t size = 0;
+               err = lzc_send_space(zhp->zfs_name, from, lzc_flags, &size);
+               if (err == 0) {
+                       send_print_verbose(fout, zhp->zfs_name, from, size,
+                           flags.parsable);
+               } else {
+                       (void) fprintf(stderr, "Cannot estimate send size: "
+                           "%s\n", strerror(errno));
+               }
+       }
+
+       if (flags.dryrun)
+               return (err);
+
        (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
            "warning: cannot send '%s'"), zhp->zfs_name);
 
-       err = lzc_send(zhp->zfs_name, from, fd, flags);
+       err = lzc_send(zhp->zfs_name, from, fd, lzc_flags);
        if (err != 0) {
                switch (errno) {
                case EXDEV: