Author: sef
Date: Tue Feb 26 19:23:22 2019
New Revision: 344601
URL: https://svnweb.freebsd.org/changeset/base/344601

Log:
  Set process title during zfs send.
  
  This adds a '-V' option to 'zfs send', which sets the process title once a
  second to the progress information.
  
  This code has been in FreeNAS for a long time now; this is just upstreaming
  it here.  It was originially written by delphij.
  
  Reviewed by:  mav
  Obtained from:        iXsystems, Inc
  Sponsored by: iXsystems, Inc
  Differential Revision:        https://reviews.freebsd.org/D19184

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

Modified: head/cddl/contrib/opensolaris/cmd/zfs/zfs.8
==============================================================================
--- head/cddl/contrib/opensolaris/cmd/zfs/zfs.8 Tue Feb 26 18:30:51 2019        
(r344600)
+++ head/cddl/contrib/opensolaris/cmd/zfs/zfs.8 Tue Feb 26 19:23:22 2019        
(r344601)
@@ -32,7 +32,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd August 11, 2018
+.Dd February 15, 2018
 .Dt ZFS 8
 .Os
 .Sh NAME
@@ -184,7 +184,7 @@
 .Ar bookmark
 .Nm
 .Cm send
-.Op Fl DLPRcenpv
+.Op Fl DLPRVcenpv
 .Op Fl i Ar snapshot | Fl I Ar snapshot
 .Ar snapshot
 .Nm
@@ -194,7 +194,7 @@
 .Ar filesystem Ns | Ns Ar volume Ns | Ns Ar snapshot
 .Nm
 .Cm send
-.Op Fl Penv
+.Op Fl PVenv
 .Fl t Ar receive_resume_token
 .Nm
 .Cm receive Ns | Ns Cm recv
@@ -2607,7 +2607,7 @@ feature.
 .It Xo
 .Nm
 .Cm send
-.Op Fl DLPRcenpv
+.Op Fl DLPRVcenpv
 .Op Fl i Ar snapshot | Fl I Ar snapshot
 .Ar snapshot
 .Xc
@@ -2753,6 +2753,8 @@ Print machine-parsable verbose information about the s
 .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 V
+Set the process title to a per-second report of how much data has been sent.
 .El
 .Pp
 The format of the stream is committed. You will be able to receive your streams

Modified: head/cddl/contrib/opensolaris/cmd/zfs/zfs_main.c
==============================================================================
--- head/cddl/contrib/opensolaris/cmd/zfs/zfs_main.c    Tue Feb 26 18:30:51 
2019        (r344600)
+++ head/cddl/contrib/opensolaris/cmd/zfs/zfs_main.c    Tue Feb 26 19:23:22 
2019        (r344601)
@@ -3813,7 +3813,7 @@ zfs_do_send(int argc, char **argv)
        };
 
        /* check options */
-       while ((c = getopt_long(argc, argv, ":i:I:RbDpvnPLet:c", long_options,
+       while ((c = getopt_long(argc, argv, ":i:I:RbDpVvnPLet:c", long_options,
            NULL)) != -1) {
                switch (c) {
                case 'i':
@@ -3836,6 +3836,10 @@ zfs_do_send(int argc, char **argv)
                case 'P':
                        flags.parsable = B_TRUE;
                        flags.verbose = B_TRUE;
+                       break;
+               case 'V':
+                       flags.progress = B_TRUE;
+                       flags.progressastitle = B_TRUE;
                        break;
                case 'v':
                        if (flags.verbose)

Modified: head/cddl/contrib/opensolaris/lib/libzfs/common/libzfs.h
==============================================================================
--- head/cddl/contrib/opensolaris/lib/libzfs/common/libzfs.h    Tue Feb 26 
18:30:51 2019        (r344600)
+++ head/cddl/contrib/opensolaris/lib/libzfs/common/libzfs.h    Tue Feb 26 
19:23:22 2019        (r344601)
@@ -651,6 +651,9 @@ typedef struct sendflags {
 
        /* compressed WRITE records are permitted */
        boolean_t compress;
+
+       /* show progress as process title(ie. -V) */
+       boolean_t progressastitle;
 } sendflags_t;
 
 typedef boolean_t (snapfilter_cb_t)(zfs_handle_t *, void *);

Modified: head/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_sendrecv.c
==============================================================================
--- head/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_sendrecv.c   Tue Feb 
26 18:30:51 2019        (r344600)
+++ head/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_sendrecv.c   Tue Feb 
26 19:23:22 2019        (r344601)
@@ -85,6 +85,8 @@ typedef struct progress_arg {
        zfs_handle_t *pa_zhp;
        int pa_fd;
        boolean_t pa_parsable;
+       boolean_t pa_astitle;
+       uint64_t pa_size;
 } progress_arg_t;
 
 typedef struct dataref {
@@ -930,6 +932,7 @@ typedef struct send_dump_data {
        uint64_t prevsnap_obj;
        boolean_t seenfrom, seento, replicate, doall, fromorigin;
        boolean_t verbose, dryrun, parsable, progress, embed_data, std_out;
+       boolean_t progressastitle;
        boolean_t large_block, compress;
        int outfd;
        boolean_t err;
@@ -1110,14 +1113,14 @@ send_progress_thread(void *arg)
        zfs_cmd_t zc = { 0 };
        zfs_handle_t *zhp = pa->pa_zhp;
        libzfs_handle_t *hdl = zhp->zfs_hdl;
-       unsigned long long bytes;
+       unsigned long long bytes, total;
        char buf[16];
        time_t t;
        struct tm *tm;
 
        (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
 
-       if (!pa->pa_parsable)
+       if (!pa->pa_parsable && !pa->pa_astitle)
                (void) fprintf(stderr, "TIME        SENT   SNAPSHOT\n");
 
        /*
@@ -1134,7 +1137,16 @@ send_progress_thread(void *arg)
                tm = localtime(&t);
                bytes = zc.zc_cookie;
 
-               if (pa->pa_parsable) {
+               if (pa->pa_astitle) {
+                       int pct;
+                       if (pa->pa_size > bytes)
+                               pct = 100 * bytes / pa->pa_size;
+                       else
+                               pct = 100;
+
+                       setproctitle("sending %s (%d%%: %llu/%llu)",
+                           zhp->zfs_name, pct, bytes, pa->pa_size);
+               } else if (pa->pa_parsable) {
                        (void) fprintf(stderr, "%02d:%02d:%02d\t%llu\t%s\n",
                            tm->tm_hour, tm->tm_min, tm->tm_sec,
                            bytes, zhp->zfs_name);
@@ -1204,6 +1216,7 @@ dump_snapshot(zfs_handle_t *zhp, void *arg)
        boolean_t isfromsnap, istosnap, fromorigin;
        boolean_t exclude = B_FALSE;
        FILE *fout = sdd->std_out ? stdout : stderr;
+       uint64_t size = 0;
 
        err = 0;
        thissnap = strchr(zhp->zfs_name, '@') + 1;
@@ -1278,15 +1291,16 @@ dump_snapshot(zfs_handle_t *zhp, void *arg)
        fromorigin = sdd->prevsnap[0] == '\0' &&
            (sdd->fromorigin || sdd->replicate);
 
-       if (sdd->verbose) {
-               uint64_t size = 0;
+       if (sdd->progress && sdd->dryrun) {
                (void) estimate_ioctl(zhp, sdd->prevsnap_obj,
                    fromorigin, flags, &size);
+               sdd->size += size;
+       }
 
+       if (sdd->verbose) {
                send_print_verbose(fout, zhp->zfs_name,
                    sdd->prevsnap[0] ? sdd->prevsnap : NULL,
                    size, sdd->parsable);
-               sdd->size += size;
        }
 
        if (!sdd->dryrun) {
@@ -1298,6 +1312,8 @@ dump_snapshot(zfs_handle_t *zhp, void *arg)
                        pa.pa_zhp = zhp;
                        pa.pa_fd = sdd->outfd;
                        pa.pa_parsable = sdd->parsable;
+                       pa.pa_size = sdd->size;
+                       pa.pa_astitle = sdd->progressastitle;
 
                        if ((err = pthread_create(&tid, NULL,
                            send_progress_thread, &pa)) != 0) {
@@ -1580,6 +1596,7 @@ zfs_send_resume(libzfs_handle_t *hdl, sendflags_t *fla
        int error = 0;
        char name[ZFS_MAX_DATASET_NAME_LEN];
        enum lzc_send_flags lzc_flags = 0;
+       uint64_t size = 0;
        FILE *fout = (flags->verbose && flags->dryrun) ? stdout : stderr;
 
        (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
@@ -1648,12 +1665,13 @@ zfs_send_resume(libzfs_handle_t *hdl, sendflags_t *fla
                fromname = name;
        }
 
-       if (flags->verbose) {
-               uint64_t size = 0;
+       if (flags->progress) {
                error = lzc_send_space(zhp->zfs_name, fromname,
                    lzc_flags, &size);
                if (error == 0)
                        size = MAX(0, (int64_t)(size - bytes));
+       }
+       if (flags->verbose) {
                send_print_verbose(fout, zhp->zfs_name, fromname,
                    size, flags->parsable);
        }
@@ -1669,6 +1687,8 @@ zfs_send_resume(libzfs_handle_t *hdl, sendflags_t *fla
                        pa.pa_zhp = zhp;
                        pa.pa_fd = outfd;
                        pa.pa_parsable = flags->parsable;
+                       pa.pa_size = size;
+                       pa.pa_astitle = flags->progressastitle;
 
                        error = pthread_create(&tid, NULL,
                            send_progress_thread, &pa);
@@ -1878,6 +1898,7 @@ zfs_send(zfs_handle_t *zhp, const char *fromsnap, cons
        sdd.verbose = flags->verbose;
        sdd.parsable = flags->parsable;
        sdd.progress = flags->progress;
+       sdd.progressastitle = flags->progressastitle;
        sdd.dryrun = flags->dryrun;
        sdd.large_block = flags->largeblock;
        sdd.embed_data = flags->embed_data;
@@ -1914,7 +1935,7 @@ zfs_send(zfs_handle_t *zhp, const char *fromsnap, cons
                sdd.cleanup_fd = -1;
                sdd.snapholds = NULL;
        }
-       if (flags->verbose || sdd.snapholds != NULL) {
+       if (flags->progress || sdd.snapholds != NULL) {
                /*
                 * Do a verbose no-op dry run to get all the verbose output
                 * or to gather snapshot hold's before generating any data,
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to