17ac89354SDon Brady /*
27ac89354SDon Brady  * CDDL HEADER START
37ac89354SDon Brady  *
47ac89354SDon Brady  * This file and its contents are supplied under the terms of the
57ac89354SDon Brady  * Common Development and Distribution License ("CDDL"), version 1.0.
67ac89354SDon Brady  * You may only use this file in accordance with the terms of version
77ac89354SDon Brady  * 1.0 of the CDDL.
87ac89354SDon Brady  *
97ac89354SDon Brady  * A full copy of the text of the CDDL should have accompanied this
107ac89354SDon Brady  * source.  A copy of the CDDL is also available via the Internet at
117ac89354SDon Brady  * http://www.illumos.org/license/CDDL.
127ac89354SDon Brady  *
137ac89354SDon Brady  * CDDL HEADER END
147ac89354SDon Brady  */
157ac89354SDon Brady 
167ac89354SDon Brady /*
177ac89354SDon Brady  * Copyright (c) 2018 by Delphix. All rights reserved.
187ac89354SDon Brady  * Copyright 2020 Joyent, Inc.
197ac89354SDon Brady  */
207ac89354SDon Brady 
217ac89354SDon Brady #include <errno.h>
227ac89354SDon Brady #include <fcntl.h>
237ac89354SDon Brady #include <stdio.h>
247ac89354SDon Brady #include <stdlib.h>
257ac89354SDon Brady #include <string.h>
267ac89354SDon Brady #include <strings.h>
277ac89354SDon Brady #include <libzfs_core.h>
287ac89354SDon Brady #include <unistd.h>
297ac89354SDon Brady 
307ac89354SDon Brady #include <sys/nvpair.h>
3109fcda9fSToomas Soome #include <sys/vdev_impl.h>
327ac89354SDon Brady #include <sys/zfs_ioctl.h>
3309fcda9fSToomas Soome #include <sys/zfs_bootenv.h>
347ac89354SDon Brady 
357ac89354SDon Brady /*
367ac89354SDon Brady  * Test the nvpair inputs for the non-legacy zfs ioctl commands.
377ac89354SDon Brady  */
387ac89354SDon Brady 
397ac89354SDon Brady boolean_t unexpected_failures;
407ac89354SDon Brady int zfs_fd;
417ac89354SDon Brady const char *active_test;
427ac89354SDon Brady 
437ac89354SDon Brady /*
447ac89354SDon Brady  * Tracks which zfs_ioc_t commands were tested
457ac89354SDon Brady  */
467ac89354SDon Brady boolean_t ioc_tested[256];
477ac89354SDon Brady 
487ac89354SDon Brady /*
497ac89354SDon Brady  * Legacy ioctls that are skipped (for now)
507ac89354SDon Brady  */
517ac89354SDon Brady static unsigned ioc_skip[] = {
527ac89354SDon Brady 	ZFS_IOC_POOL_CREATE,
537ac89354SDon Brady 	ZFS_IOC_POOL_DESTROY,
547ac89354SDon Brady 	ZFS_IOC_POOL_IMPORT,
557ac89354SDon Brady 	ZFS_IOC_POOL_EXPORT,
567ac89354SDon Brady 	ZFS_IOC_POOL_CONFIGS,
577ac89354SDon Brady 	ZFS_IOC_POOL_STATS,
587ac89354SDon Brady 	ZFS_IOC_POOL_TRYIMPORT,
597ac89354SDon Brady 	ZFS_IOC_POOL_SCAN,
607ac89354SDon Brady 	ZFS_IOC_POOL_FREEZE,
617ac89354SDon Brady 	ZFS_IOC_POOL_UPGRADE,
627ac89354SDon Brady 	ZFS_IOC_POOL_GET_HISTORY,
637ac89354SDon Brady 
647ac89354SDon Brady 	ZFS_IOC_VDEV_ADD,
657ac89354SDon Brady 	ZFS_IOC_VDEV_REMOVE,
667ac89354SDon Brady 	ZFS_IOC_VDEV_SET_STATE,
677ac89354SDon Brady 	ZFS_IOC_VDEV_ATTACH,
687ac89354SDon Brady 	ZFS_IOC_VDEV_DETACH,
697ac89354SDon Brady 	ZFS_IOC_VDEV_SETPATH,
707ac89354SDon Brady 	ZFS_IOC_VDEV_SETFRU,
717ac89354SDon Brady 
727ac89354SDon Brady 	ZFS_IOC_OBJSET_STATS,
737ac89354SDon Brady 	ZFS_IOC_OBJSET_ZPLPROPS,
747ac89354SDon Brady 	ZFS_IOC_DATASET_LIST_NEXT,
757ac89354SDon Brady 	ZFS_IOC_SNAPSHOT_LIST_NEXT,
767ac89354SDon Brady 	ZFS_IOC_SET_PROP,
777ac89354SDon Brady 	ZFS_IOC_DESTROY,
787ac89354SDon Brady 	ZFS_IOC_RENAME,
797ac89354SDon Brady 	ZFS_IOC_RECV,
807ac89354SDon Brady 	ZFS_IOC_SEND,
817ac89354SDon Brady 	ZFS_IOC_INJECT_FAULT,
827ac89354SDon Brady 	ZFS_IOC_CLEAR_FAULT,
837ac89354SDon Brady 	ZFS_IOC_INJECT_LIST_NEXT,
847ac89354SDon Brady 	ZFS_IOC_ERROR_LOG,
857ac89354SDon Brady 	ZFS_IOC_CLEAR,
867ac89354SDon Brady 	ZFS_IOC_PROMOTE,
877ac89354SDon Brady 	ZFS_IOC_DSOBJ_TO_DSNAME,
887ac89354SDon Brady 	ZFS_IOC_OBJ_TO_PATH,
897ac89354SDon Brady 	ZFS_IOC_POOL_SET_PROPS,
907ac89354SDon Brady 	ZFS_IOC_POOL_GET_PROPS,
917ac89354SDon Brady 	ZFS_IOC_SET_FSACL,
927ac89354SDon Brady 	ZFS_IOC_GET_FSACL,
937ac89354SDon Brady 	ZFS_IOC_SHARE,
947ac89354SDon Brady 	ZFS_IOC_INHERIT_PROP,
957ac89354SDon Brady 	ZFS_IOC_SMB_ACL,
967ac89354SDon Brady 	ZFS_IOC_USERSPACE_ONE,
977ac89354SDon Brady 	ZFS_IOC_USERSPACE_MANY,
987ac89354SDon Brady 	ZFS_IOC_USERSPACE_UPGRADE,
997ac89354SDon Brady 	ZFS_IOC_OBJSET_RECVD_PROPS,
1007ac89354SDon Brady 	ZFS_IOC_VDEV_SPLIT,
1017ac89354SDon Brady 	ZFS_IOC_NEXT_OBJ,
1027ac89354SDon Brady 	ZFS_IOC_DIFF,
1037ac89354SDon Brady 	ZFS_IOC_TMP_SNAPSHOT,
1047ac89354SDon Brady 	ZFS_IOC_OBJ_TO_STATS,
1057ac89354SDon Brady 	ZFS_IOC_SPACE_WRITTEN,
1067ac89354SDon Brady 	ZFS_IOC_POOL_REGUID,
1077ac89354SDon Brady 	ZFS_IOC_SEND_PROGRESS,
1087ac89354SDon Brady 
1097ac89354SDon Brady #ifndef __sun
1107ac89354SDon Brady 	ZFS_IOC_EVENTS_NEXT,
1117ac89354SDon Brady 	ZFS_IOC_EVENTS_CLEAR,
1127ac89354SDon Brady 	ZFS_IOC_EVENTS_SEEK,
113c4ecba8aSPaul Dagnelie 	ZFS_IOC_NEXTBOOT,
114c4ecba8aSPaul Dagnelie 	ZFS_IOC_JAIL,
115c4ecba8aSPaul Dagnelie 	ZFS_IOC_UNJAIL,
1167ac89354SDon Brady #else
1177ac89354SDon Brady 	/* This is still a legacy ioctl in illumos */
1187ac89354SDon Brady 	ZFS_IOC_POOL_REOPEN,
1197ac89354SDon Brady #endif
1207ac89354SDon Brady };
1217ac89354SDon Brady 
1227ac89354SDon Brady 
1237ac89354SDon Brady #define	IOC_INPUT_TEST(ioc, name, req, opt, err)		\
1247ac89354SDon Brady 	IOC_INPUT_TEST_IMPL(ioc, name, req, opt, err, B_FALSE)
1257ac89354SDon Brady 
1267ac89354SDon Brady #define	IOC_INPUT_TEST_WILD(ioc, name, req, opt, err)		\
1277ac89354SDon Brady 	IOC_INPUT_TEST_IMPL(ioc, name, req, opt, err, B_TRUE)
1287ac89354SDon Brady 
1297ac89354SDon Brady #define	IOC_INPUT_TEST_IMPL(ioc, name, req, opt, err, wild)	\
1307ac89354SDon Brady 	do {							\
1317ac89354SDon Brady 		active_test = __func__ + 5;			\
1327ac89354SDon Brady 		ioc_tested[ioc - ZFS_IOC_FIRST] = B_TRUE;	\
1337ac89354SDon Brady 		(void) lzc_ioctl_test(ioc, name, req, opt, err, wild);	\
1347ac89354SDon Brady 	} while (0)
1357ac89354SDon Brady 
1367ac89354SDon Brady /*
1377ac89354SDon Brady  * run a zfs ioctl command, verify expected results and log failures
1387ac89354SDon Brady  */
1397ac89354SDon Brady static void
lzc_ioctl_run(zfs_ioc_t ioc,const char * name,nvlist_t * innvl,int expected)1407ac89354SDon Brady lzc_ioctl_run(zfs_ioc_t ioc, const char *name, nvlist_t *innvl, int expected)
1417ac89354SDon Brady {
1427ac89354SDon Brady 	zfs_cmd_t zc = {"\0"};
1437ac89354SDon Brady 	char *packed = NULL;
1447ac89354SDon Brady 	const char *variant;
1457ac89354SDon Brady 	size_t size = 0;
1467ac89354SDon Brady 	int error = 0;
1477ac89354SDon Brady 
1487ac89354SDon Brady 	switch (expected) {
1497ac89354SDon Brady 	case ZFS_ERR_IOC_ARG_UNAVAIL:
1507ac89354SDon Brady 		variant = "unsupported input";
1517ac89354SDon Brady 		break;
1527ac89354SDon Brady 	case ZFS_ERR_IOC_ARG_REQUIRED:
1537ac89354SDon Brady 		variant = "missing input";
1547ac89354SDon Brady 		break;
1557ac89354SDon Brady 	case ZFS_ERR_IOC_ARG_BADTYPE:
1567ac89354SDon Brady 		variant = "invalid input type";
1577ac89354SDon Brady 		break;
1587ac89354SDon Brady 	default:
1597ac89354SDon Brady 		variant = "valid input";
1607ac89354SDon Brady 		break;
1617ac89354SDon Brady 	}
1627ac89354SDon Brady 
1637ac89354SDon Brady 	packed = fnvlist_pack(innvl, &size);
1647ac89354SDon Brady 	(void) strncpy(zc.zc_name, name, sizeof (zc.zc_name));
1657ac89354SDon Brady 	zc.zc_name[sizeof (zc.zc_name) - 1] = '\0';
1667ac89354SDon Brady 	zc.zc_nvlist_src = (uint64_t)(uintptr_t)packed;
1677ac89354SDon Brady 	zc.zc_nvlist_src_size = size;
1687ac89354SDon Brady 	zc.zc_nvlist_dst_size = MAX(size * 2, 128 * 1024);
1697ac89354SDon Brady 	zc.zc_nvlist_dst = (uint64_t)(uintptr_t)malloc(zc.zc_nvlist_dst_size);
1707ac89354SDon Brady 
1717ac89354SDon Brady 	if (ioctl(zfs_fd, ioc, &zc) != 0)
1727ac89354SDon Brady 		error = errno;
1737ac89354SDon Brady 
1747ac89354SDon Brady 	if (error != expected) {
1757ac89354SDon Brady 		unexpected_failures = B_TRUE;
1767ac89354SDon Brady 		(void) fprintf(stderr, "%s: Unexpected result with %s, "
1777ac89354SDon Brady 		    "error %d (expecting %d)\n",
1787ac89354SDon Brady 		    active_test, variant, error, expected);
1797ac89354SDon Brady 	}
1807ac89354SDon Brady 
1817ac89354SDon Brady 	fnvlist_pack_free(packed, size);
1827ac89354SDon Brady 	free((void *)(uintptr_t)zc.zc_nvlist_dst);
1837ac89354SDon Brady }
1847ac89354SDon Brady 
1857ac89354SDon Brady /*
1867ac89354SDon Brady  * Test each ioc for the following ioctl input errors:
1877ac89354SDon Brady  *   ZFS_ERR_IOC_ARG_UNAVAIL	an input argument is not supported by kernel
1887ac89354SDon Brady  *   ZFS_ERR_IOC_ARG_REQUIRED	a required input argument is missing
1897ac89354SDon Brady  *   ZFS_ERR_IOC_ARG_BADTYPE	an input argument has an invalid type
1907ac89354SDon Brady  */
1917ac89354SDon Brady static int
lzc_ioctl_test(zfs_ioc_t ioc,const char * name,nvlist_t * required,nvlist_t * optional,int expected_error,boolean_t wildcard)1927ac89354SDon Brady lzc_ioctl_test(zfs_ioc_t ioc, const char *name, nvlist_t *required,
1937ac89354SDon Brady     nvlist_t *optional, int expected_error, boolean_t wildcard)
1947ac89354SDon Brady {
1957ac89354SDon Brady 	nvlist_t *input = fnvlist_alloc();
1967ac89354SDon Brady 	nvlist_t *future = fnvlist_alloc();
1977ac89354SDon Brady 	int error = 0;
1987ac89354SDon Brady 
1997ac89354SDon Brady 	if (required != NULL) {
2007ac89354SDon Brady 		for (nvpair_t *pair = nvlist_next_nvpair(required, NULL);
2017ac89354SDon Brady 		    pair != NULL; pair = nvlist_next_nvpair(required, pair)) {
2027ac89354SDon Brady 			fnvlist_add_nvpair(input, pair);
2037ac89354SDon Brady 		}
2047ac89354SDon Brady 	}
2057ac89354SDon Brady 	if (optional != NULL) {
2067ac89354SDon Brady 		for (nvpair_t *pair = nvlist_next_nvpair(optional, NULL);
2077ac89354SDon Brady 		    pair != NULL; pair = nvlist_next_nvpair(optional, pair)) {
2087ac89354SDon Brady 			fnvlist_add_nvpair(input, pair);
2097ac89354SDon Brady 		}
2107ac89354SDon Brady 	}
2117ac89354SDon Brady 
2127ac89354SDon Brady 	/*
2137ac89354SDon Brady 	 * Generic input run with 'optional' nvlist pair
2147ac89354SDon Brady 	 */
2157ac89354SDon Brady 	if (!wildcard)
2167ac89354SDon Brady 		fnvlist_add_nvlist(input, "optional", future);
2177ac89354SDon Brady 	lzc_ioctl_run(ioc, name, input, expected_error);
2187ac89354SDon Brady 	if (!wildcard)
2197ac89354SDon Brady 		fnvlist_remove(input, "optional");
2207ac89354SDon Brady 
2217ac89354SDon Brady 	/*
2227ac89354SDon Brady 	 * Bogus input value
2237ac89354SDon Brady 	 */
2247ac89354SDon Brady 	if (!wildcard) {
2257ac89354SDon Brady 		fnvlist_add_string(input, "bogus_input", "bogus");
2267ac89354SDon Brady 		lzc_ioctl_run(ioc, name, input, ZFS_ERR_IOC_ARG_UNAVAIL);
2277ac89354SDon Brady 		fnvlist_remove(input, "bogus_input");
2287ac89354SDon Brady 	}
2297ac89354SDon Brady 
2307ac89354SDon Brady 	/*
2317ac89354SDon Brady 	 * Missing required inputs
2327ac89354SDon Brady 	 */
2337ac89354SDon Brady 	if (required != NULL) {
2347ac89354SDon Brady 		nvlist_t *empty = fnvlist_alloc();
2357ac89354SDon Brady 		lzc_ioctl_run(ioc, name, empty, ZFS_ERR_IOC_ARG_REQUIRED);
2367ac89354SDon Brady 		nvlist_free(empty);
2377ac89354SDon Brady 	}
2387ac89354SDon Brady 
2397ac89354SDon Brady 	/*
2407ac89354SDon Brady 	 * Wrong nvpair type
2417ac89354SDon Brady 	 */
2427ac89354SDon Brady 	if (required != NULL || optional != NULL) {
2437ac89354SDon Brady 		/*
2447ac89354SDon Brady 		 * switch the type of one of the input pairs
2457ac89354SDon Brady 		 */
2467ac89354SDon Brady 		for (nvpair_t *pair = nvlist_next_nvpair(input, NULL);
2477ac89354SDon Brady 		    pair != NULL; pair = nvlist_next_nvpair(input, pair)) {
2487ac89354SDon Brady 			char pname[MAXNAMELEN];
2497ac89354SDon Brady 			data_type_t ptype;
2507ac89354SDon Brady 
2517ac89354SDon Brady 			(void) strncpy(pname, nvpair_name(pair),
2527ac89354SDon Brady 			    sizeof (pname));
2537ac89354SDon Brady 			pname[sizeof (pname) - 1] = '\0';
2547ac89354SDon Brady 			ptype = nvpair_type(pair);
2557ac89354SDon Brady 			fnvlist_remove_nvpair(input, pair);
2567ac89354SDon Brady 
2577ac89354SDon Brady 			switch (ptype) {
2587ac89354SDon Brady 			case DATA_TYPE_STRING:
2597ac89354SDon Brady 				fnvlist_add_uint64(input, pname, 42);
2607ac89354SDon Brady 				break;
2617ac89354SDon Brady 			default:
2627ac89354SDon Brady 				fnvlist_add_string(input, pname, "bogus");
2637ac89354SDon Brady 				break;
2647ac89354SDon Brady 			}
2657ac89354SDon Brady 		}
2667ac89354SDon Brady 		lzc_ioctl_run(ioc, name, input, ZFS_ERR_IOC_ARG_BADTYPE);
2677ac89354SDon Brady 	}
2687ac89354SDon Brady 
2697ac89354SDon Brady 	nvlist_free(future);
2707ac89354SDon Brady 	nvlist_free(input);
2717ac89354SDon Brady 
2727ac89354SDon Brady 	return (error);
2737ac89354SDon Brady }
2747ac89354SDon Brady 
2757ac89354SDon Brady static void
test_pool_sync(const char * pool)2767ac89354SDon Brady test_pool_sync(const char *pool)
2777ac89354SDon Brady {
2787ac89354SDon Brady 	nvlist_t *required = fnvlist_alloc();
2797ac89354SDon Brady 
2807ac89354SDon Brady 	fnvlist_add_boolean_value(required, "force", B_TRUE);
2817ac89354SDon Brady 
2827ac89354SDon Brady 	IOC_INPUT_TEST(ZFS_IOC_POOL_SYNC, pool, required, NULL, 0);
2837ac89354SDon Brady 
2847ac89354SDon Brady 	nvlist_free(required);
2857ac89354SDon Brady }
2867ac89354SDon Brady 
2877ac89354SDon Brady #ifndef sun
2887ac89354SDon Brady static void
test_pool_reopen(const char * pool)2897ac89354SDon Brady test_pool_reopen(const char *pool)
2907ac89354SDon Brady {
2917ac89354SDon Brady 	nvlist_t *required = fnvlist_alloc();
2927ac89354SDon Brady 
2937ac89354SDon Brady 	fnvlist_add_boolean_value(required, "scrub_restart", B_FALSE);
2947ac89354SDon Brady 
2957ac89354SDon Brady 	IOC_INPUT_TEST(ZFS_IOC_POOL_REOPEN, pool, required, NULL, 0);
2967ac89354SDon Brady 
2977ac89354SDon Brady 	nvlist_free(required);
2987ac89354SDon Brady }
2997ac89354SDon Brady #endif
3007ac89354SDon Brady 
3017ac89354SDon Brady static void
test_pool_checkpoint(const char * pool)3027ac89354SDon Brady test_pool_checkpoint(const char *pool)
3037ac89354SDon Brady {
3047ac89354SDon Brady 	IOC_INPUT_TEST(ZFS_IOC_POOL_CHECKPOINT, pool, NULL, NULL, 0);
3057ac89354SDon Brady }
3067ac89354SDon Brady 
3077ac89354SDon Brady static void
test_pool_discard_checkpoint(const char * pool)3087ac89354SDon Brady test_pool_discard_checkpoint(const char *pool)
3097ac89354SDon Brady {
3107ac89354SDon Brady 	int err = lzc_pool_checkpoint(pool);
3117ac89354SDon Brady 	if (err == 0 || err == ZFS_ERR_CHECKPOINT_EXISTS)
3127ac89354SDon Brady 		IOC_INPUT_TEST(ZFS_IOC_POOL_DISCARD_CHECKPOINT, pool, NULL,
3137ac89354SDon Brady 		    NULL, 0);
3147ac89354SDon Brady }
3157ac89354SDon Brady 
3167ac89354SDon Brady static void
test_log_history(const char * pool)3177ac89354SDon Brady test_log_history(const char *pool)
3187ac89354SDon Brady {
3197ac89354SDon Brady 	nvlist_t *required = fnvlist_alloc();
3207ac89354SDon Brady 
3217ac89354SDon Brady 	fnvlist_add_string(required, "message", "input check");
3227ac89354SDon Brady 
3237ac89354SDon Brady 	IOC_INPUT_TEST(ZFS_IOC_LOG_HISTORY, pool, required, NULL, 0);
3247ac89354SDon Brady 
3257ac89354SDon Brady 	nvlist_free(required);
3267ac89354SDon Brady }
3277ac89354SDon Brady 
3287ac89354SDon Brady static void
test_create(const char * pool)3297ac89354SDon Brady test_create(const char *pool)
3307ac89354SDon Brady {
3317ac89354SDon Brady 	char dataset[MAXNAMELEN + 32];
3327ac89354SDon Brady 
3337ac89354SDon Brady 	(void) snprintf(dataset, sizeof (dataset), "%s/create-fs", pool);
3347ac89354SDon Brady 
3357ac89354SDon Brady 	nvlist_t *required = fnvlist_alloc();
3367ac89354SDon Brady 	nvlist_t *optional = fnvlist_alloc();
3377ac89354SDon Brady 	nvlist_t *props = fnvlist_alloc();
3387ac89354SDon Brady 
3397ac89354SDon Brady 	fnvlist_add_int32(required, "type", DMU_OST_ZFS);
3407ac89354SDon Brady 	fnvlist_add_uint64(props, "recordsize", 8192);
3417ac89354SDon Brady 	fnvlist_add_nvlist(optional, "props", props);
3427ac89354SDon Brady 
3437ac89354SDon Brady 	IOC_INPUT_TEST(ZFS_IOC_CREATE, dataset, required, optional, 0);
3447ac89354SDon Brady 
3457ac89354SDon Brady 	nvlist_free(required);
3467ac89354SDon Brady 	nvlist_free(optional);
3477ac89354SDon Brady }
3487ac89354SDon Brady 
3497ac89354SDon Brady static void
test_snapshot(const char * pool,const char * snapshot)3507ac89354SDon Brady test_snapshot(const char *pool, const char *snapshot)
3517ac89354SDon Brady {
3527ac89354SDon Brady 	nvlist_t *required = fnvlist_alloc();
3537ac89354SDon Brady 	nvlist_t *optional = fnvlist_alloc();
3547ac89354SDon Brady 	nvlist_t *snaps = fnvlist_alloc();
3557ac89354SDon Brady 	nvlist_t *props = fnvlist_alloc();
3567ac89354SDon Brady 
3577ac89354SDon Brady 	fnvlist_add_boolean(snaps, snapshot);
3587ac89354SDon Brady 	fnvlist_add_nvlist(required, "snaps", snaps);
3597ac89354SDon Brady 
3607ac89354SDon Brady 	fnvlist_add_string(props, "org.openzfs:launch", "September 17th, 2013");
3617ac89354SDon Brady 	fnvlist_add_nvlist(optional, "props", props);
3627ac89354SDon Brady 
3637ac89354SDon Brady 	IOC_INPUT_TEST(ZFS_IOC_SNAPSHOT, pool, required, optional, 0);
3647ac89354SDon Brady 
3657ac89354SDon Brady 	nvlist_free(props);
3667ac89354SDon Brady 	nvlist_free(snaps);
3677ac89354SDon Brady 	nvlist_free(optional);
3687ac89354SDon Brady 	nvlist_free(required);
3697ac89354SDon Brady }
3707ac89354SDon Brady 
3717ac89354SDon Brady static void
test_space_snaps(const char * snapshot)3727ac89354SDon Brady test_space_snaps(const char *snapshot)
3737ac89354SDon Brady {
3747ac89354SDon Brady 	nvlist_t *required = fnvlist_alloc();
3757ac89354SDon Brady 	fnvlist_add_string(required, "firstsnap", snapshot);
3767ac89354SDon Brady 
3777ac89354SDon Brady 	IOC_INPUT_TEST(ZFS_IOC_SPACE_SNAPS, snapshot, required, NULL, 0);
3787ac89354SDon Brady 
3797ac89354SDon Brady 	nvlist_free(required);
3807ac89354SDon Brady }
3817ac89354SDon Brady 
3827ac89354SDon Brady static void
test_destroy_snaps(const char * pool,const char * snapshot)3837ac89354SDon Brady test_destroy_snaps(const char *pool, const char *snapshot)
3847ac89354SDon Brady {
3857ac89354SDon Brady 	nvlist_t *required = fnvlist_alloc();
3867ac89354SDon Brady 	nvlist_t *snaps = fnvlist_alloc();
3877ac89354SDon Brady 
3887ac89354SDon Brady 	fnvlist_add_boolean(snaps, snapshot);
3897ac89354SDon Brady 	fnvlist_add_nvlist(required, "snaps", snaps);
3907ac89354SDon Brady 
3917ac89354SDon Brady 	IOC_INPUT_TEST(ZFS_IOC_DESTROY_SNAPS, pool, required, NULL, 0);
3927ac89354SDon Brady 
3937ac89354SDon Brady 	nvlist_free(snaps);
3947ac89354SDon Brady 	nvlist_free(required);
3957ac89354SDon Brady }
3967ac89354SDon Brady 
3977ac89354SDon Brady 
3987ac89354SDon Brady static void
test_bookmark(const char * pool,const char * snapshot,const char * bookmark)3997ac89354SDon Brady test_bookmark(const char *pool, const char *snapshot, const char *bookmark)
4007ac89354SDon Brady {
4017ac89354SDon Brady 	nvlist_t *required = fnvlist_alloc();
4027ac89354SDon Brady 
4037ac89354SDon Brady 	fnvlist_add_string(required, bookmark, snapshot);
4047ac89354SDon Brady 
4057ac89354SDon Brady 	IOC_INPUT_TEST_WILD(ZFS_IOC_BOOKMARK, pool, required, NULL, 0);
4067ac89354SDon Brady 
4077ac89354SDon Brady 	nvlist_free(required);
4087ac89354SDon Brady }
4097ac89354SDon Brady 
4107ac89354SDon Brady static void
test_get_bookmarks(const char * dataset)4117ac89354SDon Brady test_get_bookmarks(const char *dataset)
4127ac89354SDon Brady {
4137ac89354SDon Brady 	nvlist_t *optional = fnvlist_alloc();
4147ac89354SDon Brady 
4157ac89354SDon Brady 	fnvlist_add_boolean(optional, "guid");
4167ac89354SDon Brady 	fnvlist_add_boolean(optional, "createtxg");
4177ac89354SDon Brady 	fnvlist_add_boolean(optional, "creation");
4187ac89354SDon Brady 
4197ac89354SDon Brady 	IOC_INPUT_TEST_WILD(ZFS_IOC_GET_BOOKMARKS, dataset, NULL, optional, 0);
4207ac89354SDon Brady 
4217ac89354SDon Brady 	nvlist_free(optional);
4227ac89354SDon Brady }
4237ac89354SDon Brady 
4247ac89354SDon Brady static void
test_destroy_bookmarks(const char * pool,const char * bookmark)4257ac89354SDon Brady test_destroy_bookmarks(const char *pool, const char *bookmark)
4267ac89354SDon Brady {
4277ac89354SDon Brady 	nvlist_t *required = fnvlist_alloc();
4287ac89354SDon Brady 
4297ac89354SDon Brady 	fnvlist_add_boolean(required, bookmark);
4307ac89354SDon Brady 
4317ac89354SDon Brady 	IOC_INPUT_TEST_WILD(ZFS_IOC_DESTROY_BOOKMARKS, pool, required, NULL, 0);
4327ac89354SDon Brady 
4337ac89354SDon Brady 	nvlist_free(required);
4347ac89354SDon Brady }
4357ac89354SDon Brady 
4367ac89354SDon Brady static void
test_clone(const char * snapshot,const char * clone)4377ac89354SDon Brady test_clone(const char *snapshot, const char *clone)
4387ac89354SDon Brady {
4397ac89354SDon Brady 	nvlist_t *required = fnvlist_alloc();
4407ac89354SDon Brady 	nvlist_t *optional = fnvlist_alloc();
4417ac89354SDon Brady 	nvlist_t *props = fnvlist_alloc();
4427ac89354SDon Brady 
4437ac89354SDon Brady 	fnvlist_add_string(required, "origin", snapshot);
4447ac89354SDon Brady 
4457ac89354SDon Brady 	IOC_INPUT_TEST(ZFS_IOC_CLONE, clone, required, NULL, 0);
4467ac89354SDon Brady 
4477ac89354SDon Brady 	nvlist_free(props);
4487ac89354SDon Brady 	nvlist_free(optional);
4497ac89354SDon Brady 	nvlist_free(required);
4507ac89354SDon Brady }
4517ac89354SDon Brady 
4527ac89354SDon Brady static void
test_rollback(const char * dataset,const char * snapshot)4537ac89354SDon Brady test_rollback(const char *dataset, const char *snapshot)
4547ac89354SDon Brady {
4557ac89354SDon Brady 	nvlist_t *optional = fnvlist_alloc();
4567ac89354SDon Brady 
4577ac89354SDon Brady 	fnvlist_add_string(optional, "target", snapshot);
4587ac89354SDon Brady 
4597ac89354SDon Brady 	IOC_INPUT_TEST(ZFS_IOC_ROLLBACK, dataset, NULL, optional, B_FALSE);
4607ac89354SDon Brady 
4617ac89354SDon Brady 	nvlist_free(optional);
4627ac89354SDon Brady }
4637ac89354SDon Brady 
4647ac89354SDon Brady static void
test_hold(const char * pool,const char * snapshot)4657ac89354SDon Brady test_hold(const char *pool, const char *snapshot)
4667ac89354SDon Brady {
4677ac89354SDon Brady 	nvlist_t *required = fnvlist_alloc();
4687ac89354SDon Brady 	nvlist_t *optional = fnvlist_alloc();
4697ac89354SDon Brady 	nvlist_t *holds = fnvlist_alloc();
4707ac89354SDon Brady 
4717ac89354SDon Brady 	fnvlist_add_string(holds, snapshot, "libzfs_check_hold");
4727ac89354SDon Brady 	fnvlist_add_nvlist(required, "holds", holds);
4737ac89354SDon Brady 	fnvlist_add_int32(optional, "cleanup_fd", zfs_fd);
4747ac89354SDon Brady 
4757ac89354SDon Brady 	IOC_INPUT_TEST(ZFS_IOC_HOLD, pool, required, optional, 0);
4767ac89354SDon Brady 
4777ac89354SDon Brady 	nvlist_free(holds);
4787ac89354SDon Brady 	nvlist_free(optional);
4797ac89354SDon Brady 	nvlist_free(required);
4807ac89354SDon Brady }
4817ac89354SDon Brady 
4827ac89354SDon Brady static void
test_get_holds(const char * snapshot)4837ac89354SDon Brady test_get_holds(const char *snapshot)
4847ac89354SDon Brady {
4857ac89354SDon Brady 	IOC_INPUT_TEST(ZFS_IOC_GET_HOLDS, snapshot, NULL, NULL, 0);
4867ac89354SDon Brady }
4877ac89354SDon Brady 
4887ac89354SDon Brady static void
test_release(const char * pool,const char * snapshot)4897ac89354SDon Brady test_release(const char *pool, const char *snapshot)
4907ac89354SDon Brady {
4917ac89354SDon Brady 	nvlist_t *required = fnvlist_alloc();
4927ac89354SDon Brady 	nvlist_t *release = fnvlist_alloc();
4937ac89354SDon Brady 
4947ac89354SDon Brady 	fnvlist_add_boolean(release, "libzfs_check_hold");
4957ac89354SDon Brady 	fnvlist_add_nvlist(required, snapshot, release);
4967ac89354SDon Brady 
4977ac89354SDon Brady 	IOC_INPUT_TEST_WILD(ZFS_IOC_RELEASE, pool, required, NULL, 0);
4987ac89354SDon Brady 
4997ac89354SDon Brady 	nvlist_free(release);
500