mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2026-05-22 02:27:36 +03:00
OpenZFS 2605, 6980, 6902
2605 want to resume interrupted zfs send Reviewed by: George Wilson <george.wilson@delphix.com> Reviewed by: Paul Dagnelie <pcd@delphix.com> Reviewed by: Richard Elling <Richard.Elling@RichardElling.com> Reviewed by: Xin Li <delphij@freebsd.org> Reviewed by: Arne Jansen <sensille@gmx.net> Approved by: Dan McDonald <danmcd@omniti.com> Ported-by: kernelOfTruth <kerneloftruth@gmail.com> Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov> OpenZFS-issue: https://www.illumos.org/issues/2605 OpenZFS-commit: https://github.com/openzfs/openzfs/commit/9c3fd12 6980 6902 causes zfs send to break due to 32-bit/64-bit struct mismatch Reviewed by: Paul Dagnelie <pcd@delphix.com> Reviewed by: George Wilson <george.wilson@delphix.com> Approved by: Robert Mustacchi <rm@joyent.com> Ported by: Brian Behlendorf <behlendorf1@llnl.gov> OpenZFS-issue: https://www.illumos.org/issues/6980 OpenZFS-commit: https://github.com/openzfs/openzfs/commit/ea4a67f Porting notes: - All rsend and snapshop tests enabled and updated for Linux. - Fix misuse of input argument in traverse_visitbp(). - Fix ISO C90 warnings and errors. - Fix gcc 'missing braces around initializer' in 'struct send_thread_arg to_arg =' warning. - Replace 4 argument fletcher_4_native() with 3 argument version, this change was made in OpenZFS 4185 which has not been ported. - Part of the sections for 'zfs receive' and 'zfs send' was rewritten and reordered to approximate upstream. - Fix mktree xattr creation, 'user.' prefix required. - Minor fixes to newly enabled test cases - Long holds for volumes allowed during receive for minor registration.
This commit is contained in:
committed by
Brian Behlendorf
parent
669cf0ab29
commit
47dfff3b86
+103
-17
@@ -248,10 +248,11 @@ get_usage(zfs_help_t idx)
|
||||
case HELP_PROMOTE:
|
||||
return (gettext("\tpromote <clone-filesystem>\n"));
|
||||
case HELP_RECEIVE:
|
||||
return (gettext("\treceive [-vnFu] <filesystem|volume|"
|
||||
return (gettext("\treceive [-vnsFu] <filesystem|volume|"
|
||||
"snapshot>\n"
|
||||
"\treceive [-vnFu] [-o origin=<snapshot>] [-d | -e] "
|
||||
"<filesystem>\n"));
|
||||
"\treceive [-vnsFu] [-o origin=<snapshot>] [-d | -e] "
|
||||
"<filesystem>\n"
|
||||
"\treceive -A <filesystem|volume>\n"));
|
||||
case HELP_RENAME:
|
||||
return (gettext("\trename [-f] <filesystem|volume|snapshot> "
|
||||
"<filesystem|volume|snapshot>\n"
|
||||
@@ -263,7 +264,8 @@ get_usage(zfs_help_t idx)
|
||||
return (gettext("\tsend [-DnPpRvLe] [-[iI] snapshot] "
|
||||
"<snapshot>\n"
|
||||
"\tsend [-Le] [-i snapshot|bookmark] "
|
||||
"<filesystem|volume|snapshot>\n"));
|
||||
"<filesystem|volume|snapshot>\n"
|
||||
"\tsend [-nvPe] -t <receive_resume_token>\n"));
|
||||
case HELP_SET:
|
||||
return (gettext("\tset <property=value> ... "
|
||||
"<filesystem|volume|snapshot> ...\n"));
|
||||
@@ -3707,6 +3709,7 @@ zfs_do_send(int argc, char **argv)
|
||||
{
|
||||
char *fromname = NULL;
|
||||
char *toname = NULL;
|
||||
char *resume_token = NULL;
|
||||
char *cp;
|
||||
zfs_handle_t *zhp;
|
||||
sendflags_t flags = { 0 };
|
||||
@@ -3715,7 +3718,7 @@ zfs_do_send(int argc, char **argv)
|
||||
boolean_t extraverbose = B_FALSE;
|
||||
|
||||
/* check options */
|
||||
while ((c = getopt(argc, argv, ":i:I:RDpvnPLe")) != -1) {
|
||||
while ((c = getopt(argc, argv, ":i:I:RDpvnPLet:")) != -1) {
|
||||
switch (c) {
|
||||
case 'i':
|
||||
if (fromname)
|
||||
@@ -3756,6 +3759,9 @@ zfs_do_send(int argc, char **argv)
|
||||
case 'e':
|
||||
flags.embed_data = B_TRUE;
|
||||
break;
|
||||
case 't':
|
||||
resume_token = optarg;
|
||||
break;
|
||||
case ':':
|
||||
(void) fprintf(stderr, gettext("missing argument for "
|
||||
"'%c' option\n"), optopt);
|
||||
@@ -3771,14 +3777,28 @@ zfs_do_send(int argc, char **argv)
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
/* check number of arguments */
|
||||
if (argc < 1) {
|
||||
(void) fprintf(stderr, gettext("missing snapshot argument\n"));
|
||||
usage(B_FALSE);
|
||||
}
|
||||
if (argc > 1) {
|
||||
(void) fprintf(stderr, gettext("too many arguments\n"));
|
||||
usage(B_FALSE);
|
||||
if (resume_token != NULL) {
|
||||
if (fromname != NULL || flags.replicate || flags.props ||
|
||||
flags.dedup) {
|
||||
(void) fprintf(stderr,
|
||||
gettext("invalid flags combined with -t\n"));
|
||||
usage(B_FALSE);
|
||||
}
|
||||
if (argc != 0) {
|
||||
(void) fprintf(stderr, gettext("no additional "
|
||||
"arguments are permitted with -t\n"));
|
||||
usage(B_FALSE);
|
||||
}
|
||||
} else {
|
||||
if (argc < 1) {
|
||||
(void) fprintf(stderr,
|
||||
gettext("missing snapshot argument\n"));
|
||||
usage(B_FALSE);
|
||||
}
|
||||
if (argc > 1) {
|
||||
(void) fprintf(stderr, gettext("too many arguments\n"));
|
||||
usage(B_FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
if (!flags.dryrun && isatty(STDOUT_FILENO)) {
|
||||
@@ -3788,6 +3808,11 @@ zfs_do_send(int argc, char **argv)
|
||||
return (1);
|
||||
}
|
||||
|
||||
if (resume_token != NULL) {
|
||||
return (zfs_send_resume(g_zfs, &flags, STDOUT_FILENO,
|
||||
resume_token));
|
||||
}
|
||||
|
||||
/*
|
||||
* Special case sending a filesystem, or from a bookmark.
|
||||
*/
|
||||
@@ -3893,8 +3918,6 @@ zfs_do_send(int argc, char **argv)
|
||||
}
|
||||
|
||||
/*
|
||||
* zfs receive [-vnFu] [-d | -e] <fs@snap>
|
||||
*
|
||||
* Restore a backup stream from stdin.
|
||||
*/
|
||||
static int
|
||||
@@ -3902,6 +3925,8 @@ zfs_do_receive(int argc, char **argv)
|
||||
{
|
||||
int c, err;
|
||||
recvflags_t flags = { 0 };
|
||||
boolean_t abort_resumable = B_FALSE;
|
||||
|
||||
nvlist_t *props;
|
||||
nvpair_t *nvp = NULL;
|
||||
|
||||
@@ -3909,7 +3934,7 @@ zfs_do_receive(int argc, char **argv)
|
||||
nomem();
|
||||
|
||||
/* check options */
|
||||
while ((c = getopt(argc, argv, ":o:denuvF")) != -1) {
|
||||
while ((c = getopt(argc, argv, ":o:denuvFsA")) != -1) {
|
||||
switch (c) {
|
||||
case 'o':
|
||||
if (parseprop(props, optarg) != 0)
|
||||
@@ -3931,9 +3956,15 @@ zfs_do_receive(int argc, char **argv)
|
||||
case 'v':
|
||||
flags.verbose = B_TRUE;
|
||||
break;
|
||||
case 's':
|
||||
flags.resumable = B_TRUE;
|
||||
break;
|
||||
case 'F':
|
||||
flags.force = B_TRUE;
|
||||
break;
|
||||
case 'A':
|
||||
abort_resumable = B_TRUE;
|
||||
break;
|
||||
case ':':
|
||||
(void) fprintf(stderr, gettext("missing argument for "
|
||||
"'%c' option\n"), optopt);
|
||||
@@ -3966,6 +3997,44 @@ zfs_do_receive(int argc, char **argv)
|
||||
}
|
||||
}
|
||||
|
||||
if (abort_resumable) {
|
||||
if (flags.isprefix || flags.istail || flags.dryrun ||
|
||||
flags.resumable || flags.nomount) {
|
||||
(void) fprintf(stderr, gettext("invalid option"));
|
||||
usage(B_FALSE);
|
||||
}
|
||||
|
||||
char namebuf[ZFS_MAXNAMELEN];
|
||||
(void) snprintf(namebuf, sizeof (namebuf),
|
||||
"%s/%%recv", argv[0]);
|
||||
|
||||
if (zfs_dataset_exists(g_zfs, namebuf,
|
||||
ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME)) {
|
||||
zfs_handle_t *zhp = zfs_open(g_zfs,
|
||||
namebuf, ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME);
|
||||
if (zhp == NULL)
|
||||
return (1);
|
||||
err = zfs_destroy(zhp, B_FALSE);
|
||||
} else {
|
||||
zfs_handle_t *zhp = zfs_open(g_zfs,
|
||||
argv[0], ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME);
|
||||
if (zhp == NULL)
|
||||
usage(B_FALSE);
|
||||
if (!zfs_prop_get_int(zhp, ZFS_PROP_INCONSISTENT) ||
|
||||
zfs_prop_get(zhp, ZFS_PROP_RECEIVE_RESUME_TOKEN,
|
||||
NULL, 0, NULL, NULL, 0, B_TRUE) == -1) {
|
||||
(void) fprintf(stderr,
|
||||
gettext("'%s' does not have any "
|
||||
"resumable receive state to abort\n"),
|
||||
argv[0]);
|
||||
return (1);
|
||||
}
|
||||
err = zfs_destroy(zhp, B_FALSE);
|
||||
}
|
||||
|
||||
return (err != 0);
|
||||
}
|
||||
|
||||
if (isatty(STDIN_FILENO)) {
|
||||
(void) fprintf(stderr,
|
||||
gettext("Error: Backup stream can not be read "
|
||||
@@ -3973,7 +4042,6 @@ zfs_do_receive(int argc, char **argv)
|
||||
"You must redirect standard input.\n"));
|
||||
return (1);
|
||||
}
|
||||
|
||||
err = zfs_receive(g_zfs, argv[0], props, &flags, STDIN_FILENO, NULL);
|
||||
|
||||
return (err != 0);
|
||||
@@ -5803,6 +5871,24 @@ share_mount_one(zfs_handle_t *zhp, int op, int flags, char *protocol,
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* If this filesystem is inconsistent and has a receive resume
|
||||
* token, we can not mount it.
|
||||
*/
|
||||
if (zfs_prop_get_int(zhp, ZFS_PROP_INCONSISTENT) &&
|
||||
zfs_prop_get(zhp, ZFS_PROP_RECEIVE_RESUME_TOKEN,
|
||||
NULL, 0, NULL, NULL, 0, B_TRUE) == 0) {
|
||||
if (!explicit)
|
||||
return (0);
|
||||
|
||||
(void) fprintf(stderr, gettext("cannot %s '%s': "
|
||||
"Contains partially-completed state from "
|
||||
"\"zfs receive -r\", which can be resumed with "
|
||||
"\"zfs send -t\"\n"),
|
||||
cmdname, zfs_get_name(zhp));
|
||||
return (1);
|
||||
}
|
||||
|
||||
/*
|
||||
* At this point, we have verified that the mountpoint and/or
|
||||
* shareopts are appropriate for auto management. If the
|
||||
|
||||
@@ -127,7 +127,7 @@ read_hdr(dmu_replay_record_t *drr, zio_cksum_t *cksum)
|
||||
(longlong_t)saved_cksum.zc_word[1],
|
||||
(longlong_t)saved_cksum.zc_word[2],
|
||||
(longlong_t)saved_cksum.zc_word[3]);
|
||||
exit(1);
|
||||
return (0);
|
||||
}
|
||||
return (sizeof (*drr));
|
||||
}
|
||||
@@ -347,8 +347,7 @@ main(int argc, char *argv[])
|
||||
if (verbose)
|
||||
(void) printf("\n");
|
||||
|
||||
if ((DMU_GET_STREAM_HDRTYPE(drrb->drr_versioninfo) ==
|
||||
DMU_COMPOUNDSTREAM) && drr->drr_payloadlen != 0) {
|
||||
if (drr->drr_payloadlen != 0) {
|
||||
nvlist_t *nv;
|
||||
int sz = drr->drr_payloadlen;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user