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