.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
.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
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.
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
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
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);
}
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] == '@')) {
/*
(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);
}
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,
}
}
- 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");
}
}
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: