Mercurial > illumos > illumos-gate
changeset 11668:707c4515580e
6885979 zfs_send -R fails to send snapshots that get renamed during the operation
6926290 zfs_hold_range() should handle fromsnap == NULL
6926291 In zfs_send(), errno can get clobbered before we use it
author | Chris Kirby <Chris.Kirby@sun.com> |
---|---|
date | Wed, 17 Feb 2010 11:41:36 -0700 |
parents | 57af99420adf |
children | 573bcdd6e9c2 |
files | usr/src/lib/libzfs/common/libzfs_dataset.c usr/src/lib/libzfs/common/libzfs_sendrecv.c |
diffstat | 2 files changed, 19 insertions(+), 5 deletions(-) [+] |
line wrap: on
line diff
--- a/usr/src/lib/libzfs/common/libzfs_dataset.c Tue Feb 16 23:03:39 2010 -0800 +++ b/usr/src/lib/libzfs/common/libzfs_dataset.c Wed Feb 17 11:41:36 2010 -0700 @@ -4078,6 +4078,7 @@ 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 @@ arg.tosnap = tosnap; arg.tag = tag; arg.recursive = recursive; + arg.seenfrom = (fromsnap == NULL); return (zfs_iter_snapshots_sorted(zhp, zfs_hold_range_one, &arg)); }
--- a/usr/src/lib/libzfs/common/libzfs_sendrecv.c Tue Feb 16 23:03:39 2010 -0800 +++ b/usr/src/lib/libzfs/common/libzfs_sendrecv.c Wed Feb 17 11:41:36 2010 -0700 @@ -848,7 +848,7 @@ */ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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; } }