]> git.proxmox.com Git - mirror_zfs.git/blame - lib/libzfs/libzfs_sendrecv.c
Fix unsafe string operations
[mirror_zfs.git] / lib / libzfs / libzfs_sendrecv.c
CommitLineData
34dc7c2f
BB
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
1d3ba0bf 9 * or https://opensource.org/licenses/CDDL-1.0.
34dc7c2f
BB
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/*
428870ff 23 * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
196bee4c 24 * Copyright (c) 2011, 2020 by Delphix. All rights reserved.
37abac6d 25 * Copyright (c) 2012, Joyent, Inc. All rights reserved.
95fd54a1 26 * Copyright (c) 2012 Pawel Jakub Dawidek <pawel@dawidek.net>.
0cee2406 27 * All rights reserved
95fd54a1 28 * Copyright (c) 2013 Steven Hartland. All rights reserved.
671c9354 29 * Copyright 2015, OmniTI Computer Consulting, Inc. All rights reserved.
23d70cde 30 * Copyright 2016 Igor Kozhukhov <ikozhukhov@gmail.com>
d8d418ff 31 * Copyright (c) 2018, loli10K <ezomori.nozomu@gmail.com>. All rights reserved.
4c0883fb 32 * Copyright (c) 2019 Datto Inc.
34dc7c2f
BB
33 */
34
34dc7c2f
BB
35#include <assert.h>
36#include <ctype.h>
37#include <errno.h>
34dc7c2f
BB
38#include <libintl.h>
39#include <stdio.h>
40#include <stdlib.h>
d465fc58 41#include <string.h>
34dc7c2f
BB
42#include <unistd.h>
43#include <stddef.h>
44#include <fcntl.h>
45#include <sys/mount.h>
9b020fd9
BB
46#include <sys/mntent.h>
47#include <sys/mnttab.h>
48#include <sys/avl.h>
49#include <sys/debug.h>
5c3f61eb 50#include <sys/stat.h>
428870ff
BB
51#include <pthread.h>
52#include <umem.h>
37abac6d 53#include <time.h>
34dc7c2f
BB
54
55#include <libzfs.h>
9b67f605 56#include <libzfs_core.h>
e89f1295 57#include <libzutil.h>
34dc7c2f
BB
58
59#include "zfs_namecheck.h"
60#include "zfs_prop.h"
428870ff 61#include "zfs_fletcher.h"
34dc7c2f 62#include "libzfs_impl.h"
c618f87c 63#include <cityhash.h>
47dfff3b 64#include <zlib.h>
428870ff 65#include <sys/zio_checksum.h>
b5256303 66#include <sys/dsl_crypt.h>
428870ff 67#include <sys/ddt.h>
1b9d8c34 68#include <sys/socket.h>
3c67d83a 69#include <sys/sha2.h>
34dc7c2f 70
fcff0f35 71static int zfs_receive_impl(libzfs_handle_t *, const char *, const char *,
196bee4c
MA
72 recvflags_t *, int, const char *, nvlist_t *, avl_tree_t *, char **,
73 const char *, nvlist_t *);
30af21b0
PD
74static int guid_to_name_redact_snaps(libzfs_handle_t *hdl, const char *parent,
75 uint64_t guid, boolean_t bookmark_ok, uint64_t *redact_snap_guids,
76 uint64_t num_redact_snaps, char *name);
47dfff3b
MA
77static int guid_to_name(libzfs_handle_t *, const char *,
78 uint64_t, boolean_t, char *);
428870ff 79
37abac6d
BP
80typedef struct progress_arg {
81 zfs_handle_t *pa_zhp;
82 int pa_fd;
83 boolean_t pa_parsable;
30af21b0
PD
84 boolean_t pa_estimate;
85 int pa_verbosity;
37abac6d
BP
86} progress_arg_t;
87
428870ff 88static int
01a0039a 89dump_record(dmu_replay_record_t *drr, void *payload, size_t payload_len,
37f8a883 90 zio_cksum_t *zc, int outfd)
428870ff 91{
37f8a883
MA
92 ASSERT3U(offsetof(dmu_replay_record_t, drr_u.drr_checksum.drr_checksum),
93 ==, sizeof (dmu_replay_record_t) - sizeof (zio_cksum_t));
94 fletcher_4_incremental_native(drr,
95 offsetof(dmu_replay_record_t, drr_u.drr_checksum.drr_checksum), zc);
96 if (drr->drr_type != DRR_BEGIN) {
97 ASSERT(ZIO_CHECKSUM_IS_ZERO(&drr->drr_u.
98 drr_checksum.drr_checksum));
99 drr->drr_u.drr_checksum.drr_checksum = *zc;
100 }
101 fletcher_4_incremental_native(&drr->drr_u.drr_checksum.drr_checksum,
102 sizeof (zio_cksum_t), zc);
103 if (write(outfd, drr, sizeof (*drr)) == -1)
104 return (errno);
105 if (payload_len != 0) {
106 fletcher_4_incremental_native(payload, payload_len, zc);
107 if (write(outfd, payload, payload_len) == -1)
108 return (errno);
109 }
110 return (0);
428870ff
BB
111}
112
34dc7c2f
BB
113/*
114 * Routines for dealing with the AVL tree of fs-nvlists
115 */
116typedef struct fsavl_node {
117 avl_node_t fn_node;
118 nvlist_t *fn_nvfs;
119 char *fn_snapname;
120 uint64_t fn_guid;
121} fsavl_node_t;
122
123static int
124fsavl_compare(const void *arg1, const void *arg2)
125{
ee36c709
GN
126 const fsavl_node_t *fn1 = (const fsavl_node_t *)arg1;
127 const fsavl_node_t *fn2 = (const fsavl_node_t *)arg2;
128
ca577779 129 return (TREE_CMP(fn1->fn_guid, fn2->fn_guid));
34dc7c2f
BB
130}
131
132/*
133 * Given the GUID of a snapshot, find its containing filesystem and
134 * (optionally) name.
135 */
136static nvlist_t *
137fsavl_find(avl_tree_t *avl, uint64_t snapguid, char **snapname)
138{
139 fsavl_node_t fn_find;
140 fsavl_node_t *fn;
141
142 fn_find.fn_guid = snapguid;
143
144 fn = avl_find(avl, &fn_find, NULL);
145 if (fn) {
146 if (snapname)
147 *snapname = fn->fn_snapname;
148 return (fn->fn_nvfs);
149 }
150 return (NULL);
151}
152
153static void
154fsavl_destroy(avl_tree_t *avl)
155{
156 fsavl_node_t *fn;
157 void *cookie;
158
159 if (avl == NULL)
160 return;
161
162 cookie = NULL;
163 while ((fn = avl_destroy_nodes(avl, &cookie)) != NULL)
164 free(fn);
165 avl_destroy(avl);
166 free(avl);
167}
168
45d1cae3
BB
169/*
170 * Given an nvlist, produce an avl tree of snapshots, ordered by guid
171 */
34dc7c2f
BB
172static avl_tree_t *
173fsavl_create(nvlist_t *fss)
174{
175 avl_tree_t *fsavl;
176 nvpair_t *fselem = NULL;
177
178 if ((fsavl = malloc(sizeof (avl_tree_t))) == NULL)
179 return (NULL);
180
181 avl_create(fsavl, fsavl_compare, sizeof (fsavl_node_t),
182 offsetof(fsavl_node_t, fn_node));
183
184 while ((fselem = nvlist_next_nvpair(fss, fselem)) != NULL) {
185 nvlist_t *nvfs, *snaps;
186 nvpair_t *snapelem = NULL;
187
60a2434b
RM
188 nvfs = fnvpair_value_nvlist(fselem);
189 snaps = fnvlist_lookup_nvlist(nvfs, "snaps");
34dc7c2f
BB
190
191 while ((snapelem =
192 nvlist_next_nvpair(snaps, snapelem)) != NULL) {
193 fsavl_node_t *fn;
34dc7c2f 194
34dc7c2f
BB
195 if ((fn = malloc(sizeof (fsavl_node_t))) == NULL) {
196 fsavl_destroy(fsavl);
197 return (NULL);
198 }
199 fn->fn_nvfs = nvfs;
200 fn->fn_snapname = nvpair_name(snapelem);
1488e822 201 fn->fn_guid = fnvpair_value_uint64(snapelem);
34dc7c2f
BB
202
203 /*
204 * Note: if there are multiple snaps with the
205 * same GUID, we ignore all but one.
206 */
af2b1fbd
RM
207 avl_index_t where = 0;
208 if (avl_find(fsavl, fn, &where) == NULL)
209 avl_insert(fsavl, fn, where);
34dc7c2f
BB
210 else
211 free(fn);
212 }
213 }
214
215 return (fsavl);
216}
217
218/*
219 * Routines for dealing with the giant nvlist of fs-nvlists, etc.
220 */
221typedef struct send_data {
66356240
K
222 /*
223 * assigned inside every recursive call,
224 * restored from *_save on return:
225 *
226 * guid of fromsnap snapshot in parent dataset
227 * txg of fromsnap snapshot in current dataset
228 * txg of tosnap snapshot in current dataset
229 */
230
34dc7c2f 231 uint64_t parent_fromsnap_guid;
66356240
K
232 uint64_t fromsnap_txg;
233 uint64_t tosnap_txg;
234
235 /* the nvlists get accumulated during depth-first traversal */
34dc7c2f
BB
236 nvlist_t *parent_snaps;
237 nvlist_t *fss;
b128c09f 238 nvlist_t *snapprops;
9c5e88b1 239 nvlist_t *snapholds; /* user holds */
66356240
K
240
241 /* send-receive configuration, does not change during traversal */
242 const char *fsname;
34dc7c2f
BB
243 const char *fromsnap;
244 const char *tosnap;
428870ff 245 boolean_t recursive;
4c0883fb 246 boolean_t raw;
f94b3cbf 247 boolean_t doall;
4c0883fb 248 boolean_t replicate;
099fa7e4 249 boolean_t skipmissing;
66356240 250 boolean_t verbose;
4c0883fb 251 boolean_t backup;
05748550
AG
252 boolean_t seenfrom;
253 boolean_t seento;
9c5e88b1
PZ
254 boolean_t holds; /* were holds requested with send -h */
255 boolean_t props;
34dc7c2f
BB
256
257 /*
258 * The header nvlist is of the following format:
259 * {
260 * "tosnap" -> string
261 * "fromsnap" -> string (if incremental)
262 * "fss" -> {
263 * id -> {
264 *
265 * "name" -> string (full name; for debugging)
266 * "parentfromsnap" -> number (guid of fromsnap in parent)
267 *
268 * "props" -> { name -> value (only if set here) }
269 * "snaps" -> { name (lastname) -> number (guid) }
b128c09f 270 * "snapprops" -> { name (lastname) -> { name -> value } }
9c5e88b1 271 * "snapholds" -> { name (lastname) -> { holdname -> crtime } }
34dc7c2f
BB
272 *
273 * "origin" -> number (guid) (if clone)
b5256303 274 * "is_encroot" -> boolean
34dc7c2f
BB
275 * "sent" -> boolean (not on-disk)
276 * }
277 * }
278 * }
279 *
280 */
281} send_data_t;
282
faa97c16 283static void
284send_iterate_prop(zfs_handle_t *zhp, boolean_t received_only, nvlist_t *nv);
b128c09f 285
dd59c422
RM
286/*
287 * Collect guid, valid props, optionally holds, etc. of a snapshot.
288 * This interface is intended for use as a zfs_iter_snapshots_sorted visitor.
289 */
34dc7c2f
BB
290static int
291send_iterate_snap(zfs_handle_t *zhp, void *arg)
292{
293 send_data_t *sd = arg;
294 uint64_t guid = zhp->zfs_dmustats.dds_guid;
66356240 295 uint64_t txg = zhp->zfs_dmustats.dds_creation_txg;
e890dd85 296 boolean_t isfromsnap, istosnap, istosnapwithnofrom;
5cf3c24f 297 char *snapname;
dd59c422
RM
298 const char *from = sd->fromsnap;
299 const char *to = sd->tosnap;
34dc7c2f 300
5cf3c24f
AZ
301 snapname = strrchr(zhp->zfs_name, '@');
302 assert(snapname != NULL);
303 ++snapname;
dd59c422
RM
304
305 isfromsnap = (from != NULL && strcmp(from, snapname) == 0);
306 istosnap = (to != NULL && strcmp(to, snapname) == 0);
307 istosnapwithnofrom = (istosnap && from == NULL);
34dc7c2f 308
66356240
K
309 if (sd->tosnap_txg != 0 && txg > sd->tosnap_txg) {
310 if (sd->verbose) {
311 (void) fprintf(stderr, dgettext(TEXT_DOMAIN,
312 "skipping snapshot %s because it was created "
313 "after the destination snapshot (%s)\n"),
dd59c422 314 zhp->zfs_name, to);
66356240
K
315 }
316 zfs_close(zhp);
317 return (0);
318 }
319
60a2434b 320 fnvlist_add_uint64(sd->parent_snaps, snapname, guid);
dd59c422 321
34dc7c2f
BB
322 /*
323 * NB: if there is no fromsnap here (it's a newly created fs in
324 * an incremental replication), we will substitute the tosnap.
325 */
dd59c422 326 if (isfromsnap || (sd->parent_fromsnap_guid == 0 && istosnap))
34dc7c2f 327 sd->parent_fromsnap_guid = guid;
34dc7c2f 328
05748550 329 if (!sd->recursive) {
b9c07ec7
CM
330 /*
331 * To allow a doall stream to work properly
332 * with a NULL fromsnap
333 */
dd59c422 334 if (sd->doall && from == NULL && !sd->seenfrom)
b9c07ec7 335 sd->seenfrom = B_TRUE;
b9c07ec7 336
05748550
AG
337 if (!sd->seenfrom && isfromsnap) {
338 sd->seenfrom = B_TRUE;
339 zfs_close(zhp);
340 return (0);
341 }
342
e890dd85 343 if ((sd->seento || !sd->seenfrom) && !istosnapwithnofrom) {
05748550
AG
344 zfs_close(zhp);
345 return (0);
346 }
347
348 if (istosnap)
349 sd->seento = B_TRUE;
350 }
351
dd59c422 352 nvlist_t *nv = fnvlist_alloc();
faa97c16 353 send_iterate_prop(zhp, sd->backup, nv);
60a2434b
RM
354 fnvlist_add_nvlist(sd->snapprops, snapname, nv);
355 fnvlist_free(nv);
dd59c422 356
9c5e88b1 357 if (sd->holds) {
f2b36b2d
RM
358 nvlist_t *holds;
359 if (lzc_get_holds(zhp->zfs_name, &holds) == 0) {
60a2434b 360 fnvlist_add_nvlist(sd->snapholds, snapname, holds);
f2b36b2d 361 fnvlist_free(holds);
9c5e88b1 362 }
9c5e88b1 363 }
b128c09f 364
34dc7c2f
BB
365 zfs_close(zhp);
366 return (0);
367}
368
2b6b7111
RM
369/*
370 * Collect all valid props from the handle snap into an nvlist.
371 */
34dc7c2f 372static void
faa97c16 373send_iterate_prop(zfs_handle_t *zhp, boolean_t received_only, nvlist_t *nv)
34dc7c2f 374{
2b6b7111 375 nvlist_t *props;
34dc7c2f 376
faa97c16 377 if (received_only)
378 props = zfs_get_recvd_props(zhp);
379 else
380 props = zhp->zfs_props;
381
2b6b7111 382 nvpair_t *elem = NULL;
faa97c16 383 while ((elem = nvlist_next_nvpair(props, elem)) != NULL) {
34dc7c2f
BB
384 char *propname = nvpair_name(elem);
385 zfs_prop_t prop = zfs_name_to_prop(propname);
34dc7c2f 386
428870ff
BB
387 if (!zfs_prop_user(propname)) {
388 /*
389 * Realistically, this should never happen. However,
390 * we want the ability to add DSL properties without
391 * needing to make incompatible version changes. We
392 * need to ignore unknown properties to allow older
393 * software to still send datasets containing these
394 * properties, with the unknown properties elided.
395 */
396 if (prop == ZPROP_INVAL)
397 continue;
9babb374 398
428870ff
BB
399 if (zfs_prop_readonly(prop))
400 continue;
401 }
34dc7c2f 402
2b6b7111
RM
403 nvlist_t *propnv = fnvpair_value_nvlist(elem);
404
405 boolean_t isspacelimit = (prop == ZFS_PROP_QUOTA ||
406 prop == ZFS_PROP_RESERVATION ||
45d1cae3 407 prop == ZFS_PROP_REFQUOTA ||
2b6b7111
RM
408 prop == ZFS_PROP_REFRESERVATION);
409 if (isspacelimit && zhp->zfs_type == ZFS_TYPE_SNAPSHOT)
410 continue;
411
412 char *source;
413 if (nvlist_lookup_string(propnv, ZPROP_SOURCE, &source) == 0) {
414 if (strcmp(source, zhp->zfs_name) != 0 &&
415 strcmp(source, ZPROP_SOURCE_VAL_RECVD) != 0)
b128c09f 416 continue;
2b6b7111 417 } else {
428870ff
BB
418 /*
419 * May have no source before SPA_VERSION_RECVD_PROPS,
420 * but is still modifiable.
421 */
2b6b7111 422 if (!isspacelimit)
34dc7c2f
BB
423 continue;
424 }
425
426 if (zfs_prop_user(propname) ||
427 zfs_prop_get_type(prop) == PROP_TYPE_STRING) {
428 char *value;
60a2434b
RM
429 value = fnvlist_lookup_string(propnv, ZPROP_VALUE);
430 fnvlist_add_string(nv, propname, value);
34dc7c2f
BB
431 } else {
432 uint64_t value;
60a2434b
RM
433 value = fnvlist_lookup_uint64(propnv, ZPROP_VALUE);
434 fnvlist_add_uint64(nv, propname, value);
34dc7c2f
BB
435 }
436 }
437}
438
e8cf3a4f
AP
439/*
440 * returns snapshot guid
441 * and returns 0 if the snapshot does not exist
442 */
443static uint64_t
444get_snap_guid(libzfs_handle_t *hdl, const char *fs, const char *snap)
445{
446 char name[MAXPATHLEN + 1];
447 uint64_t guid = 0;
448
449 if (fs == NULL || fs[0] == '\0' || snap == NULL || snap[0] == '\0')
450 return (guid);
451
452 (void) snprintf(name, sizeof (name), "%s@%s", fs, snap);
453 zfs_handle_t *zhp = zfs_open(hdl, name, ZFS_TYPE_SNAPSHOT);
454 if (zhp != NULL) {
455 guid = zfs_prop_get_int(zhp, ZFS_PROP_GUID);
456 zfs_close(zhp);
457 }
458
459 return (guid);
460}
461
66356240
K
462/*
463 * returns snapshot creation txg
464 * and returns 0 if the snapshot does not exist
465 */
466static uint64_t
467get_snap_txg(libzfs_handle_t *hdl, const char *fs, const char *snap)
468{
469 char name[ZFS_MAX_DATASET_NAME_LEN];
470 uint64_t txg = 0;
471
472 if (fs == NULL || fs[0] == '\0' || snap == NULL || snap[0] == '\0')
473 return (txg);
474
475 (void) snprintf(name, sizeof (name), "%s@%s", fs, snap);
476 if (zfs_dataset_exists(hdl, name, ZFS_TYPE_SNAPSHOT)) {
477 zfs_handle_t *zhp = zfs_open(hdl, name, ZFS_TYPE_SNAPSHOT);
478 if (zhp != NULL) {
479 txg = zfs_prop_get_int(zhp, ZFS_PROP_CREATETXG);
480 zfs_close(zhp);
481 }
482 }
483
484 return (txg);
485}
486
45d1cae3 487/*
0c1c746a 488 * Recursively generate nvlists describing datasets. See comment
45d1cae3
BB
489 * for the data structure send_data_t above for description of contents
490 * of the nvlist.
491 */
34dc7c2f
BB
492static int
493send_iterate_fs(zfs_handle_t *zhp, void *arg)
494{
495 send_data_t *sd = arg;
b5256303 496 nvlist_t *nvfs = NULL, *nv = NULL;
428870ff 497 int rv = 0;
4c0883fb 498 uint64_t min_txg = 0, max_txg = 0;
66356240 499 uint64_t txg = zhp->zfs_dmustats.dds_creation_txg;
34dc7c2f 500 uint64_t guid = zhp->zfs_dmustats.dds_guid;
66356240 501 uint64_t fromsnap_txg, tosnap_txg;
34dc7c2f
BB
502 char guidstring[64];
503
0c1c746a
RM
504 /* These fields are restored on return from a recursive call. */
505 uint64_t parent_fromsnap_guid_save = sd->parent_fromsnap_guid;
506 uint64_t fromsnap_txg_save = sd->fromsnap_txg;
507 uint64_t tosnap_txg_save = sd->tosnap_txg;
508
66356240
K
509 fromsnap_txg = get_snap_txg(zhp->zfs_hdl, zhp->zfs_name, sd->fromsnap);
510 if (fromsnap_txg != 0)
511 sd->fromsnap_txg = fromsnap_txg;
512
513 tosnap_txg = get_snap_txg(zhp->zfs_hdl, zhp->zfs_name, sd->tosnap);
514 if (tosnap_txg != 0)
515 sd->tosnap_txg = tosnap_txg;
516
517 /*
0c1c746a 518 * On the send side, if the current dataset does not have tosnap,
66356240
K
519 * perform two additional checks:
520 *
0c1c746a
RM
521 * - Skip sending the current dataset if it was created later than
522 * the parent tosnap.
523 * - Return error if the current dataset was created earlier than
099fa7e4 524 * the parent tosnap, unless --skip-missing specified. Then
0c1c746a 525 * just print a warning.
66356240
K
526 */
527 if (sd->tosnap != NULL && tosnap_txg == 0) {
528 if (sd->tosnap_txg != 0 && txg > sd->tosnap_txg) {
529 if (sd->verbose) {
530 (void) fprintf(stderr, dgettext(TEXT_DOMAIN,
531 "skipping dataset %s: snapshot %s does "
532 "not exist\n"), zhp->zfs_name, sd->tosnap);
533 }
099fa7e4
PCG
534 } else if (sd->skipmissing) {
535 (void) fprintf(stderr, dgettext(TEXT_DOMAIN,
536 "WARNING: skipping dataset %s and its children:"
537 " snapshot %s does not exist\n"),
538 zhp->zfs_name, sd->tosnap);
66356240
K
539 } else {
540 (void) fprintf(stderr, dgettext(TEXT_DOMAIN,
541 "cannot send %s@%s%s: snapshot %s@%s does not "
542 "exist\n"), sd->fsname, sd->tosnap, sd->recursive ?
543 dgettext(TEXT_DOMAIN, " recursively") : "",
544 zhp->zfs_name, sd->tosnap);
30af21b0 545 rv = EZFS_NOENT;
66356240
K
546 }
547 goto out;
548 }
549
4c0883fb
AP
550 nvfs = fnvlist_alloc();
551 fnvlist_add_string(nvfs, "name", zhp->zfs_name);
0c1c746a 552 fnvlist_add_uint64(nvfs, "parentfromsnap", sd->parent_fromsnap_guid);
34dc7c2f 553
0c1c746a 554 if (zhp->zfs_dmustats.dds_origin[0] != '\0') {
34dc7c2f
BB
555 zfs_handle_t *origin = zfs_open(zhp->zfs_hdl,
556 zhp->zfs_dmustats.dds_origin, ZFS_TYPE_SNAPSHOT);
66356240
K
557 if (origin == NULL) {
558 rv = -1;
559 goto out;
560 }
4c0883fb
AP
561 fnvlist_add_uint64(nvfs, "origin",
562 origin->zfs_dmustats.dds_guid);
ad7e908a 563 zfs_close(origin);
34dc7c2f
BB
564 }
565
0c1c746a 566 /* Iterate over props. */
9c5e88b1 567 if (sd->props || sd->backup || sd->recursive) {
4c0883fb 568 nv = fnvlist_alloc();
9c5e88b1 569 send_iterate_prop(zhp, sd->backup, nv);
0c1c746a 570 fnvlist_add_nvlist(nvfs, "props", nv);
9c5e88b1 571 }
b5256303
TC
572 if (zfs_prop_get_int(zhp, ZFS_PROP_ENCRYPTION) != ZIO_CRYPT_OFF) {
573 boolean_t encroot;
574
0c1c746a 575 /* Determine if this dataset is an encryption root. */
b5256303
TC
576 if (zfs_crypto_get_encryption_root(zhp, &encroot, NULL) != 0) {
577 rv = -1;
578 goto out;
579 }
580
581 if (encroot)
4c0883fb 582 fnvlist_add_boolean(nvfs, "is_encroot");
b5256303
TC
583
584 /*
585 * Encrypted datasets can only be sent with properties if
586 * the raw flag is specified because the receive side doesn't
587 * currently have a mechanism for recursively asking the user
588 * for new encryption parameters.
589 */
590 if (!sd->raw) {
591 (void) fprintf(stderr, dgettext(TEXT_DOMAIN,
592 "cannot send %s@%s: encrypted dataset %s may not "
593 "be sent with properties without the raw flag\n"),
594 sd->fsname, sd->tosnap, zhp->zfs_name);
595 rv = -1;
596 goto out;
597 }
598
599 }
600
f94b3cbf 601 /*
0c1c746a
RM
602 * Iterate over snaps, and set sd->parent_fromsnap_guid.
603 *
f94b3cbf
TC
604 * If this is a "doall" send, a replicate send or we're just trying
605 * to gather a list of previous snapshots, iterate through all the
606 * snaps in the txg range. Otherwise just look at the one we're
607 * interested in.
608 */
0c1c746a
RM
609 sd->parent_fromsnap_guid = 0;
610 sd->parent_snaps = fnvlist_alloc();
611 sd->snapprops = fnvlist_alloc();
612 if (sd->holds)
613 sd->snapholds = fnvlist_alloc();
f94b3cbf
TC
614 if (sd->doall || sd->replicate || sd->tosnap == NULL) {
615 if (!sd->replicate && fromsnap_txg != 0)
616 min_txg = fromsnap_txg;
617 if (!sd->replicate && tosnap_txg != 0)
618 max_txg = tosnap_txg;
399b9819 619 (void) zfs_iter_snapshots_sorted(zhp, send_iterate_snap, sd,
f94b3cbf
TC
620 min_txg, max_txg);
621 } else {
0c1c746a 622 char snapname[MAXPATHLEN];
f94b3cbf
TC
623 zfs_handle_t *snap;
624
f0ce0436 625 (void) snprintf(snapname, sizeof (snapname), "%s@%s",
f94b3cbf
TC
626 zhp->zfs_name, sd->tosnap);
627 if (sd->fromsnap != NULL)
628 sd->seenfrom = B_TRUE;
0c1c746a 629 snap = zfs_open(zhp->zfs_hdl, snapname, ZFS_TYPE_SNAPSHOT);
f94b3cbf
TC
630 if (snap != NULL)
631 (void) send_iterate_snap(snap, sd);
632 }
633
4c0883fb 634 fnvlist_add_nvlist(nvfs, "snaps", sd->parent_snaps);
4c0883fb 635 fnvlist_free(sd->parent_snaps);
0c1c746a 636 fnvlist_add_nvlist(nvfs, "snapprops", sd->snapprops);
4c0883fb 637 fnvlist_free(sd->snapprops);
0c1c746a
RM
638 if (sd->holds) {
639 fnvlist_add_nvlist(nvfs, "snapholds", sd->snapholds);
640 fnvlist_free(sd->snapholds);
641 }
34dc7c2f 642
7a6c12fd
AJ
643 /* Do not allow the size of the properties list to exceed the limit */
644 if ((fnvlist_size(nvfs) + fnvlist_size(sd->fss)) >
645 zhp->zfs_hdl->libzfs_max_nvlist) {
646 (void) fprintf(stderr, dgettext(TEXT_DOMAIN,
647 "warning: cannot send %s@%s: the size of the list of "
648 "snapshots and properties is too large to be received "
649 "successfully.\n"
650 "Select a smaller number of snapshots to send.\n"),
651 zhp->zfs_name, sd->tosnap);
652 rv = EZFS_NOSPC;
653 goto out;
654 }
0c1c746a 655 /* Add this fs to nvlist. */
34dc7c2f
BB
656 (void) snprintf(guidstring, sizeof (guidstring),
657 "0x%llx", (longlong_t)guid);
4c0883fb 658 fnvlist_add_nvlist(sd->fss, guidstring, nvfs);
34dc7c2f 659
0c1c746a 660 /* Iterate over children. */
428870ff 661 if (sd->recursive)
399b9819 662 rv = zfs_iter_filesystems(zhp, send_iterate_fs, sd);
34dc7c2f 663
66356240 664out:
0c1c746a 665 /* Restore saved fields. */
34dc7c2f 666 sd->parent_fromsnap_guid = parent_fromsnap_guid_save;
66356240
K
667 sd->fromsnap_txg = fromsnap_txg_save;
668 sd->tosnap_txg = tosnap_txg_save;
0c1c746a 669
4c0883fb
AP
670 fnvlist_free(nv);
671 fnvlist_free(nvfs);
34dc7c2f
BB
672
673 zfs_close(zhp);
674 return (rv);
675}
676
677static int
678gather_nvlist(libzfs_handle_t *hdl, const char *fsname, const char *fromsnap,
f94b3cbf 679 const char *tosnap, boolean_t recursive, boolean_t raw, boolean_t doall,
099fa7e4
PCG
680 boolean_t replicate, boolean_t skipmissing, boolean_t verbose,
681 boolean_t backup, boolean_t holds, boolean_t props, nvlist_t **nvlp,
682 avl_tree_t **avlp)
34dc7c2f
BB
683{
684 zfs_handle_t *zhp;
685 send_data_t sd = { 0 };
686 int error;
687
688 zhp = zfs_open(hdl, fsname, ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME);
689 if (zhp == NULL)
690 return (EZFS_BADTYPE);
691
60a2434b 692 sd.fss = fnvlist_alloc();
66356240 693 sd.fsname = fsname;
34dc7c2f
BB
694 sd.fromsnap = fromsnap;
695 sd.tosnap = tosnap;
428870ff 696 sd.recursive = recursive;
b5256303 697 sd.raw = raw;
f94b3cbf 698 sd.doall = doall;
4c0883fb 699 sd.replicate = replicate;
099fa7e4 700 sd.skipmissing = skipmissing;
66356240 701 sd.verbose = verbose;
faa97c16 702 sd.backup = backup;
9c5e88b1
PZ
703 sd.holds = holds;
704 sd.props = props;
34dc7c2f
BB
705
706 if ((error = send_iterate_fs(zhp, &sd)) != 0) {
60a2434b 707 fnvlist_free(sd.fss);
34dc7c2f
BB
708 if (avlp != NULL)
709 *avlp = NULL;
710 *nvlp = NULL;
711 return (error);
712 }
713
714 if (avlp != NULL && (*avlp = fsavl_create(sd.fss)) == NULL) {
60a2434b 715 fnvlist_free(sd.fss);
34dc7c2f
BB
716 *nvlp = NULL;
717 return (EZFS_NOMEM);
718 }
719
720 *nvlp = sd.fss;
721 return (0);
722}
723
34dc7c2f
BB
724/*
725 * Routines specific to "zfs send"
726 */
727typedef struct send_dump_data {
728 /* these are all just the short snapname (the part after the @) */
729 const char *fromsnap;
730 const char *tosnap;
eca7b760 731 char prevsnap[ZFS_MAX_DATASET_NAME_LEN];
572e2857 732 uint64_t prevsnap_obj;
34dc7c2f 733 boolean_t seenfrom, seento, replicate, doall, fromorigin;
30af21b0 734 boolean_t dryrun, parsable, progress, embed_data, std_out;
9c5e88b1 735 boolean_t large_block, compress, raw, holds;
34dc7c2f
BB
736 int outfd;
737 boolean_t err;
738 nvlist_t *fss;
95fd54a1 739 nvlist_t *snapholds;
34dc7c2f 740 avl_tree_t *fsavl;
428870ff
BB
741 snapfilter_cb_t *filter_cb;
742 void *filter_cb_arg;
743 nvlist_t *debugnv;
eca7b760 744 char holdtag[ZFS_MAX_DATASET_NAME_LEN];
572e2857 745 int cleanup_fd;
30af21b0 746 int verbosity;
330d06f9 747 uint64_t size;
34dc7c2f
BB
748} send_dump_data_t;
749
330d06f9 750static int
cf7684bc 751zfs_send_space(zfs_handle_t *zhp, const char *snapname, const char *from,
752 enum lzc_send_flags flags, uint64_t *spacep)
330d06f9 753{
cf7684bc 754 assert(snapname != NULL);
330d06f9 755
a8747c04
RM
756 int error = lzc_send_space(snapname, from, flags, spacep);
757 if (error == 0)
758 return (0);
759
d68a2bfa 760 char errbuf[ERRBUFLEN];
a8747c04
RM
761 (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
762 "warning: cannot estimate space for '%s'"), snapname);
330d06f9 763
a8747c04
RM
764 libzfs_handle_t *hdl = zhp->zfs_hdl;
765 switch (error) {
766 case EXDEV:
767 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
768 "not an earlier snapshot from the same fs"));
769 return (zfs_error(hdl, EZFS_CROSSTARGET, errbuf));
770
771 case ENOENT:
772 if (zfs_dataset_exists(hdl, snapname,
773 ZFS_TYPE_SNAPSHOT)) {
330d06f9 774 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
a8747c04
RM
775 "incremental source (%s) does not exist"),
776 snapname);
330d06f9 777 }
a8747c04
RM
778 return (zfs_error(hdl, EZFS_NOENT, errbuf));
779
780 case EDQUOT:
781 case EFBIG:
782 case EIO:
783 case ENOLINK:
784 case ENOSPC:
785 case ENOSTR:
786 case ENXIO:
787 case EPIPE:
788 case ERANGE:
789 case EFAULT:
790 case EROFS:
791 case EINVAL:
792 zfs_error_aux(hdl, "%s", strerror(error));
793 return (zfs_error(hdl, EZFS_BADBACKUP, errbuf));
794
795 default:
796 return (zfs_standard_error(hdl, error, errbuf));
330d06f9 797 }
330d06f9
MA
798}
799
34dc7c2f
BB
800/*
801 * Dumps a backup of the given snapshot (incremental from fromsnap if it's not
802 * NULL) to the file descriptor specified by outfd.
803 */
804static int
572e2857 805dump_ioctl(zfs_handle_t *zhp, const char *fromsnap, uint64_t fromsnap_obj,
9b67f605
MA
806 boolean_t fromorigin, int outfd, enum lzc_send_flags flags,
807 nvlist_t *debugnv)
34dc7c2f 808{
13fe0198 809 zfs_cmd_t zc = {"\0"};
34dc7c2f 810 libzfs_handle_t *hdl = zhp->zfs_hdl;
428870ff 811 nvlist_t *thisdbg;
34dc7c2f
BB
812
813 assert(zhp->zfs_type == ZFS_TYPE_SNAPSHOT);
572e2857 814 assert(fromsnap_obj == 0 || !fromorigin);
34dc7c2f
BB
815
816 (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
34dc7c2f
BB
817 zc.zc_cookie = outfd;
818 zc.zc_obj = fromorigin;
572e2857
BB
819 zc.zc_sendobj = zfs_prop_get_int(zhp, ZFS_PROP_OBJSETID);
820 zc.zc_fromobj = fromsnap_obj;
9b67f605 821 zc.zc_flags = flags;
428870ff 822
25074b47
RM
823 if (debugnv != NULL) {
824 thisdbg = fnvlist_alloc();
825 if (fromsnap != NULL && fromsnap[0] != '\0')
826 fnvlist_add_string(thisdbg, "fromsnap", fromsnap);
428870ff
BB
827 }
828
330d06f9 829 if (zfs_ioctl(zhp->zfs_hdl, ZFS_IOC_SEND, &zc) != 0) {
d68a2bfa 830 char errbuf[ERRBUFLEN];
25074b47
RM
831 int error = errno;
832
806739f9
DS
833 (void) snprintf(errbuf, sizeof (errbuf), "%s '%s'",
834 dgettext(TEXT_DOMAIN, "warning: cannot send"),
835 zhp->zfs_name);
34dc7c2f 836
25074b47
RM
837 if (debugnv != NULL) {
838 fnvlist_add_uint64(thisdbg, "error", error);
60a2434b 839 fnvlist_add_nvlist(debugnv, zhp->zfs_name, thisdbg);
25074b47 840 fnvlist_free(thisdbg);
428870ff 841 }
428870ff 842
25074b47 843 switch (error) {
34dc7c2f
BB
844 case EXDEV:
845 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
846 "not an earlier snapshot from the same fs"));
847 return (zfs_error(hdl, EZFS_CROSSTARGET, errbuf));
848
b5256303
TC
849 case EACCES:
850 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
851 "source key must be loaded"));
852 return (zfs_error(hdl, EZFS_CRYPTOFAILED, errbuf));
853
34dc7c2f
BB
854 case ENOENT:
855 if (zfs_dataset_exists(hdl, zc.zc_name,
856 ZFS_TYPE_SNAPSHOT)) {
857 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
858 "incremental source (@%s) does not exist"),
859 zc.zc_value);
860 }
861 return (zfs_error(hdl, EZFS_NOENT, errbuf));
862
863 case EDQUOT:
864 case EFBIG:
865 case EIO:
866 case ENOLINK:
867 case ENOSPC:
868 case ENOSTR:
869 case ENXIO:
870 case EPIPE:
871 case ERANGE:
872 case EFAULT:
873 case EROFS:
860051f1 874 case EINVAL:
f00f4690 875 zfs_error_aux(hdl, "%s", strerror(errno));
34dc7c2f
BB
876 return (zfs_error(hdl, EZFS_BADBACKUP, errbuf));
877
878 default:
879 return (zfs_standard_error(hdl, errno, errbuf));
880 }
881 }
882
25074b47 883 if (debugnv != NULL) {
60a2434b 884 fnvlist_add_nvlist(debugnv, zhp->zfs_name, thisdbg);
25074b47
RM
885 fnvlist_free(thisdbg);
886 }
428870ff 887
34dc7c2f
BB
888 return (0);
889}
890
95fd54a1
SH
891static void
892gather_holds(zfs_handle_t *zhp, send_dump_data_t *sdd)
572e2857 893{
572e2857
BB
894 assert(zhp->zfs_type == ZFS_TYPE_SNAPSHOT);
895
896 /*
95fd54a1 897 * zfs_send() only sets snapholds for sends that need them,
572e2857
BB
898 * e.g. replication and doall.
899 */
95fd54a1
SH
900 if (sdd->snapholds == NULL)
901 return;
572e2857 902
95fd54a1 903 fnvlist_add_string(sdd->snapholds, zhp->zfs_name, sdd->holdtag);
572e2857
BB
904}
905
30af21b0
PD
906int
907zfs_send_progress(zfs_handle_t *zhp, int fd, uint64_t *bytes_written,
908 uint64_t *blocks_visited)
909{
659f4008
RM
910 zfs_cmd_t zc = {"\0"};
911
24f1aa02
RM
912 if (bytes_written != NULL)
913 *bytes_written = 0;
914 if (blocks_visited != NULL)
915 *blocks_visited = 0;
30af21b0
PD
916 (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
917 zc.zc_cookie = fd;
918 if (zfs_ioctl(zhp->zfs_hdl, ZFS_IOC_SEND_PROGRESS, &zc) != 0)
919 return (errno);
920 if (bytes_written != NULL)
921 *bytes_written = zc.zc_cookie;
922 if (blocks_visited != NULL)
923 *blocks_visited = zc.zc_objset_type;
924 return (0);
925}
926
37abac6d
BP
927static void *
928send_progress_thread(void *arg)
929{
930 progress_arg_t *pa = arg;
37abac6d 931 zfs_handle_t *zhp = pa->pa_zhp;
30af21b0
PD
932 uint64_t bytes;
933 uint64_t blocks;
37abac6d 934 char buf[16];
37abac6d 935 time_t t;
8ab27948 936 struct tm tm;
fbcc25c9
RM
937 int err;
938
939 if (!pa->pa_parsable) {
940 (void) fprintf(stderr,
941 "TIME %s %sSNAPSHOT %s\n",
942 pa->pa_estimate ? "BYTES" : " SENT",
943 pa->pa_verbosity >= 2 ? " BLOCKS " : "",
944 zhp->zfs_name);
945 }
37abac6d
BP
946
947 /*
948 * Print the progress from ZFS_IOC_SEND_PROGRESS every second.
949 */
950 for (;;) {
951 (void) sleep(1);
30af21b0
PD
952 if ((err = zfs_send_progress(zhp, pa->pa_fd, &bytes,
953 &blocks)) != 0) {
954 if (err == EINTR || err == ENOENT)
955 return ((void *)0);
956 return ((void *)(uintptr_t)err);
957 }
37abac6d 958
37abac6d 959 (void) time(&t);
8ab27948 960 localtime_r(&t, &tm);
37abac6d 961
30af21b0
PD
962 if (pa->pa_verbosity >= 2 && pa->pa_parsable) {
963 (void) fprintf(stderr,
964 "%02d:%02d:%02d\t%llu\t%llu\t%s\n",
8ab27948 965 tm.tm_hour, tm.tm_min, tm.tm_sec,
30af21b0
PD
966 (u_longlong_t)bytes, (u_longlong_t)blocks,
967 zhp->zfs_name);
968 } else if (pa->pa_verbosity >= 2) {
969 zfs_nicenum(bytes, buf, sizeof (buf));
970 (void) fprintf(stderr,
971 "%02d:%02d:%02d %5s %8llu %s\n",
8ab27948 972 tm.tm_hour, tm.tm_min, tm.tm_sec,
30af21b0
PD
973 buf, (u_longlong_t)blocks, zhp->zfs_name);
974 } else if (pa->pa_parsable) {
37abac6d 975 (void) fprintf(stderr, "%02d:%02d:%02d\t%llu\t%s\n",
8ab27948 976 tm.tm_hour, tm.tm_min, tm.tm_sec,
30af21b0 977 (u_longlong_t)bytes, zhp->zfs_name);
37abac6d 978 } else {
e7fbeb60 979 zfs_nicebytes(bytes, buf, sizeof (buf));
37abac6d 980 (void) fprintf(stderr, "%02d:%02d:%02d %5s %s\n",
8ab27948 981 tm.tm_hour, tm.tm_min, tm.tm_sec,
37abac6d
BP
982 buf, zhp->zfs_name);
983 }
984 }
985}
986
e3e4c30b
AZ
987static boolean_t
988send_progress_thread_exit(libzfs_handle_t *hdl, pthread_t ptid)
989{
990 void *status = NULL;
991 (void) pthread_cancel(ptid);
992 (void) pthread_join(ptid, &status);
993 int error = (int)(uintptr_t)status;
994 if (error != 0 && status != PTHREAD_CANCELED)
995 return (zfs_standard_error(hdl, error,
996 dgettext(TEXT_DOMAIN, "progress thread exited nonzero")));
997 else
998 return (B_FALSE);
999}
1000
47dfff3b
MA
1001static void
1002send_print_verbose(FILE *fout, const char *tosnap, const char *fromsnap,
1003 uint64_t size, boolean_t parsable)
1004{
1005 if (parsable) {
1006 if (fromsnap != NULL) {
447e90e3
RM
1007 (void) fprintf(fout, dgettext(TEXT_DOMAIN,
1008 "incremental\t%s\t%s"), fromsnap, tosnap);
47dfff3b 1009 } else {
447e90e3
RM
1010 (void) fprintf(fout, dgettext(TEXT_DOMAIN,
1011 "full\t%s"), tosnap);
47dfff3b 1012 }
447e90e3 1013 (void) fprintf(fout, "\t%llu", (longlong_t)size);
47dfff3b
MA
1014 } else {
1015 if (fromsnap != NULL) {
1016 if (strchr(fromsnap, '@') == NULL &&
1017 strchr(fromsnap, '#') == NULL) {
1018 (void) fprintf(fout, dgettext(TEXT_DOMAIN,
447e90e3 1019 "send from @%s to %s"), fromsnap, tosnap);
47dfff3b
MA
1020 } else {
1021 (void) fprintf(fout, dgettext(TEXT_DOMAIN,
447e90e3 1022 "send from %s to %s"), fromsnap, tosnap);
47dfff3b
MA
1023 }
1024 } else {
1025 (void) fprintf(fout, dgettext(TEXT_DOMAIN,
447e90e3
RM
1026 "full send of %s"), tosnap);
1027 }
1028 if (size != 0) {
1029 char buf[16];
1030 zfs_nicebytes(size, buf, sizeof (buf));
1031 (void) fprintf(fout, dgettext(TEXT_DOMAIN,
1032 " estimated size is %s"), buf);
47dfff3b 1033 }
47dfff3b
MA
1034 }
1035 (void) fprintf(fout, "\n");
1036}
1037
1ae78351
RM
1038/*
1039 * Send a single filesystem snapshot, updating the send dump data.
1040 * This interface is intended for use as a zfs_iter_snapshots_sorted visitor.
1041 */
34dc7c2f
BB
1042static int
1043dump_snapshot(zfs_handle_t *zhp, void *arg)
1044{
1045 send_dump_data_t *sdd = arg;
37abac6d
BP
1046 progress_arg_t pa = { 0 };
1047 pthread_t tid;
572e2857 1048 char *thissnap;
2aa34383 1049 enum lzc_send_flags flags = 0;
34dc7c2f 1050 int err;
330d06f9 1051 boolean_t isfromsnap, istosnap, fromorigin;
428870ff 1052 boolean_t exclude = B_FALSE;
93f6d7e2 1053 FILE *fout = sdd->std_out ? stdout : stderr;
34dc7c2f 1054
95fd54a1 1055 err = 0;
34dc7c2f 1056 thissnap = strchr(zhp->zfs_name, '@') + 1;
428870ff
BB
1057 isfromsnap = (sdd->fromsnap != NULL &&
1058 strcmp(sdd->fromsnap, thissnap) == 0);
34dc7c2f 1059
428870ff 1060 if (!sdd->seenfrom && isfromsnap) {
95fd54a1
SH
1061 gather_holds(zhp, sdd);
1062 sdd->seenfrom = B_TRUE;
1ae78351 1063 (void) strlcpy(sdd->prevsnap, thissnap, sizeof (sdd->prevsnap));
95fd54a1 1064 sdd->prevsnap_obj = zfs_prop_get_int(zhp, ZFS_PROP_OBJSETID);
34dc7c2f 1065 zfs_close(zhp);
95fd54a1 1066 return (0);
34dc7c2f
BB
1067 }
1068
1069 if (sdd->seento || !sdd->seenfrom) {
1070 zfs_close(zhp);
1071 return (0);
1072 }
1073
428870ff
BB
1074 istosnap = (strcmp(sdd->tosnap, thissnap) == 0);
1075 if (istosnap)
1076 sdd->seento = B_TRUE;
1077
2aa34383
DK
1078 if (sdd->large_block)
1079 flags |= LZC_SEND_FLAG_LARGE_BLOCK;
1080 if (sdd->embed_data)
1081 flags |= LZC_SEND_FLAG_EMBED_DATA;
1082 if (sdd->compress)
1083 flags |= LZC_SEND_FLAG_COMPRESS;
b5256303
TC
1084 if (sdd->raw)
1085 flags |= LZC_SEND_FLAG_RAW;
2aa34383 1086
428870ff
BB
1087 if (!sdd->doall && !isfromsnap && !istosnap) {
1088 if (sdd->replicate) {
1089 char *snapname;
1090 nvlist_t *snapprops;
1091 /*
1092 * Filter out all intermediate snapshots except origin
1093 * snapshots needed to replicate clones.
1094 */
1095 nvlist_t *nvfs = fsavl_find(sdd->fsavl,
1096 zhp->zfs_dmustats.dds_guid, &snapname);
1097
97bbeeb9
RM
1098 if (nvfs != NULL) {
1099 snapprops = fnvlist_lookup_nvlist(nvfs,
1100 "snapprops");
1101 snapprops = fnvlist_lookup_nvlist(snapprops,
1102 thissnap);
1103 exclude = !nvlist_exists(snapprops,
1104 "is_clone_origin");
1105 }
428870ff
BB
1106 } else {
1107 exclude = B_TRUE;
1108 }
1109 }
1110
1111 /*
1112 * If a filter function exists, call it to determine whether
1113 * this snapshot will be sent.
1114 */
1115 if (exclude || (sdd->filter_cb != NULL &&
1116 sdd->filter_cb(zhp, sdd->filter_cb_arg) == B_FALSE)) {
1117 /*
1118 * This snapshot is filtered out. Don't send it, and don't
572e2857 1119 * set prevsnap_obj, so it will be as if this snapshot didn't
428870ff
BB
1120 * exist, and the next accepted snapshot will be sent as
1121 * an incremental from the last accepted one, or as the
1122 * first (and full) snapshot in the case of a replication,
1123 * non-incremental send.
1124 */
1125 zfs_close(zhp);
1126 return (0);
1127 }
1128
95fd54a1 1129 gather_holds(zhp, sdd);
330d06f9
MA
1130 fromorigin = sdd->prevsnap[0] == '\0' &&
1131 (sdd->fromorigin || sdd->replicate);
1132
30af21b0 1133 if (sdd->verbosity != 0) {
47dfff3b 1134 uint64_t size = 0;
cf7684bc 1135 char fromds[ZFS_MAX_DATASET_NAME_LEN];
330d06f9 1136
cf7684bc 1137 if (sdd->prevsnap[0] != '\0') {
1138 (void) strlcpy(fromds, zhp->zfs_name, sizeof (fromds));
1139 *(strchr(fromds, '@') + 1) = '\0';
1140 (void) strlcat(fromds, sdd->prevsnap, sizeof (fromds));
1141 }
1142 if (zfs_send_space(zhp, zhp->zfs_name,
1ae78351 1143 sdd->prevsnap[0] ? fromds : NULL, flags, &size) == 0) {
cf7684bc 1144 send_print_verbose(fout, zhp->zfs_name,
1145 sdd->prevsnap[0] ? sdd->prevsnap : NULL,
1146 size, sdd->parsable);
1ae78351 1147 sdd->size += size;
cf7684bc 1148 }
34dc7c2f
BB
1149 }
1150
330d06f9 1151 if (!sdd->dryrun) {
37abac6d
BP
1152 /*
1153 * If progress reporting is requested, spawn a new thread to
1154 * poll ZFS_IOC_SEND_PROGRESS at a regular interval.
1155 */
1156 if (sdd->progress) {
1157 pa.pa_zhp = zhp;
1158 pa.pa_fd = sdd->outfd;
1159 pa.pa_parsable = sdd->parsable;
30af21b0
PD
1160 pa.pa_estimate = B_FALSE;
1161 pa.pa_verbosity = sdd->verbosity;
37abac6d
BP
1162
1163 if ((err = pthread_create(&tid, NULL,
23d70cde 1164 send_progress_thread, &pa)) != 0) {
37abac6d
BP
1165 zfs_close(zhp);
1166 return (err);
1167 }
1168 }
1169
330d06f9 1170 err = dump_ioctl(zhp, sdd->prevsnap, sdd->prevsnap_obj,
9b67f605 1171 fromorigin, sdd->outfd, flags, sdd->debugnv);
37abac6d 1172
e3e4c30b
AZ
1173 if (sdd->progress &&
1174 send_progress_thread_exit(zhp->zfs_hdl, tid))
1175 return (-1);
330d06f9 1176 }
34dc7c2f 1177
a51288aa 1178 (void) strlcpy(sdd->prevsnap, thissnap, sizeof (sdd->prevsnap));
572e2857 1179 sdd->prevsnap_obj = zfs_prop_get_int(zhp, ZFS_PROP_OBJSETID);
34dc7c2f
BB
1180 zfs_close(zhp);
1181 return (err);
1182}
1183
1910a308
RM
1184/*
1185 * Send all snapshots for a filesystem, updating the send dump data.
1186 */
34dc7c2f 1187static int
1910a308 1188dump_filesystem(zfs_handle_t *zhp, send_dump_data_t *sdd)
34dc7c2f
BB
1189{
1190 int rv = 0;
34dc7c2f 1191 boolean_t missingfrom = B_FALSE;
13fe0198 1192 zfs_cmd_t zc = {"\0"};
4c0883fb 1193 uint64_t min_txg = 0, max_txg = 0;
34dc7c2f 1194
1910a308
RM
1195 /*
1196 * Make sure the tosnap exists.
1197 */
34dc7c2f
BB
1198 (void) snprintf(zc.zc_name, sizeof (zc.zc_name), "%s@%s",
1199 zhp->zfs_name, sdd->tosnap);
b834b58a 1200 if (zfs_ioctl(zhp->zfs_hdl, ZFS_IOC_OBJSET_STATS, &zc) != 0) {
330d06f9
MA
1201 (void) fprintf(stderr, dgettext(TEXT_DOMAIN,
1202 "WARNING: could not send %s@%s: does not exist\n"),
34dc7c2f
BB
1203 zhp->zfs_name, sdd->tosnap);
1204 sdd->err = B_TRUE;
1205 return (0);
1206 }
1207
1910a308
RM
1208 /*
1209 * If this fs does not have fromsnap, and we're doing
1210 * recursive, we need to send a full stream from the
1211 * beginning (or an incremental from the origin if this
1212 * is a clone). If we're doing non-recursive, then let
1213 * them get the error.
1214 */
34dc7c2f
BB
1215 if (sdd->replicate && sdd->fromsnap) {
1216 /*
1910a308 1217 * Make sure the fromsnap exists.
34dc7c2f
BB
1218 */
1219 (void) snprintf(zc.zc_name, sizeof (zc.zc_name), "%s@%s",
1220 zhp->zfs_name, sdd->fromsnap);
1910a308 1221 if (zfs_ioctl(zhp->zfs_hdl, ZFS_IOC_OBJSET_STATS, &zc) != 0)
34dc7c2f 1222 missingfrom = B_TRUE;
34dc7c2f
BB
1223 }
1224
1910a308
RM
1225 sdd->seenfrom = sdd->seento = B_FALSE;
1226 sdd->prevsnap[0] = '\0';
572e2857 1227 sdd->prevsnap_obj = 0;
428870ff
BB
1228 if (sdd->fromsnap == NULL || missingfrom)
1229 sdd->seenfrom = B_TRUE;
34dc7c2f 1230
f94b3cbf
TC
1231 /*
1232 * Iterate through all snapshots and process the ones we will be
1233 * sending. If we only have a "from" and "to" snapshot to deal
1234 * with, we can avoid iterating through all the other snapshots.
1235 */
1236 if (sdd->doall || sdd->replicate || sdd->tosnap == NULL) {
1910a308
RM
1237 if (!sdd->replicate) {
1238 if (sdd->fromsnap != NULL) {
1239 min_txg = get_snap_txg(zhp->zfs_hdl,
1240 zhp->zfs_name, sdd->fromsnap);
1241 }
1242 if (sdd->tosnap != NULL) {
1243 max_txg = get_snap_txg(zhp->zfs_hdl,
1244 zhp->zfs_name, sdd->tosnap);
1245 }
1246 }
1247 rv = zfs_iter_snapshots_sorted(zhp, dump_snapshot, sdd,
f94b3cbf
TC
1248 min_txg, max_txg);
1249 } else {
1250 char snapname[MAXPATHLEN] = { 0 };
1251 zfs_handle_t *snap;
1252
1910a308 1253 /* Dump fromsnap. */
f94b3cbf 1254 if (!sdd->seenfrom) {
f0ce0436 1255 (void) snprintf(snapname, sizeof (snapname),
f94b3cbf
TC
1256 "%s@%s", zhp->zfs_name, sdd->fromsnap);
1257 snap = zfs_open(zhp->zfs_hdl, snapname,
1258 ZFS_TYPE_SNAPSHOT);
1259 if (snap != NULL)
1260 rv = dump_snapshot(snap, sdd);
1261 else
1262 rv = -1;
1263 }
1264
1910a308 1265 /* Dump tosnap. */
f94b3cbf 1266 if (rv == 0) {
f0ce0436 1267 (void) snprintf(snapname, sizeof (snapname),
f94b3cbf
TC
1268 "%s@%s", zhp->zfs_name, sdd->tosnap);
1269 snap = zfs_open(zhp->zfs_hdl, snapname,
1270 ZFS_TYPE_SNAPSHOT);
1271 if (snap != NULL)
1272 rv = dump_snapshot(snap, sdd);
1273 else
1274 rv = -1;
1275 }
1276 }
1277
428870ff 1278 if (!sdd->seenfrom) {
330d06f9 1279 (void) fprintf(stderr, dgettext(TEXT_DOMAIN,
428870ff 1280 "WARNING: could not send %s@%s:\n"
330d06f9 1281 "incremental source (%s@%s) does not exist\n"),
428870ff
BB
1282 zhp->zfs_name, sdd->tosnap,
1283 zhp->zfs_name, sdd->fromsnap);
1284 sdd->err = B_TRUE;
1285 } else if (!sdd->seento) {
1286 if (sdd->fromsnap) {
330d06f9 1287 (void) fprintf(stderr, dgettext(TEXT_DOMAIN,
34dc7c2f 1288 "WARNING: could not send %s@%s:\n"
428870ff 1289 "incremental source (%s@%s) "
330d06f9 1290 "is not earlier than it\n"),
34dc7c2f
BB
1291 zhp->zfs_name, sdd->tosnap,
1292 zhp->zfs_name, sdd->fromsnap);
34dc7c2f 1293 } else {
330d06f9
MA
1294 (void) fprintf(stderr, dgettext(TEXT_DOMAIN,
1295 "WARNING: "
1296 "could not send %s@%s: does not exist\n"),
428870ff 1297 zhp->zfs_name, sdd->tosnap);
34dc7c2f 1298 }
428870ff 1299 sdd->err = B_TRUE;
34dc7c2f
BB
1300 }
1301
1302 return (rv);
1303}
1304
45932229
RM
1305/*
1306 * Send all snapshots for all filesystems in sdd.
1307 */
34dc7c2f 1308static int
45932229 1309dump_filesystems(zfs_handle_t *rzhp, send_dump_data_t *sdd)
34dc7c2f 1310{
34dc7c2f
BB
1311 nvpair_t *fspair;
1312 boolean_t needagain, progress;
1313
1314 if (!sdd->replicate)
1315 return (dump_filesystem(rzhp, sdd));
1316
428870ff
BB
1317 /* Mark the clone origin snapshots. */
1318 for (fspair = nvlist_next_nvpair(sdd->fss, NULL); fspair;
1319 fspair = nvlist_next_nvpair(sdd->fss, fspair)) {
1320 nvlist_t *nvfs;
1321 uint64_t origin_guid = 0;
1322
60a2434b 1323 nvfs = fnvpair_value_nvlist(fspair);
428870ff
BB
1324 (void) nvlist_lookup_uint64(nvfs, "origin", &origin_guid);
1325 if (origin_guid != 0) {
1326 char *snapname;
1327 nvlist_t *origin_nv = fsavl_find(sdd->fsavl,
1328 origin_guid, &snapname);
1329 if (origin_nv != NULL) {
1330 nvlist_t *snapprops;
60a2434b
RM
1331 snapprops = fnvlist_lookup_nvlist(origin_nv,
1332 "snapprops");
1333 snapprops = fnvlist_lookup_nvlist(snapprops,
1334 snapname);
1335 fnvlist_add_boolean(snapprops,
1336 "is_clone_origin");
428870ff
BB
1337 }
1338 }
1339 }
34dc7c2f
BB
1340again:
1341 needagain = progress = B_FALSE;
1342 for (fspair = nvlist_next_nvpair(sdd->fss, NULL); fspair;
1343 fspair = nvlist_next_nvpair(sdd->fss, fspair)) {
330d06f9 1344 nvlist_t *fslist, *parent_nv;
34dc7c2f
BB
1345 char *fsname;
1346 zfs_handle_t *zhp;
1347 int err;
1348 uint64_t origin_guid = 0;
330d06f9 1349 uint64_t parent_guid = 0;
34dc7c2f 1350
60a2434b 1351 fslist = fnvpair_value_nvlist(fspair);
34dc7c2f
BB
1352 if (nvlist_lookup_boolean(fslist, "sent") == 0)
1353 continue;
1354
60a2434b 1355 fsname = fnvlist_lookup_string(fslist, "name");
34dc7c2f 1356 (void) nvlist_lookup_uint64(fslist, "origin", &origin_guid);
330d06f9
MA
1357 (void) nvlist_lookup_uint64(fslist, "parentfromsnap",
1358 &parent_guid);
1359
1360 if (parent_guid != 0) {
1361 parent_nv = fsavl_find(sdd->fsavl, parent_guid, NULL);
1362 if (!nvlist_exists(parent_nv, "sent")) {
45932229 1363 /* Parent has not been sent; skip this one. */
330d06f9
MA
1364 needagain = B_TRUE;
1365 continue;
1366 }
1367 }
34dc7c2f 1368
428870ff
BB
1369 if (origin_guid != 0) {
1370 nvlist_t *origin_nv = fsavl_find(sdd->fsavl,
1371 origin_guid, NULL);
1372 if (origin_nv != NULL &&
330d06f9 1373 !nvlist_exists(origin_nv, "sent")) {
428870ff 1374 /*
45932229 1375 * Origin has not been sent yet;
428870ff
BB
1376 * skip this clone.
1377 */
1378 needagain = B_TRUE;
1379 continue;
1380 }
34dc7c2f
BB
1381 }
1382
1383 zhp = zfs_open(rzhp->zfs_hdl, fsname, ZFS_TYPE_DATASET);
1384 if (zhp == NULL)
1385 return (-1);
1386 err = dump_filesystem(zhp, sdd);
60a2434b 1387 fnvlist_add_boolean(fslist, "sent");
34dc7c2f
BB
1388 progress = B_TRUE;
1389 zfs_close(zhp);
1390 if (err)
1391 return (err);
1392 }
1393 if (needagain) {
1394 assert(progress);
1395 goto again;
1396 }
330d06f9 1397
45932229 1398 /* Clean out the sent flags in case we reuse this fss. */
330d06f9
MA
1399 for (fspair = nvlist_next_nvpair(sdd->fss, NULL); fspair;
1400 fspair = nvlist_next_nvpair(sdd->fss, fspair)) {
1401 nvlist_t *fslist;
1402
60a2434b 1403 fslist = fnvpair_value_nvlist(fspair);
330d06f9
MA
1404 (void) nvlist_remove_all(fslist, "sent");
1405 }
1406
34dc7c2f
BB
1407 return (0);
1408}
1409
47dfff3b
MA
1410nvlist_t *
1411zfs_send_resume_token_to_nvlist(libzfs_handle_t *hdl, const char *token)
1412{
1413 unsigned int version;
1414 int nread, i;
1415 unsigned long long checksum, packed_len;
1416
1417 /*
1418 * Decode token header, which is:
1419 * <token version>-<checksum of payload>-<uncompressed payload length>
1420 * Note that the only supported token version is 1.
1421 */
1422 nread = sscanf(token, "%u-%llx-%llx-",
1423 &version, &checksum, &packed_len);
1424 if (nread != 3) {
1425 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1426 "resume token is corrupt (invalid format)"));
1427 return (NULL);
1428 }
1429
1430 if (version != ZFS_SEND_RESUME_TOKEN_VERSION) {
1431 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1432 "resume token is corrupt (invalid version %u)"),
1433 version);
1434 return (NULL);
1435 }
1436
2fafbfde 1437 /* Convert hexadecimal representation to binary. */
47dfff3b
MA
1438 token = strrchr(token, '-') + 1;
1439 int len = strlen(token) / 2;
1440 unsigned char *compressed = zfs_alloc(hdl, len);
1441 for (i = 0; i < len; i++) {
1442 nread = sscanf(token + i * 2, "%2hhx", compressed + i);
1443 if (nread != 1) {
1444 free(compressed);
1445 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1446 "resume token is corrupt "
1447 "(payload is not hex-encoded)"));
1448 return (NULL);
1449 }
1450 }
1451
2fafbfde 1452 /* Verify checksum. */
47dfff3b 1453 zio_cksum_t cksum;
fc897b24 1454 fletcher_4_native_varsize(compressed, len, &cksum);
47dfff3b
MA
1455 if (cksum.zc_word[0] != checksum) {
1456 free(compressed);
1457 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1458 "resume token is corrupt (incorrect checksum)"));
1459 return (NULL);
1460 }
1461
2fafbfde 1462 /* Uncompress. */
47dfff3b
MA
1463 void *packed = zfs_alloc(hdl, packed_len);
1464 uLongf packed_len_long = packed_len;
1465 if (uncompress(packed, &packed_len_long, compressed, len) != Z_OK ||
1466 packed_len_long != packed_len) {
1467 free(packed);
1468 free(compressed);
1469 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1470 "resume token is corrupt (decompression failed)"));
1471 return (NULL);
1472 }
1473
2fafbfde 1474 /* Unpack nvlist. */
47dfff3b
MA
1475 nvlist_t *nv;
1476 int error = nvlist_unpack(packed, packed_len, &nv, KM_SLEEP);
1477 free(packed);
1478 free(compressed);
1479 if (error != 0) {
1480 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1481 "resume token is corrupt (nvlist_unpack failed)"));
1482 return (NULL);
1483 }
1484 return (nv);
1485}
2fafbfde 1486
30af21b0
PD
1487static enum lzc_send_flags
1488lzc_flags_from_sendflags(const sendflags_t *flags)
1489{
1490 enum lzc_send_flags lzc_flags = 0;
d1a38ee7 1491
30af21b0
PD
1492 if (flags->largeblock)
1493 lzc_flags |= LZC_SEND_FLAG_LARGE_BLOCK;
1494 if (flags->embed_data)
1495 lzc_flags |= LZC_SEND_FLAG_EMBED_DATA;
1496 if (flags->compress)
1497 lzc_flags |= LZC_SEND_FLAG_COMPRESS;
1498 if (flags->raw)
1499 lzc_flags |= LZC_SEND_FLAG_RAW;
ba0ba69e
TC
1500 if (flags->saved)
1501 lzc_flags |= LZC_SEND_FLAG_SAVED;
d1a38ee7 1502
30af21b0
PD
1503 return (lzc_flags);
1504}
1505
1506static int
1507estimate_size(zfs_handle_t *zhp, const char *from, int fd, sendflags_t *flags,
1508 uint64_t resumeobj, uint64_t resumeoff, uint64_t bytes,
1509 const char *redactbook, char *errbuf)
1510{
1511 uint64_t size;
1512 FILE *fout = flags->dryrun ? stdout : stderr;
1513 progress_arg_t pa = { 0 };
1514 int err = 0;
1515 pthread_t ptid;
1516
1517 if (flags->progress) {
1518 pa.pa_zhp = zhp;
1519 pa.pa_fd = fd;
1520 pa.pa_parsable = flags->parsable;
1521 pa.pa_estimate = B_TRUE;
1522 pa.pa_verbosity = flags->verbosity;
1523
1524 err = pthread_create(&ptid, NULL,
1525 send_progress_thread, &pa);
1526 if (err != 0) {
f00f4690 1527 zfs_error_aux(zhp->zfs_hdl, "%s", strerror(errno));
30af21b0
PD
1528 return (zfs_error(zhp->zfs_hdl,
1529 EZFS_THREADCREATEFAILED, errbuf));
1530 }
1531 }
1532
1533 err = lzc_send_space_resume_redacted(zhp->zfs_name, from,
1534 lzc_flags_from_sendflags(flags), resumeobj, resumeoff, bytes,
1535 redactbook, fd, &size);
1536
e3e4c30b
AZ
1537 if (flags->progress && send_progress_thread_exit(zhp->zfs_hdl, ptid))
1538 return (-1);
30af21b0
PD
1539
1540 if (err != 0) {
f00f4690 1541 zfs_error_aux(zhp->zfs_hdl, "%s", strerror(err));
30af21b0
PD
1542 return (zfs_error(zhp->zfs_hdl, EZFS_BADBACKUP,
1543 errbuf));
1544 }
1545 send_print_verbose(fout, zhp->zfs_name, from, size,
1546 flags->parsable);
1547
1548 if (flags->parsable) {
1549 (void) fprintf(fout, "size\t%llu\n", (longlong_t)size);
1550 } else {
1551 char buf[16];
1552 zfs_nicenum(size, buf, sizeof (buf));
1553 (void) fprintf(fout, dgettext(TEXT_DOMAIN,
1554 "total estimated size is %s\n"), buf);
1555 }
1556 return (0);
1557}
1558
1559static boolean_t
1560redact_snaps_contains(const uint64_t *snaps, uint64_t num_snaps, uint64_t guid)
1561{
1562 for (int i = 0; i < num_snaps; i++) {
1563 if (snaps[i] == guid)
1564 return (B_TRUE);
1565 }
1566 return (B_FALSE);
1567}
1568
1569static boolean_t
1570redact_snaps_equal(const uint64_t *snaps1, uint64_t num_snaps1,
1571 const uint64_t *snaps2, uint64_t num_snaps2)
1572{
1573 if (num_snaps1 != num_snaps2)
1574 return (B_FALSE);
1575 for (int i = 0; i < num_snaps1; i++) {
1576 if (!redact_snaps_contains(snaps2, num_snaps2, snaps1[i]))
1577 return (B_FALSE);
1578 }
1579 return (B_TRUE);
1580}
1581
102eb673
RM
1582static int
1583get_bookmarks(const char *path, nvlist_t **bmarksp)
1584{
1585 nvlist_t *props = fnvlist_alloc();
1586 int error;
1587
1588 fnvlist_add_boolean(props, "redact_complete");
1589 fnvlist_add_boolean(props, zfs_prop_to_name(ZFS_PROP_REDACT_SNAPS));
1590 error = lzc_get_bookmarks(path, props, bmarksp);
1591 fnvlist_free(props);
1592 return (error);
1593}
1594
1595static nvpair_t *
1596find_redact_pair(nvlist_t *bmarks, const uint64_t *redact_snap_guids,
1597 int num_redact_snaps)
1598{
1599 nvpair_t *pair;
1600
1601 for (pair = nvlist_next_nvpair(bmarks, NULL); pair;
1602 pair = nvlist_next_nvpair(bmarks, pair)) {
1603
1604 nvlist_t *bmark = fnvpair_value_nvlist(pair);
1605 nvlist_t *vallist = fnvlist_lookup_nvlist(bmark,
1606 zfs_prop_to_name(ZFS_PROP_REDACT_SNAPS));
1607 uint_t len = 0;
1608 uint64_t *bmarksnaps = fnvlist_lookup_uint64_array(vallist,
1609 ZPROP_VALUE, &len);
1610 if (redact_snaps_equal(redact_snap_guids,
1611 num_redact_snaps, bmarksnaps, len)) {
1612 break;
1613 }
1614 }
1615 return (pair);
1616}
1617
1618static boolean_t
1619get_redact_complete(nvpair_t *pair)
1620{
1621 nvlist_t *bmark = fnvpair_value_nvlist(pair);
1622 nvlist_t *vallist = fnvlist_lookup_nvlist(bmark, "redact_complete");
1623 boolean_t complete = fnvlist_lookup_boolean_value(vallist,
1624 ZPROP_VALUE);
1625
1626 return (complete);
1627}
1628
30af21b0
PD
1629/*
1630 * Check that the list of redaction snapshots in the bookmark matches the send
1631 * we're resuming, and return whether or not it's complete.
1632 *
1633 * Note that the caller needs to free the contents of *bookname with free() if
1634 * this function returns successfully.
1635 */
1636static int
1637find_redact_book(libzfs_handle_t *hdl, const char *path,
1638 const uint64_t *redact_snap_guids, int num_redact_snaps,
1639 char **bookname)
1640{
d68a2bfa 1641 char errbuf[ERRBUFLEN];
30af21b0
PD
1642 nvlist_t *bmarks;
1643
1644 (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
1645 "cannot resume send"));
1646
102eb673 1647 int error = get_bookmarks(path, &bmarks);
30af21b0
PD
1648 if (error != 0) {
1649 if (error == ESRCH) {
1650 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1651 "nonexistent redaction bookmark provided"));
1652 } else if (error == ENOENT) {
1653 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1654 "dataset to be sent no longer exists"));
1655 } else {
1656 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1657 "unknown error: %s"), strerror(error));
1658 }
1659 return (zfs_error(hdl, EZFS_BADPROP, errbuf));
1660 }
102eb673
RM
1661 nvpair_t *pair = find_redact_pair(bmarks, redact_snap_guids,
1662 num_redact_snaps);
30af21b0
PD
1663 if (pair == NULL) {
1664 fnvlist_free(bmarks);
1665 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1666 "no appropriate redaction bookmark exists"));
1667 return (zfs_error(hdl, EZFS_BADPROP, errbuf));
1668 }
102eb673 1669 boolean_t complete = get_redact_complete(pair);
30af21b0
PD
1670 if (!complete) {
1671 fnvlist_free(bmarks);
1672 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1673 "incomplete redaction bookmark provided"));
1674 return (zfs_error(hdl, EZFS_BADPROP, errbuf));
1675 }
102eb673 1676 *bookname = strndup(nvpair_name(pair), ZFS_MAX_DATASET_NAME_LEN);
30af21b0
PD
1677 ASSERT3P(*bookname, !=, NULL);
1678 fnvlist_free(bmarks);
1679 return (0);
1680}
47dfff3b 1681
d1a38ee7
RM
1682static enum lzc_send_flags
1683lzc_flags_from_resume_nvl(nvlist_t *resume_nvl)
1684{
1685 enum lzc_send_flags lzc_flags = 0;
1686
1687 if (nvlist_exists(resume_nvl, "largeblockok"))
1688 lzc_flags |= LZC_SEND_FLAG_LARGE_BLOCK;
1689 if (nvlist_exists(resume_nvl, "embedok"))
1690 lzc_flags |= LZC_SEND_FLAG_EMBED_DATA;
1691 if (nvlist_exists(resume_nvl, "compressok"))
1692 lzc_flags |= LZC_SEND_FLAG_COMPRESS;
1693 if (nvlist_exists(resume_nvl, "rawok"))
1694 lzc_flags |= LZC_SEND_FLAG_RAW;
1695 if (nvlist_exists(resume_nvl, "savedok"))
1696 lzc_flags |= LZC_SEND_FLAG_SAVED;
1697
1698 return (lzc_flags);
1699}
1700
ba0ba69e 1701static int
3a909fe3
AZ
1702zfs_send_resume_impl_cb_impl(libzfs_handle_t *hdl, sendflags_t *flags,
1703 int outfd, nvlist_t *resume_nvl)
47dfff3b 1704{
d68a2bfa 1705 char errbuf[ERRBUFLEN];
47dfff3b
MA
1706 char *toname;
1707 char *fromname = NULL;
1708 uint64_t resumeobj, resumeoff, toguid, fromguid, bytes;
1709 zfs_handle_t *zhp;
1710 int error = 0;
eca7b760 1711 char name[ZFS_MAX_DATASET_NAME_LEN];
30af21b0
PD
1712 FILE *fout = (flags->verbosity > 0 && flags->dryrun) ? stdout : stderr;
1713 uint64_t *redact_snap_guids = NULL;
1714 int num_redact_snaps = 0;
1715 char *redact_book = NULL;
47dfff3b
MA
1716
1717 (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
1718 "cannot resume send"));
1719
30af21b0 1720 if (flags->verbosity != 0) {
aee1dd4d 1721 (void) fprintf(fout, dgettext(TEXT_DOMAIN,
47dfff3b 1722 "resume token contents:\n"));
aee1dd4d 1723 nvlist_print(fout, resume_nvl);
47dfff3b
MA
1724 }
1725
1726 if (nvlist_lookup_string(resume_nvl, "toname", &toname) != 0 ||
1727 nvlist_lookup_uint64(resume_nvl, "object", &resumeobj) != 0 ||
1728 nvlist_lookup_uint64(resume_nvl, "offset", &resumeoff) != 0 ||
1729 nvlist_lookup_uint64(resume_nvl, "bytes", &bytes) != 0 ||
1730 nvlist_lookup_uint64(resume_nvl, "toguid", &toguid) != 0) {
1731 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1732 "resume token is corrupt"));
1733 return (zfs_error(hdl, EZFS_FAULT, errbuf));
1734 }
1735 fromguid = 0;
1736 (void) nvlist_lookup_uint64(resume_nvl, "fromguid", &fromguid);
1737
ba0ba69e 1738 if (flags->saved) {
a51288aa 1739 (void) strlcpy(name, toname, sizeof (name));
ba0ba69e
TC
1740 } else {
1741 error = guid_to_name(hdl, toname, toguid, B_FALSE, name);
1742 if (error != 0) {
1743 if (zfs_dataset_exists(hdl, toname, ZFS_TYPE_DATASET)) {
1744 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1745 "'%s' is no longer the same snapshot "
1746 "used in the initial send"), toname);
1747 } else {
1748 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1749 "'%s' used in the initial send no "
1750 "longer exists"), toname);
1751 }
1752 return (zfs_error(hdl, EZFS_BADPATH, errbuf));
47dfff3b 1753 }
47dfff3b 1754 }
ba0ba69e 1755
47dfff3b
MA
1756 zhp = zfs_open(hdl, name, ZFS_TYPE_DATASET);
1757 if (zhp == NULL) {
1758 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1759 "unable to access '%s'"), name);
1760 return (zfs_error(hdl, EZFS_BADPATH, errbuf));
1761 }
1762
30af21b0
PD
1763 if (nvlist_lookup_uint64_array(resume_nvl, "book_redact_snaps",
1764 &redact_snap_guids, (uint_t *)&num_redact_snaps) != 0) {
1765 num_redact_snaps = -1;
1766 }
1767
47dfff3b 1768 if (fromguid != 0) {
30af21b0
PD
1769 if (guid_to_name_redact_snaps(hdl, toname, fromguid, B_TRUE,
1770 redact_snap_guids, num_redact_snaps, name) != 0) {
47dfff3b
MA
1771 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1772 "incremental source %#llx no longer exists"),
1773 (longlong_t)fromguid);
1774 return (zfs_error(hdl, EZFS_BADPATH, errbuf));
1775 }
1776 fromname = name;
1777 }
1778
30af21b0
PD
1779 redact_snap_guids = NULL;
1780
1781 if (nvlist_lookup_uint64_array(resume_nvl,
1782 zfs_prop_to_name(ZFS_PROP_REDACT_SNAPS), &redact_snap_guids,
1783 (uint_t *)&num_redact_snaps) == 0) {
1784 char path[ZFS_MAX_DATASET_NAME_LEN];
1785
1786 (void) strlcpy(path, toname, sizeof (path));
1787 char *at = strchr(path, '@');
1788 ASSERT3P(at, !=, NULL);
1789
1790 *at = '\0';
1791
1792 if ((error = find_redact_book(hdl, path, redact_snap_guids,
1793 num_redact_snaps, &redact_book)) != 0) {
1794 return (error);
1795 }
1796 }
1797
d1a38ee7
RM
1798 enum lzc_send_flags lzc_flags = lzc_flags_from_sendflags(flags) |
1799 lzc_flags_from_resume_nvl(resume_nvl);
1800
30af21b0
PD
1801 if (flags->verbosity != 0) {
1802 /*
1803 * Some of these may have come from the resume token, set them
1804 * here for size estimate purposes.
1805 */
1806 sendflags_t tmpflags = *flags;
1807 if (lzc_flags & LZC_SEND_FLAG_LARGE_BLOCK)
1808 tmpflags.largeblock = B_TRUE;
1809 if (lzc_flags & LZC_SEND_FLAG_COMPRESS)
1810 tmpflags.compress = B_TRUE;
1811 if (lzc_flags & LZC_SEND_FLAG_EMBED_DATA)
1812 tmpflags.embed_data = B_TRUE;
8f11b1d2
PD
1813 if (lzc_flags & LZC_SEND_FLAG_RAW)
1814 tmpflags.raw = B_TRUE;
1815 if (lzc_flags & LZC_SEND_FLAG_SAVED)
1816 tmpflags.saved = B_TRUE;
30af21b0
PD
1817 error = estimate_size(zhp, fromname, outfd, &tmpflags,
1818 resumeobj, resumeoff, bytes, redact_book, errbuf);
47dfff3b
MA
1819 }
1820
1821 if (!flags->dryrun) {
1822 progress_arg_t pa = { 0 };
1823 pthread_t tid;
1824 /*
1825 * If progress reporting is requested, spawn a new thread to
1826 * poll ZFS_IOC_SEND_PROGRESS at a regular interval.
1827 */
1828 if (flags->progress) {
1829 pa.pa_zhp = zhp;
1830 pa.pa_fd = outfd;
1831 pa.pa_parsable = flags->parsable;
30af21b0
PD
1832 pa.pa_estimate = B_FALSE;
1833 pa.pa_verbosity = flags->verbosity;
47dfff3b
MA
1834
1835 error = pthread_create(&tid, NULL,
1836 send_progress_thread, &pa);
1837 if (error != 0) {
30af21b0
PD
1838 if (redact_book != NULL)
1839 free(redact_book);
47dfff3b
MA
1840 zfs_close(zhp);
1841 return (error);
1842 }
1843 }
1844
30af21b0
PD
1845 error = lzc_send_resume_redacted(zhp->zfs_name, fromname, outfd,
1846 lzc_flags, resumeobj, resumeoff, redact_book);
1847 if (redact_book != NULL)
1848 free(redact_book);
47dfff3b 1849
e3e4c30b
AZ
1850 if (flags->progress && send_progress_thread_exit(hdl, tid))
1851 return (-1);
47dfff3b 1852
d68a2bfa 1853 char errbuf[ERRBUFLEN];
47dfff3b
MA
1854 (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
1855 "warning: cannot send '%s'"), zhp->zfs_name);
1856
1857 zfs_close(zhp);
1858
1859 switch (error) {
1860 case 0:
1861 return (0);
b5256303
TC
1862 case EACCES:
1863 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1864 "source key must be loaded"));
1865 return (zfs_error(hdl, EZFS_CRYPTOFAILED, errbuf));
30af21b0
PD
1866 case ESRCH:
1867 if (lzc_exists(zhp->zfs_name)) {
1868 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1869 "incremental source could not be found"));
1870 }
1871 return (zfs_error(hdl, EZFS_NOENT, errbuf));
b5256303 1872
47dfff3b
MA
1873 case EXDEV:
1874 case ENOENT:
1875 case EDQUOT:
1876 case EFBIG:
1877 case EIO:
1878 case ENOLINK:
1879 case ENOSPC:
1880 case ENOSTR:
1881 case ENXIO:
1882 case EPIPE:
1883 case ERANGE:
1884 case EFAULT:
1885 case EROFS:
f00f4690 1886 zfs_error_aux(hdl, "%s", strerror(errno));
47dfff3b
MA
1887 return (zfs_error(hdl, EZFS_BADBACKUP, errbuf));
1888
1889 default:
1890 return (zfs_standard_error(hdl, errno, errbuf));
1891 }
30af21b0
PD
1892 } else {
1893 if (redact_book != NULL)
1894 free(redact_book);
47dfff3b
MA
1895 }
1896
47dfff3b
MA
1897 zfs_close(zhp);
1898
1899 return (error);
1900}
1901
3a909fe3
AZ
1902struct zfs_send_resume_impl {
1903 libzfs_handle_t *hdl;
1904 sendflags_t *flags;
1905 nvlist_t *resume_nvl;
1906};
1907
1908static int
1909zfs_send_resume_impl_cb(int outfd, void *arg)
1910{
1911 struct zfs_send_resume_impl *zsri = arg;
1912 return (zfs_send_resume_impl_cb_impl(zsri->hdl, zsri->flags, outfd,
1913 zsri->resume_nvl));
1914}
1915
1916static int
1917zfs_send_resume_impl(libzfs_handle_t *hdl, sendflags_t *flags, int outfd,
1918 nvlist_t *resume_nvl)
1919{
1920 struct zfs_send_resume_impl zsri = {
1921 .hdl = hdl,
1922 .flags = flags,
1923 .resume_nvl = resume_nvl,
1924 };
1925 return (lzc_send_wrapper(zfs_send_resume_impl_cb, outfd, &zsri));
1926}
1927
ba0ba69e
TC
1928int
1929zfs_send_resume(libzfs_handle_t *hdl, sendflags_t *flags, int outfd,
1930 const char *resume_token)
1931{
1932 int ret;
d68a2bfa 1933 char errbuf[ERRBUFLEN];
ba0ba69e
TC
1934 nvlist_t *resume_nvl;
1935
1936 (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
1937 "cannot resume send"));
1938
1939 resume_nvl = zfs_send_resume_token_to_nvlist(hdl, resume_token);
1940 if (resume_nvl == NULL) {
1941 /*
1942 * zfs_error_aux has already been set by
1943 * zfs_send_resume_token_to_nvlist()
1944 */
1945 return (zfs_error(hdl, EZFS_FAULT, errbuf));
1946 }
1947
1948 ret = zfs_send_resume_impl(hdl, flags, outfd, resume_nvl);
60a2434b 1949 fnvlist_free(resume_nvl);
ba0ba69e
TC
1950
1951 return (ret);
1952}
1953
1954int
1955zfs_send_saved(zfs_handle_t *zhp, sendflags_t *flags, int outfd,
1956 const char *resume_token)
1957{
1958 int ret;
1959 libzfs_handle_t *hdl = zhp->zfs_hdl;
1960 nvlist_t *saved_nvl = NULL, *resume_nvl = NULL;
1961 uint64_t saved_guid = 0, resume_guid = 0;
1962 uint64_t obj = 0, off = 0, bytes = 0;
1963 char token_buf[ZFS_MAXPROPLEN];
d68a2bfa 1964 char errbuf[ERRBUFLEN];
ba0ba69e
TC
1965
1966 (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
1967 "saved send failed"));
1968
1969 ret = zfs_prop_get(zhp, ZFS_PROP_RECEIVE_RESUME_TOKEN,
1970 token_buf, sizeof (token_buf), NULL, NULL, 0, B_TRUE);
1971 if (ret != 0)
1972 goto out;
1973
1974 saved_nvl = zfs_send_resume_token_to_nvlist(hdl, token_buf);
1975 if (saved_nvl == NULL) {
1976 /*
1977 * zfs_error_aux has already been set by
1978 * zfs_send_resume_token_to_nvlist()
1979 */
1980 ret = zfs_error(hdl, EZFS_FAULT, errbuf);
1981 goto out;
1982 }
1983
1984 /*
1985 * If a resume token is provided we use the object and offset
1986 * from that instead of the default, which starts from the
1987 * beginning.
1988 */
1989 if (resume_token != NULL) {
1990 resume_nvl = zfs_send_resume_token_to_nvlist(hdl,
1991 resume_token);
1992 if (resume_nvl == NULL) {
1993 ret = zfs_error(hdl, EZFS_FAULT, errbuf);
1994 goto out;
1995 }
1996
1997 if (nvlist_lookup_uint64(resume_nvl, "object", &obj) != 0 ||
1998 nvlist_lookup_uint64(resume_nvl, "offset", &off) != 0 ||
1999 nvlist_lookup_uint64(resume_nvl, "bytes", &bytes) != 0 ||
2000 nvlist_lookup_uint64(resume_nvl, "toguid",
2001 &resume_guid) != 0) {
2002 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
2003 "provided resume token is corrupt"));
2004 ret = zfs_error(hdl, EZFS_FAULT, errbuf);
2005 goto out;
2006 }
2007
2008 if (nvlist_lookup_uint64(saved_nvl, "toguid",
2009 &saved_guid)) {
2010 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
2011 "dataset's resume token is corrupt"));
2012 ret = zfs_error(hdl, EZFS_FAULT, errbuf);
2013 goto out;
2014 }
2015
2016 if (resume_guid != saved_guid) {
2017 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
2018 "provided resume token does not match dataset"));
2019 ret = zfs_error(hdl, EZFS_BADBACKUP, errbuf);
2020 goto out;
2021 }
2022 }
2023
2024 (void) nvlist_remove_all(saved_nvl, "object");
2025 fnvlist_add_uint64(saved_nvl, "object", obj);
2026
2027 (void) nvlist_remove_all(saved_nvl, "offset");
2028 fnvlist_add_uint64(saved_nvl, "offset", off);
2029
2030 (void) nvlist_remove_all(saved_nvl, "bytes");
2031 fnvlist_add_uint64(saved_nvl, "bytes", bytes);
2032
2033 (void) nvlist_remove_all(saved_nvl, "toname");
2034 fnvlist_add_string(saved_nvl, "toname", zhp->zfs_name);
2035
2036 ret = zfs_send_resume_impl(hdl, flags, outfd, saved_nvl);
2037
2038out:
60a2434b
RM
2039 fnvlist_free(saved_nvl);
2040 fnvlist_free(resume_nvl);
ba0ba69e
TC
2041 return (ret);
2042}
2043
34dc7c2f 2044/*
30af21b0
PD
2045 * This function informs the target system that the recursive send is complete.
2046 * The record is also expected in the case of a send -p.
2047 */
2048static int
2049send_conclusion_record(int fd, zio_cksum_t *zc)
2050{
2051 dmu_replay_record_t drr = { 0 };
2052 drr.drr_type = DRR_END;
2053 if (zc != NULL)
2054 drr.drr_u.drr_end.drr_checksum = *zc;
2055 if (write(fd, &drr, sizeof (drr)) == -1) {
2056 return (errno);
2057 }
2058 return (0);
2059}
2060
2061/*
2062 * This function is responsible for sending the records that contain the
2063 * necessary information for the target system's libzfs to be able to set the
2064 * properties of the filesystem being received, or to be able to prepare for
2065 * a recursive receive.
2066 *
2067 * The "zhp" argument is the handle of the snapshot we are sending
2068 * (the "tosnap"). The "from" argument is the short snapshot name (the part
2069 * after the @) of the incremental source.
2070 */
2071static int
2072send_prelim_records(zfs_handle_t *zhp, const char *from, int fd,
2073 boolean_t gather_props, boolean_t recursive, boolean_t verbose,
099fa7e4
PCG
2074 boolean_t dryrun, boolean_t raw, boolean_t replicate, boolean_t skipmissing,
2075 boolean_t backup, boolean_t holds, boolean_t props, boolean_t doall,
30af21b0
PD
2076 nvlist_t **fssp, avl_tree_t **fsavlp)
2077{
2078 int err = 0;
2079 char *packbuf = NULL;
2080 size_t buflen = 0;
2081 zio_cksum_t zc = { {0} };
2082 int featureflags = 0;
2083 /* name of filesystem/volume that contains snapshot we are sending */
2084 char tofs[ZFS_MAX_DATASET_NAME_LEN];
2085 /* short name of snap we are sending */
a926aab9 2086 const char *tosnap = "";
30af21b0 2087
d68a2bfa 2088 char errbuf[ERRBUFLEN];
30af21b0
PD
2089 (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
2090 "warning: cannot send '%s'"), zhp->zfs_name);
2091 if (zhp->zfs_type == ZFS_TYPE_FILESYSTEM && zfs_prop_get_int(zhp,
2092 ZFS_PROP_VERSION) >= ZPL_VERSION_SA) {
2093 featureflags |= DMU_BACKUP_FEATURE_SA_SPILL;
2094 }
2095
2096 if (holds)
2097 featureflags |= DMU_BACKUP_FEATURE_HOLDS;
2098
2099 (void) strlcpy(tofs, zhp->zfs_name, ZFS_MAX_DATASET_NAME_LEN);
2100 char *at = strchr(tofs, '@');
2101 if (at != NULL) {
2102 *at = '\0';
2103 tosnap = at + 1;
2104 }
2105
2106 if (gather_props) {
2107 nvlist_t *hdrnv = fnvlist_alloc();
2108 nvlist_t *fss = NULL;
2109
2110 if (from != NULL)
2111 fnvlist_add_string(hdrnv, "fromsnap", from);
2112 fnvlist_add_string(hdrnv, "tosnap", tosnap);
2113 if (!recursive)
2114 fnvlist_add_boolean(hdrnv, "not_recursive");
2115
2116 if (raw) {
60a2434b 2117 fnvlist_add_boolean(hdrnv, "raw");
30af21b0
PD
2118 }
2119
2120 if ((err = gather_nvlist(zhp->zfs_hdl, tofs,
099fa7e4
PCG
2121 from, tosnap, recursive, raw, doall, replicate, skipmissing,
2122 verbose, backup, holds, props, &fss, fsavlp)) != 0) {
30af21b0
PD
2123 return (zfs_error(zhp->zfs_hdl, EZFS_BADBACKUP,
2124 errbuf));
2125 }
7a6c12fd
AJ
2126 /*
2127 * Do not allow the size of the properties list to exceed
2128 * the limit
2129 */
2130 if ((fnvlist_size(fss) + fnvlist_size(hdrnv)) >
2131 zhp->zfs_hdl->libzfs_max_nvlist) {
2132 (void) snprintf(errbuf, sizeof (errbuf),
2133 dgettext(TEXT_DOMAIN, "warning: cannot send '%s': "
2134 "the size of the list of snapshots and properties "
2135 "is too large to be received successfully.\n"
2136 "Select a smaller number of snapshots to send.\n"),
2137 zhp->zfs_name);
2138 return (zfs_error(zhp->zfs_hdl, EZFS_NOSPC,
2139 errbuf));
2140 }
30af21b0
PD
2141 fnvlist_add_nvlist(hdrnv, "fss", fss);
2142 VERIFY0(nvlist_pack(hdrnv, &packbuf, &buflen, NV_ENCODE_XDR,
2143 0));
2144 if (fssp != NULL) {
2145 *fssp = fss;
2146 } else {
60a2434b 2147 fnvlist_free(fss);
30af21b0 2148 }
60a2434b 2149 fnvlist_free(hdrnv);
30af21b0
PD
2150 }
2151
2152 if (!dryrun) {
2153 dmu_replay_record_t drr = { 0 };
2154 /* write first begin record */
2155 drr.drr_type = DRR_BEGIN;
2156 drr.drr_u.drr_begin.drr_magic = DMU_BACKUP_MAGIC;
2157 DMU_SET_STREAM_HDRTYPE(drr.drr_u.drr_begin.
2158 drr_versioninfo, DMU_COMPOUNDSTREAM);
2159 DMU_SET_FEATUREFLAGS(drr.drr_u.drr_begin.
2160 drr_versioninfo, featureflags);
2161 if (snprintf(drr.drr_u.drr_begin.drr_toname,
2162 sizeof (drr.drr_u.drr_begin.drr_toname), "%s@%s", tofs,
2163 tosnap) >= sizeof (drr.drr_u.drr_begin.drr_toname)) {
2164 return (zfs_error(zhp->zfs_hdl, EZFS_BADBACKUP,
2165 errbuf));
2166 }
2167 drr.drr_payloadlen = buflen;
2168
2169 err = dump_record(&drr, packbuf, buflen, &zc, fd);
2170 free(packbuf);
2171 if (err != 0) {
f00f4690 2172 zfs_error_aux(zhp->zfs_hdl, "%s", strerror(err));
30af21b0
PD
2173 return (zfs_error(zhp->zfs_hdl, EZFS_BADBACKUP,
2174 errbuf));
2175 }
2176 err = send_conclusion_record(fd, &zc);
2177 if (err != 0) {
f00f4690 2178 zfs_error_aux(zhp->zfs_hdl, "%s", strerror(err));
30af21b0
PD
2179 return (zfs_error(zhp->zfs_hdl, EZFS_BADBACKUP,
2180 errbuf));
2181 }
2182 }
2183 return (0);
2184}
2185
2186/*
2187 * Generate a send stream. The "zhp" argument is the filesystem/volume
2188 * that contains the snapshot to send. The "fromsnap" argument is the
2189 * short name (the part after the '@') of the snapshot that is the
2190 * incremental source to send from (if non-NULL). The "tosnap" argument
2191 * is the short name of the snapshot to send.
45d1cae3
BB
2192 *
2193 * The content of the send stream is the snapshot identified by
2194 * 'tosnap'. Incremental streams are requested in two ways:
2195 * - from the snapshot identified by "fromsnap" (if non-null) or
2196 * - from the origin of the dataset identified by zhp, which must
2197 * be a clone. In this case, "fromsnap" is null and "fromorigin"
2198 * is TRUE.
2199 *
2200 * The send stream is recursive (i.e. dumps a hierarchy of snapshots) and
428870ff 2201 * uses a special header (with a hdrtype field of DMU_COMPOUNDSTREAM)
45d1cae3 2202 * if "replicate" is set. If "doall" is set, dump all the intermediate
428870ff
BB
2203 * snapshots. The DMU_COMPOUNDSTREAM header is used in the "doall"
2204 * case too. If "props" is set, send properties.
3a909fe3
AZ
2205 *
2206 * Pre-wrapped (cf. lzc_send_wrapper()).
34dc7c2f 2207 */
3a909fe3
AZ
2208static int
2209zfs_send_cb_impl(zfs_handle_t *zhp, const char *fromsnap, const char *tosnap,
330d06f9 2210 sendflags_t *flags, int outfd, snapfilter_cb_t filter_func,
428870ff 2211 void *cb_arg, nvlist_t **debugnvp)
34dc7c2f 2212{
d68a2bfa 2213 char errbuf[ERRBUFLEN];
34dc7c2f 2214 send_dump_data_t sdd = { 0 };
330d06f9 2215 int err = 0;
34dc7c2f
BB
2216 nvlist_t *fss = NULL;
2217 avl_tree_t *fsavl = NULL;
428870ff
BB
2218 static uint64_t holdseq;
2219 int spa_version;
93f6d7e2 2220 FILE *fout;
428870ff 2221
34dc7c2f
BB
2222 (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
2223 "cannot send '%s'"), zhp->zfs_name);
2224
2225 if (fromsnap && fromsnap[0] == '\0') {
2226 zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN,
2227 "zero-length incremental source"));
2228 return (zfs_error(zhp->zfs_hdl, EZFS_NOENT, errbuf));
2229 }
2230
aad91df0
RE
2231 if (fromsnap) {
2232 char full_fromsnap_name[ZFS_MAX_DATASET_NAME_LEN];
2233 if (snprintf(full_fromsnap_name, sizeof (full_fromsnap_name),
2234 "%s@%s", zhp->zfs_name, fromsnap) >=
2235 sizeof (full_fromsnap_name)) {
2236 err = EINVAL;
2237 goto stderr_out;
2238 }
2239 zfs_handle_t *fromsnapn = zfs_open(zhp->zfs_hdl,
2240 full_fromsnap_name, ZFS_TYPE_SNAPSHOT);
2241 if (fromsnapn == NULL) {
2242 err = -1;
2243 goto err_out;
2244 }
2245 zfs_close(fromsnapn);
2246 }
2247
9c5e88b1
PZ
2248 if (flags->replicate || flags->doall || flags->props ||
2249 flags->holds || flags->backup) {
30af21b0
PD
2250 char full_tosnap_name[ZFS_MAX_DATASET_NAME_LEN];
2251 if (snprintf(full_tosnap_name, sizeof (full_tosnap_name),
2252 "%s@%s", zhp->zfs_name, tosnap) >=
2253 sizeof (full_tosnap_name)) {
2254 err = EINVAL;
2255 goto stderr_out;
34dc7c2f 2256 }
30af21b0
PD
2257 zfs_handle_t *tosnap = zfs_open(zhp->zfs_hdl,
2258 full_tosnap_name, ZFS_TYPE_SNAPSHOT);
1d20b763 2259 if (tosnap == NULL) {
2260 err = -1;
2261 goto err_out;
2262 }
30af21b0
PD
2263 err = send_prelim_records(tosnap, fromsnap, outfd,
2264 flags->replicate || flags->props || flags->holds,
2265 flags->replicate, flags->verbosity > 0, flags->dryrun,
099fa7e4
PCG
2266 flags->raw, flags->replicate, flags->skipmissing,
2267 flags->backup, flags->holds, flags->props, flags->doall,
2268 &fss, &fsavl);
30af21b0
PD
2269 zfs_close(tosnap);
2270 if (err != 0)
2271 goto err_out;
34dc7c2f
BB
2272 }
2273
2274 /* dump each stream */
2275 sdd.fromsnap = fromsnap;
2276 sdd.tosnap = tosnap;
36482bf6 2277 sdd.outfd = outfd;
330d06f9
MA
2278 sdd.replicate = flags->replicate;
2279 sdd.doall = flags->doall;
2280 sdd.fromorigin = flags->fromorigin;
34dc7c2f
BB
2281 sdd.fss = fss;
2282 sdd.fsavl = fsavl;
30af21b0 2283 sdd.verbosity = flags->verbosity;
330d06f9 2284 sdd.parsable = flags->parsable;
37abac6d 2285 sdd.progress = flags->progress;
330d06f9 2286 sdd.dryrun = flags->dryrun;
f1512ee6 2287 sdd.large_block = flags->largeblock;
9b67f605 2288 sdd.embed_data = flags->embed_data;
2aa34383 2289 sdd.compress = flags->compress;
b5256303 2290 sdd.raw = flags->raw;
9c5e88b1 2291 sdd.holds = flags->holds;
428870ff
BB
2292 sdd.filter_cb = filter_func;
2293 sdd.filter_cb_arg = cb_arg;
2294 if (debugnvp)
2295 sdd.debugnv = *debugnvp;
30af21b0 2296 if (sdd.verbosity != 0 && sdd.dryrun)
93f6d7e2
MJ
2297 sdd.std_out = B_TRUE;
2298 fout = sdd.std_out ? stdout : stderr;
e956d651
CS
2299
2300 /*
2301 * Some flags require that we place user holds on the datasets that are
2302 * being sent so they don't get destroyed during the send. We can skip
2303 * this step if the pool is imported read-only since the datasets cannot
2304 * be destroyed.
2305 */
2306 if (!flags->dryrun && !zpool_get_prop_int(zfs_get_pool_handle(zhp),
2307 ZPOOL_PROP_READONLY, NULL) &&
2308 zfs_spa_version(zhp, &spa_version) == 0 &&
2309 spa_version >= SPA_VERSION_USERREFS &&
2310 (flags->doall || flags->replicate)) {
572e2857
BB
2311 ++holdseq;
2312 (void) snprintf(sdd.holdtag, sizeof (sdd.holdtag),
2313 ".send-%d-%llu", getpid(), (u_longlong_t)holdseq);
10b575d0 2314 sdd.cleanup_fd = open(ZFS_DEV, O_RDWR | O_CLOEXEC);
572e2857
BB
2315 if (sdd.cleanup_fd < 0) {
2316 err = errno;
2317 goto stderr_out;
2318 }
95fd54a1 2319 sdd.snapholds = fnvlist_alloc();
572e2857
BB
2320 } else {
2321 sdd.cleanup_fd = -1;
95fd54a1 2322 sdd.snapholds = NULL;
572e2857 2323 }
9c5e88b1 2324
30af21b0 2325 if (flags->verbosity != 0 || sdd.snapholds != NULL) {
330d06f9
MA
2326 /*
2327 * Do a verbose no-op dry run to get all the verbose output
95fd54a1
SH
2328 * or to gather snapshot hold's before generating any data,
2329 * then do a non-verbose real run to generate the streams.
330d06f9
MA
2330 */
2331 sdd.dryrun = B_TRUE;
2332 err = dump_filesystems(zhp, &sdd);
95fd54a1
SH
2333
2334 if (err != 0)
2335 goto stderr_out;
2336
30af21b0 2337 if (flags->verbosity != 0) {
95fd54a1 2338 if (flags->parsable) {
93f6d7e2 2339 (void) fprintf(fout, "size\t%llu\n",
95fd54a1
SH
2340 (longlong_t)sdd.size);
2341 } else {
2342 char buf[16];
e7fbeb60 2343 zfs_nicebytes(sdd.size, buf, sizeof (buf));
93f6d7e2 2344 (void) fprintf(fout, dgettext(TEXT_DOMAIN,
95fd54a1
SH
2345 "total estimated size is %s\n"), buf);
2346 }
330d06f9 2347 }
95fd54a1
SH
2348
2349 /* Ensure no snaps found is treated as an error. */
2350 if (!sdd.seento) {
2351 err = ENOENT;
2352 goto err_out;
2353 }
2354
2355 /* Skip the second run if dryrun was requested. */
2356 if (flags->dryrun)
2357 goto err_out;
2358
2359 if (sdd.snapholds != NULL) {
2360 err = zfs_hold_nvl(zhp, sdd.cleanup_fd, sdd.snapholds);
2361 if (err != 0)
2362 goto stderr_out;
2363
2364 fnvlist_free(sdd.snapholds);
2365 sdd.snapholds = NULL;
2366 }
2367
2368 sdd.dryrun = B_FALSE;
30af21b0 2369 sdd.verbosity = 0;
330d06f9 2370 }
95fd54a1 2371
34dc7c2f
BB
2372 err = dump_filesystems(zhp, &sdd);
2373 fsavl_destroy(fsavl);
60a2434b 2374 fnvlist_free(fss);
34dc7c2f 2375
95fd54a1
SH
2376 /* Ensure no snaps found is treated as an error. */
2377 if (err == 0 && !sdd.seento)
2378 err = ENOENT;
2379
572e2857
BB
2380 if (sdd.cleanup_fd != -1) {
2381 VERIFY(0 == close(sdd.cleanup_fd));
2382 sdd.cleanup_fd = -1;
2383 }
2384
330d06f9 2385 if (!flags->dryrun && (flags->replicate || flags->doall ||
9c5e88b1 2386 flags->props || flags->backup || flags->holds)) {
34dc7c2f
BB
2387 /*
2388 * write final end record. NB: want to do this even if
2389 * there was some error, because it might not be totally
2390 * failed.
2391 */
10891b37
AH
2392 int err2 = send_conclusion_record(outfd, NULL);
2393 if (err2 != 0)
2394 return (zfs_standard_error(zhp->zfs_hdl, err2, errbuf));
34dc7c2f
BB
2395 }
2396
2397 return (err || sdd.err);
428870ff
BB
2398
2399stderr_out:
2400 err = zfs_standard_error(zhp->zfs_hdl, err, errbuf);
2401err_out:
95fd54a1 2402 fsavl_destroy(fsavl);
60a2434b 2403 fnvlist_free(fss);
95fd54a1
SH
2404 fnvlist_free(sdd.snapholds);
2405
572e2857
BB
2406 if (sdd.cleanup_fd != -1)
2407 VERIFY(0 == close(sdd.cleanup_fd));
428870ff 2408 return (err);
34dc7c2f
BB
2409}
2410
3a909fe3
AZ
2411struct zfs_send {
2412 zfs_handle_t *zhp;
2413 const char *fromsnap;
2414 const char *tosnap;
2415 sendflags_t *flags;
2416 snapfilter_cb_t *filter_func;
2417 void *cb_arg;
2418 nvlist_t **debugnvp;
2419};
2420
2421static int
2422zfs_send_cb(int outfd, void *arg)
2423{
2424 struct zfs_send *zs = arg;
2425 return (zfs_send_cb_impl(zs->zhp, zs->fromsnap, zs->tosnap, zs->flags,
2426 outfd, zs->filter_func, zs->cb_arg, zs->debugnvp));
2427}
2428
2429int
2430zfs_send(zfs_handle_t *zhp, const char *fromsnap, const char *tosnap,
2431 sendflags_t *flags, int outfd, snapfilter_cb_t filter_func,
2432 void *cb_arg, nvlist_t **debugnvp)
2433{
2434 struct zfs_send arg = {
2435 .zhp = zhp,
2436 .fromsnap = fromsnap,
2437 .tosnap = tosnap,
2438 .flags = flags,
2439 .filter_func = filter_func,
2440 .cb_arg = cb_arg,
2441 .debugnvp = debugnvp,
2442 };
2443 return (lzc_send_wrapper(zfs_send_cb, outfd, &arg));
2444}
2445
2446
65c7cc49 2447static zfs_handle_t *
30af21b0
PD
2448name_to_dir_handle(libzfs_handle_t *hdl, const char *snapname)
2449{
2450 char dirname[ZFS_MAX_DATASET_NAME_LEN];
2451 (void) strlcpy(dirname, snapname, ZFS_MAX_DATASET_NAME_LEN);
2452 char *c = strchr(dirname, '@');
2453 if (c != NULL)
2454 *c = '\0';
2455 return (zfs_open(hdl, dirname, ZFS_TYPE_DATASET));
2456}
2457
2458/*
2459 * Returns B_TRUE if earlier is an earlier snapshot in later's timeline; either
2460 * an earlier snapshot in the same filesystem, or a snapshot before later's
2461 * origin, or it's origin's origin, etc.
2462 */
2463static boolean_t
2464snapshot_is_before(zfs_handle_t *earlier, zfs_handle_t *later)
2465{
2466 boolean_t ret;
2467 uint64_t later_txg =
2468 (later->zfs_type == ZFS_TYPE_FILESYSTEM ||
2469 later->zfs_type == ZFS_TYPE_VOLUME ?
2470 UINT64_MAX : zfs_prop_get_int(later, ZFS_PROP_CREATETXG));
2471 uint64_t earlier_txg = zfs_prop_get_int(earlier, ZFS_PROP_CREATETXG);
2472
2473 if (earlier_txg >= later_txg)
2474 return (B_FALSE);
2475
2476 zfs_handle_t *earlier_dir = name_to_dir_handle(earlier->zfs_hdl,
2477 earlier->zfs_name);
2478 zfs_handle_t *later_dir = name_to_dir_handle(later->zfs_hdl,
2479 later->zfs_name);
2480
2481 if (strcmp(earlier_dir->zfs_name, later_dir->zfs_name) == 0) {
2482 zfs_close(earlier_dir);
2483 zfs_close(later_dir);
2484 return (B_TRUE);
2485 }
2486
2487 char clonename[ZFS_MAX_DATASET_NAME_LEN];
2488 if (zfs_prop_get(later_dir, ZFS_PROP_ORIGIN, clonename,
2489 ZFS_MAX_DATASET_NAME_LEN, NULL, NULL, 0, B_TRUE) != 0) {
2490 zfs_close(earlier_dir);
2491 zfs_close(later_dir);
2492 return (B_FALSE);
2493 }
2494
2495 zfs_handle_t *origin = zfs_open(earlier->zfs_hdl, clonename,
2496 ZFS_TYPE_DATASET);
2497 uint64_t origin_txg = zfs_prop_get_int(origin, ZFS_PROP_CREATETXG);
2498
2499 /*
2500 * If "earlier" is exactly the origin, then
2501 * snapshot_is_before(earlier, origin) will return false (because
2502 * they're the same).
2503 */
2504 if (origin_txg == earlier_txg &&
2505 strcmp(origin->zfs_name, earlier->zfs_name) == 0) {
2506 zfs_close(earlier_dir);
2507 zfs_close(later_dir);
2508 zfs_close(origin);
2509 return (B_TRUE);
2510 }
2511 zfs_close(earlier_dir);
2512 zfs_close(later_dir);
2513
2514 ret = snapshot_is_before(earlier, origin);
2515 zfs_close(origin);
2516 return (ret);
2517}
2518
2519/*
2520 * The "zhp" argument is the handle of the dataset to send (typically a
2521 * snapshot). The "from" argument is the full name of the snapshot or
2522 * bookmark that is the incremental source.
3a909fe3
AZ
2523 *
2524 * Pre-wrapped (cf. lzc_send_wrapper()).
30af21b0 2525 */
3a909fe3
AZ
2526static int
2527zfs_send_one_cb_impl(zfs_handle_t *zhp, const char *from, int fd,
2528 sendflags_t *flags, const char *redactbook)
da536844 2529{
30af21b0 2530 int err;
da536844 2531 libzfs_handle_t *hdl = zhp->zfs_hdl;
22df2457 2532 char *name = zhp->zfs_name;
196bee4c 2533 pthread_t ptid;
30af21b0 2534 progress_arg_t pa = { 0 };
30af21b0 2535
d68a2bfa 2536 char errbuf[ERRBUFLEN];
30af21b0 2537 (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
22df2457 2538 "warning: cannot send '%s'"), name);
835db585 2539
30af21b0
PD
2540 if (from != NULL && strchr(from, '@')) {
2541 zfs_handle_t *from_zhp = zfs_open(hdl, from,
2542 ZFS_TYPE_DATASET);
1d20b763 2543 if (from_zhp == NULL)
2544 return (-1);
30af21b0
PD
2545 if (!snapshot_is_before(from_zhp, zhp)) {
2546 zfs_close(from_zhp);
2547 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
2548 "not an earlier snapshot from the same fs"));
2549 return (zfs_error(hdl, EZFS_CROSSTARGET, errbuf));
2550 }
2551 zfs_close(from_zhp);
2552 }
835db585 2553
22df2457
RM
2554 if (redactbook != NULL) {
2555 char bookname[ZFS_MAX_DATASET_NAME_LEN];
2556 nvlist_t *redact_snaps;
2557 zfs_handle_t *book_zhp;
2558 char *at, *pound;
2559 int dsnamelen;
2560
2561 pound = strchr(redactbook, '#');
2562 if (pound != NULL)
2563 redactbook = pound + 1;
2564 at = strchr(name, '@');
2565 if (at == NULL) {
2566 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
2567 "cannot do a redacted send to a filesystem"));
2568 return (zfs_error(hdl, EZFS_BADTYPE, errbuf));
2569 }
2570 dsnamelen = at - name;
2571 if (snprintf(bookname, sizeof (bookname), "%.*s#%s",
2572 dsnamelen, name, redactbook)
2573 >= sizeof (bookname)) {
2574 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
2575 "invalid bookmark name"));
2576 return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf));
2577 }
2578 book_zhp = zfs_open(hdl, bookname, ZFS_TYPE_BOOKMARK);
2579 if (book_zhp == NULL)
2580 return (-1);
2581 if (nvlist_lookup_nvlist(book_zhp->zfs_props,
2582 zfs_prop_to_name(ZFS_PROP_REDACT_SNAPS),
2583 &redact_snaps) != 0 || redact_snaps == NULL) {
2584 zfs_close(book_zhp);
2585 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
2586 "not a redaction bookmark"));
2587 return (zfs_error(hdl, EZFS_BADTYPE, errbuf));
2588 }
2589 zfs_close(book_zhp);
2590 }
2591
30af21b0
PD
2592 /*
2593 * Send fs properties
2594 */
2595 if (flags->props || flags->holds || flags->backup) {
2596 /*
2597 * Note: the header generated by send_prelim_records()
2598 * assumes that the incremental source is in the same
2599 * filesystem/volume as the target (which is a requirement
2600 * when doing "zfs send -R"). But that isn't always the
2601 * case here (e.g. send from snap in origin, or send from
2602 * bookmark). We pass from=NULL, which will omit this
2603 * information from the prelim records; it isn't used
2604 * when receiving this type of stream.
2605 */
2606 err = send_prelim_records(zhp, NULL, fd, B_TRUE, B_FALSE,
2607 flags->verbosity > 0, flags->dryrun, flags->raw,
099fa7e4 2608 flags->replicate, B_FALSE, flags->backup, flags->holds,
30af21b0
PD
2609 flags->props, flags->doall, NULL, NULL);
2610 if (err != 0)
2611 return (err);
2612 }
2613
2614 /*
2615 * Perform size estimate if verbose was specified.
2616 */
2617 if (flags->verbosity != 0) {
2618 err = estimate_size(zhp, from, fd, flags, 0, 0, 0, redactbook,
2619 errbuf);
2620 if (err != 0)
2621 return (err);
2622 }
2623
2624 if (flags->dryrun)
2625 return (0);
2626
30af21b0
PD
2627 /*
2628 * If progress reporting is requested, spawn a new thread to poll
2629 * ZFS_IOC_SEND_PROGRESS at a regular interval.
2630 */
2631 if (flags->progress) {
2632 pa.pa_zhp = zhp;
2633 pa.pa_fd = fd;
2634 pa.pa_parsable = flags->parsable;
2635 pa.pa_estimate = B_FALSE;
2636 pa.pa_verbosity = flags->verbosity;
2637
2638 err = pthread_create(&ptid, NULL,
2639 send_progress_thread, &pa);
2640 if (err != 0) {
f00f4690 2641 zfs_error_aux(zhp->zfs_hdl, "%s", strerror(errno));
30af21b0
PD
2642 return (zfs_error(zhp->zfs_hdl,
2643 EZFS_THREADCREATEFAILED, errbuf));
835db585 2644 }
2645 }
2646
22df2457 2647 err = lzc_send_redacted(name, from, fd,
30af21b0 2648 lzc_flags_from_sendflags(flags), redactbook);
835db585 2649
e3e4c30b
AZ
2650 if (flags->progress && send_progress_thread_exit(hdl, ptid))
2651 return (-1);
da536844 2652
8623bd96 2653 if (err == 0 && (flags->props || flags->holds || flags->backup)) {
30af21b0 2654 /* Write the final end record. */
c14ad80f 2655 err = send_conclusion_record(fd, NULL);
30af21b0
PD
2656 if (err != 0)
2657 return (zfs_standard_error(hdl, err, errbuf));
2658 }
da536844
MA
2659 if (err != 0) {
2660 switch (errno) {
2661 case EXDEV:
2662 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
2663 "not an earlier snapshot from the same fs"));
2664 return (zfs_error(hdl, EZFS_CROSSTARGET, errbuf));
2665
2666 case ENOENT:
2667 case ESRCH:
22df2457 2668 if (lzc_exists(name)) {
da536844
MA
2669 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
2670 "incremental source (%s) does not exist"),
2671 from);
2672 }
2673 return (zfs_error(hdl, EZFS_NOENT, errbuf));
2674
b5256303
TC
2675 case EACCES:
2676 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
2677 "dataset key must be loaded"));
2678 return (zfs_error(hdl, EZFS_CRYPTOFAILED, errbuf));
2679
da536844
MA
2680 case EBUSY:
2681 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
2682 "target is busy; if a filesystem, "
2683 "it must not be mounted"));
2684 return (zfs_error(hdl, EZFS_BUSY, errbuf));
2685
2686 case EDQUOT:
22df2457 2687 case EFAULT:
da536844 2688 case EFBIG:
22df2457 2689 case EINVAL:
da536844
MA
2690 case EIO:
2691 case ENOLINK:
2692 case ENOSPC:
2693 case ENOSTR:
2694 case ENXIO:
2695 case EPIPE:
2696 case ERANGE:
da536844 2697 case EROFS:
f00f4690 2698 zfs_error_aux(hdl, "%s", strerror(errno));
da536844
MA
2699 return (zfs_error(hdl, EZFS_BADBACKUP, errbuf));
2700
2701 default:
2702 return (zfs_standard_error(hdl, errno, errbuf));
2703 }
2704 }
2705 return (err != 0);
2706}
2707
3a909fe3
AZ
2708struct zfs_send_one {
2709 zfs_handle_t *zhp;
2710 const char *from;
2711 sendflags_t *flags;
2712 const char *redactbook;
2713};
2714
2715static int
2716zfs_send_one_cb(int fd, void *arg)
2717{
2718 struct zfs_send_one *zso = arg;
2719 return (zfs_send_one_cb_impl(zso->zhp, zso->from, fd, zso->flags,
2720 zso->redactbook));
2721}
2722
2723int
2724zfs_send_one(zfs_handle_t *zhp, const char *from, int fd, sendflags_t *flags,
2725 const char *redactbook)
2726{
2727 struct zfs_send_one zso = {
2728 .zhp = zhp,
2729 .from = from,
2730 .flags = flags,
2731 .redactbook = redactbook,
2732 };
2733 return (lzc_send_wrapper(zfs_send_one_cb, fd, &zso));
2734}
2735
34dc7c2f
BB
2736/*
2737 * Routines specific to "zfs recv"
2738 */
2739
2740static int
2741recv_read(libzfs_handle_t *hdl, int fd, void *buf, int ilen,
2742 boolean_t byteswap, zio_cksum_t *zc)
2743{
2744 char *cp = buf;
2745 int rv;
2746 int len = ilen;
2747
2748 do {
2749 rv = read(fd, cp, len);
2750 cp += rv;
2751 len -= rv;
2752 } while (rv > 0);
2753
2754 if (rv < 0 || len != 0) {
2755 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
2756 "failed to read from stream"));
2757 return (zfs_error(hdl, EZFS_BADSTREAM, dgettext(TEXT_DOMAIN,
2758 "cannot receive")));
2759 }
2760
2761 if (zc) {
2762 if (byteswap)
2763 fletcher_4_incremental_byteswap(buf, ilen, zc);
2764 else
2765 fletcher_4_incremental_native(buf, ilen, zc);
2766 }
2767 return (0);
2768}
2769
2770static int
2771recv_read_nvlist(libzfs_handle_t *hdl, int fd, int len, nvlist_t **nvp,
2772 boolean_t byteswap, zio_cksum_t *zc)
2773{
2774 char *buf;
2775 int err;
2776
2777 buf = zfs_alloc(hdl, len);
34dc7c2f 2778
7a6c12fd
AJ
2779 if (len > hdl->libzfs_max_nvlist) {
2780 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "nvlist too large"));
908d43d0 2781 free(buf);
7a6c12fd
AJ
2782 return (ENOMEM);
2783 }
2784
34dc7c2f
BB
2785 err = recv_read(hdl, fd, buf, len, byteswap, zc);
2786 if (err != 0) {
2787 free(buf);
2788 return (err);
2789 }
2790
2791 err = nvlist_unpack(buf, len, nvp, 0);
2792 free(buf);
2793 if (err != 0) {
2794 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "invalid "
2795 "stream (malformed nvlist)"));
2796 return (EINVAL);
2797 }
2798 return (0);
2799}
2800
b5256303
TC
2801/*
2802 * Returns the grand origin (origin of origin of origin...) of a given handle.
2803 * If this dataset is not a clone, it simply returns a copy of the original
2804 * handle.
2805 */
2806static zfs_handle_t *
2807recv_open_grand_origin(zfs_handle_t *zhp)
2808{
2809 char origin[ZFS_MAX_DATASET_NAME_LEN];
610cb4fb 2810 zprop_source_t src;
b5256303
TC
2811 zfs_handle_t *ozhp = zfs_handle_dup(zhp);
2812
2813 while (ozhp != NULL) {
2814 if (zfs_prop_get(ozhp, ZFS_PROP_ORIGIN, origin,
2815 sizeof (origin), &src, NULL, 0, B_FALSE) != 0)
2816 break;
2817
2818 (void) zfs_close(ozhp);
2819 ozhp = zfs_open(zhp->zfs_hdl, origin, ZFS_TYPE_FILESYSTEM);
2820 }
2821
2822 return (ozhp);
2823}
2824
2825static int
dc1c630b 2826recv_rename_impl(zfs_handle_t *zhp, const char *name, const char *newname)
b5256303
TC
2827{
2828 int err;
2829 zfs_handle_t *ozhp = NULL;
2830
2831 /*
2832 * Attempt to rename the dataset. If it fails with EACCES we have
2833 * attempted to rename the dataset outside of its encryption root.
2834 * Force the dataset to become an encryption root and try again.
2835 */
dc1c630b 2836 err = lzc_rename(name, newname);
b5256303
TC
2837 if (err == EACCES) {
2838 ozhp = recv_open_grand_origin(zhp);
2839 if (ozhp == NULL) {
2840 err = ENOENT;
2841 goto out;
2842 }
2843
2844 err = lzc_change_key(ozhp->zfs_name, DCP_CMD_FORCE_NEW_KEY,
2845 NULL, NULL, 0);
2846 if (err != 0)
2847 goto out;
2848
dc1c630b 2849 err = lzc_rename(name, newname);
b5256303
TC
2850 }
2851
2852out:
2853 if (ozhp != NULL)
2854 zfs_close(ozhp);
2855 return (err);
2856}
2857
34dc7c2f
BB
2858static int
2859recv_rename(libzfs_handle_t *hdl, const char *name, const char *tryname,
330d06f9 2860 int baselen, char *newname, recvflags_t *flags)
34dc7c2f
BB
2861{
2862 static int seq;
34dc7c2f 2863 int err;
b5256303
TC
2864 prop_changelist_t *clp = NULL;
2865 zfs_handle_t *zhp = NULL;
34dc7c2f
BB
2866
2867 zhp = zfs_open(hdl, name, ZFS_TYPE_DATASET);
b5256303
TC
2868 if (zhp == NULL) {
2869 err = -1;
2870 goto out;
2871 }
b128c09f 2872 clp = changelist_gather(zhp, ZFS_PROP_NAME, 0,
330d06f9 2873 flags->force ? MS_FORCE : 0);
b5256303
TC
2874 if (clp == NULL) {
2875 err = -1;
2876 goto out;
2877 }
34dc7c2f
BB
2878 err = changelist_prefix(clp);
2879 if (err)
b5256303 2880 goto out;
34dc7c2f
BB
2881
2882 if (tryname) {
a51288aa 2883 (void) strlcpy(newname, tryname, ZFS_MAX_DATASET_NAME_LEN);
330d06f9 2884 if (flags->verbose) {
34dc7c2f 2885 (void) printf("attempting rename %s to %s\n",
dc1c630b 2886 name, newname);
34dc7c2f 2887 }
dc1c630b 2888 err = recv_rename_impl(zhp, name, newname);
34dc7c2f
BB
2889 if (err == 0)
2890 changelist_rename(clp, name, tryname);
2891 } else {
2892 err = ENOENT;
2893 }
2894
13fe0198 2895 if (err != 0 && strncmp(name + baselen, "recv-", 5) != 0) {
34dc7c2f
BB
2896 seq++;
2897
eca7b760
IK
2898 (void) snprintf(newname, ZFS_MAX_DATASET_NAME_LEN,
2899 "%.*srecv-%u-%u", baselen, name, getpid(), seq);
34dc7c2f 2900
330d06f9 2901 if (flags->verbose) {
34dc7c2f 2902 (void) printf("failed - trying rename %s to %s\n",
dc1c630b 2903 name, newname);
34dc7c2f 2904 }
dc1c630b 2905 err = recv_rename_impl(zhp, name, newname);
34dc7c2f
BB
2906 if (err == 0)
2907 changelist_rename(clp, name, newname);
330d06f9 2908 if (err && flags->verbose) {
34dc7c2f
BB
2909 (void) printf("failed (%u) - "
2910 "will try again on next pass\n", errno);
2911 }
2912 err = EAGAIN;
330d06f9 2913 } else if (flags->verbose) {
34dc7c2f
BB
2914 if (err == 0)
2915 (void) printf("success\n");
2916 else
2917 (void) printf("failed (%u)\n", errno);
2918 }
2919
2920 (void) changelist_postfix(clp);
b5256303
TC
2921
2922out:
2923 if (clp != NULL)
2924 changelist_free(clp);
2925 if (zhp != NULL)
2926 zfs_close(zhp);
2927
2928 return (err);
2929}
2930
2931static int
2932recv_promote(libzfs_handle_t *hdl, const char *fsname,
2933 const char *origin_fsname, recvflags_t *flags)
2934{
2935 int err;
2936 zfs_cmd_t zc = {"\0"};
2937 zfs_handle_t *zhp = NULL, *ozhp = NULL;
2938
2939 if (flags->verbose)
2940 (void) printf("promoting %s\n", fsname);
2941
2942 (void) strlcpy(zc.zc_value, origin_fsname, sizeof (zc.zc_value));
2943 (void) strlcpy(zc.zc_name, fsname, sizeof (zc.zc_name));
2944
2945 /*
2946 * Attempt to promote the dataset. If it fails with EACCES the
2947 * promotion would cause this dataset to leave its encryption root.
2948 * Force the origin to become an encryption root and try again.
2949 */
2950 err = zfs_ioctl(hdl, ZFS_IOC_PROMOTE, &zc);
2951 if (err == EACCES) {
2952 zhp = zfs_open(hdl, fsname, ZFS_TYPE_DATASET);
2953 if (zhp == NULL) {
2954 err = -1;
2955 goto out;
2956 }
2957
2958 ozhp = recv_open_grand_origin(zhp);
2959 if (ozhp == NULL) {
2960 err = -1;
2961 goto out;
2962 }
2963
2964 err = lzc_change_key(ozhp->zfs_name, DCP_CMD_FORCE_NEW_KEY,
2965 NULL, NULL, 0);
2966 if (err != 0)
2967 goto out;
2968
2969 err = zfs_ioctl(hdl, ZFS_IOC_PROMOTE, &zc);
2970 }
2971
2972out:
2973 if (zhp != NULL)
2974 zfs_close(zhp);
2975 if (ozhp != NULL)
2976 zfs_close(ozhp);
34dc7c2f
BB
2977
2978 return (err);
2979}
2980
2981static int
2982recv_destroy(libzfs_handle_t *hdl, const char *name, int baselen,
330d06f9 2983 char *newname, recvflags_t *flags)
34dc7c2f 2984{
34dc7c2f
BB
2985 int err = 0;
2986 prop_changelist_t *clp;
2987 zfs_handle_t *zhp;
45d1cae3
BB
2988 boolean_t defer = B_FALSE;
2989 int spa_version;
34dc7c2f
BB
2990
2991 zhp = zfs_open(hdl, name, ZFS_TYPE_DATASET);
2992 if (zhp == NULL)
2993 return (-1);
63652e15
DS
2994 zfs_type_t type = zfs_get_type(zhp);
2995 if (type == ZFS_TYPE_SNAPSHOT &&
45d1cae3
BB
2996 zfs_spa_version(zhp, &spa_version) == 0 &&
2997 spa_version >= SPA_VERSION_USERREFS)
2998 defer = B_TRUE;
63652e15
DS
2999 clp = changelist_gather(zhp, ZFS_PROP_NAME, 0,
3000 flags->force ? MS_FORCE : 0);
34dc7c2f
BB
3001 zfs_close(zhp);
3002 if (clp == NULL)
3003 return (-1);
63652e15 3004
34dc7c2f
BB
3005 err = changelist_prefix(clp);
3006 if (err)
3007 return (err);
3008
330d06f9 3009 if (flags->verbose)
dc1c630b 3010 (void) printf("attempting destroy %s\n", name);
63652e15 3011 if (type == ZFS_TYPE_SNAPSHOT) {
dc1c630b
AG
3012 nvlist_t *nv = fnvlist_alloc();
3013 fnvlist_add_boolean(nv, name);
3014 err = lzc_destroy_snaps(nv, defer, NULL);
3015 fnvlist_free(nv);
3016 } else {
3017 err = lzc_destroy(name);
3018 }
34dc7c2f 3019 if (err == 0) {
330d06f9 3020 if (flags->verbose)
34dc7c2f 3021 (void) printf("success\n");
dc1c630b 3022 changelist_remove(clp, name);
34dc7c2f
BB
3023 }
3024
3025 (void) changelist_postfix(clp);
3026 changelist_free(clp);
3027
45d1cae3 3028 /*
428870ff
BB
3029 * Deferred destroy might destroy the snapshot or only mark it to be
3030 * destroyed later, and it returns success in either case.
45d1cae3 3031 */
428870ff
BB
3032 if (err != 0 || (defer && zfs_dataset_exists(hdl, name,
3033 ZFS_TYPE_SNAPSHOT))) {
34dc7c2f 3034 err = recv_rename(hdl, name, NULL, baselen, newname, flags);
428870ff 3035 }
34dc7c2f
BB
3036
3037 return (err);
3038}
3039
3040typedef struct guid_to_name_data {
3041 uint64_t guid;
47dfff3b 3042 boolean_t bookmark_ok;
34dc7c2f 3043 char *name;
330d06f9 3044 char *skip;
30af21b0
PD
3045 uint64_t *redact_snap_guids;
3046 uint64_t num_redact_snaps;
34dc7c2f
BB
3047} guid_to_name_data_t;
3048
65c7cc49 3049static boolean_t
30af21b0
PD
3050redact_snaps_match(zfs_handle_t *zhp, guid_to_name_data_t *gtnd)
3051{
3052 uint64_t *bmark_snaps;
3053 uint_t bmark_num_snaps;
3054 nvlist_t *nvl;
3055 if (zhp->zfs_type != ZFS_TYPE_BOOKMARK)
3056 return (B_FALSE);
3057
3058 nvl = fnvlist_lookup_nvlist(zhp->zfs_props,
3059 zfs_prop_to_name(ZFS_PROP_REDACT_SNAPS));
3060 bmark_snaps = fnvlist_lookup_uint64_array(nvl, ZPROP_VALUE,
3061 &bmark_num_snaps);
3062 if (bmark_num_snaps != gtnd->num_redact_snaps)
3063 return (B_FALSE);
3064 int i = 0;
3065 for (; i < bmark_num_snaps; i++) {
3066 int j = 0;
3067 for (; j < bmark_num_snaps; j++) {
3068 if (bmark_snaps[i] == gtnd->redact_snap_guids[j])
3069 break;
3070 }
3071 if (j == bmark_num_snaps)
3072 break;
3073 }
3074 return (i == bmark_num_snaps);
3075}
3076
34dc7c2f
BB
3077static int
3078guid_to_name_cb(zfs_handle_t *zhp, void *arg)
3079{
3080 guid_to_name_data_t *gtnd = arg;
47dfff3b 3081 const char *slash;
34dc7c2f
BB
3082 int err;
3083
330d06f9 3084 if (gtnd->skip != NULL &&
47dfff3b
MA
3085 (slash = strrchr(zhp->zfs_name, '/')) != NULL &&
3086 strcmp(slash + 1, gtnd->skip) == 0) {
3087 zfs_close(zhp);
330d06f9
MA
3088 return (0);
3089 }
3090
30af21b0
PD
3091 if (zfs_prop_get_int(zhp, ZFS_PROP_GUID) == gtnd->guid &&
3092 (gtnd->num_redact_snaps == -1 || redact_snaps_match(zhp, gtnd))) {
34dc7c2f 3093 (void) strcpy(gtnd->name, zhp->zfs_name);
428870ff 3094 zfs_close(zhp);
34dc7c2f
BB
3095 return (EEXIST);
3096 }
330d06f9 3097
399b9819 3098 err = zfs_iter_children(zhp, guid_to_name_cb, gtnd);
47dfff3b 3099 if (err != EEXIST && gtnd->bookmark_ok)
399b9819 3100 err = zfs_iter_bookmarks(zhp, guid_to_name_cb, gtnd);
34dc7c2f
BB
3101 zfs_close(zhp);
3102 return (err);
3103}
3104
330d06f9
MA
3105/*
3106 * Attempt to find the local dataset associated with this guid. In the case of
3107 * multiple matches, we attempt to find the "best" match by searching
3108 * progressively larger portions of the hierarchy. This allows one to send a
3109 * tree of datasets individually and guarantee that we will find the source
3110 * guid within that hierarchy, even if there are multiple matches elsewhere.
30af21b0
PD
3111 *
3112 * If num_redact_snaps is not -1, we attempt to find a redaction bookmark with
3113 * the specified number of redaction snapshots. If num_redact_snaps isn't 0 or
3114 * -1, then redact_snap_guids will be an array of the guids of the snapshots the
3115 * redaction bookmark was created with. If num_redact_snaps is -1, then we will
3116 * attempt to find a snapshot or bookmark (if bookmark_ok is passed) with the
3117 * given guid. Note that a redaction bookmark can be returned if
3118 * num_redact_snaps == -1.
330d06f9 3119 */
34dc7c2f 3120static int
30af21b0
PD
3121guid_to_name_redact_snaps(libzfs_handle_t *hdl, const char *parent,
3122 uint64_t guid, boolean_t bookmark_ok, uint64_t *redact_snap_guids,
3123 uint64_t num_redact_snaps, char *name)
34dc7c2f 3124{
eca7b760 3125 char pname[ZFS_MAX_DATASET_NAME_LEN];
34dc7c2f 3126 guid_to_name_data_t gtnd;
34dc7c2f
BB
3127
3128 gtnd.guid = guid;
47dfff3b 3129 gtnd.bookmark_ok = bookmark_ok;
34dc7c2f 3130 gtnd.name = name;
330d06f9 3131 gtnd.skip = NULL;
30af21b0
PD
3132 gtnd.redact_snap_guids = redact_snap_guids;
3133 gtnd.num_redact_snaps = num_redact_snaps;
34dc7c2f 3134
330d06f9 3135 /*
47dfff3b
MA
3136 * Search progressively larger portions of the hierarchy, starting
3137 * with the filesystem specified by 'parent'. This will
330d06f9
MA
3138 * select the "most local" version of the origin snapshot in the case
3139 * that there are multiple matching snapshots in the system.
3140 */
47dfff3b
MA
3141 (void) strlcpy(pname, parent, sizeof (pname));
3142 char *cp = strrchr(pname, '@');
3143 if (cp == NULL)
3144 cp = strchr(pname, '\0');
3145 for (; cp != NULL; cp = strrchr(pname, '/')) {
330d06f9 3146 /* Chop off the last component and open the parent */
34dc7c2f 3147 *cp = '\0';
47dfff3b 3148 zfs_handle_t *zhp = make_dataset_handle(hdl, pname);
330d06f9
MA
3149
3150 if (zhp == NULL)
3151 continue;
47dfff3b
MA
3152 int err = guid_to_name_cb(zfs_handle_dup(zhp), &gtnd);
3153 if (err != EEXIST)
399b9819 3154 err = zfs_iter_children(zhp, guid_to_name_cb, &gtnd);
47dfff3b 3155 if (err != EEXIST && bookmark_ok)
399b9819 3156 err = zfs_iter_bookmarks(zhp, guid_to_name_cb, &gtnd);
34dc7c2f 3157 zfs_close(zhp);
330d06f9
MA
3158 if (err == EEXIST)
3159 return (0);
34dc7c2f 3160
330d06f9 3161 /*
47dfff3b
MA
3162 * Remember the last portion of the dataset so we skip it next
3163 * time through (as we've already searched that portion of the
3164 * hierarchy).
330d06f9 3165 */
47dfff3b 3166 gtnd.skip = strrchr(pname, '/') + 1;
330d06f9 3167 }
34dc7c2f 3168
330d06f9 3169 return (ENOENT);
34dc7c2f
BB
3170}
3171
30af21b0
PD
3172static int
3173guid_to_name(libzfs_handle_t *hdl, const char *parent, uint64_t guid,
3174 boolean_t bookmark_ok, char *name)
3175{
3176 return (guid_to_name_redact_snaps(hdl, parent, guid, bookmark_ok, NULL,
3177 -1, name));
3178}
3179
34dc7c2f 3180/*
330d06f9
MA
3181 * Return +1 if guid1 is before guid2, 0 if they are the same, and -1 if
3182 * guid1 is after guid2.
34dc7c2f
BB
3183 */
3184static int
3185created_before(libzfs_handle_t *hdl, avl_tree_t *avl,
3186 uint64_t guid1, uint64_t guid2)
3187{
3188 nvlist_t *nvfs;
98401d23 3189 char *fsname = NULL, *snapname = NULL;
eca7b760 3190 char buf[ZFS_MAX_DATASET_NAME_LEN];
34dc7c2f 3191 int rv;
330d06f9
MA
3192 zfs_handle_t *guid1hdl, *guid2hdl;
3193 uint64_t create1, create2;
34dc7c2f
BB
3194
3195 if (guid2 == 0)
3196 return (0);
3197 if (guid1 == 0)
3198 return (1);
3199
3200 nvfs = fsavl_find(avl, guid1, &snapname);
60a2434b 3201 fsname = fnvlist_lookup_string(nvfs, "name");
34dc7c2f 3202 (void) snprintf(buf, sizeof (buf), "%s@%s", fsname, snapname);
330d06f9
MA
3203 guid1hdl = zfs_open(hdl, buf, ZFS_TYPE_SNAPSHOT);
3204 if (guid1hdl == NULL)
34dc7c2f
BB
3205 return (-1);
3206
3207 nvfs = fsavl_find(avl, guid2, &snapname);
60a2434b 3208 fsname = fnvlist_lookup_string(nvfs, "name");
34dc7c2f 3209 (void) snprintf(buf, sizeof (buf), "%s@%s", fsname, snapname);
330d06f9
MA
3210 guid2hdl = zfs_open(hdl, buf, ZFS_TYPE_SNAPSHOT);
3211 if (guid2hdl == NULL) {
3212 zfs_close(guid1hdl);
34dc7c2f
BB
3213 return (-1);
3214 }
3215
330d06f9
MA
3216 create1 = zfs_prop_get_int(guid1hdl, ZFS_PROP_CREATETXG);
3217 create2 = zfs_prop_get_int(guid2hdl, ZFS_PROP_CREATETXG);
34dc7c2f 3218
330d06f9
MA
3219 if (create1 < create2)
3220 rv = -1;
3221 else if (create1 > create2)
3222 rv = +1;
3223 else
3224 rv = 0;
3225
3226 zfs_close(guid1hdl);
3227 zfs_close(guid2hdl);
34dc7c2f
BB
3228
3229 return (rv);
3230}
3231
b5256303 3232/*
83472fab 3233 * This function reestablishes the hierarchy of encryption roots after a
b5256303
TC
3234 * recursive incremental receive has completed. This must be done after the
3235 * second call to recv_incremental_replication() has renamed and promoted all
83472fab 3236 * sent datasets to their final locations in the dataset hierarchy.
b5256303
TC
3237 */
3238static int
bb61cc31 3239recv_fix_encryption_hierarchy(libzfs_handle_t *hdl, const char *top_zfs,
7633c0ae 3240 nvlist_t *stream_nv)
b5256303
TC
3241{
3242 int err;
3243 nvpair_t *fselem = NULL;
3244 nvlist_t *stream_fss;
3245
60a2434b 3246 stream_fss = fnvlist_lookup_nvlist(stream_nv, "fss");
b5256303
TC
3247
3248 while ((fselem = nvlist_next_nvpair(stream_fss, fselem)) != NULL) {
3249 zfs_handle_t *zhp = NULL;
3250 uint64_t crypt;
3251 nvlist_t *snaps, *props, *stream_nvfs = NULL;
3252 nvpair_t *snapel = NULL;
3253 boolean_t is_encroot, is_clone, stream_encroot;
3254 char *cp;
3255 char *stream_keylocation = NULL;
3256 char keylocation[MAXNAMELEN];
3257 char fsname[ZFS_MAX_DATASET_NAME_LEN];
3258
3259 keylocation[0] = '\0';
60a2434b
RM
3260 stream_nvfs = fnvpair_value_nvlist(fselem);
3261 snaps = fnvlist_lookup_nvlist(stream_nvfs, "snaps");
3262 props = fnvlist_lookup_nvlist(stream_nvfs, "props");
b5256303
TC
3263 stream_encroot = nvlist_exists(stream_nvfs, "is_encroot");
3264
3265 /* find a snapshot from the stream that exists locally */
3266 err = ENOENT;
3267 while ((snapel = nvlist_next_nvpair(snaps, snapel)) != NULL) {
3268 uint64_t guid;
3269
60a2434b 3270 guid = fnvpair_value_uint64(snapel);
bb61cc31 3271 err = guid_to_name(hdl, top_zfs, guid, B_FALSE,
b5256303
TC
3272 fsname);
3273 if (err == 0)
3274 break;
3275 }
3276
3277 if (err != 0)
3278 continue;
3279
3280 cp = strchr(fsname, '@');
3281 if (cp != NULL)
3282 *cp = '\0';
3283
3284 zhp = zfs_open(hdl, fsname, ZFS_TYPE_DATASET);
3285 if (zhp == NULL) {
3286 err = ENOENT;
3287 goto error;
3288 }
3289
3290 crypt = zfs_prop_get_int(zhp, ZFS_PROP_ENCRYPTION);
3291 is_clone = zhp->zfs_dmustats.dds_origin[0] != '\0';
3292 (void) zfs_crypto_get_encryption_root(zhp, &is_encroot, NULL);
3293
da689887 3294 /* we don't need to do anything for unencrypted datasets */
b5256303
TC
3295 if (crypt == ZIO_CRYPT_OFF) {
3296 zfs_close(zhp);
3297 continue;
3298 }
3299
3300 /*
3301 * If the dataset is flagged as an encryption root, was not
3302 * received as a clone and is not currently an encryption root,
3303 * force it to become one. Fixup the keylocation if necessary.
3304 */
3305 if (stream_encroot) {
3306 if (!is_clone && !is_encroot) {
3307 err = lzc_change_key(fsname,
3308 DCP_CMD_FORCE_NEW_KEY, NULL, NULL, 0);
3309 if (err != 0) {
3310 zfs_close(zhp);
3311 goto error;
3312 }
3313 }
3314
60a2434b
RM
3315 stream_keylocation = fnvlist_lookup_string(props,
3316 zfs_prop_to_name(ZFS_PROP_KEYLOCATION));
b5256303
TC
3317
3318 /*
3319 * Refresh the properties in case the call to
3320 * lzc_change_key() changed the value.
3321 */
3322 zfs_refresh_properties(zhp);
3323 err = zfs_prop_get(zhp, ZFS_PROP_KEYLOCATION,
3324 keylocation, sizeof (keylocation), NULL, NULL,
3325 0, B_TRUE);
3326 if (err != 0) {
3327 zfs_close(zhp);
3328 goto error;
3329 }
3330
3331 if (strcmp(keylocation, stream_keylocation) != 0) {
3332 err = zfs_prop_set(zhp,
3333 zfs_prop_to_name(ZFS_PROP_KEYLOCATION),
3334 stream_keylocation);
3335 if (err != 0) {
3336 zfs_close(zhp);
3337 goto error;
3338 }
3339 }
3340 }
3341
3342 /*
3343 * If the dataset is not flagged as an encryption root and is
3344 * currently an encryption root, force it to inherit from its
4807c0ba
TC
3345 * parent. The root of a raw send should never be
3346 * force-inherited.
b5256303 3347 */
4807c0ba
TC
3348 if (!stream_encroot && is_encroot &&
3349 strcmp(top_zfs, fsname) != 0) {
b5256303
TC
3350 err = lzc_change_key(fsname, DCP_CMD_FORCE_INHERIT,
3351 NULL, NULL, 0);
3352 if (err != 0) {
3353 zfs_close(zhp);
3354 goto error;
3355 }
3356 }
3357
3358 zfs_close(zhp);
3359 }
3360
3361 return (0);
3362
3363error:
3364 return (err);
3365}
3366
34dc7c2f
BB
3367static int
3368recv_incremental_replication(libzfs_handle_t *hdl, const char *tofs,
330d06f9 3369 recvflags_t *flags, nvlist_t *stream_nv, avl_tree_t *stream_avl,
428870ff 3370 nvlist_t *renamed)
34dc7c2f 3371{
7509a3d2 3372 nvlist_t *local_nv, *deleted = NULL;
34dc7c2f
BB
3373 avl_tree_t *local_avl;
3374 nvpair_t *fselem, *nextfselem;
428870ff 3375 char *fromsnap;
eca7b760 3376 char newname[ZFS_MAX_DATASET_NAME_LEN];
7509a3d2 3377 char guidname[32];
34dc7c2f 3378 int error;
428870ff
BB
3379 boolean_t needagain, progress, recursive;
3380 char *s1, *s2;
34dc7c2f 3381
60a2434b 3382 fromsnap = fnvlist_lookup_string(stream_nv, "fromsnap");
428870ff
BB
3383
3384 recursive = (nvlist_lookup_boolean(stream_nv, "not_recursive") ==
3385 ENOENT);
34dc7c2f 3386
330d06f9 3387 if (flags->dryrun)
34dc7c2f
BB
3388 return (0);
3389
3390again:
3391 needagain = progress = B_FALSE;
3392
60a2434b 3393 deleted = fnvlist_alloc();
7509a3d2 3394
34dc7c2f 3395 if ((error = gather_nvlist(hdl, tofs, fromsnap, NULL,
099fa7e4 3396 recursive, B_TRUE, B_FALSE, recursive, B_FALSE, B_FALSE, B_FALSE,
f94b3cbf 3397 B_FALSE, B_TRUE, &local_nv, &local_avl)) != 0)
34dc7c2f
BB
3398 return (error);
3399
3400 /*
3401 * Process deletes and renames
3402 */
3403 for (fselem = nvlist_next_nvpair(local_nv, NULL);
3404 fselem; fselem = nextfselem) {
3405 nvlist_t *nvfs, *snaps;
3406 nvlist_t *stream_nvfs = NULL;
3407 nvpair_t *snapelem, *nextsnapelem;
3408 uint64_t fromguid = 0;
3409 uint64_t originguid = 0;
3410 uint64_t stream_originguid = 0;
3411 uint64_t parent_fromsnap_guid, stream_parent_fromsnap_guid;
3412 char *fsname, *stream_fsname;
3413
3414 nextfselem = nvlist_next_nvpair(local_nv, fselem);
3415
60a2434b
RM
3416 nvfs = fnvpair_value_nvlist(fselem);
3417 snaps = fnvlist_lookup_nvlist(nvfs, "snaps");
3418 fsname = fnvlist_lookup_string(nvfs, "name");
3419 parent_fromsnap_guid = fnvlist_lookup_uint64(nvfs,
3420 "parentfromsnap");
34dc7c2f
BB
3421 (void) nvlist_lookup_uint64(nvfs, "origin", &originguid);
3422
3423 /*
3424 * First find the stream's fs, so we can check for
3425 * a different origin (due to "zfs promote")
3426 */
3427 for (snapelem = nvlist_next_nvpair(snaps, NULL);
3428 snapelem; snapelem = nvlist_next_nvpair(snaps, snapelem)) {
3429 uint64_t thisguid;
3430
60a2434b 3431 thisguid = fnvpair_value_uint64(snapelem);
34dc7c2f
BB
3432 stream_nvfs = fsavl_find(stream_avl, thisguid, NULL);
3433
3434 if (stream_nvfs != NULL)
3435 break;
3436 }
3437
3438 /* check for promote */
3439 (void) nvlist_lookup_uint64(stream_nvfs, "origin",
3440 &stream_originguid);
3441 if (stream_nvfs && originguid != stream_originguid) {
3442 switch (created_before(hdl, local_avl,
3443 stream_originguid, originguid)) {
3444 case 1: {
3445 /* promote it! */
34dc7c2f
BB
3446 nvlist_t *origin_nvfs;
3447 char *origin_fsname;
3448
34dc7c2f
BB
3449 origin_nvfs = fsavl_find(local_avl, originguid,
3450 NULL);
60a2434b
RM
3451 origin_fsname = fnvlist_lookup_string(
3452 origin_nvfs, "name");
b5256303
TC
3453 error = recv_promote(hdl, fsname, origin_fsname,
3454 flags);
34dc7c2f
BB
3455 if (error == 0)
3456 progress = B_TRUE;
3457 break;
3458 }
3459 default:
3460 break;
3461 case -1:
3462 fsavl_destroy(local_avl);
60a2434b 3463 fnvlist_free(local_nv);
34dc7c2f
BB
3464 return (-1);
3465 }
3466 /*
3467 * We had/have the wrong origin, therefore our
3468 * list of snapshots is wrong. Need to handle
3469 * them on the next pass.
3470 */
3471 needagain = B_TRUE;
3472 continue;
3473 }
3474
3475 for (snapelem = nvlist_next_nvpair(snaps, NULL);
3476 snapelem; snapelem = nextsnapelem) {
3477 uint64_t thisguid;
3478 char *stream_snapname;
b128c09f 3479 nvlist_t *found, *props;
34dc7c2f
BB
3480
3481 nextsnapelem = nvlist_next_nvpair(snaps, snapelem);
3482
60a2434b 3483 thisguid = fnvpair_value_uint64(snapelem);
34dc7c2f
BB
3484 found = fsavl_find(stream_avl, thisguid,
3485 &stream_snapname);
3486
3487 /* check for delete */
3488 if (found == NULL) {
eca7b760 3489 char name[ZFS_MAX_DATASET_NAME_LEN];
34dc7c2f 3490
330d06f9 3491 if (!flags->force)
34dc7c2f
BB
3492 continue;
3493
3494 (void) snprintf(name, sizeof (name), "%s@%s",
3495 fsname, nvpair_name(snapelem));
3496
3497 error = recv_destroy(hdl, name,
3498 strlen(fsname)+1, newname, flags);
3499 if (error)
3500 needagain = B_TRUE;
3501 else
3502 progress = B_TRUE;
3df29340
BB
3503 sprintf(guidname, "%llu",
3504 (u_longlong_t)thisguid);
7509a3d2 3505 nvlist_add_boolean(deleted, guidname);
34dc7c2f
BB
3506 continue;
3507 }
3508
3509 stream_nvfs = found;
3510
b128c09f
BB
3511 if (0 == nvlist_lookup_nvlist(stream_nvfs, "snapprops",
3512 &props) && 0 == nvlist_lookup_nvlist(props,
3513 stream_snapname, &props)) {
13fe0198 3514 zfs_cmd_t zc = {"\0"};
b128c09f 3515
428870ff 3516 zc.zc_cookie = B_TRUE; /* received */
b128c09f
BB
3517 (void) snprintf(zc.zc_name, sizeof (zc.zc_name),
3518 "%s@%s", fsname, nvpair_name(snapelem));
18dbf5c8
AZ
3519 zcmd_write_src_nvlist(hdl, &zc, props);
3520 (void) zfs_ioctl(hdl,
3521 ZFS_IOC_SET_PROP, &zc);
3522 zcmd_free_nvlists(&zc);
b128c09f
BB
3523 }
3524
34dc7c2f
BB
3525 /* check for different snapname */
3526 if (strcmp(nvpair_name(snapelem),
3527 stream_snapname) != 0) {
eca7b760
IK
3528 char name[ZFS_MAX_DATASET_NAME_LEN];
3529 char tryname[ZFS_MAX_DATASET_NAME_LEN];
34dc7c2f
BB
3530
3531 (void) snprintf(name, sizeof (name), "%s@%s",
3532 fsname, nvpair_name(snapelem));
3533 (void) snprintf(tryname, sizeof (name), "%s@%s",
3534 fsname, stream_snapname);
3535
3536 error = recv_rename(hdl, name, tryname,
3537 strlen(fsname)+1, newname, flags);
3538 if (error)
3539 needagain = B_TRUE;
3540 else
3541 progress = B_TRUE;
3542 }
3543
3544 if (strcmp(stream_snapname, fromsnap) == 0)
3545 fromguid = thisguid;
3546 }
3547
3548 /* check for delete */
3549 if (stream_nvfs == NULL) {
330d06f9 3550 if (!flags->force)
34dc7c2f
BB
3551 continue;
3552
3553 error = recv_destroy(hdl, fsname, strlen(tofs)+1,
3554 newname, flags);
3555 if (error)
3556 needagain = B_TRUE;
3557 else
3558 progress = B_TRUE;
3df29340 3559 sprintf(guidname, "%llu",
02730c33 3560 (u_longlong_t)parent_fromsnap_guid);
7509a3d2 3561 nvlist_add_boolean(deleted, guidname);
34dc7c2f
BB
3562 continue;
3563 }
3564
428870ff 3565 if (fromguid == 0) {
330d06f9 3566 if (flags->verbose) {
428870ff
BB
3567 (void) printf("local fs %s does not have "
3568 "fromsnap (%s in stream); must have "
3569 "been deleted locally; ignoring\n",
3570 fsname, fromsnap);
3571 }
34dc7c2f
BB
3572 continue;
3573 }
3574
60a2434b
RM
3575 stream_fsname = fnvlist_lookup_string(stream_nvfs, "name");
3576 stream_parent_fromsnap_guid = fnvlist_lookup_uint64(
3577 stream_nvfs, "parentfromsnap");
34dc7c2f 3578
428870ff
BB
3579 s1 = strrchr(fsname, '/');
3580 s2 = strrchr(stream_fsname, '/');
3581
7509a3d2 3582 /*
3583 * Check if we're going to rename based on parent guid change
3584 * and the current parent guid was also deleted. If it was then
3585 * rename will fail and is likely unneeded, so avoid this and
3586 * force an early retry to determine the new
3587 * parent_fromsnap_guid.
3588 */
3589 if (stream_parent_fromsnap_guid != 0 &&
3590 parent_fromsnap_guid != 0 &&
3591 stream_parent_fromsnap_guid != parent_fromsnap_guid) {
3df29340 3592 sprintf(guidname, "%llu",
02730c33 3593 (u_longlong_t)parent_fromsnap_guid);
7509a3d2 3594 if (nvlist_exists(deleted, guidname)) {
3595 progress = B_TRUE;
3596 needagain = B_TRUE;
3597 goto doagain;
3598 }
3599 }
3600
428870ff
BB
3601 /*
3602 * Check for rename. If the exact receive path is specified, it
3603 * does not count as a rename, but we still need to check the
3604 * datasets beneath it.
3605 */
34dc7c2f 3606 if ((stream_parent_fromsnap_guid != 0 &&
428870ff 3607 parent_fromsnap_guid != 0 &&
34dc7c2f 3608 stream_parent_fromsnap_guid != parent_fromsnap_guid) ||
330d06f9 3609 ((flags->isprefix || strcmp(tofs, fsname) != 0) &&
428870ff 3610 (s1 != NULL) && (s2 != NULL) && strcmp(s1, s2) != 0)) {
34dc7c2f 3611 nvlist_t *parent;
eca7b760 3612 char tryname[ZFS_MAX_DATASET_NAME_LEN];
34dc7c2f
BB
3613
3614 parent = fsavl_find(local_avl,
3615 stream_parent_fromsnap_guid, NULL);
3616 /*
3617 * NB: parent might not be found if we used the
3618 * tosnap for stream_parent_fromsnap_guid,
3619 * because the parent is a newly-created fs;
3620 * we'll be able to rename it after we recv the
3621 * new fs.
3622 */
3623 if (parent != NULL) {
3624 char *pname;
3625
60a2434b 3626 pname = fnvlist_lookup_string(parent, "name");
34dc7c2f
BB
3627 (void) snprintf(tryname, sizeof (tryname),
3628 "%s%s", pname, strrchr(stream_fsname, '/'));
3629 } else {
3630 tryname[0] = '\0';
330d06f9 3631 if (flags->verbose) {
34dc7c2f
BB
3632 (void) printf("local fs %s new parent "
3633 "not found\n", fsname);
3634 }
3635 }
3636
428870ff
BB
3637 newname[0] = '\0';
3638
34dc7c2f
BB
3639 error = recv_rename(hdl, fsname, tryname,
3640 strlen(tofs)+1, newname, flags);
428870ff
BB
3641
3642 if (renamed != NULL && newname[0] != '\0') {
60a2434b 3643 fnvlist_add_boolean(renamed, newname);
428870ff
BB
3644 }
3645
34dc7c2f
BB
3646 if (error)
3647 needagain = B_TRUE;
3648 else
3649 progress = B_TRUE;
3650 }
3651 }
3652
7509a3d2 3653doagain:
34dc7c2f 3654 fsavl_destroy(local_avl);
60a2434b
RM
3655 fnvlist_free(local_nv);
3656 fnvlist_free(deleted);
34dc7c2f
BB
3657
3658 if (needagain && progress) {
3659 /* do another pass to fix up temporary names */
330d06f9 3660 if (flags->verbose)
34dc7c2f
BB
3661 (void) printf("another pass:\n");
3662 goto again;
3663 }
3664
b5256303 3665 return (needagain || error != 0);
34dc7c2f
BB
3666}
3667
3668static int
3669zfs_receive_package(libzfs_handle_t *hdl, int fd, const char *destname,
330d06f9 3670 recvflags_t *flags, dmu_replay_record_t *drr, zio_cksum_t *zc,
196bee4c 3671 char **top_zfs, nvlist_t *cmdprops)
34dc7c2f
BB
3672{
3673 nvlist_t *stream_nv = NULL;
3674 avl_tree_t *stream_avl = NULL;
3675 char *fromsnap = NULL;
671c9354 3676 char *sendsnap = NULL;
428870ff 3677 char *cp;
eca7b760
IK
3678 char tofs[ZFS_MAX_DATASET_NAME_LEN];
3679 char sendfs[ZFS_MAX_DATASET_NAME_LEN];
d68a2bfa 3680 char errbuf[ERRBUFLEN];
34dc7c2f
BB
3681 dmu_replay_record_t drre;
3682 int error;
3683 boolean_t anyerr = B_FALSE;
3684 boolean_t softerr = B_FALSE;
b5256303 3685 boolean_t recursive, raw;
34dc7c2f
BB
3686
3687 (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
3688 "cannot receive"));
3689
34dc7c2f
BB
3690 assert(drr->drr_type == DRR_BEGIN);
3691 assert(drr->drr_u.drr_begin.drr_magic == DMU_BACKUP_MAGIC);
428870ff
BB
3692 assert(DMU_GET_STREAM_HDRTYPE(drr->drr_u.drr_begin.drr_versioninfo) ==
3693 DMU_COMPOUNDSTREAM);
34dc7c2f
BB
3694
3695 /*
3696 * Read in the nvlist from the stream.
3697 */
3698 if (drr->drr_payloadlen != 0) {
34dc7c2f 3699 error = recv_read_nvlist(hdl, fd, drr->drr_payloadlen,
330d06f9 3700 &stream_nv, flags->byteswap, zc);
34dc7c2f
BB
3701 if (error) {
3702 error = zfs_error(hdl, EZFS_BADSTREAM, errbuf);
3703 goto out;
3704 }
3705 }
3706
428870ff
BB
3707 recursive = (nvlist_lookup_boolean(stream_nv, "not_recursive") ==
3708 ENOENT);
b5256303 3709 raw = (nvlist_lookup_boolean(stream_nv, "raw") == 0);
428870ff
BB
3710
3711 if (recursive && strchr(destname, '@')) {
3712 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3713 "cannot specify snapshot name for multi-snapshot stream"));
3714 error = zfs_error(hdl, EZFS_BADSTREAM, errbuf);
3715 goto out;
3716 }
3717
34dc7c2f
BB
3718 /*
3719 * Read in the end record and verify checksum.
3720 */
3721 if (0 != (error = recv_read(hdl, fd, &drre, sizeof (drre),
330d06f9 3722 flags->byteswap, NULL)))
34dc7c2f 3723 goto out;
330d06f9 3724 if (flags->byteswap) {
34dc7c2f
BB
3725 drre.drr_type = BSWAP_32(drre.drr_type);
3726 drre.drr_u.drr_end.drr_checksum.zc_word[0] =
3727 BSWAP_64(drre.drr_u.drr_end.drr_checksum.zc_word[0]);
3728 drre.drr_u.drr_end.drr_checksum.zc_word[1] =
3729 BSWAP_64(drre.drr_u.drr_end.drr_checksum.zc_word[1]);
3730 drre.drr_u.drr_end.drr_checksum.zc_word[2] =
3731 BSWAP_64(drre.drr_u.drr_end.drr_checksum.zc_word[2]);
3732 drre.drr_u.drr_end.drr_checksum.zc_word[3] =
3733 BSWAP_64(drre.drr_u.drr_end.drr_checksum.zc_word[3]);
3734 }
3735 if (drre.drr_type != DRR_END) {
3736 error = zfs_error(hdl, EZFS_BADSTREAM, errbuf);
3737 goto out;
3738 }
3739 if (!ZIO_CHECKSUM_EQUAL(drre.drr_u.drr_end.drr_checksum, *zc)) {
3740 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3741 "incorrect header checksum"));
3742 error = zfs_error(hdl, EZFS_BADSTREAM, errbuf);
3743 goto out;
3744 }
3745
3746 (void) nvlist_lookup_string(stream_nv, "fromsnap", &fromsnap);
3747
3748 if (drr->drr_payloadlen != 0) {
3749 nvlist_t *stream_fss;
3750
60a2434b 3751 stream_fss = fnvlist_lookup_nvlist(stream_nv, "fss");
34dc7c2f
BB
3752 if ((stream_avl = fsavl_create(stream_fss)) == NULL) {
3753 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3754 "couldn't allocate avl tree"));
3755 error = zfs_error(hdl, EZFS_NOMEM, errbuf);
3756 goto out;
3757 }
3758
4c3c6b6c 3759 if (fromsnap != NULL && recursive) {
428870ff
BB
3760 nvlist_t *renamed = NULL;
3761 nvpair_t *pair = NULL;
3762
eca7b760 3763 (void) strlcpy(tofs, destname, sizeof (tofs));
330d06f9 3764 if (flags->isprefix) {
428870ff
BB
3765 struct drr_begin *drrb = &drr->drr_u.drr_begin;
3766 int i;
3767
330d06f9 3768 if (flags->istail) {
428870ff
BB
3769 cp = strrchr(drrb->drr_toname, '/');
3770 if (cp == NULL) {
3771 (void) strlcat(tofs, "/",
eca7b760 3772 sizeof (tofs));
428870ff
BB
3773 i = 0;
3774 } else {
3775 i = (cp - drrb->drr_toname);
3776 }
3777 } else {
3778 i = strcspn(drrb->drr_toname, "/@");
3779 }
34dc7c2f 3780 /* zfs_receive_one() will create_parents() */
428870ff 3781 (void) strlcat(tofs, &drrb->drr_toname[i],
eca7b760 3782 sizeof (tofs));
34dc7c2f
BB
3783 *strchr(tofs, '@') = '\0';
3784 }
428870ff 3785
4c3c6b6c 3786 if (!flags->dryrun && !flags->nomount) {
60a2434b 3787 renamed = fnvlist_alloc();
428870ff
BB
3788 }
3789
3790 softerr = recv_incremental_replication(hdl, tofs, flags,
3791 stream_nv, stream_avl, renamed);
3792
3793 /* Unmount renamed filesystems before receiving. */
3794 while ((pair = nvlist_next_nvpair(renamed,
3795 pair)) != NULL) {
3796 zfs_handle_t *zhp;
3797 prop_changelist_t *clp = NULL;
3798
3799 zhp = zfs_open(hdl, nvpair_name(pair),
3800 ZFS_TYPE_FILESYSTEM);
3801 if (zhp != NULL) {
3802 clp = changelist_gather(zhp,
a57d3d45
MZ
3803 ZFS_PROP_MOUNTPOINT, 0,
3804 flags->forceunmount ? MS_FORCE : 0);
428870ff
BB
3805 zfs_close(zhp);
3806 if (clp != NULL) {
3807 softerr |=
3808 changelist_prefix(clp);
3809 changelist_free(clp);
3810 }
3811 }
3812 }
3813
60a2434b 3814 fnvlist_free(renamed);
34dc7c2f
BB
3815 }
3816 }
3817
428870ff
BB
3818 /*
3819 * Get the fs specified by the first path in the stream (the top level
3820 * specified by 'zfs send') and pass it to each invocation of
3821 * zfs_receive_one().
3822 */
3823 (void) strlcpy(sendfs, drr->drr_u.drr_begin.drr_toname,
eca7b760 3824 sizeof (sendfs));
671c9354 3825 if ((cp = strchr(sendfs, '@')) != NULL) {
428870ff 3826 *cp = '\0';
671c9354
DM
3827 /*
3828 * Find the "sendsnap", the final snapshot in a replication
3829 * stream. zfs_receive_one() handles certain errors
3830 * differently, depending on if the contained stream is the
3831 * last one or not.
3832 */
3833 sendsnap = (cp + 1);
3834 }
34dc7c2f
BB
3835
3836 /* Finally, receive each contained stream */
3837 do {
3838 /*
3839 * we should figure out if it has a recoverable
3840 * error, in which case do a recv_skip() and drive on.
3841 * Note, if we fail due to already having this guid,
3842 * zfs_receive_one() will take care of it (ie,
3843 * recv_skip() and return 0).
3844 */
fcff0f35 3845 error = zfs_receive_impl(hdl, destname, NULL, flags, fd,
196bee4c 3846 sendfs, stream_nv, stream_avl, top_zfs, sendsnap, cmdprops);
34dc7c2f
BB
3847 if (error == ENODATA) {
3848 error = 0;
3849 break;
3850 }
3851 anyerr |= error;
3852 } while (error == 0);
3853
4c3c6b6c 3854 if (drr->drr_payloadlen != 0 && recursive && fromsnap != NULL) {
34dc7c2f
BB
3855 /*
3856 * Now that we have the fs's they sent us, try the
3857 * renames again.
3858 */
3859 softerr = recv_incremental_replication(hdl, tofs, flags,
428870ff 3860 stream_nv, stream_avl, NULL);
34dc7c2f
BB
3861 }
3862
bb61cc31
TC
3863 if (raw && softerr == 0 && *top_zfs != NULL) {
3864 softerr = recv_fix_encryption_hierarchy(hdl, *top_zfs,
7633c0ae 3865 stream_nv);
b5256303
TC
3866 }
3867
34dc7c2f
BB
3868out:
3869 fsavl_destroy(stream_avl);
60a2434b 3870 fnvlist_free(stream_nv);
34dc7c2f
BB
3871 if (softerr)
3872 error = -2;
3873 if (anyerr)
3874 error = -1;
3875 return (error);
3876}
3877
428870ff
BB
3878static void
3879trunc_prop_errs(int truncated)
3880{
3881 ASSERT(truncated != 0);
3882
3883 if (truncated == 1)
3884 (void) fprintf(stderr, dgettext(TEXT_DOMAIN,
3885 "1 more property could not be set\n"));
3886 else
3887 (void) fprintf(stderr, dgettext(TEXT_DOMAIN,
3888 "%d more properties could not be set\n"), truncated);
3889}
3890
34dc7c2f
BB
3891static int
3892recv_skip(libzfs_handle_t *hdl, int fd, boolean_t byteswap)
3893{
3894 dmu_replay_record_t *drr;
f1512ee6 3895 void *buf = zfs_alloc(hdl, SPA_MAXBLOCKSIZE);
870e7a52 3896 uint64_t payload_size;
d68a2bfa 3897 char errbuf[ERRBUFLEN];
428870ff
BB
3898
3899 (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
870e7a52 3900 "cannot receive"));
34dc7c2f
BB
3901
3902 /* XXX would be great to use lseek if possible... */
3903 drr = buf;
3904
3905 while (recv_read(hdl, fd, drr, sizeof (dmu_replay_record_t),
3906 byteswap, NULL) == 0) {
3907 if (byteswap)
3908 drr->drr_type = BSWAP_32(drr->drr_type);
3909
3910 switch (drr->drr_type) {
3911 case DRR_BEGIN:
428870ff 3912 if (drr->drr_payloadlen != 0) {
47dfff3b
MA
3913 (void) recv_read(hdl, fd, buf,
3914 drr->drr_payloadlen, B_FALSE, NULL);
428870ff 3915 }
34dc7c2f
BB
3916 break;
3917
3918 case DRR_END:
3919 free(buf);
3920 return (0);
3921
3922 case DRR_OBJECT:
3923 if (byteswap) {
3924 drr->drr_u.drr_object.drr_bonuslen =
3925 BSWAP_32(drr->drr_u.drr_object.
3926 drr_bonuslen);
870e7a52
TC
3927 drr->drr_u.drr_object.drr_raw_bonuslen =
3928 BSWAP_32(drr->drr_u.drr_object.
3929 drr_raw_bonuslen);
34dc7c2f 3930 }
870e7a52
TC
3931
3932 payload_size =
3933 DRR_OBJECT_PAYLOAD_SIZE(&drr->drr_u.drr_object);
3934 (void) recv_read(hdl, fd, buf, payload_size,
34dc7c2f
BB
3935 B_FALSE, NULL);
3936 break;
3937
3938 case DRR_WRITE:
3939 if (byteswap) {
2aa34383
DK
3940 drr->drr_u.drr_write.drr_logical_size =
3941 BSWAP_64(
3942 drr->drr_u.drr_write.drr_logical_size);
3943 drr->drr_u.drr_write.drr_compressed_size =
3944 BSWAP_64(
3945 drr->drr_u.drr_write.drr_compressed_size);
34dc7c2f 3946 }
870e7a52 3947 payload_size =
2aa34383 3948 DRR_WRITE_PAYLOAD_SIZE(&drr->drr_u.drr_write);
7a6c12fd 3949 assert(payload_size <= SPA_MAXBLOCKSIZE);
34dc7c2f 3950 (void) recv_read(hdl, fd, buf,
2aa34383 3951 payload_size, B_FALSE, NULL);
34dc7c2f 3952 break;
428870ff
BB
3953 case DRR_SPILL:
3954 if (byteswap) {
9f8026c8 3955 drr->drr_u.drr_spill.drr_length =
428870ff 3956 BSWAP_64(drr->drr_u.drr_spill.drr_length);
870e7a52
TC
3957 drr->drr_u.drr_spill.drr_compressed_size =
3958 BSWAP_64(drr->drr_u.drr_spill.
3959 drr_compressed_size);
428870ff 3960 }
870e7a52
TC
3961
3962 payload_size =
3963 DRR_SPILL_PAYLOAD_SIZE(&drr->drr_u.drr_spill);
3964 (void) recv_read(hdl, fd, buf, payload_size,
3965 B_FALSE, NULL);
428870ff 3966 break;
9b67f605
MA
3967 case DRR_WRITE_EMBEDDED:
3968 if (byteswap) {
3969 drr->drr_u.drr_write_embedded.drr_psize =
3970 BSWAP_32(drr->drr_u.drr_write_embedded.
3971 drr_psize);
3972 }
3973 (void) recv_read(hdl, fd, buf,
3974 P2ROUNDUP(drr->drr_u.drr_write_embedded.drr_psize,
3975 8), B_FALSE, NULL);
3976 break;
30af21b0 3977 case DRR_OBJECT_RANGE:
428870ff 3978 case DRR_WRITE_BYREF:
34dc7c2f
BB
3979 case DRR_FREEOBJECTS:
3980 case DRR_FREE:
3981 break;
3982
3983 default:
428870ff
BB
3984 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3985 "invalid record type"));
fad5fb01 3986 free(buf);
428870ff 3987 return (zfs_error(hdl, EZFS_BADSTREAM, errbuf));
34dc7c2f
BB
3988 }
3989 }
3990
3991 free(buf);
3992 return (-1);
3993}
3994
47dfff3b
MA
3995static void
3996recv_ecksum_set_aux(libzfs_handle_t *hdl, const char *target_snap,
7145123b 3997 boolean_t resumable, boolean_t checksum)
47dfff3b 3998{
eca7b760 3999 char target_fs[ZFS_MAX_DATASET_NAME_LEN];
47dfff3b 4000
7145123b
PD
4001 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, (checksum ?
4002 "checksum mismatch" : "incomplete stream")));
47dfff3b
MA
4003
4004 if (!resumable)
4005 return;
4006 (void) strlcpy(target_fs, target_snap, sizeof (target_fs));
4007 *strchr(target_fs, '@') = '\0';
4008 zfs_handle_t *zhp = zfs_open(hdl, target_fs,
4009 ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME);
4010 if (zhp == NULL)
4011 return;
4012
4013 char token_buf[ZFS_MAXPROPLEN];
4014 int error = zfs_prop_get(zhp, ZFS_PROP_RECEIVE_RESUME_TOKEN,
4015 token_buf, sizeof (token_buf),
4016 NULL, NULL, 0, B_TRUE);
4017 if (error == 0) {
4018 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
4019 "checksum mismatch or incomplete stream.\n"
4020 "Partially received snapshot is saved.\n"
4021 "A resuming stream can be generated on the sending "
4022 "system by running:\n"
4023 " zfs send -t %s"),
4024 token_buf);
4025 }
4026 zfs_close(zhp);
4027}
4028
a3eeab2d 4029/*
4030 * Prepare a new nvlist of properties that are to override (-o) or be excluded
4031 * (-x) from the received dataset
4032 * recvprops: received properties from the send stream
4033 * cmdprops: raw input properties from command line
4034 * origprops: properties, both locally-set and received, currently set on the
4035 * target dataset if it exists, NULL otherwise.
4036 * oxprops: valid output override (-o) and excluded (-x) properties
4037 */
4038static int
d9c460a0
TC
4039zfs_setup_cmdline_props(libzfs_handle_t *hdl, zfs_type_t type,
4040 char *fsname, boolean_t zoned, boolean_t recursive, boolean_t newfs,
4041 boolean_t raw, boolean_t toplevel, nvlist_t *recvprops, nvlist_t *cmdprops,
4042 nvlist_t *origprops, nvlist_t **oxprops, uint8_t **wkeydata_out,
4043 uint_t *wkeylen_out, const char *errbuf)
a3eeab2d 4044{
4045 nvpair_t *nvp;
4046 nvlist_t *oprops, *voprops;
4047 zfs_handle_t *zhp = NULL;
4048 zpool_handle_t *zpool_hdl = NULL;
d9c460a0 4049 char *cp;
a3eeab2d 4050 int ret = 0;
d9c460a0 4051 char namebuf[ZFS_MAX_DATASET_NAME_LEN];
a3eeab2d 4052
4053 if (nvlist_empty(cmdprops))
4054 return (0); /* No properties to override or exclude */
4055
4056 *oxprops = fnvlist_alloc();
4057 oprops = fnvlist_alloc();
4058
d9c460a0
TC
4059 strlcpy(namebuf, fsname, ZFS_MAX_DATASET_NAME_LEN);
4060
4061 /*
4062 * Get our dataset handle. The target dataset may not exist yet.
4063 */
4064 if (zfs_dataset_exists(hdl, namebuf, ZFS_TYPE_DATASET)) {
4065 zhp = zfs_open(hdl, namebuf, ZFS_TYPE_DATASET);
4066 if (zhp == NULL) {
4067 ret = -1;
4068 goto error;
4069 }
4070 }
4071
4072 /* open the zpool handle */
4073 cp = strchr(namebuf, '/');
4074 if (cp != NULL)
4075 *cp = '\0';
4076 zpool_hdl = zpool_open(hdl, namebuf);
4077 if (zpool_hdl == NULL) {
4078 ret = -1;
4079 goto error;
4080 }
4081
4082 /* restore namebuf to match fsname for later use */
4083 if (cp != NULL)
4084 *cp = '/';
4085
a3eeab2d 4086 /*
4087 * first iteration: process excluded (-x) properties now and gather
4088 * added (-o) properties to be later processed by zfs_valid_proplist()
4089 */
4090 nvp = NULL;
4091 while ((nvp = nvlist_next_nvpair(cmdprops, nvp)) != NULL) {
4092 const char *name = nvpair_name(nvp);
4093 zfs_prop_t prop = zfs_name_to_prop(name);
4094
4476ccd9
RE
4095 /*
4096 * It turns out, if we don't normalize "aliased" names
4097 * e.g. compress= against the "real" names (e.g. compression)
4098 * here, then setting/excluding them does not work as
4099 * intended.
4100 *
4101 * But since user-defined properties wouldn't have a valid
4102 * mapping here, we do this conditional dance.
4103 */
4104 const char *newname = name;
4105 if (prop >= ZFS_PROP_TYPE)
4106 newname = zfs_prop_to_name(prop);
4107
a3eeab2d 4108 /* "origin" is processed separately, don't handle it here */
4109 if (prop == ZFS_PROP_ORIGIN)
4110 continue;
4111
d9c460a0
TC
4112 /* raw streams can't override encryption properties */
4113 if ((zfs_prop_encryption_key_param(prop) ||
b4238327 4114 prop == ZFS_PROP_ENCRYPTION) && raw) {
d9c460a0
TC
4115 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
4116 "encryption property '%s' cannot "
b4238327
TC
4117 "be set or excluded for raw streams."), name);
4118 ret = zfs_error(hdl, EZFS_BADPROP, errbuf);
4119 goto error;
4120 }
4121
4122 /* incremental streams can only exclude encryption properties */
4123 if ((zfs_prop_encryption_key_param(prop) ||
4124 prop == ZFS_PROP_ENCRYPTION) && !newfs &&
4125 nvpair_type(nvp) != DATA_TYPE_BOOLEAN) {
4126 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
4127 "encryption property '%s' cannot "
4128 "be set for incremental streams."), name);
d9c460a0
TC
4129 ret = zfs_error(hdl, EZFS_BADPROP, errbuf);
4130 goto error;
4131 }
4132
a3eeab2d 4133 switch (nvpair_type(nvp)) {
4134 case DATA_TYPE_BOOLEAN: /* -x property */
4135 /*
4136 * DATA_TYPE_BOOLEAN is the way we're asked to "exclude"
4137 * a property: this is done by forcing an explicit
4138 * inherit on the destination so the effective value is
4139 * not the one we received from the send stream.
b0269cd8
I
4140 */
4141 if (!zfs_prop_valid_for_type(prop, type, B_FALSE) &&
4142 !zfs_prop_user(name)) {
4143 (void) fprintf(stderr, dgettext(TEXT_DOMAIN,
4144 "Warning: %s: property '%s' does not "
4145 "apply to datasets of this type\n"),
4146 fsname, name);
4147 continue;
4148 }
4149 /*
a3eeab2d 4150 * We do this only if the property is not already
4151 * locally-set, in which case its value will take
4152 * priority over the received anyway.
4153 */
4476ccd9 4154 if (nvlist_exists(origprops, newname)) {
a3eeab2d 4155 nvlist_t *attrs;
b4238327 4156 char *source = NULL;
a3eeab2d 4157
4476ccd9
RE
4158 attrs = fnvlist_lookup_nvlist(origprops,
4159 newname);
b4238327
TC
4160 if (nvlist_lookup_string(attrs,
4161 ZPROP_SOURCE, &source) == 0 &&
4162 strcmp(source, ZPROP_SOURCE_VAL_RECVD) != 0)
a3eeab2d 4163 continue;
4164 }
4165 /*
4166 * We can't force an explicit inherit on non-inheritable
4167 * properties: if we're asked to exclude this kind of
4168 * values we remove them from "recvprops" input nvlist.
4169 */
63652e15
DS
4170 if (!zfs_prop_user(name) && /* can be inherited too */
4171 !zfs_prop_inheritable(prop) &&
4476ccd9
RE
4172 nvlist_exists(recvprops, newname))
4173 fnvlist_remove(recvprops, newname);
a3eeab2d 4174 else
4476ccd9 4175 fnvlist_add_boolean(*oxprops, newname);
a3eeab2d 4176 break;
4177 case DATA_TYPE_STRING: /* -o property=value */
b0269cd8
I
4178 /*
4179 * we're trying to override a property that does not
4180 * make sense for this type of dataset, but we don't
4181 * want to fail if the receive is recursive: this comes
4182 * in handy when the send stream contains, for
4183 * instance, a child ZVOL and we're trying to receive
4184 * it with "-o atime=on"
4185 */
4186 if (!zfs_prop_valid_for_type(prop, type, B_FALSE) &&
4187 !zfs_prop_user(name)) {
4188 if (recursive)
4189 continue;
4190 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
4191 "property '%s' does not apply to datasets "
4192 "of this type"), name);
4193 ret = zfs_error(hdl, EZFS_BADPROP, errbuf);
4194 goto error;
4195 }
4476ccd9
RE
4196 fnvlist_add_string(oprops, newname,
4197 fnvpair_value_string(nvp));
a3eeab2d 4198 break;
4199 default:
4200 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
4201 "property '%s' must be a string or boolean"), name);
4202 ret = zfs_error(hdl, EZFS_BADPROP, errbuf);
4203 goto error;
4204 }
4205 }
4206
4207 if (toplevel) {
4208 /* convert override strings properties to native */
4209 if ((voprops = zfs_valid_proplist(hdl, ZFS_TYPE_DATASET,
b5256303 4210 oprops, zoned, zhp, zpool_hdl, B_FALSE, errbuf)) == NULL) {
a3eeab2d 4211 ret = zfs_error(hdl, EZFS_BADPROP, errbuf);
4212 goto error;
4213 }
4214
d9c460a0
TC
4215 /*
4216 * zfs_crypto_create() requires the parent name. Get it
4217 * by truncating the fsname copy stored in namebuf.
4218 */
4219 cp = strrchr(namebuf, '/');
4220 if (cp != NULL)
4221 *cp = '\0';
4222
4223 if (!raw && zfs_crypto_create(hdl, namebuf, voprops, NULL,
4224 B_FALSE, wkeydata_out, wkeylen_out) != 0) {
4225 fnvlist_free(voprops);
4226 ret = zfs_error(hdl, EZFS_CRYPTOFAILED, errbuf);
4227 goto error;
4228 }
4229
a3eeab2d 4230 /* second pass: process "-o" properties */
4231 fnvlist_merge(*oxprops, voprops);
4232 fnvlist_free(voprops);
4233 } else {
4234 /* override props on child dataset are inherited */
4235 nvp = NULL;
4236 while ((nvp = nvlist_next_nvpair(oprops, nvp)) != NULL) {
4237 const char *name = nvpair_name(nvp);
4238 fnvlist_add_boolean(*oxprops, name);
4239 }
4240 }
4241
4242error:
d9c460a0
TC
4243 if (zhp != NULL)
4244 zfs_close(zhp);
4245 if (zpool_hdl != NULL)
4246 zpool_close(zpool_hdl);
a3eeab2d 4247 fnvlist_free(oprops);
4248 return (ret);
4249}
4250
34dc7c2f
BB
4251/*
4252 * Restores a backup of tosnap from the file descriptor specified by infd.
4253 */
4254static int
4255zfs_receive_one(libzfs_handle_t *hdl, int infd, const char *tosnap,
fcff0f35
PD
4256 const char *originsnap, recvflags_t *flags, dmu_replay_record_t *drr,
4257 dmu_replay_record_t *drr_noswap, const char *sendfs, nvlist_t *stream_nv,
196bee4c
MA
4258 avl_tree_t *stream_avl, char **top_zfs,
4259 const char *finalsnap, nvlist_t *cmdprops)
34dc7c2f 4260{
67de71e6 4261 struct timespec begin_time;
428870ff 4262 int ioctl_err, ioctl_errno, err;
34dc7c2f
BB
4263 char *cp;
4264 struct drr_begin *drrb = &drr->drr_u.drr_begin;
d68a2bfa 4265 char errbuf[ERRBUFLEN];
428870ff 4266 const char *chopprefix;
34dc7c2f 4267 boolean_t newfs = B_FALSE;
a132c2b4 4268 boolean_t stream_wantsnewfs, stream_resumingnewfs;
43e52edd
BB
4269 boolean_t newprops = B_FALSE;
4270 uint64_t read_bytes = 0;
4271 uint64_t errflags = 0;
34dc7c2f
BB
4272 uint64_t parent_snapguid = 0;
4273 prop_changelist_t *clp = NULL;
b128c09f 4274 nvlist_t *snapprops_nvlist = NULL;
9c5e88b1 4275 nvlist_t *snapholds_nvlist = NULL;
428870ff 4276 zprop_errflags_t prop_errflags;
43e52edd 4277 nvlist_t *prop_errors = NULL;
428870ff 4278 boolean_t recursive;
671c9354 4279 char *snapname = NULL;
43e52edd 4280 char destsnap[MAXPATHLEN * 2];
861166b0 4281 char origin[MAXNAMELEN] = {0};
43e52edd 4282 char name[MAXPATHLEN];
861166b0 4283 char tmp_keylocation[MAXNAMELEN] = {0};
a3eeab2d 4284 nvlist_t *rcvprops = NULL; /* props received from the send stream */
4285 nvlist_t *oxprops = NULL; /* override (-o) and exclude (-x) props */
4286 nvlist_t *origprops = NULL; /* original props (if destination exists) */
806739f9 4287 zfs_type_t type = ZFS_TYPE_INVALID;
bee7e4ff 4288 boolean_t toplevel = B_FALSE;
a3eeab2d 4289 boolean_t zoned = B_FALSE;
c03f0470 4290 boolean_t hastoken = B_FALSE;
30af21b0 4291 boolean_t redacted;
d9c460a0
TC
4292 uint8_t *wkeydata = NULL;
4293 uint_t wkeylen = 0;
34dc7c2f 4294
67de71e6
AZ
4295#ifndef CLOCK_MONOTONIC_RAW
4296#define CLOCK_MONOTONIC_RAW CLOCK_MONOTONIC
4297#endif
4298 clock_gettime(CLOCK_MONOTONIC_RAW, &begin_time);
34dc7c2f
BB
4299
4300 (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
4301 "cannot receive"));
4302
428870ff
BB
4303 recursive = (nvlist_lookup_boolean(stream_nv, "not_recursive") ==
4304 ENOENT);
4305
9c5e88b1
PZ
4306 /* Did the user request holds be skipped via zfs recv -k? */
4307 boolean_t holds = flags->holds && !flags->skipholds;
4308
34dc7c2f 4309 if (stream_avl != NULL) {
b5256303 4310 char *keylocation = NULL;
48f783de 4311 nvlist_t *lookup = NULL;
b128c09f
BB
4312 nvlist_t *fs = fsavl_find(stream_avl, drrb->drr_toguid,
4313 &snapname);
34dc7c2f
BB
4314
4315 (void) nvlist_lookup_uint64(fs, "parentfromsnap",
4316 &parent_snapguid);
a3eeab2d 4317 err = nvlist_lookup_nvlist(fs, "props", &rcvprops);
43e52edd 4318 if (err) {
60a2434b 4319 rcvprops = fnvlist_alloc();
43e52edd
BB
4320 newprops = B_TRUE;
4321 }
34dc7c2f 4322
b5256303
TC
4323 /*
4324 * The keylocation property may only be set on encryption roots,
4325 * but this dataset might not become an encryption root until
83472fab 4326 * recv_fix_encryption_hierarchy() is called. That function
b5256303
TC
4327 * will fixup the keylocation anyway, so we temporarily unset
4328 * the keylocation for now to avoid any errors from the receive
4329 * ioctl.
4330 */
4331 err = nvlist_lookup_string(rcvprops,
4332 zfs_prop_to_name(ZFS_PROP_KEYLOCATION), &keylocation);
4333 if (err == 0) {
a51288aa 4334 strlcpy(tmp_keylocation, keylocation, MAXNAMELEN);
b5256303
TC
4335 (void) nvlist_remove_all(rcvprops,
4336 zfs_prop_to_name(ZFS_PROP_KEYLOCATION));
4337 }
4338
330d06f9 4339 if (flags->canmountoff) {
60a2434b
RM
4340 fnvlist_add_uint64(rcvprops,
4341 zfs_prop_to_name(ZFS_PROP_CANMOUNT), 0);
9c5e88b1 4342 } else if (newprops) { /* nothing in rcvprops, eliminate it */
60a2434b 4343 fnvlist_free(rcvprops);
9c5e88b1
PZ
4344 rcvprops = NULL;
4345 newprops = B_FALSE;
34dc7c2f 4346 }
48f783de 4347 if (0 == nvlist_lookup_nvlist(fs, "snapprops", &lookup)) {
60a2434b
RM
4348 snapprops_nvlist = fnvlist_lookup_nvlist(lookup,
4349 snapname);
48f783de 4350 }
9c5e88b1
PZ
4351 if (holds) {
4352 if (0 == nvlist_lookup_nvlist(fs, "snapholds",
4353 &lookup)) {
60a2434b
RM
4354 snapholds_nvlist = fnvlist_lookup_nvlist(
4355 lookup, snapname);
9c5e88b1
PZ
4356 }
4357 }
34dc7c2f
BB
4358 }
4359
428870ff
BB
4360 cp = NULL;
4361
34dc7c2f
BB
4362 /*
4363 * Determine how much of the snapshot name stored in the stream
4364 * we are going to tack on to the name they specified on the
4365 * command line, and how much we are going to chop off.
4366 *
4367 * If they specified a snapshot, chop the entire name stored in
4368 * the stream.
4369 */
330d06f9 4370 if (flags->istail) {
428870ff
BB
4371 /*
4372 * A filesystem was specified with -e. We want to tack on only
4373 * the tail of the sent snapshot path.
4374 */
4375 if (strchr(tosnap, '@')) {
4376 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "invalid "
4377 "argument - snapshot not allowed with -e"));
43e52edd
BB
4378 err = zfs_error(hdl, EZFS_INVALIDNAME, errbuf);
4379 goto out;
428870ff
BB
4380 }
4381
4382 chopprefix = strrchr(sendfs, '/');
4383
4384 if (chopprefix == NULL) {
4385 /*
4386 * The tail is the poolname, so we need to
4387 * prepend a path separator.
4388 */
4389 int len = strlen(drrb->drr_toname);
4390 cp = malloc(len + 2);
4391 cp[0] = '/';
4392 (void) strcpy(&cp[1], drrb->drr_toname);
4393 chopprefix = cp;
4394 } else {
4395 chopprefix = drrb->drr_toname + (chopprefix - sendfs);
4396 }
330d06f9 4397 } else if (flags->isprefix) {
34dc7c2f 4398 /*
428870ff
BB
4399 * A filesystem was specified with -d. We want to tack on
4400 * everything but the first element of the sent snapshot path
4401 * (all but the pool name).
34dc7c2f
BB
4402 */
4403 if (strchr(tosnap, '@')) {
4404 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "invalid "
4405 "argument - snapshot not allowed with -d"));
43e52edd
BB
4406 err = zfs_error(hdl, EZFS_INVALIDNAME, errbuf);
4407 goto out;
34dc7c2f 4408 }
428870ff
BB
4409
4410 chopprefix = strchr(drrb->drr_toname, '/');
4411 if (chopprefix == NULL)
4412 chopprefix = strchr(drrb->drr_toname, '@');
34dc7c2f
BB
4413 } else if (strchr(tosnap, '@') == NULL) {
4414 /*
428870ff
BB
4415 * If a filesystem was specified without -d or -e, we want to
4416 * tack on everything after the fs specified by 'zfs send'.
34dc7c2f 4417 */
428870ff
BB
4418 chopprefix = drrb->drr_toname + strlen(sendfs);
4419 } else {
4420 /* A snapshot was specified as an exact path (no -d or -e). */
4421 if (recursive) {
4422 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
4423 "cannot specify snapshot name for multi-snapshot "
4424 "stream"));
43e52edd
BB
4425 err = zfs_error(hdl, EZFS_BADSTREAM, errbuf);
4426 goto out;
428870ff
BB
4427 }
4428 chopprefix = drrb->drr_toname + strlen(drrb->drr_toname);
34dc7c2f 4429 }
428870ff
BB
4430
4431 ASSERT(strstr(drrb->drr_toname, sendfs) == drrb->drr_toname);
bdbd5477 4432 ASSERT(chopprefix > drrb->drr_toname || strchr(sendfs, '/') == NULL);
4433 ASSERT(chopprefix <= drrb->drr_toname + strlen(drrb->drr_toname) ||
4434 strchr(sendfs, '/') == NULL);
428870ff
BB
4435 ASSERT(chopprefix[0] == '/' || chopprefix[0] == '@' ||
4436 chopprefix[0] == '\0');
34dc7c2f
BB
4437
4438 /*
43e52edd 4439 * Determine name of destination snapshot.
34dc7c2f 4440 */
45cb520b 4441 (void) strlcpy(destsnap, tosnap, sizeof (destsnap));
43e52edd 4442 (void) strlcat(destsnap, chopprefix, sizeof (destsnap));
428870ff 4443 free(cp);
43e52edd
BB
4444 if (!zfs_name_valid(destsnap, ZFS_TYPE_SNAPSHOT)) {
4445 err = zfs_error(hdl, EZFS_INVALIDNAME, errbuf);
4446 goto out;
34dc7c2f
BB
4447 }
4448
4449 /*
43e52edd 4450 * Determine the name of the origin snapshot.
34dc7c2f 4451 */
160af771 4452 if (originsnap) {
21a4f5cc 4453 (void) strlcpy(origin, originsnap, sizeof (origin));
160af771
GM
4454 if (flags->verbose)
4455 (void) printf("using provided clone origin %s\n",
4456 origin);
4457 } else if (drrb->drr_flags & DRR_FLAG_CLONE) {
43e52edd
BB
4458 if (guid_to_name(hdl, destsnap,
4459 drrb->drr_fromguid, B_FALSE, origin) != 0) {
34dc7c2f
BB
4460 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
4461 "local origin for clone %s does not exist"),
43e52edd
BB
4462 destsnap);
4463 err = zfs_error(hdl, EZFS_NOENT, errbuf);
4464 goto out;
34dc7c2f 4465 }
330d06f9 4466 if (flags->verbose)
43e52edd 4467 (void) printf("found clone origin %s\n", origin);
34dc7c2f
BB
4468 }
4469
196bee4c 4470 if ((DMU_GET_FEATUREFLAGS(drrb->drr_versioninfo) &
652bdc9b
MA
4471 DMU_BACKUP_FEATURE_DEDUP)) {
4472 (void) fprintf(stderr,
196bee4c
MA
4473 gettext("ERROR: \"zfs receive\" no longer supports "
4474 "deduplicated send streams. Use\n"
4475 "the \"zstream redup\" command to convert this stream "
4476 "to a regular,\n"
4477 "non-deduplicated stream.\n"));
4478 err = zfs_error(hdl, EZFS_NOTSUP, errbuf);
4479 goto out;
652bdc9b
MA
4480 }
4481
47dfff3b
MA
4482 boolean_t resuming = DMU_GET_FEATUREFLAGS(drrb->drr_versioninfo) &
4483 DMU_BACKUP_FEATURE_RESUMING;
b5256303
TC
4484 boolean_t raw = DMU_GET_FEATUREFLAGS(drrb->drr_versioninfo) &
4485 DMU_BACKUP_FEATURE_RAW;
9b840763
TC
4486 boolean_t embedded = DMU_GET_FEATUREFLAGS(drrb->drr_versioninfo) &
4487 DMU_BACKUP_FEATURE_EMBED_DATA;
b8864a23 4488 stream_wantsnewfs = (drrb->drr_fromguid == 0 ||
47dfff3b 4489 (drrb->drr_flags & DRR_FLAG_CLONE) || originsnap) && !resuming;
a132c2b4
AS
4490 stream_resumingnewfs = (drrb->drr_fromguid == 0 ||
4491 (drrb->drr_flags & DRR_FLAG_CLONE) || originsnap) && resuming;
34dc7c2f
BB
4492
4493 if (stream_wantsnewfs) {
4494 /*
4495 * if the parent fs does not exist, look for it based on
4496 * the parent snap GUID
4497 */
4498 (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
4499 "cannot receive new filesystem stream"));
4500
a51288aa 4501 (void) strlcpy(name, destsnap, sizeof (name));
43e52edd 4502 cp = strrchr(name, '/');
34dc7c2f
BB
4503 if (cp)
4504 *cp = '\0';
4505 if (cp &&
43e52edd 4506 !zfs_dataset_exists(hdl, name, ZFS_TYPE_DATASET)) {
eca7b760 4507 char suffix[ZFS_MAX_DATASET_NAME_LEN];
a51288aa
RY
4508 (void) strlcpy(suffix, strrchr(destsnap, '/'),
4509 sizeof (suffix));
43e52edd
BB
4510 if (guid_to_name(hdl, name, parent_snapguid,
4511 B_FALSE, destsnap) == 0) {
4512 *strchr(destsnap, '@') = '\0';
a51288aa
RY
4513 (void) strlcat(destsnap, suffix,
4514 sizeof (destsnap) - strlen(destsnap));
34dc7c2f
BB
4515 }
4516 }
4517 } else {
4518 /*
ebeb6f23
AG
4519 * If the fs does not exist, look for it based on the
4520 * fromsnap GUID.
34dc7c2f 4521 */
ebeb6f23
AG
4522 if (resuming) {
4523 (void) snprintf(errbuf, sizeof (errbuf),
4524 dgettext(TEXT_DOMAIN,
4525 "cannot receive resume stream"));
4526 } else {
4527 (void) snprintf(errbuf, sizeof (errbuf),
4528 dgettext(TEXT_DOMAIN,
4529 "cannot receive incremental stream"));
4530 }
34dc7c2f 4531
a51288aa 4532 (void) strlcpy(name, destsnap, sizeof (name));
43e52edd 4533 *strchr(name, '@') = '\0';
34dc7c2f 4534
428870ff
BB
4535 /*
4536 * If the exact receive path was specified and this is the
4537 * topmost path in the stream, then if the fs does not exist we
4538 * should look no further.
4539 */
330d06f9 4540 if ((flags->isprefix || (*(chopprefix = drrb->drr_toname +
428870ff 4541 strlen(sendfs)) != '\0' && *chopprefix != '@')) &&
43e52edd 4542 !zfs_dataset_exists(hdl, name, ZFS_TYPE_DATASET)) {
eca7b760 4543 char snap[ZFS_MAX_DATASET_NAME_LEN];
a51288aa
RY
4544 (void) strlcpy(snap, strchr(destsnap, '@'),
4545 sizeof (snap));
43e52edd
BB
4546 if (guid_to_name(hdl, name, drrb->drr_fromguid,
4547 B_FALSE, destsnap) == 0) {
4548 *strchr(destsnap, '@') = '\0';
a51288aa
RY
4549 (void) strlcat(destsnap, snap,
4550 sizeof (destsnap) - strlen(destsnap));
34dc7c2f
BB
4551 }
4552 }
4553 }
4554
a51288aa 4555 (void) strlcpy(name, destsnap, sizeof (name));
43e52edd 4556 *strchr(name, '@') = '\0';
34dc7c2f 4557
30af21b0
PD
4558 redacted = DMU_GET_FEATUREFLAGS(drrb->drr_versioninfo) &
4559 DMU_BACKUP_FEATURE_REDACTED;
4560
e8cf3a4f
AP
4561 if (flags->heal) {
4562 if (flags->isprefix || flags->istail || flags->force ||
4563 flags->canmountoff || flags->resumable || flags->nomount ||
4564 flags->skipholds) {
4565 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
4566 "corrective recv can not be used when combined with"
4567 " this flag"));
4568 err = zfs_error(hdl, EZFS_INVALIDNAME, errbuf);
4569 goto out;
4570 }
4571 uint64_t guid =
4572 get_snap_guid(hdl, name, strchr(destsnap, '@') + 1);
4573 if (guid == 0) {
4574 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
4575 "corrective recv must specify an existing snapshot"
4576 " to heal"));
4577 err = zfs_error(hdl, EZFS_INVALIDNAME, errbuf);
4578 goto out;
4579 } else if (guid != drrb->drr_toguid) {
4580 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
4581 "local snapshot doesn't match the snapshot"
4582 " in the provided stream"));
4583 err = zfs_error(hdl, EZFS_WRONG_PARENT, errbuf);
4584 goto out;
4585 }
4586 } else if (zfs_dataset_exists(hdl, name, ZFS_TYPE_DATASET)) {
43e52edd 4587 zfs_cmd_t zc = {"\0"};
e8cf3a4f 4588 zfs_handle_t *zhp = NULL;
4a385862 4589 boolean_t encrypted;
428870ff 4590
43e52edd
BB
4591 (void) strcpy(zc.zc_name, name);
4592
34dc7c2f 4593 /*
47dfff3b
MA
4594 * Destination fs exists. It must be one of these cases:
4595 * - an incremental send stream
4596 * - the stream specifies a new fs (full stream or clone)
4597 * and they want us to blow away the existing fs (and
4598 * have therefore specified -F and removed any snapshots)
4599 * - we are resuming a failed receive.
34dc7c2f 4600 */
34dc7c2f 4601 if (stream_wantsnewfs) {
d8d418ff 4602 boolean_t is_volume = drrb->drr_type == DMU_OST_ZVOL;
330d06f9 4603 if (!flags->force) {
34dc7c2f
BB
4604 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
4605 "destination '%s' exists\n"
43e52edd
BB
4606 "must specify -F to overwrite it"), name);
4607 err = zfs_error(hdl, EZFS_EXISTS, errbuf);
4608 goto out;
34dc7c2f 4609 }
b834b58a 4610 if (zfs_ioctl(hdl, ZFS_IOC_SNAPSHOT_LIST_NEXT,
34dc7c2f 4611 &zc) == 0) {
34dc7c2f
BB
4612 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
4613 "destination has snapshots (eg. %s)\n"
4614 "must destroy them to overwrite it"),
b53cb02d 4615 zc.zc_name);
43e52edd
BB
4616 err = zfs_error(hdl, EZFS_EXISTS, errbuf);
4617 goto out;
34dc7c2f 4618 }
d8d418ff 4619 if (is_volume && strrchr(name, '/') == NULL) {
4620 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
4621 "destination %s is the root dataset\n"
4622 "cannot overwrite with a ZVOL"),
4623 name);
4624 err = zfs_error(hdl, EZFS_EXISTS, errbuf);
4625 goto out;
4626 }
4627 if (is_volume &&
b834b58a 4628 zfs_ioctl(hdl, ZFS_IOC_DATASET_LIST_NEXT,
d8d418ff 4629 &zc) == 0) {
4630 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
4631 "destination has children (eg. %s)\n"
4632 "cannot overwrite with a ZVOL"),
4633 zc.zc_name);
4634 err = zfs_error(hdl, EZFS_WRONG_PARENT, errbuf);
4635 goto out;
4636 }
34dc7c2f
BB
4637 }
4638
43e52edd 4639 if ((zhp = zfs_open(hdl, name,
34dc7c2f 4640 ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME)) == NULL) {
43e52edd
BB
4641 err = -1;
4642 goto out;
34dc7c2f
BB
4643 }
4644
3ed9d688
JP
4645 /*
4646 * When receiving full/newfs on existing dataset, then it
4647 * should be done with "-F" flag. Its enforced for initial
4648 * receive in previous checks in this function.
4649 * Similarly, on resuming full/newfs recv on existing dataset,
4650 * it should be done with "-F" flag.
4651 *
4652 * When dataset doesn't exist, then full/newfs recv is done on
4653 * newly created dataset and it's marked INCONSISTENT. But
4654 * When receiving on existing dataset, recv is first done on
4655 * %recv and its marked INCONSISTENT. Existing dataset is not
4656 * marked INCONSISTENT.
4657 * Resume of full/newfs receive with dataset not INCONSISTENT
4658 * indicates that its resuming newfs on existing dataset. So,
4659 * enforce "-F" flag in this case.
4660 */
4661 if (stream_resumingnewfs &&
4662 !zfs_prop_get_int(zhp, ZFS_PROP_INCONSISTENT) &&
4663 !flags->force) {
4664 zfs_close(zhp);
4665 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
4666 "Resuming recv on existing destination '%s'\n"
4667 "must specify -F to overwrite it"), name);
4668 err = zfs_error(hdl, EZFS_RESUME_EXISTS, errbuf);
4669 goto out;
4670 }
4671
34dc7c2f
BB
4672 if (stream_wantsnewfs &&
4673 zhp->zfs_dmustats.dds_origin[0]) {
34dc7c2f
BB
4674 zfs_close(zhp);
4675 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
4676 "destination '%s' is a clone\n"
43e52edd
BB
4677 "must destroy it to overwrite it"), name);
4678 err = zfs_error(hdl, EZFS_EXISTS, errbuf);
4679 goto out;
34dc7c2f
BB
4680 }
4681
b5256303 4682 /*
4a385862 4683 * Raw sends can not be performed as an incremental on top
78595377 4684 * of existing unencrypted datasets. zfs recv -F can't be
4a385862
TC
4685 * used to blow away an existing encrypted filesystem. This
4686 * is because it would require the dsl dir to point to the
4687 * new key (or lack of a key) and the old key at the same
4688 * time. The -F flag may still be used for deleting
4689 * intermediate snapshots that would otherwise prevent the
4690 * receive from working.
b5256303 4691 */
4a385862
TC
4692 encrypted = zfs_prop_get_int(zhp, ZFS_PROP_ENCRYPTION) !=
4693 ZIO_CRYPT_OFF;
4694 if (!stream_wantsnewfs && !encrypted && raw) {
b5256303
TC
4695 zfs_close(zhp);
4696 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
4a385862
TC
4697 "cannot perform raw receive on top of "
4698 "existing unencrypted dataset"));
b5256303
TC
4699 err = zfs_error(hdl, EZFS_BADRESTORE, errbuf);
4700 goto out;
4701 }
4702
4a385862
TC
4703 if (stream_wantsnewfs && flags->force &&
4704 ((raw && !encrypted) || encrypted)) {
4705 zfs_close(zhp);
4706 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
4707 "zfs receive -F cannot be used to destroy an "
4708 "encrypted filesystem or overwrite an "
4709 "unencrypted one with an encrypted one"));
4710 err = zfs_error(hdl, EZFS_BADRESTORE, errbuf);
4711 goto out;
4712 }
b5256303 4713
330d06f9 4714 if (!flags->dryrun && zhp->zfs_type == ZFS_TYPE_FILESYSTEM &&
a132c2b4 4715 (stream_wantsnewfs || stream_resumingnewfs)) {
34dc7c2f 4716 /* We can't do online recv in this case */
a57d3d45
MZ
4717 clp = changelist_gather(zhp, ZFS_PROP_NAME, 0,
4718 flags->forceunmount ? MS_FORCE : 0);
34dc7c2f 4719 if (clp == NULL) {
45d1cae3 4720 zfs_close(zhp);
43e52edd
BB
4721 err = -1;
4722 goto out;
34dc7c2f
BB
4723 }
4724 if (changelist_prefix(clp) != 0) {
4725 changelist_free(clp);
45d1cae3 4726 zfs_close(zhp);
43e52edd
BB
4727 err = -1;
4728 goto out;
34dc7c2f
BB
4729 }
4730 }
47dfff3b
MA
4731
4732 /*
4733 * If we are resuming a newfs, set newfs here so that we will
4734 * mount it if the recv succeeds this time. We can tell
4735 * that it was a newfs on the first recv because the fs
4736 * itself will be inconsistent (if the fs existed when we
4737 * did the first recv, we would have received it into
4738 * .../%recv).
4739 */
4740 if (resuming && zfs_prop_get_int(zhp, ZFS_PROP_INCONSISTENT))
4741 newfs = B_TRUE;
4742
a3eeab2d 4743 /* we want to know if we're zoned when validating -o|-x props */
4744 zoned = zfs_prop_get_int(zhp, ZFS_PROP_ZONED);
4745
c03f0470 4746 /* may need this info later, get it now we have zhp around */
4747 if (zfs_prop_get(zhp, ZFS_PROP_RECEIVE_RESUME_TOKEN, NULL, 0,
4748 NULL, NULL, 0, B_TRUE) == 0)
4749 hastoken = B_TRUE;
4750
a3eeab2d 4751 /* gather existing properties on destination */
4752 origprops = fnvlist_alloc();
4753 fnvlist_merge(origprops, zhp->zfs_props);
4754 fnvlist_merge(origprops, zhp->zfs_user_props);
4755
34dc7c2f
BB
4756 zfs_close(zhp);
4757 } else {
b5256303
TC
4758 zfs_handle_t *zhp;
4759
34dc7c2f
BB
4760 /*
4761 * Destination filesystem does not exist. Therefore we better
4762 * be creating a new filesystem (either from a full backup, or
4763 * a clone). It would therefore be invalid if the user
4764 * specified only the pool name (i.e. if the destination name
4765 * contained no slash character).
4766 */
a64f903b
GN
4767 cp = strrchr(name, '/');
4768
4769 if (!stream_wantsnewfs || cp == NULL) {
34dc7c2f 4770 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
43e52edd
BB
4771 "destination '%s' does not exist"), name);
4772 err = zfs_error(hdl, EZFS_NOENT, errbuf);
4773 goto out;
34dc7c2f
BB
4774 }
4775
4776 /*
4777 * Trim off the final dataset component so we perform the
4778 * recvbackup ioctl to the filesystems's parent.
4779 */
4780 *cp = '\0';
4781
330d06f9 4782 if (flags->isprefix && !flags->istail && !flags->dryrun &&
43e52edd
BB
4783 create_parents(hdl, destsnap, strlen(tosnap)) != 0) {
4784 err = zfs_error(hdl, EZFS_BADRESTORE, errbuf);
4785 goto out;
34dc7c2f
BB
4786 }
4787
d8d418ff 4788 /* validate parent */
4789 zhp = zfs_open(hdl, name, ZFS_TYPE_DATASET);
4790 if (zhp == NULL) {
4791 err = zfs_error(hdl, EZFS_BADRESTORE, errbuf);
4792 goto out;
4793 }
4794 if (zfs_get_type(zhp) != ZFS_TYPE_FILESYSTEM) {
4795 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
4796 "parent '%s' is not a filesystem"), name);
4797 err = zfs_error(hdl, EZFS_WRONG_PARENT, errbuf);
4798 zfs_close(zhp);
4799 goto out;
4800 }
4801
d8d418ff 4802 zfs_close(zhp);
b5256303 4803
34dc7c2f 4804 newfs = B_TRUE;
b5256303 4805 *cp = '/';
34dc7c2f
BB
4806 }
4807
330d06f9 4808 if (flags->verbose) {
e8cf3a4f 4809 (void) printf("%s %s%s stream of %s into %s\n",
330d06f9 4810 flags->dryrun ? "would receive" : "receiving",
e8cf3a4f 4811 flags->heal ? " corrective" : "",
34dc7c2f 4812 drrb->drr_fromguid ? "incremental" : "full",
43e52edd 4813 drrb->drr_toname, destsnap);
34dc7c2f
BB
4814 (void) fflush(stdout);
4815 }
4816
bb61cc31
TC
4817 /*
4818 * If this is the top-level dataset, record it so we can use it
4819 * for recursive operations later.
4820 */
4821 if (top_zfs != NULL &&
4822 (*top_zfs == NULL || strcmp(*top_zfs, name) == 0)) {
bee7e4ff 4823 toplevel = B_TRUE;
bb61cc31
TC
4824 if (*top_zfs == NULL)
4825 *top_zfs = zfs_strdup(hdl, name);
4826 }
4827
a3eeab2d 4828 if (drrb->drr_type == DMU_OST_ZVOL) {
4829 type = ZFS_TYPE_VOLUME;
4830 } else if (drrb->drr_type == DMU_OST_ZFS) {
4831 type = ZFS_TYPE_FILESYSTEM;
4832 } else {
4833 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
4834 "invalid record type: 0x%d"), drrb->drr_type);
4835 err = zfs_error(hdl, EZFS_BADSTREAM, errbuf);
4836 goto out;
4837 }
d9c460a0
TC
4838 if ((err = zfs_setup_cmdline_props(hdl, type, name, zoned, recursive,
4839 stream_wantsnewfs, raw, toplevel, rcvprops, cmdprops, origprops,
4840 &oxprops, &wkeydata, &wkeylen, errbuf)) != 0)
a3eeab2d 4841 goto out;
4842
da689887
TC
4843 /*
4844 * When sending with properties (zfs send -p), the encryption property
4845 * is not included because it is a SETONCE property and therefore
4846 * treated as read only. However, we are always able to determine its
4847 * value because raw sends will include it in the DRR_BDEGIN payload
4848 * and non-raw sends with properties are not allowed for encrypted
4849 * datasets. Therefore, if this is a non-raw properties stream, we can
4850 * infer that the value should be ZIO_CRYPT_OFF and manually add that
4851 * to the received properties.
4852 */
4853 if (stream_wantsnewfs && !raw && rcvprops != NULL &&
4854 !nvlist_exists(cmdprops, zfs_prop_to_name(ZFS_PROP_ENCRYPTION))) {
4855 if (oxprops == NULL)
4856 oxprops = fnvlist_alloc();
4857 fnvlist_add_uint64(oxprops,
4858 zfs_prop_to_name(ZFS_PROP_ENCRYPTION), ZIO_CRYPT_OFF);
4859 }
4860
ee6615e0
I
4861 if (flags->dryrun) {
4862 void *buf = zfs_alloc(hdl, SPA_MAXBLOCKSIZE);
4863
4864 /*
4865 * We have read the DRR_BEGIN record, but we have
4866 * not yet read the payload. For non-dryrun sends
4867 * this will be done by the kernel, so we must
4868 * emulate that here, before attempting to read
4869 * more records.
4870 */
4871 err = recv_read(hdl, infd, buf, drr->drr_payloadlen,
4872 flags->byteswap, NULL);
4873 free(buf);
4874 if (err != 0)
4875 goto out;
4876
4877 err = recv_skip(hdl, infd, flags->byteswap);
4878 goto out;
4879 }
4880
e8cf3a4f
AP
4881 if (flags->heal) {
4882 err = ioctl_err = lzc_receive_with_heal(destsnap, rcvprops,
4883 oxprops, wkeydata, wkeylen, origin, flags->force,
4884 flags->heal, flags->resumable, raw, infd, drr_noswap, -1,
4885 &read_bytes, &errflags, NULL, &prop_errors);
4886 } else {
4887 err = ioctl_err = lzc_receive_with_cmdprops(destsnap, rcvprops,
4888 oxprops, wkeydata, wkeylen, origin, flags->force,
4889 flags->resumable, raw, infd, drr_noswap, -1, &read_bytes,
4890 &errflags, NULL, &prop_errors);
4891 }
43e52edd
BB
4892 ioctl_errno = ioctl_err;
4893 prop_errflags = errflags;
428870ff
BB
4894
4895 if (err == 0) {
428870ff
BB
4896 nvpair_t *prop_err = NULL;
4897
4898 while ((prop_err = nvlist_next_nvpair(prop_errors,
4899 prop_err)) != NULL) {
4900 char tbuf[1024];
4901 zfs_prop_t prop;
4902 int intval;
4903
4904 prop = zfs_name_to_prop(nvpair_name(prop_err));
4905 (void) nvpair_value_int32(prop_err, &intval);
4906 if (strcmp(nvpair_name(prop_err),
4907 ZPROP_N_MORE_ERRORS) == 0) {
4908 trunc_prop_errs(intval);
4909 break;
671c9354
DM
4910 } else if (snapname == NULL || finalsnap == NULL ||
4911 strcmp(finalsnap, snapname) == 0 ||
4912 strcmp(nvpair_name(prop_err),
4913 zfs_prop_to_name(ZFS_PROP_REFQUOTA)) != 0) {
4914 /*
4915 * Skip the special case of, for example,
4916 * "refquota", errors on intermediate
4917 * snapshots leading up to a final one.
4918 * That's why we have all of the checks above.
4919 *
4920 * See zfs_ioctl.c's extract_delay_props() for
4921 * a list of props which can fail on
4922 * intermediate snapshots, but shouldn't
4923 * affect the overall receive.
4924 */
428870ff
BB
4925 (void) snprintf(tbuf, sizeof (tbuf),
4926 dgettext(TEXT_DOMAIN,
4927 "cannot receive %s property on %s"),
43e52edd 4928 nvpair_name(prop_err), name);
428870ff
BB
4929 zfs_setprop_error(hdl, prop, intval, tbuf);
4930 }
4931 }
428870ff
BB
4932 }
4933
b128c09f 4934 if (err == 0 && snapprops_nvlist) {
43e52edd 4935 zfs_cmd_t zc = {"\0"};
b128c09f 4936
a51288aa 4937 (void) strlcpy(zc.zc_name, destsnap, sizeof (zc.zc_name));
43e52edd 4938 zc.zc_cookie = B_TRUE; /* received */
18dbf5c8
AZ
4939 zcmd_write_src_nvlist(hdl, &zc, snapprops_nvlist);
4940 (void) zfs_ioctl(hdl, ZFS_IOC_SET_PROP, &zc);
4941 zcmd_free_nvlists(&zc);
b128c09f 4942 }
9c5e88b1
PZ
4943 if (err == 0 && snapholds_nvlist) {
4944 nvpair_t *pair;
4945 nvlist_t *holds, *errors = NULL;
4946 int cleanup_fd = -1;
4947
4948 VERIFY(0 == nvlist_alloc(&holds, 0, KM_SLEEP));
4949 for (pair = nvlist_next_nvpair(snapholds_nvlist, NULL);
4950 pair != NULL;
4951 pair = nvlist_next_nvpair(snapholds_nvlist, pair)) {
60a2434b 4952 fnvlist_add_string(holds, destsnap, nvpair_name(pair));
9c5e88b1
PZ
4953 }
4954 (void) lzc_hold(holds, cleanup_fd, &errors);
60a2434b
RM
4955 fnvlist_free(snapholds_nvlist);
4956 fnvlist_free(holds);
9c5e88b1 4957 }
b128c09f 4958
428870ff 4959 if (err && (ioctl_errno == ENOENT || ioctl_errno == EEXIST)) {
34dc7c2f
BB
4960 /*
4961 * It may be that this snapshot already exists,
4962 * in which case we want to consume & ignore it
4963 * rather than failing.
4964 */
4965 avl_tree_t *local_avl;
4966 nvlist_t *local_nv, *fs;
43e52edd 4967 cp = strchr(destsnap, '@');
34dc7c2f
BB
4968
4969 /*
4970 * XXX Do this faster by just iterating over snaps in
4971 * this fs. Also if zc_value does not exist, we will
4972 * get a strange "does not exist" error message.
4973 */
4974 *cp = '\0';
b5256303 4975 if (gather_nvlist(hdl, destsnap, NULL, NULL, B_FALSE, B_TRUE,
099fa7e4
PCG
4976 B_FALSE, B_FALSE, B_FALSE, B_FALSE, B_FALSE, B_FALSE,
4977 B_TRUE, &local_nv, &local_avl) == 0) {
34dc7c2f
BB
4978 *cp = '@';
4979 fs = fsavl_find(local_avl, drrb->drr_toguid, NULL);
4980 fsavl_destroy(local_avl);
60a2434b 4981 fnvlist_free(local_nv);
34dc7c2f
BB
4982
4983 if (fs != NULL) {
330d06f9 4984 if (flags->verbose) {
34dc7c2f 4985 (void) printf("snap %s already exists; "
43e52edd 4986 "ignoring\n", destsnap);
34dc7c2f 4987 }
428870ff 4988 err = ioctl_err = recv_skip(hdl, infd,
330d06f9 4989 flags->byteswap);
34dc7c2f
BB
4990 }
4991 }
4992 *cp = '@';
4993 }
4994
34dc7c2f
BB
4995 if (ioctl_err != 0) {
4996 switch (ioctl_errno) {
4997 case ENODEV:
43e52edd 4998 cp = strchr(destsnap, '@');
34dc7c2f
BB
4999 *cp = '\0';
5000 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
5001 "most recent snapshot of %s does not\n"
43e52edd 5002 "match incremental source"), destsnap);
34dc7c2f
BB
5003 (void) zfs_error(hdl, EZFS_BADRESTORE, errbuf);
5004 *cp = '@';
5005 break;
5006 case ETXTBSY:
5007 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
5008 "destination %s has been modified\n"
43e52edd 5009 "since most recent snapshot"), name);
34dc7c2f
BB
5010 (void) zfs_error(hdl, EZFS_BADRESTORE, errbuf);
5011 break;
b5256303 5012 case EACCES:
e8cf3a4f
AP
5013 if (flags->heal) {
5014 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
5015 "key must be loaded to do a non-raw "
5016 "corrective recv on an encrypted "
5017 "dataset."));
5018 } else if (raw && stream_wantsnewfs) {
b5256303
TC
5019 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
5020 "failed to create encryption key"));
5021 } else if (raw && !stream_wantsnewfs) {
5022 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
5023 "encryption key does not match "
5024 "existing key"));
5025 } else {
5026 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
5027 "inherited key must be loaded"));
5028 }
5029 (void) zfs_error(hdl, EZFS_CRYPTOFAILED, errbuf);
5030 break;
34dc7c2f 5031 case EEXIST:
43e52edd 5032 cp = strchr(destsnap, '@');
34dc7c2f
BB
5033 if (newfs) {
5034 /* it's the containing fs that exists */
5035 *cp = '\0';
5036 }
5037 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
5038 "destination already exists"));
5039 (void) zfs_error_fmt(hdl, EZFS_EXISTS,
5040 dgettext(TEXT_DOMAIN, "cannot restore to %s"),
43e52edd 5041 destsnap);
34dc7c2f
BB
5042 *cp = '@';
5043 break;
5044 case EINVAL:
2ba59fa9 5045 if (flags->resumable) {
43e52edd
BB
5046 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
5047 "kernel modules must be upgraded to "
5048 "receive this stream."));
2ba59fa9 5049 } else if (embedded && !raw) {
9b840763
TC
5050 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
5051 "incompatible embedded data stream "
5052 "feature with encrypted receive."));
2ba59fa9 5053 }
34dc7c2f
BB
5054 (void) zfs_error(hdl, EZFS_BADSTREAM, errbuf);
5055 break;
5056 case ECKSUM:
7145123b 5057 case ZFS_ERR_STREAM_TRUNCATED:
e8cf3a4f
AP
5058 if (flags->heal)
5059 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
5060 "corrective receive was not able to "
5061 "reconstruct the data needed for "
5062 "healing."));
5063 else
5064 recv_ecksum_set_aux(hdl, destsnap,
5065 flags->resumable, ioctl_err == ECKSUM);
34dc7c2f
BB
5066 (void) zfs_error(hdl, EZFS_BADSTREAM, errbuf);
5067 break;
7bcb7f08
MA
5068 case ZFS_ERR_STREAM_LARGE_BLOCK_MISMATCH:
5069 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
5070 "incremental send stream requires -L "
5071 "(--large-block), to match previous receive."));
5072 (void) zfs_error(hdl, EZFS_BADSTREAM, errbuf);
5073 break;
428870ff 5074 case ENOTSUP:
e8cf3a4f
AP
5075 if (flags->heal)
5076 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
5077 "stream is not compatible with the "
5078 "data in the pool."));
5079 else
5080 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
5081 "pool must be upgraded to receive this "
5082 "stream."));
428870ff
BB
5083 (void) zfs_error(hdl, EZFS_BADVERSION, errbuf);
5084 break;
5085 case EDQUOT:
5086 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
c03f0470 5087 "destination %s space quota exceeded."), name);
330d06f9 5088 (void) zfs_error(hdl, EZFS_NOSPC, errbuf);
428870ff 5089 break;
f00ab3f2
TC
5090 case ZFS_ERR_FROM_IVSET_GUID_MISSING:
5091 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
73c25a78 5092 "IV set guid missing. See errata %u at "
a2f944a1
RM
5093 "https://openzfs.github.io/openzfs-docs/msg/"
5094 "ZFS-8000-ER."),
f00ab3f2
TC
5095 ZPOOL_ERRATA_ZOL_8308_ENCRYPTION);
5096 (void) zfs_error(hdl, EZFS_BADSTREAM, errbuf);
5097 break;
5098 case ZFS_ERR_FROM_IVSET_GUID_MISMATCH:
5099 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
5100 "IV set guid mismatch. See the 'zfs receive' "
5101 "man page section\n discussing the limitations "
5102 "of raw encrypted send streams."));
5103 (void) zfs_error(hdl, EZFS_BADSTREAM, errbuf);
5104 break;
caf9dd20
BB
5105 case ZFS_ERR_SPILL_BLOCK_FLAG_MISSING:
5106 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
5107 "Spill block flag missing for raw send.\n"
5108 "The zfs software on the sending system must "
5109 "be updated."));
5110 (void) zfs_error(hdl, EZFS_BADSTREAM, errbuf);
5111 break;
3ed9d688
JP
5112 case ZFS_ERR_RESUME_EXISTS:
5113 cp = strchr(destsnap, '@');
5114 if (newfs) {
5115 /* it's the containing fs that exists */
5116 *cp = '\0';
5117 }
5118 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
5119 "Resuming recv on existing dataset without force"));
5120 (void) zfs_error_fmt(hdl, EZFS_RESUME_EXISTS,
5121 dgettext(TEXT_DOMAIN, "cannot resume recv %s"),
5122 destsnap);
5123 *cp = '@';
5124 break;
c03f0470 5125 case EBUSY:
5126 if (hastoken) {
5127 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
5128 "destination %s contains "
5129 "partially-complete state from "
5130 "\"zfs receive -s\"."), name);
5131 (void) zfs_error(hdl, EZFS_BUSY, errbuf);
5132 break;
5133 }
9a70e97f 5134 zfs_fallthrough;
34dc7c2f
BB
5135 default:
5136 (void) zfs_standard_error(hdl, ioctl_errno, errbuf);
5137 }
5138 }
5139
5140 /*
428870ff
BB
5141 * Mount the target filesystem (if created). Also mount any
5142 * children of the target filesystem if we did a replication
5143 * receive (indicated by stream_avl being non-NULL).
34dc7c2f 5144 */
34dc7c2f 5145 if (clp) {
89d43feb
GM
5146 if (!flags->nomount)
5147 err |= changelist_postfix(clp);
34dc7c2f
BB
5148 changelist_free(clp);
5149 }
5150
bb61cc31
TC
5151 if ((newfs || stream_avl) && type == ZFS_TYPE_FILESYSTEM && !redacted)
5152 flags->domount = B_TRUE;
5153
428870ff
BB
5154 if (prop_errflags & ZPROP_ERR_NOCLEAR) {
5155 (void) fprintf(stderr, dgettext(TEXT_DOMAIN, "Warning: "
43e52edd 5156 "failed to clear unreceived properties on %s"), name);
428870ff
BB
5157 (void) fprintf(stderr, "\n");
5158 }
5159 if (prop_errflags & ZPROP_ERR_NORESTORE) {
5160 (void) fprintf(stderr, dgettext(TEXT_DOMAIN, "Warning: "
43e52edd 5161 "failed to restore original properties on %s"), name);
428870ff
BB
5162 (void) fprintf(stderr, "\n");
5163 }
5164
43e52edd
BB
5165 if (err || ioctl_err) {
5166 err = -1;
5167 goto out;
5168 }
572e2857 5169
330d06f9 5170 if (flags->verbose) {
34dc7c2f
BB
5171 char buf1[64];
5172 char buf2[64];
43e52edd 5173 uint64_t bytes = read_bytes;
67de71e6
AZ
5174 struct timespec delta;
5175 clock_gettime(CLOCK_MONOTONIC_RAW, &delta);
5176 if (begin_time.tv_nsec > delta.tv_nsec) {
5177 delta.tv_nsec =
5178 1000000000 + delta.tv_nsec - begin_time.tv_nsec;
5179 delta.tv_sec -= 1;
5180 } else
5181 delta.tv_nsec -= begin_time.tv_nsec;
5182 delta.tv_sec -= begin_time.tv_sec;
5183 if (delta.tv_sec == 0 && delta.tv_nsec == 0)
5184 delta.tv_nsec = 1;
5185 double delta_f = delta.tv_sec + (delta.tv_nsec / 1e9);
e7fbeb60 5186 zfs_nicebytes(bytes, buf1, sizeof (buf1));
67de71e6 5187 zfs_nicebytes(bytes / delta_f, buf2, sizeof (buf2));
34dc7c2f 5188
67de71e6
AZ
5189 (void) printf("received %s stream in %.2f seconds (%s/sec)\n",
5190 buf1, delta_f, buf2);
34dc7c2f
BB
5191 }
5192
43e52edd
BB
5193 err = 0;
5194out:
5195 if (prop_errors != NULL)
60a2434b 5196 fnvlist_free(prop_errors);
43e52edd 5197
b5256303 5198 if (tmp_keylocation[0] != '\0') {
60a2434b
RM
5199 fnvlist_add_string(rcvprops,
5200 zfs_prop_to_name(ZFS_PROP_KEYLOCATION), tmp_keylocation);
b5256303
TC
5201 }
5202
43e52edd 5203 if (newprops)
60a2434b 5204 fnvlist_free(rcvprops);
a3eeab2d 5205
60a2434b
RM
5206 fnvlist_free(oxprops);
5207 fnvlist_free(origprops);
43e52edd
BB
5208
5209 return (err);
34dc7c2f
BB
5210}
5211
a3eeab2d 5212/*
5213 * Check properties we were asked to override (both -o|-x)
5214 */
5215static boolean_t
5216zfs_receive_checkprops(libzfs_handle_t *hdl, nvlist_t *props,
5217 const char *errbuf)
5218{
ae07fc13 5219 nvpair_t *nvp = NULL;
a3eeab2d 5220 zfs_prop_t prop;
5221 const char *name;
5222
a3eeab2d 5223 while ((nvp = nvlist_next_nvpair(props, nvp)) != NULL) {
5224 name = nvpair_name(nvp);
5225 prop = zfs_name_to_prop(name);
5226
4ff7a8fa 5227 if (prop == ZPROP_USERPROP) {
a3eeab2d 5228 if (!zfs_prop_user(name)) {
5229 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
7633c0ae 5230 "%s: invalid property '%s'"), errbuf, name);
a3eeab2d 5231 return (B_FALSE);
5232 }
5233 continue;
5234 }
5235 /*
5236 * "origin" is readonly but is used to receive datasets as
5237 * clones so we don't raise an error here
5238 */
5239 if (prop == ZFS_PROP_ORIGIN)
5240 continue;
5241
d9c460a0
TC
5242 /* encryption params have their own verification later */
5243 if (prop == ZFS_PROP_ENCRYPTION ||
5244 zfs_prop_encryption_key_param(prop))
5245 continue;
5246
a3eeab2d 5247 /*
5248 * cannot override readonly, set-once and other specific
5249 * settable properties
5250 */
5251 if (zfs_prop_readonly(prop) || prop == ZFS_PROP_VERSION ||
5252 prop == ZFS_PROP_VOLSIZE) {
5253 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
7633c0ae 5254 "%s: invalid property '%s'"), errbuf, name);
a3eeab2d 5255 return (B_FALSE);
5256 }
5257 }
5258
5259 return (B_TRUE);
5260}
5261
b128c09f 5262static int
fcff0f35
PD
5263zfs_receive_impl(libzfs_handle_t *hdl, const char *tosnap,
5264 const char *originsnap, recvflags_t *flags, int infd, const char *sendfs,
196bee4c
MA
5265 nvlist_t *stream_nv, avl_tree_t *stream_avl, char **top_zfs,
5266 const char *finalsnap, nvlist_t *cmdprops)
34dc7c2f
BB
5267{
5268 int err;
5269 dmu_replay_record_t drr, drr_noswap;
5270 struct drr_begin *drrb = &drr.drr_u.drr_begin;
d68a2bfa 5271 char errbuf[ERRBUFLEN];
2598c001 5272 zio_cksum_t zcksum = { { 0 } };
428870ff
BB
5273 uint64_t featureflags;
5274 int hdrtype;
34dc7c2f
BB
5275
5276 (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
5277 "cannot receive"));
5278
a3eeab2d 5279 /* check cmdline props, raise an error if they cannot be received */
7633c0ae 5280 if (!zfs_receive_checkprops(hdl, cmdprops, errbuf))
ae07fc13 5281 return (zfs_error(hdl, EZFS_BADPROP, errbuf));
a3eeab2d 5282
330d06f9 5283 if (flags->isprefix &&
34dc7c2f
BB
5284 !zfs_dataset_exists(hdl, tosnap, ZFS_TYPE_DATASET)) {
5285 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "specified fs "
5286 "(%s) does not exist"), tosnap);
5287 return (zfs_error(hdl, EZFS_NOENT, errbuf));
5288 }
fcff0f35
PD
5289 if (originsnap &&
5290 !zfs_dataset_exists(hdl, originsnap, ZFS_TYPE_DATASET)) {
5291 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "specified origin fs "
5292 "(%s) does not exist"), originsnap);
5293 return (zfs_error(hdl, EZFS_NOENT, errbuf));
5294 }
34dc7c2f
BB
5295
5296 /* read in the BEGIN record */
5297 if (0 != (err = recv_read(hdl, infd, &drr, sizeof (drr), B_FALSE,
5298 &zcksum)))
5299 return (err);
5300
5301 if (drr.drr_type == DRR_END || drr.drr_type == BSWAP_32(DRR_END)) {
5302 /* It's the double end record at the end of a package */
5303 return (ENODATA);
5304 }
5305
5306 /* the kernel needs the non-byteswapped begin record */
5307 drr_noswap = drr;
5308
330d06f9 5309 flags->byteswap = B_FALSE;
34dc7c2f
BB
5310 if (drrb->drr_magic == BSWAP_64(DMU_BACKUP_MAGIC)) {
5311 /*
5312 * We computed the checksum in the wrong byteorder in
5313 * recv_read() above; do it again correctly.
5314 */
861166b0 5315 memset(&zcksum, 0, sizeof (zio_cksum_t));
34dc7c2f 5316 fletcher_4_incremental_byteswap(&drr, sizeof (drr), &zcksum);
330d06f9 5317 flags->byteswap = B_TRUE;
34dc7c2f
BB
5318
5319 drr.drr_type = BSWAP_32(drr.drr_type);
5320 drr.drr_payloadlen = BSWAP_32(drr.drr_payloadlen);
5321 drrb->drr_magic = BSWAP_64(drrb->drr_magic);
428870ff 5322 drrb->drr_versioninfo = BSWAP_64(drrb->drr_versioninfo);
34dc7c2f
BB
5323 drrb->drr_creation_time = BSWAP_64(drrb->drr_creation_time);
5324 drrb->drr_type = BSWAP_32(drrb->drr_type);
5325 drrb->drr_flags = BSWAP_32(drrb->drr_flags);
5326 drrb->drr_toguid = BSWAP_64(drrb->drr_toguid);
5327 drrb->drr_fromguid = BSWAP_64(drrb->drr_fromguid);
5328 }
5329
5330 if (drrb->drr_magic != DMU_BACKUP_MAGIC || drr.drr_type != DRR_BEGIN) {
5331 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "invalid "
5332 "stream (bad magic number)"));
5333 return (zfs_error(hdl, EZFS_BADSTREAM, errbuf));
5334 }
5335
428870ff
BB
5336 featureflags = DMU_GET_FEATUREFLAGS(drrb->drr_versioninfo);
5337 hdrtype = DMU_GET_STREAM_HDRTYPE(drrb->drr_versioninfo);
5338
5339 if (!DMU_STREAM_SUPPORTED(featureflags) ||
5340 (hdrtype != DMU_SUBSTREAM && hdrtype != DMU_COMPOUNDSTREAM)) {
a2ffc0e0
RE
5341 /*
5342 * Let's be explicit about this one, since rather than
5343 * being a new feature we can't know, it's an old
5344 * feature we dropped.
5345 */
5346 if (featureflags & DMU_BACKUP_FEATURE_DEDUP) {
5347 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
5348 "stream has deprecated feature: dedup, try "
5349 "'zstream redup [send in a file] | zfs recv "
5350 "[...]'"));
5351 } else {
5352 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
5353 "stream has unsupported feature, feature flags = "
5354 "%llx (unknown flags = %llx)"),
5355 (u_longlong_t)featureflags,
5356 (u_longlong_t)((featureflags) &
5357 ~DMU_BACKUP_FEATURE_MASK));
5358 }
428870ff
BB
5359 return (zfs_error(hdl, EZFS_BADSTREAM, errbuf));
5360 }
5361
9c5e88b1 5362 /* Holds feature is set once in the compound stream header. */
c618f87c 5363 if (featureflags & DMU_BACKUP_FEATURE_HOLDS)
9c5e88b1
PZ
5364 flags->holds = B_TRUE;
5365
34dc7c2f
BB
5366 if (strchr(drrb->drr_toname, '@') == NULL) {
5367 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "invalid "
5368 "stream (bad snapshot name)"));
5369 return (zfs_error(hdl, EZFS_BADSTREAM, errbuf));
5370 }
5371
428870ff 5372 if (DMU_GET_STREAM_HDRTYPE(drrb->drr_versioninfo) == DMU_SUBSTREAM) {
eca7b760 5373 char nonpackage_sendfs[ZFS_MAX_DATASET_NAME_LEN];
428870ff
BB
5374 if (sendfs == NULL) {
5375 /*
5376 * We were not called from zfs_receive_package(). Get
5377 * the fs specified by 'zfs send'.
5378 */
5379 char *cp;
5380 (void) strlcpy(nonpackage_sendfs,
eca7b760
IK
5381 drr.drr_u.drr_begin.drr_toname,
5382 sizeof (nonpackage_sendfs));
428870ff
BB
5383 if ((cp = strchr(nonpackage_sendfs, '@')) != NULL)
5384 *cp = '\0';
5385 sendfs = nonpackage_sendfs;
671c9354 5386 VERIFY(finalsnap == NULL);
428870ff 5387 }
fcff0f35
PD
5388 return (zfs_receive_one(hdl, infd, tosnap, originsnap, flags,
5389 &drr, &drr_noswap, sendfs, stream_nv, stream_avl, top_zfs,
196bee4c 5390 finalsnap, cmdprops));
428870ff
BB
5391 } else {
5392 assert(DMU_GET_STREAM_HDRTYPE(drrb->drr_versioninfo) ==
5393 DMU_COMPOUNDSTREAM);
fcff0f35 5394 return (zfs_receive_package(hdl, infd, tosnap, flags, &drr,
196bee4c 5395 &zcksum, top_zfs, cmdprops));
34dc7c2f
BB
5396 }
5397}
b128c09f
BB
5398
5399/*
5400 * Restores a backup of tosnap from the file descriptor specified by infd.
5401 * Return 0 on total success, -2 if some things couldn't be
5402 * destroyed/renamed/promoted, -1 if some things couldn't be received.
47dfff3b
MA
5403 * (-1 will override -2, if -1 and the resumable flag was specified the
5404 * transfer can be resumed if the sending side supports it).
b128c09f
BB
5405 */
5406int
fcff0f35
PD
5407zfs_receive(libzfs_handle_t *hdl, const char *tosnap, nvlist_t *props,
5408 recvflags_t *flags, int infd, avl_tree_t *stream_avl)
b128c09f
BB
5409{
5410 char *top_zfs = NULL;
5411 int err;
5c3f61eb 5412 struct stat sb;
fcff0f35 5413 char *originsnap = NULL;
5c3f61eb
RY
5414
5415 /*
5416 * The only way fstat can fail is if we do not have a valid file
5417 * descriptor.
5418 */
5419 if (fstat(infd, &sb) == -1) {
5420 perror("fstat");
5421 return (-2);
5422 }
5423
fcff0f35
PD
5424 if (props) {
5425 err = nvlist_lookup_string(props, "origin", &originsnap);
5426 if (err && err != ENOENT)
5427 return (err);
5428 }
5429
fcff0f35 5430 err = zfs_receive_impl(hdl, tosnap, originsnap, flags, infd, NULL, NULL,
196bee4c 5431 stream_avl, &top_zfs, NULL, props);
b128c09f 5432
bb61cc31 5433 if (err == 0 && !flags->nomount && flags->domount && top_zfs) {
689f093e
GN
5434 zfs_handle_t *zhp = NULL;
5435 prop_changelist_t *clp = NULL;
b128c09f 5436
bb61cc31
TC
5437 zhp = zfs_open(hdl, top_zfs,
5438 ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME);
5439 if (zhp == NULL) {
5440 err = -1;
5441 goto out;
5442 } else {
5443 if (zhp->zfs_type == ZFS_TYPE_VOLUME) {
5444 zfs_close(zhp);
5445 goto out;
5446 }
5447
b128c09f 5448 clp = changelist_gather(zhp, ZFS_PROP_MOUNTPOINT,
a57d3d45
MZ
5449 CL_GATHER_MOUNT_ALWAYS,
5450 flags->forceunmount ? MS_FORCE : 0);
b128c09f 5451 zfs_close(zhp);
bb61cc31
TC
5452 if (clp == NULL) {
5453 err = -1;
5454 goto out;
b128c09f 5455 }
bb61cc31
TC
5456
5457 /* mount and share received datasets */
5458 err = changelist_postfix(clp);
5459 changelist_free(clp);
5460 if (err != 0)
5461 err = -1;
b128c09f 5462 }
b128c09f 5463 }
bb61cc31
TC
5464
5465out:
b128c09f
BB
5466 if (top_zfs)
5467 free(top_zfs);
5468
5469 return (err);
5470}