Skip to content

Commit e2ef1cb

Browse files
jasonbkingbehlendorf
authored andcommitted
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 <[email protected]> Signed-off-by: Jason King <[email protected]> Closes #9738
1 parent 79add96 commit e2ef1cb

File tree

7 files changed

+162
-11
lines changed

7 files changed

+162
-11
lines changed

include/sys/dsl_prop.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
/*
2222
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
2323
* Copyright (c) 2012 by Delphix. All rights reserved.
24+
* Copyright 2019 Joyent, Inc.
2425
*/
2526

2627
#ifndef _SYS_DSL_PROP_H
@@ -61,6 +62,12 @@ typedef struct dsl_props_arg {
6162
zprop_source_t pa_source;
6263
} dsl_props_arg_t;
6364

65+
typedef struct dsl_props_set_arg {
66+
const char *dpsa_dsname;
67+
zprop_source_t dpsa_source;
68+
nvlist_t *dpsa_props;
69+
} dsl_props_set_arg_t;
70+
6471
void dsl_prop_init(dsl_dir_t *dd);
6572
void dsl_prop_fini(dsl_dir_t *dd);
6673
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,
8592
int intsz, int numints, void *buf, char *setpoint,
8693
boolean_t snapshot);
8794

95+
int dsl_props_set_check(void *arg, dmu_tx_t *tx);
96+
void dsl_props_set_sync(void *arg, dmu_tx_t *tx);
8897
void dsl_props_set_sync_impl(struct dsl_dataset *ds, zprop_source_t source,
8998
nvlist_t *props, dmu_tx_t *tx);
9099
void dsl_prop_set_sync_impl(struct dsl_dataset *ds, const char *propname,

man/man8/zfs-program.8

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,9 @@
99
.\"
1010
.\"
1111
.\" Copyright (c) 2016, 2019 by Delphix. All Rights Reserved.
12+
.\" Copyright 2020 Joyent, Inc.
1213
.\"
13-
.Dd February 26, 2019
14+
.Dd January 15, 2020
1415
.Dt ZFS-PROGRAM 8
1516
.Os
1617
.Sh NAME
@@ -364,6 +365,27 @@ Valid only for destroying snapshots.
364365
If set to true, and the snapshot has holds or clones, allows the snapshot to be
365366
marked for deferred deletion rather than failing.
366367
.Ed
368+
.It Em zfs.sync.inherit(dataset, property)
369+
Clears the specified property in the given dataset, causing it to be inherited
370+
from an ancestor, or restored to the default if no ancestor property is set.
371+
The
372+
.Ql zfs inherit -S
373+
option has not been implemented.
374+
Returns 0 on success, or a nonzero error code if the property could not be
375+
cleared.
376+
.Pp
377+
dataset (string)
378+
.Bd -ragged -compact -offset "xxxx"
379+
Filesystem or snapshot containing the property to clear.
380+
.Ed
381+
.Pp
382+
property (string)
383+
.Bd -ragged -compact -offset "xxxx"
384+
The property to clear.
385+
Allowed properties are the same as those for the
386+
.Nm zfs Cm inherit
387+
command.
388+
.Ed
367389
.It Em zfs.sync.promote(dataset)
368390
Promote the given clone to a filesystem.
369391
Returns 0 on successful promotion, or a nonzero error code otherwise.

module/zfs/dsl_prop.c

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
2323
* Copyright (c) 2012, 2015 by Delphix. All rights reserved.
2424
* Copyright (c) 2013 Martin Matuska. All rights reserved.
25-
* Copyright 2015, Joyent, Inc.
25+
* Copyright 2019 Joyent, Inc.
2626
*/
2727

2828
#include <sys/zfs_context.h>
@@ -856,13 +856,7 @@ dsl_prop_inherit(const char *dsname, const char *propname,
856856
return (error);
857857
}
858858

859-
typedef struct dsl_props_set_arg {
860-
const char *dpsa_dsname;
861-
zprop_source_t dpsa_source;
862-
nvlist_t *dpsa_props;
863-
} dsl_props_set_arg_t;
864-
865-
static int
859+
int
866860
dsl_props_set_check(void *arg, dmu_tx_t *tx)
867861
{
868862
dsl_props_set_arg_t *dpsa = arg;
@@ -940,7 +934,7 @@ dsl_props_set_sync_impl(dsl_dataset_t *ds, zprop_source_t source,
940934
}
941935
}
942936

943-
static void
937+
void
944938
dsl_props_set_sync(void *arg, dmu_tx_t *tx)
945939
{
946940
dsl_props_set_arg_t *dpsa = arg;

module/zfs/zcp_synctask.c

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515

1616
/*
1717
* Copyright (c) 2016, 2017 by Delphix. All rights reserved.
18+
* Copyright 2020 Joyent, Inc.
1819
*/
1920

2021
#include <sys/lua/lua.h>
@@ -35,6 +36,12 @@
3536

3637
#define DST_AVG_BLKSHIFT 14
3738

39+
typedef struct zcp_inherit_prop_arg {
40+
lua_State *zipa_state;
41+
const char *zipa_prop;
42+
dsl_props_set_arg_t zipa_dpsa;
43+
} zcp_inherit_prop_arg_t;
44+
3845
typedef int (zcp_synctask_func_t)(lua_State *, boolean_t, nvlist_t *);
3946
typedef struct zcp_synctask_info {
4047
const char *name;
@@ -275,6 +282,84 @@ zcp_synctask_snapshot(lua_State *state, boolean_t sync, nvlist_t *err_details)
275282
return (err);
276283
}
277284

285+
static int zcp_synctask_inherit_prop(lua_State *, boolean_t,
286+
nvlist_t *err_details);
287+
static zcp_synctask_info_t zcp_synctask_inherit_prop_info = {
288+
.name = "inherit",
289+
.func = zcp_synctask_inherit_prop,
290+
.space_check = ZFS_SPACE_CHECK_RESERVED,
291+
.blocks_modified = 2, /* 2 * numprops */
292+
.pargs = {
293+
{ .za_name = "dataset", .za_lua_type = LUA_TSTRING },
294+
{ .za_name = "property", .za_lua_type = LUA_TSTRING },
295+
{ NULL, 0 }
296+
},
297+
.kwargs = {
298+
{ NULL, 0 }
299+
},
300+
};
301+
302+
static int
303+
zcp_synctask_inherit_prop_check(void *arg, dmu_tx_t *tx)
304+
{
305+
zcp_inherit_prop_arg_t *args = arg;
306+
zfs_prop_t prop = zfs_name_to_prop(args->zipa_prop);
307+
308+
if (prop == ZPROP_INVAL) {
309+
if (zfs_prop_user(args->zipa_prop))
310+
return (0);
311+
312+
return (EINVAL);
313+
}
314+
315+
if (zfs_prop_readonly(prop))
316+
return (EINVAL);
317+
318+
if (!zfs_prop_inheritable(prop))
319+
return (EINVAL);
320+
321+
return (dsl_props_set_check(&args->zipa_dpsa, tx));
322+
}
323+
324+
static void
325+
zcp_synctask_inherit_prop_sync(void *arg, dmu_tx_t *tx)
326+
{
327+
zcp_inherit_prop_arg_t *args = arg;
328+
dsl_props_set_arg_t *dpsa = &args->zipa_dpsa;
329+
330+
dsl_props_set_sync(dpsa, tx);
331+
}
332+
333+
static int
334+
zcp_synctask_inherit_prop(lua_State *state, boolean_t sync,
335+
nvlist_t *err_details)
336+
{
337+
int err;
338+
zcp_inherit_prop_arg_t zipa = { 0 };
339+
dsl_props_set_arg_t *dpsa = &zipa.zipa_dpsa;
340+
341+
const char *dsname = lua_tostring(state, 1);
342+
const char *prop = lua_tostring(state, 2);
343+
344+
zipa.zipa_state = state;
345+
zipa.zipa_prop = prop;
346+
dpsa->dpsa_dsname = dsname;
347+
dpsa->dpsa_source = ZPROP_SRC_INHERITED;
348+
dpsa->dpsa_props = fnvlist_alloc();
349+
fnvlist_add_boolean(dpsa->dpsa_props, prop);
350+
351+
zcp_cleanup_handler_t *zch = zcp_register_cleanup(state,
352+
(zcp_cleanup_t *)&fnvlist_free, dpsa->dpsa_props);
353+
354+
err = zcp_sync_task(state, zcp_synctask_inherit_prop_check,
355+
zcp_synctask_inherit_prop_sync, &zipa, sync, dsname);
356+
357+
zcp_deregister_cleanup(state, zch);
358+
fnvlist_free(dpsa->dpsa_props);
359+
360+
return (err);
361+
}
362+
278363
static int
279364
zcp_synctask_wrapper(lua_State *state)
280365
{
@@ -343,6 +428,7 @@ zcp_load_synctask_lib(lua_State *state, boolean_t sync)
343428
&zcp_synctask_promote_info,
344429
&zcp_synctask_rollback_info,
345430
&zcp_synctask_snapshot_info,
431+
&zcp_synctask_inherit_prop_info,
346432
NULL
347433
};
348434

tests/runfiles/common.run

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ tags = ['functional', 'channel_program', 'lua_core']
8080
tests = ['tst.destroy_fs', 'tst.destroy_snap', 'tst.get_count_and_limit',
8181
'tst.get_index_props', 'tst.get_mountpoint', 'tst.get_neg',
8282
'tst.get_number_props', 'tst.get_string_props', 'tst.get_type',
83-
'tst.get_userquota', 'tst.get_written', 'tst.list_bookmarks',
83+
'tst.get_userquota', 'tst.get_written', 'tst.inherit', 'tst.list_bookmarks',
8484
'tst.list_children', 'tst.list_clones', 'tst.list_holds',
8585
'tst.list_snapshots', 'tst.list_system_props',
8686
'tst.list_user_props', 'tst.parse_args_neg','tst.promote_conflict',

tests/zfs-tests/tests/functional/channel_program/synctask_core/Makefile.am

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ dist_pkgdata_SCRIPTS = \
1313
tst.get_type.ksh \
1414
tst.get_userquota.ksh \
1515
tst.get_written.ksh \
16+
tst.inherit.ksh \
1617
tst.list_bookmarks.ksh \
1718
tst.list_children.ksh \
1819
tst.list_clones.ksh \
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
#!/bin/ksh -p
2+
#
3+
# This file and its contents are supplied under the terms of the
4+
# Common Development and Distribution License ("CDDL"), version 1.0.
5+
# You may only use this file in accordance with the terms of version
6+
# 1.0 of the CDDL.
7+
#
8+
# A full copy of the text of the CDDL should have accompanied this
9+
# source. A copy of the CDDL is also available via the Internet at
10+
# http://www.illumos.org/license/CDDL.
11+
#
12+
13+
#
14+
# Copyright 2020 Joyent, Inc.
15+
#
16+
17+
. $STF_SUITE/tests/functional/channel_program/channel_common.kshlib
18+
19+
verify_runnable "global"
20+
21+
fs=$TESTPOOL/$TESTFS
22+
testprop="com.joyent:testprop"
23+
testval="testval"
24+
25+
log_must dataset_setprop $fs $testprop $testval
26+
log_must_program_sync $TESTPOOL - $fs $testprop <<-EOF
27+
arg = ...
28+
fs = arg["argv"][1]
29+
prop = arg["argv"][2]
30+
err = zfs.sync.inherit(fs, prop)
31+
msg = "resetting " .. prop .. " on " .. fs .. " err=" .. err
32+
return msg
33+
EOF
34+
35+
36+
prop=$(get_prop $testprop $fs)
37+
[[ "$prop" == "-" ]] || log_fail "Property still set after inheriting"
38+
39+
log_pass "Inherit/clear property with channel program works."

0 commit comments

Comments
 (0)