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