--- old/usr/src/lib/libzfs/common/libzfs_sendrecv.c	Wed Dec  2 13:25:01 2015
+++ new/usr/src/lib/libzfs/common/libzfs_sendrecv.c	Wed Dec  2 13:25:01 2015
@@ -24,6 +24,7 @@
  * Copyright (c) 2011, 2015 by Delphix. All rights reserved.
  * Copyright (c) 2012, Joyent, Inc. All rights reserved.
  * Copyright (c) 2013 Steven Hartland. All rights reserved.
+ * Copyright 2015, OmniTI Computer Consulting, Inc. All rights reserved.
  */
 
 #include <assert.h>
@@ -58,7 +59,7 @@
 
 static int zfs_receive_impl(libzfs_handle_t *, const char *, const char *,
     recvflags_t *, int, const char *, nvlist_t *, avl_tree_t *, char **, int,
-    uint64_t *);
+    uint64_t *, const char *);
 static int guid_to_name(libzfs_handle_t *, const char *,
     uint64_t, boolean_t, char *);
 
@@ -2561,6 +2562,7 @@
 	nvlist_t *stream_nv = NULL;
 	avl_tree_t *stream_avl = NULL;
 	char *fromsnap = NULL;
+	char *sendsnap = NULL;
 	char *cp;
 	char tofs[ZFS_MAXNAMELEN];
 	char sendfs[ZFS_MAXNAMELEN];
@@ -2709,8 +2711,15 @@
 	 */
 	(void) strlcpy(sendfs, drr->drr_u.drr_begin.drr_toname,
 	    ZFS_MAXNAMELEN);
-	if ((cp = strchr(sendfs, '@')) != NULL)
+	if ((cp = strchr(sendfs, '@')) != NULL) {
 		*cp = '\0';
+		/*
+		 * Find the "sendsnap", the final snapshot in a replication
+		 * stream, so zfs_receive_one() can set filesystem properties
+		 * ONLY when receiving that final snapshot.
+		 */
+		sendsnap = (cp + 1);
+	}
 
 	/* Finally, receive each contained stream */
 	do {
@@ -2723,7 +2732,7 @@
 		 */
 		error = zfs_receive_impl(hdl, destname, NULL, flags, fd,
 		    sendfs, stream_nv, stream_avl, top_zfs, cleanup_fd,
-		    action_handlep);
+		    action_handlep, sendsnap);
 		if (error == ENODATA) {
 			error = 0;
 			break;
@@ -2887,9 +2896,9 @@
 static int
 zfs_receive_one(libzfs_handle_t *hdl, int infd, const char *tosnap,
     const char *originsnap, recvflags_t *flags, dmu_replay_record_t *drr,
-    dmu_replay_record_t *drr_noswap, const char *sendfs, nvlist_t *stream_nv,
+    dmu_replay_record_t *drr_noswap, const char *sendfs,
     avl_tree_t *stream_avl, char **top_zfs, int cleanup_fd,
-    uint64_t *action_handlep)
+    uint64_t *action_handlep, const char *finalsnap)
 {
 	zfs_cmd_t zc = { 0 };
 	time_t begin_time;
@@ -2905,7 +2914,6 @@
 	prop_changelist_t *clp = NULL;
 	nvlist_t *snapprops_nvlist = NULL;
 	zprop_errflags_t prop_errflags;
-	boolean_t recursive;
 
 	begin_time = time(NULL);
 
@@ -2912,9 +2920,6 @@
 	(void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
 	    "cannot receive"));
 
-	recursive = (nvlist_lookup_boolean(stream_nv, "not_recursive") ==
-	    ENOENT);
-
 	if (stream_avl != NULL) {
 		char *snapname;
 		nvlist_t *fs = fsavl_find(stream_avl, drrb->drr_toguid,
@@ -2921,11 +2926,20 @@
 		    &snapname);
 		nvlist_t *props;
 		int ret;
+		boolean_t is_finalsnap;
 
+		VERIFY(fs != NULL);
 		(void) nvlist_lookup_uint64(fs, "parentfromsnap",
 		    &parent_snapguid);
-		err = nvlist_lookup_nvlist(fs, "props", &props);
-		if (err)
+		/*
+		 * Can safely use strcmp because at least "snapname" has been
+		 * verified.
+		 */
+		is_finalsnap = (strcmp(snapname, finalsnap) == 0);
+
+		if (is_finalsnap)
+			err = nvlist_lookup_nvlist(fs, "props", &props);
+		if (!is_finalsnap || err)
 			VERIFY(0 == nvlist_alloc(&props, NV_UNIQUE_NAME, 0));
 
 		if (flags->canmountoff) {
@@ -2933,7 +2947,7 @@
 			    zfs_prop_to_name(ZFS_PROP_CANMOUNT), 0));
 		}
 		ret = zcmd_write_src_nvlist(hdl, &zc, props);
-		if (err)
+		if (!is_finalsnap || err)
 			nvlist_free(props);
 
 		if (0 == nvlist_lookup_nvlist(fs, "snapprops", &props)) {
@@ -3004,7 +3018,7 @@
 		chopprefix = drrb->drr_toname + strlen(sendfs);
 	} else {
 		/* A snapshot was specified as an exact path (no -d or -e). */
-		if (recursive) {
+		if (flags->recursive) {
 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
 			    "cannot specify snapshot name for multi-snapshot "
 			    "stream"));
@@ -3448,7 +3462,7 @@
 zfs_receive_impl(libzfs_handle_t *hdl, const char *tosnap,
     const char *originsnap, recvflags_t *flags, int infd, const char *sendfs,
     nvlist_t *stream_nv, avl_tree_t *stream_avl, char **top_zfs, int cleanup_fd,
-    uint64_t *action_handlep)
+    uint64_t *action_handlep, const char *finalsnap)
 {
 	int err;
 	dmu_replay_record_t drr, drr_noswap;
@@ -3544,10 +3558,17 @@
 			if ((cp = strchr(nonpackage_sendfs, '@')) != NULL)
 				*cp = '\0';
 			sendfs = nonpackage_sendfs;
+			VERIFY(finalsnap == NULL);
 		}
-		return (zfs_receive_one(hdl, infd, tosnap, originsnap, flags,
-		    &drr, &drr_noswap, sendfs, stream_nv, stream_avl, top_zfs,
-		    cleanup_fd, action_handlep));
+		flags->recursive =
+		    (nvlist_lookup_boolean(stream_nv, "not_recursive") ==
+		    ENOENT);
+		err = zfs_receive_one(hdl, infd, tosnap, originsnap, flags,
+		    &drr, &drr_noswap, sendfs, stream_avl, top_zfs,
+		    cleanup_fd, action_handlep, finalsnap);
+		/* Clear out internal-only flags. */
+		flags->recursive = B_FALSE;
+		return (err);
 	} else {
 		assert(DMU_GET_STREAM_HDRTYPE(drrb->drr_versioninfo) ==
 		    DMU_COMPOUNDSTREAM);
@@ -3582,7 +3603,7 @@
 	VERIFY(cleanup_fd >= 0);
 
 	err = zfs_receive_impl(hdl, tosnap, originsnap, flags, infd, NULL, NULL,
-	    stream_avl, &top_zfs, cleanup_fd, &action_handle);
+	    stream_avl, &top_zfs, cleanup_fd, &action_handle, NULL);
 
 	VERIFY(0 == close(cleanup_fd));
 
