aboutsummaryrefslogtreecommitdiff
path: root/cddl/contrib/opensolaris/lib
diff options
context:
space:
mode:
authorSean Eric Fagan <sef@FreeBSD.org>2019-02-26 19:23:22 +0000
committerSean Eric Fagan <sef@FreeBSD.org>2019-02-26 19:23:22 +0000
commit50792eb553bf2cebaea3ddaea066100ab9e51f2d (patch)
tree964b2f9d6fbea085c41c05f2077a2d2745903a68 /cddl/contrib/opensolaris/lib
parent3843d88ca8cb214593db38aa2d8ab548e3592426 (diff)
downloadsrc-50792eb553bf2cebaea3ddaea066100ab9e51f2d.tar.gz
src-50792eb553bf2cebaea3ddaea066100ab9e51f2d.zip
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
Notes
Notes: svn path=/head/; revision=344601
Diffstat (limited to 'cddl/contrib/opensolaris/lib')
-rw-r--r--cddl/contrib/opensolaris/lib/libzfs/common/libzfs.h3
-rw-r--r--cddl/contrib/opensolaris/lib/libzfs/common/libzfs_sendrecv.c39
2 files changed, 33 insertions, 9 deletions
diff --git a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs.h b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs.h
index 337fd97f8bd3..f75effd338fc 100644
--- a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs.h
+++ b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs.h
@@ -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 *);
diff --git a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_sendrecv.c b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_sendrecv.c
index 9622778bdd0b..3b87c6910b2b 100644
--- a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_sendrecv.c
+++ b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_sendrecv.c
@@ -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 *flags, int outfd,
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 *flags, int outfd,
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 *flags, int outfd,
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, const char *tosnap,
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, const char *tosnap,
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,