Date: Tue, 23 Jun 2020 11:16:17 -0700 From: Matthew Macy <mmacy@freebsd.org> To: Toomas Soome <tsoome@freebsd.org> Cc: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: Re: svn commit: r362531 - in head: cddl/contrib/opensolaris/cmd/zfs cddl/contrib/opensolaris/lib/libzfs/common cddl/contrib/opensolaris/lib/libzfs_core/common sys/cddl/contrib/opensolaris/uts/common/fs... Message-ID: <CAPrugNq_DCEgfM9byAtjfH_7hSwOPnmQ44aPzdD6MESw-4H3Zw@mail.gmail.com> In-Reply-To: <202006230642.05N6gdF9092071@repo.freebsd.org> References: <202006230642.05N6gdF9092071@repo.freebsd.org>
next in thread | previous in thread | raw e-mail | index | archive | help
Are you planning on MFCing this? That=E2=80=99s the main value to MFVs at t= his point. Thanks. On Mon, Jun 22, 2020 at 23:42 Toomas Soome <tsoome@freebsd.org> wrote: > Author: tsoome > Date: Tue Jun 23 06:42:39 2020 > New Revision: 362531 > URL: https://svnweb.freebsd.org/changeset/base/362531 > > Log: > MFOpenZFS: Add basic zfs ioc input nvpair validation > > We want newer versions of libzfs_core to run against an existing > zfs kernel module (i.e. a deferred reboot or module reload after > an update). > > Programmatically document, via a zfs_ioc_key_t, the valid arguments > for the ioc commands that rely on nvpair input arguments (i.e. non > legacy commands from libzfs_core). Automatically verify the expected > pairs before dispatching a command. > > This initial phase focuses on the non-legacy ioctls. A follow-on > change can address the legacy ioctl input from the zfs_cmd_t. > > The zfs_ioc_key_t for zfs_keys_channel_program looks like: > > static const zfs_ioc_key_t zfs_keys_channel_program[] =3D { > {"program", DATA_TYPE_STRING, 0}, > {"arg", DATA_TYPE_UNKNOWN, 0}, > {"sync", DATA_TYPE_BOOLEAN_VALUE, ZK_OPTIONAL}, > {"instrlimit", DATA_TYPE_UINT64, ZK_OPTIONAL}, > {"memlimit", DATA_TYPE_UINT64, ZK_OPTIONAL}, > }; > > Introduce four input errors to identify specific input failures > (in addition to generic argument value errors like EINVAL, ERANGE, > EBADF, and E2BIG). > > ZFS_ERR_IOC_CMD_UNAVAIL the ioctl number is not supported by kernel > ZFS_ERR_IOC_ARG_UNAVAIL an input argument is not supported by kernel > ZFS_ERR_IOC_ARG_REQUIRED a required input argument is missing > ZFS_ERR_IOC_ARG_BADTYPE an input argument has an invalid type > > Reviewed by: allanjude > Obtained from: OpenZFS > Sponsored by: Netflix, Klara Inc. > Differential Revision: https://reviews.freebsd.org/D25393 > > Modified: > head/cddl/contrib/opensolaris/cmd/zfs/zfs_main.c > head/cddl/contrib/opensolaris/lib/libzfs/common/libzfs.h > head/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_util.c > head/cddl/contrib/opensolaris/lib/libzfs_core/common/libzfs_core.c > head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c > head/sys/cddl/contrib/opensolaris/uts/common/sys/fs/zfs.h > > Modified: head/cddl/contrib/opensolaris/cmd/zfs/zfs_main.c > > =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D > --- head/cddl/contrib/opensolaris/cmd/zfs/zfs_main.c Tue Jun 23 > 04:58:36 2020 (r362530) > +++ head/cddl/contrib/opensolaris/cmd/zfs/zfs_main.c Tue Jun 23 > 06:42:39 2020 (r362531) > @@ -7235,7 +7235,7 @@ zfs_do_bookmark(int argc, char **argv) > fnvlist_free(nvl); > > if (ret !=3D 0) { > - const char *err_msg; > + const char *err_msg =3D NULL; > char errbuf[1024]; > > (void) snprintf(errbuf, sizeof (errbuf), > @@ -7259,11 +7259,13 @@ zfs_do_bookmark(int argc, char **argv) > err_msg =3D "out of space"; > break; > default: > - err_msg =3D "unknown error"; > + (void) zfs_standard_error(g_zfs, ret, errbuf); > break; > } > - (void) fprintf(stderr, "%s: %s\n", errbuf, > - dgettext(TEXT_DOMAIN, err_msg)); > + if (err_msg !=3D NULL) { > + (void) fprintf(stderr, "%s: %s\n", errbuf, > + dgettext(TEXT_DOMAIN, err_msg)); > + } > } > > return (ret !=3D 0); > @@ -7280,7 +7282,7 @@ zfs_do_channel_program(int argc, char **argv) > char c; > char *progbuf, *filename, *poolname; > size_t progsize, progread; > - nvlist_t *outnvl; > + nvlist_t *outnvl =3D NULL; > uint64_t instrlimit =3D ZCP_DEFAULT_INSTRLIMIT; > uint64_t memlimit =3D ZCP_DEFAULT_MEMLIMIT; > boolean_t sync_flag =3D B_TRUE, json_output =3D B_FALSE; > @@ -7420,7 +7422,8 @@ zfs_do_channel_program(int argc, char **argv) > * falling back on strerror() for an unexpected return > code. > */ > char *errstring =3D NULL; > - if (nvlist_exists(outnvl, ZCP_RET_ERROR)) { > + const char *msg =3D gettext("Channel program execution > failed"); > + if (outnvl !=3D NULL && nvlist_exists(outnvl, > ZCP_RET_ERROR)) { > (void) nvlist_lookup_string(outnvl, > ZCP_RET_ERROR, &errstring); > if (errstring =3D=3D NULL) > @@ -7449,12 +7452,11 @@ zfs_do_channel_program(int argc, char **argv) > "programs must be run as root."; > break; > default: > - errstring =3D strerror(ret); > + (void) zfs_standard_error(g_zfs, ret, msg= ); > } > } > - (void) fprintf(stderr, > - gettext("Channel program execution failed:\n%s\n"), > - errstring); > + if (errstring !=3D NULL) > + (void) fprintf(stderr, "%s:\n%s\n", msg, > errstring); > } else { > if (json_output) { > (void) nvlist_print_json(stdout, outnvl); > > Modified: head/cddl/contrib/opensolaris/lib/libzfs/common/libzfs.h > > =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D > --- head/cddl/contrib/opensolaris/lib/libzfs/common/libzfs.h Tue Jun 2= 3 > 04:58:36 2020 (r362530) > +++ head/cddl/contrib/opensolaris/lib/libzfs/common/libzfs.h Tue Jun 2= 3 > 06:42:39 2020 (r362531) > @@ -22,7 +22,7 @@ > /* > * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights > reserved. > * Copyright (c) 2011 Pawel Jakub Dawidek. All rights reserved. > - * Copyright (c) 2011, 2017 by Delphix. All rights reserved. > + * Copyright (c) 2011, 2020 by Delphix. All rights reserved. > * Copyright 2019 Joyent, Inc. > * Copyright (c) 2012 Martin Matuska <mm@FreeBSD.org>. All rights > reserved. > * Copyright (c) 2013 Steven Hartland. All rights reserved. > @@ -142,6 +142,7 @@ typedef enum zfs_error { > EZFS_INITIALIZING, /* currently initializing */ > EZFS_NO_INITIALIZE, /* no active initialize */ > EZFS_WRONG_PARENT, /* invalid parent dataset (e.g ZVOL) */ > + EZFS_IOC_NOTSUPPORTED, /* operation not supported by zfs module = */ > EZFS_UNKNOWN > } zfs_error_t; > > > Modified: head/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_util.c > > =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D > --- head/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_util.c > Tue Jun 23 04:58:36 2020 (r362530) > +++ head/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_util.c > Tue Jun 23 06:42:39 2020 (r362531) > @@ -22,7 +22,7 @@ > /* > * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights > reserved. > * Copyright 2019 Joyent, Inc. > - * Copyright (c) 2011, 2017 by Delphix. All rights reserved. > + * Copyright (c) 2011, 2018 by Delphix. All rights reserved. > * Copyright 2016 Igor Kozhukhov <ikozhukhov@gmail.com> > * Copyright (c) 2017 Datto Inc. > */ > @@ -207,6 +207,9 @@ libzfs_error_description(libzfs_handle_t *hdl) > case EZFS_NOTSUP: > return (dgettext(TEXT_DOMAIN, "operation not supported " > "on this dataset")); > + case EZFS_IOC_NOTSUPPORTED: > + return (dgettext(TEXT_DOMAIN, "operation not supported by= " > + "zfs kernel module")); > case EZFS_ACTIVE_SPARE: > return (dgettext(TEXT_DOMAIN, "pool has active shared > spare " > "device")); > @@ -433,6 +436,22 @@ zfs_standard_error_fmt(libzfs_handle_t *hdl, int err= or > case EREMOTEIO: > zfs_verror(hdl, EZFS_ACTIVE_POOL, fmt, ap); > break; > + case ZFS_ERR_IOC_CMD_UNAVAIL: > + zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "the loaded zfs = " > + "module does not support this operation. A reboot may= " > + "be required to enable this operation.")); > + zfs_verror(hdl, EZFS_IOC_NOTSUPPORTED, fmt, ap); > + break; > + case ZFS_ERR_IOC_ARG_UNAVAIL: > + zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "the loaded zfs = " > + "module does not support an option for this operation= . > " > + "A reboot may be required to enable this option.")); > + zfs_verror(hdl, EZFS_IOC_NOTSUPPORTED, fmt, ap); > + break; > + case ZFS_ERR_IOC_ARG_REQUIRED: > + case ZFS_ERR_IOC_ARG_BADTYPE: > + zfs_verror(hdl, EZFS_IOC_NOTSUPPORTED, fmt, ap); > + break; > default: > zfs_error_aux(hdl, strerror(error)); > zfs_verror(hdl, EZFS_UNKNOWN, fmt, ap); > @@ -541,6 +560,22 @@ zpool_standard_error_fmt(libzfs_handle_t *hdl, int e= rr > break; > case ZFS_ERR_WRONG_PARENT: > zfs_verror(hdl, EZFS_WRONG_PARENT, fmt, ap); > + break; > + case ZFS_ERR_IOC_CMD_UNAVAIL: > + zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "the loaded zfs = " > + "module does not support this operation. A reboot may= " > + "be required to enable this operation.")); > + zfs_verror(hdl, EZFS_IOC_NOTSUPPORTED, fmt, ap); > + break; > + case ZFS_ERR_IOC_ARG_UNAVAIL: > + zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "the loaded zfs = " > + "module does not support an option for this operation= . > " > + "A reboot may be required to enable this option.")); > + zfs_verror(hdl, EZFS_IOC_NOTSUPPORTED, fmt, ap); > + break; > + case ZFS_ERR_IOC_ARG_REQUIRED: > + case ZFS_ERR_IOC_ARG_BADTYPE: > + zfs_verror(hdl, EZFS_IOC_NOTSUPPORTED, fmt, ap); > break; > default: > zfs_error_aux(hdl, strerror(error)); > > Modified: > head/cddl/contrib/opensolaris/lib/libzfs_core/common/libzfs_core.c > > =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D > --- head/cddl/contrib/opensolaris/lib/libzfs_core/common/libzfs_core.c > Tue Jun 23 04:58:36 2020 (r362530) > +++ head/cddl/contrib/opensolaris/lib/libzfs_core/common/libzfs_core.c > Tue Jun 23 06:42:39 2020 (r362531) > @@ -20,7 +20,7 @@ > */ > > /* > - * Copyright (c) 2012, 2017 by Delphix. All rights reserved. > + * Copyright (c) 2012, 2018 by Delphix. All rights reserved. > * Copyright (c) 2013 Steven Hartland. All rights reserved. > * Copyright (c) 2014 Integros [integros.com] > * Copyright 2017 RackTop Systems. > @@ -80,6 +80,9 @@ > #include <unistd.h> > #include <stdlib.h> > #include <string.h> > +#ifdef ZFS_DEBUG > +#include <stdio.h> > +#endif > #include <errno.h> > #include <fcntl.h> > #include <pthread.h> > @@ -99,6 +102,42 @@ static int g_fd =3D -1; > static pthread_mutex_t g_lock =3D PTHREAD_MUTEX_INITIALIZER; > static int g_refcount; > > +#ifdef ZFS_DEBUG > +static zfs_ioc_t fail_ioc_cmd; > +static zfs_errno_t fail_ioc_err; > + > +static void > +libzfs_core_debug_ioc(void) > +{ > + /* > + * To test running newer user space binaries with kernel's > + * that don't yet support an ioctl or a new ioctl arg we > + * provide an override to intentionally fail an ioctl. > + * > + * USAGE: > + * The override variable, ZFS_IOC_TEST, is of the form "cmd:err" > + * > + * For example, to fail a ZFS_IOC_POOL_CHECKPOINT with a > + * ZFS_ERR_IOC_CMD_UNAVAIL, the string would be "0x5a4d:1029" > + * > + * $ sudo sh -c "ZFS_IOC_TEST=3D0x5a4d:1029 zpool checkpoint tank= " > + * cannot checkpoint 'tank': the loaded zfs module does not suppo= rt > + * this operation. A reboot may be required to enable this > operation. > + */ > + if (fail_ioc_cmd =3D=3D 0) { > + char *ioc_test =3D getenv("ZFS_IOC_TEST"); > + unsigned int ioc_num =3D 0, ioc_err =3D 0; > + > + if (ioc_test !=3D NULL && > + sscanf(ioc_test, "%i:%i", &ioc_num, &ioc_err) =3D=3D = 2 && > + ioc_num < ZFS_IOC_LAST) { > + fail_ioc_cmd =3D ioc_num; > + fail_ioc_err =3D ioc_err; > + } > + } > +} > +#endif > + > int > libzfs_core_init(void) > { > @@ -111,6 +150,10 @@ libzfs_core_init(void) > } > } > g_refcount++; > + > +#ifdef ZFS_DEBUG > + libzfs_core_debug_ioc(); > +#endif > (void) pthread_mutex_unlock(&g_lock); > > return (0); > @@ -146,6 +189,11 @@ lzc_ioctl(zfs_ioc_t ioc, const char *name, > > ASSERT3S(g_refcount, >, 0); > VERIFY3S(g_fd, !=3D, -1); > + > +#ifdef ZFS_DEBUG > + if (ioc =3D=3D fail_ioc_cmd) > + return (fail_ioc_err); > +#endif > > if (name !=3D NULL) > (void) strlcpy(zc.zc_name, name, sizeof (zc.zc_name)); > > Modified: head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c > > =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D > --- head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c > Tue Jun 23 04:58:36 2020 (r362530) > +++ head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c > Tue Jun 23 06:42:39 2020 (r362531) > @@ -27,7 +27,7 @@ > * Copyright 2015, OmniTI Computer Consulting, Inc. All rights reserved. > * Copyright 2015 Nexenta Systems, Inc. All rights reserved. > * Copyright (c) 2014, 2016 Joyent, Inc. All rights reserved. > - * Copyright (c) 2011, 2017 by Delphix. All rights reserved. > + * Copyright (c) 2011, 2018 by Delphix. All rights reserved. > * Copyright (c) 2013 by Saso Kiselkov. All rights reserved. > * Copyright (c) 2013 Steven Hartland. All rights reserved. > * Copyright (c) 2014 Integros [integros.com] > @@ -61,8 +61,9 @@ > * > * zfs_ioc_t ioc > * The ioctl request number, which userland will pass to ioctl(2). > - * The ioctl numbers can change from release to release, because > - * the caller (libzfs) must be matched to the kernel. > + * We want newer versions of libzfs and libzfs_core to run against > + * existing zfs kernel modules (i.e. a deferred reboot after an update= ). > + * Therefore the ioctl numbers cannot change from release to release. > * > * zfs_secpolicy_func_t *secpolicy > * This function will be called before the zfs_ioc_func_t, to > @@ -88,6 +89,10 @@ > * Multiple checks can be or-ed together (e.g. POOL_CHECK_SUSPENDED | > * POOL_CHECK_READONLY). > * > + * zfs_ioc_key_t *nvl_keys > + * The list of expected/allowable innvl input keys. This list is used > + * to validate the nvlist input to the ioctl. > + * > * boolean_t smush_outnvlist > * If smush_outnvlist is true, then the output is presumed to be a > * list of errors, and it will be "smushed" down to fit into the > @@ -136,7 +141,17 @@ > * use the outnvl if they succeed, because the caller can not > * distinguish between the operation failing, and > * deserialization failing. > + * > + * > + * IOCTL Interface Errors > + * > + * The following ioctl input errors can be returned: > + * ZFS_ERR_IOC_CMD_UNAVAIL the ioctl number is not supported by kern= el > + * ZFS_ERR_IOC_ARG_UNAVAIL an input argument is not supported by > kernel > + * ZFS_ERR_IOC_ARG_REQUIRED a required input argument is missing > + * ZFS_ERR_IOC_ARG_BADTYPE an input argument has an invalid type > */ > + > #ifdef __FreeBSD__ > #include "opt_kstack_pages.h" > #endif > @@ -208,6 +223,10 @@ > #include "lua.h" > #include "lauxlib.h" > > +#ifndef ARRAY_SIZE > +#define ARRAY_SIZE(x) nitems(x) > +#endif > + > static struct cdev *zfsdev; > > extern void zfs_init(void); > @@ -222,7 +241,38 @@ typedef int zfs_ioc_legacy_func_t(zfs_cmd_t *); > typedef int zfs_ioc_func_t(const char *, nvlist_t *, nvlist_t *); > typedef int zfs_secpolicy_func_t(zfs_cmd_t *, nvlist_t *, cred_t *); > > +/* > + * IOC Keys are used to document and validate user->kernel interface > inputs. > + * See zfs_keys_recv_new for an example declaration. Any key name that i= s > not > + * listed will be rejected as input. > + * > + * The keyname 'optional' is always allowed, and must be an nvlist if > present. > + * Arguments which older kernels can safely ignore can be placed under t= he > + * "optional" key. > + * > + * When adding new keys to an existing ioc for new functionality, > consider: > + * - adding an entry into zfs_sysfs.c zfs_features[] list > + * - updating the libzfs_input_check.c test utility > + * > + * Note: in the ZK_WILDCARDLIST case, the name serves as documentation > + * for the expected name (bookmark, snapshot, property, etc) but there > + * is no validation in the preflight zfs_check_input_nvpairs() check. > + */ > typedef enum { > + ZK_OPTIONAL =3D 1 << 0, /* pair is optional */ > + ZK_WILDCARDLIST =3D 1 << 1, /* one or more unspecified key > names */ > +} ioc_key_flag_t; > + > +/* DATA_TYPE_ANY is used when zkey_type can vary. */ > +#define DATA_TYPE_ANY DATA_TYPE_UNKNOWN > + > +typedef struct zfs_ioc_key { > + const char *zkey_name; > + data_type_t zkey_type; > + ioc_key_flag_t zkey_flags; > +} zfs_ioc_key_t; > + > +typedef enum { > NO_NAME, > POOL_NAME, > DATASET_NAME, > @@ -244,6 +294,8 @@ typedef struct zfs_ioc_vec { > zfs_ioc_poolcheck_t zvec_pool_check; > boolean_t zvec_smush_outnvlist; > const char *zvec_name; > + const zfs_ioc_key_t *zvec_nvl_keys; > + size_t zvec_nvl_key_count; > } zfs_ioc_vec_t; > > /* This array is indexed by zfs_userquota_prop_t */ > @@ -865,8 +917,8 @@ zfs_secpolicy_destroy_snaps(zfs_cmd_t *zc, nvlist_t *= i > nvpair_t *pair, *nextpair; > int error =3D 0; > > - if (nvlist_lookup_nvlist(innvl, "snaps", &snaps) !=3D 0) > - return (SET_ERROR(EINVAL)); > + snaps =3D fnvlist_lookup_nvlist(innvl, "snaps"); > + > for (pair =3D nvlist_next_nvpair(snaps, NULL); pair !=3D NULL; > pair =3D nextpair) { > nextpair =3D nvlist_next_nvpair(snaps, pair); > @@ -1042,8 +1094,8 @@ zfs_secpolicy_snapshot(zfs_cmd_t *zc, nvlist_t > *innvl, > int error; > nvpair_t *pair; > > - if (nvlist_lookup_nvlist(innvl, "snaps", &snaps) !=3D 0) > - return (SET_ERROR(EINVAL)); > + snaps =3D fnvlist_lookup_nvlist(innvl, "snaps"); > + > for (pair =3D nvlist_next_nvpair(snaps, NULL); pair !=3D NULL; > pair =3D nvlist_next_nvpair(snaps, pair)) { > char *name =3D nvpair_name(pair); > @@ -1063,7 +1115,7 @@ zfs_secpolicy_snapshot(zfs_cmd_t *zc, nvlist_t > *innvl, > } > > /* > - * Check for permission to create each snapshot in the nvlist. > + * Check for permission to create each bookmark in the nvlist. > */ > /* ARGSUSED */ > static int > @@ -1292,9 +1344,7 @@ zfs_secpolicy_hold(zfs_cmd_t *zc, nvlist_t *innvl, > cre > nvlist_t *holds; > int error; > > - error =3D nvlist_lookup_nvlist(innvl, "holds", &holds); > - if (error !=3D 0) > - return (SET_ERROR(EINVAL)); > + holds =3D fnvlist_lookup_nvlist(innvl, "holds"); > > for (pair =3D nvlist_next_nvpair(holds, NULL); pair !=3D NULL; > pair =3D nvlist_next_nvpair(holds, pair)) { > @@ -1349,12 +1399,14 @@ zfs_secpolicy_tmp_snapshot(zfs_cmd_t *zc, nvlist_= t > *in > return (0); > > error =3D zfs_secpolicy_snapshot_perms(zc->zc_name, cr); > - if (error =3D=3D 0) > - error =3D zfs_secpolicy_hold(zc, innvl, cr); > - if (error =3D=3D 0) > - error =3D zfs_secpolicy_release(zc, innvl, cr); > - if (error =3D=3D 0) > - error =3D zfs_secpolicy_destroy(zc, innvl, cr); > + if (innvl !=3D NULL) { > + if (error =3D=3D 0) > + error =3D zfs_secpolicy_hold(zc, innvl, cr); > + if (error =3D=3D 0) > + error =3D zfs_secpolicy_release(zc, innvl, cr); > + if (error =3D=3D 0) > + error =3D zfs_secpolicy_destroy(zc, innvl, cr); > + } > return (error); > } > > @@ -3309,6 +3361,13 @@ zfs_fill_zplprops_root(uint64_t spa_vers, nvlist_t > *cr > * > * outnvl: propname -> error code (int32) > */ > + > +static const zfs_ioc_key_t zfs_keys_create[] =3D { > + {"type", DATA_TYPE_INT32, 0}, > + {"props", DATA_TYPE_NVLIST, ZK_OPTIONAL}, > + {"hidden_args", DATA_TYPE_NVLIST, ZK_OPTIONAL}, > +}; > + > static int > zfs_ioc_create(const char *fsname, nvlist_t *innvl, nvlist_t *outnvl) > { > @@ -3316,13 +3375,10 @@ zfs_ioc_create(const char *fsname, nvlist_t > *innvl, nv > zfs_creat_t zct =3D { 0 }; > nvlist_t *nvprops =3D NULL; > void (*cbfunc)(objset_t *os, void *arg, cred_t *cr, dmu_tx_t *tx)= ; > - int32_t type32; > dmu_objset_type_t type; > boolean_t is_insensitive =3D B_FALSE; > > - if (nvlist_lookup_int32(innvl, "type", &type32) !=3D 0) > - return (SET_ERROR(EINVAL)); > - type =3D type32; > + type =3D (dmu_objset_type_t)fnvlist_lookup_int32(innvl, "type"); > (void) nvlist_lookup_nvlist(innvl, "props", &nvprops); > > switch (type) { > @@ -3427,6 +3483,12 @@ zfs_ioc_create(const char *fsname, nvlist_t *innvl= , > nv > * > * outnvl: propname -> error code (int32) > */ > +static const zfs_ioc_key_t zfs_keys_clone[] =3D { > + {"origin", DATA_TYPE_STRING, 0}, > + {"props", DATA_TYPE_NVLIST, ZK_OPTIONAL}, > + {"hidden_args", DATA_TYPE_NVLIST, ZK_OPTIONAL}, > +}; > + > static int > zfs_ioc_clone(const char *fsname, nvlist_t *innvl, nvlist_t *outnvl) > { > @@ -3434,8 +3496,7 @@ zfs_ioc_clone(const char *fsname, nvlist_t *innvl, > nvl > nvlist_t *nvprops =3D NULL; > char *origin_name; > > - if (nvlist_lookup_string(innvl, "origin", &origin_name) !=3D 0) > - return (SET_ERROR(EINVAL)); > + origin_name =3D fnvlist_lookup_string(innvl, "origin"); > (void) nvlist_lookup_nvlist(innvl, "props", &nvprops); > > if (strchr(fsname, '@') || > @@ -3460,6 +3521,10 @@ zfs_ioc_clone(const char *fsname, nvlist_t *innvl, > nvl > return (error); > } > > +static const zfs_ioc_key_t zfs_keys_remap[] =3D { > + /* no nvl keys */ > +}; > + > /* ARGSUSED */ > static int > zfs_ioc_remap(const char *fsname, nvlist_t *innvl, nvlist_t *outnvl) > @@ -3479,6 +3544,11 @@ zfs_ioc_remap(const char *fsname, nvlist_t *innvl, > nvl > * > * outnvl: snapshot -> error code (int32) > */ > +static const zfs_ioc_key_t zfs_keys_snapshot[] =3D { > + {"snaps", DATA_TYPE_NVLIST, 0}, > + {"props", DATA_TYPE_NVLIST, ZK_OPTIONAL}, > +}; > + > static int > zfs_ioc_snapshot(const char *poolname, nvlist_t *innvl, nvlist_t *outnvl= ) > { > @@ -3494,8 +3564,7 @@ zfs_ioc_snapshot(const char *poolname, nvlist_t > *innvl > if ((error =3D zfs_check_userprops(props)) !=3D 0) > return (error); > > - if (nvlist_lookup_nvlist(innvl, "snaps", &snaps) !=3D 0) > - return (SET_ERROR(EINVAL)); > + snaps =3D fnvlist_lookup_nvlist(innvl, "snaps"); > poollen =3D strlen(poolname); > for (pair =3D nvlist_next_nvpair(snaps, NULL); pair !=3D NULL; > pair =3D nvlist_next_nvpair(snaps, pair)) { > @@ -3546,6 +3615,10 @@ zfs_ioc_snapshot(const char *poolname, nvlist_t > *innvl > /* > * innvl: "message" -> string > */ > +static const zfs_ioc_key_t zfs_keys_log_history[] =3D { > + {"message", DATA_TYPE_STRING, 0}, > +}; > + > /* ARGSUSED */ > static int > zfs_ioc_log_history(const char *unused, nvlist_t *innvl, nvlist_t *outnv= l) > @@ -3569,10 +3642,7 @@ zfs_ioc_log_history(const char *unused, nvlist_t > *innv > if (error !=3D 0) > return (error); > > - if (nvlist_lookup_string(innvl, "message", &message) !=3D 0) { > - spa_close(spa, FTAG); > - return (SET_ERROR(EINVAL)); > - } > + message =3D fnvlist_lookup_string(innvl, "message"); > > if (spa_version(spa) < SPA_VERSION_ZPOOL_HISTORY) { > spa_close(spa, FTAG); > @@ -3585,6 +3655,10 @@ zfs_ioc_log_history(const char *unused, nvlist_t > *innv > } > > #ifdef __FreeBSD__ > +static const zfs_ioc_key_t zfs_keys_nextboot[] =3D { > + {"command", DATA_TYPE_STRING, 0}, > +}; > + > static int > zfs_ioc_nextboot(const char *unused, nvlist_t *innvl, nvlist_t *outnvl) > { > @@ -3602,9 +3676,7 @@ zfs_ioc_nextboot(const char *unused, nvlist_t > *innvl, > if (nvlist_lookup_uint64(innvl, > ZPOOL_CONFIG_GUID, &vdev_guid) !=3D 0) > return (EINVAL); > - if (nvlist_lookup_string(innvl, > - "command", &command) !=3D 0) > - return (EINVAL); > + command =3D fnvlist_lookup_string(innvl, "command"); > > mutex_enter(&spa_namespace_lock); > spa =3D spa_by_guid(pool_guid, vdev_guid); > @@ -3721,6 +3793,11 @@ zfs_destroy_unmount_origin(const char *fsname) > * outnvl: snapshot -> error code (int32) > * > */ > +static const zfs_ioc_key_t zfs_keys_destroy_snaps[] =3D { > + {"snaps", DATA_TYPE_NVLIST, 0}, > + {"defer", DATA_TYPE_BOOLEAN, ZK_OPTIONAL}, > +}; > + > /* ARGSUSED */ > static int > zfs_ioc_destroy_snaps(const char *poolname, nvlist_t *innvl, nvlist_t > *outnvl) > @@ -3730,8 +3807,7 @@ zfs_ioc_destroy_snaps(const char *poolname, nvlist_= t > * > nvpair_t *pair; > boolean_t defer; > > - if (nvlist_lookup_nvlist(innvl, "snaps", &snaps) !=3D 0) > - return (SET_ERROR(EINVAL)); > + snaps =3D fnvlist_lookup_nvlist(innvl, "snaps"); > defer =3D nvlist_exists(innvl, "defer"); > > poollen =3D strlen(poolname); > @@ -3764,6 +3840,10 @@ zfs_ioc_destroy_snaps(const char *poolname, > nvlist_t * > * outnvl: bookmark -> error code (int32) > * > */ > +static const zfs_ioc_key_t zfs_keys_bookmark[] =3D { > + {"<bookmark>...", DATA_TYPE_STRING, ZK_WILDCARDLIST}, > +}; > + > /* ARGSUSED */ > static int > zfs_ioc_bookmark(const char *poolname, nvlist_t *innvl, nvlist_t *outnvl= ) > @@ -3801,6 +3881,10 @@ zfs_ioc_bookmark(const char *poolname, nvlist_t > *innvl > * } > * > */ > +static const zfs_ioc_key_t zfs_keys_get_bookmarks[] =3D { > + {"<property>...", DATA_TYPE_BOOLEAN, ZK_WILDCARDLIST | > ZK_OPTIONAL}, > +}; > + > static int > zfs_ioc_get_bookmarks(const char *fsname, nvlist_t *innvl, nvlist_t > *outnvl) > { > @@ -3815,6 +3899,10 @@ zfs_ioc_get_bookmarks(const char *fsname, nvlist_t > *in > * outnvl: bookmark -> error code (int32) > * > */ > +static const zfs_ioc_key_t zfs_keys_destroy_bookmarks[] =3D { > + {"<bookmark>...", DATA_TYPE_BOOLEAN, ZK_WILDCARDLIST}, > +}; > + > static int > zfs_ioc_destroy_bookmarks(const char *poolname, nvlist_t *innvl, > nvlist_t *outnvl) > @@ -3847,6 +3935,14 @@ zfs_ioc_destroy_bookmarks(const char *poolname, > nvlist > return (error); > } > > +static const zfs_ioc_key_t zfs_keys_channel_program[] =3D { > + {"program", DATA_TYPE_STRING, 0}, > + {"arg", DATA_TYPE_ANY, 0}, > + {"sync", DATA_TYPE_BOOLEAN_VALUE, ZK_OPTIONAL}, > + {"instrlimit", DATA_TYPE_UINT64, ZK_OPTIONAL}, > + {"memlimit", DATA_TYPE_UINT64, ZK_OPTIONAL}, > +}; > + > static int > zfs_ioc_channel_program(const char *poolname, nvlist_t *innvl, > nvlist_t *outnvl) > @@ -3856,9 +3952,7 @@ zfs_ioc_channel_program(const char *poolname, > nvlist_t > boolean_t sync_flag; > nvpair_t *nvarg =3D NULL; > > - if (0 !=3D nvlist_lookup_string(innvl, ZCP_ARG_PROGRAM, &program)= ) { > - return (EINVAL); > - } > + program =3D fnvlist_lookup_string(innvl, ZCP_ARG_PROGRAM); > if (0 !=3D nvlist_lookup_boolean_value(innvl, ZCP_ARG_SYNC, > &sync_flag)) { > sync_flag =3D B_TRUE; > } > @@ -3868,9 +3962,7 @@ zfs_ioc_channel_program(const char *poolname, > nvlist_t > if (0 !=3D nvlist_lookup_uint64(innvl, ZCP_ARG_MEMLIMIT, &memlimi= t)) > { > memlimit =3D ZCP_DEFAULT_MEMLIMIT; > } > - if (0 !=3D nvlist_lookup_nvpair(innvl, ZCP_ARG_ARGLIST, &nvarg)) = { > - return (EINVAL); > - } > + nvarg =3D fnvlist_lookup_nvpair(innvl, ZCP_ARG_ARGLIST); > > if (instrlimit =3D=3D 0 || instrlimit > zfs_lua_max_instrlimit) > return (EINVAL); > @@ -3885,6 +3977,10 @@ zfs_ioc_channel_program(const char *poolname, > nvlist_t > * innvl: unused > * outnvl: empty > */ > +static const zfs_ioc_key_t zfs_keys_pool_checkpoint[] =3D { > + /* no nvl keys */ > +}; > + > /* ARGSUSED */ > static int > zfs_ioc_pool_checkpoint(const char *poolname, nvlist_t *innvl, nvlist_t > *outnvl) > @@ -3896,6 +3992,10 @@ zfs_ioc_pool_checkpoint(const char *poolname, > nvlist_t > * innvl: unused > * outnvl: empty > */ > +static const zfs_ioc_key_t zfs_keys_pool_discard_checkpoint[] =3D { > + /* no nvl keys */ > +}; > + > /* ARGSUSED */ > static int > zfs_ioc_pool_discard_checkpoint(const char *poolname, nvlist_t *innvl, > @@ -3955,6 +4055,11 @@ zfs_ioc_destroy(zfs_cmd_t *zc) > * } > * > */ > +static const zfs_ioc_key_t zfs_keys_pool_initialize[] =3D { > + {ZPOOL_INITIALIZE_COMMAND, DATA_TYPE_UINT64, 0}, > + {ZPOOL_INITIALIZE_VDEVS, DATA_TYPE_NVLIST, 0} > +}; > + > static int > zfs_ioc_pool_initialize(const char *poolname, nvlist_t *innvl, nvlist_t > *outnvl) > { > @@ -4020,6 +4125,10 @@ zfs_ioc_pool_initialize(const char *poolname, > nvlist_t > * outnvl: "target" -> name of most recent snapshot > * } > */ > +static const zfs_ioc_key_t zfs_keys_rollback[] =3D { > + {"target", DATA_TYPE_STRING, ZK_OPTIONAL}, > +}; > + > /* ARGSUSED */ > static int > zfs_ioc_rollback(const char *fsname, nvlist_t *innvl, nvlist_t *outnvl) > @@ -5167,13 +5276,33 @@ zfs_ioc_clear(zfs_cmd_t *zc) > return (error); > } > > +/* > + * Reopen all the vdevs associated with the pool. > + * > + * innvl: { > + * "scrub_restart" -> when true and scrub is running, allow to restart > + * scrub as the side effect of the reopen (boolean). > + * } > + * > + * outnvl is unused > + */ > +static const zfs_ioc_key_t zfs_keys_pool_reopen[] =3D { > + {"scrub_restart", DATA_TYPE_BOOLEAN_VALUE, > ZK_OPTIONAL}, > +}; > + > static int > -zfs_ioc_pool_reopen(zfs_cmd_t *zc) > +zfs_ioc_pool_reopen(const char *pool, nvlist_t *innvl, nvlist_t *outnvl) > { > spa_t *spa; > int error; > + boolean_t scrub_restart =3D B_TRUE; > > - error =3D spa_open(zc->zc_name, &spa, FTAG); > + if (innvl) { > + scrub_restart =3D fnvlist_lookup_boolean_value(innvl, > + "scrub_restart"); > + } > + > + error =3D spa_open(pool, &spa, FTAG); > if (error !=3D 0) > return (error); > > @@ -5185,7 +5314,8 @@ zfs_ioc_pool_reopen(zfs_cmd_t *zc) > * the scan as a side effect of the reopen. Otherwise, let > * vdev_open() decided if a resilver is required. > */ > - spa->spa_scrub_reopen =3D dsl_scan_resilvering(spa->spa_dsl_pool)= ; > + spa->spa_scrub_reopen =3D (!scrub_restart && > + dsl_scan_resilvering(spa->spa_dsl_pool)); > vdev_reopen(spa->spa_root_vdev); > spa->spa_scrub_reopen =3D B_FALSE; > > @@ -5193,6 +5323,7 @@ zfs_ioc_pool_reopen(zfs_cmd_t *zc) > spa_close(spa, FTAG); > return (0); > } > + > /* > * inputs: > * zc_name name of filesystem > @@ -5789,6 +5920,11 @@ zfs_ioc_smb_acl(zfs_cmd_t *zc) > * ... > * } > */ > +static const zfs_ioc_key_t zfs_keys_hold[] =3D { > + {"holds", DATA_TYPE_NVLIST, 0}, > + {"cleanup_fd", DATA_TYPE_INT32, ZK_OPTIONAL}, > +}; > + > /* ARGSUSED */ > static int > zfs_ioc_hold(const char *pool, nvlist_t *args, nvlist_t *errlist) > @@ -5799,9 +5935,7 @@ zfs_ioc_hold(const char *pool, nvlist_t *args, > nvlist_ > int error; > minor_t minor =3D 0; > > - error =3D nvlist_lookup_nvlist(args, "holds", &holds); > - if (error !=3D 0) > - return (SET_ERROR(EINVAL)); > + holds =3D fnvlist_lookup_nvlist(args, "holds"); > > /* make sure the user didn't pass us any invalid (empty) tags */ > for (pair =3D nvlist_next_nvpair(holds, NULL); pair !=3D NULL; > @@ -5836,11 +5970,14 @@ zfs_ioc_hold(const char *pool, nvlist_t *args, > nvlist_ > * ... > * } > */ > +static const zfs_ioc_key_t zfs_keys_get_holds[] =3D { > + /* no nvl keys */ > +}; > + > /* ARGSUSED */ > static int > zfs_ioc_get_holds(const char *snapname, nvlist_t *args, nvlist_t *outnvl= ) > { > - ASSERT3P(args, =3D=3D, NULL); > return (dsl_dataset_get_holds(snapname, outnvl)); > } > > @@ -5855,6 +5992,10 @@ zfs_ioc_get_holds(const char *snapname, nvlist_t > *args > * ... > * } > */ > +static const zfs_ioc_key_t zfs_keys_release[] =3D { > + {"<snapname>...", DATA_TYPE_NVLIST, ZK_WILDCARDLIST}, > +}; > + > /* ARGSUSED */ > static int > zfs_ioc_release(const char *pool, nvlist_t *holds, nvlist_t *errlist) > @@ -5913,6 +6054,10 @@ zfs_ioc_space_written(zfs_cmd_t *zc) > * "uncompressed" -> uncompressed space in bytes > * } > */ > +static const zfs_ioc_key_t zfs_keys_space_snaps[] =3D { > + {"firstsnap", DATA_TYPE_STRING, 0}, > +}; > + > static int > zfs_ioc_space_snaps(const char *lastsnap, nvlist_t *innvl, nvlist_t > *outnvl) > { > @@ -5922,8 +6067,7 @@ zfs_ioc_space_snaps(const char *lastsnap, nvlist_t > *in > char *firstsnap; > uint64_t used, comp, uncomp; > > - if (nvlist_lookup_string(innvl, "firstsnap", &firstsnap) !=3D 0) > - return (SET_ERROR(EINVAL)); > + firstsnap =3D fnvlist_lookup_string(innvl, "firstsnap"); > > error =3D dsl_pool_hold(lastsnap, FTAG, &dp); > if (error !=3D 0) > @@ -5991,6 +6135,17 @@ zfs_ioc_unjail(zfs_cmd_t *zc) > * > * outnvl is unused > */ > +static const zfs_ioc_key_t zfs_keys_send_new[] =3D { > + {"fd", DATA_TYPE_INT32, 0}, > + {"fromsnap", DATA_TYPE_STRING, ZK_OPTIONAL}, > + {"largeblockok", DATA_TYPE_BOOLEAN, ZK_OPTIONAL}, > + {"embedok", DATA_TYPE_BOOLEAN, ZK_OPTIONAL}, > + {"compressok", DATA_TYPE_BOOLEAN, ZK_OPTIONAL}, > + {"rawok", DATA_TYPE_BOOLEAN, ZK_OPTIONAL}, > + {"resume_object", DATA_TYPE_UINT64, ZK_OPTIONAL}, > + {"resume_offset", DATA_TYPE_UINT64, ZK_OPTIONAL}, > +}; > + > /* ARGSUSED */ > static int > zfs_ioc_send_new(const char *snapname, nvlist_t *innvl, nvlist_t *outnvl= ) > @@ -6006,9 +6161,7 @@ zfs_ioc_send_new(const char *snapname, nvlist_t > *innvl > uint64_t resumeobj =3D 0; > uint64_t resumeoff =3D 0; > > - error =3D nvlist_lookup_int32(innvl, "fd", &fd); > - if (error !=3D 0) > - return (SET_ERROR(EINVAL)); > + fd =3D fnvlist_lookup_int32(innvl, "fd"); > > (void) nvlist_lookup_string(innvl, "fromsnap", &fromname); > > @@ -6065,6 +6218,15 @@ zfs_ioc_send_new(const char *snapname, nvlist_t > *innvl > * "space" -> bytes of space (uint64) > * } > */ > +static const zfs_ioc_key_t zfs_keys_send_space[] =3D { > + {"from", DATA_TYPE_STRING, ZK_OPTIONAL}, > + {"fromsnap", DATA_TYPE_STRING, ZK_OPTIONAL}, > + {"largeblockok", DATA_TYPE_BOOLEAN, ZK_OPTIONAL}, > + {"embedok", DATA_TYPE_BOOLEAN, ZK_OPTIONAL}, > + {"compressok", DATA_TYPE_BOOLEAN, ZK_OPTIONAL}, > + {"rawok", DATA_TYPE_BOOLEAN, ZK_OPTIONAL}, > +}; > + > static int > zfs_ioc_send_space(const char *snapname, nvlist_t *innvl, nvlist_t > *outnvl) > { > @@ -6153,6 +6315,10 @@ out: > * > * onvl is unused > */ > +static const zfs_ioc_key_t zfs_keys_pool_sync[] =3D { > + {"force", DATA_TYPE_BOOLEAN_VALUE, 0}, > +}; > + > /* ARGSUSED */ > static int > zfs_ioc_pool_sync(const char *pool, nvlist_t *innvl, nvlist_t *onvl) > @@ -6206,7 +6372,7 @@ static void > zfs_ioctl_register(const char *name, zfs_ioc_t ioc, zfs_ioc_func_t *func= , > zfs_secpolicy_func_t *secpolicy, zfs_ioc_namecheck_t namecheck, > zfs_ioc_poolcheck_t pool_check, boolean_t smush_outnvlist, > - boolean_t allow_log) > + boolean_t allow_log, const zfs_ioc_key_t *nvl_keys, size_t num_keys) > { > zfs_ioc_vec_t *vec =3D &zfs_ioc_vec[ioc - ZFS_IOC_FIRST]; > > @@ -6225,6 +6391,8 @@ zfs_ioctl_register(const char *name, zfs_ioc_t ioc, > zf > vec->zvec_pool_check =3D pool_check; > vec->zvec_smush_outnvlist =3D smush_outnvlist; > vec->zvec_allow_log =3D allow_log; > + vec->zvec_nvl_keys =3D nvl_keys; > + vec->zvec_nvl_key_count =3D num_keys; > } > > static void > @@ -6287,89 +6455,115 @@ zfs_ioctl_init(void) > { > zfs_ioctl_register("snapshot", ZFS_IOC_SNAPSHOT, > zfs_ioc_snapshot, zfs_secpolicy_snapshot, POOL_NAME, > - POOL_CHECK_SUSPENDED | POOL_CHECK_READONLY, B_TRUE, B_TRUE); > + POOL_CHECK_SUSPENDED | POOL_CHECK_READONLY, B_TRUE, B_TRUE, > + zfs_keys_snapshot, ARRAY_SIZE(zfs_keys_snapshot)); > > zfs_ioctl_register("log_history", ZFS_IOC_LOG_HISTORY, > zfs_ioc_log_history, zfs_secpolicy_log_history, NO_NAME, > - POOL_CHECK_SUSPENDED | POOL_CHECK_READONLY, B_FALSE, B_FALSE)= ; > + POOL_CHECK_SUSPENDED | POOL_CHECK_READONLY, B_FALSE, B_FALSE, > + zfs_keys_log_history, ARRAY_SIZE(zfs_keys_log_history)); > > zfs_ioctl_register("space_snaps", ZFS_IOC_SPACE_SNAPS, > zfs_ioc_space_snaps, zfs_secpolicy_read, DATASET_NAME, > - POOL_CHECK_SUSPENDED, B_FALSE, B_FALSE); > + POOL_CHECK_SUSPENDED, B_FALSE, B_FALSE, > + zfs_keys_space_snaps, ARRAY_SIZE(zfs_keys_space_snaps)); > > zfs_ioctl_register("send", ZFS_IOC_SEND_NEW, > zfs_ioc_send_new, zfs_secpolicy_send_new, DATASET_NAME, > - POOL_CHECK_SUSPENDED, B_FALSE, B_FALSE); > + POOL_CHECK_SUSPENDED, B_FALSE, B_FALSE, > + zfs_keys_send_new, ARRAY_SIZE(zfs_keys_send_new)); > > zfs_ioctl_register("send_space", ZFS_IOC_SEND_SPACE, > zfs_ioc_send_space, zfs_secpolicy_read, DATASET_NAME, > - POOL_CHECK_SUSPENDED, B_FALSE, B_FALSE); > + POOL_CHECK_SUSPENDED, B_FALSE, B_FALSE, > + zfs_keys_send_space, ARRAY_SIZE(zfs_keys_send_space)); > > zfs_ioctl_register("create", ZFS_IOC_CREATE, > zfs_ioc_create, zfs_secpolicy_create_clone, DATASET_NAME, > - POOL_CHECK_SUSPENDED | POOL_CHECK_READONLY, B_TRUE, B_TRUE); > + POOL_CHECK_SUSPENDED | POOL_CHECK_READONLY, B_TRUE, B_TRUE, > + zfs_keys_create, ARRAY_SIZE(zfs_keys_create)); > > zfs_ioctl_register("clone", ZFS_IOC_CLONE, > zfs_ioc_clone, zfs_secpolicy_create_clone, DATASET_NAME, > - POOL_CHECK_SUSPENDED | POOL_CHECK_READONLY, B_TRUE, B_TRUE); > + POOL_CHECK_SUSPENDED | POOL_CHECK_READONLY, B_TRUE, B_TRUE, > + zfs_keys_clone, ARRAY_SIZE(zfs_keys_clone)); > > zfs_ioctl_register("remap", ZFS_IOC_REMAP, > zfs_ioc_remap, zfs_secpolicy_remap, DATASET_NAME, > - POOL_CHECK_SUSPENDED | POOL_CHECK_READONLY, B_FALSE, B_TRUE); > + POOL_CHECK_SUSPENDED | POOL_CHECK_READONLY, B_FALSE, B_TRUE, > + zfs_keys_remap, ARRAY_SIZE(zfs_keys_remap)); > > zfs_ioctl_register("destroy_snaps", ZFS_IOC_DESTROY_SNAPS, > zfs_ioc_destroy_snaps, zfs_secpolicy_destroy_snaps, POOL_NAME= , > - POOL_CHECK_SUSPENDED | POOL_CHECK_READONLY, B_TRUE, B_TRUE); > + POOL_CHECK_SUSPENDED | POOL_CHECK_READONLY, B_TRUE, B_TRUE, > + zfs_keys_destroy_snaps, ARRAY_SIZE(zfs_keys_destroy_snaps)); > > zfs_ioctl_register("hold", ZFS_IOC_HOLD, > zfs_ioc_hold, zfs_secpolicy_hold, POOL_NAME, > - POOL_CHECK_SUSPENDED | POOL_CHECK_READONLY, B_TRUE, B_TRUE); > + POOL_CHECK_SUSPENDED | POOL_CHECK_READONLY, B_TRUE, B_TRUE, > + zfs_keys_hold, ARRAY_SIZE(zfs_keys_hold)); > zfs_ioctl_register("release", ZFS_IOC_RELEASE, > zfs_ioc_release, zfs_secpolicy_release, POOL_NAME, > - POOL_CHECK_SUSPENDED | POOL_CHECK_READONLY, B_TRUE, B_TRUE); > + POOL_CHECK_SUSPENDED | POOL_CHECK_READONLY, B_TRUE, B_TRUE, > + zfs_keys_release, ARRAY_SIZE(zfs_keys_release)); > > zfs_ioctl_register("get_holds", ZFS_IOC_GET_HOLDS, > zfs_ioc_get_holds, zfs_secpolicy_read, DATASET_NAME, > - POOL_CHECK_SUSPENDED, B_FALSE, B_FALSE); > + POOL_CHECK_SUSPENDED, B_FALSE, B_FALSE, > + zfs_keys_get_holds, ARRAY_SIZE(zfs_keys_get_holds)); > > zfs_ioctl_register("rollback", ZFS_IOC_ROLLBACK, > zfs_ioc_rollback, zfs_secpolicy_rollback, DATASET_NAME, > - POOL_CHECK_SUSPENDED | POOL_CHECK_READONLY, B_FALSE, B_TRUE); > + POOL_CHECK_SUSPENDED | POOL_CHECK_READONLY, B_FALSE, B_TRUE, > + zfs_keys_rollback, ARRAY_SIZE(zfs_keys_rollback)); > > zfs_ioctl_register("bookmark", ZFS_IOC_BOOKMARK, > zfs_ioc_bookmark, zfs_secpolicy_bookmark, POOL_NAME, > - POOL_CHECK_SUSPENDED | POOL_CHECK_READONLY, B_TRUE, B_TRUE); > + POOL_CHECK_SUSPENDED | POOL_CHECK_READONLY, B_TRUE, B_TRUE, > + zfs_keys_bookmark, ARRAY_SIZE(zfs_keys_bookmark)); > > zfs_ioctl_register("get_bookmarks", ZFS_IOC_GET_BOOKMARKS, > zfs_ioc_get_bookmarks, zfs_secpolicy_read, DATASET_NAME, > - POOL_CHECK_SUSPENDED, B_FALSE, B_FALSE); > + POOL_CHECK_SUSPENDED, B_FALSE, B_FALSE, > + zfs_keys_get_bookmarks, ARRAY_SIZE(zfs_keys_get_bookmarks)); > > zfs_ioctl_register("destroy_bookmarks", ZFS_IOC_DESTROY_BOOKMARKS= , > zfs_ioc_destroy_bookmarks, zfs_secpolicy_destroy_bookmarks, > POOL_NAME, > - POOL_CHECK_SUSPENDED | POOL_CHECK_READONLY, B_TRUE, B_TRUE); > + POOL_CHECK_SUSPENDED | POOL_CHECK_READONLY, B_TRUE, B_TRUE, > + zfs_keys_destroy_bookmarks, > + ARRAY_SIZE(zfs_keys_destroy_bookmarks)); > > zfs_ioctl_register("channel_program", ZFS_IOC_CHANNEL_PROGRAM, > zfs_ioc_channel_program, zfs_secpolicy_config, > POOL_NAME, POOL_CHECK_SUSPENDED | POOL_CHECK_READONLY, B_TRUE= , > - B_TRUE); > + B_TRUE, zfs_keys_channel_program, > + ARRAY_SIZE(zfs_keys_channel_program)); > > zfs_ioctl_register("zpool_checkpoint", ZFS_IOC_POOL_CHECKPOINT, > zfs_ioc_pool_checkpoint, zfs_secpolicy_config, POOL_NAME, > - POOL_CHECK_SUSPENDED | POOL_CHECK_READONLY, B_TRUE, B_TRUE); > + POOL_CHECK_SUSPENDED | POOL_CHECK_READONLY, B_TRUE, B_TRUE, > + zfs_keys_pool_checkpoint, > ARRAY_SIZE(zfs_keys_pool_checkpoint)); > > zfs_ioctl_register("zpool_discard_checkpoint", > ZFS_IOC_POOL_DISCARD_CHECKPOINT, > zfs_ioc_pool_discard_checkpoint, > zfs_secpolicy_config, POOL_NAME, > - POOL_CHECK_SUSPENDED | POOL_CHECK_READONLY, B_TRUE, B_TRUE); > + POOL_CHECK_SUSPENDED | POOL_CHECK_READONLY, B_TRUE, B_TRUE, > + zfs_keys_pool_discard_checkpoint, > + ARRAY_SIZE(zfs_keys_pool_discard_checkpoint)); > > zfs_ioctl_register("initialize", ZFS_IOC_POOL_INITIALIZE, > zfs_ioc_pool_initialize, zfs_secpolicy_config, POOL_NAME, > - POOL_CHECK_SUSPENDED | POOL_CHECK_READONLY, B_TRUE, B_TRUE); > + POOL_CHECK_SUSPENDED | POOL_CHECK_READONLY, B_TRUE, B_TRUE, > > *** DIFF OUTPUT TRUNCATED AT 1000 LINES *** >
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?CAPrugNq_DCEgfM9byAtjfH_7hSwOPnmQ44aPzdD6MESw-4H3Zw>