/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License (the "License").
 * You may not use this file except in compliance with the License.
 *
 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
 * or http://www.opensolaris.org/os/licensing.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
 * If applicable, add the following below this CDDL HEADER, with the
 * fields enclosed by brackets "[]" replaced with your own identifying
 * information: Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 */

/*
 * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
 * Copyright (c) 2011, 2015 by Delphix. All rights reserved.
 * Copyright (c) 2012, Joyent, Inc. All rights reserved.
 * Copyright (c) 2012 Pawel Jakub Dawidek <pawel@dawidek.net>.
 * All rights reserved
 * Copyright (c) 2013 Steven Hartland. All rights reserved.
 * Copyright 2015, OmniTI Computer Consulting, Inc. All rights reserved.
 * Copyright 2016 Igor Kozhukhov <ikozhukhov@gmail.com>
 * Copyright (c) 2018, loli10K <ezomori.nozomu@gmail.com>. All rights reserved.
 * Copyright (c) 2019 Datto Inc.
 */

#include <assert.h>
#include <ctype.h>
#include <errno.h>
#include <libintl.h>
#include <stdio.h>
#include <stdlib.h>
#include <strings.h>
#include <unistd.h>
#include <stddef.h>
#include <fcntl.h>
#include <sys/mount.h>
#include <sys/mntent.h>
#include <sys/mnttab.h>
#include <sys/avl.h>
#include <sys/debug.h>
#include <sys/stat.h>
#include <stddef.h>
#include <pthread.h>
#include <umem.h>
#include <time.h>

#include <libzfs.h>
#include <libzfs_core.h>
#include <libzutil.h>

#include "zfs_namecheck.h"
#include "zfs_prop.h"
#include "zfs_fletcher.h"
#include "libzfs_impl.h"
#include <zlib.h>
#include <sys/zio_checksum.h>
#include <sys/dsl_crypt.h>
#include <sys/ddt.h>
#include <sys/socket.h>
#include <sys/sha2.h>

/* in libzfs_dataset.c */
extern void zfs_setprop_error(libzfs_handle_t *, zfs_prop_t, int, char *);

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 *, const char *, nvlist_t *);
static int guid_to_name(libzfs_handle_t *, const char *,
    uint64_t, boolean_t, char *);

static const zio_cksum_t zero_cksum = { { 0 } };

typedef struct dedup_arg {
	int	inputfd;
	int	outputfd;
	libzfs_handle_t  *dedup_hdl;
} dedup_arg_t;

typedef struct progress_arg {
	zfs_handle_t *pa_zhp;
	int pa_fd;
	boolean_t pa_parsable;
} progress_arg_t;

typedef struct dataref {
	uint64_t ref_guid;
	uint64_t ref_object;
	uint64_t ref_offset;
} dataref_t;

typedef struct dedup_entry {
	struct dedup_entry	*dde_next;
	zio_cksum_t dde_chksum;
	uint64_t dde_prop;
	dataref_t dde_ref;
} dedup_entry_t;

#define	MAX_DDT_PHYSMEM_PERCENT		20
#define	SMALLEST_POSSIBLE_MAX_DDT_MB		128

typedef struct dedup_table {
	dedup_entry_t	**dedup_hash_array;
	umem_cache_t	*ddecache;
	uint64_t	max_ddt_size;  /* max dedup table size in bytes */
	uint64_t	cur_ddt_size;  /* current dedup table size in bytes */
	uint64_t	ddt_count;
	int		numhashbits;
	boolean_t	ddt_full;
} dedup_table_t;

static int
high_order_bit(uint64_t n)
{
	int count;

	for (count = 0; n != 0; count++)
		n >>= 1;
	return (count);
}

static size_t
ssread(void *buf, size_t len, FILE *stream)
{
	size_t outlen;

	if ((outlen = fread(buf, len, 1, stream)) == 0)
		return (0);

	return (outlen);
}

static void
ddt_hash_append(libzfs_handle_t *hdl, dedup_table_t *ddt, dedup_entry_t **ddepp,
    zio_cksum_t *cs, uint64_t prop, dataref_t *dr)
{
	dedup_entry_t	*dde;

	if (ddt->cur_ddt_size >= ddt->max_ddt_size) {
		if (ddt->ddt_full == B_FALSE) {
			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
			    "Dedup table full.  Deduplication will continue "
			    "with existing table entries"));
			ddt->ddt_full = B_TRUE;
		}
		return;
	}

	if ((dde = umem_cache_alloc(ddt->ddecache, UMEM_DEFAULT))
	    != NULL) {
		assert(*ddepp == NULL);
		dde->dde_next = NULL;
		dde->dde_chksum = *cs;
		dde->dde_prop = prop;
		dde->dde_ref = *dr;
		*ddepp = dde;
		ddt->cur_ddt_size += sizeof (dedup_entry_t);
		ddt->ddt_count++;
	}
}

/*
 * Using the specified dedup table, do a lookup for an entry with
 * the checksum cs.  If found, return the block's reference info
 * in *dr. Otherwise, insert a new entry in the dedup table, using
 * the reference information specified by *dr.
 *
 * return value:  true - entry was found
 *		  false - entry was not found
 */
static boolean_t
ddt_update(libzfs_handle_t *hdl, dedup_table_t *ddt, zio_cksum_t *cs,
    uint64_t prop, dataref_t *dr)
{
	uint32_t hashcode;
	dedup_entry_t **ddepp;

	hashcode = BF64_GET(cs->zc_word[0], 0, ddt->numhashbits);

	for (ddepp = &(ddt->dedup_hash_array[hashcode]); *ddepp != NULL;
	    ddepp = &((*ddepp)->dde_next)) {
		if (ZIO_CHECKSUM_EQUAL(((*ddepp)->dde_chksum), *cs) &&
		    (*ddepp)->dde_prop == prop) {
			*dr = (*ddepp)->dde_ref;
			return (B_TRUE);
		}
	}
	ddt_hash_append(hdl, ddt, ddepp, cs, prop, dr);
	return (B_FALSE);
}

static int
dump_record(dmu_replay_record_t *drr, void *payload, int payload_len,
    zio_cksum_t *zc, int outfd)
{
	ASSERT3U(offsetof(dmu_replay_record_t, drr_u.drr_checksum.drr_checksum),
	    ==, sizeof (dmu_replay_record_t) - sizeof (zio_cksum_t));
	fletcher_4_incremental_native(drr,
	    offsetof(dmu_replay_record_t, drr_u.drr_checksum.drr_checksum), zc);
	if (drr->drr_type != DRR_BEGIN) {
		ASSERT(ZIO_CHECKSUM_IS_ZERO(&drr->drr_u.
		    drr_checksum.drr_checksum));
		drr->drr_u.drr_checksum.drr_checksum = *zc;
	}
	fletcher_4_incremental_native(&drr->drr_u.drr_checksum.drr_checksum,
	    sizeof (zio_cksum_t), zc);
	if (write(outfd, drr, sizeof (*drr)) == -1)
		return (errno);
	if (payload_len != 0) {
		fletcher_4_incremental_native(payload, payload_len, zc);
		if (write(outfd, payload, payload_len) == -1)
			return (errno);
	}
	return (0);
}

/*
 * This function is started in a separate thread when the dedup option
 * has been requested.  The main send thread determines the list of
 * snapshots to be included in the send stream and makes the ioctl calls
 * for each one.  But instead of having the ioctl send the output to the
 * the output fd specified by the caller of zfs_send()), the
 * ioctl is told to direct the output to a pipe, which is read by the
 * alternate thread running THIS function.  This function does the
 * dedup'ing by:
 *  1. building a dedup table (the DDT)
 *  2. doing checksums on each data block and inserting a record in the DDT
 *  3. looking for matching checksums, and
 *  4.  sending a DRR_WRITE_BYREF record instead of a write record whenever
 *      a duplicate block is found.
 * The output of this function then goes to the output fd requested
 * by the caller of zfs_send().
 */
static void *
cksummer(void *arg)
{
	dedup_arg_t *dda = arg;
	char *buf = zfs_alloc(dda->dedup_hdl, SPA_MAXBLOCKSIZE);
	dmu_replay_record_t thedrr = { 0 };
	dmu_replay_record_t *drr = &thedrr;
	FILE *ofp;
	int outfd;
	dedup_table_t ddt;
	zio_cksum_t stream_cksum;
	uint64_t numbuckets;

#ifdef _ILP32
	ddt.max_ddt_size = SMALLEST_POSSIBLE_MAX_DDT_MB << 20;
#else
	uint64_t physmem = sysconf(_SC_PHYS_PAGES) * sysconf(_SC_PAGESIZE);
	ddt.max_ddt_size =
	    MAX((physmem * MAX_DDT_PHYSMEM_PERCENT) / 100,
	    SMALLEST_POSSIBLE_MAX_DDT_MB << 20);
#endif

	numbuckets = ddt.max_ddt_size / (sizeof (dedup_entry_t));

	/*
	 * numbuckets must be a power of 2.  Increase number to
	 * a power of 2 if necessary.
	 */
	if (!ISP2(numbuckets))
		numbuckets = 1ULL << high_order_bit(numbuckets);

	ddt.dedup_hash_array = calloc(numbuckets, sizeof (dedup_entry_t *));
	ddt.ddecache = umem_cache_create("dde", sizeof (dedup_entry_t), 0,
	    NULL, NULL, NULL, NULL, NULL, 0);
	ddt.cur_ddt_size = numbuckets * sizeof (dedup_entry_t *);
	ddt.numhashbits = high_order_bit(numbuckets) - 1;
	ddt.ddt_full = B_FALSE;

	outfd = dda->outputfd;
	ofp = fdopen(dda->inputfd, "r");
	while (ssread(drr, sizeof (*drr), ofp) != 0) {

		/*
		 * kernel filled in checksum, we are going to write same
		 * record, but need to regenerate checksum.
		 */
		if (drr->drr_type != DRR_BEGIN) {
			bzero(&drr->drr_u.drr_checksum.drr_checksum,
			    sizeof (drr->drr_u.drr_checksum.drr_checksum));
		}

		switch (drr->drr_type) {
		case DRR_BEGIN:
		{
			struct drr_begin *drrb = &drr->drr_u.drr_begin;
			int fflags;
			int sz = 0;
			ZIO_SET_CHECKSUM(&stream_cksum, 0, 0, 0, 0);

			ASSERT3U(drrb->drr_magic, ==, DMU_BACKUP_MAGIC);

			/* set the DEDUP feature flag for this stream */
			fflags = DMU_GET_FEATUREFLAGS(drrb->drr_versioninfo);
			fflags |= (DMU_BACKUP_FEATURE_DEDUP |
			    DMU_BACKUP_FEATURE_DEDUPPROPS);
			DMU_SET_FEATUREFLAGS(drrb->drr_versioninfo, fflags);

			if (drr->drr_payloadlen != 0) {
				sz = drr->drr_payloadlen;

				if (sz > SPA_MAXBLOCKSIZE) {
					buf = zfs_realloc(dda->dedup_hdl, buf,
					    SPA_MAXBLOCKSIZE, sz);
				}
				(void) ssread(buf, sz, ofp);
				if (ferror(stdin))
					perror("fread");
			}
			if (dump_record(drr, buf, sz, &stream_cksum,
			    outfd) != 0)
				goto out;
			break;
		}

		case DRR_END:
		{
			struct drr_end *drre = &drr->drr_u.drr_end;
			/* use the recalculated checksum */
			drre->drr_checksum = stream_cksum;
			if (dump_record(drr, NULL, 0, &stream_cksum,
			    outfd) != 0)
				goto out;
			break;
		}

		case DRR_OBJECT:
		{
			struct drr_object *drro = &drr->drr_u.drr_object;
			if (drro->drr_bonuslen > 0) {
				(void) ssread(buf,
				    DRR_OBJECT_PAYLOAD_SIZE(drro), ofp);
			}
			if (dump_record(drr, buf, DRR_OBJECT_PAYLOAD_SIZE(drro),
			    &stream_cksum, outfd) != 0)
				goto out;
			break;
		}

		case DRR_SPILL:
		{
			struct drr_spill *drrs = &drr->drr_u.drr_spill;
			(void) ssread(buf, DRR_SPILL_PAYLOAD_SIZE(drrs), ofp);
			if (dump_record(drr, buf, DRR_SPILL_PAYLOAD_SIZE(drrs),
			    &stream_cksum, outfd) != 0)
				goto out;
			break;
		}

		case DRR_FREEOBJECTS:
		{
			if (dump_record(drr, NULL, 0, &stream_cksum,
			    outfd) != 0)
				goto out;
			break;
		}

		case DRR_WRITE:
		{
			struct drr_write *drrw = &drr->drr_u.drr_write;
			dataref_t	dataref;
			uint64_t	payload_size;

			payload_size = DRR_WRITE_PAYLOAD_SIZE(drrw);
			(void) ssread(buf, payload_size, ofp);

			/*
			 * Use the existing checksum if it's dedup-capable,
			 * else calculate a SHA256 checksum for it.
			 */

			if (ZIO_CHECKSUM_EQUAL(drrw->drr_key.ddk_cksum,
			    zero_cksum) ||
			    !DRR_IS_DEDUP_CAPABLE(drrw->drr_flags)) {
				SHA2_CTX ctx;
				zio_cksum_t tmpsha256;

				SHA2Init(SHA256, &ctx);
				SHA2Update(&ctx, buf, payload_size);
				SHA2Final(&tmpsha256, &ctx);

				drrw->drr_key.ddk_cksum.zc_word[0] =
				    BE_64(tmpsha256.zc_word[0]);
				drrw->drr_key.ddk_cksum.zc_word[1] =
				    BE_64(tmpsha256.zc_word[1]);
				drrw->drr_key.ddk_cksum.zc_word[2] =
				    BE_64(tmpsha256.zc_word[2]);
				drrw->drr_key.ddk_cksum.zc_word[3] =
				    BE_64(tmpsha256.zc_word[3]);
				drrw->drr_checksumtype = ZIO_CHECKSUM_SHA256;
				drrw->drr_flags |= DRR_CHECKSUM_DEDUP;
			}

			dataref.ref_guid = drrw->drr_toguid;
			dataref.ref_object = drrw->drr_object;
			dataref.ref_offset = drrw->drr_offset;

			if (ddt_update(dda->dedup_hdl, &ddt,
			    &drrw->drr_key.ddk_cksum, drrw->drr_key.ddk_prop,
			    &dataref)) {
				dmu_replay_record_t wbr_drr = {0};
				struct drr_write_byref *wbr_drrr =
				    &wbr_drr.drr_u.drr_write_byref;

				/* block already present in stream */
				wbr_drr.drr_type = DRR_WRITE_BYREF;

				wbr_drrr->drr_object = drrw->drr_object;
				wbr_drrr->drr_offset = drrw->drr_offset;
				wbr_drrr->drr_length = drrw->drr_logical_size;
				wbr_drrr->drr_toguid = drrw->drr_toguid;
				wbr_drrr->drr_refguid = dataref.ref_guid;
				wbr_drrr->drr_refobject =
				    dataref.ref_object;
				wbr_drrr->drr_refoffset =
				    dataref.ref_offset;

				wbr_drrr->drr_checksumtype =
				    drrw->drr_checksumtype;
				wbr_drrr->drr_flags = drrw->drr_flags;
				wbr_drrr->drr_key.ddk_cksum =
				    drrw->drr_key.ddk_cksum;
				wbr_drrr->drr_key.ddk_prop =
				    drrw->drr_key.ddk_prop;

				if (dump_record(&wbr_drr, NULL, 0,
				    &stream_cksum, outfd) != 0)
					goto out;
			} else {
				/* block not previously seen */
				if (dump_record(drr, buf, payload_size,
				    &stream_cksum, outfd) != 0)
					goto out;
			}
			break;
		}

		case DRR_WRITE_EMBEDDED:
		{
			struct drr_write_embedded *drrwe =
			    &drr->drr_u.drr_write_embedded;
			(void) ssread(buf,
			    P2ROUNDUP((uint64_t)drrwe->drr_psize, 8), ofp);
			if (dump_record(drr, buf,
			    P2ROUNDUP((uint64_t)drrwe->drr_psize, 8),
			    &stream_cksum, outfd) != 0)
				goto out;
			break;
		}

		case DRR_FREE:
		{
			if (dump_record(drr, NULL, 0, &stream_cksum,
			    outfd) != 0)
				goto out;
			break;
		}

		case DRR_OBJECT_RANGE:
		{
			if (dump_record(drr, NULL, 0, &stream_cksum,
			    outfd) != 0)
				goto out;
			break;
		}

		default:
			(void) fprintf(stderr, "INVALID record type 0x%x\n",
			    drr->drr_type);
			/* should never happen, so assert */
			assert(B_FALSE);
		}
	}
out:
	umem_cache_destroy(ddt.ddecache);
	free(ddt.dedup_hash_array);
	free(buf);
	(void) fclose(ofp);

	return (NULL);
}

/*
 * Routines for dealing with the AVL tree of fs-nvlists
 */
typedef struct fsavl_node {
	avl_node_t fn_node;
	nvlist_t *fn_nvfs;
	char *fn_snapname;
	uint64_t fn_guid;
} fsavl_node_t;

static int
fsavl_compare(const void *arg1, const void *arg2)
{
	const fsavl_node_t *fn1 = (const fsavl_node_t *)arg1;
	const fsavl_node_t *fn2 = (const fsavl_node_t *)arg2;

	return (AVL_CMP(fn1->fn_guid, fn2->fn_guid));
}

/*
 * Given the GUID of a snapshot, find its containing filesystem and
 * (optionally) name.
 */
static nvlist_t *
fsavl_find(avl_tree_t *avl, uint64_t snapguid, char **snapname)
{
	fsavl_node_t fn_find;
	fsavl_node_t *fn;

	fn_find.fn_guid = snapguid;

	fn = avl_find(avl, &fn_find, NULL);
	if (fn) {
		if (snapname)
			*snapname = fn->fn_snapname;
		return (fn->fn_nvfs);
	}
	return (NULL);
}

static void
fsavl_destroy(avl_tree_t *avl)
{
	fsavl_node_t *fn;
	void *cookie;

	if (avl == NULL)
		return;

	cookie = NULL;
	while ((fn = avl_destroy_nodes(avl, &cookie)) != NULL)
		free(fn);
	avl_destroy(avl);
	free(avl);
}

/*
 * Given an nvlist, produce an avl tree of snapshots, ordered by guid
 */
static avl_tree_t *
fsavl_create(nvlist_t *fss)
{
	avl_tree_t *fsavl;
	nvpair_t *fselem = NULL;

	if ((fsavl = malloc(sizeof (avl_tree_t))) == NULL)
		return (NULL);

	avl_create(fsavl, fsavl_compare, sizeof (fsavl_node_t),
	    offsetof(fsavl_node_t, fn_node));

	while ((fselem = nvlist_next_nvpair(fss, fselem)) != NULL) {
		nvlist_t *nvfs, *snaps;
		nvpair_t *snapelem = NULL;

		VERIFY(0 == nvpair_value_nvlist(fselem, &nvfs));
		VERIFY(0 == nvlist_lookup_nvlist(nvfs, "snaps", &snaps));

		while ((snapelem =
		    nvlist_next_nvpair(snaps, snapelem)) != NULL) {
			fsavl_node_t *fn;
			uint64_t guid;

			VERIFY(0 == nvpair_value_uint64(snapelem, &guid));
			if ((fn = malloc(sizeof (fsavl_node_t))) == NULL) {
				fsavl_destroy(fsavl);
				return (NULL);
			}
			fn->fn_nvfs = nvfs;
			fn->fn_snapname = nvpair_name(snapelem);
			fn->fn_guid = guid;

			/*
			 * Note: if there are multiple snaps with the
			 * same GUID, we ignore all but one.
			 */
			if (avl_find(fsavl, fn, NULL) == NULL)
				avl_add(fsavl, fn);
			else
				free(fn);
		}
	}

	return (fsavl);
}

/*
 * Routines for dealing with the giant nvlist of fs-nvlists, etc.
 */
typedef struct send_data {
	/*
	 * assigned inside every recursive call,
	 * restored from *_save on return:
	 *
	 * guid of fromsnap snapshot in parent dataset
	 * txg of fromsnap snapshot in current dataset
	 * txg of tosnap snapshot in current dataset
	 */

	uint64_t parent_fromsnap_guid;
	uint64_t fromsnap_txg;
	uint64_t tosnap_txg;

	/* the nvlists get accumulated during depth-first traversal */
	nvlist_t *parent_snaps;
	nvlist_t *fss;
	nvlist_t *snapprops;
	nvlist_t *snapholds;	/* user holds */

	/* send-receive configuration, does not change during traversal */
	const char *fsname;
	const char *fromsnap;
	const char *tosnap;
	boolean_t recursive;
	boolean_t raw;
	boolean_t doall;
	boolean_t replicate;
	boolean_t verbose;
	boolean_t backup;
	boolean_t seenfrom;
	boolean_t seento;
	boolean_t holds;	/* were holds requested with send -h */
	boolean_t props;

	/*
	 * The header nvlist is of the following format:
	 * {
	 *   "tosnap" -> string
	 *   "fromsnap" -> string (if incremental)
	 *   "fss" -> {
	 *	id -> {
	 *
	 *	 "name" -> string (full name; for debugging)
	 *	 "parentfromsnap" -> number (guid of fromsnap in parent)
	 *
	 *	 "props" -> { name -> value (only if set here) }
	 *	 "snaps" -> { name (lastname) -> number (guid) }
	 *	 "snapprops" -> { name (lastname) -> { name -> value } }
	 *	 "snapholds" -> { name (lastname) -> { holdname -> crtime } }
	 *
	 *	 "origin" -> number (guid) (if clone)
	 *	 "is_encroot" -> boolean
	 *	 "sent" -> boolean (not on-disk)
	 *	}
	 *   }
	 * }
	 *
	 */
} send_data_t;

static void
send_iterate_prop(zfs_handle_t *zhp, boolean_t received_only, nvlist_t *nv);

static int
send_iterate_snap(zfs_handle_t *zhp, void *arg)
{
	send_data_t *sd = arg;
	uint64_t guid = zhp->zfs_dmustats.dds_guid;
	uint64_t txg = zhp->zfs_dmustats.dds_creation_txg;
	char *snapname;
	nvlist_t *nv;
	boolean_t isfromsnap, istosnap, istosnapwithnofrom;

	snapname = strrchr(zhp->zfs_name, '@')+1;
	isfromsnap = (sd->fromsnap != NULL &&
	    strcmp(sd->fromsnap, snapname) == 0);
	istosnap = (sd->tosnap != NULL && (strcmp(sd->tosnap, snapname) == 0));
	istosnapwithnofrom = (istosnap && sd->fromsnap == NULL);

	if (sd->tosnap_txg != 0 && txg > sd->tosnap_txg) {
		if (sd->verbose) {
			(void) fprintf(stderr, dgettext(TEXT_DOMAIN,
			    "skipping snapshot %s because it was created "
			    "after the destination snapshot (%s)\n"),
			    zhp->zfs_name, sd->tosnap);
		}
		zfs_close(zhp);
		return (0);
	}

	VERIFY(0 == nvlist_add_uint64(sd->parent_snaps, snapname, guid));
	/*
	 * NB: if there is no fromsnap here (it's a newly created fs in
	 * an incremental replication), we will substitute the tosnap.
	 */
	if (isfromsnap || (sd->parent_fromsnap_guid == 0 && istosnap)) {
		sd->parent_fromsnap_guid = guid;
	}

	if (!sd->recursive) {
		if (!sd->seenfrom && isfromsnap) {
			sd->seenfrom = B_TRUE;
			zfs_close(zhp);
			return (0);
		}

		if ((sd->seento || !sd->seenfrom) && !istosnapwithnofrom) {
			zfs_close(zhp);
			return (0);
		}

		if (istosnap)
			sd->seento = B_TRUE;
	}

	VERIFY(0 == nvlist_alloc(&nv, NV_UNIQUE_NAME, 0));
	send_iterate_prop(zhp, sd->backup, nv);
	VERIFY(0 == nvlist_add_nvlist(sd->snapprops, snapname, nv));
	nvlist_free(nv);
	if (sd->holds) {
		nvlist_t *holds = fnvlist_alloc();
		int err = lzc_get_holds(zhp->zfs_name, &holds);
		if (err == 0) {
			VERIFY(0 == nvlist_add_nvlist(sd->snapholds,
			    snapname, holds));
		}
		fnvlist_free(holds);
	}

	zfs_close(zhp);
	return (0);
}

static void
send_iterate_prop(zfs_handle_t *zhp, boolean_t received_only, nvlist_t *nv)
{
	nvlist_t *props = NULL;
	nvpair_t *elem = NULL;

	if (received_only)
		props = zfs_get_recvd_props(zhp);
	else
		props = zhp->zfs_props;

	while ((elem = nvlist_next_nvpair(props, elem)) != NULL) {
		char *propname = nvpair_name(elem);
		zfs_prop_t prop = zfs_name_to_prop(propname);
		nvlist_t *propnv;

		if (!zfs_prop_user(propname)) {
			/*
			 * Realistically, this should never happen.  However,
			 * we want the ability to add DSL properties without
			 * needing to make incompatible version changes.  We
			 * need to ignore unknown properties to allow older
			 * software to still send datasets containing these
			 * properties, with the unknown properties elided.
			 */
			if (prop == ZPROP_INVAL)
				continue;

			if (zfs_prop_readonly(prop))
				continue;
		}

		verify(nvpair_value_nvlist(elem, &propnv) == 0);
		if (prop == ZFS_PROP_QUOTA || prop == ZFS_PROP_RESERVATION ||
		    prop == ZFS_PROP_REFQUOTA ||
		    prop == ZFS_PROP_REFRESERVATION) {
			char *source;
			uint64_t value;
			verify(nvlist_lookup_uint64(propnv,
			    ZPROP_VALUE, &value) == 0);
			if (zhp->zfs_type == ZFS_TYPE_SNAPSHOT)
				continue;
			/*
			 * May have no source before SPA_VERSION_RECVD_PROPS,
			 * but is still modifiable.
			 */
			if (nvlist_lookup_string(propnv,
			    ZPROP_SOURCE, &source) == 0) {
				if ((strcmp(source, zhp->zfs_name) != 0) &&
				    (strcmp(source,
				    ZPROP_SOURCE_VAL_RECVD) != 0))
					continue;
			}
		} else {
			char *source;
			if (nvlist_lookup_string(propnv,
			    ZPROP_SOURCE, &source) != 0)
				continue;
			if ((strcmp(source, zhp->zfs_name) != 0) &&
			    (strcmp(source, ZPROP_SOURCE_VAL_RECVD) != 0))
				continue;
		}

		if (zfs_prop_user(propname) ||
		    zfs_prop_get_type(prop) == PROP_TYPE_STRING) {
			char *value;
			verify(nvlist_lookup_string(propnv,
			    ZPROP_VALUE, &value) == 0);
			VERIFY(0 == nvlist_add_string(nv, propname, value));
		} else {
			uint64_t value;
			verify(nvlist_lookup_uint64(propnv,
			    ZPROP_VALUE, &value) == 0);
			VERIFY(0 == nvlist_add_uint64(nv, propname, value));
		}
	}
}

/*
 * returns snapshot creation txg
 * and returns 0 if the snapshot does not exist
 */
static uint64_t
get_snap_txg(libzfs_handle_t *hdl, const char *fs, const char *snap)
{
	char name[ZFS_MAX_DATASET_NAME_LEN];
	uint64_t txg = 0;

	if (fs == NULL || fs[0] == '\0' || snap == NULL || snap[0] == '\0')
		return (txg);

	(void) snprintf(name, sizeof (name), "%s@%s", fs, snap);
	if (zfs_dataset_exists(hdl, name, ZFS_TYPE_SNAPSHOT)) {
		zfs_handle_t *zhp = zfs_open(hdl, name, ZFS_TYPE_SNAPSHOT);
		if (zhp != NULL) {
			txg = zfs_prop_get_int(zhp, ZFS_PROP_CREATETXG);
			zfs_close(zhp);
		}
	}

	return (txg);
}

/*
 * recursively generate nvlists describing datasets.  See comment
 * for the data structure send_data_t above for description of contents
 * of the nvlist.
 */
static int
send_iterate_fs(zfs_handle_t *zhp, void *arg)
{
	send_data_t *sd = arg;
	nvlist_t *nvfs = NULL, *nv = NULL;
	int rv = 0;
	uint64_t min_txg = 0, max_txg = 0;
	uint64_t parent_fromsnap_guid_save = sd->parent_fromsnap_guid;
	uint64_t fromsnap_txg_save = sd->fromsnap_txg;
	uint64_t tosnap_txg_save = sd->tosnap_txg;
	uint64_t txg = zhp->zfs_dmustats.dds_creation_txg;
	uint64_t guid = zhp->zfs_dmustats.dds_guid;
	uint64_t fromsnap_txg, tosnap_txg;
	char guidstring[64];

	fromsnap_txg = get_snap_txg(zhp->zfs_hdl, zhp->zfs_name, sd->fromsnap);
	if (fromsnap_txg != 0)
		sd->fromsnap_txg = fromsnap_txg;

	tosnap_txg = get_snap_txg(zhp->zfs_hdl, zhp->zfs_name, sd->tosnap);
	if (tosnap_txg != 0)
		sd->tosnap_txg = tosnap_txg;

	/*
	 * on the send side, if the current dataset does not have tosnap,
	 * perform two additional checks:
	 *
	 * - skip sending the current dataset if it was created later than
	 *   the parent tosnap
	 * - return error if the current dataset was created earlier than
	 *   the parent tosnap
	 */
	if (sd->tosnap != NULL && tosnap_txg == 0) {
		if (sd->tosnap_txg != 0 && txg > sd->tosnap_txg) {
			if (sd->verbose) {
				(void) fprintf(stderr, dgettext(TEXT_DOMAIN,
				    "skipping dataset %s: snapshot %s does "
				    "not exist\n"), zhp->zfs_name, sd->tosnap);
			}
		} else {
			(void) fprintf(stderr, dgettext(TEXT_DOMAIN,
			    "cannot send %s@%s%s: snapshot %s@%s does not "
			    "exist\n"), sd->fsname, sd->tosnap, sd->recursive ?
			    dgettext(TEXT_DOMAIN, " recursively") : "",
			    zhp->zfs_name, sd->tosnap);
			rv = -1;
		}
		goto out;
	}

	nvfs = fnvlist_alloc();
	fnvlist_add_string(nvfs, "name", zhp->zfs_name);
	fnvlist_add_uint64(nvfs, "parentfromsnap",
	    sd->parent_fromsnap_guid);

	if (zhp->zfs_dmustats.dds_origin[0]) {
		zfs_handle_t *origin = zfs_open(zhp->zfs_hdl,
		    zhp->zfs_dmustats.dds_origin, ZFS_TYPE_SNAPSHOT);
		if (origin == NULL) {
			rv = -1;
			goto out;
		}
		fnvlist_add_uint64(nvfs, "origin",
		    origin->zfs_dmustats.dds_guid);

		zfs_close(origin);
	}

	/* iterate over props */
	if (sd->props || sd->backup || sd->recursive) {
		nv = fnvlist_alloc();
		send_iterate_prop(zhp, sd->backup, nv);
	}
	if (zfs_prop_get_int(zhp, ZFS_PROP_ENCRYPTION) != ZIO_CRYPT_OFF) {
		boolean_t encroot;

		/* determine if this dataset is an encryption root */
		if (zfs_crypto_get_encryption_root(zhp, &encroot, NULL) != 0) {
			rv = -1;
			goto out;
		}

		if (encroot)
			fnvlist_add_boolean(nvfs, "is_encroot");

		/*
		 * Encrypted datasets can only be sent with properties if
		 * the raw flag is specified because the receive side doesn't
		 * currently have a mechanism for recursively asking the user
		 * for new encryption parameters.
		 */
		if (!sd->raw) {
			(void) fprintf(stderr, dgettext(TEXT_DOMAIN,
			    "cannot send %s@%s: encrypted dataset %s may not "
			    "be sent with properties without the raw flag\n"),
			    sd->fsname, sd->tosnap, zhp->zfs_name);
			rv = -1;
			goto out;
		}

	}

	if (nv != NULL)
		fnvlist_add_nvlist(nvfs, "props", nv);

	/* iterate over snaps, and set sd->parent_fromsnap_guid */
	sd->parent_fromsnap_guid = 0;
	sd->parent_snaps = fnvlist_alloc();
	sd->snapprops = fnvlist_alloc();
	if (sd->holds)
		VERIFY(0 == nvlist_alloc(&sd->snapholds, NV_UNIQUE_NAME, 0));


	/*
	 * If this is a "doall" send, a replicate send or we're just trying
	 * to gather a list of previous snapshots, iterate through all the
	 * snaps in the txg range. Otherwise just look at the one we're
	 * interested in.
	 */
	if (sd->doall || sd->replicate || sd->tosnap == NULL) {
		if (!sd->replicate && fromsnap_txg != 0)
			min_txg = fromsnap_txg;
		if (!sd->replicate && tosnap_txg != 0)
			max_txg = tosnap_txg;
		(void) zfs_iter_snapshots_sorted(zhp, send_iterate_snap, sd,
		    min_txg, max_txg);
	} else {
		char snapname[MAXPATHLEN] = { 0 };
		zfs_handle_t *snap;

		(void) snprintf(snapname, sizeof (snapname), "%s@%s",
		    zhp->zfs_name, sd->tosnap);
		if (sd->fromsnap != NULL)
			sd->seenfrom = B_TRUE;
		snap = zfs_open(zhp->zfs_hdl, snapname,
		    ZFS_TYPE_SNAPSHOT);
		if (snap != NULL)
			(void) send_iterate_snap(snap, sd);
	}

	fnvlist_add_nvlist(nvfs, "snaps", sd->parent_snaps);
	fnvlist_add_nvlist(nvfs, "snapprops", sd->snapprops);
	if (sd->holds)
		fnvlist_add_nvlist(nvfs, "snapholds", sd->snapholds);
	fnvlist_free(sd->parent_snaps);
	fnvlist_free(sd->snapprops);
	fnvlist_free(sd->snapholds);

	/* add this fs to nvlist */
	(void) snprintf(guidstring, sizeof (guidstring),
	    "0x%llx", (longlong_t)guid);
	fnvlist_add_nvlist(sd->fss, guidstring, nvfs);

	/* iterate over children */
	if (sd->recursive)
		rv = zfs_iter_filesystems(zhp, send_iterate_fs, sd);

out:
	sd->parent_fromsnap_guid = parent_fromsnap_guid_save;
	sd->fromsnap_txg = fromsnap_txg_save;
	sd->tosnap_txg = tosnap_txg_save;
	fnvlist_free(nv);
	fnvlist_free(nvfs);

	zfs_close(zhp);
	return (rv);
}

static int
gather_nvlist(libzfs_handle_t *hdl, const char *fsname, const char *fromsnap,
    const char *tosnap, boolean_t recursive, boolean_t raw, boolean_t doall,
    boolean_t replicate, boolean_t verbose, boolean_t backup, boolean_t holds,
    boolean_t props, nvlist_t **nvlp, avl_tree_t **avlp)
{
	zfs_handle_t *zhp;
	send_data_t sd = { 0 };
	int error;

	zhp = zfs_open(hdl, fsname, ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME);
	if (zhp == NULL)
		return (EZFS_BADTYPE);

	VERIFY(0 == nvlist_alloc(&sd.fss, NV_UNIQUE_NAME, 0));
	sd.fsname = fsname;
	sd.fromsnap = fromsnap;
	sd.tosnap = tosnap;
	sd.recursive = recursive;
	sd.raw = raw;
	sd.doall = doall;
	sd.replicate = replicate;
	sd.verbose = verbose;
	sd.backup = backup;
	sd.holds = holds;
	sd.props = props;

	if ((error = send_iterate_fs(zhp, &sd)) != 0) {
		nvlist_free(sd.fss);
		if (avlp != NULL)
			*avlp = NULL;
		*nvlp = NULL;
		return (error);
	}

	if (avlp != NULL && (*avlp = fsavl_create(sd.fss)) == NULL) {
		nvlist_free(sd.fss);
		*nvlp = NULL;
		return (EZFS_NOMEM);
	}

	*nvlp = sd.fss;
	return (0);
}

/*
 * Routines specific to "zfs send"
 */
typedef struct send_dump_data {
	/* these are all just the short snapname (the part after the @) */
	const char *fromsnap;
	const char *tosnap;
	char prevsnap[ZFS_MAX_DATASET_NAME_LEN];
	uint64_t prevsnap_obj;
	boolean_t seenfrom, seento, replicate, doall, fromorigin;
	boolean_t verbose, dryrun, parsable, progress, embed_data, block_diff, std_out;
	boolean_t large_block, compress, raw, holds;
	int outfd;
	boolean_t err;
	nvlist_t *fss;
	nvlist_t *snapholds;
	avl_tree_t *fsavl;
	snapfilter_cb_t *filter_cb;
	void *filter_cb_arg;
	nvlist_t *debugnv;
	char holdtag[ZFS_MAX_DATASET_NAME_LEN];
	int cleanup_fd;
	uint64_t size;
} send_dump_data_t;

static int
zfs_send_space(zfs_handle_t *zhp, const char *snapname, const char *from,
    enum lzc_send_flags flags, uint64_t *spacep)
{
	libzfs_handle_t *hdl = zhp->zfs_hdl;
	int error;

	assert(snapname != NULL);
	error = lzc_send_space(snapname, from, flags, spacep);

	if (error != 0) {
		char errbuf[1024];
		(void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
		    "warning: cannot estimate space for '%s'"), snapname);

		switch (error) {
		case EXDEV:
			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
			    "not an earlier snapshot from the same fs"));
			return (zfs_error(hdl, EZFS_CROSSTARGET, errbuf));

		case ENOENT:
			if (zfs_dataset_exists(hdl, snapname,
			    ZFS_TYPE_SNAPSHOT)) {
				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
				    "incremental source (%s) does not exist"),
				    snapname);
			}
			return (zfs_error(hdl, EZFS_NOENT, errbuf));

		case EDQUOT:
		case EFBIG:
		case EIO:
		case ENOLINK:
		case ENOSPC:
		case ENOSTR:
		case ENXIO:
		case EPIPE:
		case ERANGE:
		case EFAULT:
		case EROFS:
		case EINVAL:
			zfs_error_aux(hdl, strerror(error));
			return (zfs_error(hdl, EZFS_BADBACKUP, errbuf));

		default:
			return (zfs_standard_error(hdl, error, errbuf));
		}
	}

	return (0);
}

/*
 * Dumps a backup of the given snapshot (incremental from fromsnap if it's not
 * NULL) to the file descriptor specified by outfd.
 */
static int
dump_ioctl(zfs_handle_t *zhp, const char *fromsnap, uint64_t fromsnap_obj,
    boolean_t fromorigin, int outfd, enum lzc_send_flags flags,
    nvlist_t *debugnv, boolean_t block_diff)
{
	zfs_cmd_t zc = {"\0"};
	libzfs_handle_t *hdl = zhp->zfs_hdl;
	nvlist_t *thisdbg;

	assert(zhp->zfs_type == ZFS_TYPE_SNAPSHOT);
	assert(fromsnap_obj == 0 || !fromorigin);

	(void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
	zc.zc_cookie = outfd;
	zc.zc_obj = fromorigin;
	zc.zc_sendobj = zfs_prop_get_int(zhp, ZFS_PROP_OBJSETID);
	zc.zc_fromobj = fromsnap_obj;
	zc.zc_flags = flags;
	zc.zc_block_diff = block_diff ? BLOCK_DIFF_MAGIC : 0;

	VERIFY(0 == nvlist_alloc(&thisdbg, NV_UNIQUE_NAME, 0));
	if (fromsnap && fromsnap[0] != '\0') {
		VERIFY(0 == nvlist_add_string(thisdbg,
		    "fromsnap", fromsnap));
	}

	if (zfs_ioctl(zhp->zfs_hdl, ZFS_IOC_SEND, &zc) != 0) {
		char errbuf[1024];
		(void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
		    "warning: cannot send '%s'"), zhp->zfs_name);

		VERIFY(0 == nvlist_add_uint64(thisdbg, "error", errno));
		if (debugnv) {
			VERIFY(0 == nvlist_add_nvlist(debugnv,
			    zhp->zfs_name, thisdbg));
		}
		nvlist_free(thisdbg);

		switch (errno) {
		case EXDEV:
			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
			    "not an earlier snapshot from the same fs"));
			return (zfs_error(hdl, EZFS_CROSSTARGET, errbuf));

		case EACCES:
			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
			    "source key must be loaded"));
			return (zfs_error(hdl, EZFS_CRYPTOFAILED, errbuf));

		case ENOENT:
			if (zfs_dataset_exists(hdl, zc.zc_name,
			    ZFS_TYPE_SNAPSHOT)) {
				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
				    "incremental source (@%s) does not exist"),
				    zc.zc_value);
			}
			return (zfs_error(hdl, EZFS_NOENT, errbuf));

		case EDQUOT:
		case EFBIG:
		case EIO:
		case ENOLINK:
		case ENOSPC:
		case ENOSTR:
		case ENXIO:
		case EPIPE:
		case ERANGE:
		case EFAULT:
		case EROFS:
			zfs_error_aux(hdl, strerror(errno));
			return (zfs_error(hdl, EZFS_BADBACKUP, errbuf));

		default:
			return (zfs_standard_error(hdl, errno, errbuf));
		}
	}

	if (debugnv)
		VERIFY(0 == nvlist_add_nvlist(debugnv, zhp->zfs_name, thisdbg));
	nvlist_free(thisdbg);

	return (0);
}

static void
gather_holds(zfs_handle_t *zhp, send_dump_data_t *sdd)
{
	assert(zhp->zfs_type == ZFS_TYPE_SNAPSHOT);

	/*
	 * zfs_send() only sets snapholds for sends that need them,
	 * e.g. replication and doall.
	 */
	if (sdd->snapholds == NULL)
		return;

	fnvlist_add_string(sdd->snapholds, zhp->zfs_name, sdd->holdtag);
}

static void *
send_progress_thread(void *arg)
{
	progress_arg_t *pa = arg;
	zfs_cmd_t zc = {"\0"};
	zfs_handle_t *zhp = pa->pa_zhp;
	libzfs_handle_t *hdl = zhp->zfs_hdl;
	unsigned long long bytes;
	char buf[16];
	time_t t;
	struct tm *tm;

	(void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));

	if (!pa->pa_parsable)
		(void) fprintf(stderr, "TIME        SENT   SNAPSHOT %s\n",
		    zhp->zfs_name);

	/*
	 * Print the progress from ZFS_IOC_SEND_PROGRESS every second.
	 */
	for (;;) {
		(void) sleep(1);

		zc.zc_cookie = pa->pa_fd;
		if (zfs_ioctl(hdl, ZFS_IOC_SEND_PROGRESS, &zc) != 0)
			return ((void *)-1);

		(void) time(&t);
		tm = localtime(&t);
		bytes = zc.zc_cookie;

		if (pa->pa_parsable) {
			(void) fprintf(stderr, "%02d:%02d:%02d\t%llu\t%s\n",
			    tm->tm_hour, tm->tm_min, tm->tm_sec,
			    bytes, zhp->zfs_name);
		} else {
			zfs_nicebytes(bytes, buf, sizeof (buf));
			(void) fprintf(stderr, "%02d:%02d:%02d   %5s   %s\n",
			    tm->tm_hour, tm->tm_min, tm->tm_sec,
			    buf, zhp->zfs_name);
		}
	}
}

static void
send_print_verbose(FILE *fout, const char *tosnap, const char *fromsnap,
    uint64_t size, boolean_t parsable)
{
	if (parsable) {
		if (fromsnap != NULL) {
			(void) fprintf(fout, "incremental\t%s\t%s",
			    fromsnap, tosnap);
		} else {
			(void) fprintf(fout, "full\t%s",
			    tosnap);
		}
	} else {
		if (fromsnap != NULL) {
			if (strchr(fromsnap, '@') == NULL &&
			    strchr(fromsnap, '#') == NULL) {
				(void) fprintf(fout, dgettext(TEXT_DOMAIN,
				    "send from @%s to %s"),
				    fromsnap, tosnap);
			} else {
				(void) fprintf(fout, dgettext(TEXT_DOMAIN,
				    "send from %s to %s"),
				    fromsnap, tosnap);
			}
		} else {
			(void) fprintf(fout, dgettext(TEXT_DOMAIN,
			    "full send of %s"),
			    tosnap);
		}
	}

	if (parsable) {
		(void) fprintf(fout, "\t%llu",
		    (longlong_t)size);
	} else if (size != 0) {
		char buf[16];
		zfs_nicebytes(size, buf, sizeof (buf));
		(void) fprintf(fout, dgettext(TEXT_DOMAIN,
		    " estimated size is %s"), buf);
	}
	(void) fprintf(fout, "\n");
}

static int
dump_snapshot(zfs_handle_t *zhp, void *arg)
{
	send_dump_data_t *sdd = arg;
	progress_arg_t pa = { 0 };
	pthread_t tid;
	char *thissnap;
	enum lzc_send_flags flags = 0;
	int err;
	boolean_t isfromsnap, istosnap, fromorigin;
	boolean_t exclude = B_FALSE;
	FILE *fout = sdd->std_out ? stdout : stderr;

	err = 0;
	thissnap = strchr(zhp->zfs_name, '@') + 1;
	isfromsnap = (sdd->fromsnap != NULL &&
	    strcmp(sdd->fromsnap, thissnap) == 0);

	if (!sdd->seenfrom && isfromsnap) {
		gather_holds(zhp, sdd);
		sdd->seenfrom = B_TRUE;
		(void) strlcpy(sdd->prevsnap, thissnap,
		    sizeof (sdd->prevsnap));
		sdd->prevsnap_obj = zfs_prop_get_int(zhp, ZFS_PROP_OBJSETID);
		zfs_close(zhp);
		return (0);
	}

	if (sdd->seento || !sdd->seenfrom) {
		zfs_close(zhp);
		return (0);
	}

	istosnap = (strcmp(sdd->tosnap, thissnap) == 0);
	if (istosnap)
		sdd->seento = B_TRUE;

	if (sdd->large_block)
		flags |= LZC_SEND_FLAG_LARGE_BLOCK;
	if (sdd->embed_data)
		flags |= LZC_SEND_FLAG_EMBED_DATA;
	if (sdd->compress)
		flags |= LZC_SEND_FLAG_COMPRESS;
	if (sdd->raw)
		flags |= LZC_SEND_FLAG_RAW;

	if (!sdd->doall && !isfromsnap && !istosnap) {
		if (sdd->replicate) {
			char *snapname;
			nvlist_t *snapprops;
			/*
			 * Filter out all intermediate snapshots except origin
			 * snapshots needed to replicate clones.
			 */
			nvlist_t *nvfs = fsavl_find(sdd->fsavl,
			    zhp->zfs_dmustats.dds_guid, &snapname);

			VERIFY(0 == nvlist_lookup_nvlist(nvfs,
			    "snapprops", &snapprops));
			VERIFY(0 == nvlist_lookup_nvlist(snapprops,
			    thissnap, &snapprops));
			exclude = !nvlist_exists(snapprops, "is_clone_origin");
		} else {
			exclude = B_TRUE;
		}
	}

	/*
	 * If a filter function exists, call it to determine whether
	 * this snapshot will be sent.
	 */
	if (exclude || (sdd->filter_cb != NULL &&
	    sdd->filter_cb(zhp, sdd->filter_cb_arg) == B_FALSE)) {
		/*
		 * This snapshot is filtered out.  Don't send it, and don't
		 * set prevsnap_obj, so it will be as if this snapshot didn't
		 * exist, and the next accepted snapshot will be sent as
		 * an incremental from the last accepted one, or as the
		 * first (and full) snapshot in the case of a replication,
		 * non-incremental send.
		 */
		zfs_close(zhp);
		return (0);
	}

	gather_holds(zhp, sdd);
	fromorigin = sdd->prevsnap[0] == '\0' &&
	    (sdd->fromorigin || sdd->replicate);

	if (sdd->verbose) {
		uint64_t size = 0;
		char fromds[ZFS_MAX_DATASET_NAME_LEN];

		if (sdd->prevsnap[0] != '\0') {
			(void) strlcpy(fromds, zhp->zfs_name, sizeof (fromds));
			*(strchr(fromds, '@') + 1) = '\0';
			(void) strlcat(fromds, sdd->prevsnap, sizeof (fromds));
		}
		if (zfs_send_space(zhp, zhp->zfs_name,
		    sdd->prevsnap[0] ? fromds : NULL, flags, &size) != 0) {
			size = 0; /* cannot estimate send space */
		} else {
			send_print_verbose(fout, zhp->zfs_name,
			    sdd->prevsnap[0] ? sdd->prevsnap : NULL,
			    size, sdd->parsable);
		}
		sdd->size += size;
	}

	if (!sdd->dryrun) {
		/*
		 * If progress reporting is requested, spawn a new thread to
		 * poll ZFS_IOC_SEND_PROGRESS at a regular interval.
		 */
		if (sdd->progress) {
			pa.pa_zhp = zhp;
			pa.pa_fd = sdd->outfd;
			pa.pa_parsable = sdd->parsable;

			if ((err = pthread_create(&tid, NULL,
			    send_progress_thread, &pa)) != 0) {
				zfs_close(zhp);
				return (err);
			}
		}

		err = dump_ioctl(zhp, sdd->prevsnap, sdd->prevsnap_obj,
		    fromorigin, sdd->outfd, flags, sdd->debugnv, sdd->block_diff);

		if (sdd->progress) {
			(void) pthread_cancel(tid);
			(void) pthread_join(tid, NULL);
		}
	}

	(void) strcpy(sdd->prevsnap, thissnap);
	sdd->prevsnap_obj = zfs_prop_get_int(zhp, ZFS_PROP_OBJSETID);
	zfs_close(zhp);
	return (err);
}

static int
dump_filesystem(zfs_handle_t *zhp, void *arg)
{
	int rv = 0;
	send_dump_data_t *sdd = arg;
	boolean_t missingfrom = B_FALSE;
	zfs_cmd_t zc = {"\0"};
	uint64_t min_txg = 0, max_txg = 0;

	(void) snprintf(zc.zc_name, sizeof (zc.zc_name), "%s@%s",
	    zhp->zfs_name, sdd->tosnap);
	if (ioctl(zhp->zfs_hdl->libzfs_fd, ZFS_IOC_OBJSET_STATS, &zc) != 0) {
		(void) fprintf(stderr, dgettext(TEXT_DOMAIN,
		    "WARNING: could not send %s@%s: does not exist\n"),
		    zhp->zfs_name, sdd->tosnap);
		sdd->err = B_TRUE;
		return (0);
	}

	if (sdd->replicate && sdd->fromsnap) {
		/*
		 * If this fs does not have fromsnap, and we're doing
		 * recursive, we need to send a full stream from the
		 * beginning (or an incremental from the origin if this
		 * is a clone).  If we're doing non-recursive, then let
		 * them get the error.
		 */
		(void) snprintf(zc.zc_name, sizeof (zc.zc_name), "%s@%s",
		    zhp->zfs_name, sdd->fromsnap);
		if (ioctl(zhp->zfs_hdl->libzfs_fd,
		    ZFS_IOC_OBJSET_STATS, &zc) != 0) {
			missingfrom = B_TRUE;
		}
	}

	sdd->seenfrom = sdd->seento = sdd->prevsnap[0] = 0;
	sdd->prevsnap_obj = 0;
	if (sdd->fromsnap == NULL || missingfrom)
		sdd->seenfrom = B_TRUE;



	/*
	 * Iterate through all snapshots and process the ones we will be
	 * sending. If we only have a "from" and "to" snapshot to deal
	 * with, we can avoid iterating through all the other snapshots.
	 */
	if (sdd->doall || sdd->replicate || sdd->tosnap == NULL) {
		if (!sdd->replicate && sdd->fromsnap != NULL)
			min_txg = get_snap_txg(zhp->zfs_hdl, zhp->zfs_name,
			    sdd->fromsnap);
		if (!sdd->replicate && sdd->tosnap != NULL)
			max_txg = get_snap_txg(zhp->zfs_hdl, zhp->zfs_name,
			    sdd->tosnap);
		rv = zfs_iter_snapshots_sorted(zhp, dump_snapshot, arg,
		    min_txg, max_txg);
	} else {
		char snapname[MAXPATHLEN] = { 0 };
		zfs_handle_t *snap;

		if (!sdd->seenfrom) {
			(void) snprintf(snapname, sizeof (snapname),
			    "%s@%s", zhp->zfs_name, sdd->fromsnap);
			snap = zfs_open(zhp->zfs_hdl, snapname,
			    ZFS_TYPE_SNAPSHOT);
			if (snap != NULL)
				rv = dump_snapshot(snap, sdd);
			else
				rv = -1;
		}

		if (rv == 0) {
			(void) snprintf(snapname, sizeof (snapname),
			    "%s@%s", zhp->zfs_name, sdd->tosnap);
			snap = zfs_open(zhp->zfs_hdl, snapname,
			    ZFS_TYPE_SNAPSHOT);
			if (snap != NULL)
				rv = dump_snapshot(snap, sdd);
			else
				rv = -1;
		}
	}

	if (!sdd->seenfrom) {
		(void) fprintf(stderr, dgettext(TEXT_DOMAIN,
		    "WARNING: could not send %s@%s:\n"
		    "incremental source (%s@%s) does not exist\n"),
		    zhp->zfs_name, sdd->tosnap,
		    zhp->zfs_name, sdd->fromsnap);
		sdd->err = B_TRUE;
	} else if (!sdd->seento) {
		if (sdd->fromsnap) {
			(void) fprintf(stderr, dgettext(TEXT_DOMAIN,
			    "WARNING: could not send %s@%s:\n"
			    "incremental source (%s@%s) "
			    "is not earlier than it\n"),
			    zhp->zfs_name, sdd->tosnap,
			    zhp->zfs_name, sdd->fromsnap);
		} else {
			(void) fprintf(stderr, dgettext(TEXT_DOMAIN,
			    "WARNING: "
			    "could not send %s@%s: does not exist\n"),
			    zhp->zfs_name, sdd->tosnap);
		}
		sdd->err = B_TRUE;
	}

	return (rv);
}

static int
dump_filesystems(zfs_handle_t *rzhp, void *arg)
{
	send_dump_data_t *sdd = arg;
	nvpair_t *fspair;
	boolean_t needagain, progress;

	if (!sdd->replicate)
		return (dump_filesystem(rzhp, sdd));

	/* Mark the clone origin snapshots. */
	for (fspair = nvlist_next_nvpair(sdd->fss, NULL); fspair;
	    fspair = nvlist_next_nvpair(sdd->fss, fspair)) {
		nvlist_t *nvfs;
		uint64_t origin_guid = 0;

		VERIFY(0 == nvpair_value_nvlist(fspair, &nvfs));
		(void) nvlist_lookup_uint64(nvfs, "origin", &origin_guid);
		if (origin_guid != 0) {
			char *snapname;
			nvlist_t *origin_nv = fsavl_find(sdd->fsavl,
			    origin_guid, &snapname);
			if (origin_nv != NULL) {
				nvlist_t *snapprops;
				VERIFY(0 == nvlist_lookup_nvlist(origin_nv,
				    "snapprops", &snapprops));
				VERIFY(0 == nvlist_lookup_nvlist(snapprops,
				    snapname, &snapprops));
				VERIFY(0 == nvlist_add_boolean(
				    snapprops, "is_clone_origin"));
			}
		}
	}
again:
	needagain = progress = B_FALSE;
	for (fspair = nvlist_next_nvpair(sdd->fss, NULL); fspair;
	    fspair = nvlist_next_nvpair(sdd->fss, fspair)) {
		nvlist_t *fslist, *parent_nv;
		char *fsname;
		zfs_handle_t *zhp;
		int err;
		uint64_t origin_guid = 0;
		uint64_t parent_guid = 0;

		VERIFY(nvpair_value_nvlist(fspair, &fslist) == 0);
		if (nvlist_lookup_boolean(fslist, "sent") == 0)
			continue;

		VERIFY(nvlist_lookup_string(fslist, "name", &fsname) == 0);
		(void) nvlist_lookup_uint64(fslist, "origin", &origin_guid);
		(void) nvlist_lookup_uint64(fslist, "parentfromsnap",
		    &parent_guid);

		if (parent_guid != 0) {
			parent_nv = fsavl_find(sdd->fsavl, parent_guid, NULL);
			if (!nvlist_exists(parent_nv, "sent")) {
				/* parent has not been sent; skip this one */
				needagain = B_TRUE;
				continue;
			}
		}

		if (origin_guid != 0) {
			nvlist_t *origin_nv = fsavl_find(sdd->fsavl,
			    origin_guid, NULL);
			if (origin_nv != NULL &&
			    !nvlist_exists(origin_nv, "sent")) {
				/*
				 * origin has not been sent yet;
				 * skip this clone.
				 */
				needagain = B_TRUE;
				continue;
			}
		}

		zhp = zfs_open(rzhp->zfs_hdl, fsname, ZFS_TYPE_DATASET);
		if (zhp == NULL)
			return (-1);
		err = dump_filesystem(zhp, sdd);
		VERIFY(nvlist_add_boolean(fslist, "sent") == 0);
		progress = B_TRUE;
		zfs_close(zhp);
		if (err)
			return (err);
	}
	if (needagain) {
		assert(progress);
		goto again;
	}

	/* clean out the sent flags in case we reuse this fss */
	for (fspair = nvlist_next_nvpair(sdd->fss, NULL); fspair;
	    fspair = nvlist_next_nvpair(sdd->fss, fspair)) {
		nvlist_t *fslist;

		VERIFY(nvpair_value_nvlist(fspair, &fslist) == 0);
		(void) nvlist_remove_all(fslist, "sent");
	}

	return (0);
}

nvlist_t *
zfs_send_resume_token_to_nvlist(libzfs_handle_t *hdl, const char *token)
{
	unsigned int version;
	int nread, i;
	unsigned long long checksum, packed_len;

	/*
	 * Decode token header, which is:
	 *   <token version>-<checksum of payload>-<uncompressed payload length>
	 * Note that the only supported token version is 1.
	 */
	nread = sscanf(token, "%u-%llx-%llx-",
	    &version, &checksum, &packed_len);
	if (nread != 3) {
		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
		    "resume token is corrupt (invalid format)"));
		return (NULL);
	}

	if (version != ZFS_SEND_RESUME_TOKEN_VERSION) {
		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
		    "resume token is corrupt (invalid version %u)"),
		    version);
		return (NULL);
	}

	/* convert hexadecimal representation to binary */
	token = strrchr(token, '-') + 1;
	int len = strlen(token) / 2;
	unsigned char *compressed = zfs_alloc(hdl, len);
	for (i = 0; i < len; i++) {
		nread = sscanf(token + i * 2, "%2hhx", compressed + i);
		if (nread != 1) {
			free(compressed);
			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
			    "resume token is corrupt "
			    "(payload is not hex-encoded)"));
			return (NULL);
		}
	}

	/* verify checksum */
	zio_cksum_t cksum;
	fletcher_4_native_varsize(compressed, len, &cksum);
	if (cksum.zc_word[0] != checksum) {
		free(compressed);
		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
		    "resume token is corrupt (incorrect checksum)"));
		return (NULL);
	}

	/* uncompress */
	void *packed = zfs_alloc(hdl, packed_len);
	uLongf packed_len_long = packed_len;
	if (uncompress(packed, &packed_len_long, compressed, len) != Z_OK ||
	    packed_len_long != packed_len) {
		free(packed);
		free(compressed);
		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
		    "resume token is corrupt (decompression failed)"));
		return (NULL);
	}

	/* unpack nvlist */
	nvlist_t *nv;
	int error = nvlist_unpack(packed, packed_len, &nv, KM_SLEEP);
	free(packed);
	free(compressed);
	if (error != 0) {
		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
		    "resume token is corrupt (nvlist_unpack failed)"));
		return (NULL);
	}
	return (nv);
}

int
zfs_send_resume(libzfs_handle_t *hdl, sendflags_t *flags, int outfd,
    const char *resume_token)
{
	char errbuf[1024];
	char *toname;
	char *fromname = NULL;
	uint64_t resumeobj, resumeoff, toguid, fromguid, bytes;
	zfs_handle_t *zhp;
	int error = 0;
	char name[ZFS_MAX_DATASET_NAME_LEN];
	enum lzc_send_flags lzc_flags = 0;
	FILE *fout = (flags->verbose && flags->dryrun) ? stdout : stderr;

	(void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
	    "cannot resume send"));

	nvlist_t *resume_nvl =
	    zfs_send_resume_token_to_nvlist(hdl, resume_token);
	if (resume_nvl == NULL) {
		/*
		 * zfs_error_aux has already been set by
		 * zfs_send_resume_token_to_nvlist
		 */
		return (zfs_error(hdl, EZFS_FAULT, errbuf));
	}
	if (flags->verbose) {
		(void) fprintf(fout, dgettext(TEXT_DOMAIN,
		    "resume token contents:\n"));
		nvlist_print(fout, resume_nvl);
	}

	if (nvlist_lookup_string(resume_nvl, "toname", &toname) != 0 ||
	    nvlist_lookup_uint64(resume_nvl, "object", &resumeobj) != 0 ||
	    nvlist_lookup_uint64(resume_nvl, "offset", &resumeoff) != 0 ||
	    nvlist_lookup_uint64(resume_nvl, "bytes", &bytes) != 0 ||
	    nvlist_lookup_uint64(resume_nvl, "toguid", &toguid) != 0) {
		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
		    "resume token is corrupt"));
		return (zfs_error(hdl, EZFS_FAULT, errbuf));
	}
	fromguid = 0;
	(void) nvlist_lookup_uint64(resume_nvl, "fromguid", &fromguid);

	if (flags->largeblock || nvlist_exists(resume_nvl, "largeblockok"))
		lzc_flags |= LZC_SEND_FLAG_LARGE_BLOCK;
	if (flags->embed_data || nvlist_exists(resume_nvl, "embedok"))
		lzc_flags |= LZC_SEND_FLAG_EMBED_DATA;
	if (flags->compress || nvlist_exists(resume_nvl, "compressok"))
		lzc_flags |= LZC_SEND_FLAG_COMPRESS;
	if (flags->raw || nvlist_exists(resume_nvl, "rawok"))
		lzc_flags |= LZC_SEND_FLAG_RAW;

	if (guid_to_name(hdl, toname, toguid, B_FALSE, name) != 0) {
		if (zfs_dataset_exists(hdl, toname, ZFS_TYPE_DATASET)) {
			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
			    "'%s' is no longer the same snapshot used in "
			    "the initial send"), toname);
		} else {
			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
			    "'%s' used in the initial send no longer exists"),
			    toname);
		}
		return (zfs_error(hdl, EZFS_BADPATH, errbuf));
	}
	zhp = zfs_open(hdl, name, ZFS_TYPE_DATASET);
	if (zhp == NULL) {
		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
		    "unable to access '%s'"), name);
		return (zfs_error(hdl, EZFS_BADPATH, errbuf));
	}

	if (fromguid != 0) {
		if (guid_to_name(hdl, toname, fromguid, B_TRUE, name) != 0) {
			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
			    "incremental source %#llx no longer exists"),
			    (longlong_t)fromguid);
			return (zfs_error(hdl, EZFS_BADPATH, errbuf));
		}
		fromname = name;
	}

	if (flags->verbose) {
		uint64_t size = 0;
		error = lzc_send_space(zhp->zfs_name, fromname,
		    lzc_flags, &size);
		if (error == 0)
			size = MAX(0, (int64_t)(size - bytes));
		send_print_verbose(fout, zhp->zfs_name, fromname,
		    size, flags->parsable);
	}

	if (!flags->dryrun) {
		progress_arg_t pa = { 0 };
		pthread_t tid;
		/*
		 * If progress reporting is requested, spawn a new thread to
		 * poll ZFS_IOC_SEND_PROGRESS at a regular interval.
		 */
		if (flags->progress) {
			pa.pa_zhp = zhp;
			pa.pa_fd = outfd;
			pa.pa_parsable = flags->parsable;

			error = pthread_create(&tid, NULL,
			    send_progress_thread, &pa);
			if (error != 0) {
				zfs_close(zhp);
				return (error);
			}
		}

		error = lzc_send_resume(zhp->zfs_name, fromname, outfd,
		    lzc_flags, resumeobj, resumeoff);

		if (flags->progress) {
			(void) pthread_cancel(tid);
			(void) pthread_join(tid, NULL);
		}

		char errbuf[1024];
		(void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
		    "warning: cannot send '%s'"), zhp->zfs_name);

		zfs_close(zhp);

		switch (error) {
		case 0:
			return (0);
		case EACCES:
			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
			    "source key must be loaded"));
			return (zfs_error(hdl, EZFS_CRYPTOFAILED, errbuf));

		case EXDEV:
		case ENOENT:
		case EDQUOT:
		case EFBIG:
		case EIO:
		case ENOLINK:
		case ENOSPC:
		case ENOSTR:
		case ENXIO:
		case EPIPE:
		case ERANGE:
		case EFAULT:
		case EROFS:
			zfs_error_aux(hdl, strerror(errno));
			return (zfs_error(hdl, EZFS_BADBACKUP, errbuf));

		default:
			return (zfs_standard_error(hdl, errno, errbuf));
		}
	}


	zfs_close(zhp);

	return (error);
}

/*
 * Generate a send stream for the dataset identified by the argument zhp.
 *
 * The content of the send stream is the snapshot identified by
 * 'tosnap'.  Incremental streams are requested in two ways:
 *     - from the snapshot identified by "fromsnap" (if non-null) or
 *     - from the origin of the dataset identified by zhp, which must
 *	 be a clone.  In this case, "fromsnap" is null and "fromorigin"
 *	 is TRUE.
 *
 * The send stream is recursive (i.e. dumps a hierarchy of snapshots) and
 * uses a special header (with a hdrtype field of DMU_COMPOUNDSTREAM)
 * if "replicate" is set.  If "doall" is set, dump all the intermediate
 * snapshots. The DMU_COMPOUNDSTREAM header is used in the "doall"
 * case too. If "props" is set, send properties.
 */
int
zfs_send(zfs_handle_t *zhp, const char *fromsnap, const char *tosnap,
    sendflags_t *flags, int outfd, snapfilter_cb_t filter_func,
    void *cb_arg, nvlist_t **debugnvp)
{
	char errbuf[1024];
	send_dump_data_t sdd = { 0 };
	int err = 0;
	nvlist_t *fss = NULL;
	avl_tree_t *fsavl = NULL;
	static uint64_t holdseq;
	int spa_version;
	pthread_t tid = 0;
	int pipefd[2];
	dedup_arg_t dda = { 0 };
	int featureflags = 0;
	FILE *fout;

	(void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
	    "cannot send '%s'"), zhp->zfs_name);

	if (fromsnap && fromsnap[0] == '\0') {
		zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN,
		    "zero-length incremental source"));
		return (zfs_error(zhp->zfs_hdl, EZFS_NOENT, errbuf));
	}

	if (zhp->zfs_type == ZFS_TYPE_FILESYSTEM) {
		uint64_t version;
		version = zfs_prop_get_int(zhp, ZFS_PROP_VERSION);
		if (version >= ZPL_VERSION_SA) {
			featureflags |= DMU_BACKUP_FEATURE_SA_SPILL;
		}
	}

	if (flags->holds)
		featureflags |= DMU_BACKUP_FEATURE_HOLDS;

	/*
	 * Start the dedup thread if this is a dedup stream. We do not bother
	 * doing this if this a raw send of an encrypted dataset with dedup off
	 * because normal encrypted blocks won't dedup.
	 */
	if (flags->dedup && !flags->dryrun && !(flags->raw &&
	    zfs_prop_get_int(zhp, ZFS_PROP_ENCRYPTION) != ZIO_CRYPT_OFF &&
	    zfs_prop_get_int(zhp, ZFS_PROP_DEDUP) == ZIO_CHECKSUM_OFF)) {
		featureflags |= (DMU_BACKUP_FEATURE_DEDUP |
		    DMU_BACKUP_FEATURE_DEDUPPROPS);
		if ((err = socketpair(AF_UNIX, SOCK_STREAM, 0, pipefd)) != 0) {
			zfs_error_aux(zhp->zfs_hdl, strerror(errno));
			return (zfs_error(zhp->zfs_hdl, EZFS_PIPEFAILED,
			    errbuf));
		}
		dda.outputfd = outfd;
		dda.inputfd = pipefd[1];
		dda.dedup_hdl = zhp->zfs_hdl;
		if ((err = pthread_create(&tid, NULL, cksummer, &dda)) != 0) {
			(void) close(pipefd[0]);
			(void) close(pipefd[1]);
			zfs_error_aux(zhp->zfs_hdl, strerror(errno));
			return (zfs_error(zhp->zfs_hdl,
			    EZFS_THREADCREATEFAILED, errbuf));
		}
	}

	if (flags->replicate || flags->doall || flags->props ||
	    flags->holds || flags->backup) {
		dmu_replay_record_t drr = { 0 };
		char *packbuf = NULL;
		size_t buflen = 0;
		zio_cksum_t zc;

		ZIO_SET_CHECKSUM(&zc, 0, 0, 0, 0);

		if (flags->replicate || flags->props || flags->backup ||
		    flags->holds) {
			nvlist_t *hdrnv;

			VERIFY(0 == nvlist_alloc(&hdrnv, NV_UNIQUE_NAME, 0));
			if (fromsnap) {
				VERIFY(0 == nvlist_add_string(hdrnv,
				    "fromsnap", fromsnap));
			}
			VERIFY(0 == nvlist_add_string(hdrnv, "tosnap", tosnap));
			if (!flags->replicate) {
				VERIFY(0 == nvlist_add_boolean(hdrnv,
				    "not_recursive"));
			}
			if (flags->raw) {
				VERIFY(0 == nvlist_add_boolean(hdrnv, "raw"));
			}

			err = gather_nvlist(zhp->zfs_hdl, zhp->zfs_name,
			    fromsnap, tosnap, flags->replicate, flags->raw,
			    flags->doall, flags->replicate, flags->verbose,
			    flags->backup, flags->holds, flags->props, &fss,
			    &fsavl);
			if (err)
				goto err_out;
			VERIFY(0 == nvlist_add_nvlist(hdrnv, "fss", fss));
			err = nvlist_pack(hdrnv, &packbuf, &buflen,
			    NV_ENCODE_XDR, 0);
			if (debugnvp)
				*debugnvp = hdrnv;
			else
				nvlist_free(hdrnv);
			if (err)
				goto stderr_out;
		}

		if (!flags->dryrun) {
			/* write first begin record */
			drr.drr_type = DRR_BEGIN;
			drr.drr_u.drr_begin.drr_magic = DMU_BACKUP_MAGIC;
			DMU_SET_STREAM_HDRTYPE(drr.drr_u.drr_begin.
			    drr_versioninfo, DMU_COMPOUNDSTREAM);
			DMU_SET_FEATUREFLAGS(drr.drr_u.drr_begin.
			    drr_versioninfo, featureflags);
			if (snprintf(drr.drr_u.drr_begin.drr_toname,
			    sizeof (drr.drr_u.drr_begin.drr_toname),
			    "%s@%s", zhp->zfs_name, tosnap) >=
			    sizeof (drr.drr_u.drr_begin.drr_toname)) {
				err = EINVAL;
				goto stderr_out;
			}
			drr.drr_payloadlen = buflen;

			err = dump_record(&drr, packbuf, buflen, &zc, outfd);
			free(packbuf);
			if (err != 0)
				goto stderr_out;

			/* write end record */
			bzero(&drr, sizeof (drr));
			drr.drr_type = DRR_END;
			drr.drr_u.drr_end.drr_checksum = zc;
			err = write(outfd, &drr, sizeof (drr));
			if (err == -1) {
				err = errno;
				goto stderr_out;
			}

			err = 0;
		}
	}

	/* dump each stream */
	sdd.fromsnap = fromsnap;
	sdd.tosnap = tosnap;
	if (tid != 0)
		sdd.outfd = pipefd[0];
	else
		sdd.outfd = outfd;
	sdd.replicate = flags->replicate;
	sdd.doall = flags->doall;
	sdd.fromorigin = flags->fromorigin;
	sdd.fss = fss;
	sdd.fsavl = fsavl;
	sdd.verbose = flags->verbose;
	sdd.parsable = flags->parsable;
	sdd.progress = flags->progress;
	sdd.dryrun = flags->dryrun;
	sdd.large_block = flags->largeblock;
	sdd.embed_data = flags->embed_data;
	sdd.block_diff = flags->block_diff;
	sdd.compress = flags->compress;
	sdd.raw = flags->raw;
	sdd.holds = flags->holds;
	sdd.filter_cb = filter_func;
	sdd.filter_cb_arg = cb_arg;
	if (debugnvp)
		sdd.debugnv = *debugnvp;
	if (sdd.verbose && sdd.dryrun)
		sdd.std_out = B_TRUE;
	fout = sdd.std_out ? stdout : stderr;

	/*
	 * Some flags require that we place user holds on the datasets that are
	 * being sent so they don't get destroyed during the send. We can skip
	 * this step if the pool is imported read-only since the datasets cannot
	 * be destroyed.
	 */
	if (!flags->dryrun && !zpool_get_prop_int(zfs_get_pool_handle(zhp),
	    ZPOOL_PROP_READONLY, NULL) &&
	    zfs_spa_version(zhp, &spa_version) == 0 &&
	    spa_version >= SPA_VERSION_USERREFS &&
	    (flags->doall || flags->replicate)) {
		++holdseq;
		(void) snprintf(sdd.holdtag, sizeof (sdd.holdtag),
		    ".send-%d-%llu", getpid(), (u_longlong_t)holdseq);
		sdd.cleanup_fd = open(ZFS_DEV, O_RDWR);
		if (sdd.cleanup_fd < 0) {
			err = errno;
			goto stderr_out;
		}
		sdd.snapholds = fnvlist_alloc();
	} else {
		sdd.cleanup_fd = -1;
		sdd.snapholds = NULL;
	}

	if (flags->verbose || sdd.snapholds != NULL) {
		/*
		 * Do a verbose no-op dry run to get all the verbose output
		 * or to gather snapshot hold's before generating any data,
		 * then do a non-verbose real run to generate the streams.
		 */
		sdd.dryrun = B_TRUE;
		err = dump_filesystems(zhp, &sdd);

		if (err != 0)
			goto stderr_out;

		if (flags->verbose) {
			if (flags->parsable) {
				(void) fprintf(fout, "size\t%llu\n",
				    (longlong_t)sdd.size);
			} else {
				char buf[16];
				zfs_nicebytes(sdd.size, buf, sizeof (buf));
				(void) fprintf(fout, dgettext(TEXT_DOMAIN,
				    "total estimated size is %s\n"), buf);
			}
		}

		/* Ensure no snaps found is treated as an error. */
		if (!sdd.seento) {
			err = ENOENT;
			goto err_out;
		}

		/* Skip the second run if dryrun was requested. */
		if (flags->dryrun)
			goto err_out;

		if (sdd.snapholds != NULL) {
			err = zfs_hold_nvl(zhp, sdd.cleanup_fd, sdd.snapholds);
			if (err != 0)
				goto stderr_out;

			fnvlist_free(sdd.snapholds);
			sdd.snapholds = NULL;
		}

		sdd.dryrun = B_FALSE;
		sdd.verbose = B_FALSE;
	}

	err = dump_filesystems(zhp, &sdd);
	fsavl_destroy(fsavl);
	nvlist_free(fss);

	/* Ensure no snaps found is treated as an error. */
	if (err == 0 && !sdd.seento)
		err = ENOENT;

	if (tid != 0) {
		if (err != 0)
			(void) pthread_cancel(tid);
		(void) close(pipefd[0]);
		(void) pthread_join(tid, NULL);
	}

	if (sdd.cleanup_fd != -1) {
		VERIFY(0 == close(sdd.cleanup_fd));
		sdd.cleanup_fd = -1;
	}

	if (!flags->dryrun && (flags->replicate || flags->doall ||
	    flags->props || flags->backup || flags->holds)) {
		/*
		 * write final end record.  NB: want to do this even if
		 * there was some error, because it might not be totally
		 * failed.
		 */
		dmu_replay_record_t drr = { 0 };
		drr.drr_type = DRR_END;
		if (write(outfd, &drr, sizeof (drr)) == -1) {
			return (zfs_standard_error(zhp->zfs_hdl,
			    errno, errbuf));
		}
	}

	return (err || sdd.err);

stderr_out:
	err = zfs_standard_error(zhp->zfs_hdl, err, errbuf);
err_out:
	fsavl_destroy(fsavl);
	nvlist_free(fss);
	fnvlist_free(sdd.snapholds);

	if (sdd.cleanup_fd != -1)
		VERIFY(0 == close(sdd.cleanup_fd));
	if (tid != 0) {
		(void) pthread_cancel(tid);
		(void) close(pipefd[0]);
		(void) pthread_join(tid, NULL);
	}
	return (err);
}

int
zfs_send_one(zfs_handle_t *zhp, const char *from, int fd, sendflags_t flags)
{
	int err = 0;
	libzfs_handle_t *hdl = zhp->zfs_hdl;
	enum lzc_send_flags lzc_flags = 0;
	FILE *fout = (flags.verbose && flags.dryrun) ? stdout : stderr;
	char errbuf[1024];

	if (flags.largeblock)
		lzc_flags |= LZC_SEND_FLAG_LARGE_BLOCK;
	if (flags.embed_data)
		lzc_flags |= LZC_SEND_FLAG_EMBED_DATA;
	if (flags.compress)
		lzc_flags |= LZC_SEND_FLAG_COMPRESS;
	if (flags.raw)
		lzc_flags |= LZC_SEND_FLAG_RAW;

	if (flags.verbose) {
		uint64_t size = 0;
		err = lzc_send_space(zhp->zfs_name, from, lzc_flags, &size);
		if (err == 0) {
			send_print_verbose(fout, zhp->zfs_name, from, size,
			    flags.parsable);
		} else {
			(void) fprintf(stderr, "Cannot estimate send size: "
			    "%s\n", strerror(errno));
		}
	}

	if (flags.dryrun)
		return (err);

	(void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
	    "warning: cannot send '%s'"), zhp->zfs_name);

	err = lzc_send(zhp->zfs_name, from, fd, lzc_flags);
	if (err != 0) {
		switch (errno) {
		case EXDEV:
			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
			    "not an earlier snapshot from the same fs"));
			return (zfs_error(hdl, EZFS_CROSSTARGET, errbuf));

		case ENOENT:
		case ESRCH:
			if (lzc_exists(zhp->zfs_name)) {
				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
				    "incremental source (%s) does not exist"),
				    from);
			}
			return (zfs_error(hdl, EZFS_NOENT, errbuf));

		case EACCES:
			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
			    "dataset key must be loaded"));
			return (zfs_error(hdl, EZFS_CRYPTOFAILED, errbuf));

		case EBUSY:
			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
			    "target is busy; if a filesystem, "
			    "it must not be mounted"));
			return (zfs_error(hdl, EZFS_BUSY, errbuf));

		case EDQUOT:
		case EFBIG:
		case EIO:
		case ENOLINK:
		case ENOSPC:
		case ENOSTR:
		case ENXIO:
		case EPIPE:
		case ERANGE:
		case EFAULT:
		case EROFS:
			zfs_error_aux(hdl, strerror(errno));
			return (zfs_error(hdl, EZFS_BADBACKUP, errbuf));

		default:
			return (zfs_standard_error(hdl, errno, errbuf));
		}
	}
	return (err != 0);
}

/*
 * Routines specific to "zfs recv"
 */

static int
recv_read(libzfs_handle_t *hdl, int fd, void *buf, int ilen,
    boolean_t byteswap, zio_cksum_t *zc)
{
	char *cp = buf;
	int rv;
	int len = ilen;

	assert(ilen <= SPA_MAXBLOCKSIZE);

	do {
		rv = read(fd, cp, len);
		cp += rv;
		len -= rv;
	} while (rv > 0);

	if (rv < 0 || len != 0) {
		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
		    "failed to read from stream"));
		return (zfs_error(hdl, EZFS_BADSTREAM, dgettext(TEXT_DOMAIN,
		    "cannot receive")));
	}

	if (zc) {
		if (byteswap)
			fletcher_4_incremental_byteswap(buf, ilen, zc);
		else
			fletcher_4_incremental_native(buf, ilen, zc);
	}
	return (0);
}

static int
recv_read_nvlist(libzfs_handle_t *hdl, int fd, int len, nvlist_t **nvp,
    boolean_t byteswap, zio_cksum_t *zc)
{
	char *buf;
	int err;

	buf = zfs_alloc(hdl, len);
	if (buf == NULL)
		return (ENOMEM);

	err = recv_read(hdl, fd, buf, len, byteswap, zc);
	if (err != 0) {
		free(buf);
		return (err);
	}

	err = nvlist_unpack(buf, len, nvp, 0);
	free(buf);
	if (err != 0) {
		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "invalid "
		    "stream (malformed nvlist)"));
		return (EINVAL);
	}
	return (0);
}

/*
 * Returns the grand origin (origin of origin of origin...) of a given handle.
 * If this dataset is not a clone, it simply returns a copy of the original
 * handle.
 */
static zfs_handle_t *
recv_open_grand_origin(zfs_handle_t *zhp)
{
	char origin[ZFS_MAX_DATASET_NAME_LEN];
	zprop_source_t src;
	zfs_handle_t *ozhp = zfs_handle_dup(zhp);

	while (ozhp != NULL) {
		if (zfs_prop_get(ozhp, ZFS_PROP_ORIGIN, origin,
		    sizeof (origin), &src, NULL, 0, B_FALSE) != 0)
			break;

		(void) zfs_close(ozhp);
		ozhp = zfs_open(zhp->zfs_hdl, origin, ZFS_TYPE_FILESYSTEM);
	}

	return (ozhp);
}

static int
recv_rename_impl(zfs_handle_t *zhp, const char *name, const char *newname)
{
	int err;
	zfs_handle_t *ozhp = NULL;

	/*
	 * Attempt to rename the dataset. If it fails with EACCES we have
	 * attempted to rename the dataset outside of its encryption root.
	 * Force the dataset to become an encryption root and try again.
	 */
	err = lzc_rename(name, newname);
	if (err == EACCES) {
		ozhp = recv_open_grand_origin(zhp);
		if (ozhp == NULL) {
			err = ENOENT;
			goto out;
		}

		err = lzc_change_key(ozhp->zfs_name, DCP_CMD_FORCE_NEW_KEY,
		    NULL, NULL, 0);
		if (err != 0)
			goto out;

		err = lzc_rename(name, newname);
	}

out:
	if (ozhp != NULL)
		zfs_close(ozhp);
	return (err);
}

static int
recv_rename(libzfs_handle_t *hdl, const char *name, const char *tryname,
    int baselen, char *newname, recvflags_t *flags)
{
	static int seq;
	int err;
	prop_changelist_t *clp = NULL;
	zfs_handle_t *zhp = NULL;

	zhp = zfs_open(hdl, name, ZFS_TYPE_DATASET);
	if (zhp == NULL) {
		err = -1;
		goto out;
	}
	clp = changelist_gather(zhp, ZFS_PROP_NAME, 0,
	    flags->force ? MS_FORCE : 0);
	if (clp == NULL) {
		err = -1;
		goto out;
	}
	err = changelist_prefix(clp);
	if (err)
		goto out;

	if (tryname) {
		(void) strcpy(newname, tryname);
		if (flags->verbose) {
			(void) printf("attempting rename %s to %s\n",
			    name, newname);
		}
		err = recv_rename_impl(zhp, name, newname);
		if (err == 0)
			changelist_rename(clp, name, tryname);
	} else {
		err = ENOENT;
	}

	if (err != 0 && strncmp(name + baselen, "recv-", 5) != 0) {
		seq++;

		(void) snprintf(newname, ZFS_MAX_DATASET_NAME_LEN,
		    "%.*srecv-%u-%u", baselen, name, getpid(), seq);

		if (flags->verbose) {
			(void) printf("failed - trying rename %s to %s\n",
			    name, newname);
		}
		err = recv_rename_impl(zhp, name, newname);
		if (err == 0)
			changelist_rename(clp, name, newname);
		if (err && flags->verbose) {
			(void) printf("failed (%u) - "
			    "will try again on next pass\n", errno);
		}
		err = EAGAIN;
	} else if (flags->verbose) {
		if (err == 0)
			(void) printf("success\n");
		else
			(void) printf("failed (%u)\n", errno);
	}

	(void) changelist_postfix(clp);

out:
	if (clp != NULL)
		changelist_free(clp);
	if (zhp != NULL)
		zfs_close(zhp);

	return (err);
}

static int
recv_promote(libzfs_handle_t *hdl, const char *fsname,
    const char *origin_fsname, recvflags_t *flags)
{
	int err;
	zfs_cmd_t zc = {"\0"};
	zfs_handle_t *zhp = NULL, *ozhp = NULL;

	if (flags->verbose)
		(void) printf("promoting %s\n", fsname);

	(void) strlcpy(zc.zc_value, origin_fsname, sizeof (zc.zc_value));
	(void) strlcpy(zc.zc_name, fsname, sizeof (zc.zc_name));

	/*
	 * Attempt to promote the dataset. If it fails with EACCES the
	 * promotion would cause this dataset to leave its encryption root.
	 * Force the origin to become an encryption root and try again.
	 */
	err = zfs_ioctl(hdl, ZFS_IOC_PROMOTE, &zc);
	if (err == EACCES) {
		zhp = zfs_open(hdl, fsname, ZFS_TYPE_DATASET);
		if (zhp == NULL) {
			err = -1;
			goto out;
		}

		ozhp = recv_open_grand_origin(zhp);
		if (ozhp == NULL) {
			err = -1;
			goto out;
		}

		err = lzc_change_key(ozhp->zfs_name, DCP_CMD_FORCE_NEW_KEY,
		    NULL, NULL, 0);
		if (err != 0)
			goto out;

		err = zfs_ioctl(hdl, ZFS_IOC_PROMOTE, &zc);
	}

out:
	if (zhp != NULL)
		zfs_close(zhp);
	if (ozhp != NULL)
		zfs_close(ozhp);

	return (err);
}

static int
recv_destroy(libzfs_handle_t *hdl, const char *name, int baselen,
    char *newname, recvflags_t *flags)
{
	int err = 0;
	prop_changelist_t *clp;
	zfs_handle_t *zhp;
	boolean_t defer = B_FALSE;
	int spa_version;

	zhp = zfs_open(hdl, name, ZFS_TYPE_DATASET);
	if (zhp == NULL)
		return (-1);
	clp = changelist_gather(zhp, ZFS_PROP_NAME, 0,
	    flags->force ? MS_FORCE : 0);
	if (zfs_get_type(zhp) == ZFS_TYPE_SNAPSHOT &&
	    zfs_spa_version(zhp, &spa_version) == 0 &&
	    spa_version >= SPA_VERSION_USERREFS)
		defer = B_TRUE;
	zfs_close(zhp);
	if (clp == NULL)
		return (-1);
	err = changelist_prefix(clp);
	if (err)
		return (err);

	if (flags->verbose)
		(void) printf("attempting destroy %s\n", name);
	if (zhp->zfs_type == ZFS_TYPE_SNAPSHOT) {
		nvlist_t *nv = fnvlist_alloc();
		fnvlist_add_boolean(nv, name);
		err = lzc_destroy_snaps(nv, defer, NULL);
		fnvlist_free(nv);
	} else {
		err = lzc_destroy(name);
	}
	if (err == 0) {
		if (flags->verbose)
			(void) printf("success\n");
		changelist_remove(clp, name);
	}

	(void) changelist_postfix(clp);
	changelist_free(clp);

	/*
	 * Deferred destroy might destroy the snapshot or only mark it to be
	 * destroyed later, and it returns success in either case.
	 */
	if (err != 0 || (defer && zfs_dataset_exists(hdl, name,
	    ZFS_TYPE_SNAPSHOT))) {
		err = recv_rename(hdl, name, NULL, baselen, newname, flags);
	}

	return (err);
}

typedef struct guid_to_name_data {
	uint64_t guid;
	boolean_t bookmark_ok;
	char *name;
	char *skip;
} guid_to_name_data_t;

static int
guid_to_name_cb(zfs_handle_t *zhp, void *arg)
{
	guid_to_name_data_t *gtnd = arg;
	const char *slash;
	int err;

	if (gtnd->skip != NULL &&
	    (slash = strrchr(zhp->zfs_name, '/')) != NULL &&
	    strcmp(slash + 1, gtnd->skip) == 0) {
		zfs_close(zhp);
		return (0);
	}

	if (zfs_prop_get_int(zhp, ZFS_PROP_GUID) == gtnd->guid) {
		(void) strcpy(gtnd->name, zhp->zfs_name);
		zfs_close(zhp);
		return (EEXIST);
	}

	err = zfs_iter_children(zhp, guid_to_name_cb, gtnd);
	if (err != EEXIST && gtnd->bookmark_ok)
		err = zfs_iter_bookmarks(zhp, guid_to_name_cb, gtnd);
	zfs_close(zhp);
	return (err);
}

/*
 * Attempt to find the local dataset associated with this guid.  In the case of
 * multiple matches, we attempt to find the "best" match by searching
 * progressively larger portions of the hierarchy.  This allows one to send a
 * tree of datasets individually and guarantee that we will find the source
 * guid within that hierarchy, even if there are multiple matches elsewhere.
 */
static int
guid_to_name(libzfs_handle_t *hdl, const char *parent, uint64_t guid,
    boolean_t bookmark_ok, char *name)
{
	char pname[ZFS_MAX_DATASET_NAME_LEN];
	guid_to_name_data_t gtnd;

	gtnd.guid = guid;
	gtnd.bookmark_ok = bookmark_ok;
	gtnd.name = name;
	gtnd.skip = NULL;

	/*
	 * Search progressively larger portions of the hierarchy, starting
	 * with the filesystem specified by 'parent'.  This will
	 * select the "most local" version of the origin snapshot in the case
	 * that there are multiple matching snapshots in the system.
	 */
	(void) strlcpy(pname, parent, sizeof (pname));
	char *cp = strrchr(pname, '@');
	if (cp == NULL)
		cp = strchr(pname, '\0');
	for (; cp != NULL; cp = strrchr(pname, '/')) {
		/* Chop off the last component and open the parent */
		*cp = '\0';
		zfs_handle_t *zhp = make_dataset_handle(hdl, pname);

		if (zhp == NULL)
			continue;
		int err = guid_to_name_cb(zfs_handle_dup(zhp), &gtnd);
		if (err != EEXIST)
			err = zfs_iter_children(zhp, guid_to_name_cb, &gtnd);
		if (err != EEXIST && bookmark_ok)
			err = zfs_iter_bookmarks(zhp, guid_to_name_cb, &gtnd);
		zfs_close(zhp);
		if (err == EEXIST)
			return (0);

		/*
		 * Remember the last portion of the dataset so we skip it next
		 * time through (as we've already searched that portion of the
		 * hierarchy).
		 */
		gtnd.skip = strrchr(pname, '/') + 1;
	}

	return (ENOENT);
}

/*
 * Return +1 if guid1 is before guid2, 0 if they are the same, and -1 if
 * guid1 is after guid2.
 */
static int
created_before(libzfs_handle_t *hdl, avl_tree_t *avl,
    uint64_t guid1, uint64_t guid2)
{
	nvlist_t *nvfs;
	char *fsname = NULL, *snapname = NULL;
	char buf[ZFS_MAX_DATASET_NAME_LEN];
	int rv;
	zfs_handle_t *guid1hdl, *guid2hdl;
	uint64_t create1, create2;

	if (guid2 == 0)
		return (0);
	if (guid1 == 0)
		return (1);

	nvfs = fsavl_find(avl, guid1, &snapname);
	VERIFY(0 == nvlist_lookup_string(nvfs, "name", &fsname));
	(void) snprintf(buf, sizeof (buf), "%s@%s", fsname, snapname);
	guid1hdl = zfs_open(hdl, buf, ZFS_TYPE_SNAPSHOT);
	if (guid1hdl == NULL)
		return (-1);

	nvfs = fsavl_find(avl, guid2, &snapname);
	VERIFY(0 == nvlist_lookup_string(nvfs, "name", &fsname));
	(void) snprintf(buf, sizeof (buf), "%s@%s", fsname, snapname);
	guid2hdl = zfs_open(hdl, buf, ZFS_TYPE_SNAPSHOT);
	if (guid2hdl == NULL) {
		zfs_close(guid1hdl);
		return (-1);
	}

	create1 = zfs_prop_get_int(guid1hdl, ZFS_PROP_CREATETXG);
	create2 = zfs_prop_get_int(guid2hdl, ZFS_PROP_CREATETXG);

	if (create1 < create2)
		rv = -1;
	else if (create1 > create2)
		rv = +1;
	else
		rv = 0;

	zfs_close(guid1hdl);
	zfs_close(guid2hdl);

	return (rv);
}

/*
 * This function reestablishes the hierarchy of encryption roots after a
 * recursive incremental receive has completed. This must be done after the
 * second call to recv_incremental_replication() has renamed and promoted all
 * sent datasets to their final locations in the dataset hierarchy.
 */
static int
recv_fix_encryption_hierarchy(libzfs_handle_t *hdl, const char *destname,
    nvlist_t *stream_nv, avl_tree_t *stream_avl)
{
	int err;
	nvpair_t *fselem = NULL;
	nvlist_t *stream_fss;
	char *cp;
	char top_zfs[ZFS_MAX_DATASET_NAME_LEN];

	(void) strcpy(top_zfs, destname);
	cp = strrchr(top_zfs, '@');
	if (cp != NULL)
		*cp = '\0';

	VERIFY(0 == nvlist_lookup_nvlist(stream_nv, "fss", &stream_fss));

	while ((fselem = nvlist_next_nvpair(stream_fss, fselem)) != NULL) {
		zfs_handle_t *zhp = NULL;
		uint64_t crypt;
		nvlist_t *snaps, *props, *stream_nvfs = NULL;
		nvpair_t *snapel = NULL;
		boolean_t is_encroot, is_clone, stream_encroot;
		char *cp;
		char *stream_keylocation = NULL;
		char keylocation[MAXNAMELEN];
		char fsname[ZFS_MAX_DATASET_NAME_LEN];

		keylocation[0] = '\0';
		VERIFY(0 == nvpair_value_nvlist(fselem, &stream_nvfs));
		VERIFY(0 == nvlist_lookup_nvlist(stream_nvfs, "snaps", &snaps));
		VERIFY(0 == nvlist_lookup_nvlist(stream_nvfs, "props", &props));
		stream_encroot = nvlist_exists(stream_nvfs, "is_encroot");

		/* find a snapshot from the stream that exists locally */
		err = ENOENT;
		while ((snapel = nvlist_next_nvpair(snaps, snapel)) != NULL) {
			uint64_t guid;

			VERIFY(0 == nvpair_value_uint64(snapel, &guid));
			err = guid_to_name(hdl, destname, guid, B_FALSE,
			    fsname);
			if (err == 0)
				break;
		}

		if (err != 0)
			continue;

		cp = strchr(fsname, '@');
		if (cp != NULL)
			*cp = '\0';

		zhp = zfs_open(hdl, fsname, ZFS_TYPE_DATASET);
		if (zhp == NULL) {
			err = ENOENT;
			goto error;
		}

		crypt = zfs_prop_get_int(zhp, ZFS_PROP_ENCRYPTION);
		is_clone = zhp->zfs_dmustats.dds_origin[0] != '\0';
		(void) zfs_crypto_get_encryption_root(zhp, &is_encroot, NULL);

		/* we don't need to do anything for unencrypted datasets */
		if (crypt == ZIO_CRYPT_OFF) {
			zfs_close(zhp);
			continue;
		}

		/*
		 * If the dataset is flagged as an encryption root, was not
		 * received as a clone and is not currently an encryption root,
		 * force it to become one. Fixup the keylocation if necessary.
		 */
		if (stream_encroot) {
			if (!is_clone && !is_encroot) {
				err = lzc_change_key(fsname,
				    DCP_CMD_FORCE_NEW_KEY, NULL, NULL, 0);
				if (err != 0) {
					zfs_close(zhp);
					goto error;
				}
			}

			VERIFY(0 == nvlist_lookup_string(props,
			    zfs_prop_to_name(ZFS_PROP_KEYLOCATION),
			    &stream_keylocation));

			/*
			 * Refresh the properties in case the call to
			 * lzc_change_key() changed the value.
			 */
			zfs_refresh_properties(zhp);
			err = zfs_prop_get(zhp, ZFS_PROP_KEYLOCATION,
			    keylocation, sizeof (keylocation), NULL, NULL,
			    0, B_TRUE);
			if (err != 0) {
				zfs_close(zhp);
				goto error;
			}

			if (strcmp(keylocation, stream_keylocation) != 0) {
				err = zfs_prop_set(zhp,
				    zfs_prop_to_name(ZFS_PROP_KEYLOCATION),
				    stream_keylocation);
				if (err != 0) {
					zfs_close(zhp);
					goto error;
				}
			}
		}

		/*
		 * If the dataset is not flagged as an encryption root and is
		 * currently an encryption root, force it to inherit from its
		 * parent. The root of a raw send should never be
		 * force-inherited.
		 */
		if (!stream_encroot && is_encroot &&
		    strcmp(top_zfs, fsname) != 0) {
			err = lzc_change_key(fsname, DCP_CMD_FORCE_INHERIT,
			    NULL, NULL, 0);
			if (err != 0) {
				zfs_close(zhp);
				goto error;
			}
		}

		zfs_close(zhp);
	}

	return (0);

error:
	return (err);
}

static int
recv_incremental_replication(libzfs_handle_t *hdl, const char *tofs,
    recvflags_t *flags, nvlist_t *stream_nv, avl_tree_t *stream_avl,
    nvlist_t *renamed)
{
	nvlist_t *local_nv, *deleted = NULL;
	avl_tree_t *local_avl;
	nvpair_t *fselem, *nextfselem;
	char *fromsnap;
	char newname[ZFS_MAX_DATASET_NAME_LEN];
	char guidname[32];
	int error;
	boolean_t needagain, progress, recursive;
	char *s1, *s2;

	VERIFY(0 == nvlist_lookup_string(stream_nv, "fromsnap", &fromsnap));

	recursive = (nvlist_lookup_boolean(stream_nv, "not_recursive") ==
	    ENOENT);

	if (flags->dryrun)
		return (0);

again:
	needagain = progress = B_FALSE;

	VERIFY(0 == nvlist_alloc(&deleted, NV_UNIQUE_NAME, 0));

	if ((error = gather_nvlist(hdl, tofs, fromsnap, NULL,
	    recursive, B_TRUE, B_FALSE, recursive, B_FALSE, B_FALSE,
	    B_FALSE, B_TRUE, &local_nv, &local_avl)) != 0)
		return (error);

	/*
	 * Process deletes and renames
	 */
	for (fselem = nvlist_next_nvpair(local_nv, NULL);
	    fselem; fselem = nextfselem) {
		nvlist_t *nvfs, *snaps;
		nvlist_t *stream_nvfs = NULL;
		nvpair_t *snapelem, *nextsnapelem;
		uint64_t fromguid = 0;
		uint64_t originguid = 0;
		uint64_t stream_originguid = 0;
		uint64_t parent_fromsnap_guid, stream_parent_fromsnap_guid;
		char *fsname, *stream_fsname;

		nextfselem = nvlist_next_nvpair(local_nv, fselem);

		VERIFY(0 == nvpair_value_nvlist(fselem, &nvfs));
		VERIFY(0 == nvlist_lookup_nvlist(nvfs, "snaps", &snaps));
		VERIFY(0 == nvlist_lookup_string(nvfs, "name", &fsname));
		VERIFY(0 == nvlist_lookup_uint64(nvfs, "parentfromsnap",
		    &parent_fromsnap_guid));
		(void) nvlist_lookup_uint64(nvfs, "origin", &originguid);

		/*
		 * First find the stream's fs, so we can check for
		 * a different origin (due to "zfs promote")
		 */
		for (snapelem = nvlist_next_nvpair(snaps, NULL);
		    snapelem; snapelem = nvlist_next_nvpair(snaps, snapelem)) {
			uint64_t thisguid;

			VERIFY(0 == nvpair_value_uint64(snapelem, &thisguid));
			stream_nvfs = fsavl_find(stream_avl, thisguid, NULL);

			if (stream_nvfs != NULL)
				break;
		}

		/* check for promote */
		(void) nvlist_lookup_uint64(stream_nvfs, "origin",
		    &stream_originguid);
		if (stream_nvfs && originguid != stream_originguid) {
			switch (created_before(hdl, local_avl,
			    stream_originguid, originguid)) {
			case 1: {
				/* promote it! */
				nvlist_t *origin_nvfs;
				char *origin_fsname;

				origin_nvfs = fsavl_find(local_avl, originguid,
				    NULL);
				VERIFY(0 == nvlist_lookup_string(origin_nvfs,
				    "name", &origin_fsname));
				error = recv_promote(hdl, fsname, origin_fsname,
				    flags);
				if (error == 0)
					progress = B_TRUE;
				break;
			}
			default:
				break;
			case -1:
				fsavl_destroy(local_avl);
				nvlist_free(local_nv);
				return (-1);
			}
			/*
			 * We had/have the wrong origin, therefore our
			 * list of snapshots is wrong.  Need to handle
			 * them on the next pass.
			 */
			needagain = B_TRUE;
			continue;
		}

		for (snapelem = nvlist_next_nvpair(snaps, NULL);
		    snapelem; snapelem = nextsnapelem) {
			uint64_t thisguid;
			char *stream_snapname;
			nvlist_t *found, *props;

			nextsnapelem = nvlist_next_nvpair(snaps, snapelem);

			VERIFY(0 == nvpair_value_uint64(snapelem, &thisguid));
			found = fsavl_find(stream_avl, thisguid,
			    &stream_snapname);

			/* check for delete */
			if (found == NULL) {
				char name[ZFS_MAX_DATASET_NAME_LEN];

				if (!flags->force)
					continue;

				(void) snprintf(name, sizeof (name), "%s@%s",
				    fsname, nvpair_name(snapelem));

				error = recv_destroy(hdl, name,
				    strlen(fsname)+1, newname, flags);
				if (error)
					needagain = B_TRUE;
				else
					progress = B_TRUE;
				sprintf(guidname, "%llu",
				    (u_longlong_t)thisguid);
				nvlist_add_boolean(deleted, guidname);
				continue;
			}

			stream_nvfs = found;

			if (0 == nvlist_lookup_nvlist(stream_nvfs, "snapprops",
			    &props) && 0 == nvlist_lookup_nvlist(props,
			    stream_snapname, &props)) {
				zfs_cmd_t zc = {"\0"};

				zc.zc_cookie = B_TRUE; /* received */
				(void) snprintf(zc.zc_name, sizeof (zc.zc_name),
				    "%s@%s", fsname, nvpair_name(snapelem));
				if (zcmd_write_src_nvlist(hdl, &zc,
				    props) == 0) {
					(void) zfs_ioctl(hdl,
					    ZFS_IOC_SET_PROP, &zc);
					zcmd_free_nvlists(&zc);
				}
			}

			/* check for different snapname */
			if (strcmp(nvpair_name(snapelem),
			    stream_snapname) != 0) {
				char name[ZFS_MAX_DATASET_NAME_LEN];
				char tryname[ZFS_MAX_DATASET_NAME_LEN];

				(void) snprintf(name, sizeof (name), "%s@%s",
				    fsname, nvpair_name(snapelem));
				(void) snprintf(tryname, sizeof (name), "%s@%s",
				    fsname, stream_snapname);

				error = recv_rename(hdl, name, tryname,
				    strlen(fsname)+1, newname, flags);
				if (error)
					needagain = B_TRUE;
				else
					progress = B_TRUE;
			}

			if (strcmp(stream_snapname, fromsnap) == 0)
				fromguid = thisguid;
		}

		/* check for delete */
		if (stream_nvfs == NULL) {
			if (!flags->force)
				continue;

			error = recv_destroy(hdl, fsname, strlen(tofs)+1,
			    newname, flags);
			if (error)
				needagain = B_TRUE;
			else
				progress = B_TRUE;
			sprintf(guidname, "%llu",
			    (u_longlong_t)parent_fromsnap_guid);
			nvlist_add_boolean(deleted, guidname);
			continue;
		}

		if (fromguid == 0) {
			if (flags->verbose) {
				(void) printf("local fs %s does not have "
				    "fromsnap (%s in stream); must have "
				    "been deleted locally; ignoring\n",
				    fsname, fromsnap);
			}
			continue;
		}

		VERIFY(0 == nvlist_lookup_string(stream_nvfs,
		    "name", &stream_fsname));
		VERIFY(0 == nvlist_lookup_uint64(stream_nvfs,
		    "parentfromsnap", &stream_parent_fromsnap_guid));

		s1 = strrchr(fsname, '/');
		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, "%llu",
			    (u_longlong_t)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.
		 */
		if ((stream_parent_fromsnap_guid != 0 &&
		    parent_fromsnap_guid != 0 &&
		    stream_parent_fromsnap_guid != parent_fromsnap_guid) ||
		    ((flags->isprefix || strcmp(tofs, fsname) != 0) &&
		    (s1 != NULL) && (s2 != NULL) && strcmp(s1, s2) != 0)) {
			nvlist_t *parent;
			char tryname[ZFS_MAX_DATASET_NAME_LEN];

			parent = fsavl_find(local_avl,
			    stream_parent_fromsnap_guid, NULL);
			/*
			 * NB: parent might not be found if we used the
			 * tosnap for stream_parent_fromsnap_guid,
			 * because the parent is a newly-created fs;
			 * we'll be able to rename it after we recv the
			 * new fs.
			 */
			if (parent != NULL) {
				char *pname;

				VERIFY(0 == nvlist_lookup_string(parent, "name",
				    &pname));
				(void) snprintf(tryname, sizeof (tryname),
				    "%s%s", pname, strrchr(stream_fsname, '/'));
			} else {
				tryname[0] = '\0';
				if (flags->verbose) {
					(void) printf("local fs %s new parent "
					    "not found\n", fsname);
				}
			}

			newname[0] = '\0';

			error = recv_rename(hdl, fsname, tryname,
			    strlen(tofs)+1, newname, flags);

			if (renamed != NULL && newname[0] != '\0') {
				VERIFY(0 == nvlist_add_boolean(renamed,
				    newname));
			}

			if (error)
				needagain = B_TRUE;
			else
				progress = B_TRUE;
		}
	}

doagain:
	fsavl_destroy(local_avl);
	nvlist_free(local_nv);
	nvlist_free(deleted);

	if (needagain && progress) {
		/* do another pass to fix up temporary names */
		if (flags->verbose)
			(void) printf("another pass:\n");
		goto again;
	}

	return (needagain || error != 0);
}

static int
zfs_receive_package(libzfs_handle_t *hdl, int fd, const char *destname,
    recvflags_t *flags, dmu_replay_record_t *drr, zio_cksum_t *zc,
    char **top_zfs, int cleanup_fd, uint64_t *action_handlep,
    nvlist_t *cmdprops)
{
	nvlist_t *stream_nv = NULL;
	avl_tree_t *stream_avl = NULL;
	char *fromsnap = NULL;
	char *sendsnap = NULL;
	char *cp;
	char tofs[ZFS_MAX_DATASET_NAME_LEN];
	char sendfs[ZFS_MAX_DATASET_NAME_LEN];
	char errbuf[1024];
	dmu_replay_record_t drre;
	int error;
	boolean_t anyerr = B_FALSE;
	boolean_t softerr = B_FALSE;
	boolean_t recursive, raw;

	(void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
	    "cannot receive"));

	assert(drr->drr_type == DRR_BEGIN);
	assert(drr->drr_u.drr_begin.drr_magic == DMU_BACKUP_MAGIC);
	assert(DMU_GET_STREAM_HDRTYPE(drr->drr_u.drr_begin.drr_versioninfo) ==
	    DMU_COMPOUNDSTREAM);

	/*
	 * Read in the nvlist from the stream.
	 */
	if (drr->drr_payloadlen != 0) {
		error = recv_read_nvlist(hdl, fd, drr->drr_payloadlen,
		    &stream_nv, flags->byteswap, zc);
		if (error) {
			error = zfs_error(hdl, EZFS_BADSTREAM, errbuf);
			goto out;
		}
	}

	recursive = (nvlist_lookup_boolean(stream_nv, "not_recursive") ==
	    ENOENT);
	raw = (nvlist_lookup_boolean(stream_nv, "raw") == 0);

	if (recursive && strchr(destname, '@')) {
		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
		    "cannot specify snapshot name for multi-snapshot stream"));
		error = zfs_error(hdl, EZFS_BADSTREAM, errbuf);
		goto out;
	}

	/*
	 * Read in the end record and verify checksum.
	 */
	if (0 != (error = recv_read(hdl, fd, &drre, sizeof (drre),
	    flags->byteswap, NULL)))
		goto out;
	if (flags->byteswap) {
		drre.drr_type = BSWAP_32(drre.drr_type);
		drre.drr_u.drr_end.drr_checksum.zc_word[0] =
		    BSWAP_64(drre.drr_u.drr_end.drr_checksum.zc_word[0]);
		drre.drr_u.drr_end.drr_checksum.zc_word[1] =
		    BSWAP_64(drre.drr_u.drr_end.drr_checksum.zc_word[1]);
		drre.drr_u.drr_end.drr_checksum.zc_word[2] =
		    BSWAP_64(drre.drr_u.drr_end.drr_checksum.zc_word[2]);
		drre.drr_u.drr_end.drr_checksum.zc_word[3] =
		    BSWAP_64(drre.drr_u.drr_end.drr_checksum.zc_word[3]);
	}
	if (drre.drr_type != DRR_END) {
		error = zfs_error(hdl, EZFS_BADSTREAM, errbuf);
		goto out;
	}
	if (!ZIO_CHECKSUM_EQUAL(drre.drr_u.drr_end.drr_checksum, *zc)) {
		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
		    "incorrect header checksum"));
		error = zfs_error(hdl, EZFS_BADSTREAM, errbuf);
		goto out;
	}

	(void) nvlist_lookup_string(stream_nv, "fromsnap", &fromsnap);

	if (drr->drr_payloadlen != 0) {
		nvlist_t *stream_fss;

		VERIFY(0 == nvlist_lookup_nvlist(stream_nv, "fss",
		    &stream_fss));
		if ((stream_avl = fsavl_create(stream_fss)) == NULL) {
			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
			    "couldn't allocate avl tree"));
			error = zfs_error(hdl, EZFS_NOMEM, errbuf);
			goto out;
		}

		if (fromsnap != NULL && recursive) {
			nvlist_t *renamed = NULL;
			nvpair_t *pair = NULL;

			(void) strlcpy(tofs, destname, sizeof (tofs));
			if (flags->isprefix) {
				struct drr_begin *drrb = &drr->drr_u.drr_begin;
				int i;

				if (flags->istail) {
					cp = strrchr(drrb->drr_toname, '/');
					if (cp == NULL) {
						(void) strlcat(tofs, "/",
						    sizeof (tofs));
						i = 0;
					} else {
						i = (cp - drrb->drr_toname);
					}
				} else {
					i = strcspn(drrb->drr_toname, "/@");
				}
				/* zfs_receive_one() will create_parents() */
				(void) strlcat(tofs, &drrb->drr_toname[i],
				    sizeof (tofs));
				*strchr(tofs, '@') = '\0';
			}

			if (!flags->dryrun && !flags->nomount) {
				VERIFY(0 == nvlist_alloc(&renamed,
				    NV_UNIQUE_NAME, 0));
			}

			softerr = recv_incremental_replication(hdl, tofs, flags,
			    stream_nv, stream_avl, renamed);

			/* Unmount renamed filesystems before receiving. */
			while ((pair = nvlist_next_nvpair(renamed,
			    pair)) != NULL) {
				zfs_handle_t *zhp;
				prop_changelist_t *clp = NULL;

				zhp = zfs_open(hdl, nvpair_name(pair),
				    ZFS_TYPE_FILESYSTEM);
				if (zhp != NULL) {
					clp = changelist_gather(zhp,
					    ZFS_PROP_MOUNTPOINT, 0, 0);
					zfs_close(zhp);
					if (clp != NULL) {
						softerr |=
						    changelist_prefix(clp);
						changelist_free(clp);
					}
				}
			}

			nvlist_free(renamed);
		}
	}

	/*
	 * Get the fs specified by the first path in the stream (the top level
	 * specified by 'zfs send') and pass it to each invocation of
	 * zfs_receive_one().
	 */
	(void) strlcpy(sendfs, drr->drr_u.drr_begin.drr_toname,
	    sizeof (sendfs));
	if ((cp = strchr(sendfs, '@')) != NULL) {
		*cp = '\0';
		/*
		 * Find the "sendsnap", the final snapshot in a replication
		 * stream.  zfs_receive_one() handles certain errors
		 * differently, depending on if the contained stream is the
		 * last one or not.
		 */
		sendsnap = (cp + 1);
	}

	/* Finally, receive each contained stream */
	do {
		/*
		 * we should figure out if it has a recoverable
		 * error, in which case do a recv_skip() and drive on.
		 * Note, if we fail due to already having this guid,
		 * zfs_receive_one() will take care of it (ie,
		 * recv_skip() and return 0).
		 */
		error = zfs_receive_impl(hdl, destname, NULL, flags, fd,
		    sendfs, stream_nv, stream_avl, top_zfs, cleanup_fd,
		    action_handlep, sendsnap, cmdprops);
		if (error == ENODATA) {
			error = 0;
			break;
		}
		anyerr |= error;
	} while (error == 0);

	if (drr->drr_payloadlen != 0 && recursive && fromsnap != NULL) {
		/*
		 * Now that we have the fs's they sent us, try the
		 * renames again.
		 */
		softerr = recv_incremental_replication(hdl, tofs, flags,
		    stream_nv, stream_avl, NULL);
	}

	if (raw && softerr == 0) {
		softerr = recv_fix_encryption_hierarchy(hdl, destname,
		    stream_nv, stream_avl);
	}

out:
	fsavl_destroy(stream_avl);
	nvlist_free(stream_nv);
	if (softerr)
		error = -2;
	if (anyerr)
		error = -1;
	return (error);
}

static void
trunc_prop_errs(int truncated)
{
	ASSERT(truncated != 0);

	if (truncated == 1)
		(void) fprintf(stderr, dgettext(TEXT_DOMAIN,
		    "1 more property could not be set\n"));
	else
		(void) fprintf(stderr, dgettext(TEXT_DOMAIN,
		    "%d more properties could not be set\n"), truncated);
}

static int
recv_skip(libzfs_handle_t *hdl, int fd, boolean_t byteswap)
{
	dmu_replay_record_t *drr;
	void *buf = zfs_alloc(hdl, SPA_MAXBLOCKSIZE);
	uint64_t payload_size;
	char errbuf[1024];

	(void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
	    "cannot receive"));

	/* XXX would be great to use lseek if possible... */
	drr = buf;

	while (recv_read(hdl, fd, drr, sizeof (dmu_replay_record_t),
	    byteswap, NULL) == 0) {
		if (byteswap)
			drr->drr_type = BSWAP_32(drr->drr_type);

		switch (drr->drr_type) {
		case DRR_BEGIN:
			if (drr->drr_payloadlen != 0) {
				(void) recv_read(hdl, fd, buf,
				    drr->drr_payloadlen, B_FALSE, NULL);
			}
			break;

		case DRR_END:
			free(buf);
			return (0);

		case DRR_OBJECT:
			if (byteswap) {
				drr->drr_u.drr_object.drr_bonuslen =
				    BSWAP_32(drr->drr_u.drr_object.
				    drr_bonuslen);
				drr->drr_u.drr_object.drr_raw_bonuslen =
				    BSWAP_32(drr->drr_u.drr_object.
				    drr_raw_bonuslen);
			}

			payload_size =
			    DRR_OBJECT_PAYLOAD_SIZE(&drr->drr_u.drr_object);
			(void) recv_read(hdl, fd, buf, payload_size,
			    B_FALSE, NULL);
			break;

		case DRR_WRITE:
			if (byteswap) {
				drr->drr_u.drr_write.drr_logical_size =
				    BSWAP_64(
				    drr->drr_u.drr_write.drr_logical_size);
				drr->drr_u.drr_write.drr_compressed_size =
				    BSWAP_64(
				    drr->drr_u.drr_write.drr_compressed_size);
			}
			payload_size =
			    DRR_WRITE_PAYLOAD_SIZE(&drr->drr_u.drr_write);
			(void) recv_read(hdl, fd, buf,
			    payload_size, B_FALSE, NULL);
			break;
		case DRR_SPILL:
			if (byteswap) {
				drr->drr_u.drr_spill.drr_length =
				    BSWAP_64(drr->drr_u.drr_spill.drr_length);
				drr->drr_u.drr_spill.drr_compressed_size =
				    BSWAP_64(drr->drr_u.drr_spill.
				    drr_compressed_size);
			}

			payload_size =
			    DRR_SPILL_PAYLOAD_SIZE(&drr->drr_u.drr_spill);
			(void) recv_read(hdl, fd, buf, payload_size,
			    B_FALSE, NULL);
			break;
		case DRR_WRITE_EMBEDDED:
			if (byteswap) {
				drr->drr_u.drr_write_embedded.drr_psize =
				    BSWAP_32(drr->drr_u.drr_write_embedded.
				    drr_psize);
			}
			(void) recv_read(hdl, fd, buf,
			    P2ROUNDUP(drr->drr_u.drr_write_embedded.drr_psize,
			    8), B_FALSE, NULL);
			break;
		case DRR_OBJECT_RANGE:
		case DRR_WRITE_BYREF:
		case DRR_FREEOBJECTS:
		case DRR_FREE:
			break;

		default:
			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
			    "invalid record type"));
			free(buf);
			return (zfs_error(hdl, EZFS_BADSTREAM, errbuf));
		}
	}

	free(buf);
	return (-1);
}

static void
recv_ecksum_set_aux(libzfs_handle_t *hdl, const char *target_snap,
    boolean_t resumable)
{
	char target_fs[ZFS_MAX_DATASET_NAME_LEN];

	zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
	    "checksum mismatch or incomplete stream"));

	if (!resumable)
		return;
	(void) strlcpy(target_fs, target_snap, sizeof (target_fs));
	*strchr(target_fs, '@') = '\0';
	zfs_handle_t *zhp = zfs_open(hdl, target_fs,
	    ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME);
	if (zhp == NULL)
		return;

	char token_buf[ZFS_MAXPROPLEN];
	int error = zfs_prop_get(zhp, ZFS_PROP_RECEIVE_RESUME_TOKEN,
	    token_buf, sizeof (token_buf),
	    NULL, NULL, 0, B_TRUE);
	if (error == 0) {
		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
		    "checksum mismatch or incomplete stream.\n"
		    "Partially received snapshot is saved.\n"
		    "A resuming stream can be generated on the sending "
		    "system by running:\n"
		    "    zfs send -t %s"),
		    token_buf);
	}
	zfs_close(zhp);
}

/*
 * Prepare a new nvlist of properties that are to override (-o) or be excluded
 * (-x) from the received dataset
 * recvprops: received properties from the send stream
 * cmdprops: raw input properties from command line
 * origprops: properties, both locally-set and received, currently set on the
 *            target dataset if it exists, NULL otherwise.
 * oxprops: valid output override (-o) and excluded (-x) properties
 */
static int
zfs_setup_cmdline_props(libzfs_handle_t *hdl, zfs_type_t type,
    char *fsname, boolean_t zoned, boolean_t recursive, boolean_t newfs,
    boolean_t raw, boolean_t toplevel, nvlist_t *recvprops, nvlist_t *cmdprops,
    nvlist_t *origprops, nvlist_t **oxprops, uint8_t **wkeydata_out,
    uint_t *wkeylen_out, const char *errbuf)
{
	nvpair_t *nvp;
	nvlist_t *oprops, *voprops;
	zfs_handle_t *zhp = NULL;
	zpool_handle_t *zpool_hdl = NULL;
	char *cp;
	int ret = 0;
	char namebuf[ZFS_MAX_DATASET_NAME_LEN];

	if (nvlist_empty(cmdprops))
		return (0); /* No properties to override or exclude */

	*oxprops = fnvlist_alloc();
	oprops = fnvlist_alloc();

	strlcpy(namebuf, fsname, ZFS_MAX_DATASET_NAME_LEN);

	/*
	 * Get our dataset handle. The target dataset may not exist yet.
	 */
	if (zfs_dataset_exists(hdl, namebuf, ZFS_TYPE_DATASET)) {
		zhp = zfs_open(hdl, namebuf, ZFS_TYPE_DATASET);
		if (zhp == NULL) {
			ret = -1;
			goto error;
		}
	}

	/* open the zpool handle */
	cp = strchr(namebuf, '/');
	if (cp != NULL)
		*cp = '\0';
	zpool_hdl = zpool_open(hdl, namebuf);
	if (zpool_hdl == NULL) {
		ret = -1;
		goto error;
	}

	/* restore namebuf to match fsname for later use */
	if (cp != NULL)
		*cp = '/';

	/*
	 * first iteration: process excluded (-x) properties now and gather
	 * added (-o) properties to be later processed by zfs_valid_proplist()
	 */
	nvp = NULL;
	while ((nvp = nvlist_next_nvpair(cmdprops, nvp)) != NULL) {
		const char *name = nvpair_name(nvp);
		zfs_prop_t prop = zfs_name_to_prop(name);

		/* "origin" is processed separately, don't handle it here */
		if (prop == ZFS_PROP_ORIGIN)
			continue;

		/*
		 * we're trying to override or exclude a property that does not
		 * make sense for this type of dataset, but we don't want to
		 * fail if the receive is recursive: this comes in handy when
		 * the send stream contains, for instance, a child ZVOL and
		 * we're trying to receive it with "-o atime=on"
		 */
		if (!zfs_prop_valid_for_type(prop, type, B_FALSE) &&
		    !zfs_prop_user(name)) {
			if (recursive)
				continue;
			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
			    "property '%s' does not apply to datasets of this "
			    "type"), name);
			ret = zfs_error(hdl, EZFS_BADPROP, errbuf);
			goto error;
		}

		/* raw streams can't override encryption properties */
		if ((zfs_prop_encryption_key_param(prop) ||
		    prop == ZFS_PROP_ENCRYPTION) && raw) {
			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
			    "encryption property '%s' cannot "
			    "be set or excluded for raw streams."), name);
			ret = zfs_error(hdl, EZFS_BADPROP, errbuf);
			goto error;
		}

		/* incremental streams can only exclude encryption properties */
		if ((zfs_prop_encryption_key_param(prop) ||
		    prop == ZFS_PROP_ENCRYPTION) && !newfs &&
		    nvpair_type(nvp) != DATA_TYPE_BOOLEAN) {
			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
			    "encryption property '%s' cannot "
			    "be set for incremental streams."), name);
			ret = zfs_error(hdl, EZFS_BADPROP, errbuf);
			goto error;
		}

		switch (nvpair_type(nvp)) {
		case DATA_TYPE_BOOLEAN: /* -x property */
			/*
			 * DATA_TYPE_BOOLEAN is the way we're asked to "exclude"
			 * a property: this is done by forcing an explicit
			 * inherit on the destination so the effective value is
			 * not the one we received from the send stream.
			 * We do this only if the property is not already
			 * locally-set, in which case its value will take
			 * priority over the received anyway.
			 */
			if (nvlist_exists(origprops, name)) {
				nvlist_t *attrs;
				char *source = NULL;

				attrs = fnvlist_lookup_nvlist(origprops, name);
				if (nvlist_lookup_string(attrs,
				    ZPROP_SOURCE, &source) == 0 &&
				    strcmp(source, ZPROP_SOURCE_VAL_RECVD) != 0)
					continue;
			}
			/*
			 * We can't force an explicit inherit on non-inheritable
			 * properties: if we're asked to exclude this kind of
			 * values we remove them from "recvprops" input nvlist.
			 */
			if (!zfs_prop_inheritable(prop) &&
			    !zfs_prop_user(name) && /* can be inherited too */
			    nvlist_exists(recvprops, name))
				fnvlist_remove(recvprops, name);
			else
				fnvlist_add_nvpair(*oxprops, nvp);
			break;
		case DATA_TYPE_STRING: /* -o property=value */
			fnvlist_add_nvpair(oprops, nvp);
			break;
		default:
			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
			    "property '%s' must be a string or boolean"), name);
			ret = zfs_error(hdl, EZFS_BADPROP, errbuf);
			goto error;
		}
	}

	if (toplevel) {
		/* convert override strings properties to native */
		if ((voprops = zfs_valid_proplist(hdl, ZFS_TYPE_DATASET,
		    oprops, zoned, zhp, zpool_hdl, B_FALSE, errbuf)) == NULL) {
			ret = zfs_error(hdl, EZFS_BADPROP, errbuf);
			goto error;
		}

		/*
		 * zfs_crypto_create() requires the parent name. Get it
		 * by truncating the fsname copy stored in namebuf.
		 */
		cp = strrchr(namebuf, '/');
		if (cp != NULL)
			*cp = '\0';

		if (!raw && zfs_crypto_create(hdl, namebuf, voprops, NULL,
		    B_FALSE, wkeydata_out, wkeylen_out) != 0) {
			fnvlist_free(voprops);
			ret = zfs_error(hdl, EZFS_CRYPTOFAILED, errbuf);
			goto error;
		}

		/* second pass: process "-o" properties */
		fnvlist_merge(*oxprops, voprops);
		fnvlist_free(voprops);
	} else {
		/* override props on child dataset are inherited */
		nvp = NULL;
		while ((nvp = nvlist_next_nvpair(oprops, nvp)) != NULL) {
			const char *name = nvpair_name(nvp);
			fnvlist_add_boolean(*oxprops, name);
		}
	}

error:
	if (zhp != NULL)
		zfs_close(zhp);
	if (zpool_hdl != NULL)
		zpool_close(zpool_hdl);
	fnvlist_free(oprops);
	return (ret);
}

/*
 * Restores a backup of tosnap from the file descriptor specified by infd.
 */
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,
    avl_tree_t *stream_avl, char **top_zfs, int cleanup_fd,
    uint64_t *action_handlep, const char *finalsnap, nvlist_t *cmdprops)
{
	time_t begin_time;
	int ioctl_err, ioctl_errno, err;
	char *cp;
	struct drr_begin *drrb = &drr->drr_u.drr_begin;
	char errbuf[1024];
	const char *chopprefix;
	boolean_t newfs = B_FALSE;
	boolean_t stream_wantsnewfs;
	boolean_t newprops = B_FALSE;
	uint64_t read_bytes = 0;
	uint64_t errflags = 0;
	uint64_t parent_snapguid = 0;
	prop_changelist_t *clp = NULL;
	nvlist_t *snapprops_nvlist = NULL;
	nvlist_t *snapholds_nvlist = NULL;
	zprop_errflags_t prop_errflags;
	nvlist_t *prop_errors = NULL;
	boolean_t recursive;
	char *snapname = NULL;
	char destsnap[MAXPATHLEN * 2];
	char origin[MAXNAMELEN];
	char name[MAXPATHLEN];
	char tmp_keylocation[MAXNAMELEN];
	nvlist_t *rcvprops = NULL; /* props received from the send stream */
	nvlist_t *oxprops = NULL; /* override (-o) and exclude (-x) props */
	nvlist_t *origprops = NULL; /* original props (if destination exists) */
	zfs_type_t type;
	boolean_t toplevel = B_FALSE;
	boolean_t zoned = B_FALSE;
	boolean_t hastoken = B_FALSE;
	uint8_t *wkeydata = NULL;
	uint_t wkeylen = 0;

	begin_time = time(NULL);
	bzero(origin, MAXNAMELEN);
	bzero(tmp_keylocation, MAXNAMELEN);

	(void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
	    "cannot receive"));

	recursive = (nvlist_lookup_boolean(stream_nv, "not_recursive") ==
	    ENOENT);

	/* Did the user request holds be skipped via zfs recv -k? */
	boolean_t holds = flags->holds && !flags->skipholds;

	if (stream_avl != NULL) {
		char *keylocation = NULL;
		nvlist_t *lookup = NULL;
		nvlist_t *fs = fsavl_find(stream_avl, drrb->drr_toguid,
		    &snapname);

		(void) nvlist_lookup_uint64(fs, "parentfromsnap",
		    &parent_snapguid);
		err = nvlist_lookup_nvlist(fs, "props", &rcvprops);
		if (err) {
			VERIFY(0 == nvlist_alloc(&rcvprops, NV_UNIQUE_NAME, 0));
			newprops = B_TRUE;
		}

		/*
		 * The keylocation property may only be set on encryption roots,
		 * but this dataset might not become an encryption root until
		 * recv_fix_encryption_hierarchy() is called. That function
		 * will fixup the keylocation anyway, so we temporarily unset
		 * the keylocation for now to avoid any errors from the receive
		 * ioctl.
		 */
		err = nvlist_lookup_string(rcvprops,
		    zfs_prop_to_name(ZFS_PROP_KEYLOCATION), &keylocation);
		if (err == 0) {
			strcpy(tmp_keylocation, keylocation);
			(void) nvlist_remove_all(rcvprops,
			    zfs_prop_to_name(ZFS_PROP_KEYLOCATION));
		}

		if (flags->canmountoff) {
			VERIFY(0 == nvlist_add_uint64(rcvprops,
			    zfs_prop_to_name(ZFS_PROP_CANMOUNT), 0));
		} else if (newprops) {	/* nothing in rcvprops, eliminate it */
			nvlist_free(rcvprops);
			rcvprops = NULL;
			newprops = B_FALSE;
		}
		if (0 == nvlist_lookup_nvlist(fs, "snapprops", &lookup)) {
			VERIFY(0 == nvlist_lookup_nvlist(lookup,
			    snapname, &snapprops_nvlist));
		}
		if (holds) {
			if (0 == nvlist_lookup_nvlist(fs, "snapholds",
			    &lookup)) {
				VERIFY(0 == nvlist_lookup_nvlist(lookup,
				    snapname, &snapholds_nvlist));
			}
		}
	}

	cp = NULL;

	/*
	 * Determine how much of the snapshot name stored in the stream
	 * we are going to tack on to the name they specified on the
	 * command line, and how much we are going to chop off.
	 *
	 * If they specified a snapshot, chop the entire name stored in
	 * the stream.
	 */
	if (flags->istail) {
		/*
		 * A filesystem was specified with -e. We want to tack on only
		 * the tail of the sent snapshot path.
		 */
		if (strchr(tosnap, '@')) {
			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "invalid "
			    "argument - snapshot not allowed with -e"));
			err = zfs_error(hdl, EZFS_INVALIDNAME, errbuf);
			goto out;
		}

		chopprefix = strrchr(sendfs, '/');

		if (chopprefix == NULL) {
			/*
			 * The tail is the poolname, so we need to
			 * prepend a path separator.
			 */
			int len = strlen(drrb->drr_toname);
			cp = malloc(len + 2);
			cp[0] = '/';
			(void) strcpy(&cp[1], drrb->drr_toname);
			chopprefix = cp;
		} else {
			chopprefix = drrb->drr_toname + (chopprefix - sendfs);
		}
	} else if (flags->isprefix) {
		/*
		 * A filesystem was specified with -d. We want to tack on
		 * everything but the first element of the sent snapshot path
		 * (all but the pool name).
		 */
		if (strchr(tosnap, '@')) {
			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "invalid "
			    "argument - snapshot not allowed with -d"));
			err = zfs_error(hdl, EZFS_INVALIDNAME, errbuf);
			goto out;
		}

		chopprefix = strchr(drrb->drr_toname, '/');
		if (chopprefix == NULL)
			chopprefix = strchr(drrb->drr_toname, '@');
	} else if (strchr(tosnap, '@') == NULL) {
		/*
		 * If a filesystem was specified without -d or -e, we want to
		 * tack on everything after the fs specified by 'zfs send'.
		 */
		chopprefix = drrb->drr_toname + strlen(sendfs);
	} else {
		/* A snapshot was specified as an exact path (no -d or -e). */
		if (recursive) {
			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
			    "cannot specify snapshot name for multi-snapshot "
			    "stream"));
			err = zfs_error(hdl, EZFS_BADSTREAM, errbuf);
			goto out;
		}
		chopprefix = drrb->drr_toname + strlen(drrb->drr_toname);
	}

	ASSERT(strstr(drrb->drr_toname, sendfs) == drrb->drr_toname);
	ASSERT(chopprefix > drrb->drr_toname || strchr(sendfs, '/') == NULL);
	ASSERT(chopprefix <= drrb->drr_toname + strlen(drrb->drr_toname) ||
	    strchr(sendfs, '/') == NULL);
	ASSERT(chopprefix[0] == '/' || chopprefix[0] == '@' ||
	    chopprefix[0] == '\0');

	/*
	 * Determine name of destination snapshot.
	 */
	(void) strlcpy(destsnap, tosnap, sizeof (destsnap));
	(void) strlcat(destsnap, chopprefix, sizeof (destsnap));
	free(cp);
	if (!zfs_name_valid(destsnap, ZFS_TYPE_SNAPSHOT)) {
		err = zfs_error(hdl, EZFS_INVALIDNAME, errbuf);
		goto out;
	}

	/*
	 * Determine the name of the origin snapshot.
	 */
	if (originsnap) {
		(void) strlcpy(origin, originsnap, sizeof (origin));
		if (flags->verbose)
			(void) printf("using provided clone origin %s\n",
			    origin);
	} else if (drrb->drr_flags & DRR_FLAG_CLONE) {
		if (guid_to_name(hdl, destsnap,
		    drrb->drr_fromguid, B_FALSE, origin) != 0) {
			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
			    "local origin for clone %s does not exist"),
			    destsnap);
			err = zfs_error(hdl, EZFS_NOENT, errbuf);
			goto out;
		}
		if (flags->verbose)
			(void) printf("found clone origin %s\n", origin);
	}

	if (!hdl->libzfs_dedup_warning_printed &&
	    (DMU_GET_FEATUREFLAGS(drrb->drr_versioninfo) &
	    DMU_BACKUP_FEATURE_DEDUP)) {
		(void) fprintf(stderr,
		    gettext("WARNING: This is a deduplicated send stream.  "
		    "The ability to send and\n"
		    "receive deduplicated send streams is deprecated.  "
		    "In the future, the\n"
		    "ability to receive a deduplicated send stream with "
		    "\"zfs receive\" will be\n"
		    "removed. However, in the future, a utility will be "
		    "provided to convert a\n"
		    "deduplicated send stream to a regular "
		    "(non-deduplicated) stream. This\n"
		    "future utility will require that the send stream be "
		    "located in a\n"
		    "seek-able file, rather than provided by a pipe.\n\n"));
		hdl->libzfs_dedup_warning_printed = B_TRUE;
	}

	boolean_t resuming = DMU_GET_FEATUREFLAGS(drrb->drr_versioninfo) &
	    DMU_BACKUP_FEATURE_RESUMING;
	boolean_t raw = DMU_GET_FEATUREFLAGS(drrb->drr_versioninfo) &
	    DMU_BACKUP_FEATURE_RAW;
	boolean_t embedded = DMU_GET_FEATUREFLAGS(drrb->drr_versioninfo) &
	    DMU_BACKUP_FEATURE_EMBED_DATA;
	stream_wantsnewfs = (drrb->drr_fromguid == 0 ||
	    (drrb->drr_flags & DRR_FLAG_CLONE) || originsnap) && !resuming;

	if (stream_wantsnewfs) {
		/*
		 * if the parent fs does not exist, look for it based on
		 * the parent snap GUID
		 */
		(void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
		    "cannot receive new filesystem stream"));

		(void) strcpy(name, destsnap);
		cp = strrchr(name, '/');
		if (cp)
			*cp = '\0';
		if (cp &&
		    !zfs_dataset_exists(hdl, name, ZFS_TYPE_DATASET)) {
			char suffix[ZFS_MAX_DATASET_NAME_LEN];
			(void) strcpy(suffix, strrchr(destsnap, '/'));
			if (guid_to_name(hdl, name, parent_snapguid,
			    B_FALSE, destsnap) == 0) {
				*strchr(destsnap, '@') = '\0';
				(void) strcat(destsnap, suffix);
			}
		}
	} else {
		/*
		 * If the fs does not exist, look for it based on the
		 * fromsnap GUID.
		 */
		if (resuming) {
			(void) snprintf(errbuf, sizeof (errbuf),
			    dgettext(TEXT_DOMAIN,
			    "cannot receive resume stream"));
		} else {
			(void) snprintf(errbuf, sizeof (errbuf),
			    dgettext(TEXT_DOMAIN,
			    "cannot receive incremental stream"));
		}

		(void) strcpy(name, destsnap);
		*strchr(name, '@') = '\0';

		/*
		 * If the exact receive path was specified and this is the
		 * topmost path in the stream, then if the fs does not exist we
		 * should look no further.
		 */
		if ((flags->isprefix || (*(chopprefix = drrb->drr_toname +
		    strlen(sendfs)) != '\0' && *chopprefix != '@')) &&
		    !zfs_dataset_exists(hdl, name, ZFS_TYPE_DATASET)) {
			char snap[ZFS_MAX_DATASET_NAME_LEN];
			(void) strcpy(snap, strchr(destsnap, '@'));
			if (guid_to_name(hdl, name, drrb->drr_fromguid,
			    B_FALSE, destsnap) == 0) {
				*strchr(destsnap, '@') = '\0';
				(void) strcat(destsnap, snap);
			}
		}
	}

	(void) strcpy(name, destsnap);
	*strchr(name, '@') = '\0';

	if (zfs_dataset_exists(hdl, name, ZFS_TYPE_DATASET)) {
		zfs_cmd_t zc = {"\0"};
		zfs_handle_t *zhp;
		boolean_t encrypted;

		(void) strcpy(zc.zc_name, name);

		/*
		 * Destination fs exists.  It must be one of these cases:
		 *  - an incremental send stream
		 *  - the stream specifies a new fs (full stream or clone)
		 *    and they want us to blow away the existing fs (and
		 *    have therefore specified -F and removed any snapshots)
		 *  - we are resuming a failed receive.
		 */
		if (stream_wantsnewfs) {
			boolean_t is_volume = drrb->drr_type == DMU_OST_ZVOL;
			if (!flags->force) {
				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
				    "destination '%s' exists\n"
				    "must specify -F to overwrite it"), name);
				err = zfs_error(hdl, EZFS_EXISTS, errbuf);
				goto out;
			}
			if (ioctl(hdl->libzfs_fd, ZFS_IOC_SNAPSHOT_LIST_NEXT,
			    &zc) == 0) {
				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
				    "destination has snapshots (eg. %s)\n"
				    "must destroy them to overwrite it"),
				    zc.zc_name);
				err = zfs_error(hdl, EZFS_EXISTS, errbuf);
				goto out;
			}
			if (is_volume && strrchr(name, '/') == NULL) {
				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
				    "destination %s is the root dataset\n"
				    "cannot overwrite with a ZVOL"),
				    name);
				err = zfs_error(hdl, EZFS_EXISTS, errbuf);
				goto out;
			}
			if (is_volume &&
			    ioctl(hdl->libzfs_fd, ZFS_IOC_DATASET_LIST_NEXT,
			    &zc) == 0) {
				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
				    "destination has children (eg. %s)\n"
				    "cannot overwrite with a ZVOL"),
				    zc.zc_name);
				err = zfs_error(hdl, EZFS_WRONG_PARENT, errbuf);
				goto out;
			}
		}

		if ((zhp = zfs_open(hdl, name,
		    ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME)) == NULL) {
			err = -1;
			goto out;
		}

		if (stream_wantsnewfs &&
		    zhp->zfs_dmustats.dds_origin[0]) {
			zfs_close(zhp);
			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
			    "destination '%s' is a clone\n"
			    "must destroy it to overwrite it"), name);
			err = zfs_error(hdl, EZFS_EXISTS, errbuf);
			goto out;
		}

		/*
		 * Raw sends can not be performed as an incremental on top
		 * of existing unencrypted datasets. zfs recv -F can't be
		 * used to blow away an existing encrypted filesystem. This
		 * is because it would require the dsl dir to point to the
		 * new key (or lack of a key) and the old key at the same
		 * time. The -F flag may still be used for deleting
		 * intermediate snapshots that would otherwise prevent the
		 * receive from working.
		 */
		encrypted = zfs_prop_get_int(zhp, ZFS_PROP_ENCRYPTION) !=
		    ZIO_CRYPT_OFF;
		if (!stream_wantsnewfs && !encrypted && raw) {
			zfs_close(zhp);
			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
			    "cannot perform raw receive on top of "
			    "existing unencrypted dataset"));
			err = zfs_error(hdl, EZFS_BADRESTORE, errbuf);
			goto out;
		}

		if (stream_wantsnewfs && flags->force &&
		    ((raw && !encrypted) || encrypted)) {
			zfs_close(zhp);
			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
			    "zfs receive -F cannot be used to destroy an "
			    "encrypted filesystem or overwrite an "
			    "unencrypted one with an encrypted one"));
			err = zfs_error(hdl, EZFS_BADRESTORE, errbuf);
			goto out;
		}

		if (!flags->dryrun && zhp->zfs_type == ZFS_TYPE_FILESYSTEM &&
		    stream_wantsnewfs) {
			/* We can't do online recv in this case */
			clp = changelist_gather(zhp, ZFS_PROP_NAME, 0, 0);
			if (clp == NULL) {
				zfs_close(zhp);
				err = -1;
				goto out;
			}
			if (changelist_prefix(clp) != 0) {
				changelist_free(clp);
				zfs_close(zhp);
				err = -1;
				goto out;
			}
		}

		/*
		 * If we are resuming a newfs, set newfs here so that we will
		 * mount it if the recv succeeds this time.  We can tell
		 * that it was a newfs on the first recv because the fs
		 * itself will be inconsistent (if the fs existed when we
		 * did the first recv, we would have received it into
		 * .../%recv).
		 */
		if (resuming && zfs_prop_get_int(zhp, ZFS_PROP_INCONSISTENT))
			newfs = B_TRUE;

		/* we want to know if we're zoned when validating -o|-x props */
		zoned = zfs_prop_get_int(zhp, ZFS_PROP_ZONED);

		/* may need this info later, get it now we have zhp around */
		if (zfs_prop_get(zhp, ZFS_PROP_RECEIVE_RESUME_TOKEN, NULL, 0,
		    NULL, NULL, 0, B_TRUE) == 0)
			hastoken = B_TRUE;

		/* gather existing properties on destination */
		origprops = fnvlist_alloc();
		fnvlist_merge(origprops, zhp->zfs_props);
		fnvlist_merge(origprops, zhp->zfs_user_props);

		zfs_close(zhp);
	} else {
		zfs_handle_t *zhp;

		/*
		 * Destination filesystem does not exist.  Therefore we better
		 * be creating a new filesystem (either from a full backup, or
		 * a clone).  It would therefore be invalid if the user
		 * specified only the pool name (i.e. if the destination name
		 * contained no slash character).
		 */
		cp = strrchr(name, '/');

		if (!stream_wantsnewfs || cp == NULL) {
			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
			    "destination '%s' does not exist"), name);
			err = zfs_error(hdl, EZFS_NOENT, errbuf);
			goto out;
		}

		/*
		 * Trim off the final dataset component so we perform the
		 * recvbackup ioctl to the filesystems's parent.
		 */
		*cp = '\0';

		if (flags->isprefix && !flags->istail && !flags->dryrun &&
		    create_parents(hdl, destsnap, strlen(tosnap)) != 0) {
			err = zfs_error(hdl, EZFS_BADRESTORE, errbuf);
			goto out;
		}

		/* validate parent */
		zhp = zfs_open(hdl, name, ZFS_TYPE_DATASET);
		if (zhp == NULL) {
			err = zfs_error(hdl, EZFS_BADRESTORE, errbuf);
			goto out;
		}
		if (zfs_get_type(zhp) != ZFS_TYPE_FILESYSTEM) {
			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
			    "parent '%s' is not a filesystem"), name);
			err = zfs_error(hdl, EZFS_WRONG_PARENT, errbuf);
			zfs_close(zhp);
			goto out;
		}

		zfs_close(zhp);

		newfs = B_TRUE;
		*cp = '/';
	}

	if (flags->verbose) {
		(void) printf("%s %s stream of %s into %s\n",
		    flags->dryrun ? "would receive" : "receiving",
		    drrb->drr_fromguid ? "incremental" : "full",
		    drrb->drr_toname, destsnap);
		(void) fflush(stdout);
	}

	if (flags->dryrun) {
		void *buf = zfs_alloc(hdl, SPA_MAXBLOCKSIZE);

		/*
		 * We have read the DRR_BEGIN record, but we have
		 * not yet read the payload. For non-dryrun sends
		 * this will be done by the kernel, so we must
		 * emulate that here, before attempting to read
		 * more records.
		 */
		err = recv_read(hdl, infd, buf, drr->drr_payloadlen,
		    flags->byteswap, NULL);
		free(buf);
		if (err != 0)
			goto out;

		err = recv_skip(hdl, infd, flags->byteswap);
		goto out;
	}

	if (top_zfs && (*top_zfs == NULL || strcmp(*top_zfs, name) == 0))
		toplevel = B_TRUE;
	if (drrb->drr_type == DMU_OST_ZVOL) {
		type = ZFS_TYPE_VOLUME;
	} else if (drrb->drr_type == DMU_OST_ZFS) {
		type = ZFS_TYPE_FILESYSTEM;
	} else {
		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
		    "invalid record type: 0x%d"), drrb->drr_type);
		err = zfs_error(hdl, EZFS_BADSTREAM, errbuf);
		goto out;
	}
	if ((err = zfs_setup_cmdline_props(hdl, type, name, zoned, recursive,
	    stream_wantsnewfs, raw, toplevel, rcvprops, cmdprops, origprops,
	    &oxprops, &wkeydata, &wkeylen, errbuf)) != 0)
		goto out;

	/*
	 * When sending with properties (zfs send -p), the encryption property
	 * is not included because it is a SETONCE property and therefore
	 * treated as read only. However, we are always able to determine its
	 * value because raw sends will include it in the DRR_BDEGIN payload
	 * and non-raw sends with properties are not allowed for encrypted
	 * datasets. Therefore, if this is a non-raw properties stream, we can
	 * infer that the value should be ZIO_CRYPT_OFF and manually add that
	 * to the received properties.
	 */
	if (stream_wantsnewfs && !raw && rcvprops != NULL &&
	    !nvlist_exists(cmdprops, zfs_prop_to_name(ZFS_PROP_ENCRYPTION))) {
		if (oxprops == NULL)
			oxprops = fnvlist_alloc();
		fnvlist_add_uint64(oxprops,
		    zfs_prop_to_name(ZFS_PROP_ENCRYPTION), ZIO_CRYPT_OFF);
	}

	err = ioctl_err = lzc_receive_with_cmdprops(destsnap, rcvprops,
	    oxprops, wkeydata, wkeylen, origin, flags->force, flags->resumable,
	    raw, infd, drr_noswap, cleanup_fd, &read_bytes, &errflags,
	    action_handlep, &prop_errors);
	ioctl_errno = ioctl_err;
	prop_errflags = errflags;

	if (err == 0) {
		nvpair_t *prop_err = NULL;

		while ((prop_err = nvlist_next_nvpair(prop_errors,
		    prop_err)) != NULL) {
			char tbuf[1024];
			zfs_prop_t prop;
			int intval;

			prop = zfs_name_to_prop(nvpair_name(prop_err));
			(void) nvpair_value_int32(prop_err, &intval);
			if (strcmp(nvpair_name(prop_err),
			    ZPROP_N_MORE_ERRORS) == 0) {
				trunc_prop_errs(intval);
				break;
			} else if (snapname == NULL || finalsnap == NULL ||
			    strcmp(finalsnap, snapname) == 0 ||
			    strcmp(nvpair_name(prop_err),
			    zfs_prop_to_name(ZFS_PROP_REFQUOTA)) != 0) {
				/*
				 * Skip the special case of, for example,
				 * "refquota", errors on intermediate
				 * snapshots leading up to a final one.
				 * That's why we have all of the checks above.
				 *
				 * See zfs_ioctl.c's extract_delay_props() for
				 * a list of props which can fail on
				 * intermediate snapshots, but shouldn't
				 * affect the overall receive.
				 */
				(void) snprintf(tbuf, sizeof (tbuf),
				    dgettext(TEXT_DOMAIN,
				    "cannot receive %s property on %s"),
				    nvpair_name(prop_err), name);
				zfs_setprop_error(hdl, prop, intval, tbuf);
			}
		}
	}

	if (err == 0 && snapprops_nvlist) {
		zfs_cmd_t zc = {"\0"};

		(void) strcpy(zc.zc_name, destsnap);
		zc.zc_cookie = B_TRUE; /* received */
		if (zcmd_write_src_nvlist(hdl, &zc, snapprops_nvlist) == 0) {
			(void) zfs_ioctl(hdl, ZFS_IOC_SET_PROP, &zc);
			zcmd_free_nvlists(&zc);
		}
	}
	if (err == 0 && snapholds_nvlist) {
		nvpair_t *pair;
		nvlist_t *holds, *errors = NULL;
		int cleanup_fd = -1;

		VERIFY(0 == nvlist_alloc(&holds, 0, KM_SLEEP));
		for (pair = nvlist_next_nvpair(snapholds_nvlist, NULL);
		    pair != NULL;
		    pair = nvlist_next_nvpair(snapholds_nvlist, pair)) {
			VERIFY(0 == nvlist_add_string(holds, destsnap,
			    nvpair_name(pair)));
		}
		(void) lzc_hold(holds, cleanup_fd, &errors);
		nvlist_free(snapholds_nvlist);
		nvlist_free(holds);
	}

	if (err && (ioctl_errno == ENOENT || ioctl_errno == EEXIST)) {
		/*
		 * It may be that this snapshot already exists,
		 * in which case we want to consume & ignore it
		 * rather than failing.
		 */
		avl_tree_t *local_avl;
		nvlist_t *local_nv, *fs;
		cp = strchr(destsnap, '@');

		/*
		 * XXX Do this faster by just iterating over snaps in
		 * this fs.  Also if zc_value does not exist, we will
		 * get a strange "does not exist" error message.
		 */
		*cp = '\0';
		if (gather_nvlist(hdl, destsnap, NULL, NULL, B_FALSE, B_TRUE,
		    B_FALSE, B_FALSE, B_FALSE, B_FALSE, B_FALSE, B_TRUE,
		    &local_nv, &local_avl) == 0) {
			*cp = '@';
			fs = fsavl_find(local_avl, drrb->drr_toguid, NULL);
			fsavl_destroy(local_avl);
			nvlist_free(local_nv);

			if (fs != NULL) {
				if (flags->verbose) {
					(void) printf("snap %s already exists; "
					    "ignoring\n", destsnap);
				}
				err = ioctl_err = recv_skip(hdl, infd,
				    flags->byteswap);
			}
		}
		*cp = '@';
	}

	if (ioctl_err != 0) {
		switch (ioctl_errno) {
		case ENODEV:
			cp = strchr(destsnap, '@');
			*cp = '\0';
			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
			    "most recent snapshot of %s does not\n"
			    "match incremental source"), destsnap);
			(void) zfs_error(hdl, EZFS_BADRESTORE, errbuf);
			*cp = '@';
			break;
		case ETXTBSY:
			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
			    "destination %s has been modified\n"
			    "since most recent snapshot"), name);
			(void) zfs_error(hdl, EZFS_BADRESTORE, errbuf);
			break;
		case EACCES:
			if (raw && stream_wantsnewfs) {
				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
				    "failed to create encryption key"));
			} else if (raw && !stream_wantsnewfs) {
				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
				    "encryption key does not match "
				    "existing key"));
			} else {
				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
				    "inherited key must be loaded"));
			}
			(void) zfs_error(hdl, EZFS_CRYPTOFAILED, errbuf);
			break;
		case EEXIST:
			cp = strchr(destsnap, '@');
			if (newfs) {
				/* it's the containing fs that exists */
				*cp = '\0';
			}
			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
			    "destination already exists"));
			(void) zfs_error_fmt(hdl, EZFS_EXISTS,
			    dgettext(TEXT_DOMAIN, "cannot restore to %s"),
			    destsnap);
			*cp = '@';
			break;
		case EINVAL:
			if (flags->resumable) {
				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
				    "kernel modules must be upgraded to "
				    "receive this stream."));
			} else if (embedded && !raw) {
				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
				    "incompatible embedded data stream "
				    "feature with encrypted receive."));
			}
			(void) zfs_error(hdl, EZFS_BADSTREAM, errbuf);
			break;
		case ECKSUM:
			recv_ecksum_set_aux(hdl, destsnap, flags->resumable);
			(void) zfs_error(hdl, EZFS_BADSTREAM, errbuf);
			break;
		case ENOTSUP:
			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
			    "pool must be upgraded to receive this stream."));
			(void) zfs_error(hdl, EZFS_BADVERSION, errbuf);
			break;
		case EDQUOT:
			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
			    "destination %s space quota exceeded."), name);
			(void) zfs_error(hdl, EZFS_NOSPC, errbuf);
			break;
		case ZFS_ERR_FROM_IVSET_GUID_MISSING:
			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
			    "IV set guid missing. See errata %u at "
			    "http://zfsonlinux.org/msg/ZFS-8000-ER."),
			    ZPOOL_ERRATA_ZOL_8308_ENCRYPTION);
			(void) zfs_error(hdl, EZFS_BADSTREAM, errbuf);
			break;
		case ZFS_ERR_FROM_IVSET_GUID_MISMATCH:
			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
			    "IV set guid mismatch. See the 'zfs receive' "
			    "man page section\n discussing the limitations "
			    "of raw encrypted send streams."));
			(void) zfs_error(hdl, EZFS_BADSTREAM, errbuf);
			break;
		case ZFS_ERR_SPILL_BLOCK_FLAG_MISSING:
			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
			    "Spill block flag missing for raw send.\n"
			    "The zfs software on the sending system must "
			    "be updated."));
			(void) zfs_error(hdl, EZFS_BADSTREAM, errbuf);
			break;
		case EBUSY:
			if (hastoken) {
				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
				    "destination %s contains "
				    "partially-complete state from "
				    "\"zfs receive -s\"."), name);
				(void) zfs_error(hdl, EZFS_BUSY, errbuf);
				break;
			}
			/* fallthru */
		default:
			(void) zfs_standard_error(hdl, ioctl_errno, errbuf);
		}
	}

	/*
	 * Mount the target filesystem (if created).  Also mount any
	 * children of the target filesystem if we did a replication
	 * receive (indicated by stream_avl being non-NULL).
	 */
	cp = strchr(destsnap, '@');
	if (cp && (ioctl_err == 0 || !newfs)) {
		zfs_handle_t *h;

		*cp = '\0';
		h = zfs_open(hdl, destsnap,
		    ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME);
		if (h != NULL) {
			if (h->zfs_type == ZFS_TYPE_VOLUME) {
				*cp = '@';
			} else if (newfs || stream_avl) {
				/*
				 * Track the first/top of hierarchy fs,
				 * for mounting and sharing later.
				 */
				if (top_zfs && *top_zfs == NULL)
					*top_zfs = zfs_strdup(hdl, destsnap);
			}
			zfs_close(h);
		}
		*cp = '@';
	}

	if (clp) {
		if (!flags->nomount)
			err |= changelist_postfix(clp);
		changelist_free(clp);
	}

	if (prop_errflags & ZPROP_ERR_NOCLEAR) {
		(void) fprintf(stderr, dgettext(TEXT_DOMAIN, "Warning: "
		    "failed to clear unreceived properties on %s"), name);
		(void) fprintf(stderr, "\n");
	}
	if (prop_errflags & ZPROP_ERR_NORESTORE) {
		(void) fprintf(stderr, dgettext(TEXT_DOMAIN, "Warning: "
		    "failed to restore original properties on %s"), name);
		(void) fprintf(stderr, "\n");
	}

	if (err || ioctl_err) {
		err = -1;
		goto out;
	}

	if (flags->verbose) {
		char buf1[64];
		char buf2[64];
		uint64_t bytes = read_bytes;
		time_t delta = time(NULL) - begin_time;
		if (delta == 0)
			delta = 1;
		zfs_nicebytes(bytes, buf1, sizeof (buf1));
		zfs_nicebytes(bytes/delta, buf2, sizeof (buf1));

		(void) printf("received %s stream in %lu seconds (%s/sec)\n",
		    buf1, delta, buf2);
	}

	err = 0;
out:
	if (prop_errors != NULL)
		nvlist_free(prop_errors);

	if (tmp_keylocation[0] != '\0') {
		VERIFY(0 == nvlist_add_string(rcvprops,
		    zfs_prop_to_name(ZFS_PROP_KEYLOCATION), tmp_keylocation));
	}

	if (newprops)
		nvlist_free(rcvprops);

	nvlist_free(oxprops);
	nvlist_free(origprops);

	return (err);
}

/*
 * Check properties we were asked to override (both -o|-x)
 */
static boolean_t
zfs_receive_checkprops(libzfs_handle_t *hdl, nvlist_t *props,
    const char *errbuf)
{
	nvpair_t *nvp;
	zfs_prop_t prop;
	const char *name;

	nvp = NULL;
	while ((nvp = nvlist_next_nvpair(props, nvp)) != NULL) {
		name = nvpair_name(nvp);
		prop = zfs_name_to_prop(name);

		if (prop == ZPROP_INVAL) {
			if (!zfs_prop_user(name)) {
				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
				    "invalid property '%s'"), name);
				return (B_FALSE);
			}
			continue;
		}
		/*
		 * "origin" is readonly but is used to receive datasets as
		 * clones so we don't raise an error here
		 */
		if (prop == ZFS_PROP_ORIGIN)
			continue;

		/* encryption params have their own verification later */
		if (prop == ZFS_PROP_ENCRYPTION ||
		    zfs_prop_encryption_key_param(prop))
			continue;

		/*
		 * cannot override readonly, set-once and other specific
		 * settable properties
		 */
		if (zfs_prop_readonly(prop) || prop == ZFS_PROP_VERSION ||
		    prop == ZFS_PROP_VOLSIZE) {
			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
			    "invalid property '%s'"), name);
			return (B_FALSE);
		}
	}

	return (B_TRUE);
}

static int
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, const char *finalsnap, nvlist_t *cmdprops)
{
	int err;
	dmu_replay_record_t drr, drr_noswap;
	struct drr_begin *drrb = &drr.drr_u.drr_begin;
	char errbuf[1024];
	zio_cksum_t zcksum = { { 0 } };
	uint64_t featureflags;
	int hdrtype;

	(void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
	    "cannot receive"));

	/* check cmdline props, raise an error if they cannot be received */
	if (!zfs_receive_checkprops(hdl, cmdprops, errbuf)) {
		return (zfs_error(hdl, EZFS_BADPROP, errbuf));
	}

	if (flags->isprefix &&
	    !zfs_dataset_exists(hdl, tosnap, ZFS_TYPE_DATASET)) {
		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "specified fs "
		    "(%s) does not exist"), tosnap);
		return (zfs_error(hdl, EZFS_NOENT, errbuf));
	}
	if (originsnap &&
	    !zfs_dataset_exists(hdl, originsnap, ZFS_TYPE_DATASET)) {
		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "specified origin fs "
		    "(%s) does not exist"), originsnap);
		return (zfs_error(hdl, EZFS_NOENT, errbuf));
	}

	/* read in the BEGIN record */
	if (0 != (err = recv_read(hdl, infd, &drr, sizeof (drr), B_FALSE,
	    &zcksum)))
		return (err);

	if (drr.drr_type == DRR_END || drr.drr_type == BSWAP_32(DRR_END)) {
		/* It's the double end record at the end of a package */
		return (ENODATA);
	}

	/* the kernel needs the non-byteswapped begin record */
	drr_noswap = drr;

	flags->byteswap = B_FALSE;
	if (drrb->drr_magic == BSWAP_64(DMU_BACKUP_MAGIC)) {
		/*
		 * We computed the checksum in the wrong byteorder in
		 * recv_read() above; do it again correctly.
		 */
		bzero(&zcksum, sizeof (zio_cksum_t));
		fletcher_4_incremental_byteswap(&drr, sizeof (drr), &zcksum);
		flags->byteswap = B_TRUE;

		drr.drr_type = BSWAP_32(drr.drr_type);
		drr.drr_payloadlen = BSWAP_32(drr.drr_payloadlen);
		drrb->drr_magic = BSWAP_64(drrb->drr_magic);
		drrb->drr_versioninfo = BSWAP_64(drrb->drr_versioninfo);
		drrb->drr_creation_time = BSWAP_64(drrb->drr_creation_time);
		drrb->drr_type = BSWAP_32(drrb->drr_type);
		drrb->drr_flags = BSWAP_32(drrb->drr_flags);
		drrb->drr_toguid = BSWAP_64(drrb->drr_toguid);
		drrb->drr_fromguid = BSWAP_64(drrb->drr_fromguid);
	}

	if (drrb->drr_magic != DMU_BACKUP_MAGIC || drr.drr_type != DRR_BEGIN) {
		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "invalid "
		    "stream (bad magic number)"));
		return (zfs_error(hdl, EZFS_BADSTREAM, errbuf));
	}

	featureflags = DMU_GET_FEATUREFLAGS(drrb->drr_versioninfo);
	hdrtype = DMU_GET_STREAM_HDRTYPE(drrb->drr_versioninfo);

	if (!DMU_STREAM_SUPPORTED(featureflags) ||
	    (hdrtype != DMU_SUBSTREAM && hdrtype != DMU_COMPOUNDSTREAM)) {
		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
		    "stream has unsupported feature, feature flags = %lx"),
		    featureflags);
		return (zfs_error(hdl, EZFS_BADSTREAM, errbuf));
	}

	/* Holds feature is set once in the compound stream header. */
	boolean_t holds = (DMU_GET_FEATUREFLAGS(drrb->drr_versioninfo) &
	    DMU_BACKUP_FEATURE_HOLDS);
	if (holds)
		flags->holds = B_TRUE;

	if (strchr(drrb->drr_toname, '@') == NULL) {
		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "invalid "
		    "stream (bad snapshot name)"));
		return (zfs_error(hdl, EZFS_BADSTREAM, errbuf));
	}

	if (DMU_GET_STREAM_HDRTYPE(drrb->drr_versioninfo) == DMU_SUBSTREAM) {
		char nonpackage_sendfs[ZFS_MAX_DATASET_NAME_LEN];
		if (sendfs == NULL) {
			/*
			 * We were not called from zfs_receive_package(). Get
			 * the fs specified by 'zfs send'.
			 */
			char *cp;
			(void) strlcpy(nonpackage_sendfs,
			    drr.drr_u.drr_begin.drr_toname,
			    sizeof (nonpackage_sendfs));
			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, finalsnap, cmdprops));
	} else {
		assert(DMU_GET_STREAM_HDRTYPE(drrb->drr_versioninfo) ==
		    DMU_COMPOUNDSTREAM);
		return (zfs_receive_package(hdl, infd, tosnap, flags, &drr,
		    &zcksum, top_zfs, cleanup_fd, action_handlep, cmdprops));
	}
}

/*
 * Restores a backup of tosnap from the file descriptor specified by infd.
 * Return 0 on total success, -2 if some things couldn't be
 * destroyed/renamed/promoted, -1 if some things couldn't be received.
 * (-1 will override -2, if -1 and the resumable flag was specified the
 * transfer can be resumed if the sending side supports it).
 */
int
zfs_receive(libzfs_handle_t *hdl, const char *tosnap, nvlist_t *props,
    recvflags_t *flags, int infd, avl_tree_t *stream_avl)
{
	char *top_zfs = NULL;
	int err;
	int cleanup_fd;
	uint64_t action_handle = 0;
	struct stat sb;
	char *originsnap = NULL;

	/*
	 * The only way fstat can fail is if we do not have a valid file
	 * descriptor.
	 */
	if (fstat(infd, &sb) == -1) {
		perror("fstat");
		return (-2);
	}

#ifdef __linux__
#ifndef F_SETPIPE_SZ
#define	F_SETPIPE_SZ (F_SETLEASE + 7)
#endif /* F_SETPIPE_SZ */

#ifndef F_GETPIPE_SZ
#define	F_GETPIPE_SZ (F_GETLEASE + 7)
#endif /* F_GETPIPE_SZ */

	/*
	 * It is not uncommon for gigabytes to be processed in zfs receive.
	 * Speculatively increase the buffer size via Linux-specific fcntl()
	 * call.
	 */
	if (S_ISFIFO(sb.st_mode)) {
		FILE *procf = fopen("/proc/sys/fs/pipe-max-size", "r");

		if (procf != NULL) {
			unsigned long max_psize;
			long cur_psize;
			if (fscanf(procf, "%lu", &max_psize) > 0) {
				cur_psize = fcntl(infd, F_GETPIPE_SZ);
				if (cur_psize > 0 &&
				    max_psize > (unsigned long) cur_psize)
					(void) fcntl(infd, F_SETPIPE_SZ,
					    max_psize);
			}
			fclose(procf);
		}
	}
#endif /* __linux__ */

	if (props) {
		err = nvlist_lookup_string(props, "origin", &originsnap);
		if (err && err != ENOENT)
			return (err);
	}

	cleanup_fd = open(ZFS_DEV, O_RDWR);
	VERIFY(cleanup_fd >= 0);

	err = zfs_receive_impl(hdl, tosnap, originsnap, flags, infd, NULL, NULL,
	    stream_avl, &top_zfs, cleanup_fd, &action_handle, NULL, props);

	VERIFY(0 == close(cleanup_fd));

	if (err == 0 && !flags->nomount && top_zfs) {
		zfs_handle_t *zhp = NULL;
		prop_changelist_t *clp = NULL;

		zhp = zfs_open(hdl, top_zfs, ZFS_TYPE_FILESYSTEM);
		if (zhp != NULL) {
			clp = changelist_gather(zhp, ZFS_PROP_MOUNTPOINT,
			    CL_GATHER_MOUNT_ALWAYS, 0);
			zfs_close(zhp);
			if (clp != NULL) {
				/* mount and share received datasets */
				err = changelist_postfix(clp);
				changelist_free(clp);
			}
		}
		if (zhp == NULL || clp == NULL || err)
			err = -1;
	}
	if (top_zfs)
		free(top_zfs);

	return (err);
}
