4 * This file and its contents are supplied under the terms of the
5 * Common Development and Distribution License ("CDDL"), version 1.0.
6 * You may only use this file in accordance with the terms of version
9 * A full copy of the text of the CDDL should have accompanied this
10 * source. A copy of the CDDL is also available via the Internet at
11 * http://www.illumos.org/license/CDDL.
17 * Copyright (c) 2018 by Delphix. All rights reserved.
24 #include <libzfs_core.h>
27 #include <sys/nvpair.h>
28 #include <sys/vdev_impl.h>
29 #include <sys/zfs_ioctl.h>
30 #include <sys/zfs_bootenv.h>
33 * Test the nvpair inputs for the non-legacy zfs ioctl commands.
36 boolean_t unexpected_failures
;
38 const char *active_test
;
41 * Tracks which zfs_ioc_t commands were tested
43 boolean_t ioc_tested
[ZFS_IOC_LAST
- ZFS_IOC_FIRST
];
46 * Legacy ioctls that are skipped (for now)
48 static unsigned ioc_skip
[] = {
55 ZFS_IOC_POOL_TRYIMPORT
,
59 ZFS_IOC_POOL_GET_HISTORY
,
63 ZFS_IOC_VDEV_SET_STATE
,
70 ZFS_IOC_OBJSET_ZPLPROPS
,
71 ZFS_IOC_DATASET_LIST_NEXT
,
72 ZFS_IOC_SNAPSHOT_LIST_NEXT
,
80 ZFS_IOC_INJECT_LIST_NEXT
,
84 ZFS_IOC_DSOBJ_TO_DSNAME
,
86 ZFS_IOC_POOL_SET_PROPS
,
87 ZFS_IOC_POOL_GET_PROPS
,
93 ZFS_IOC_USERSPACE_ONE
,
94 ZFS_IOC_USERSPACE_MANY
,
95 ZFS_IOC_USERSPACE_UPGRADE
,
96 ZFS_IOC_OBJSET_RECVD_PROPS
,
100 ZFS_IOC_TMP_SNAPSHOT
,
101 ZFS_IOC_OBJ_TO_STATS
,
102 ZFS_IOC_SPACE_WRITTEN
,
104 ZFS_IOC_SEND_PROGRESS
,
106 ZFS_IOC_EVENTS_CLEAR
,
114 #define IOC_INPUT_TEST(ioc, name, req, opt, err) \
115 IOC_INPUT_TEST_IMPL(ioc, name, req, opt, err, B_FALSE)
117 #define IOC_INPUT_TEST_WILD(ioc, name, req, opt, err) \
118 IOC_INPUT_TEST_IMPL(ioc, name, req, opt, err, B_TRUE)
120 #define IOC_INPUT_TEST_IMPL(ioc, name, req, opt, err, wild) \
122 active_test = __func__ + 5; \
123 ioc_tested[ioc - ZFS_IOC_FIRST] = B_TRUE; \
124 lzc_ioctl_test(ioc, name, req, opt, err, wild); \
128 * run a zfs ioctl command, verify expected results and log failures
131 lzc_ioctl_run(zfs_ioc_t ioc
, const char *name
, nvlist_t
*innvl
, int expected
)
133 zfs_cmd_t zc
= {"\0"};
140 case ZFS_ERR_IOC_ARG_UNAVAIL
:
141 variant
= "unsupported input";
143 case ZFS_ERR_IOC_ARG_REQUIRED
:
144 variant
= "missing input";
146 case ZFS_ERR_IOC_ARG_BADTYPE
:
147 variant
= "invalid input type";
150 variant
= "valid input";
154 packed
= fnvlist_pack(innvl
, &size
);
155 (void) strlcpy(zc
.zc_name
, name
, sizeof (zc
.zc_name
));
156 zc
.zc_name
[sizeof (zc
.zc_name
) - 1] = '\0';
157 zc
.zc_nvlist_src
= (uint64_t)(uintptr_t)packed
;
158 zc
.zc_nvlist_src_size
= size
;
159 zc
.zc_nvlist_dst_size
= MAX(size
* 2, 128 * 1024);
160 zc
.zc_nvlist_dst
= (uint64_t)(uintptr_t)malloc(zc
.zc_nvlist_dst_size
);
162 if (zfs_ioctl_fd(zfs_fd
, ioc
, &zc
) != 0)
165 if (error
!= expected
) {
166 unexpected_failures
= B_TRUE
;
167 (void) fprintf(stderr
, "%s: Unexpected result with %s, "
168 "error %d (expecting %d)\n",
169 active_test
, variant
, error
, expected
);
172 fnvlist_pack_free(packed
, size
);
173 free((void *)(uintptr_t)zc
.zc_nvlist_dst
);
177 * Test each ioc for the following ioctl input errors:
178 * ZFS_ERR_IOC_ARG_UNAVAIL an input argument is not supported by kernel
179 * ZFS_ERR_IOC_ARG_REQUIRED a required input argument is missing
180 * ZFS_ERR_IOC_ARG_BADTYPE an input argument has an invalid type
183 lzc_ioctl_test(zfs_ioc_t ioc
, const char *name
, nvlist_t
*required
,
184 nvlist_t
*optional
, int expected_error
, boolean_t wildcard
)
186 nvlist_t
*input
= fnvlist_alloc();
187 nvlist_t
*future
= fnvlist_alloc();
190 if (required
!= NULL
) {
191 for (nvpair_t
*pair
= nvlist_next_nvpair(required
, NULL
);
192 pair
!= NULL
; pair
= nvlist_next_nvpair(required
, pair
)) {
193 fnvlist_add_nvpair(input
, pair
);
196 if (optional
!= NULL
) {
197 for (nvpair_t
*pair
= nvlist_next_nvpair(optional
, NULL
);
198 pair
!= NULL
; pair
= nvlist_next_nvpair(optional
, pair
)) {
199 fnvlist_add_nvpair(input
, pair
);
204 * Generic input run with 'optional' nvlist pair
207 fnvlist_add_nvlist(input
, "optional", future
);
208 lzc_ioctl_run(ioc
, name
, input
, expected_error
);
210 fnvlist_remove(input
, "optional");
216 fnvlist_add_string(input
, "bogus_input", "bogus");
217 lzc_ioctl_run(ioc
, name
, input
, ZFS_ERR_IOC_ARG_UNAVAIL
);
218 fnvlist_remove(input
, "bogus_input");
222 * Missing required inputs
224 if (required
!= NULL
) {
225 nvlist_t
*empty
= fnvlist_alloc();
226 lzc_ioctl_run(ioc
, name
, empty
, ZFS_ERR_IOC_ARG_REQUIRED
);
233 if (required
!= NULL
|| optional
!= NULL
) {
235 * switch the type of one of the input pairs
237 for (nvpair_t
*pair
= nvlist_next_nvpair(input
, NULL
);
238 pair
!= NULL
; pair
= nvlist_next_nvpair(input
, pair
)) {
239 char pname
[MAXNAMELEN
];
242 strlcpy(pname
, nvpair_name(pair
), sizeof (pname
));
243 pname
[sizeof (pname
) - 1] = '\0';
244 ptype
= nvpair_type(pair
);
245 fnvlist_remove_nvpair(input
, pair
);
248 case DATA_TYPE_STRING
:
249 fnvlist_add_uint64(input
, pname
, 42);
252 fnvlist_add_string(input
, pname
, "bogus");
256 lzc_ioctl_run(ioc
, name
, input
, ZFS_ERR_IOC_ARG_BADTYPE
);
266 test_pool_sync(const char *pool
)
268 nvlist_t
*required
= fnvlist_alloc();
270 fnvlist_add_boolean_value(required
, "force", B_TRUE
);
272 IOC_INPUT_TEST(ZFS_IOC_POOL_SYNC
, pool
, required
, NULL
, 0);
274 nvlist_free(required
);
278 test_pool_reopen(const char *pool
)
280 nvlist_t
*optional
= fnvlist_alloc();
282 fnvlist_add_boolean_value(optional
, "scrub_restart", B_FALSE
);
284 IOC_INPUT_TEST(ZFS_IOC_POOL_REOPEN
, pool
, NULL
, optional
, 0);
286 nvlist_free(optional
);
290 test_pool_checkpoint(const char *pool
)
292 IOC_INPUT_TEST(ZFS_IOC_POOL_CHECKPOINT
, pool
, NULL
, NULL
, 0);
296 test_pool_discard_checkpoint(const char *pool
)
298 int err
= lzc_pool_checkpoint(pool
);
299 if (err
== 0 || err
== ZFS_ERR_CHECKPOINT_EXISTS
)
300 IOC_INPUT_TEST(ZFS_IOC_POOL_DISCARD_CHECKPOINT
, pool
, NULL
,
305 test_log_history(const char *pool
)
307 nvlist_t
*required
= fnvlist_alloc();
309 fnvlist_add_string(required
, "message", "input check");
311 IOC_INPUT_TEST(ZFS_IOC_LOG_HISTORY
, pool
, required
, NULL
, 0);
313 nvlist_free(required
);
317 test_create(const char *pool
)
319 char dataset
[MAXNAMELEN
+ 32];
321 (void) snprintf(dataset
, sizeof (dataset
), "%s/create-fs", pool
);
323 nvlist_t
*required
= fnvlist_alloc();
324 nvlist_t
*optional
= fnvlist_alloc();
325 nvlist_t
*props
= fnvlist_alloc();
327 fnvlist_add_int32(required
, "type", DMU_OST_ZFS
);
328 fnvlist_add_uint64(props
, "recordsize", 8192);
329 fnvlist_add_nvlist(optional
, "props", props
);
331 IOC_INPUT_TEST(ZFS_IOC_CREATE
, dataset
, required
, optional
, 0);
333 nvlist_free(required
);
334 nvlist_free(optional
);
338 test_snapshot(const char *pool
, const char *snapshot
)
340 nvlist_t
*required
= fnvlist_alloc();
341 nvlist_t
*optional
= fnvlist_alloc();
342 nvlist_t
*snaps
= fnvlist_alloc();
343 nvlist_t
*props
= fnvlist_alloc();
345 fnvlist_add_boolean(snaps
, snapshot
);
346 fnvlist_add_nvlist(required
, "snaps", snaps
);
348 fnvlist_add_string(props
, "org.openzfs:launch", "September 17th, 2013");
349 fnvlist_add_nvlist(optional
, "props", props
);
351 IOC_INPUT_TEST(ZFS_IOC_SNAPSHOT
, pool
, required
, optional
, 0);
355 nvlist_free(optional
);
356 nvlist_free(required
);
360 test_space_snaps(const char *snapshot
)
362 nvlist_t
*required
= fnvlist_alloc();
363 fnvlist_add_string(required
, "firstsnap", snapshot
);
365 IOC_INPUT_TEST(ZFS_IOC_SPACE_SNAPS
, snapshot
, required
, NULL
, 0);
367 nvlist_free(required
);
371 test_destroy_snaps(const char *pool
, const char *snapshot
)
373 nvlist_t
*required
= fnvlist_alloc();
374 nvlist_t
*snaps
= fnvlist_alloc();
376 fnvlist_add_boolean(snaps
, snapshot
);
377 fnvlist_add_nvlist(required
, "snaps", snaps
);
379 IOC_INPUT_TEST(ZFS_IOC_DESTROY_SNAPS
, pool
, required
, NULL
, 0);
382 nvlist_free(required
);
387 test_bookmark(const char *pool
, const char *snapshot
, const char *bookmark
)
389 nvlist_t
*required
= fnvlist_alloc();
391 fnvlist_add_string(required
, bookmark
, snapshot
);
393 IOC_INPUT_TEST_WILD(ZFS_IOC_BOOKMARK
, pool
, required
, NULL
, 0);
395 nvlist_free(required
);
399 test_get_bookmarks(const char *dataset
)
401 nvlist_t
*optional
= fnvlist_alloc();
403 fnvlist_add_boolean(optional
, "guid");
404 fnvlist_add_boolean(optional
, "createtxg");
405 fnvlist_add_boolean(optional
, "creation");
407 IOC_INPUT_TEST_WILD(ZFS_IOC_GET_BOOKMARKS
, dataset
, NULL
, optional
, 0);
409 nvlist_free(optional
);
413 test_destroy_bookmarks(const char *pool
, const char *bookmark
)
415 nvlist_t
*required
= fnvlist_alloc();
417 fnvlist_add_boolean(required
, bookmark
);
419 IOC_INPUT_TEST_WILD(ZFS_IOC_DESTROY_BOOKMARKS
, pool
, required
, NULL
, 0);
421 nvlist_free(required
);
425 test_clone(const char *snapshot
, const char *clone
)
427 nvlist_t
*required
= fnvlist_alloc();
428 nvlist_t
*optional
= fnvlist_alloc();
429 nvlist_t
*props
= fnvlist_alloc();
431 fnvlist_add_string(required
, "origin", snapshot
);
433 IOC_INPUT_TEST(ZFS_IOC_CLONE
, clone
, required
, NULL
, 0);
436 nvlist_free(optional
);
437 nvlist_free(required
);
441 test_rollback(const char *dataset
, const char *snapshot
)
443 nvlist_t
*optional
= fnvlist_alloc();
445 fnvlist_add_string(optional
, "target", snapshot
);
447 IOC_INPUT_TEST(ZFS_IOC_ROLLBACK
, dataset
, NULL
, optional
, B_FALSE
);
449 nvlist_free(optional
);
453 test_hold(const char *pool
, const char *snapshot
)
455 nvlist_t
*required
= fnvlist_alloc();
456 nvlist_t
*optional
= fnvlist_alloc();
457 nvlist_t
*holds
= fnvlist_alloc();
459 fnvlist_add_string(holds
, snapshot
, "libzfs_check_hold");
460 fnvlist_add_nvlist(required
, "holds", holds
);
461 fnvlist_add_int32(optional
, "cleanup_fd", zfs_fd
);
463 IOC_INPUT_TEST(ZFS_IOC_HOLD
, pool
, required
, optional
, 0);
466 nvlist_free(optional
);
467 nvlist_free(required
);
471 test_get_holds(const char *snapshot
)
473 IOC_INPUT_TEST(ZFS_IOC_GET_HOLDS
, snapshot
, NULL
, NULL
, 0);
477 test_release(const char *pool
, const char *snapshot
)
479 nvlist_t
*required
= fnvlist_alloc();
480 nvlist_t
*release
= fnvlist_alloc();
482 fnvlist_add_boolean(release
, "libzfs_check_hold");
483 fnvlist_add_nvlist(required
, snapshot
, release
);
485 IOC_INPUT_TEST_WILD(ZFS_IOC_RELEASE
, pool
, required
, NULL
, 0);
487 nvlist_free(release
);
488 nvlist_free(required
);
493 test_send_new(const char *snapshot
, int fd
)
495 nvlist_t
*required
= fnvlist_alloc();
496 nvlist_t
*optional
= fnvlist_alloc();
498 fnvlist_add_int32(required
, "fd", fd
);
500 fnvlist_add_boolean(optional
, "largeblockok");
501 fnvlist_add_boolean(optional
, "embedok");
502 fnvlist_add_boolean(optional
, "compressok");
503 fnvlist_add_boolean(optional
, "rawok");
506 * TODO - Resumable send is harder to set up. So we currently
507 * ignore testing for that variant.
510 fnvlist_add_string(optional
, "fromsnap", from
);
511 fnvlist_add_uint64(optional
, "resume_object", resumeobj
);
512 fnvlist_add_uint64(optional
, "resume_offset", offset
);
513 fnvlist_add_boolean(optional
, "savedok");
515 IOC_INPUT_TEST(ZFS_IOC_SEND_NEW
, snapshot
, required
, optional
, 0);
517 nvlist_free(optional
);
518 nvlist_free(required
);
522 test_recv_new(const char *dataset
, int fd
)
524 dmu_replay_record_t drr
= { 0 };
525 nvlist_t
*required
= fnvlist_alloc();
526 nvlist_t
*optional
= fnvlist_alloc();
527 nvlist_t
*props
= fnvlist_alloc();
528 char snapshot
[MAXNAMELEN
+ 32];
531 int cleanup_fd
= open(ZFS_DEV
, O_RDWR
);
533 (void) snprintf(snapshot
, sizeof (snapshot
), "%s@replicant", dataset
);
535 count
= pread(fd
, &drr
, sizeof (drr
), 0);
536 if (count
!= sizeof (drr
)) {
537 (void) fprintf(stderr
, "could not read stream: %s\n",
541 fnvlist_add_string(required
, "snapname", snapshot
);
542 fnvlist_add_byte_array(required
, "begin_record", (uchar_t
*)&drr
,
544 fnvlist_add_int32(required
, "input_fd", fd
);
546 fnvlist_add_string(props
, "org.openzfs:launch", "September 17th, 2013");
547 fnvlist_add_nvlist(optional
, "localprops", props
);
548 fnvlist_add_boolean(optional
, "force");
549 fnvlist_add_int32(optional
, "cleanup_fd", cleanup_fd
);
552 * TODO - Resumable receive is harder to set up. So we currently
553 * ignore testing for one.
556 fnvlist_add_nvlist(optional
, "props", recvdprops
);
557 fnvlist_add_string(optional
, "origin", origin
);
558 fnvlist_add_boolean(optional
, "resumable");
559 fnvlist_add_uint64(optional
, "action_handle", *action_handle
);
561 IOC_INPUT_TEST(ZFS_IOC_RECV_NEW
, dataset
, required
, optional
,
562 ZFS_ERR_STREAM_TRUNCATED
);
565 nvlist_free(optional
);
566 nvlist_free(required
);
568 (void) close(cleanup_fd
);
572 test_send_space(const char *snapshot1
, const char *snapshot2
)
574 nvlist_t
*optional
= fnvlist_alloc();
576 fnvlist_add_string(optional
, "from", snapshot1
);
577 fnvlist_add_boolean(optional
, "largeblockok");
578 fnvlist_add_boolean(optional
, "embedok");
579 fnvlist_add_boolean(optional
, "compressok");
580 fnvlist_add_boolean(optional
, "rawok");
582 IOC_INPUT_TEST(ZFS_IOC_SEND_SPACE
, snapshot2
, NULL
, optional
, 0);
584 nvlist_free(optional
);
588 test_remap(const char *dataset
)
590 IOC_INPUT_TEST(ZFS_IOC_REMAP
, dataset
, NULL
, NULL
, 0);
594 test_channel_program(const char *pool
)
596 const char *program
=
598 "argv = arg[\"argv\"]\n"
600 char *const argv
[1] = { "Hello World!" };
601 nvlist_t
*required
= fnvlist_alloc();
602 nvlist_t
*optional
= fnvlist_alloc();
603 nvlist_t
*args
= fnvlist_alloc();
605 fnvlist_add_string(required
, "program", program
);
606 fnvlist_add_string_array(args
, "argv", argv
, 1);
607 fnvlist_add_nvlist(required
, "arg", args
);
609 fnvlist_add_boolean_value(optional
, "sync", B_TRUE
);
610 fnvlist_add_uint64(optional
, "instrlimit", 1000 * 1000);
611 fnvlist_add_uint64(optional
, "memlimit", 8192 * 1024);
613 IOC_INPUT_TEST(ZFS_IOC_CHANNEL_PROGRAM
, pool
, required
, optional
, 0);
616 nvlist_free(optional
);
617 nvlist_free(required
);
620 #define WRAPPING_KEY_LEN 32
623 test_load_key(const char *dataset
)
625 nvlist_t
*required
= fnvlist_alloc();
626 nvlist_t
*optional
= fnvlist_alloc();
627 nvlist_t
*hidden
= fnvlist_alloc();
628 uint8_t keydata
[WRAPPING_KEY_LEN
] = {0};
630 fnvlist_add_uint8_array(hidden
, "wkeydata", keydata
, sizeof (keydata
));
631 fnvlist_add_nvlist(required
, "hidden_args", hidden
);
632 fnvlist_add_boolean(optional
, "noop");
634 IOC_INPUT_TEST(ZFS_IOC_LOAD_KEY
, dataset
, required
, optional
, EINVAL
);
636 nvlist_free(optional
);
637 nvlist_free(required
);
641 test_change_key(const char *dataset
)
643 IOC_INPUT_TEST(ZFS_IOC_CHANGE_KEY
, dataset
, NULL
, NULL
, EINVAL
);
647 test_unload_key(const char *dataset
)
649 IOC_INPUT_TEST(ZFS_IOC_UNLOAD_KEY
, dataset
, NULL
, NULL
, EACCES
);
653 test_vdev_initialize(const char *pool
)
655 nvlist_t
*required
= fnvlist_alloc();
656 nvlist_t
*vdev_guids
= fnvlist_alloc();
658 fnvlist_add_uint64(vdev_guids
, "path", 0xdeadbeefdeadbeef);
659 fnvlist_add_uint64(required
, ZPOOL_INITIALIZE_COMMAND
,
660 POOL_INITIALIZE_START
);
661 fnvlist_add_nvlist(required
, ZPOOL_INITIALIZE_VDEVS
, vdev_guids
);
663 IOC_INPUT_TEST(ZFS_IOC_POOL_INITIALIZE
, pool
, required
, NULL
, EINVAL
);
664 nvlist_free(vdev_guids
);
665 nvlist_free(required
);
669 test_vdev_trim(const char *pool
)
671 nvlist_t
*required
= fnvlist_alloc();
672 nvlist_t
*optional
= fnvlist_alloc();
673 nvlist_t
*vdev_guids
= fnvlist_alloc();
675 fnvlist_add_uint64(vdev_guids
, "path", 0xdeadbeefdeadbeef);
676 fnvlist_add_uint64(required
, ZPOOL_TRIM_COMMAND
, POOL_TRIM_START
);
677 fnvlist_add_nvlist(required
, ZPOOL_TRIM_VDEVS
, vdev_guids
);
678 fnvlist_add_uint64(optional
, ZPOOL_TRIM_RATE
, 1ULL << 30);
679 fnvlist_add_boolean_value(optional
, ZPOOL_TRIM_SECURE
, B_TRUE
);
681 IOC_INPUT_TEST(ZFS_IOC_POOL_TRIM
, pool
, required
, optional
, EINVAL
);
682 nvlist_free(vdev_guids
);
683 nvlist_free(optional
);
684 nvlist_free(required
);
688 zfs_destroy(const char *dataset
)
690 zfs_cmd_t zc
= {"\0"};
693 (void) strlcpy(zc
.zc_name
, dataset
, sizeof (zc
.zc_name
));
694 zc
.zc_name
[sizeof (zc
.zc_name
) - 1] = '\0';
695 err
= zfs_ioctl_fd(zfs_fd
, ZFS_IOC_DESTROY
, &zc
);
697 return (err
== 0 ? 0 : errno
);
701 test_redact(const char *snapshot1
, const char *snapshot2
)
703 nvlist_t
*required
= fnvlist_alloc();
704 nvlist_t
*snapnv
= fnvlist_alloc();
705 char bookmark
[MAXNAMELEN
+ 32];
707 fnvlist_add_string(required
, "bookname", "testbookmark");
708 fnvlist_add_boolean(snapnv
, snapshot2
);
709 fnvlist_add_nvlist(required
, "snapnv", snapnv
);
711 IOC_INPUT_TEST(ZFS_IOC_REDACT
, snapshot1
, required
, NULL
, 0);
714 nvlist_free(required
);
716 strlcpy(bookmark
, snapshot1
, sizeof (bookmark
));
717 *strchr(bookmark
, '@') = '\0';
718 strlcat(bookmark
, "#testbookmark", sizeof (bookmark
) -
720 zfs_destroy(bookmark
);
724 test_get_bookmark_props(const char *bookmark
)
726 IOC_INPUT_TEST(ZFS_IOC_GET_BOOKMARK_PROPS
, bookmark
, NULL
, NULL
, 0);
730 test_wait(const char *pool
)
732 nvlist_t
*required
= fnvlist_alloc();
733 nvlist_t
*optional
= fnvlist_alloc();
735 fnvlist_add_int32(required
, "wait_activity", 2);
736 fnvlist_add_uint64(optional
, "wait_tag", 0xdeadbeefdeadbeef);
738 IOC_INPUT_TEST(ZFS_IOC_WAIT
, pool
, required
, optional
, EINVAL
);
740 nvlist_free(required
);
741 nvlist_free(optional
);
745 test_wait_fs(const char *dataset
)
747 nvlist_t
*required
= fnvlist_alloc();
749 fnvlist_add_int32(required
, "wait_activity", 2);
751 IOC_INPUT_TEST(ZFS_IOC_WAIT_FS
, dataset
, required
, NULL
, EINVAL
);
753 nvlist_free(required
);
757 test_get_bootenv(const char *pool
)
759 IOC_INPUT_TEST(ZFS_IOC_GET_BOOTENV
, pool
, NULL
, NULL
, 0);
763 test_set_bootenv(const char *pool
)
765 nvlist_t
*required
= fnvlist_alloc();
767 fnvlist_add_uint64(required
, "version", VB_RAW
);
768 fnvlist_add_string(required
, GRUB_ENVMAP
, "test");
770 IOC_INPUT_TEST_WILD(ZFS_IOC_SET_BOOTENV
, pool
, required
, NULL
, 0);
772 nvlist_free(required
);
776 zfs_ioc_input_tests(const char *pool
)
778 char filepath
[] = "/tmp/ioc_test_file_XXXXXX";
779 char dataset
[ZFS_MAX_DATASET_NAME_LEN
];
780 char snapbase
[ZFS_MAX_DATASET_NAME_LEN
+ 32];
781 char snapshot
[ZFS_MAX_DATASET_NAME_LEN
+ 32];
782 char bookmark
[ZFS_MAX_DATASET_NAME_LEN
+ 32];
783 char backup
[ZFS_MAX_DATASET_NAME_LEN
];
784 char clone
[ZFS_MAX_DATASET_NAME_LEN
];
785 char clonesnap
[ZFS_MAX_DATASET_NAME_LEN
+ 32];
789 * Setup names and create a working dataset
791 (void) snprintf(dataset
, sizeof (dataset
), "%s/test-fs", pool
);
792 (void) snprintf(snapbase
, sizeof (snapbase
), "%s@snapbase", dataset
);
793 (void) snprintf(snapshot
, sizeof (snapshot
), "%s@snapshot", dataset
);
794 (void) snprintf(bookmark
, sizeof (bookmark
), "%s#bookmark", dataset
);
795 (void) snprintf(clone
, sizeof (clone
), "%s/test-fs-clone", pool
);
796 (void) snprintf(clonesnap
, sizeof (clonesnap
), "%s@snap", clone
);
797 (void) snprintf(backup
, sizeof (backup
), "%s/backup", pool
);
799 err
= lzc_create(dataset
, LZC_DATSET_TYPE_ZFS
, NULL
, NULL
, -1);
801 (void) fprintf(stderr
, "could not create '%s': %s\n",
802 dataset
, strerror(errno
));
806 tmpfd
= mkstemp(filepath
);
808 (void) fprintf(stderr
, "could not create '%s': %s\n",
809 filepath
, strerror(errno
));
814 * run a test for each ioctl
815 * Note that some test build on previous test operations
817 test_pool_sync(pool
);
818 test_pool_reopen(pool
);
819 test_pool_checkpoint(pool
);
820 test_pool_discard_checkpoint(pool
);
821 test_log_history(pool
);
823 test_create(dataset
);
824 test_snapshot(pool
, snapbase
);
825 test_snapshot(pool
, snapshot
);
827 test_space_snaps(snapshot
);
828 test_send_space(snapbase
, snapshot
);
829 test_send_new(snapshot
, tmpfd
);
830 test_recv_new(backup
, tmpfd
);
832 test_bookmark(pool
, snapshot
, bookmark
);
833 test_get_bookmarks(dataset
);
834 test_get_bookmark_props(bookmark
);
835 test_destroy_bookmarks(pool
, bookmark
);
837 test_hold(pool
, snapshot
);
838 test_get_holds(snapshot
);
839 test_release(pool
, snapshot
);
841 test_clone(snapshot
, clone
);
842 test_snapshot(pool
, clonesnap
);
843 test_redact(snapshot
, clonesnap
);
844 zfs_destroy(clonesnap
);
847 test_rollback(dataset
, snapshot
);
848 test_destroy_snaps(pool
, snapshot
);
849 test_destroy_snaps(pool
, snapbase
);
852 test_channel_program(pool
);
854 test_load_key(dataset
);
855 test_change_key(dataset
);
856 test_unload_key(dataset
);
858 test_vdev_initialize(pool
);
859 test_vdev_trim(pool
);
862 test_wait_fs(dataset
);
864 test_set_bootenv(pool
);
865 test_get_bootenv(pool
);
870 zfs_cmd_t zc
= {"\0"};
872 nvlist_t
*snaps
= fnvlist_alloc();
873 fnvlist_add_boolean(snaps
, snapshot
);
874 (void) lzc_destroy_snaps(snaps
, B_FALSE
, NULL
);
877 (void) zfs_destroy(dataset
);
878 (void) zfs_destroy(backup
);
881 (void) unlink(filepath
);
884 * All the unused slots should yield ZFS_ERR_IOC_CMD_UNAVAIL
886 for (int i
= 0; i
< ARRAY_SIZE(ioc_skip
); i
++) {
887 if (ioc_tested
[ioc_skip
[i
] - ZFS_IOC_FIRST
])
888 (void) fprintf(stderr
, "cmd %d tested, not skipped!\n",
889 (int)(ioc_skip
[i
] - ZFS_IOC_FIRST
));
891 ioc_tested
[ioc_skip
[i
] - ZFS_IOC_FIRST
] = B_TRUE
;
894 (void) strlcpy(zc
.zc_name
, pool
, sizeof (zc
.zc_name
));
895 zc
.zc_name
[sizeof (zc
.zc_name
) - 1] = '\0';
897 for (unsigned ioc
= ZFS_IOC_FIRST
; ioc
< ZFS_IOC_LAST
; ioc
++) {
898 unsigned cmd
= ioc
- ZFS_IOC_FIRST
;
903 if (zfs_ioctl_fd(zfs_fd
, ioc
, &zc
) != 0 &&
904 errno
!= ZFS_ERR_IOC_CMD_UNAVAIL
) {
905 (void) fprintf(stderr
, "cmd %d is missing a test case "
906 "(%d)\n", cmd
, errno
);
915 ZFS_IOC_BASE
= ('Z' << 8),
917 ZFS_IOC_PLATFORM_BASE
= ZFS_IOC_BASE
+ 0x80,
921 * Canonical reference check of /dev/zfs ioctl numbers.
922 * These cannot change and new ioctl numbers must be appended.
925 validate_ioc_values(void)
927 boolean_t result
= B_TRUE
;
929 #define CHECK(expr) do { \
932 fprintf(stderr, "(%s) === FALSE\n", #expr); \
936 CHECK(ZFS_IOC_BASE
+ 0 == ZFS_IOC_POOL_CREATE
);
937 CHECK(ZFS_IOC_BASE
+ 1 == ZFS_IOC_POOL_DESTROY
);
938 CHECK(ZFS_IOC_BASE
+ 2 == ZFS_IOC_POOL_IMPORT
);
939 CHECK(ZFS_IOC_BASE
+ 3 == ZFS_IOC_POOL_EXPORT
);
940 CHECK(ZFS_IOC_BASE
+ 4 == ZFS_IOC_POOL_CONFIGS
);
941 CHECK(ZFS_IOC_BASE
+ 5 == ZFS_IOC_POOL_STATS
);
942 CHECK(ZFS_IOC_BASE
+ 6 == ZFS_IOC_POOL_TRYIMPORT
);
943 CHECK(ZFS_IOC_BASE
+ 7 == ZFS_IOC_POOL_SCAN
);
944 CHECK(ZFS_IOC_BASE
+ 8 == ZFS_IOC_POOL_FREEZE
);
945 CHECK(ZFS_IOC_BASE
+ 9 == ZFS_IOC_POOL_UPGRADE
);
946 CHECK(ZFS_IOC_BASE
+ 10 == ZFS_IOC_POOL_GET_HISTORY
);
947 CHECK(ZFS_IOC_BASE
+ 11 == ZFS_IOC_VDEV_ADD
);
948 CHECK(ZFS_IOC_BASE
+ 12 == ZFS_IOC_VDEV_REMOVE
);
949 CHECK(ZFS_IOC_BASE
+ 13 == ZFS_IOC_VDEV_SET_STATE
);
950 CHECK(ZFS_IOC_BASE
+ 14 == ZFS_IOC_VDEV_ATTACH
);
951 CHECK(ZFS_IOC_BASE
+ 15 == ZFS_IOC_VDEV_DETACH
);
952 CHECK(ZFS_IOC_BASE
+ 16 == ZFS_IOC_VDEV_SETPATH
);
953 CHECK(ZFS_IOC_BASE
+ 17 == ZFS_IOC_VDEV_SETFRU
);
954 CHECK(ZFS_IOC_BASE
+ 18 == ZFS_IOC_OBJSET_STATS
);
955 CHECK(ZFS_IOC_BASE
+ 19 == ZFS_IOC_OBJSET_ZPLPROPS
);
956 CHECK(ZFS_IOC_BASE
+ 20 == ZFS_IOC_DATASET_LIST_NEXT
);
957 CHECK(ZFS_IOC_BASE
+ 21 == ZFS_IOC_SNAPSHOT_LIST_NEXT
);
958 CHECK(ZFS_IOC_BASE
+ 22 == ZFS_IOC_SET_PROP
);
959 CHECK(ZFS_IOC_BASE
+ 23 == ZFS_IOC_CREATE
);
960 CHECK(ZFS_IOC_BASE
+ 24 == ZFS_IOC_DESTROY
);
961 CHECK(ZFS_IOC_BASE
+ 25 == ZFS_IOC_ROLLBACK
);
962 CHECK(ZFS_IOC_BASE
+ 26 == ZFS_IOC_RENAME
);
963 CHECK(ZFS_IOC_BASE
+ 27 == ZFS_IOC_RECV
);
964 CHECK(ZFS_IOC_BASE
+ 28 == ZFS_IOC_SEND
);
965 CHECK(ZFS_IOC_BASE
+ 29 == ZFS_IOC_INJECT_FAULT
);
966 CHECK(ZFS_IOC_BASE
+ 30 == ZFS_IOC_CLEAR_FAULT
);
967 CHECK(ZFS_IOC_BASE
+ 31 == ZFS_IOC_INJECT_LIST_NEXT
);
968 CHECK(ZFS_IOC_BASE
+ 32 == ZFS_IOC_ERROR_LOG
);
969 CHECK(ZFS_IOC_BASE
+ 33 == ZFS_IOC_CLEAR
);
970 CHECK(ZFS_IOC_BASE
+ 34 == ZFS_IOC_PROMOTE
);
971 CHECK(ZFS_IOC_BASE
+ 35 == ZFS_IOC_SNAPSHOT
);
972 CHECK(ZFS_IOC_BASE
+ 36 == ZFS_IOC_DSOBJ_TO_DSNAME
);
973 CHECK(ZFS_IOC_BASE
+ 37 == ZFS_IOC_OBJ_TO_PATH
);
974 CHECK(ZFS_IOC_BASE
+ 38 == ZFS_IOC_POOL_SET_PROPS
);
975 CHECK(ZFS_IOC_BASE
+ 39 == ZFS_IOC_POOL_GET_PROPS
);
976 CHECK(ZFS_IOC_BASE
+ 40 == ZFS_IOC_SET_FSACL
);
977 CHECK(ZFS_IOC_BASE
+ 41 == ZFS_IOC_GET_FSACL
);
978 CHECK(ZFS_IOC_BASE
+ 42 == ZFS_IOC_SHARE
);
979 CHECK(ZFS_IOC_BASE
+ 43 == ZFS_IOC_INHERIT_PROP
);
980 CHECK(ZFS_IOC_BASE
+ 44 == ZFS_IOC_SMB_ACL
);
981 CHECK(ZFS_IOC_BASE
+ 45 == ZFS_IOC_USERSPACE_ONE
);
982 CHECK(ZFS_IOC_BASE
+ 46 == ZFS_IOC_USERSPACE_MANY
);
983 CHECK(ZFS_IOC_BASE
+ 47 == ZFS_IOC_USERSPACE_UPGRADE
);
984 CHECK(ZFS_IOC_BASE
+ 48 == ZFS_IOC_HOLD
);
985 CHECK(ZFS_IOC_BASE
+ 49 == ZFS_IOC_RELEASE
);
986 CHECK(ZFS_IOC_BASE
+ 50 == ZFS_IOC_GET_HOLDS
);
987 CHECK(ZFS_IOC_BASE
+ 51 == ZFS_IOC_OBJSET_RECVD_PROPS
);
988 CHECK(ZFS_IOC_BASE
+ 52 == ZFS_IOC_VDEV_SPLIT
);
989 CHECK(ZFS_IOC_BASE
+ 53 == ZFS_IOC_NEXT_OBJ
);
990 CHECK(ZFS_IOC_BASE
+ 54 == ZFS_IOC_DIFF
);
991 CHECK(ZFS_IOC_BASE
+ 55 == ZFS_IOC_TMP_SNAPSHOT
);
992 CHECK(ZFS_IOC_BASE
+ 56 == ZFS_IOC_OBJ_TO_STATS
);
993 CHECK(ZFS_IOC_BASE
+ 57 == ZFS_IOC_SPACE_WRITTEN
);
994 CHECK(ZFS_IOC_BASE
+ 58 == ZFS_IOC_SPACE_SNAPS
);
995 CHECK(ZFS_IOC_BASE
+ 59 == ZFS_IOC_DESTROY_SNAPS
);
996 CHECK(ZFS_IOC_BASE
+ 60 == ZFS_IOC_POOL_REGUID
);
997 CHECK(ZFS_IOC_BASE
+ 61 == ZFS_IOC_POOL_REOPEN
);
998 CHECK(ZFS_IOC_BASE
+ 62 == ZFS_IOC_SEND_PROGRESS
);
999 CHECK(ZFS_IOC_BASE
+ 63 == ZFS_IOC_LOG_HISTORY
);
1000 CHECK(ZFS_IOC_BASE
+ 64 == ZFS_IOC_SEND_NEW
);
1001 CHECK(ZFS_IOC_BASE
+ 65 == ZFS_IOC_SEND_SPACE
);
1002 CHECK(ZFS_IOC_BASE
+ 66 == ZFS_IOC_CLONE
);
1003 CHECK(ZFS_IOC_BASE
+ 67 == ZFS_IOC_BOOKMARK
);
1004 CHECK(ZFS_IOC_BASE
+ 68 == ZFS_IOC_GET_BOOKMARKS
);
1005 CHECK(ZFS_IOC_BASE
+ 69 == ZFS_IOC_DESTROY_BOOKMARKS
);
1006 CHECK(ZFS_IOC_BASE
+ 70 == ZFS_IOC_RECV_NEW
);
1007 CHECK(ZFS_IOC_BASE
+ 71 == ZFS_IOC_POOL_SYNC
);
1008 CHECK(ZFS_IOC_BASE
+ 72 == ZFS_IOC_CHANNEL_PROGRAM
);
1009 CHECK(ZFS_IOC_BASE
+ 73 == ZFS_IOC_LOAD_KEY
);
1010 CHECK(ZFS_IOC_BASE
+ 74 == ZFS_IOC_UNLOAD_KEY
);
1011 CHECK(ZFS_IOC_BASE
+ 75 == ZFS_IOC_CHANGE_KEY
);
1012 CHECK(ZFS_IOC_BASE
+ 76 == ZFS_IOC_REMAP
);
1013 CHECK(ZFS_IOC_BASE
+ 77 == ZFS_IOC_POOL_CHECKPOINT
);
1014 CHECK(ZFS_IOC_BASE
+ 78 == ZFS_IOC_POOL_DISCARD_CHECKPOINT
);
1015 CHECK(ZFS_IOC_BASE
+ 79 == ZFS_IOC_POOL_INITIALIZE
);
1016 CHECK(ZFS_IOC_BASE
+ 80 == ZFS_IOC_POOL_TRIM
);
1017 CHECK(ZFS_IOC_BASE
+ 81 == ZFS_IOC_REDACT
);
1018 CHECK(ZFS_IOC_BASE
+ 82 == ZFS_IOC_GET_BOOKMARK_PROPS
);
1019 CHECK(ZFS_IOC_BASE
+ 83 == ZFS_IOC_WAIT
);
1020 CHECK(ZFS_IOC_BASE
+ 84 == ZFS_IOC_WAIT_FS
);
1021 CHECK(ZFS_IOC_PLATFORM_BASE
+ 1 == ZFS_IOC_EVENTS_NEXT
);
1022 CHECK(ZFS_IOC_PLATFORM_BASE
+ 2 == ZFS_IOC_EVENTS_CLEAR
);
1023 CHECK(ZFS_IOC_PLATFORM_BASE
+ 3 == ZFS_IOC_EVENTS_SEEK
);
1024 CHECK(ZFS_IOC_PLATFORM_BASE
+ 4 == ZFS_IOC_NEXTBOOT
);
1025 CHECK(ZFS_IOC_PLATFORM_BASE
+ 5 == ZFS_IOC_JAIL
);
1026 CHECK(ZFS_IOC_PLATFORM_BASE
+ 6 == ZFS_IOC_UNJAIL
);
1027 CHECK(ZFS_IOC_PLATFORM_BASE
+ 7 == ZFS_IOC_SET_BOOTENV
);
1028 CHECK(ZFS_IOC_PLATFORM_BASE
+ 8 == ZFS_IOC_GET_BOOTENV
);
1036 main(int argc
, const char *argv
[])
1039 (void) fprintf(stderr
, "usage: %s <pool>\n", argv
[0]);
1043 if (!validate_ioc_values()) {
1044 (void) fprintf(stderr
, "WARNING: zfs_ioc_t has binary "
1045 "incompatible command values\n");
1049 (void) libzfs_core_init();
1050 zfs_fd
= open(ZFS_DEV
, O_RDWR
);
1052 (void) fprintf(stderr
, "open: %s\n", strerror(errno
));
1057 zfs_ioc_input_tests(argv
[1]);
1059 (void) close(zfs_fd
);
1062 return (unexpected_failures
);