Skip to content
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

Support setting user properties in a channel program #9950

Merged
merged 1 commit into from
Feb 14, 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
1 change: 1 addition & 0 deletions include/sys/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ COMMON_H = \
$(top_srcdir)/include/sys/zcp_global.h \
$(top_srcdir)/include/sys/zcp_iter.h \
$(top_srcdir)/include/sys/zcp_prop.h \
$(top_srcdir)/include/sys/zcp_set.h \
$(top_srcdir)/include/sys/zfeature.h \
$(top_srcdir)/include/sys/zfs_acl.h \
$(top_srcdir)/include/sys/zfs_context.h \
Expand Down
44 changes: 44 additions & 0 deletions include/sys/zcp_set.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/*
* CDDL HEADER START
*
* 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.
*
* CDDL HEADER END
*/

/*
* Copyright 2019 Joyent, Inc.
*/

#ifndef _SYS_ZCP_SET_H
#define _SYS_ZCP_SET_H

#include <sys/dmu_tx.h>
#include <sys/dsl_pool.h>

#ifdef __cplusplus
extern "C" {
#endif

typedef struct zcp_set_prop_arg {
lua_State *state;
const char *dsname;
const char *prop;
const char *val;
} zcp_set_prop_arg_t;

int zcp_set_prop_check(void *arg, dmu_tx_t *tx);
void zcp_set_prop_sync(void *arg, dmu_tx_t *tx);

#ifdef __cplusplus
}
#endif

#endif /* _SYS_ZCP_SET_H */
1 change: 1 addition & 0 deletions lib/libzpool/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,7 @@ KERNEL_C = \
zcp_get.c \
zcp_global.c \
zcp_iter.c \
zcp_set.c \
zcp_synctask.c \
zfeature.c \
zfs_byteswap.c \
Expand Down
25 changes: 23 additions & 2 deletions man/man8/zfs-program.8
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
.\" Copyright (c) 2019, 2020 by Christian Schwarz. All Rights Reserved.
.\" Copyright 2020 Joyent, Inc.
.\"
.Dd January 15, 2020
.Dd February 3, 2020
.Dt ZFS-PROGRAM 8
.Os
.Sh NAME
Expand Down Expand Up @@ -155,7 +155,7 @@ can guarantee that it will finish successfully against a similar size system.
If a channel program attempts to return too large a value, the program will
fully execute but exit with a nonzero status code and no return value.
.Pp
.Em Note:
.Em Note :
ZFS API functions do not generate Fatal Errors when correctly invoked, they
return an error code and the channel program continues executing.
See the
Expand Down Expand Up @@ -408,6 +408,26 @@ filesystem (string)
.Bd -ragged -compact -offset "xxxx"
Filesystem to rollback.
.Ed
.It Em zfs.sync.set_prop(dataset, property, value)
Sets the given property on a dataset.
Currently only user properties are supported.
Returns 0 if the property was set, or a nonzero error code otherwise.
.Pp
dataset (string)
.Bd -ragged -compact -offset "xxxx"
The dataset where the property will be set.
.Ed
.Pp
property (string)
.Bd -ragged -compact -offset "xxxx"
The property to set.
Only user properties are supported.
.Ed
.Pp
value (string)
.Bd -ragged -compact -offset "xxxx"
The value of the property to be set.
.Ed
.It Em zfs.sync.snapshot(dataset)
Create a snapshot of a filesystem.
Returns 0 if the snapshot was successfully created,
Expand Down Expand Up @@ -455,6 +475,7 @@ The available zfs.check functions are:
.It Em zfs.check.destroy(dataset, [defer=true|false])
.It Em zfs.check.promote(dataset)
.It Em zfs.check.rollback(filesystem)
.It Em zfs.check.set_property(dataset, property, value)
.It Em zfs.check.snapshot(dataset)
.El
.It Sy zfs.list submodule
Expand Down
1 change: 1 addition & 0 deletions module/zfs/Makefile.in
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ $(MODULE)-objs += zcp.o
$(MODULE)-objs += zcp_get.o
$(MODULE)-objs += zcp_global.o
$(MODULE)-objs += zcp_iter.o
$(MODULE)-objs += zcp_set.o
$(MODULE)-objs += zcp_synctask.o
$(MODULE)-objs += zfeature.o
$(MODULE)-objs += zfs_byteswap.o
Expand Down
100 changes: 100 additions & 0 deletions module/zfs/zcp_set.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
/*
* CDDL HEADER START
*
* 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.
*
* CDDL HEADER END
*/

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

#include <sys/lua/lua.h>
#include <sys/lua/lualib.h>
#include <sys/lua/lauxlib.h>

#include <sys/dsl_prop.h>
#include <sys/dsl_dir.h>
#include <sys/dsl_synctask.h>
#include <sys/dsl_dataset.h>
#include <sys/zcp.h>
#include <sys/zcp_set.h>
#include <sys/zcp_iter.h>
#include <sys/zcp_global.h>
#include <sys/zvol.h>

#include <zfs_prop.h>

static void
zcp_set_user_prop(lua_State *state, dsl_pool_t *dp, const char *dsname,
const char *prop_name, const char *prop_val, dmu_tx_t *tx)
{
dsl_dataset_t *ds = zcp_dataset_hold(state, dp, dsname, FTAG);
if (ds == NULL)
return; /* not reached; zcp_dataset_hold() longjmp'd */

nvlist_t *nvl = fnvlist_alloc();
fnvlist_add_string(nvl, prop_name, prop_val);

dsl_props_set_sync_impl(ds, ZPROP_SRC_LOCAL, nvl, tx);

fnvlist_free(nvl);
dsl_dataset_rele(ds, FTAG);
}

int
zcp_set_prop_check(void *arg, dmu_tx_t *tx)
{
zcp_set_prop_arg_t *args = arg;
const char *prop_name = args->prop;
dsl_props_set_arg_t dpsa = {
.dpsa_dsname = args->dsname,
.dpsa_source = ZPROP_SRC_LOCAL,
};
nvlist_t *nvl = NULL;
int ret = 0;

/*
* Only user properties are currently supported. When non-user
* properties are supported, we will want to use
* zfs_valid_proplist() to verify the properties.
*/
if (!zfs_prop_user(prop_name)) {
return (EINVAL);
}

nvl = fnvlist_alloc();
fnvlist_add_string(nvl, args->prop, args->val);
dpsa.dpsa_props = nvl;

ret = dsl_props_set_check(&dpsa, tx);
nvlist_free(nvl);

return (ret);
}

void
zcp_set_prop_sync(void *arg, dmu_tx_t *tx)
{
zcp_set_prop_arg_t *args = arg;
zcp_run_info_t *ri = zcp_run_info(args->state);
dsl_pool_t *dp = ri->zri_pool;

const char *dsname = args->dsname;
const char *prop_name = args->prop;
const char *prop_val = args->val;

if (zfs_prop_user(prop_name)) {
zcp_set_user_prop(args->state, dp, dsname, prop_name,
prop_val, tx);
}
}
40 changes: 40 additions & 0 deletions module/zfs/zcp_synctask.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include <sys/lua/lauxlib.h>

#include <sys/zcp.h>
#include <sys/zcp_set.h>
#include <sys/dsl_dir.h>
#include <sys/dsl_pool.h>
#include <sys/dsl_prop.h>
Expand Down Expand Up @@ -414,6 +415,44 @@ zcp_synctask_bookmark(lua_State *state, boolean_t sync, nvlist_t *err_details)
return (err);
}

static int zcp_synctask_set_prop(lua_State *, boolean_t, nvlist_t *err_details);
static zcp_synctask_info_t zcp_synctask_set_prop_info = {
.name = "set_prop",
.func = zcp_synctask_set_prop,
.space_check = ZFS_SPACE_CHECK_RESERVED,
.blocks_modified = 2,
.pargs = {
{ .za_name = "dataset", .za_lua_type = LUA_TSTRING},
{ .za_name = "property", .za_lua_type = LUA_TSTRING},
{ .za_name = "value", .za_lua_type = LUA_TSTRING},
{ NULL, 0 }
},
.kwargs = {
{ NULL, 0 }
}
};

static int
zcp_synctask_set_prop(lua_State *state, boolean_t sync, nvlist_t *err_details)
{
int err;
zcp_set_prop_arg_t args = { 0 };

const char *dsname = lua_tostring(state, 1);
const char *prop = lua_tostring(state, 2);
const char *val = lua_tostring(state, 3);

args.state = state;
args.dsname = dsname;
args.prop = prop;
args.val = val;

err = zcp_sync_task(state, zcp_set_prop_check, zcp_set_prop_sync,
&args, sync, dsname);

return (err);
}

static int
zcp_synctask_wrapper(lua_State *state)
{
Expand Down Expand Up @@ -484,6 +523,7 @@ zcp_load_synctask_lib(lua_State *state, boolean_t sync)
&zcp_synctask_snapshot_info,
&zcp_synctask_inherit_prop_info,
&zcp_synctask_bookmark_info,
&zcp_synctask_set_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 @@ -85,7 +85,7 @@ tests = ['tst.destroy_fs', 'tst.destroy_snap', 'tst.get_count_and_limit',
'tst.list_snapshots', 'tst.list_system_props',
'tst.list_user_props', 'tst.parse_args_neg','tst.promote_conflict',
'tst.promote_multiple', 'tst.promote_simple', 'tst.rollback_mult',
'tst.rollback_one', 'tst.snapshot_destroy', 'tst.snapshot_neg',
'tst.rollback_one', 'tst.set_props', 'tst.snapshot_destroy', 'tst.snapshot_neg',
'tst.snapshot_recursive', 'tst.snapshot_simple',
'tst.bookmark.create', 'tst.bookmark.copy',
'tst.terminate_by_signal'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ dist_pkgdata_SCRIPTS = \
tst.promote_simple.ksh \
tst.rollback_mult.ksh \
tst.rollback_one.ksh \
tst.set_props.ksh \
tst.snapshot_destroy.ksh \
tst.snapshot_neg.ksh \
tst.snapshot_recursive.ksh \
Expand All @@ -43,6 +44,7 @@ dist_pkgdata_DATA = \
tst.get_string_props.out \
tst.get_string_props.zcp \
tst.promote_conflict.zcp \
tst.set_props.zcp \
tst.snapshot_destroy.zcp \
tst.snapshot_neg.zcp \
tst.snapshot_recursive.zcp \
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
#!/bin/ksh -p
behlendorf marked this conversation as resolved.
Show resolved Hide resolved
#
# 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) 2016 by Delphix. All rights reserved.
#

. $STF_SUITE/tests/functional/channel_program/channel_common.kshlib

#
# DESCRIPTION:
# Setting user props should work correctly on datasets.
#

verify_runnable "global"

fs=$TESTPOOL/$TESTFS/testchild

function cleanup
{
destroy_dataset $fs "-R"
}

log_onexit cleanup

log_must zfs create $fs

log_must_program_sync $TESTPOOL $ZCP_ROOT/synctask_core/tst.set_props.zcp $fs

log_pass "Setting props from channel program works correctly."
Loading