aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLOLi <[email protected]>2018-02-12 21:28:59 +0100
committerBrian Behlendorf <[email protected]>2018-02-12 12:28:59 -0800
commitc03f04708caecf9a4a4ce2134aaa6a8cabe499c9 (patch)
tree581d4eba079667d0ed1b1b0c184d6bf1caffa633
parenta893627fac8d4ed37cf00e671322dfdaa02d4f1c (diff)
'zfs receive' fails with "dataset is busy"
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 <[email protected]> Reviewed-by: Brian Behlendorf <[email protected]> Reviewed-by: George Melikov <[email protected]> Signed-off-by: loli10K <[email protected]> Closes #7129 Closes #7154
-rw-r--r--cmd/zfs/zfs_main.c2
-rw-r--r--lib/libzfs/libzfs_sendrecv.c18
2 files changed, 18 insertions, 2 deletions
diff --git a/cmd/zfs/zfs_main.c b/cmd/zfs/zfs_main.c
index fce228a20..991dd4444 100644
--- a/cmd/zfs/zfs_main.c
+++ b/cmd/zfs/zfs_main.c
@@ -6123,7 +6123,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 e12a9db43..9ac2a9026 100644
--- a/lib/libzfs/libzfs_sendrecv.c
+++ b/lib/libzfs/libzfs_sendrecv.c
@@ -3605,6 +3605,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);
@@ -3928,6 +3929,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);
@@ -4186,9 +4192,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);
}