Skip to content

Commit

Permalink
Allow for "zfs receive" to skip existing snapshots
Browse files Browse the repository at this point in the history
by adding the option "-s" to zfs receive.

Signed-off-by: Turbo Fredriksson <[email protected]>

Closes: #2666
  • Loading branch information
FransUrbo committed Sep 8, 2015
1 parent 3b36f83 commit e108a79
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 10 deletions.
11 changes: 7 additions & 4 deletions cmd/zfs/zfs_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -247,9 +247,9 @@ get_usage(zfs_help_t idx)
case HELP_PROMOTE:
return (gettext("\tpromote <clone-filesystem>\n"));
case HELP_RECEIVE:
return (gettext("\treceive [-vnFu] <filesystem|volume|"
return (gettext("\treceive [-vnFus] <filesystem|volume|"
"snapshot>\n"
"\treceive [-vnFu] [-d | -e] <filesystem>\n"));
"\treceive [-vnFus] [-d | -e] <filesystem>\n"));
case HELP_RENAME:
return (gettext("\trename [-f] <filesystem|volume|snapshot> "
"<filesystem|volume|snapshot>\n"
Expand Down Expand Up @@ -3856,7 +3856,7 @@ zfs_do_send(int argc, char **argv)
}

/*
* zfs receive [-vnFu] [-d | -e] <fs@snap>
* zfs receive [-vnFus] [-d | -e] <fs@snap>
*
* Restore a backup stream from stdin.
*/
Expand All @@ -3867,8 +3867,11 @@ zfs_do_receive(int argc, char **argv)
recvflags_t flags = { 0 };

/* check options */
while ((c = getopt(argc, argv, ":denuvF")) != -1) {
while ((c = getopt(argc, argv, ":denuvFs")) != -1) {
switch (c) {
case 's':
flags.skip = B_TRUE;
break;
case 'd':
flags.isprefix = B_TRUE;
break;
Expand Down
3 changes: 3 additions & 0 deletions include/libzfs.h
Original file line number Diff line number Diff line change
Expand Up @@ -675,6 +675,9 @@ typedef struct recvflags {

/* do not mount file systems as they are extracted (private) */
boolean_t nomount;

/* skip existing snapshots */
boolean_t skip;
} recvflags_t;

extern int zfs_receive(libzfs_handle_t *, const char *, recvflags_t *,
Expand Down
16 changes: 14 additions & 2 deletions lib/libzfs/libzfs_sendrecv.c
Original file line number Diff line number Diff line change
Expand Up @@ -2874,13 +2874,14 @@ zfs_receive_one(libzfs_handle_t *hdl, int infd, const char *tosnap,
zfs_handle_t *zhp;

/*
* Destination fs exists. Therefore this should either
* Destination fs exists (and we have not been asked to
* skip existing snapshots). Therefore this should either
* be an incremental, or the stream specifies a new fs
* (full stream or clone) and they want us to blow it
* away (and have therefore specified -F and removed any
* snapshots).
*/
if (stream_wantsnewfs) {
if (stream_wantsnewfs && !flags->skip) {
if (!flags->force) {
zcmd_free_nvlists(&zc);
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
Expand Down Expand Up @@ -2968,6 +2969,17 @@ zfs_receive_one(libzfs_handle_t *hdl, int infd, const char *tosnap,
zc.zc_begin_record = drr_noswap->drr_u.drr_begin;
zc.zc_cookie = infd;
zc.zc_guid = flags->force;

if (zfs_dataset_exists(hdl, zc.zc_value, ZFS_TYPE_SNAPSHOT) &&
flags->skip) {
(void) printf("skipping snapshot %s - %s already exists\n",
drrb->drr_toname, zc.zc_value);
(void) fflush(stdout);

zcmd_free_nvlists(&zc);
return (recv_skip(hdl, infd, flags->byteswap));
}

if (flags->verbose) {
(void) printf("%s %s stream of %s into %s\n",
flags->dryrun ? "would receive" : "receiving",
Expand Down
35 changes: 31 additions & 4 deletions man/man8/zfs.8
Original file line number Diff line number Diff line change
Expand Up @@ -184,12 +184,12 @@ zfs \- configures ZFS file systems

.LP
.nf
\fBzfs\fR \fBreceive | recv\fR [\fB-vnFu\fR] \fIfilesystem\fR|\fIvolume\fR|\fIsnapshot\fR
\fBzfs\fR \fBreceive | recv\fR [\fB-vnFus\fR] \fIfilesystem\fR|\fIvolume\fR|\fIsnapshot\fR
.fi

.LP
.nf
\fBzfs\fR \fBreceive | recv\fR [\fB-vnFu\fR] [\fB-d\fR|\fB-e\fR] \fIfilesystem\fR
\fBzfs\fR \fBreceive | recv\fR [\fB-vnFus\fR] [\fB-d\fR|\fB-e\fR] \fIfilesystem\fR
.fi

.LP
Expand Down Expand Up @@ -2934,11 +2934,11 @@ then the receiving system must have that feature enabled as well. See
.ne 2
.mk
.na
\fB\fBzfs receive\fR [\fB-vnFu\fR] \fIfilesystem\fR|\fIvolume\fR|\fIsnapshot\fR\fR
\fB\fBzfs receive\fR [\fB-vnFus\fR] \fIfilesystem\fR|\fIvolume\fR|\fIsnapshot\fR\fR
.ad
.br
.na
\fB\fBzfs receive\fR [\fB-vnFu\fR] [\fB-d\fR|\fB-e\fR] \fIfilesystem\fR\fR
\fB\fBzfs receive\fR [\fB-vnFus\fR] [\fB-d\fR|\fB-e\fR] \fIfilesystem\fR\fR
.ad
.sp .6
.RS 4n
Expand Down Expand Up @@ -3017,6 +3017,33 @@ Do not actually receive the stream. This can be useful in conjunction with the \
Force a rollback of the file system to the most recent snapshot before performing the receive operation. If receiving an incremental replication stream (for example, one generated by \fBzfs send -R -[iI]\fR), destroy snapshots and file systems that do not exist on the sending side.
.RE

.sp
.ne 2
.na
\fB\fB-e\fR\fR
.ad
.sp .6
.RS 4n
Generate a more compact stream by using WRITE_EMBEDDED records for blocks
which are stored more compactly on disk by the \fBembedded_data\fR pool
feature. This flag has no effect if the \fBembedded_data\fR feature is
disabled. The receiving system must have the \fBembedded_data\fR feature
enabled. If the \fBlz4_compress\fR feature is active on the sending system,
then the receiving system must have that feature enabled as well. See
\fBzpool-features\fR(5) for details on ZFS feature flags and the
\fBembedded_data\fR feature.
.RE

.sp
.ne 2
.mk
.na
\fB\fB-s\fR\fR
.ad
.sp .6
.RS 4n
Skip existing snapshots in a stream.
.RE
.RE

.sp
Expand Down

0 comments on commit e108a79

Please sign in to comment.