Support inheriting properties in channel programs
This adds support in channel programs to inherit properties analogous to `zfs inherit` by adding `zfs.sync.inherit` and `zfs.check.inherit` functions to the ZFS LUA API. Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov> Signed-off-by: Jason King <jason.king@joyent.com> Closes #9738
This commit is contained in:
parent
79add96766
commit
e2ef1cbf04
|
@ -21,6 +21,7 @@
|
|||
/*
|
||||
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012 by Delphix. All rights reserved.
|
||||
* Copyright 2019 Joyent, Inc.
|
||||
*/
|
||||
|
||||
#ifndef _SYS_DSL_PROP_H
|
||||
|
@ -61,6 +62,12 @@ typedef struct dsl_props_arg {
|
|||
zprop_source_t pa_source;
|
||||
} dsl_props_arg_t;
|
||||
|
||||
typedef struct dsl_props_set_arg {
|
||||
const char *dpsa_dsname;
|
||||
zprop_source_t dpsa_source;
|
||||
nvlist_t *dpsa_props;
|
||||
} dsl_props_set_arg_t;
|
||||
|
||||
void dsl_prop_init(dsl_dir_t *dd);
|
||||
void dsl_prop_fini(dsl_dir_t *dd);
|
||||
int dsl_prop_register(struct dsl_dataset *ds, const char *propname,
|
||||
|
@ -85,6 +92,8 @@ int dsl_prop_get_dd(struct dsl_dir *dd, const char *propname,
|
|||
int intsz, int numints, void *buf, char *setpoint,
|
||||
boolean_t snapshot);
|
||||
|
||||
int dsl_props_set_check(void *arg, dmu_tx_t *tx);
|
||||
void dsl_props_set_sync(void *arg, dmu_tx_t *tx);
|
||||
void dsl_props_set_sync_impl(struct dsl_dataset *ds, zprop_source_t source,
|
||||
nvlist_t *props, dmu_tx_t *tx);
|
||||
void dsl_prop_set_sync_impl(struct dsl_dataset *ds, const char *propname,
|
||||
|
|
|
@ -9,8 +9,9 @@
|
|||
.\"
|
||||
.\"
|
||||
.\" Copyright (c) 2016, 2019 by Delphix. All Rights Reserved.
|
||||
.\" Copyright 2020 Joyent, Inc.
|
||||
.\"
|
||||
.Dd February 26, 2019
|
||||
.Dd January 15, 2020
|
||||
.Dt ZFS-PROGRAM 8
|
||||
.Os
|
||||
.Sh NAME
|
||||
|
@ -364,6 +365,27 @@ Valid only for destroying snapshots.
|
|||
If set to true, and the snapshot has holds or clones, allows the snapshot to be
|
||||
marked for deferred deletion rather than failing.
|
||||
.Ed
|
||||
.It Em zfs.sync.inherit(dataset, property)
|
||||
Clears the specified property in the given dataset, causing it to be inherited
|
||||
from an ancestor, or restored to the default if no ancestor property is set.
|
||||
The
|
||||
.Ql zfs inherit -S
|
||||
option has not been implemented.
|
||||
Returns 0 on success, or a nonzero error code if the property could not be
|
||||
cleared.
|
||||
.Pp
|
||||
dataset (string)
|
||||
.Bd -ragged -compact -offset "xxxx"
|
||||
Filesystem or snapshot containing the property to clear.
|
||||
.Ed
|
||||
.Pp
|
||||
property (string)
|
||||
.Bd -ragged -compact -offset "xxxx"
|
||||
The property to clear.
|
||||
Allowed properties are the same as those for the
|
||||
.Nm zfs Cm inherit
|
||||
command.
|
||||
.Ed
|
||||
.It Em zfs.sync.promote(dataset)
|
||||
Promote the given clone to a filesystem.
|
||||
Returns 0 on successful promotion, or a nonzero error code otherwise.
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 2015 by Delphix. All rights reserved.
|
||||
* Copyright (c) 2013 Martin Matuska. All rights reserved.
|
||||
* Copyright 2015, Joyent, Inc.
|
||||
* Copyright 2019 Joyent, Inc.
|
||||
*/
|
||||
|
||||
#include <sys/zfs_context.h>
|
||||
|
@ -856,13 +856,7 @@ dsl_prop_inherit(const char *dsname, const char *propname,
|
|||
return (error);
|
||||
}
|
||||
|
||||
typedef struct dsl_props_set_arg {
|
||||
const char *dpsa_dsname;
|
||||
zprop_source_t dpsa_source;
|
||||
nvlist_t *dpsa_props;
|
||||
} dsl_props_set_arg_t;
|
||||
|
||||
static int
|
||||
int
|
||||
dsl_props_set_check(void *arg, dmu_tx_t *tx)
|
||||
{
|
||||
dsl_props_set_arg_t *dpsa = arg;
|
||||
|
@ -940,7 +934,7 @@ dsl_props_set_sync_impl(dsl_dataset_t *ds, zprop_source_t source,
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
void
|
||||
dsl_props_set_sync(void *arg, dmu_tx_t *tx)
|
||||
{
|
||||
dsl_props_set_arg_t *dpsa = arg;
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
|
||||
/*
|
||||
* Copyright (c) 2016, 2017 by Delphix. All rights reserved.
|
||||
* Copyright 2020 Joyent, Inc.
|
||||
*/
|
||||
|
||||
#include <sys/lua/lua.h>
|
||||
|
@ -35,6 +36,12 @@
|
|||
|
||||
#define DST_AVG_BLKSHIFT 14
|
||||
|
||||
typedef struct zcp_inherit_prop_arg {
|
||||
lua_State *zipa_state;
|
||||
const char *zipa_prop;
|
||||
dsl_props_set_arg_t zipa_dpsa;
|
||||
} zcp_inherit_prop_arg_t;
|
||||
|
||||
typedef int (zcp_synctask_func_t)(lua_State *, boolean_t, nvlist_t *);
|
||||
typedef struct zcp_synctask_info {
|
||||
const char *name;
|
||||
|
@ -275,6 +282,84 @@ zcp_synctask_snapshot(lua_State *state, boolean_t sync, nvlist_t *err_details)
|
|||
return (err);
|
||||
}
|
||||
|
||||
static int zcp_synctask_inherit_prop(lua_State *, boolean_t,
|
||||
nvlist_t *err_details);
|
||||
static zcp_synctask_info_t zcp_synctask_inherit_prop_info = {
|
||||
.name = "inherit",
|
||||
.func = zcp_synctask_inherit_prop,
|
||||
.space_check = ZFS_SPACE_CHECK_RESERVED,
|
||||
.blocks_modified = 2, /* 2 * numprops */
|
||||
.pargs = {
|
||||
{ .za_name = "dataset", .za_lua_type = LUA_TSTRING },
|
||||
{ .za_name = "property", .za_lua_type = LUA_TSTRING },
|
||||
{ NULL, 0 }
|
||||
},
|
||||
.kwargs = {
|
||||
{ NULL, 0 }
|
||||
},
|
||||
};
|
||||
|
||||
static int
|
||||
zcp_synctask_inherit_prop_check(void *arg, dmu_tx_t *tx)
|
||||
{
|
||||
zcp_inherit_prop_arg_t *args = arg;
|
||||
zfs_prop_t prop = zfs_name_to_prop(args->zipa_prop);
|
||||
|
||||
if (prop == ZPROP_INVAL) {
|
||||
if (zfs_prop_user(args->zipa_prop))
|
||||
return (0);
|
||||
|
||||
return (EINVAL);
|
||||
}
|
||||
|
||||
if (zfs_prop_readonly(prop))
|
||||
return (EINVAL);
|
||||
|
||||
if (!zfs_prop_inheritable(prop))
|
||||
return (EINVAL);
|
||||
|
||||
return (dsl_props_set_check(&args->zipa_dpsa, tx));
|
||||
}
|
||||
|
||||
static void
|
||||
zcp_synctask_inherit_prop_sync(void *arg, dmu_tx_t *tx)
|
||||
{
|
||||
zcp_inherit_prop_arg_t *args = arg;
|
||||
dsl_props_set_arg_t *dpsa = &args->zipa_dpsa;
|
||||
|
||||
dsl_props_set_sync(dpsa, tx);
|
||||
}
|
||||
|
||||
static int
|
||||
zcp_synctask_inherit_prop(lua_State *state, boolean_t sync,
|
||||
nvlist_t *err_details)
|
||||
{
|
||||
int err;
|
||||
zcp_inherit_prop_arg_t zipa = { 0 };
|
||||
dsl_props_set_arg_t *dpsa = &zipa.zipa_dpsa;
|
||||
|
||||
const char *dsname = lua_tostring(state, 1);
|
||||
const char *prop = lua_tostring(state, 2);
|
||||
|
||||
zipa.zipa_state = state;
|
||||
zipa.zipa_prop = prop;
|
||||
dpsa->dpsa_dsname = dsname;
|
||||
dpsa->dpsa_source = ZPROP_SRC_INHERITED;
|
||||
dpsa->dpsa_props = fnvlist_alloc();
|
||||
fnvlist_add_boolean(dpsa->dpsa_props, prop);
|
||||
|
||||
zcp_cleanup_handler_t *zch = zcp_register_cleanup(state,
|
||||
(zcp_cleanup_t *)&fnvlist_free, dpsa->dpsa_props);
|
||||
|
||||
err = zcp_sync_task(state, zcp_synctask_inherit_prop_check,
|
||||
zcp_synctask_inherit_prop_sync, &zipa, sync, dsname);
|
||||
|
||||
zcp_deregister_cleanup(state, zch);
|
||||
fnvlist_free(dpsa->dpsa_props);
|
||||
|
||||
return (err);
|
||||
}
|
||||
|
||||
static int
|
||||
zcp_synctask_wrapper(lua_State *state)
|
||||
{
|
||||
|
@ -343,6 +428,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_inherit_prop_info,
|
||||
NULL
|
||||
};
|
||||
|
||||
|
|
|
@ -80,7 +80,7 @@ tags = ['functional', 'channel_program', 'lua_core']
|
|||
tests = ['tst.destroy_fs', 'tst.destroy_snap', 'tst.get_count_and_limit',
|
||||
'tst.get_index_props', 'tst.get_mountpoint', 'tst.get_neg',
|
||||
'tst.get_number_props', 'tst.get_string_props', 'tst.get_type',
|
||||
'tst.get_userquota', 'tst.get_written', 'tst.list_bookmarks',
|
||||
'tst.get_userquota', 'tst.get_written', 'tst.inherit', 'tst.list_bookmarks',
|
||||
'tst.list_children', 'tst.list_clones', 'tst.list_holds',
|
||||
'tst.list_snapshots', 'tst.list_system_props',
|
||||
'tst.list_user_props', 'tst.parse_args_neg','tst.promote_conflict',
|
||||
|
|
|
@ -13,6 +13,7 @@ dist_pkgdata_SCRIPTS = \
|
|||
tst.get_type.ksh \
|
||||
tst.get_userquota.ksh \
|
||||
tst.get_written.ksh \
|
||||
tst.inherit.ksh \
|
||||
tst.list_bookmarks.ksh \
|
||||
tst.list_children.ksh \
|
||||
tst.list_clones.ksh \
|
||||
|
|
|
@ -0,0 +1,39 @@
|
|||
#!/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 2020 Joyent, Inc.
|
||||
#
|
||||
|
||||
. $STF_SUITE/tests/functional/channel_program/channel_common.kshlib
|
||||
|
||||
verify_runnable "global"
|
||||
|
||||
fs=$TESTPOOL/$TESTFS
|
||||
testprop="com.joyent:testprop"
|
||||
testval="testval"
|
||||
|
||||
log_must dataset_setprop $fs $testprop $testval
|
||||
log_must_program_sync $TESTPOOL - $fs $testprop <<-EOF
|
||||
arg = ...
|
||||
fs = arg["argv"][1]
|
||||
prop = arg["argv"][2]
|
||||
err = zfs.sync.inherit(fs, prop)
|
||||
msg = "resetting " .. prop .. " on " .. fs .. " err=" .. err
|
||||
return msg
|
||||
EOF
|
||||
|
||||
|
||||
prop=$(get_prop $testprop $fs)
|
||||
[[ "$prop" == "-" ]] || log_fail "Property still set after inheriting"
|
||||
|
||||
log_pass "Inherit/clear property with channel program works."
|
Loading…
Reference in New Issue