Home | History | Annotate | Line # | Download | only in common
      1  1.1  haad /*
      2  1.1  haad  * CDDL HEADER START
      3  1.1  haad  *
      4  1.1  haad  * The contents of this file are subject to the terms of the
      5  1.1  haad  * Common Development and Distribution License (the "License").
      6  1.1  haad  * You may not use this file except in compliance with the License.
      7  1.1  haad  *
      8  1.1  haad  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
      9  1.1  haad  * or http://www.opensolaris.org/os/licensing.
     10  1.1  haad  * See the License for the specific language governing permissions
     11  1.1  haad  * and limitations under the License.
     12  1.1  haad  *
     13  1.1  haad  * When distributing Covered Code, include this CDDL HEADER in each
     14  1.1  haad  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
     15  1.1  haad  * If applicable, add the following below this CDDL HEADER, with the
     16  1.1  haad  * fields enclosed by brackets "[]" replaced with your own identifying
     17  1.1  haad  * information: Portions Copyright [yyyy] [name of copyright owner]
     18  1.1  haad  *
     19  1.1  haad  * CDDL HEADER END
     20  1.1  haad  */
     21  1.1  haad 
     22  1.1  haad /*
     23  1.3   chs  * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
     24  1.3   chs  * Copyright (c) 2011, 2015 by Delphix. All rights reserved.
     25  1.3   chs  * Copyright (c) 2012, Joyent, Inc. All rights reserved.
     26  1.3   chs  * Copyright (c) 2012 Pawel Jakub Dawidek. All rights reserved.
     27  1.3   chs  * Copyright (c) 2013 Steven Hartland. All rights reserved.
     28  1.3   chs  * Copyright 2015, OmniTI Computer Consulting, Inc. All rights reserved.
     29  1.3   chs  * Copyright (c) 2014 Integros [integros.com]
     30  1.3   chs  * Copyright 2016 Igor Kozhukhov <ikozhukhov (at) gmail.com>
     31  1.1  haad  */
     32  1.1  haad 
     33  1.1  haad #include <assert.h>
     34  1.1  haad #include <ctype.h>
     35  1.1  haad #include <errno.h>
     36  1.1  haad #include <libintl.h>
     37  1.1  haad #include <stdio.h>
     38  1.1  haad #include <stdlib.h>
     39  1.1  haad #include <strings.h>
     40  1.1  haad #include <unistd.h>
     41  1.1  haad #include <stddef.h>
     42  1.1  haad #include <fcntl.h>
     43  1.3   chs #include <sys/param.h>
     44  1.1  haad #include <sys/mount.h>
     45  1.2   dsl #include <pthread.h>
     46  1.2   dsl #include <umem.h>
     47  1.3   chs #include <time.h>
     48  1.1  haad 
     49  1.1  haad #include <libzfs.h>
     50  1.3   chs #include <libzfs_core.h>
     51  1.1  haad 
     52  1.1  haad #include "zfs_namecheck.h"
     53  1.1  haad #include "zfs_prop.h"
     54  1.2   dsl #include "zfs_fletcher.h"
     55  1.1  haad #include "libzfs_impl.h"
     56  1.3   chs #include <zlib.h>
     57  1.2   dsl #include <sha2.h>
     58  1.2   dsl #include <sys/zio_checksum.h>
     59  1.2   dsl #include <sys/ddt.h>
     60  1.1  haad 
     61  1.3   chs #ifdef __FreeBSD__
     62  1.3   chs extern int zfs_ioctl_version;
     63  1.3   chs /* We need to use something for ENODATA. */
     64  1.3   chs #define	ENODATA	EIDRM
     65  1.3   chs #endif
     66  1.3   chs 
     67  1.2   dsl /* in libzfs_dataset.c */
     68  1.2   dsl extern void zfs_setprop_error(libzfs_handle_t *, zfs_prop_t, int, char *);
     69  1.1  haad 
     70  1.3   chs static int zfs_receive_impl(libzfs_handle_t *, const char *, const char *,
     71  1.3   chs     recvflags_t *, int, const char *, nvlist_t *, avl_tree_t *, char **, int,
     72  1.3   chs     uint64_t *, const char *);
     73  1.3   chs static int guid_to_name(libzfs_handle_t *, const char *,
     74  1.3   chs     uint64_t, boolean_t, char *);
     75  1.1  haad 
     76  1.2   dsl static const zio_cksum_t zero_cksum = { 0 };
     77  1.2   dsl 
     78  1.2   dsl typedef struct dedup_arg {
     79  1.2   dsl 	int	inputfd;
     80  1.2   dsl 	int	outputfd;
     81  1.2   dsl 	libzfs_handle_t  *dedup_hdl;
     82  1.2   dsl } dedup_arg_t;
     83  1.2   dsl 
     84  1.3   chs typedef struct progress_arg {
     85  1.3   chs 	zfs_handle_t *pa_zhp;
     86  1.3   chs 	int pa_fd;
     87  1.3   chs 	boolean_t pa_parsable;
     88  1.3   chs } progress_arg_t;
     89  1.3   chs 
     90  1.2   dsl typedef struct dataref {
     91  1.2   dsl 	uint64_t ref_guid;
     92  1.2   dsl 	uint64_t ref_object;
     93  1.2   dsl 	uint64_t ref_offset;
     94  1.2   dsl } dataref_t;
     95  1.2   dsl 
     96  1.2   dsl typedef struct dedup_entry {
     97  1.2   dsl 	struct dedup_entry	*dde_next;
     98  1.2   dsl 	zio_cksum_t dde_chksum;
     99  1.2   dsl 	uint64_t dde_prop;
    100  1.2   dsl 	dataref_t dde_ref;
    101  1.2   dsl } dedup_entry_t;
    102  1.2   dsl 
    103  1.2   dsl #define	MAX_DDT_PHYSMEM_PERCENT		20
    104  1.2   dsl #define	SMALLEST_POSSIBLE_MAX_DDT_MB		128
    105  1.2   dsl 
    106  1.2   dsl typedef struct dedup_table {
    107  1.2   dsl 	dedup_entry_t	**dedup_hash_array;
    108  1.2   dsl 	umem_cache_t	*ddecache;
    109  1.2   dsl 	uint64_t	max_ddt_size;  /* max dedup table size in bytes */
    110  1.2   dsl 	uint64_t	cur_ddt_size;  /* current dedup table size in bytes */
    111  1.2   dsl 	uint64_t	ddt_count;
    112  1.2   dsl 	int		numhashbits;
    113  1.2   dsl 	boolean_t	ddt_full;
    114  1.2   dsl } dedup_table_t;
    115  1.2   dsl 
    116  1.2   dsl static int
    117  1.2   dsl high_order_bit(uint64_t n)
    118  1.2   dsl {
    119  1.2   dsl 	int count;
    120  1.2   dsl 
    121  1.2   dsl 	for (count = 0; n != 0; count++)
    122  1.2   dsl 		n >>= 1;
    123  1.2   dsl 	return (count);
    124  1.2   dsl }
    125  1.2   dsl 
    126  1.2   dsl static size_t
    127  1.2   dsl ssread(void *buf, size_t len, FILE *stream)
    128  1.2   dsl {
    129  1.2   dsl 	size_t outlen;
    130  1.2   dsl 
    131  1.2   dsl 	if ((outlen = fread(buf, len, 1, stream)) == 0)
    132  1.2   dsl 		return (0);
    133  1.2   dsl 
    134  1.2   dsl 	return (outlen);
    135  1.2   dsl }
    136  1.2   dsl 
    137  1.2   dsl static void
    138  1.2   dsl ddt_hash_append(libzfs_handle_t *hdl, dedup_table_t *ddt, dedup_entry_t **ddepp,
    139  1.2   dsl     zio_cksum_t *cs, uint64_t prop, dataref_t *dr)
    140  1.2   dsl {
    141  1.2   dsl 	dedup_entry_t	*dde;
    142  1.2   dsl 
    143  1.2   dsl 	if (ddt->cur_ddt_size >= ddt->max_ddt_size) {
    144  1.2   dsl 		if (ddt->ddt_full == B_FALSE) {
    145  1.2   dsl 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
    146  1.2   dsl 			    "Dedup table full.  Deduplication will continue "
    147  1.2   dsl 			    "with existing table entries"));
    148  1.2   dsl 			ddt->ddt_full = B_TRUE;
    149  1.2   dsl 		}
    150  1.2   dsl 		return;
    151  1.2   dsl 	}
    152  1.2   dsl 
    153  1.2   dsl 	if ((dde = umem_cache_alloc(ddt->ddecache, UMEM_DEFAULT))
    154  1.2   dsl 	    != NULL) {
    155  1.2   dsl 		assert(*ddepp == NULL);
    156  1.2   dsl 		dde->dde_next = NULL;
    157  1.2   dsl 		dde->dde_chksum = *cs;
    158  1.2   dsl 		dde->dde_prop = prop;
    159  1.2   dsl 		dde->dde_ref = *dr;
    160  1.2   dsl 		*ddepp = dde;
    161  1.2   dsl 		ddt->cur_ddt_size += sizeof (dedup_entry_t);
    162  1.2   dsl 		ddt->ddt_count++;
    163  1.2   dsl 	}
    164  1.2   dsl }
    165  1.2   dsl 
    166  1.2   dsl /*
    167  1.2   dsl  * Using the specified dedup table, do a lookup for an entry with
    168  1.2   dsl  * the checksum cs.  If found, return the block's reference info
    169  1.2   dsl  * in *dr. Otherwise, insert a new entry in the dedup table, using
    170  1.2   dsl  * the reference information specified by *dr.
    171  1.2   dsl  *
    172  1.2   dsl  * return value:  true - entry was found
    173  1.2   dsl  *		  false - entry was not found
    174  1.2   dsl  */
    175  1.2   dsl static boolean_t
    176  1.2   dsl ddt_update(libzfs_handle_t *hdl, dedup_table_t *ddt, zio_cksum_t *cs,
    177  1.2   dsl     uint64_t prop, dataref_t *dr)
    178  1.2   dsl {
    179  1.2   dsl 	uint32_t hashcode;
    180  1.2   dsl 	dedup_entry_t **ddepp;
    181  1.2   dsl 
    182  1.2   dsl 	hashcode = BF64_GET(cs->zc_word[0], 0, ddt->numhashbits);
    183  1.2   dsl 
    184  1.2   dsl 	for (ddepp = &(ddt->dedup_hash_array[hashcode]); *ddepp != NULL;
    185  1.2   dsl 	    ddepp = &((*ddepp)->dde_next)) {
    186  1.2   dsl 		if (ZIO_CHECKSUM_EQUAL(((*ddepp)->dde_chksum), *cs) &&
    187  1.2   dsl 		    (*ddepp)->dde_prop == prop) {
    188  1.2   dsl 			*dr = (*ddepp)->dde_ref;
    189  1.2   dsl 			return (B_TRUE);
    190  1.2   dsl 		}
    191  1.2   dsl 	}
    192  1.2   dsl 	ddt_hash_append(hdl, ddt, ddepp, cs, prop, dr);
    193  1.2   dsl 	return (B_FALSE);
    194  1.2   dsl }
    195  1.2   dsl 
    196  1.2   dsl static int
    197  1.3   chs dump_record(dmu_replay_record_t *drr, void *payload, int payload_len,
    198  1.3   chs     zio_cksum_t *zc, int outfd)
    199  1.2   dsl {
    200  1.3   chs 	ASSERT3U(offsetof(dmu_replay_record_t, drr_u.drr_checksum.drr_checksum),
    201  1.3   chs 	    ==, sizeof (dmu_replay_record_t) - sizeof (zio_cksum_t));
    202  1.3   chs 	fletcher_4_incremental_native(drr,
    203  1.3   chs 	    offsetof(dmu_replay_record_t, drr_u.drr_checksum.drr_checksum), zc);
    204  1.3   chs 	if (drr->drr_type != DRR_BEGIN) {
    205  1.3   chs 		ASSERT(ZIO_CHECKSUM_IS_ZERO(&drr->drr_u.
    206  1.3   chs 		    drr_checksum.drr_checksum));
    207  1.3   chs 		drr->drr_u.drr_checksum.drr_checksum = *zc;
    208  1.3   chs 	}
    209  1.3   chs 	fletcher_4_incremental_native(&drr->drr_u.drr_checksum.drr_checksum,
    210  1.3   chs 	    sizeof (zio_cksum_t), zc);
    211  1.3   chs 	if (write(outfd, drr, sizeof (*drr)) == -1)
    212  1.3   chs 		return (errno);
    213  1.3   chs 	if (payload_len != 0) {
    214  1.3   chs 		fletcher_4_incremental_native(payload, payload_len, zc);
    215  1.3   chs 		if (write(outfd, payload, payload_len) == -1)
    216  1.3   chs 			return (errno);
    217  1.3   chs 	}
    218  1.3   chs 	return (0);
    219  1.2   dsl }
    220  1.2   dsl 
    221  1.2   dsl /*
    222  1.2   dsl  * This function is started in a separate thread when the dedup option
    223  1.2   dsl  * has been requested.  The main send thread determines the list of
    224  1.2   dsl  * snapshots to be included in the send stream and makes the ioctl calls
    225  1.2   dsl  * for each one.  But instead of having the ioctl send the output to the
    226  1.2   dsl  * the output fd specified by the caller of zfs_send()), the
    227  1.2   dsl  * ioctl is told to direct the output to a pipe, which is read by the
    228  1.2   dsl  * alternate thread running THIS function.  This function does the
    229  1.2   dsl  * dedup'ing by:
    230  1.2   dsl  *  1. building a dedup table (the DDT)
    231  1.2   dsl  *  2. doing checksums on each data block and inserting a record in the DDT
    232  1.2   dsl  *  3. looking for matching checksums, and
    233  1.2   dsl  *  4.  sending a DRR_WRITE_BYREF record instead of a write record whenever
    234  1.2   dsl  *      a duplicate block is found.
    235  1.2   dsl  * The output of this function then goes to the output fd requested
    236  1.2   dsl  * by the caller of zfs_send().
    237  1.2   dsl  */
    238  1.2   dsl static void *
    239  1.2   dsl cksummer(void *arg)
    240  1.2   dsl {
    241  1.2   dsl 	dedup_arg_t *dda = arg;
    242  1.3   chs 	char *buf = zfs_alloc(dda->dedup_hdl, SPA_MAXBLOCKSIZE);
    243  1.2   dsl 	dmu_replay_record_t thedrr;
    244  1.2   dsl 	dmu_replay_record_t *drr = &thedrr;
    245  1.2   dsl 	FILE *ofp;
    246  1.2   dsl 	int outfd;
    247  1.2   dsl 	dedup_table_t ddt;
    248  1.2   dsl 	zio_cksum_t stream_cksum;
    249  1.2   dsl 	uint64_t physmem = sysconf(_SC_PHYS_PAGES) * sysconf(_SC_PAGESIZE);
    250  1.2   dsl 	uint64_t numbuckets;
    251  1.2   dsl 
    252  1.2   dsl 	ddt.max_ddt_size =
    253  1.3   chs 	    MAX((physmem * MAX_DDT_PHYSMEM_PERCENT) / 100,
    254  1.3   chs 	    SMALLEST_POSSIBLE_MAX_DDT_MB << 20);
    255  1.2   dsl 
    256  1.3   chs 	numbuckets = ddt.max_ddt_size / (sizeof (dedup_entry_t));
    257  1.2   dsl 
    258  1.2   dsl 	/*
    259  1.2   dsl 	 * numbuckets must be a power of 2.  Increase number to
    260  1.2   dsl 	 * a power of 2 if necessary.
    261  1.2   dsl 	 */
    262  1.2   dsl 	if (!ISP2(numbuckets))
    263  1.2   dsl 		numbuckets = 1 << high_order_bit(numbuckets);
    264  1.2   dsl 
    265  1.2   dsl 	ddt.dedup_hash_array = calloc(numbuckets, sizeof (dedup_entry_t *));
    266  1.2   dsl 	ddt.ddecache = umem_cache_create("dde", sizeof (dedup_entry_t), 0,
    267  1.2   dsl 	    NULL, NULL, NULL, NULL, NULL, 0);
    268  1.2   dsl 	ddt.cur_ddt_size = numbuckets * sizeof (dedup_entry_t *);
    269  1.2   dsl 	ddt.numhashbits = high_order_bit(numbuckets) - 1;
    270  1.2   dsl 	ddt.ddt_full = B_FALSE;
    271  1.2   dsl 
    272  1.2   dsl 	outfd = dda->outputfd;
    273  1.2   dsl 	ofp = fdopen(dda->inputfd, "r");
    274  1.3   chs 	while (ssread(drr, sizeof (*drr), ofp) != 0) {
    275  1.2   dsl 
    276  1.2   dsl 		switch (drr->drr_type) {
    277  1.2   dsl 		case DRR_BEGIN:
    278  1.2   dsl 		{
    279  1.3   chs 			struct drr_begin *drrb = &drr->drr_u.drr_begin;
    280  1.3   chs 			int fflags;
    281  1.3   chs 			int sz = 0;
    282  1.2   dsl 			ZIO_SET_CHECKSUM(&stream_cksum, 0, 0, 0, 0);
    283  1.2   dsl 
    284  1.3   chs 			ASSERT3U(drrb->drr_magic, ==, DMU_BACKUP_MAGIC);
    285  1.3   chs 
    286  1.2   dsl 			/* set the DEDUP feature flag for this stream */
    287  1.2   dsl 			fflags = DMU_GET_FEATUREFLAGS(drrb->drr_versioninfo);
    288  1.2   dsl 			fflags |= (DMU_BACKUP_FEATURE_DEDUP |
    289  1.2   dsl 			    DMU_BACKUP_FEATURE_DEDUPPROPS);
    290  1.2   dsl 			DMU_SET_FEATUREFLAGS(drrb->drr_versioninfo, fflags);
    291  1.2   dsl 
    292  1.3   chs 			if (drr->drr_payloadlen != 0) {
    293  1.3   chs 				sz = drr->drr_payloadlen;
    294  1.3   chs 
    295  1.3   chs 				if (sz > SPA_MAXBLOCKSIZE) {
    296  1.3   chs 					buf = zfs_realloc(dda->dedup_hdl, buf,
    297  1.3   chs 					    SPA_MAXBLOCKSIZE, sz);
    298  1.2   dsl 				}
    299  1.2   dsl 				(void) ssread(buf, sz, ofp);
    300  1.2   dsl 				if (ferror(stdin))
    301  1.2   dsl 					perror("fread");
    302  1.2   dsl 			}
    303  1.3   chs 			if (dump_record(drr, buf, sz, &stream_cksum,
    304  1.3   chs 			    outfd) != 0)
    305  1.3   chs 				goto out;
    306  1.2   dsl 			break;
    307  1.2   dsl 		}
    308  1.2   dsl 
    309  1.2   dsl 		case DRR_END:
    310  1.2   dsl 		{
    311  1.3   chs 			struct drr_end *drre = &drr->drr_u.drr_end;
    312  1.2   dsl 			/* use the recalculated checksum */
    313  1.3   chs 			drre->drr_checksum = stream_cksum;
    314  1.3   chs 			if (dump_record(drr, NULL, 0, &stream_cksum,
    315  1.3   chs 			    outfd) != 0)
    316  1.2   dsl 				goto out;
    317  1.2   dsl 			break;
    318  1.2   dsl 		}
    319  1.2   dsl 
    320  1.2   dsl 		case DRR_OBJECT:
    321  1.2   dsl 		{
    322  1.3   chs 			struct drr_object *drro = &drr->drr_u.drr_object;
    323  1.2   dsl 			if (drro->drr_bonuslen > 0) {
    324  1.2   dsl 				(void) ssread(buf,
    325  1.2   dsl 				    P2ROUNDUP((uint64_t)drro->drr_bonuslen, 8),
    326  1.2   dsl 				    ofp);
    327  1.2   dsl 			}
    328  1.3   chs 			if (dump_record(drr, buf,
    329  1.3   chs 			    P2ROUNDUP((uint64_t)drro->drr_bonuslen, 8),
    330  1.3   chs 			    &stream_cksum, outfd) != 0)
    331  1.3   chs 				goto out;
    332  1.3   chs 			break;
    333  1.3   chs 		}
    334  1.3   chs 
    335  1.3   chs 		case DRR_SPILL:
    336  1.3   chs 		{
    337  1.3   chs 			struct drr_spill *drrs = &drr->drr_u.drr_spill;
    338  1.3   chs 			(void) ssread(buf, drrs->drr_length, ofp);
    339  1.3   chs 			if (dump_record(drr, buf, drrs->drr_length,
    340  1.3   chs 			    &stream_cksum, outfd) != 0)
    341  1.3   chs 				goto out;
    342  1.2   dsl 			break;
    343  1.2   dsl 		}
    344  1.2   dsl 
    345  1.2   dsl 		case DRR_FREEOBJECTS:
    346  1.2   dsl 		{
    347  1.3   chs 			if (dump_record(drr, NULL, 0, &stream_cksum,
    348  1.3   chs 			    outfd) != 0)
    349  1.2   dsl 				goto out;
    350  1.2   dsl 			break;
    351  1.2   dsl 		}
    352  1.2   dsl 
    353  1.2   dsl 		case DRR_WRITE:
    354  1.2   dsl 		{
    355  1.3   chs 			struct drr_write *drrw = &drr->drr_u.drr_write;
    356  1.2   dsl 			dataref_t	dataref;
    357  1.2   dsl 
    358  1.2   dsl 			(void) ssread(buf, drrw->drr_length, ofp);
    359  1.2   dsl 
    360  1.2   dsl 			/*
    361  1.2   dsl 			 * Use the existing checksum if it's dedup-capable,
    362  1.2   dsl 			 * else calculate a SHA256 checksum for it.
    363  1.2   dsl 			 */
    364  1.2   dsl 
    365  1.2   dsl 			if (ZIO_CHECKSUM_EQUAL(drrw->drr_key.ddk_cksum,
    366  1.2   dsl 			    zero_cksum) ||
    367  1.2   dsl 			    !DRR_IS_DEDUP_CAPABLE(drrw->drr_checksumflags)) {
    368  1.2   dsl 				SHA256_CTX	ctx;
    369  1.2   dsl 				zio_cksum_t	tmpsha256;
    370  1.2   dsl 
    371  1.2   dsl 				SHA256Init(&ctx);
    372  1.2   dsl 				SHA256Update(&ctx, buf, drrw->drr_length);
    373  1.2   dsl 				SHA256Final(&tmpsha256, &ctx);
    374  1.2   dsl 				drrw->drr_key.ddk_cksum.zc_word[0] =
    375  1.2   dsl 				    BE_64(tmpsha256.zc_word[0]);
    376  1.2   dsl 				drrw->drr_key.ddk_cksum.zc_word[1] =
    377  1.2   dsl 				    BE_64(tmpsha256.zc_word[1]);
    378  1.2   dsl 				drrw->drr_key.ddk_cksum.zc_word[2] =
    379  1.2   dsl 				    BE_64(tmpsha256.zc_word[2]);
    380  1.2   dsl 				drrw->drr_key.ddk_cksum.zc_word[3] =
    381  1.2   dsl 				    BE_64(tmpsha256.zc_word[3]);
    382  1.2   dsl 				drrw->drr_checksumtype = ZIO_CHECKSUM_SHA256;
    383  1.2   dsl 				drrw->drr_checksumflags = DRR_CHECKSUM_DEDUP;
    384  1.2   dsl 			}
    385  1.2   dsl 
    386  1.2   dsl 			dataref.ref_guid = drrw->drr_toguid;
    387  1.2   dsl 			dataref.ref_object = drrw->drr_object;
    388  1.2   dsl 			dataref.ref_offset = drrw->drr_offset;
    389  1.2   dsl 
    390  1.2   dsl 			if (ddt_update(dda->dedup_hdl, &ddt,
    391  1.2   dsl 			    &drrw->drr_key.ddk_cksum, drrw->drr_key.ddk_prop,
    392  1.2   dsl 			    &dataref)) {
    393  1.3   chs 				dmu_replay_record_t wbr_drr = {0};
    394  1.3   chs 				struct drr_write_byref *wbr_drrr =
    395  1.3   chs 				    &wbr_drr.drr_u.drr_write_byref;
    396  1.3   chs 
    397  1.2   dsl 				/* block already present in stream */
    398  1.3   chs 				wbr_drr.drr_type = DRR_WRITE_BYREF;
    399  1.3   chs 
    400  1.2   dsl 				wbr_drrr->drr_object = drrw->drr_object;
    401  1.2   dsl 				wbr_drrr->drr_offset = drrw->drr_offset;
    402  1.2   dsl 				wbr_drrr->drr_length = drrw->drr_length;
    403  1.2   dsl 				wbr_drrr->drr_toguid = drrw->drr_toguid;
    404  1.2   dsl 				wbr_drrr->drr_refguid = dataref.ref_guid;
    405  1.2   dsl 				wbr_drrr->drr_refobject =
    406  1.2   dsl 				    dataref.ref_object;
    407  1.2   dsl 				wbr_drrr->drr_refoffset =
    408  1.2   dsl 				    dataref.ref_offset;
    409  1.2   dsl 
    410  1.2   dsl 				wbr_drrr->drr_checksumtype =
    411  1.2   dsl 				    drrw->drr_checksumtype;
    412  1.2   dsl 				wbr_drrr->drr_checksumflags =
    413  1.2   dsl 				    drrw->drr_checksumtype;
    414  1.2   dsl 				wbr_drrr->drr_key.ddk_cksum =
    415  1.2   dsl 				    drrw->drr_key.ddk_cksum;
    416  1.2   dsl 				wbr_drrr->drr_key.ddk_prop =
    417  1.2   dsl 				    drrw->drr_key.ddk_prop;
    418  1.2   dsl 
    419  1.3   chs 				if (dump_record(&wbr_drr, NULL, 0,
    420  1.3   chs 				    &stream_cksum, outfd) != 0)
    421  1.2   dsl 					goto out;
    422  1.2   dsl 			} else {
    423  1.2   dsl 				/* block not previously seen */
    424  1.3   chs 				if (dump_record(drr, buf, drrw->drr_length,
    425  1.3   chs 				    &stream_cksum, outfd) != 0)
    426  1.2   dsl 					goto out;
    427  1.2   dsl 			}
    428  1.2   dsl 			break;
    429  1.2   dsl 		}
    430  1.2   dsl 
    431  1.3   chs 		case DRR_WRITE_EMBEDDED:
    432  1.3   chs 		{
    433  1.3   chs 			struct drr_write_embedded *drrwe =
    434  1.3   chs 			    &drr->drr_u.drr_write_embedded;
    435  1.3   chs 			(void) ssread(buf,
    436  1.3   chs 			    P2ROUNDUP((uint64_t)drrwe->drr_psize, 8), ofp);
    437  1.3   chs 			if (dump_record(drr, buf,
    438  1.3   chs 			    P2ROUNDUP((uint64_t)drrwe->drr_psize, 8),
    439  1.3   chs 			    &stream_cksum, outfd) != 0)
    440  1.3   chs 				goto out;
    441  1.3   chs 			break;
    442  1.3   chs 		}
    443  1.3   chs 
    444  1.2   dsl 		case DRR_FREE:
    445  1.2   dsl 		{
    446  1.3   chs 			if (dump_record(drr, NULL, 0, &stream_cksum,
    447  1.3   chs 			    outfd) != 0)
    448  1.2   dsl 				goto out;
    449  1.2   dsl 			break;
    450  1.2   dsl 		}
    451  1.2   dsl 
    452  1.2   dsl 		default:
    453  1.3   chs 			(void) fprintf(stderr, "INVALID record type 0x%x\n",
    454  1.2   dsl 			    drr->drr_type);
    455  1.2   dsl 			/* should never happen, so assert */
    456  1.2   dsl 			assert(B_FALSE);
    457  1.2   dsl 		}
    458  1.2   dsl 	}
    459  1.2   dsl out:
    460  1.2   dsl 	umem_cache_destroy(ddt.ddecache);
    461  1.2   dsl 	free(ddt.dedup_hash_array);
    462  1.2   dsl 	free(buf);
    463  1.2   dsl 	(void) fclose(ofp);
    464  1.2   dsl 
    465  1.2   dsl 	return (NULL);
    466  1.2   dsl }
    467  1.2   dsl 
    468  1.1  haad /*
    469  1.1  haad  * Routines for dealing with the AVL tree of fs-nvlists
    470  1.1  haad  */
    471  1.1  haad typedef struct fsavl_node {
    472  1.1  haad 	avl_node_t fn_node;
    473  1.1  haad 	nvlist_t *fn_nvfs;
    474  1.1  haad 	char *fn_snapname;
    475  1.1  haad 	uint64_t fn_guid;
    476  1.1  haad } fsavl_node_t;
    477  1.1  haad 
    478  1.1  haad static int
    479  1.1  haad fsavl_compare(const void *arg1, const void *arg2)
    480  1.1  haad {
    481  1.1  haad 	const fsavl_node_t *fn1 = arg1;
    482  1.1  haad 	const fsavl_node_t *fn2 = arg2;
    483  1.1  haad 
    484  1.1  haad 	if (fn1->fn_guid > fn2->fn_guid)
    485  1.1  haad 		return (+1);
    486  1.1  haad 	else if (fn1->fn_guid < fn2->fn_guid)
    487  1.1  haad 		return (-1);
    488  1.1  haad 	else
    489  1.1  haad 		return (0);
    490  1.1  haad }
    491  1.1  haad 
    492  1.1  haad /*
    493  1.1  haad  * Given the GUID of a snapshot, find its containing filesystem and
    494  1.1  haad  * (optionally) name.
    495  1.1  haad  */
    496  1.1  haad static nvlist_t *
    497  1.1  haad fsavl_find(avl_tree_t *avl, uint64_t snapguid, char **snapname)
    498  1.1  haad {
    499  1.1  haad 	fsavl_node_t fn_find;
    500  1.1  haad 	fsavl_node_t *fn;
    501  1.1  haad 
    502  1.1  haad 	fn_find.fn_guid = snapguid;
    503  1.1  haad 
    504  1.1  haad 	fn = avl_find(avl, &fn_find, NULL);
    505  1.1  haad 	if (fn) {
    506  1.1  haad 		if (snapname)
    507  1.1  haad 			*snapname = fn->fn_snapname;
    508  1.1  haad 		return (fn->fn_nvfs);
    509  1.1  haad 	}
    510  1.1  haad 	return (NULL);
    511  1.1  haad }
    512  1.1  haad 
    513  1.1  haad static void
    514  1.1  haad fsavl_destroy(avl_tree_t *avl)
    515  1.1  haad {
    516  1.1  haad 	fsavl_node_t *fn;
    517  1.1  haad 	void *cookie;
    518  1.1  haad 
    519  1.1  haad 	if (avl == NULL)
    520  1.1  haad 		return;
    521  1.1  haad 
    522  1.1  haad 	cookie = NULL;
    523  1.1  haad 	while ((fn = avl_destroy_nodes(avl, &cookie)) != NULL)
    524  1.1  haad 		free(fn);
    525  1.1  haad 	avl_destroy(avl);
    526  1.1  haad 	free(avl);
    527  1.1  haad }
    528  1.1  haad 
    529  1.2   dsl /*
    530  1.2   dsl  * Given an nvlist, produce an avl tree of snapshots, ordered by guid
    531  1.2   dsl  */
    532  1.1  haad static avl_tree_t *
    533  1.1  haad fsavl_create(nvlist_t *fss)
    534  1.1  haad {
    535  1.1  haad 	avl_tree_t *fsavl;
    536  1.1  haad 	nvpair_t *fselem = NULL;
    537  1.1  haad 
    538  1.1  haad 	if ((fsavl = malloc(sizeof (avl_tree_t))) == NULL)
    539  1.1  haad 		return (NULL);
    540  1.1  haad 
    541  1.1  haad 	avl_create(fsavl, fsavl_compare, sizeof (fsavl_node_t),
    542  1.1  haad 	    offsetof(fsavl_node_t, fn_node));
    543  1.1  haad 
    544  1.1  haad 	while ((fselem = nvlist_next_nvpair(fss, fselem)) != NULL) {
    545  1.1  haad 		nvlist_t *nvfs, *snaps;
    546  1.1  haad 		nvpair_t *snapelem = NULL;
    547  1.1  haad 
    548  1.1  haad 		VERIFY(0 == nvpair_value_nvlist(fselem, &nvfs));
    549  1.1  haad 		VERIFY(0 == nvlist_lookup_nvlist(nvfs, "snaps", &snaps));
    550  1.1  haad 
    551  1.1  haad 		while ((snapelem =
    552  1.1  haad 		    nvlist_next_nvpair(snaps, snapelem)) != NULL) {
    553  1.1  haad 			fsavl_node_t *fn;
    554  1.1  haad 			uint64_t guid;
    555  1.1  haad 
    556  1.1  haad 			VERIFY(0 == nvpair_value_uint64(snapelem, &guid));
    557  1.1  haad 			if ((fn = malloc(sizeof (fsavl_node_t))) == NULL) {
    558  1.1  haad 				fsavl_destroy(fsavl);
    559  1.1  haad 				return (NULL);
    560  1.1  haad 			}
    561  1.1  haad 			fn->fn_nvfs = nvfs;
    562  1.1  haad 			fn->fn_snapname = nvpair_name(snapelem);
    563  1.1  haad 			fn->fn_guid = guid;
    564  1.1  haad 
    565  1.1  haad 			/*
    566  1.1  haad 			 * Note: if there are multiple snaps with the
    567  1.1  haad 			 * same GUID, we ignore all but one.
    568  1.1  haad 			 */
    569  1.1  haad 			if (avl_find(fsavl, fn, NULL) == NULL)
    570  1.1  haad 				avl_add(fsavl, fn);
    571  1.1  haad 			else
    572  1.1  haad 				free(fn);
    573  1.1  haad 		}
    574  1.1  haad 	}
    575  1.1  haad 
    576  1.1  haad 	return (fsavl);
    577  1.1  haad }
    578  1.1  haad 
    579  1.1  haad /*
    580  1.1  haad  * Routines for dealing with the giant nvlist of fs-nvlists, etc.
    581  1.1  haad  */
    582  1.1  haad typedef struct send_data {
    583  1.3   chs 	/*
    584  1.3   chs 	 * assigned inside every recursive call,
    585  1.3   chs 	 * restored from *_save on return:
    586  1.3   chs 	 *
    587  1.3   chs 	 * guid of fromsnap snapshot in parent dataset
    588  1.3   chs 	 * txg of fromsnap snapshot in current dataset
    589  1.3   chs 	 * txg of tosnap snapshot in current dataset
    590  1.3   chs 	 */
    591  1.3   chs 
    592  1.1  haad 	uint64_t parent_fromsnap_guid;
    593  1.3   chs 	uint64_t fromsnap_txg;
    594  1.3   chs 	uint64_t tosnap_txg;
    595  1.3   chs 
    596  1.3   chs 	/* the nvlists get accumulated during depth-first traversal */
    597  1.1  haad 	nvlist_t *parent_snaps;
    598  1.1  haad 	nvlist_t *fss;
    599  1.1  haad 	nvlist_t *snapprops;
    600  1.3   chs 
    601  1.3   chs 	/* send-receive configuration, does not change during traversal */
    602  1.3   chs 	const char *fsname;
    603  1.1  haad 	const char *fromsnap;
    604  1.1  haad 	const char *tosnap;
    605  1.2   dsl 	boolean_t recursive;
    606  1.3   chs 	boolean_t verbose;
    607  1.1  haad 
    608  1.1  haad 	/*
    609  1.1  haad 	 * The header nvlist is of the following format:
    610  1.1  haad 	 * {
    611  1.1  haad 	 *   "tosnap" -> string
    612  1.1  haad 	 *   "fromsnap" -> string (if incremental)
    613  1.1  haad 	 *   "fss" -> {
    614  1.1  haad 	 *	id -> {
    615  1.1  haad 	 *
    616  1.1  haad 	 *	 "name" -> string (full name; for debugging)
    617  1.1  haad 	 *	 "parentfromsnap" -> number (guid of fromsnap in parent)
    618  1.1  haad 	 *
    619  1.1  haad 	 *	 "props" -> { name -> value (only if set here) }
    620  1.1  haad 	 *	 "snaps" -> { name (lastname) -> number (guid) }
    621  1.1  haad 	 *	 "snapprops" -> { name (lastname) -> { name -> value } }
    622  1.1  haad 	 *
    623  1.1  haad 	 *	 "origin" -> number (guid) (if clone)
    624  1.1  haad 	 *	 "sent" -> boolean (not on-disk)
    625  1.1  haad 	 *	}
    626  1.1  haad 	 *   }
    627  1.1  haad 	 * }
    628  1.1  haad 	 *
    629  1.1  haad 	 */
    630  1.1  haad } send_data_t;
    631  1.1  haad 
    632  1.1  haad static void send_iterate_prop(zfs_handle_t *zhp, nvlist_t *nv);
    633  1.1  haad 
    634  1.1  haad static int
    635  1.1  haad send_iterate_snap(zfs_handle_t *zhp, void *arg)
    636  1.1  haad {
    637  1.1  haad 	send_data_t *sd = arg;
    638  1.1  haad 	uint64_t guid = zhp->zfs_dmustats.dds_guid;
    639  1.3   chs 	uint64_t txg = zhp->zfs_dmustats.dds_creation_txg;
    640  1.1  haad 	char *snapname;
    641  1.1  haad 	nvlist_t *nv;
    642  1.1  haad 
    643  1.1  haad 	snapname = strrchr(zhp->zfs_name, '@')+1;
    644  1.1  haad 
    645  1.3   chs 	if (sd->tosnap_txg != 0 && txg > sd->tosnap_txg) {
    646  1.3   chs 		if (sd->verbose) {
    647  1.3   chs 			(void) fprintf(stderr, dgettext(TEXT_DOMAIN,
    648  1.3   chs 			    "skipping snapshot %s because it was created "
    649  1.3   chs 			    "after the destination snapshot (%s)\n"),
    650  1.3   chs 			    zhp->zfs_name, sd->tosnap);
    651  1.3   chs 		}
    652  1.3   chs 		zfs_close(zhp);
    653  1.3   chs 		return (0);
    654  1.3   chs 	}
    655  1.3   chs 
    656  1.1  haad 	VERIFY(0 == nvlist_add_uint64(sd->parent_snaps, snapname, guid));
    657  1.1  haad 	/*
    658  1.1  haad 	 * NB: if there is no fromsnap here (it's a newly created fs in
    659  1.1  haad 	 * an incremental replication), we will substitute the tosnap.
    660  1.1  haad 	 */
    661  1.1  haad 	if ((sd->fromsnap && strcmp(snapname, sd->fromsnap) == 0) ||
    662  1.1  haad 	    (sd->parent_fromsnap_guid == 0 && sd->tosnap &&
    663  1.1  haad 	    strcmp(snapname, sd->tosnap) == 0)) {
    664  1.1  haad 		sd->parent_fromsnap_guid = guid;
    665  1.1  haad 	}
    666  1.1  haad 
    667  1.1  haad 	VERIFY(0 == nvlist_alloc(&nv, NV_UNIQUE_NAME, 0));
    668  1.1  haad 	send_iterate_prop(zhp, nv);
    669  1.1  haad 	VERIFY(0 == nvlist_add_nvlist(sd->snapprops, snapname, nv));
    670  1.1  haad 	nvlist_free(nv);
    671  1.1  haad 
    672  1.1  haad 	zfs_close(zhp);
    673  1.1  haad 	return (0);
    674  1.1  haad }
    675  1.1  haad 
    676  1.1  haad static void
    677  1.1  haad send_iterate_prop(zfs_handle_t *zhp, nvlist_t *nv)
    678  1.1  haad {
    679  1.1  haad 	nvpair_t *elem = NULL;
    680  1.1  haad 
    681  1.1  haad 	while ((elem = nvlist_next_nvpair(zhp->zfs_props, elem)) != NULL) {
    682  1.1  haad 		char *propname = nvpair_name(elem);
    683  1.1  haad 		zfs_prop_t prop = zfs_name_to_prop(propname);
    684  1.1  haad 		nvlist_t *propnv;
    685  1.1  haad 
    686  1.2   dsl 		if (!zfs_prop_user(propname)) {
    687  1.2   dsl 			/*
    688  1.2   dsl 			 * Realistically, this should never happen.  However,
    689  1.2   dsl 			 * we want the ability to add DSL properties without
    690  1.2   dsl 			 * needing to make incompatible version changes.  We
    691  1.2   dsl 			 * need to ignore unknown properties to allow older
    692  1.2   dsl 			 * software to still send datasets containing these
    693  1.2   dsl 			 * properties, with the unknown properties elided.
    694  1.2   dsl 			 */
    695  1.2   dsl 			if (prop == ZPROP_INVAL)
    696  1.2   dsl 				continue;
    697  1.2   dsl 
    698  1.2   dsl 			if (zfs_prop_readonly(prop))
    699  1.2   dsl 				continue;
    700  1.2   dsl 		}
    701  1.1  haad 
    702  1.1  haad 		verify(nvpair_value_nvlist(elem, &propnv) == 0);
    703  1.2   dsl 		if (prop == ZFS_PROP_QUOTA || prop == ZFS_PROP_RESERVATION ||
    704  1.2   dsl 		    prop == ZFS_PROP_REFQUOTA ||
    705  1.2   dsl 		    prop == ZFS_PROP_REFRESERVATION) {
    706  1.2   dsl 			char *source;
    707  1.1  haad 			uint64_t value;
    708  1.1  haad 			verify(nvlist_lookup_uint64(propnv,
    709  1.1  haad 			    ZPROP_VALUE, &value) == 0);
    710  1.1  haad 			if (zhp->zfs_type == ZFS_TYPE_SNAPSHOT)
    711  1.1  haad 				continue;
    712  1.2   dsl 			/*
    713  1.2   dsl 			 * May have no source before SPA_VERSION_RECVD_PROPS,
    714  1.2   dsl 			 * but is still modifiable.
    715  1.2   dsl 			 */
    716  1.2   dsl 			if (nvlist_lookup_string(propnv,
    717  1.2   dsl 			    ZPROP_SOURCE, &source) == 0) {
    718  1.2   dsl 				if ((strcmp(source, zhp->zfs_name) != 0) &&
    719  1.2   dsl 				    (strcmp(source,
    720  1.2   dsl 				    ZPROP_SOURCE_VAL_RECVD) != 0))
    721  1.2   dsl 					continue;
    722  1.2   dsl 			}
    723  1.1  haad 		} else {
    724  1.1  haad 			char *source;
    725  1.1  haad 			if (nvlist_lookup_string(propnv,
    726  1.1  haad 			    ZPROP_SOURCE, &source) != 0)
    727  1.1  haad 				continue;
    728  1.2   dsl 			if ((strcmp(source, zhp->zfs_name) != 0) &&
    729  1.2   dsl 			    (strcmp(source, ZPROP_SOURCE_VAL_RECVD) != 0))
    730  1.1  haad 				continue;
    731  1.1  haad 		}
    732  1.1  haad 
    733  1.1  haad 		if (zfs_prop_user(propname) ||
    734  1.1  haad 		    zfs_prop_get_type(prop) == PROP_TYPE_STRING) {
    735  1.1  haad 			char *value;
    736  1.1  haad 			verify(nvlist_lookup_string(propnv,
    737  1.1  haad 			    ZPROP_VALUE, &value) == 0);
    738  1.1  haad 			VERIFY(0 == nvlist_add_string(nv, propname, value));
    739  1.1  haad 		} else {
    740  1.1  haad 			uint64_t value;
    741  1.1  haad 			verify(nvlist_lookup_uint64(propnv,
    742  1.1  haad 			    ZPROP_VALUE, &value) == 0);
    743  1.1  haad 			VERIFY(0 == nvlist_add_uint64(nv, propname, value));
    744  1.1  haad 		}
    745  1.1  haad 	}
    746  1.1  haad }
    747  1.1  haad 
    748  1.2   dsl /*
    749  1.3   chs  * returns snapshot creation txg
    750  1.3   chs  * and returns 0 if the snapshot does not exist
    751  1.3   chs  */
    752  1.3   chs static uint64_t
    753  1.3   chs get_snap_txg(libzfs_handle_t *hdl, const char *fs, const char *snap)
    754  1.3   chs {
    755  1.3   chs 	char name[ZFS_MAX_DATASET_NAME_LEN];
    756  1.3   chs 	uint64_t txg = 0;
    757  1.3   chs 
    758  1.3   chs 	if (fs == NULL || fs[0] == '\0' || snap == NULL || snap[0] == '\0')
    759  1.3   chs 		return (txg);
    760  1.3   chs 
    761  1.3   chs 	(void) snprintf(name, sizeof (name), "%s@%s", fs, snap);
    762  1.3   chs 	if (zfs_dataset_exists(hdl, name, ZFS_TYPE_SNAPSHOT)) {
    763  1.3   chs 		zfs_handle_t *zhp = zfs_open(hdl, name, ZFS_TYPE_SNAPSHOT);
    764  1.3   chs 		if (zhp != NULL) {
    765  1.3   chs 			txg = zfs_prop_get_int(zhp, ZFS_PROP_CREATETXG);
    766  1.3   chs 			zfs_close(zhp);
    767  1.3   chs 		}
    768  1.3   chs 	}
    769  1.3   chs 
    770  1.3   chs 	return (txg);
    771  1.3   chs }
    772  1.3   chs 
    773  1.3   chs /*
    774  1.2   dsl  * recursively generate nvlists describing datasets.  See comment
    775  1.2   dsl  * for the data structure send_data_t above for description of contents
    776  1.2   dsl  * of the nvlist.
    777  1.2   dsl  */
    778  1.1  haad static int
    779  1.1  haad send_iterate_fs(zfs_handle_t *zhp, void *arg)
    780  1.1  haad {
    781  1.1  haad 	send_data_t *sd = arg;
    782  1.1  haad 	nvlist_t *nvfs, *nv;
    783  1.2   dsl 	int rv = 0;
    784  1.1  haad 	uint64_t parent_fromsnap_guid_save = sd->parent_fromsnap_guid;
    785  1.3   chs 	uint64_t fromsnap_txg_save = sd->fromsnap_txg;
    786  1.3   chs 	uint64_t tosnap_txg_save = sd->tosnap_txg;
    787  1.3   chs 	uint64_t txg = zhp->zfs_dmustats.dds_creation_txg;
    788  1.1  haad 	uint64_t guid = zhp->zfs_dmustats.dds_guid;
    789  1.3   chs 	uint64_t fromsnap_txg, tosnap_txg;
    790  1.1  haad 	char guidstring[64];
    791  1.1  haad 
    792  1.3   chs 	fromsnap_txg = get_snap_txg(zhp->zfs_hdl, zhp->zfs_name, sd->fromsnap);
    793  1.3   chs 	if (fromsnap_txg != 0)
    794  1.3   chs 		sd->fromsnap_txg = fromsnap_txg;
    795  1.3   chs 
    796  1.3   chs 	tosnap_txg = get_snap_txg(zhp->zfs_hdl, zhp->zfs_name, sd->tosnap);
    797  1.3   chs 	if (tosnap_txg != 0)
    798  1.3   chs 		sd->tosnap_txg = tosnap_txg;
    799  1.3   chs 
    800  1.3   chs 	/*
    801  1.3   chs 	 * on the send side, if the current dataset does not have tosnap,
    802  1.3   chs 	 * perform two additional checks:
    803  1.3   chs 	 *
    804  1.3   chs 	 * - skip sending the current dataset if it was created later than
    805  1.3   chs 	 *   the parent tosnap
    806  1.3   chs 	 * - return error if the current dataset was created earlier than
    807  1.3   chs 	 *   the parent tosnap
    808  1.3   chs 	 */
    809  1.3   chs 	if (sd->tosnap != NULL && tosnap_txg == 0) {
    810  1.3   chs 		if (sd->tosnap_txg != 0 && txg > sd->tosnap_txg) {
    811  1.3   chs 			if (sd->verbose) {
    812  1.3   chs 				(void) fprintf(stderr, dgettext(TEXT_DOMAIN,
    813  1.3   chs 				    "skipping dataset %s: snapshot %s does "
    814  1.3   chs 				    "not exist\n"), zhp->zfs_name, sd->tosnap);
    815  1.3   chs 			}
    816  1.3   chs 		} else {
    817  1.3   chs 			(void) fprintf(stderr, dgettext(TEXT_DOMAIN,
    818  1.3   chs 			    "cannot send %s@%s%s: snapshot %s@%s does not "
    819  1.3   chs 			    "exist\n"), sd->fsname, sd->tosnap, sd->recursive ?
    820  1.3   chs 			    dgettext(TEXT_DOMAIN, " recursively") : "",
    821  1.3   chs 			    zhp->zfs_name, sd->tosnap);
    822  1.3   chs 			rv = -1;
    823  1.3   chs 		}
    824  1.3   chs 		goto out;
    825  1.3   chs 	}
    826  1.3   chs 
    827  1.1  haad 	VERIFY(0 == nvlist_alloc(&nvfs, NV_UNIQUE_NAME, 0));
    828  1.1  haad 	VERIFY(0 == nvlist_add_string(nvfs, "name", zhp->zfs_name));
    829  1.1  haad 	VERIFY(0 == nvlist_add_uint64(nvfs, "parentfromsnap",
    830  1.1  haad 	    sd->parent_fromsnap_guid));
    831  1.1  haad 
    832  1.1  haad 	if (zhp->zfs_dmustats.dds_origin[0]) {
    833  1.1  haad 		zfs_handle_t *origin = zfs_open(zhp->zfs_hdl,
    834  1.1  haad 		    zhp->zfs_dmustats.dds_origin, ZFS_TYPE_SNAPSHOT);
    835  1.3   chs 		if (origin == NULL) {
    836  1.3   chs 			rv = -1;
    837  1.3   chs 			goto out;
    838  1.3   chs 		}
    839  1.1  haad 		VERIFY(0 == nvlist_add_uint64(nvfs, "origin",
    840  1.1  haad 		    origin->zfs_dmustats.dds_guid));
    841  1.1  haad 	}
    842  1.1  haad 
    843  1.1  haad 	/* iterate over props */
    844  1.1  haad 	VERIFY(0 == nvlist_alloc(&nv, NV_UNIQUE_NAME, 0));
    845  1.1  haad 	send_iterate_prop(zhp, nv);
    846  1.1  haad 	VERIFY(0 == nvlist_add_nvlist(nvfs, "props", nv));
    847  1.1  haad 	nvlist_free(nv);
    848  1.1  haad 
    849  1.1  haad 	/* iterate over snaps, and set sd->parent_fromsnap_guid */
    850  1.1  haad 	sd->parent_fromsnap_guid = 0;
    851  1.1  haad 	VERIFY(0 == nvlist_alloc(&sd->parent_snaps, NV_UNIQUE_NAME, 0));
    852  1.1  haad 	VERIFY(0 == nvlist_alloc(&sd->snapprops, NV_UNIQUE_NAME, 0));
    853  1.3   chs 	(void) zfs_iter_snapshots_sorted(zhp, send_iterate_snap, sd);
    854  1.1  haad 	VERIFY(0 == nvlist_add_nvlist(nvfs, "snaps", sd->parent_snaps));
    855  1.1  haad 	VERIFY(0 == nvlist_add_nvlist(nvfs, "snapprops", sd->snapprops));
    856  1.1  haad 	nvlist_free(sd->parent_snaps);
    857  1.1  haad 	nvlist_free(sd->snapprops);
    858  1.1  haad 
    859  1.1  haad 	/* add this fs to nvlist */
    860  1.1  haad 	(void) snprintf(guidstring, sizeof (guidstring),
    861  1.1  haad 	    "0x%llx", (longlong_t)guid);
    862  1.1  haad 	VERIFY(0 == nvlist_add_nvlist(sd->fss, guidstring, nvfs));
    863  1.1  haad 	nvlist_free(nvfs);
    864  1.1  haad 
    865  1.1  haad 	/* iterate over children */
    866  1.2   dsl 	if (sd->recursive)
    867  1.2   dsl 		rv = zfs_iter_filesystems(zhp, send_iterate_fs, sd);
    868  1.1  haad 
    869  1.3   chs out:
    870  1.1  haad 	sd->parent_fromsnap_guid = parent_fromsnap_guid_save;
    871  1.3   chs 	sd->fromsnap_txg = fromsnap_txg_save;
    872  1.3   chs 	sd->tosnap_txg = tosnap_txg_save;
    873  1.1  haad 
    874  1.1  haad 	zfs_close(zhp);
    875  1.1  haad 	return (rv);
    876  1.1  haad }
    877  1.1  haad 
    878  1.1  haad static int
    879  1.1  haad gather_nvlist(libzfs_handle_t *hdl, const char *fsname, const char *fromsnap,
    880  1.3   chs     const char *tosnap, boolean_t recursive, boolean_t verbose,
    881  1.3   chs     nvlist_t **nvlp, avl_tree_t **avlp)
    882  1.1  haad {
    883  1.1  haad 	zfs_handle_t *zhp;
    884  1.1  haad 	send_data_t sd = { 0 };
    885  1.1  haad 	int error;
    886  1.1  haad 
    887  1.1  haad 	zhp = zfs_open(hdl, fsname, ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME);
    888  1.1  haad 	if (zhp == NULL)
    889  1.1  haad 		return (EZFS_BADTYPE);
    890  1.1  haad 
    891  1.1  haad 	VERIFY(0 == nvlist_alloc(&sd.fss, NV_UNIQUE_NAME, 0));
    892  1.3   chs 	sd.fsname = fsname;
    893  1.1  haad 	sd.fromsnap = fromsnap;
    894  1.1  haad 	sd.tosnap = tosnap;
    895  1.2   dsl 	sd.recursive = recursive;
    896  1.3   chs 	sd.verbose = verbose;
    897  1.1  haad 
    898  1.1  haad 	if ((error = send_iterate_fs(zhp, &sd)) != 0) {
    899  1.1  haad 		nvlist_free(sd.fss);
    900  1.1  haad 		if (avlp != NULL)
    901  1.1  haad 			*avlp = NULL;
    902  1.1  haad 		*nvlp = NULL;
    903  1.1  haad 		return (error);
    904  1.1  haad 	}
    905  1.1  haad 
    906  1.1  haad 	if (avlp != NULL && (*avlp = fsavl_create(sd.fss)) == NULL) {
    907  1.1  haad 		nvlist_free(sd.fss);
    908  1.1  haad 		*nvlp = NULL;
    909  1.1  haad 		return (EZFS_NOMEM);
    910  1.1  haad 	}
    911  1.1  haad 
    912  1.1  haad 	*nvlp = sd.fss;
    913  1.1  haad 	return (0);
    914  1.1  haad }
    915  1.1  haad 
    916  1.1  haad /*
    917  1.3   chs  * Routines specific to "zfs send"
    918  1.1  haad  */
    919  1.3   chs typedef struct send_dump_data {
    920  1.3   chs 	/* these are all just the short snapname (the part after the @) */
    921  1.3   chs 	const char *fromsnap;
    922  1.3   chs 	const char *tosnap;
    923  1.3   chs 	char prevsnap[ZFS_MAX_DATASET_NAME_LEN];
    924  1.3   chs 	uint64_t prevsnap_obj;
    925  1.3   chs 	boolean_t seenfrom, seento, replicate, doall, fromorigin;
    926  1.3   chs 	boolean_t verbose, dryrun, parsable, progress, embed_data, std_out;
    927  1.3   chs 	boolean_t large_block;
    928  1.3   chs 	int outfd;
    929  1.3   chs 	boolean_t err;
    930  1.3   chs 	nvlist_t *fss;
    931  1.3   chs 	nvlist_t *snapholds;
    932  1.3   chs 	avl_tree_t *fsavl;
    933  1.3   chs 	snapfilter_cb_t *filter_cb;
    934  1.3   chs 	void *filter_cb_arg;
    935  1.3   chs 	nvlist_t *debugnv;
    936  1.3   chs 	char holdtag[ZFS_MAX_DATASET_NAME_LEN];
    937  1.3   chs 	int cleanup_fd;
    938  1.3   chs 	uint64_t size;
    939  1.3   chs } send_dump_data_t;
    940  1.1  haad 
    941  1.1  haad static int
    942  1.3   chs estimate_ioctl(zfs_handle_t *zhp, uint64_t fromsnap_obj,
    943  1.3   chs     boolean_t fromorigin, uint64_t *sizep)
    944  1.1  haad {
    945  1.3   chs 	zfs_cmd_t zc = { 0 };
    946  1.3   chs 	libzfs_handle_t *hdl = zhp->zfs_hdl;
    947  1.1  haad 
    948  1.3   chs 	assert(zhp->zfs_type == ZFS_TYPE_SNAPSHOT);
    949  1.3   chs 	assert(fromsnap_obj == 0 || !fromorigin);
    950  1.1  haad 
    951  1.3   chs 	(void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
    952  1.3   chs 	zc.zc_obj = fromorigin;
    953  1.3   chs 	zc.zc_sendobj = zfs_prop_get_int(zhp, ZFS_PROP_OBJSETID);
    954  1.3   chs 	zc.zc_fromobj = fromsnap_obj;
    955  1.3   chs 	zc.zc_guid = 1;  /* estimate flag */
    956  1.1  haad 
    957  1.3   chs 	if (zfs_ioctl(zhp->zfs_hdl, ZFS_IOC_SEND, &zc) != 0) {
    958  1.3   chs 		char errbuf[1024];
    959  1.3   chs 		(void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
    960  1.3   chs 		    "warning: cannot estimate space for '%s'"), zhp->zfs_name);
    961  1.1  haad 
    962  1.3   chs 		switch (errno) {
    963  1.3   chs 		case EXDEV:
    964  1.3   chs 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
    965  1.3   chs 			    "not an earlier snapshot from the same fs"));
    966  1.3   chs 			return (zfs_error(hdl, EZFS_CROSSTARGET, errbuf));
    967  1.1  haad 
    968  1.3   chs 		case ENOENT:
    969  1.3   chs 			if (zfs_dataset_exists(hdl, zc.zc_name,
    970  1.3   chs 			    ZFS_TYPE_SNAPSHOT)) {
    971  1.3   chs 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
    972  1.3   chs 				    "incremental source (@%s) does not exist"),
    973  1.3   chs 				    zc.zc_value);
    974  1.3   chs 			}
    975  1.3   chs 			return (zfs_error(hdl, EZFS_NOENT, errbuf));
    976  1.1  haad 
    977  1.3   chs 		case EDQUOT:
    978  1.3   chs 		case EFBIG:
    979  1.3   chs 		case EIO:
    980  1.3   chs 		case ENOLINK:
    981  1.3   chs 		case ENOSPC:
    982  1.3   chs 		case ENXIO:
    983  1.3   chs 		case EPIPE:
    984  1.3   chs 		case ERANGE:
    985  1.3   chs 		case EFAULT:
    986  1.3   chs 		case EROFS:
    987  1.3   chs 			zfs_error_aux(hdl, strerror(errno));
    988  1.3   chs 			return (zfs_error(hdl, EZFS_BADBACKUP, errbuf));
    989  1.1  haad 
    990  1.3   chs 		default:
    991  1.3   chs 			return (zfs_standard_error(hdl, errno, errbuf));
    992  1.3   chs 		}
    993  1.3   chs 	}
    994  1.1  haad 
    995  1.3   chs 	*sizep = zc.zc_objset_type;
    996  1.1  haad 
    997  1.3   chs 	return (0);
    998  1.1  haad }
    999  1.1  haad 
   1000  1.1  haad /*
   1001  1.1  haad  * Dumps a backup of the given snapshot (incremental from fromsnap if it's not
   1002  1.1  haad  * NULL) to the file descriptor specified by outfd.
   1003  1.1  haad  */
   1004  1.1  haad static int
   1005  1.3   chs dump_ioctl(zfs_handle_t *zhp, const char *fromsnap, uint64_t fromsnap_obj,
   1006  1.3   chs     boolean_t fromorigin, int outfd, enum lzc_send_flags flags,
   1007  1.3   chs     nvlist_t *debugnv)
   1008  1.1  haad {
   1009  1.1  haad 	zfs_cmd_t zc = { 0 };
   1010  1.1  haad 	libzfs_handle_t *hdl = zhp->zfs_hdl;
   1011  1.3   chs 	nvlist_t *thisdbg;
   1012  1.1  haad 
   1013  1.1  haad 	assert(zhp->zfs_type == ZFS_TYPE_SNAPSHOT);
   1014  1.3   chs 	assert(fromsnap_obj == 0 || !fromorigin);
   1015  1.1  haad 
   1016  1.1  haad 	(void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
   1017  1.1  haad 	zc.zc_cookie = outfd;
   1018  1.1  haad 	zc.zc_obj = fromorigin;
   1019  1.3   chs 	zc.zc_sendobj = zfs_prop_get_int(zhp, ZFS_PROP_OBJSETID);
   1020  1.3   chs 	zc.zc_fromobj = fromsnap_obj;
   1021  1.3   chs 	zc.zc_flags = flags;
   1022  1.1  haad 
   1023  1.3   chs 	VERIFY(0 == nvlist_alloc(&thisdbg, NV_UNIQUE_NAME, 0));
   1024  1.3   chs 	if (fromsnap && fromsnap[0] != '\0') {
   1025  1.3   chs 		VERIFY(0 == nvlist_add_string(thisdbg,
   1026  1.3   chs 		    "fromsnap", fromsnap));
   1027  1.3   chs 	}
   1028  1.2   dsl 
   1029  1.3   chs 	if (zfs_ioctl(zhp->zfs_hdl, ZFS_IOC_SEND, &zc) != 0) {
   1030  1.1  haad 		char errbuf[1024];
   1031  1.1  haad 		(void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
   1032  1.1  haad 		    "warning: cannot send '%s'"), zhp->zfs_name);
   1033  1.1  haad 
   1034  1.3   chs 		VERIFY(0 == nvlist_add_uint64(thisdbg, "error", errno));
   1035  1.3   chs 		if (debugnv) {
   1036  1.3   chs 			VERIFY(0 == nvlist_add_nvlist(debugnv,
   1037  1.3   chs 			    zhp->zfs_name, thisdbg));
   1038  1.3   chs 		}
   1039  1.3   chs 		nvlist_free(thisdbg);
   1040  1.3   chs 
   1041  1.1  haad 		switch (errno) {
   1042  1.1  haad 		case EXDEV:
   1043  1.1  haad 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
   1044  1.1  haad 			    "not an earlier snapshot from the same fs"));
   1045  1.1  haad 			return (zfs_error(hdl, EZFS_CROSSTARGET, errbuf));
   1046  1.1  haad 
   1047  1.1  haad 		case ENOENT:
   1048  1.1  haad 			if (zfs_dataset_exists(hdl, zc.zc_name,
   1049  1.1  haad 			    ZFS_TYPE_SNAPSHOT)) {
   1050  1.1  haad 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
   1051  1.1  haad 				    "incremental source (@%s) does not exist"),
   1052  1.1  haad 				    zc.zc_value);
   1053  1.1  haad 			}
   1054  1.1  haad 			return (zfs_error(hdl, EZFS_NOENT, errbuf));
   1055  1.1  haad 
   1056  1.1  haad 		case EDQUOT:
   1057  1.1  haad 		case EFBIG:
   1058  1.1  haad 		case EIO:
   1059  1.1  haad 		case ENOLINK:
   1060  1.1  haad 		case ENOSPC:
   1061  1.3   chs #ifdef illumos
   1062  1.1  haad 		case ENOSTR:
   1063  1.3   chs #endif
   1064  1.1  haad 		case ENXIO:
   1065  1.1  haad 		case EPIPE:
   1066  1.1  haad 		case ERANGE:
   1067  1.1  haad 		case EFAULT:
   1068  1.1  haad 		case EROFS:
   1069  1.1  haad 			zfs_error_aux(hdl, strerror(errno));
   1070  1.1  haad 			return (zfs_error(hdl, EZFS_BADBACKUP, errbuf));
   1071  1.1  haad 
   1072  1.1  haad 		default:
   1073  1.1  haad 			return (zfs_standard_error(hdl, errno, errbuf));
   1074  1.1  haad 		}
   1075  1.1  haad 	}
   1076  1.1  haad 
   1077  1.3   chs 	if (debugnv)
   1078  1.3   chs 		VERIFY(0 == nvlist_add_nvlist(debugnv, zhp->zfs_name, thisdbg));
   1079  1.3   chs 	nvlist_free(thisdbg);
   1080  1.3   chs 
   1081  1.1  haad 	return (0);
   1082  1.1  haad }
   1083  1.1  haad 
   1084  1.3   chs static void
   1085  1.3   chs gather_holds(zfs_handle_t *zhp, send_dump_data_t *sdd)
   1086  1.3   chs {
   1087  1.3   chs 	assert(zhp->zfs_type == ZFS_TYPE_SNAPSHOT);
   1088  1.3   chs 
   1089  1.3   chs 	/*
   1090  1.3   chs 	 * zfs_send() only sets snapholds for sends that need them,
   1091  1.3   chs 	 * e.g. replication and doall.
   1092  1.3   chs 	 */
   1093  1.3   chs 	if (sdd->snapholds == NULL)
   1094  1.3   chs 		return;
   1095  1.3   chs 
   1096  1.3   chs 	fnvlist_add_string(sdd->snapholds, zhp->zfs_name, sdd->holdtag);
   1097  1.3   chs }
   1098  1.3   chs 
   1099  1.3   chs static void *
   1100  1.3   chs send_progress_thread(void *arg)
   1101  1.3   chs {
   1102  1.3   chs 	progress_arg_t *pa = arg;
   1103  1.3   chs 	zfs_cmd_t zc = { 0 };
   1104  1.3   chs 	zfs_handle_t *zhp = pa->pa_zhp;
   1105  1.3   chs 	libzfs_handle_t *hdl = zhp->zfs_hdl;
   1106  1.3   chs 	unsigned long long bytes;
   1107  1.3   chs 	char buf[16];
   1108  1.3   chs 	time_t t;
   1109  1.3   chs 	struct tm *tm;
   1110  1.3   chs 
   1111  1.3   chs 	(void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
   1112  1.3   chs 
   1113  1.3   chs 	if (!pa->pa_parsable)
   1114  1.3   chs 		(void) fprintf(stderr, "TIME        SENT   SNAPSHOT\n");
   1115  1.3   chs 
   1116  1.3   chs 	/*
   1117  1.3   chs 	 * Print the progress from ZFS_IOC_SEND_PROGRESS every second.
   1118  1.3   chs 	 */
   1119  1.3   chs 	for (;;) {
   1120  1.3   chs 		(void) sleep(1);
   1121  1.3   chs 
   1122  1.3   chs 		zc.zc_cookie = pa->pa_fd;
   1123  1.3   chs 		if (zfs_ioctl(hdl, ZFS_IOC_SEND_PROGRESS, &zc) != 0)
   1124  1.3   chs 			return ((void *)-1);
   1125  1.3   chs 
   1126  1.3   chs 		(void) time(&t);
   1127  1.3   chs 		tm = localtime(&t);
   1128  1.3   chs 		bytes = zc.zc_cookie;
   1129  1.3   chs 
   1130  1.3   chs 		if (pa->pa_parsable) {
   1131  1.3   chs 			(void) fprintf(stderr, "%02d:%02d:%02d\t%llu\t%s\n",
   1132  1.3   chs 			    tm->tm_hour, tm->tm_min, tm->tm_sec,
   1133  1.3   chs 			    bytes, zhp->zfs_name);
   1134  1.3   chs 		} else {
   1135  1.3   chs 			zfs_nicenum(bytes, buf, sizeof (buf));
   1136  1.3   chs 			(void) fprintf(stderr, "%02d:%02d:%02d   %5s   %s\n",
   1137  1.3   chs 			    tm->tm_hour, tm->tm_min, tm->tm_sec,
   1138  1.3   chs 			    buf, zhp->zfs_name);
   1139  1.3   chs 		}
   1140  1.3   chs 	}
   1141  1.3   chs }
   1142  1.3   chs 
   1143  1.3   chs static void
   1144  1.3   chs send_print_verbose(FILE *fout, const char *tosnap, const char *fromsnap,
   1145  1.3   chs     uint64_t size, boolean_t parsable)
   1146  1.3   chs {
   1147  1.3   chs 	if (parsable) {
   1148  1.3   chs 		if (fromsnap != NULL) {
   1149  1.3   chs 			(void) fprintf(fout, "incremental\t%s\t%s",
   1150  1.3   chs 			    fromsnap, tosnap);
   1151  1.3   chs 		} else {
   1152  1.3   chs 			(void) fprintf(fout, "full\t%s",
   1153  1.3   chs 			    tosnap);
   1154  1.3   chs 		}
   1155  1.3   chs 	} else {
   1156  1.3   chs 		if (fromsnap != NULL) {
   1157  1.3   chs 			if (strchr(fromsnap, '@') == NULL &&
   1158  1.3   chs 			    strchr(fromsnap, '#') == NULL) {
   1159  1.3   chs 				(void) fprintf(fout, dgettext(TEXT_DOMAIN,
   1160  1.3   chs 				    "send from @%s to %s"),
   1161  1.3   chs 				    fromsnap, tosnap);
   1162  1.3   chs 			} else {
   1163  1.3   chs 				(void) fprintf(fout, dgettext(TEXT_DOMAIN,
   1164  1.3   chs 				    "send from %s to %s"),
   1165  1.3   chs 				    fromsnap, tosnap);
   1166  1.3   chs 			}
   1167  1.3   chs 		} else {
   1168  1.3   chs 			(void) fprintf(fout, dgettext(TEXT_DOMAIN,
   1169  1.3   chs 			    "full send of %s"),
   1170  1.3   chs 			    tosnap);
   1171  1.3   chs 		}
   1172  1.3   chs 	}
   1173  1.3   chs 
   1174  1.3   chs 	if (size != 0) {
   1175  1.3   chs 		if (parsable) {
   1176  1.3   chs 			(void) fprintf(fout, "\t%llu",
   1177  1.3   chs 			    (longlong_t)size);
   1178  1.3   chs 		} else {
   1179  1.3   chs 			char buf[16];
   1180  1.3   chs 			zfs_nicenum(size, buf, sizeof (buf));
   1181  1.3   chs 			(void) fprintf(fout, dgettext(TEXT_DOMAIN,
   1182  1.3   chs 			    " estimated size is %s"), buf);
   1183  1.3   chs 		}
   1184  1.3   chs 	}
   1185  1.3   chs 	(void) fprintf(fout, "\n");
   1186  1.3   chs }
   1187  1.3   chs 
   1188  1.1  haad static int
   1189  1.1  haad dump_snapshot(zfs_handle_t *zhp, void *arg)
   1190  1.1  haad {
   1191  1.1  haad 	send_dump_data_t *sdd = arg;
   1192  1.3   chs 	progress_arg_t pa = { 0 };
   1193  1.3   chs 	pthread_t tid;
   1194  1.3   chs 	char *thissnap;
   1195  1.1  haad 	int err;
   1196  1.3   chs 	boolean_t isfromsnap, istosnap, fromorigin;
   1197  1.3   chs 	boolean_t exclude = B_FALSE;
   1198  1.3   chs 	FILE *fout = sdd->std_out ? stdout : stderr;
   1199  1.1  haad 
   1200  1.3   chs 	err = 0;
   1201  1.1  haad 	thissnap = strchr(zhp->zfs_name, '@') + 1;
   1202  1.3   chs 	isfromsnap = (sdd->fromsnap != NULL &&
   1203  1.3   chs 	    strcmp(sdd->fromsnap, thissnap) == 0);
   1204  1.1  haad 
   1205  1.3   chs 	if (!sdd->seenfrom && isfromsnap) {
   1206  1.3   chs 		gather_holds(zhp, sdd);
   1207  1.1  haad 		sdd->seenfrom = B_TRUE;
   1208  1.2   dsl 		(void) strcpy(sdd->prevsnap, thissnap);
   1209  1.3   chs 		sdd->prevsnap_obj = zfs_prop_get_int(zhp, ZFS_PROP_OBJSETID);
   1210  1.1  haad 		zfs_close(zhp);
   1211  1.1  haad 		return (0);
   1212  1.1  haad 	}
   1213  1.1  haad 
   1214  1.1  haad 	if (sdd->seento || !sdd->seenfrom) {
   1215  1.1  haad 		zfs_close(zhp);
   1216  1.1  haad 		return (0);
   1217  1.1  haad 	}
   1218  1.1  haad 
   1219  1.3   chs 	istosnap = (strcmp(sdd->tosnap, thissnap) == 0);
   1220  1.3   chs 	if (istosnap)
   1221  1.2   dsl 		sdd->seento = B_TRUE;
   1222  1.2   dsl 
   1223  1.3   chs 	if (!sdd->doall && !isfromsnap && !istosnap) {
   1224  1.3   chs 		if (sdd->replicate) {
   1225  1.3   chs 			char *snapname;
   1226  1.3   chs 			nvlist_t *snapprops;
   1227  1.3   chs 			/*
   1228  1.3   chs 			 * Filter out all intermediate snapshots except origin
   1229  1.3   chs 			 * snapshots needed to replicate clones.
   1230  1.3   chs 			 */
   1231  1.3   chs 			nvlist_t *nvfs = fsavl_find(sdd->fsavl,
   1232  1.3   chs 			    zhp->zfs_dmustats.dds_guid, &snapname);
   1233  1.3   chs 
   1234  1.3   chs 			VERIFY(0 == nvlist_lookup_nvlist(nvfs,
   1235  1.3   chs 			    "snapprops", &snapprops));
   1236  1.3   chs 			VERIFY(0 == nvlist_lookup_nvlist(snapprops,
   1237  1.3   chs 			    thissnap, &snapprops));
   1238  1.3   chs 			exclude = !nvlist_exists(snapprops, "is_clone_origin");
   1239  1.3   chs 		} else {
   1240  1.3   chs 			exclude = B_TRUE;
   1241  1.3   chs 		}
   1242  1.3   chs 	}
   1243  1.3   chs 
   1244  1.2   dsl 	/*
   1245  1.2   dsl 	 * If a filter function exists, call it to determine whether
   1246  1.2   dsl 	 * this snapshot will be sent.
   1247  1.2   dsl 	 */
   1248  1.3   chs 	if (exclude || (sdd->filter_cb != NULL &&
   1249  1.3   chs 	    sdd->filter_cb(zhp, sdd->filter_cb_arg) == B_FALSE)) {
   1250  1.2   dsl 		/*
   1251  1.2   dsl 		 * This snapshot is filtered out.  Don't send it, and don't
   1252  1.3   chs 		 * set prevsnap_obj, so it will be as if this snapshot didn't
   1253  1.2   dsl 		 * exist, and the next accepted snapshot will be sent as
   1254  1.2   dsl 		 * an incremental from the last accepted one, or as the
   1255  1.2   dsl 		 * first (and full) snapshot in the case of a replication,
   1256  1.2   dsl 		 * non-incremental send.
   1257  1.2   dsl 		 */
   1258  1.2   dsl 		zfs_close(zhp);
   1259  1.2   dsl 		return (0);
   1260  1.2   dsl 	}
   1261  1.2   dsl 
   1262  1.3   chs 	gather_holds(zhp, sdd);
   1263  1.3   chs 	fromorigin = sdd->prevsnap[0] == '\0' &&
   1264  1.3   chs 	    (sdd->fromorigin || sdd->replicate);
   1265  1.3   chs 
   1266  1.1  haad 	if (sdd->verbose) {
   1267  1.3   chs 		uint64_t size = 0;
   1268  1.3   chs 		(void) estimate_ioctl(zhp, sdd->prevsnap_obj,
   1269  1.3   chs 		    fromorigin, &size);
   1270  1.3   chs 
   1271  1.3   chs 		send_print_verbose(fout, zhp->zfs_name,
   1272  1.3   chs 		    sdd->prevsnap[0] ? sdd->prevsnap : NULL,
   1273  1.3   chs 		    size, sdd->parsable);
   1274  1.3   chs 		sdd->size += size;
   1275  1.1  haad 	}
   1276  1.1  haad 
   1277  1.3   chs 	if (!sdd->dryrun) {
   1278  1.3   chs 		/*
   1279  1.3   chs 		 * If progress reporting is requested, spawn a new thread to
   1280  1.3   chs 		 * poll ZFS_IOC_SEND_PROGRESS at a regular interval.
   1281  1.3   chs 		 */
   1282  1.3   chs 		if (sdd->progress) {
   1283  1.3   chs 			pa.pa_zhp = zhp;
   1284  1.3   chs 			pa.pa_fd = sdd->outfd;
   1285  1.3   chs 			pa.pa_parsable = sdd->parsable;
   1286  1.3   chs 
   1287  1.3   chs 			if ((err = pthread_create(&tid, NULL,
   1288  1.3   chs 			    send_progress_thread, &pa)) != 0) {
   1289  1.3   chs 				zfs_close(zhp);
   1290  1.3   chs 				return (err);
   1291  1.3   chs 			}
   1292  1.3   chs 		}
   1293  1.3   chs 
   1294  1.3   chs 		enum lzc_send_flags flags = 0;
   1295  1.3   chs 		if (sdd->large_block)
   1296  1.3   chs 			flags |= LZC_SEND_FLAG_LARGE_BLOCK;
   1297  1.3   chs 		if (sdd->embed_data)
   1298  1.3   chs 			flags |= LZC_SEND_FLAG_EMBED_DATA;
   1299  1.1  haad 
   1300  1.3   chs 		err = dump_ioctl(zhp, sdd->prevsnap, sdd->prevsnap_obj,
   1301  1.3   chs 		    fromorigin, sdd->outfd, flags, sdd->debugnv);
   1302  1.3   chs 
   1303  1.3   chs 		if (sdd->progress) {
   1304  1.3   chs 			(void) pthread_cancel(tid);
   1305  1.3   chs 			(void) pthread_join(tid, NULL);
   1306  1.3   chs 		}
   1307  1.3   chs 	}
   1308  1.3   chs 
   1309  1.3   chs 	(void) strcpy(sdd->prevsnap, thissnap);
   1310  1.3   chs 	sdd->prevsnap_obj = zfs_prop_get_int(zhp, ZFS_PROP_OBJSETID);
   1311  1.1  haad 	zfs_close(zhp);
   1312  1.1  haad 	return (err);
   1313  1.1  haad }
   1314  1.1  haad 
   1315  1.1  haad static int
   1316  1.1  haad dump_filesystem(zfs_handle_t *zhp, void *arg)
   1317  1.1  haad {
   1318  1.1  haad 	int rv = 0;
   1319  1.1  haad 	send_dump_data_t *sdd = arg;
   1320  1.1  haad 	boolean_t missingfrom = B_FALSE;
   1321  1.1  haad 	zfs_cmd_t zc = { 0 };
   1322  1.1  haad 
   1323  1.1  haad 	(void) snprintf(zc.zc_name, sizeof (zc.zc_name), "%s@%s",
   1324  1.1  haad 	    zhp->zfs_name, sdd->tosnap);
   1325  1.1  haad 	if (ioctl(zhp->zfs_hdl->libzfs_fd, ZFS_IOC_OBJSET_STATS, &zc) != 0) {
   1326  1.3   chs 		(void) fprintf(stderr, dgettext(TEXT_DOMAIN,
   1327  1.3   chs 		    "WARNING: could not send %s@%s: does not exist\n"),
   1328  1.1  haad 		    zhp->zfs_name, sdd->tosnap);
   1329  1.1  haad 		sdd->err = B_TRUE;
   1330  1.1  haad 		return (0);
   1331  1.1  haad 	}
   1332  1.1  haad 
   1333  1.1  haad 	if (sdd->replicate && sdd->fromsnap) {
   1334  1.1  haad 		/*
   1335  1.1  haad 		 * If this fs does not have fromsnap, and we're doing
   1336  1.1  haad 		 * recursive, we need to send a full stream from the
   1337  1.1  haad 		 * beginning (or an incremental from the origin if this
   1338  1.1  haad 		 * is a clone).  If we're doing non-recursive, then let
   1339  1.1  haad 		 * them get the error.
   1340  1.1  haad 		 */
   1341  1.1  haad 		(void) snprintf(zc.zc_name, sizeof (zc.zc_name), "%s@%s",
   1342  1.1  haad 		    zhp->zfs_name, sdd->fromsnap);
   1343  1.1  haad 		if (ioctl(zhp->zfs_hdl->libzfs_fd,
   1344  1.1  haad 		    ZFS_IOC_OBJSET_STATS, &zc) != 0) {
   1345  1.1  haad 			missingfrom = B_TRUE;
   1346  1.1  haad 		}
   1347  1.1  haad 	}
   1348  1.1  haad 
   1349  1.3   chs 	sdd->seenfrom = sdd->seento = sdd->prevsnap[0] = 0;
   1350  1.3   chs 	sdd->prevsnap_obj = 0;
   1351  1.3   chs 	if (sdd->fromsnap == NULL || missingfrom)
   1352  1.3   chs 		sdd->seenfrom = B_TRUE;
   1353  1.3   chs 
   1354  1.3   chs 	rv = zfs_iter_snapshots_sorted(zhp, dump_snapshot, arg);
   1355  1.3   chs 	if (!sdd->seenfrom) {
   1356  1.3   chs 		(void) fprintf(stderr, dgettext(TEXT_DOMAIN,
   1357  1.3   chs 		    "WARNING: could not send %s@%s:\n"
   1358  1.3   chs 		    "incremental source (%s@%s) does not exist\n"),
   1359  1.3   chs 		    zhp->zfs_name, sdd->tosnap,
   1360  1.3   chs 		    zhp->zfs_name, sdd->fromsnap);
   1361  1.3   chs 		sdd->err = B_TRUE;
   1362  1.3   chs 	} else if (!sdd->seento) {
   1363  1.3   chs 		if (sdd->fromsnap) {
   1364  1.3   chs 			(void) fprintf(stderr, dgettext(TEXT_DOMAIN,
   1365  1.1  haad 			    "WARNING: could not send %s@%s:\n"
   1366  1.3   chs 			    "incremental source (%s@%s) "
   1367  1.3   chs 			    "is not earlier than it\n"),
   1368  1.1  haad 			    zhp->zfs_name, sdd->tosnap,
   1369  1.1  haad 			    zhp->zfs_name, sdd->fromsnap);
   1370  1.1  haad 		} else {
   1371  1.3   chs 			(void) fprintf(stderr, dgettext(TEXT_DOMAIN,
   1372  1.3   chs 			    "WARNING: "
   1373  1.3   chs 			    "could not send %s@%s: does not exist\n"),
   1374  1.3   chs 			    zhp->zfs_name, sdd->tosnap);
   1375  1.1  haad 		}
   1376  1.3   chs 		sdd->err = B_TRUE;
   1377  1.1  haad 	}
   1378  1.1  haad 
   1379  1.1  haad 	return (rv);
   1380  1.1  haad }
   1381  1.1  haad 
   1382  1.1  haad static int
   1383  1.1  haad dump_filesystems(zfs_handle_t *rzhp, void *arg)
   1384  1.1  haad {
   1385  1.1  haad 	send_dump_data_t *sdd = arg;
   1386  1.1  haad 	nvpair_t *fspair;
   1387  1.1  haad 	boolean_t needagain, progress;
   1388  1.1  haad 
   1389  1.1  haad 	if (!sdd->replicate)
   1390  1.1  haad 		return (dump_filesystem(rzhp, sdd));
   1391  1.1  haad 
   1392  1.3   chs 	/* Mark the clone origin snapshots. */
   1393  1.3   chs 	for (fspair = nvlist_next_nvpair(sdd->fss, NULL); fspair;
   1394  1.3   chs 	    fspair = nvlist_next_nvpair(sdd->fss, fspair)) {
   1395  1.3   chs 		nvlist_t *nvfs;
   1396  1.3   chs 		uint64_t origin_guid = 0;
   1397  1.3   chs 
   1398  1.3   chs 		VERIFY(0 == nvpair_value_nvlist(fspair, &nvfs));
   1399  1.3   chs 		(void) nvlist_lookup_uint64(nvfs, "origin", &origin_guid);
   1400  1.3   chs 		if (origin_guid != 0) {
   1401  1.3   chs 			char *snapname;
   1402  1.3   chs 			nvlist_t *origin_nv = fsavl_find(sdd->fsavl,
   1403  1.3   chs 			    origin_guid, &snapname);
   1404  1.3   chs 			if (origin_nv != NULL) {
   1405  1.3   chs 				nvlist_t *snapprops;
   1406  1.3   chs 				VERIFY(0 == nvlist_lookup_nvlist(origin_nv,
   1407  1.3   chs 				    "snapprops", &snapprops));
   1408  1.3   chs 				VERIFY(0 == nvlist_lookup_nvlist(snapprops,
   1409  1.3   chs 				    snapname, &snapprops));
   1410  1.3   chs 				VERIFY(0 == nvlist_add_boolean(
   1411  1.3   chs 				    snapprops, "is_clone_origin"));
   1412  1.3   chs 			}
   1413  1.3   chs 		}
   1414  1.3   chs 	}
   1415  1.1  haad again:
   1416  1.1  haad 	needagain = progress = B_FALSE;
   1417  1.1  haad 	for (fspair = nvlist_next_nvpair(sdd->fss, NULL); fspair;
   1418  1.1  haad 	    fspair = nvlist_next_nvpair(sdd->fss, fspair)) {
   1419  1.3   chs 		nvlist_t *fslist, *parent_nv;
   1420  1.1  haad 		char *fsname;
   1421  1.1  haad 		zfs_handle_t *zhp;
   1422  1.1  haad 		int err;
   1423  1.1  haad 		uint64_t origin_guid = 0;
   1424  1.3   chs 		uint64_t parent_guid = 0;
   1425  1.1  haad 
   1426  1.1  haad 		VERIFY(nvpair_value_nvlist(fspair, &fslist) == 0);
   1427  1.1  haad 		if (nvlist_lookup_boolean(fslist, "sent") == 0)
   1428  1.1  haad 			continue;
   1429  1.1  haad 
   1430  1.1  haad 		VERIFY(nvlist_lookup_string(fslist, "name", &fsname) == 0);
   1431  1.1  haad 		(void) nvlist_lookup_uint64(fslist, "origin", &origin_guid);
   1432  1.3   chs 		(void) nvlist_lookup_uint64(fslist, "parentfromsnap",
   1433  1.3   chs 		    &parent_guid);
   1434  1.1  haad 
   1435  1.3   chs 		if (parent_guid != 0) {
   1436  1.3   chs 			parent_nv = fsavl_find(sdd->fsavl, parent_guid, NULL);
   1437  1.3   chs 			if (!nvlist_exists(parent_nv, "sent")) {
   1438  1.3   chs 				/* parent has not been sent; skip this one */
   1439  1.3   chs 				needagain = B_TRUE;
   1440  1.3   chs 				continue;
   1441  1.3   chs 			}
   1442  1.3   chs 		}
   1443  1.3   chs 
   1444  1.3   chs 		if (origin_guid != 0) {
   1445  1.3   chs 			nvlist_t *origin_nv = fsavl_find(sdd->fsavl,
   1446  1.3   chs 			    origin_guid, NULL);
   1447  1.3   chs 			if (origin_nv != NULL &&
   1448  1.3   chs 			    !nvlist_exists(origin_nv, "sent")) {
   1449  1.3   chs 				/*
   1450  1.3   chs 				 * origin has not been sent yet;
   1451  1.3   chs 				 * skip this clone.
   1452  1.3   chs 				 */
   1453  1.3   chs 				needagain = B_TRUE;
   1454  1.3   chs 				continue;
   1455  1.3   chs 			}
   1456  1.1  haad 		}
   1457  1.1  haad 
   1458  1.1  haad 		zhp = zfs_open(rzhp->zfs_hdl, fsname, ZFS_TYPE_DATASET);
   1459  1.1  haad 		if (zhp == NULL)
   1460  1.1  haad 			return (-1);
   1461  1.1  haad 		err = dump_filesystem(zhp, sdd);
   1462  1.1  haad 		VERIFY(nvlist_add_boolean(fslist, "sent") == 0);
   1463  1.1  haad 		progress = B_TRUE;
   1464  1.1  haad 		zfs_close(zhp);
   1465  1.1  haad 		if (err)
   1466  1.1  haad 			return (err);
   1467  1.1  haad 	}
   1468  1.1  haad 	if (needagain) {
   1469  1.1  haad 		assert(progress);
   1470  1.1  haad 		goto again;
   1471  1.1  haad 	}
   1472  1.3   chs 
   1473  1.3   chs 	/* clean out the sent flags in case we reuse this fss */
   1474  1.3   chs 	for (fspair = nvlist_next_nvpair(sdd->fss, NULL); fspair;
   1475  1.3   chs 	    fspair = nvlist_next_nvpair(sdd->fss, fspair)) {
   1476  1.3   chs 		nvlist_t *fslist;
   1477  1.3   chs 
   1478  1.3   chs 		VERIFY(nvpair_value_nvlist(fspair, &fslist) == 0);
   1479  1.3   chs 		(void) nvlist_remove_all(fslist, "sent");
   1480  1.3   chs 	}
   1481  1.3   chs 
   1482  1.1  haad 	return (0);
   1483  1.1  haad }
   1484  1.1  haad 
   1485  1.3   chs nvlist_t *
   1486  1.3   chs zfs_send_resume_token_to_nvlist(libzfs_handle_t *hdl, const char *token)
   1487  1.3   chs {
   1488  1.3   chs 	unsigned int version;
   1489  1.3   chs 	int nread;
   1490  1.3   chs 	unsigned long long checksum, packed_len;
   1491  1.3   chs 
   1492  1.3   chs 	/*
   1493  1.3   chs 	 * Decode token header, which is:
   1494  1.3   chs 	 *   <token version>-<checksum of payload>-<uncompressed payload length>
   1495  1.3   chs 	 * Note that the only supported token version is 1.
   1496  1.3   chs 	 */
   1497  1.3   chs 	nread = sscanf(token, "%u-%llx-%llx-",
   1498  1.3   chs 	    &version, &checksum, &packed_len);
   1499  1.3   chs 	if (nread != 3) {
   1500  1.3   chs 		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
   1501  1.3   chs 		    "resume token is corrupt (invalid format)"));
   1502  1.3   chs 		return (NULL);
   1503  1.3   chs 	}
   1504  1.3   chs 
   1505  1.3   chs 	if (version != ZFS_SEND_RESUME_TOKEN_VERSION) {
   1506  1.3   chs 		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
   1507  1.3   chs 		    "resume token is corrupt (invalid version %u)"),
   1508  1.3   chs 		    version);
   1509  1.3   chs 		return (NULL);
   1510  1.3   chs 	}
   1511  1.3   chs 
   1512  1.3   chs 	/* convert hexadecimal representation to binary */
   1513  1.3   chs 	token = strrchr(token, '-') + 1;
   1514  1.3   chs 	int len = strlen(token) / 2;
   1515  1.3   chs 	unsigned char *compressed = zfs_alloc(hdl, len);
   1516  1.3   chs 	for (int i = 0; i < len; i++) {
   1517  1.3   chs 		nread = sscanf(token + i * 2, "%2hhx", compressed + i);
   1518  1.3   chs 		if (nread != 1) {
   1519  1.3   chs 			free(compressed);
   1520  1.3   chs 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
   1521  1.3   chs 			    "resume token is corrupt "
   1522  1.3   chs 			    "(payload is not hex-encoded)"));
   1523  1.3   chs 			return (NULL);
   1524  1.3   chs 		}
   1525  1.3   chs 	}
   1526  1.3   chs 
   1527  1.3   chs 	/* verify checksum */
   1528  1.3   chs 	zio_cksum_t cksum;
   1529  1.3   chs 	fletcher_4_native(compressed, len, NULL, &cksum);
   1530  1.3   chs 	if (cksum.zc_word[0] != checksum) {
   1531  1.3   chs 		free(compressed);
   1532  1.3   chs 		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
   1533  1.3   chs 		    "resume token is corrupt (incorrect checksum)"));
   1534  1.3   chs 		return (NULL);
   1535  1.3   chs 	}
   1536  1.3   chs 
   1537  1.3   chs 	/* uncompress */
   1538  1.3   chs 	void *packed = zfs_alloc(hdl, packed_len);
   1539  1.3   chs 	uLongf packed_len_long = packed_len;
   1540  1.3   chs 	if (uncompress(packed, &packed_len_long, compressed, len) != Z_OK ||
   1541  1.3   chs 	    packed_len_long != packed_len) {
   1542  1.3   chs 		free(packed);
   1543  1.3   chs 		free(compressed);
   1544  1.3   chs 		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
   1545  1.3   chs 		    "resume token is corrupt (decompression failed)"));
   1546  1.3   chs 		return (NULL);
   1547  1.3   chs 	}
   1548  1.3   chs 
   1549  1.3   chs 	/* unpack nvlist */
   1550  1.3   chs 	nvlist_t *nv;
   1551  1.3   chs 	int error = nvlist_unpack(packed, packed_len, &nv, KM_SLEEP);
   1552  1.3   chs 	free(packed);
   1553  1.3   chs 	free(compressed);
   1554  1.3   chs 	if (error != 0) {
   1555  1.3   chs 		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
   1556  1.3   chs 		    "resume token is corrupt (nvlist_unpack failed)"));
   1557  1.3   chs 		return (NULL);
   1558  1.3   chs 	}
   1559  1.3   chs 	return (nv);
   1560  1.3   chs }
   1561  1.3   chs 
   1562  1.3   chs int
   1563  1.3   chs zfs_send_resume(libzfs_handle_t *hdl, sendflags_t *flags, int outfd,
   1564  1.3   chs     const char *resume_token)
   1565  1.3   chs {
   1566  1.3   chs 	char errbuf[1024];
   1567  1.3   chs 	char *toname;
   1568  1.3   chs 	char *fromname = NULL;
   1569  1.3   chs 	uint64_t resumeobj, resumeoff, toguid, fromguid, bytes;
   1570  1.3   chs 	zfs_handle_t *zhp;
   1571  1.3   chs 	int error = 0;
   1572  1.3   chs 	char name[ZFS_MAX_DATASET_NAME_LEN];
   1573  1.3   chs 	enum lzc_send_flags lzc_flags = 0;
   1574  1.3   chs 
   1575  1.3   chs 	(void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
   1576  1.3   chs 	    "cannot resume send"));
   1577  1.3   chs 
   1578  1.3   chs 	nvlist_t *resume_nvl =
   1579  1.3   chs 	    zfs_send_resume_token_to_nvlist(hdl, resume_token);
   1580  1.3   chs 	if (resume_nvl == NULL) {
   1581  1.3   chs 		/*
   1582  1.3   chs 		 * zfs_error_aux has already been set by
   1583  1.3   chs 		 * zfs_send_resume_token_to_nvlist
   1584  1.3   chs 		 */
   1585  1.3   chs 		return (zfs_error(hdl, EZFS_FAULT, errbuf));
   1586  1.3   chs 	}
   1587  1.3   chs 	if (flags->verbose) {
   1588  1.3   chs 		(void) fprintf(stderr, dgettext(TEXT_DOMAIN,
   1589  1.3   chs 		    "resume token contents:\n"));
   1590  1.3   chs 		nvlist_print(stderr, resume_nvl);
   1591  1.3   chs 	}
   1592  1.3   chs 
   1593  1.3   chs 	if (nvlist_lookup_string(resume_nvl, "toname", &toname) != 0 ||
   1594  1.3   chs 	    nvlist_lookup_uint64(resume_nvl, "object", &resumeobj) != 0 ||
   1595  1.3   chs 	    nvlist_lookup_uint64(resume_nvl, "offset", &resumeoff) != 0 ||
   1596  1.3   chs 	    nvlist_lookup_uint64(resume_nvl, "bytes", &bytes) != 0 ||
   1597  1.3   chs 	    nvlist_lookup_uint64(resume_nvl, "toguid", &toguid) != 0) {
   1598  1.3   chs 		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
   1599  1.3   chs 		    "resume token is corrupt"));
   1600  1.3   chs 		return (zfs_error(hdl, EZFS_FAULT, errbuf));
   1601  1.3   chs 	}
   1602  1.3   chs 	fromguid = 0;
   1603  1.3   chs 	(void) nvlist_lookup_uint64(resume_nvl, "fromguid", &fromguid);
   1604  1.3   chs 
   1605  1.3   chs 	if (flags->embed_data || nvlist_exists(resume_nvl, "embedok"))
   1606  1.3   chs 		lzc_flags |= LZC_SEND_FLAG_EMBED_DATA;
   1607  1.3   chs 
   1608  1.3   chs 	if (guid_to_name(hdl, toname, toguid, B_FALSE, name) != 0) {
   1609  1.3   chs 		if (zfs_dataset_exists(hdl, toname, ZFS_TYPE_DATASET)) {
   1610  1.3   chs 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
   1611  1.3   chs 			    "'%s' is no longer the same snapshot used in "
   1612  1.3   chs 			    "the initial send"), toname);
   1613  1.3   chs 		} else {
   1614  1.3   chs 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
   1615  1.3   chs 			    "'%s' used in the initial send no longer exists"),
   1616  1.3   chs 			    toname);
   1617  1.3   chs 		}
   1618  1.3   chs 		return (zfs_error(hdl, EZFS_BADPATH, errbuf));
   1619  1.3   chs 	}
   1620  1.3   chs 	zhp = zfs_open(hdl, name, ZFS_TYPE_DATASET);
   1621  1.3   chs 	if (zhp == NULL) {
   1622  1.3   chs 		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
   1623  1.3   chs 		    "unable to access '%s'"), name);
   1624  1.3   chs 		return (zfs_error(hdl, EZFS_BADPATH, errbuf));
   1625  1.3   chs 	}
   1626  1.3   chs 
   1627  1.3   chs 	if (fromguid != 0) {
   1628  1.3   chs 		if (guid_to_name(hdl, toname, fromguid, B_TRUE, name) != 0) {
   1629  1.3   chs 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
   1630  1.3   chs 			    "incremental source %#llx no longer exists"),
   1631  1.3   chs 			    (longlong_t)fromguid);
   1632  1.3   chs 			return (zfs_error(hdl, EZFS_BADPATH, errbuf));
   1633  1.3   chs 		}
   1634  1.3   chs 		fromname = name;
   1635  1.3   chs 	}
   1636  1.3   chs 
   1637  1.3   chs 	if (flags->verbose) {
   1638  1.3   chs 		uint64_t size = 0;
   1639  1.3   chs 		error = lzc_send_space(zhp->zfs_name, fromname, &size);
   1640  1.3   chs 		if (error == 0)
   1641  1.3   chs 			size = MAX(0, (int64_t)(size - bytes));
   1642  1.3   chs 		send_print_verbose(stderr, zhp->zfs_name, fromname,
   1643  1.3   chs 		    size, flags->parsable);
   1644  1.3   chs 	}
   1645  1.3   chs 
   1646  1.3   chs 	if (!flags->dryrun) {
   1647  1.3   chs 		progress_arg_t pa = { 0 };
   1648  1.3   chs 		pthread_t tid;
   1649  1.3   chs 		/*
   1650  1.3   chs 		 * If progress reporting is requested, spawn a new thread to
   1651  1.3   chs 		 * poll ZFS_IOC_SEND_PROGRESS at a regular interval.
   1652  1.3   chs 		 */
   1653  1.3   chs 		if (flags->progress) {
   1654  1.3   chs 			pa.pa_zhp = zhp;
   1655  1.3   chs 			pa.pa_fd = outfd;
   1656  1.3   chs 			pa.pa_parsable = flags->parsable;
   1657  1.3   chs 
   1658  1.3   chs 			error = pthread_create(&tid, NULL,
   1659  1.3   chs 			    send_progress_thread, &pa);
   1660  1.3   chs 			if (error != 0) {
   1661  1.3   chs 				zfs_close(zhp);
   1662  1.3   chs 				return (error);
   1663  1.3   chs 			}
   1664  1.3   chs 		}
   1665  1.3   chs 
   1666  1.3   chs 		error = lzc_send_resume(zhp->zfs_name, fromname, outfd,
   1667  1.3   chs 		    lzc_flags, resumeobj, resumeoff);
   1668  1.3   chs 
   1669  1.3   chs 		if (flags->progress) {
   1670  1.3   chs 			(void) pthread_cancel(tid);
   1671  1.3   chs 			(void) pthread_join(tid, NULL);
   1672  1.3   chs 		}
   1673  1.3   chs 
   1674  1.3   chs 		char errbuf[1024];
   1675  1.3   chs 		(void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
   1676  1.3   chs 		    "warning: cannot send '%s'"), zhp->zfs_name);
   1677  1.3   chs 
   1678  1.3   chs 		zfs_close(zhp);
   1679  1.3   chs 
   1680  1.3   chs 		switch (error) {
   1681  1.3   chs 		case 0:
   1682  1.3   chs 			return (0);
   1683  1.3   chs 		case EXDEV:
   1684  1.3   chs 		case ENOENT:
   1685  1.3   chs 		case EDQUOT:
   1686  1.3   chs 		case EFBIG:
   1687  1.3   chs 		case EIO:
   1688  1.3   chs 		case ENOLINK:
   1689  1.3   chs 		case ENOSPC:
   1690  1.3   chs #ifdef illumos
   1691  1.3   chs 		case ENOSTR:
   1692  1.3   chs #endif
   1693  1.3   chs 		case ENXIO:
   1694  1.3   chs 		case EPIPE:
   1695  1.3   chs 		case ERANGE:
   1696  1.3   chs 		case EFAULT:
   1697  1.3   chs 		case EROFS:
   1698  1.3   chs 			zfs_error_aux(hdl, strerror(errno));
   1699  1.3   chs 			return (zfs_error(hdl, EZFS_BADBACKUP, errbuf));
   1700  1.3   chs 
   1701  1.3   chs 		default:
   1702  1.3   chs 			return (zfs_standard_error(hdl, errno, errbuf));
   1703  1.3   chs 		}
   1704  1.3   chs 	}
   1705  1.3   chs 
   1706  1.3   chs 
   1707  1.3   chs 	zfs_close(zhp);
   1708  1.3   chs 
   1709  1.3   chs 	return (error);
   1710  1.3   chs }
   1711  1.3   chs 
   1712  1.1  haad /*
   1713  1.2   dsl  * Generate a send stream for the dataset identified by the argument zhp.
   1714  1.2   dsl  *
   1715  1.2   dsl  * The content of the send stream is the snapshot identified by
   1716  1.2   dsl  * 'tosnap'.  Incremental streams are requested in two ways:
   1717  1.2   dsl  *     - from the snapshot identified by "fromsnap" (if non-null) or
   1718  1.2   dsl  *     - from the origin of the dataset identified by zhp, which must
   1719  1.2   dsl  *	 be a clone.  In this case, "fromsnap" is null and "fromorigin"
   1720  1.2   dsl  *	 is TRUE.
   1721  1.2   dsl  *
   1722  1.2   dsl  * The send stream is recursive (i.e. dumps a hierarchy of snapshots) and
   1723  1.2   dsl  * uses a special header (with a hdrtype field of DMU_COMPOUNDSTREAM)
   1724  1.2   dsl  * if "replicate" is set.  If "doall" is set, dump all the intermediate
   1725  1.2   dsl  * snapshots. The DMU_COMPOUNDSTREAM header is used in the "doall"
   1726  1.2   dsl  * case too. If "props" is set, send properties.
   1727  1.1  haad  */
   1728  1.1  haad int
   1729  1.1  haad zfs_send(zfs_handle_t *zhp, const char *fromsnap, const char *tosnap,
   1730  1.3   chs     sendflags_t *flags, int outfd, snapfilter_cb_t filter_func,
   1731  1.3   chs     void *cb_arg, nvlist_t **debugnvp)
   1732  1.1  haad {
   1733  1.1  haad 	char errbuf[1024];
   1734  1.1  haad 	send_dump_data_t sdd = { 0 };
   1735  1.3   chs 	int err = 0;
   1736  1.1  haad 	nvlist_t *fss = NULL;
   1737  1.1  haad 	avl_tree_t *fsavl = NULL;
   1738  1.2   dsl 	static uint64_t holdseq;
   1739  1.2   dsl 	int spa_version;
   1740  1.3   chs 	pthread_t tid = 0;
   1741  1.2   dsl 	int pipefd[2];
   1742  1.2   dsl 	dedup_arg_t dda = { 0 };
   1743  1.2   dsl 	int featureflags = 0;
   1744  1.3   chs 	FILE *fout;
   1745  1.1  haad 
   1746  1.1  haad 	(void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
   1747  1.1  haad 	    "cannot send '%s'"), zhp->zfs_name);
   1748  1.1  haad 
   1749  1.1  haad 	if (fromsnap && fromsnap[0] == '\0') {
   1750  1.1  haad 		zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN,
   1751  1.1  haad 		    "zero-length incremental source"));
   1752  1.1  haad 		return (zfs_error(zhp->zfs_hdl, EZFS_NOENT, errbuf));
   1753  1.1  haad 	}
   1754  1.1  haad 
   1755  1.3   chs 	if (zhp->zfs_type == ZFS_TYPE_FILESYSTEM) {
   1756  1.3   chs 		uint64_t version;
   1757  1.3   chs 		version = zfs_prop_get_int(zhp, ZFS_PROP_VERSION);
   1758  1.3   chs 		if (version >= ZPL_VERSION_SA) {
   1759  1.3   chs 			featureflags |= DMU_BACKUP_FEATURE_SA_SPILL;
   1760  1.3   chs 		}
   1761  1.3   chs 	}
   1762  1.2   dsl 
   1763  1.3   chs 	if (flags->dedup && !flags->dryrun) {
   1764  1.2   dsl 		featureflags |= (DMU_BACKUP_FEATURE_DEDUP |
   1765  1.2   dsl 		    DMU_BACKUP_FEATURE_DEDUPPROPS);
   1766  1.3   chs 		if ((err = pipe(pipefd)) != 0) {
   1767  1.2   dsl 			zfs_error_aux(zhp->zfs_hdl, strerror(errno));
   1768  1.2   dsl 			return (zfs_error(zhp->zfs_hdl, EZFS_PIPEFAILED,
   1769  1.2   dsl 			    errbuf));
   1770  1.2   dsl 		}
   1771  1.2   dsl 		dda.outputfd = outfd;
   1772  1.2   dsl 		dda.inputfd = pipefd[1];
   1773  1.2   dsl 		dda.dedup_hdl = zhp->zfs_hdl;
   1774  1.3   chs 		if ((err = pthread_create(&tid, NULL, cksummer, &dda)) != 0) {
   1775  1.2   dsl 			(void) close(pipefd[0]);
   1776  1.2   dsl 			(void) close(pipefd[1]);
   1777  1.2   dsl 			zfs_error_aux(zhp->zfs_hdl, strerror(errno));
   1778  1.2   dsl 			return (zfs_error(zhp->zfs_hdl,
   1779  1.2   dsl 			    EZFS_THREADCREATEFAILED, errbuf));
   1780  1.2   dsl 		}
   1781  1.2   dsl 	}
   1782  1.2   dsl 
   1783  1.3   chs 	if (flags->replicate || flags->doall || flags->props) {
   1784  1.1  haad 		dmu_replay_record_t drr = { 0 };
   1785  1.1  haad 		char *packbuf = NULL;
   1786  1.1  haad 		size_t buflen = 0;
   1787  1.1  haad 		zio_cksum_t zc = { 0 };
   1788  1.1  haad 
   1789  1.3   chs 		if (flags->replicate || flags->props) {
   1790  1.1  haad 			nvlist_t *hdrnv;
   1791  1.1  haad 
   1792  1.1  haad 			VERIFY(0 == nvlist_alloc(&hdrnv, NV_UNIQUE_NAME, 0));
   1793  1.1  haad 			if (fromsnap) {
   1794  1.1  haad 				VERIFY(0 == nvlist_add_string(hdrnv,
   1795  1.1  haad 				    "fromsnap", fromsnap));
   1796  1.1  haad 			}
   1797  1.1  haad 			VERIFY(0 == nvlist_add_string(hdrnv, "tosnap", tosnap));
   1798  1.3   chs 			if (!flags->replicate) {
   1799  1.2   dsl 				VERIFY(0 == nvlist_add_boolean(hdrnv,
   1800  1.2   dsl 				    "not_recursive"));
   1801  1.2   dsl 			}
   1802  1.1  haad 
   1803  1.1  haad 			err = gather_nvlist(zhp->zfs_hdl, zhp->zfs_name,
   1804  1.3   chs 			    fromsnap, tosnap, flags->replicate, flags->verbose,
   1805  1.3   chs 			    &fss, &fsavl);
   1806  1.3   chs 			if (err)
   1807  1.2   dsl 				goto err_out;
   1808  1.1  haad 			VERIFY(0 == nvlist_add_nvlist(hdrnv, "fss", fss));
   1809  1.1  haad 			err = nvlist_pack(hdrnv, &packbuf, &buflen,
   1810  1.1  haad 			    NV_ENCODE_XDR, 0);
   1811  1.3   chs 			if (debugnvp)
   1812  1.3   chs 				*debugnvp = hdrnv;
   1813  1.3   chs 			else
   1814  1.3   chs 				nvlist_free(hdrnv);
   1815  1.3   chs 			if (err)
   1816  1.2   dsl 				goto stderr_out;
   1817  1.1  haad 		}
   1818  1.1  haad 
   1819  1.3   chs 		if (!flags->dryrun) {
   1820  1.3   chs 			/* write first begin record */
   1821  1.3   chs 			drr.drr_type = DRR_BEGIN;
   1822  1.3   chs 			drr.drr_u.drr_begin.drr_magic = DMU_BACKUP_MAGIC;
   1823  1.3   chs 			DMU_SET_STREAM_HDRTYPE(drr.drr_u.drr_begin.
   1824  1.3   chs 			    drr_versioninfo, DMU_COMPOUNDSTREAM);
   1825  1.3   chs 			DMU_SET_FEATUREFLAGS(drr.drr_u.drr_begin.
   1826  1.3   chs 			    drr_versioninfo, featureflags);
   1827  1.3   chs 			(void) snprintf(drr.drr_u.drr_begin.drr_toname,
   1828  1.3   chs 			    sizeof (drr.drr_u.drr_begin.drr_toname),
   1829  1.3   chs 			    "%s@%s", zhp->zfs_name, tosnap);
   1830  1.3   chs 			drr.drr_payloadlen = buflen;
   1831  1.3   chs 
   1832  1.3   chs 			err = dump_record(&drr, packbuf, buflen, &zc, outfd);
   1833  1.3   chs 			free(packbuf);
   1834  1.3   chs 			if (err != 0)
   1835  1.3   chs 				goto stderr_out;
   1836  1.1  haad 
   1837  1.3   chs 			/* write end record */
   1838  1.1  haad 			bzero(&drr, sizeof (drr));
   1839  1.1  haad 			drr.drr_type = DRR_END;
   1840  1.1  haad 			drr.drr_u.drr_end.drr_checksum = zc;
   1841  1.1  haad 			err = write(outfd, &drr, sizeof (drr));
   1842  1.1  haad 			if (err == -1) {
   1843  1.2   dsl 				err = errno;
   1844  1.2   dsl 				goto stderr_out;
   1845  1.1  haad 			}
   1846  1.3   chs 
   1847  1.3   chs 			err = 0;
   1848  1.1  haad 		}
   1849  1.1  haad 	}
   1850  1.1  haad 
   1851  1.1  haad 	/* dump each stream */
   1852  1.1  haad 	sdd.fromsnap = fromsnap;
   1853  1.1  haad 	sdd.tosnap = tosnap;
   1854  1.3   chs 	if (tid != 0)
   1855  1.2   dsl 		sdd.outfd = pipefd[0];
   1856  1.2   dsl 	else
   1857  1.2   dsl 		sdd.outfd = outfd;
   1858  1.3   chs 	sdd.replicate = flags->replicate;
   1859  1.3   chs 	sdd.doall = flags->doall;
   1860  1.3   chs 	sdd.fromorigin = flags->fromorigin;
   1861  1.1  haad 	sdd.fss = fss;
   1862  1.1  haad 	sdd.fsavl = fsavl;
   1863  1.3   chs 	sdd.verbose = flags->verbose;
   1864  1.3   chs 	sdd.parsable = flags->parsable;
   1865  1.3   chs 	sdd.progress = flags->progress;
   1866  1.3   chs 	sdd.dryrun = flags->dryrun;
   1867  1.3   chs 	sdd.large_block = flags->largeblock;
   1868  1.3   chs 	sdd.embed_data = flags->embed_data;
   1869  1.2   dsl 	sdd.filter_cb = filter_func;
   1870  1.2   dsl 	sdd.filter_cb_arg = cb_arg;
   1871  1.3   chs 	if (debugnvp)
   1872  1.3   chs 		sdd.debugnv = *debugnvp;
   1873  1.3   chs 	if (sdd.verbose && sdd.dryrun)
   1874  1.3   chs 		sdd.std_out = B_TRUE;
   1875  1.3   chs 	fout = sdd.std_out ? stdout : stderr;
   1876  1.3   chs 
   1877  1.3   chs 	/*
   1878  1.3   chs 	 * Some flags require that we place user holds on the datasets that are
   1879  1.3   chs 	 * being sent so they don't get destroyed during the send. We can skip
   1880  1.3   chs 	 * this step if the pool is imported read-only since the datasets cannot
   1881  1.3   chs 	 * be destroyed.
   1882  1.3   chs 	 */
   1883  1.3   chs 	if (!flags->dryrun && !zpool_get_prop_int(zfs_get_pool_handle(zhp),
   1884  1.3   chs 	    ZPOOL_PROP_READONLY, NULL) &&
   1885  1.3   chs 	    zfs_spa_version(zhp, &spa_version) == 0 &&
   1886  1.3   chs 	    spa_version >= SPA_VERSION_USERREFS &&
   1887  1.3   chs 	    (flags->doall || flags->replicate)) {
   1888  1.3   chs 		++holdseq;
   1889  1.3   chs 		(void) snprintf(sdd.holdtag, sizeof (sdd.holdtag),
   1890  1.3   chs 		    ".send-%d-%llu", getpid(), (u_longlong_t)holdseq);
   1891  1.3   chs 		sdd.cleanup_fd = open(ZFS_DEV, O_RDWR|O_EXCL);
   1892  1.3   chs 		if (sdd.cleanup_fd < 0) {
   1893  1.3   chs 			err = errno;
   1894  1.3   chs 			goto stderr_out;
   1895  1.3   chs 		}
   1896  1.3   chs 		sdd.snapholds = fnvlist_alloc();
   1897  1.3   chs 	} else {
   1898  1.3   chs 		sdd.cleanup_fd = -1;
   1899  1.3   chs 		sdd.snapholds = NULL;
   1900  1.3   chs 	}
   1901  1.3   chs 	if (flags->verbose || sdd.snapholds != NULL) {
   1902  1.3   chs 		/*
   1903  1.3   chs 		 * Do a verbose no-op dry run to get all the verbose output
   1904  1.3   chs 		 * or to gather snapshot hold's before generating any data,
   1905  1.3   chs 		 * then do a non-verbose real run to generate the streams.
   1906  1.3   chs 		 */
   1907  1.3   chs 		sdd.dryrun = B_TRUE;
   1908  1.3   chs 		err = dump_filesystems(zhp, &sdd);
   1909  1.3   chs 
   1910  1.3   chs 		if (err != 0)
   1911  1.3   chs 			goto stderr_out;
   1912  1.3   chs 
   1913  1.3   chs 		if (flags->verbose) {
   1914  1.3   chs 			if (flags->parsable) {
   1915  1.3   chs 				(void) fprintf(fout, "size\t%llu\n",
   1916  1.3   chs 				    (longlong_t)sdd.size);
   1917  1.3   chs 			} else {
   1918  1.3   chs 				char buf[16];
   1919  1.3   chs 				zfs_nicenum(sdd.size, buf, sizeof (buf));
   1920  1.3   chs 				(void) fprintf(fout, dgettext(TEXT_DOMAIN,
   1921  1.3   chs 				    "total estimated size is %s\n"), buf);
   1922  1.3   chs 			}
   1923  1.3   chs 		}
   1924  1.3   chs 
   1925  1.3   chs 		/* Ensure no snaps found is treated as an error. */
   1926  1.3   chs 		if (!sdd.seento) {
   1927  1.3   chs 			err = ENOENT;
   1928  1.3   chs 			goto err_out;
   1929  1.3   chs 		}
   1930  1.3   chs 
   1931  1.3   chs 		/* Skip the second run if dryrun was requested. */
   1932  1.3   chs 		if (flags->dryrun)
   1933  1.3   chs 			goto err_out;
   1934  1.3   chs 
   1935  1.3   chs 		if (sdd.snapholds != NULL) {
   1936  1.3   chs 			err = zfs_hold_nvl(zhp, sdd.cleanup_fd, sdd.snapholds);
   1937  1.3   chs 			if (err != 0)
   1938  1.3   chs 				goto stderr_out;
   1939  1.3   chs 
   1940  1.3   chs 			fnvlist_free(sdd.snapholds);
   1941  1.3   chs 			sdd.snapholds = NULL;
   1942  1.3   chs 		}
   1943  1.3   chs 
   1944  1.3   chs 		sdd.dryrun = B_FALSE;
   1945  1.3   chs 		sdd.verbose = B_FALSE;
   1946  1.3   chs 	}
   1947  1.3   chs 
   1948  1.1  haad 	err = dump_filesystems(zhp, &sdd);
   1949  1.1  haad 	fsavl_destroy(fsavl);
   1950  1.1  haad 	nvlist_free(fss);
   1951  1.1  haad 
   1952  1.3   chs 	/* Ensure no snaps found is treated as an error. */
   1953  1.3   chs 	if (err == 0 && !sdd.seento)
   1954  1.3   chs 		err = ENOENT;
   1955  1.3   chs 
   1956  1.3   chs 	if (tid != 0) {
   1957  1.3   chs 		if (err != 0)
   1958  1.3   chs 			(void) pthread_cancel(tid);
   1959  1.2   dsl 		(void) close(pipefd[0]);
   1960  1.2   dsl 		(void) pthread_join(tid, NULL);
   1961  1.2   dsl 	}
   1962  1.2   dsl 
   1963  1.3   chs 	if (sdd.cleanup_fd != -1) {
   1964  1.3   chs 		VERIFY(0 == close(sdd.cleanup_fd));
   1965  1.3   chs 		sdd.cleanup_fd = -1;
   1966  1.3   chs 	}
   1967  1.3   chs 
   1968  1.3   chs 	if (!flags->dryrun && (flags->replicate || flags->doall ||
   1969  1.3   chs 	    flags->props)) {
   1970  1.1  haad 		/*
   1971  1.1  haad 		 * write final end record.  NB: want to do this even if
   1972  1.1  haad 		 * there was some error, because it might not be totally
   1973  1.1  haad 		 * failed.
   1974  1.1  haad 		 */
   1975  1.1  haad 		dmu_replay_record_t drr = { 0 };
   1976  1.1  haad 		drr.drr_type = DRR_END;
   1977  1.1  haad 		if (write(outfd, &drr, sizeof (drr)) == -1) {
   1978  1.1  haad 			return (zfs_standard_error(zhp->zfs_hdl,
   1979  1.1  haad 			    errno, errbuf));
   1980  1.1  haad 		}
   1981  1.1  haad 	}
   1982  1.1  haad 
   1983  1.1  haad 	return (err || sdd.err);
   1984  1.2   dsl 
   1985  1.2   dsl stderr_out:
   1986  1.2   dsl 	err = zfs_standard_error(zhp->zfs_hdl, err, errbuf);
   1987  1.2   dsl err_out:
   1988  1.3   chs 	fsavl_destroy(fsavl);
   1989  1.3   chs 	nvlist_free(fss);
   1990  1.3   chs 	fnvlist_free(sdd.snapholds);
   1991  1.3   chs 
   1992  1.3   chs 	if (sdd.cleanup_fd != -1)
   1993  1.3   chs 		VERIFY(0 == close(sdd.cleanup_fd));
   1994  1.3   chs 	if (tid != 0) {
   1995  1.2   dsl 		(void) pthread_cancel(tid);
   1996  1.3   chs 		(void) close(pipefd[0]);
   1997  1.2   dsl 		(void) pthread_join(tid, NULL);
   1998  1.2   dsl 	}
   1999  1.2   dsl 	return (err);
   2000  1.1  haad }
   2001  1.1  haad 
   2002  1.3   chs int
   2003  1.3   chs zfs_send_one(zfs_handle_t *zhp, const char *from, int fd,
   2004  1.3   chs     enum lzc_send_flags flags)
   2005  1.3   chs {
   2006  1.3   chs 	int err;
   2007  1.3   chs 	libzfs_handle_t *hdl = zhp->zfs_hdl;
   2008  1.3   chs 
   2009  1.3   chs 	char errbuf[1024];
   2010  1.3   chs 	(void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
   2011  1.3   chs 	    "warning: cannot send '%s'"), zhp->zfs_name);
   2012  1.3   chs 
   2013  1.3   chs 	err = lzc_send(zhp->zfs_name, from, fd, flags);
   2014  1.3   chs 	if (err != 0) {
   2015  1.3   chs 		switch (errno) {
   2016  1.3   chs 		case EXDEV:
   2017  1.3   chs 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
   2018  1.3   chs 			    "not an earlier snapshot from the same fs"));
   2019  1.3   chs 			return (zfs_error(hdl, EZFS_CROSSTARGET, errbuf));
   2020  1.3   chs 
   2021  1.3   chs 		case ENOENT:
   2022  1.3   chs 		case ESRCH:
   2023  1.3   chs 			if (lzc_exists(zhp->zfs_name)) {
   2024  1.3   chs 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
   2025  1.3   chs 				    "incremental source (%s) does not exist"),
   2026  1.3   chs 				    from);
   2027  1.3   chs 			}
   2028  1.3   chs 			return (zfs_error(hdl, EZFS_NOENT, errbuf));
   2029  1.3   chs 
   2030  1.3   chs 		case EBUSY:
   2031  1.3   chs 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
   2032  1.3   chs 			    "target is busy; if a filesystem, "
   2033  1.3   chs 			    "it must not be mounted"));
   2034  1.3   chs 			return (zfs_error(hdl, EZFS_BUSY, errbuf));
   2035  1.3   chs 
   2036  1.3   chs 		case EDQUOT:
   2037  1.3   chs 		case EFBIG:
   2038  1.3   chs 		case EIO:
   2039  1.3   chs 		case ENOLINK:
   2040  1.3   chs 		case ENOSPC:
   2041  1.3   chs #ifdef illumos
   2042  1.3   chs 		case ENOSTR:
   2043  1.3   chs #endif
   2044  1.3   chs 		case ENXIO:
   2045  1.3   chs 		case EPIPE:
   2046  1.3   chs 		case ERANGE:
   2047  1.3   chs 		case EFAULT:
   2048  1.3   chs 		case EROFS:
   2049  1.3   chs 			zfs_error_aux(hdl, strerror(errno));
   2050  1.3   chs 			return (zfs_error(hdl, EZFS_BADBACKUP, errbuf));
   2051  1.3   chs 
   2052  1.3   chs 		default:
   2053  1.3   chs 			return (zfs_standard_error(hdl, errno, errbuf));
   2054  1.3   chs 		}
   2055  1.3   chs 	}
   2056  1.3   chs 	return (err != 0);
   2057  1.3   chs }
   2058  1.3   chs 
   2059  1.1  haad /*
   2060  1.1  haad  * Routines specific to "zfs recv"
   2061  1.1  haad  */
   2062  1.1  haad 
   2063  1.1  haad static int
   2064  1.1  haad recv_read(libzfs_handle_t *hdl, int fd, void *buf, int ilen,
   2065  1.1  haad     boolean_t byteswap, zio_cksum_t *zc)
   2066  1.1  haad {
   2067  1.1  haad 	char *cp = buf;
   2068  1.1  haad 	int rv;
   2069  1.1  haad 	int len = ilen;
   2070  1.1  haad 
   2071  1.3   chs 	assert(ilen <= SPA_MAXBLOCKSIZE);
   2072  1.3   chs 
   2073  1.1  haad 	do {
   2074  1.1  haad 		rv = read(fd, cp, len);
   2075  1.1  haad 		cp += rv;
   2076  1.1  haad 		len -= rv;
   2077  1.1  haad 	} while (rv > 0);
   2078  1.1  haad 
   2079  1.1  haad 	if (rv < 0 || len != 0) {
   2080  1.1  haad 		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
   2081  1.1  haad 		    "failed to read from stream"));
   2082  1.1  haad 		return (zfs_error(hdl, EZFS_BADSTREAM, dgettext(TEXT_DOMAIN,
   2083  1.1  haad 		    "cannot receive")));
   2084  1.1  haad 	}
   2085  1.1  haad 
   2086  1.1  haad 	if (zc) {
   2087  1.1  haad 		if (byteswap)
   2088  1.1  haad 			fletcher_4_incremental_byteswap(buf, ilen, zc);
   2089  1.1  haad 		else
   2090  1.1  haad 			fletcher_4_incremental_native(buf, ilen, zc);
   2091  1.1  haad 	}
   2092  1.1  haad 	return (0);
   2093  1.1  haad }
   2094  1.1  haad 
   2095  1.1  haad static int
   2096  1.1  haad recv_read_nvlist(libzfs_handle_t *hdl, int fd, int len, nvlist_t **nvp,
   2097  1.1  haad     boolean_t byteswap, zio_cksum_t *zc)
   2098  1.1  haad {
   2099  1.1  haad 	char *buf;
   2100  1.1  haad 	int err;
   2101  1.1  haad 
   2102  1.1  haad 	buf = zfs_alloc(hdl, len);
   2103  1.1  haad 	if (buf == NULL)
   2104  1.1  haad 		return (ENOMEM);
   2105  1.1  haad 
   2106  1.1  haad 	err = recv_read(hdl, fd, buf, len, byteswap, zc);
   2107  1.1  haad 	if (err != 0) {
   2108  1.1  haad 		free(buf);
   2109  1.1  haad 		return (err);
   2110  1.1  haad 	}
   2111  1.1  haad 
   2112  1.1  haad 	err = nvlist_unpack(buf, len, nvp, 0);
   2113  1.1  haad 	free(buf);
   2114  1.1  haad 	if (err != 0) {
   2115  1.1  haad 		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "invalid "
   2116  1.1  haad 		    "stream (malformed nvlist)"));
   2117  1.1  haad 		return (EINVAL);
   2118  1.1  haad 	}
   2119  1.1  haad 	return (0);
   2120  1.1  haad }
   2121  1.1  haad 
   2122  1.1  haad static int
   2123  1.1  haad recv_rename(libzfs_handle_t *hdl, const char *name, const char *tryname,
   2124  1.3   chs     int baselen, char *newname, recvflags_t *flags)
   2125  1.1  haad {
   2126  1.1  haad 	static int seq;
   2127  1.1  haad 	zfs_cmd_t zc = { 0 };
   2128  1.1  haad 	int err;
   2129  1.1  haad 	prop_changelist_t *clp;
   2130  1.1  haad 	zfs_handle_t *zhp;
   2131  1.1  haad 
   2132  1.1  haad 	zhp = zfs_open(hdl, name, ZFS_TYPE_DATASET);
   2133  1.1  haad 	if (zhp == NULL)
   2134  1.1  haad 		return (-1);
   2135  1.1  haad 	clp = changelist_gather(zhp, ZFS_PROP_NAME, 0,
   2136  1.3   chs 	    flags->force ? MS_FORCE : 0);
   2137  1.1  haad 	zfs_close(zhp);
   2138  1.1  haad 	if (clp == NULL)
   2139  1.1  haad 		return (-1);
   2140  1.1  haad 	err = changelist_prefix(clp);
   2141  1.1  haad 	if (err)
   2142  1.1  haad 		return (err);
   2143  1.1  haad 
   2144  1.2   dsl 	zc.zc_objset_type = DMU_OST_ZFS;
   2145  1.2   dsl 	(void) strlcpy(zc.zc_name, name, sizeof (zc.zc_name));
   2146  1.2   dsl 
   2147  1.1  haad 	if (tryname) {
   2148  1.1  haad 		(void) strcpy(newname, tryname);
   2149  1.1  haad 
   2150  1.1  haad 		(void) strlcpy(zc.zc_value, tryname, sizeof (zc.zc_value));
   2151  1.1  haad 
   2152  1.3   chs 		if (flags->verbose) {
   2153  1.1  haad 			(void) printf("attempting rename %s to %s\n",
   2154  1.1  haad 			    zc.zc_name, zc.zc_value);
   2155  1.1  haad 		}
   2156  1.1  haad 		err = ioctl(hdl->libzfs_fd, ZFS_IOC_RENAME, &zc);
   2157  1.1  haad 		if (err == 0)
   2158  1.1  haad 			changelist_rename(clp, name, tryname);
   2159  1.1  haad 	} else {
   2160  1.1  haad 		err = ENOENT;
   2161  1.1  haad 	}
   2162  1.1  haad 
   2163  1.3   chs 	if (err != 0 && strncmp(name + baselen, "recv-", 5) != 0) {
   2164  1.1  haad 		seq++;
   2165  1.1  haad 
   2166  1.3   chs 		(void) snprintf(newname, ZFS_MAX_DATASET_NAME_LEN,
   2167  1.3   chs 		    "%.*srecv-%u-%u", baselen, name, getpid(), seq);
   2168  1.1  haad 		(void) strlcpy(zc.zc_value, newname, sizeof (zc.zc_value));
   2169  1.1  haad 
   2170  1.3   chs 		if (flags->verbose) {
   2171  1.1  haad 			(void) printf("failed - trying rename %s to %s\n",
   2172  1.1  haad 			    zc.zc_name, zc.zc_value);
   2173  1.1  haad 		}
   2174  1.1  haad 		err = ioctl(hdl->libzfs_fd, ZFS_IOC_RENAME, &zc);
   2175  1.1  haad 		if (err == 0)
   2176  1.1  haad 			changelist_rename(clp, name, newname);
   2177  1.3   chs 		if (err && flags->verbose) {
   2178  1.1  haad 			(void) printf("failed (%u) - "
   2179  1.1  haad 			    "will try again on next pass\n", errno);
   2180  1.1  haad 		}
   2181  1.1  haad 		err = EAGAIN;
   2182  1.3   chs 	} else if (flags->verbose) {
   2183  1.1  haad 		if (err == 0)
   2184  1.1  haad 			(void) printf("success\n");
   2185  1.1  haad 		else
   2186  1.1  haad 			(void) printf("failed (%u)\n", errno);
   2187  1.1  haad 	}
   2188  1.1  haad 
   2189  1.1  haad 	(void) changelist_postfix(clp);
   2190  1.1  haad 	changelist_free(clp);
   2191  1.1  haad 
   2192  1.1  haad 	return (err);
   2193  1.1  haad }
   2194  1.1  haad 
   2195  1.1  haad static int
   2196  1.1  haad recv_destroy(libzfs_handle_t *hdl, const char *name, int baselen,
   2197  1.3   chs     char *newname, recvflags_t *flags)
   2198  1.1  haad {
   2199  1.1  haad 	zfs_cmd_t zc = { 0 };
   2200  1.1  haad 	int err = 0;
   2201  1.1  haad 	prop_changelist_t *clp;
   2202  1.1  haad 	zfs_handle_t *zhp;
   2203  1.2   dsl 	boolean_t defer = B_FALSE;
   2204  1.2   dsl 	int spa_version;
   2205  1.1  haad 
   2206  1.1  haad 	zhp = zfs_open(hdl, name, ZFS_TYPE_DATASET);
   2207  1.1  haad 	if (zhp == NULL)
   2208  1.1  haad 		return (-1);
   2209  1.1  haad 	clp = changelist_gather(zhp, ZFS_PROP_NAME, 0,
   2210  1.3   chs 	    flags->force ? MS_FORCE : 0);
   2211  1.2   dsl 	if (zfs_get_type(zhp) == ZFS_TYPE_SNAPSHOT &&
   2212  1.2   dsl 	    zfs_spa_version(zhp, &spa_version) == 0 &&
   2213  1.2   dsl 	    spa_version >= SPA_VERSION_USERREFS)
   2214  1.2   dsl 		defer = B_TRUE;
   2215  1.1  haad 	zfs_close(zhp);
   2216  1.1  haad 	if (clp == NULL)
   2217  1.1  haad 		return (-1);
   2218  1.1  haad 	err = changelist_prefix(clp);
   2219  1.1  haad 	if (err)
   2220  1.1  haad 		return (err);
   2221  1.1  haad 
   2222  1.1  haad 	zc.zc_objset_type = DMU_OST_ZFS;
   2223  1.2   dsl 	zc.zc_defer_destroy = defer;
   2224  1.1  haad 	(void) strlcpy(zc.zc_name, name, sizeof (zc.zc_name));
   2225  1.1  haad 
   2226  1.3   chs 	if (flags->verbose)
   2227  1.1  haad 		(void) printf("attempting destroy %s\n", zc.zc_name);
   2228  1.1  haad 	err = ioctl(hdl->libzfs_fd, ZFS_IOC_DESTROY, &zc);
   2229  1.1  haad 	if (err == 0) {
   2230  1.3   chs 		if (flags->verbose)
   2231  1.1  haad 			(void) printf("success\n");
   2232  1.1  haad 		changelist_remove(clp, zc.zc_name);
   2233  1.1  haad 	}
   2234  1.1  haad 
   2235  1.1  haad 	(void) changelist_postfix(clp);
   2236  1.1  haad 	changelist_free(clp);
   2237  1.1  haad 
   2238  1.2   dsl 	/*
   2239  1.2   dsl 	 * Deferred destroy might destroy the snapshot or only mark it to be
   2240  1.2   dsl 	 * destroyed later, and it returns success in either case.
   2241  1.2   dsl 	 */
   2242  1.2   dsl 	if (err != 0 || (defer && zfs_dataset_exists(hdl, name,
   2243  1.2   dsl 	    ZFS_TYPE_SNAPSHOT))) {
   2244  1.1  haad 		err = recv_rename(hdl, name, NULL, baselen, newname, flags);
   2245  1.2   dsl 	}
   2246  1.1  haad 
   2247  1.1  haad 	return (err);
   2248  1.1  haad }
   2249  1.1  haad 
   2250  1.1  haad typedef struct guid_to_name_data {
   2251  1.1  haad 	uint64_t guid;
   2252  1.3   chs 	boolean_t bookmark_ok;
   2253  1.1  haad 	char *name;
   2254  1.3   chs 	char *skip;
   2255  1.1  haad } guid_to_name_data_t;
   2256  1.1  haad 
   2257  1.1  haad static int
   2258  1.1  haad guid_to_name_cb(zfs_handle_t *zhp, void *arg)
   2259  1.1  haad {
   2260  1.1  haad 	guid_to_name_data_t *gtnd = arg;
   2261  1.3   chs 	const char *slash;
   2262  1.1  haad 	int err;
   2263  1.1  haad 
   2264  1.3   chs 	if (gtnd->skip != NULL &&
   2265  1.3   chs 	    (slash = strrchr(zhp->zfs_name, '/')) != NULL &&
   2266  1.3   chs 	    strcmp(slash + 1, gtnd->skip) == 0) {
   2267  1.3   chs 		zfs_close(zhp);
   2268  1.3   chs 		return (0);
   2269  1.3   chs 	}
   2270  1.3   chs 
   2271  1.3   chs 	if (zfs_prop_get_int(zhp, ZFS_PROP_GUID) == gtnd->guid) {
   2272  1.1  haad 		(void) strcpy(gtnd->name, zhp->zfs_name);
   2273  1.2   dsl 		zfs_close(zhp);
   2274  1.1  haad 		return (EEXIST);
   2275  1.1  haad 	}
   2276  1.3   chs 
   2277  1.1  haad 	err = zfs_iter_children(zhp, guid_to_name_cb, gtnd);
   2278  1.3   chs 	if (err != EEXIST && gtnd->bookmark_ok)
   2279  1.3   chs 		err = zfs_iter_bookmarks(zhp, guid_to_name_cb, gtnd);
   2280  1.1  haad 	zfs_close(zhp);
   2281  1.1  haad 	return (err);
   2282  1.1  haad }
   2283  1.1  haad 
   2284  1.3   chs /*
   2285  1.3   chs  * Attempt to find the local dataset associated with this guid.  In the case of
   2286  1.3   chs  * multiple matches, we attempt to find the "best" match by searching
   2287  1.3   chs  * progressively larger portions of the hierarchy.  This allows one to send a
   2288  1.3   chs  * tree of datasets individually and guarantee that we will find the source
   2289  1.3   chs  * guid within that hierarchy, even if there are multiple matches elsewhere.
   2290  1.3   chs  */
   2291  1.1  haad static int
   2292  1.1  haad guid_to_name(libzfs_handle_t *hdl, const char *parent, uint64_t guid,
   2293  1.3   chs     boolean_t bookmark_ok, char *name)
   2294  1.1  haad {
   2295  1.3   chs 	char pname[ZFS_MAX_DATASET_NAME_LEN];
   2296  1.1  haad 	guid_to_name_data_t gtnd;
   2297  1.1  haad 
   2298  1.1  haad 	gtnd.guid = guid;
   2299  1.3   chs 	gtnd.bookmark_ok = bookmark_ok;
   2300  1.1  haad 	gtnd.name = name;
   2301  1.3   chs 	gtnd.skip = NULL;
   2302  1.1  haad 
   2303  1.3   chs 	/*
   2304  1.3   chs 	 * Search progressively larger portions of the hierarchy, starting
   2305  1.3   chs 	 * with the filesystem specified by 'parent'.  This will
   2306  1.3   chs 	 * select the "most local" version of the origin snapshot in the case
   2307  1.3   chs 	 * that there are multiple matching snapshots in the system.
   2308  1.3   chs 	 */
   2309  1.3   chs 	(void) strlcpy(pname, parent, sizeof (pname));
   2310  1.3   chs 	char *cp = strrchr(pname, '@');
   2311  1.3   chs 	if (cp == NULL)
   2312  1.3   chs 		cp = strchr(pname, '\0');
   2313  1.3   chs 	for (; cp != NULL; cp = strrchr(pname, '/')) {
   2314  1.3   chs 		/* Chop off the last component and open the parent */
   2315  1.1  haad 		*cp = '\0';
   2316  1.3   chs 		zfs_handle_t *zhp = make_dataset_handle(hdl, pname);
   2317  1.1  haad 
   2318  1.3   chs 		if (zhp == NULL)
   2319  1.3   chs 			continue;
   2320  1.3   chs 		int err = guid_to_name_cb(zfs_handle_dup(zhp), &gtnd);
   2321  1.3   chs 		if (err != EEXIST)
   2322  1.3   chs 			err = zfs_iter_children(zhp, guid_to_name_cb, &gtnd);
   2323  1.3   chs 		if (err != EEXIST && bookmark_ok)
   2324  1.3   chs 			err = zfs_iter_bookmarks(zhp, guid_to_name_cb, &gtnd);
   2325  1.1  haad 		zfs_close(zhp);
   2326  1.3   chs 		if (err == EEXIST)
   2327  1.3   chs 			return (0);
   2328  1.3   chs 
   2329  1.3   chs 		/*
   2330  1.3   chs 		 * Remember the last portion of the dataset so we skip it next
   2331  1.3   chs 		 * time through (as we've already searched that portion of the
   2332  1.3   chs 		 * hierarchy).
   2333  1.3   chs 		 */
   2334  1.3   chs 		gtnd.skip = strrchr(pname, '/') + 1;
   2335  1.1  haad 	}
   2336  1.1  haad 
   2337  1.3   chs 	return (ENOENT);
   2338  1.1  haad }
   2339  1.1  haad 
   2340  1.1  haad /*
   2341  1.3   chs  * Return +1 if guid1 is before guid2, 0 if they are the same, and -1 if
   2342  1.3   chs  * guid1 is after guid2.
   2343  1.1  haad  */
   2344  1.1  haad static int
   2345  1.1  haad created_before(libzfs_handle_t *hdl, avl_tree_t *avl,
   2346  1.1  haad     uint64_t guid1, uint64_t guid2)
   2347  1.1  haad {
   2348  1.1  haad 	nvlist_t *nvfs;
   2349  1.1  haad 	char *fsname, *snapname;
   2350  1.3   chs 	char buf[ZFS_MAX_DATASET_NAME_LEN];
   2351  1.1  haad 	int rv;
   2352  1.3   chs 	zfs_handle_t *guid1hdl, *guid2hdl;
   2353  1.3   chs 	uint64_t create1, create2;
   2354  1.1  haad 
   2355  1.1  haad 	if (guid2 == 0)
   2356  1.1  haad 		return (0);
   2357  1.1  haad 	if (guid1 == 0)
   2358  1.1  haad 		return (1);
   2359  1.1  haad 
   2360  1.1  haad 	nvfs = fsavl_find(avl, guid1, &snapname);
   2361  1.1  haad 	VERIFY(0 == nvlist_lookup_string(nvfs, "name", &fsname));
   2362  1.1  haad 	(void) snprintf(buf, sizeof (buf), "%s@%s", fsname, snapname);
   2363  1.3   chs 	guid1hdl = zfs_open(hdl, buf, ZFS_TYPE_SNAPSHOT);
   2364  1.3   chs 	if (guid1hdl == NULL)
   2365  1.1  haad 		return (-1);
   2366  1.1  haad 
   2367  1.1  haad 	nvfs = fsavl_find(avl, guid2, &snapname);
   2368  1.1  haad 	VERIFY(0 == nvlist_lookup_string(nvfs, "name", &fsname));
   2369  1.1  haad 	(void) snprintf(buf, sizeof (buf), "%s@%s", fsname, snapname);
   2370  1.3   chs 	guid2hdl = zfs_open(hdl, buf, ZFS_TYPE_SNAPSHOT);
   2371  1.3   chs 	if (guid2hdl == NULL) {
   2372  1.3   chs 		zfs_close(guid1hdl);
   2373  1.1  haad 		return (-1);
   2374  1.1  haad 	}
   2375  1.1  haad 
   2376  1.3   chs 	create1 = zfs_prop_get_int(guid1hdl, ZFS_PROP_CREATETXG);
   2377  1.3   chs 	create2 = zfs_prop_get_int(guid2hdl, ZFS_PROP_CREATETXG);
   2378  1.3   chs 
   2379  1.3   chs 	if (create1 < create2)
   2380  1.3   chs 		rv = -1;
   2381  1.3   chs 	else if (create1 > create2)
   2382  1.3   chs 		rv = +1;
   2383  1.3   chs 	else
   2384  1.3   chs 		rv = 0;
   2385  1.1  haad 
   2386  1.3   chs 	zfs_close(guid1hdl);
   2387  1.3   chs 	zfs_close(guid2hdl);
   2388  1.1  haad 
   2389  1.1  haad 	return (rv);
   2390  1.1  haad }
   2391  1.1  haad 
   2392  1.1  haad static int
   2393  1.1  haad recv_incremental_replication(libzfs_handle_t *hdl, const char *tofs,
   2394  1.3   chs     recvflags_t *flags, nvlist_t *stream_nv, avl_tree_t *stream_avl,
   2395  1.3   chs     nvlist_t *renamed)
   2396  1.1  haad {
   2397  1.3   chs 	nvlist_t *local_nv, *deleted = NULL;
   2398  1.1  haad 	avl_tree_t *local_avl;
   2399  1.1  haad 	nvpair_t *fselem, *nextfselem;
   2400  1.3   chs 	char *fromsnap;
   2401  1.3   chs 	char newname[ZFS_MAX_DATASET_NAME_LEN];
   2402  1.3   chs 	char guidname[32];
   2403  1.1  haad 	int error;
   2404  1.2   dsl 	boolean_t needagain, progress, recursive;
   2405  1.2   dsl 	char *s1, *s2;
   2406  1.1  haad 
   2407  1.1  haad 	VERIFY(0 == nvlist_lookup_string(stream_nv, "fromsnap", &fromsnap));
   2408  1.1  haad 
   2409  1.2   dsl 	recursive = (nvlist_lookup_boolean(stream_nv, "not_recursive") ==
   2410  1.2   dsl 	    ENOENT);
   2411  1.2   dsl 
   2412  1.3   chs 	if (flags->dryrun)
   2413  1.1  haad 		return (0);
   2414  1.1  haad 
   2415  1.1  haad again:
   2416  1.1  haad 	needagain = progress = B_FALSE;
   2417  1.1  haad 
   2418  1.3   chs 	VERIFY(0 == nvlist_alloc(&deleted, NV_UNIQUE_NAME, 0));
   2419  1.3   chs 
   2420  1.1  haad 	if ((error = gather_nvlist(hdl, tofs, fromsnap, NULL,
   2421  1.3   chs 	    recursive, B_FALSE, &local_nv, &local_avl)) != 0)
   2422  1.1  haad 		return (error);
   2423  1.1  haad 
   2424  1.1  haad 	/*
   2425  1.1  haad 	 * Process deletes and renames
   2426  1.1  haad 	 */
   2427  1.1  haad 	for (fselem = nvlist_next_nvpair(local_nv, NULL);
   2428  1.1  haad 	    fselem; fselem = nextfselem) {
   2429  1.1  haad 		nvlist_t *nvfs, *snaps;
   2430  1.1  haad 		nvlist_t *stream_nvfs = NULL;
   2431  1.1  haad 		nvpair_t *snapelem, *nextsnapelem;
   2432  1.1  haad 		uint64_t fromguid = 0;
   2433  1.1  haad 		uint64_t originguid = 0;
   2434  1.1  haad 		uint64_t stream_originguid = 0;
   2435  1.1  haad 		uint64_t parent_fromsnap_guid, stream_parent_fromsnap_guid;
   2436  1.1  haad 		char *fsname, *stream_fsname;
   2437  1.1  haad 
   2438  1.1  haad 		nextfselem = nvlist_next_nvpair(local_nv, fselem);
   2439  1.1  haad 
   2440  1.1  haad 		VERIFY(0 == nvpair_value_nvlist(fselem, &nvfs));
   2441  1.1  haad 		VERIFY(0 == nvlist_lookup_nvlist(nvfs, "snaps", &snaps));
   2442  1.1  haad 		VERIFY(0 == nvlist_lookup_string(nvfs, "name", &fsname));
   2443  1.1  haad 		VERIFY(0 == nvlist_lookup_uint64(nvfs, "parentfromsnap",
   2444  1.1  haad 		    &parent_fromsnap_guid));
   2445  1.1  haad 		(void) nvlist_lookup_uint64(nvfs, "origin", &originguid);
   2446  1.1  haad 
   2447  1.1  haad 		/*
   2448  1.1  haad 		 * First find the stream's fs, so we can check for
   2449  1.1  haad 		 * a different origin (due to "zfs promote")
   2450  1.1  haad 		 */
   2451  1.1  haad 		for (snapelem = nvlist_next_nvpair(snaps, NULL);
   2452  1.1  haad 		    snapelem; snapelem = nvlist_next_nvpair(snaps, snapelem)) {
   2453  1.1  haad 			uint64_t thisguid;
   2454  1.1  haad 
   2455  1.1  haad 			VERIFY(0 == nvpair_value_uint64(snapelem, &thisguid));
   2456  1.1  haad 			stream_nvfs = fsavl_find(stream_avl, thisguid, NULL);
   2457  1.1  haad 
   2458  1.1  haad 			if (stream_nvfs != NULL)
   2459  1.1  haad 				break;
   2460  1.1  haad 		}
   2461  1.1  haad 
   2462  1.1  haad 		/* check for promote */
   2463  1.1  haad 		(void) nvlist_lookup_uint64(stream_nvfs, "origin",
   2464  1.1  haad 		    &stream_originguid);
   2465  1.1  haad 		if (stream_nvfs && originguid != stream_originguid) {
   2466  1.1  haad 			switch (created_before(hdl, local_avl,
   2467  1.1  haad 			    stream_originguid, originguid)) {
   2468  1.1  haad 			case 1: {
   2469  1.1  haad 				/* promote it! */
   2470  1.1  haad 				zfs_cmd_t zc = { 0 };
   2471  1.1  haad 				nvlist_t *origin_nvfs;
   2472  1.1  haad 				char *origin_fsname;
   2473  1.1  haad 
   2474  1.3   chs 				if (flags->verbose)
   2475  1.1  haad 					(void) printf("promoting %s\n", fsname);
   2476  1.1  haad 
   2477  1.1  haad 				origin_nvfs = fsavl_find(local_avl, originguid,
   2478  1.1  haad 				    NULL);
   2479  1.1  haad 				VERIFY(0 == nvlist_lookup_string(origin_nvfs,
   2480  1.1  haad 				    "name", &origin_fsname));
   2481  1.1  haad 				(void) strlcpy(zc.zc_value, origin_fsname,
   2482  1.1  haad 				    sizeof (zc.zc_value));
   2483  1.1  haad 				(void) strlcpy(zc.zc_name, fsname,
   2484  1.1  haad 				    sizeof (zc.zc_name));
   2485  1.1  haad 				error = zfs_ioctl(hdl, ZFS_IOC_PROMOTE, &zc);
   2486  1.1  haad 				if (error == 0)
   2487  1.1  haad 					progress = B_TRUE;
   2488  1.1  haad 				break;
   2489  1.1  haad 			}
   2490  1.1  haad 			default:
   2491  1.1  haad 				break;
   2492  1.1  haad 			case -1:
   2493  1.1  haad 				fsavl_destroy(local_avl);
   2494  1.1  haad 				nvlist_free(local_nv);
   2495  1.1  haad 				return (-1);
   2496  1.1  haad 			}
   2497  1.1  haad 			/*
   2498  1.1  haad 			 * We had/have the wrong origin, therefore our
   2499  1.1  haad 			 * list of snapshots is wrong.  Need to handle
   2500  1.1  haad 			 * them on the next pass.
   2501  1.1  haad 			 */
   2502  1.1  haad 			needagain = B_TRUE;
   2503  1.1  haad 			continue;
   2504  1.1  haad 		}
   2505  1.1  haad 
   2506  1.1  haad 		for (snapelem = nvlist_next_nvpair(snaps, NULL);
   2507  1.1  haad 		    snapelem; snapelem = nextsnapelem) {
   2508  1.1  haad 			uint64_t thisguid;
   2509  1.1  haad 			char *stream_snapname;
   2510  1.1  haad 			nvlist_t *found, *props;
   2511  1.1  haad 
   2512  1.1  haad 			nextsnapelem = nvlist_next_nvpair(snaps, snapelem);
   2513  1.1  haad 
   2514  1.1  haad 			VERIFY(0 == nvpair_value_uint64(snapelem, &thisguid));
   2515  1.1  haad 			found = fsavl_find(stream_avl, thisguid,
   2516  1.1  haad 			    &stream_snapname);
   2517  1.1  haad 
   2518  1.1  haad 			/* check for delete */
   2519  1.1  haad 			if (found == NULL) {
   2520  1.3   chs 				char name[ZFS_MAX_DATASET_NAME_LEN];
   2521  1.1  haad 
   2522  1.3   chs 				if (!flags->force)
   2523  1.1  haad 					continue;
   2524  1.1  haad 
   2525  1.1  haad 				(void) snprintf(name, sizeof (name), "%s@%s",
   2526  1.1  haad 				    fsname, nvpair_name(snapelem));
   2527  1.1  haad 
   2528  1.1  haad 				error = recv_destroy(hdl, name,
   2529  1.1  haad 				    strlen(fsname)+1, newname, flags);
   2530  1.1  haad 				if (error)
   2531  1.1  haad 					needagain = B_TRUE;
   2532  1.1  haad 				else
   2533  1.1  haad 					progress = B_TRUE;
   2534  1.3   chs 				sprintf(guidname, "%lu", thisguid);
   2535  1.3   chs 				nvlist_add_boolean(deleted, guidname);
   2536  1.1  haad 				continue;
   2537  1.1  haad 			}
   2538  1.1  haad 
   2539  1.1  haad 			stream_nvfs = found;
   2540  1.1  haad 
   2541  1.1  haad 			if (0 == nvlist_lookup_nvlist(stream_nvfs, "snapprops",
   2542  1.1  haad 			    &props) && 0 == nvlist_lookup_nvlist(props,
   2543  1.1  haad 			    stream_snapname, &props)) {
   2544  1.1  haad 				zfs_cmd_t zc = { 0 };
   2545  1.1  haad 
   2546  1.2   dsl 				zc.zc_cookie = B_TRUE; /* received */
   2547  1.1  haad 				(void) snprintf(zc.zc_name, sizeof (zc.zc_name),
   2548  1.1  haad 				    "%s@%s", fsname, nvpair_name(snapelem));
   2549  1.1  haad 				if (zcmd_write_src_nvlist(hdl, &zc,
   2550  1.1  haad 				    props) == 0) {
   2551  1.1  haad 					(void) zfs_ioctl(hdl,
   2552  1.1  haad 					    ZFS_IOC_SET_PROP, &zc);
   2553  1.1  haad 					zcmd_free_nvlists(&zc);
   2554  1.1  haad 				}
   2555  1.1  haad 			}
   2556  1.1  haad 
   2557  1.1  haad 			/* check for different snapname */
   2558  1.1  haad 			if (strcmp(nvpair_name(snapelem),
   2559  1.1  haad 			    stream_snapname) != 0) {
   2560  1.3   chs 				char name[ZFS_MAX_DATASET_NAME_LEN];
   2561  1.3   chs 				char tryname[ZFS_MAX_DATASET_NAME_LEN];
   2562  1.1  haad 
   2563  1.1  haad 				(void) snprintf(name, sizeof (name), "%s@%s",
   2564  1.1  haad 				    fsname, nvpair_name(snapelem));
   2565  1.1  haad 				(void) snprintf(tryname, sizeof (name), "%s@%s",
   2566  1.1  haad 				    fsname, stream_snapname);
   2567  1.1  haad 
   2568  1.1  haad 				error = recv_rename(hdl, name, tryname,
   2569  1.1  haad 				    strlen(fsname)+1, newname, flags);
   2570  1.1  haad 				if (error)
   2571  1.1  haad 					needagain = B_TRUE;
   2572  1.1  haad 				else
   2573  1.1  haad 					progress = B_TRUE;
   2574  1.1  haad 			}
   2575  1.1  haad 
   2576  1.1  haad 			if (strcmp(stream_snapname, fromsnap) == 0)
   2577  1.1  haad 				fromguid = thisguid;
   2578  1.1  haad 		}
   2579  1.1  haad 
   2580  1.1  haad 		/* check for delete */
   2581  1.1  haad 		if (stream_nvfs == NULL) {
   2582  1.3   chs 			if (!flags->force)
   2583  1.1  haad 				continue;
   2584  1.1  haad 
   2585  1.1  haad 			error = recv_destroy(hdl, fsname, strlen(tofs)+1,
   2586  1.1  haad 			    newname, flags);
   2587  1.1  haad 			if (error)
   2588  1.1  haad 				needagain = B_TRUE;
   2589  1.1  haad 			else
   2590  1.1  haad 				progress = B_TRUE;
   2591  1.3   chs 			sprintf(guidname, "%lu", parent_fromsnap_guid);
   2592  1.3   chs 			nvlist_add_boolean(deleted, guidname);
   2593  1.1  haad 			continue;
   2594  1.1  haad 		}
   2595  1.1  haad 
   2596  1.3   chs 		if (fromguid == 0) {
   2597  1.3   chs 			if (flags->verbose) {
   2598  1.3   chs 				(void) printf("local fs %s does not have "
   2599  1.3   chs 				    "fromsnap (%s in stream); must have "
   2600  1.3   chs 				    "been deleted locally; ignoring\n",
   2601  1.3   chs 				    fsname, fromsnap);
   2602  1.3   chs 			}
   2603  1.1  haad 			continue;
   2604  1.1  haad 		}
   2605  1.1  haad 
   2606  1.1  haad 		VERIFY(0 == nvlist_lookup_string(stream_nvfs,
   2607  1.1  haad 		    "name", &stream_fsname));
   2608  1.1  haad 		VERIFY(0 == nvlist_lookup_uint64(stream_nvfs,
   2609  1.1  haad 		    "parentfromsnap", &stream_parent_fromsnap_guid));
   2610  1.1  haad 
   2611  1.2   dsl 		s1 = strrchr(fsname, '/');
   2612  1.2   dsl 		s2 = strrchr(stream_fsname, '/');
   2613  1.2   dsl 
   2614  1.3   chs 		/*
   2615  1.3   chs 		 * Check if we're going to rename based on parent guid change
   2616  1.3   chs 		 * and the current parent guid was also deleted. If it was then
   2617  1.3   chs 		 * rename will fail and is likely unneeded, so avoid this and
   2618  1.3   chs 		 * force an early retry to determine the new
   2619  1.3   chs 		 * parent_fromsnap_guid.
   2620  1.3   chs 		 */
   2621  1.3   chs 		if (stream_parent_fromsnap_guid != 0 &&
   2622  1.3   chs                     parent_fromsnap_guid != 0 &&
   2623  1.3   chs                     stream_parent_fromsnap_guid != parent_fromsnap_guid) {
   2624  1.3   chs 			sprintf(guidname, "%lu", parent_fromsnap_guid);
   2625  1.3   chs 			if (nvlist_exists(deleted, guidname)) {
   2626  1.3   chs 				progress = B_TRUE;
   2627  1.3   chs 				needagain = B_TRUE;
   2628  1.3   chs 				goto doagain;
   2629  1.3   chs 			}
   2630  1.3   chs 		}
   2631  1.3   chs 
   2632  1.3   chs 		/*
   2633  1.3   chs 		 * Check for rename. If the exact receive path is specified, it
   2634  1.3   chs 		 * does not count as a rename, but we still need to check the
   2635  1.3   chs 		 * datasets beneath it.
   2636  1.3   chs 		 */
   2637  1.1  haad 		if ((stream_parent_fromsnap_guid != 0 &&
   2638  1.3   chs 		    parent_fromsnap_guid != 0 &&
   2639  1.1  haad 		    stream_parent_fromsnap_guid != parent_fromsnap_guid) ||
   2640  1.3   chs 		    ((flags->isprefix || strcmp(tofs, fsname) != 0) &&
   2641  1.3   chs 		    (s1 != NULL) && (s2 != NULL) && strcmp(s1, s2) != 0)) {
   2642  1.1  haad 			nvlist_t *parent;
   2643  1.3   chs 			char tryname[ZFS_MAX_DATASET_NAME_LEN];
   2644  1.1  haad 
   2645  1.1  haad 			parent = fsavl_find(local_avl,
   2646  1.1  haad 			    stream_parent_fromsnap_guid, NULL);
   2647  1.1  haad 			/*
   2648  1.1  haad 			 * NB: parent might not be found if we used the
   2649  1.1  haad 			 * tosnap for stream_parent_fromsnap_guid,
   2650  1.1  haad 			 * because the parent is a newly-created fs;
   2651  1.1  haad 			 * we'll be able to rename it after we recv the
   2652  1.1  haad 			 * new fs.
   2653  1.1  haad 			 */
   2654  1.1  haad 			if (parent != NULL) {
   2655  1.1  haad 				char *pname;
   2656  1.1  haad 
   2657  1.1  haad 				VERIFY(0 == nvlist_lookup_string(parent, "name",
   2658  1.1  haad 				    &pname));
   2659  1.1  haad 				(void) snprintf(tryname, sizeof (tryname),
   2660  1.1  haad 				    "%s%s", pname, strrchr(stream_fsname, '/'));
   2661  1.1  haad 			} else {
   2662  1.1  haad 				tryname[0] = '\0';
   2663  1.3   chs 				if (flags->verbose) {
   2664  1.1  haad 					(void) printf("local fs %s new parent "
   2665  1.1  haad 					    "not found\n", fsname);
   2666  1.1  haad 				}
   2667  1.1  haad 			}
   2668  1.1  haad 
   2669  1.3   chs 			newname[0] = '\0';
   2670  1.3   chs 
   2671  1.1  haad 			error = recv_rename(hdl, fsname, tryname,
   2672  1.1  haad 			    strlen(tofs)+1, newname, flags);
   2673  1.3   chs 
   2674  1.3   chs 			if (renamed != NULL && newname[0] != '\0') {
   2675  1.3   chs 				VERIFY(0 == nvlist_add_boolean(renamed,
   2676  1.3   chs 				    newname));
   2677  1.3   chs 			}
   2678  1.3   chs 
   2679  1.1  haad 			if (error)
   2680  1.1  haad 				needagain = B_TRUE;
   2681  1.1  haad 			else
   2682  1.1  haad 				progress = B_TRUE;
   2683  1.1  haad 		}
   2684  1.1  haad 	}
   2685  1.1  haad 
   2686  1.3   chs doagain:
   2687  1.1  haad 	fsavl_destroy(local_avl);
   2688  1.1  haad 	nvlist_free(local_nv);
   2689  1.3   chs 	nvlist_free(deleted);
   2690  1.1  haad 
   2691  1.1  haad 	if (needagain && progress) {
   2692  1.1  haad 		/* do another pass to fix up temporary names */
   2693  1.3   chs 		if (flags->verbose)
   2694  1.1  haad 			(void) printf("another pass:\n");
   2695  1.1  haad 		goto again;
   2696  1.1  haad 	}
   2697  1.1  haad 
   2698  1.1  haad 	return (needagain);
   2699  1.1  haad }
   2700  1.1  haad 
   2701  1.1  haad static int
   2702  1.1  haad zfs_receive_package(libzfs_handle_t *hdl, int fd, const char *destname,
   2703  1.3   chs     recvflags_t *flags, dmu_replay_record_t *drr, zio_cksum_t *zc,
   2704  1.3   chs     char **top_zfs, int cleanup_fd, uint64_t *action_handlep)
   2705  1.1  haad {
   2706  1.1  haad 	nvlist_t *stream_nv = NULL;
   2707  1.1  haad 	avl_tree_t *stream_avl = NULL;
   2708  1.1  haad 	char *fromsnap = NULL;
   2709  1.3   chs 	char *sendsnap = NULL;
   2710  1.3   chs 	char *cp;
   2711  1.3   chs 	char tofs[ZFS_MAX_DATASET_NAME_LEN];
   2712  1.3   chs 	char sendfs[ZFS_MAX_DATASET_NAME_LEN];
   2713  1.1  haad 	char errbuf[1024];
   2714  1.1  haad 	dmu_replay_record_t drre;
   2715  1.1  haad 	int error;
   2716  1.1  haad 	boolean_t anyerr = B_FALSE;
   2717  1.1  haad 	boolean_t softerr = B_FALSE;
   2718  1.3   chs 	boolean_t recursive;
   2719  1.1  haad 
   2720  1.1  haad 	(void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
   2721  1.1  haad 	    "cannot receive"));
   2722  1.1  haad 
   2723  1.1  haad 	assert(drr->drr_type == DRR_BEGIN);
   2724  1.1  haad 	assert(drr->drr_u.drr_begin.drr_magic == DMU_BACKUP_MAGIC);
   2725  1.2   dsl 	assert(DMU_GET_STREAM_HDRTYPE(drr->drr_u.drr_begin.drr_versioninfo) ==
   2726  1.2   dsl 	    DMU_COMPOUNDSTREAM);
   2727  1.1  haad 
   2728  1.1  haad 	/*
   2729  1.1  haad 	 * Read in the nvlist from the stream.
   2730  1.1  haad 	 */
   2731  1.1  haad 	if (drr->drr_payloadlen != 0) {
   2732  1.1  haad 		error = recv_read_nvlist(hdl, fd, drr->drr_payloadlen,
   2733  1.3   chs 		    &stream_nv, flags->byteswap, zc);
   2734  1.1  haad 		if (error) {
   2735  1.1  haad 			error = zfs_error(hdl, EZFS_BADSTREAM, errbuf);
   2736  1.1  haad 			goto out;
   2737  1.1  haad 		}
   2738  1.1  haad 	}
   2739  1.1  haad 
   2740  1.3   chs 	recursive = (nvlist_lookup_boolean(stream_nv, "not_recursive") ==
   2741  1.3   chs 	    ENOENT);
   2742  1.3   chs 
   2743  1.3   chs 	if (recursive && strchr(destname, '@')) {
   2744  1.3   chs 		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
   2745  1.3   chs 		    "cannot specify snapshot name for multi-snapshot stream"));
   2746  1.3   chs 		error = zfs_error(hdl, EZFS_BADSTREAM, errbuf);
   2747  1.3   chs 		goto out;
   2748  1.3   chs 	}
   2749  1.3   chs 
   2750  1.1  haad 	/*
   2751  1.1  haad 	 * Read in the end record and verify checksum.
   2752  1.1  haad 	 */
   2753  1.1  haad 	if (0 != (error = recv_read(hdl, fd, &drre, sizeof (drre),
   2754  1.3   chs 	    flags->byteswap, NULL)))
   2755  1.1  haad 		goto out;
   2756  1.3   chs 	if (flags->byteswap) {
   2757  1.1  haad 		drre.drr_type = BSWAP_32(drre.drr_type);
   2758  1.1  haad 		drre.drr_u.drr_end.drr_checksum.zc_word[0] =
   2759  1.1  haad 		    BSWAP_64(drre.drr_u.drr_end.drr_checksum.zc_word[0]);
   2760  1.1  haad 		drre.drr_u.drr_end.drr_checksum.zc_word[1] =
   2761  1.1  haad 		    BSWAP_64(drre.drr_u.drr_end.drr_checksum.zc_word[1]);
   2762  1.1  haad 		drre.drr_u.drr_end.drr_checksum.zc_word[2] =
   2763  1.1  haad 		    BSWAP_64(drre.drr_u.drr_end.drr_checksum.zc_word[2]);
   2764  1.1  haad 		drre.drr_u.drr_end.drr_checksum.zc_word[3] =
   2765  1.1  haad 		    BSWAP_64(drre.drr_u.drr_end.drr_checksum.zc_word[3]);
   2766  1.1  haad 	}
   2767  1.1  haad 	if (drre.drr_type != DRR_END) {
   2768  1.1  haad 		error = zfs_error(hdl, EZFS_BADSTREAM, errbuf);
   2769  1.1  haad 		goto out;
   2770  1.1  haad 	}
   2771  1.1  haad 	if (!ZIO_CHECKSUM_EQUAL(drre.drr_u.drr_end.drr_checksum, *zc)) {
   2772  1.1  haad 		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
   2773  1.1  haad 		    "incorrect header checksum"));
   2774  1.1  haad 		error = zfs_error(hdl, EZFS_BADSTREAM, errbuf);
   2775  1.1  haad 		goto out;
   2776  1.1  haad 	}
   2777  1.1  haad 
   2778  1.1  haad 	(void) nvlist_lookup_string(stream_nv, "fromsnap", &fromsnap);
   2779  1.1  haad 
   2780  1.1  haad 	if (drr->drr_payloadlen != 0) {
   2781  1.1  haad 		nvlist_t *stream_fss;
   2782  1.1  haad 
   2783  1.1  haad 		VERIFY(0 == nvlist_lookup_nvlist(stream_nv, "fss",
   2784  1.1  haad 		    &stream_fss));
   2785  1.1  haad 		if ((stream_avl = fsavl_create(stream_fss)) == NULL) {
   2786  1.1  haad 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
   2787  1.1  haad 			    "couldn't allocate avl tree"));
   2788  1.1  haad 			error = zfs_error(hdl, EZFS_NOMEM, errbuf);
   2789  1.1  haad 			goto out;
   2790  1.1  haad 		}
   2791  1.1  haad 
   2792  1.1  haad 		if (fromsnap != NULL) {
   2793  1.3   chs 			nvlist_t *renamed = NULL;
   2794  1.3   chs 			nvpair_t *pair = NULL;
   2795  1.3   chs 
   2796  1.3   chs 			(void) strlcpy(tofs, destname, sizeof (tofs));
   2797  1.3   chs 			if (flags->isprefix) {
   2798  1.3   chs 				struct drr_begin *drrb = &drr->drr_u.drr_begin;
   2799  1.3   chs 				int i;
   2800  1.3   chs 
   2801  1.3   chs 				if (flags->istail) {
   2802  1.3   chs 					cp = strrchr(drrb->drr_toname, '/');
   2803  1.3   chs 					if (cp == NULL) {
   2804  1.3   chs 						(void) strlcat(tofs, "/",
   2805  1.3   chs 						    sizeof (tofs));
   2806  1.3   chs 						i = 0;
   2807  1.3   chs 					} else {
   2808  1.3   chs 						i = (cp - drrb->drr_toname);
   2809  1.3   chs 					}
   2810  1.3   chs 				} else {
   2811  1.3   chs 					i = strcspn(drrb->drr_toname, "/@");
   2812  1.3   chs 				}
   2813  1.1  haad 				/* zfs_receive_one() will create_parents() */
   2814  1.3   chs 				(void) strlcat(tofs, &drrb->drr_toname[i],
   2815  1.3   chs 				    sizeof (tofs));
   2816  1.1  haad 				*strchr(tofs, '@') = '\0';
   2817  1.1  haad 			}
   2818  1.3   chs 
   2819  1.3   chs 			if (recursive && !flags->dryrun && !flags->nomount) {
   2820  1.3   chs 				VERIFY(0 == nvlist_alloc(&renamed,
   2821  1.3   chs 				    NV_UNIQUE_NAME, 0));
   2822  1.3   chs 			}
   2823  1.3   chs 
   2824  1.3   chs 			softerr = recv_incremental_replication(hdl, tofs, flags,
   2825  1.3   chs 			    stream_nv, stream_avl, renamed);
   2826  1.3   chs 
   2827  1.3   chs 			/* Unmount renamed filesystems before receiving. */
   2828  1.3   chs 			while ((pair = nvlist_next_nvpair(renamed,
   2829  1.3   chs 			    pair)) != NULL) {
   2830  1.3   chs 				zfs_handle_t *zhp;
   2831  1.3   chs 				prop_changelist_t *clp = NULL;
   2832  1.3   chs 
   2833  1.3   chs 				zhp = zfs_open(hdl, nvpair_name(pair),
   2834  1.3   chs 				    ZFS_TYPE_FILESYSTEM);
   2835  1.3   chs 				if (zhp != NULL) {
   2836  1.3   chs 					clp = changelist_gather(zhp,
   2837  1.3   chs 					    ZFS_PROP_MOUNTPOINT, 0, 0);
   2838  1.3   chs 					zfs_close(zhp);
   2839  1.3   chs 					if (clp != NULL) {
   2840  1.3   chs 						softerr |=
   2841  1.3   chs 						    changelist_prefix(clp);
   2842  1.3   chs 						changelist_free(clp);
   2843  1.3   chs 					}
   2844  1.3   chs 				}
   2845  1.3   chs 			}
   2846  1.3   chs 
   2847  1.3   chs 			nvlist_free(renamed);
   2848  1.1  haad 		}
   2849  1.1  haad 	}
   2850  1.1  haad 
   2851  1.3   chs 	/*
   2852  1.3   chs 	 * Get the fs specified by the first path in the stream (the top level
   2853  1.3   chs 	 * specified by 'zfs send') and pass it to each invocation of
   2854  1.3   chs 	 * zfs_receive_one().
   2855  1.3   chs 	 */
   2856  1.3   chs 	(void) strlcpy(sendfs, drr->drr_u.drr_begin.drr_toname,
   2857  1.3   chs 	    sizeof (sendfs));
   2858  1.3   chs 	if ((cp = strchr(sendfs, '@')) != NULL) {
   2859  1.3   chs 		*cp = '\0';
   2860  1.3   chs 		/*
   2861  1.3   chs 		 * Find the "sendsnap", the final snapshot in a replication
   2862  1.3   chs 		 * stream.  zfs_receive_one() handles certain errors
   2863  1.3   chs 		 * differently, depending on if the contained stream is the
   2864  1.3   chs 		 * last one or not.
   2865  1.3   chs 		 */
   2866  1.3   chs 		sendsnap = (cp + 1);
   2867  1.3   chs 	}
   2868  1.1  haad 
   2869  1.1  haad 	/* Finally, receive each contained stream */
   2870  1.1  haad 	do {
   2871  1.1  haad 		/*
   2872  1.1  haad 		 * we should figure out if it has a recoverable
   2873  1.1  haad 		 * error, in which case do a recv_skip() and drive on.
   2874  1.1  haad 		 * Note, if we fail due to already having this guid,
   2875  1.1  haad 		 * zfs_receive_one() will take care of it (ie,
   2876  1.1  haad 		 * recv_skip() and return 0).
   2877  1.1  haad 		 */
   2878  1.3   chs 		error = zfs_receive_impl(hdl, destname, NULL, flags, fd,
   2879  1.3   chs 		    sendfs, stream_nv, stream_avl, top_zfs, cleanup_fd,
   2880  1.3   chs 		    action_handlep, sendsnap);
   2881  1.1  haad 		if (error == ENODATA) {
   2882  1.1  haad 			error = 0;
   2883  1.1  haad 			break;
   2884  1.1  haad 		}
   2885  1.1  haad 		anyerr |= error;
   2886  1.1  haad 	} while (error == 0);
   2887  1.1  haad 
   2888  1.1  haad 	if (drr->drr_payloadlen != 0 && fromsnap != NULL) {
   2889  1.1  haad 		/*
   2890  1.1  haad 		 * Now that we have the fs's they sent us, try the
   2891  1.1  haad 		 * renames again.
   2892  1.1  haad 		 */
   2893  1.1  haad 		softerr = recv_incremental_replication(hdl, tofs, flags,
   2894  1.3   chs 		    stream_nv, stream_avl, NULL);
   2895  1.1  haad 	}
   2896  1.1  haad 
   2897  1.1  haad out:
   2898  1.1  haad 	fsavl_destroy(stream_avl);
   2899  1.3   chs 	nvlist_free(stream_nv);
   2900  1.1  haad 	if (softerr)
   2901  1.1  haad 		error = -2;
   2902  1.1  haad 	if (anyerr)
   2903  1.1  haad 		error = -1;
   2904  1.1  haad 	return (error);
   2905  1.1  haad }
   2906  1.1  haad 
   2907  1.2   dsl static void
   2908  1.2   dsl trunc_prop_errs(int truncated)
   2909  1.2   dsl {
   2910  1.2   dsl 	ASSERT(truncated != 0);
   2911  1.2   dsl 
   2912  1.2   dsl 	if (truncated == 1)
   2913  1.2   dsl 		(void) fprintf(stderr, dgettext(TEXT_DOMAIN,
   2914  1.2   dsl 		    "1 more property could not be set\n"));
   2915  1.2   dsl 	else
   2916  1.2   dsl 		(void) fprintf(stderr, dgettext(TEXT_DOMAIN,
   2917  1.2   dsl 		    "%d more properties could not be set\n"), truncated);
   2918  1.2   dsl }
   2919  1.2   dsl 
   2920  1.1  haad static int
   2921  1.1  haad recv_skip(libzfs_handle_t *hdl, int fd, boolean_t byteswap)
   2922  1.1  haad {
   2923  1.1  haad 	dmu_replay_record_t *drr;
   2924  1.3   chs 	void *buf = zfs_alloc(hdl, SPA_MAXBLOCKSIZE);
   2925  1.2   dsl 	char errbuf[1024];
   2926  1.2   dsl 
   2927  1.2   dsl 	(void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
   2928  1.2   dsl 	    "cannot receive:"));
   2929  1.1  haad 
   2930  1.1  haad 	/* XXX would be great to use lseek if possible... */
   2931  1.1  haad 	drr = buf;
   2932  1.1  haad 
   2933  1.1  haad 	while (recv_read(hdl, fd, drr, sizeof (dmu_replay_record_t),
   2934  1.1  haad 	    byteswap, NULL) == 0) {
   2935  1.1  haad 		if (byteswap)
   2936  1.1  haad 			drr->drr_type = BSWAP_32(drr->drr_type);
   2937  1.1  haad 
   2938  1.1  haad 		switch (drr->drr_type) {
   2939  1.1  haad 		case DRR_BEGIN:
   2940  1.2   dsl 			if (drr->drr_payloadlen != 0) {
   2941  1.3   chs 				(void) recv_read(hdl, fd, buf,
   2942  1.3   chs 				    drr->drr_payloadlen, B_FALSE, NULL);
   2943  1.2   dsl 			}
   2944  1.1  haad 			break;
   2945  1.1  haad 
   2946  1.1  haad 		case DRR_END:
   2947  1.1  haad 			free(buf);
   2948  1.1  haad 			return (0);
   2949  1.1  haad 
   2950  1.1  haad 		case DRR_OBJECT:
   2951  1.1  haad 			if (byteswap) {
   2952  1.1  haad 				drr->drr_u.drr_object.drr_bonuslen =
   2953  1.1  haad 				    BSWAP_32(drr->drr_u.drr_object.
   2954  1.1  haad 				    drr_bonuslen);
   2955  1.1  haad 			}
   2956  1.1  haad 			(void) recv_read(hdl, fd, buf,
   2957  1.1  haad 			    P2ROUNDUP(drr->drr_u.drr_object.drr_bonuslen, 8),
   2958  1.1  haad 			    B_FALSE, NULL);
   2959  1.1  haad 			break;
   2960  1.1  haad 
   2961  1.1  haad 		case DRR_WRITE:
   2962  1.1  haad 			if (byteswap) {
   2963  1.1  haad 				drr->drr_u.drr_write.drr_length =
   2964  1.1  haad 				    BSWAP_64(drr->drr_u.drr_write.drr_length);
   2965  1.1  haad 			}
   2966  1.1  haad 			(void) recv_read(hdl, fd, buf,
   2967  1.1  haad 			    drr->drr_u.drr_write.drr_length, B_FALSE, NULL);
   2968  1.1  haad 			break;
   2969  1.3   chs 		case DRR_SPILL:
   2970  1.3   chs 			if (byteswap) {
   2971  1.3   chs 				drr->drr_u.drr_spill.drr_length =
   2972  1.3   chs 				    BSWAP_64(drr->drr_u.drr_spill.drr_length);
   2973  1.3   chs 			}
   2974  1.3   chs 			(void) recv_read(hdl, fd, buf,
   2975  1.3   chs 			    drr->drr_u.drr_spill.drr_length, B_FALSE, NULL);
   2976  1.3   chs 			break;
   2977  1.3   chs 		case DRR_WRITE_EMBEDDED:
   2978  1.3   chs 			if (byteswap) {
   2979  1.3   chs 				drr->drr_u.drr_write_embedded.drr_psize =
   2980  1.3   chs 				    BSWAP_32(drr->drr_u.drr_write_embedded.
   2981  1.3   chs 				    drr_psize);
   2982  1.3   chs 			}
   2983  1.3   chs 			(void) recv_read(hdl, fd, buf,
   2984  1.3   chs 			    P2ROUNDUP(drr->drr_u.drr_write_embedded.drr_psize,
   2985  1.3   chs 			    8), B_FALSE, NULL);
   2986  1.3   chs 			break;
   2987  1.2   dsl 		case DRR_WRITE_BYREF:
   2988  1.1  haad 		case DRR_FREEOBJECTS:
   2989  1.1  haad 		case DRR_FREE:
   2990  1.1  haad 			break;
   2991  1.1  haad 
   2992  1.1  haad 		default:
   2993  1.2   dsl 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
   2994  1.2   dsl 			    "invalid record type"));
   2995  1.2   dsl 			return (zfs_error(hdl, EZFS_BADSTREAM, errbuf));
   2996  1.1  haad 		}
   2997  1.1  haad 	}
   2998  1.1  haad 
   2999  1.1  haad 	free(buf);
   3000  1.1  haad 	return (-1);
   3001  1.1  haad }
   3002  1.1  haad 
   3003  1.3   chs static void
   3004  1.3   chs recv_ecksum_set_aux(libzfs_handle_t *hdl, const char *target_snap,
   3005  1.3   chs     boolean_t resumable)
   3006  1.3   chs {
   3007  1.3   chs 	char target_fs[ZFS_MAX_DATASET_NAME_LEN];
   3008  1.3   chs 
   3009  1.3   chs 	zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
   3010  1.3   chs 	    "checksum mismatch or incomplete stream"));
   3011  1.3   chs 
   3012  1.3   chs 	if (!resumable)
   3013  1.3   chs 		return;
   3014  1.3   chs 	(void) strlcpy(target_fs, target_snap, sizeof (target_fs));
   3015  1.3   chs 	*strchr(target_fs, '@') = '\0';
   3016  1.3   chs 	zfs_handle_t *zhp = zfs_open(hdl, target_fs,
   3017  1.3   chs 	    ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME);
   3018  1.3   chs 	if (zhp == NULL)
   3019  1.3   chs 		return;
   3020  1.3   chs 
   3021  1.3   chs 	char token_buf[ZFS_MAXPROPLEN];
   3022  1.3   chs 	int error = zfs_prop_get(zhp, ZFS_PROP_RECEIVE_RESUME_TOKEN,
   3023  1.3   chs 	    token_buf, sizeof (token_buf),
   3024  1.3   chs 	    NULL, NULL, 0, B_TRUE);
   3025  1.3   chs 	if (error == 0) {
   3026  1.3   chs 		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
   3027  1.3   chs 		    "checksum mismatch or incomplete stream.\n"
   3028  1.3   chs 		    "Partially received snapshot is saved.\n"
   3029  1.3   chs 		    "A resuming stream can be generated on the sending "
   3030  1.3   chs 		    "system by running:\n"
   3031  1.3   chs 		    "    zfs send -t %s"),
   3032  1.3   chs 		    token_buf);
   3033  1.3   chs 	}
   3034  1.3   chs 	zfs_close(zhp);
   3035  1.3   chs }
   3036  1.3   chs 
   3037  1.1  haad /*
   3038  1.1  haad  * Restores a backup of tosnap from the file descriptor specified by infd.
   3039  1.1  haad  */
   3040  1.1  haad static int
   3041  1.1  haad zfs_receive_one(libzfs_handle_t *hdl, int infd, const char *tosnap,
   3042  1.3   chs     const char *originsnap, recvflags_t *flags, dmu_replay_record_t *drr,
   3043  1.3   chs     dmu_replay_record_t *drr_noswap, const char *sendfs, nvlist_t *stream_nv,
   3044  1.3   chs     avl_tree_t *stream_avl, char **top_zfs, int cleanup_fd,
   3045  1.3   chs     uint64_t *action_handlep, const char *finalsnap)
   3046  1.1  haad {
   3047  1.1  haad 	zfs_cmd_t zc = { 0 };
   3048  1.1  haad 	time_t begin_time;
   3049  1.3   chs 	int ioctl_err, ioctl_errno, err;
   3050  1.1  haad 	char *cp;
   3051  1.1  haad 	struct drr_begin *drrb = &drr->drr_u.drr_begin;
   3052  1.1  haad 	char errbuf[1024];
   3053  1.2   dsl 	char prop_errbuf[1024];
   3054  1.3   chs 	const char *chopprefix;
   3055  1.1  haad 	boolean_t newfs = B_FALSE;
   3056  1.1  haad 	boolean_t stream_wantsnewfs;
   3057  1.1  haad 	uint64_t parent_snapguid = 0;
   3058  1.1  haad 	prop_changelist_t *clp = NULL;
   3059  1.1  haad 	nvlist_t *snapprops_nvlist = NULL;
   3060  1.2   dsl 	zprop_errflags_t prop_errflags;
   3061  1.3   chs 	boolean_t recursive;
   3062  1.3   chs 	char *snapname = NULL;
   3063  1.1  haad 
   3064  1.1  haad 	begin_time = time(NULL);
   3065  1.1  haad 
   3066  1.1  haad 	(void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
   3067  1.1  haad 	    "cannot receive"));
   3068  1.1  haad 
   3069  1.3   chs 	recursive = (nvlist_lookup_boolean(stream_nv, "not_recursive") ==
   3070  1.3   chs 	    ENOENT);
   3071  1.3   chs 
   3072  1.1  haad 	if (stream_avl != NULL) {
   3073  1.1  haad 		nvlist_t *fs = fsavl_find(stream_avl, drrb->drr_toguid,
   3074  1.1  haad 		    &snapname);
   3075  1.1  haad 		nvlist_t *props;
   3076  1.1  haad 		int ret;
   3077  1.1  haad 
   3078  1.1  haad 		(void) nvlist_lookup_uint64(fs, "parentfromsnap",
   3079  1.1  haad 		    &parent_snapguid);
   3080  1.1  haad 		err = nvlist_lookup_nvlist(fs, "props", &props);
   3081  1.1  haad 		if (err)
   3082  1.1  haad 			VERIFY(0 == nvlist_alloc(&props, NV_UNIQUE_NAME, 0));
   3083  1.1  haad 
   3084  1.3   chs 		if (flags->canmountoff) {
   3085  1.1  haad 			VERIFY(0 == nvlist_add_uint64(props,
   3086  1.1  haad 			    zfs_prop_to_name(ZFS_PROP_CANMOUNT), 0));
   3087  1.1  haad 		}
   3088  1.1  haad 		ret = zcmd_write_src_nvlist(hdl, &zc, props);
   3089  1.1  haad 		if (err)
   3090  1.1  haad 			nvlist_free(props);
   3091  1.1  haad 
   3092  1.1  haad 		if (0 == nvlist_lookup_nvlist(fs, "snapprops", &props)) {
   3093  1.1  haad 			VERIFY(0 == nvlist_lookup_nvlist(props,
   3094  1.1  haad 			    snapname, &snapprops_nvlist));
   3095  1.1  haad 		}
   3096  1.1  haad 
   3097  1.1  haad 		if (ret != 0)
   3098  1.1  haad 			return (-1);
   3099  1.1  haad 	}
   3100  1.1  haad 
   3101  1.3   chs 	cp = NULL;
   3102  1.3   chs 
   3103  1.1  haad 	/*
   3104  1.1  haad 	 * Determine how much of the snapshot name stored in the stream
   3105  1.1  haad 	 * we are going to tack on to the name they specified on the
   3106  1.1  haad 	 * command line, and how much we are going to chop off.
   3107  1.1  haad 	 *
   3108  1.1  haad 	 * If they specified a snapshot, chop the entire name stored in
   3109  1.1  haad 	 * the stream.
   3110  1.1  haad 	 */
   3111  1.3   chs 	if (flags->istail) {
   3112  1.3   chs 		/*
   3113  1.3   chs 		 * A filesystem was specified with -e. We want to tack on only
   3114  1.3   chs 		 * the tail of the sent snapshot path.
   3115  1.3   chs 		 */
   3116  1.3   chs 		if (strchr(tosnap, '@')) {
   3117  1.3   chs 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "invalid "
   3118  1.3   chs 			    "argument - snapshot not allowed with -e"));
   3119  1.3   chs 			return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf));
   3120  1.3   chs 		}
   3121  1.3   chs 
   3122  1.3   chs 		chopprefix = strrchr(sendfs, '/');
   3123  1.3   chs 
   3124  1.3   chs 		if (chopprefix == NULL) {
   3125  1.3   chs 			/*
   3126  1.3   chs 			 * The tail is the poolname, so we need to
   3127  1.3   chs 			 * prepend a path separator.
   3128  1.3   chs 			 */
   3129  1.3   chs 			int len = strlen(drrb->drr_toname);
   3130  1.3   chs 			cp = malloc(len + 2);
   3131  1.3   chs 			cp[0] = '/';
   3132  1.3   chs 			(void) strcpy(&cp[1], drrb->drr_toname);
   3133  1.3   chs 			chopprefix = cp;
   3134  1.3   chs 		} else {
   3135  1.3   chs 			chopprefix = drrb->drr_toname + (chopprefix - sendfs);
   3136  1.3   chs 		}
   3137  1.3   chs 	} else if (flags->isprefix) {
   3138  1.1  haad 		/*
   3139  1.3   chs 		 * A filesystem was specified with -d. We want to tack on
   3140  1.2   dsl 		 * everything but the first element of the sent snapshot path
   3141  1.3   chs 		 * (all but the pool name).
   3142  1.1  haad 		 */
   3143  1.1  haad 		if (strchr(tosnap, '@')) {
   3144  1.1  haad 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "invalid "
   3145  1.3   chs 			    "argument - snapshot not allowed with -d"));
   3146  1.1  haad 			return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf));
   3147  1.1  haad 		}
   3148  1.3   chs 
   3149  1.3   chs 		chopprefix = strchr(drrb->drr_toname, '/');
   3150  1.3   chs 		if (chopprefix == NULL)
   3151  1.3   chs 			chopprefix = strchr(drrb->drr_toname, '@');
   3152  1.1  haad 	} else if (strchr(tosnap, '@') == NULL) {
   3153  1.1  haad 		/*
   3154  1.3   chs 		 * If a filesystem was specified without -d or -e, we want to
   3155  1.3   chs 		 * tack on everything after the fs specified by 'zfs send'.
   3156  1.1  haad 		 */
   3157  1.3   chs 		chopprefix = drrb->drr_toname + strlen(sendfs);
   3158  1.3   chs 	} else {
   3159  1.3   chs 		/* A snapshot was specified as an exact path (no -d or -e). */
   3160  1.3   chs 		if (recursive) {
   3161  1.3   chs 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
   3162  1.3   chs 			    "cannot specify snapshot name for multi-snapshot "
   3163  1.3   chs 			    "stream"));
   3164  1.3   chs 			return (zfs_error(hdl, EZFS_BADSTREAM, errbuf));
   3165  1.3   chs 		}
   3166  1.3   chs 		chopprefix = drrb->drr_toname + strlen(drrb->drr_toname);
   3167  1.1  haad 	}
   3168  1.3   chs 
   3169  1.3   chs 	ASSERT(strstr(drrb->drr_toname, sendfs) == drrb->drr_toname);
   3170  1.3   chs 	ASSERT(chopprefix > drrb->drr_toname);
   3171  1.3   chs 	ASSERT(chopprefix <= drrb->drr_toname + strlen(drrb->drr_toname));
   3172  1.3   chs 	ASSERT(chopprefix[0] == '/' || chopprefix[0] == '@' ||
   3173  1.3   chs 	    chopprefix[0] == '\0');
   3174  1.1  haad 
   3175  1.1  haad 	/*
   3176  1.1  haad 	 * Determine name of destination snapshot, store in zc_value.
   3177  1.1  haad 	 */
   3178  1.1  haad 	(void) strcpy(zc.zc_value, tosnap);
   3179  1.3   chs 	(void) strncat(zc.zc_value, chopprefix, sizeof (zc.zc_value));
   3180  1.3   chs #ifdef __FreeBSD__
   3181  1.3   chs 	if (zfs_ioctl_version == ZFS_IOCVER_UNDEF)
   3182  1.3   chs 		zfs_ioctl_version = get_zfs_ioctl_version();
   3183  1.3   chs 	/*
   3184  1.3   chs 	 * For forward compatibility hide tosnap in zc_value
   3185  1.3   chs 	 */
   3186  1.3   chs 	if (zfs_ioctl_version < ZFS_IOCVER_LZC)
   3187  1.3   chs 		(void) strcpy(zc.zc_value + strlen(zc.zc_value) + 1, tosnap);
   3188  1.3   chs #endif
   3189  1.3   chs 	free(cp);
   3190  1.1  haad 	if (!zfs_name_valid(zc.zc_value, ZFS_TYPE_SNAPSHOT)) {
   3191  1.1  haad 		zcmd_free_nvlists(&zc);
   3192  1.1  haad 		return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf));
   3193  1.1  haad 	}
   3194  1.1  haad 
   3195  1.1  haad 	/*
   3196  1.1  haad 	 * Determine the name of the origin snapshot, store in zc_string.
   3197  1.1  haad 	 */
   3198  1.1  haad 	if (drrb->drr_flags & DRR_FLAG_CLONE) {
   3199  1.3   chs 		if (guid_to_name(hdl, zc.zc_value,
   3200  1.3   chs 		    drrb->drr_fromguid, B_FALSE, zc.zc_string) != 0) {
   3201  1.1  haad 			zcmd_free_nvlists(&zc);
   3202  1.1  haad 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
   3203  1.1  haad 			    "local origin for clone %s does not exist"),
   3204  1.1  haad 			    zc.zc_value);
   3205  1.1  haad 			return (zfs_error(hdl, EZFS_NOENT, errbuf));
   3206  1.1  haad 		}
   3207  1.3   chs 		if (flags->verbose)
   3208  1.1  haad 			(void) printf("found clone origin %s\n", zc.zc_string);
   3209  1.3   chs 	} else if (originsnap) {
   3210  1.3   chs 		(void) strncpy(zc.zc_string, originsnap, sizeof (zc.zc_string));
   3211  1.3   chs 		if (flags->verbose)
   3212  1.3   chs 			(void) printf("using provided clone origin %s\n",
   3213  1.3   chs 			    zc.zc_string);
   3214  1.1  haad 	}
   3215  1.1  haad 
   3216  1.3   chs 	boolean_t resuming = DMU_GET_FEATUREFLAGS(drrb->drr_versioninfo) &
   3217  1.3   chs 	    DMU_BACKUP_FEATURE_RESUMING;
   3218  1.2   dsl 	stream_wantsnewfs = (drrb->drr_fromguid == 0 ||
   3219  1.3   chs 	    (drrb->drr_flags & DRR_FLAG_CLONE) || originsnap) && !resuming;
   3220  1.1  haad 
   3221  1.1  haad 	if (stream_wantsnewfs) {
   3222  1.1  haad 		/*
   3223  1.1  haad 		 * if the parent fs does not exist, look for it based on
   3224  1.1  haad 		 * the parent snap GUID
   3225  1.1  haad 		 */
   3226  1.1  haad 		(void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
   3227  1.1  haad 		    "cannot receive new filesystem stream"));
   3228  1.1  haad 
   3229  1.1  haad 		(void) strcpy(zc.zc_name, zc.zc_value);
   3230  1.1  haad 		cp = strrchr(zc.zc_name, '/');
   3231  1.1  haad 		if (cp)
   3232  1.1  haad 			*cp = '\0';
   3233  1.1  haad 		if (cp &&
   3234  1.1  haad 		    !zfs_dataset_exists(hdl, zc.zc_name, ZFS_TYPE_DATASET)) {
   3235  1.3   chs 			char suffix[ZFS_MAX_DATASET_NAME_LEN];
   3236  1.1  haad 			(void) strcpy(suffix, strrchr(zc.zc_value, '/'));
   3237  1.3   chs 			if (guid_to_name(hdl, zc.zc_name, parent_snapguid,
   3238  1.3   chs 			    B_FALSE, zc.zc_value) == 0) {
   3239  1.1  haad 				*strchr(zc.zc_value, '@') = '\0';
   3240  1.1  haad 				(void) strcat(zc.zc_value, suffix);
   3241  1.1  haad 			}
   3242  1.1  haad 		}
   3243  1.1  haad 	} else {
   3244  1.1  haad 		/*
   3245  1.1  haad 		 * if the fs does not exist, look for it based on the
   3246  1.1  haad 		 * fromsnap GUID
   3247  1.1  haad 		 */
   3248  1.1  haad 		(void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
   3249  1.1  haad 		    "cannot receive incremental stream"));
   3250  1.1  haad 
   3251  1.1  haad 		(void) strcpy(zc.zc_name, zc.zc_value);
   3252  1.1  haad 		*strchr(zc.zc_name, '@') = '\0';
   3253  1.1  haad 
   3254  1.3   chs 		/*
   3255  1.3   chs 		 * If the exact receive path was specified and this is the
   3256  1.3   chs 		 * topmost path in the stream, then if the fs does not exist we
   3257  1.3   chs 		 * should look no further.
   3258  1.3   chs 		 */
   3259  1.3   chs 		if ((flags->isprefix || (*(chopprefix = drrb->drr_toname +
   3260  1.3   chs 		    strlen(sendfs)) != '\0' && *chopprefix != '@')) &&
   3261  1.3   chs 		    !zfs_dataset_exists(hdl, zc.zc_name, ZFS_TYPE_DATASET)) {
   3262  1.3   chs 			char snap[ZFS_MAX_DATASET_NAME_LEN];
   3263  1.1  haad 			(void) strcpy(snap, strchr(zc.zc_value, '@'));
   3264  1.3   chs 			if (guid_to_name(hdl, zc.zc_name, drrb->drr_fromguid,
   3265  1.3   chs 			    B_FALSE, zc.zc_value) == 0) {
   3266  1.1  haad 				*strchr(zc.zc_value, '@') = '\0';
   3267  1.1  haad 				(void) strcat(zc.zc_value, snap);
   3268  1.1  haad 			}
   3269  1.1  haad 		}
   3270  1.1  haad 	}
   3271  1.1  haad 
   3272  1.1  haad 	(void) strcpy(zc.zc_name, zc.zc_value);
   3273  1.1  haad 	*strchr(zc.zc_name, '@') = '\0';
   3274  1.1  haad 
   3275  1.1  haad 	if (zfs_dataset_exists(hdl, zc.zc_name, ZFS_TYPE_DATASET)) {
   3276  1.1  haad 		zfs_handle_t *zhp;
   3277  1.3   chs 
   3278  1.1  haad 		/*
   3279  1.3   chs 		 * Destination fs exists.  It must be one of these cases:
   3280  1.3   chs 		 *  - an incremental send stream
   3281  1.3   chs 		 *  - the stream specifies a new fs (full stream or clone)
   3282  1.3   chs 		 *    and they want us to blow away the existing fs (and
   3283  1.3   chs 		 *    have therefore specified -F and removed any snapshots)
   3284  1.3   chs 		 *  - we are resuming a failed receive.
   3285  1.1  haad 		 */
   3286  1.1  haad 		if (stream_wantsnewfs) {
   3287  1.3   chs 			if (!flags->force) {
   3288  1.1  haad 				zcmd_free_nvlists(&zc);
   3289  1.1  haad 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
   3290  1.1  haad 				    "destination '%s' exists\n"
   3291  1.1  haad 				    "must specify -F to overwrite it"),
   3292  1.1  haad 				    zc.zc_name);
   3293  1.1  haad 				return (zfs_error(hdl, EZFS_EXISTS, errbuf));
   3294  1.1  haad 			}
   3295  1.1  haad 			if (ioctl(hdl->libzfs_fd, ZFS_IOC_SNAPSHOT_LIST_NEXT,
   3296  1.1  haad 			    &zc) == 0) {
   3297  1.1  haad 				zcmd_free_nvlists(&zc);
   3298  1.1  haad 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
   3299  1.1  haad 				    "destination has snapshots (eg. %s)\n"
   3300  1.1  haad 				    "must destroy them to overwrite it"),
   3301  1.1  haad 				    zc.zc_name);
   3302  1.1  haad 				return (zfs_error(hdl, EZFS_EXISTS, errbuf));
   3303  1.1  haad 			}
   3304  1.1  haad 		}
   3305  1.1  haad 
   3306  1.1  haad 		if ((zhp = zfs_open(hdl, zc.zc_name,
   3307  1.1  haad 		    ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME)) == NULL) {
   3308  1.1  haad 			zcmd_free_nvlists(&zc);
   3309  1.1  haad 			return (-1);
   3310  1.1  haad 		}
   3311  1.1  haad 
   3312  1.1  haad 		if (stream_wantsnewfs &&
   3313  1.1  haad 		    zhp->zfs_dmustats.dds_origin[0]) {
   3314  1.1  haad 			zcmd_free_nvlists(&zc);
   3315  1.1  haad 			zfs_close(zhp);
   3316  1.1  haad 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
   3317  1.1  haad 			    "destination '%s' is a clone\n"
   3318  1.1  haad 			    "must destroy it to overwrite it"),
   3319  1.1  haad 			    zc.zc_name);
   3320  1.1  haad 			return (zfs_error(hdl, EZFS_EXISTS, errbuf));
   3321  1.1  haad 		}
   3322  1.1  haad 
   3323  1.3   chs 		if (!flags->dryrun && zhp->zfs_type == ZFS_TYPE_FILESYSTEM &&
   3324  1.1  haad 		    stream_wantsnewfs) {
   3325  1.1  haad 			/* We can't do online recv in this case */
   3326  1.1  haad 			clp = changelist_gather(zhp, ZFS_PROP_NAME, 0, 0);
   3327  1.1  haad 			if (clp == NULL) {
   3328  1.2   dsl 				zfs_close(zhp);
   3329  1.1  haad 				zcmd_free_nvlists(&zc);
   3330  1.1  haad 				return (-1);
   3331  1.1  haad 			}
   3332  1.1  haad 			if (changelist_prefix(clp) != 0) {
   3333  1.1  haad 				changelist_free(clp);
   3334  1.2   dsl 				zfs_close(zhp);
   3335  1.1  haad 				zcmd_free_nvlists(&zc);
   3336  1.1  haad 				return (-1);
   3337  1.1  haad 			}
   3338  1.1  haad 		}
   3339  1.3   chs 
   3340  1.3   chs 		/*
   3341  1.3   chs 		 * If we are resuming a newfs, set newfs here so that we will
   3342  1.3   chs 		 * mount it if the recv succeeds this time.  We can tell
   3343  1.3   chs 		 * that it was a newfs on the first recv because the fs
   3344  1.3   chs 		 * itself will be inconsistent (if the fs existed when we
   3345  1.3   chs 		 * did the first recv, we would have received it into
   3346  1.3   chs 		 * .../%recv).
   3347  1.3   chs 		 */
   3348  1.3   chs 		if (resuming && zfs_prop_get_int(zhp, ZFS_PROP_INCONSISTENT))
   3349  1.3   chs 			newfs = B_TRUE;
   3350  1.3   chs 
   3351  1.1  haad 		zfs_close(zhp);
   3352  1.1  haad 	} else {
   3353  1.1  haad 		/*
   3354  1.1  haad 		 * Destination filesystem does not exist.  Therefore we better
   3355  1.1  haad 		 * be creating a new filesystem (either from a full backup, or
   3356  1.1  haad 		 * a clone).  It would therefore be invalid if the user
   3357  1.1  haad 		 * specified only the pool name (i.e. if the destination name
   3358  1.1  haad 		 * contained no slash character).
   3359  1.1  haad 		 */
   3360  1.1  haad 		if (!stream_wantsnewfs ||
   3361  1.1  haad 		    (cp = strrchr(zc.zc_name, '/')) == NULL) {
   3362  1.1  haad 			zcmd_free_nvlists(&zc);
   3363  1.1  haad 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
   3364  1.1  haad 			    "destination '%s' does not exist"), zc.zc_name);
   3365  1.1  haad 			return (zfs_error(hdl, EZFS_NOENT, errbuf));
   3366  1.1  haad 		}
   3367  1.1  haad 
   3368  1.1  haad 		/*
   3369  1.1  haad 		 * Trim off the final dataset component so we perform the
   3370  1.1  haad 		 * recvbackup ioctl to the filesystems's parent.
   3371  1.1  haad 		 */
   3372  1.1  haad 		*cp = '\0';
   3373  1.1  haad 
   3374  1.3   chs 		if (flags->isprefix && !flags->istail && !flags->dryrun &&
   3375  1.1  haad 		    create_parents(hdl, zc.zc_value, strlen(tosnap)) != 0) {
   3376  1.1  haad 			zcmd_free_nvlists(&zc);
   3377  1.1  haad 			return (zfs_error(hdl, EZFS_BADRESTORE, errbuf));
   3378  1.1  haad 		}
   3379  1.1  haad 
   3380  1.1  haad 		newfs = B_TRUE;
   3381  1.1  haad 	}
   3382  1.1  haad 
   3383  1.3   chs 	zc.zc_begin_record = *drr_noswap;
   3384  1.1  haad 	zc.zc_cookie = infd;
   3385  1.3   chs 	zc.zc_guid = flags->force;
   3386  1.3   chs 	zc.zc_resumable = flags->resumable;
   3387  1.3   chs 	if (flags->verbose) {
   3388  1.1  haad 		(void) printf("%s %s stream of %s into %s\n",
   3389  1.3   chs 		    flags->dryrun ? "would receive" : "receiving",
   3390  1.1  haad 		    drrb->drr_fromguid ? "incremental" : "full",
   3391  1.1  haad 		    drrb->drr_toname, zc.zc_value);
   3392  1.1  haad 		(void) fflush(stdout);
   3393  1.1  haad 	}
   3394  1.1  haad 
   3395  1.3   chs 	if (flags->dryrun) {
   3396  1.1  haad 		zcmd_free_nvlists(&zc);
   3397  1.3   chs 		return (recv_skip(hdl, infd, flags->byteswap));
   3398  1.1  haad 	}
   3399  1.1  haad 
   3400  1.2   dsl 	zc.zc_nvlist_dst = (uint64_t)(uintptr_t)prop_errbuf;
   3401  1.2   dsl 	zc.zc_nvlist_dst_size = sizeof (prop_errbuf);
   3402  1.3   chs 	zc.zc_cleanup_fd = cleanup_fd;
   3403  1.3   chs 	zc.zc_action_handle = *action_handlep;
   3404  1.2   dsl 
   3405  1.1  haad 	err = ioctl_err = zfs_ioctl(hdl, ZFS_IOC_RECV, &zc);
   3406  1.1  haad 	ioctl_errno = errno;
   3407  1.2   dsl 	prop_errflags = (zprop_errflags_t)zc.zc_obj;
   3408  1.2   dsl 
   3409  1.2   dsl 	if (err == 0) {
   3410  1.2   dsl 		nvlist_t *prop_errors;
   3411  1.2   dsl 		VERIFY(0 == nvlist_unpack((void *)(uintptr_t)zc.zc_nvlist_dst,
   3412  1.2   dsl 		    zc.zc_nvlist_dst_size, &prop_errors, 0));
   3413  1.2   dsl 
   3414  1.2   dsl 		nvpair_t *prop_err = NULL;
   3415  1.2   dsl 
   3416  1.2   dsl 		while ((prop_err = nvlist_next_nvpair(prop_errors,
   3417  1.2   dsl 		    prop_err)) != NULL) {
   3418  1.2   dsl 			char tbuf[1024];
   3419  1.2   dsl 			zfs_prop_t prop;
   3420  1.2   dsl 			int intval;
   3421  1.2   dsl 
   3422  1.2   dsl 			prop = zfs_name_to_prop(nvpair_name(prop_err));
   3423  1.2   dsl 			(void) nvpair_value_int32(prop_err, &intval);
   3424  1.2   dsl 			if (strcmp(nvpair_name(prop_err),
   3425  1.2   dsl 			    ZPROP_N_MORE_ERRORS) == 0) {
   3426  1.2   dsl 				trunc_prop_errs(intval);
   3427  1.2   dsl 				break;
   3428  1.3   chs 			} else if (snapname == NULL || finalsnap == NULL ||
   3429  1.3   chs 			    strcmp(finalsnap, snapname) == 0 ||
   3430  1.3   chs 			    strcmp(nvpair_name(prop_err),
   3431  1.3   chs 			    zfs_prop_to_name(ZFS_PROP_REFQUOTA)) != 0) {
   3432  1.3   chs 				/*
   3433  1.3   chs 				 * Skip the special case of, for example,
   3434  1.3   chs 				 * "refquota", errors on intermediate
   3435  1.3   chs 				 * snapshots leading up to a final one.
   3436  1.3   chs 				 * That's why we have all of the checks above.
   3437  1.3   chs 				 *
   3438  1.3   chs 				 * See zfs_ioctl.c's extract_delay_props() for
   3439  1.3   chs 				 * a list of props which can fail on
   3440  1.3   chs 				 * intermediate snapshots, but shouldn't
   3441  1.3   chs 				 * affect the overall receive.
   3442  1.3   chs 				 */
   3443  1.2   dsl 				(void) snprintf(tbuf, sizeof (tbuf),
   3444  1.2   dsl 				    dgettext(TEXT_DOMAIN,
   3445  1.2   dsl 				    "cannot receive %s property on %s"),
   3446  1.2   dsl 				    nvpair_name(prop_err), zc.zc_name);
   3447  1.2   dsl 				zfs_setprop_error(hdl, prop, intval, tbuf);
   3448  1.2   dsl 			}
   3449  1.2   dsl 		}
   3450  1.2   dsl 		nvlist_free(prop_errors);
   3451  1.2   dsl 	}
   3452  1.2   dsl 
   3453  1.2   dsl 	zc.zc_nvlist_dst = 0;
   3454  1.2   dsl 	zc.zc_nvlist_dst_size = 0;
   3455  1.1  haad 	zcmd_free_nvlists(&zc);
   3456  1.1  haad 
   3457  1.1  haad 	if (err == 0 && snapprops_nvlist) {
   3458  1.1  haad 		zfs_cmd_t zc2 = { 0 };
   3459  1.1  haad 
   3460  1.1  haad 		(void) strcpy(zc2.zc_name, zc.zc_value);
   3461  1.2   dsl 		zc2.zc_cookie = B_TRUE; /* received */
   3462  1.1  haad 		if (zcmd_write_src_nvlist(hdl, &zc2, snapprops_nvlist) == 0) {
   3463  1.1  haad 			(void) zfs_ioctl(hdl, ZFS_IOC_SET_PROP, &zc2);
   3464  1.1  haad 			zcmd_free_nvlists(&zc2);
   3465  1.1  haad 		}
   3466  1.1  haad 	}
   3467  1.1  haad 
   3468  1.3   chs 	if (err && (ioctl_errno == ENOENT || ioctl_errno == EEXIST)) {
   3469  1.1  haad 		/*
   3470  1.1  haad 		 * It may be that this snapshot already exists,
   3471  1.1  haad 		 * in which case we want to consume & ignore it
   3472  1.1  haad 		 * rather than failing.
   3473  1.1  haad 		 */
   3474  1.1  haad 		avl_tree_t *local_avl;
   3475  1.1  haad 		nvlist_t *local_nv, *fs;
   3476  1.3   chs 		cp = strchr(zc.zc_value, '@');
   3477  1.1  haad 
   3478  1.1  haad 		/*
   3479  1.1  haad 		 * XXX Do this faster by just iterating over snaps in
   3480  1.1  haad 		 * this fs.  Also if zc_value does not exist, we will
   3481  1.1  haad 		 * get a strange "does not exist" error message.
   3482  1.1  haad 		 */
   3483  1.1  haad 		*cp = '\0';
   3484  1.2   dsl 		if (gather_nvlist(hdl, zc.zc_value, NULL, NULL, B_FALSE,
   3485  1.3   chs 		    B_FALSE, &local_nv, &local_avl) == 0) {
   3486  1.1  haad 			*cp = '@';
   3487  1.1  haad 			fs = fsavl_find(local_avl, drrb->drr_toguid, NULL);
   3488  1.1  haad 			fsavl_destroy(local_avl);
   3489  1.1  haad 			nvlist_free(local_nv);
   3490  1.1  haad 
   3491  1.1  haad 			if (fs != NULL) {
   3492  1.3   chs 				if (flags->verbose) {
   3493  1.1  haad 					(void) printf("snap %s already exists; "
   3494  1.1  haad 					    "ignoring\n", zc.zc_value);
   3495  1.1  haad 				}
   3496  1.2   dsl 				err = ioctl_err = recv_skip(hdl, infd,
   3497  1.3   chs 				    flags->byteswap);
   3498  1.1  haad 			}
   3499  1.1  haad 		}
   3500  1.1  haad 		*cp = '@';
   3501  1.1  haad 	}
   3502  1.1  haad 
   3503  1.1  haad 	if (ioctl_err != 0) {
   3504  1.1  haad 		switch (ioctl_errno) {
   3505  1.1  haad 		case ENODEV:
   3506  1.1  haad 			cp = strchr(zc.zc_value, '@');
   3507  1.1  haad 			*cp = '\0';
   3508  1.1  haad 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
   3509  1.1  haad 			    "most recent snapshot of %s does not\n"
   3510  1.1  haad 			    "match incremental source"), zc.zc_value);
   3511  1.1  haad 			(void) zfs_error(hdl, EZFS_BADRESTORE, errbuf);
   3512  1.1  haad 			*cp = '@';
   3513  1.1  haad 			break;
   3514  1.1  haad 		case ETXTBSY:
   3515  1.1  haad 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
   3516  1.1  haad 			    "destination %s has been modified\n"
   3517  1.1  haad 			    "since most recent snapshot"), zc.zc_name);
   3518  1.1  haad 			(void) zfs_error(hdl, EZFS_BADRESTORE, errbuf);
   3519  1.1  haad 			break;
   3520  1.1  haad 		case EEXIST:
   3521  1.1  haad 			cp = strchr(zc.zc_value, '@');
   3522  1.1  haad 			if (newfs) {
   3523  1.1  haad 				/* it's the containing fs that exists */
   3524  1.1  haad 				*cp = '\0';
   3525  1.1  haad 			}
   3526  1.1  haad 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
   3527  1.1  haad 			    "destination already exists"));
   3528  1.1  haad 			(void) zfs_error_fmt(hdl, EZFS_EXISTS,
   3529  1.1  haad 			    dgettext(TEXT_DOMAIN, "cannot restore to %s"),
   3530  1.1  haad 			    zc.zc_value);
   3531  1.1  haad 			*cp = '@';
   3532  1.1  haad 			break;
   3533  1.1  haad 		case EINVAL:
   3534  1.1  haad 			(void) zfs_error(hdl, EZFS_BADSTREAM, errbuf);
   3535  1.1  haad 			break;
   3536  1.1  haad 		case ECKSUM:
   3537  1.3   chs 			recv_ecksum_set_aux(hdl, zc.zc_value, flags->resumable);
   3538  1.3   chs 			(void) zfs_error(hdl, EZFS_BADSTREAM, errbuf);
   3539  1.3   chs 			break;
   3540  1.3   chs 		case ENOTSUP:
   3541  1.1  haad 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
   3542  1.3   chs 			    "pool must be upgraded to receive this stream."));
   3543  1.3   chs 			(void) zfs_error(hdl, EZFS_BADVERSION, errbuf);
   3544  1.3   chs 			break;
   3545  1.3   chs 		case EDQUOT:
   3546  1.3   chs 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
   3547  1.3   chs 			    "destination %s space quota exceeded"), zc.zc_name);
   3548  1.3   chs 			(void) zfs_error(hdl, EZFS_NOSPC, errbuf);
   3549  1.1  haad 			break;
   3550  1.1  haad 		default:
   3551  1.1  haad 			(void) zfs_standard_error(hdl, ioctl_errno, errbuf);
   3552  1.1  haad 		}
   3553  1.1  haad 	}
   3554  1.1  haad 
   3555  1.1  haad 	/*
   3556  1.2   dsl 	 * Mount the target filesystem (if created).  Also mount any
   3557  1.2   dsl 	 * children of the target filesystem if we did a replication
   3558  1.2   dsl 	 * receive (indicated by stream_avl being non-NULL).
   3559  1.1  haad 	 */
   3560  1.1  haad 	cp = strchr(zc.zc_value, '@');
   3561  1.1  haad 	if (cp && (ioctl_err == 0 || !newfs)) {
   3562  1.1  haad 		zfs_handle_t *h;
   3563  1.1  haad 
   3564  1.1  haad 		*cp = '\0';
   3565  1.1  haad 		h = zfs_open(hdl, zc.zc_value,
   3566  1.1  haad 		    ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME);
   3567  1.1  haad 		if (h != NULL) {
   3568  1.1  haad 			if (h->zfs_type == ZFS_TYPE_VOLUME) {
   3569  1.1  haad 				*cp = '@';
   3570  1.2   dsl 			} else if (newfs || stream_avl) {
   3571  1.1  haad 				/*
   3572  1.1  haad 				 * Track the first/top of hierarchy fs,
   3573  1.1  haad 				 * for mounting and sharing later.
   3574  1.1  haad 				 */
   3575  1.1  haad 				if (top_zfs && *top_zfs == NULL)
   3576  1.1  haad 					*top_zfs = zfs_strdup(hdl, zc.zc_value);
   3577  1.1  haad 			}
   3578  1.1  haad 			zfs_close(h);
   3579  1.1  haad 		}
   3580  1.1  haad 		*cp = '@';
   3581  1.1  haad 	}
   3582  1.1  haad 
   3583  1.1  haad 	if (clp) {
   3584  1.3   chs 		if (!flags->nomount)
   3585  1.3   chs 			err |= changelist_postfix(clp);
   3586  1.1  haad 		changelist_free(clp);
   3587  1.1  haad 	}
   3588  1.1  haad 
   3589  1.2   dsl 	if (prop_errflags & ZPROP_ERR_NOCLEAR) {
   3590  1.2   dsl 		(void) fprintf(stderr, dgettext(TEXT_DOMAIN, "Warning: "
   3591  1.2   dsl 		    "failed to clear unreceived properties on %s"),
   3592  1.2   dsl 		    zc.zc_name);
   3593  1.2   dsl 		(void) fprintf(stderr, "\n");
   3594  1.2   dsl 	}
   3595  1.2   dsl 	if (prop_errflags & ZPROP_ERR_NORESTORE) {
   3596  1.2   dsl 		(void) fprintf(stderr, dgettext(TEXT_DOMAIN, "Warning: "
   3597  1.2   dsl 		    "failed to restore original properties on %s"),
   3598  1.2   dsl 		    zc.zc_name);
   3599  1.2   dsl 		(void) fprintf(stderr, "\n");
   3600  1.2   dsl 	}
   3601  1.2   dsl 
   3602  1.1  haad 	if (err || ioctl_err)
   3603  1.1  haad 		return (-1);
   3604  1.1  haad 
   3605  1.3   chs 	*action_handlep = zc.zc_action_handle;
   3606  1.3   chs 
   3607  1.3   chs 	if (flags->verbose) {
   3608  1.1  haad 		char buf1[64];
   3609  1.1  haad 		char buf2[64];
   3610  1.1  haad 		uint64_t bytes = zc.zc_cookie;
   3611  1.1  haad 		time_t delta = time(NULL) - begin_time;
   3612  1.1  haad 		if (delta == 0)
   3613  1.1  haad 			delta = 1;
   3614  1.1  haad 		zfs_nicenum(bytes, buf1, sizeof (buf1));
   3615  1.1  haad 		zfs_nicenum(bytes/delta, buf2, sizeof (buf1));
   3616  1.1  haad 
   3617  1.1  haad 		(void) printf("received %sB stream in %lu seconds (%sB/sec)\n",
   3618  1.1  haad 		    buf1, delta, buf2);
   3619  1.1  haad 	}
   3620  1.1  haad 
   3621  1.1  haad 	return (0);
   3622  1.1  haad }
   3623  1.1  haad 
   3624  1.1  haad static int
   3625  1.3   chs zfs_receive_impl(libzfs_handle_t *hdl, const char *tosnap,
   3626  1.3   chs     const char *originsnap, recvflags_t *flags, int infd, const char *sendfs,
   3627  1.3   chs     nvlist_t *stream_nv, avl_tree_t *stream_avl, char **top_zfs, int cleanup_fd,
   3628  1.3   chs     uint64_t *action_handlep, const char *finalsnap)
   3629  1.1  haad {
   3630  1.1  haad 	int err;
   3631  1.1  haad 	dmu_replay_record_t drr, drr_noswap;
   3632  1.1  haad 	struct drr_begin *drrb = &drr.drr_u.drr_begin;
   3633  1.1  haad 	char errbuf[1024];
   3634  1.1  haad 	zio_cksum_t zcksum = { 0 };
   3635  1.2   dsl 	uint64_t featureflags;
   3636  1.2   dsl 	int hdrtype;
   3637  1.1  haad 
   3638  1.1  haad 	(void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
   3639  1.1  haad 	    "cannot receive"));
   3640  1.1  haad 
   3641  1.3   chs 	if (flags->isprefix &&
   3642  1.1  haad 	    !zfs_dataset_exists(hdl, tosnap, ZFS_TYPE_DATASET)) {
   3643  1.1  haad 		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "specified fs "
   3644  1.1  haad 		    "(%s) does not exist"), tosnap);
   3645  1.1  haad 		return (zfs_error(hdl, EZFS_NOENT, errbuf));
   3646  1.1  haad 	}
   3647  1.3   chs 	if (originsnap &&
   3648  1.3   chs 	    !zfs_dataset_exists(hdl, originsnap, ZFS_TYPE_DATASET)) {
   3649  1.3   chs 		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "specified origin fs "
   3650  1.3   chs 		    "(%s) does not exist"), originsnap);
   3651  1.3   chs 		return (zfs_error(hdl, EZFS_NOENT, errbuf));
   3652  1.3   chs 	}
   3653  1.1  haad 
   3654  1.1  haad 	/* read in the BEGIN record */
   3655  1.1  haad 	if (0 != (err = recv_read(hdl, infd, &drr, sizeof (drr), B_FALSE,
   3656  1.1  haad 	    &zcksum)))
   3657  1.1  haad 		return (err);
   3658  1.1  haad 
   3659  1.1  haad 	if (drr.drr_type == DRR_END || drr.drr_type == BSWAP_32(DRR_END)) {
   3660  1.1  haad 		/* It's the double end record at the end of a package */
   3661  1.1  haad 		return (ENODATA);
   3662  1.1  haad 	}
   3663  1.1  haad 
   3664  1.1  haad 	/* the kernel needs the non-byteswapped begin record */
   3665  1.1  haad 	drr_noswap = drr;
   3666  1.1  haad 
   3667  1.3   chs 	flags->byteswap = B_FALSE;
   3668  1.1  haad 	if (drrb->drr_magic == BSWAP_64(DMU_BACKUP_MAGIC)) {
   3669  1.1  haad 		/*
   3670  1.1  haad 		 * We computed the checksum in the wrong byteorder in
   3671  1.1  haad 		 * recv_read() above; do it again correctly.
   3672  1.1  haad 		 */
   3673  1.1  haad 		bzero(&zcksum, sizeof (zio_cksum_t));
   3674  1.1  haad 		fletcher_4_incremental_byteswap(&drr, sizeof (drr), &zcksum);
   3675  1.3   chs 		flags->byteswap = B_TRUE;
   3676  1.1  haad 
   3677  1.1  haad 		drr.drr_type = BSWAP_32(drr.drr_type);
   3678  1.1  haad 		drr.drr_payloadlen = BSWAP_32(drr.drr_payloadlen);
   3679  1.1  haad 		drrb->drr_magic = BSWAP_64(drrb->drr_magic);
   3680  1.2   dsl 		drrb->drr_versioninfo = BSWAP_64(drrb->drr_versioninfo);
   3681  1.1  haad 		drrb->drr_creation_time = BSWAP_64(drrb->drr_creation_time);
   3682  1.1  haad 		drrb->drr_type = BSWAP_32(drrb->drr_type);
   3683  1.1  haad 		drrb->drr_flags = BSWAP_32(drrb->drr_flags);
   3684  1.1  haad 		drrb->drr_toguid = BSWAP_64(drrb->drr_toguid);
   3685  1.1  haad 		drrb->drr_fromguid = BSWAP_64(drrb->drr_fromguid);
   3686  1.1  haad 	}
   3687  1.1  haad 
   3688  1.1  haad 	if (drrb->drr_magic != DMU_BACKUP_MAGIC || drr.drr_type != DRR_BEGIN) {
   3689  1.1  haad 		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "invalid "
   3690  1.1  haad 		    "stream (bad magic number)"));
   3691  1.1  haad 		return (zfs_error(hdl, EZFS_BADSTREAM, errbuf));
   3692  1.1  haad 	}
   3693  1.1  haad 
   3694  1.2   dsl 	featureflags = DMU_GET_FEATUREFLAGS(drrb->drr_versioninfo);
   3695  1.2   dsl 	hdrtype = DMU_GET_STREAM_HDRTYPE(drrb->drr_versioninfo);
   3696  1.2   dsl 
   3697  1.2   dsl 	if (!DMU_STREAM_SUPPORTED(featureflags) ||
   3698  1.2   dsl 	    (hdrtype != DMU_SUBSTREAM && hdrtype != DMU_COMPOUNDSTREAM)) {
   3699  1.2   dsl 		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
   3700  1.2   dsl 		    "stream has unsupported feature, feature flags = %lx"),
   3701  1.2   dsl 		    featureflags);
   3702  1.2   dsl 		return (zfs_error(hdl, EZFS_BADSTREAM, errbuf));
   3703  1.2   dsl 	}
   3704  1.2   dsl 
   3705  1.1  haad 	if (strchr(drrb->drr_toname, '@') == NULL) {
   3706  1.1  haad 		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "invalid "
   3707  1.1  haad 		    "stream (bad snapshot name)"));
   3708  1.1  haad 		return (zfs_error(hdl, EZFS_BADSTREAM, errbuf));
   3709  1.1  haad 	}
   3710  1.1  haad 
   3711  1.2   dsl 	if (DMU_GET_STREAM_HDRTYPE(drrb->drr_versioninfo) == DMU_SUBSTREAM) {
   3712  1.3   chs 		char nonpackage_sendfs[ZFS_MAX_DATASET_NAME_LEN];
   3713  1.3   chs 		if (sendfs == NULL) {
   3714  1.3   chs 			/*
   3715  1.3   chs 			 * We were not called from zfs_receive_package(). Get
   3716  1.3   chs 			 * the fs specified by 'zfs send'.
   3717  1.3   chs 			 */
   3718  1.3   chs 			char *cp;
   3719  1.3   chs 			(void) strlcpy(nonpackage_sendfs,
   3720  1.3   chs 			    drr.drr_u.drr_begin.drr_toname,
   3721  1.3   chs 			    sizeof (nonpackage_sendfs));
   3722  1.3   chs 			if ((cp = strchr(nonpackage_sendfs, '@')) != NULL)
   3723  1.3   chs 				*cp = '\0';
   3724  1.3   chs 			sendfs = nonpackage_sendfs;
   3725  1.3   chs 			VERIFY(finalsnap == NULL);
   3726  1.3   chs 		}
   3727  1.3   chs 		return (zfs_receive_one(hdl, infd, tosnap, originsnap, flags,
   3728  1.3   chs 		    &drr, &drr_noswap, sendfs, stream_nv, stream_avl, top_zfs,
   3729  1.3   chs 		    cleanup_fd, action_handlep, finalsnap));
   3730  1.3   chs 	} else {
   3731  1.2   dsl 		assert(DMU_GET_STREAM_HDRTYPE(drrb->drr_versioninfo) ==
   3732  1.2   dsl 		    DMU_COMPOUNDSTREAM);
   3733  1.3   chs 		return (zfs_receive_package(hdl, infd, tosnap, flags, &drr,
   3734  1.3   chs 		    &zcksum, top_zfs, cleanup_fd, action_handlep));
   3735  1.1  haad 	}
   3736  1.1  haad }
   3737  1.1  haad 
   3738  1.1  haad /*
   3739  1.1  haad  * Restores a backup of tosnap from the file descriptor specified by infd.
   3740  1.1  haad  * Return 0 on total success, -2 if some things couldn't be
   3741  1.1  haad  * destroyed/renamed/promoted, -1 if some things couldn't be received.
   3742  1.3   chs  * (-1 will override -2, if -1 and the resumable flag was specified the
   3743  1.3   chs  * transfer can be resumed if the sending side supports it).
   3744  1.1  haad  */
   3745  1.1  haad int
   3746  1.3   chs zfs_receive(libzfs_handle_t *hdl, const char *tosnap, nvlist_t *props,
   3747  1.3   chs     recvflags_t *flags, int infd, avl_tree_t *stream_avl)
   3748  1.1  haad {
   3749  1.1  haad 	char *top_zfs = NULL;
   3750  1.1  haad 	int err;
   3751  1.3   chs 	int cleanup_fd;
   3752  1.3   chs 	uint64_t action_handle = 0;
   3753  1.3   chs 	char *originsnap = NULL;
   3754  1.3   chs 	if (props) {
   3755  1.3   chs 		err = nvlist_lookup_string(props, "origin", &originsnap);
   3756  1.3   chs 		if (err && err != ENOENT)
   3757  1.3   chs 			return (err);
   3758  1.3   chs 	}
   3759  1.3   chs 
   3760  1.3   chs 	cleanup_fd = open(ZFS_DEV, O_RDWR|O_EXCL);
   3761  1.3   chs 	VERIFY(cleanup_fd >= 0);
   3762  1.3   chs 
   3763  1.3   chs 	err = zfs_receive_impl(hdl, tosnap, originsnap, flags, infd, NULL, NULL,
   3764  1.3   chs 	    stream_avl, &top_zfs, cleanup_fd, &action_handle, NULL);
   3765  1.1  haad 
   3766  1.3   chs 	VERIFY(0 == close(cleanup_fd));
   3767  1.1  haad 
   3768  1.3   chs 	if (err == 0 && !flags->nomount && top_zfs) {
   3769  1.1  haad 		zfs_handle_t *zhp;
   3770  1.1  haad 		prop_changelist_t *clp;
   3771  1.1  haad 
   3772  1.1  haad 		zhp = zfs_open(hdl, top_zfs, ZFS_TYPE_FILESYSTEM);
   3773  1.1  haad 		if (zhp != NULL) {
   3774  1.1  haad 			clp = changelist_gather(zhp, ZFS_PROP_MOUNTPOINT,
   3775  1.1  haad 			    CL_GATHER_MOUNT_ALWAYS, 0);
   3776  1.1  haad 			zfs_close(zhp);
   3777  1.1  haad 			if (clp != NULL) {
   3778  1.1  haad 				/* mount and share received datasets */
   3779  1.1  haad 				err = changelist_postfix(clp);
   3780  1.1  haad 				changelist_free(clp);
   3781  1.1  haad 			}
   3782  1.1  haad 		}
   3783  1.1  haad 		if (zhp == NULL || clp == NULL || err)
   3784  1.1  haad 			err = -1;
   3785  1.1  haad 	}
   3786  1.1  haad 	if (top_zfs)
   3787  1.1  haad 		free(top_zfs);
   3788  1.1  haad 
   3789  1.1  haad 	return (err);
   3790  1.1  haad }
   3791