4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
24 * Copyright (c) 2011, 2015 by Delphix. All rights reserved.
25 * Copyright (c) 2012, Joyent, Inc. All rights reserved.
26 * Copyright (c) 2012 Pawel Jakub Dawidek <pawel@dawidek.net>.
28 * Copyright (c) 2013 Steven Hartland. All rights reserved.
29 * Copyright 2015, OmniTI Computer Consulting, Inc. All rights reserved.
42 #include <sys/mount.h>
43 #include <sys/mntent.h>
44 #include <sys/mnttab.h>
46 #include <sys/debug.h>
54 #include <libzfs_core.h>
56 #include "zfs_namecheck.h"
58 #include "zfs_fletcher.h"
59 #include "libzfs_impl.h"
61 #include <sys/zio_checksum.h>
63 #include <sys/socket.h>
66 /* in libzfs_dataset.c */
67 extern void zfs_setprop_error(libzfs_handle_t
*, zfs_prop_t
, int, char *);
69 static int zfs_receive_impl(libzfs_handle_t
*, const char *, const char *,
70 recvflags_t
*, int, const char *, nvlist_t
*, avl_tree_t
*, char **, int,
71 uint64_t *, const char *);
72 static int guid_to_name(libzfs_handle_t
*, const char *,
73 uint64_t, boolean_t
, char *);
75 static const zio_cksum_t zero_cksum
= { { 0 } };
77 typedef struct dedup_arg
{
80 libzfs_handle_t
*dedup_hdl
;
83 typedef struct progress_arg
{
86 boolean_t pa_parsable
;
89 typedef struct dataref
{
95 typedef struct dedup_entry
{
96 struct dedup_entry
*dde_next
;
97 zio_cksum_t dde_chksum
;
102 #define MAX_DDT_PHYSMEM_PERCENT 20
103 #define SMALLEST_POSSIBLE_MAX_DDT_MB 128
105 typedef struct dedup_table
{
106 dedup_entry_t
**dedup_hash_array
;
107 umem_cache_t
*ddecache
;
108 uint64_t max_ddt_size
; /* max dedup table size in bytes */
109 uint64_t cur_ddt_size
; /* current dedup table size in bytes */
116 high_order_bit(uint64_t n
)
120 for (count
= 0; n
!= 0; count
++)
126 ssread(void *buf
, size_t len
, FILE *stream
)
130 if ((outlen
= fread(buf
, len
, 1, stream
)) == 0)
137 ddt_hash_append(libzfs_handle_t
*hdl
, dedup_table_t
*ddt
, dedup_entry_t
**ddepp
,
138 zio_cksum_t
*cs
, uint64_t prop
, dataref_t
*dr
)
142 if (ddt
->cur_ddt_size
>= ddt
->max_ddt_size
) {
143 if (ddt
->ddt_full
== B_FALSE
) {
144 zfs_error_aux(hdl
, dgettext(TEXT_DOMAIN
,
145 "Dedup table full. Deduplication will continue "
146 "with existing table entries"));
147 ddt
->ddt_full
= B_TRUE
;
152 if ((dde
= umem_cache_alloc(ddt
->ddecache
, UMEM_DEFAULT
))
154 assert(*ddepp
== NULL
);
155 dde
->dde_next
= NULL
;
156 dde
->dde_chksum
= *cs
;
157 dde
->dde_prop
= prop
;
160 ddt
->cur_ddt_size
+= sizeof (dedup_entry_t
);
166 * Using the specified dedup table, do a lookup for an entry with
167 * the checksum cs. If found, return the block's reference info
168 * in *dr. Otherwise, insert a new entry in the dedup table, using
169 * the reference information specified by *dr.
171 * return value: true - entry was found
172 * false - entry was not found
175 ddt_update(libzfs_handle_t
*hdl
, dedup_table_t
*ddt
, zio_cksum_t
*cs
,
176 uint64_t prop
, dataref_t
*dr
)
179 dedup_entry_t
**ddepp
;
181 hashcode
= BF64_GET(cs
->zc_word
[0], 0, ddt
->numhashbits
);
183 for (ddepp
= &(ddt
->dedup_hash_array
[hashcode
]); *ddepp
!= NULL
;
184 ddepp
= &((*ddepp
)->dde_next
)) {
185 if (ZIO_CHECKSUM_EQUAL(((*ddepp
)->dde_chksum
), *cs
) &&
186 (*ddepp
)->dde_prop
== prop
) {
187 *dr
= (*ddepp
)->dde_ref
;
191 ddt_hash_append(hdl
, ddt
, ddepp
, cs
, prop
, dr
);
196 dump_record(dmu_replay_record_t
*drr
, void *payload
, int payload_len
,
197 zio_cksum_t
*zc
, int outfd
)
199 ASSERT3U(offsetof(dmu_replay_record_t
, drr_u
.drr_checksum
.drr_checksum
),
200 ==, sizeof (dmu_replay_record_t
) - sizeof (zio_cksum_t
));
201 fletcher_4_incremental_native(drr
,
202 offsetof(dmu_replay_record_t
, drr_u
.drr_checksum
.drr_checksum
), zc
);
203 if (drr
->drr_type
!= DRR_BEGIN
) {
204 ASSERT(ZIO_CHECKSUM_IS_ZERO(&drr
->drr_u
.
205 drr_checksum
.drr_checksum
));
206 drr
->drr_u
.drr_checksum
.drr_checksum
= *zc
;
208 fletcher_4_incremental_native(&drr
->drr_u
.drr_checksum
.drr_checksum
,
209 sizeof (zio_cksum_t
), zc
);
210 if (write(outfd
, drr
, sizeof (*drr
)) == -1)
212 if (payload_len
!= 0) {
213 fletcher_4_incremental_native(payload
, payload_len
, zc
);
214 if (write(outfd
, payload
, payload_len
) == -1)
221 * This function is started in a separate thread when the dedup option
222 * has been requested. The main send thread determines the list of
223 * snapshots to be included in the send stream and makes the ioctl calls
224 * for each one. But instead of having the ioctl send the output to the
225 * the output fd specified by the caller of zfs_send()), the
226 * ioctl is told to direct the output to a pipe, which is read by the
227 * alternate thread running THIS function. This function does the
229 * 1. building a dedup table (the DDT)
230 * 2. doing checksums on each data block and inserting a record in the DDT
231 * 3. looking for matching checksums, and
232 * 4. sending a DRR_WRITE_BYREF record instead of a write record whenever
233 * a duplicate block is found.
234 * The output of this function then goes to the output fd requested
235 * by the caller of zfs_send().
240 dedup_arg_t
*dda
= arg
;
241 char *buf
= zfs_alloc(dda
->dedup_hdl
, SPA_MAXBLOCKSIZE
);
242 dmu_replay_record_t thedrr
= { 0 };
243 dmu_replay_record_t
*drr
= &thedrr
;
247 zio_cksum_t stream_cksum
;
248 uint64_t physmem
= sysconf(_SC_PHYS_PAGES
) * sysconf(_SC_PAGESIZE
);
252 MAX((physmem
* MAX_DDT_PHYSMEM_PERCENT
) / 100,
253 SMALLEST_POSSIBLE_MAX_DDT_MB
<< 20);
255 numbuckets
= ddt
.max_ddt_size
/ (sizeof (dedup_entry_t
));
258 * numbuckets must be a power of 2. Increase number to
259 * a power of 2 if necessary.
261 if (!ISP2(numbuckets
))
262 numbuckets
= 1ULL << high_order_bit(numbuckets
);
264 ddt
.dedup_hash_array
= calloc(numbuckets
, sizeof (dedup_entry_t
*));
265 ddt
.ddecache
= umem_cache_create("dde", sizeof (dedup_entry_t
), 0,
266 NULL
, NULL
, NULL
, NULL
, NULL
, 0);
267 ddt
.cur_ddt_size
= numbuckets
* sizeof (dedup_entry_t
*);
268 ddt
.numhashbits
= high_order_bit(numbuckets
) - 1;
269 ddt
.ddt_full
= B_FALSE
;
271 outfd
= dda
->outputfd
;
272 ofp
= fdopen(dda
->inputfd
, "r");
273 while (ssread(drr
, sizeof (*drr
), ofp
) != 0) {
275 switch (drr
->drr_type
) {
278 struct drr_begin
*drrb
= &drr
->drr_u
.drr_begin
;
281 ZIO_SET_CHECKSUM(&stream_cksum
, 0, 0, 0, 0);
283 ASSERT3U(drrb
->drr_magic
, ==, DMU_BACKUP_MAGIC
);
285 /* set the DEDUP feature flag for this stream */
286 fflags
= DMU_GET_FEATUREFLAGS(drrb
->drr_versioninfo
);
287 fflags
|= (DMU_BACKUP_FEATURE_DEDUP
|
288 DMU_BACKUP_FEATURE_DEDUPPROPS
);
289 DMU_SET_FEATUREFLAGS(drrb
->drr_versioninfo
, fflags
);
291 if (drr
->drr_payloadlen
!= 0) {
292 sz
= drr
->drr_payloadlen
;
294 if (sz
> SPA_MAXBLOCKSIZE
) {
295 buf
= zfs_realloc(dda
->dedup_hdl
, buf
,
296 SPA_MAXBLOCKSIZE
, sz
);
298 (void) ssread(buf
, sz
, ofp
);
302 if (dump_record(drr
, buf
, sz
, &stream_cksum
,
310 struct drr_end
*drre
= &drr
->drr_u
.drr_end
;
311 /* use the recalculated checksum */
312 drre
->drr_checksum
= stream_cksum
;
313 if (dump_record(drr
, NULL
, 0, &stream_cksum
,
321 struct drr_object
*drro
= &drr
->drr_u
.drr_object
;
322 if (drro
->drr_bonuslen
> 0) {
324 P2ROUNDUP((uint64_t)drro
->drr_bonuslen
, 8),
327 if (dump_record(drr
, buf
,
328 P2ROUNDUP((uint64_t)drro
->drr_bonuslen
, 8),
329 &stream_cksum
, outfd
) != 0)
336 struct drr_spill
*drrs
= &drr
->drr_u
.drr_spill
;
337 (void) ssread(buf
, drrs
->drr_length
, ofp
);
338 if (dump_record(drr
, buf
, drrs
->drr_length
,
339 &stream_cksum
, outfd
) != 0)
344 case DRR_FREEOBJECTS
:
346 if (dump_record(drr
, NULL
, 0, &stream_cksum
,
354 struct drr_write
*drrw
= &drr
->drr_u
.drr_write
;
356 uint64_t payload_size
;
358 payload_size
= DRR_WRITE_PAYLOAD_SIZE(drrw
);
359 (void) ssread(buf
, payload_size
, ofp
);
362 * Use the existing checksum if it's dedup-capable,
363 * else calculate a SHA256 checksum for it.
366 if (ZIO_CHECKSUM_EQUAL(drrw
->drr_key
.ddk_cksum
,
368 !DRR_IS_DEDUP_CAPABLE(drrw
->drr_checksumflags
)) {
370 zio_cksum_t tmpsha256
;
372 SHA2Init(SHA256
, &ctx
);
373 SHA2Update(&ctx
, buf
, payload_size
);
374 SHA2Final(&tmpsha256
, &ctx
);
376 drrw
->drr_key
.ddk_cksum
.zc_word
[0] =
377 BE_64(tmpsha256
.zc_word
[0]);
378 drrw
->drr_key
.ddk_cksum
.zc_word
[1] =
379 BE_64(tmpsha256
.zc_word
[1]);
380 drrw
->drr_key
.ddk_cksum
.zc_word
[2] =
381 BE_64(tmpsha256
.zc_word
[2]);
382 drrw
->drr_key
.ddk_cksum
.zc_word
[3] =
383 BE_64(tmpsha256
.zc_word
[3]);
384 drrw
->drr_checksumtype
= ZIO_CHECKSUM_SHA256
;
385 drrw
->drr_checksumflags
= DRR_CHECKSUM_DEDUP
;
388 dataref
.ref_guid
= drrw
->drr_toguid
;
389 dataref
.ref_object
= drrw
->drr_object
;
390 dataref
.ref_offset
= drrw
->drr_offset
;
392 if (ddt_update(dda
->dedup_hdl
, &ddt
,
393 &drrw
->drr_key
.ddk_cksum
, drrw
->drr_key
.ddk_prop
,
395 dmu_replay_record_t wbr_drr
= {0};
396 struct drr_write_byref
*wbr_drrr
=
397 &wbr_drr
.drr_u
.drr_write_byref
;
399 /* block already present in stream */
400 wbr_drr
.drr_type
= DRR_WRITE_BYREF
;
402 wbr_drrr
->drr_object
= drrw
->drr_object
;
403 wbr_drrr
->drr_offset
= drrw
->drr_offset
;
404 wbr_drrr
->drr_length
= drrw
->drr_logical_size
;
405 wbr_drrr
->drr_toguid
= drrw
->drr_toguid
;
406 wbr_drrr
->drr_refguid
= dataref
.ref_guid
;
407 wbr_drrr
->drr_refobject
=
409 wbr_drrr
->drr_refoffset
=
412 wbr_drrr
->drr_checksumtype
=
413 drrw
->drr_checksumtype
;
414 wbr_drrr
->drr_checksumflags
=
415 drrw
->drr_checksumtype
;
416 wbr_drrr
->drr_key
.ddk_cksum
=
417 drrw
->drr_key
.ddk_cksum
;
418 wbr_drrr
->drr_key
.ddk_prop
=
419 drrw
->drr_key
.ddk_prop
;
421 if (dump_record(&wbr_drr
, NULL
, 0,
422 &stream_cksum
, outfd
) != 0)
425 /* block not previously seen */
426 if (dump_record(drr
, buf
, payload_size
,
427 &stream_cksum
, outfd
) != 0)
433 case DRR_WRITE_EMBEDDED
:
435 struct drr_write_embedded
*drrwe
=
436 &drr
->drr_u
.drr_write_embedded
;
438 P2ROUNDUP((uint64_t)drrwe
->drr_psize
, 8), ofp
);
439 if (dump_record(drr
, buf
,
440 P2ROUNDUP((uint64_t)drrwe
->drr_psize
, 8),
441 &stream_cksum
, outfd
) != 0)
448 if (dump_record(drr
, NULL
, 0, &stream_cksum
,
455 (void) fprintf(stderr
, "INVALID record type 0x%x\n",
457 /* should never happen, so assert */
462 umem_cache_destroy(ddt
.ddecache
);
463 free(ddt
.dedup_hash_array
);
471 * Routines for dealing with the AVL tree of fs-nvlists
473 typedef struct fsavl_node
{
481 fsavl_compare(const void *arg1
, const void *arg2
)
483 const fsavl_node_t
*fn1
= (const fsavl_node_t
*)arg1
;
484 const fsavl_node_t
*fn2
= (const fsavl_node_t
*)arg2
;
486 return (AVL_CMP(fn1
->fn_guid
, fn2
->fn_guid
));
490 * Given the GUID of a snapshot, find its containing filesystem and
494 fsavl_find(avl_tree_t
*avl
, uint64_t snapguid
, char **snapname
)
496 fsavl_node_t fn_find
;
499 fn_find
.fn_guid
= snapguid
;
501 fn
= avl_find(avl
, &fn_find
, NULL
);
504 *snapname
= fn
->fn_snapname
;
505 return (fn
->fn_nvfs
);
511 fsavl_destroy(avl_tree_t
*avl
)
520 while ((fn
= avl_destroy_nodes(avl
, &cookie
)) != NULL
)
527 * Given an nvlist, produce an avl tree of snapshots, ordered by guid
530 fsavl_create(nvlist_t
*fss
)
533 nvpair_t
*fselem
= NULL
;
535 if ((fsavl
= malloc(sizeof (avl_tree_t
))) == NULL
)
538 avl_create(fsavl
, fsavl_compare
, sizeof (fsavl_node_t
),
539 offsetof(fsavl_node_t
, fn_node
));
541 while ((fselem
= nvlist_next_nvpair(fss
, fselem
)) != NULL
) {
542 nvlist_t
*nvfs
, *snaps
;
543 nvpair_t
*snapelem
= NULL
;
545 VERIFY(0 == nvpair_value_nvlist(fselem
, &nvfs
));
546 VERIFY(0 == nvlist_lookup_nvlist(nvfs
, "snaps", &snaps
));
549 nvlist_next_nvpair(snaps
, snapelem
)) != NULL
) {
553 VERIFY(0 == nvpair_value_uint64(snapelem
, &guid
));
554 if ((fn
= malloc(sizeof (fsavl_node_t
))) == NULL
) {
555 fsavl_destroy(fsavl
);
559 fn
->fn_snapname
= nvpair_name(snapelem
);
563 * Note: if there are multiple snaps with the
564 * same GUID, we ignore all but one.
566 if (avl_find(fsavl
, fn
, NULL
) == NULL
)
577 * Routines for dealing with the giant nvlist of fs-nvlists, etc.
579 typedef struct send_data
{
581 * assigned inside every recursive call,
582 * restored from *_save on return:
584 * guid of fromsnap snapshot in parent dataset
585 * txg of fromsnap snapshot in current dataset
586 * txg of tosnap snapshot in current dataset
589 uint64_t parent_fromsnap_guid
;
590 uint64_t fromsnap_txg
;
593 /* the nvlists get accumulated during depth-first traversal */
594 nvlist_t
*parent_snaps
;
598 /* send-receive configuration, does not change during traversal */
600 const char *fromsnap
;
608 * The header nvlist is of the following format:
611 * "fromsnap" -> string (if incremental)
615 * "name" -> string (full name; for debugging)
616 * "parentfromsnap" -> number (guid of fromsnap in parent)
618 * "props" -> { name -> value (only if set here) }
619 * "snaps" -> { name (lastname) -> number (guid) }
620 * "snapprops" -> { name (lastname) -> { name -> value } }
622 * "origin" -> number (guid) (if clone)
623 * "sent" -> boolean (not on-disk)
631 static void send_iterate_prop(zfs_handle_t
*zhp
, nvlist_t
*nv
);
634 send_iterate_snap(zfs_handle_t
*zhp
, void *arg
)
636 send_data_t
*sd
= arg
;
637 uint64_t guid
= zhp
->zfs_dmustats
.dds_guid
;
638 uint64_t txg
= zhp
->zfs_dmustats
.dds_creation_txg
;
641 boolean_t isfromsnap
, istosnap
, istosnapwithnofrom
;
643 snapname
= strrchr(zhp
->zfs_name
, '@')+1;
644 isfromsnap
= (sd
->fromsnap
!= NULL
&&
645 strcmp(sd
->fromsnap
, snapname
) == 0);
646 istosnap
= (sd
->tosnap
!= NULL
&& (strcmp(sd
->tosnap
, snapname
) == 0));
647 istosnapwithnofrom
= (istosnap
&& sd
->fromsnap
== NULL
);
649 if (sd
->tosnap_txg
!= 0 && txg
> sd
->tosnap_txg
) {
651 (void) fprintf(stderr
, dgettext(TEXT_DOMAIN
,
652 "skipping snapshot %s because it was created "
653 "after the destination snapshot (%s)\n"),
654 zhp
->zfs_name
, sd
->tosnap
);
660 VERIFY(0 == nvlist_add_uint64(sd
->parent_snaps
, snapname
, guid
));
662 * NB: if there is no fromsnap here (it's a newly created fs in
663 * an incremental replication), we will substitute the tosnap.
665 if (isfromsnap
|| (sd
->parent_fromsnap_guid
== 0 && istosnap
)) {
666 sd
->parent_fromsnap_guid
= guid
;
669 if (!sd
->recursive
) {
670 if (!sd
->seenfrom
&& isfromsnap
) {
671 sd
->seenfrom
= B_TRUE
;
676 if ((sd
->seento
|| !sd
->seenfrom
) && !istosnapwithnofrom
) {
685 VERIFY(0 == nvlist_alloc(&nv
, NV_UNIQUE_NAME
, 0));
686 send_iterate_prop(zhp
, nv
);
687 VERIFY(0 == nvlist_add_nvlist(sd
->snapprops
, snapname
, nv
));
695 send_iterate_prop(zfs_handle_t
*zhp
, nvlist_t
*nv
)
697 nvpair_t
*elem
= NULL
;
699 while ((elem
= nvlist_next_nvpair(zhp
->zfs_props
, elem
)) != NULL
) {
700 char *propname
= nvpair_name(elem
);
701 zfs_prop_t prop
= zfs_name_to_prop(propname
);
704 if (!zfs_prop_user(propname
)) {
706 * Realistically, this should never happen. However,
707 * we want the ability to add DSL properties without
708 * needing to make incompatible version changes. We
709 * need to ignore unknown properties to allow older
710 * software to still send datasets containing these
711 * properties, with the unknown properties elided.
713 if (prop
== ZPROP_INVAL
)
716 if (zfs_prop_readonly(prop
))
720 verify(nvpair_value_nvlist(elem
, &propnv
) == 0);
721 if (prop
== ZFS_PROP_QUOTA
|| prop
== ZFS_PROP_RESERVATION
||
722 prop
== ZFS_PROP_REFQUOTA
||
723 prop
== ZFS_PROP_REFRESERVATION
) {
726 verify(nvlist_lookup_uint64(propnv
,
727 ZPROP_VALUE
, &value
) == 0);
728 if (zhp
->zfs_type
== ZFS_TYPE_SNAPSHOT
)
731 * May have no source before SPA_VERSION_RECVD_PROPS,
732 * but is still modifiable.
734 if (nvlist_lookup_string(propnv
,
735 ZPROP_SOURCE
, &source
) == 0) {
736 if ((strcmp(source
, zhp
->zfs_name
) != 0) &&
738 ZPROP_SOURCE_VAL_RECVD
) != 0))
743 if (nvlist_lookup_string(propnv
,
744 ZPROP_SOURCE
, &source
) != 0)
746 if ((strcmp(source
, zhp
->zfs_name
) != 0) &&
747 (strcmp(source
, ZPROP_SOURCE_VAL_RECVD
) != 0))
751 if (zfs_prop_user(propname
) ||
752 zfs_prop_get_type(prop
) == PROP_TYPE_STRING
) {
754 verify(nvlist_lookup_string(propnv
,
755 ZPROP_VALUE
, &value
) == 0);
756 VERIFY(0 == nvlist_add_string(nv
, propname
, value
));
759 verify(nvlist_lookup_uint64(propnv
,
760 ZPROP_VALUE
, &value
) == 0);
761 VERIFY(0 == nvlist_add_uint64(nv
, propname
, value
));
767 * returns snapshot creation txg
768 * and returns 0 if the snapshot does not exist
771 get_snap_txg(libzfs_handle_t
*hdl
, const char *fs
, const char *snap
)
773 char name
[ZFS_MAX_DATASET_NAME_LEN
];
776 if (fs
== NULL
|| fs
[0] == '\0' || snap
== NULL
|| snap
[0] == '\0')
779 (void) snprintf(name
, sizeof (name
), "%s@%s", fs
, snap
);
780 if (zfs_dataset_exists(hdl
, name
, ZFS_TYPE_SNAPSHOT
)) {
781 zfs_handle_t
*zhp
= zfs_open(hdl
, name
, ZFS_TYPE_SNAPSHOT
);
783 txg
= zfs_prop_get_int(zhp
, ZFS_PROP_CREATETXG
);
792 * recursively generate nvlists describing datasets. See comment
793 * for the data structure send_data_t above for description of contents
797 send_iterate_fs(zfs_handle_t
*zhp
, void *arg
)
799 send_data_t
*sd
= arg
;
802 uint64_t parent_fromsnap_guid_save
= sd
->parent_fromsnap_guid
;
803 uint64_t fromsnap_txg_save
= sd
->fromsnap_txg
;
804 uint64_t tosnap_txg_save
= sd
->tosnap_txg
;
805 uint64_t txg
= zhp
->zfs_dmustats
.dds_creation_txg
;
806 uint64_t guid
= zhp
->zfs_dmustats
.dds_guid
;
807 uint64_t fromsnap_txg
, tosnap_txg
;
810 fromsnap_txg
= get_snap_txg(zhp
->zfs_hdl
, zhp
->zfs_name
, sd
->fromsnap
);
811 if (fromsnap_txg
!= 0)
812 sd
->fromsnap_txg
= fromsnap_txg
;
814 tosnap_txg
= get_snap_txg(zhp
->zfs_hdl
, zhp
->zfs_name
, sd
->tosnap
);
816 sd
->tosnap_txg
= tosnap_txg
;
819 * on the send side, if the current dataset does not have tosnap,
820 * perform two additional checks:
822 * - skip sending the current dataset if it was created later than
824 * - return error if the current dataset was created earlier than
827 if (sd
->tosnap
!= NULL
&& tosnap_txg
== 0) {
828 if (sd
->tosnap_txg
!= 0 && txg
> sd
->tosnap_txg
) {
830 (void) fprintf(stderr
, dgettext(TEXT_DOMAIN
,
831 "skipping dataset %s: snapshot %s does "
832 "not exist\n"), zhp
->zfs_name
, sd
->tosnap
);
835 (void) fprintf(stderr
, dgettext(TEXT_DOMAIN
,
836 "cannot send %s@%s%s: snapshot %s@%s does not "
837 "exist\n"), sd
->fsname
, sd
->tosnap
, sd
->recursive
?
838 dgettext(TEXT_DOMAIN
, " recursively") : "",
839 zhp
->zfs_name
, sd
->tosnap
);
845 VERIFY(0 == nvlist_alloc(&nvfs
, NV_UNIQUE_NAME
, 0));
846 VERIFY(0 == nvlist_add_string(nvfs
, "name", zhp
->zfs_name
));
847 VERIFY(0 == nvlist_add_uint64(nvfs
, "parentfromsnap",
848 sd
->parent_fromsnap_guid
));
850 if (zhp
->zfs_dmustats
.dds_origin
[0]) {
851 zfs_handle_t
*origin
= zfs_open(zhp
->zfs_hdl
,
852 zhp
->zfs_dmustats
.dds_origin
, ZFS_TYPE_SNAPSHOT
);
853 if (origin
== NULL
) {
857 VERIFY(0 == nvlist_add_uint64(nvfs
, "origin",
858 origin
->zfs_dmustats
.dds_guid
));
861 /* iterate over props */
862 VERIFY(0 == nvlist_alloc(&nv
, NV_UNIQUE_NAME
, 0));
863 send_iterate_prop(zhp
, nv
);
864 VERIFY(0 == nvlist_add_nvlist(nvfs
, "props", nv
));
867 /* iterate over snaps, and set sd->parent_fromsnap_guid */
868 sd
->parent_fromsnap_guid
= 0;
869 VERIFY(0 == nvlist_alloc(&sd
->parent_snaps
, NV_UNIQUE_NAME
, 0));
870 VERIFY(0 == nvlist_alloc(&sd
->snapprops
, NV_UNIQUE_NAME
, 0));
871 (void) zfs_iter_snapshots_sorted(zhp
, send_iterate_snap
, sd
);
872 VERIFY(0 == nvlist_add_nvlist(nvfs
, "snaps", sd
->parent_snaps
));
873 VERIFY(0 == nvlist_add_nvlist(nvfs
, "snapprops", sd
->snapprops
));
874 nvlist_free(sd
->parent_snaps
);
875 nvlist_free(sd
->snapprops
);
877 /* add this fs to nvlist */
878 (void) snprintf(guidstring
, sizeof (guidstring
),
879 "0x%llx", (longlong_t
)guid
);
880 VERIFY(0 == nvlist_add_nvlist(sd
->fss
, guidstring
, nvfs
));
883 /* iterate over children */
885 rv
= zfs_iter_filesystems(zhp
, send_iterate_fs
, sd
);
888 sd
->parent_fromsnap_guid
= parent_fromsnap_guid_save
;
889 sd
->fromsnap_txg
= fromsnap_txg_save
;
890 sd
->tosnap_txg
= tosnap_txg_save
;
897 gather_nvlist(libzfs_handle_t
*hdl
, const char *fsname
, const char *fromsnap
,
898 const char *tosnap
, boolean_t recursive
, boolean_t verbose
,
899 nvlist_t
**nvlp
, avl_tree_t
**avlp
)
902 send_data_t sd
= { 0 };
905 zhp
= zfs_open(hdl
, fsname
, ZFS_TYPE_FILESYSTEM
| ZFS_TYPE_VOLUME
);
907 return (EZFS_BADTYPE
);
909 VERIFY(0 == nvlist_alloc(&sd
.fss
, NV_UNIQUE_NAME
, 0));
911 sd
.fromsnap
= fromsnap
;
913 sd
.recursive
= recursive
;
914 sd
.verbose
= verbose
;
916 if ((error
= send_iterate_fs(zhp
, &sd
)) != 0) {
924 if (avlp
!= NULL
&& (*avlp
= fsavl_create(sd
.fss
)) == NULL
) {
935 * Routines specific to "zfs send"
937 typedef struct send_dump_data
{
938 /* these are all just the short snapname (the part after the @) */
939 const char *fromsnap
;
941 char prevsnap
[ZFS_MAX_DATASET_NAME_LEN
];
942 uint64_t prevsnap_obj
;
943 boolean_t seenfrom
, seento
, replicate
, doall
, fromorigin
;
944 boolean_t verbose
, dryrun
, parsable
, progress
, embed_data
, std_out
;
945 boolean_t large_block
, compress
;
951 snapfilter_cb_t
*filter_cb
;
954 char holdtag
[ZFS_MAX_DATASET_NAME_LEN
];
960 estimate_ioctl(zfs_handle_t
*zhp
, uint64_t fromsnap_obj
,
961 boolean_t fromorigin
, enum lzc_send_flags flags
, uint64_t *sizep
)
963 zfs_cmd_t zc
= {"\0"};
964 libzfs_handle_t
*hdl
= zhp
->zfs_hdl
;
966 assert(zhp
->zfs_type
== ZFS_TYPE_SNAPSHOT
);
967 assert(fromsnap_obj
== 0 || !fromorigin
);
969 (void) strlcpy(zc
.zc_name
, zhp
->zfs_name
, sizeof (zc
.zc_name
));
970 zc
.zc_obj
= fromorigin
;
971 zc
.zc_sendobj
= zfs_prop_get_int(zhp
, ZFS_PROP_OBJSETID
);
972 zc
.zc_fromobj
= fromsnap_obj
;
973 zc
.zc_guid
= 1; /* estimate flag */
976 if (zfs_ioctl(zhp
->zfs_hdl
, ZFS_IOC_SEND
, &zc
) != 0) {
978 (void) snprintf(errbuf
, sizeof (errbuf
), dgettext(TEXT_DOMAIN
,
979 "warning: cannot estimate space for '%s'"), zhp
->zfs_name
);
983 zfs_error_aux(hdl
, dgettext(TEXT_DOMAIN
,
984 "not an earlier snapshot from the same fs"));
985 return (zfs_error(hdl
, EZFS_CROSSTARGET
, errbuf
));
988 if (zfs_dataset_exists(hdl
, zc
.zc_name
,
989 ZFS_TYPE_SNAPSHOT
)) {
990 zfs_error_aux(hdl
, dgettext(TEXT_DOMAIN
,
991 "incremental source (@%s) does not exist"),
994 return (zfs_error(hdl
, EZFS_NOENT
, errbuf
));
1007 zfs_error_aux(hdl
, strerror(errno
));
1008 return (zfs_error(hdl
, EZFS_BADBACKUP
, errbuf
));
1011 return (zfs_standard_error(hdl
, errno
, errbuf
));
1015 *sizep
= zc
.zc_objset_type
;
1021 * Dumps a backup of the given snapshot (incremental from fromsnap if it's not
1022 * NULL) to the file descriptor specified by outfd.
1025 dump_ioctl(zfs_handle_t
*zhp
, const char *fromsnap
, uint64_t fromsnap_obj
,
1026 boolean_t fromorigin
, int outfd
, enum lzc_send_flags flags
,
1029 zfs_cmd_t zc
= {"\0"};
1030 libzfs_handle_t
*hdl
= zhp
->zfs_hdl
;
1033 assert(zhp
->zfs_type
== ZFS_TYPE_SNAPSHOT
);
1034 assert(fromsnap_obj
== 0 || !fromorigin
);
1036 (void) strlcpy(zc
.zc_name
, zhp
->zfs_name
, sizeof (zc
.zc_name
));
1037 zc
.zc_cookie
= outfd
;
1038 zc
.zc_obj
= fromorigin
;
1039 zc
.zc_sendobj
= zfs_prop_get_int(zhp
, ZFS_PROP_OBJSETID
);
1040 zc
.zc_fromobj
= fromsnap_obj
;
1041 zc
.zc_flags
= flags
;
1043 VERIFY(0 == nvlist_alloc(&thisdbg
, NV_UNIQUE_NAME
, 0));
1044 if (fromsnap
&& fromsnap
[0] != '\0') {
1045 VERIFY(0 == nvlist_add_string(thisdbg
,
1046 "fromsnap", fromsnap
));
1049 if (zfs_ioctl(zhp
->zfs_hdl
, ZFS_IOC_SEND
, &zc
) != 0) {
1051 (void) snprintf(errbuf
, sizeof (errbuf
), dgettext(TEXT_DOMAIN
,
1052 "warning: cannot send '%s'"), zhp
->zfs_name
);
1054 VERIFY(0 == nvlist_add_uint64(thisdbg
, "error", errno
));
1056 VERIFY(0 == nvlist_add_nvlist(debugnv
,
1057 zhp
->zfs_name
, thisdbg
));
1059 nvlist_free(thisdbg
);
1063 zfs_error_aux(hdl
, dgettext(TEXT_DOMAIN
,
1064 "not an earlier snapshot from the same fs"));
1065 return (zfs_error(hdl
, EZFS_CROSSTARGET
, errbuf
));
1068 if (zfs_dataset_exists(hdl
, zc
.zc_name
,
1069 ZFS_TYPE_SNAPSHOT
)) {
1070 zfs_error_aux(hdl
, dgettext(TEXT_DOMAIN
,
1071 "incremental source (@%s) does not exist"),
1074 return (zfs_error(hdl
, EZFS_NOENT
, errbuf
));
1087 zfs_error_aux(hdl
, strerror(errno
));
1088 return (zfs_error(hdl
, EZFS_BADBACKUP
, errbuf
));
1091 return (zfs_standard_error(hdl
, errno
, errbuf
));
1096 VERIFY(0 == nvlist_add_nvlist(debugnv
, zhp
->zfs_name
, thisdbg
));
1097 nvlist_free(thisdbg
);
1103 gather_holds(zfs_handle_t
*zhp
, send_dump_data_t
*sdd
)
1105 assert(zhp
->zfs_type
== ZFS_TYPE_SNAPSHOT
);
1108 * zfs_send() only sets snapholds for sends that need them,
1109 * e.g. replication and doall.
1111 if (sdd
->snapholds
== NULL
)
1114 fnvlist_add_string(sdd
->snapholds
, zhp
->zfs_name
, sdd
->holdtag
);
1118 send_progress_thread(void *arg
)
1120 progress_arg_t
*pa
= arg
;
1121 zfs_cmd_t zc
= {"\0"};
1122 zfs_handle_t
*zhp
= pa
->pa_zhp
;
1123 libzfs_handle_t
*hdl
= zhp
->zfs_hdl
;
1124 unsigned long long bytes
;
1129 (void) strlcpy(zc
.zc_name
, zhp
->zfs_name
, sizeof (zc
.zc_name
));
1131 if (!pa
->pa_parsable
)
1132 (void) fprintf(stderr
, "TIME SENT SNAPSHOT\n");
1135 * Print the progress from ZFS_IOC_SEND_PROGRESS every second.
1140 zc
.zc_cookie
= pa
->pa_fd
;
1141 if (zfs_ioctl(hdl
, ZFS_IOC_SEND_PROGRESS
, &zc
) != 0)
1142 return ((void *)-1);
1146 bytes
= zc
.zc_cookie
;
1148 if (pa
->pa_parsable
) {
1149 (void) fprintf(stderr
, "%02d:%02d:%02d\t%llu\t%s\n",
1150 tm
->tm_hour
, tm
->tm_min
, tm
->tm_sec
,
1151 bytes
, zhp
->zfs_name
);
1153 zfs_nicenum(bytes
, buf
, sizeof (buf
));
1154 (void) fprintf(stderr
, "%02d:%02d:%02d %5s %s\n",
1155 tm
->tm_hour
, tm
->tm_min
, tm
->tm_sec
,
1156 buf
, zhp
->zfs_name
);
1162 send_print_verbose(FILE *fout
, const char *tosnap
, const char *fromsnap
,
1163 uint64_t size
, boolean_t parsable
)
1166 if (fromsnap
!= NULL
) {
1167 (void) fprintf(fout
, "incremental\t%s\t%s",
1170 (void) fprintf(fout
, "full\t%s",
1174 if (fromsnap
!= NULL
) {
1175 if (strchr(fromsnap
, '@') == NULL
&&
1176 strchr(fromsnap
, '#') == NULL
) {
1177 (void) fprintf(fout
, dgettext(TEXT_DOMAIN
,
1178 "send from @%s to %s"),
1181 (void) fprintf(fout
, dgettext(TEXT_DOMAIN
,
1182 "send from %s to %s"),
1186 (void) fprintf(fout
, dgettext(TEXT_DOMAIN
,
1194 (void) fprintf(fout
, "\t%llu",
1198 zfs_nicenum(size
, buf
, sizeof (buf
));
1199 (void) fprintf(fout
, dgettext(TEXT_DOMAIN
,
1200 " estimated size is %s"), buf
);
1203 (void) fprintf(fout
, "\n");
1207 dump_snapshot(zfs_handle_t
*zhp
, void *arg
)
1209 send_dump_data_t
*sdd
= arg
;
1210 progress_arg_t pa
= { 0 };
1213 enum lzc_send_flags flags
= 0;
1215 boolean_t isfromsnap
, istosnap
, fromorigin
;
1216 boolean_t exclude
= B_FALSE
;
1217 FILE *fout
= sdd
->std_out
? stdout
: stderr
;
1220 thissnap
= strchr(zhp
->zfs_name
, '@') + 1;
1221 isfromsnap
= (sdd
->fromsnap
!= NULL
&&
1222 strcmp(sdd
->fromsnap
, thissnap
) == 0);
1224 if (!sdd
->seenfrom
&& isfromsnap
) {
1225 gather_holds(zhp
, sdd
);
1226 sdd
->seenfrom
= B_TRUE
;
1227 (void) strlcpy(sdd
->prevsnap
, thissnap
,
1228 sizeof (sdd
->prevsnap
));
1229 sdd
->prevsnap_obj
= zfs_prop_get_int(zhp
, ZFS_PROP_OBJSETID
);
1234 if (sdd
->seento
|| !sdd
->seenfrom
) {
1239 istosnap
= (strcmp(sdd
->tosnap
, thissnap
) == 0);
1241 sdd
->seento
= B_TRUE
;
1243 if (sdd
->large_block
)
1244 flags
|= LZC_SEND_FLAG_LARGE_BLOCK
;
1245 if (sdd
->embed_data
)
1246 flags
|= LZC_SEND_FLAG_EMBED_DATA
;
1248 flags
|= LZC_SEND_FLAG_COMPRESS
;
1250 if (!sdd
->doall
&& !isfromsnap
&& !istosnap
) {
1251 if (sdd
->replicate
) {
1253 nvlist_t
*snapprops
;
1255 * Filter out all intermediate snapshots except origin
1256 * snapshots needed to replicate clones.
1258 nvlist_t
*nvfs
= fsavl_find(sdd
->fsavl
,
1259 zhp
->zfs_dmustats
.dds_guid
, &snapname
);
1261 VERIFY(0 == nvlist_lookup_nvlist(nvfs
,
1262 "snapprops", &snapprops
));
1263 VERIFY(0 == nvlist_lookup_nvlist(snapprops
,
1264 thissnap
, &snapprops
));
1265 exclude
= !nvlist_exists(snapprops
, "is_clone_origin");
1272 * If a filter function exists, call it to determine whether
1273 * this snapshot will be sent.
1275 if (exclude
|| (sdd
->filter_cb
!= NULL
&&
1276 sdd
->filter_cb(zhp
, sdd
->filter_cb_arg
) == B_FALSE
)) {
1278 * This snapshot is filtered out. Don't send it, and don't
1279 * set prevsnap_obj, so it will be as if this snapshot didn't
1280 * exist, and the next accepted snapshot will be sent as
1281 * an incremental from the last accepted one, or as the
1282 * first (and full) snapshot in the case of a replication,
1283 * non-incremental send.
1289 gather_holds(zhp
, sdd
);
1290 fromorigin
= sdd
->prevsnap
[0] == '\0' &&
1291 (sdd
->fromorigin
|| sdd
->replicate
);
1295 (void) estimate_ioctl(zhp
, sdd
->prevsnap_obj
,
1296 fromorigin
, flags
, &size
);
1298 send_print_verbose(fout
, zhp
->zfs_name
,
1299 sdd
->prevsnap
[0] ? sdd
->prevsnap
: NULL
,
1300 size
, sdd
->parsable
);
1306 * If progress reporting is requested, spawn a new thread to
1307 * poll ZFS_IOC_SEND_PROGRESS at a regular interval.
1309 if (sdd
->progress
) {
1311 pa
.pa_fd
= sdd
->outfd
;
1312 pa
.pa_parsable
= sdd
->parsable
;
1314 if ((err
= pthread_create(&tid
, NULL
,
1315 send_progress_thread
, &pa
))) {
1321 err
= dump_ioctl(zhp
, sdd
->prevsnap
, sdd
->prevsnap_obj
,
1322 fromorigin
, sdd
->outfd
, flags
, sdd
->debugnv
);
1324 if (sdd
->progress
) {
1325 (void) pthread_cancel(tid
);
1326 (void) pthread_join(tid
, NULL
);
1330 (void) strcpy(sdd
->prevsnap
, thissnap
);
1331 sdd
->prevsnap_obj
= zfs_prop_get_int(zhp
, ZFS_PROP_OBJSETID
);
1337 dump_filesystem(zfs_handle_t
*zhp
, void *arg
)
1340 send_dump_data_t
*sdd
= arg
;
1341 boolean_t missingfrom
= B_FALSE
;
1342 zfs_cmd_t zc
= {"\0"};
1344 (void) snprintf(zc
.zc_name
, sizeof (zc
.zc_name
), "%s@%s",
1345 zhp
->zfs_name
, sdd
->tosnap
);
1346 if (ioctl(zhp
->zfs_hdl
->libzfs_fd
, ZFS_IOC_OBJSET_STATS
, &zc
) != 0) {
1347 (void) fprintf(stderr
, dgettext(TEXT_DOMAIN
,
1348 "WARNING: could not send %s@%s: does not exist\n"),
1349 zhp
->zfs_name
, sdd
->tosnap
);
1354 if (sdd
->replicate
&& sdd
->fromsnap
) {
1356 * If this fs does not have fromsnap, and we're doing
1357 * recursive, we need to send a full stream from the
1358 * beginning (or an incremental from the origin if this
1359 * is a clone). If we're doing non-recursive, then let
1360 * them get the error.
1362 (void) snprintf(zc
.zc_name
, sizeof (zc
.zc_name
), "%s@%s",
1363 zhp
->zfs_name
, sdd
->fromsnap
);
1364 if (ioctl(zhp
->zfs_hdl
->libzfs_fd
,
1365 ZFS_IOC_OBJSET_STATS
, &zc
) != 0) {
1366 missingfrom
= B_TRUE
;
1370 sdd
->seenfrom
= sdd
->seento
= sdd
->prevsnap
[0] = 0;
1371 sdd
->prevsnap_obj
= 0;
1372 if (sdd
->fromsnap
== NULL
|| missingfrom
)
1373 sdd
->seenfrom
= B_TRUE
;
1375 rv
= zfs_iter_snapshots_sorted(zhp
, dump_snapshot
, arg
);
1376 if (!sdd
->seenfrom
) {
1377 (void) fprintf(stderr
, dgettext(TEXT_DOMAIN
,
1378 "WARNING: could not send %s@%s:\n"
1379 "incremental source (%s@%s) does not exist\n"),
1380 zhp
->zfs_name
, sdd
->tosnap
,
1381 zhp
->zfs_name
, sdd
->fromsnap
);
1383 } else if (!sdd
->seento
) {
1384 if (sdd
->fromsnap
) {
1385 (void) fprintf(stderr
, dgettext(TEXT_DOMAIN
,
1386 "WARNING: could not send %s@%s:\n"
1387 "incremental source (%s@%s) "
1388 "is not earlier than it\n"),
1389 zhp
->zfs_name
, sdd
->tosnap
,
1390 zhp
->zfs_name
, sdd
->fromsnap
);
1392 (void) fprintf(stderr
, dgettext(TEXT_DOMAIN
,
1394 "could not send %s@%s: does not exist\n"),
1395 zhp
->zfs_name
, sdd
->tosnap
);
1404 dump_filesystems(zfs_handle_t
*rzhp
, void *arg
)
1406 send_dump_data_t
*sdd
= arg
;
1408 boolean_t needagain
, progress
;
1410 if (!sdd
->replicate
)
1411 return (dump_filesystem(rzhp
, sdd
));
1413 /* Mark the clone origin snapshots. */
1414 for (fspair
= nvlist_next_nvpair(sdd
->fss
, NULL
); fspair
;
1415 fspair
= nvlist_next_nvpair(sdd
->fss
, fspair
)) {
1417 uint64_t origin_guid
= 0;
1419 VERIFY(0 == nvpair_value_nvlist(fspair
, &nvfs
));
1420 (void) nvlist_lookup_uint64(nvfs
, "origin", &origin_guid
);
1421 if (origin_guid
!= 0) {
1423 nvlist_t
*origin_nv
= fsavl_find(sdd
->fsavl
,
1424 origin_guid
, &snapname
);
1425 if (origin_nv
!= NULL
) {
1426 nvlist_t
*snapprops
;
1427 VERIFY(0 == nvlist_lookup_nvlist(origin_nv
,
1428 "snapprops", &snapprops
));
1429 VERIFY(0 == nvlist_lookup_nvlist(snapprops
,
1430 snapname
, &snapprops
));
1431 VERIFY(0 == nvlist_add_boolean(
1432 snapprops
, "is_clone_origin"));
1437 needagain
= progress
= B_FALSE
;
1438 for (fspair
= nvlist_next_nvpair(sdd
->fss
, NULL
); fspair
;
1439 fspair
= nvlist_next_nvpair(sdd
->fss
, fspair
)) {
1440 nvlist_t
*fslist
, *parent_nv
;
1444 uint64_t origin_guid
= 0;
1445 uint64_t parent_guid
= 0;
1447 VERIFY(nvpair_value_nvlist(fspair
, &fslist
) == 0);
1448 if (nvlist_lookup_boolean(fslist
, "sent") == 0)
1451 VERIFY(nvlist_lookup_string(fslist
, "name", &fsname
) == 0);
1452 (void) nvlist_lookup_uint64(fslist
, "origin", &origin_guid
);
1453 (void) nvlist_lookup_uint64(fslist
, "parentfromsnap",
1456 if (parent_guid
!= 0) {
1457 parent_nv
= fsavl_find(sdd
->fsavl
, parent_guid
, NULL
);
1458 if (!nvlist_exists(parent_nv
, "sent")) {
1459 /* parent has not been sent; skip this one */
1465 if (origin_guid
!= 0) {
1466 nvlist_t
*origin_nv
= fsavl_find(sdd
->fsavl
,
1468 if (origin_nv
!= NULL
&&
1469 !nvlist_exists(origin_nv
, "sent")) {
1471 * origin has not been sent yet;
1479 zhp
= zfs_open(rzhp
->zfs_hdl
, fsname
, ZFS_TYPE_DATASET
);
1482 err
= dump_filesystem(zhp
, sdd
);
1483 VERIFY(nvlist_add_boolean(fslist
, "sent") == 0);
1494 /* clean out the sent flags in case we reuse this fss */
1495 for (fspair
= nvlist_next_nvpair(sdd
->fss
, NULL
); fspair
;
1496 fspair
= nvlist_next_nvpair(sdd
->fss
, fspair
)) {
1499 VERIFY(nvpair_value_nvlist(fspair
, &fslist
) == 0);
1500 (void) nvlist_remove_all(fslist
, "sent");
1507 zfs_send_resume_token_to_nvlist(libzfs_handle_t
*hdl
, const char *token
)
1509 unsigned int version
;
1511 unsigned long long checksum
, packed_len
;
1514 * Decode token header, which is:
1515 * <token version>-<checksum of payload>-<uncompressed payload length>
1516 * Note that the only supported token version is 1.
1518 nread
= sscanf(token
, "%u-%llx-%llx-",
1519 &version
, &checksum
, &packed_len
);
1521 zfs_error_aux(hdl
, dgettext(TEXT_DOMAIN
,
1522 "resume token is corrupt (invalid format)"));
1526 if (version
!= ZFS_SEND_RESUME_TOKEN_VERSION
) {
1527 zfs_error_aux(hdl
, dgettext(TEXT_DOMAIN
,
1528 "resume token is corrupt (invalid version %u)"),
1533 /* convert hexadecimal representation to binary */
1534 token
= strrchr(token
, '-') + 1;
1535 int len
= strlen(token
) / 2;
1536 unsigned char *compressed
= zfs_alloc(hdl
, len
);
1537 for (i
= 0; i
< len
; i
++) {
1538 nread
= sscanf(token
+ i
* 2, "%2hhx", compressed
+ i
);
1541 zfs_error_aux(hdl
, dgettext(TEXT_DOMAIN
,
1542 "resume token is corrupt "
1543 "(payload is not hex-encoded)"));
1548 /* verify checksum */
1550 fletcher_4_native_varsize(compressed
, len
, &cksum
);
1551 if (cksum
.zc_word
[0] != checksum
) {
1553 zfs_error_aux(hdl
, dgettext(TEXT_DOMAIN
,
1554 "resume token is corrupt (incorrect checksum)"));
1559 void *packed
= zfs_alloc(hdl
, packed_len
);
1560 uLongf packed_len_long
= packed_len
;
1561 if (uncompress(packed
, &packed_len_long
, compressed
, len
) != Z_OK
||
1562 packed_len_long
!= packed_len
) {
1565 zfs_error_aux(hdl
, dgettext(TEXT_DOMAIN
,
1566 "resume token is corrupt (decompression failed)"));
1572 int error
= nvlist_unpack(packed
, packed_len
, &nv
, KM_SLEEP
);
1576 zfs_error_aux(hdl
, dgettext(TEXT_DOMAIN
,
1577 "resume token is corrupt (nvlist_unpack failed)"));
1584 zfs_send_resume(libzfs_handle_t
*hdl
, sendflags_t
*flags
, int outfd
,
1585 const char *resume_token
)
1589 char *fromname
= NULL
;
1590 uint64_t resumeobj
, resumeoff
, toguid
, fromguid
, bytes
;
1593 char name
[ZFS_MAX_DATASET_NAME_LEN
];
1594 enum lzc_send_flags lzc_flags
= 0;
1596 (void) snprintf(errbuf
, sizeof (errbuf
), dgettext(TEXT_DOMAIN
,
1597 "cannot resume send"));
1599 nvlist_t
*resume_nvl
=
1600 zfs_send_resume_token_to_nvlist(hdl
, resume_token
);
1601 if (resume_nvl
== NULL
) {
1603 * zfs_error_aux has already been set by
1604 * zfs_send_resume_token_to_nvlist
1606 return (zfs_error(hdl
, EZFS_FAULT
, errbuf
));
1608 if (flags
->verbose
) {
1609 (void) fprintf(stderr
, dgettext(TEXT_DOMAIN
,
1610 "resume token contents:\n"));
1611 nvlist_print(stderr
, resume_nvl
);
1614 if (nvlist_lookup_string(resume_nvl
, "toname", &toname
) != 0 ||
1615 nvlist_lookup_uint64(resume_nvl
, "object", &resumeobj
) != 0 ||
1616 nvlist_lookup_uint64(resume_nvl
, "offset", &resumeoff
) != 0 ||
1617 nvlist_lookup_uint64(resume_nvl
, "bytes", &bytes
) != 0 ||
1618 nvlist_lookup_uint64(resume_nvl
, "toguid", &toguid
) != 0) {
1619 zfs_error_aux(hdl
, dgettext(TEXT_DOMAIN
,
1620 "resume token is corrupt"));
1621 return (zfs_error(hdl
, EZFS_FAULT
, errbuf
));
1624 (void) nvlist_lookup_uint64(resume_nvl
, "fromguid", &fromguid
);
1626 if (flags
->largeblock
|| nvlist_exists(resume_nvl
, "largeblockok"))
1627 lzc_flags
|= LZC_SEND_FLAG_LARGE_BLOCK
;
1628 if (flags
->embed_data
|| nvlist_exists(resume_nvl
, "embedok"))
1629 lzc_flags
|= LZC_SEND_FLAG_EMBED_DATA
;
1630 if (flags
->compress
|| nvlist_exists(resume_nvl
, "compressok"))
1631 lzc_flags
|= LZC_SEND_FLAG_COMPRESS
;
1633 if (guid_to_name(hdl
, toname
, toguid
, B_FALSE
, name
) != 0) {
1634 if (zfs_dataset_exists(hdl
, toname
, ZFS_TYPE_DATASET
)) {
1635 zfs_error_aux(hdl
, dgettext(TEXT_DOMAIN
,
1636 "'%s' is no longer the same snapshot used in "
1637 "the initial send"), toname
);
1639 zfs_error_aux(hdl
, dgettext(TEXT_DOMAIN
,
1640 "'%s' used in the initial send no longer exists"),
1643 return (zfs_error(hdl
, EZFS_BADPATH
, errbuf
));
1645 zhp
= zfs_open(hdl
, name
, ZFS_TYPE_DATASET
);
1647 zfs_error_aux(hdl
, dgettext(TEXT_DOMAIN
,
1648 "unable to access '%s'"), name
);
1649 return (zfs_error(hdl
, EZFS_BADPATH
, errbuf
));
1652 if (fromguid
!= 0) {
1653 if (guid_to_name(hdl
, toname
, fromguid
, B_TRUE
, name
) != 0) {
1654 zfs_error_aux(hdl
, dgettext(TEXT_DOMAIN
,
1655 "incremental source %#llx no longer exists"),
1656 (longlong_t
)fromguid
);
1657 return (zfs_error(hdl
, EZFS_BADPATH
, errbuf
));
1662 if (flags
->verbose
) {
1664 error
= lzc_send_space(zhp
->zfs_name
, fromname
,
1667 size
= MAX(0, (int64_t)(size
- bytes
));
1668 send_print_verbose(stderr
, zhp
->zfs_name
, fromname
,
1669 size
, flags
->parsable
);
1672 if (!flags
->dryrun
) {
1673 progress_arg_t pa
= { 0 };
1676 * If progress reporting is requested, spawn a new thread to
1677 * poll ZFS_IOC_SEND_PROGRESS at a regular interval.
1679 if (flags
->progress
) {
1682 pa
.pa_parsable
= flags
->parsable
;
1684 error
= pthread_create(&tid
, NULL
,
1685 send_progress_thread
, &pa
);
1692 error
= lzc_send_resume(zhp
->zfs_name
, fromname
, outfd
,
1693 lzc_flags
, resumeobj
, resumeoff
);
1695 if (flags
->progress
) {
1696 (void) pthread_cancel(tid
);
1697 (void) pthread_join(tid
, NULL
);
1701 (void) snprintf(errbuf
, sizeof (errbuf
), dgettext(TEXT_DOMAIN
,
1702 "warning: cannot send '%s'"), zhp
->zfs_name
);
1722 zfs_error_aux(hdl
, strerror(errno
));
1723 return (zfs_error(hdl
, EZFS_BADBACKUP
, errbuf
));
1726 return (zfs_standard_error(hdl
, errno
, errbuf
));
1737 * Generate a send stream for the dataset identified by the argument zhp.
1739 * The content of the send stream is the snapshot identified by
1740 * 'tosnap'. Incremental streams are requested in two ways:
1741 * - from the snapshot identified by "fromsnap" (if non-null) or
1742 * - from the origin of the dataset identified by zhp, which must
1743 * be a clone. In this case, "fromsnap" is null and "fromorigin"
1746 * The send stream is recursive (i.e. dumps a hierarchy of snapshots) and
1747 * uses a special header (with a hdrtype field of DMU_COMPOUNDSTREAM)
1748 * if "replicate" is set. If "doall" is set, dump all the intermediate
1749 * snapshots. The DMU_COMPOUNDSTREAM header is used in the "doall"
1750 * case too. If "props" is set, send properties.
1753 zfs_send(zfs_handle_t
*zhp
, const char *fromsnap
, const char *tosnap
,
1754 sendflags_t
*flags
, int outfd
, snapfilter_cb_t filter_func
,
1755 void *cb_arg
, nvlist_t
**debugnvp
)
1758 send_dump_data_t sdd
= { 0 };
1760 nvlist_t
*fss
= NULL
;
1761 avl_tree_t
*fsavl
= NULL
;
1762 static uint64_t holdseq
;
1766 dedup_arg_t dda
= { 0 };
1767 int featureflags
= 0;
1770 (void) snprintf(errbuf
, sizeof (errbuf
), dgettext(TEXT_DOMAIN
,
1771 "cannot send '%s'"), zhp
->zfs_name
);
1773 if (fromsnap
&& fromsnap
[0] == '\0') {
1774 zfs_error_aux(zhp
->zfs_hdl
, dgettext(TEXT_DOMAIN
,
1775 "zero-length incremental source"));
1776 return (zfs_error(zhp
->zfs_hdl
, EZFS_NOENT
, errbuf
));
1779 if (zhp
->zfs_type
== ZFS_TYPE_FILESYSTEM
) {
1781 version
= zfs_prop_get_int(zhp
, ZFS_PROP_VERSION
);
1782 if (version
>= ZPL_VERSION_SA
) {
1783 featureflags
|= DMU_BACKUP_FEATURE_SA_SPILL
;
1787 if (flags
->dedup
&& !flags
->dryrun
) {
1788 featureflags
|= (DMU_BACKUP_FEATURE_DEDUP
|
1789 DMU_BACKUP_FEATURE_DEDUPPROPS
);
1790 if ((err
= socketpair(AF_UNIX
, SOCK_STREAM
, 0, pipefd
))) {
1791 zfs_error_aux(zhp
->zfs_hdl
, strerror(errno
));
1792 return (zfs_error(zhp
->zfs_hdl
, EZFS_PIPEFAILED
,
1795 dda
.outputfd
= outfd
;
1796 dda
.inputfd
= pipefd
[1];
1797 dda
.dedup_hdl
= zhp
->zfs_hdl
;
1798 if ((err
= pthread_create(&tid
, NULL
, cksummer
, &dda
))) {
1799 (void) close(pipefd
[0]);
1800 (void) close(pipefd
[1]);
1801 zfs_error_aux(zhp
->zfs_hdl
, strerror(errno
));
1802 return (zfs_error(zhp
->zfs_hdl
,
1803 EZFS_THREADCREATEFAILED
, errbuf
));
1807 if (flags
->replicate
|| flags
->doall
|| flags
->props
) {
1808 dmu_replay_record_t drr
= { 0 };
1809 char *packbuf
= NULL
;
1813 ZIO_SET_CHECKSUM(&zc
, 0, 0, 0, 0);
1815 if (flags
->replicate
|| flags
->props
) {
1818 VERIFY(0 == nvlist_alloc(&hdrnv
, NV_UNIQUE_NAME
, 0));
1820 VERIFY(0 == nvlist_add_string(hdrnv
,
1821 "fromsnap", fromsnap
));
1823 VERIFY(0 == nvlist_add_string(hdrnv
, "tosnap", tosnap
));
1824 if (!flags
->replicate
) {
1825 VERIFY(0 == nvlist_add_boolean(hdrnv
,
1829 err
= gather_nvlist(zhp
->zfs_hdl
, zhp
->zfs_name
,
1830 fromsnap
, tosnap
, flags
->replicate
, flags
->verbose
,
1834 VERIFY(0 == nvlist_add_nvlist(hdrnv
, "fss", fss
));
1835 err
= nvlist_pack(hdrnv
, &packbuf
, &buflen
,
1845 if (!flags
->dryrun
) {
1846 /* write first begin record */
1847 drr
.drr_type
= DRR_BEGIN
;
1848 drr
.drr_u
.drr_begin
.drr_magic
= DMU_BACKUP_MAGIC
;
1849 DMU_SET_STREAM_HDRTYPE(drr
.drr_u
.drr_begin
.
1850 drr_versioninfo
, DMU_COMPOUNDSTREAM
);
1851 DMU_SET_FEATUREFLAGS(drr
.drr_u
.drr_begin
.
1852 drr_versioninfo
, featureflags
);
1853 (void) snprintf(drr
.drr_u
.drr_begin
.drr_toname
,
1854 sizeof (drr
.drr_u
.drr_begin
.drr_toname
),
1855 "%s@%s", zhp
->zfs_name
, tosnap
);
1856 drr
.drr_payloadlen
= buflen
;
1858 err
= dump_record(&drr
, packbuf
, buflen
, &zc
, outfd
);
1863 /* write end record */
1864 bzero(&drr
, sizeof (drr
));
1865 drr
.drr_type
= DRR_END
;
1866 drr
.drr_u
.drr_end
.drr_checksum
= zc
;
1867 err
= write(outfd
, &drr
, sizeof (drr
));
1877 /* dump each stream */
1878 sdd
.fromsnap
= fromsnap
;
1879 sdd
.tosnap
= tosnap
;
1881 sdd
.outfd
= pipefd
[0];
1884 sdd
.replicate
= flags
->replicate
;
1885 sdd
.doall
= flags
->doall
;
1886 sdd
.fromorigin
= flags
->fromorigin
;
1889 sdd
.verbose
= flags
->verbose
;
1890 sdd
.parsable
= flags
->parsable
;
1891 sdd
.progress
= flags
->progress
;
1892 sdd
.dryrun
= flags
->dryrun
;
1893 sdd
.large_block
= flags
->largeblock
;
1894 sdd
.embed_data
= flags
->embed_data
;
1895 sdd
.compress
= flags
->compress
;
1896 sdd
.filter_cb
= filter_func
;
1897 sdd
.filter_cb_arg
= cb_arg
;
1899 sdd
.debugnv
= *debugnvp
;
1900 if (sdd
.verbose
&& sdd
.dryrun
)
1901 sdd
.std_out
= B_TRUE
;
1902 fout
= sdd
.std_out
? stdout
: stderr
;
1905 * Some flags require that we place user holds on the datasets that are
1906 * being sent so they don't get destroyed during the send. We can skip
1907 * this step if the pool is imported read-only since the datasets cannot
1910 if (!flags
->dryrun
&& !zpool_get_prop_int(zfs_get_pool_handle(zhp
),
1911 ZPOOL_PROP_READONLY
, NULL
) &&
1912 zfs_spa_version(zhp
, &spa_version
) == 0 &&
1913 spa_version
>= SPA_VERSION_USERREFS
&&
1914 (flags
->doall
|| flags
->replicate
)) {
1916 (void) snprintf(sdd
.holdtag
, sizeof (sdd
.holdtag
),
1917 ".send-%d-%llu", getpid(), (u_longlong_t
)holdseq
);
1918 sdd
.cleanup_fd
= open(ZFS_DEV
, O_RDWR
);
1919 if (sdd
.cleanup_fd
< 0) {
1923 sdd
.snapholds
= fnvlist_alloc();
1925 sdd
.cleanup_fd
= -1;
1926 sdd
.snapholds
= NULL
;
1928 if (flags
->verbose
|| sdd
.snapholds
!= NULL
) {
1930 * Do a verbose no-op dry run to get all the verbose output
1931 * or to gather snapshot hold's before generating any data,
1932 * then do a non-verbose real run to generate the streams.
1934 sdd
.dryrun
= B_TRUE
;
1935 err
= dump_filesystems(zhp
, &sdd
);
1940 if (flags
->verbose
) {
1941 if (flags
->parsable
) {
1942 (void) fprintf(fout
, "size\t%llu\n",
1943 (longlong_t
)sdd
.size
);
1946 zfs_nicenum(sdd
.size
, buf
, sizeof (buf
));
1947 (void) fprintf(fout
, dgettext(TEXT_DOMAIN
,
1948 "total estimated size is %s\n"), buf
);
1952 /* Ensure no snaps found is treated as an error. */
1958 /* Skip the second run if dryrun was requested. */
1962 if (sdd
.snapholds
!= NULL
) {
1963 err
= zfs_hold_nvl(zhp
, sdd
.cleanup_fd
, sdd
.snapholds
);
1967 fnvlist_free(sdd
.snapholds
);
1968 sdd
.snapholds
= NULL
;
1971 sdd
.dryrun
= B_FALSE
;
1972 sdd
.verbose
= B_FALSE
;
1975 err
= dump_filesystems(zhp
, &sdd
);
1976 fsavl_destroy(fsavl
);
1979 /* Ensure no snaps found is treated as an error. */
1980 if (err
== 0 && !sdd
.seento
)
1985 (void) pthread_cancel(tid
);
1986 (void) close(pipefd
[0]);
1987 (void) pthread_join(tid
, NULL
);
1990 if (sdd
.cleanup_fd
!= -1) {
1991 VERIFY(0 == close(sdd
.cleanup_fd
));
1992 sdd
.cleanup_fd
= -1;
1995 if (!flags
->dryrun
&& (flags
->replicate
|| flags
->doall
||
1998 * write final end record. NB: want to do this even if
1999 * there was some error, because it might not be totally
2002 dmu_replay_record_t drr
= { 0 };
2003 drr
.drr_type
= DRR_END
;
2004 if (write(outfd
, &drr
, sizeof (drr
)) == -1) {
2005 return (zfs_standard_error(zhp
->zfs_hdl
,
2010 return (err
|| sdd
.err
);
2013 err
= zfs_standard_error(zhp
->zfs_hdl
, err
, errbuf
);
2015 fsavl_destroy(fsavl
);
2017 fnvlist_free(sdd
.snapholds
);
2019 if (sdd
.cleanup_fd
!= -1)
2020 VERIFY(0 == close(sdd
.cleanup_fd
));
2022 (void) pthread_cancel(tid
);
2023 (void) close(pipefd
[0]);
2024 (void) pthread_join(tid
, NULL
);
2030 zfs_send_one(zfs_handle_t
*zhp
, const char *from
, int fd
,
2031 enum lzc_send_flags flags
)
2034 libzfs_handle_t
*hdl
= zhp
->zfs_hdl
;
2037 (void) snprintf(errbuf
, sizeof (errbuf
), dgettext(TEXT_DOMAIN
,
2038 "warning: cannot send '%s'"), zhp
->zfs_name
);
2040 err
= lzc_send(zhp
->zfs_name
, from
, fd
, flags
);
2044 zfs_error_aux(hdl
, dgettext(TEXT_DOMAIN
,
2045 "not an earlier snapshot from the same fs"));
2046 return (zfs_error(hdl
, EZFS_CROSSTARGET
, errbuf
));
2050 if (lzc_exists(zhp
->zfs_name
)) {
2051 zfs_error_aux(hdl
, dgettext(TEXT_DOMAIN
,
2052 "incremental source (%s) does not exist"),
2055 return (zfs_error(hdl
, EZFS_NOENT
, errbuf
));
2058 zfs_error_aux(hdl
, dgettext(TEXT_DOMAIN
,
2059 "target is busy; if a filesystem, "
2060 "it must not be mounted"));
2061 return (zfs_error(hdl
, EZFS_BUSY
, errbuf
));
2074 zfs_error_aux(hdl
, strerror(errno
));
2075 return (zfs_error(hdl
, EZFS_BADBACKUP
, errbuf
));
2078 return (zfs_standard_error(hdl
, errno
, errbuf
));
2085 * Routines specific to "zfs recv"
2089 recv_read(libzfs_handle_t
*hdl
, int fd
, void *buf
, int ilen
,
2090 boolean_t byteswap
, zio_cksum_t
*zc
)
2096 assert(ilen
<= SPA_MAXBLOCKSIZE
);
2099 rv
= read(fd
, cp
, len
);
2104 if (rv
< 0 || len
!= 0) {
2105 zfs_error_aux(hdl
, dgettext(TEXT_DOMAIN
,
2106 "failed to read from stream"));
2107 return (zfs_error(hdl
, EZFS_BADSTREAM
, dgettext(TEXT_DOMAIN
,
2108 "cannot receive")));
2113 fletcher_4_incremental_byteswap(buf
, ilen
, zc
);
2115 fletcher_4_incremental_native(buf
, ilen
, zc
);
2121 recv_read_nvlist(libzfs_handle_t
*hdl
, int fd
, int len
, nvlist_t
**nvp
,
2122 boolean_t byteswap
, zio_cksum_t
*zc
)
2127 buf
= zfs_alloc(hdl
, len
);
2131 err
= recv_read(hdl
, fd
, buf
, len
, byteswap
, zc
);
2137 err
= nvlist_unpack(buf
, len
, nvp
, 0);
2140 zfs_error_aux(hdl
, dgettext(TEXT_DOMAIN
, "invalid "
2141 "stream (malformed nvlist)"));
2148 recv_rename(libzfs_handle_t
*hdl
, const char *name
, const char *tryname
,
2149 int baselen
, char *newname
, recvflags_t
*flags
)
2152 zfs_cmd_t zc
= {"\0"};
2154 prop_changelist_t
*clp
;
2157 zhp
= zfs_open(hdl
, name
, ZFS_TYPE_DATASET
);
2160 clp
= changelist_gather(zhp
, ZFS_PROP_NAME
, 0,
2161 flags
->force
? MS_FORCE
: 0);
2165 err
= changelist_prefix(clp
);
2169 zc
.zc_objset_type
= DMU_OST_ZFS
;
2170 (void) strlcpy(zc
.zc_name
, name
, sizeof (zc
.zc_name
));
2173 (void) strcpy(newname
, tryname
);
2175 (void) strlcpy(zc
.zc_value
, tryname
, sizeof (zc
.zc_value
));
2177 if (flags
->verbose
) {
2178 (void) printf("attempting rename %s to %s\n",
2179 zc
.zc_name
, zc
.zc_value
);
2181 err
= ioctl(hdl
->libzfs_fd
, ZFS_IOC_RENAME
, &zc
);
2183 changelist_rename(clp
, name
, tryname
);
2188 if (err
!= 0 && strncmp(name
+ baselen
, "recv-", 5) != 0) {
2191 (void) snprintf(newname
, ZFS_MAX_DATASET_NAME_LEN
,
2192 "%.*srecv-%u-%u", baselen
, name
, getpid(), seq
);
2193 (void) strlcpy(zc
.zc_value
, newname
, sizeof (zc
.zc_value
));
2195 if (flags
->verbose
) {
2196 (void) printf("failed - trying rename %s to %s\n",
2197 zc
.zc_name
, zc
.zc_value
);
2199 err
= ioctl(hdl
->libzfs_fd
, ZFS_IOC_RENAME
, &zc
);
2201 changelist_rename(clp
, name
, newname
);
2202 if (err
&& flags
->verbose
) {
2203 (void) printf("failed (%u) - "
2204 "will try again on next pass\n", errno
);
2207 } else if (flags
->verbose
) {
2209 (void) printf("success\n");
2211 (void) printf("failed (%u)\n", errno
);
2214 (void) changelist_postfix(clp
);
2215 changelist_free(clp
);
2221 recv_destroy(libzfs_handle_t
*hdl
, const char *name
, int baselen
,
2222 char *newname
, recvflags_t
*flags
)
2224 zfs_cmd_t zc
= {"\0"};
2226 prop_changelist_t
*clp
;
2228 boolean_t defer
= B_FALSE
;
2231 zhp
= zfs_open(hdl
, name
, ZFS_TYPE_DATASET
);
2234 clp
= changelist_gather(zhp
, ZFS_PROP_NAME
, 0,
2235 flags
->force
? MS_FORCE
: 0);
2236 if (zfs_get_type(zhp
) == ZFS_TYPE_SNAPSHOT
&&
2237 zfs_spa_version(zhp
, &spa_version
) == 0 &&
2238 spa_version
>= SPA_VERSION_USERREFS
)
2243 err
= changelist_prefix(clp
);
2247 zc
.zc_objset_type
= DMU_OST_ZFS
;
2248 zc
.zc_defer_destroy
= defer
;
2249 (void) strlcpy(zc
.zc_name
, name
, sizeof (zc
.zc_name
));
2252 (void) printf("attempting destroy %s\n", zc
.zc_name
);
2253 err
= ioctl(hdl
->libzfs_fd
, ZFS_IOC_DESTROY
, &zc
);
2256 (void) printf("success\n");
2257 changelist_remove(clp
, zc
.zc_name
);
2260 (void) changelist_postfix(clp
);
2261 changelist_free(clp
);
2264 * Deferred destroy might destroy the snapshot or only mark it to be
2265 * destroyed later, and it returns success in either case.
2267 if (err
!= 0 || (defer
&& zfs_dataset_exists(hdl
, name
,
2268 ZFS_TYPE_SNAPSHOT
))) {
2269 err
= recv_rename(hdl
, name
, NULL
, baselen
, newname
, flags
);
2275 typedef struct guid_to_name_data
{
2277 boolean_t bookmark_ok
;
2280 } guid_to_name_data_t
;
2283 guid_to_name_cb(zfs_handle_t
*zhp
, void *arg
)
2285 guid_to_name_data_t
*gtnd
= arg
;
2289 if (gtnd
->skip
!= NULL
&&
2290 (slash
= strrchr(zhp
->zfs_name
, '/')) != NULL
&&
2291 strcmp(slash
+ 1, gtnd
->skip
) == 0) {
2296 if (zfs_prop_get_int(zhp
, ZFS_PROP_GUID
) == gtnd
->guid
) {
2297 (void) strcpy(gtnd
->name
, zhp
->zfs_name
);
2302 err
= zfs_iter_children(zhp
, guid_to_name_cb
, gtnd
);
2303 if (err
!= EEXIST
&& gtnd
->bookmark_ok
)
2304 err
= zfs_iter_bookmarks(zhp
, guid_to_name_cb
, gtnd
);
2310 * Attempt to find the local dataset associated with this guid. In the case of
2311 * multiple matches, we attempt to find the "best" match by searching
2312 * progressively larger portions of the hierarchy. This allows one to send a
2313 * tree of datasets individually and guarantee that we will find the source
2314 * guid within that hierarchy, even if there are multiple matches elsewhere.
2317 guid_to_name(libzfs_handle_t
*hdl
, const char *parent
, uint64_t guid
,
2318 boolean_t bookmark_ok
, char *name
)
2320 char pname
[ZFS_MAX_DATASET_NAME_LEN
];
2321 guid_to_name_data_t gtnd
;
2324 gtnd
.bookmark_ok
= bookmark_ok
;
2329 * Search progressively larger portions of the hierarchy, starting
2330 * with the filesystem specified by 'parent'. This will
2331 * select the "most local" version of the origin snapshot in the case
2332 * that there are multiple matching snapshots in the system.
2334 (void) strlcpy(pname
, parent
, sizeof (pname
));
2335 char *cp
= strrchr(pname
, '@');
2337 cp
= strchr(pname
, '\0');
2338 for (; cp
!= NULL
; cp
= strrchr(pname
, '/')) {
2339 /* Chop off the last component and open the parent */
2341 zfs_handle_t
*zhp
= make_dataset_handle(hdl
, pname
);
2345 int err
= guid_to_name_cb(zfs_handle_dup(zhp
), >nd
);
2347 err
= zfs_iter_children(zhp
, guid_to_name_cb
, >nd
);
2348 if (err
!= EEXIST
&& bookmark_ok
)
2349 err
= zfs_iter_bookmarks(zhp
, guid_to_name_cb
, >nd
);
2355 * Remember the last portion of the dataset so we skip it next
2356 * time through (as we've already searched that portion of the
2359 gtnd
.skip
= strrchr(pname
, '/') + 1;
2366 * Return +1 if guid1 is before guid2, 0 if they are the same, and -1 if
2367 * guid1 is after guid2.
2370 created_before(libzfs_handle_t
*hdl
, avl_tree_t
*avl
,
2371 uint64_t guid1
, uint64_t guid2
)
2374 char *fsname
= NULL
, *snapname
= NULL
;
2375 char buf
[ZFS_MAX_DATASET_NAME_LEN
];
2377 zfs_handle_t
*guid1hdl
, *guid2hdl
;
2378 uint64_t create1
, create2
;
2385 nvfs
= fsavl_find(avl
, guid1
, &snapname
);
2386 VERIFY(0 == nvlist_lookup_string(nvfs
, "name", &fsname
));
2387 (void) snprintf(buf
, sizeof (buf
), "%s@%s", fsname
, snapname
);
2388 guid1hdl
= zfs_open(hdl
, buf
, ZFS_TYPE_SNAPSHOT
);
2389 if (guid1hdl
== NULL
)
2392 nvfs
= fsavl_find(avl
, guid2
, &snapname
);
2393 VERIFY(0 == nvlist_lookup_string(nvfs
, "name", &fsname
));
2394 (void) snprintf(buf
, sizeof (buf
), "%s@%s", fsname
, snapname
);
2395 guid2hdl
= zfs_open(hdl
, buf
, ZFS_TYPE_SNAPSHOT
);
2396 if (guid2hdl
== NULL
) {
2397 zfs_close(guid1hdl
);
2401 create1
= zfs_prop_get_int(guid1hdl
, ZFS_PROP_CREATETXG
);
2402 create2
= zfs_prop_get_int(guid2hdl
, ZFS_PROP_CREATETXG
);
2404 if (create1
< create2
)
2406 else if (create1
> create2
)
2411 zfs_close(guid1hdl
);
2412 zfs_close(guid2hdl
);
2418 recv_incremental_replication(libzfs_handle_t
*hdl
, const char *tofs
,
2419 recvflags_t
*flags
, nvlist_t
*stream_nv
, avl_tree_t
*stream_avl
,
2422 nvlist_t
*local_nv
, *deleted
= NULL
;
2423 avl_tree_t
*local_avl
;
2424 nvpair_t
*fselem
, *nextfselem
;
2426 char newname
[ZFS_MAX_DATASET_NAME_LEN
];
2429 boolean_t needagain
, progress
, recursive
;
2432 VERIFY(0 == nvlist_lookup_string(stream_nv
, "fromsnap", &fromsnap
));
2434 recursive
= (nvlist_lookup_boolean(stream_nv
, "not_recursive") ==
2441 needagain
= progress
= B_FALSE
;
2443 VERIFY(0 == nvlist_alloc(&deleted
, NV_UNIQUE_NAME
, 0));
2445 if ((error
= gather_nvlist(hdl
, tofs
, fromsnap
, NULL
,
2446 recursive
, B_FALSE
, &local_nv
, &local_avl
)) != 0)
2450 * Process deletes and renames
2452 for (fselem
= nvlist_next_nvpair(local_nv
, NULL
);
2453 fselem
; fselem
= nextfselem
) {
2454 nvlist_t
*nvfs
, *snaps
;
2455 nvlist_t
*stream_nvfs
= NULL
;
2456 nvpair_t
*snapelem
, *nextsnapelem
;
2457 uint64_t fromguid
= 0;
2458 uint64_t originguid
= 0;
2459 uint64_t stream_originguid
= 0;
2460 uint64_t parent_fromsnap_guid
, stream_parent_fromsnap_guid
;
2461 char *fsname
, *stream_fsname
;
2463 nextfselem
= nvlist_next_nvpair(local_nv
, fselem
);
2465 VERIFY(0 == nvpair_value_nvlist(fselem
, &nvfs
));
2466 VERIFY(0 == nvlist_lookup_nvlist(nvfs
, "snaps", &snaps
));
2467 VERIFY(0 == nvlist_lookup_string(nvfs
, "name", &fsname
));
2468 VERIFY(0 == nvlist_lookup_uint64(nvfs
, "parentfromsnap",
2469 &parent_fromsnap_guid
));
2470 (void) nvlist_lookup_uint64(nvfs
, "origin", &originguid
);
2473 * First find the stream's fs, so we can check for
2474 * a different origin (due to "zfs promote")
2476 for (snapelem
= nvlist_next_nvpair(snaps
, NULL
);
2477 snapelem
; snapelem
= nvlist_next_nvpair(snaps
, snapelem
)) {
2480 VERIFY(0 == nvpair_value_uint64(snapelem
, &thisguid
));
2481 stream_nvfs
= fsavl_find(stream_avl
, thisguid
, NULL
);
2483 if (stream_nvfs
!= NULL
)
2487 /* check for promote */
2488 (void) nvlist_lookup_uint64(stream_nvfs
, "origin",
2489 &stream_originguid
);
2490 if (stream_nvfs
&& originguid
!= stream_originguid
) {
2491 switch (created_before(hdl
, local_avl
,
2492 stream_originguid
, originguid
)) {
2495 zfs_cmd_t zc
= {"\0"};
2496 nvlist_t
*origin_nvfs
;
2497 char *origin_fsname
;
2500 (void) printf("promoting %s\n", fsname
);
2502 origin_nvfs
= fsavl_find(local_avl
, originguid
,
2504 VERIFY(0 == nvlist_lookup_string(origin_nvfs
,
2505 "name", &origin_fsname
));
2506 (void) strlcpy(zc
.zc_value
, origin_fsname
,
2507 sizeof (zc
.zc_value
));
2508 (void) strlcpy(zc
.zc_name
, fsname
,
2509 sizeof (zc
.zc_name
));
2510 error
= zfs_ioctl(hdl
, ZFS_IOC_PROMOTE
, &zc
);
2518 fsavl_destroy(local_avl
);
2519 nvlist_free(local_nv
);
2523 * We had/have the wrong origin, therefore our
2524 * list of snapshots is wrong. Need to handle
2525 * them on the next pass.
2531 for (snapelem
= nvlist_next_nvpair(snaps
, NULL
);
2532 snapelem
; snapelem
= nextsnapelem
) {
2534 char *stream_snapname
;
2535 nvlist_t
*found
, *props
;
2537 nextsnapelem
= nvlist_next_nvpair(snaps
, snapelem
);
2539 VERIFY(0 == nvpair_value_uint64(snapelem
, &thisguid
));
2540 found
= fsavl_find(stream_avl
, thisguid
,
2543 /* check for delete */
2544 if (found
== NULL
) {
2545 char name
[ZFS_MAX_DATASET_NAME_LEN
];
2550 (void) snprintf(name
, sizeof (name
), "%s@%s",
2551 fsname
, nvpair_name(snapelem
));
2553 error
= recv_destroy(hdl
, name
,
2554 strlen(fsname
)+1, newname
, flags
);
2559 sprintf(guidname
, "%llu",
2560 (u_longlong_t
)thisguid
);
2561 nvlist_add_boolean(deleted
, guidname
);
2565 stream_nvfs
= found
;
2567 if (0 == nvlist_lookup_nvlist(stream_nvfs
, "snapprops",
2568 &props
) && 0 == nvlist_lookup_nvlist(props
,
2569 stream_snapname
, &props
)) {
2570 zfs_cmd_t zc
= {"\0"};
2572 zc
.zc_cookie
= B_TRUE
; /* received */
2573 (void) snprintf(zc
.zc_name
, sizeof (zc
.zc_name
),
2574 "%s@%s", fsname
, nvpair_name(snapelem
));
2575 if (zcmd_write_src_nvlist(hdl
, &zc
,
2577 (void) zfs_ioctl(hdl
,
2578 ZFS_IOC_SET_PROP
, &zc
);
2579 zcmd_free_nvlists(&zc
);
2583 /* check for different snapname */
2584 if (strcmp(nvpair_name(snapelem
),
2585 stream_snapname
) != 0) {
2586 char name
[ZFS_MAX_DATASET_NAME_LEN
];
2587 char tryname
[ZFS_MAX_DATASET_NAME_LEN
];
2589 (void) snprintf(name
, sizeof (name
), "%s@%s",
2590 fsname
, nvpair_name(snapelem
));
2591 (void) snprintf(tryname
, sizeof (name
), "%s@%s",
2592 fsname
, stream_snapname
);
2594 error
= recv_rename(hdl
, name
, tryname
,
2595 strlen(fsname
)+1, newname
, flags
);
2602 if (strcmp(stream_snapname
, fromsnap
) == 0)
2603 fromguid
= thisguid
;
2606 /* check for delete */
2607 if (stream_nvfs
== NULL
) {
2611 error
= recv_destroy(hdl
, fsname
, strlen(tofs
)+1,
2617 sprintf(guidname
, "%llu",
2618 (u_longlong_t
) parent_fromsnap_guid
);
2619 nvlist_add_boolean(deleted
, guidname
);
2623 if (fromguid
== 0) {
2624 if (flags
->verbose
) {
2625 (void) printf("local fs %s does not have "
2626 "fromsnap (%s in stream); must have "
2627 "been deleted locally; ignoring\n",
2633 VERIFY(0 == nvlist_lookup_string(stream_nvfs
,
2634 "name", &stream_fsname
));
2635 VERIFY(0 == nvlist_lookup_uint64(stream_nvfs
,
2636 "parentfromsnap", &stream_parent_fromsnap_guid
));
2638 s1
= strrchr(fsname
, '/');
2639 s2
= strrchr(stream_fsname
, '/');
2642 * Check if we're going to rename based on parent guid change
2643 * and the current parent guid was also deleted. If it was then
2644 * rename will fail and is likely unneeded, so avoid this and
2645 * force an early retry to determine the new
2646 * parent_fromsnap_guid.
2648 if (stream_parent_fromsnap_guid
!= 0 &&
2649 parent_fromsnap_guid
!= 0 &&
2650 stream_parent_fromsnap_guid
!= parent_fromsnap_guid
) {
2651 sprintf(guidname
, "%llu",
2652 (u_longlong_t
) parent_fromsnap_guid
);
2653 if (nvlist_exists(deleted
, guidname
)) {
2661 * Check for rename. If the exact receive path is specified, it
2662 * does not count as a rename, but we still need to check the
2663 * datasets beneath it.
2665 if ((stream_parent_fromsnap_guid
!= 0 &&
2666 parent_fromsnap_guid
!= 0 &&
2667 stream_parent_fromsnap_guid
!= parent_fromsnap_guid
) ||
2668 ((flags
->isprefix
|| strcmp(tofs
, fsname
) != 0) &&
2669 (s1
!= NULL
) && (s2
!= NULL
) && strcmp(s1
, s2
) != 0)) {
2671 char tryname
[ZFS_MAX_DATASET_NAME_LEN
];
2673 parent
= fsavl_find(local_avl
,
2674 stream_parent_fromsnap_guid
, NULL
);
2676 * NB: parent might not be found if we used the
2677 * tosnap for stream_parent_fromsnap_guid,
2678 * because the parent is a newly-created fs;
2679 * we'll be able to rename it after we recv the
2682 if (parent
!= NULL
) {
2685 VERIFY(0 == nvlist_lookup_string(parent
, "name",
2687 (void) snprintf(tryname
, sizeof (tryname
),
2688 "%s%s", pname
, strrchr(stream_fsname
, '/'));
2691 if (flags
->verbose
) {
2692 (void) printf("local fs %s new parent "
2693 "not found\n", fsname
);
2699 error
= recv_rename(hdl
, fsname
, tryname
,
2700 strlen(tofs
)+1, newname
, flags
);
2702 if (renamed
!= NULL
&& newname
[0] != '\0') {
2703 VERIFY(0 == nvlist_add_boolean(renamed
,
2715 fsavl_destroy(local_avl
);
2716 nvlist_free(local_nv
);
2717 nvlist_free(deleted
);
2719 if (needagain
&& progress
) {
2720 /* do another pass to fix up temporary names */
2722 (void) printf("another pass:\n");
2730 zfs_receive_package(libzfs_handle_t
*hdl
, int fd
, const char *destname
,
2731 recvflags_t
*flags
, dmu_replay_record_t
*drr
, zio_cksum_t
*zc
,
2732 char **top_zfs
, int cleanup_fd
, uint64_t *action_handlep
)
2734 nvlist_t
*stream_nv
= NULL
;
2735 avl_tree_t
*stream_avl
= NULL
;
2736 char *fromsnap
= NULL
;
2737 char *sendsnap
= NULL
;
2739 char tofs
[ZFS_MAX_DATASET_NAME_LEN
];
2740 char sendfs
[ZFS_MAX_DATASET_NAME_LEN
];
2742 dmu_replay_record_t drre
;
2744 boolean_t anyerr
= B_FALSE
;
2745 boolean_t softerr
= B_FALSE
;
2746 boolean_t recursive
;
2748 (void) snprintf(errbuf
, sizeof (errbuf
), dgettext(TEXT_DOMAIN
,
2751 assert(drr
->drr_type
== DRR_BEGIN
);
2752 assert(drr
->drr_u
.drr_begin
.drr_magic
== DMU_BACKUP_MAGIC
);
2753 assert(DMU_GET_STREAM_HDRTYPE(drr
->drr_u
.drr_begin
.drr_versioninfo
) ==
2754 DMU_COMPOUNDSTREAM
);
2757 * Read in the nvlist from the stream.
2759 if (drr
->drr_payloadlen
!= 0) {
2760 error
= recv_read_nvlist(hdl
, fd
, drr
->drr_payloadlen
,
2761 &stream_nv
, flags
->byteswap
, zc
);
2763 error
= zfs_error(hdl
, EZFS_BADSTREAM
, errbuf
);
2768 recursive
= (nvlist_lookup_boolean(stream_nv
, "not_recursive") ==
2771 if (recursive
&& strchr(destname
, '@')) {
2772 zfs_error_aux(hdl
, dgettext(TEXT_DOMAIN
,
2773 "cannot specify snapshot name for multi-snapshot stream"));
2774 error
= zfs_error(hdl
, EZFS_BADSTREAM
, errbuf
);
2779 * Read in the end record and verify checksum.
2781 if (0 != (error
= recv_read(hdl
, fd
, &drre
, sizeof (drre
),
2782 flags
->byteswap
, NULL
)))
2784 if (flags
->byteswap
) {
2785 drre
.drr_type
= BSWAP_32(drre
.drr_type
);
2786 drre
.drr_u
.drr_end
.drr_checksum
.zc_word
[0] =
2787 BSWAP_64(drre
.drr_u
.drr_end
.drr_checksum
.zc_word
[0]);
2788 drre
.drr_u
.drr_end
.drr_checksum
.zc_word
[1] =
2789 BSWAP_64(drre
.drr_u
.drr_end
.drr_checksum
.zc_word
[1]);
2790 drre
.drr_u
.drr_end
.drr_checksum
.zc_word
[2] =
2791 BSWAP_64(drre
.drr_u
.drr_end
.drr_checksum
.zc_word
[2]);
2792 drre
.drr_u
.drr_end
.drr_checksum
.zc_word
[3] =
2793 BSWAP_64(drre
.drr_u
.drr_end
.drr_checksum
.zc_word
[3]);
2795 if (drre
.drr_type
!= DRR_END
) {
2796 error
= zfs_error(hdl
, EZFS_BADSTREAM
, errbuf
);
2799 if (!ZIO_CHECKSUM_EQUAL(drre
.drr_u
.drr_end
.drr_checksum
, *zc
)) {
2800 zfs_error_aux(hdl
, dgettext(TEXT_DOMAIN
,
2801 "incorrect header checksum"));
2802 error
= zfs_error(hdl
, EZFS_BADSTREAM
, errbuf
);
2806 (void) nvlist_lookup_string(stream_nv
, "fromsnap", &fromsnap
);
2808 if (drr
->drr_payloadlen
!= 0) {
2809 nvlist_t
*stream_fss
;
2811 VERIFY(0 == nvlist_lookup_nvlist(stream_nv
, "fss",
2813 if ((stream_avl
= fsavl_create(stream_fss
)) == NULL
) {
2814 zfs_error_aux(hdl
, dgettext(TEXT_DOMAIN
,
2815 "couldn't allocate avl tree"));
2816 error
= zfs_error(hdl
, EZFS_NOMEM
, errbuf
);
2820 if (fromsnap
!= NULL
) {
2821 nvlist_t
*renamed
= NULL
;
2822 nvpair_t
*pair
= NULL
;
2824 (void) strlcpy(tofs
, destname
, sizeof (tofs
));
2825 if (flags
->isprefix
) {
2826 struct drr_begin
*drrb
= &drr
->drr_u
.drr_begin
;
2829 if (flags
->istail
) {
2830 cp
= strrchr(drrb
->drr_toname
, '/');
2832 (void) strlcat(tofs
, "/",
2836 i
= (cp
- drrb
->drr_toname
);
2839 i
= strcspn(drrb
->drr_toname
, "/@");
2841 /* zfs_receive_one() will create_parents() */
2842 (void) strlcat(tofs
, &drrb
->drr_toname
[i
],
2844 *strchr(tofs
, '@') = '\0';
2847 if (recursive
&& !flags
->dryrun
&& !flags
->nomount
) {
2848 VERIFY(0 == nvlist_alloc(&renamed
,
2849 NV_UNIQUE_NAME
, 0));
2852 softerr
= recv_incremental_replication(hdl
, tofs
, flags
,
2853 stream_nv
, stream_avl
, renamed
);
2855 /* Unmount renamed filesystems before receiving. */
2856 while ((pair
= nvlist_next_nvpair(renamed
,
2859 prop_changelist_t
*clp
= NULL
;
2861 zhp
= zfs_open(hdl
, nvpair_name(pair
),
2862 ZFS_TYPE_FILESYSTEM
);
2864 clp
= changelist_gather(zhp
,
2865 ZFS_PROP_MOUNTPOINT
, 0, 0);
2869 changelist_prefix(clp
);
2870 changelist_free(clp
);
2875 nvlist_free(renamed
);
2880 * Get the fs specified by the first path in the stream (the top level
2881 * specified by 'zfs send') and pass it to each invocation of
2882 * zfs_receive_one().
2884 (void) strlcpy(sendfs
, drr
->drr_u
.drr_begin
.drr_toname
,
2886 if ((cp
= strchr(sendfs
, '@')) != NULL
) {
2889 * Find the "sendsnap", the final snapshot in a replication
2890 * stream. zfs_receive_one() handles certain errors
2891 * differently, depending on if the contained stream is the
2894 sendsnap
= (cp
+ 1);
2897 /* Finally, receive each contained stream */
2900 * we should figure out if it has a recoverable
2901 * error, in which case do a recv_skip() and drive on.
2902 * Note, if we fail due to already having this guid,
2903 * zfs_receive_one() will take care of it (ie,
2904 * recv_skip() and return 0).
2906 error
= zfs_receive_impl(hdl
, destname
, NULL
, flags
, fd
,
2907 sendfs
, stream_nv
, stream_avl
, top_zfs
, cleanup_fd
,
2908 action_handlep
, sendsnap
);
2909 if (error
== ENODATA
) {
2914 } while (error
== 0);
2916 if (drr
->drr_payloadlen
!= 0 && fromsnap
!= NULL
) {
2918 * Now that we have the fs's they sent us, try the
2921 softerr
= recv_incremental_replication(hdl
, tofs
, flags
,
2922 stream_nv
, stream_avl
, NULL
);
2926 fsavl_destroy(stream_avl
);
2927 nvlist_free(stream_nv
);
2936 trunc_prop_errs(int truncated
)
2938 ASSERT(truncated
!= 0);
2941 (void) fprintf(stderr
, dgettext(TEXT_DOMAIN
,
2942 "1 more property could not be set\n"));
2944 (void) fprintf(stderr
, dgettext(TEXT_DOMAIN
,
2945 "%d more properties could not be set\n"), truncated
);
2949 recv_skip(libzfs_handle_t
*hdl
, int fd
, boolean_t byteswap
)
2951 dmu_replay_record_t
*drr
;
2952 void *buf
= zfs_alloc(hdl
, SPA_MAXBLOCKSIZE
);
2955 (void) snprintf(errbuf
, sizeof (errbuf
), dgettext(TEXT_DOMAIN
,
2956 "cannot receive:"));
2958 /* XXX would be great to use lseek if possible... */
2961 while (recv_read(hdl
, fd
, drr
, sizeof (dmu_replay_record_t
),
2962 byteswap
, NULL
) == 0) {
2964 drr
->drr_type
= BSWAP_32(drr
->drr_type
);
2966 switch (drr
->drr_type
) {
2968 if (drr
->drr_payloadlen
!= 0) {
2969 (void) recv_read(hdl
, fd
, buf
,
2970 drr
->drr_payloadlen
, B_FALSE
, NULL
);
2980 drr
->drr_u
.drr_object
.drr_bonuslen
=
2981 BSWAP_32(drr
->drr_u
.drr_object
.
2984 (void) recv_read(hdl
, fd
, buf
,
2985 P2ROUNDUP(drr
->drr_u
.drr_object
.drr_bonuslen
, 8),
2991 drr
->drr_u
.drr_write
.drr_logical_size
=
2993 drr
->drr_u
.drr_write
.drr_logical_size
);
2994 drr
->drr_u
.drr_write
.drr_compressed_size
=
2996 drr
->drr_u
.drr_write
.drr_compressed_size
);
2998 uint64_t payload_size
=
2999 DRR_WRITE_PAYLOAD_SIZE(&drr
->drr_u
.drr_write
);
3000 (void) recv_read(hdl
, fd
, buf
,
3001 payload_size
, B_FALSE
, NULL
);
3005 drr
->drr_u
.drr_spill
.drr_length
=
3006 BSWAP_64(drr
->drr_u
.drr_spill
.drr_length
);
3008 (void) recv_read(hdl
, fd
, buf
,
3009 drr
->drr_u
.drr_spill
.drr_length
, B_FALSE
, NULL
);
3011 case DRR_WRITE_EMBEDDED
:
3013 drr
->drr_u
.drr_write_embedded
.drr_psize
=
3014 BSWAP_32(drr
->drr_u
.drr_write_embedded
.
3017 (void) recv_read(hdl
, fd
, buf
,
3018 P2ROUNDUP(drr
->drr_u
.drr_write_embedded
.drr_psize
,
3021 case DRR_WRITE_BYREF
:
3022 case DRR_FREEOBJECTS
:
3027 zfs_error_aux(hdl
, dgettext(TEXT_DOMAIN
,
3028 "invalid record type"));
3030 return (zfs_error(hdl
, EZFS_BADSTREAM
, errbuf
));
3039 recv_ecksum_set_aux(libzfs_handle_t
*hdl
, const char *target_snap
,
3040 boolean_t resumable
)
3042 char target_fs
[ZFS_MAX_DATASET_NAME_LEN
];
3044 zfs_error_aux(hdl
, dgettext(TEXT_DOMAIN
,
3045 "checksum mismatch or incomplete stream"));
3049 (void) strlcpy(target_fs
, target_snap
, sizeof (target_fs
));
3050 *strchr(target_fs
, '@') = '\0';
3051 zfs_handle_t
*zhp
= zfs_open(hdl
, target_fs
,
3052 ZFS_TYPE_FILESYSTEM
| ZFS_TYPE_VOLUME
);
3056 char token_buf
[ZFS_MAXPROPLEN
];
3057 int error
= zfs_prop_get(zhp
, ZFS_PROP_RECEIVE_RESUME_TOKEN
,
3058 token_buf
, sizeof (token_buf
),
3059 NULL
, NULL
, 0, B_TRUE
);
3061 zfs_error_aux(hdl
, dgettext(TEXT_DOMAIN
,
3062 "checksum mismatch or incomplete stream.\n"
3063 "Partially received snapshot is saved.\n"
3064 "A resuming stream can be generated on the sending "
3065 "system by running:\n"
3073 * Restores a backup of tosnap from the file descriptor specified by infd.
3076 zfs_receive_one(libzfs_handle_t
*hdl
, int infd
, const char *tosnap
,
3077 const char *originsnap
, recvflags_t
*flags
, dmu_replay_record_t
*drr
,
3078 dmu_replay_record_t
*drr_noswap
, const char *sendfs
, nvlist_t
*stream_nv
,
3079 avl_tree_t
*stream_avl
, char **top_zfs
, int cleanup_fd
,
3080 uint64_t *action_handlep
, const char *finalsnap
)
3083 int ioctl_err
, ioctl_errno
, err
;
3085 struct drr_begin
*drrb
= &drr
->drr_u
.drr_begin
;
3087 const char *chopprefix
;
3088 boolean_t newfs
= B_FALSE
;
3089 boolean_t stream_wantsnewfs
;
3090 boolean_t newprops
= B_FALSE
;
3091 uint64_t read_bytes
= 0;
3092 uint64_t errflags
= 0;
3093 uint64_t parent_snapguid
= 0;
3094 prop_changelist_t
*clp
= NULL
;
3095 nvlist_t
*snapprops_nvlist
= NULL
;
3096 zprop_errflags_t prop_errflags
;
3097 nvlist_t
*prop_errors
= NULL
;
3098 boolean_t recursive
;
3099 char *snapname
= NULL
;
3100 char destsnap
[MAXPATHLEN
* 2];
3101 char origin
[MAXNAMELEN
];
3102 char name
[MAXPATHLEN
];
3103 nvlist_t
*props
= NULL
;
3105 begin_time
= time(NULL
);
3106 bzero(origin
, MAXNAMELEN
);
3108 (void) snprintf(errbuf
, sizeof (errbuf
), dgettext(TEXT_DOMAIN
,
3111 recursive
= (nvlist_lookup_boolean(stream_nv
, "not_recursive") ==
3114 if (stream_avl
!= NULL
) {
3115 nvlist_t
*lookup
= NULL
;
3116 nvlist_t
*fs
= fsavl_find(stream_avl
, drrb
->drr_toguid
,
3119 (void) nvlist_lookup_uint64(fs
, "parentfromsnap",
3121 err
= nvlist_lookup_nvlist(fs
, "props", &props
);
3123 VERIFY(0 == nvlist_alloc(&props
, NV_UNIQUE_NAME
, 0));
3127 if (flags
->canmountoff
) {
3128 VERIFY(0 == nvlist_add_uint64(props
,
3129 zfs_prop_to_name(ZFS_PROP_CANMOUNT
), 0));
3131 if (0 == nvlist_lookup_nvlist(fs
, "snapprops", &lookup
)) {
3132 VERIFY(0 == nvlist_lookup_nvlist(lookup
,
3133 snapname
, &snapprops_nvlist
));
3140 * Determine how much of the snapshot name stored in the stream
3141 * we are going to tack on to the name they specified on the
3142 * command line, and how much we are going to chop off.
3144 * If they specified a snapshot, chop the entire name stored in
3147 if (flags
->istail
) {
3149 * A filesystem was specified with -e. We want to tack on only
3150 * the tail of the sent snapshot path.
3152 if (strchr(tosnap
, '@')) {
3153 zfs_error_aux(hdl
, dgettext(TEXT_DOMAIN
, "invalid "
3154 "argument - snapshot not allowed with -e"));
3155 err
= zfs_error(hdl
, EZFS_INVALIDNAME
, errbuf
);
3159 chopprefix
= strrchr(sendfs
, '/');
3161 if (chopprefix
== NULL
) {
3163 * The tail is the poolname, so we need to
3164 * prepend a path separator.
3166 int len
= strlen(drrb
->drr_toname
);
3167 cp
= malloc(len
+ 2);
3169 (void) strcpy(&cp
[1], drrb
->drr_toname
);
3172 chopprefix
= drrb
->drr_toname
+ (chopprefix
- sendfs
);
3174 } else if (flags
->isprefix
) {
3176 * A filesystem was specified with -d. We want to tack on
3177 * everything but the first element of the sent snapshot path
3178 * (all but the pool name).
3180 if (strchr(tosnap
, '@')) {
3181 zfs_error_aux(hdl
, dgettext(TEXT_DOMAIN
, "invalid "
3182 "argument - snapshot not allowed with -d"));
3183 err
= zfs_error(hdl
, EZFS_INVALIDNAME
, errbuf
);
3187 chopprefix
= strchr(drrb
->drr_toname
, '/');
3188 if (chopprefix
== NULL
)
3189 chopprefix
= strchr(drrb
->drr_toname
, '@');
3190 } else if (strchr(tosnap
, '@') == NULL
) {
3192 * If a filesystem was specified without -d or -e, we want to
3193 * tack on everything after the fs specified by 'zfs send'.
3195 chopprefix
= drrb
->drr_toname
+ strlen(sendfs
);
3197 /* A snapshot was specified as an exact path (no -d or -e). */
3199 zfs_error_aux(hdl
, dgettext(TEXT_DOMAIN
,
3200 "cannot specify snapshot name for multi-snapshot "
3202 err
= zfs_error(hdl
, EZFS_BADSTREAM
, errbuf
);
3205 chopprefix
= drrb
->drr_toname
+ strlen(drrb
->drr_toname
);
3208 ASSERT(strstr(drrb
->drr_toname
, sendfs
) == drrb
->drr_toname
);
3209 ASSERT(chopprefix
> drrb
->drr_toname
);
3210 ASSERT(chopprefix
<= drrb
->drr_toname
+ strlen(drrb
->drr_toname
));
3211 ASSERT(chopprefix
[0] == '/' || chopprefix
[0] == '@' ||
3212 chopprefix
[0] == '\0');
3215 * Determine name of destination snapshot.
3217 (void) strlcpy(destsnap
, tosnap
, sizeof (destsnap
));
3218 (void) strlcat(destsnap
, chopprefix
, sizeof (destsnap
));
3220 if (!zfs_name_valid(destsnap
, ZFS_TYPE_SNAPSHOT
)) {
3221 err
= zfs_error(hdl
, EZFS_INVALIDNAME
, errbuf
);
3226 * Determine the name of the origin snapshot.
3228 if (drrb
->drr_flags
& DRR_FLAG_CLONE
) {
3229 if (guid_to_name(hdl
, destsnap
,
3230 drrb
->drr_fromguid
, B_FALSE
, origin
) != 0) {
3231 zfs_error_aux(hdl
, dgettext(TEXT_DOMAIN
,
3232 "local origin for clone %s does not exist"),
3234 err
= zfs_error(hdl
, EZFS_NOENT
, errbuf
);
3238 (void) printf("found clone origin %s\n", origin
);
3239 } else if (originsnap
) {
3240 (void) strncpy(origin
, originsnap
, sizeof (origin
));
3242 (void) printf("using provided clone origin %s\n",
3246 boolean_t resuming
= DMU_GET_FEATUREFLAGS(drrb
->drr_versioninfo
) &
3247 DMU_BACKUP_FEATURE_RESUMING
;
3248 stream_wantsnewfs
= (drrb
->drr_fromguid
== 0 ||
3249 (drrb
->drr_flags
& DRR_FLAG_CLONE
) || originsnap
) && !resuming
;
3251 if (stream_wantsnewfs
) {
3253 * if the parent fs does not exist, look for it based on
3254 * the parent snap GUID
3256 (void) snprintf(errbuf
, sizeof (errbuf
), dgettext(TEXT_DOMAIN
,
3257 "cannot receive new filesystem stream"));
3259 (void) strcpy(name
, destsnap
);
3260 cp
= strrchr(name
, '/');
3264 !zfs_dataset_exists(hdl
, name
, ZFS_TYPE_DATASET
)) {
3265 char suffix
[ZFS_MAX_DATASET_NAME_LEN
];
3266 (void) strcpy(suffix
, strrchr(destsnap
, '/'));
3267 if (guid_to_name(hdl
, name
, parent_snapguid
,
3268 B_FALSE
, destsnap
) == 0) {
3269 *strchr(destsnap
, '@') = '\0';
3270 (void) strcat(destsnap
, suffix
);
3275 * if the fs does not exist, look for it based on the
3278 (void) snprintf(errbuf
, sizeof (errbuf
), dgettext(TEXT_DOMAIN
,
3279 "cannot receive incremental stream"));
3281 (void) strcpy(name
, destsnap
);
3282 *strchr(name
, '@') = '\0';
3285 * If the exact receive path was specified and this is the
3286 * topmost path in the stream, then if the fs does not exist we
3287 * should look no further.
3289 if ((flags
->isprefix
|| (*(chopprefix
= drrb
->drr_toname
+
3290 strlen(sendfs
)) != '\0' && *chopprefix
!= '@')) &&
3291 !zfs_dataset_exists(hdl
, name
, ZFS_TYPE_DATASET
)) {
3292 char snap
[ZFS_MAX_DATASET_NAME_LEN
];
3293 (void) strcpy(snap
, strchr(destsnap
, '@'));
3294 if (guid_to_name(hdl
, name
, drrb
->drr_fromguid
,
3295 B_FALSE
, destsnap
) == 0) {
3296 *strchr(destsnap
, '@') = '\0';
3297 (void) strcat(destsnap
, snap
);
3302 (void) strcpy(name
, destsnap
);
3303 *strchr(name
, '@') = '\0';
3305 if (zfs_dataset_exists(hdl
, name
, ZFS_TYPE_DATASET
)) {
3306 zfs_cmd_t zc
= {"\0"};
3309 (void) strcpy(zc
.zc_name
, name
);
3312 * Destination fs exists. It must be one of these cases:
3313 * - an incremental send stream
3314 * - the stream specifies a new fs (full stream or clone)
3315 * and they want us to blow away the existing fs (and
3316 * have therefore specified -F and removed any snapshots)
3317 * - we are resuming a failed receive.
3319 if (stream_wantsnewfs
) {
3320 if (!flags
->force
) {
3321 zfs_error_aux(hdl
, dgettext(TEXT_DOMAIN
,
3322 "destination '%s' exists\n"
3323 "must specify -F to overwrite it"), name
);
3324 err
= zfs_error(hdl
, EZFS_EXISTS
, errbuf
);
3327 if (ioctl(hdl
->libzfs_fd
, ZFS_IOC_SNAPSHOT_LIST_NEXT
,
3329 zfs_error_aux(hdl
, dgettext(TEXT_DOMAIN
,
3330 "destination has snapshots (eg. %s)\n"
3331 "must destroy them to overwrite it"),
3333 err
= zfs_error(hdl
, EZFS_EXISTS
, errbuf
);
3338 if ((zhp
= zfs_open(hdl
, name
,
3339 ZFS_TYPE_FILESYSTEM
| ZFS_TYPE_VOLUME
)) == NULL
) {
3344 if (stream_wantsnewfs
&&
3345 zhp
->zfs_dmustats
.dds_origin
[0]) {
3347 zfs_error_aux(hdl
, dgettext(TEXT_DOMAIN
,
3348 "destination '%s' is a clone\n"
3349 "must destroy it to overwrite it"), name
);
3350 err
= zfs_error(hdl
, EZFS_EXISTS
, errbuf
);
3354 if (!flags
->dryrun
&& zhp
->zfs_type
== ZFS_TYPE_FILESYSTEM
&&
3355 stream_wantsnewfs
) {
3356 /* We can't do online recv in this case */
3357 clp
= changelist_gather(zhp
, ZFS_PROP_NAME
, 0, 0);
3363 if (changelist_prefix(clp
) != 0) {
3364 changelist_free(clp
);
3372 * If we are resuming a newfs, set newfs here so that we will
3373 * mount it if the recv succeeds this time. We can tell
3374 * that it was a newfs on the first recv because the fs
3375 * itself will be inconsistent (if the fs existed when we
3376 * did the first recv, we would have received it into
3379 if (resuming
&& zfs_prop_get_int(zhp
, ZFS_PROP_INCONSISTENT
))
3385 * Destination filesystem does not exist. Therefore we better
3386 * be creating a new filesystem (either from a full backup, or
3387 * a clone). It would therefore be invalid if the user
3388 * specified only the pool name (i.e. if the destination name
3389 * contained no slash character).
3391 cp
= strrchr(name
, '/');
3393 if (!stream_wantsnewfs
|| cp
== NULL
) {
3394 zfs_error_aux(hdl
, dgettext(TEXT_DOMAIN
,
3395 "destination '%s' does not exist"), name
);
3396 err
= zfs_error(hdl
, EZFS_NOENT
, errbuf
);
3401 * Trim off the final dataset component so we perform the
3402 * recvbackup ioctl to the filesystems's parent.
3406 if (flags
->isprefix
&& !flags
->istail
&& !flags
->dryrun
&&
3407 create_parents(hdl
, destsnap
, strlen(tosnap
)) != 0) {
3408 err
= zfs_error(hdl
, EZFS_BADRESTORE
, errbuf
);
3415 if (flags
->verbose
) {
3416 (void) printf("%s %s stream of %s into %s\n",
3417 flags
->dryrun
? "would receive" : "receiving",
3418 drrb
->drr_fromguid
? "incremental" : "full",
3419 drrb
->drr_toname
, destsnap
);
3420 (void) fflush(stdout
);
3423 if (flags
->dryrun
) {
3424 err
= recv_skip(hdl
, infd
, flags
->byteswap
);
3428 err
= ioctl_err
= lzc_receive_one(destsnap
, props
, origin
,
3429 flags
->force
, flags
->resumable
, infd
, drr_noswap
, cleanup_fd
,
3430 &read_bytes
, &errflags
, action_handlep
, &prop_errors
);
3431 ioctl_errno
= ioctl_err
;
3432 prop_errflags
= errflags
;
3435 nvpair_t
*prop_err
= NULL
;
3437 while ((prop_err
= nvlist_next_nvpair(prop_errors
,
3438 prop_err
)) != NULL
) {
3443 prop
= zfs_name_to_prop(nvpair_name(prop_err
));
3444 (void) nvpair_value_int32(prop_err
, &intval
);
3445 if (strcmp(nvpair_name(prop_err
),
3446 ZPROP_N_MORE_ERRORS
) == 0) {
3447 trunc_prop_errs(intval
);
3449 } else if (snapname
== NULL
|| finalsnap
== NULL
||
3450 strcmp(finalsnap
, snapname
) == 0 ||
3451 strcmp(nvpair_name(prop_err
),
3452 zfs_prop_to_name(ZFS_PROP_REFQUOTA
)) != 0) {
3454 * Skip the special case of, for example,
3455 * "refquota", errors on intermediate
3456 * snapshots leading up to a final one.
3457 * That's why we have all of the checks above.
3459 * See zfs_ioctl.c's extract_delay_props() for
3460 * a list of props which can fail on
3461 * intermediate snapshots, but shouldn't
3462 * affect the overall receive.
3464 (void) snprintf(tbuf
, sizeof (tbuf
),
3465 dgettext(TEXT_DOMAIN
,
3466 "cannot receive %s property on %s"),
3467 nvpair_name(prop_err
), name
);
3468 zfs_setprop_error(hdl
, prop
, intval
, tbuf
);
3473 if (err
== 0 && snapprops_nvlist
) {
3474 zfs_cmd_t zc
= {"\0"};
3476 (void) strcpy(zc
.zc_name
, destsnap
);
3477 zc
.zc_cookie
= B_TRUE
; /* received */
3478 if (zcmd_write_src_nvlist(hdl
, &zc
, snapprops_nvlist
) == 0) {
3479 (void) zfs_ioctl(hdl
, ZFS_IOC_SET_PROP
, &zc
);
3480 zcmd_free_nvlists(&zc
);
3484 if (err
&& (ioctl_errno
== ENOENT
|| ioctl_errno
== EEXIST
)) {
3486 * It may be that this snapshot already exists,
3487 * in which case we want to consume & ignore it
3488 * rather than failing.
3490 avl_tree_t
*local_avl
;
3491 nvlist_t
*local_nv
, *fs
;
3492 cp
= strchr(destsnap
, '@');
3495 * XXX Do this faster by just iterating over snaps in
3496 * this fs. Also if zc_value does not exist, we will
3497 * get a strange "does not exist" error message.
3500 if (gather_nvlist(hdl
, destsnap
, NULL
, NULL
, B_FALSE
,
3501 B_FALSE
, &local_nv
, &local_avl
) == 0) {
3503 fs
= fsavl_find(local_avl
, drrb
->drr_toguid
, NULL
);
3504 fsavl_destroy(local_avl
);
3505 nvlist_free(local_nv
);
3508 if (flags
->verbose
) {
3509 (void) printf("snap %s already exists; "
3510 "ignoring\n", destsnap
);
3512 err
= ioctl_err
= recv_skip(hdl
, infd
,
3519 if (ioctl_err
!= 0) {
3520 switch (ioctl_errno
) {
3522 cp
= strchr(destsnap
, '@');
3524 zfs_error_aux(hdl
, dgettext(TEXT_DOMAIN
,
3525 "most recent snapshot of %s does not\n"
3526 "match incremental source"), destsnap
);
3527 (void) zfs_error(hdl
, EZFS_BADRESTORE
, errbuf
);
3531 zfs_error_aux(hdl
, dgettext(TEXT_DOMAIN
,
3532 "destination %s has been modified\n"
3533 "since most recent snapshot"), name
);
3534 (void) zfs_error(hdl
, EZFS_BADRESTORE
, errbuf
);
3537 cp
= strchr(destsnap
, '@');
3539 /* it's the containing fs that exists */
3542 zfs_error_aux(hdl
, dgettext(TEXT_DOMAIN
,
3543 "destination already exists"));
3544 (void) zfs_error_fmt(hdl
, EZFS_EXISTS
,
3545 dgettext(TEXT_DOMAIN
, "cannot restore to %s"),
3550 if (flags
->resumable
)
3551 zfs_error_aux(hdl
, dgettext(TEXT_DOMAIN
,
3552 "kernel modules must be upgraded to "
3553 "receive this stream."));
3554 (void) zfs_error(hdl
, EZFS_BADSTREAM
, errbuf
);
3557 recv_ecksum_set_aux(hdl
, destsnap
, flags
->resumable
);
3558 (void) zfs_error(hdl
, EZFS_BADSTREAM
, errbuf
);
3561 zfs_error_aux(hdl
, dgettext(TEXT_DOMAIN
,
3562 "pool must be upgraded to receive this stream."));
3563 (void) zfs_error(hdl
, EZFS_BADVERSION
, errbuf
);
3566 zfs_error_aux(hdl
, dgettext(TEXT_DOMAIN
,
3567 "destination %s space quota exceeded"), name
);
3568 (void) zfs_error(hdl
, EZFS_NOSPC
, errbuf
);
3571 (void) zfs_standard_error(hdl
, ioctl_errno
, errbuf
);
3576 * Mount the target filesystem (if created). Also mount any
3577 * children of the target filesystem if we did a replication
3578 * receive (indicated by stream_avl being non-NULL).
3580 cp
= strchr(destsnap
, '@');
3581 if (cp
&& (ioctl_err
== 0 || !newfs
)) {
3585 h
= zfs_open(hdl
, destsnap
,
3586 ZFS_TYPE_FILESYSTEM
| ZFS_TYPE_VOLUME
);
3588 if (h
->zfs_type
== ZFS_TYPE_VOLUME
) {
3590 } else if (newfs
|| stream_avl
) {
3592 * Track the first/top of hierarchy fs,
3593 * for mounting and sharing later.
3595 if (top_zfs
&& *top_zfs
== NULL
)
3596 *top_zfs
= zfs_strdup(hdl
, destsnap
);
3604 err
|= changelist_postfix(clp
);
3605 changelist_free(clp
);
3608 if (prop_errflags
& ZPROP_ERR_NOCLEAR
) {
3609 (void) fprintf(stderr
, dgettext(TEXT_DOMAIN
, "Warning: "
3610 "failed to clear unreceived properties on %s"), name
);
3611 (void) fprintf(stderr
, "\n");
3613 if (prop_errflags
& ZPROP_ERR_NORESTORE
) {
3614 (void) fprintf(stderr
, dgettext(TEXT_DOMAIN
, "Warning: "
3615 "failed to restore original properties on %s"), name
);
3616 (void) fprintf(stderr
, "\n");
3619 if (err
|| ioctl_err
) {
3624 if (flags
->verbose
) {
3627 uint64_t bytes
= read_bytes
;
3628 time_t delta
= time(NULL
) - begin_time
;
3631 zfs_nicenum(bytes
, buf1
, sizeof (buf1
));
3632 zfs_nicenum(bytes
/delta
, buf2
, sizeof (buf1
));
3634 (void) printf("received %sB stream in %lu seconds (%sB/sec)\n",
3640 if (prop_errors
!= NULL
)
3641 nvlist_free(prop_errors
);
3650 zfs_receive_impl(libzfs_handle_t
*hdl
, const char *tosnap
,
3651 const char *originsnap
, recvflags_t
*flags
, int infd
, const char *sendfs
,
3652 nvlist_t
*stream_nv
, avl_tree_t
*stream_avl
, char **top_zfs
, int cleanup_fd
,
3653 uint64_t *action_handlep
, const char *finalsnap
)
3656 dmu_replay_record_t drr
, drr_noswap
;
3657 struct drr_begin
*drrb
= &drr
.drr_u
.drr_begin
;
3659 zio_cksum_t zcksum
= { { 0 } };
3660 uint64_t featureflags
;
3663 (void) snprintf(errbuf
, sizeof (errbuf
), dgettext(TEXT_DOMAIN
,
3666 if (flags
->isprefix
&&
3667 !zfs_dataset_exists(hdl
, tosnap
, ZFS_TYPE_DATASET
)) {
3668 zfs_error_aux(hdl
, dgettext(TEXT_DOMAIN
, "specified fs "
3669 "(%s) does not exist"), tosnap
);
3670 return (zfs_error(hdl
, EZFS_NOENT
, errbuf
));
3673 !zfs_dataset_exists(hdl
, originsnap
, ZFS_TYPE_DATASET
)) {
3674 zfs_error_aux(hdl
, dgettext(TEXT_DOMAIN
, "specified origin fs "
3675 "(%s) does not exist"), originsnap
);
3676 return (zfs_error(hdl
, EZFS_NOENT
, errbuf
));
3679 /* read in the BEGIN record */
3680 if (0 != (err
= recv_read(hdl
, infd
, &drr
, sizeof (drr
), B_FALSE
,
3684 if (drr
.drr_type
== DRR_END
|| drr
.drr_type
== BSWAP_32(DRR_END
)) {
3685 /* It's the double end record at the end of a package */
3689 /* the kernel needs the non-byteswapped begin record */
3692 flags
->byteswap
= B_FALSE
;
3693 if (drrb
->drr_magic
== BSWAP_64(DMU_BACKUP_MAGIC
)) {
3695 * We computed the checksum in the wrong byteorder in
3696 * recv_read() above; do it again correctly.
3698 bzero(&zcksum
, sizeof (zio_cksum_t
));
3699 fletcher_4_incremental_byteswap(&drr
, sizeof (drr
), &zcksum
);
3700 flags
->byteswap
= B_TRUE
;
3702 drr
.drr_type
= BSWAP_32(drr
.drr_type
);
3703 drr
.drr_payloadlen
= BSWAP_32(drr
.drr_payloadlen
);
3704 drrb
->drr_magic
= BSWAP_64(drrb
->drr_magic
);
3705 drrb
->drr_versioninfo
= BSWAP_64(drrb
->drr_versioninfo
);
3706 drrb
->drr_creation_time
= BSWAP_64(drrb
->drr_creation_time
);
3707 drrb
->drr_type
= BSWAP_32(drrb
->drr_type
);
3708 drrb
->drr_flags
= BSWAP_32(drrb
->drr_flags
);
3709 drrb
->drr_toguid
= BSWAP_64(drrb
->drr_toguid
);
3710 drrb
->drr_fromguid
= BSWAP_64(drrb
->drr_fromguid
);
3713 if (drrb
->drr_magic
!= DMU_BACKUP_MAGIC
|| drr
.drr_type
!= DRR_BEGIN
) {
3714 zfs_error_aux(hdl
, dgettext(TEXT_DOMAIN
, "invalid "
3715 "stream (bad magic number)"));
3716 return (zfs_error(hdl
, EZFS_BADSTREAM
, errbuf
));
3719 featureflags
= DMU_GET_FEATUREFLAGS(drrb
->drr_versioninfo
);
3720 hdrtype
= DMU_GET_STREAM_HDRTYPE(drrb
->drr_versioninfo
);
3722 if (!DMU_STREAM_SUPPORTED(featureflags
) ||
3723 (hdrtype
!= DMU_SUBSTREAM
&& hdrtype
!= DMU_COMPOUNDSTREAM
)) {
3724 zfs_error_aux(hdl
, dgettext(TEXT_DOMAIN
,
3725 "stream has unsupported feature, feature flags = %lx"),
3727 return (zfs_error(hdl
, EZFS_BADSTREAM
, errbuf
));
3730 if (strchr(drrb
->drr_toname
, '@') == NULL
) {
3731 zfs_error_aux(hdl
, dgettext(TEXT_DOMAIN
, "invalid "
3732 "stream (bad snapshot name)"));
3733 return (zfs_error(hdl
, EZFS_BADSTREAM
, errbuf
));
3736 if (DMU_GET_STREAM_HDRTYPE(drrb
->drr_versioninfo
) == DMU_SUBSTREAM
) {
3737 char nonpackage_sendfs
[ZFS_MAX_DATASET_NAME_LEN
];
3738 if (sendfs
== NULL
) {
3740 * We were not called from zfs_receive_package(). Get
3741 * the fs specified by 'zfs send'.
3744 (void) strlcpy(nonpackage_sendfs
,
3745 drr
.drr_u
.drr_begin
.drr_toname
,
3746 sizeof (nonpackage_sendfs
));
3747 if ((cp
= strchr(nonpackage_sendfs
, '@')) != NULL
)
3749 sendfs
= nonpackage_sendfs
;
3750 VERIFY(finalsnap
== NULL
);
3752 return (zfs_receive_one(hdl
, infd
, tosnap
, originsnap
, flags
,
3753 &drr
, &drr_noswap
, sendfs
, stream_nv
, stream_avl
, top_zfs
,
3754 cleanup_fd
, action_handlep
, finalsnap
));
3756 assert(DMU_GET_STREAM_HDRTYPE(drrb
->drr_versioninfo
) ==
3757 DMU_COMPOUNDSTREAM
);
3758 return (zfs_receive_package(hdl
, infd
, tosnap
, flags
, &drr
,
3759 &zcksum
, top_zfs
, cleanup_fd
, action_handlep
));
3764 * Restores a backup of tosnap from the file descriptor specified by infd.
3765 * Return 0 on total success, -2 if some things couldn't be
3766 * destroyed/renamed/promoted, -1 if some things couldn't be received.
3767 * (-1 will override -2, if -1 and the resumable flag was specified the
3768 * transfer can be resumed if the sending side supports it).
3771 zfs_receive(libzfs_handle_t
*hdl
, const char *tosnap
, nvlist_t
*props
,
3772 recvflags_t
*flags
, int infd
, avl_tree_t
*stream_avl
)
3774 char *top_zfs
= NULL
;
3777 uint64_t action_handle
= 0;
3779 char *originsnap
= NULL
;
3782 * The only way fstat can fail is if we do not have a valid file
3785 if (fstat(infd
, &sb
) == -1) {
3791 #ifndef F_SETPIPE_SZ
3792 #define F_SETPIPE_SZ (F_SETLEASE + 7)
3793 #endif /* F_SETPIPE_SZ */
3795 #ifndef F_GETPIPE_SZ
3796 #define F_GETPIPE_SZ (F_GETLEASE + 7)
3797 #endif /* F_GETPIPE_SZ */
3800 * It is not uncommon for gigabytes to be processed in zfs receive.
3801 * Speculatively increase the buffer size via Linux-specific fcntl()
3804 if (S_ISFIFO(sb
.st_mode
)) {
3805 FILE *procf
= fopen("/proc/sys/fs/pipe-max-size", "r");
3807 if (procf
!= NULL
) {
3808 unsigned long max_psize
;
3810 if (fscanf(procf
, "%lu", &max_psize
) > 0) {
3811 cur_psize
= fcntl(infd
, F_GETPIPE_SZ
);
3812 if (cur_psize
> 0 &&
3813 max_psize
> (unsigned long) cur_psize
)
3814 (void) fcntl(infd
, F_SETPIPE_SZ
,
3820 #endif /* __linux__ */
3823 err
= nvlist_lookup_string(props
, "origin", &originsnap
);
3824 if (err
&& err
!= ENOENT
)
3828 cleanup_fd
= open(ZFS_DEV
, O_RDWR
);
3829 VERIFY(cleanup_fd
>= 0);
3831 err
= zfs_receive_impl(hdl
, tosnap
, originsnap
, flags
, infd
, NULL
, NULL
,
3832 stream_avl
, &top_zfs
, cleanup_fd
, &action_handle
, NULL
);
3834 VERIFY(0 == close(cleanup_fd
));
3836 if (err
== 0 && !flags
->nomount
&& top_zfs
) {
3837 zfs_handle_t
*zhp
= NULL
;
3838 prop_changelist_t
*clp
= NULL
;
3840 zhp
= zfs_open(hdl
, top_zfs
, ZFS_TYPE_FILESYSTEM
);
3842 clp
= changelist_gather(zhp
, ZFS_PROP_MOUNTPOINT
,
3843 CL_GATHER_MOUNT_ALWAYS
, 0);
3846 /* mount and share received datasets */
3847 err
= changelist_postfix(clp
);
3848 changelist_free(clp
);
3851 if (zhp
== NULL
|| clp
== NULL
|| err
)