summaryrefslogtreecommitdiff
path: root/usr/src/lib/libzfs
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/lib/libzfs')
-rw-r--r--usr/src/lib/libzfs/common/libzfs_dataset.c2
-rw-r--r--usr/src/lib/libzfs/common/libzfs_sendrecv.c22
2 files changed, 19 insertions, 5 deletions
diff --git a/usr/src/lib/libzfs/common/libzfs_dataset.c b/usr/src/lib/libzfs/common/libzfs_dataset.c
index 0f131a949f..bd63372301 100644
--- a/usr/src/lib/libzfs/common/libzfs_dataset.c
+++ b/usr/src/lib/libzfs/common/libzfs_dataset.c
@@ -4078,6 +4078,7 @@ zfs_hold_range(zfs_handle_t *zhp, const char *fromsnap, const char *tosnap,
arg.temphold = temphold;
arg.holding = B_TRUE;
arg.recursive = recursive;
+ arg.seenfrom = (fromsnap == NULL);
error = zfs_iter_snapshots_sorted(zhp, zfs_hold_range_one, &arg);
@@ -4147,6 +4148,7 @@ zfs_release_range(zfs_handle_t *zhp, const char *fromsnap, const char *tosnap,
arg.tosnap = tosnap;
arg.tag = tag;
arg.recursive = recursive;
+ arg.seenfrom = (fromsnap == NULL);
return (zfs_iter_snapshots_sorted(zhp, zfs_hold_range_one, &arg));
}
diff --git a/usr/src/lib/libzfs/common/libzfs_sendrecv.c b/usr/src/lib/libzfs/common/libzfs_sendrecv.c
index 04d2b540b5..c8d85c8b86 100644
--- a/usr/src/lib/libzfs/common/libzfs_sendrecv.c
+++ b/usr/src/lib/libzfs/common/libzfs_sendrecv.c
@@ -848,7 +848,7 @@ typedef struct send_dump_data {
*/
static int
dump_ioctl(zfs_handle_t *zhp, const char *fromsnap, boolean_t fromorigin,
- int outfd)
+ int outfd, boolean_t enoent_ok, boolean_t *got_enoent)
{
zfs_cmd_t zc = { 0 };
libzfs_handle_t *hdl = zhp->zfs_hdl;
@@ -862,6 +862,8 @@ dump_ioctl(zfs_handle_t *zhp, const char *fromsnap, boolean_t fromorigin,
zc.zc_cookie = outfd;
zc.zc_obj = fromorigin;
+ *got_enoent = B_FALSE;
+
if (ioctl(zhp->zfs_hdl->libzfs_fd, ZFS_IOC_SEND, &zc) != 0) {
char errbuf[1024];
(void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
@@ -875,6 +877,10 @@ dump_ioctl(zfs_handle_t *zhp, const char *fromsnap, boolean_t fromorigin,
return (zfs_error(hdl, EZFS_CROSSTARGET, errbuf));
case ENOENT:
+ if (enoent_ok) {
+ *got_enoent = B_TRUE;
+ return (0);
+ }
if (zfs_dataset_exists(hdl, zc.zc_name,
ZFS_TYPE_SNAPSHOT)) {
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
@@ -911,6 +917,7 @@ dump_snapshot(zfs_handle_t *zhp, void *arg)
send_dump_data_t *sdd = arg;
const char *thissnap;
int err;
+ boolean_t got_enoent;
thissnap = strchr(zhp->zfs_name, '@') + 1;
@@ -956,9 +963,12 @@ dump_snapshot(zfs_handle_t *zhp, void *arg)
err = dump_ioctl(zhp, sdd->prevsnap,
sdd->prevsnap[0] == '\0' && (sdd->fromorigin || sdd->replicate),
- sdd->outfd);
+ sdd->outfd, B_TRUE, &got_enoent);
- (void) strcpy(sdd->prevsnap, thissnap);
+ if (got_enoent)
+ err = 0;
+ else
+ (void) strcpy(sdd->prevsnap, thissnap);
zfs_close(zhp);
return (err);
}
@@ -1038,10 +1048,12 @@ dump_filesystem(zfs_handle_t *zhp, void *arg)
if (sdd->filter_cb == NULL ||
sdd->filter_cb(snapzhp, sdd->filter_cb_arg) ==
B_TRUE) {
+ boolean_t got_enoent;
+
rv = dump_ioctl(snapzhp,
missingfrom ? NULL : sdd->fromsnap,
sdd->fromorigin || missingfrom,
- sdd->outfd);
+ sdd->outfd, B_FALSE, &got_enoent);
}
sdd->seento = B_TRUE;
zfs_close(snapzhp);
@@ -1267,11 +1279,11 @@ zfs_send(zfs_handle_t *zhp, const char *fromsnap, const char *tosnap,
if (err == -1) {
fsavl_destroy(fsavl);
nvlist_free(fss);
+ err = errno;
if (holdsnaps) {
(void) zfs_release_range(zhp, fromsnap,
tosnap, holdtag, flags.replicate);
}
- err = errno;
goto stderr_out;
}
}