7fdf8cc174
until investigation of upstream issue[1] is completed. 1: https://github.com/zfsonlinux/zfs/issues/7401
91 lines
3.3 KiB
Diff
91 lines
3.3 KiB
Diff
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: LOLi <loli10K@users.noreply.github.com>
|
|
Date: Mon, 12 Feb 2018 21:28:59 +0100
|
|
Subject: [PATCH] 'zfs receive' fails with "dataset is busy"
|
|
MIME-Version: 1.0
|
|
Content-Type: text/plain; charset=UTF-8
|
|
Content-Transfer-Encoding: 8bit
|
|
|
|
Receiving an incremental stream after an interrupted "zfs receive -s"
|
|
fails with the message "dataset is busy": this is because we still have
|
|
the hidden clone ../%recv from the resumable receive.
|
|
|
|
Improve the error message suggesting the existence of a partially
|
|
complete resumable stream from "zfs receive -s" which can be either
|
|
aborted ("zfs receive -A") or resumed ("zfs send -t").
|
|
|
|
Reviewed-by: Giuseppe Di Natale <dinatale2@llnl.gov>
|
|
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
|
|
Reviewed-by: George Melikov <mail@gmelikov.ru>
|
|
Signed-off-by: loli10K <ezomori.nozomu@gmail.com>
|
|
Closes #7129
|
|
Closes #7154
|
|
(cherry picked from commit 1d805a534b5e1768413a0242b8e92b97cb1a796c)
|
|
Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
|
|
---
|
|
cmd/zfs/zfs_main.c | 2 +-
|
|
lib/libzfs/libzfs_sendrecv.c | 18 +++++++++++++++++-
|
|
2 files changed, 18 insertions(+), 2 deletions(-)
|
|
|
|
diff --git a/cmd/zfs/zfs_main.c b/cmd/zfs/zfs_main.c
|
|
index e8fe6a9fa..f57df8581 100644
|
|
--- a/cmd/zfs/zfs_main.c
|
|
+++ b/cmd/zfs/zfs_main.c
|
|
@@ -6072,7 +6072,7 @@ share_mount_one(zfs_handle_t *zhp, int op, int flags, char *protocol,
|
|
|
|
(void) fprintf(stderr, gettext("cannot %s '%s': "
|
|
"Contains partially-completed state from "
|
|
- "\"zfs receive -r\", which can be resumed with "
|
|
+ "\"zfs receive -s\", which can be resumed with "
|
|
"\"zfs send -t\"\n"),
|
|
cmdname, zfs_get_name(zhp));
|
|
return (1);
|
|
diff --git a/lib/libzfs/libzfs_sendrecv.c b/lib/libzfs/libzfs_sendrecv.c
|
|
index ec190022f..66d89067b 100644
|
|
--- a/lib/libzfs/libzfs_sendrecv.c
|
|
+++ b/lib/libzfs/libzfs_sendrecv.c
|
|
@@ -3254,6 +3254,7 @@ zfs_receive_one(libzfs_handle_t *hdl, int infd, const char *tosnap,
|
|
zfs_type_t type;
|
|
boolean_t toplevel = B_FALSE;
|
|
boolean_t zoned = B_FALSE;
|
|
+ boolean_t hastoken = B_FALSE;
|
|
|
|
begin_time = time(NULL);
|
|
bzero(origin, MAXNAMELEN);
|
|
@@ -3535,6 +3536,11 @@ zfs_receive_one(libzfs_handle_t *hdl, int infd, const char *tosnap,
|
|
/* we want to know if we're zoned when validating -o|-x props */
|
|
zoned = zfs_prop_get_int(zhp, ZFS_PROP_ZONED);
|
|
|
|
+ /* may need this info later, get it now we have zhp around */
|
|
+ if (zfs_prop_get(zhp, ZFS_PROP_RECEIVE_RESUME_TOKEN, NULL, 0,
|
|
+ NULL, NULL, 0, B_TRUE) == 0)
|
|
+ hastoken = B_TRUE;
|
|
+
|
|
/* gather existing properties on destination */
|
|
origprops = fnvlist_alloc();
|
|
fnvlist_merge(origprops, zhp->zfs_props);
|
|
@@ -3741,9 +3747,19 @@ zfs_receive_one(libzfs_handle_t *hdl, int infd, const char *tosnap,
|
|
break;
|
|
case EDQUOT:
|
|
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
|
|
- "destination %s space quota exceeded"), name);
|
|
+ "destination %s space quota exceeded."), name);
|
|
(void) zfs_error(hdl, EZFS_NOSPC, errbuf);
|
|
break;
|
|
+ case EBUSY:
|
|
+ if (hastoken) {
|
|
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
|
|
+ "destination %s contains "
|
|
+ "partially-complete state from "
|
|
+ "\"zfs receive -s\"."), name);
|
|
+ (void) zfs_error(hdl, EZFS_BUSY, errbuf);
|
|
+ break;
|
|
+ }
|
|
+ /* fallthru */
|
|
default:
|
|
(void) zfs_standard_error(hdl, ioctl_errno, errbuf);
|
|
}
|
|
--
|
|
2.14.2
|
|
|