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