mirror of
https://git.FreeBSD.org/src.git
synced 2024-12-11 09:50:12 +00:00
MFZoL: Add -vnP support to 'zfs send' for bookmarks
zfsonlinux/zfs@835db58592 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
This commit is contained in:
parent
840fa0f86d
commit
496ba62c36
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=352447
@ -190,8 +190,8 @@
|
||||
.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
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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 @@ zfs_send(zfs_handle_t *zhp, const char *fromsnap, const char *tosnap,
|
||||
}
|
||||
|
||||
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:
|
||||
|
Loading…
Reference in New Issue
Block a user