summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/libzfs/libzfs_sendrecv.c523
-rw-r--r--lib/libzfs_core/libzfs_core.c44
2 files changed, 34 insertions, 533 deletions
diff --git a/lib/libzfs/libzfs_sendrecv.c b/lib/libzfs/libzfs_sendrecv.c
index 43a39e789..c65673dd3 100644
--- a/lib/libzfs/libzfs_sendrecv.c
+++ b/lib/libzfs/libzfs_sendrecv.c
@@ -21,7 +21,7 @@
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2011, 2018 by Delphix. All rights reserved.
+ * Copyright (c) 2011, 2020 by Delphix. All rights reserved.
* Copyright (c) 2012, Joyent, Inc. All rights reserved.
* Copyright (c) 2012 Pawel Jakub Dawidek <[email protected]>.
* All rights reserved
@@ -73,22 +73,14 @@
extern void zfs_setprop_error(libzfs_handle_t *, zfs_prop_t, int, char *);
static int zfs_receive_impl(libzfs_handle_t *, const char *, const char *,
- recvflags_t *, int, const char *, nvlist_t *, avl_tree_t *, char **, int,
- uint64_t *, const char *, nvlist_t *);
+ recvflags_t *, int, const char *, nvlist_t *, avl_tree_t *, char **,
+ const char *, nvlist_t *);
static int guid_to_name_redact_snaps(libzfs_handle_t *hdl, const char *parent,
uint64_t guid, boolean_t bookmark_ok, uint64_t *redact_snap_guids,
uint64_t num_redact_snaps, char *name);
static int guid_to_name(libzfs_handle_t *, const char *,
uint64_t, boolean_t, char *);
-static const zio_cksum_t zero_cksum = { { 0 } };
-
-typedef struct dedup_arg {
- int inputfd;
- int outputfd;
- libzfs_handle_t *dedup_hdl;
-} dedup_arg_t;
-
typedef struct progress_arg {
zfs_handle_t *pa_zhp;
int pa_fd;
@@ -97,112 +89,6 @@ typedef struct progress_arg {
int pa_verbosity;
} progress_arg_t;
-typedef struct dataref {
- uint64_t ref_guid;
- uint64_t ref_object;
- uint64_t ref_offset;
-} dataref_t;
-
-typedef struct dedup_entry {
- struct dedup_entry *dde_next;
- zio_cksum_t dde_chksum;
- uint64_t dde_prop;
- dataref_t dde_ref;
-} dedup_entry_t;
-
-#define MAX_DDT_PHYSMEM_PERCENT 20
-#define SMALLEST_POSSIBLE_MAX_DDT_MB 128
-
-typedef struct dedup_table {
- dedup_entry_t **dedup_hash_array;
- umem_cache_t *ddecache;
- uint64_t max_ddt_size; /* max dedup table size in bytes */
- uint64_t cur_ddt_size; /* current dedup table size in bytes */
- uint64_t ddt_count;
- int numhashbits;
- boolean_t ddt_full;
-} dedup_table_t;
-
-static int
-high_order_bit(uint64_t n)
-{
- int count;
-
- for (count = 0; n != 0; count++)
- n >>= 1;
- return (count);
-}
-
-static size_t
-ssread(void *buf, size_t len, FILE *stream)
-{
- size_t outlen;
-
- if ((outlen = fread(buf, len, 1, stream)) == 0)
- return (0);
-
- return (outlen);
-}
-
-static void
-ddt_hash_append(libzfs_handle_t *hdl, dedup_table_t *ddt, dedup_entry_t **ddepp,
- zio_cksum_t *cs, uint64_t prop, dataref_t *dr)
-{
- dedup_entry_t *dde;
-
- if (ddt->cur_ddt_size >= ddt->max_ddt_size) {
- if (ddt->ddt_full == B_FALSE) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "Dedup table full. Deduplication will continue "
- "with existing table entries"));
- ddt->ddt_full = B_TRUE;
- }
- return;
- }
-
- if ((dde = umem_cache_alloc(ddt->ddecache, UMEM_DEFAULT))
- != NULL) {
- assert(*ddepp == NULL);
- dde->dde_next = NULL;
- dde->dde_chksum = *cs;
- dde->dde_prop = prop;
- dde->dde_ref = *dr;
- *ddepp = dde;
- ddt->cur_ddt_size += sizeof (dedup_entry_t);
- ddt->ddt_count++;
- }
-}
-
-/*
- * Using the specified dedup table, do a lookup for an entry with
- * the checksum cs. If found, return the block's reference info
- * in *dr. Otherwise, insert a new entry in the dedup table, using
- * the reference information specified by *dr.
- *
- * return value: true - entry was found
- * false - entry was not found
- */
-static boolean_t
-ddt_update(libzfs_handle_t *hdl, dedup_table_t *ddt, zio_cksum_t *cs,
- uint64_t prop, dataref_t *dr)
-{
- uint32_t hashcode;
- dedup_entry_t **ddepp;
-
- hashcode = BF64_GET(cs->zc_word[0], 0, ddt->numhashbits);
-
- for (ddepp = &(ddt->dedup_hash_array[hashcode]); *ddepp != NULL;
- ddepp = &((*ddepp)->dde_next)) {
- if (ZIO_CHECKSUM_EQUAL(((*ddepp)->dde_chksum), *cs) &&
- (*ddepp)->dde_prop == prop) {
- *dr = (*ddepp)->dde_ref;
- return (B_TRUE);
- }
- }
- ddt_hash_append(hdl, ddt, ddepp, cs, prop, dr);
- return (B_FALSE);
-}
-
static int
dump_record(dmu_replay_record_t *drr, void *payload, int payload_len,
zio_cksum_t *zc, int outfd)
@@ -229,274 +115,6 @@ dump_record(dmu_replay_record_t *drr, void *payload, int payload_len,
}
/*
- * This function is started in a separate thread when the dedup option
- * has been requested. The main send thread determines the list of
- * snapshots to be included in the send stream and makes the ioctl calls
- * for each one. But instead of having the ioctl send the output to the
- * the output fd specified by the caller of zfs_send()), the
- * ioctl is told to direct the output to a pipe, which is read by the
- * alternate thread running THIS function. This function does the
- * dedup'ing by:
- * 1. building a dedup table (the DDT)
- * 2. doing checksums on each data block and inserting a record in the DDT
- * 3. looking for matching checksums, and
- * 4. sending a DRR_WRITE_BYREF record instead of a write record whenever
- * a duplicate block is found.
- * The output of this function then goes to the output fd requested
- * by the caller of zfs_send().
- */
-static void *
-cksummer(void *arg)
-{
- dedup_arg_t *dda = arg;
- char *buf = zfs_alloc(dda->dedup_hdl, SPA_MAXBLOCKSIZE);
- dmu_replay_record_t thedrr = { 0 };
- dmu_replay_record_t *drr = &thedrr;
- FILE *ofp;
- int outfd;
- dedup_table_t ddt;
- zio_cksum_t stream_cksum;
- uint64_t numbuckets;
-
-#ifdef _ILP32
- ddt.max_ddt_size = SMALLEST_POSSIBLE_MAX_DDT_MB << 20;
-#else
- uint64_t physmem = sysconf(_SC_PHYS_PAGES) * sysconf(_SC_PAGESIZE);
- ddt.max_ddt_size =
- MAX((physmem * MAX_DDT_PHYSMEM_PERCENT) / 100,
- SMALLEST_POSSIBLE_MAX_DDT_MB << 20);
-#endif
-
- numbuckets = ddt.max_ddt_size / (sizeof (dedup_entry_t));
-
- /*
- * numbuckets must be a power of 2. Increase number to
- * a power of 2 if necessary.
- */
- if (!ISP2(numbuckets))
- numbuckets = 1ULL << high_order_bit(numbuckets);
-
- ddt.dedup_hash_array = calloc(numbuckets, sizeof (dedup_entry_t *));
- ddt.ddecache = umem_cache_create("dde", sizeof (dedup_entry_t), 0,
- NULL, NULL, NULL, NULL, NULL, 0);
- ddt.cur_ddt_size = numbuckets * sizeof (dedup_entry_t *);
- ddt.numhashbits = high_order_bit(numbuckets) - 1;
- ddt.ddt_full = B_FALSE;
-
- outfd = dda->outputfd;
- ofp = fdopen(dda->inputfd, "r");
- while (ssread(drr, sizeof (*drr), ofp) != 0) {
-
- /*
- * kernel filled in checksum, we are going to write same
- * record, but need to regenerate checksum.
- */
- if (drr->drr_type != DRR_BEGIN) {
- bzero(&drr->drr_u.drr_checksum.drr_checksum,
- sizeof (drr->drr_u.drr_checksum.drr_checksum));
- }
-
- switch (drr->drr_type) {
- case DRR_BEGIN:
- {
- struct drr_begin *drrb = &drr->drr_u.drr_begin;
- int fflags;
- int sz = 0;
- ZIO_SET_CHECKSUM(&stream_cksum, 0, 0, 0, 0);
-
- ASSERT3U(drrb->drr_magic, ==, DMU_BACKUP_MAGIC);
-
- /* set the DEDUP feature flag for this stream */
- fflags = DMU_GET_FEATUREFLAGS(drrb->drr_versioninfo);
- fflags |= (DMU_BACKUP_FEATURE_DEDUP |
- DMU_BACKUP_FEATURE_DEDUPPROPS);
- DMU_SET_FEATUREFLAGS(drrb->drr_versioninfo, fflags);
-
- if (drr->drr_payloadlen != 0) {
- sz = drr->drr_payloadlen;
-
- if (sz > SPA_MAXBLOCKSIZE) {
- buf = zfs_realloc(dda->dedup_hdl, buf,
- SPA_MAXBLOCKSIZE, sz);
- }
- (void) ssread(buf, sz, ofp);
- if (ferror(stdin))
- perror("fread");
- }
- if (dump_record(drr, buf, sz, &stream_cksum,
- outfd) != 0)
- goto out;
- break;
- }
-
- case DRR_END:
- {
- struct drr_end *drre = &drr->drr_u.drr_end;
- /* use the recalculated checksum */
- drre->drr_checksum = stream_cksum;
- if (dump_record(drr, NULL, 0, &stream_cksum,
- outfd) != 0)
- goto out;
- break;
- }
-
- case DRR_OBJECT:
- {
- struct drr_object *drro = &drr->drr_u.drr_object;
- if (drro->drr_bonuslen > 0) {
- (void) ssread(buf,
- DRR_OBJECT_PAYLOAD_SIZE(drro), ofp);
- }
- if (dump_record(drr, buf, DRR_OBJECT_PAYLOAD_SIZE(drro),
- &stream_cksum, outfd) != 0)
- goto out;
- break;
- }
-
- case DRR_SPILL:
- {
- struct drr_spill *drrs = &drr->drr_u.drr_spill;
- (void) ssread(buf, DRR_SPILL_PAYLOAD_SIZE(drrs), ofp);
- if (dump_record(drr, buf, DRR_SPILL_PAYLOAD_SIZE(drrs),
- &stream_cksum, outfd) != 0)
- goto out;
- break;
- }
-
- case DRR_FREEOBJECTS:
- {
- if (dump_record(drr, NULL, 0, &stream_cksum,
- outfd) != 0)
- goto out;
- break;
- }
-
- case DRR_WRITE:
- {
- struct drr_write *drrw = &drr->drr_u.drr_write;
- dataref_t dataref;
- uint64_t payload_size;
-
- payload_size = DRR_WRITE_PAYLOAD_SIZE(drrw);
- (void) ssread(buf, payload_size, ofp);
-
- /*
- * Use the existing checksum if it's dedup-capable,
- * else calculate a SHA256 checksum for it.
- */
-
- if (ZIO_CHECKSUM_EQUAL(drrw->drr_key.ddk_cksum,
- zero_cksum) ||
- !DRR_IS_DEDUP_CAPABLE(drrw->drr_flags)) {
- SHA2_CTX ctx;
- zio_cksum_t tmpsha256;
-
- SHA2Init(SHA256, &ctx);
- SHA2Update(&ctx, buf, payload_size);
- SHA2Final(&tmpsha256, &ctx);
-
- drrw->drr_key.ddk_cksum.zc_word[0] =
- BE_64(tmpsha256.zc_word[0]);
- drrw->drr_key.ddk_cksum.zc_word[1] =
- BE_64(tmpsha256.zc_word[1]);
- drrw->drr_key.ddk_cksum.zc_word[2] =
- BE_64(tmpsha256.zc_word[2]);
- drrw->drr_key.ddk_cksum.zc_word[3] =
- BE_64(tmpsha256.zc_word[3]);
- drrw->drr_checksumtype = ZIO_CHECKSUM_SHA256;
- drrw->drr_flags |= DRR_CHECKSUM_DEDUP;
- }
-
- dataref.ref_guid = drrw->drr_toguid;
- dataref.ref_object = drrw->drr_object;
- dataref.ref_offset = drrw->drr_offset;
-
- if (ddt_update(dda->dedup_hdl, &ddt,
- &drrw->drr_key.ddk_cksum, drrw->drr_key.ddk_prop,
- &dataref)) {
- dmu_replay_record_t wbr_drr = {0};
- struct drr_write_byref *wbr_drrr =
- &wbr_drr.drr_u.drr_write_byref;
-
- /* block already present in stream */
- wbr_drr.drr_type = DRR_WRITE_BYREF;
-
- wbr_drrr->drr_object = drrw->drr_object;
- wbr_drrr->drr_offset = drrw->drr_offset;
- wbr_drrr->drr_length = drrw->drr_logical_size;
- wbr_drrr->drr_toguid = drrw->drr_toguid;
- wbr_drrr->drr_refguid = dataref.ref_guid;
- wbr_drrr->drr_refobject =
- dataref.ref_object;
- wbr_drrr->drr_refoffset =
- dataref.ref_offset;
-
- wbr_drrr->drr_checksumtype =
- drrw->drr_checksumtype;
- wbr_drrr->drr_flags = drrw->drr_flags;
- wbr_drrr->drr_key.ddk_cksum =
- drrw->drr_key.ddk_cksum;
- wbr_drrr->drr_key.ddk_prop =
- drrw->drr_key.ddk_prop;
-
- if (dump_record(&wbr_drr, NULL, 0,
- &stream_cksum, outfd) != 0)
- goto out;
- } else {
- /* block not previously seen */
- if (dump_record(drr, buf, payload_size,
- &stream_cksum, outfd) != 0)
- goto out;
- }
- break;
- }
-
- case DRR_WRITE_EMBEDDED:
- {
- struct drr_write_embedded *drrwe =
- &drr->drr_u.drr_write_embedded;
- (void) ssread(buf,
- P2ROUNDUP((uint64_t)drrwe->drr_psize, 8), ofp);
- if (dump_record(drr, buf,
- P2ROUNDUP((uint64_t)drrwe->drr_psize, 8),
- &stream_cksum, outfd) != 0)
- goto out;
- break;
- }
-
- case DRR_FREE:
- {
- if (dump_record(drr, NULL, 0, &stream_cksum,
- outfd) != 0)
- goto out;
- break;
- }
-
- case DRR_OBJECT_RANGE:
- {
- if (dump_record(drr, NULL, 0, &stream_cksum,
- outfd) != 0)
- goto out;
- break;
- }
-
- default:
- (void) fprintf(stderr, "INVALID record type 0x%x\n",
- drr->drr_type);
- /* should never happen, so assert */
- assert(B_FALSE);
- }
- }
-out:
- umem_cache_destroy(ddt.ddecache);
- free(ddt.dedup_hash_array);
- free(buf);
- (void) fclose(ofp);
-
- return (NULL);
-}
-
-/*
* Routines for dealing with the AVL tree of fs-nvlists
*/
typedef struct fsavl_node {
@@ -2478,7 +2096,6 @@ zfs_send(zfs_handle_t *zhp, const char *fromsnap, const char *tosnap,
int spa_version;
pthread_t tid = 0;
int pipefd[2];
- dedup_arg_t dda = { 0 };
int featureflags = 0;
FILE *fout;
@@ -2502,33 +2119,6 @@ zfs_send(zfs_handle_t *zhp, const char *fromsnap, const char *tosnap,
if (flags->holds)
featureflags |= DMU_BACKUP_FEATURE_HOLDS;
- /*
- * Start the dedup thread if this is a dedup stream. We do not bother
- * doing this if this a raw send of an encrypted dataset with dedup off
- * because normal encrypted blocks won't dedup.
- */
- if (flags->dedup && !flags->dryrun && !(flags->raw &&
- zfs_prop_get_int(zhp, ZFS_PROP_ENCRYPTION) != ZIO_CRYPT_OFF &&
- zfs_prop_get_int(zhp, ZFS_PROP_DEDUP) == ZIO_CHECKSUM_OFF)) {
- featureflags |= (DMU_BACKUP_FEATURE_DEDUP |
- DMU_BACKUP_FEATURE_DEDUPPROPS);
- if ((err = socketpair(AF_UNIX, SOCK_STREAM, 0, pipefd)) != 0) {
- zfs_error_aux(zhp->zfs_hdl, strerror(errno));
- return (zfs_error(zhp->zfs_hdl, EZFS_PIPEFAILED,
- errbuf));
- }
- dda.outputfd = outfd;
- dda.inputfd = pipefd[1];
- dda.dedup_hdl = zhp->zfs_hdl;
- if ((err = pthread_create(&tid, NULL, cksummer, &dda)) != 0) {
- (void) close(pipefd[0]);
- (void) close(pipefd[1]);
- zfs_error_aux(zhp->zfs_hdl, strerror(errno));
- return (zfs_error(zhp->zfs_hdl,
- EZFS_THREADCREATEFAILED, errbuf));
- }
- }
-
if (flags->replicate || flags->doall || flags->props ||
flags->holds || flags->backup) {
char full_tosnap_name[ZFS_MAX_DATASET_NAME_LEN];
@@ -2706,34 +2296,6 @@ err_out:
return (err);
}
-static int
-get_dedup_fd(zfs_handle_t *zhp, dedup_arg_t *dda, int fd, pthread_t *tid,
- int *outfd)
-{
- int pipefd[2];
- char errbuf[1024];
- int err;
- (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
- "warning: cannot send '%s'"), zhp->zfs_name);
- if ((err = socketpair(AF_UNIX, SOCK_STREAM, 0, pipefd)) != 0) {
- zfs_error_aux(zhp->zfs_hdl, strerror(errno));
- return (zfs_error(zhp->zfs_hdl, EZFS_PIPEFAILED,
- errbuf));
- }
- dda->outputfd = fd;
- dda->inputfd = pipefd[1];
- dda->dedup_hdl = zhp->zfs_hdl;
- if ((err = pthread_create(tid, NULL, cksummer, dda)) != 0) {
- (void) close(pipefd[0]);
- (void) close(pipefd[1]);
- zfs_error_aux(zhp->zfs_hdl, strerror(err));
- return (zfs_error(zhp->zfs_hdl, EZFS_THREADCREATEFAILED,
- errbuf));
- }
- *outfd = pipefd[0];
- return (0);
-}
-
zfs_handle_t *
name_to_dir_handle(libzfs_handle_t *hdl, const char *snapname)
{
@@ -2819,9 +2381,8 @@ zfs_send_one(zfs_handle_t *zhp, const char *from, int fd, sendflags_t *flags,
libzfs_handle_t *hdl = zhp->zfs_hdl;
char *name = zhp->zfs_name;
int orig_fd = fd;
- pthread_t ddtid, ptid;
+ pthread_t ptid;
progress_arg_t pa = { 0 };
- dedup_arg_t dda = { 0 };
char errbuf[1024];
(void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
@@ -2915,16 +2476,6 @@ zfs_send_one(zfs_handle_t *zhp, const char *from, int fd, sendflags_t *flags,
return (0);
/*
- * If deduplication is requested, spawn a thread that will deduplicate
- * the data coming out of the kernel.
- */
- if (flags->dedup) {
- err = get_dedup_fd(zhp, &dda, fd, &ddtid, &fd);
- if (err != 0)
- return (err);
- }
-
- /*
* If progress reporting is requested, spawn a new thread to poll
* ZFS_IOC_SEND_PROGRESS at a regular interval.
*/
@@ -2939,11 +2490,6 @@ zfs_send_one(zfs_handle_t *zhp, const char *from, int fd, sendflags_t *flags,
send_progress_thread, &pa);
if (err != 0) {
zfs_error_aux(zhp->zfs_hdl, strerror(errno));
- if (flags->dedup) {
- (void) pthread_cancel(ddtid);
- (void) close(fd);
- (void) pthread_join(ddtid, NULL);
- }
return (zfs_error(zhp->zfs_hdl,
EZFS_THREADCREATEFAILED, errbuf));
}
@@ -2966,12 +2512,6 @@ zfs_send_one(zfs_handle_t *zhp, const char *from, int fd, sendflags_t *flags,
return (zfs_standard_error(hdl, error, errbuf));
}
}
- if (flags->dedup) {
- if (err != 0)
- (void) pthread_cancel(ddtid);
- (void) close(fd);
- (void) pthread_join(ddtid, NULL);
- }
if (flags->props || flags->holds || flags->backup) {
/* Write the final end record. */
@@ -3965,8 +3505,7 @@ doagain:
static int
zfs_receive_package(libzfs_handle_t *hdl, int fd, const char *destname,
recvflags_t *flags, dmu_replay_record_t *drr, zio_cksum_t *zc,
- char **top_zfs, int cleanup_fd, uint64_t *action_handlep,
- nvlist_t *cmdprops)
+ char **top_zfs, nvlist_t *cmdprops)
{
nvlist_t *stream_nv = NULL;
avl_tree_t *stream_avl = NULL;
@@ -4143,8 +3682,7 @@ zfs_receive_package(libzfs_handle_t *hdl, int fd, const char *destname,
* recv_skip() and return 0).
*/
error = zfs_receive_impl(hdl, destname, NULL, flags, fd,
- sendfs, stream_nv, stream_avl, top_zfs, cleanup_fd,
- action_handlep, sendsnap, cmdprops);
+ sendfs, stream_nv, stream_avl, top_zfs, sendsnap, cmdprops);
if (error == ENODATA) {
error = 0;
break;
@@ -4530,8 +4068,8 @@ static int
zfs_receive_one(libzfs_handle_t *hdl, int infd, const char *tosnap,
const char *originsnap, recvflags_t *flags, dmu_replay_record_t *drr,
dmu_replay_record_t *drr_noswap, const char *sendfs, nvlist_t *stream_nv,
- avl_tree_t *stream_avl, char **top_zfs, int cleanup_fd,
- uint64_t *action_handlep, const char *finalsnap, nvlist_t *cmdprops)
+ avl_tree_t *stream_avl, char **top_zfs,
+ const char *finalsnap, nvlist_t *cmdprops)
{
time_t begin_time;
int ioctl_err, ioctl_errno, err;
@@ -4741,24 +4279,16 @@ zfs_receive_one(libzfs_handle_t *hdl, int infd, const char *tosnap,
(void) printf("found clone origin %s\n", origin);
}
- if (!hdl->libzfs_dedup_warning_printed &&
- (DMU_GET_FEATUREFLAGS(drrb->drr_versioninfo) &
+ if ((DMU_GET_FEATUREFLAGS(drrb->drr_versioninfo) &
DMU_BACKUP_FEATURE_DEDUP)) {
(void) fprintf(stderr,
- gettext("WARNING: This is a deduplicated send stream. "
- "The ability to send and\n"
- "receive deduplicated send streams is deprecated. "
- "In the future, the\n"
- "ability to receive a deduplicated send stream with "
- "\"zfs receive\" will be\n"
- "removed. However, in the future, a utility will be "
- "provided to convert a\n"
- "deduplicated send stream to a regular "
- "(non-deduplicated) stream. This\n"
- "future utility will require that the send stream be "
- "located in a\n"
- "seek-able file, rather than provided by a pipe.\n\n"));
- hdl->libzfs_dedup_warning_printed = B_TRUE;
+ gettext("ERROR: \"zfs receive\" no longer supports "
+ "deduplicated send streams. Use\n"
+ "the \"zstream redup\" command to convert this stream "
+ "to a regular,\n"
+ "non-deduplicated stream.\n"));
+ err = zfs_error(hdl, EZFS_NOTSUP, errbuf);
+ goto out;
}
boolean_t resuming = DMU_GET_FEATUREFLAGS(drrb->drr_versioninfo) &
@@ -5103,8 +4633,8 @@ zfs_receive_one(libzfs_handle_t *hdl, int infd, const char *tosnap,
err = ioctl_err = lzc_receive_with_cmdprops(destsnap, rcvprops,
oxprops, wkeydata, wkeylen, origin, flags->force, flags->resumable,
- raw, infd, drr_noswap, cleanup_fd, &read_bytes, &errflags,
- action_handlep, &prop_errors);
+ raw, infd, drr_noswap, -1, &read_bytes, &errflags,
+ NULL, &prop_errors);
ioctl_errno = ioctl_err;
prop_errflags = errflags;
@@ -5435,8 +4965,8 @@ zfs_receive_checkprops(libzfs_handle_t *hdl, nvlist_t *props,
static int
zfs_receive_impl(libzfs_handle_t *hdl, const char *tosnap,
const char *originsnap, recvflags_t *flags, int infd, const char *sendfs,
- nvlist_t *stream_nv, avl_tree_t *stream_avl, char **top_zfs, int cleanup_fd,
- uint64_t *action_handlep, const char *finalsnap, nvlist_t *cmdprops)
+ nvlist_t *stream_nv, avl_tree_t *stream_avl, char **top_zfs,
+ const char *finalsnap, nvlist_t *cmdprops)
{
int err;
dmu_replay_record_t drr, drr_noswap;
@@ -5546,12 +5076,12 @@ zfs_receive_impl(libzfs_handle_t *hdl, const char *tosnap,
}
return (zfs_receive_one(hdl, infd, tosnap, originsnap, flags,
&drr, &drr_noswap, sendfs, stream_nv, stream_avl, top_zfs,
- cleanup_fd, action_handlep, finalsnap, cmdprops));
+ finalsnap, cmdprops));
} else {
assert(DMU_GET_STREAM_HDRTYPE(drrb->drr_versioninfo) ==
DMU_COMPOUNDSTREAM);
return (zfs_receive_package(hdl, infd, tosnap, flags, &drr,
- &zcksum, top_zfs, cleanup_fd, action_handlep, cmdprops));
+ &zcksum, top_zfs, cmdprops));
}
}
@@ -5568,8 +5098,6 @@ zfs_receive(libzfs_handle_t *hdl, const char *tosnap, nvlist_t *props,
{
char *top_zfs = NULL;
int err;
- int cleanup_fd;
- uint64_t action_handle = 0;
struct stat sb;
char *originsnap = NULL;
@@ -5595,13 +5123,8 @@ zfs_receive(libzfs_handle_t *hdl, const char *tosnap, nvlist_t *props,
return (err);
}
- cleanup_fd = open(ZFS_DEV, O_RDWR);
- VERIFY(cleanup_fd >= 0);
-
err = zfs_receive_impl(hdl, tosnap, originsnap, flags, infd, NULL, NULL,
- stream_avl, &top_zfs, cleanup_fd, &action_handle, NULL, props);
-
- VERIFY(0 == close(cleanup_fd));
+ stream_avl, &top_zfs, NULL, props);
if (err == 0 && !flags->nomount && flags->domount && top_zfs) {
zfs_handle_t *zhp = NULL;
diff --git a/lib/libzfs_core/libzfs_core.c b/lib/libzfs_core/libzfs_core.c
index 18143d364..4e83b624b 100644
--- a/lib/libzfs_core/libzfs_core.c
+++ b/lib/libzfs_core/libzfs_core.c
@@ -20,7 +20,7 @@
*/
/*
- * Copyright (c) 2012, 2018 by Delphix. All rights reserved.
+ * Copyright (c) 2012, 2020 by Delphix. All rights reserved.
* Copyright (c) 2013 Steven Hartland. All rights reserved.
* Copyright (c) 2017 Datto Inc.
* Copyright 2017 RackTop Systems.
@@ -783,9 +783,8 @@ static int
recv_impl(const char *snapname, nvlist_t *recvdprops, nvlist_t *localprops,
uint8_t *wkeydata, uint_t wkeylen, const char *origin, boolean_t force,
boolean_t resumable, boolean_t raw, int input_fd,
- const dmu_replay_record_t *begin_record, int cleanup_fd,
- uint64_t *read_bytes, uint64_t *errflags, uint64_t *action_handle,
- nvlist_t **errors)
+ const dmu_replay_record_t *begin_record, uint64_t *read_bytes,
+ uint64_t *errflags, nvlist_t **errors)
{
dmu_replay_record_t drr;
char fsname[MAXPATHLEN];
@@ -868,12 +867,6 @@ recv_impl(const char *snapname, nvlist_t *recvdprops, nvlist_t *localprops,
if (resumable)
fnvlist_add_boolean(innvl, "resumable");
- if (cleanup_fd >= 0)
- fnvlist_add_int32(innvl, "cleanup_fd", cleanup_fd);
-
- if (action_handle != NULL)
- fnvlist_add_uint64(innvl, "action_handle",
- *action_handle);
error = lzc_ioctl(ZFS_IOC_RECV_NEW, fsname, innvl, &outnvl);
@@ -885,10 +878,6 @@ recv_impl(const char *snapname, nvlist_t *recvdprops, nvlist_t *localprops,
error = nvlist_lookup_uint64(outnvl, "error_flags",
errflags);
- if (error == 0 && action_handle != NULL)
- error = nvlist_lookup_uint64(outnvl, "action_handle",
- action_handle);
-
if (error == 0 && errors != NULL) {
nvlist_t *nvl;
error = nvlist_lookup_nvlist(outnvl, "errors", &nvl);
@@ -931,12 +920,6 @@ recv_impl(const char *snapname, nvlist_t *recvdprops, nvlist_t *localprops,
zc.zc_cleanup_fd = -1;
zc.zc_action_handle = 0;
- if (cleanup_fd >= 0)
- zc.zc_cleanup_fd = cleanup_fd;
-
- if (action_handle != NULL)
- zc.zc_action_handle = *action_handle;
-
zc.zc_nvlist_dst_size = 128 * 1024;
zc.zc_nvlist_dst = (uint64_t)(uintptr_t)
malloc(zc.zc_nvlist_dst_size);
@@ -951,9 +934,6 @@ recv_impl(const char *snapname, nvlist_t *recvdprops, nvlist_t *localprops,
if (errflags != NULL)
*errflags = zc.zc_obj;
- if (action_handle != NULL)
- *action_handle = zc.zc_action_handle;
-
if (errors != NULL)
VERIFY0(nvlist_unpack(
(void *)(uintptr_t)zc.zc_nvlist_dst,
@@ -986,7 +966,7 @@ lzc_receive(const char *snapname, nvlist_t *props, const char *origin,
boolean_t force, boolean_t raw, int fd)
{
return (recv_impl(snapname, props, NULL, NULL, 0, origin, force,
- B_FALSE, raw, fd, NULL, -1, NULL, NULL, NULL, NULL));
+ B_FALSE, raw, fd, NULL, NULL, NULL, NULL));
}
/*
@@ -1000,7 +980,7 @@ lzc_receive_resumable(const char *snapname, nvlist_t *props, const char *origin,
boolean_t force, boolean_t raw, int fd)
{
return (recv_impl(snapname, props, NULL, NULL, 0, origin, force,
- B_TRUE, raw, fd, NULL, -1, NULL, NULL, NULL, NULL));
+ B_TRUE, raw, fd, NULL, NULL, NULL, NULL));
}
/*
@@ -1023,7 +1003,7 @@ lzc_receive_with_header(const char *snapname, nvlist_t *props,
return (EINVAL);
return (recv_impl(snapname, props, NULL, NULL, 0, origin, force,
- resumable, raw, fd, begin_record, -1, NULL, NULL, NULL, NULL));
+ resumable, raw, fd, begin_record, NULL, NULL, NULL));
}
/*
@@ -1039,9 +1019,7 @@ lzc_receive_with_header(const char *snapname, nvlist_t *props,
* The 'errflags' value will contain zprop_errflags_t flags which are
* used to describe any failures.
*
- * The 'action_handle' is used to pass the handle for this guid/ds mapping.
- * It should be set to zero on first call and will contain an updated handle
- * on success, it should be passed in subsequent calls.
+ * The 'action_handle' and 'cleanup_fd' are no longer used, and are ignored.
*
* The 'errors' nvlist contains an entry for each unapplied received
* property. Callers are responsible for freeing this nvlist.
@@ -1053,8 +1031,8 @@ int lzc_receive_one(const char *snapname, nvlist_t *props,
nvlist_t **errors)
{
return (recv_impl(snapname, props, NULL, NULL, 0, origin, force,
- resumable, raw, input_fd, begin_record, cleanup_fd, read_bytes,
- errflags, action_handle, errors));
+ resumable, raw, input_fd, begin_record,
+ read_bytes, errflags, errors));
}
/*
@@ -1073,8 +1051,8 @@ int lzc_receive_with_cmdprops(const char *snapname, nvlist_t *props,
nvlist_t **errors)
{
return (recv_impl(snapname, props, cmdprops, wkeydata, wkeylen, origin,
- force, resumable, raw, input_fd, begin_record, cleanup_fd,
- read_bytes, errflags, action_handle, errors));
+ force, resumable, raw, input_fd, begin_record,
+ read_bytes, errflags, errors));
}
/*