]> git.proxmox.com Git - mirror_zfs.git/blame - lib/libzfs/libzfs_sendrecv.c
lib{efi,avl,share,tpool,zfs_core,zfsbootenv,zutil}: -fvisibility=hidden
[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:
f00f4690 771 zfs_error_aux(hdl, "%s", 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:
f00f4690 852 zfs_error_aux(hdl, "%s", strerror(errno));
34dc7c2f
BB
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) {
f00f4690 1482 zfs_error_aux(zhp->zfs_hdl, "%s", strerror(errno));
30af21b0
PD
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) {
f00f4690 1508 zfs_error_aux(zhp->zfs_hdl, "%s", strerror(err));
30af21b0
PD
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:
f00f4690 1825 zfs_error_aux(hdl, "%s", strerror(errno));
47dfff3b
MA
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) {
f00f4690 2085 zfs_error_aux(zhp->zfs_hdl, "%s", strerror(err));
30af21b0
PD
2086 return (zfs_error(zhp->zfs_hdl, EZFS_BADBACKUP,
2087 errbuf));
2088 }
2089 err = send_conclusion_record(fd, &zc);
2090 if (err != 0) {
f00f4690 2091 zfs_error_aux(zhp->zfs_hdl, "%s", strerror(err));
30af21b0
PD
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;
93f6d7e2 2131 FILE *fout;
428870ff 2132
34dc7c2f
BB
2133 (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
2134 "cannot send '%s'"), zhp->zfs_name);
2135
2136 if (fromsnap && fromsnap[0] == '\0') {
2137 zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN,
2138 "zero-length incremental source"));
2139 return (zfs_error(zhp->zfs_hdl, EZFS_NOENT, errbuf));
2140 }
2141
9c5e88b1
PZ
2142 if (flags->replicate || flags->doall || flags->props ||
2143 flags->holds || flags->backup) {
30af21b0
PD
2144 char full_tosnap_name[ZFS_MAX_DATASET_NAME_LEN];
2145 if (snprintf(full_tosnap_name, sizeof (full_tosnap_name),
2146 "%s@%s", zhp->zfs_name, tosnap) >=
2147 sizeof (full_tosnap_name)) {
2148 err = EINVAL;
2149 goto stderr_out;
34dc7c2f 2150 }
30af21b0
PD
2151 zfs_handle_t *tosnap = zfs_open(zhp->zfs_hdl,
2152 full_tosnap_name, ZFS_TYPE_SNAPSHOT);
1d20b763 2153 if (tosnap == NULL) {
2154 err = -1;
2155 goto err_out;
2156 }
30af21b0
PD
2157 err = send_prelim_records(tosnap, fromsnap, outfd,
2158 flags->replicate || flags->props || flags->holds,
2159 flags->replicate, flags->verbosity > 0, flags->dryrun,
099fa7e4
PCG
2160 flags->raw, flags->replicate, flags->skipmissing,
2161 flags->backup, flags->holds, flags->props, flags->doall,
2162 &fss, &fsavl);
30af21b0
PD
2163 zfs_close(tosnap);
2164 if (err != 0)
2165 goto err_out;
34dc7c2f
BB
2166 }
2167
2168 /* dump each stream */
2169 sdd.fromsnap = fromsnap;
2170 sdd.tosnap = tosnap;
36482bf6 2171 sdd.outfd = outfd;
330d06f9
MA
2172 sdd.replicate = flags->replicate;
2173 sdd.doall = flags->doall;
2174 sdd.fromorigin = flags->fromorigin;
34dc7c2f
BB
2175 sdd.fss = fss;
2176 sdd.fsavl = fsavl;
30af21b0 2177 sdd.verbosity = flags->verbosity;
330d06f9 2178 sdd.parsable = flags->parsable;
37abac6d 2179 sdd.progress = flags->progress;
330d06f9 2180 sdd.dryrun = flags->dryrun;
f1512ee6 2181 sdd.large_block = flags->largeblock;
9b67f605 2182 sdd.embed_data = flags->embed_data;
2aa34383 2183 sdd.compress = flags->compress;
b5256303 2184 sdd.raw = flags->raw;
9c5e88b1 2185 sdd.holds = flags->holds;
428870ff
BB
2186 sdd.filter_cb = filter_func;
2187 sdd.filter_cb_arg = cb_arg;
2188 if (debugnvp)
2189 sdd.debugnv = *debugnvp;
30af21b0 2190 if (sdd.verbosity != 0 && sdd.dryrun)
93f6d7e2
MJ
2191 sdd.std_out = B_TRUE;
2192 fout = sdd.std_out ? stdout : stderr;
e956d651
CS
2193
2194 /*
2195 * Some flags require that we place user holds on the datasets that are
2196 * being sent so they don't get destroyed during the send. We can skip
2197 * this step if the pool is imported read-only since the datasets cannot
2198 * be destroyed.
2199 */
2200 if (!flags->dryrun && !zpool_get_prop_int(zfs_get_pool_handle(zhp),
2201 ZPOOL_PROP_READONLY, NULL) &&
2202 zfs_spa_version(zhp, &spa_version) == 0 &&
2203 spa_version >= SPA_VERSION_USERREFS &&
2204 (flags->doall || flags->replicate)) {
572e2857
BB
2205 ++holdseq;
2206 (void) snprintf(sdd.holdtag, sizeof (sdd.holdtag),
2207 ".send-%d-%llu", getpid(), (u_longlong_t)holdseq);
10b575d0 2208 sdd.cleanup_fd = open(ZFS_DEV, O_RDWR | O_CLOEXEC);
572e2857
BB
2209 if (sdd.cleanup_fd < 0) {
2210 err = errno;
2211 goto stderr_out;
2212 }
95fd54a1 2213 sdd.snapholds = fnvlist_alloc();
572e2857
BB
2214 } else {
2215 sdd.cleanup_fd = -1;
95fd54a1 2216 sdd.snapholds = NULL;
572e2857 2217 }
9c5e88b1 2218
30af21b0 2219 if (flags->verbosity != 0 || sdd.snapholds != NULL) {
330d06f9
MA
2220 /*
2221 * Do a verbose no-op dry run to get all the verbose output
95fd54a1
SH
2222 * or to gather snapshot hold's before generating any data,
2223 * then do a non-verbose real run to generate the streams.
330d06f9
MA
2224 */
2225 sdd.dryrun = B_TRUE;
2226 err = dump_filesystems(zhp, &sdd);
95fd54a1
SH
2227
2228 if (err != 0)
2229 goto stderr_out;
2230
30af21b0 2231 if (flags->verbosity != 0) {
95fd54a1 2232 if (flags->parsable) {
93f6d7e2 2233 (void) fprintf(fout, "size\t%llu\n",
95fd54a1
SH
2234 (longlong_t)sdd.size);
2235 } else {
2236 char buf[16];
e7fbeb60 2237 zfs_nicebytes(sdd.size, buf, sizeof (buf));
93f6d7e2 2238 (void) fprintf(fout, dgettext(TEXT_DOMAIN,
95fd54a1
SH
2239 "total estimated size is %s\n"), buf);
2240 }
330d06f9 2241 }
95fd54a1
SH
2242
2243 /* Ensure no snaps found is treated as an error. */
2244 if (!sdd.seento) {
2245 err = ENOENT;
2246 goto err_out;
2247 }
2248
2249 /* Skip the second run if dryrun was requested. */
2250 if (flags->dryrun)
2251 goto err_out;
2252
2253 if (sdd.snapholds != NULL) {
2254 err = zfs_hold_nvl(zhp, sdd.cleanup_fd, sdd.snapholds);
2255 if (err != 0)
2256 goto stderr_out;
2257
2258 fnvlist_free(sdd.snapholds);
2259 sdd.snapholds = NULL;
2260 }
2261
2262 sdd.dryrun = B_FALSE;
30af21b0 2263 sdd.verbosity = 0;
330d06f9 2264 }
95fd54a1 2265
34dc7c2f
BB
2266 err = dump_filesystems(zhp, &sdd);
2267 fsavl_destroy(fsavl);
60a2434b 2268 fnvlist_free(fss);
34dc7c2f 2269
95fd54a1
SH
2270 /* Ensure no snaps found is treated as an error. */
2271 if (err == 0 && !sdd.seento)
2272 err = ENOENT;
2273
572e2857
BB
2274 if (sdd.cleanup_fd != -1) {
2275 VERIFY(0 == close(sdd.cleanup_fd));
2276 sdd.cleanup_fd = -1;
2277 }
2278
330d06f9 2279 if (!flags->dryrun && (flags->replicate || flags->doall ||
9c5e88b1 2280 flags->props || flags->backup || flags->holds)) {
34dc7c2f
BB
2281 /*
2282 * write final end record. NB: want to do this even if
2283 * there was some error, because it might not be totally
2284 * failed.
2285 */
30af21b0
PD
2286 err = send_conclusion_record(outfd, NULL);
2287 if (err != 0)
2288 return (zfs_standard_error(zhp->zfs_hdl, err, errbuf));
34dc7c2f
BB
2289 }
2290
2291 return (err || sdd.err);
428870ff
BB
2292
2293stderr_out:
2294 err = zfs_standard_error(zhp->zfs_hdl, err, errbuf);
2295err_out:
95fd54a1 2296 fsavl_destroy(fsavl);
60a2434b 2297 fnvlist_free(fss);
95fd54a1
SH
2298 fnvlist_free(sdd.snapholds);
2299
572e2857
BB
2300 if (sdd.cleanup_fd != -1)
2301 VERIFY(0 == close(sdd.cleanup_fd));
428870ff 2302 return (err);
34dc7c2f
BB
2303}
2304
65c7cc49 2305static zfs_handle_t *
30af21b0
PD
2306name_to_dir_handle(libzfs_handle_t *hdl, const char *snapname)
2307{
2308 char dirname[ZFS_MAX_DATASET_NAME_LEN];
2309 (void) strlcpy(dirname, snapname, ZFS_MAX_DATASET_NAME_LEN);
2310 char *c = strchr(dirname, '@');
2311 if (c != NULL)
2312 *c = '\0';
2313 return (zfs_open(hdl, dirname, ZFS_TYPE_DATASET));
2314}
2315
2316/*
2317 * Returns B_TRUE if earlier is an earlier snapshot in later's timeline; either
2318 * an earlier snapshot in the same filesystem, or a snapshot before later's
2319 * origin, or it's origin's origin, etc.
2320 */
2321static boolean_t
2322snapshot_is_before(zfs_handle_t *earlier, zfs_handle_t *later)
2323{
2324 boolean_t ret;
2325 uint64_t later_txg =
2326 (later->zfs_type == ZFS_TYPE_FILESYSTEM ||
2327 later->zfs_type == ZFS_TYPE_VOLUME ?
2328 UINT64_MAX : zfs_prop_get_int(later, ZFS_PROP_CREATETXG));
2329 uint64_t earlier_txg = zfs_prop_get_int(earlier, ZFS_PROP_CREATETXG);
2330
2331 if (earlier_txg >= later_txg)
2332 return (B_FALSE);
2333
2334 zfs_handle_t *earlier_dir = name_to_dir_handle(earlier->zfs_hdl,
2335 earlier->zfs_name);
2336 zfs_handle_t *later_dir = name_to_dir_handle(later->zfs_hdl,
2337 later->zfs_name);
2338
2339 if (strcmp(earlier_dir->zfs_name, later_dir->zfs_name) == 0) {
2340 zfs_close(earlier_dir);
2341 zfs_close(later_dir);
2342 return (B_TRUE);
2343 }
2344
2345 char clonename[ZFS_MAX_DATASET_NAME_LEN];
2346 if (zfs_prop_get(later_dir, ZFS_PROP_ORIGIN, clonename,
2347 ZFS_MAX_DATASET_NAME_LEN, NULL, NULL, 0, B_TRUE) != 0) {
2348 zfs_close(earlier_dir);
2349 zfs_close(later_dir);
2350 return (B_FALSE);
2351 }
2352
2353 zfs_handle_t *origin = zfs_open(earlier->zfs_hdl, clonename,
2354 ZFS_TYPE_DATASET);
2355 uint64_t origin_txg = zfs_prop_get_int(origin, ZFS_PROP_CREATETXG);
2356
2357 /*
2358 * If "earlier" is exactly the origin, then
2359 * snapshot_is_before(earlier, origin) will return false (because
2360 * they're the same).
2361 */
2362 if (origin_txg == earlier_txg &&
2363 strcmp(origin->zfs_name, earlier->zfs_name) == 0) {
2364 zfs_close(earlier_dir);
2365 zfs_close(later_dir);
2366 zfs_close(origin);
2367 return (B_TRUE);
2368 }
2369 zfs_close(earlier_dir);
2370 zfs_close(later_dir);
2371
2372 ret = snapshot_is_before(earlier, origin);
2373 zfs_close(origin);
2374 return (ret);
2375}
2376
2377/*
2378 * The "zhp" argument is the handle of the dataset to send (typically a
2379 * snapshot). The "from" argument is the full name of the snapshot or
2380 * bookmark that is the incremental source.
2381 */
da536844 2382int
30af21b0
PD
2383zfs_send_one(zfs_handle_t *zhp, const char *from, int fd, sendflags_t *flags,
2384 const char *redactbook)
da536844 2385{
30af21b0 2386 int err;
da536844 2387 libzfs_handle_t *hdl = zhp->zfs_hdl;
22df2457 2388 char *name = zhp->zfs_name;
30af21b0 2389 int orig_fd = fd;
196bee4c 2390 pthread_t ptid;
30af21b0 2391 progress_arg_t pa = { 0 };
30af21b0 2392
da536844 2393 char errbuf[1024];
30af21b0 2394 (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
22df2457 2395 "warning: cannot send '%s'"), name);
835db585 2396
30af21b0
PD
2397 if (from != NULL && strchr(from, '@')) {
2398 zfs_handle_t *from_zhp = zfs_open(hdl, from,
2399 ZFS_TYPE_DATASET);
1d20b763 2400 if (from_zhp == NULL)
2401 return (-1);
30af21b0
PD
2402 if (!snapshot_is_before(from_zhp, zhp)) {
2403 zfs_close(from_zhp);
2404 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
2405 "not an earlier snapshot from the same fs"));
2406 return (zfs_error(hdl, EZFS_CROSSTARGET, errbuf));
2407 }
2408 zfs_close(from_zhp);
2409 }
835db585 2410
22df2457
RM
2411 if (redactbook != NULL) {
2412 char bookname[ZFS_MAX_DATASET_NAME_LEN];
2413 nvlist_t *redact_snaps;
2414 zfs_handle_t *book_zhp;
2415 char *at, *pound;
2416 int dsnamelen;
2417
2418 pound = strchr(redactbook, '#');
2419 if (pound != NULL)
2420 redactbook = pound + 1;
2421 at = strchr(name, '@');
2422 if (at == NULL) {
2423 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
2424 "cannot do a redacted send to a filesystem"));
2425 return (zfs_error(hdl, EZFS_BADTYPE, errbuf));
2426 }
2427 dsnamelen = at - name;
2428 if (snprintf(bookname, sizeof (bookname), "%.*s#%s",
2429 dsnamelen, name, redactbook)
2430 >= sizeof (bookname)) {
2431 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
2432 "invalid bookmark name"));
2433 return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf));
2434 }
2435 book_zhp = zfs_open(hdl, bookname, ZFS_TYPE_BOOKMARK);
2436 if (book_zhp == NULL)
2437 return (-1);
2438 if (nvlist_lookup_nvlist(book_zhp->zfs_props,
2439 zfs_prop_to_name(ZFS_PROP_REDACT_SNAPS),
2440 &redact_snaps) != 0 || redact_snaps == NULL) {
2441 zfs_close(book_zhp);
2442 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
2443 "not a redaction bookmark"));
2444 return (zfs_error(hdl, EZFS_BADTYPE, errbuf));
2445 }
2446 zfs_close(book_zhp);
2447 }
2448
30af21b0
PD
2449 /*
2450 * Send fs properties
2451 */
2452 if (flags->props || flags->holds || flags->backup) {
2453 /*
2454 * Note: the header generated by send_prelim_records()
2455 * assumes that the incremental source is in the same
2456 * filesystem/volume as the target (which is a requirement
2457 * when doing "zfs send -R"). But that isn't always the
2458 * case here (e.g. send from snap in origin, or send from
2459 * bookmark). We pass from=NULL, which will omit this
2460 * information from the prelim records; it isn't used
2461 * when receiving this type of stream.
2462 */
2463 err = send_prelim_records(zhp, NULL, fd, B_TRUE, B_FALSE,
2464 flags->verbosity > 0, flags->dryrun, flags->raw,
099fa7e4 2465 flags->replicate, B_FALSE, flags->backup, flags->holds,
30af21b0
PD
2466 flags->props, flags->doall, NULL, NULL);
2467 if (err != 0)
2468 return (err);
2469 }
2470
2471 /*
2472 * Perform size estimate if verbose was specified.
2473 */
2474 if (flags->verbosity != 0) {
2475 err = estimate_size(zhp, from, fd, flags, 0, 0, 0, redactbook,
2476 errbuf);
2477 if (err != 0)
2478 return (err);
2479 }
2480
2481 if (flags->dryrun)
2482 return (0);
2483
30af21b0
PD
2484 /*
2485 * If progress reporting is requested, spawn a new thread to poll
2486 * ZFS_IOC_SEND_PROGRESS at a regular interval.
2487 */
2488 if (flags->progress) {
2489 pa.pa_zhp = zhp;
2490 pa.pa_fd = fd;
2491 pa.pa_parsable = flags->parsable;
2492 pa.pa_estimate = B_FALSE;
2493 pa.pa_verbosity = flags->verbosity;
2494
2495 err = pthread_create(&ptid, NULL,
2496 send_progress_thread, &pa);
2497 if (err != 0) {
f00f4690 2498 zfs_error_aux(zhp->zfs_hdl, "%s", strerror(errno));
30af21b0
PD
2499 return (zfs_error(zhp->zfs_hdl,
2500 EZFS_THREADCREATEFAILED, errbuf));
835db585 2501 }
2502 }
2503
22df2457 2504 err = lzc_send_redacted(name, from, fd,
30af21b0 2505 lzc_flags_from_sendflags(flags), redactbook);
835db585 2506
30af21b0
PD
2507 if (flags->progress) {
2508 void *status = NULL;
2509 if (err != 0)
2510 (void) pthread_cancel(ptid);
2511 (void) pthread_join(ptid, &status);
2512 int error = (int)(uintptr_t)status;
f00f4690
AZ
2513 if (error != 0 && status != PTHREAD_CANCELED)
2514 return (zfs_standard_error_fmt(hdl, error,
2515 dgettext(TEXT_DOMAIN,
2516 "progress thread exited nonzero")));
30af21b0 2517 }
da536844 2518
30af21b0
PD
2519 if (flags->props || flags->holds || flags->backup) {
2520 /* Write the final end record. */
2521 err = send_conclusion_record(orig_fd, NULL);
2522 if (err != 0)
2523 return (zfs_standard_error(hdl, err, errbuf));
2524 }
da536844
MA
2525 if (err != 0) {
2526 switch (errno) {
2527 case EXDEV:
2528 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
2529 "not an earlier snapshot from the same fs"));
2530 return (zfs_error(hdl, EZFS_CROSSTARGET, errbuf));
2531
2532 case ENOENT:
2533 case ESRCH:
22df2457 2534 if (lzc_exists(name)) {
da536844
MA
2535 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
2536 "incremental source (%s) does not exist"),
2537 from);
2538 }
2539 return (zfs_error(hdl, EZFS_NOENT, errbuf));
2540
b5256303
TC
2541 case EACCES:
2542 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
2543 "dataset key must be loaded"));
2544 return (zfs_error(hdl, EZFS_CRYPTOFAILED, errbuf));
2545
da536844
MA
2546 case EBUSY:
2547 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
2548 "target is busy; if a filesystem, "
2549 "it must not be mounted"));
2550 return (zfs_error(hdl, EZFS_BUSY, errbuf));
2551
2552 case EDQUOT:
22df2457 2553 case EFAULT:
da536844 2554 case EFBIG:
22df2457 2555 case EINVAL:
da536844
MA
2556 case EIO:
2557 case ENOLINK:
2558 case ENOSPC:
2559 case ENOSTR:
2560 case ENXIO:
2561 case EPIPE:
2562 case ERANGE:
da536844 2563 case EROFS:
f00f4690 2564 zfs_error_aux(hdl, "%s", strerror(errno));
da536844
MA
2565 return (zfs_error(hdl, EZFS_BADBACKUP, errbuf));
2566
2567 default:
2568 return (zfs_standard_error(hdl, errno, errbuf));
2569 }
2570 }
2571 return (err != 0);
2572}
2573
34dc7c2f
BB
2574/*
2575 * Routines specific to "zfs recv"
2576 */
2577
2578static int
2579recv_read(libzfs_handle_t *hdl, int fd, void *buf, int ilen,
2580 boolean_t byteswap, zio_cksum_t *zc)
2581{
2582 char *cp = buf;
2583 int rv;
2584 int len = ilen;
2585
2586 do {
2587 rv = read(fd, cp, len);
2588 cp += rv;
2589 len -= rv;
2590 } while (rv > 0);
2591
2592 if (rv < 0 || len != 0) {
2593 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
2594 "failed to read from stream"));
2595 return (zfs_error(hdl, EZFS_BADSTREAM, dgettext(TEXT_DOMAIN,
2596 "cannot receive")));
2597 }
2598
2599 if (zc) {
2600 if (byteswap)
2601 fletcher_4_incremental_byteswap(buf, ilen, zc);
2602 else
2603 fletcher_4_incremental_native(buf, ilen, zc);
2604 }
2605 return (0);
2606}
2607
2608static int
2609recv_read_nvlist(libzfs_handle_t *hdl, int fd, int len, nvlist_t **nvp,
2610 boolean_t byteswap, zio_cksum_t *zc)
2611{
2612 char *buf;
2613 int err;
2614
2615 buf = zfs_alloc(hdl, len);
2616 if (buf == NULL)
2617 return (ENOMEM);
2618
7a6c12fd
AJ
2619 if (len > hdl->libzfs_max_nvlist) {
2620 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "nvlist too large"));
908d43d0 2621 free(buf);
7a6c12fd
AJ
2622 return (ENOMEM);
2623 }
2624
34dc7c2f
BB
2625 err = recv_read(hdl, fd, buf, len, byteswap, zc);
2626 if (err != 0) {
2627 free(buf);
2628 return (err);
2629 }
2630
2631 err = nvlist_unpack(buf, len, nvp, 0);
2632 free(buf);
2633 if (err != 0) {
2634 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "invalid "
2635 "stream (malformed nvlist)"));
2636 return (EINVAL);
2637 }
2638 return (0);
2639}
2640
b5256303
TC
2641/*
2642 * Returns the grand origin (origin of origin of origin...) of a given handle.
2643 * If this dataset is not a clone, it simply returns a copy of the original
2644 * handle.
2645 */
2646static zfs_handle_t *
2647recv_open_grand_origin(zfs_handle_t *zhp)
2648{
2649 char origin[ZFS_MAX_DATASET_NAME_LEN];
610cb4fb 2650 zprop_source_t src;
b5256303
TC
2651 zfs_handle_t *ozhp = zfs_handle_dup(zhp);
2652
2653 while (ozhp != NULL) {
2654 if (zfs_prop_get(ozhp, ZFS_PROP_ORIGIN, origin,
2655 sizeof (origin), &src, NULL, 0, B_FALSE) != 0)
2656 break;
2657
2658 (void) zfs_close(ozhp);
2659 ozhp = zfs_open(zhp->zfs_hdl, origin, ZFS_TYPE_FILESYSTEM);
2660 }
2661
2662 return (ozhp);
2663}
2664
2665static int
dc1c630b 2666recv_rename_impl(zfs_handle_t *zhp, const char *name, const char *newname)
b5256303
TC
2667{
2668 int err;
2669 zfs_handle_t *ozhp = NULL;
2670
2671 /*
2672 * Attempt to rename the dataset. If it fails with EACCES we have
2673 * attempted to rename the dataset outside of its encryption root.
2674 * Force the dataset to become an encryption root and try again.
2675 */
dc1c630b 2676 err = lzc_rename(name, newname);
b5256303
TC
2677 if (err == EACCES) {
2678 ozhp = recv_open_grand_origin(zhp);
2679 if (ozhp == NULL) {
2680 err = ENOENT;
2681 goto out;
2682 }
2683
2684 err = lzc_change_key(ozhp->zfs_name, DCP_CMD_FORCE_NEW_KEY,
2685 NULL, NULL, 0);
2686 if (err != 0)
2687 goto out;
2688
dc1c630b 2689 err = lzc_rename(name, newname);
b5256303
TC
2690 }
2691
2692out:
2693 if (ozhp != NULL)
2694 zfs_close(ozhp);
2695 return (err);
2696}
2697
34dc7c2f
BB
2698static int
2699recv_rename(libzfs_handle_t *hdl, const char *name, const char *tryname,
330d06f9 2700 int baselen, char *newname, recvflags_t *flags)
34dc7c2f
BB
2701{
2702 static int seq;
34dc7c2f 2703 int err;
b5256303
TC
2704 prop_changelist_t *clp = NULL;
2705 zfs_handle_t *zhp = NULL;
34dc7c2f
BB
2706
2707 zhp = zfs_open(hdl, name, ZFS_TYPE_DATASET);
b5256303
TC
2708 if (zhp == NULL) {
2709 err = -1;
2710 goto out;
2711 }
b128c09f 2712 clp = changelist_gather(zhp, ZFS_PROP_NAME, 0,
330d06f9 2713 flags->force ? MS_FORCE : 0);
b5256303
TC
2714 if (clp == NULL) {
2715 err = -1;
2716 goto out;
2717 }
34dc7c2f
BB
2718 err = changelist_prefix(clp);
2719 if (err)
b5256303 2720 goto out;
34dc7c2f
BB
2721
2722 if (tryname) {
2723 (void) strcpy(newname, tryname);
330d06f9 2724 if (flags->verbose) {
34dc7c2f 2725 (void) printf("attempting rename %s to %s\n",
dc1c630b 2726 name, newname);
34dc7c2f 2727 }
dc1c630b 2728 err = recv_rename_impl(zhp, name, newname);
34dc7c2f
BB
2729 if (err == 0)
2730 changelist_rename(clp, name, tryname);
2731 } else {
2732 err = ENOENT;
2733 }
2734
13fe0198 2735 if (err != 0 && strncmp(name + baselen, "recv-", 5) != 0) {
34dc7c2f
BB
2736 seq++;
2737
eca7b760
IK
2738 (void) snprintf(newname, ZFS_MAX_DATASET_NAME_LEN,
2739 "%.*srecv-%u-%u", baselen, name, getpid(), seq);
34dc7c2f 2740
330d06f9 2741 if (flags->verbose) {
34dc7c2f 2742 (void) printf("failed - trying rename %s to %s\n",
dc1c630b 2743 name, newname);
34dc7c2f 2744 }
dc1c630b 2745 err = recv_rename_impl(zhp, name, newname);
34dc7c2f
BB
2746 if (err == 0)
2747 changelist_rename(clp, name, newname);
330d06f9 2748 if (err && flags->verbose) {
34dc7c2f
BB
2749 (void) printf("failed (%u) - "
2750 "will try again on next pass\n", errno);
2751 }
2752 err = EAGAIN;
330d06f9 2753 } else if (flags->verbose) {
34dc7c2f
BB
2754 if (err == 0)
2755 (void) printf("success\n");
2756 else
2757 (void) printf("failed (%u)\n", errno);
2758 }
2759
2760 (void) changelist_postfix(clp);
b5256303
TC
2761
2762out:
2763 if (clp != NULL)
2764 changelist_free(clp);
2765 if (zhp != NULL)
2766 zfs_close(zhp);
2767
2768 return (err);
2769}
2770
2771static int
2772recv_promote(libzfs_handle_t *hdl, const char *fsname,
2773 const char *origin_fsname, recvflags_t *flags)
2774{
2775 int err;
2776 zfs_cmd_t zc = {"\0"};
2777 zfs_handle_t *zhp = NULL, *ozhp = NULL;
2778
2779 if (flags->verbose)
2780 (void) printf("promoting %s\n", fsname);
2781
2782 (void) strlcpy(zc.zc_value, origin_fsname, sizeof (zc.zc_value));
2783 (void) strlcpy(zc.zc_name, fsname, sizeof (zc.zc_name));
2784
2785 /*
2786 * Attempt to promote the dataset. If it fails with EACCES the
2787 * promotion would cause this dataset to leave its encryption root.
2788 * Force the origin to become an encryption root and try again.
2789 */
2790 err = zfs_ioctl(hdl, ZFS_IOC_PROMOTE, &zc);
2791 if (err == EACCES) {
2792 zhp = zfs_open(hdl, fsname, ZFS_TYPE_DATASET);
2793 if (zhp == NULL) {
2794 err = -1;
2795 goto out;
2796 }
2797
2798 ozhp = recv_open_grand_origin(zhp);
2799 if (ozhp == NULL) {
2800 err = -1;
2801 goto out;
2802 }
2803
2804 err = lzc_change_key(ozhp->zfs_name, DCP_CMD_FORCE_NEW_KEY,
2805 NULL, NULL, 0);
2806 if (err != 0)
2807 goto out;
2808
2809 err = zfs_ioctl(hdl, ZFS_IOC_PROMOTE, &zc);
2810 }
2811
2812out:
2813 if (zhp != NULL)
2814 zfs_close(zhp);
2815 if (ozhp != NULL)
2816 zfs_close(ozhp);
34dc7c2f
BB
2817
2818 return (err);
2819}
2820
2821static int
2822recv_destroy(libzfs_handle_t *hdl, const char *name, int baselen,
330d06f9 2823 char *newname, recvflags_t *flags)
34dc7c2f 2824{
34dc7c2f
BB
2825 int err = 0;
2826 prop_changelist_t *clp;
2827 zfs_handle_t *zhp;
45d1cae3
BB
2828 boolean_t defer = B_FALSE;
2829 int spa_version;
34dc7c2f
BB
2830
2831 zhp = zfs_open(hdl, name, ZFS_TYPE_DATASET);
2832 if (zhp == NULL)
2833 return (-1);
b128c09f 2834 clp = changelist_gather(zhp, ZFS_PROP_NAME, 0,
330d06f9 2835 flags->force ? MS_FORCE : 0);
45d1cae3
BB
2836 if (zfs_get_type(zhp) == ZFS_TYPE_SNAPSHOT &&
2837 zfs_spa_version(zhp, &spa_version) == 0 &&
2838 spa_version >= SPA_VERSION_USERREFS)
2839 defer = B_TRUE;
34dc7c2f
BB
2840 zfs_close(zhp);
2841 if (clp == NULL)
2842 return (-1);
2843 err = changelist_prefix(clp);
2844 if (err)
2845 return (err);
2846
330d06f9 2847 if (flags->verbose)
dc1c630b
AG
2848 (void) printf("attempting destroy %s\n", name);
2849 if (zhp->zfs_type == ZFS_TYPE_SNAPSHOT) {
2850 nvlist_t *nv = fnvlist_alloc();
2851 fnvlist_add_boolean(nv, name);
2852 err = lzc_destroy_snaps(nv, defer, NULL);
2853 fnvlist_free(nv);
2854 } else {
2855 err = lzc_destroy(name);
2856 }
34dc7c2f 2857 if (err == 0) {
330d06f9 2858 if (flags->verbose)
34dc7c2f 2859 (void) printf("success\n");
dc1c630b 2860 changelist_remove(clp, name);
34dc7c2f
BB
2861 }
2862
2863 (void) changelist_postfix(clp);
2864 changelist_free(clp);
2865
45d1cae3 2866 /*
428870ff
BB
2867 * Deferred destroy might destroy the snapshot or only mark it to be
2868 * destroyed later, and it returns success in either case.
45d1cae3 2869 */
428870ff
BB
2870 if (err != 0 || (defer && zfs_dataset_exists(hdl, name,
2871 ZFS_TYPE_SNAPSHOT))) {
34dc7c2f 2872 err = recv_rename(hdl, name, NULL, baselen, newname, flags);
428870ff 2873 }
34dc7c2f
BB
2874
2875 return (err);
2876}
2877
2878typedef struct guid_to_name_data {
2879 uint64_t guid;
47dfff3b 2880 boolean_t bookmark_ok;
34dc7c2f 2881 char *name;
330d06f9 2882 char *skip;
30af21b0
PD
2883 uint64_t *redact_snap_guids;
2884 uint64_t num_redact_snaps;
34dc7c2f
BB
2885} guid_to_name_data_t;
2886
65c7cc49 2887static boolean_t
30af21b0
PD
2888redact_snaps_match(zfs_handle_t *zhp, guid_to_name_data_t *gtnd)
2889{
2890 uint64_t *bmark_snaps;
2891 uint_t bmark_num_snaps;
2892 nvlist_t *nvl;
2893 if (zhp->zfs_type != ZFS_TYPE_BOOKMARK)
2894 return (B_FALSE);
2895
2896 nvl = fnvlist_lookup_nvlist(zhp->zfs_props,
2897 zfs_prop_to_name(ZFS_PROP_REDACT_SNAPS));
2898 bmark_snaps = fnvlist_lookup_uint64_array(nvl, ZPROP_VALUE,
2899 &bmark_num_snaps);
2900 if (bmark_num_snaps != gtnd->num_redact_snaps)
2901 return (B_FALSE);
2902 int i = 0;
2903 for (; i < bmark_num_snaps; i++) {
2904 int j = 0;
2905 for (; j < bmark_num_snaps; j++) {
2906 if (bmark_snaps[i] == gtnd->redact_snap_guids[j])
2907 break;
2908 }
2909 if (j == bmark_num_snaps)
2910 break;
2911 }
2912 return (i == bmark_num_snaps);
2913}
2914
34dc7c2f
BB
2915static int
2916guid_to_name_cb(zfs_handle_t *zhp, void *arg)
2917{
2918 guid_to_name_data_t *gtnd = arg;
47dfff3b 2919 const char *slash;
34dc7c2f
BB
2920 int err;
2921
330d06f9 2922 if (gtnd->skip != NULL &&
47dfff3b
MA
2923 (slash = strrchr(zhp->zfs_name, '/')) != NULL &&
2924 strcmp(slash + 1, gtnd->skip) == 0) {
2925 zfs_close(zhp);
330d06f9
MA
2926 return (0);
2927 }
2928
30af21b0
PD
2929 if (zfs_prop_get_int(zhp, ZFS_PROP_GUID) == gtnd->guid &&
2930 (gtnd->num_redact_snaps == -1 || redact_snaps_match(zhp, gtnd))) {
34dc7c2f 2931 (void) strcpy(gtnd->name, zhp->zfs_name);
428870ff 2932 zfs_close(zhp);
34dc7c2f
BB
2933 return (EEXIST);
2934 }
330d06f9 2935
34dc7c2f 2936 err = zfs_iter_children(zhp, guid_to_name_cb, gtnd);
47dfff3b
MA
2937 if (err != EEXIST && gtnd->bookmark_ok)
2938 err = zfs_iter_bookmarks(zhp, guid_to_name_cb, gtnd);
34dc7c2f
BB
2939 zfs_close(zhp);
2940 return (err);
2941}
2942
330d06f9
MA
2943/*
2944 * Attempt to find the local dataset associated with this guid. In the case of
2945 * multiple matches, we attempt to find the "best" match by searching
2946 * progressively larger portions of the hierarchy. This allows one to send a
2947 * tree of datasets individually and guarantee that we will find the source
2948 * guid within that hierarchy, even if there are multiple matches elsewhere.
30af21b0
PD
2949 *
2950 * If num_redact_snaps is not -1, we attempt to find a redaction bookmark with
2951 * the specified number of redaction snapshots. If num_redact_snaps isn't 0 or
2952 * -1, then redact_snap_guids will be an array of the guids of the snapshots the
2953 * redaction bookmark was created with. If num_redact_snaps is -1, then we will
2954 * attempt to find a snapshot or bookmark (if bookmark_ok is passed) with the
2955 * given guid. Note that a redaction bookmark can be returned if
2956 * num_redact_snaps == -1.
330d06f9 2957 */
34dc7c2f 2958static int
30af21b0
PD
2959guid_to_name_redact_snaps(libzfs_handle_t *hdl, const char *parent,
2960 uint64_t guid, boolean_t bookmark_ok, uint64_t *redact_snap_guids,
2961 uint64_t num_redact_snaps, char *name)
34dc7c2f 2962{
eca7b760 2963 char pname[ZFS_MAX_DATASET_NAME_LEN];
34dc7c2f 2964 guid_to_name_data_t gtnd;
34dc7c2f
BB
2965
2966 gtnd.guid = guid;
47dfff3b 2967 gtnd.bookmark_ok = bookmark_ok;
34dc7c2f 2968 gtnd.name = name;
330d06f9 2969 gtnd.skip = NULL;
30af21b0
PD
2970 gtnd.redact_snap_guids = redact_snap_guids;
2971 gtnd.num_redact_snaps = num_redact_snaps;
34dc7c2f 2972
330d06f9 2973 /*
47dfff3b
MA
2974 * Search progressively larger portions of the hierarchy, starting
2975 * with the filesystem specified by 'parent'. This will
330d06f9
MA
2976 * select the "most local" version of the origin snapshot in the case
2977 * that there are multiple matching snapshots in the system.
2978 */
47dfff3b
MA
2979 (void) strlcpy(pname, parent, sizeof (pname));
2980 char *cp = strrchr(pname, '@');
2981 if (cp == NULL)
2982 cp = strchr(pname, '\0');
2983 for (; cp != NULL; cp = strrchr(pname, '/')) {
330d06f9 2984 /* Chop off the last component and open the parent */
34dc7c2f 2985 *cp = '\0';
47dfff3b 2986 zfs_handle_t *zhp = make_dataset_handle(hdl, pname);
330d06f9
MA
2987
2988 if (zhp == NULL)
2989 continue;
47dfff3b
MA
2990 int err = guid_to_name_cb(zfs_handle_dup(zhp), &gtnd);
2991 if (err != EEXIST)
2992 err = zfs_iter_children(zhp, guid_to_name_cb, &gtnd);
2993 if (err != EEXIST && bookmark_ok)
2994 err = zfs_iter_bookmarks(zhp, guid_to_name_cb, &gtnd);
34dc7c2f 2995 zfs_close(zhp);
330d06f9
MA
2996 if (err == EEXIST)
2997 return (0);
34dc7c2f 2998
330d06f9 2999 /*
47dfff3b
MA
3000 * Remember the last portion of the dataset so we skip it next
3001 * time through (as we've already searched that portion of the
3002 * hierarchy).
330d06f9 3003 */
47dfff3b 3004 gtnd.skip = strrchr(pname, '/') + 1;
330d06f9 3005 }
34dc7c2f 3006
330d06f9 3007 return (ENOENT);
34dc7c2f
BB
3008}
3009
30af21b0
PD
3010static int
3011guid_to_name(libzfs_handle_t *hdl, const char *parent, uint64_t guid,
3012 boolean_t bookmark_ok, char *name)
3013{
3014 return (guid_to_name_redact_snaps(hdl, parent, guid, bookmark_ok, NULL,
3015 -1, name));
3016}
3017
34dc7c2f 3018/*
330d06f9
MA
3019 * Return +1 if guid1 is before guid2, 0 if they are the same, and -1 if
3020 * guid1 is after guid2.
34dc7c2f
BB
3021 */
3022static int
3023created_before(libzfs_handle_t *hdl, avl_tree_t *avl,
3024 uint64_t guid1, uint64_t guid2)
3025{
3026 nvlist_t *nvfs;
98401d23 3027 char *fsname = NULL, *snapname = NULL;
eca7b760 3028 char buf[ZFS_MAX_DATASET_NAME_LEN];
34dc7c2f 3029 int rv;
330d06f9
MA
3030 zfs_handle_t *guid1hdl, *guid2hdl;
3031 uint64_t create1, create2;
34dc7c2f
BB
3032
3033 if (guid2 == 0)
3034 return (0);
3035 if (guid1 == 0)
3036 return (1);
3037
3038 nvfs = fsavl_find(avl, guid1, &snapname);
60a2434b 3039 fsname = fnvlist_lookup_string(nvfs, "name");
34dc7c2f 3040 (void) snprintf(buf, sizeof (buf), "%s@%s", fsname, snapname);
330d06f9
MA
3041 guid1hdl = zfs_open(hdl, buf, ZFS_TYPE_SNAPSHOT);
3042 if (guid1hdl == NULL)
34dc7c2f
BB
3043 return (-1);
3044
3045 nvfs = fsavl_find(avl, guid2, &snapname);
60a2434b 3046 fsname = fnvlist_lookup_string(nvfs, "name");
34dc7c2f 3047 (void) snprintf(buf, sizeof (buf), "%s@%s", fsname, snapname);
330d06f9
MA
3048 guid2hdl = zfs_open(hdl, buf, ZFS_TYPE_SNAPSHOT);
3049 if (guid2hdl == NULL) {
3050 zfs_close(guid1hdl);
34dc7c2f
BB
3051 return (-1);
3052 }
3053
330d06f9
MA
3054 create1 = zfs_prop_get_int(guid1hdl, ZFS_PROP_CREATETXG);
3055 create2 = zfs_prop_get_int(guid2hdl, ZFS_PROP_CREATETXG);
34dc7c2f 3056
330d06f9
MA
3057 if (create1 < create2)
3058 rv = -1;
3059 else if (create1 > create2)
3060 rv = +1;
3061 else
3062 rv = 0;
3063
3064 zfs_close(guid1hdl);
3065 zfs_close(guid2hdl);
34dc7c2f
BB
3066
3067 return (rv);
3068}
3069
b5256303 3070/*
83472fab 3071 * This function reestablishes the hierarchy of encryption roots after a
b5256303
TC
3072 * recursive incremental receive has completed. This must be done after the
3073 * second call to recv_incremental_replication() has renamed and promoted all
83472fab 3074 * sent datasets to their final locations in the dataset hierarchy.
b5256303
TC
3075 */
3076static int
bb61cc31 3077recv_fix_encryption_hierarchy(libzfs_handle_t *hdl, const char *top_zfs,
b5256303
TC
3078 nvlist_t *stream_nv, avl_tree_t *stream_avl)
3079{
3080 int err;
3081 nvpair_t *fselem = NULL;
3082 nvlist_t *stream_fss;
3083
60a2434b 3084 stream_fss = fnvlist_lookup_nvlist(stream_nv, "fss");
b5256303
TC
3085
3086 while ((fselem = nvlist_next_nvpair(stream_fss, fselem)) != NULL) {
3087 zfs_handle_t *zhp = NULL;
3088 uint64_t crypt;
3089 nvlist_t *snaps, *props, *stream_nvfs = NULL;
3090 nvpair_t *snapel = NULL;
3091 boolean_t is_encroot, is_clone, stream_encroot;
3092 char *cp;
3093 char *stream_keylocation = NULL;
3094 char keylocation[MAXNAMELEN];
3095 char fsname[ZFS_MAX_DATASET_NAME_LEN];
3096
3097 keylocation[0] = '\0';
60a2434b
RM
3098 stream_nvfs = fnvpair_value_nvlist(fselem);
3099 snaps = fnvlist_lookup_nvlist(stream_nvfs, "snaps");
3100 props = fnvlist_lookup_nvlist(stream_nvfs, "props");
b5256303
TC
3101 stream_encroot = nvlist_exists(stream_nvfs, "is_encroot");
3102
3103 /* find a snapshot from the stream that exists locally */
3104 err = ENOENT;
3105 while ((snapel = nvlist_next_nvpair(snaps, snapel)) != NULL) {
3106 uint64_t guid;
3107
60a2434b 3108 guid = fnvpair_value_uint64(snapel);
bb61cc31 3109 err = guid_to_name(hdl, top_zfs, guid, B_FALSE,
b5256303
TC
3110 fsname);
3111 if (err == 0)
3112 break;
3113 }
3114
3115 if (err != 0)
3116 continue;
3117
3118 cp = strchr(fsname, '@');
3119 if (cp != NULL)
3120 *cp = '\0';
3121
3122 zhp = zfs_open(hdl, fsname, ZFS_TYPE_DATASET);
3123 if (zhp == NULL) {
3124 err = ENOENT;
3125 goto error;
3126 }
3127
3128 crypt = zfs_prop_get_int(zhp, ZFS_PROP_ENCRYPTION);
3129 is_clone = zhp->zfs_dmustats.dds_origin[0] != '\0';
3130 (void) zfs_crypto_get_encryption_root(zhp, &is_encroot, NULL);
3131
da689887 3132 /* we don't need to do anything for unencrypted datasets */
b5256303
TC
3133 if (crypt == ZIO_CRYPT_OFF) {
3134 zfs_close(zhp);
3135 continue;
3136 }
3137
3138 /*
3139 * If the dataset is flagged as an encryption root, was not
3140 * received as a clone and is not currently an encryption root,
3141 * force it to become one. Fixup the keylocation if necessary.
3142 */
3143 if (stream_encroot) {
3144 if (!is_clone && !is_encroot) {
3145 err = lzc_change_key(fsname,
3146 DCP_CMD_FORCE_NEW_KEY, NULL, NULL, 0);
3147 if (err != 0) {
3148 zfs_close(zhp);
3149 goto error;
3150 }
3151 }
3152
60a2434b
RM
3153 stream_keylocation = fnvlist_lookup_string(props,
3154 zfs_prop_to_name(ZFS_PROP_KEYLOCATION));
b5256303
TC
3155
3156 /*
3157 * Refresh the properties in case the call to
3158 * lzc_change_key() changed the value.
3159 */
3160 zfs_refresh_properties(zhp);
3161 err = zfs_prop_get(zhp, ZFS_PROP_KEYLOCATION,
3162 keylocation, sizeof (keylocation), NULL, NULL,
3163 0, B_TRUE);
3164 if (err != 0) {
3165 zfs_close(zhp);
3166 goto error;
3167 }
3168
3169 if (strcmp(keylocation, stream_keylocation) != 0) {
3170 err = zfs_prop_set(zhp,
3171 zfs_prop_to_name(ZFS_PROP_KEYLOCATION),
3172 stream_keylocation);
3173 if (err != 0) {
3174 zfs_close(zhp);
3175 goto error;
3176 }
3177 }
3178 }
3179
3180 /*
3181 * If the dataset is not flagged as an encryption root and is
3182 * currently an encryption root, force it to inherit from its
4807c0ba
TC
3183 * parent. The root of a raw send should never be
3184 * force-inherited.
b5256303 3185 */
4807c0ba
TC
3186 if (!stream_encroot && is_encroot &&
3187 strcmp(top_zfs, fsname) != 0) {
b5256303
TC
3188 err = lzc_change_key(fsname, DCP_CMD_FORCE_INHERIT,
3189 NULL, NULL, 0);
3190 if (err != 0) {
3191 zfs_close(zhp);
3192 goto error;
3193 }
3194 }
3195
3196 zfs_close(zhp);
3197 }
3198
3199 return (0);
3200
3201error:
3202 return (err);
3203}
3204
34dc7c2f
BB
3205static int
3206recv_incremental_replication(libzfs_handle_t *hdl, const char *tofs,
330d06f9 3207 recvflags_t *flags, nvlist_t *stream_nv, avl_tree_t *stream_avl,
428870ff 3208 nvlist_t *renamed)
34dc7c2f 3209{
7509a3d2 3210 nvlist_t *local_nv, *deleted = NULL;
34dc7c2f
BB
3211 avl_tree_t *local_avl;
3212 nvpair_t *fselem, *nextfselem;
428870ff 3213 char *fromsnap;
eca7b760 3214 char newname[ZFS_MAX_DATASET_NAME_LEN];
7509a3d2 3215 char guidname[32];
34dc7c2f 3216 int error;
428870ff
BB
3217 boolean_t needagain, progress, recursive;
3218 char *s1, *s2;
34dc7c2f 3219
60a2434b 3220 fromsnap = fnvlist_lookup_string(stream_nv, "fromsnap");
428870ff
BB
3221
3222 recursive = (nvlist_lookup_boolean(stream_nv, "not_recursive") ==
3223 ENOENT);
34dc7c2f 3224
330d06f9 3225 if (flags->dryrun)
34dc7c2f
BB
3226 return (0);
3227
3228again:
3229 needagain = progress = B_FALSE;
3230
60a2434b 3231 deleted = fnvlist_alloc();
7509a3d2 3232
34dc7c2f 3233 if ((error = gather_nvlist(hdl, tofs, fromsnap, NULL,
099fa7e4 3234 recursive, B_TRUE, B_FALSE, recursive, B_FALSE, B_FALSE, B_FALSE,
f94b3cbf 3235 B_FALSE, B_TRUE, &local_nv, &local_avl)) != 0)
34dc7c2f
BB
3236 return (error);
3237
3238 /*
3239 * Process deletes and renames
3240 */
3241 for (fselem = nvlist_next_nvpair(local_nv, NULL);
3242 fselem; fselem = nextfselem) {
3243 nvlist_t *nvfs, *snaps;
3244 nvlist_t *stream_nvfs = NULL;
3245 nvpair_t *snapelem, *nextsnapelem;
3246 uint64_t fromguid = 0;
3247 uint64_t originguid = 0;
3248 uint64_t stream_originguid = 0;
3249 uint64_t parent_fromsnap_guid, stream_parent_fromsnap_guid;
3250 char *fsname, *stream_fsname;
3251
3252 nextfselem = nvlist_next_nvpair(local_nv, fselem);
3253
60a2434b
RM
3254 nvfs = fnvpair_value_nvlist(fselem);
3255 snaps = fnvlist_lookup_nvlist(nvfs, "snaps");
3256 fsname = fnvlist_lookup_string(nvfs, "name");
3257 parent_fromsnap_guid = fnvlist_lookup_uint64(nvfs,
3258 "parentfromsnap");
34dc7c2f
BB
3259 (void) nvlist_lookup_uint64(nvfs, "origin", &originguid);
3260
3261 /*
3262 * First find the stream's fs, so we can check for
3263 * a different origin (due to "zfs promote")
3264 */
3265 for (snapelem = nvlist_next_nvpair(snaps, NULL);
3266 snapelem; snapelem = nvlist_next_nvpair(snaps, snapelem)) {
3267 uint64_t thisguid;
3268
60a2434b 3269 thisguid = fnvpair_value_uint64(snapelem);
34dc7c2f
BB
3270 stream_nvfs = fsavl_find(stream_avl, thisguid, NULL);
3271
3272 if (stream_nvfs != NULL)
3273 break;
3274 }
3275
3276 /* check for promote */
3277 (void) nvlist_lookup_uint64(stream_nvfs, "origin",
3278 &stream_originguid);
3279 if (stream_nvfs && originguid != stream_originguid) {
3280 switch (created_before(hdl, local_avl,
3281 stream_originguid, originguid)) {
3282 case 1: {
3283 /* promote it! */
34dc7c2f
BB
3284 nvlist_t *origin_nvfs;
3285 char *origin_fsname;
3286
34dc7c2f
BB
3287 origin_nvfs = fsavl_find(local_avl, originguid,
3288 NULL);
60a2434b
RM
3289 origin_fsname = fnvlist_lookup_string(
3290 origin_nvfs, "name");
b5256303
TC
3291 error = recv_promote(hdl, fsname, origin_fsname,
3292 flags);
34dc7c2f
BB
3293 if (error == 0)
3294 progress = B_TRUE;
3295 break;
3296 }
3297 default:
3298 break;
3299 case -1:
3300 fsavl_destroy(local_avl);
60a2434b 3301 fnvlist_free(local_nv);
34dc7c2f
BB
3302 return (-1);
3303 }
3304 /*
3305 * We had/have the wrong origin, therefore our
3306 * list of snapshots is wrong. Need to handle
3307 * them on the next pass.
3308 */
3309 needagain = B_TRUE;
3310 continue;
3311 }
3312
3313 for (snapelem = nvlist_next_nvpair(snaps, NULL);
3314 snapelem; snapelem = nextsnapelem) {
3315 uint64_t thisguid;
3316 char *stream_snapname;
b128c09f 3317 nvlist_t *found, *props;
34dc7c2f
BB
3318
3319 nextsnapelem = nvlist_next_nvpair(snaps, snapelem);
3320
60a2434b 3321 thisguid = fnvpair_value_uint64(snapelem);
34dc7c2f
BB
3322 found = fsavl_find(stream_avl, thisguid,
3323 &stream_snapname);
3324
3325 /* check for delete */
3326 if (found == NULL) {
eca7b760 3327 char name[ZFS_MAX_DATASET_NAME_LEN];
34dc7c2f 3328
330d06f9 3329 if (!flags->force)
34dc7c2f
BB
3330 continue;
3331
3332 (void) snprintf(name, sizeof (name), "%s@%s",
3333 fsname, nvpair_name(snapelem));
3334
3335 error = recv_destroy(hdl, name,
3336 strlen(fsname)+1, newname, flags);
3337 if (error)
3338 needagain = B_TRUE;
3339 else
3340 progress = B_TRUE;
3df29340
BB
3341 sprintf(guidname, "%llu",
3342 (u_longlong_t)thisguid);
7509a3d2 3343 nvlist_add_boolean(deleted, guidname);
34dc7c2f
BB
3344 continue;
3345 }
3346
3347 stream_nvfs = found;
3348
b128c09f
BB
3349 if (0 == nvlist_lookup_nvlist(stream_nvfs, "snapprops",
3350 &props) && 0 == nvlist_lookup_nvlist(props,
3351 stream_snapname, &props)) {
13fe0198 3352 zfs_cmd_t zc = {"\0"};
b128c09f 3353
428870ff 3354 zc.zc_cookie = B_TRUE; /* received */
b128c09f
BB
3355 (void) snprintf(zc.zc_name, sizeof (zc.zc_name),
3356 "%s@%s", fsname, nvpair_name(snapelem));
3357 if (zcmd_write_src_nvlist(hdl, &zc,
3358 props) == 0) {
3359 (void) zfs_ioctl(hdl,
3360 ZFS_IOC_SET_PROP, &zc);
3361 zcmd_free_nvlists(&zc);
3362 }
3363 }
3364
34dc7c2f
BB
3365 /* check for different snapname */
3366 if (strcmp(nvpair_name(snapelem),
3367 stream_snapname) != 0) {
eca7b760
IK
3368 char name[ZFS_MAX_DATASET_NAME_LEN];
3369 char tryname[ZFS_MAX_DATASET_NAME_LEN];
34dc7c2f
BB
3370
3371 (void) snprintf(name, sizeof (name), "%s@%s",
3372 fsname, nvpair_name(snapelem));
3373 (void) snprintf(tryname, sizeof (name), "%s@%s",
3374 fsname, stream_snapname);
3375
3376 error = recv_rename(hdl, name, tryname,
3377 strlen(fsname)+1, newname, flags);
3378 if (error)
3379 needagain = B_TRUE;
3380 else
3381 progress = B_TRUE;
3382 }
3383
3384 if (strcmp(stream_snapname, fromsnap) == 0)
3385 fromguid = thisguid;
3386 }
3387
3388 /* check for delete */
3389 if (stream_nvfs == NULL) {
330d06f9 3390 if (!flags->force)
34dc7c2f
BB
3391 continue;
3392
3393 error = recv_destroy(hdl, fsname, strlen(tofs)+1,
3394 newname, flags);
3395 if (error)
3396 needagain = B_TRUE;
3397 else
3398 progress = B_TRUE;
3df29340 3399 sprintf(guidname, "%llu",
02730c33 3400 (u_longlong_t)parent_fromsnap_guid);
7509a3d2 3401 nvlist_add_boolean(deleted, guidname);
34dc7c2f
BB
3402 continue;
3403 }
3404
428870ff 3405 if (fromguid == 0) {
330d06f9 3406 if (flags->verbose) {
428870ff
BB
3407 (void) printf("local fs %s does not have "
3408 "fromsnap (%s in stream); must have "
3409 "been deleted locally; ignoring\n",
3410 fsname, fromsnap);
3411 }
34dc7c2f
BB
3412 continue;
3413 }
3414
60a2434b
RM
3415 stream_fsname = fnvlist_lookup_string(stream_nvfs, "name");
3416 stream_parent_fromsnap_guid = fnvlist_lookup_uint64(
3417 stream_nvfs, "parentfromsnap");
34dc7c2f 3418
428870ff
BB
3419 s1 = strrchr(fsname, '/');
3420 s2 = strrchr(stream_fsname, '/');
3421
7509a3d2 3422 /*
3423 * Check if we're going to rename based on parent guid change
3424 * and the current parent guid was also deleted. If it was then
3425 * rename will fail and is likely unneeded, so avoid this and
3426 * force an early retry to determine the new
3427 * parent_fromsnap_guid.
3428 */
3429 if (stream_parent_fromsnap_guid != 0 &&
3430 parent_fromsnap_guid != 0 &&
3431 stream_parent_fromsnap_guid != parent_fromsnap_guid) {
3df29340 3432 sprintf(guidname, "%llu",
02730c33 3433 (u_longlong_t)parent_fromsnap_guid);
7509a3d2 3434 if (nvlist_exists(deleted, guidname)) {
3435 progress = B_TRUE;
3436 needagain = B_TRUE;
3437 goto doagain;
3438 }
3439 }
3440
428870ff
BB
3441 /*
3442 * Check for rename. If the exact receive path is specified, it
3443 * does not count as a rename, but we still need to check the
3444 * datasets beneath it.
3445 */
34dc7c2f 3446 if ((stream_parent_fromsnap_guid != 0 &&
428870ff 3447 parent_fromsnap_guid != 0 &&
34dc7c2f 3448 stream_parent_fromsnap_guid != parent_fromsnap_guid) ||
330d06f9 3449 ((flags->isprefix || strcmp(tofs, fsname) != 0) &&
428870ff 3450 (s1 != NULL) && (s2 != NULL) && strcmp(s1, s2) != 0)) {
34dc7c2f 3451 nvlist_t *parent;
eca7b760 3452 char tryname[ZFS_MAX_DATASET_NAME_LEN];
34dc7c2f
BB
3453
3454 parent = fsavl_find(local_avl,
3455 stream_parent_fromsnap_guid, NULL);
3456 /*
3457 * NB: parent might not be found if we used the
3458 * tosnap for stream_parent_fromsnap_guid,
3459 * because the parent is a newly-created fs;
3460 * we'll be able to rename it after we recv the
3461 * new fs.
3462 */
3463 if (parent != NULL) {
3464 char *pname;
3465
60a2434b 3466 pname = fnvlist_lookup_string(parent, "name");
34dc7c2f
BB
3467 (void) snprintf(tryname, sizeof (tryname),
3468 "%s%s", pname, strrchr(stream_fsname, '/'));
3469 } else {
3470 tryname[0] = '\0';
330d06f9 3471 if (flags->verbose) {
34dc7c2f
BB
3472 (void) printf("local fs %s new parent "
3473 "not found\n", fsname);
3474 }
3475 }
3476
428870ff
BB
3477 newname[0] = '\0';
3478
34dc7c2f
BB
3479 error = recv_rename(hdl, fsname, tryname,
3480 strlen(tofs)+1, newname, flags);
428870ff
BB
3481
3482 if (renamed != NULL && newname[0] != '\0') {
60a2434b 3483 fnvlist_add_boolean(renamed, newname);
428870ff
BB
3484 }
3485
34dc7c2f
BB
3486 if (error)
3487 needagain = B_TRUE;
3488 else
3489 progress = B_TRUE;
3490 }
3491 }
3492
7509a3d2 3493doagain:
34dc7c2f 3494 fsavl_destroy(local_avl);
60a2434b
RM
3495 fnvlist_free(local_nv);
3496 fnvlist_free(deleted);
34dc7c2f
BB
3497
3498 if (needagain && progress) {
3499 /* do another pass to fix up temporary names */
330d06f9 3500 if (flags->verbose)
34dc7c2f
BB
3501 (void) printf("another pass:\n");
3502 goto again;
3503 }
3504
b5256303 3505 return (needagain || error != 0);
34dc7c2f
BB
3506}
3507
3508static int
3509zfs_receive_package(libzfs_handle_t *hdl, int fd, const char *destname,
330d06f9 3510 recvflags_t *flags, dmu_replay_record_t *drr, zio_cksum_t *zc,
196bee4c 3511 char **top_zfs, nvlist_t *cmdprops)
34dc7c2f
BB
3512{
3513 nvlist_t *stream_nv = NULL;
3514 avl_tree_t *stream_avl = NULL;
3515 char *fromsnap = NULL;
671c9354 3516 char *sendsnap = NULL;
428870ff 3517 char *cp;
eca7b760
IK
3518 char tofs[ZFS_MAX_DATASET_NAME_LEN];
3519 char sendfs[ZFS_MAX_DATASET_NAME_LEN];
34dc7c2f
BB
3520 char errbuf[1024];
3521 dmu_replay_record_t drre;
3522 int error;
3523 boolean_t anyerr = B_FALSE;
3524 boolean_t softerr = B_FALSE;
b5256303 3525 boolean_t recursive, raw;
34dc7c2f
BB
3526
3527 (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
3528 "cannot receive"));
3529
34dc7c2f
BB
3530 assert(drr->drr_type == DRR_BEGIN);
3531 assert(drr->drr_u.drr_begin.drr_magic == DMU_BACKUP_MAGIC);
428870ff
BB
3532 assert(DMU_GET_STREAM_HDRTYPE(drr->drr_u.drr_begin.drr_versioninfo) ==
3533 DMU_COMPOUNDSTREAM);
34dc7c2f
BB
3534
3535 /*
3536 * Read in the nvlist from the stream.
3537 */
3538 if (drr->drr_payloadlen != 0) {
34dc7c2f 3539 error = recv_read_nvlist(hdl, fd, drr->drr_payloadlen,
330d06f9 3540 &stream_nv, flags->byteswap, zc);
34dc7c2f
BB
3541 if (error) {
3542 error = zfs_error(hdl, EZFS_BADSTREAM, errbuf);
3543 goto out;
3544 }
3545 }
3546
428870ff
BB
3547 recursive = (nvlist_lookup_boolean(stream_nv, "not_recursive") ==
3548 ENOENT);
b5256303 3549 raw = (nvlist_lookup_boolean(stream_nv, "raw") == 0);
428870ff
BB
3550
3551 if (recursive && strchr(destname, '@')) {
3552 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3553 "cannot specify snapshot name for multi-snapshot stream"));
3554 error = zfs_error(hdl, EZFS_BADSTREAM, errbuf);
3555 goto out;
3556 }
3557
34dc7c2f
BB
3558 /*
3559 * Read in the end record and verify checksum.
3560 */
3561 if (0 != (error = recv_read(hdl, fd, &drre, sizeof (drre),
330d06f9 3562 flags->byteswap, NULL)))
34dc7c2f 3563 goto out;
330d06f9 3564 if (flags->byteswap) {
34dc7c2f
BB
3565 drre.drr_type = BSWAP_32(drre.drr_type);
3566 drre.drr_u.drr_end.drr_checksum.zc_word[0] =
3567 BSWAP_64(drre.drr_u.drr_end.drr_checksum.zc_word[0]);
3568 drre.drr_u.drr_end.drr_checksum.zc_word[1] =
3569 BSWAP_64(drre.drr_u.drr_end.drr_checksum.zc_word[1]);
3570 drre.drr_u.drr_end.drr_checksum.zc_word[2] =
3571 BSWAP_64(drre.drr_u.drr_end.drr_checksum.zc_word[2]);
3572 drre.drr_u.drr_end.drr_checksum.zc_word[3] =
3573 BSWAP_64(drre.drr_u.drr_end.drr_checksum.zc_word[3]);
3574 }
3575 if (drre.drr_type != DRR_END) {
3576 error = zfs_error(hdl, EZFS_BADSTREAM, errbuf);
3577 goto out;
3578 }
3579 if (!ZIO_CHECKSUM_EQUAL(drre.drr_u.drr_end.drr_checksum, *zc)) {
3580 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3581 "incorrect header checksum"));
3582 error = zfs_error(hdl, EZFS_BADSTREAM, errbuf);
3583 goto out;
3584 }
3585
3586 (void) nvlist_lookup_string(stream_nv, "fromsnap", &fromsnap);
3587
3588 if (drr->drr_payloadlen != 0) {
3589 nvlist_t *stream_fss;
3590
60a2434b 3591 stream_fss = fnvlist_lookup_nvlist(stream_nv, "fss");
34dc7c2f
BB
3592 if ((stream_avl = fsavl_create(stream_fss)) == NULL) {
3593 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3594 "couldn't allocate avl tree"));
3595 error = zfs_error(hdl, EZFS_NOMEM, errbuf);
3596 goto out;
3597 }
3598
4c3c6b6c 3599 if (fromsnap != NULL && recursive) {
428870ff
BB
3600 nvlist_t *renamed = NULL;
3601 nvpair_t *pair = NULL;
3602
eca7b760 3603 (void) strlcpy(tofs, destname, sizeof (tofs));
330d06f9 3604 if (flags->isprefix) {
428870ff
BB
3605 struct drr_begin *drrb = &drr->drr_u.drr_begin;
3606 int i;
3607
330d06f9 3608 if (flags->istail) {
428870ff
BB
3609 cp = strrchr(drrb->drr_toname, '/');
3610 if (cp == NULL) {
3611 (void) strlcat(tofs, "/",
eca7b760 3612 sizeof (tofs));
428870ff
BB
3613 i = 0;
3614 } else {
3615 i = (cp - drrb->drr_toname);
3616 }
3617 } else {
3618 i = strcspn(drrb->drr_toname, "/@");
3619 }
34dc7c2f 3620 /* zfs_receive_one() will create_parents() */
428870ff 3621 (void) strlcat(tofs, &drrb->drr_toname[i],
eca7b760 3622 sizeof (tofs));
34dc7c2f
BB
3623 *strchr(tofs, '@') = '\0';
3624 }
428870ff 3625
4c3c6b6c 3626 if (!flags->dryrun && !flags->nomount) {
60a2434b 3627 renamed = fnvlist_alloc();
428870ff
BB
3628 }
3629
3630 softerr = recv_incremental_replication(hdl, tofs, flags,
3631 stream_nv, stream_avl, renamed);
3632
3633 /* Unmount renamed filesystems before receiving. */
3634 while ((pair = nvlist_next_nvpair(renamed,
3635 pair)) != NULL) {
3636 zfs_handle_t *zhp;
3637 prop_changelist_t *clp = NULL;
3638
3639 zhp = zfs_open(hdl, nvpair_name(pair),
3640 ZFS_TYPE_FILESYSTEM);
3641 if (zhp != NULL) {
3642 clp = changelist_gather(zhp,
a57d3d45
MZ
3643 ZFS_PROP_MOUNTPOINT, 0,
3644 flags->forceunmount ? MS_FORCE : 0);
428870ff
BB
3645 zfs_close(zhp);
3646 if (clp != NULL) {
3647 softerr |=
3648 changelist_prefix(clp);
3649 changelist_free(clp);
3650 }
3651 }
3652 }
3653
60a2434b 3654 fnvlist_free(renamed);
34dc7c2f
BB
3655 }
3656 }
3657
428870ff
BB
3658 /*
3659 * Get the fs specified by the first path in the stream (the top level
3660 * specified by 'zfs send') and pass it to each invocation of
3661 * zfs_receive_one().
3662 */
3663 (void) strlcpy(sendfs, drr->drr_u.drr_begin.drr_toname,
eca7b760 3664 sizeof (sendfs));
671c9354 3665 if ((cp = strchr(sendfs, '@')) != NULL) {
428870ff 3666 *cp = '\0';
671c9354
DM
3667 /*
3668 * Find the "sendsnap", the final snapshot in a replication
3669 * stream. zfs_receive_one() handles certain errors
3670 * differently, depending on if the contained stream is the
3671 * last one or not.
3672 */
3673 sendsnap = (cp + 1);
3674 }
34dc7c2f
BB
3675
3676 /* Finally, receive each contained stream */
3677 do {
3678 /*
3679 * we should figure out if it has a recoverable
3680 * error, in which case do a recv_skip() and drive on.
3681 * Note, if we fail due to already having this guid,
3682 * zfs_receive_one() will take care of it (ie,
3683 * recv_skip() and return 0).
3684 */
fcff0f35 3685 error = zfs_receive_impl(hdl, destname, NULL, flags, fd,
196bee4c 3686 sendfs, stream_nv, stream_avl, top_zfs, sendsnap, cmdprops);
34dc7c2f
BB
3687 if (error == ENODATA) {
3688 error = 0;
3689 break;
3690 }
3691 anyerr |= error;
3692 } while (error == 0);
3693
4c3c6b6c 3694 if (drr->drr_payloadlen != 0 && recursive && fromsnap != NULL) {
34dc7c2f
BB
3695 /*
3696 * Now that we have the fs's they sent us, try the
3697 * renames again.
3698 */
3699 softerr = recv_incremental_replication(hdl, tofs, flags,
428870ff 3700 stream_nv, stream_avl, NULL);
34dc7c2f
BB
3701 }
3702
bb61cc31
TC
3703 if (raw && softerr == 0 && *top_zfs != NULL) {
3704 softerr = recv_fix_encryption_hierarchy(hdl, *top_zfs,
b5256303
TC
3705 stream_nv, stream_avl);
3706 }
3707
34dc7c2f
BB
3708out:
3709 fsavl_destroy(stream_avl);
60a2434b 3710 fnvlist_free(stream_nv);
34dc7c2f
BB
3711 if (softerr)
3712 error = -2;
3713 if (anyerr)
3714 error = -1;
3715 return (error);
3716}
3717
428870ff
BB
3718static void
3719trunc_prop_errs(int truncated)
3720{
3721 ASSERT(truncated != 0);
3722
3723 if (truncated == 1)
3724 (void) fprintf(stderr, dgettext(TEXT_DOMAIN,
3725 "1 more property could not be set\n"));
3726 else
3727 (void) fprintf(stderr, dgettext(TEXT_DOMAIN,
3728 "%d more properties could not be set\n"), truncated);
3729}
3730
34dc7c2f
BB
3731static int
3732recv_skip(libzfs_handle_t *hdl, int fd, boolean_t byteswap)
3733{
3734 dmu_replay_record_t *drr;
f1512ee6 3735 void *buf = zfs_alloc(hdl, SPA_MAXBLOCKSIZE);
870e7a52 3736 uint64_t payload_size;
428870ff
BB
3737 char errbuf[1024];
3738
3739 (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
870e7a52 3740 "cannot receive"));
34dc7c2f
BB
3741
3742 /* XXX would be great to use lseek if possible... */
3743 drr = buf;
3744
3745 while (recv_read(hdl, fd, drr, sizeof (dmu_replay_record_t),
3746 byteswap, NULL) == 0) {
3747 if (byteswap)
3748 drr->drr_type = BSWAP_32(drr->drr_type);
3749
3750 switch (drr->drr_type) {
3751 case DRR_BEGIN:
428870ff 3752 if (drr->drr_payloadlen != 0) {
47dfff3b
MA
3753 (void) recv_read(hdl, fd, buf,
3754 drr->drr_payloadlen, B_FALSE, NULL);
428870ff 3755 }
34dc7c2f
BB
3756 break;
3757
3758 case DRR_END:
3759 free(buf);
3760 return (0);
3761
3762 case DRR_OBJECT:
3763 if (byteswap) {
3764 drr->drr_u.drr_object.drr_bonuslen =
3765 BSWAP_32(drr->drr_u.drr_object.
3766 drr_bonuslen);
870e7a52
TC
3767 drr->drr_u.drr_object.drr_raw_bonuslen =
3768 BSWAP_32(drr->drr_u.drr_object.
3769 drr_raw_bonuslen);
34dc7c2f 3770 }
870e7a52
TC
3771
3772 payload_size =
3773 DRR_OBJECT_PAYLOAD_SIZE(&drr->drr_u.drr_object);
3774 (void) recv_read(hdl, fd, buf, payload_size,
34dc7c2f
BB
3775 B_FALSE, NULL);
3776 break;
3777
3778 case DRR_WRITE:
3779 if (byteswap) {
2aa34383
DK
3780 drr->drr_u.drr_write.drr_logical_size =
3781 BSWAP_64(
3782 drr->drr_u.drr_write.drr_logical_size);
3783 drr->drr_u.drr_write.drr_compressed_size =
3784 BSWAP_64(
3785 drr->drr_u.drr_write.drr_compressed_size);
34dc7c2f 3786 }
870e7a52 3787 payload_size =
2aa34383 3788 DRR_WRITE_PAYLOAD_SIZE(&drr->drr_u.drr_write);
7a6c12fd 3789 assert(payload_size <= SPA_MAXBLOCKSIZE);
34dc7c2f 3790 (void) recv_read(hdl, fd, buf,
2aa34383 3791 payload_size, B_FALSE, NULL);
34dc7c2f 3792 break;
428870ff
BB
3793 case DRR_SPILL:
3794 if (byteswap) {
9f8026c8 3795 drr->drr_u.drr_spill.drr_length =
428870ff 3796 BSWAP_64(drr->drr_u.drr_spill.drr_length);
870e7a52
TC
3797 drr->drr_u.drr_spill.drr_compressed_size =
3798 BSWAP_64(drr->drr_u.drr_spill.
3799 drr_compressed_size);
428870ff 3800 }
870e7a52
TC
3801
3802 payload_size =
3803 DRR_SPILL_PAYLOAD_SIZE(&drr->drr_u.drr_spill);
3804 (void) recv_read(hdl, fd, buf, payload_size,
3805 B_FALSE, NULL);
428870ff 3806 break;
9b67f605
MA
3807 case DRR_WRITE_EMBEDDED:
3808 if (byteswap) {
3809 drr->drr_u.drr_write_embedded.drr_psize =
3810 BSWAP_32(drr->drr_u.drr_write_embedded.
3811 drr_psize);
3812 }
3813 (void) recv_read(hdl, fd, buf,
3814 P2ROUNDUP(drr->drr_u.drr_write_embedded.drr_psize,
3815 8), B_FALSE, NULL);
3816 break;
30af21b0 3817 case DRR_OBJECT_RANGE:
428870ff 3818 case DRR_WRITE_BYREF:
34dc7c2f
BB
3819 case DRR_FREEOBJECTS:
3820 case DRR_FREE:
3821 break;
3822
3823 default:
428870ff
BB
3824 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3825 "invalid record type"));
fad5fb01 3826 free(buf);
428870ff 3827 return (zfs_error(hdl, EZFS_BADSTREAM, errbuf));
34dc7c2f
BB
3828 }
3829 }
3830
3831 free(buf);
3832 return (-1);
3833}
3834
47dfff3b
MA
3835static void
3836recv_ecksum_set_aux(libzfs_handle_t *hdl, const char *target_snap,
7145123b 3837 boolean_t resumable, boolean_t checksum)
47dfff3b 3838{
eca7b760 3839 char target_fs[ZFS_MAX_DATASET_NAME_LEN];
47dfff3b 3840
7145123b
PD
3841 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, (checksum ?
3842 "checksum mismatch" : "incomplete stream")));
47dfff3b
MA
3843
3844 if (!resumable)
3845 return;
3846 (void) strlcpy(target_fs, target_snap, sizeof (target_fs));
3847 *strchr(target_fs, '@') = '\0';
3848 zfs_handle_t *zhp = zfs_open(hdl, target_fs,
3849 ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME);
3850 if (zhp == NULL)
3851 return;
3852
3853 char token_buf[ZFS_MAXPROPLEN];
3854 int error = zfs_prop_get(zhp, ZFS_PROP_RECEIVE_RESUME_TOKEN,
3855 token_buf, sizeof (token_buf),
3856 NULL, NULL, 0, B_TRUE);
3857 if (error == 0) {
3858 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3859 "checksum mismatch or incomplete stream.\n"
3860 "Partially received snapshot is saved.\n"
3861 "A resuming stream can be generated on the sending "
3862 "system by running:\n"
3863 " zfs send -t %s"),
3864 token_buf);
3865 }
3866 zfs_close(zhp);
3867}
3868
a3eeab2d 3869/*
3870 * Prepare a new nvlist of properties that are to override (-o) or be excluded
3871 * (-x) from the received dataset
3872 * recvprops: received properties from the send stream
3873 * cmdprops: raw input properties from command line
3874 * origprops: properties, both locally-set and received, currently set on the
3875 * target dataset if it exists, NULL otherwise.
3876 * oxprops: valid output override (-o) and excluded (-x) properties
3877 */
3878static int
d9c460a0
TC
3879zfs_setup_cmdline_props(libzfs_handle_t *hdl, zfs_type_t type,
3880 char *fsname, boolean_t zoned, boolean_t recursive, boolean_t newfs,
3881 boolean_t raw, boolean_t toplevel, nvlist_t *recvprops, nvlist_t *cmdprops,
3882 nvlist_t *origprops, nvlist_t **oxprops, uint8_t **wkeydata_out,
3883 uint_t *wkeylen_out, const char *errbuf)
a3eeab2d 3884{
3885 nvpair_t *nvp;
3886 nvlist_t *oprops, *voprops;
3887 zfs_handle_t *zhp = NULL;
3888 zpool_handle_t *zpool_hdl = NULL;
d9c460a0 3889 char *cp;
a3eeab2d 3890 int ret = 0;
d9c460a0 3891 char namebuf[ZFS_MAX_DATASET_NAME_LEN];
a3eeab2d 3892
3893 if (nvlist_empty(cmdprops))
3894 return (0); /* No properties to override or exclude */
3895
3896 *oxprops = fnvlist_alloc();
3897 oprops = fnvlist_alloc();
3898
d9c460a0
TC
3899 strlcpy(namebuf, fsname, ZFS_MAX_DATASET_NAME_LEN);
3900
3901 /*
3902 * Get our dataset handle. The target dataset may not exist yet.
3903 */
3904 if (zfs_dataset_exists(hdl, namebuf, ZFS_TYPE_DATASET)) {
3905 zhp = zfs_open(hdl, namebuf, ZFS_TYPE_DATASET);
3906 if (zhp == NULL) {
3907 ret = -1;
3908 goto error;
3909 }
3910 }
3911
3912 /* open the zpool handle */
3913 cp = strchr(namebuf, '/');
3914 if (cp != NULL)
3915 *cp = '\0';
3916 zpool_hdl = zpool_open(hdl, namebuf);
3917 if (zpool_hdl == NULL) {
3918 ret = -1;
3919 goto error;
3920 }
3921
3922 /* restore namebuf to match fsname for later use */
3923 if (cp != NULL)
3924 *cp = '/';
3925
a3eeab2d 3926 /*
3927 * first iteration: process excluded (-x) properties now and gather
3928 * added (-o) properties to be later processed by zfs_valid_proplist()
3929 */
3930 nvp = NULL;
3931 while ((nvp = nvlist_next_nvpair(cmdprops, nvp)) != NULL) {
3932 const char *name = nvpair_name(nvp);
3933 zfs_prop_t prop = zfs_name_to_prop(name);
3934
3935 /* "origin" is processed separately, don't handle it here */
3936 if (prop == ZFS_PROP_ORIGIN)
3937 continue;
3938
d9c460a0
TC
3939 /* raw streams can't override encryption properties */
3940 if ((zfs_prop_encryption_key_param(prop) ||
b4238327 3941 prop == ZFS_PROP_ENCRYPTION) && raw) {
d9c460a0
TC
3942 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3943 "encryption property '%s' cannot "
b4238327
TC
3944 "be set or excluded for raw streams."), name);
3945 ret = zfs_error(hdl, EZFS_BADPROP, errbuf);
3946 goto error;
3947 }
3948
3949 /* incremental streams can only exclude encryption properties */
3950 if ((zfs_prop_encryption_key_param(prop) ||
3951 prop == ZFS_PROP_ENCRYPTION) && !newfs &&
3952 nvpair_type(nvp) != DATA_TYPE_BOOLEAN) {
3953 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3954 "encryption property '%s' cannot "
3955 "be set for incremental streams."), name);
d9c460a0
TC
3956 ret = zfs_error(hdl, EZFS_BADPROP, errbuf);
3957 goto error;
3958 }
3959
a3eeab2d 3960 switch (nvpair_type(nvp)) {
3961 case DATA_TYPE_BOOLEAN: /* -x property */
3962 /*
3963 * DATA_TYPE_BOOLEAN is the way we're asked to "exclude"
3964 * a property: this is done by forcing an explicit
3965 * inherit on the destination so the effective value is
3966 * not the one we received from the send stream.
b0269cd8
I
3967 */
3968 if (!zfs_prop_valid_for_type(prop, type, B_FALSE) &&
3969 !zfs_prop_user(name)) {
3970 (void) fprintf(stderr, dgettext(TEXT_DOMAIN,
3971 "Warning: %s: property '%s' does not "
3972 "apply to datasets of this type\n"),
3973 fsname, name);
3974 continue;
3975 }
3976 /*
a3eeab2d 3977 * We do this only if the property is not already
3978 * locally-set, in which case its value will take
3979 * priority over the received anyway.
3980 */
3981 if (nvlist_exists(origprops, name)) {
3982 nvlist_t *attrs;
b4238327 3983 char *source = NULL;
a3eeab2d 3984
3985 attrs = fnvlist_lookup_nvlist(origprops, name);
b4238327
TC
3986 if (nvlist_lookup_string(attrs,
3987 ZPROP_SOURCE, &source) == 0 &&
3988 strcmp(source, ZPROP_SOURCE_VAL_RECVD) != 0)
a3eeab2d 3989 continue;
3990 }
3991 /*
3992 * We can't force an explicit inherit on non-inheritable
3993 * properties: if we're asked to exclude this kind of
3994 * values we remove them from "recvprops" input nvlist.
3995 */
3996 if (!zfs_prop_inheritable(prop) &&
3997 !zfs_prop_user(name) && /* can be inherited too */
3998 nvlist_exists(recvprops, name))
3999 fnvlist_remove(recvprops, name);
4000 else
4001 fnvlist_add_nvpair(*oxprops, nvp);
4002 break;
4003 case DATA_TYPE_STRING: /* -o property=value */
b0269cd8
I
4004 /*
4005 * we're trying to override a property that does not
4006 * make sense for this type of dataset, but we don't
4007 * want to fail if the receive is recursive: this comes
4008 * in handy when the send stream contains, for
4009 * instance, a child ZVOL and we're trying to receive
4010 * it with "-o atime=on"
4011 */
4012 if (!zfs_prop_valid_for_type(prop, type, B_FALSE) &&
4013 !zfs_prop_user(name)) {
4014 if (recursive)
4015 continue;
4016 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
4017 "property '%s' does not apply to datasets "
4018 "of this type"), name);
4019 ret = zfs_error(hdl, EZFS_BADPROP, errbuf);
4020 goto error;
4021 }
a3eeab2d 4022 fnvlist_add_nvpair(oprops, nvp);
4023 break;
4024 default:
4025 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
4026 "property '%s' must be a string or boolean"), name);
4027 ret = zfs_error(hdl, EZFS_BADPROP, errbuf);
4028 goto error;
4029 }
4030 }
4031
4032 if (toplevel) {
4033 /* convert override strings properties to native */
4034 if ((voprops = zfs_valid_proplist(hdl, ZFS_TYPE_DATASET,
b5256303 4035 oprops, zoned, zhp, zpool_hdl, B_FALSE, errbuf)) == NULL) {
a3eeab2d 4036 ret = zfs_error(hdl, EZFS_BADPROP, errbuf);
4037 goto error;
4038 }
4039
d9c460a0
TC
4040 /*
4041 * zfs_crypto_create() requires the parent name. Get it
4042 * by truncating the fsname copy stored in namebuf.
4043 */
4044 cp = strrchr(namebuf, '/');
4045 if (cp != NULL)
4046 *cp = '\0';
4047
4048 if (!raw && zfs_crypto_create(hdl, namebuf, voprops, NULL,
4049 B_FALSE, wkeydata_out, wkeylen_out) != 0) {
4050 fnvlist_free(voprops);
4051 ret = zfs_error(hdl, EZFS_CRYPTOFAILED, errbuf);
4052 goto error;
4053 }
4054
a3eeab2d 4055 /* second pass: process "-o" properties */
4056 fnvlist_merge(*oxprops, voprops);
4057 fnvlist_free(voprops);
4058 } else {
4059 /* override props on child dataset are inherited */
4060 nvp = NULL;
4061 while ((nvp = nvlist_next_nvpair(oprops, nvp)) != NULL) {
4062 const char *name = nvpair_name(nvp);
4063 fnvlist_add_boolean(*oxprops, name);
4064 }
4065 }
4066
4067error:
d9c460a0
TC
4068 if (zhp != NULL)
4069 zfs_close(zhp);
4070 if (zpool_hdl != NULL)
4071 zpool_close(zpool_hdl);
a3eeab2d 4072 fnvlist_free(oprops);
4073 return (ret);
4074}
4075
34dc7c2f
BB
4076/*
4077 * Restores a backup of tosnap from the file descriptor specified by infd.
4078 */
4079static int
4080zfs_receive_one(libzfs_handle_t *hdl, int infd, const char *tosnap,
fcff0f35
PD
4081 const char *originsnap, recvflags_t *flags, dmu_replay_record_t *drr,
4082 dmu_replay_record_t *drr_noswap, const char *sendfs, nvlist_t *stream_nv,
196bee4c
MA
4083 avl_tree_t *stream_avl, char **top_zfs,
4084 const char *finalsnap, nvlist_t *cmdprops)
34dc7c2f 4085{
34dc7c2f 4086 time_t begin_time;
428870ff 4087 int ioctl_err, ioctl_errno, err;
34dc7c2f
BB
4088 char *cp;
4089 struct drr_begin *drrb = &drr->drr_u.drr_begin;
4090 char errbuf[1024];
428870ff 4091 const char *chopprefix;
34dc7c2f 4092 boolean_t newfs = B_FALSE;
a132c2b4 4093 boolean_t stream_wantsnewfs, stream_resumingnewfs;
43e52edd
BB
4094 boolean_t newprops = B_FALSE;
4095 uint64_t read_bytes = 0;
4096 uint64_t errflags = 0;
34dc7c2f
BB
4097 uint64_t parent_snapguid = 0;
4098 prop_changelist_t *clp = NULL;
b128c09f 4099 nvlist_t *snapprops_nvlist = NULL;
9c5e88b1 4100 nvlist_t *snapholds_nvlist = NULL;
428870ff 4101 zprop_errflags_t prop_errflags;
43e52edd 4102 nvlist_t *prop_errors = NULL;
428870ff 4103 boolean_t recursive;
671c9354 4104 char *snapname = NULL;
43e52edd
BB
4105 char destsnap[MAXPATHLEN * 2];
4106 char origin[MAXNAMELEN];
4107 char name[MAXPATHLEN];
b5256303 4108 char tmp_keylocation[MAXNAMELEN];
a3eeab2d 4109 nvlist_t *rcvprops = NULL; /* props received from the send stream */
4110 nvlist_t *oxprops = NULL; /* override (-o) and exclude (-x) props */
4111 nvlist_t *origprops = NULL; /* original props (if destination exists) */
4112 zfs_type_t type;
bee7e4ff 4113 boolean_t toplevel = B_FALSE;
a3eeab2d 4114 boolean_t zoned = B_FALSE;
c03f0470 4115 boolean_t hastoken = B_FALSE;
30af21b0 4116 boolean_t redacted;
d9c460a0
TC
4117 uint8_t *wkeydata = NULL;
4118 uint_t wkeylen = 0;
34dc7c2f
BB
4119
4120 begin_time = time(NULL);
43e52edd 4121 bzero(origin, MAXNAMELEN);
b5256303 4122 bzero(tmp_keylocation, MAXNAMELEN);
34dc7c2f
BB
4123
4124 (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
4125 "cannot receive"));
4126
428870ff
BB
4127 recursive = (nvlist_lookup_boolean(stream_nv, "not_recursive") ==
4128 ENOENT);
4129
9c5e88b1
PZ
4130 /* Did the user request holds be skipped via zfs recv -k? */
4131 boolean_t holds = flags->holds && !flags->skipholds;
4132
34dc7c2f 4133 if (stream_avl != NULL) {
b5256303 4134 char *keylocation = NULL;
48f783de 4135 nvlist_t *lookup = NULL;
b128c09f
BB
4136 nvlist_t *fs = fsavl_find(stream_avl, drrb->drr_toguid,
4137 &snapname);
34dc7c2f
BB
4138
4139 (void) nvlist_lookup_uint64(fs, "parentfromsnap",
4140 &parent_snapguid);
a3eeab2d 4141 err = nvlist_lookup_nvlist(fs, "props", &rcvprops);
43e52edd 4142 if (err) {
60a2434b 4143 rcvprops = fnvlist_alloc();
43e52edd
BB
4144 newprops = B_TRUE;
4145 }
34dc7c2f 4146
b5256303
TC
4147 /*
4148 * The keylocation property may only be set on encryption roots,
4149 * but this dataset might not become an encryption root until
83472fab 4150 * recv_fix_encryption_hierarchy() is called. That function
b5256303
TC
4151 * will fixup the keylocation anyway, so we temporarily unset
4152 * the keylocation for now to avoid any errors from the receive
4153 * ioctl.
4154 */
4155 err = nvlist_lookup_string(rcvprops,
4156 zfs_prop_to_name(ZFS_PROP_KEYLOCATION), &keylocation);
4157 if (err == 0) {
4158 strcpy(tmp_keylocation, keylocation);
4159 (void) nvlist_remove_all(rcvprops,
4160 zfs_prop_to_name(ZFS_PROP_KEYLOCATION));
4161 }
4162
330d06f9 4163 if (flags->canmountoff) {
60a2434b
RM
4164 fnvlist_add_uint64(rcvprops,
4165 zfs_prop_to_name(ZFS_PROP_CANMOUNT), 0);
9c5e88b1 4166 } else if (newprops) { /* nothing in rcvprops, eliminate it */
60a2434b 4167 fnvlist_free(rcvprops);
9c5e88b1
PZ
4168 rcvprops = NULL;
4169 newprops = B_FALSE;
34dc7c2f 4170 }
48f783de 4171 if (0 == nvlist_lookup_nvlist(fs, "snapprops", &lookup)) {
60a2434b
RM
4172 snapprops_nvlist = fnvlist_lookup_nvlist(lookup,
4173 snapname);
48f783de 4174 }
9c5e88b1
PZ
4175 if (holds) {
4176 if (0 == nvlist_lookup_nvlist(fs, "snapholds",
4177 &lookup)) {
60a2434b
RM
4178 snapholds_nvlist = fnvlist_lookup_nvlist(
4179 lookup, snapname);
9c5e88b1
PZ
4180 }
4181 }
34dc7c2f
BB
4182 }
4183
428870ff
BB
4184 cp = NULL;
4185
34dc7c2f
BB
4186 /*
4187 * Determine how much of the snapshot name stored in the stream
4188 * we are going to tack on to the name they specified on the
4189 * command line, and how much we are going to chop off.
4190 *
4191 * If they specified a snapshot, chop the entire name stored in
4192 * the stream.
4193 */
330d06f9 4194 if (flags->istail) {
428870ff
BB
4195 /*
4196 * A filesystem was specified with -e. We want to tack on only
4197 * the tail of the sent snapshot path.
4198 */
4199 if (strchr(tosnap, '@')) {
4200 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "invalid "
4201 "argument - snapshot not allowed with -e"));
43e52edd
BB
4202 err = zfs_error(hdl, EZFS_INVALIDNAME, errbuf);
4203 goto out;
428870ff
BB
4204 }
4205
4206 chopprefix = strrchr(sendfs, '/');
4207
4208 if (chopprefix == NULL) {
4209 /*
4210 * The tail is the poolname, so we need to
4211 * prepend a path separator.
4212 */
4213 int len = strlen(drrb->drr_toname);
4214 cp = malloc(len + 2);
4215 cp[0] = '/';
4216 (void) strcpy(&cp[1], drrb->drr_toname);
4217 chopprefix = cp;
4218 } else {
4219 chopprefix = drrb->drr_toname + (chopprefix - sendfs);
4220 }
330d06f9 4221 } else if (flags->isprefix) {
34dc7c2f 4222 /*
428870ff
BB
4223 * A filesystem was specified with -d. We want to tack on
4224 * everything but the first element of the sent snapshot path
4225 * (all but the pool name).
34dc7c2f
BB
4226 */
4227 if (strchr(tosnap, '@')) {
4228 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "invalid "
4229 "argument - snapshot not allowed with -d"));
43e52edd
BB
4230 err = zfs_error(hdl, EZFS_INVALIDNAME, errbuf);
4231 goto out;
34dc7c2f 4232 }
428870ff
BB
4233
4234 chopprefix = strchr(drrb->drr_toname, '/');
4235 if (chopprefix == NULL)
4236 chopprefix = strchr(drrb->drr_toname, '@');
34dc7c2f
BB
4237 } else if (strchr(tosnap, '@') == NULL) {
4238 /*
428870ff
BB
4239 * If a filesystem was specified without -d or -e, we want to
4240 * tack on everything after the fs specified by 'zfs send'.
34dc7c2f 4241 */
428870ff
BB
4242 chopprefix = drrb->drr_toname + strlen(sendfs);
4243 } else {
4244 /* A snapshot was specified as an exact path (no -d or -e). */
4245 if (recursive) {
4246 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
4247 "cannot specify snapshot name for multi-snapshot "
4248 "stream"));
43e52edd
BB
4249 err = zfs_error(hdl, EZFS_BADSTREAM, errbuf);
4250 goto out;
428870ff
BB
4251 }
4252 chopprefix = drrb->drr_toname + strlen(drrb->drr_toname);
34dc7c2f 4253 }
428870ff
BB
4254
4255 ASSERT(strstr(drrb->drr_toname, sendfs) == drrb->drr_toname);
bdbd5477 4256 ASSERT(chopprefix > drrb->drr_toname || strchr(sendfs, '/') == NULL);
4257 ASSERT(chopprefix <= drrb->drr_toname + strlen(drrb->drr_toname) ||
4258 strchr(sendfs, '/') == NULL);
428870ff
BB
4259 ASSERT(chopprefix[0] == '/' || chopprefix[0] == '@' ||
4260 chopprefix[0] == '\0');
34dc7c2f
BB
4261
4262 /*
43e52edd 4263 * Determine name of destination snapshot.
34dc7c2f 4264 */
45cb520b 4265 (void) strlcpy(destsnap, tosnap, sizeof (destsnap));
43e52edd 4266 (void) strlcat(destsnap, chopprefix, sizeof (destsnap));
428870ff 4267 free(cp);
43e52edd
BB
4268 if (!zfs_name_valid(destsnap, ZFS_TYPE_SNAPSHOT)) {
4269 err = zfs_error(hdl, EZFS_INVALIDNAME, errbuf);
4270 goto out;
34dc7c2f
BB
4271 }
4272
4273 /*
43e52edd 4274 * Determine the name of the origin snapshot.
34dc7c2f 4275 */
160af771 4276 if (originsnap) {
21a4f5cc 4277 (void) strlcpy(origin, originsnap, sizeof (origin));
160af771
GM
4278 if (flags->verbose)
4279 (void) printf("using provided clone origin %s\n",
4280 origin);
4281 } else if (drrb->drr_flags & DRR_FLAG_CLONE) {
43e52edd
BB
4282 if (guid_to_name(hdl, destsnap,
4283 drrb->drr_fromguid, B_FALSE, origin) != 0) {
34dc7c2f
BB
4284 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
4285 "local origin for clone %s does not exist"),
43e52edd
BB
4286 destsnap);
4287 err = zfs_error(hdl, EZFS_NOENT, errbuf);
4288 goto out;
34dc7c2f 4289 }
330d06f9 4290 if (flags->verbose)
43e52edd 4291 (void) printf("found clone origin %s\n", origin);
34dc7c2f
BB
4292 }
4293
196bee4c 4294 if ((DMU_GET_FEATUREFLAGS(drrb->drr_versioninfo) &
652bdc9b
MA
4295 DMU_BACKUP_FEATURE_DEDUP)) {
4296 (void) fprintf(stderr,
196bee4c
MA
4297 gettext("ERROR: \"zfs receive\" no longer supports "
4298 "deduplicated send streams. Use\n"
4299 "the \"zstream redup\" command to convert this stream "
4300 "to a regular,\n"
4301 "non-deduplicated stream.\n"));
4302 err = zfs_error(hdl, EZFS_NOTSUP, errbuf);
4303 goto out;
652bdc9b
MA
4304 }
4305
47dfff3b
MA
4306 boolean_t resuming = DMU_GET_FEATUREFLAGS(drrb->drr_versioninfo) &
4307 DMU_BACKUP_FEATURE_RESUMING;
b5256303
TC
4308 boolean_t raw = DMU_GET_FEATUREFLAGS(drrb->drr_versioninfo) &
4309 DMU_BACKUP_FEATURE_RAW;
9b840763
TC
4310 boolean_t embedded = DMU_GET_FEATUREFLAGS(drrb->drr_versioninfo) &
4311 DMU_BACKUP_FEATURE_EMBED_DATA;
b8864a23 4312 stream_wantsnewfs = (drrb->drr_fromguid == 0 ||
47dfff3b 4313 (drrb->drr_flags & DRR_FLAG_CLONE) || originsnap) && !resuming;
a132c2b4
AS
4314 stream_resumingnewfs = (drrb->drr_fromguid == 0 ||
4315 (drrb->drr_flags & DRR_FLAG_CLONE) || originsnap) && resuming;
34dc7c2f
BB
4316
4317 if (stream_wantsnewfs) {
4318 /*
4319 * if the parent fs does not exist, look for it based on
4320 * the parent snap GUID
4321 */
4322 (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
4323 "cannot receive new filesystem stream"));
4324
43e52edd
BB
4325 (void) strcpy(name, destsnap);
4326 cp = strrchr(name, '/');
34dc7c2f
BB
4327 if (cp)
4328 *cp = '\0';
4329 if (cp &&
43e52edd 4330 !zfs_dataset_exists(hdl, name, ZFS_TYPE_DATASET)) {
eca7b760 4331 char suffix[ZFS_MAX_DATASET_NAME_LEN];
43e52edd
BB
4332 (void) strcpy(suffix, strrchr(destsnap, '/'));
4333 if (guid_to_name(hdl, name, parent_snapguid,
4334 B_FALSE, destsnap) == 0) {
4335 *strchr(destsnap, '@') = '\0';
4336 (void) strcat(destsnap, suffix);
34dc7c2f
BB
4337 }
4338 }
4339 } else {
4340 /*
ebeb6f23
AG
4341 * If the fs does not exist, look for it based on the
4342 * fromsnap GUID.
34dc7c2f 4343 */
ebeb6f23
AG
4344 if (resuming) {
4345 (void) snprintf(errbuf, sizeof (errbuf),
4346 dgettext(TEXT_DOMAIN,
4347 "cannot receive resume stream"));
4348 } else {
4349 (void) snprintf(errbuf, sizeof (errbuf),
4350 dgettext(TEXT_DOMAIN,
4351 "cannot receive incremental stream"));
4352 }
34dc7c2f 4353
43e52edd
BB
4354 (void) strcpy(name, destsnap);
4355 *strchr(name, '@') = '\0';
34dc7c2f 4356
428870ff
BB
4357 /*
4358 * If the exact receive path was specified and this is the
4359 * topmost path in the stream, then if the fs does not exist we
4360 * should look no further.
4361 */
330d06f9 4362 if ((flags->isprefix || (*(chopprefix = drrb->drr_toname +
428870ff 4363 strlen(sendfs)) != '\0' && *chopprefix != '@')) &&
43e52edd 4364 !zfs_dataset_exists(hdl, name, ZFS_TYPE_DATASET)) {
eca7b760 4365 char snap[ZFS_MAX_DATASET_NAME_LEN];
43e52edd
BB
4366 (void) strcpy(snap, strchr(destsnap, '@'));
4367 if (guid_to_name(hdl, name, drrb->drr_fromguid,
4368 B_FALSE, destsnap) == 0) {
4369 *strchr(destsnap, '@') = '\0';
4370 (void) strcat(destsnap, snap);
34dc7c2f
BB
4371 }
4372 }
4373 }
4374
43e52edd
BB
4375 (void) strcpy(name, destsnap);
4376 *strchr(name, '@') = '\0';
34dc7c2f 4377
30af21b0
PD
4378 redacted = DMU_GET_FEATUREFLAGS(drrb->drr_versioninfo) &
4379 DMU_BACKUP_FEATURE_REDACTED;
4380
43e52edd
BB
4381 if (zfs_dataset_exists(hdl, name, ZFS_TYPE_DATASET)) {
4382 zfs_cmd_t zc = {"\0"};
34dc7c2f 4383 zfs_handle_t *zhp;
4a385862 4384 boolean_t encrypted;
428870ff 4385
43e52edd
BB
4386 (void) strcpy(zc.zc_name, name);
4387
34dc7c2f 4388 /*
47dfff3b
MA
4389 * Destination fs exists. It must be one of these cases:
4390 * - an incremental send stream
4391 * - the stream specifies a new fs (full stream or clone)
4392 * and they want us to blow away the existing fs (and
4393 * have therefore specified -F and removed any snapshots)
4394 * - we are resuming a failed receive.
34dc7c2f 4395 */
34dc7c2f 4396 if (stream_wantsnewfs) {
d8d418ff 4397 boolean_t is_volume = drrb->drr_type == DMU_OST_ZVOL;
330d06f9 4398 if (!flags->force) {
34dc7c2f
BB
4399 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
4400 "destination '%s' exists\n"
43e52edd
BB
4401 "must specify -F to overwrite it"), name);
4402 err = zfs_error(hdl, EZFS_EXISTS, errbuf);
4403 goto out;
34dc7c2f 4404 }
b834b58a 4405 if (zfs_ioctl(hdl, ZFS_IOC_SNAPSHOT_LIST_NEXT,
34dc7c2f 4406 &zc) == 0) {
34dc7c2f
BB
4407 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
4408 "destination has snapshots (eg. %s)\n"
4409 "must destroy them to overwrite it"),
b53cb02d 4410 zc.zc_name);
43e52edd
BB
4411 err = zfs_error(hdl, EZFS_EXISTS, errbuf);
4412 goto out;
34dc7c2f 4413 }
d8d418ff 4414 if (is_volume && strrchr(name, '/') == NULL) {
4415 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
4416 "destination %s is the root dataset\n"
4417 "cannot overwrite with a ZVOL"),
4418 name);
4419 err = zfs_error(hdl, EZFS_EXISTS, errbuf);
4420 goto out;
4421 }
4422 if (is_volume &&
b834b58a 4423 zfs_ioctl(hdl, ZFS_IOC_DATASET_LIST_NEXT,
d8d418ff 4424 &zc) == 0) {
4425 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
4426 "destination has children (eg. %s)\n"
4427 "cannot overwrite with a ZVOL"),
4428 zc.zc_name);
4429 err = zfs_error(hdl, EZFS_WRONG_PARENT, errbuf);
4430 goto out;
4431 }
34dc7c2f
BB
4432 }
4433
43e52edd 4434 if ((zhp = zfs_open(hdl, name,
34dc7c2f 4435 ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME)) == NULL) {
43e52edd
BB
4436 err = -1;
4437 goto out;
34dc7c2f
BB
4438 }
4439
4440 if (stream_wantsnewfs &&
4441 zhp->zfs_dmustats.dds_origin[0]) {
34dc7c2f
BB
4442 zfs_close(zhp);
4443 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
4444 "destination '%s' is a clone\n"
43e52edd
BB
4445 "must destroy it to overwrite it"), name);
4446 err = zfs_error(hdl, EZFS_EXISTS, errbuf);
4447 goto out;
34dc7c2f
BB
4448 }
4449
b5256303 4450 /*
4a385862 4451 * Raw sends can not be performed as an incremental on top
78595377 4452 * of existing unencrypted datasets. zfs recv -F can't be
4a385862
TC
4453 * used to blow away an existing encrypted filesystem. This
4454 * is because it would require the dsl dir to point to the
4455 * new key (or lack of a key) and the old key at the same
4456 * time. The -F flag may still be used for deleting
4457 * intermediate snapshots that would otherwise prevent the
4458 * receive from working.
b5256303 4459 */
4a385862
TC
4460 encrypted = zfs_prop_get_int(zhp, ZFS_PROP_ENCRYPTION) !=
4461 ZIO_CRYPT_OFF;
4462 if (!stream_wantsnewfs && !encrypted && raw) {
b5256303
TC
4463 zfs_close(zhp);
4464 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
4a385862
TC
4465 "cannot perform raw receive on top of "
4466 "existing unencrypted dataset"));
b5256303
TC
4467 err = zfs_error(hdl, EZFS_BADRESTORE, errbuf);
4468 goto out;
4469 }
4470
4a385862
TC
4471 if (stream_wantsnewfs && flags->force &&
4472 ((raw && !encrypted) || encrypted)) {
4473 zfs_close(zhp);
4474 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
4475 "zfs receive -F cannot be used to destroy an "
4476 "encrypted filesystem or overwrite an "
4477 "unencrypted one with an encrypted one"));
4478 err = zfs_error(hdl, EZFS_BADRESTORE, errbuf);
4479 goto out;
4480 }
b5256303 4481
330d06f9 4482 if (!flags->dryrun && zhp->zfs_type == ZFS_TYPE_FILESYSTEM &&
a132c2b4 4483 (stream_wantsnewfs || stream_resumingnewfs)) {
34dc7c2f 4484 /* We can't do online recv in this case */
a57d3d45
MZ
4485 clp = changelist_gather(zhp, ZFS_PROP_NAME, 0,
4486 flags->forceunmount ? MS_FORCE : 0);
34dc7c2f 4487 if (clp == NULL) {
45d1cae3 4488 zfs_close(zhp);
43e52edd
BB
4489 err = -1;
4490 goto out;
34dc7c2f
BB
4491 }
4492 if (changelist_prefix(clp) != 0) {
4493 changelist_free(clp);
45d1cae3 4494 zfs_close(zhp);
43e52edd
BB
4495 err = -1;
4496 goto out;
34dc7c2f
BB
4497 }
4498 }
47dfff3b
MA
4499
4500 /*
4501 * If we are resuming a newfs, set newfs here so that we will
4502 * mount it if the recv succeeds this time. We can tell
4503 * that it was a newfs on the first recv because the fs
4504 * itself will be inconsistent (if the fs existed when we
4505 * did the first recv, we would have received it into
4506 * .../%recv).
4507 */
4508 if (resuming && zfs_prop_get_int(zhp, ZFS_PROP_INCONSISTENT))
4509 newfs = B_TRUE;
4510
a3eeab2d 4511 /* we want to know if we're zoned when validating -o|-x props */
4512 zoned = zfs_prop_get_int(zhp, ZFS_PROP_ZONED);
4513
c03f0470 4514 /* may need this info later, get it now we have zhp around */
4515 if (zfs_prop_get(zhp, ZFS_PROP_RECEIVE_RESUME_TOKEN, NULL, 0,
4516 NULL, NULL, 0, B_TRUE) == 0)
4517 hastoken = B_TRUE;
4518
a3eeab2d 4519 /* gather existing properties on destination */
4520 origprops = fnvlist_alloc();
4521 fnvlist_merge(origprops, zhp->zfs_props);
4522 fnvlist_merge(origprops, zhp->zfs_user_props);
4523
34dc7c2f
BB
4524 zfs_close(zhp);
4525 } else {
b5256303
TC
4526 zfs_handle_t *zhp;
4527
34dc7c2f
BB
4528 /*
4529 * Destination filesystem does not exist. Therefore we better
4530 * be creating a new filesystem (either from a full backup, or
4531 * a clone). It would therefore be invalid if the user
4532 * specified only the pool name (i.e. if the destination name
4533 * contained no slash character).
4534 */
a64f903b
GN
4535 cp = strrchr(name, '/');
4536
4537 if (!stream_wantsnewfs || cp == NULL) {
34dc7c2f 4538 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
43e52edd
BB
4539 "destination '%s' does not exist"), name);
4540 err = zfs_error(hdl, EZFS_NOENT, errbuf);
4541 goto out;
34dc7c2f
BB
4542 }
4543
4544 /*
4545 * Trim off the final dataset component so we perform the
4546 * recvbackup ioctl to the filesystems's parent.
4547 */
4548 *cp = '\0';
4549
330d06f9 4550 if (flags->isprefix && !flags->istail && !flags->dryrun &&
43e52edd
BB
4551 create_parents(hdl, destsnap, strlen(tosnap)) != 0) {
4552 err = zfs_error(hdl, EZFS_BADRESTORE, errbuf);
4553 goto out;
34dc7c2f
BB
4554 }
4555
d8d418ff 4556 /* validate parent */
4557 zhp = zfs_open(hdl, name, ZFS_TYPE_DATASET);
4558 if (zhp == NULL) {
4559 err = zfs_error(hdl, EZFS_BADRESTORE, errbuf);
4560 goto out;
4561 }
4562 if (zfs_get_type(zhp) != ZFS_TYPE_FILESYSTEM) {
4563 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
4564 "parent '%s' is not a filesystem"), name);
4565 err = zfs_error(hdl, EZFS_WRONG_PARENT, errbuf);
4566 zfs_close(zhp);
4567 goto out;
4568 }
4569
d8d418ff 4570 zfs_close(zhp);
b5256303 4571
34dc7c2f 4572 newfs = B_TRUE;
b5256303 4573 *cp = '/';
34dc7c2f
BB
4574 }
4575
330d06f9 4576 if (flags->verbose) {
34dc7c2f 4577 (void) printf("%s %s stream of %s into %s\n",
330d06f9 4578 flags->dryrun ? "would receive" : "receiving",
34dc7c2f 4579 drrb->drr_fromguid ? "incremental" : "full",
43e52edd 4580 drrb->drr_toname, destsnap);
34dc7c2f
BB
4581 (void) fflush(stdout);
4582 }
4583
bb61cc31
TC
4584 /*
4585 * If this is the top-level dataset, record it so we can use it
4586 * for recursive operations later.
4587 */
4588 if (top_zfs != NULL &&
4589 (*top_zfs == NULL || strcmp(*top_zfs, name) == 0)) {
bee7e4ff 4590 toplevel = B_TRUE;
bb61cc31
TC
4591 if (*top_zfs == NULL)
4592 *top_zfs = zfs_strdup(hdl, name);
4593 }
4594
a3eeab2d 4595 if (drrb->drr_type == DMU_OST_ZVOL) {
4596 type = ZFS_TYPE_VOLUME;
4597 } else if (drrb->drr_type == DMU_OST_ZFS) {
4598 type = ZFS_TYPE_FILESYSTEM;
4599 } else {
4600 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
4601 "invalid record type: 0x%d"), drrb->drr_type);
4602 err = zfs_error(hdl, EZFS_BADSTREAM, errbuf);
4603 goto out;
4604 }
d9c460a0
TC
4605 if ((err = zfs_setup_cmdline_props(hdl, type, name, zoned, recursive,
4606 stream_wantsnewfs, raw, toplevel, rcvprops, cmdprops, origprops,
4607 &oxprops, &wkeydata, &wkeylen, errbuf)) != 0)
a3eeab2d 4608 goto out;
4609
da689887
TC
4610 /*
4611 * When sending with properties (zfs send -p), the encryption property
4612 * is not included because it is a SETONCE property and therefore
4613 * treated as read only. However, we are always able to determine its
4614 * value because raw sends will include it in the DRR_BDEGIN payload
4615 * and non-raw sends with properties are not allowed for encrypted
4616 * datasets. Therefore, if this is a non-raw properties stream, we can
4617 * infer that the value should be ZIO_CRYPT_OFF and manually add that
4618 * to the received properties.
4619 */
4620 if (stream_wantsnewfs && !raw && rcvprops != NULL &&
4621 !nvlist_exists(cmdprops, zfs_prop_to_name(ZFS_PROP_ENCRYPTION))) {
4622 if (oxprops == NULL)
4623 oxprops = fnvlist_alloc();
4624 fnvlist_add_uint64(oxprops,
4625 zfs_prop_to_name(ZFS_PROP_ENCRYPTION), ZIO_CRYPT_OFF);
4626 }
4627
ee6615e0
I
4628 if (flags->dryrun) {
4629 void *buf = zfs_alloc(hdl, SPA_MAXBLOCKSIZE);
4630
4631 /*
4632 * We have read the DRR_BEGIN record, but we have
4633 * not yet read the payload. For non-dryrun sends
4634 * this will be done by the kernel, so we must
4635 * emulate that here, before attempting to read
4636 * more records.
4637 */
4638 err = recv_read(hdl, infd, buf, drr->drr_payloadlen,
4639 flags->byteswap, NULL);
4640 free(buf);
4641 if (err != 0)
4642 goto out;
4643
4644 err = recv_skip(hdl, infd, flags->byteswap);
4645 goto out;
4646 }
4647
d9c460a0
TC
4648 err = ioctl_err = lzc_receive_with_cmdprops(destsnap, rcvprops,
4649 oxprops, wkeydata, wkeylen, origin, flags->force, flags->resumable,
196bee4c
MA
4650 raw, infd, drr_noswap, -1, &read_bytes, &errflags,
4651 NULL, &prop_errors);
43e52edd
BB
4652 ioctl_errno = ioctl_err;
4653 prop_errflags = errflags;
428870ff
BB
4654
4655 if (err == 0) {
428870ff
BB
4656 nvpair_t *prop_err = NULL;
4657
4658 while ((prop_err = nvlist_next_nvpair(prop_errors,
4659 prop_err)) != NULL) {
4660 char tbuf[1024];
4661 zfs_prop_t prop;
4662 int intval;
4663
4664 prop = zfs_name_to_prop(nvpair_name(prop_err));
4665 (void) nvpair_value_int32(prop_err, &intval);
4666 if (strcmp(nvpair_name(prop_err),
4667 ZPROP_N_MORE_ERRORS) == 0) {
4668 trunc_prop_errs(intval);
4669 break;
671c9354
DM
4670 } else if (snapname == NULL || finalsnap == NULL ||
4671 strcmp(finalsnap, snapname) == 0 ||
4672 strcmp(nvpair_name(prop_err),
4673 zfs_prop_to_name(ZFS_PROP_REFQUOTA)) != 0) {
4674 /*
4675 * Skip the special case of, for example,
4676 * "refquota", errors on intermediate
4677 * snapshots leading up to a final one.
4678 * That's why we have all of the checks above.
4679 *
4680 * See zfs_ioctl.c's extract_delay_props() for
4681 * a list of props which can fail on
4682 * intermediate snapshots, but shouldn't
4683 * affect the overall receive.
4684 */
428870ff
BB
4685 (void) snprintf(tbuf, sizeof (tbuf),
4686 dgettext(TEXT_DOMAIN,
4687 "cannot receive %s property on %s"),
43e52edd 4688 nvpair_name(prop_err), name);
428870ff
BB
4689 zfs_setprop_error(hdl, prop, intval, tbuf);
4690 }
4691 }
428870ff
BB
4692 }
4693
b128c09f 4694 if (err == 0 && snapprops_nvlist) {
43e52edd 4695 zfs_cmd_t zc = {"\0"};
b128c09f 4696
43e52edd
BB
4697 (void) strcpy(zc.zc_name, destsnap);
4698 zc.zc_cookie = B_TRUE; /* received */
4699 if (zcmd_write_src_nvlist(hdl, &zc, snapprops_nvlist) == 0) {
4700 (void) zfs_ioctl(hdl, ZFS_IOC_SET_PROP, &zc);
4701 zcmd_free_nvlists(&zc);
b128c09f
BB
4702 }
4703 }
9c5e88b1
PZ
4704 if (err == 0 && snapholds_nvlist) {
4705 nvpair_t *pair;
4706 nvlist_t *holds, *errors = NULL;
4707 int cleanup_fd = -1;
4708
4709 VERIFY(0 == nvlist_alloc(&holds, 0, KM_SLEEP));
4710 for (pair = nvlist_next_nvpair(snapholds_nvlist, NULL);
4711 pair != NULL;
4712 pair = nvlist_next_nvpair(snapholds_nvlist, pair)) {
60a2434b 4713 fnvlist_add_string(holds, destsnap, nvpair_name(pair));
9c5e88b1
PZ
4714 }
4715 (void) lzc_hold(holds, cleanup_fd, &errors);
60a2434b
RM
4716 fnvlist_free(snapholds_nvlist);
4717 fnvlist_free(holds);
9c5e88b1 4718 }
b128c09f 4719
428870ff 4720 if (err && (ioctl_errno == ENOENT || ioctl_errno == EEXIST)) {
34dc7c2f
BB
4721 /*
4722 * It may be that this snapshot already exists,
4723 * in which case we want to consume & ignore it
4724 * rather than failing.
4725 */
4726 avl_tree_t *local_avl;
4727 nvlist_t *local_nv, *fs;
43e52edd 4728 cp = strchr(destsnap, '@');
34dc7c2f
BB
4729
4730 /*
4731 * XXX Do this faster by just iterating over snaps in
4732 * this fs. Also if zc_value does not exist, we will
4733 * get a strange "does not exist" error message.
4734 */
4735 *cp = '\0';
b5256303 4736 if (gather_nvlist(hdl, destsnap, NULL, NULL, B_FALSE, B_TRUE,
099fa7e4
PCG
4737 B_FALSE, B_FALSE, B_FALSE, B_FALSE, B_FALSE, B_FALSE,
4738 B_TRUE, &local_nv, &local_avl) == 0) {
34dc7c2f
BB
4739 *cp = '@';
4740 fs = fsavl_find(local_avl, drrb->drr_toguid, NULL);
4741 fsavl_destroy(local_avl);
60a2434b 4742 fnvlist_free(local_nv);
34dc7c2f
BB
4743
4744 if (fs != NULL) {
330d06f9 4745 if (flags->verbose) {
34dc7c2f 4746 (void) printf("snap %s already exists; "
43e52edd 4747 "ignoring\n", destsnap);
34dc7c2f 4748 }
428870ff 4749 err = ioctl_err = recv_skip(hdl, infd,
330d06f9 4750 flags->byteswap);
34dc7c2f
BB
4751 }
4752 }
4753 *cp = '@';
4754 }
4755
34dc7c2f
BB
4756 if (ioctl_err != 0) {
4757 switch (ioctl_errno) {
4758 case ENODEV:
43e52edd 4759 cp = strchr(destsnap, '@');
34dc7c2f
BB
4760 *cp = '\0';
4761 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
4762 "most recent snapshot of %s does not\n"
43e52edd 4763 "match incremental source"), destsnap);
34dc7c2f
BB
4764 (void) zfs_error(hdl, EZFS_BADRESTORE, errbuf);
4765 *cp = '@';
4766 break;
4767 case ETXTBSY:
4768 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
4769 "destination %s has been modified\n"
43e52edd 4770 "since most recent snapshot"), name);
34dc7c2f
BB
4771 (void) zfs_error(hdl, EZFS_BADRESTORE, errbuf);
4772 break;
b5256303
TC
4773 case EACCES:
4774 if (raw && stream_wantsnewfs) {
4775 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
4776 "failed to create encryption key"));
4777 } else if (raw && !stream_wantsnewfs) {
4778 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
4779 "encryption key does not match "
4780 "existing key"));
4781 } else {
4782 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
4783 "inherited key must be loaded"));
4784 }
4785 (void) zfs_error(hdl, EZFS_CRYPTOFAILED, errbuf);
4786 break;
34dc7c2f 4787 case EEXIST:
43e52edd 4788 cp = strchr(destsnap, '@');
34dc7c2f
BB
4789 if (newfs) {
4790 /* it's the containing fs that exists */
4791 *cp = '\0';
4792 }
4793 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
4794 "destination already exists"));
4795 (void) zfs_error_fmt(hdl, EZFS_EXISTS,
4796 dgettext(TEXT_DOMAIN, "cannot restore to %s"),
43e52edd 4797 destsnap);
34dc7c2f
BB
4798 *cp = '@';
4799 break;
4800 case EINVAL:
2ba59fa9 4801 if (flags->resumable) {
43e52edd
BB
4802 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
4803 "kernel modules must be upgraded to "
4804 "receive this stream."));
2ba59fa9 4805 } else if (embedded && !raw) {
9b840763
TC
4806 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
4807 "incompatible embedded data stream "
4808 "feature with encrypted receive."));
2ba59fa9 4809 }
34dc7c2f
BB
4810 (void) zfs_error(hdl, EZFS_BADSTREAM, errbuf);
4811 break;
4812 case ECKSUM:
7145123b
PD
4813 case ZFS_ERR_STREAM_TRUNCATED:
4814 recv_ecksum_set_aux(hdl, destsnap, flags->resumable,
4815 ioctl_err == ECKSUM);
34dc7c2f
BB
4816 (void) zfs_error(hdl, EZFS_BADSTREAM, errbuf);
4817 break;
7bcb7f08
MA
4818 case ZFS_ERR_STREAM_LARGE_BLOCK_MISMATCH:
4819 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
4820 "incremental send stream requires -L "
4821 "(--large-block), to match previous receive."));
4822 (void) zfs_error(hdl, EZFS_BADSTREAM, errbuf);
4823 break;
428870ff
BB
4824 case ENOTSUP:
4825 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
4826 "pool must be upgraded to receive this stream."));
4827 (void) zfs_error(hdl, EZFS_BADVERSION, errbuf);
4828 break;
4829 case EDQUOT:
4830 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
c03f0470 4831 "destination %s space quota exceeded."), name);
330d06f9 4832 (void) zfs_error(hdl, EZFS_NOSPC, errbuf);
428870ff 4833 break;
f00ab3f2
TC
4834 case ZFS_ERR_FROM_IVSET_GUID_MISSING:
4835 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
73c25a78 4836 "IV set guid missing. See errata %u at "
a2f944a1
RM
4837 "https://openzfs.github.io/openzfs-docs/msg/"
4838 "ZFS-8000-ER."),
f00ab3f2
TC
4839 ZPOOL_ERRATA_ZOL_8308_ENCRYPTION);
4840 (void) zfs_error(hdl, EZFS_BADSTREAM, errbuf);
4841 break;
4842 case ZFS_ERR_FROM_IVSET_GUID_MISMATCH:
4843 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
4844 "IV set guid mismatch. See the 'zfs receive' "
4845 "man page section\n discussing the limitations "
4846 "of raw encrypted send streams."));
4847 (void) zfs_error(hdl, EZFS_BADSTREAM, errbuf);
4848 break;
caf9dd20
BB
4849 case ZFS_ERR_SPILL_BLOCK_FLAG_MISSING:
4850 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
4851 "Spill block flag missing for raw send.\n"
4852 "The zfs software on the sending system must "
4853 "be updated."));
4854 (void) zfs_error(hdl, EZFS_BADSTREAM, errbuf);
4855 break;
c03f0470 4856 case EBUSY:
4857 if (hastoken) {
4858 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
4859 "destination %s contains "
4860 "partially-complete state from "
4861 "\"zfs receive -s\"."), name);
4862 (void) zfs_error(hdl, EZFS_BUSY, errbuf);
4863 break;
4864 }
4865 /* fallthru */
34dc7c2f
BB
4866 default:
4867 (void) zfs_standard_error(hdl, ioctl_errno, errbuf);
4868 }
4869 }
4870
4871 /*
428870ff
BB
4872 * Mount the target filesystem (if created). Also mount any
4873 * children of the target filesystem if we did a replication
4874 * receive (indicated by stream_avl being non-NULL).
34dc7c2f 4875 */
34dc7c2f 4876 if (clp) {
89d43feb
GM
4877 if (!flags->nomount)
4878 err |= changelist_postfix(clp);
34dc7c2f
BB
4879 changelist_free(clp);
4880 }
4881
bb61cc31
TC
4882 if ((newfs || stream_avl) && type == ZFS_TYPE_FILESYSTEM && !redacted)
4883 flags->domount = B_TRUE;
4884
428870ff
BB
4885 if (prop_errflags & ZPROP_ERR_NOCLEAR) {
4886 (void) fprintf(stderr, dgettext(TEXT_DOMAIN, "Warning: "
43e52edd 4887 "failed to clear unreceived properties on %s"), name);
428870ff
BB
4888 (void) fprintf(stderr, "\n");
4889 }
4890 if (prop_errflags & ZPROP_ERR_NORESTORE) {
4891 (void) fprintf(stderr, dgettext(TEXT_DOMAIN, "Warning: "
43e52edd 4892 "failed to restore original properties on %s"), name);
428870ff
BB
4893 (void) fprintf(stderr, "\n");
4894 }
4895
43e52edd
BB
4896 if (err || ioctl_err) {
4897 err = -1;
4898 goto out;
4899 }
572e2857 4900
330d06f9 4901 if (flags->verbose) {
34dc7c2f
BB
4902 char buf1[64];
4903 char buf2[64];
43e52edd 4904 uint64_t bytes = read_bytes;
34dc7c2f
BB
4905 time_t delta = time(NULL) - begin_time;
4906 if (delta == 0)
4907 delta = 1;
e7fbeb60 4908 zfs_nicebytes(bytes, buf1, sizeof (buf1));
4909 zfs_nicebytes(bytes/delta, buf2, sizeof (buf1));
34dc7c2f 4910
a1ba1209
AZ
4911 (void) printf("received %s stream in %lld seconds (%s/sec)\n",
4912 buf1, (longlong_t)delta, buf2);
34dc7c2f
BB
4913 }
4914
43e52edd
BB
4915 err = 0;
4916out:
4917 if (prop_errors != NULL)
60a2434b 4918 fnvlist_free(prop_errors);
43e52edd 4919
b5256303 4920 if (tmp_keylocation[0] != '\0') {
60a2434b
RM
4921 fnvlist_add_string(rcvprops,
4922 zfs_prop_to_name(ZFS_PROP_KEYLOCATION), tmp_keylocation);
b5256303
TC
4923 }
4924
43e52edd 4925 if (newprops)
60a2434b 4926 fnvlist_free(rcvprops);
a3eeab2d 4927
60a2434b
RM
4928 fnvlist_free(oxprops);
4929 fnvlist_free(origprops);
43e52edd
BB
4930
4931 return (err);
34dc7c2f
BB
4932}
4933
a3eeab2d 4934/*
4935 * Check properties we were asked to override (both -o|-x)
4936 */
4937static boolean_t
4938zfs_receive_checkprops(libzfs_handle_t *hdl, nvlist_t *props,
4939 const char *errbuf)
4940{
4941 nvpair_t *nvp;
4942 zfs_prop_t prop;
4943 const char *name;
4944
4945 nvp = NULL;
4946 while ((nvp = nvlist_next_nvpair(props, nvp)) != NULL) {
4947 name = nvpair_name(nvp);
4948 prop = zfs_name_to_prop(name);
4949
4950 if (prop == ZPROP_INVAL) {
4951 if (!zfs_prop_user(name)) {
4952 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
4953 "invalid property '%s'"), name);
4954 return (B_FALSE);
4955 }
4956 continue;
4957 }
4958 /*
4959 * "origin" is readonly but is used to receive datasets as
4960 * clones so we don't raise an error here
4961 */
4962 if (prop == ZFS_PROP_ORIGIN)
4963 continue;
4964
d9c460a0
TC
4965 /* encryption params have their own verification later */
4966 if (prop == ZFS_PROP_ENCRYPTION ||
4967 zfs_prop_encryption_key_param(prop))
4968 continue;
4969
a3eeab2d 4970 /*
4971 * cannot override readonly, set-once and other specific
4972 * settable properties
4973 */
4974 if (zfs_prop_readonly(prop) || prop == ZFS_PROP_VERSION ||
4975 prop == ZFS_PROP_VOLSIZE) {
4976 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
4977 "invalid property '%s'"), name);
4978 return (B_FALSE);
4979 }
4980 }
4981
4982 return (B_TRUE);
4983}
4984
b128c09f 4985static int
fcff0f35
PD
4986zfs_receive_impl(libzfs_handle_t *hdl, const char *tosnap,
4987 const char *originsnap, recvflags_t *flags, int infd, const char *sendfs,
196bee4c
MA
4988 nvlist_t *stream_nv, avl_tree_t *stream_avl, char **top_zfs,
4989 const char *finalsnap, nvlist_t *cmdprops)
34dc7c2f
BB
4990{
4991 int err;
4992 dmu_replay_record_t drr, drr_noswap;
4993 struct drr_begin *drrb = &drr.drr_u.drr_begin;
4994 char errbuf[1024];
2598c001 4995 zio_cksum_t zcksum = { { 0 } };
428870ff
BB
4996 uint64_t featureflags;
4997 int hdrtype;
34dc7c2f
BB
4998
4999 (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
5000 "cannot receive"));
5001
a3eeab2d 5002 /* check cmdline props, raise an error if they cannot be received */
5003 if (!zfs_receive_checkprops(hdl, cmdprops, errbuf)) {
5004 return (zfs_error(hdl, EZFS_BADPROP, errbuf));
5005 }
5006
330d06f9 5007 if (flags->isprefix &&
34dc7c2f
BB
5008 !zfs_dataset_exists(hdl, tosnap, ZFS_TYPE_DATASET)) {
5009 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "specified fs "
5010 "(%s) does not exist"), tosnap);
5011 return (zfs_error(hdl, EZFS_NOENT, errbuf));
5012 }
fcff0f35
PD
5013 if (originsnap &&
5014 !zfs_dataset_exists(hdl, originsnap, ZFS_TYPE_DATASET)) {
5015 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "specified origin fs "
5016 "(%s) does not exist"), originsnap);
5017 return (zfs_error(hdl, EZFS_NOENT, errbuf));
5018 }
34dc7c2f
BB
5019
5020 /* read in the BEGIN record */
5021 if (0 != (err = recv_read(hdl, infd, &drr, sizeof (drr), B_FALSE,
5022 &zcksum)))
5023 return (err);
5024
5025 if (drr.drr_type == DRR_END || drr.drr_type == BSWAP_32(DRR_END)) {
5026 /* It's the double end record at the end of a package */
5027 return (ENODATA);
5028 }
5029
5030 /* the kernel needs the non-byteswapped begin record */
5031 drr_noswap = drr;
5032
330d06f9 5033 flags->byteswap = B_FALSE;
34dc7c2f
BB
5034 if (drrb->drr_magic == BSWAP_64(DMU_BACKUP_MAGIC)) {
5035 /*
5036 * We computed the checksum in the wrong byteorder in
5037 * recv_read() above; do it again correctly.
5038 */
5039 bzero(&zcksum, sizeof (zio_cksum_t));
5040 fletcher_4_incremental_byteswap(&drr, sizeof (drr), &zcksum);
330d06f9 5041 flags->byteswap = B_TRUE;
34dc7c2f
BB
5042
5043 drr.drr_type = BSWAP_32(drr.drr_type);
5044 drr.drr_payloadlen = BSWAP_32(drr.drr_payloadlen);
5045 drrb->drr_magic = BSWAP_64(drrb->drr_magic);
428870ff 5046 drrb->drr_versioninfo = BSWAP_64(drrb->drr_versioninfo);
34dc7c2f
BB
5047 drrb->drr_creation_time = BSWAP_64(drrb->drr_creation_time);
5048 drrb->drr_type = BSWAP_32(drrb->drr_type);
5049 drrb->drr_flags = BSWAP_32(drrb->drr_flags);
5050 drrb->drr_toguid = BSWAP_64(drrb->drr_toguid);
5051 drrb->drr_fromguid = BSWAP_64(drrb->drr_fromguid);
5052 }
5053
5054 if (drrb->drr_magic != DMU_BACKUP_MAGIC || drr.drr_type != DRR_BEGIN) {
5055 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "invalid "
5056 "stream (bad magic number)"));
5057 return (zfs_error(hdl, EZFS_BADSTREAM, errbuf));
5058 }
5059
428870ff
BB
5060 featureflags = DMU_GET_FEATUREFLAGS(drrb->drr_versioninfo);
5061 hdrtype = DMU_GET_STREAM_HDRTYPE(drrb->drr_versioninfo);
5062
5063 if (!DMU_STREAM_SUPPORTED(featureflags) ||
5064 (hdrtype != DMU_SUBSTREAM && hdrtype != DMU_COMPOUNDSTREAM)) {
5065 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
f00f4690
AZ
5066 "stream has unsupported feature, feature flags = %llx"),
5067 (unsigned long long)featureflags);
428870ff
BB
5068 return (zfs_error(hdl, EZFS_BADSTREAM, errbuf));
5069 }
5070
9c5e88b1 5071 /* Holds feature is set once in the compound stream header. */
c618f87c 5072 if (featureflags & DMU_BACKUP_FEATURE_HOLDS)
9c5e88b1
PZ
5073 flags->holds = B_TRUE;
5074
34dc7c2f
BB
5075 if (strchr(drrb->drr_toname, '@') == NULL) {
5076 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "invalid "
5077 "stream (bad snapshot name)"));
5078 return (zfs_error(hdl, EZFS_BADSTREAM, errbuf));
5079 }
5080
428870ff 5081 if (DMU_GET_STREAM_HDRTYPE(drrb->drr_versioninfo) == DMU_SUBSTREAM) {
eca7b760 5082 char nonpackage_sendfs[ZFS_MAX_DATASET_NAME_LEN];
428870ff
BB
5083 if (sendfs == NULL) {
5084 /*
5085 * We were not called from zfs_receive_package(). Get
5086 * the fs specified by 'zfs send'.
5087 */
5088 char *cp;
5089 (void) strlcpy(nonpackage_sendfs,
eca7b760
IK
5090 drr.drr_u.drr_begin.drr_toname,
5091 sizeof (nonpackage_sendfs));
428870ff
BB
5092 if ((cp = strchr(nonpackage_sendfs, '@')) != NULL)
5093 *cp = '\0';
5094 sendfs = nonpackage_sendfs;
671c9354 5095 VERIFY(finalsnap == NULL);
428870ff 5096 }
fcff0f35
PD
5097 return (zfs_receive_one(hdl, infd, tosnap, originsnap, flags,
5098 &drr, &drr_noswap, sendfs, stream_nv, stream_avl, top_zfs,
196bee4c 5099 finalsnap, cmdprops));
428870ff
BB
5100 } else {
5101 assert(DMU_GET_STREAM_HDRTYPE(drrb->drr_versioninfo) ==
5102 DMU_COMPOUNDSTREAM);
fcff0f35 5103 return (zfs_receive_package(hdl, infd, tosnap, flags, &drr,
196bee4c 5104 &zcksum, top_zfs, cmdprops));
34dc7c2f
BB
5105 }
5106}
b128c09f
BB
5107
5108/*
5109 * Restores a backup of tosnap from the file descriptor specified by infd.
5110 * Return 0 on total success, -2 if some things couldn't be
5111 * destroyed/renamed/promoted, -1 if some things couldn't be received.
47dfff3b
MA
5112 * (-1 will override -2, if -1 and the resumable flag was specified the
5113 * transfer can be resumed if the sending side supports it).
b128c09f
BB
5114 */
5115int
fcff0f35
PD
5116zfs_receive(libzfs_handle_t *hdl, const char *tosnap, nvlist_t *props,
5117 recvflags_t *flags, int infd, avl_tree_t *stream_avl)
b128c09f
BB
5118{
5119 char *top_zfs = NULL;
5120 int err;
5c3f61eb 5121 struct stat sb;
fcff0f35 5122 char *originsnap = NULL;
5c3f61eb
RY
5123
5124 /*
5125 * The only way fstat can fail is if we do not have a valid file
5126 * descriptor.
5127 */
5128 if (fstat(infd, &sb) == -1) {
5129 perror("fstat");
5130 return (-2);
5131 }
5132
5c3f61eb
RY
5133 /*
5134 * It is not uncommon for gigabytes to be processed in zfs receive.
73cdcc63 5135 * Speculatively increase the buffer size if supported by the platform.
5c3f61eb 5136 */
73cdcc63
MM
5137 if (S_ISFIFO(sb.st_mode))
5138 libzfs_set_pipe_max(infd);
572e2857 5139
fcff0f35
PD
5140 if (props) {
5141 err = nvlist_lookup_string(props, "origin", &originsnap);
5142 if (err && err != ENOENT)
5143 return (err);
5144 }
5145
fcff0f35 5146 err = zfs_receive_impl(hdl, tosnap, originsnap, flags, infd, NULL, NULL,
196bee4c 5147 stream_avl, &top_zfs, NULL, props);
b128c09f 5148
bb61cc31 5149 if (err == 0 && !flags->nomount && flags->domount && top_zfs) {
689f093e
GN
5150 zfs_handle_t *zhp = NULL;
5151 prop_changelist_t *clp = NULL;
b128c09f 5152
bb61cc31
TC
5153 zhp = zfs_open(hdl, top_zfs,
5154 ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME);
5155 if (zhp == NULL) {
5156 err = -1;
5157 goto out;
5158 } else {
5159 if (zhp->zfs_type == ZFS_TYPE_VOLUME) {
5160 zfs_close(zhp);
5161 goto out;
5162 }
5163
b128c09f 5164 clp = changelist_gather(zhp, ZFS_PROP_MOUNTPOINT,
a57d3d45
MZ
5165 CL_GATHER_MOUNT_ALWAYS,
5166 flags->forceunmount ? MS_FORCE : 0);
b128c09f 5167 zfs_close(zhp);
bb61cc31
TC
5168 if (clp == NULL) {
5169 err = -1;
5170 goto out;
b128c09f 5171 }
bb61cc31
TC
5172
5173 /* mount and share received datasets */
5174 err = changelist_postfix(clp);
5175 changelist_free(clp);
5176 if (err != 0)
5177 err = -1;
b128c09f 5178 }
b128c09f 5179 }
bb61cc31
TC
5180
5181out:
b128c09f
BB
5182 if (top_zfs)
5183 free(top_zfs);
5184
5185 return (err);
5186}