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>
26 #include <sys/nvpair.h>
27 #include <sys/zfs_ioctl.h>
30 * Test the nvpair inputs for the non-legacy zfs ioctl commands.
33 boolean_t unexpected_failures
;
35 const char *active_test
;
38 * Tracks which zfs_ioc_t commands were tested
40 boolean_t ioc_tested
[256];
43 * Legacy ioctls that are skipped (for now)
45 static unsigned ioc_skip
[] = {
52 ZFS_IOC_POOL_TRYIMPORT
,
56 ZFS_IOC_POOL_GET_HISTORY
,
60 ZFS_IOC_VDEV_SET_STATE
,
67 ZFS_IOC_OBJSET_ZPLPROPS
,
68 ZFS_IOC_DATASET_LIST_NEXT
,
69 ZFS_IOC_SNAPSHOT_LIST_NEXT
,
77 ZFS_IOC_INJECT_LIST_NEXT
,
81 ZFS_IOC_DSOBJ_TO_DSNAME
,
83 ZFS_IOC_POOL_SET_PROPS
,
84 ZFS_IOC_POOL_GET_PROPS
,
90 ZFS_IOC_USERSPACE_ONE
,
91 ZFS_IOC_USERSPACE_MANY
,
92 ZFS_IOC_USERSPACE_UPGRADE
,
93 ZFS_IOC_OBJSET_RECVD_PROPS
,
99 ZFS_IOC_SPACE_WRITTEN
,
101 ZFS_IOC_SEND_PROGRESS
,
104 ZFS_IOC_EVENTS_CLEAR
,
109 #define IOC_INPUT_TEST(ioc, name, req, opt, err) \
110 IOC_INPUT_TEST_IMPL(ioc, name, req, opt, err, B_FALSE)
112 #define IOC_INPUT_TEST_WILD(ioc, name, req, opt, err) \
113 IOC_INPUT_TEST_IMPL(ioc, name, req, opt, err, B_TRUE)
115 #define IOC_INPUT_TEST_IMPL(ioc, name, req, opt, err, wild) \
117 active_test = __func__ + 5; \
118 ioc_tested[ioc - ZFS_IOC_FIRST] = B_TRUE; \
119 lzc_ioctl_test(ioc, name, req, opt, err, wild); \
123 * run a zfs ioctl command, verify expected results and log failures
126 lzc_ioctl_run(zfs_ioc_t ioc
, const char *name
, nvlist_t
*innvl
, int expected
)
128 zfs_cmd_t zc
= {"\0"};
135 case ZFS_ERR_IOC_ARG_UNAVAIL
:
136 variant
= "unsupported input";
138 case ZFS_ERR_IOC_ARG_REQUIRED
:
139 variant
= "missing input";
141 case ZFS_ERR_IOC_ARG_BADTYPE
:
142 variant
= "invalid input type";
145 variant
= "valid input";
149 packed
= fnvlist_pack(innvl
, &size
);
150 (void) strlcpy(zc
.zc_name
, name
, sizeof (zc
.zc_name
));
151 zc
.zc_name
[sizeof (zc
.zc_name
) - 1] = '\0';
152 zc
.zc_nvlist_src
= (uint64_t)(uintptr_t)packed
;
153 zc
.zc_nvlist_src_size
= size
;
154 zc
.zc_nvlist_dst_size
= MAX(size
* 2, 128 * 1024);
155 zc
.zc_nvlist_dst
= (uint64_t)(uintptr_t)malloc(zc
.zc_nvlist_dst_size
);
157 if (ioctl(zfs_fd
, ioc
, &zc
) != 0)
160 if (error
!= expected
) {
161 unexpected_failures
= B_TRUE
;
162 (void) fprintf(stderr
, "%s: Unexpected result with %s, "
163 "error %d (expecting %d)\n",
164 active_test
, variant
, error
, expected
);
167 fnvlist_pack_free(packed
, size
);
168 free((void *)(uintptr_t)zc
.zc_nvlist_dst
);
172 * Test each ioc for the folowing ioctl input errors:
173 * ZFS_ERR_IOC_ARG_UNAVAIL an input argument is not supported by kernel
174 * ZFS_ERR_IOC_ARG_REQUIRED a required input argument is missing
175 * ZFS_ERR_IOC_ARG_BADTYPE an input argument has an invalid type
178 lzc_ioctl_test(zfs_ioc_t ioc
, const char *name
, nvlist_t
*required
,
179 nvlist_t
*optional
, int expected_error
, boolean_t wildcard
)
181 nvlist_t
*input
= fnvlist_alloc();
182 nvlist_t
*future
= fnvlist_alloc();
185 if (required
!= NULL
) {
186 for (nvpair_t
*pair
= nvlist_next_nvpair(required
, NULL
);
187 pair
!= NULL
; pair
= nvlist_next_nvpair(required
, pair
)) {
188 fnvlist_add_nvpair(input
, pair
);
191 if (optional
!= NULL
) {
192 for (nvpair_t
*pair
= nvlist_next_nvpair(optional
, NULL
);
193 pair
!= NULL
; pair
= nvlist_next_nvpair(optional
, pair
)) {
194 fnvlist_add_nvpair(input
, pair
);
199 * Generic input run with 'optional' nvlist pair
202 fnvlist_add_nvlist(input
, "optional", future
);
203 lzc_ioctl_run(ioc
, name
, input
, expected_error
);
205 fnvlist_remove(input
, "optional");
211 fnvlist_add_string(input
, "bogus_input", "bogus");
212 lzc_ioctl_run(ioc
, name
, input
, ZFS_ERR_IOC_ARG_UNAVAIL
);
213 fnvlist_remove(input
, "bogus_input");
217 * Missing required inputs
219 if (required
!= NULL
) {
220 nvlist_t
*empty
= fnvlist_alloc();
221 lzc_ioctl_run(ioc
, name
, empty
, ZFS_ERR_IOC_ARG_REQUIRED
);
228 if (required
!= NULL
|| optional
!= NULL
) {
230 * switch the type of one of the input pairs
232 for (nvpair_t
*pair
= nvlist_next_nvpair(input
, NULL
);
233 pair
!= NULL
; pair
= nvlist_next_nvpair(input
, pair
)) {
234 char pname
[MAXNAMELEN
];
237 strlcpy(pname
, nvpair_name(pair
), sizeof (pname
));
238 pname
[sizeof (pname
) - 1] = '\0';
239 ptype
= nvpair_type(pair
);
240 fnvlist_remove_nvpair(input
, pair
);
243 case DATA_TYPE_STRING
:
244 fnvlist_add_uint64(input
, pname
, 42);
247 fnvlist_add_string(input
, pname
, "bogus");
251 lzc_ioctl_run(ioc
, name
, input
, ZFS_ERR_IOC_ARG_BADTYPE
);
261 test_pool_sync(const char *pool
)
263 nvlist_t
*required
= fnvlist_alloc();
265 fnvlist_add_boolean_value(required
, "force", B_TRUE
);
267 IOC_INPUT_TEST(ZFS_IOC_POOL_SYNC
, pool
, required
, NULL
, 0);
269 nvlist_free(required
);
273 test_pool_reopen(const char *pool
)
275 nvlist_t
*required
= fnvlist_alloc();
277 fnvlist_add_boolean_value(required
, "scrub_restart", B_FALSE
);
279 IOC_INPUT_TEST(ZFS_IOC_POOL_REOPEN
, pool
, required
, NULL
, 0);
281 nvlist_free(required
);
285 test_pool_checkpoint(const char *pool
)
287 IOC_INPUT_TEST(ZFS_IOC_POOL_CHECKPOINT
, pool
, NULL
, NULL
, 0);
291 test_pool_discard_checkpoint(const char *pool
)
293 int err
= lzc_pool_checkpoint(pool
);
294 if (err
== 0 || err
== ZFS_ERR_CHECKPOINT_EXISTS
)
295 IOC_INPUT_TEST(ZFS_IOC_POOL_DISCARD_CHECKPOINT
, pool
, NULL
,
300 test_log_history(const char *pool
)
302 nvlist_t
*required
= fnvlist_alloc();
304 fnvlist_add_string(required
, "message", "input check");
306 IOC_INPUT_TEST(ZFS_IOC_LOG_HISTORY
, pool
, required
, NULL
, 0);
308 nvlist_free(required
);
312 test_create(const char *pool
)
314 char dataset
[MAXNAMELEN
+ 32];
316 (void) snprintf(dataset
, sizeof (dataset
), "%s/create-fs", pool
);
318 nvlist_t
*required
= fnvlist_alloc();
319 nvlist_t
*optional
= fnvlist_alloc();
320 nvlist_t
*props
= fnvlist_alloc();
322 fnvlist_add_int32(required
, "type", DMU_OST_ZFS
);
323 fnvlist_add_uint64(props
, "recordsize", 8192);
324 fnvlist_add_nvlist(optional
, "props", props
);
326 IOC_INPUT_TEST(ZFS_IOC_CREATE
, dataset
, required
, optional
, 0);
328 nvlist_free(required
);
329 nvlist_free(optional
);
333 test_snapshot(const char *pool
, const char *snapshot
)
335 nvlist_t
*required
= fnvlist_alloc();
336 nvlist_t
*optional
= fnvlist_alloc();
337 nvlist_t
*snaps
= fnvlist_alloc();
338 nvlist_t
*props
= fnvlist_alloc();
340 fnvlist_add_boolean(snaps
, snapshot
);
341 fnvlist_add_nvlist(required
, "snaps", snaps
);
343 fnvlist_add_string(props
, "org.openzfs:launch", "September 17th, 2013");
344 fnvlist_add_nvlist(optional
, "props", props
);
346 IOC_INPUT_TEST(ZFS_IOC_SNAPSHOT
, pool
, required
, optional
, 0);
350 nvlist_free(optional
);
351 nvlist_free(required
);
355 test_space_snaps(const char *snapshot
)
357 nvlist_t
*required
= fnvlist_alloc();
358 fnvlist_add_string(required
, "firstsnap", snapshot
);
360 IOC_INPUT_TEST(ZFS_IOC_SPACE_SNAPS
, snapshot
, required
, NULL
, 0);
362 nvlist_free(required
);
366 test_destroy_snaps(const char *pool
, const char *snapshot
)
368 nvlist_t
*required
= fnvlist_alloc();
369 nvlist_t
*snaps
= fnvlist_alloc();
371 fnvlist_add_boolean(snaps
, snapshot
);
372 fnvlist_add_nvlist(required
, "snaps", snaps
);
374 IOC_INPUT_TEST(ZFS_IOC_DESTROY_SNAPS
, pool
, required
, NULL
, 0);
377 nvlist_free(required
);
382 test_bookmark(const char *pool
, const char *snapshot
, const char *bookmark
)
384 nvlist_t
*required
= fnvlist_alloc();
386 fnvlist_add_string(required
, bookmark
, snapshot
);
388 IOC_INPUT_TEST_WILD(ZFS_IOC_BOOKMARK
, pool
, required
, NULL
, 0);
390 nvlist_free(required
);
394 test_get_bookmarks(const char *dataset
)
396 nvlist_t
*optional
= fnvlist_alloc();
398 fnvlist_add_boolean(optional
, "guid");
399 fnvlist_add_boolean(optional
, "createtxg");
400 fnvlist_add_boolean(optional
, "creation");
402 IOC_INPUT_TEST_WILD(ZFS_IOC_GET_BOOKMARKS
, dataset
, NULL
, optional
, 0);
404 nvlist_free(optional
);
408 test_destroy_bookmarks(const char *pool
, const char *bookmark
)
410 nvlist_t
*required
= fnvlist_alloc();
412 fnvlist_add_boolean(required
, bookmark
);
414 IOC_INPUT_TEST_WILD(ZFS_IOC_DESTROY_BOOKMARKS
, pool
, required
, NULL
, 0);
416 nvlist_free(required
);
420 test_clone(const char *snapshot
, const char *clone
)
422 nvlist_t
*required
= fnvlist_alloc();
423 nvlist_t
*optional
= fnvlist_alloc();
424 nvlist_t
*props
= fnvlist_alloc();
426 fnvlist_add_string(required
, "origin", snapshot
);
428 IOC_INPUT_TEST(ZFS_IOC_CLONE
, clone
, required
, NULL
, 0);
431 nvlist_free(optional
);
432 nvlist_free(required
);
436 test_rollback(const char *dataset
, const char *snapshot
)
438 nvlist_t
*optional
= fnvlist_alloc();
440 fnvlist_add_string(optional
, "target", snapshot
);
442 IOC_INPUT_TEST(ZFS_IOC_ROLLBACK
, dataset
, NULL
, optional
, B_FALSE
);
444 nvlist_free(optional
);
448 test_hold(const char *pool
, const char *snapshot
)
450 nvlist_t
*required
= fnvlist_alloc();
451 nvlist_t
*optional
= fnvlist_alloc();
452 nvlist_t
*holds
= fnvlist_alloc();
454 fnvlist_add_string(holds
, snapshot
, "libzfs_check_hold");
455 fnvlist_add_nvlist(required
, "holds", holds
);
456 fnvlist_add_int32(optional
, "cleanup_fd", zfs_fd
);
458 IOC_INPUT_TEST(ZFS_IOC_HOLD
, pool
, required
, optional
, 0);
461 nvlist_free(optional
);
462 nvlist_free(required
);
466 test_get_holds(const char *snapshot
)
468 IOC_INPUT_TEST(ZFS_IOC_GET_HOLDS
, snapshot
, NULL
, NULL
, 0);
472 test_release(const char *pool
, const char *snapshot
)
474 nvlist_t
*required
= fnvlist_alloc();
475 nvlist_t
*release
= fnvlist_alloc();
477 fnvlist_add_boolean(release
, "libzfs_check_hold");
478 fnvlist_add_nvlist(required
, snapshot
, release
);
480 IOC_INPUT_TEST_WILD(ZFS_IOC_RELEASE
, pool
, required
, NULL
, 0);
482 nvlist_free(release
);
483 nvlist_free(required
);
488 test_send_new(const char *snapshot
, int fd
)
490 nvlist_t
*required
= fnvlist_alloc();
491 nvlist_t
*optional
= fnvlist_alloc();
493 fnvlist_add_int32(required
, "fd", fd
);
495 fnvlist_add_boolean(optional
, "largeblockok");
496 fnvlist_add_boolean(optional
, "embedok");
497 fnvlist_add_boolean(optional
, "compressok");
498 fnvlist_add_boolean(optional
, "rawok");
501 * TODO - Resumable send is harder to set up. So we currently
502 * ignore testing for that variant.
505 fnvlist_add_string(optional
, "fromsnap", from
);
506 fnvlist_add_uint64(optional
, "resume_object", resumeobj
);
507 fnvlist_add_uint64(optional
, "resume_offset", offset
);
509 IOC_INPUT_TEST(ZFS_IOC_SEND_NEW
, snapshot
, required
, optional
, 0);
511 nvlist_free(optional
);
512 nvlist_free(required
);
516 test_recv_new(const char *dataset
, int fd
)
518 dmu_replay_record_t drr
= { 0 };
519 nvlist_t
*required
= fnvlist_alloc();
520 nvlist_t
*optional
= fnvlist_alloc();
521 nvlist_t
*props
= fnvlist_alloc();
522 char snapshot
[MAXNAMELEN
+ 32];
525 int cleanup_fd
= open(ZFS_DEV
, O_RDWR
);
527 (void) snprintf(snapshot
, sizeof (snapshot
), "%s@replicant", dataset
);
529 count
= pread(fd
, &drr
, sizeof (drr
), 0);
530 if (count
!= sizeof (drr
)) {
531 (void) fprintf(stderr
, "could not read stream: %s\n",
535 fnvlist_add_string(required
, "snapname", snapshot
);
536 fnvlist_add_byte_array(required
, "begin_record", (uchar_t
*)&drr
,
538 fnvlist_add_int32(required
, "input_fd", fd
);
540 fnvlist_add_string(props
, "org.openzfs:launch", "September 17th, 2013");
541 fnvlist_add_nvlist(optional
, "localprops", props
);
542 fnvlist_add_boolean(optional
, "force");
543 fnvlist_add_int32(optional
, "cleanup_fd", cleanup_fd
);
546 * TODO - Resumable receive is harder to set up. So we currently
547 * ignore testing for one.
550 fnvlist_add_nvlist(optional
, "props", recvdprops
);
551 fnvlist_add_string(optional
, "origin", origin
);
552 fnvlist_add_boolean(optional
, "resumable");
553 fnvlist_add_uint64(optional
, "action_handle", *action_handle
);
555 IOC_INPUT_TEST(ZFS_IOC_RECV_NEW
, dataset
, required
, optional
, EBADE
);
558 nvlist_free(optional
);
559 nvlist_free(required
);
561 (void) close(cleanup_fd
);
565 test_send_space(const char *snapshot1
, const char *snapshot2
)
567 nvlist_t
*optional
= fnvlist_alloc();
569 fnvlist_add_string(optional
, "from", snapshot1
);
570 fnvlist_add_boolean(optional
, "largeblockok");
571 fnvlist_add_boolean(optional
, "embedok");
572 fnvlist_add_boolean(optional
, "compressok");
573 fnvlist_add_boolean(optional
, "rawok");
575 IOC_INPUT_TEST(ZFS_IOC_SEND_SPACE
, snapshot2
, NULL
, optional
, 0);
577 nvlist_free(optional
);
581 test_remap(const char *dataset
)
583 IOC_INPUT_TEST(ZFS_IOC_REMAP
, dataset
, NULL
, NULL
, 0);
587 test_channel_program(const char *pool
)
589 const char *program
=
591 "argv = arg[\"argv\"]\n"
593 char *const argv
[1] = { "Hello World!" };
594 nvlist_t
*required
= fnvlist_alloc();
595 nvlist_t
*optional
= fnvlist_alloc();
596 nvlist_t
*args
= fnvlist_alloc();
598 fnvlist_add_string(required
, "program", program
);
599 fnvlist_add_string_array(args
, "argv", argv
, 1);
600 fnvlist_add_nvlist(required
, "arg", args
);
602 fnvlist_add_boolean_value(optional
, "sync", B_TRUE
);
603 fnvlist_add_uint64(optional
, "instrlimit", 1000 * 1000);
604 fnvlist_add_uint64(optional
, "memlimit", 8192 * 1024);
606 IOC_INPUT_TEST(ZFS_IOC_CHANNEL_PROGRAM
, pool
, required
, optional
, 0);
609 nvlist_free(optional
);
610 nvlist_free(required
);
613 #define WRAPPING_KEY_LEN 32
616 test_load_key(const char *dataset
)
618 nvlist_t
*required
= fnvlist_alloc();
619 nvlist_t
*optional
= fnvlist_alloc();
620 nvlist_t
*hidden
= fnvlist_alloc();
621 uint8_t keydata
[WRAPPING_KEY_LEN
] = {0};
623 fnvlist_add_uint8_array(hidden
, "wkeydata", keydata
, sizeof (keydata
));
624 fnvlist_add_nvlist(required
, "hidden_args", hidden
);
625 fnvlist_add_boolean(optional
, "noop");
627 IOC_INPUT_TEST(ZFS_IOC_LOAD_KEY
, dataset
, required
, optional
, EINVAL
);
629 nvlist_free(optional
);
630 nvlist_free(required
);
634 test_change_key(const char *dataset
)
636 IOC_INPUT_TEST(ZFS_IOC_CHANGE_KEY
, dataset
, NULL
, NULL
, EINVAL
);
640 test_unload_key(const char *dataset
)
642 IOC_INPUT_TEST(ZFS_IOC_UNLOAD_KEY
, dataset
, NULL
, NULL
, EACCES
);
646 test_vdev_initialize(const char *pool
)
648 nvlist_t
*required
= fnvlist_alloc();
649 nvlist_t
*vdev_guids
= fnvlist_alloc();
651 fnvlist_add_uint64(vdev_guids
, "path", 0xdeadbeefdeadbeef);
652 fnvlist_add_uint64(required
, ZPOOL_INITIALIZE_COMMAND
,
654 fnvlist_add_nvlist(required
, ZPOOL_INITIALIZE_VDEVS
, vdev_guids
);
656 IOC_INPUT_TEST(ZFS_IOC_POOL_INITIALIZE
, pool
, required
, NULL
, EINVAL
);
657 nvlist_free(vdev_guids
);
658 nvlist_free(required
);
662 zfs_destroy(const char *dataset
)
664 zfs_cmd_t zc
= {"\0"};
667 (void) strlcpy(zc
.zc_name
, dataset
, sizeof (zc
.zc_name
));
668 zc
.zc_name
[sizeof (zc
.zc_name
) - 1] = '\0';
669 err
= ioctl(zfs_fd
, ZFS_IOC_DESTROY
, &zc
);
671 return (err
== 0 ? 0 : errno
);
675 zfs_ioc_input_tests(const char *pool
)
677 char filepath
[] = "/tmp/ioc_test_file_XXXXXX";
678 char dataset
[ZFS_MAX_DATASET_NAME_LEN
];
679 char snapbase
[ZFS_MAX_DATASET_NAME_LEN
+ 32];
680 char snapshot
[ZFS_MAX_DATASET_NAME_LEN
+ 32];
681 char bookmark
[ZFS_MAX_DATASET_NAME_LEN
+ 32];
682 char backup
[ZFS_MAX_DATASET_NAME_LEN
];
683 char clone
[ZFS_MAX_DATASET_NAME_LEN
];
687 * Setup names and create a working dataset
689 (void) snprintf(dataset
, sizeof (dataset
), "%s/test-fs", pool
);
690 (void) snprintf(snapbase
, sizeof (snapbase
), "%s@snapbase", dataset
);
691 (void) snprintf(snapshot
, sizeof (snapshot
), "%s@snapshot", dataset
);
692 (void) snprintf(bookmark
, sizeof (bookmark
), "%s#bookmark", dataset
);
693 (void) snprintf(clone
, sizeof (clone
), "%s/test-fs-clone", pool
);
694 (void) snprintf(backup
, sizeof (backup
), "%s/backup", pool
);
696 err
= lzc_create(dataset
, DMU_OST_ZFS
, NULL
, NULL
, 0);
698 (void) fprintf(stderr
, "could not create '%s': %s\n",
699 dataset
, strerror(errno
));
703 tmpfd
= mkstemp(filepath
);
705 (void) fprintf(stderr
, "could not create '%s': %s\n",
706 filepath
, strerror(errno
));
711 * run a test for each ioctl
712 * Note that some test build on previous test operations
714 test_pool_sync(pool
);
715 test_pool_reopen(pool
);
716 test_pool_checkpoint(pool
);
717 test_pool_discard_checkpoint(pool
);
718 test_log_history(pool
);
720 test_create(dataset
);
721 test_snapshot(pool
, snapbase
);
722 test_snapshot(pool
, snapshot
);
724 test_space_snaps(snapshot
);
725 test_send_space(snapbase
, snapshot
);
726 test_send_new(snapshot
, tmpfd
);
727 test_recv_new(backup
, tmpfd
);
729 test_bookmark(pool
, snapshot
, bookmark
);
730 test_get_bookmarks(dataset
);
731 test_destroy_bookmarks(pool
, bookmark
);
733 test_hold(pool
, snapshot
);
734 test_get_holds(snapshot
);
735 test_release(pool
, snapshot
);
737 test_clone(snapshot
, clone
);
740 test_rollback(dataset
, snapshot
);
741 test_destroy_snaps(pool
, snapshot
);
742 test_destroy_snaps(pool
, snapbase
);
745 test_channel_program(pool
);
747 test_load_key(dataset
);
748 test_change_key(dataset
);
749 test_unload_key(dataset
);
751 test_vdev_initialize(pool
);
756 zfs_cmd_t zc
= {"\0"};
758 nvlist_t
*snaps
= fnvlist_alloc();
759 fnvlist_add_boolean(snaps
, snapshot
);
760 (void) lzc_destroy_snaps(snaps
, B_FALSE
, NULL
);
763 (void) zfs_destroy(dataset
);
764 (void) zfs_destroy(backup
);
767 (void) unlink(filepath
);
770 * All the unused slots should yield ZFS_ERR_IOC_CMD_UNAVAIL
772 for (int i
= 0; i
< ARRAY_SIZE(ioc_skip
); i
++) {
773 if (ioc_tested
[ioc_skip
[i
] - ZFS_IOC_FIRST
])
774 (void) fprintf(stderr
, "cmd %d tested, not skipped!\n",
775 (int)(ioc_skip
[i
] - ZFS_IOC_FIRST
));
777 ioc_tested
[ioc_skip
[i
] - ZFS_IOC_FIRST
] = B_TRUE
;
780 (void) strlcpy(zc
.zc_name
, pool
, sizeof (zc
.zc_name
));
781 zc
.zc_name
[sizeof (zc
.zc_name
) - 1] = '\0';
783 for (unsigned ioc
= ZFS_IOC_FIRST
; ioc
< ZFS_IOC_LAST
; ioc
++) {
784 unsigned cmd
= ioc
- ZFS_IOC_FIRST
;
789 if (ioctl(zfs_fd
, ioc
, &zc
) != 0 &&
790 errno
!= ZFS_ERR_IOC_CMD_UNAVAIL
) {
791 (void) fprintf(stderr
, "cmd %d is missing a test case "
792 "(%d)\n", cmd
, errno
);
798 ZFS_IOC_BASE
= ('Z' << 8),
799 LINUX_IOC_BASE
= ('Z' << 8) + 0x80,
800 FREEBSD_IOC_BASE
= ('Z' << 8) + 0xC0,
804 * Canonical reference check of /dev/zfs ioctl numbers.
805 * These cannot change and new ioctl numbers must be appended.
808 validate_ioc_values(void)
811 ZFS_IOC_BASE
+ 0 == ZFS_IOC_POOL_CREATE
&&
812 ZFS_IOC_BASE
+ 1 == ZFS_IOC_POOL_DESTROY
&&
813 ZFS_IOC_BASE
+ 2 == ZFS_IOC_POOL_IMPORT
&&
814 ZFS_IOC_BASE
+ 3 == ZFS_IOC_POOL_EXPORT
&&
815 ZFS_IOC_BASE
+ 4 == ZFS_IOC_POOL_CONFIGS
&&
816 ZFS_IOC_BASE
+ 5 == ZFS_IOC_POOL_STATS
&&
817 ZFS_IOC_BASE
+ 6 == ZFS_IOC_POOL_TRYIMPORT
&&
818 ZFS_IOC_BASE
+ 7 == ZFS_IOC_POOL_SCAN
&&
819 ZFS_IOC_BASE
+ 8 == ZFS_IOC_POOL_FREEZE
&&
820 ZFS_IOC_BASE
+ 9 == ZFS_IOC_POOL_UPGRADE
&&
821 ZFS_IOC_BASE
+ 10 == ZFS_IOC_POOL_GET_HISTORY
&&
822 ZFS_IOC_BASE
+ 11 == ZFS_IOC_VDEV_ADD
&&
823 ZFS_IOC_BASE
+ 12 == ZFS_IOC_VDEV_REMOVE
&&
824 ZFS_IOC_BASE
+ 13 == ZFS_IOC_VDEV_SET_STATE
&&
825 ZFS_IOC_BASE
+ 14 == ZFS_IOC_VDEV_ATTACH
&&
826 ZFS_IOC_BASE
+ 15 == ZFS_IOC_VDEV_DETACH
&&
827 ZFS_IOC_BASE
+ 16 == ZFS_IOC_VDEV_SETPATH
&&
828 ZFS_IOC_BASE
+ 17 == ZFS_IOC_VDEV_SETFRU
&&
829 ZFS_IOC_BASE
+ 18 == ZFS_IOC_OBJSET_STATS
&&
830 ZFS_IOC_BASE
+ 19 == ZFS_IOC_OBJSET_ZPLPROPS
&&
831 ZFS_IOC_BASE
+ 20 == ZFS_IOC_DATASET_LIST_NEXT
&&
832 ZFS_IOC_BASE
+ 21 == ZFS_IOC_SNAPSHOT_LIST_NEXT
&&
833 ZFS_IOC_BASE
+ 22 == ZFS_IOC_SET_PROP
&&
834 ZFS_IOC_BASE
+ 23 == ZFS_IOC_CREATE
&&
835 ZFS_IOC_BASE
+ 24 == ZFS_IOC_DESTROY
&&
836 ZFS_IOC_BASE
+ 25 == ZFS_IOC_ROLLBACK
&&
837 ZFS_IOC_BASE
+ 26 == ZFS_IOC_RENAME
&&
838 ZFS_IOC_BASE
+ 27 == ZFS_IOC_RECV
&&
839 ZFS_IOC_BASE
+ 28 == ZFS_IOC_SEND
&&
840 ZFS_IOC_BASE
+ 29 == ZFS_IOC_INJECT_FAULT
&&
841 ZFS_IOC_BASE
+ 30 == ZFS_IOC_CLEAR_FAULT
&&
842 ZFS_IOC_BASE
+ 31 == ZFS_IOC_INJECT_LIST_NEXT
&&
843 ZFS_IOC_BASE
+ 32 == ZFS_IOC_ERROR_LOG
&&
844 ZFS_IOC_BASE
+ 33 == ZFS_IOC_CLEAR
&&
845 ZFS_IOC_BASE
+ 34 == ZFS_IOC_PROMOTE
&&
846 ZFS_IOC_BASE
+ 35 == ZFS_IOC_SNAPSHOT
&&
847 ZFS_IOC_BASE
+ 36 == ZFS_IOC_DSOBJ_TO_DSNAME
&&
848 ZFS_IOC_BASE
+ 37 == ZFS_IOC_OBJ_TO_PATH
&&
849 ZFS_IOC_BASE
+ 38 == ZFS_IOC_POOL_SET_PROPS
&&
850 ZFS_IOC_BASE
+ 39 == ZFS_IOC_POOL_GET_PROPS
&&
851 ZFS_IOC_BASE
+ 40 == ZFS_IOC_SET_FSACL
&&
852 ZFS_IOC_BASE
+ 41 == ZFS_IOC_GET_FSACL
&&
853 ZFS_IOC_BASE
+ 42 == ZFS_IOC_SHARE
&&
854 ZFS_IOC_BASE
+ 43 == ZFS_IOC_INHERIT_PROP
&&
855 ZFS_IOC_BASE
+ 44 == ZFS_IOC_SMB_ACL
&&
856 ZFS_IOC_BASE
+ 45 == ZFS_IOC_USERSPACE_ONE
&&
857 ZFS_IOC_BASE
+ 46 == ZFS_IOC_USERSPACE_MANY
&&
858 ZFS_IOC_BASE
+ 47 == ZFS_IOC_USERSPACE_UPGRADE
&&
859 ZFS_IOC_BASE
+ 48 == ZFS_IOC_HOLD
&&
860 ZFS_IOC_BASE
+ 49 == ZFS_IOC_RELEASE
&&
861 ZFS_IOC_BASE
+ 50 == ZFS_IOC_GET_HOLDS
&&
862 ZFS_IOC_BASE
+ 51 == ZFS_IOC_OBJSET_RECVD_PROPS
&&
863 ZFS_IOC_BASE
+ 52 == ZFS_IOC_VDEV_SPLIT
&&
864 ZFS_IOC_BASE
+ 53 == ZFS_IOC_NEXT_OBJ
&&
865 ZFS_IOC_BASE
+ 54 == ZFS_IOC_DIFF
&&
866 ZFS_IOC_BASE
+ 55 == ZFS_IOC_TMP_SNAPSHOT
&&
867 ZFS_IOC_BASE
+ 56 == ZFS_IOC_OBJ_TO_STATS
&&
868 ZFS_IOC_BASE
+ 57 == ZFS_IOC_SPACE_WRITTEN
&&
869 ZFS_IOC_BASE
+ 58 == ZFS_IOC_SPACE_SNAPS
&&
870 ZFS_IOC_BASE
+ 59 == ZFS_IOC_DESTROY_SNAPS
&&
871 ZFS_IOC_BASE
+ 60 == ZFS_IOC_POOL_REGUID
&&
872 ZFS_IOC_BASE
+ 61 == ZFS_IOC_POOL_REOPEN
&&
873 ZFS_IOC_BASE
+ 62 == ZFS_IOC_SEND_PROGRESS
&&
874 ZFS_IOC_BASE
+ 63 == ZFS_IOC_LOG_HISTORY
&&
875 ZFS_IOC_BASE
+ 64 == ZFS_IOC_SEND_NEW
&&
876 ZFS_IOC_BASE
+ 65 == ZFS_IOC_SEND_SPACE
&&
877 ZFS_IOC_BASE
+ 66 == ZFS_IOC_CLONE
&&
878 ZFS_IOC_BASE
+ 67 == ZFS_IOC_BOOKMARK
&&
879 ZFS_IOC_BASE
+ 68 == ZFS_IOC_GET_BOOKMARKS
&&
880 ZFS_IOC_BASE
+ 69 == ZFS_IOC_DESTROY_BOOKMARKS
&&
881 ZFS_IOC_BASE
+ 70 == ZFS_IOC_CHANNEL_PROGRAM
&&
882 ZFS_IOC_BASE
+ 71 == ZFS_IOC_RECV_NEW
&&
883 ZFS_IOC_BASE
+ 72 == ZFS_IOC_POOL_SYNC
&&
884 ZFS_IOC_BASE
+ 73 == ZFS_IOC_LOAD_KEY
&&
885 ZFS_IOC_BASE
+ 74 == ZFS_IOC_UNLOAD_KEY
&&
886 ZFS_IOC_BASE
+ 75 == ZFS_IOC_CHANGE_KEY
&&
887 ZFS_IOC_BASE
+ 76 == ZFS_IOC_REMAP
&&
888 ZFS_IOC_BASE
+ 77 == ZFS_IOC_POOL_CHECKPOINT
&&
889 ZFS_IOC_BASE
+ 78 == ZFS_IOC_POOL_DISCARD_CHECKPOINT
&&
890 ZFS_IOC_BASE
+ 79 == ZFS_IOC_POOL_INITIALIZE
&&
891 LINUX_IOC_BASE
+ 1 == ZFS_IOC_EVENTS_NEXT
&&
892 LINUX_IOC_BASE
+ 2 == ZFS_IOC_EVENTS_CLEAR
&&
893 LINUX_IOC_BASE
+ 3 == ZFS_IOC_EVENTS_SEEK
);
897 main(int argc
, const char *argv
[])
900 (void) fprintf(stderr
, "usage: %s <pool>\n", argv
[0]);
904 if (!validate_ioc_values()) {
905 (void) fprintf(stderr
, "WARNING: zfs_ioc_t has binary "
906 "incompatible command values\n");
910 (void) libzfs_core_init();
911 zfs_fd
= open(ZFS_DEV
, O_RDWR
);
913 (void) fprintf(stderr
, "open: %s\n", strerror(errno
));
918 zfs_ioc_input_tests(argv
[1]);
920 (void) close(zfs_fd
);
923 return (unexpected_failures
);