Add zfs.sync.snapshot_rename
Only the single snapshot rename is provided. The recursive or more complex rename can be scripted. Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov> Reviewed-by: George Melikov <mail@gmelikov.ru> Signed-off-by: Andriy Gapon <avg@FreeBSD.org> Closes #13802
This commit is contained in:
parent
7bb707ffaf
commit
ee9f3bca55
|
@ -301,6 +301,14 @@ typedef struct dsl_dataset_snapshot_arg {
|
||||||
proc_t *ddsa_proc;
|
proc_t *ddsa_proc;
|
||||||
} dsl_dataset_snapshot_arg_t;
|
} dsl_dataset_snapshot_arg_t;
|
||||||
|
|
||||||
|
typedef struct dsl_dataset_rename_snapshot_arg {
|
||||||
|
const char *ddrsa_fsname;
|
||||||
|
const char *ddrsa_oldsnapname;
|
||||||
|
const char *ddrsa_newsnapname;
|
||||||
|
boolean_t ddrsa_recursive;
|
||||||
|
dmu_tx_t *ddrsa_tx;
|
||||||
|
} dsl_dataset_rename_snapshot_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.
|
||||||
|
@ -473,6 +481,9 @@ 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);
|
||||||
|
|
||||||
|
int dsl_dataset_rename_snapshot_check(void *arg, dmu_tx_t *tx);
|
||||||
|
void dsl_dataset_rename_snapshot_sync(void *arg, dmu_tx_t *tx);
|
||||||
|
|
||||||
uint64_t dsl_dataset_get_remap_deadlist_object(dsl_dataset_t *ds);
|
uint64_t dsl_dataset_get_remap_deadlist_object(dsl_dataset_t *ds);
|
||||||
void dsl_dataset_create_remap_deadlist(dsl_dataset_t *ds, dmu_tx_t *tx);
|
void dsl_dataset_create_remap_deadlist(dsl_dataset_t *ds, dmu_tx_t *tx);
|
||||||
boolean_t dsl_dataset_remap_deadlist_exists(dsl_dataset_t *ds);
|
boolean_t dsl_dataset_remap_deadlist_exists(dsl_dataset_t *ds);
|
||||||
|
|
|
@ -424,6 +424,19 @@ To enable taking snapshots from ZCP scripts, the pool must be upgraded.
|
||||||
.It Ar dataset Pq string
|
.It Ar dataset Pq string
|
||||||
Name of snapshot to create.
|
Name of snapshot to create.
|
||||||
.El
|
.El
|
||||||
|
.It Fn zfs.sync.rename_snapshot dataset oldsnapname newsnapname
|
||||||
|
Rename a snapshot of a filesystem or a volume.
|
||||||
|
Returns 0 if the snapshot was successfully renamed,
|
||||||
|
and a nonzero error code otherwise.
|
||||||
|
.Pp
|
||||||
|
.Bl -tag -compact -width "newbookmark (string)"
|
||||||
|
.It Ar dataset Pq string
|
||||||
|
Name of the snapshot's parent dataset.
|
||||||
|
.It Ar oldsnapname Pq string
|
||||||
|
Original name of the snapshot.
|
||||||
|
.It Ar newsnapname Pq string
|
||||||
|
New name of the snapshot.
|
||||||
|
.El
|
||||||
.It Fn zfs.sync.bookmark source newbookmark
|
.It Fn zfs.sync.bookmark source newbookmark
|
||||||
Create a bookmark of an existing source snapshot or bookmark.
|
Create a bookmark of an existing source snapshot or bookmark.
|
||||||
Returns 0 if the new bookmark was successfully created,
|
Returns 0 if the new bookmark was successfully created,
|
||||||
|
|
|
@ -2915,14 +2915,6 @@ dsl_dataset_modified_since_snap(dsl_dataset_t *ds, dsl_dataset_t *snap)
|
||||||
return (B_FALSE);
|
return (B_FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct dsl_dataset_rename_snapshot_arg {
|
|
||||||
const char *ddrsa_fsname;
|
|
||||||
const char *ddrsa_oldsnapname;
|
|
||||||
const char *ddrsa_newsnapname;
|
|
||||||
boolean_t ddrsa_recursive;
|
|
||||||
dmu_tx_t *ddrsa_tx;
|
|
||||||
} dsl_dataset_rename_snapshot_arg_t;
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
dsl_dataset_rename_snapshot_check_impl(dsl_pool_t *dp,
|
dsl_dataset_rename_snapshot_check_impl(dsl_pool_t *dp,
|
||||||
dsl_dataset_t *hds, void *arg)
|
dsl_dataset_t *hds, void *arg)
|
||||||
|
@ -2953,7 +2945,7 @@ dsl_dataset_rename_snapshot_check_impl(dsl_pool_t *dp,
|
||||||
return (error);
|
return (error);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
int
|
||||||
dsl_dataset_rename_snapshot_check(void *arg, dmu_tx_t *tx)
|
dsl_dataset_rename_snapshot_check(void *arg, dmu_tx_t *tx)
|
||||||
{
|
{
|
||||||
dsl_dataset_rename_snapshot_arg_t *ddrsa = arg;
|
dsl_dataset_rename_snapshot_arg_t *ddrsa = arg;
|
||||||
|
@ -3015,7 +3007,7 @@ dsl_dataset_rename_snapshot_sync_impl(dsl_pool_t *dp,
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
void
|
||||||
dsl_dataset_rename_snapshot_sync(void *arg, dmu_tx_t *tx)
|
dsl_dataset_rename_snapshot_sync(void *arg, dmu_tx_t *tx)
|
||||||
{
|
{
|
||||||
dsl_dataset_rename_snapshot_arg_t *ddrsa = arg;
|
dsl_dataset_rename_snapshot_arg_t *ddrsa = arg;
|
||||||
|
|
|
@ -302,6 +302,42 @@ zcp_synctask_snapshot(lua_State *state, boolean_t sync, nvlist_t *err_details)
|
||||||
return (err);
|
return (err);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int zcp_synctask_rename_snapshot(lua_State *, boolean_t, nvlist_t *);
|
||||||
|
static const zcp_synctask_info_t zcp_synctask_rename_snapshot_info = {
|
||||||
|
.name = "rename_snapshot",
|
||||||
|
.func = zcp_synctask_rename_snapshot,
|
||||||
|
.pargs = {
|
||||||
|
{.za_name = "filesystem | volume", .za_lua_type = LUA_TSTRING },
|
||||||
|
{.za_name = "oldsnapname", .za_lua_type = LUA_TSTRING },
|
||||||
|
{.za_name = "newsnapname", .za_lua_type = LUA_TSTRING },
|
||||||
|
{NULL, 0}
|
||||||
|
},
|
||||||
|
.space_check = ZFS_SPACE_CHECK_RESERVED,
|
||||||
|
.blocks_modified = 1
|
||||||
|
};
|
||||||
|
|
||||||
|
static int
|
||||||
|
zcp_synctask_rename_snapshot(lua_State *state, boolean_t sync,
|
||||||
|
nvlist_t *err_details)
|
||||||
|
{
|
||||||
|
(void) err_details;
|
||||||
|
int err;
|
||||||
|
const char *fsname = lua_tostring(state, 1);
|
||||||
|
const char *oldsnapname = lua_tostring(state, 2);
|
||||||
|
const char *newsnapname = lua_tostring(state, 3);
|
||||||
|
|
||||||
|
struct dsl_dataset_rename_snapshot_arg ddrsa = { 0 };
|
||||||
|
ddrsa.ddrsa_fsname = fsname;
|
||||||
|
ddrsa.ddrsa_oldsnapname = oldsnapname;
|
||||||
|
ddrsa.ddrsa_newsnapname = newsnapname;
|
||||||
|
ddrsa.ddrsa_recursive = B_FALSE;
|
||||||
|
|
||||||
|
err = zcp_sync_task(state, dsl_dataset_rename_snapshot_check,
|
||||||
|
dsl_dataset_rename_snapshot_sync, &ddrsa, sync, NULL);
|
||||||
|
|
||||||
|
return (err);
|
||||||
|
}
|
||||||
|
|
||||||
static int zcp_synctask_inherit_prop(lua_State *, boolean_t,
|
static int zcp_synctask_inherit_prop(lua_State *, boolean_t,
|
||||||
nvlist_t *err_details);
|
nvlist_t *err_details);
|
||||||
static const zcp_synctask_info_t zcp_synctask_inherit_prop_info = {
|
static const zcp_synctask_info_t zcp_synctask_inherit_prop_info = {
|
||||||
|
@ -529,6 +565,7 @@ zcp_load_synctask_lib(lua_State *state, boolean_t sync)
|
||||||
&zcp_synctask_promote_info,
|
&zcp_synctask_promote_info,
|
||||||
&zcp_synctask_rollback_info,
|
&zcp_synctask_rollback_info,
|
||||||
&zcp_synctask_snapshot_info,
|
&zcp_synctask_snapshot_info,
|
||||||
|
&zcp_synctask_rename_snapshot_info,
|
||||||
&zcp_synctask_inherit_prop_info,
|
&zcp_synctask_inherit_prop_info,
|
||||||
&zcp_synctask_bookmark_info,
|
&zcp_synctask_bookmark_info,
|
||||||
&zcp_synctask_set_prop_info,
|
&zcp_synctask_set_prop_info,
|
||||||
|
|
|
@ -129,6 +129,7 @@ nobase_dist_datadir_zfs_tests_tests_DATA += \
|
||||||
functional/channel_program/synctask_core/tst.snapshot_destroy.zcp \
|
functional/channel_program/synctask_core/tst.snapshot_destroy.zcp \
|
||||||
functional/channel_program/synctask_core/tst.snapshot_neg.zcp \
|
functional/channel_program/synctask_core/tst.snapshot_neg.zcp \
|
||||||
functional/channel_program/synctask_core/tst.snapshot_recursive.zcp \
|
functional/channel_program/synctask_core/tst.snapshot_recursive.zcp \
|
||||||
|
functional/channel_program/synctask_core/tst.snapshot_rename.zcp \
|
||||||
functional/channel_program/synctask_core/tst.snapshot_simple.zcp \
|
functional/channel_program/synctask_core/tst.snapshot_simple.zcp \
|
||||||
functional/checksum/default.cfg \
|
functional/checksum/default.cfg \
|
||||||
functional/clean_mirror/clean_mirror_common.kshlib \
|
functional/clean_mirror/clean_mirror_common.kshlib \
|
||||||
|
@ -536,6 +537,7 @@ nobase_dist_datadir_zfs_tests_tests_SCRIPTS += \
|
||||||
functional/channel_program/synctask_core/tst.snapshot_destroy.ksh \
|
functional/channel_program/synctask_core/tst.snapshot_destroy.ksh \
|
||||||
functional/channel_program/synctask_core/tst.snapshot_neg.ksh \
|
functional/channel_program/synctask_core/tst.snapshot_neg.ksh \
|
||||||
functional/channel_program/synctask_core/tst.snapshot_recursive.ksh \
|
functional/channel_program/synctask_core/tst.snapshot_recursive.ksh \
|
||||||
|
functional/channel_program/synctask_core/tst.snapshot_rename.ksh \
|
||||||
functional/channel_program/synctask_core/tst.snapshot_simple.ksh \
|
functional/channel_program/synctask_core/tst.snapshot_simple.ksh \
|
||||||
functional/channel_program/synctask_core/tst.terminate_by_signal.ksh \
|
functional/channel_program/synctask_core/tst.terminate_by_signal.ksh \
|
||||||
functional/chattr/chattr_001_pos.ksh \
|
functional/chattr/chattr_001_pos.ksh \
|
||||||
|
|
|
@ -0,0 +1,41 @@
|
||||||
|
#!/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) 2022 by Andriy Gapon. All rights reserved.
|
||||||
|
#
|
||||||
|
|
||||||
|
. $STF_SUITE/tests/functional/channel_program/channel_common.kshlib
|
||||||
|
|
||||||
|
#
|
||||||
|
# DESCRIPTION: Make sure basic snapshot functionality works in channel programs
|
||||||
|
#
|
||||||
|
|
||||||
|
verify_runnable "global"
|
||||||
|
|
||||||
|
fs=$TESTPOOL/$TESTFS/testchild
|
||||||
|
snapname1=testsnap1
|
||||||
|
snapname2=testsnap2
|
||||||
|
|
||||||
|
function cleanup
|
||||||
|
{
|
||||||
|
destroy_dataset $fs "-R"
|
||||||
|
}
|
||||||
|
|
||||||
|
log_onexit cleanup
|
||||||
|
|
||||||
|
log_must zfs create $fs
|
||||||
|
|
||||||
|
log_must_program_sync $TESTPOOL \
|
||||||
|
$ZCP_ROOT/synctask_core/tst.snapshot_rename.zcp $fs $snapname1 $snapname2
|
||||||
|
|
||||||
|
log_pass "Snapshot renaming works"
|
|
@ -0,0 +1,27 @@
|
||||||
|
--
|
||||||
|
-- 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) 2022 by Andriy Gapon. All rights reserved.
|
||||||
|
--
|
||||||
|
|
||||||
|
-- This program should be invoked as "zfs program <pool> <prog> <fs> <snap>"
|
||||||
|
|
||||||
|
args = ...
|
||||||
|
argv = args["argv"]
|
||||||
|
assert(zfs.sync.snapshot(argv[1] .. "@" .. argv[2]) == 0)
|
||||||
|
assert(zfs.sync.rename_snapshot(argv[1], argv[2], argv[3]) == 0)
|
||||||
|
snaps = {}
|
||||||
|
for s in zfs.list.snapshots(argv[1]) do
|
||||||
|
table.insert(snaps, s)
|
||||||
|
end
|
||||||
|
assert(#snaps == 1)
|
||||||
|
assert(snaps[1] == (argv[1] .. "@" .. argv[3]))
|
Loading…
Reference in New Issue