svn commit: r251417 - stable/9/cddl/contrib/opensolaris/lib/libzfs/common
Steven Hartland
smh at FreeBSD.org
Wed Jun 5 11:55:35 UTC 2013
Author: smh
Date: Wed Jun 5 11:55:35 2013
New Revision: 251417
URL: http://svnweb.freebsd.org/changeset/base/251417
Log:
MFC r244194:
Fix zfs receive errors caused by snapshot replication being processed in
random order.
PR: kern/172259
Modified:
stable/9/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_sendrecv.c
Directory Properties:
stable/9/cddl/contrib/opensolaris/ (props changed)
stable/9/cddl/contrib/opensolaris/lib/libzfs/ (props changed)
Modified: stable/9/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_sendrecv.c
==============================================================================
--- stable/9/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_sendrecv.c Wed Jun 5 11:46:43 2013 (r251416)
+++ stable/9/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_sendrecv.c Wed Jun 5 11:55:35 2013 (r251417)
@@ -731,7 +731,7 @@ send_iterate_fs(zfs_handle_t *zhp, void
sd->parent_fromsnap_guid = 0;
VERIFY(0 == nvlist_alloc(&sd->parent_snaps, NV_UNIQUE_NAME, 0));
VERIFY(0 == nvlist_alloc(&sd->snapprops, NV_UNIQUE_NAME, 0));
- (void) zfs_iter_snapshots(zhp, B_FALSE, send_iterate_snap, sd);
+ (void) zfs_iter_snapshots_sorted(zhp, send_iterate_snap, sd);
VERIFY(0 == nvlist_add_nvlist(nvfs, "snaps", sd->parent_snaps));
VERIFY(0 == nvlist_add_nvlist(nvfs, "snapprops", sd->snapprops));
nvlist_free(sd->parent_snaps);
@@ -1946,11 +1946,12 @@ recv_incremental_replication(libzfs_hand
recvflags_t *flags, nvlist_t *stream_nv, avl_tree_t *stream_avl,
nvlist_t *renamed)
{
- nvlist_t *local_nv;
+ nvlist_t *local_nv, *deleted = NULL;
avl_tree_t *local_avl;
nvpair_t *fselem, *nextfselem;
char *fromsnap;
char newname[ZFS_MAXNAMELEN];
+ char guidname[32];
int error;
boolean_t needagain, progress, recursive;
char *s1, *s2;
@@ -1966,6 +1967,8 @@ recv_incremental_replication(libzfs_hand
again:
needagain = progress = B_FALSE;
+ VERIFY(0 == nvlist_alloc(&deleted, NV_UNIQUE_NAME, 0));
+
if ((error = gather_nvlist(hdl, tofs, fromsnap, NULL,
recursive, &local_nv, &local_avl)) != 0)
return (error);
@@ -2080,6 +2083,8 @@ again:
needagain = B_TRUE;
else
progress = B_TRUE;
+ sprintf(guidname, "%lu", thisguid);
+ nvlist_add_boolean(deleted, guidname);
continue;
}
@@ -2135,6 +2140,8 @@ again:
needagain = B_TRUE;
else
progress = B_TRUE;
+ sprintf(guidname, "%lu", parent_fromsnap_guid);
+ nvlist_add_boolean(deleted, guidname);
continue;
}
@@ -2157,6 +2164,24 @@ again:
s2 = strrchr(stream_fsname, '/');
/*
+ * Check if we're going to rename based on parent guid change
+ * and the current parent guid was also deleted. If it was then
+ * rename will fail and is likely unneeded, so avoid this and
+ * force an early retry to determine the new
+ * parent_fromsnap_guid.
+ */
+ if (stream_parent_fromsnap_guid != 0 &&
+ parent_fromsnap_guid != 0 &&
+ stream_parent_fromsnap_guid != parent_fromsnap_guid) {
+ sprintf(guidname, "%lu", parent_fromsnap_guid);
+ if (nvlist_exists(deleted, guidname)) {
+ progress = B_TRUE;
+ needagain = B_TRUE;
+ goto doagain;
+ }
+ }
+
+ /*
* Check for rename. If the exact receive path is specified, it
* does not count as a rename, but we still need to check the
* datasets beneath it.
@@ -2210,8 +2235,10 @@ again:
}
}
+doagain:
fsavl_destroy(local_avl);
nvlist_free(local_nv);
+ nvlist_free(deleted);
if (needagain && progress) {
/* do another pass to fix up temporary names */
More information about the svn-src-stable-9
mailing list