Skip to content

Support inheriting properties in channel programs #9738

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jan 23, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions include/sys/dsl_prop.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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,
Expand All @@ -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,
Expand Down
24 changes: 23 additions & 1 deletion man/man8/zfs-program.8
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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.
Expand Down
12 changes: 3 additions & 9 deletions module/zfs/dsl_prop.c
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down
86 changes: 86 additions & 0 deletions module/zfs/zcp_synctask.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

/*
* Copyright (c) 2016, 2017 by Delphix. All rights reserved.
* Copyright 2020 Joyent, Inc.
*/

#include <sys/lua/lua.h>
Expand All @@ -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;
Expand Down Expand Up @@ -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)
{
Expand Down Expand Up @@ -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
};

Expand Down
2 changes: 1 addition & 1 deletion tests/runfiles/common.run
Original file line number Diff line number Diff line change
Expand Up @@ -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',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 \
Expand Down
Original file line number Diff line number Diff line change
@@ -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."