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:
Christian Schwarz 2020-01-16 02:15:05 +01:00 committed by Brian Behlendorf
parent a73f361fdb
commit 948f0c4419
10 changed files with 231 additions and 17 deletions

View File

@ -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 *);

View File

@ -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

View File

@ -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;

View File

@ -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
}; };

View File

@ -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']

View File

@ -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

View File

@ -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"

View File

@ -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)

View File

@ -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"

View File

@ -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]))