]> git.proxmox.com Git - mirror_zfs.git/commitdiff
Add zfs.sync.snapshot_rename
authorAndriy Gapon <avg@FreeBSD.org>
Fri, 2 Sep 2022 20:31:19 +0000 (23:31 +0300)
committerGitHub <noreply@github.com>
Fri, 2 Sep 2022 20:31:19 +0000 (13:31 -0700)
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

include/sys/dsl_dataset.h
man/man8/zfs-program.8
module/zfs/dsl_dataset.c
module/zfs/zcp_synctask.c
tests/zfs-tests/tests/Makefile.am
tests/zfs-tests/tests/functional/channel_program/synctask_core/tst.snapshot_rename.ksh [new file with mode: 0755]
tests/zfs-tests/tests/functional/channel_program/synctask_core/tst.snapshot_rename.zcp [new file with mode: 0644]

index 81d25da831bff273165659a3030e84de5895a3a9..3450527af7e03e088f288850c48b7d076d03cdb4 100644 (file)
@@ -301,6 +301,14 @@ typedef struct dsl_dataset_snapshot_arg {
        proc_t *ddsa_proc;
 } 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
  * 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,
     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);
 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);
index 06415b2190eb30e78ffe529508ba5e1a36186c03..928620362be7fc3995d9293b5bba413f0f455e98 100644 (file)
@@ -424,6 +424,19 @@ To enable taking snapshots from ZCP scripts, the pool must be upgraded.
 .It Ar dataset Pq string
 Name of snapshot to create.
 .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
 Create a bookmark of an existing source snapshot or bookmark.
 Returns 0 if the new bookmark was successfully created,
index 8f3240a5debae9cff453b1af6b347d7ee6727da1..44da6a3f0d403f3aea3a32a164866385968d2a5f 100644 (file)
@@ -2915,14 +2915,6 @@ dsl_dataset_modified_since_snap(dsl_dataset_t *ds, dsl_dataset_t *snap)
        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
 dsl_dataset_rename_snapshot_check_impl(dsl_pool_t *dp,
     dsl_dataset_t *hds, void *arg)
@@ -2953,7 +2945,7 @@ dsl_dataset_rename_snapshot_check_impl(dsl_pool_t *dp,
        return (error);
 }
 
-static int
+int
 dsl_dataset_rename_snapshot_check(void *arg, dmu_tx_t *tx)
 {
        dsl_dataset_rename_snapshot_arg_t *ddrsa = arg;
@@ -3015,7 +3007,7 @@ dsl_dataset_rename_snapshot_sync_impl(dsl_pool_t *dp,
        return (0);
 }
 
-static void
+void
 dsl_dataset_rename_snapshot_sync(void *arg, dmu_tx_t *tx)
 {
        dsl_dataset_rename_snapshot_arg_t *ddrsa = arg;
index 24210117eca0443f6b846dc28c53fd9d257e6a10..058910054d97201b7cf9f038c82759bf6001c62a 100644 (file)
@@ -302,6 +302,42 @@ zcp_synctask_snapshot(lua_State *state, boolean_t sync, nvlist_t *err_details)
        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,
     nvlist_t *err_details);
 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_rollback_info,
                &zcp_synctask_snapshot_info,
+               &zcp_synctask_rename_snapshot_info,
                &zcp_synctask_inherit_prop_info,
                &zcp_synctask_bookmark_info,
                &zcp_synctask_set_prop_info,
index b80489af25516a5d463dbc38a642ea0ddb94d488..89b2ca866c214559692db89454fd79f5673120ad 100644 (file)
@@ -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_neg.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/checksum/default.cfg \
        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_neg.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.terminate_by_signal.ksh \
        functional/chattr/chattr_001_pos.ksh \
diff --git a/tests/zfs-tests/tests/functional/channel_program/synctask_core/tst.snapshot_rename.ksh b/tests/zfs-tests/tests/functional/channel_program/synctask_core/tst.snapshot_rename.ksh
new file mode 100755 (executable)
index 0000000..0561e4b
--- /dev/null
@@ -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"
diff --git a/tests/zfs-tests/tests/functional/channel_program/synctask_core/tst.snapshot_rename.zcp b/tests/zfs-tests/tests/functional/channel_program/synctask_core/tst.snapshot_rename.zcp
new file mode 100644 (file)
index 0000000..ef893d1
--- /dev/null
@@ -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]))