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