Separate warning for incomplete and corrupt streams
This change adds a separate return code to zfs_ioc_recv that is used for incomplete streams, in addition to the existing return code for streams that contain corruption. Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov> Reviewed-by: Matthew Ahrens <mahrens@delphix.com> Signed-off-by: Paul Dagnelie <pcd@delphix.com> Closes #10122
This commit is contained in:
parent
5b3b79559c
commit
7145123b0a
|
@ -94,6 +94,7 @@ zfs_errno = enum_with_offset(1024, [
|
||||||
'ZFS_ERR_UNKNOWN_SEND_STREAM_FEATURE',
|
'ZFS_ERR_UNKNOWN_SEND_STREAM_FEATURE',
|
||||||
'ZFS_ERR_EXPORT_IN_PROGRESS',
|
'ZFS_ERR_EXPORT_IN_PROGRESS',
|
||||||
'ZFS_ERR_BOOKMARK_SOURCE_NOT_ANCESTOR',
|
'ZFS_ERR_BOOKMARK_SOURCE_NOT_ANCESTOR',
|
||||||
|
'ZFS_ERR_STREAM_TRUNCATED',
|
||||||
],
|
],
|
||||||
{}
|
{}
|
||||||
)
|
)
|
||||||
|
|
|
@ -469,6 +469,8 @@ def lzc_receive_translate_errors(
|
||||||
raise lzc_exc.BadStream()
|
raise lzc_exc.BadStream()
|
||||||
if ret == ZFS_ERR_WRONG_PARENT:
|
if ret == ZFS_ERR_WRONG_PARENT:
|
||||||
raise lzc_exc.WrongParent(_fs_name(snapname))
|
raise lzc_exc.WrongParent(_fs_name(snapname))
|
||||||
|
if ret == zfs_errno.ZFS_ERR_STREAM_TRUNCATED:
|
||||||
|
raise lzc_exc.StreamTruncated()
|
||||||
|
|
||||||
raise lzc_exc.StreamIOError(ret)
|
raise lzc_exc.StreamIOError(ret)
|
||||||
|
|
||||||
|
|
|
@ -29,7 +29,8 @@ from ._constants import (
|
||||||
ZFS_ERR_NO_CHECKPOINT,
|
ZFS_ERR_NO_CHECKPOINT,
|
||||||
ZFS_ERR_DEVRM_IN_PROGRESS,
|
ZFS_ERR_DEVRM_IN_PROGRESS,
|
||||||
ZFS_ERR_VDEV_TOO_BIG,
|
ZFS_ERR_VDEV_TOO_BIG,
|
||||||
ZFS_ERR_WRONG_PARENT
|
ZFS_ERR_WRONG_PARENT,
|
||||||
|
zfs_errno
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -351,6 +352,11 @@ class StreamFeatureIncompatible(ZFSError):
|
||||||
message = "Incompatible embedded feature with encrypted receive"
|
message = "Incompatible embedded feature with encrypted receive"
|
||||||
|
|
||||||
|
|
||||||
|
class StreamTruncated(ZFSError):
|
||||||
|
errno = zfs_errno.ZFS_ERR_STREAM_TRUNCATED
|
||||||
|
message = "incomplete stream"
|
||||||
|
|
||||||
|
|
||||||
class ReceivePropertyFailure(MultipleOperationsFailure):
|
class ReceivePropertyFailure(MultipleOperationsFailure):
|
||||||
message = "Receiving of properties failed for one or more reasons"
|
message = "Receiving of properties failed for one or more reasons"
|
||||||
|
|
||||||
|
|
|
@ -2714,7 +2714,7 @@ class ZFSTest(unittest.TestCase):
|
||||||
lzc.lzc_send(src, None, stream.fileno())
|
lzc.lzc_send(src, None, stream.fileno())
|
||||||
stream.seek(0)
|
stream.seek(0)
|
||||||
stream.truncate(1024 * 3)
|
stream.truncate(1024 * 3)
|
||||||
with self.assertRaises(lzc_exc.BadStream):
|
with self.assertRaises(lzc_exc.StreamTruncated):
|
||||||
lzc.lzc_receive_resumable(dst, stream.fileno())
|
lzc.lzc_receive_resumable(dst, stream.fileno())
|
||||||
# Resume token code from zfs_send_resume_token_to_nvlist()
|
# Resume token code from zfs_send_resume_token_to_nvlist()
|
||||||
# XXX: if used more than twice move this code into an external func
|
# XXX: if used more than twice move this code into an external func
|
||||||
|
@ -2771,7 +2771,7 @@ class ZFSTest(unittest.TestCase):
|
||||||
lzc.lzc_send(snap2, snap1, stream.fileno())
|
lzc.lzc_send(snap2, snap1, stream.fileno())
|
||||||
stream.seek(0)
|
stream.seek(0)
|
||||||
stream.truncate(1024 * 3)
|
stream.truncate(1024 * 3)
|
||||||
with self.assertRaises(lzc_exc.BadStream):
|
with self.assertRaises(lzc_exc.StreamTruncated):
|
||||||
lzc.lzc_receive_resumable(dst2, stream.fileno())
|
lzc.lzc_receive_resumable(dst2, stream.fileno())
|
||||||
# Resume token code from zfs_send_resume_token_to_nvlist()
|
# Resume token code from zfs_send_resume_token_to_nvlist()
|
||||||
# format: <version>-<cksum>-<packed-size>-<compressed-payload>
|
# format: <version>-<cksum>-<packed-size>-<compressed-payload>
|
||||||
|
|
|
@ -1330,6 +1330,7 @@ typedef enum {
|
||||||
ZFS_ERR_UNKNOWN_SEND_STREAM_FEATURE,
|
ZFS_ERR_UNKNOWN_SEND_STREAM_FEATURE,
|
||||||
ZFS_ERR_EXPORT_IN_PROGRESS,
|
ZFS_ERR_EXPORT_IN_PROGRESS,
|
||||||
ZFS_ERR_BOOKMARK_SOURCE_NOT_ANCESTOR,
|
ZFS_ERR_BOOKMARK_SOURCE_NOT_ANCESTOR,
|
||||||
|
ZFS_ERR_STREAM_TRUNCATED,
|
||||||
} zfs_errno_t;
|
} zfs_errno_t;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -4253,12 +4253,12 @@ recv_skip(libzfs_handle_t *hdl, int fd, boolean_t byteswap)
|
||||||
|
|
||||||
static void
|
static void
|
||||||
recv_ecksum_set_aux(libzfs_handle_t *hdl, const char *target_snap,
|
recv_ecksum_set_aux(libzfs_handle_t *hdl, const char *target_snap,
|
||||||
boolean_t resumable)
|
boolean_t resumable, boolean_t checksum)
|
||||||
{
|
{
|
||||||
char target_fs[ZFS_MAX_DATASET_NAME_LEN];
|
char target_fs[ZFS_MAX_DATASET_NAME_LEN];
|
||||||
|
|
||||||
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
|
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, (checksum ?
|
||||||
"checksum mismatch or incomplete stream"));
|
"checksum mismatch" : "incomplete stream")));
|
||||||
|
|
||||||
if (!resumable)
|
if (!resumable)
|
||||||
return;
|
return;
|
||||||
|
@ -5206,7 +5206,9 @@ zfs_receive_one(libzfs_handle_t *hdl, int infd, const char *tosnap,
|
||||||
(void) zfs_error(hdl, EZFS_BADSTREAM, errbuf);
|
(void) zfs_error(hdl, EZFS_BADSTREAM, errbuf);
|
||||||
break;
|
break;
|
||||||
case ECKSUM:
|
case ECKSUM:
|
||||||
recv_ecksum_set_aux(hdl, destsnap, flags->resumable);
|
case ZFS_ERR_STREAM_TRUNCATED:
|
||||||
|
recv_ecksum_set_aux(hdl, destsnap, flags->resumable,
|
||||||
|
ioctl_err == ECKSUM);
|
||||||
(void) zfs_error(hdl, EZFS_BADSTREAM, errbuf);
|
(void) zfs_error(hdl, EZFS_BADSTREAM, errbuf);
|
||||||
break;
|
break;
|
||||||
case ENOTSUP:
|
case ENOTSUP:
|
||||||
|
|
|
@ -1265,10 +1265,11 @@ receive_read(dmu_recv_cookie_t *drc, int len, void *buf)
|
||||||
len - done, &resid);
|
len - done, &resid);
|
||||||
if (resid == len - done) {
|
if (resid == len - done) {
|
||||||
/*
|
/*
|
||||||
* Note: ECKSUM indicates that the receive
|
* Note: ECKSUM or ZFS_ERR_STREAM_TRUNCATED indicates
|
||||||
* was interrupted and can potentially be resumed.
|
* that the receive was interrupted and can
|
||||||
|
* potentially be resumed.
|
||||||
*/
|
*/
|
||||||
drc->drc_err = SET_ERROR(ECKSUM);
|
drc->drc_err = SET_ERROR(ZFS_ERR_STREAM_TRUNCATED);
|
||||||
}
|
}
|
||||||
drc->drc_voff += len - done - resid;
|
drc->drc_voff += len - done - resid;
|
||||||
done = len - resid;
|
done = len - resid;
|
||||||
|
|
|
@ -556,7 +556,7 @@ test_recv_new(const char *dataset, int fd)
|
||||||
fnvlist_add_boolean(optional, "resumable");
|
fnvlist_add_boolean(optional, "resumable");
|
||||||
fnvlist_add_uint64(optional, "action_handle", *action_handle);
|
fnvlist_add_uint64(optional, "action_handle", *action_handle);
|
||||||
#endif
|
#endif
|
||||||
IOC_INPUT_TEST(ZFS_IOC_RECV_NEW, dataset, required, optional, ECKSUM);
|
IOC_INPUT_TEST(ZFS_IOC_RECV_NEW, dataset, required, optional, ZFS_ERR_STREAM_TRUNCATED);
|
||||||
|
|
||||||
nvlist_free(props);
|
nvlist_free(props);
|
||||||
nvlist_free(optional);
|
nvlist_free(optional);
|
||||||
|
|
Loading…
Reference in New Issue