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
This commit is contained in:
parent
3843d88ca8
commit
50792eb553
@ -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 stream package generated.
|
||||
.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
|
||||
|
@ -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':
|
||||
@ -3837,6 +3837,10 @@ zfs_do_send(int argc, char **argv)
|
||||
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)
|
||||
extraverbose = B_TRUE;
|
||||
|
@ -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 *);
|
||||
|
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user