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