OpenZFS 8592 - ZFS channel programs - rollback
Authored by: Brad Lewis <brad.lewis@delphix.com> Reviewed by: Chris Williamson <chris.williamson@delphix.com> Reviewed by: Matthew Ahrens <mahrens@delphix.com> Approved by: Robert Mustacchi <rm@joyent.com> Ported-by: Don Brady <don.brady@delphix.com> ZFS channel programs should be able to perform a rollback. OpenZFS-issue: https://www.illumos.org/issues/8592 OpenZFS-commit: https://github.com/openzfs/openzfs/commit/d46b5ed6
This commit is contained in:
parent
475eca4908
commit
af07368986
|
@ -20,7 +20,7 @@
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||||
* Copyright (c) 2011, 2016 by Delphix. All rights reserved.
|
* Copyright (c) 2011, 2017 by Delphix. All rights reserved.
|
||||||
* Copyright (c) 2013 Steven Hartland. All rights reserved.
|
* Copyright (c) 2013 Steven Hartland. All rights reserved.
|
||||||
* Copyright (c) 2014 Spectra Logic Corporation, All rights reserved.
|
* Copyright (c) 2014 Spectra Logic Corporation, All rights reserved.
|
||||||
*/
|
*/
|
||||||
|
@ -245,6 +245,13 @@ typedef struct dsl_dataset_promote_arg {
|
||||||
cred_t *cr;
|
cred_t *cr;
|
||||||
} dsl_dataset_promote_arg_t;
|
} dsl_dataset_promote_arg_t;
|
||||||
|
|
||||||
|
typedef struct dsl_dataset_rollback_arg {
|
||||||
|
const char *ddra_fsname;
|
||||||
|
const char *ddra_tosnap;
|
||||||
|
void *ddra_owner;
|
||||||
|
nvlist_t *ddra_result;
|
||||||
|
} dsl_dataset_rollback_arg_t;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The max length of a temporary tag prefix is the number of hex digits
|
* The max length of a temporary tag prefix is the number of hex digits
|
||||||
* required to express UINT64_MAX plus one for the hyphen.
|
* required to express UINT64_MAX plus one for the hyphen.
|
||||||
|
@ -394,6 +401,9 @@ void dsl_dataset_set_refreservation_sync_impl(dsl_dataset_t *ds,
|
||||||
void dsl_dataset_zapify(dsl_dataset_t *ds, dmu_tx_t *tx);
|
void dsl_dataset_zapify(dsl_dataset_t *ds, dmu_tx_t *tx);
|
||||||
boolean_t dsl_dataset_is_zapified(dsl_dataset_t *ds);
|
boolean_t dsl_dataset_is_zapified(dsl_dataset_t *ds);
|
||||||
boolean_t dsl_dataset_has_resume_receive_state(dsl_dataset_t *ds);
|
boolean_t dsl_dataset_has_resume_receive_state(dsl_dataset_t *ds);
|
||||||
|
|
||||||
|
int dsl_dataset_rollback_check(void *arg, dmu_tx_t *tx);
|
||||||
|
void dsl_dataset_rollback_sync(void *arg, dmu_tx_t *tx);
|
||||||
int dsl_dataset_rollback(const char *fsname, const char *tosnap, void *owner,
|
int dsl_dataset_rollback(const char *fsname, const char *tosnap, void *owner,
|
||||||
nvlist_t *result);
|
nvlist_t *result);
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
.\" http://www.illumos.org/license/CDDL.
|
.\" http://www.illumos.org/license/CDDL.
|
||||||
.\"
|
.\"
|
||||||
.\"
|
.\"
|
||||||
.\" Copyright (c) 2016 by Delphix. All Rights Reserved.
|
.\" Copyright (c) 2016, 2017 by Delphix. All Rights Reserved.
|
||||||
.\"
|
.\"
|
||||||
.Dd January 21, 2016
|
.Dd January 21, 2016
|
||||||
.Dt ZFS-PROGRAM 8
|
.Dt ZFS-PROGRAM 8
|
||||||
|
@ -361,6 +361,17 @@ dataset (string)
|
||||||
.Bd -ragged -compact -offset "xxxx"
|
.Bd -ragged -compact -offset "xxxx"
|
||||||
Clone to be promoted.
|
Clone to be promoted.
|
||||||
.Ed
|
.Ed
|
||||||
|
.It Em zfs.sync.rollback(filesystem)
|
||||||
|
Rollback to the previous snapshot for a dataset.
|
||||||
|
Returns 0 on successful rollback, or a nonzero error code otherwise.
|
||||||
|
Rollbacks can be performed on filesystems or zvols, but not on snapshots
|
||||||
|
or mounted datasets.
|
||||||
|
EBUSY is returned in the case where the filesystem is mounted.
|
||||||
|
.Pp
|
||||||
|
filesystem (string)
|
||||||
|
.Bd -ragged -compact -offset "xxxx"
|
||||||
|
Filesystem to rollback.
|
||||||
|
.Ed
|
||||||
.El
|
.El
|
||||||
.It Sy zfs.check submodule
|
.It Sy zfs.check submodule
|
||||||
For each function in the zfs.sync submodule, there is a corresponding zfs.check
|
For each function in the zfs.sync submodule, there is a corresponding zfs.check
|
||||||
|
@ -380,6 +391,7 @@ The available zfs.check functions are:
|
||||||
.Bl -tag -width "xx"
|
.Bl -tag -width "xx"
|
||||||
.It Em zfs.check.destroy(dataset, [defer=true|false])
|
.It Em zfs.check.destroy(dataset, [defer=true|false])
|
||||||
.It Em zfs.check.promote(dataset)
|
.It Em zfs.check.promote(dataset)
|
||||||
|
.It Em zfs.check.rollback(filesystem)
|
||||||
.El
|
.El
|
||||||
.It Sy zfs.list submodule
|
.It Sy zfs.list submodule
|
||||||
The zfs.list submodule provides functions for iterating over datasets and
|
The zfs.list submodule provides functions for iterating over datasets and
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||||
* Copyright (c) 2011, 2016 by Delphix. All rights reserved.
|
* Copyright (c) 2011, 2017 by Delphix. All rights reserved.
|
||||||
* Copyright (c) 2014, Joyent, Inc. All rights reserved.
|
* Copyright (c) 2014, Joyent, Inc. All rights reserved.
|
||||||
* Copyright (c) 2014 RackTop Systems.
|
* Copyright (c) 2014 RackTop Systems.
|
||||||
* Copyright (c) 2014 Spectra Logic Corporation, All rights reserved.
|
* Copyright (c) 2014 Spectra Logic Corporation, All rights reserved.
|
||||||
|
@ -2526,14 +2526,7 @@ dsl_dataset_handoff_check(dsl_dataset_t *ds, void *owner, dmu_tx_t *tx)
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct dsl_dataset_rollback_arg {
|
int
|
||||||
const char *ddra_fsname;
|
|
||||||
const char *ddra_tosnap;
|
|
||||||
void *ddra_owner;
|
|
||||||
nvlist_t *ddra_result;
|
|
||||||
} dsl_dataset_rollback_arg_t;
|
|
||||||
|
|
||||||
static int
|
|
||||||
dsl_dataset_rollback_check(void *arg, dmu_tx_t *tx)
|
dsl_dataset_rollback_check(void *arg, dmu_tx_t *tx)
|
||||||
{
|
{
|
||||||
dsl_dataset_rollback_arg_t *ddra = arg;
|
dsl_dataset_rollback_arg_t *ddra = arg;
|
||||||
|
@ -2641,7 +2634,7 @@ dsl_dataset_rollback_check(void *arg, dmu_tx_t *tx)
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
void
|
||||||
dsl_dataset_rollback_sync(void *arg, dmu_tx_t *tx)
|
dsl_dataset_rollback_sync(void *arg, dmu_tx_t *tx)
|
||||||
{
|
{
|
||||||
dsl_dataset_rollback_arg_t *ddra = arg;
|
dsl_dataset_rollback_arg_t *ddra = arg;
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2016 by Delphix. All rights reserved.
|
* Copyright (c) 2016, 2017 by Delphix. All rights reserved.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/lua/lua.h>
|
#include <sys/lua/lua.h>
|
||||||
|
@ -177,6 +177,37 @@ zcp_synctask_promote(lua_State *state, boolean_t sync, nvlist_t *err_details)
|
||||||
return (err);
|
return (err);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int zcp_synctask_rollback(lua_State *, boolean_t, nvlist_t *err_details);
|
||||||
|
static zcp_synctask_info_t zcp_synctask_rollback_info = {
|
||||||
|
.name = "rollback",
|
||||||
|
.func = zcp_synctask_rollback,
|
||||||
|
.space_check = ZFS_SPACE_CHECK_RESERVED,
|
||||||
|
.blocks_modified = 1,
|
||||||
|
.pargs = {
|
||||||
|
{.za_name = "filesystem", .za_lua_type = LUA_TSTRING},
|
||||||
|
{0, 0}
|
||||||
|
},
|
||||||
|
.kwargs = {
|
||||||
|
{0, 0}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
static int
|
||||||
|
zcp_synctask_rollback(lua_State *state, boolean_t sync, nvlist_t *err_details)
|
||||||
|
{
|
||||||
|
int err;
|
||||||
|
const char *dsname = lua_tostring(state, 1);
|
||||||
|
dsl_dataset_rollback_arg_t ddra = { 0 };
|
||||||
|
|
||||||
|
ddra.ddra_fsname = dsname;
|
||||||
|
ddra.ddra_result = err_details;
|
||||||
|
|
||||||
|
err = zcp_sync_task(state, dsl_dataset_rollback_check,
|
||||||
|
dsl_dataset_rollback_sync, &ddra, sync, dsname);
|
||||||
|
|
||||||
|
return (err);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
zcp_synctask_wrapper_cleanup(void *arg)
|
zcp_synctask_wrapper_cleanup(void *arg)
|
||||||
{
|
{
|
||||||
|
@ -247,6 +278,7 @@ zcp_load_synctask_lib(lua_State *state, boolean_t sync)
|
||||||
zcp_synctask_info_t *zcp_synctask_funcs[] = {
|
zcp_synctask_info_t *zcp_synctask_funcs[] = {
|
||||||
&zcp_synctask_destroy_info,
|
&zcp_synctask_destroy_info,
|
||||||
&zcp_synctask_promote_info,
|
&zcp_synctask_promote_info,
|
||||||
|
&zcp_synctask_rollback_info,
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -78,7 +78,7 @@ tests = ['tst.destroy_fs', 'tst.destroy_snap', 'tst.get_count_and_limit',
|
||||||
'tst.get_userquota', 'tst.get_written', 'tst.list_children',
|
'tst.get_userquota', 'tst.get_written', 'tst.list_children',
|
||||||
'tst.list_clones', 'tst.list_snapshots', 'tst.list_system_props',
|
'tst.list_clones', 'tst.list_snapshots', 'tst.list_system_props',
|
||||||
'tst.parse_args_neg', 'tst.promote_conflict', 'tst.promote_multiple',
|
'tst.parse_args_neg', 'tst.promote_conflict', 'tst.promote_multiple',
|
||||||
'tst.promote_simple']
|
'tst.promote_simple', 'tst.rollback_mult', 'tst.rollback_one']
|
||||||
tags = ['functional', 'channel_program', 'synctask_core']
|
tags = ['functional', 'channel_program', 'synctask_core']
|
||||||
|
|
||||||
[tests/functional/chattr]
|
[tests/functional/chattr]
|
||||||
|
|
|
@ -27,4 +27,6 @@ dist_pkgdata_SCRIPTS = \
|
||||||
tst.promote_conflict.ksh \
|
tst.promote_conflict.ksh \
|
||||||
tst.promote_conflict.zcp \
|
tst.promote_conflict.zcp \
|
||||||
tst.promote_multiple.ksh \
|
tst.promote_multiple.ksh \
|
||||||
tst.promote_simple.ksh
|
tst.promote_simple.ksh \
|
||||||
|
tst.rollback_mult.ksh \
|
||||||
|
tst.rollback_one.ksh
|
||||||
|
|
|
@ -0,0 +1,61 @@
|
||||||
|
#!/bin/ksh -p
|
||||||
|
#
|
||||||
|
# This file and its contents are supplied under the terms of the
|
||||||
|
# Common Development and Distribution License ("CDDL"), version 1.0.
|
||||||
|
# You may only use this file in accordance with the terms of version
|
||||||
|
# 1.0 of the CDDL.
|
||||||
|
#
|
||||||
|
# A full copy of the text of the CDDL should have accompanied this
|
||||||
|
# source. A copy of the CDDL is also available via the Internet at
|
||||||
|
# http://www.illumos.org/license/CDDL.
|
||||||
|
#
|
||||||
|
|
||||||
|
#
|
||||||
|
# Copyright (c) 2016, 2017 by Delphix. All rights reserved.
|
||||||
|
#
|
||||||
|
|
||||||
|
. $STF_SUITE/tests/functional/channel_program/channel_common.kshlib
|
||||||
|
|
||||||
|
verify_runnable "global"
|
||||||
|
snap1=$TESTPOOL/$TESTFS@$TESTSNAP1
|
||||||
|
snap2=$TESTPOOL/$TESTFS@$TESTSNAP2
|
||||||
|
fs=$TESTPOOL/$TESTFS
|
||||||
|
file=$TESTDIR/$TESTFILE0
|
||||||
|
|
||||||
|
function cleanup
|
||||||
|
{
|
||||||
|
datasetexists $snap1 && log_must zfs destroy $snap1 && \
|
||||||
|
log_must rm $file
|
||||||
|
}
|
||||||
|
|
||||||
|
log_onexit cleanup
|
||||||
|
|
||||||
|
log_must mkfile 128b $file
|
||||||
|
create_snapshot $TESTPOOL/$TESTFS $TESTSNAP1
|
||||||
|
log_must rm $file
|
||||||
|
create_snapshot $TESTPOOL/$TESTFS $TESTSNAP2
|
||||||
|
|
||||||
|
log_must snapexists $snap1
|
||||||
|
log_must snapexists $snap2
|
||||||
|
log_must zfs unmount $fs
|
||||||
|
|
||||||
|
log_must_program $TESTPOOL - $fs $snap2 <<-EOF
|
||||||
|
arg = ...
|
||||||
|
fs = arg["argv"][1]
|
||||||
|
snap = arg["argv"][2]
|
||||||
|
err = zfs.sync.rollback(fs)
|
||||||
|
if err == 0 then
|
||||||
|
err = zfs.sync.destroy(snap)
|
||||||
|
end
|
||||||
|
if err == 0 then
|
||||||
|
err = zfs.sync.rollback(fs)
|
||||||
|
end
|
||||||
|
msg = "rolling back " .. fs .. " err=" .. err
|
||||||
|
return msg
|
||||||
|
EOF
|
||||||
|
|
||||||
|
log_must zfs mount $fs
|
||||||
|
log_must [ -f $file ]
|
||||||
|
log_mustnot snapexists $snap2
|
||||||
|
|
||||||
|
log_pass "Rolling back snapshot with channel program works."
|
|
@ -0,0 +1,51 @@
|
||||||
|
#!/bin/ksh -p
|
||||||
|
#
|
||||||
|
# This file and its contents are supplied under the terms of the
|
||||||
|
# Common Development and Distribution License ("CDDL"), version 1.0.
|
||||||
|
# You may only use this file in accordance with the terms of version
|
||||||
|
# 1.0 of the CDDL.
|
||||||
|
#
|
||||||
|
# A full copy of the text of the CDDL should have accompanied this
|
||||||
|
# source. A copy of the CDDL is also available via the Internet at
|
||||||
|
# http://www.illumos.org/license/CDDL.
|
||||||
|
#
|
||||||
|
|
||||||
|
#
|
||||||
|
# Copyright (c) 2016, 2017 by Delphix. All rights reserved.
|
||||||
|
#
|
||||||
|
|
||||||
|
. $STF_SUITE/tests/functional/channel_program/channel_common.kshlib
|
||||||
|
|
||||||
|
verify_runnable "global"
|
||||||
|
snap=$TESTPOOL/$TESTFS@$TESTSNAP
|
||||||
|
fs=$TESTPOOL/$TESTFS
|
||||||
|
file=$TESTDIR/$TESTFILE0
|
||||||
|
|
||||||
|
function cleanup
|
||||||
|
{
|
||||||
|
datasetexists $snap && log_must zfs destroy $snap && \
|
||||||
|
log_must rm $file
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
log_onexit cleanup
|
||||||
|
|
||||||
|
log_must mkfile 128b $file
|
||||||
|
create_snapshot $TESTPOOL/$TESTFS $TESTSNAP
|
||||||
|
log_must rm $file
|
||||||
|
|
||||||
|
log_must snapexists $snap
|
||||||
|
log_must zfs unmount $fs
|
||||||
|
|
||||||
|
log_must_program $TESTPOOL - $fs <<-EOF
|
||||||
|
arg = ...
|
||||||
|
fs = arg["argv"][1]
|
||||||
|
err = zfs.sync.rollback(fs)
|
||||||
|
msg = "rolling back " .. fs .. " err=" .. err
|
||||||
|
return msg
|
||||||
|
EOF
|
||||||
|
|
||||||
|
log_must zfs mount $fs
|
||||||
|
log_must [ -f $file ]
|
||||||
|
|
||||||
|
log_pass "Rolling back snapshot with channel program works."
|
Loading…
Reference in New Issue