mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2024-12-26 19:19:32 +03:00
zcp: add zfs.sync.bookmark
Add support for bookmark creation and cloning. Reviewed-by: Matt Ahrens <matt@delphix.com> Reviewed-by: Paul Dagnelie <pcd@delphix.com> Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov> Signed-off-by: Christian Schwarz <me@cschwarz.com> Closes #9571
This commit is contained in:
parent
a73f361fdb
commit
948f0c4419
@ -102,8 +102,25 @@ typedef struct redact_block_phys {
|
|||||||
|
|
||||||
typedef int (*rl_traverse_callback_t)(redact_block_phys_t *, void *);
|
typedef int (*rl_traverse_callback_t)(redact_block_phys_t *, void *);
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct dsl_bookmark_create_arg {
|
||||||
|
nvlist_t *dbca_bmarks;
|
||||||
|
nvlist_t *dbca_errors;
|
||||||
|
} dsl_bookmark_create_arg_t;
|
||||||
|
|
||||||
|
typedef struct dsl_bookmark_create_redacted_arg {
|
||||||
|
const char *dbcra_bmark;
|
||||||
|
const char *dbcra_snap;
|
||||||
|
redaction_list_t **dbcra_rl;
|
||||||
|
uint64_t dbcra_numsnaps;
|
||||||
|
uint64_t *dbcra_snaps;
|
||||||
|
void *dbcra_tag;
|
||||||
|
} dsl_bookmark_create_redacted_arg_t;
|
||||||
|
|
||||||
int dsl_bookmark_create(nvlist_t *, nvlist_t *);
|
int dsl_bookmark_create(nvlist_t *, nvlist_t *);
|
||||||
int dsl_bookmark_create_nvl_validate(nvlist_t *);
|
int dsl_bookmark_create_nvl_validate(nvlist_t *);
|
||||||
|
int dsl_bookmark_create_check(void *arg, dmu_tx_t *tx);
|
||||||
|
void dsl_bookmark_create_sync(void *arg, dmu_tx_t *tx);
|
||||||
int dsl_bookmark_create_redacted(const char *, const char *, uint64_t,
|
int dsl_bookmark_create_redacted(const char *, const char *, uint64_t,
|
||||||
uint64_t *, void *, redaction_list_t **);
|
uint64_t *, void *, redaction_list_t **);
|
||||||
int dsl_get_bookmarks(const char *, nvlist_t *, nvlist_t *);
|
int dsl_get_bookmarks(const char *, nvlist_t *, nvlist_t *);
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
.\"
|
.\"
|
||||||
.\"
|
.\"
|
||||||
.\" Copyright (c) 2016, 2019 by Delphix. All Rights Reserved.
|
.\" Copyright (c) 2016, 2019 by Delphix. All Rights Reserved.
|
||||||
|
.\" Copyright (c) 2019, 2020 by Christian Schwarz. All Rights Reserved.
|
||||||
.\" Copyright 2020 Joyent, Inc.
|
.\" Copyright 2020 Joyent, Inc.
|
||||||
.\"
|
.\"
|
||||||
.Dd January 15, 2020
|
.Dd January 15, 2020
|
||||||
@ -419,6 +420,21 @@ dataset (string)
|
|||||||
.Bd -ragged -compact -offset "xxxx"
|
.Bd -ragged -compact -offset "xxxx"
|
||||||
Name of snapshot to create.
|
Name of snapshot to create.
|
||||||
.Ed
|
.Ed
|
||||||
|
.It Em zfs.sync.bookmark(source, newbookmark)
|
||||||
|
Create a bookmark of an existing source snapshot or bookmark.
|
||||||
|
Returns 0 if the new bookmark was successfully created,
|
||||||
|
and a nonzero error code otherwise.
|
||||||
|
.Pp
|
||||||
|
Note: Bookmarking requires the corresponding pool feature to be enabled.
|
||||||
|
.Pp
|
||||||
|
source (string)
|
||||||
|
.Bd -ragged -compact -offset "xxxx"
|
||||||
|
Full name of the existing snapshot or bookmark.
|
||||||
|
.Ed
|
||||||
|
.Pp
|
||||||
|
newbookmark (string)
|
||||||
|
.Bd -ragged -compact -offset "xxxx"
|
||||||
|
Full name of the new bookmark.
|
||||||
.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
|
||||||
|
@ -205,20 +205,6 @@ dsl_bookmark_create_nvl_validate(nvlist_t *bmarks)
|
|||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct dsl_bookmark_create_redacted_arg {
|
|
||||||
const char *dbcra_bmark;
|
|
||||||
const char *dbcra_snap;
|
|
||||||
redaction_list_t **dbcra_rl;
|
|
||||||
uint64_t dbcra_numsnaps;
|
|
||||||
uint64_t *dbcra_snaps;
|
|
||||||
void *dbcra_tag;
|
|
||||||
} dsl_bookmark_create_redacted_arg_t;
|
|
||||||
|
|
||||||
typedef struct dsl_bookmark_create_arg {
|
|
||||||
nvlist_t *dbca_bmarks;
|
|
||||||
nvlist_t *dbca_errors;
|
|
||||||
} dsl_bookmark_create_arg_t;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* expects that newbm and source have been validated using
|
* expects that newbm and source have been validated using
|
||||||
* dsl_bookmark_create_nvl_validate_pair
|
* dsl_bookmark_create_nvl_validate_pair
|
||||||
@ -301,7 +287,7 @@ eholdnewbmds:
|
|||||||
return (error);
|
return (error);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
int
|
||||||
dsl_bookmark_create_check(void *arg, dmu_tx_t *tx)
|
dsl_bookmark_create_check(void *arg, dmu_tx_t *tx)
|
||||||
{
|
{
|
||||||
dsl_bookmark_create_arg_t *dbca = arg;
|
dsl_bookmark_create_arg_t *dbca = arg;
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2016, 2017 by Delphix. All rights reserved.
|
* Copyright (c) 2016, 2017 by Delphix. All rights reserved.
|
||||||
|
* Copyright (c) 2019, 2020 by Christian Schwarz. All rights reserved.
|
||||||
* Copyright 2020 Joyent, Inc.
|
* Copyright 2020 Joyent, Inc.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -370,6 +371,49 @@ zcp_synctask_inherit_prop(lua_State *state, boolean_t sync,
|
|||||||
return (err);
|
return (err);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int zcp_synctask_bookmark(lua_State *, boolean_t, nvlist_t *);
|
||||||
|
static zcp_synctask_info_t zcp_synctask_bookmark_info = {
|
||||||
|
.name = "bookmark",
|
||||||
|
.func = zcp_synctask_bookmark,
|
||||||
|
.pargs = {
|
||||||
|
{.za_name = "snapshot | bookmark", .za_lua_type = LUA_TSTRING},
|
||||||
|
{.za_name = "bookmark", .za_lua_type = LUA_TSTRING},
|
||||||
|
{NULL, 0}
|
||||||
|
},
|
||||||
|
.kwargs = {
|
||||||
|
{NULL, 0}
|
||||||
|
},
|
||||||
|
.space_check = ZFS_SPACE_CHECK_NORMAL,
|
||||||
|
.blocks_modified = 1,
|
||||||
|
};
|
||||||
|
|
||||||
|
/* ARGSUSED */
|
||||||
|
static int
|
||||||
|
zcp_synctask_bookmark(lua_State *state, boolean_t sync, nvlist_t *err_details)
|
||||||
|
{
|
||||||
|
int err;
|
||||||
|
const char *source = lua_tostring(state, 1);
|
||||||
|
const char *new = lua_tostring(state, 2);
|
||||||
|
|
||||||
|
nvlist_t *bmarks = fnvlist_alloc();
|
||||||
|
fnvlist_add_string(bmarks, new, source);
|
||||||
|
|
||||||
|
zcp_cleanup_handler_t *zch = zcp_register_cleanup(state,
|
||||||
|
(zcp_cleanup_t *)&fnvlist_free, bmarks);
|
||||||
|
|
||||||
|
dsl_bookmark_create_arg_t dbca = {
|
||||||
|
.dbca_bmarks = bmarks,
|
||||||
|
.dbca_errors = NULL,
|
||||||
|
};
|
||||||
|
err = zcp_sync_task(state, dsl_bookmark_create_check,
|
||||||
|
dsl_bookmark_create_sync, &dbca, sync, source);
|
||||||
|
|
||||||
|
zcp_deregister_cleanup(state, zch);
|
||||||
|
fnvlist_free(bmarks);
|
||||||
|
|
||||||
|
return (err);
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
zcp_synctask_wrapper(lua_State *state)
|
zcp_synctask_wrapper(lua_State *state)
|
||||||
{
|
{
|
||||||
@ -439,6 +483,7 @@ zcp_load_synctask_lib(lua_State *state, boolean_t sync)
|
|||||||
&zcp_synctask_rollback_info,
|
&zcp_synctask_rollback_info,
|
||||||
&zcp_synctask_snapshot_info,
|
&zcp_synctask_snapshot_info,
|
||||||
&zcp_synctask_inherit_prop_info,
|
&zcp_synctask_inherit_prop_info,
|
||||||
|
&zcp_synctask_bookmark_info,
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -87,7 +87,7 @@ tests = ['tst.destroy_fs', 'tst.destroy_snap', 'tst.get_count_and_limit',
|
|||||||
'tst.promote_multiple', 'tst.promote_simple', 'tst.rollback_mult',
|
'tst.promote_multiple', 'tst.promote_simple', 'tst.rollback_mult',
|
||||||
'tst.rollback_one', 'tst.snapshot_destroy', 'tst.snapshot_neg',
|
'tst.rollback_one', 'tst.snapshot_destroy', 'tst.snapshot_neg',
|
||||||
'tst.snapshot_recursive', 'tst.snapshot_simple',
|
'tst.snapshot_recursive', 'tst.snapshot_simple',
|
||||||
'tst.bookmark.create', 'tst.bookmark.clone',
|
'tst.bookmark.create', 'tst.bookmark.copy',
|
||||||
'tst.terminate_by_signal'
|
'tst.terminate_by_signal'
|
||||||
]
|
]
|
||||||
tags = ['functional', 'channel_program', 'synctask_core']
|
tags = ['functional', 'channel_program', 'synctask_core']
|
||||||
|
@ -30,6 +30,8 @@ dist_pkgdata_SCRIPTS = \
|
|||||||
tst.snapshot_destroy.ksh \
|
tst.snapshot_destroy.ksh \
|
||||||
tst.snapshot_neg.ksh \
|
tst.snapshot_neg.ksh \
|
||||||
tst.snapshot_recursive.ksh \
|
tst.snapshot_recursive.ksh \
|
||||||
|
tst.bookmark.create.ksh \
|
||||||
|
tst.bookmark.copy.ksh \
|
||||||
tst.snapshot_simple.ksh \
|
tst.snapshot_simple.ksh \
|
||||||
tst.terminate_by_signal.ksh
|
tst.terminate_by_signal.ksh
|
||||||
|
|
||||||
@ -44,4 +46,6 @@ dist_pkgdata_DATA = \
|
|||||||
tst.snapshot_destroy.zcp \
|
tst.snapshot_destroy.zcp \
|
||||||
tst.snapshot_neg.zcp \
|
tst.snapshot_neg.zcp \
|
||||||
tst.snapshot_recursive.zcp \
|
tst.snapshot_recursive.zcp \
|
||||||
tst.snapshot_simple.zcp
|
tst.snapshot_simple.zcp \
|
||||||
|
tst.bookmark.create.zcp \
|
||||||
|
tst.bookmark.copy.zcp
|
||||||
|
@ -0,0 +1,45 @@
|
|||||||
|
#!/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) 2019, 2020 by Christian Schwarz. All rights reserved.
|
||||||
|
#
|
||||||
|
|
||||||
|
. $STF_SUITE/tests/functional/channel_program/channel_common.kshlib
|
||||||
|
|
||||||
|
#
|
||||||
|
# DESCRIPTION: Make sure bookmark copying works in channel programs
|
||||||
|
#
|
||||||
|
|
||||||
|
verify_runnable "global"
|
||||||
|
|
||||||
|
fs=$TESTPOOL/$TESTFS/testchild
|
||||||
|
snapname=testsnap
|
||||||
|
bookname=testbookmark
|
||||||
|
bookcopyname=testbookmark_copy
|
||||||
|
|
||||||
|
function cleanup
|
||||||
|
{
|
||||||
|
destroy_dataset $fs "-R"
|
||||||
|
}
|
||||||
|
|
||||||
|
log_onexit cleanup
|
||||||
|
|
||||||
|
log_must zfs create $fs
|
||||||
|
|
||||||
|
log_must zfs snapshot $fs@$snapname
|
||||||
|
log_must zfs bookmark $fs@$snapname "$fs#$bookname"
|
||||||
|
|
||||||
|
log_must_program_sync $TESTPOOL \
|
||||||
|
$ZCP_ROOT/synctask_core/tst.bookmark.copy.zcp $fs $bookname $bookcopyname
|
||||||
|
|
||||||
|
log_pass "Simple bookmark copying works"
|
@ -0,0 +1,32 @@
|
|||||||
|
--
|
||||||
|
-- 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) 2019, 2020 by Christian Schwarz. All rights reserved.
|
||||||
|
--
|
||||||
|
|
||||||
|
-- This program should be invoked as "zfs program <pool> <prog> <fs> <source_book> <new_book>"
|
||||||
|
|
||||||
|
args = ...
|
||||||
|
argv = args["argv"]
|
||||||
|
fs = argv[1]
|
||||||
|
source = fs .. "#" .. argv[2]
|
||||||
|
new = fs .. "#" .. argv[3]
|
||||||
|
assert(zfs.sync.bookmark(source, new) == 0)
|
||||||
|
books = {}
|
||||||
|
count = 0
|
||||||
|
for s in zfs.list.bookmarks(fs) do
|
||||||
|
count = count + 1
|
||||||
|
books[s] = 1
|
||||||
|
end
|
||||||
|
assert(count == 2)
|
||||||
|
assert(books[source] == 1)
|
||||||
|
assert(books[new] == 1)
|
@ -0,0 +1,43 @@
|
|||||||
|
#!/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) 2019, 2020 by Christian Schwarz. All rights reserved.
|
||||||
|
#
|
||||||
|
|
||||||
|
. $STF_SUITE/tests/functional/channel_program/channel_common.kshlib
|
||||||
|
|
||||||
|
#
|
||||||
|
# DESCRIPTION: Make sure basic bookmark functionality works in channel programs
|
||||||
|
#
|
||||||
|
|
||||||
|
verify_runnable "global"
|
||||||
|
|
||||||
|
fs=$TESTPOOL/$TESTFS/testchild
|
||||||
|
snapname=testsnap
|
||||||
|
bookname=testbookmark
|
||||||
|
|
||||||
|
function cleanup
|
||||||
|
{
|
||||||
|
destroy_dataset $fs "-R"
|
||||||
|
}
|
||||||
|
|
||||||
|
log_onexit cleanup
|
||||||
|
|
||||||
|
log_must zfs create $fs
|
||||||
|
|
||||||
|
log_must zfs snapshot $fs@$snapname
|
||||||
|
|
||||||
|
log_must_program_sync $TESTPOOL \
|
||||||
|
$ZCP_ROOT/synctask_core/tst.bookmark.create.zcp $fs $snapname $bookname
|
||||||
|
|
||||||
|
log_pass "Simple bookmark creation works"
|
@ -0,0 +1,26 @@
|
|||||||
|
--
|
||||||
|
-- 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) 2019, 2020 by Christian Schwarz. All rights reserved.
|
||||||
|
--
|
||||||
|
|
||||||
|
-- This program should be invoked as "zfs program <pool> <prog> <fs> <snap> <book>"
|
||||||
|
|
||||||
|
args = ...
|
||||||
|
argv = args["argv"]
|
||||||
|
assert(zfs.sync.bookmark(argv[1] .. "@" .. argv[2], argv[1] .. "#" .. argv[3]) == 0)
|
||||||
|
books = {}
|
||||||
|
for s in zfs.list.bookmarks(argv[1]) do
|
||||||
|
table.insert(books, s)
|
||||||
|
end
|
||||||
|
assert(#books == 1)
|
||||||
|
assert(books[1] == (argv[1] .. "#" .. argv[3]))
|
Loading…
Reference in New Issue
Block a user