From 521ea8da0d611c4175ac0a37366527ef087e8297 Mon Sep 17 00:00:00 2001 From: Jorgen Lundman Date: Mon, 26 Aug 2013 11:29:37 +0900 Subject: [PATCH] Receiving Solaris11 streams will have 0x20 (spill blocks set) which is incompatible with us. We will strip this bit and attempt to receive stream anyway, which has a fair chance of succeeding. --- include/sys/zfs_ioctl.h | 17 +++++++++++++++++ lib/libzfs/libzfs_sendrecv.c | 6 ++++++ lib/libzfs/libzfs_util.c | 4 ++++ module/zfs/zfs_ioctl.c | 2 +- 4 files changed, 28 insertions(+), 1 deletion(-) diff --git a/include/sys/zfs_ioctl.h b/include/sys/zfs_ioctl.h index 2e00dd5944..51166bfc02 100644 --- a/include/sys/zfs_ioctl.h +++ b/include/sys/zfs_ioctl.h @@ -82,6 +82,23 @@ typedef enum drr_headertype { #define DMU_BACKUP_FEATURE_DEDUPPROPS (0x2) #define DMU_BACKUP_FEATURE_SA_SPILL (0x4) + /* Unsure what Oracle called this bit */ +#define DMU_BACKUP_FEATURE_SPILLBLOCKS (0x20) + /* +NOTE 3: Fix to 7097870 (spill block can be dropped in some situations during + incremental receive) introduces backward incompatibility with zfs + send/recv. I.e., ZFS streams created with this patch will not be + receivable with older ZFS versions and it will fail with below error + message in destination host: + + "cannot receive: stream has unsupported feature, feature flags = 24" + + This change is to allow important fix in ZFS to avoid metadata + corruptions related to ACL. An upgrade to same or greater version + of ZFS is required in destination for ZFS streams to work properly. + */ + + /* * Mask of all supported backup features */ diff --git a/lib/libzfs/libzfs_sendrecv.c b/lib/libzfs/libzfs_sendrecv.c index ba890ab5c2..5b1c820906 100644 --- a/lib/libzfs/libzfs_sendrecv.c +++ b/lib/libzfs/libzfs_sendrecv.c @@ -3236,6 +3236,12 @@ zfs_receive_impl(libzfs_handle_t *hdl, const char *tosnap, recvflags_t *flags, featureflags = DMU_GET_FEATUREFLAGS(drrb->drr_versioninfo); hdrtype = DMU_GET_STREAM_HDRTYPE(drrb->drr_versioninfo); + if (featureflags & DMU_BACKUP_FEATURE_SPILLBLOCKS) { + fprintf(stderr, "Warning: receive stream has Spill Blocks set which may be incompatible with this version.\r\n"); + featureflags &= ~DMU_BACKUP_FEATURE_SPILLBLOCKS; + } + + if (!DMU_STREAM_SUPPORTED(featureflags) || (hdrtype != DMU_SUBSTREAM && hdrtype != DMU_COMPOUNDSTREAM)) { zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, diff --git a/lib/libzfs/libzfs_util.c b/lib/libzfs/libzfs_util.c index 77735c5d98..5e1d639386 100644 --- a/lib/libzfs/libzfs_util.c +++ b/lib/libzfs/libzfs_util.c @@ -765,6 +765,8 @@ libzfs_init(void) libzfs_mnttab_init(hdl); + //fprintf(stderr, "make_dataset_handle %p\r\n", hdl->libzfs_log_str); + return (hdl); } @@ -1116,6 +1118,8 @@ zfs_ioctl(libzfs_handle_t *hdl, int request, zfs_cmd_t *zc) { int error; + //fprintf(stderr, "zc_history set to %p '%s'\r\n", hdl->libzfs_log_str, + // hdl->libzfs_log_str); zc->zc_history = (uint64_t)(uintptr_t)hdl->libzfs_log_str; error = ioctl(hdl->libzfs_fd, request, zc); diff --git a/module/zfs/zfs_ioctl.c b/module/zfs/zfs_ioctl.c index 19671afe9e..7b06974695 100644 --- a/module/zfs/zfs_ioctl.c +++ b/module/zfs/zfs_ioctl.c @@ -155,7 +155,7 @@ history_str_get(zfs_cmd_t *zc) //Darwin requires that the third argument to copyinstr not be NULL. size_t len = 0; - if (zc->zc_history == 0) + if (zc->zc_history == NULL) return (NULL); buf = kmem_alloc(HIS_MAX_RECORD_LEN, KM_SLEEP | KM_NODEBUG);