]> CyberLeo.Net >> Repos - FreeBSD/stable/8.git/blob - cddl/contrib/opensolaris/lib/libzfs/common/libzfs_sendrecv.c
Copy head to stable/8 as part of 8.0 Release cycle.
[FreeBSD/stable/8.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 2008 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26
27 #include <assert.h>
28 #include <ctype.h>
29 #include <errno.h>
30 #include <libintl.h>
31 #include <stdio.h>
32 #include <stdlib.h>
33 #include <strings.h>
34 #include <unistd.h>
35 #include <stddef.h>
36 #include <fcntl.h>
37 #include <sys/param.h>
38 #include <sys/mount.h>
39 #include <sys/mntent.h>
40 #include <sys/mnttab.h>
41 #include <sys/avl.h>
42 #include <stddef.h>
43
44 #include <libzfs.h>
45
46 #include "zfs_namecheck.h"
47 #include "zfs_prop.h"
48 #include "libzfs_impl.h"
49
50 #include <fletcher.c> /* XXX */
51
52 /* We need to use something for ENODATA. */
53 #define ENODATA EIDRM
54
55 static int zfs_receive_impl(libzfs_handle_t *, const char *, recvflags_t,
56     int, avl_tree_t *, char **);
57
58 /*
59  * Routines for dealing with the AVL tree of fs-nvlists
60  */
61 typedef struct fsavl_node {
62         avl_node_t fn_node;
63         nvlist_t *fn_nvfs;
64         char *fn_snapname;
65         uint64_t fn_guid;
66 } fsavl_node_t;
67
68 static int
69 fsavl_compare(const void *arg1, const void *arg2)
70 {
71         const fsavl_node_t *fn1 = arg1;
72         const fsavl_node_t *fn2 = arg2;
73
74         if (fn1->fn_guid > fn2->fn_guid)
75                 return (+1);
76         else if (fn1->fn_guid < fn2->fn_guid)
77                 return (-1);
78         else
79                 return (0);
80 }
81
82 /*
83  * Given the GUID of a snapshot, find its containing filesystem and
84  * (optionally) name.
85  */
86 static nvlist_t *
87 fsavl_find(avl_tree_t *avl, uint64_t snapguid, char **snapname)
88 {
89         fsavl_node_t fn_find;
90         fsavl_node_t *fn;
91
92         fn_find.fn_guid = snapguid;
93
94         fn = avl_find(avl, &fn_find, NULL);
95         if (fn) {
96                 if (snapname)
97                         *snapname = fn->fn_snapname;
98                 return (fn->fn_nvfs);
99         }
100         return (NULL);
101 }
102
103 static void
104 fsavl_destroy(avl_tree_t *avl)
105 {
106         fsavl_node_t *fn;
107         void *cookie;
108
109         if (avl == NULL)
110                 return;
111
112         cookie = NULL;
113         while ((fn = avl_destroy_nodes(avl, &cookie)) != NULL)
114                 free(fn);
115         avl_destroy(avl);
116         free(avl);
117 }
118
119 static avl_tree_t *
120 fsavl_create(nvlist_t *fss)
121 {
122         avl_tree_t *fsavl;
123         nvpair_t *fselem = NULL;
124
125         if ((fsavl = malloc(sizeof (avl_tree_t))) == NULL)
126                 return (NULL);
127
128         avl_create(fsavl, fsavl_compare, sizeof (fsavl_node_t),
129             offsetof(fsavl_node_t, fn_node));
130
131         while ((fselem = nvlist_next_nvpair(fss, fselem)) != NULL) {
132                 nvlist_t *nvfs, *snaps;
133                 nvpair_t *snapelem = NULL;
134
135                 VERIFY(0 == nvpair_value_nvlist(fselem, &nvfs));
136                 VERIFY(0 == nvlist_lookup_nvlist(nvfs, "snaps", &snaps));
137
138                 while ((snapelem =
139                     nvlist_next_nvpair(snaps, snapelem)) != NULL) {
140                         fsavl_node_t *fn;
141                         uint64_t guid;
142
143                         VERIFY(0 == nvpair_value_uint64(snapelem, &guid));
144                         if ((fn = malloc(sizeof (fsavl_node_t))) == NULL) {
145                                 fsavl_destroy(fsavl);
146                                 return (NULL);
147                         }
148                         fn->fn_nvfs = nvfs;
149                         fn->fn_snapname = nvpair_name(snapelem);
150                         fn->fn_guid = guid;
151
152                         /*
153                          * Note: if there are multiple snaps with the
154                          * same GUID, we ignore all but one.
155                          */
156                         if (avl_find(fsavl, fn, NULL) == NULL)
157                                 avl_add(fsavl, fn);
158                         else
159                                 free(fn);
160                 }
161         }
162
163         return (fsavl);
164 }
165
166 /*
167  * Routines for dealing with the giant nvlist of fs-nvlists, etc.
168  */
169 typedef struct send_data {
170         uint64_t parent_fromsnap_guid;
171         nvlist_t *parent_snaps;
172         nvlist_t *fss;
173         nvlist_t *snapprops;
174         const char *fromsnap;
175         const char *tosnap;
176
177         /*
178          * The header nvlist is of the following format:
179          * {
180          *   "tosnap" -> string
181          *   "fromsnap" -> string (if incremental)
182          *   "fss" -> {
183          *      id -> {
184          *
185          *       "name" -> string (full name; for debugging)
186          *       "parentfromsnap" -> number (guid of fromsnap in parent)
187          *
188          *       "props" -> { name -> value (only if set here) }
189          *       "snaps" -> { name (lastname) -> number (guid) }
190          *       "snapprops" -> { name (lastname) -> { name -> value } }
191          *
192          *       "origin" -> number (guid) (if clone)
193          *       "sent" -> boolean (not on-disk)
194          *      }
195          *   }
196          * }
197          *
198          */
199 } send_data_t;
200
201 static void send_iterate_prop(zfs_handle_t *zhp, nvlist_t *nv);
202
203 static int
204 send_iterate_snap(zfs_handle_t *zhp, void *arg)
205 {
206         send_data_t *sd = arg;
207         uint64_t guid = zhp->zfs_dmustats.dds_guid;
208         char *snapname;
209         nvlist_t *nv;
210
211         snapname = strrchr(zhp->zfs_name, '@')+1;
212
213         VERIFY(0 == nvlist_add_uint64(sd->parent_snaps, snapname, guid));
214         /*
215          * NB: if there is no fromsnap here (it's a newly created fs in
216          * an incremental replication), we will substitute the tosnap.
217          */
218         if ((sd->fromsnap && strcmp(snapname, sd->fromsnap) == 0) ||
219             (sd->parent_fromsnap_guid == 0 && sd->tosnap &&
220             strcmp(snapname, sd->tosnap) == 0)) {
221                 sd->parent_fromsnap_guid = guid;
222         }
223
224         VERIFY(0 == nvlist_alloc(&nv, NV_UNIQUE_NAME, 0));
225         send_iterate_prop(zhp, nv);
226         VERIFY(0 == nvlist_add_nvlist(sd->snapprops, snapname, nv));
227         nvlist_free(nv);
228
229         zfs_close(zhp);
230         return (0);
231 }
232
233 static void
234 send_iterate_prop(zfs_handle_t *zhp, nvlist_t *nv)
235 {
236         nvpair_t *elem = NULL;
237
238         while ((elem = nvlist_next_nvpair(zhp->zfs_props, elem)) != NULL) {
239                 char *propname = nvpair_name(elem);
240                 zfs_prop_t prop = zfs_name_to_prop(propname);
241                 nvlist_t *propnv;
242
243                 if (!zfs_prop_user(propname) && zfs_prop_readonly(prop))
244                         continue;
245
246                 verify(nvpair_value_nvlist(elem, &propnv) == 0);
247                 if (prop == ZFS_PROP_QUOTA || prop == ZFS_PROP_RESERVATION) {
248                         /* these guys are modifyable, but have no source */
249                         uint64_t value;
250                         verify(nvlist_lookup_uint64(propnv,
251                             ZPROP_VALUE, &value) == 0);
252                         if (zhp->zfs_type == ZFS_TYPE_SNAPSHOT)
253                                 continue;
254                 } else {
255                         char *source;
256                         if (nvlist_lookup_string(propnv,
257                             ZPROP_SOURCE, &source) != 0)
258                                 continue;
259                         if (strcmp(source, zhp->zfs_name) != 0)
260                                 continue;
261                 }
262
263                 if (zfs_prop_user(propname) ||
264                     zfs_prop_get_type(prop) == PROP_TYPE_STRING) {
265                         char *value;
266                         verify(nvlist_lookup_string(propnv,
267                             ZPROP_VALUE, &value) == 0);
268                         VERIFY(0 == nvlist_add_string(nv, propname, value));
269                 } else {
270                         uint64_t value;
271                         verify(nvlist_lookup_uint64(propnv,
272                             ZPROP_VALUE, &value) == 0);
273                         VERIFY(0 == nvlist_add_uint64(nv, propname, value));
274                 }
275         }
276 }
277
278 static int
279 send_iterate_fs(zfs_handle_t *zhp, void *arg)
280 {
281         send_data_t *sd = arg;
282         nvlist_t *nvfs, *nv;
283         int rv;
284         uint64_t parent_fromsnap_guid_save = sd->parent_fromsnap_guid;
285         uint64_t guid = zhp->zfs_dmustats.dds_guid;
286         char guidstring[64];
287
288         VERIFY(0 == nvlist_alloc(&nvfs, NV_UNIQUE_NAME, 0));
289         VERIFY(0 == nvlist_add_string(nvfs, "name", zhp->zfs_name));
290         VERIFY(0 == nvlist_add_uint64(nvfs, "parentfromsnap",
291             sd->parent_fromsnap_guid));
292
293         if (zhp->zfs_dmustats.dds_origin[0]) {
294                 zfs_handle_t *origin = zfs_open(zhp->zfs_hdl,
295                     zhp->zfs_dmustats.dds_origin, ZFS_TYPE_SNAPSHOT);
296                 if (origin == NULL)
297                         return (-1);
298                 VERIFY(0 == nvlist_add_uint64(nvfs, "origin",
299                     origin->zfs_dmustats.dds_guid));
300         }
301
302         /* iterate over props */
303         VERIFY(0 == nvlist_alloc(&nv, NV_UNIQUE_NAME, 0));
304         send_iterate_prop(zhp, nv);
305         VERIFY(0 == nvlist_add_nvlist(nvfs, "props", nv));
306         nvlist_free(nv);
307
308         /* iterate over snaps, and set sd->parent_fromsnap_guid */
309         sd->parent_fromsnap_guid = 0;
310         VERIFY(0 == nvlist_alloc(&sd->parent_snaps, NV_UNIQUE_NAME, 0));
311         VERIFY(0 == nvlist_alloc(&sd->snapprops, NV_UNIQUE_NAME, 0));
312         (void) zfs_iter_snapshots(zhp, send_iterate_snap, sd);
313         VERIFY(0 == nvlist_add_nvlist(nvfs, "snaps", sd->parent_snaps));
314         VERIFY(0 == nvlist_add_nvlist(nvfs, "snapprops", sd->snapprops));
315         nvlist_free(sd->parent_snaps);
316         nvlist_free(sd->snapprops);
317
318         /* add this fs to nvlist */
319         (void) snprintf(guidstring, sizeof (guidstring),
320             "0x%llx", (longlong_t)guid);
321         VERIFY(0 == nvlist_add_nvlist(sd->fss, guidstring, nvfs));
322         nvlist_free(nvfs);
323
324         /* iterate over children */
325         rv = zfs_iter_filesystems(zhp, send_iterate_fs, sd);
326
327         sd->parent_fromsnap_guid = parent_fromsnap_guid_save;
328
329         zfs_close(zhp);
330         return (rv);
331 }
332
333 static int
334 gather_nvlist(libzfs_handle_t *hdl, const char *fsname, const char *fromsnap,
335     const char *tosnap, nvlist_t **nvlp, avl_tree_t **avlp)
336 {
337         zfs_handle_t *zhp;
338         send_data_t sd = { 0 };
339         int error;
340
341         zhp = zfs_open(hdl, fsname, ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME);
342         if (zhp == NULL)
343                 return (EZFS_BADTYPE);
344
345         VERIFY(0 == nvlist_alloc(&sd.fss, NV_UNIQUE_NAME, 0));
346         sd.fromsnap = fromsnap;
347         sd.tosnap = tosnap;
348
349         if ((error = send_iterate_fs(zhp, &sd)) != 0) {
350                 nvlist_free(sd.fss);
351                 if (avlp != NULL)
352                         *avlp = NULL;
353                 *nvlp = NULL;
354                 return (error);
355         }
356
357         if (avlp != NULL && (*avlp = fsavl_create(sd.fss)) == NULL) {
358                 nvlist_free(sd.fss);
359                 *nvlp = NULL;
360                 return (EZFS_NOMEM);
361         }
362
363         *nvlp = sd.fss;
364         return (0);
365 }
366
367 /*
368  * Routines for dealing with the sorted snapshot functionality
369  */
370 typedef struct zfs_node {
371         zfs_handle_t    *zn_handle;
372         avl_node_t      zn_avlnode;
373 } zfs_node_t;
374
375 static int
376 zfs_sort_snaps(zfs_handle_t *zhp, void *data)
377 {
378         avl_tree_t *avl = data;
379         zfs_node_t *node = zfs_alloc(zhp->zfs_hdl, sizeof (zfs_node_t));
380
381         node->zn_handle = zhp;
382         avl_add(avl, node);
383         return (0);
384 }
385
386 /* ARGSUSED */
387 static int
388 zfs_snapshot_compare(const void *larg, const void *rarg)
389 {
390         zfs_handle_t *l = ((zfs_node_t *)larg)->zn_handle;
391         zfs_handle_t *r = ((zfs_node_t *)rarg)->zn_handle;
392         uint64_t lcreate, rcreate;
393
394         /*
395          * Sort them according to creation time.  We use the hidden
396          * CREATETXG property to get an absolute ordering of snapshots.
397          */
398         lcreate = zfs_prop_get_int(l, ZFS_PROP_CREATETXG);
399         rcreate = zfs_prop_get_int(r, ZFS_PROP_CREATETXG);
400
401         if (lcreate < rcreate)
402                 return (-1);
403         else if (lcreate > rcreate)
404                 return (+1);
405         else
406                 return (0);
407 }
408
409 static int
410 zfs_iter_snapshots_sorted(zfs_handle_t *zhp, zfs_iter_f callback, void *data)
411 {
412         int ret = 0;
413         zfs_node_t *node;
414         avl_tree_t avl;
415         void *cookie = NULL;
416
417         avl_create(&avl, zfs_snapshot_compare,
418             sizeof (zfs_node_t), offsetof(zfs_node_t, zn_avlnode));
419
420         ret = zfs_iter_snapshots(zhp, zfs_sort_snaps, &avl);
421
422         for (node = avl_first(&avl); node != NULL; node = AVL_NEXT(&avl, node))
423                 ret |= callback(node->zn_handle, data);
424
425         while ((node = avl_destroy_nodes(&avl, &cookie)) != NULL)
426                 free(node);
427
428         avl_destroy(&avl);
429
430         return (ret);
431 }
432
433 /*
434  * Routines specific to "zfs send"
435  */
436 typedef struct send_dump_data {
437         /* these are all just the short snapname (the part after the @) */
438         const char *fromsnap;
439         const char *tosnap;
440         char lastsnap[ZFS_MAXNAMELEN];
441         boolean_t seenfrom, seento, replicate, doall, fromorigin;
442         boolean_t verbose;
443         int outfd;
444         boolean_t err;
445         nvlist_t *fss;
446         avl_tree_t *fsavl;
447 } send_dump_data_t;
448
449 /*
450  * Dumps a backup of the given snapshot (incremental from fromsnap if it's not
451  * NULL) to the file descriptor specified by outfd.
452  */
453 static int
454 dump_ioctl(zfs_handle_t *zhp, const char *fromsnap, boolean_t fromorigin,
455     int outfd)
456 {
457         zfs_cmd_t zc = { 0 };
458         libzfs_handle_t *hdl = zhp->zfs_hdl;
459
460         assert(zhp->zfs_type == ZFS_TYPE_SNAPSHOT);
461         assert(fromsnap == NULL || fromsnap[0] == '\0' || !fromorigin);
462
463         (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
464         if (fromsnap)
465                 (void) strlcpy(zc.zc_value, fromsnap, sizeof (zc.zc_value));
466         zc.zc_cookie = outfd;
467         zc.zc_obj = fromorigin;
468
469         if (ioctl(zhp->zfs_hdl->libzfs_fd, ZFS_IOC_SEND, &zc) != 0) {
470                 char errbuf[1024];
471                 (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
472                     "warning: cannot send '%s'"), zhp->zfs_name);
473
474                 switch (errno) {
475
476                 case EXDEV:
477                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
478                             "not an earlier snapshot from the same fs"));
479                         return (zfs_error(hdl, EZFS_CROSSTARGET, errbuf));
480
481                 case ENOENT:
482                         if (zfs_dataset_exists(hdl, zc.zc_name,
483                             ZFS_TYPE_SNAPSHOT)) {
484                                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
485                                     "incremental source (@%s) does not exist"),
486                                     zc.zc_value);
487                         }
488                         return (zfs_error(hdl, EZFS_NOENT, errbuf));
489
490                 case EDQUOT:
491                 case EFBIG:
492                 case EIO:
493                 case ENOLINK:
494                 case ENOSPC:
495                 case ENXIO:
496                 case EPIPE:
497                 case ERANGE:
498                 case EFAULT:
499                 case EROFS:
500                         zfs_error_aux(hdl, strerror(errno));
501                         return (zfs_error(hdl, EZFS_BADBACKUP, errbuf));
502
503                 default:
504                         return (zfs_standard_error(hdl, errno, errbuf));
505                 }
506         }
507
508         return (0);
509 }
510
511 static int
512 dump_snapshot(zfs_handle_t *zhp, void *arg)
513 {
514         send_dump_data_t *sdd = arg;
515         const char *thissnap;
516         int err;
517
518         thissnap = strchr(zhp->zfs_name, '@') + 1;
519
520         if (sdd->fromsnap && !sdd->seenfrom &&
521             strcmp(sdd->fromsnap, thissnap) == 0) {
522                 sdd->seenfrom = B_TRUE;
523                 (void) strcpy(sdd->lastsnap, thissnap);
524                 zfs_close(zhp);
525                 return (0);
526         }
527
528         if (sdd->seento || !sdd->seenfrom) {
529                 zfs_close(zhp);
530                 return (0);
531         }
532
533         /* send it */
534         if (sdd->verbose) {
535                 (void) fprintf(stderr, "sending from @%s to %s\n",
536                     sdd->lastsnap, zhp->zfs_name);
537         }
538
539         err = dump_ioctl(zhp, sdd->lastsnap,
540             sdd->lastsnap[0] == '\0' && (sdd->fromorigin || sdd->replicate),
541             sdd->outfd);
542
543         if (!sdd->seento && strcmp(sdd->tosnap, thissnap) == 0)
544                 sdd->seento = B_TRUE;
545
546         (void) strcpy(sdd->lastsnap, thissnap);
547         zfs_close(zhp);
548         return (err);
549 }
550
551 static int
552 dump_filesystem(zfs_handle_t *zhp, void *arg)
553 {
554         int rv = 0;
555         send_dump_data_t *sdd = arg;
556         boolean_t missingfrom = B_FALSE;
557         zfs_cmd_t zc = { 0 };
558
559         (void) snprintf(zc.zc_name, sizeof (zc.zc_name), "%s@%s",
560             zhp->zfs_name, sdd->tosnap);
561         if (ioctl(zhp->zfs_hdl->libzfs_fd, ZFS_IOC_OBJSET_STATS, &zc) != 0) {
562                 (void) fprintf(stderr, "WARNING: "
563                     "could not send %s@%s: does not exist\n",
564                     zhp->zfs_name, sdd->tosnap);
565                 sdd->err = B_TRUE;
566                 return (0);
567         }
568
569         if (sdd->replicate && sdd->fromsnap) {
570                 /*
571                  * If this fs does not have fromsnap, and we're doing
572                  * recursive, we need to send a full stream from the
573                  * beginning (or an incremental from the origin if this
574                  * is a clone).  If we're doing non-recursive, then let
575                  * them get the error.
576                  */
577                 (void) snprintf(zc.zc_name, sizeof (zc.zc_name), "%s@%s",
578                     zhp->zfs_name, sdd->fromsnap);
579                 if (ioctl(zhp->zfs_hdl->libzfs_fd,
580                     ZFS_IOC_OBJSET_STATS, &zc) != 0) {
581                         missingfrom = B_TRUE;
582                 }
583         }
584
585         if (sdd->doall) {
586                 sdd->seenfrom = sdd->seento = sdd->lastsnap[0] = 0;
587                 if (sdd->fromsnap == NULL || missingfrom)
588                         sdd->seenfrom = B_TRUE;
589
590                 rv = zfs_iter_snapshots_sorted(zhp, dump_snapshot, arg);
591                 if (!sdd->seenfrom) {
592                         (void) fprintf(stderr,
593                             "WARNING: could not send %s@%s:\n"
594                             "incremental source (%s@%s) does not exist\n",
595                             zhp->zfs_name, sdd->tosnap,
596                             zhp->zfs_name, sdd->fromsnap);
597                         sdd->err = B_TRUE;
598                 } else if (!sdd->seento) {
599                         (void) fprintf(stderr,
600                             "WARNING: could not send %s@%s:\n"
601                             "incremental source (%s@%s) "
602                             "is not earlier than it\n",
603                             zhp->zfs_name, sdd->tosnap,
604                             zhp->zfs_name, sdd->fromsnap);
605                         sdd->err = B_TRUE;
606                 }
607         } else {
608                 zfs_handle_t *snapzhp;
609                 char snapname[ZFS_MAXNAMELEN];
610
611                 (void) snprintf(snapname, sizeof (snapname), "%s@%s",
612                     zfs_get_name(zhp), sdd->tosnap);
613                 snapzhp = zfs_open(zhp->zfs_hdl, snapname, ZFS_TYPE_SNAPSHOT);
614                 if (snapzhp == NULL) {
615                         rv = -1;
616                 } else {
617                         rv = dump_ioctl(snapzhp,
618                             missingfrom ? NULL : sdd->fromsnap,
619                             sdd->fromorigin || missingfrom,
620                             sdd->outfd);
621                         sdd->seento = B_TRUE;
622                         zfs_close(snapzhp);
623                 }
624         }
625
626         return (rv);
627 }
628
629 static int
630 dump_filesystems(zfs_handle_t *rzhp, void *arg)
631 {
632         send_dump_data_t *sdd = arg;
633         nvpair_t *fspair;
634         boolean_t needagain, progress;
635
636         if (!sdd->replicate)
637                 return (dump_filesystem(rzhp, sdd));
638
639 again:
640         needagain = progress = B_FALSE;
641         for (fspair = nvlist_next_nvpair(sdd->fss, NULL); fspair;
642             fspair = nvlist_next_nvpair(sdd->fss, fspair)) {
643                 nvlist_t *fslist;
644                 char *fsname;
645                 zfs_handle_t *zhp;
646                 int err;
647                 uint64_t origin_guid = 0;
648                 nvlist_t *origin_nv;
649
650                 VERIFY(nvpair_value_nvlist(fspair, &fslist) == 0);
651                 if (nvlist_lookup_boolean(fslist, "sent") == 0)
652                         continue;
653
654                 VERIFY(nvlist_lookup_string(fslist, "name", &fsname) == 0);
655                 (void) nvlist_lookup_uint64(fslist, "origin", &origin_guid);
656
657                 origin_nv = fsavl_find(sdd->fsavl, origin_guid, NULL);
658                 if (origin_nv &&
659                     nvlist_lookup_boolean(origin_nv, "sent") == ENOENT) {
660                         /*
661                          * origin has not been sent yet;
662                          * skip this clone.
663                          */
664                         needagain = B_TRUE;
665                         continue;
666                 }
667
668                 zhp = zfs_open(rzhp->zfs_hdl, fsname, ZFS_TYPE_DATASET);
669                 if (zhp == NULL)
670                         return (-1);
671                 err = dump_filesystem(zhp, sdd);
672                 VERIFY(nvlist_add_boolean(fslist, "sent") == 0);
673                 progress = B_TRUE;
674                 zfs_close(zhp);
675                 if (err)
676                         return (err);
677         }
678         if (needagain) {
679                 assert(progress);
680                 goto again;
681         }
682         return (0);
683 }
684
685 /*
686  * Dumps a backup of tosnap, incremental from fromsnap if it isn't NULL.
687  * If 'doall', dump all intermediate snaps.
688  * If 'replicate', dump special header and do recursively.
689  */
690 int
691 zfs_send(zfs_handle_t *zhp, const char *fromsnap, const char *tosnap,
692     boolean_t replicate, boolean_t doall, boolean_t fromorigin,
693     boolean_t verbose, int outfd)
694 {
695         char errbuf[1024];
696         send_dump_data_t sdd = { 0 };
697         int err;
698         nvlist_t *fss = NULL;
699         avl_tree_t *fsavl = NULL;
700
701         (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
702             "cannot send '%s'"), zhp->zfs_name);
703
704         if (fromsnap && fromsnap[0] == '\0') {
705                 zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN,
706                     "zero-length incremental source"));
707                 return (zfs_error(zhp->zfs_hdl, EZFS_NOENT, errbuf));
708         }
709
710         if (replicate || doall) {
711                 dmu_replay_record_t drr = { 0 };
712                 char *packbuf = NULL;
713                 size_t buflen = 0;
714                 zio_cksum_t zc = { 0 };
715
716                 assert(fromsnap || doall);
717
718                 if (replicate) {
719                         nvlist_t *hdrnv;
720
721                         VERIFY(0 == nvlist_alloc(&hdrnv, NV_UNIQUE_NAME, 0));
722                         if (fromsnap) {
723                                 VERIFY(0 == nvlist_add_string(hdrnv,
724                                     "fromsnap", fromsnap));
725                         }
726                         VERIFY(0 == nvlist_add_string(hdrnv, "tosnap", tosnap));
727
728                         err = gather_nvlist(zhp->zfs_hdl, zhp->zfs_name,
729                             fromsnap, tosnap, &fss, &fsavl);
730                         if (err)
731                                 return (err);
732                         VERIFY(0 == nvlist_add_nvlist(hdrnv, "fss", fss));
733                         err = nvlist_pack(hdrnv, &packbuf, &buflen,
734                             NV_ENCODE_XDR, 0);
735                         nvlist_free(hdrnv);
736                         if (err) {
737                                 fsavl_destroy(fsavl);
738                                 nvlist_free(fss);
739                                 return (zfs_standard_error(zhp->zfs_hdl,
740                                     err, errbuf));
741                         }
742                 }
743
744                 /* write first begin record */
745                 drr.drr_type = DRR_BEGIN;
746                 drr.drr_u.drr_begin.drr_magic = DMU_BACKUP_MAGIC;
747                 drr.drr_u.drr_begin.drr_version = DMU_BACKUP_HEADER_VERSION;
748                 (void) snprintf(drr.drr_u.drr_begin.drr_toname,
749                     sizeof (drr.drr_u.drr_begin.drr_toname),
750                     "%s@%s", zhp->zfs_name, tosnap);
751                 drr.drr_payloadlen = buflen;
752                 fletcher_4_incremental_native(&drr, sizeof (drr), &zc);
753                 err = write(outfd, &drr, sizeof (drr));
754
755                 /* write header nvlist */
756                 if (err != -1) {
757                         fletcher_4_incremental_native(packbuf, buflen, &zc);
758                         err = write(outfd, packbuf, buflen);
759                 }
760                 free(packbuf);
761                 if (err == -1) {
762                         fsavl_destroy(fsavl);
763                         nvlist_free(fss);
764                         return (zfs_standard_error(zhp->zfs_hdl,
765                             errno, errbuf));
766                 }
767
768                 /* write end record */
769                 if (err != -1) {
770                         bzero(&drr, sizeof (drr));
771                         drr.drr_type = DRR_END;
772                         drr.drr_u.drr_end.drr_checksum = zc;
773                         err = write(outfd, &drr, sizeof (drr));
774                         if (err == -1) {
775                                 fsavl_destroy(fsavl);
776                                 nvlist_free(fss);
777                                 return (zfs_standard_error(zhp->zfs_hdl,
778                                     errno, errbuf));
779                         }
780                 }
781         }
782
783         /* dump each stream */
784         sdd.fromsnap = fromsnap;
785         sdd.tosnap = tosnap;
786         sdd.outfd = outfd;
787         sdd.replicate = replicate;
788         sdd.doall = doall;
789         sdd.fromorigin = fromorigin;
790         sdd.fss = fss;
791         sdd.fsavl = fsavl;
792         sdd.verbose = verbose;
793         err = dump_filesystems(zhp, &sdd);
794         fsavl_destroy(fsavl);
795         nvlist_free(fss);
796
797         if (replicate || doall) {
798                 /*
799                  * write final end record.  NB: want to do this even if
800                  * there was some error, because it might not be totally
801                  * failed.
802                  */
803                 dmu_replay_record_t drr = { 0 };
804                 drr.drr_type = DRR_END;
805                 if (write(outfd, &drr, sizeof (drr)) == -1) {
806                         return (zfs_standard_error(zhp->zfs_hdl,
807                             errno, errbuf));
808                 }
809         }
810
811         return (err || sdd.err);
812 }
813
814 /*
815  * Routines specific to "zfs recv"
816  */
817
818 static int
819 recv_read(libzfs_handle_t *hdl, int fd, void *buf, int ilen,
820     boolean_t byteswap, zio_cksum_t *zc)
821 {
822         char *cp = buf;
823         int rv;
824         int len = ilen;
825
826         do {
827                 rv = read(fd, cp, len);
828                 cp += rv;
829                 len -= rv;
830         } while (rv > 0);
831
832         if (rv < 0 || len != 0) {
833                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
834                     "failed to read from stream"));
835                 return (zfs_error(hdl, EZFS_BADSTREAM, dgettext(TEXT_DOMAIN,
836                     "cannot receive")));
837         }
838
839         if (zc) {
840                 if (byteswap)
841                         fletcher_4_incremental_byteswap(buf, ilen, zc);
842                 else
843                         fletcher_4_incremental_native(buf, ilen, zc);
844         }
845         return (0);
846 }
847
848 static int
849 recv_read_nvlist(libzfs_handle_t *hdl, int fd, int len, nvlist_t **nvp,
850     boolean_t byteswap, zio_cksum_t *zc)
851 {
852         char *buf;
853         int err;
854
855         buf = zfs_alloc(hdl, len);
856         if (buf == NULL)
857                 return (ENOMEM);
858
859         err = recv_read(hdl, fd, buf, len, byteswap, zc);
860         if (err != 0) {
861                 free(buf);
862                 return (err);
863         }
864
865         err = nvlist_unpack(buf, len, nvp, 0);
866         free(buf);
867         if (err != 0) {
868                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "invalid "
869                     "stream (malformed nvlist)"));
870                 return (EINVAL);
871         }
872         return (0);
873 }
874
875 static int
876 recv_rename(libzfs_handle_t *hdl, const char *name, const char *tryname,
877     int baselen, char *newname, recvflags_t flags)
878 {
879         static int seq;
880         zfs_cmd_t zc = { 0 };
881         int err;
882         prop_changelist_t *clp;
883         zfs_handle_t *zhp;
884
885         zhp = zfs_open(hdl, name, ZFS_TYPE_DATASET);
886         if (zhp == NULL)
887                 return (-1);
888         clp = changelist_gather(zhp, ZFS_PROP_NAME, 0,
889             flags.force ? MS_FORCE : 0);
890         zfs_close(zhp);
891         if (clp == NULL)
892                 return (-1);
893         err = changelist_prefix(clp);
894         if (err)
895                 return (err);
896
897         if (tryname) {
898                 (void) strcpy(newname, tryname);
899
900                 zc.zc_objset_type = DMU_OST_ZFS;
901                 (void) strlcpy(zc.zc_name, name, sizeof (zc.zc_name));
902                 (void) strlcpy(zc.zc_value, tryname, sizeof (zc.zc_value));
903
904                 if (flags.verbose) {
905                         (void) printf("attempting rename %s to %s\n",
906                             zc.zc_name, zc.zc_value);
907                 }
908                 err = ioctl(hdl->libzfs_fd, ZFS_IOC_RENAME, &zc);
909                 if (err == 0)
910                         changelist_rename(clp, name, tryname);
911         } else {
912                 err = ENOENT;
913         }
914
915         if (err != 0 && strncmp(name+baselen, "recv-", 5) != 0) {
916                 seq++;
917
918                 (void) strncpy(newname, name, baselen);
919                 (void) snprintf(newname+baselen, ZFS_MAXNAMELEN-baselen,
920                     "recv-%u-%u", getpid(), seq);
921                 (void) strlcpy(zc.zc_value, newname, sizeof (zc.zc_value));
922
923                 if (flags.verbose) {
924                         (void) printf("failed - trying rename %s to %s\n",
925                             zc.zc_name, zc.zc_value);
926                 }
927                 err = ioctl(hdl->libzfs_fd, ZFS_IOC_RENAME, &zc);
928                 if (err == 0)
929                         changelist_rename(clp, name, newname);
930                 if (err && flags.verbose) {
931                         (void) printf("failed (%u) - "
932                             "will try again on next pass\n", errno);
933                 }
934                 err = EAGAIN;
935         } else if (flags.verbose) {
936                 if (err == 0)
937                         (void) printf("success\n");
938                 else
939                         (void) printf("failed (%u)\n", errno);
940         }
941
942         (void) changelist_postfix(clp);
943         changelist_free(clp);
944
945         return (err);
946 }
947
948 static int
949 recv_destroy(libzfs_handle_t *hdl, const char *name, int baselen,
950     char *newname, recvflags_t flags)
951 {
952         zfs_cmd_t zc = { 0 };
953         int err = 0;
954         prop_changelist_t *clp;
955         zfs_handle_t *zhp;
956
957         zhp = zfs_open(hdl, name, ZFS_TYPE_DATASET);
958         if (zhp == NULL)
959                 return (-1);
960         clp = changelist_gather(zhp, ZFS_PROP_NAME, 0,
961             flags.force ? MS_FORCE : 0);
962         zfs_close(zhp);
963         if (clp == NULL)
964                 return (-1);
965         err = changelist_prefix(clp);
966         if (err)
967                 return (err);
968
969         zc.zc_objset_type = DMU_OST_ZFS;
970         (void) strlcpy(zc.zc_name, name, sizeof (zc.zc_name));
971
972         if (flags.verbose)
973                 (void) printf("attempting destroy %s\n", zc.zc_name);
974         err = ioctl(hdl->libzfs_fd, ZFS_IOC_DESTROY, &zc);
975
976         if (err == 0) {
977                 if (flags.verbose)
978                         (void) printf("success\n");
979                 changelist_remove(clp, zc.zc_name);
980         }
981
982         (void) changelist_postfix(clp);
983         changelist_free(clp);
984
985         if (err != 0)
986                 err = recv_rename(hdl, name, NULL, baselen, newname, flags);
987
988         return (err);
989 }
990
991 typedef struct guid_to_name_data {
992         uint64_t guid;
993         char *name;
994 } guid_to_name_data_t;
995
996 static int
997 guid_to_name_cb(zfs_handle_t *zhp, void *arg)
998 {
999         guid_to_name_data_t *gtnd = arg;
1000         int err;
1001
1002         if (zhp->zfs_dmustats.dds_guid == gtnd->guid) {
1003                 (void) strcpy(gtnd->name, zhp->zfs_name);
1004                 return (EEXIST);
1005         }
1006         err = zfs_iter_children(zhp, guid_to_name_cb, gtnd);
1007         zfs_close(zhp);
1008         return (err);
1009 }
1010
1011 static int
1012 guid_to_name(libzfs_handle_t *hdl, const char *parent, uint64_t guid,
1013     char *name)
1014 {
1015         /* exhaustive search all local snapshots */
1016         guid_to_name_data_t gtnd;
1017         int err = 0;
1018         zfs_handle_t *zhp;
1019         char *cp;
1020
1021         gtnd.guid = guid;
1022         gtnd.name = name;
1023
1024         if (strchr(parent, '@') == NULL) {
1025                 zhp = make_dataset_handle(hdl, parent);
1026                 if (zhp != NULL) {
1027                         err = zfs_iter_children(zhp, guid_to_name_cb, &gtnd);
1028                         zfs_close(zhp);
1029                         if (err == EEXIST)
1030                                 return (0);
1031                 }
1032         }
1033
1034         cp = strchr(parent, '/');
1035         if (cp)
1036                 *cp = '\0';
1037         zhp = make_dataset_handle(hdl, parent);
1038         if (cp)
1039                 *cp = '/';
1040
1041         if (zhp) {
1042                 err = zfs_iter_children(zhp, guid_to_name_cb, &gtnd);
1043                 zfs_close(zhp);
1044         }
1045
1046         return (err == EEXIST ? 0 : ENOENT);
1047
1048 }
1049
1050 /*
1051  * Return true if dataset guid1 is created before guid2.
1052  */
1053 static int
1054 created_before(libzfs_handle_t *hdl, avl_tree_t *avl,
1055     uint64_t guid1, uint64_t guid2)
1056 {
1057         nvlist_t *nvfs;
1058         char *fsname, *snapname;
1059         char buf[ZFS_MAXNAMELEN];
1060         int rv;
1061         zfs_node_t zn1, zn2;
1062
1063         if (guid2 == 0)
1064                 return (0);
1065         if (guid1 == 0)
1066                 return (1);
1067
1068         nvfs = fsavl_find(avl, guid1, &snapname);
1069         VERIFY(0 == nvlist_lookup_string(nvfs, "name", &fsname));
1070         (void) snprintf(buf, sizeof (buf), "%s@%s", fsname, snapname);
1071         zn1.zn_handle = zfs_open(hdl, buf, ZFS_TYPE_SNAPSHOT);
1072         if (zn1.zn_handle == NULL)
1073                 return (-1);
1074
1075         nvfs = fsavl_find(avl, guid2, &snapname);
1076         VERIFY(0 == nvlist_lookup_string(nvfs, "name", &fsname));
1077         (void) snprintf(buf, sizeof (buf), "%s@%s", fsname, snapname);
1078         zn2.zn_handle = zfs_open(hdl, buf, ZFS_TYPE_SNAPSHOT);
1079         if (zn2.zn_handle == NULL) {
1080                 zfs_close(zn2.zn_handle);
1081                 return (-1);
1082         }
1083
1084         rv = (zfs_snapshot_compare(&zn1, &zn2) == -1);
1085
1086         zfs_close(zn1.zn_handle);
1087         zfs_close(zn2.zn_handle);
1088
1089         return (rv);
1090 }
1091
1092 static int
1093 recv_incremental_replication(libzfs_handle_t *hdl, const char *tofs,
1094     recvflags_t flags, nvlist_t *stream_nv, avl_tree_t *stream_avl)
1095 {
1096         nvlist_t *local_nv;
1097         avl_tree_t *local_avl;
1098         nvpair_t *fselem, *nextfselem;
1099         char *tosnap, *fromsnap;
1100         char newname[ZFS_MAXNAMELEN];
1101         int error;
1102         boolean_t needagain, progress;
1103
1104         VERIFY(0 == nvlist_lookup_string(stream_nv, "fromsnap", &fromsnap));
1105         VERIFY(0 == nvlist_lookup_string(stream_nv, "tosnap", &tosnap));
1106
1107         if (flags.dryrun)
1108                 return (0);
1109
1110 again:
1111         needagain = progress = B_FALSE;
1112
1113         if ((error = gather_nvlist(hdl, tofs, fromsnap, NULL,
1114             &local_nv, &local_avl)) != 0)
1115                 return (error);
1116
1117         /*
1118          * Process deletes and renames
1119          */
1120         for (fselem = nvlist_next_nvpair(local_nv, NULL);
1121             fselem; fselem = nextfselem) {
1122                 nvlist_t *nvfs, *snaps;
1123                 nvlist_t *stream_nvfs = NULL;
1124                 nvpair_t *snapelem, *nextsnapelem;
1125                 uint64_t fromguid = 0;
1126                 uint64_t originguid = 0;
1127                 uint64_t stream_originguid = 0;
1128                 uint64_t parent_fromsnap_guid, stream_parent_fromsnap_guid;
1129                 char *fsname, *stream_fsname;
1130
1131                 nextfselem = nvlist_next_nvpair(local_nv, fselem);
1132
1133                 VERIFY(0 == nvpair_value_nvlist(fselem, &nvfs));
1134                 VERIFY(0 == nvlist_lookup_nvlist(nvfs, "snaps", &snaps));
1135                 VERIFY(0 == nvlist_lookup_string(nvfs, "name", &fsname));
1136                 VERIFY(0 == nvlist_lookup_uint64(nvfs, "parentfromsnap",
1137                     &parent_fromsnap_guid));
1138                 (void) nvlist_lookup_uint64(nvfs, "origin", &originguid);
1139
1140                 /*
1141                  * First find the stream's fs, so we can check for
1142                  * a different origin (due to "zfs promote")
1143                  */
1144                 for (snapelem = nvlist_next_nvpair(snaps, NULL);
1145                     snapelem; snapelem = nvlist_next_nvpair(snaps, snapelem)) {
1146                         uint64_t thisguid;
1147
1148                         VERIFY(0 == nvpair_value_uint64(snapelem, &thisguid));
1149                         stream_nvfs = fsavl_find(stream_avl, thisguid, NULL);
1150
1151                         if (stream_nvfs != NULL)
1152                                 break;
1153                 }
1154
1155                 /* check for promote */
1156                 (void) nvlist_lookup_uint64(stream_nvfs, "origin",
1157                     &stream_originguid);
1158                 if (stream_nvfs && originguid != stream_originguid) {
1159                         switch (created_before(hdl, local_avl,
1160                             stream_originguid, originguid)) {
1161                         case 1: {
1162                                 /* promote it! */
1163                                 zfs_cmd_t zc = { 0 };
1164                                 nvlist_t *origin_nvfs;
1165                                 char *origin_fsname;
1166
1167                                 if (flags.verbose)
1168                                         (void) printf("promoting %s\n", fsname);
1169
1170                                 origin_nvfs = fsavl_find(local_avl, originguid,
1171                                     NULL);
1172                                 VERIFY(0 == nvlist_lookup_string(origin_nvfs,
1173                                     "name", &origin_fsname));
1174                                 (void) strlcpy(zc.zc_value, origin_fsname,
1175                                     sizeof (zc.zc_value));
1176                                 (void) strlcpy(zc.zc_name, fsname,
1177                                     sizeof (zc.zc_name));
1178                                 error = zfs_ioctl(hdl, ZFS_IOC_PROMOTE, &zc);
1179                                 if (error == 0)
1180                                         progress = B_TRUE;
1181                                 break;
1182                         }
1183                         default:
1184                                 break;
1185                         case -1:
1186                                 fsavl_destroy(local_avl);
1187                                 nvlist_free(local_nv);
1188                                 return (-1);
1189                         }
1190                         /*
1191                          * We had/have the wrong origin, therefore our
1192                          * list of snapshots is wrong.  Need to handle
1193                          * them on the next pass.
1194                          */
1195                         needagain = B_TRUE;
1196                         continue;
1197                 }
1198
1199                 for (snapelem = nvlist_next_nvpair(snaps, NULL);
1200                     snapelem; snapelem = nextsnapelem) {
1201                         uint64_t thisguid;
1202                         char *stream_snapname;
1203                         nvlist_t *found, *props;
1204
1205                         nextsnapelem = nvlist_next_nvpair(snaps, snapelem);
1206
1207                         VERIFY(0 == nvpair_value_uint64(snapelem, &thisguid));
1208                         found = fsavl_find(stream_avl, thisguid,
1209                             &stream_snapname);
1210
1211                         /* check for delete */
1212                         if (found == NULL) {
1213                                 char name[ZFS_MAXNAMELEN];
1214
1215                                 if (!flags.force)
1216                                         continue;
1217
1218                                 (void) snprintf(name, sizeof (name), "%s@%s",
1219                                     fsname, nvpair_name(snapelem));
1220
1221                                 error = recv_destroy(hdl, name,
1222                                     strlen(fsname)+1, newname, flags);
1223                                 if (error)
1224                                         needagain = B_TRUE;
1225                                 else
1226                                         progress = B_TRUE;
1227                                 continue;
1228                         }
1229
1230                         stream_nvfs = found;
1231
1232                         if (0 == nvlist_lookup_nvlist(stream_nvfs, "snapprops",
1233                             &props) && 0 == nvlist_lookup_nvlist(props,
1234                             stream_snapname, &props)) {
1235                                 zfs_cmd_t zc = { 0 };
1236
1237                                 zc.zc_cookie = B_TRUE; /* clear current props */
1238                                 (void) snprintf(zc.zc_name, sizeof (zc.zc_name),
1239                                     "%s@%s", fsname, nvpair_name(snapelem));
1240                                 if (zcmd_write_src_nvlist(hdl, &zc,
1241                                     props) == 0) {
1242                                         (void) zfs_ioctl(hdl,
1243                                             ZFS_IOC_SET_PROP, &zc);
1244                                         zcmd_free_nvlists(&zc);
1245                                 }
1246                         }
1247
1248                         /* check for different snapname */
1249                         if (strcmp(nvpair_name(snapelem),
1250                             stream_snapname) != 0) {
1251                                 char name[ZFS_MAXNAMELEN];
1252                                 char tryname[ZFS_MAXNAMELEN];
1253
1254                                 (void) snprintf(name, sizeof (name), "%s@%s",
1255                                     fsname, nvpair_name(snapelem));
1256                                 (void) snprintf(tryname, sizeof (name), "%s@%s",
1257                                     fsname, stream_snapname);
1258
1259                                 error = recv_rename(hdl, name, tryname,
1260                                     strlen(fsname)+1, newname, flags);
1261                                 if (error)
1262                                         needagain = B_TRUE;
1263                                 else
1264                                         progress = B_TRUE;
1265                         }
1266
1267                         if (strcmp(stream_snapname, fromsnap) == 0)
1268                                 fromguid = thisguid;
1269                 }
1270
1271                 /* check for delete */
1272                 if (stream_nvfs == NULL) {
1273                         if (!flags.force)
1274                                 continue;
1275
1276                         error = recv_destroy(hdl, fsname, strlen(tofs)+1,
1277                             newname, flags);
1278                         if (error)
1279                                 needagain = B_TRUE;
1280                         else
1281                                 progress = B_TRUE;
1282                         continue;
1283                 }
1284
1285                 if (fromguid == 0 && flags.verbose) {
1286                         (void) printf("local fs %s does not have fromsnap "
1287                             "(%s in stream); must have been deleted locally; "
1288                             "ignoring\n", fsname, fromsnap);
1289                         continue;
1290                 }
1291
1292                 VERIFY(0 == nvlist_lookup_string(stream_nvfs,
1293                     "name", &stream_fsname));
1294                 VERIFY(0 == nvlist_lookup_uint64(stream_nvfs,
1295                     "parentfromsnap", &stream_parent_fromsnap_guid));
1296
1297                 /* check for rename */
1298                 if ((stream_parent_fromsnap_guid != 0 &&
1299                     stream_parent_fromsnap_guid != parent_fromsnap_guid) ||
1300                     strcmp(strrchr(fsname, '/'),
1301                     strrchr(stream_fsname, '/')) != 0) {
1302                         nvlist_t *parent;
1303                         char tryname[ZFS_MAXNAMELEN];
1304
1305                         parent = fsavl_find(local_avl,
1306                             stream_parent_fromsnap_guid, NULL);
1307                         /*
1308                          * NB: parent might not be found if we used the
1309                          * tosnap for stream_parent_fromsnap_guid,
1310                          * because the parent is a newly-created fs;
1311                          * we'll be able to rename it after we recv the
1312                          * new fs.
1313                          */
1314                         if (parent != NULL) {
1315                                 char *pname;
1316
1317                                 VERIFY(0 == nvlist_lookup_string(parent, "name",
1318                                     &pname));
1319                                 (void) snprintf(tryname, sizeof (tryname),
1320                                     "%s%s", pname, strrchr(stream_fsname, '/'));
1321                         } else {
1322                                 tryname[0] = '\0';
1323                                 if (flags.verbose) {
1324                                         (void) printf("local fs %s new parent "
1325                                             "not found\n", fsname);
1326                                 }
1327                         }
1328
1329                         error = recv_rename(hdl, fsname, tryname,
1330                             strlen(tofs)+1, newname, flags);
1331                         if (error)
1332                                 needagain = B_TRUE;
1333                         else
1334                                 progress = B_TRUE;
1335                 }
1336         }
1337
1338         fsavl_destroy(local_avl);
1339         nvlist_free(local_nv);
1340
1341         if (needagain && progress) {
1342                 /* do another pass to fix up temporary names */
1343                 if (flags.verbose)
1344                         (void) printf("another pass:\n");
1345                 goto again;
1346         }
1347
1348         return (needagain);
1349 }
1350
1351 static int
1352 zfs_receive_package(libzfs_handle_t *hdl, int fd, const char *destname,
1353     recvflags_t flags, dmu_replay_record_t *drr, zio_cksum_t *zc,
1354     char **top_zfs)
1355 {
1356         nvlist_t *stream_nv = NULL;
1357         avl_tree_t *stream_avl = NULL;
1358         char *fromsnap = NULL;
1359         char tofs[ZFS_MAXNAMELEN];
1360         char errbuf[1024];
1361         dmu_replay_record_t drre;
1362         int error;
1363         boolean_t anyerr = B_FALSE;
1364         boolean_t softerr = B_FALSE;
1365
1366         (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
1367             "cannot receive"));
1368
1369         if (strchr(destname, '@')) {
1370                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1371                     "can not specify snapshot name for multi-snapshot stream"));
1372                 return (zfs_error(hdl, EZFS_BADSTREAM, errbuf));
1373         }
1374
1375         assert(drr->drr_type == DRR_BEGIN);
1376         assert(drr->drr_u.drr_begin.drr_magic == DMU_BACKUP_MAGIC);
1377         assert(drr->drr_u.drr_begin.drr_version == DMU_BACKUP_HEADER_VERSION);
1378
1379         /*
1380          * Read in the nvlist from the stream.
1381          */
1382         if (drr->drr_payloadlen != 0) {
1383                 if (!flags.isprefix) {
1384                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1385                             "must use -d to receive replication "
1386                             "(send -R) stream"));
1387                         return (zfs_error(hdl, EZFS_BADSTREAM, errbuf));
1388                 }
1389
1390                 error = recv_read_nvlist(hdl, fd, drr->drr_payloadlen,
1391                     &stream_nv, flags.byteswap, zc);
1392                 if (error) {
1393                         error = zfs_error(hdl, EZFS_BADSTREAM, errbuf);
1394                         goto out;
1395                 }
1396         }
1397
1398         /*
1399          * Read in the end record and verify checksum.
1400          */
1401         if (0 != (error = recv_read(hdl, fd, &drre, sizeof (drre),
1402             flags.byteswap, NULL)))
1403                 goto out;
1404         if (flags.byteswap) {
1405                 drre.drr_type = BSWAP_32(drre.drr_type);
1406                 drre.drr_u.drr_end.drr_checksum.zc_word[0] =
1407                     BSWAP_64(drre.drr_u.drr_end.drr_checksum.zc_word[0]);
1408                 drre.drr_u.drr_end.drr_checksum.zc_word[1] =
1409                     BSWAP_64(drre.drr_u.drr_end.drr_checksum.zc_word[1]);
1410                 drre.drr_u.drr_end.drr_checksum.zc_word[2] =
1411                     BSWAP_64(drre.drr_u.drr_end.drr_checksum.zc_word[2]);
1412                 drre.drr_u.drr_end.drr_checksum.zc_word[3] =
1413                     BSWAP_64(drre.drr_u.drr_end.drr_checksum.zc_word[3]);
1414         }
1415         if (drre.drr_type != DRR_END) {
1416                 error = zfs_error(hdl, EZFS_BADSTREAM, errbuf);
1417                 goto out;
1418         }
1419         if (!ZIO_CHECKSUM_EQUAL(drre.drr_u.drr_end.drr_checksum, *zc)) {
1420                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1421                     "incorrect header checksum"));
1422                 error = zfs_error(hdl, EZFS_BADSTREAM, errbuf);
1423                 goto out;
1424         }
1425
1426         (void) nvlist_lookup_string(stream_nv, "fromsnap", &fromsnap);
1427
1428         if (drr->drr_payloadlen != 0) {
1429                 nvlist_t *stream_fss;
1430
1431                 VERIFY(0 == nvlist_lookup_nvlist(stream_nv, "fss",
1432                     &stream_fss));
1433                 if ((stream_avl = fsavl_create(stream_fss)) == NULL) {
1434                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1435                             "couldn't allocate avl tree"));
1436                         error = zfs_error(hdl, EZFS_NOMEM, errbuf);
1437                         goto out;
1438                 }
1439
1440                 if (fromsnap != NULL) {
1441                         (void) strlcpy(tofs, destname, ZFS_MAXNAMELEN);
1442                         if (flags.isprefix) {
1443                                 int i = strcspn(drr->drr_u.drr_begin.drr_toname,
1444                                     "/@");
1445                                 /* zfs_receive_one() will create_parents() */
1446                                 (void) strlcat(tofs,
1447                                     &drr->drr_u.drr_begin.drr_toname[i],
1448                                     ZFS_MAXNAMELEN);
1449                                 *strchr(tofs, '@') = '\0';
1450                         }
1451                         softerr = recv_incremental_replication(hdl, tofs,
1452                             flags, stream_nv, stream_avl);
1453                 }
1454         }
1455
1456
1457         /* Finally, receive each contained stream */
1458         do {
1459                 /*
1460                  * we should figure out if it has a recoverable
1461                  * error, in which case do a recv_skip() and drive on.
1462                  * Note, if we fail due to already having this guid,
1463                  * zfs_receive_one() will take care of it (ie,
1464                  * recv_skip() and return 0).
1465                  */
1466                 error = zfs_receive_impl(hdl, destname, flags, fd,
1467                     stream_avl, top_zfs);
1468                 if (error == ENODATA) {
1469                         error = 0;
1470                         break;
1471                 }
1472                 anyerr |= error;
1473         } while (error == 0);
1474
1475         if (drr->drr_payloadlen != 0 && fromsnap != NULL) {
1476                 /*
1477                  * Now that we have the fs's they sent us, try the
1478                  * renames again.
1479                  */
1480                 softerr = recv_incremental_replication(hdl, tofs, flags,
1481                     stream_nv, stream_avl);
1482         }
1483
1484 out:
1485         fsavl_destroy(stream_avl);
1486         if (stream_nv)
1487                 nvlist_free(stream_nv);
1488         if (softerr)
1489                 error = -2;
1490         if (anyerr)
1491                 error = -1;
1492         return (error);
1493 }
1494
1495 static int
1496 recv_skip(libzfs_handle_t *hdl, int fd, boolean_t byteswap)
1497 {
1498         dmu_replay_record_t *drr;
1499         void *buf = malloc(1<<20);
1500
1501         /* XXX would be great to use lseek if possible... */
1502         drr = buf;
1503
1504         while (recv_read(hdl, fd, drr, sizeof (dmu_replay_record_t),
1505             byteswap, NULL) == 0) {
1506                 if (byteswap)
1507                         drr->drr_type = BSWAP_32(drr->drr_type);
1508
1509                 switch (drr->drr_type) {
1510                 case DRR_BEGIN:
1511                         /* NB: not to be used on v2 stream packages */
1512                         assert(drr->drr_payloadlen == 0);
1513                         break;
1514
1515                 case DRR_END:
1516                         free(buf);
1517                         return (0);
1518
1519                 case DRR_OBJECT:
1520                         if (byteswap) {
1521                                 drr->drr_u.drr_object.drr_bonuslen =
1522                                     BSWAP_32(drr->drr_u.drr_object.
1523                                     drr_bonuslen);
1524                         }
1525                         (void) recv_read(hdl, fd, buf,
1526                             P2ROUNDUP(drr->drr_u.drr_object.drr_bonuslen, 8),
1527                             B_FALSE, NULL);
1528                         break;
1529
1530                 case DRR_WRITE:
1531                         if (byteswap) {
1532                                 drr->drr_u.drr_write.drr_length =
1533                                     BSWAP_64(drr->drr_u.drr_write.drr_length);
1534                         }
1535                         (void) recv_read(hdl, fd, buf,
1536                             drr->drr_u.drr_write.drr_length, B_FALSE, NULL);
1537                         break;
1538
1539                 case DRR_FREEOBJECTS:
1540                 case DRR_FREE:
1541                         break;
1542
1543                 default:
1544                         assert(!"invalid record type");
1545                 }
1546         }
1547
1548         free(buf);
1549         return (-1);
1550 }
1551
1552 /*
1553  * Restores a backup of tosnap from the file descriptor specified by infd.
1554  */
1555 static int
1556 zfs_receive_one(libzfs_handle_t *hdl, int infd, const char *tosnap,
1557     recvflags_t flags, dmu_replay_record_t *drr,
1558     dmu_replay_record_t *drr_noswap, avl_tree_t *stream_avl,
1559     char **top_zfs)
1560 {
1561         zfs_cmd_t zc = { 0 };
1562         time_t begin_time;
1563         int ioctl_err, ioctl_errno, err, choplen;
1564         char *cp;
1565         struct drr_begin *drrb = &drr->drr_u.drr_begin;
1566         char errbuf[1024];
1567         char chopprefix[ZFS_MAXNAMELEN];
1568         boolean_t newfs = B_FALSE;
1569         boolean_t stream_wantsnewfs;
1570         uint64_t parent_snapguid = 0;
1571         prop_changelist_t *clp = NULL;
1572         nvlist_t *snapprops_nvlist = NULL;
1573
1574         begin_time = time(NULL);
1575
1576         (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
1577             "cannot receive"));
1578
1579         if (stream_avl != NULL) {
1580                 char *snapname;
1581                 nvlist_t *fs = fsavl_find(stream_avl, drrb->drr_toguid,
1582                     &snapname);
1583                 nvlist_t *props;
1584                 int ret;
1585
1586                 (void) nvlist_lookup_uint64(fs, "parentfromsnap",
1587                     &parent_snapguid);
1588                 err = nvlist_lookup_nvlist(fs, "props", &props);
1589                 if (err)
1590                         VERIFY(0 == nvlist_alloc(&props, NV_UNIQUE_NAME, 0));
1591
1592                 if (flags.canmountoff) {
1593                         VERIFY(0 == nvlist_add_uint64(props,
1594                             zfs_prop_to_name(ZFS_PROP_CANMOUNT), 0));
1595                 }
1596                 ret = zcmd_write_src_nvlist(hdl, &zc, props);
1597                 if (err)
1598                         nvlist_free(props);
1599
1600                 if (0 == nvlist_lookup_nvlist(fs, "snapprops", &props)) {
1601                         VERIFY(0 == nvlist_lookup_nvlist(props,
1602                             snapname, &snapprops_nvlist));
1603                 }
1604
1605                 if (ret != 0)
1606                         return (-1);
1607         }
1608
1609         /*
1610          * Determine how much of the snapshot name stored in the stream
1611          * we are going to tack on to the name they specified on the
1612          * command line, and how much we are going to chop off.
1613          *
1614          * If they specified a snapshot, chop the entire name stored in
1615          * the stream.
1616          */
1617         (void) strcpy(chopprefix, drrb->drr_toname);
1618         if (flags.isprefix) {
1619                 /*
1620                  * They specified a fs with -d, we want to tack on
1621                  * everything but the pool name stored in the stream
1622                  */
1623                 if (strchr(tosnap, '@')) {
1624                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "invalid "
1625                             "argument - snapshot not allowed with -d"));
1626                         return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf));
1627                 }
1628                 cp = strchr(chopprefix, '/');
1629                 if (cp == NULL)
1630                         cp = strchr(chopprefix, '@');
1631                 *cp = '\0';
1632         } else if (strchr(tosnap, '@') == NULL) {
1633                 /*
1634                  * If they specified a filesystem without -d, we want to
1635                  * tack on everything after the fs specified in the
1636                  * first name from the stream.
1637                  */
1638                 cp = strchr(chopprefix, '@');
1639                 *cp = '\0';
1640         }
1641         choplen = strlen(chopprefix);
1642
1643         /*
1644          * Determine name of destination snapshot, store in zc_value.
1645          */
1646         (void) strcpy(zc.zc_value, tosnap);
1647         (void) strncat(zc.zc_value, drrb->drr_toname+choplen,
1648             sizeof (zc.zc_value));
1649         if (!zfs_name_valid(zc.zc_value, ZFS_TYPE_SNAPSHOT)) {
1650                 zcmd_free_nvlists(&zc);
1651                 return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf));
1652         }
1653
1654         /*
1655          * Determine the name of the origin snapshot, store in zc_string.
1656          */
1657         if (drrb->drr_flags & DRR_FLAG_CLONE) {
1658                 if (guid_to_name(hdl, tosnap,
1659                     drrb->drr_fromguid, zc.zc_string) != 0) {
1660                         zcmd_free_nvlists(&zc);
1661                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1662                             "local origin for clone %s does not exist"),
1663                             zc.zc_value);
1664                         return (zfs_error(hdl, EZFS_NOENT, errbuf));
1665                 }
1666                 if (flags.verbose)
1667                         (void) printf("found clone origin %s\n", zc.zc_string);
1668         }
1669
1670         stream_wantsnewfs = (drrb->drr_fromguid == 0 ||
1671             (drrb->drr_flags & DRR_FLAG_CLONE));
1672
1673         if (stream_wantsnewfs) {
1674                 /*
1675                  * if the parent fs does not exist, look for it based on
1676                  * the parent snap GUID
1677                  */
1678                 (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
1679                     "cannot receive new filesystem stream"));
1680
1681                 (void) strcpy(zc.zc_name, zc.zc_value);
1682                 cp = strrchr(zc.zc_name, '/');
1683                 if (cp)
1684                         *cp = '\0';
1685                 if (cp &&
1686                     !zfs_dataset_exists(hdl, zc.zc_name, ZFS_TYPE_DATASET)) {
1687                         char suffix[ZFS_MAXNAMELEN];
1688                         (void) strcpy(suffix, strrchr(zc.zc_value, '/'));
1689                         if (guid_to_name(hdl, tosnap, parent_snapguid,
1690                             zc.zc_value) == 0) {
1691                                 *strchr(zc.zc_value, '@') = '\0';
1692                                 (void) strcat(zc.zc_value, suffix);
1693                         }
1694                 }
1695         } else {
1696                 /*
1697                  * if the fs does not exist, look for it based on the
1698                  * fromsnap GUID
1699                  */
1700                 (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
1701                     "cannot receive incremental stream"));
1702
1703                 (void) strcpy(zc.zc_name, zc.zc_value);
1704                 *strchr(zc.zc_name, '@') = '\0';
1705
1706                 if (!zfs_dataset_exists(hdl, zc.zc_name, ZFS_TYPE_DATASET)) {
1707                         char snap[ZFS_MAXNAMELEN];
1708                         (void) strcpy(snap, strchr(zc.zc_value, '@'));
1709                         if (guid_to_name(hdl, tosnap, drrb->drr_fromguid,
1710                             zc.zc_value) == 0) {
1711                                 *strchr(zc.zc_value, '@') = '\0';
1712                                 (void) strcat(zc.zc_value, snap);
1713                         }
1714                 }
1715         }
1716
1717         (void) strcpy(zc.zc_name, zc.zc_value);
1718         *strchr(zc.zc_name, '@') = '\0';
1719
1720         if (zfs_dataset_exists(hdl, zc.zc_name, ZFS_TYPE_DATASET)) {
1721                 zfs_handle_t *zhp;
1722                 /*
1723                  * Destination fs exists.  Therefore this should either
1724                  * be an incremental, or the stream specifies a new fs
1725                  * (full stream or clone) and they want us to blow it
1726                  * away (and have therefore specified -F and removed any
1727                  * snapshots).
1728                  */
1729
1730                 if (stream_wantsnewfs) {
1731                         if (!flags.force) {
1732                                 zcmd_free_nvlists(&zc);
1733                                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1734                                     "destination '%s' exists\n"
1735                                     "must specify -F to overwrite it"),
1736                                     zc.zc_name);
1737                                 return (zfs_error(hdl, EZFS_EXISTS, errbuf));
1738                         }
1739                         if (ioctl(hdl->libzfs_fd, ZFS_IOC_SNAPSHOT_LIST_NEXT,
1740                             &zc) == 0) {
1741                                 zcmd_free_nvlists(&zc);
1742                                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1743                                     "destination has snapshots (eg. %s)\n"
1744                                     "must destroy them to overwrite it"),
1745                                     zc.zc_name);
1746                                 return (zfs_error(hdl, EZFS_EXISTS, errbuf));
1747                         }
1748                 }
1749
1750                 if ((zhp = zfs_open(hdl, zc.zc_name,
1751                     ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME)) == NULL) {
1752                         zcmd_free_nvlists(&zc);
1753                         return (-1);
1754                 }
1755
1756                 if (stream_wantsnewfs &&
1757                     zhp->zfs_dmustats.dds_origin[0]) {
1758                         zcmd_free_nvlists(&zc);
1759                         zfs_close(zhp);
1760                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1761                             "destination '%s' is a clone\n"
1762                             "must destroy it to overwrite it"),
1763                             zc.zc_name);
1764                         return (zfs_error(hdl, EZFS_EXISTS, errbuf));
1765                 }
1766
1767                 if (!flags.dryrun && zhp->zfs_type == ZFS_TYPE_FILESYSTEM &&
1768                     stream_wantsnewfs) {
1769                         /* We can't do online recv in this case */
1770                         clp = changelist_gather(zhp, ZFS_PROP_NAME, 0, 0);
1771                         if (clp == NULL) {
1772                                 zcmd_free_nvlists(&zc);
1773                                 return (-1);
1774                         }
1775                         if (changelist_prefix(clp) != 0) {
1776                                 changelist_free(clp);
1777                                 zcmd_free_nvlists(&zc);
1778                                 return (-1);
1779                         }
1780                 }
1781                 if (!flags.dryrun && zhp->zfs_type == ZFS_TYPE_VOLUME &&
1782                     zvol_remove_link(hdl, zhp->zfs_name) != 0) {
1783                         zfs_close(zhp);
1784                         zcmd_free_nvlists(&zc);
1785                         return (-1);
1786                 }
1787                 zfs_close(zhp);
1788         } else {
1789                 /*
1790                  * Destination filesystem does not exist.  Therefore we better
1791                  * be creating a new filesystem (either from a full backup, or
1792                  * a clone).  It would therefore be invalid if the user
1793                  * specified only the pool name (i.e. if the destination name
1794                  * contained no slash character).
1795                  */
1796                 if (!stream_wantsnewfs ||
1797                     (cp = strrchr(zc.zc_name, '/')) == NULL) {
1798                         zcmd_free_nvlists(&zc);
1799                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1800                             "destination '%s' does not exist"), zc.zc_name);
1801                         return (zfs_error(hdl, EZFS_NOENT, errbuf));
1802                 }
1803
1804                 /*
1805                  * Trim off the final dataset component so we perform the
1806                  * recvbackup ioctl to the filesystems's parent.
1807                  */
1808                 *cp = '\0';
1809
1810                 if (flags.isprefix && !flags.dryrun &&
1811                     create_parents(hdl, zc.zc_value, strlen(tosnap)) != 0) {
1812                         zcmd_free_nvlists(&zc);
1813                         return (zfs_error(hdl, EZFS_BADRESTORE, errbuf));
1814                 }
1815
1816                 newfs = B_TRUE;
1817         }
1818
1819         zc.zc_begin_record = drr_noswap->drr_u.drr_begin;
1820         zc.zc_cookie = infd;
1821         zc.zc_guid = flags.force;
1822         if (flags.verbose) {
1823                 (void) printf("%s %s stream of %s into %s\n",
1824                     flags.dryrun ? "would receive" : "receiving",
1825                     drrb->drr_fromguid ? "incremental" : "full",
1826                     drrb->drr_toname, zc.zc_value);
1827                 (void) fflush(stdout);
1828         }
1829
1830         if (flags.dryrun) {
1831                 zcmd_free_nvlists(&zc);
1832                 return (recv_skip(hdl, infd, flags.byteswap));
1833         }
1834
1835         err = ioctl_err = zfs_ioctl(hdl, ZFS_IOC_RECV, &zc);
1836         ioctl_errno = errno;
1837         zcmd_free_nvlists(&zc);
1838
1839         if (err == 0 && snapprops_nvlist) {
1840                 zfs_cmd_t zc2 = { 0 };
1841
1842                 (void) strcpy(zc2.zc_name, zc.zc_value);
1843                 if (zcmd_write_src_nvlist(hdl, &zc2, snapprops_nvlist) == 0) {
1844                         (void) zfs_ioctl(hdl, ZFS_IOC_SET_PROP, &zc2);
1845                         zcmd_free_nvlists(&zc2);
1846                 }
1847         }
1848
1849         if (err && (ioctl_errno == ENOENT || ioctl_errno == ENODEV)) {
1850                 /*
1851                  * It may be that this snapshot already exists,
1852                  * in which case we want to consume & ignore it
1853                  * rather than failing.
1854                  */
1855                 avl_tree_t *local_avl;
1856                 nvlist_t *local_nv, *fs;
1857                 char *cp = strchr(zc.zc_value, '@');
1858
1859                 /*
1860                  * XXX Do this faster by just iterating over snaps in
1861                  * this fs.  Also if zc_value does not exist, we will
1862                  * get a strange "does not exist" error message.
1863                  */
1864                 *cp = '\0';
1865                 if (gather_nvlist(hdl, zc.zc_value, NULL, NULL,
1866                     &local_nv, &local_avl) == 0) {
1867                         *cp = '@';
1868                         fs = fsavl_find(local_avl, drrb->drr_toguid, NULL);
1869                         fsavl_destroy(local_avl);
1870                         nvlist_free(local_nv);
1871
1872                         if (fs != NULL) {
1873                                 if (flags.verbose) {
1874                                         (void) printf("snap %s already exists; "
1875                                             "ignoring\n", zc.zc_value);
1876                                 }
1877                                 ioctl_err = recv_skip(hdl, infd,
1878                                     flags.byteswap);
1879                         }
1880                 }
1881                 *cp = '@';
1882         }
1883
1884
1885         if (ioctl_err != 0) {
1886                 switch (ioctl_errno) {
1887                 case ENODEV:
1888                         cp = strchr(zc.zc_value, '@');
1889                         *cp = '\0';
1890                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1891                             "most recent snapshot of %s does not\n"
1892                             "match incremental source"), zc.zc_value);
1893                         (void) zfs_error(hdl, EZFS_BADRESTORE, errbuf);
1894                         *cp = '@';
1895                         break;
1896                 case ETXTBSY:
1897                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1898                             "destination %s has been modified\n"
1899                             "since most recent snapshot"), zc.zc_name);
1900                         (void) zfs_error(hdl, EZFS_BADRESTORE, errbuf);
1901                         break;
1902                 case EEXIST:
1903                         cp = strchr(zc.zc_value, '@');
1904                         if (newfs) {
1905                                 /* it's the containing fs that exists */
1906                                 *cp = '\0';
1907                         }
1908                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1909                             "destination already exists"));
1910                         (void) zfs_error_fmt(hdl, EZFS_EXISTS,
1911                             dgettext(TEXT_DOMAIN, "cannot restore to %s"),
1912                             zc.zc_value);
1913                         *cp = '@';
1914                         break;
1915                 case EINVAL:
1916                         (void) zfs_error(hdl, EZFS_BADSTREAM, errbuf);
1917                         break;
1918                 case ECKSUM:
1919                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1920                             "invalid stream (checksum mismatch)"));
1921                         (void) zfs_error(hdl, EZFS_BADSTREAM, errbuf);
1922                         break;
1923                 default:
1924                         (void) zfs_standard_error(hdl, ioctl_errno, errbuf);
1925                 }
1926         }
1927
1928         /*
1929          * Mount or recreate the /dev links for the target filesystem
1930          * (if created, or if we tore them down to do an incremental
1931          * restore), and the /dev links for the new snapshot (if
1932          * created). Also mount any children of the target filesystem
1933          * if we did an incremental receive.
1934          */
1935         cp = strchr(zc.zc_value, '@');
1936         if (cp && (ioctl_err == 0 || !newfs)) {
1937                 zfs_handle_t *h;
1938
1939                 *cp = '\0';
1940                 h = zfs_open(hdl, zc.zc_value,
1941                     ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME);
1942                 if (h != NULL) {
1943                         if (h->zfs_type == ZFS_TYPE_VOLUME) {
1944                                 *cp = '@';
1945                                 err = zvol_create_link(hdl, h->zfs_name);
1946                                 if (err == 0 && ioctl_err == 0)
1947                                         err = zvol_create_link(hdl,
1948                                             zc.zc_value);
1949                         } else if (newfs) {
1950                                 /*
1951                                  * Track the first/top of hierarchy fs,
1952                                  * for mounting and sharing later.
1953                                  */
1954                                 if (top_zfs && *top_zfs == NULL)
1955                                         *top_zfs = zfs_strdup(hdl, zc.zc_value);
1956                         }
1957                         zfs_close(h);
1958                 }
1959                 *cp = '@';
1960         }
1961
1962         if (clp) {
1963                 err |= changelist_postfix(clp);
1964                 changelist_free(clp);
1965         }
1966
1967         if (err || ioctl_err)
1968                 return (-1);
1969
1970         if (flags.verbose) {
1971                 char buf1[64];
1972                 char buf2[64];
1973                 uint64_t bytes = zc.zc_cookie;
1974                 time_t delta = time(NULL) - begin_time;
1975                 if (delta == 0)
1976                         delta = 1;
1977                 zfs_nicenum(bytes, buf1, sizeof (buf1));
1978                 zfs_nicenum(bytes/delta, buf2, sizeof (buf1));
1979
1980                 (void) printf("received %sB stream in %lu seconds (%sB/sec)\n",
1981                     buf1, delta, buf2);
1982         }
1983
1984         return (0);
1985 }
1986
1987 static int
1988 zfs_receive_impl(libzfs_handle_t *hdl, const char *tosnap, recvflags_t flags,
1989     int infd, avl_tree_t *stream_avl, char **top_zfs)
1990 {
1991         int err;
1992         dmu_replay_record_t drr, drr_noswap;
1993         struct drr_begin *drrb = &drr.drr_u.drr_begin;
1994         char errbuf[1024];
1995         zio_cksum_t zcksum = { 0 };
1996
1997         (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
1998             "cannot receive"));
1999
2000         if (flags.isprefix &&
2001             !zfs_dataset_exists(hdl, tosnap, ZFS_TYPE_DATASET)) {
2002                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "specified fs "
2003                     "(%s) does not exist"), tosnap);
2004                 return (zfs_error(hdl, EZFS_NOENT, errbuf));
2005         }
2006
2007         /* read in the BEGIN record */
2008         if (0 != (err = recv_read(hdl, infd, &drr, sizeof (drr), B_FALSE,
2009             &zcksum)))
2010                 return (err);
2011
2012         if (drr.drr_type == DRR_END || drr.drr_type == BSWAP_32(DRR_END)) {
2013                 /* It's the double end record at the end of a package */
2014                 return (ENODATA);
2015         }
2016
2017         /* the kernel needs the non-byteswapped begin record */
2018         drr_noswap = drr;
2019
2020         flags.byteswap = B_FALSE;
2021         if (drrb->drr_magic == BSWAP_64(DMU_BACKUP_MAGIC)) {
2022                 /*
2023                  * We computed the checksum in the wrong byteorder in
2024                  * recv_read() above; do it again correctly.
2025                  */
2026                 bzero(&zcksum, sizeof (zio_cksum_t));
2027                 fletcher_4_incremental_byteswap(&drr, sizeof (drr), &zcksum);
2028                 flags.byteswap = B_TRUE;
2029
2030                 drr.drr_type = BSWAP_32(drr.drr_type);
2031                 drr.drr_payloadlen = BSWAP_32(drr.drr_payloadlen);
2032                 drrb->drr_magic = BSWAP_64(drrb->drr_magic);
2033                 drrb->drr_version = BSWAP_64(drrb->drr_version);
2034                 drrb->drr_creation_time = BSWAP_64(drrb->drr_creation_time);
2035                 drrb->drr_type = BSWAP_32(drrb->drr_type);
2036                 drrb->drr_flags = BSWAP_32(drrb->drr_flags);
2037                 drrb->drr_toguid = BSWAP_64(drrb->drr_toguid);
2038                 drrb->drr_fromguid = BSWAP_64(drrb->drr_fromguid);
2039         }
2040
2041         if (drrb->drr_magic != DMU_BACKUP_MAGIC || drr.drr_type != DRR_BEGIN) {
2042                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "invalid "
2043                     "stream (bad magic number)"));
2044                 return (zfs_error(hdl, EZFS_BADSTREAM, errbuf));
2045         }
2046
2047         if (strchr(drrb->drr_toname, '@') == NULL) {
2048                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "invalid "
2049                     "stream (bad snapshot name)"));
2050                 return (zfs_error(hdl, EZFS_BADSTREAM, errbuf));
2051         }
2052
2053         if (drrb->drr_version == DMU_BACKUP_STREAM_VERSION) {
2054                 return (zfs_receive_one(hdl, infd, tosnap, flags,
2055                     &drr, &drr_noswap, stream_avl, top_zfs));
2056         } else if (drrb->drr_version == DMU_BACKUP_HEADER_VERSION) {
2057                 return (zfs_receive_package(hdl, infd, tosnap, flags,
2058                     &drr, &zcksum, top_zfs));
2059         } else {
2060                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
2061                     "stream is unsupported version %llu"),
2062                     drrb->drr_version);
2063                 return (zfs_error(hdl, EZFS_BADSTREAM, errbuf));
2064         }
2065 }
2066
2067 /*
2068  * Restores a backup of tosnap from the file descriptor specified by infd.
2069  * Return 0 on total success, -2 if some things couldn't be
2070  * destroyed/renamed/promoted, -1 if some things couldn't be received.
2071  * (-1 will override -2).
2072  */
2073 int
2074 zfs_receive(libzfs_handle_t *hdl, const char *tosnap, recvflags_t flags,
2075     int infd, avl_tree_t *stream_avl)
2076 {
2077         char *top_zfs = NULL;
2078         int err;
2079
2080         err = zfs_receive_impl(hdl, tosnap, flags, infd, stream_avl, &top_zfs);
2081
2082         if (err == 0 && top_zfs) {
2083                 zfs_handle_t *zhp;
2084                 prop_changelist_t *clp;
2085
2086                 zhp = zfs_open(hdl, top_zfs, ZFS_TYPE_FILESYSTEM);
2087                 if (zhp != NULL) {
2088                         clp = changelist_gather(zhp, ZFS_PROP_MOUNTPOINT,
2089                             CL_GATHER_MOUNT_ALWAYS, 0);
2090                         zfs_close(zhp);
2091                         if (clp != NULL) {
2092                                 /* mount and share received datasets */
2093                                 err = changelist_postfix(clp);
2094                                 changelist_free(clp);
2095                         }
2096                 }
2097                 if (zhp == NULL || clp == NULL || err)
2098                         err = -1;
2099         }
2100         if (top_zfs)
2101                 free(top_zfs);
2102
2103         return (err);
2104 }