]> CyberLeo.Net >> Repos - FreeBSD/releng/8.1.git/blob - cddl/contrib/opensolaris/lib/libzfs/common/libzfs_sendrecv.c
Copy stable/8 to releng/8.1 in preparation for 8.1-RC1.
[FreeBSD/releng/8.1.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                 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, *p1, *p2;
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                 p1 = strrchr(fsname, '/');
1299                 p2 = strrchr(stream_fsname, '/');
1300                 if ((stream_parent_fromsnap_guid != 0 &&
1301                     stream_parent_fromsnap_guid != parent_fromsnap_guid) ||
1302                     (p1 != NULL && p2 != NULL && strcmp (p1, p2) != 0)) {
1303                         nvlist_t *parent;
1304                         char tryname[ZFS_MAXNAMELEN];
1305
1306                         parent = fsavl_find(local_avl,
1307                             stream_parent_fromsnap_guid, NULL);
1308                         /*
1309                          * NB: parent might not be found if we used the
1310                          * tosnap for stream_parent_fromsnap_guid,
1311                          * because the parent is a newly-created fs;
1312                          * we'll be able to rename it after we recv the
1313                          * new fs.
1314                          */
1315                         if (parent != NULL) {
1316                                 char *pname;
1317
1318                                 VERIFY(0 == nvlist_lookup_string(parent, "name",
1319                                     &pname));
1320                                 (void) snprintf(tryname, sizeof (tryname),
1321                                     "%s%s", pname, p2 != NULL ? p2 : "");
1322                         } else {
1323                                 tryname[0] = '\0';
1324                                 if (flags.verbose) {
1325                                         (void) printf("local fs %s new parent "
1326                                             "not found\n", fsname);
1327                                 }
1328                         }
1329
1330                         error = recv_rename(hdl, fsname, tryname,
1331                             strlen(tofs)+1, newname, flags);
1332                         if (error)
1333                                 needagain = B_TRUE;
1334                         else
1335                                 progress = B_TRUE;
1336                 }
1337         }
1338
1339         fsavl_destroy(local_avl);
1340         nvlist_free(local_nv);
1341
1342         if (needagain && progress) {
1343                 /* do another pass to fix up temporary names */
1344                 if (flags.verbose)
1345                         (void) printf("another pass:\n");
1346                 goto again;
1347         }
1348
1349         return (needagain);
1350 }
1351
1352 static int
1353 zfs_receive_package(libzfs_handle_t *hdl, int fd, const char *destname,
1354     recvflags_t flags, dmu_replay_record_t *drr, zio_cksum_t *zc,
1355     char **top_zfs)
1356 {
1357         nvlist_t *stream_nv = NULL;
1358         avl_tree_t *stream_avl = NULL;
1359         char *fromsnap = NULL;
1360         char tofs[ZFS_MAXNAMELEN];
1361         char errbuf[1024];
1362         dmu_replay_record_t drre;
1363         int error;
1364         boolean_t anyerr = B_FALSE;
1365         boolean_t softerr = B_FALSE;
1366
1367         (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
1368             "cannot receive"));
1369
1370         if (strchr(destname, '@')) {
1371                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1372                     "can not specify snapshot name for multi-snapshot stream"));
1373                 return (zfs_error(hdl, EZFS_BADSTREAM, errbuf));
1374         }
1375
1376         assert(drr->drr_type == DRR_BEGIN);
1377         assert(drr->drr_u.drr_begin.drr_magic == DMU_BACKUP_MAGIC);
1378         assert(drr->drr_u.drr_begin.drr_version == DMU_BACKUP_HEADER_VERSION);
1379
1380         /*
1381          * Read in the nvlist from the stream.
1382          */
1383         if (drr->drr_payloadlen != 0) {
1384                 if (!flags.isprefix) {
1385                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1386                             "must use -d to receive replication "
1387                             "(send -R) stream"));
1388                         return (zfs_error(hdl, EZFS_BADSTREAM, errbuf));
1389                 }
1390
1391                 error = recv_read_nvlist(hdl, fd, drr->drr_payloadlen,
1392                     &stream_nv, flags.byteswap, zc);
1393                 if (error) {
1394                         error = zfs_error(hdl, EZFS_BADSTREAM, errbuf);
1395                         goto out;
1396                 }
1397         }
1398
1399         /*
1400          * Read in the end record and verify checksum.
1401          */
1402         if (0 != (error = recv_read(hdl, fd, &drre, sizeof (drre),
1403             flags.byteswap, NULL)))
1404                 goto out;
1405         if (flags.byteswap) {
1406                 drre.drr_type = BSWAP_32(drre.drr_type);
1407                 drre.drr_u.drr_end.drr_checksum.zc_word[0] =
1408                     BSWAP_64(drre.drr_u.drr_end.drr_checksum.zc_word[0]);
1409                 drre.drr_u.drr_end.drr_checksum.zc_word[1] =
1410                     BSWAP_64(drre.drr_u.drr_end.drr_checksum.zc_word[1]);
1411                 drre.drr_u.drr_end.drr_checksum.zc_word[2] =
1412                     BSWAP_64(drre.drr_u.drr_end.drr_checksum.zc_word[2]);
1413                 drre.drr_u.drr_end.drr_checksum.zc_word[3] =
1414                     BSWAP_64(drre.drr_u.drr_end.drr_checksum.zc_word[3]);
1415         }
1416         if (drre.drr_type != DRR_END) {
1417                 error = zfs_error(hdl, EZFS_BADSTREAM, errbuf);
1418                 goto out;
1419         }
1420         if (!ZIO_CHECKSUM_EQUAL(drre.drr_u.drr_end.drr_checksum, *zc)) {
1421                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1422                     "incorrect header checksum"));
1423                 error = zfs_error(hdl, EZFS_BADSTREAM, errbuf);
1424                 goto out;
1425         }
1426
1427         (void) nvlist_lookup_string(stream_nv, "fromsnap", &fromsnap);
1428
1429         if (drr->drr_payloadlen != 0) {
1430                 nvlist_t *stream_fss;
1431
1432                 VERIFY(0 == nvlist_lookup_nvlist(stream_nv, "fss",
1433                     &stream_fss));
1434                 if ((stream_avl = fsavl_create(stream_fss)) == NULL) {
1435                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1436                             "couldn't allocate avl tree"));
1437                         error = zfs_error(hdl, EZFS_NOMEM, errbuf);
1438                         goto out;
1439                 }
1440
1441                 if (fromsnap != NULL) {
1442                         (void) strlcpy(tofs, destname, ZFS_MAXNAMELEN);
1443                         if (flags.isprefix) {
1444                                 int i = strcspn(drr->drr_u.drr_begin.drr_toname,
1445                                     "/@");
1446                                 /* zfs_receive_one() will create_parents() */
1447                                 (void) strlcat(tofs,
1448                                     &drr->drr_u.drr_begin.drr_toname[i],
1449                                     ZFS_MAXNAMELEN);
1450                                 *strchr(tofs, '@') = '\0';
1451                         }
1452                         softerr = recv_incremental_replication(hdl, tofs,
1453                             flags, stream_nv, stream_avl);
1454                 }
1455         }
1456
1457
1458         /* Finally, receive each contained stream */
1459         do {
1460                 /*
1461                  * we should figure out if it has a recoverable
1462                  * error, in which case do a recv_skip() and drive on.
1463                  * Note, if we fail due to already having this guid,
1464                  * zfs_receive_one() will take care of it (ie,
1465                  * recv_skip() and return 0).
1466                  */
1467                 error = zfs_receive_impl(hdl, destname, flags, fd,
1468                     stream_avl, top_zfs);
1469                 if (error == ENODATA) {
1470                         error = 0;
1471                         break;
1472                 }
1473                 anyerr |= error;
1474         } while (error == 0);
1475
1476         if (drr->drr_payloadlen != 0 && fromsnap != NULL) {
1477                 /*
1478                  * Now that we have the fs's they sent us, try the
1479                  * renames again.
1480                  */
1481                 softerr = recv_incremental_replication(hdl, tofs, flags,
1482                     stream_nv, stream_avl);
1483         }
1484
1485 out:
1486         fsavl_destroy(stream_avl);
1487         if (stream_nv)
1488                 nvlist_free(stream_nv);
1489         if (softerr)
1490                 error = -2;
1491         if (anyerr)
1492                 error = -1;
1493         return (error);
1494 }
1495
1496 static int
1497 recv_skip(libzfs_handle_t *hdl, int fd, boolean_t byteswap)
1498 {
1499         dmu_replay_record_t *drr;
1500         void *buf = malloc(1<<20);
1501
1502         /* XXX would be great to use lseek if possible... */
1503         drr = buf;
1504
1505         while (recv_read(hdl, fd, drr, sizeof (dmu_replay_record_t),
1506             byteswap, NULL) == 0) {
1507                 if (byteswap)
1508                         drr->drr_type = BSWAP_32(drr->drr_type);
1509
1510                 switch (drr->drr_type) {
1511                 case DRR_BEGIN:
1512                         /* NB: not to be used on v2 stream packages */
1513                         assert(drr->drr_payloadlen == 0);
1514                         break;
1515
1516                 case DRR_END:
1517                         free(buf);
1518                         return (0);
1519
1520                 case DRR_OBJECT:
1521                         if (byteswap) {
1522                                 drr->drr_u.drr_object.drr_bonuslen =
1523                                     BSWAP_32(drr->drr_u.drr_object.
1524                                     drr_bonuslen);
1525                         }
1526                         (void) recv_read(hdl, fd, buf,
1527                             P2ROUNDUP(drr->drr_u.drr_object.drr_bonuslen, 8),
1528                             B_FALSE, NULL);
1529                         break;
1530
1531                 case DRR_WRITE:
1532                         if (byteswap) {
1533                                 drr->drr_u.drr_write.drr_length =
1534                                     BSWAP_64(drr->drr_u.drr_write.drr_length);
1535                         }
1536                         (void) recv_read(hdl, fd, buf,
1537                             drr->drr_u.drr_write.drr_length, B_FALSE, NULL);
1538                         break;
1539
1540                 case DRR_FREEOBJECTS:
1541                 case DRR_FREE:
1542                         break;
1543
1544                 default:
1545                         assert(!"invalid record type");
1546                 }
1547         }
1548
1549         free(buf);
1550         return (-1);
1551 }
1552
1553 /*
1554  * Restores a backup of tosnap from the file descriptor specified by infd.
1555  */
1556 static int
1557 zfs_receive_one(libzfs_handle_t *hdl, int infd, const char *tosnap,
1558     recvflags_t flags, dmu_replay_record_t *drr,
1559     dmu_replay_record_t *drr_noswap, avl_tree_t *stream_avl,
1560     char **top_zfs)
1561 {
1562         zfs_cmd_t zc = { 0 };
1563         time_t begin_time;
1564         int ioctl_err, ioctl_errno, err, choplen;
1565         char *cp;
1566         struct drr_begin *drrb = &drr->drr_u.drr_begin;
1567         char errbuf[1024];
1568         char chopprefix[ZFS_MAXNAMELEN];
1569         boolean_t newfs = B_FALSE;
1570         boolean_t stream_wantsnewfs;
1571         uint64_t parent_snapguid = 0;
1572         prop_changelist_t *clp = NULL;
1573         nvlist_t *snapprops_nvlist = NULL;
1574
1575         begin_time = time(NULL);
1576
1577         (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
1578             "cannot receive"));
1579
1580         if (stream_avl != NULL) {
1581                 char *snapname;
1582                 nvlist_t *fs = fsavl_find(stream_avl, drrb->drr_toguid,
1583                     &snapname);
1584                 nvlist_t *props;
1585                 int ret;
1586
1587                 (void) nvlist_lookup_uint64(fs, "parentfromsnap",
1588                     &parent_snapguid);
1589                 err = nvlist_lookup_nvlist(fs, "props", &props);
1590                 if (err)
1591                         VERIFY(0 == nvlist_alloc(&props, NV_UNIQUE_NAME, 0));
1592
1593                 if (flags.canmountoff) {
1594                         VERIFY(0 == nvlist_add_uint64(props,
1595                             zfs_prop_to_name(ZFS_PROP_CANMOUNT), 0));
1596                 }
1597                 ret = zcmd_write_src_nvlist(hdl, &zc, props);
1598                 if (err)
1599                         nvlist_free(props);
1600
1601                 if (0 == nvlist_lookup_nvlist(fs, "snapprops", &props)) {
1602                         VERIFY(0 == nvlist_lookup_nvlist(props,
1603                             snapname, &snapprops_nvlist));
1604                 }
1605
1606                 if (ret != 0)
1607                         return (-1);
1608         }
1609
1610         /*
1611          * Determine how much of the snapshot name stored in the stream
1612          * we are going to tack on to the name they specified on the
1613          * command line, and how much we are going to chop off.
1614          *
1615          * If they specified a snapshot, chop the entire name stored in
1616          * the stream.
1617          */
1618         (void) strcpy(chopprefix, drrb->drr_toname);
1619         if (flags.isprefix) {
1620                 /*
1621                  * They specified a fs with -d, we want to tack on
1622                  * everything but the pool name stored in the stream
1623                  */
1624                 if (strchr(tosnap, '@')) {
1625                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "invalid "
1626                             "argument - snapshot not allowed with -d"));
1627                         return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf));
1628                 }
1629                 cp = strchr(chopprefix, '/');
1630                 if (cp == NULL)
1631                         cp = strchr(chopprefix, '@');
1632                 *cp = '\0';
1633         } else if (strchr(tosnap, '@') == NULL) {
1634                 /*
1635                  * If they specified a filesystem without -d, we want to
1636                  * tack on everything after the fs specified in the
1637                  * first name from the stream.
1638                  */
1639                 cp = strchr(chopprefix, '@');
1640                 *cp = '\0';
1641         }
1642         choplen = strlen(chopprefix);
1643
1644         /*
1645          * Determine name of destination snapshot, store in zc_value.
1646          */
1647         (void) strcpy(zc.zc_value, tosnap);
1648         (void) strncat(zc.zc_value, drrb->drr_toname+choplen,
1649             sizeof (zc.zc_value));
1650         if (!zfs_name_valid(zc.zc_value, ZFS_TYPE_SNAPSHOT)) {
1651                 zcmd_free_nvlists(&zc);
1652                 return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf));
1653         }
1654
1655         /*
1656          * Determine the name of the origin snapshot, store in zc_string.
1657          */
1658         if (drrb->drr_flags & DRR_FLAG_CLONE) {
1659                 if (guid_to_name(hdl, tosnap,
1660                     drrb->drr_fromguid, zc.zc_string) != 0) {
1661                         zcmd_free_nvlists(&zc);
1662                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1663                             "local origin for clone %s does not exist"),
1664                             zc.zc_value);
1665                         return (zfs_error(hdl, EZFS_NOENT, errbuf));
1666                 }
1667                 if (flags.verbose)
1668                         (void) printf("found clone origin %s\n", zc.zc_string);
1669         }
1670
1671         stream_wantsnewfs = (drrb->drr_fromguid == 0 ||
1672             (drrb->drr_flags & DRR_FLAG_CLONE));
1673
1674         if (stream_wantsnewfs) {
1675                 /*
1676                  * if the parent fs does not exist, look for it based on
1677                  * the parent snap GUID
1678                  */
1679                 (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
1680                     "cannot receive new filesystem stream"));
1681
1682                 (void) strcpy(zc.zc_name, zc.zc_value);
1683                 cp = strrchr(zc.zc_name, '/');
1684                 if (cp)
1685                         *cp = '\0';
1686                 if (cp &&
1687                     !zfs_dataset_exists(hdl, zc.zc_name, ZFS_TYPE_DATASET)) {
1688                         char suffix[ZFS_MAXNAMELEN];
1689                         (void) strcpy(suffix, strrchr(zc.zc_value, '/'));
1690                         if (guid_to_name(hdl, tosnap, parent_snapguid,
1691                             zc.zc_value) == 0) {
1692                                 *strchr(zc.zc_value, '@') = '\0';
1693                                 (void) strcat(zc.zc_value, suffix);
1694                         }
1695                 }
1696         } else {
1697                 /*
1698                  * if the fs does not exist, look for it based on the
1699                  * fromsnap GUID
1700                  */
1701                 (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
1702                     "cannot receive incremental stream"));
1703
1704                 (void) strcpy(zc.zc_name, zc.zc_value);
1705                 *strchr(zc.zc_name, '@') = '\0';
1706
1707                 if (!zfs_dataset_exists(hdl, zc.zc_name, ZFS_TYPE_DATASET)) {
1708                         char snap[ZFS_MAXNAMELEN];
1709                         (void) strcpy(snap, strchr(zc.zc_value, '@'));
1710                         if (guid_to_name(hdl, tosnap, drrb->drr_fromguid,
1711                             zc.zc_value) == 0) {
1712                                 *strchr(zc.zc_value, '@') = '\0';
1713                                 (void) strcat(zc.zc_value, snap);
1714                         }
1715                 }
1716         }
1717
1718         (void) strcpy(zc.zc_name, zc.zc_value);
1719         *strchr(zc.zc_name, '@') = '\0';
1720
1721         if (zfs_dataset_exists(hdl, zc.zc_name, ZFS_TYPE_DATASET)) {
1722                 zfs_handle_t *zhp;
1723                 /*
1724                  * Destination fs exists.  Therefore this should either
1725                  * be an incremental, or the stream specifies a new fs
1726                  * (full stream or clone) and they want us to blow it
1727                  * away (and have therefore specified -F and removed any
1728                  * snapshots).
1729                  */
1730
1731                 if (stream_wantsnewfs) {
1732                         if (!flags.force) {
1733                                 zcmd_free_nvlists(&zc);
1734                                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1735                                     "destination '%s' exists\n"
1736                                     "must specify -F to overwrite it"),
1737                                     zc.zc_name);
1738                                 return (zfs_error(hdl, EZFS_EXISTS, errbuf));
1739                         }
1740                         if (ioctl(hdl->libzfs_fd, ZFS_IOC_SNAPSHOT_LIST_NEXT,
1741                             &zc) == 0) {
1742                                 zcmd_free_nvlists(&zc);
1743                                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1744                                     "destination has snapshots (eg. %s)\n"
1745                                     "must destroy them to overwrite it"),
1746                                     zc.zc_name);
1747                                 return (zfs_error(hdl, EZFS_EXISTS, errbuf));
1748                         }
1749                 }
1750
1751                 if ((zhp = zfs_open(hdl, zc.zc_name,
1752                     ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME)) == NULL) {
1753                         zcmd_free_nvlists(&zc);
1754                         return (-1);
1755                 }
1756
1757                 if (stream_wantsnewfs &&
1758                     zhp->zfs_dmustats.dds_origin[0]) {
1759                         zcmd_free_nvlists(&zc);
1760                         zfs_close(zhp);
1761                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1762                             "destination '%s' is a clone\n"
1763                             "must destroy it to overwrite it"),
1764                             zc.zc_name);
1765                         return (zfs_error(hdl, EZFS_EXISTS, errbuf));
1766                 }
1767
1768                 if (!flags.dryrun && zhp->zfs_type == ZFS_TYPE_FILESYSTEM &&
1769                     stream_wantsnewfs) {
1770                         /* We can't do online recv in this case */
1771                         clp = changelist_gather(zhp, ZFS_PROP_NAME, 0, 0);
1772                         if (clp == NULL) {
1773                                 zcmd_free_nvlists(&zc);
1774                                 return (-1);
1775                         }
1776                         if (changelist_prefix(clp) != 0) {
1777                                 changelist_free(clp);
1778                                 zcmd_free_nvlists(&zc);
1779                                 return (-1);
1780                         }
1781                 }
1782                 if (!flags.dryrun && zhp->zfs_type == ZFS_TYPE_VOLUME &&
1783                     zvol_remove_link(hdl, zhp->zfs_name) != 0) {
1784                         zfs_close(zhp);
1785                         zcmd_free_nvlists(&zc);
1786                         return (-1);
1787                 }
1788                 zfs_close(zhp);
1789         } else {
1790                 /*
1791                  * Destination filesystem does not exist.  Therefore we better
1792                  * be creating a new filesystem (either from a full backup, or
1793                  * a clone).  It would therefore be invalid if the user
1794                  * specified only the pool name (i.e. if the destination name
1795                  * contained no slash character).
1796                  */
1797                 if (!stream_wantsnewfs ||
1798                     (cp = strrchr(zc.zc_name, '/')) == NULL) {
1799                         zcmd_free_nvlists(&zc);
1800                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1801                             "destination '%s' does not exist"), zc.zc_name);
1802                         return (zfs_error(hdl, EZFS_NOENT, errbuf));
1803                 }
1804
1805                 /*
1806                  * Trim off the final dataset component so we perform the
1807                  * recvbackup ioctl to the filesystems's parent.
1808                  */
1809                 *cp = '\0';
1810
1811                 if (flags.isprefix && !flags.dryrun &&
1812                     create_parents(hdl, zc.zc_value, strlen(tosnap)) != 0) {
1813                         zcmd_free_nvlists(&zc);
1814                         return (zfs_error(hdl, EZFS_BADRESTORE, errbuf));
1815                 }
1816
1817                 newfs = B_TRUE;
1818         }
1819
1820         zc.zc_begin_record = drr_noswap->drr_u.drr_begin;
1821         zc.zc_cookie = infd;
1822         zc.zc_guid = flags.force;
1823         if (flags.verbose) {
1824                 (void) printf("%s %s stream of %s into %s\n",
1825                     flags.dryrun ? "would receive" : "receiving",
1826                     drrb->drr_fromguid ? "incremental" : "full",
1827                     drrb->drr_toname, zc.zc_value);
1828                 (void) fflush(stdout);
1829         }
1830
1831         if (flags.dryrun) {
1832                 zcmd_free_nvlists(&zc);
1833                 return (recv_skip(hdl, infd, flags.byteswap));
1834         }
1835
1836         err = ioctl_err = zfs_ioctl(hdl, ZFS_IOC_RECV, &zc);
1837         ioctl_errno = errno;
1838         zcmd_free_nvlists(&zc);
1839
1840         if (err == 0 && snapprops_nvlist) {
1841                 zfs_cmd_t zc2 = { 0 };
1842
1843                 (void) strcpy(zc2.zc_name, zc.zc_value);
1844                 if (zcmd_write_src_nvlist(hdl, &zc2, snapprops_nvlist) == 0) {
1845                         (void) zfs_ioctl(hdl, ZFS_IOC_SET_PROP, &zc2);
1846                         zcmd_free_nvlists(&zc2);
1847                 }
1848         }
1849
1850         if (err && (ioctl_errno == ENOENT || ioctl_errno == ENODEV)) {
1851                 /*
1852                  * It may be that this snapshot already exists,
1853                  * in which case we want to consume & ignore it
1854                  * rather than failing.
1855                  */
1856                 avl_tree_t *local_avl;
1857                 nvlist_t *local_nv, *fs;
1858                 char *cp = strchr(zc.zc_value, '@');
1859
1860                 /*
1861                  * XXX Do this faster by just iterating over snaps in
1862                  * this fs.  Also if zc_value does not exist, we will
1863                  * get a strange "does not exist" error message.
1864                  */
1865                 *cp = '\0';
1866                 if (gather_nvlist(hdl, zc.zc_value, NULL, NULL,
1867                     &local_nv, &local_avl) == 0) {
1868                         *cp = '@';
1869                         fs = fsavl_find(local_avl, drrb->drr_toguid, NULL);
1870                         fsavl_destroy(local_avl);
1871                         nvlist_free(local_nv);
1872
1873                         if (fs != NULL) {
1874                                 if (flags.verbose) {
1875                                         (void) printf("snap %s already exists; "
1876                                             "ignoring\n", zc.zc_value);
1877                                 }
1878                                 ioctl_err = recv_skip(hdl, infd,
1879                                     flags.byteswap);
1880                         }
1881                 }
1882                 *cp = '@';
1883         }
1884
1885
1886         if (ioctl_err != 0) {
1887                 switch (ioctl_errno) {
1888                 case ENODEV:
1889                         cp = strchr(zc.zc_value, '@');
1890                         *cp = '\0';
1891                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1892                             "most recent snapshot of %s does not\n"
1893                             "match incremental source"), zc.zc_value);
1894                         (void) zfs_error(hdl, EZFS_BADRESTORE, errbuf);
1895                         *cp = '@';
1896                         break;
1897                 case ETXTBSY:
1898                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1899                             "destination %s has been modified\n"
1900                             "since most recent snapshot"), zc.zc_name);
1901                         (void) zfs_error(hdl, EZFS_BADRESTORE, errbuf);
1902                         break;
1903                 case EEXIST:
1904                         cp = strchr(zc.zc_value, '@');
1905                         if (newfs) {
1906                                 /* it's the containing fs that exists */
1907                                 *cp = '\0';
1908                         }
1909                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1910                             "destination already exists"));
1911                         (void) zfs_error_fmt(hdl, EZFS_EXISTS,
1912                             dgettext(TEXT_DOMAIN, "cannot restore to %s"),
1913                             zc.zc_value);
1914                         *cp = '@';
1915                         break;
1916                 case EINVAL:
1917                         (void) zfs_error(hdl, EZFS_BADSTREAM, errbuf);
1918                         break;
1919                 case ECKSUM:
1920                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1921                             "invalid stream (checksum mismatch)"));
1922                         (void) zfs_error(hdl, EZFS_BADSTREAM, errbuf);
1923                         break;
1924                 default:
1925                         (void) zfs_standard_error(hdl, ioctl_errno, errbuf);
1926                 }
1927         }
1928
1929         /*
1930          * Mount or recreate the /dev links for the target filesystem
1931          * (if created, or if we tore them down to do an incremental
1932          * restore), and the /dev links for the new snapshot (if
1933          * created). Also mount any children of the target filesystem
1934          * if we did an incremental receive.
1935          */
1936         cp = strchr(zc.zc_value, '@');
1937         if (cp && (ioctl_err == 0 || !newfs)) {
1938                 zfs_handle_t *h;
1939
1940                 *cp = '\0';
1941                 h = zfs_open(hdl, zc.zc_value,
1942                     ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME);
1943                 if (h != NULL) {
1944                         if (h->zfs_type == ZFS_TYPE_VOLUME) {
1945                                 *cp = '@';
1946                                 err = zvol_create_link(hdl, h->zfs_name);
1947                                 if (err == 0 && ioctl_err == 0)
1948                                         err = zvol_create_link(hdl,
1949                                             zc.zc_value);
1950                         } else if (newfs) {
1951                                 /*
1952                                  * Track the first/top of hierarchy fs,
1953                                  * for mounting and sharing later.
1954                                  */
1955                                 if (top_zfs && *top_zfs == NULL)
1956                                         *top_zfs = zfs_strdup(hdl, zc.zc_value);
1957                         }
1958                         zfs_close(h);
1959                 }
1960                 *cp = '@';
1961         }
1962
1963         if (clp) {
1964                 err |= changelist_postfix(clp);
1965                 changelist_free(clp);
1966         }
1967
1968         if (err || ioctl_err)
1969                 return (-1);
1970
1971         if (flags.verbose) {
1972                 char buf1[64];
1973                 char buf2[64];
1974                 uint64_t bytes = zc.zc_cookie;
1975                 time_t delta = time(NULL) - begin_time;
1976                 if (delta == 0)
1977                         delta = 1;
1978                 zfs_nicenum(bytes, buf1, sizeof (buf1));
1979                 zfs_nicenum(bytes/delta, buf2, sizeof (buf1));
1980
1981                 (void) printf("received %sB stream in %lu seconds (%sB/sec)\n",
1982                     buf1, delta, buf2);
1983         }
1984
1985         return (0);
1986 }
1987
1988 static int
1989 zfs_receive_impl(libzfs_handle_t *hdl, const char *tosnap, recvflags_t flags,
1990     int infd, avl_tree_t *stream_avl, char **top_zfs)
1991 {
1992         int err;
1993         dmu_replay_record_t drr, drr_noswap;
1994         struct drr_begin *drrb = &drr.drr_u.drr_begin;
1995         char errbuf[1024];
1996         zio_cksum_t zcksum = { 0 };
1997
1998         (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
1999             "cannot receive"));
2000
2001         if (flags.isprefix &&
2002             !zfs_dataset_exists(hdl, tosnap, ZFS_TYPE_DATASET)) {
2003                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "specified fs "
2004                     "(%s) does not exist"), tosnap);
2005                 return (zfs_error(hdl, EZFS_NOENT, errbuf));
2006         }
2007
2008         /* read in the BEGIN record */
2009         if (0 != (err = recv_read(hdl, infd, &drr, sizeof (drr), B_FALSE,
2010             &zcksum)))
2011                 return (err);
2012
2013         if (drr.drr_type == DRR_END || drr.drr_type == BSWAP_32(DRR_END)) {
2014                 /* It's the double end record at the end of a package */
2015                 return (ENODATA);
2016         }
2017
2018         /* the kernel needs the non-byteswapped begin record */
2019         drr_noswap = drr;
2020
2021         flags.byteswap = B_FALSE;
2022         if (drrb->drr_magic == BSWAP_64(DMU_BACKUP_MAGIC)) {
2023                 /*
2024                  * We computed the checksum in the wrong byteorder in
2025                  * recv_read() above; do it again correctly.
2026                  */
2027                 bzero(&zcksum, sizeof (zio_cksum_t));
2028                 fletcher_4_incremental_byteswap(&drr, sizeof (drr), &zcksum);
2029                 flags.byteswap = B_TRUE;
2030
2031                 drr.drr_type = BSWAP_32(drr.drr_type);
2032                 drr.drr_payloadlen = BSWAP_32(drr.drr_payloadlen);
2033                 drrb->drr_magic = BSWAP_64(drrb->drr_magic);
2034                 drrb->drr_version = BSWAP_64(drrb->drr_version);
2035                 drrb->drr_creation_time = BSWAP_64(drrb->drr_creation_time);
2036                 drrb->drr_type = BSWAP_32(drrb->drr_type);
2037                 drrb->drr_flags = BSWAP_32(drrb->drr_flags);
2038                 drrb->drr_toguid = BSWAP_64(drrb->drr_toguid);
2039                 drrb->drr_fromguid = BSWAP_64(drrb->drr_fromguid);
2040         }
2041
2042         if (drrb->drr_magic != DMU_BACKUP_MAGIC || drr.drr_type != DRR_BEGIN) {
2043                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "invalid "
2044                     "stream (bad magic number)"));
2045                 return (zfs_error(hdl, EZFS_BADSTREAM, errbuf));
2046         }
2047
2048         if (strchr(drrb->drr_toname, '@') == NULL) {
2049                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "invalid "
2050                     "stream (bad snapshot name)"));
2051                 return (zfs_error(hdl, EZFS_BADSTREAM, errbuf));
2052         }
2053
2054         if (drrb->drr_version == DMU_BACKUP_STREAM_VERSION) {
2055                 return (zfs_receive_one(hdl, infd, tosnap, flags,
2056                     &drr, &drr_noswap, stream_avl, top_zfs));
2057         } else if (drrb->drr_version == DMU_BACKUP_HEADER_VERSION) {
2058                 return (zfs_receive_package(hdl, infd, tosnap, flags,
2059                     &drr, &zcksum, top_zfs));
2060         } else {
2061                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
2062                     "stream is unsupported version %llu"),
2063                     drrb->drr_version);
2064                 return (zfs_error(hdl, EZFS_BADSTREAM, errbuf));
2065         }
2066 }
2067
2068 /*
2069  * Restores a backup of tosnap from the file descriptor specified by infd.
2070  * Return 0 on total success, -2 if some things couldn't be
2071  * destroyed/renamed/promoted, -1 if some things couldn't be received.
2072  * (-1 will override -2).
2073  */
2074 int
2075 zfs_receive(libzfs_handle_t *hdl, const char *tosnap, recvflags_t flags,
2076     int infd, avl_tree_t *stream_avl)
2077 {
2078         char *top_zfs = NULL;
2079         int err;
2080
2081         err = zfs_receive_impl(hdl, tosnap, flags, infd, stream_avl, &top_zfs);
2082
2083         if (err == 0 && !flags.nomount && top_zfs) {
2084                 zfs_handle_t *zhp;
2085                 prop_changelist_t *clp;
2086
2087                 zhp = zfs_open(hdl, top_zfs, ZFS_TYPE_FILESYSTEM);
2088                 if (zhp != NULL) {
2089                         clp = changelist_gather(zhp, ZFS_PROP_MOUNTPOINT,
2090                             CL_GATHER_MOUNT_ALWAYS, 0);
2091                         zfs_close(zhp);
2092                         if (clp != NULL) {
2093                                 /* mount and share received datasets */
2094                                 err = changelist_postfix(clp);
2095                                 changelist_free(clp);
2096                         }
2097                 }
2098                 if (zhp == NULL || clp == NULL || err)
2099                         err = -1;
2100         }
2101         if (top_zfs)
2102                 free(top_zfs);
2103
2104         return (err);
2105 }