The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/contrib/openzfs/tests/zfs-tests/cmd/libzfs_input_check.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*
    2  * CDDL HEADER START
    3  *
    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
    7  * 1.0 of the CDDL.
    8  *
    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.
   12  *
   13  * CDDL HEADER END
   14  */
   15 
   16 /*
   17  * Copyright (c) 2018 by Delphix. All rights reserved.
   18  */
   19 
   20 #include <stdio.h>
   21 #include <stdlib.h>
   22 #include <string.h>
   23 #include <libzfs_core.h>
   24 #include <libzutil.h>
   25 
   26 #include <sys/nvpair.h>
   27 #include <sys/vdev_impl.h>
   28 #include <sys/zfs_ioctl.h>
   29 #include <sys/zfs_bootenv.h>
   30 
   31 /*
   32  * Test the nvpair inputs for the non-legacy zfs ioctl commands.
   33  */
   34 
   35 static boolean_t unexpected_failures;
   36 static int zfs_fd;
   37 static const char *active_test;
   38 
   39 /*
   40  * Tracks which zfs_ioc_t commands were tested
   41  */
   42 static boolean_t ioc_tested[ZFS_IOC_LAST - ZFS_IOC_FIRST];
   43 
   44 /*
   45  * Legacy ioctls that are skipped (for now)
   46  */
   47 static const zfs_ioc_t ioc_skip[] = {
   48         ZFS_IOC_POOL_CREATE,
   49         ZFS_IOC_POOL_DESTROY,
   50         ZFS_IOC_POOL_IMPORT,
   51         ZFS_IOC_POOL_EXPORT,
   52         ZFS_IOC_POOL_CONFIGS,
   53         ZFS_IOC_POOL_STATS,
   54         ZFS_IOC_POOL_TRYIMPORT,
   55         ZFS_IOC_POOL_SCAN,
   56         ZFS_IOC_POOL_FREEZE,
   57         ZFS_IOC_POOL_UPGRADE,
   58         ZFS_IOC_POOL_GET_HISTORY,
   59 
   60         ZFS_IOC_VDEV_ADD,
   61         ZFS_IOC_VDEV_REMOVE,
   62         ZFS_IOC_VDEV_SET_STATE,
   63         ZFS_IOC_VDEV_ATTACH,
   64         ZFS_IOC_VDEV_DETACH,
   65         ZFS_IOC_VDEV_SETPATH,
   66         ZFS_IOC_VDEV_SETFRU,
   67 
   68         ZFS_IOC_OBJSET_STATS,
   69         ZFS_IOC_OBJSET_ZPLPROPS,
   70         ZFS_IOC_DATASET_LIST_NEXT,
   71         ZFS_IOC_SNAPSHOT_LIST_NEXT,
   72         ZFS_IOC_SET_PROP,
   73         ZFS_IOC_DESTROY,
   74         ZFS_IOC_RENAME,
   75         ZFS_IOC_RECV,
   76         ZFS_IOC_SEND,
   77         ZFS_IOC_INJECT_FAULT,
   78         ZFS_IOC_CLEAR_FAULT,
   79         ZFS_IOC_INJECT_LIST_NEXT,
   80         ZFS_IOC_ERROR_LOG,
   81         ZFS_IOC_CLEAR,
   82         ZFS_IOC_PROMOTE,
   83         ZFS_IOC_DSOBJ_TO_DSNAME,
   84         ZFS_IOC_OBJ_TO_PATH,
   85         ZFS_IOC_POOL_SET_PROPS,
   86         ZFS_IOC_POOL_GET_PROPS,
   87         ZFS_IOC_SET_FSACL,
   88         ZFS_IOC_GET_FSACL,
   89         ZFS_IOC_SHARE,
   90         ZFS_IOC_INHERIT_PROP,
   91         ZFS_IOC_SMB_ACL,
   92         ZFS_IOC_USERSPACE_ONE,
   93         ZFS_IOC_USERSPACE_MANY,
   94         ZFS_IOC_USERSPACE_UPGRADE,
   95         ZFS_IOC_OBJSET_RECVD_PROPS,
   96         ZFS_IOC_VDEV_SPLIT,
   97         ZFS_IOC_NEXT_OBJ,
   98         ZFS_IOC_DIFF,
   99         ZFS_IOC_TMP_SNAPSHOT,
  100         ZFS_IOC_OBJ_TO_STATS,
  101         ZFS_IOC_SPACE_WRITTEN,
  102         ZFS_IOC_POOL_REGUID,
  103         ZFS_IOC_SEND_PROGRESS,
  104         ZFS_IOC_EVENTS_NEXT,
  105         ZFS_IOC_EVENTS_CLEAR,
  106         ZFS_IOC_EVENTS_SEEK,
  107         ZFS_IOC_NEXTBOOT,
  108         ZFS_IOC_JAIL,
  109         ZFS_IOC_UNJAIL,
  110 };
  111 
  112 
  113 #define IOC_INPUT_TEST(ioc, name, req, opt, err)                \
  114         IOC_INPUT_TEST_IMPL(ioc, name, req, opt, err, B_FALSE)
  115 
  116 #define IOC_INPUT_TEST_WILD(ioc, name, req, opt, err)           \
  117         IOC_INPUT_TEST_IMPL(ioc, name, req, opt, err, B_TRUE)
  118 
  119 #define IOC_INPUT_TEST_IMPL(ioc, name, req, opt, err, wild)     \
  120         do {                                                    \
  121                 active_test = __func__ + 5;                     \
  122                 ioc_tested[ioc - ZFS_IOC_FIRST] = B_TRUE;       \
  123                 lzc_ioctl_test(ioc, name, req, opt, err, wild); \
  124         } while (0)
  125 
  126 /*
  127  * run a zfs ioctl command, verify expected results and log failures
  128  */
  129 static void
  130 lzc_ioctl_run(zfs_ioc_t ioc, const char *name, nvlist_t *innvl, int expected)
  131 {
  132         zfs_cmd_t zc = {"\0"};
  133         char *packed = NULL;
  134         const char *variant;
  135         size_t size = 0;
  136         int error = 0;
  137 
  138         switch (expected) {
  139         case ZFS_ERR_IOC_ARG_UNAVAIL:
  140                 variant = "unsupported input";
  141                 break;
  142         case ZFS_ERR_IOC_ARG_REQUIRED:
  143                 variant = "missing input";
  144                 break;
  145         case ZFS_ERR_IOC_ARG_BADTYPE:
  146                 variant = "invalid input type";
  147                 break;
  148         default:
  149                 variant = "valid input";
  150                 break;
  151         }
  152 
  153         packed = fnvlist_pack(innvl, &size);
  154         (void) strlcpy(zc.zc_name, name, sizeof (zc.zc_name));
  155         zc.zc_name[sizeof (zc.zc_name) - 1] = '\0';
  156         zc.zc_nvlist_src = (uint64_t)(uintptr_t)packed;
  157         zc.zc_nvlist_src_size = size;
  158         zc.zc_nvlist_dst_size = MAX(size * 2, 128 * 1024);
  159         zc.zc_nvlist_dst = (uint64_t)(uintptr_t)malloc(zc.zc_nvlist_dst_size);
  160 
  161         if (lzc_ioctl_fd(zfs_fd, ioc, &zc) != 0)
  162                 error = errno;
  163 
  164         if (error != expected) {
  165                 unexpected_failures = B_TRUE;
  166                 (void) fprintf(stderr, "%s: Unexpected result with %s, "
  167                     "error %d (expecting %d)\n",
  168                     active_test, variant, error, expected);
  169         }
  170 
  171         fnvlist_pack_free(packed, size);
  172         free((void *)(uintptr_t)zc.zc_nvlist_dst);
  173 }
  174 
  175 /*
  176  * Test each ioc for the following ioctl input errors:
  177  *   ZFS_ERR_IOC_ARG_UNAVAIL    an input argument is not supported by kernel
  178  *   ZFS_ERR_IOC_ARG_REQUIRED   a required input argument is missing
  179  *   ZFS_ERR_IOC_ARG_BADTYPE    an input argument has an invalid type
  180  */
  181 static int
  182 lzc_ioctl_test(zfs_ioc_t ioc, const char *name, nvlist_t *required,
  183     nvlist_t *optional, int expected_error, boolean_t wildcard)
  184 {
  185         nvlist_t *input = fnvlist_alloc();
  186         nvlist_t *future = fnvlist_alloc();
  187         int error = 0;
  188 
  189         if (required != NULL) {
  190                 for (nvpair_t *pair = nvlist_next_nvpair(required, NULL);
  191                     pair != NULL; pair = nvlist_next_nvpair(required, pair)) {
  192                         fnvlist_add_nvpair(input, pair);
  193                 }
  194         }
  195         if (optional != NULL) {
  196                 for (nvpair_t *pair = nvlist_next_nvpair(optional, NULL);
  197                     pair != NULL; pair = nvlist_next_nvpair(optional, pair)) {
  198                         fnvlist_add_nvpair(input, pair);
  199                 }
  200         }
  201 
  202         /*
  203          * Generic input run with 'optional' nvlist pair
  204          */
  205         if (!wildcard)
  206                 fnvlist_add_nvlist(input, "optional", future);
  207         lzc_ioctl_run(ioc, name, input, expected_error);
  208         if (!wildcard)
  209                 fnvlist_remove(input, "optional");
  210 
  211         /*
  212          * Bogus input value
  213          */
  214         if (!wildcard) {
  215                 fnvlist_add_string(input, "bogus_input", "bogus");
  216                 lzc_ioctl_run(ioc, name, input, ZFS_ERR_IOC_ARG_UNAVAIL);
  217                 fnvlist_remove(input, "bogus_input");
  218         }
  219 
  220         /*
  221          * Missing required inputs
  222          */
  223         if (required != NULL) {
  224                 nvlist_t *empty = fnvlist_alloc();
  225                 lzc_ioctl_run(ioc, name, empty, ZFS_ERR_IOC_ARG_REQUIRED);
  226                 nvlist_free(empty);
  227         }
  228 
  229         /*
  230          * Wrong nvpair type
  231          */
  232         if (required != NULL || optional != NULL) {
  233                 /*
  234                  * switch the type of one of the input pairs
  235                  */
  236                 for (nvpair_t *pair = nvlist_next_nvpair(input, NULL);
  237                     pair != NULL; pair = nvlist_next_nvpair(input, pair)) {
  238                         char pname[MAXNAMELEN];
  239                         data_type_t ptype;
  240 
  241                         strlcpy(pname, nvpair_name(pair), sizeof (pname));
  242                         pname[sizeof (pname) - 1] = '\0';
  243                         ptype = nvpair_type(pair);
  244                         fnvlist_remove_nvpair(input, pair);
  245 
  246                         switch (ptype) {
  247                         case DATA_TYPE_STRING:
  248                                 fnvlist_add_uint64(input, pname, 42);
  249                                 break;
  250                         default:
  251                                 fnvlist_add_string(input, pname, "bogus");
  252                                 break;
  253                         }
  254                 }
  255                 lzc_ioctl_run(ioc, name, input, ZFS_ERR_IOC_ARG_BADTYPE);
  256         }
  257 
  258         nvlist_free(future);
  259         nvlist_free(input);
  260 
  261         return (error);
  262 }
  263 
  264 static void
  265 test_pool_sync(const char *pool)
  266 {
  267         nvlist_t *required = fnvlist_alloc();
  268 
  269         fnvlist_add_boolean_value(required, "force", B_TRUE);
  270 
  271         IOC_INPUT_TEST(ZFS_IOC_POOL_SYNC, pool, required, NULL, 0);
  272 
  273         nvlist_free(required);
  274 }
  275 
  276 static void
  277 test_pool_reopen(const char *pool)
  278 {
  279         nvlist_t *optional = fnvlist_alloc();
  280 
  281         fnvlist_add_boolean_value(optional, "scrub_restart", B_FALSE);
  282 
  283         IOC_INPUT_TEST(ZFS_IOC_POOL_REOPEN, pool, NULL, optional, 0);
  284 
  285         nvlist_free(optional);
  286 }
  287 
  288 static void
  289 test_pool_checkpoint(const char *pool)
  290 {
  291         IOC_INPUT_TEST(ZFS_IOC_POOL_CHECKPOINT, pool, NULL, NULL, 0);
  292 }
  293 
  294 static void
  295 test_pool_discard_checkpoint(const char *pool)
  296 {
  297         int err = lzc_pool_checkpoint(pool);
  298         if (err == 0 || err == ZFS_ERR_CHECKPOINT_EXISTS)
  299                 IOC_INPUT_TEST(ZFS_IOC_POOL_DISCARD_CHECKPOINT, pool, NULL,
  300                     NULL, 0);
  301 }
  302 
  303 static void
  304 test_log_history(const char *pool)
  305 {
  306         nvlist_t *required = fnvlist_alloc();
  307 
  308         fnvlist_add_string(required, "message", "input check");
  309 
  310         IOC_INPUT_TEST(ZFS_IOC_LOG_HISTORY, pool, required, NULL, 0);
  311 
  312         nvlist_free(required);
  313 }
  314 
  315 static void
  316 test_create(const char *pool)
  317 {
  318         char dataset[MAXNAMELEN + 32];
  319 
  320         (void) snprintf(dataset, sizeof (dataset), "%s/create-fs", pool);
  321 
  322         nvlist_t *required = fnvlist_alloc();
  323         nvlist_t *optional = fnvlist_alloc();
  324         nvlist_t *props = fnvlist_alloc();
  325 
  326         fnvlist_add_int32(required, "type", DMU_OST_ZFS);
  327         fnvlist_add_uint64(props, "recordsize", 8192);
  328         fnvlist_add_nvlist(optional, "props", props);
  329 
  330         IOC_INPUT_TEST(ZFS_IOC_CREATE, dataset, required, optional, 0);
  331 
  332         nvlist_free(required);
  333         nvlist_free(optional);
  334 }
  335 
  336 static void
  337 test_snapshot(const char *pool, const char *snapshot)
  338 {
  339         nvlist_t *required = fnvlist_alloc();
  340         nvlist_t *optional = fnvlist_alloc();
  341         nvlist_t *snaps = fnvlist_alloc();
  342         nvlist_t *props = fnvlist_alloc();
  343 
  344         fnvlist_add_boolean(snaps, snapshot);
  345         fnvlist_add_nvlist(required, "snaps", snaps);
  346 
  347         fnvlist_add_string(props, "org.openzfs:launch", "September 17th, 2013");
  348         fnvlist_add_nvlist(optional, "props", props);
  349 
  350         IOC_INPUT_TEST(ZFS_IOC_SNAPSHOT, pool, required, optional, 0);
  351 
  352         nvlist_free(props);
  353         nvlist_free(snaps);
  354         nvlist_free(optional);
  355         nvlist_free(required);
  356 }
  357 
  358 static void
  359 test_space_snaps(const char *snapshot)
  360 {
  361         nvlist_t *required = fnvlist_alloc();
  362         fnvlist_add_string(required, "firstsnap", snapshot);
  363 
  364         IOC_INPUT_TEST(ZFS_IOC_SPACE_SNAPS, snapshot, required, NULL, 0);
  365 
  366         nvlist_free(required);
  367 }
  368 
  369 static void
  370 test_destroy_snaps(const char *pool, const char *snapshot)
  371 {
  372         nvlist_t *required = fnvlist_alloc();
  373         nvlist_t *snaps = fnvlist_alloc();
  374 
  375         fnvlist_add_boolean(snaps, snapshot);
  376         fnvlist_add_nvlist(required, "snaps", snaps);
  377 
  378         IOC_INPUT_TEST(ZFS_IOC_DESTROY_SNAPS, pool, required, NULL, 0);
  379 
  380         nvlist_free(snaps);
  381         nvlist_free(required);
  382 }
  383 
  384 
  385 static void
  386 test_bookmark(const char *pool, const char *snapshot, const char *bookmark)
  387 {
  388         nvlist_t *required = fnvlist_alloc();
  389 
  390         fnvlist_add_string(required, bookmark, snapshot);
  391 
  392         IOC_INPUT_TEST_WILD(ZFS_IOC_BOOKMARK, pool, required, NULL, 0);
  393 
  394         nvlist_free(required);
  395 }
  396 
  397 static void
  398 test_get_bookmarks(const char *dataset)
  399 {
  400         nvlist_t *optional = fnvlist_alloc();
  401 
  402         fnvlist_add_boolean(optional, "guid");
  403         fnvlist_add_boolean(optional, "createtxg");
  404         fnvlist_add_boolean(optional, "creation");
  405 
  406         IOC_INPUT_TEST_WILD(ZFS_IOC_GET_BOOKMARKS, dataset, NULL, optional, 0);
  407 
  408         nvlist_free(optional);
  409 }
  410 
  411 static void
  412 test_destroy_bookmarks(const char *pool, const char *bookmark)
  413 {
  414         nvlist_t *required = fnvlist_alloc();
  415 
  416         fnvlist_add_boolean(required, bookmark);
  417 
  418         IOC_INPUT_TEST_WILD(ZFS_IOC_DESTROY_BOOKMARKS, pool, required, NULL, 0);
  419 
  420         nvlist_free(required);
  421 }
  422 
  423 static void
  424 test_clone(const char *snapshot, const char *clone)
  425 {
  426         nvlist_t *required = fnvlist_alloc();
  427         nvlist_t *optional = fnvlist_alloc();
  428         nvlist_t *props = fnvlist_alloc();
  429 
  430         fnvlist_add_string(required, "origin", snapshot);
  431 
  432         IOC_INPUT_TEST(ZFS_IOC_CLONE, clone, required, NULL, 0);
  433 
  434         nvlist_free(props);
  435         nvlist_free(optional);
  436         nvlist_free(required);
  437 }
  438 
  439 static void
  440 test_rollback(const char *dataset, const char *snapshot)
  441 {
  442         nvlist_t *optional = fnvlist_alloc();
  443 
  444         fnvlist_add_string(optional, "target", snapshot);
  445 
  446         IOC_INPUT_TEST(ZFS_IOC_ROLLBACK, dataset, NULL, optional, B_FALSE);
  447 
  448         nvlist_free(optional);
  449 }
  450 
  451 static void
  452 test_hold(const char *pool, const char *snapshot)
  453 {
  454         nvlist_t *required = fnvlist_alloc();
  455         nvlist_t *optional = fnvlist_alloc();
  456         nvlist_t *holds = fnvlist_alloc();
  457 
  458         fnvlist_add_string(holds, snapshot, "libzfs_check_hold");
  459         fnvlist_add_nvlist(required, "holds", holds);
  460         fnvlist_add_int32(optional, "cleanup_fd", zfs_fd);
  461 
  462         IOC_INPUT_TEST(ZFS_IOC_HOLD, pool, required, optional, 0);
  463 
  464         nvlist_free(holds);
  465         nvlist_free(optional);
  466         nvlist_free(required);
  467 }
  468 
  469 static void
  470 test_get_holds(const char *snapshot)
  471 {
  472         IOC_INPUT_TEST(ZFS_IOC_GET_HOLDS, snapshot, NULL, NULL, 0);
  473 }
  474 
  475 static void
  476 test_release(const char *pool, const char *snapshot)
  477 {
  478         nvlist_t *required = fnvlist_alloc();
  479         nvlist_t *release = fnvlist_alloc();
  480 
  481         fnvlist_add_boolean(release, "libzfs_check_hold");
  482         fnvlist_add_nvlist(required, snapshot, release);
  483 
  484         IOC_INPUT_TEST_WILD(ZFS_IOC_RELEASE, pool, required, NULL, 0);
  485 
  486         nvlist_free(release);
  487         nvlist_free(required);
  488 }
  489 
  490 
  491 static void
  492 test_send_new(const char *snapshot, int fd)
  493 {
  494         nvlist_t *required = fnvlist_alloc();
  495         nvlist_t *optional = fnvlist_alloc();
  496 
  497         fnvlist_add_int32(required, "fd", fd);
  498 
  499         fnvlist_add_boolean(optional, "largeblockok");
  500         fnvlist_add_boolean(optional, "embedok");
  501         fnvlist_add_boolean(optional, "compressok");
  502         fnvlist_add_boolean(optional, "rawok");
  503 
  504         /*
  505          * TODO - Resumable send is harder to set up. So we currently
  506          * ignore testing for that variant.
  507          */
  508 #if 0
  509         fnvlist_add_string(optional, "fromsnap", from);
  510         fnvlist_add_uint64(optional, "resume_object", resumeobj);
  511         fnvlist_add_uint64(optional, "resume_offset", offset);
  512         fnvlist_add_boolean(optional, "savedok");
  513 #endif
  514         IOC_INPUT_TEST(ZFS_IOC_SEND_NEW, snapshot, required, optional, 0);
  515 
  516         nvlist_free(optional);
  517         nvlist_free(required);
  518 }
  519 
  520 static void
  521 test_recv_new(const char *dataset, int fd)
  522 {
  523         dmu_replay_record_t drr = { 0 };
  524         nvlist_t *required = fnvlist_alloc();
  525         nvlist_t *optional = fnvlist_alloc();
  526         nvlist_t *props = fnvlist_alloc();
  527         char snapshot[MAXNAMELEN + 32];
  528         ssize_t count;
  529 
  530         int cleanup_fd = open(ZFS_DEV, O_RDWR);
  531         if (cleanup_fd == -1) {
  532                 (void) fprintf(stderr, "open(%s) failed: %s\n", ZFS_DEV,
  533                     strerror(errno));
  534                 exit(EXIT_FAILURE);
  535         }
  536         (void) snprintf(snapshot, sizeof (snapshot), "%s@replicant", dataset);
  537 
  538         count = pread(fd, &drr, sizeof (drr), 0);
  539         if (count != sizeof (drr)) {
  540                 (void) fprintf(stderr, "could not read stream: %s\n",
  541                     strerror(errno));
  542         }
  543 
  544         fnvlist_add_string(required, "snapname", snapshot);
  545         fnvlist_add_byte_array(required, "begin_record", (uchar_t *)&drr,
  546             sizeof (drr));
  547         fnvlist_add_int32(required, "input_fd", fd);
  548 
  549         fnvlist_add_string(props, "org.openzfs:launch", "September 17th, 2013");
  550         fnvlist_add_nvlist(optional, "localprops", props);
  551         fnvlist_add_boolean(optional, "force");
  552         fnvlist_add_boolean(optional, "heal");
  553         fnvlist_add_int32(optional, "cleanup_fd", cleanup_fd);
  554 
  555         /*
  556          * TODO - Resumable receive is harder to set up. So we currently
  557          * ignore testing for one.
  558          */
  559 #if 0
  560         fnvlist_add_nvlist(optional, "props", recvdprops);
  561         fnvlist_add_string(optional, "origin", origin);
  562         fnvlist_add_boolean(optional, "resumable");
  563         fnvlist_add_uint64(optional, "action_handle", *action_handle);
  564 #endif
  565         IOC_INPUT_TEST(ZFS_IOC_RECV_NEW, dataset, required, optional,
  566             ZFS_ERR_STREAM_TRUNCATED);
  567 
  568         nvlist_free(props);
  569         nvlist_free(optional);
  570         nvlist_free(required);
  571 
  572         (void) close(cleanup_fd);
  573 }
  574 
  575 static void
  576 test_send_space(const char *snapshot1, const char *snapshot2)
  577 {
  578         nvlist_t *optional = fnvlist_alloc();
  579 
  580         fnvlist_add_string(optional, "from", snapshot1);
  581         fnvlist_add_boolean(optional, "largeblockok");
  582         fnvlist_add_boolean(optional, "embedok");
  583         fnvlist_add_boolean(optional, "compressok");
  584         fnvlist_add_boolean(optional, "rawok");
  585 
  586         IOC_INPUT_TEST(ZFS_IOC_SEND_SPACE, snapshot2, NULL, optional, 0);
  587 
  588         nvlist_free(optional);
  589 }
  590 
  591 static void
  592 test_remap(const char *dataset)
  593 {
  594         IOC_INPUT_TEST(ZFS_IOC_REMAP, dataset, NULL, NULL, 0);
  595 }
  596 
  597 static void
  598 test_channel_program(const char *pool)
  599 {
  600         const char *program =
  601             "arg = ...\n"
  602             "argv = arg[\"argv\"]\n"
  603             "return argv[1]";
  604         const char *const argv[1] = { "Hello World!" };
  605         nvlist_t *required = fnvlist_alloc();
  606         nvlist_t *optional = fnvlist_alloc();
  607         nvlist_t *args = fnvlist_alloc();
  608 
  609         fnvlist_add_string(required, "program", program);
  610         fnvlist_add_string_array(args, "argv", argv, 1);
  611         fnvlist_add_nvlist(required, "arg", args);
  612 
  613         fnvlist_add_boolean_value(optional, "sync", B_TRUE);
  614         fnvlist_add_uint64(optional, "instrlimit", 1000 * 1000);
  615         fnvlist_add_uint64(optional, "memlimit", 8192 * 1024);
  616 
  617         IOC_INPUT_TEST(ZFS_IOC_CHANNEL_PROGRAM, pool, required, optional, 0);
  618 
  619         nvlist_free(args);
  620         nvlist_free(optional);
  621         nvlist_free(required);
  622 }
  623 
  624 #define WRAPPING_KEY_LEN        32
  625 
  626 static void
  627 test_load_key(const char *dataset)
  628 {
  629         nvlist_t *required = fnvlist_alloc();
  630         nvlist_t *optional = fnvlist_alloc();
  631         nvlist_t *hidden = fnvlist_alloc();
  632         uint8_t keydata[WRAPPING_KEY_LEN] = {0};
  633 
  634         fnvlist_add_uint8_array(hidden, "wkeydata", keydata, sizeof (keydata));
  635         fnvlist_add_nvlist(required, "hidden_args", hidden);
  636         fnvlist_add_boolean(optional, "noop");
  637 
  638         IOC_INPUT_TEST(ZFS_IOC_LOAD_KEY, dataset, required, optional, EINVAL);
  639         nvlist_free(hidden);
  640         nvlist_free(optional);
  641         nvlist_free(required);
  642 }
  643 
  644 static void
  645 test_change_key(const char *dataset)
  646 {
  647         IOC_INPUT_TEST(ZFS_IOC_CHANGE_KEY, dataset, NULL, NULL, EINVAL);
  648 }
  649 
  650 static void
  651 test_unload_key(const char *dataset)
  652 {
  653         IOC_INPUT_TEST(ZFS_IOC_UNLOAD_KEY, dataset, NULL, NULL, EACCES);
  654 }
  655 
  656 static void
  657 test_vdev_initialize(const char *pool)
  658 {
  659         nvlist_t *required = fnvlist_alloc();
  660         nvlist_t *vdev_guids = fnvlist_alloc();
  661 
  662         fnvlist_add_uint64(vdev_guids, "path", 0xdeadbeefdeadbeef);
  663         fnvlist_add_uint64(required, ZPOOL_INITIALIZE_COMMAND,
  664             POOL_INITIALIZE_START);
  665         fnvlist_add_nvlist(required, ZPOOL_INITIALIZE_VDEVS, vdev_guids);
  666 
  667         IOC_INPUT_TEST(ZFS_IOC_POOL_INITIALIZE, pool, required, NULL, EINVAL);
  668         nvlist_free(vdev_guids);
  669         nvlist_free(required);
  670 }
  671 
  672 static void
  673 test_vdev_trim(const char *pool)
  674 {
  675         nvlist_t *required = fnvlist_alloc();
  676         nvlist_t *optional = fnvlist_alloc();
  677         nvlist_t *vdev_guids = fnvlist_alloc();
  678 
  679         fnvlist_add_uint64(vdev_guids, "path", 0xdeadbeefdeadbeef);
  680         fnvlist_add_uint64(required, ZPOOL_TRIM_COMMAND, POOL_TRIM_START);
  681         fnvlist_add_nvlist(required, ZPOOL_TRIM_VDEVS, vdev_guids);
  682         fnvlist_add_uint64(optional, ZPOOL_TRIM_RATE, 1ULL << 30);
  683         fnvlist_add_boolean_value(optional, ZPOOL_TRIM_SECURE, B_TRUE);
  684 
  685         IOC_INPUT_TEST(ZFS_IOC_POOL_TRIM, pool, required, optional, EINVAL);
  686         nvlist_free(vdev_guids);
  687         nvlist_free(optional);
  688         nvlist_free(required);
  689 }
  690 
  691 static int
  692 zfs_destroy(const char *dataset)
  693 {
  694         zfs_cmd_t zc = {"\0"};
  695         int err;
  696 
  697         (void) strlcpy(zc.zc_name, dataset, sizeof (zc.zc_name));
  698         zc.zc_name[sizeof (zc.zc_name) - 1] = '\0';
  699         err = lzc_ioctl_fd(zfs_fd, ZFS_IOC_DESTROY, &zc);
  700 
  701         return (err == 0 ? 0 : errno);
  702 }
  703 
  704 static void
  705 test_redact(const char *snapshot1, const char *snapshot2)
  706 {
  707         nvlist_t *required = fnvlist_alloc();
  708         nvlist_t *snapnv = fnvlist_alloc();
  709         char bookmark[MAXNAMELEN + 32];
  710 
  711         fnvlist_add_string(required, "bookname", "testbookmark");
  712         fnvlist_add_boolean(snapnv, snapshot2);
  713         fnvlist_add_nvlist(required, "snapnv", snapnv);
  714 
  715         IOC_INPUT_TEST(ZFS_IOC_REDACT, snapshot1, required, NULL, 0);
  716 
  717         nvlist_free(snapnv);
  718         nvlist_free(required);
  719 
  720         strlcpy(bookmark, snapshot1, sizeof (bookmark));
  721         *strchr(bookmark, '@') = '\0';
  722         strlcat(bookmark, "#testbookmark", sizeof (bookmark) -
  723             strlen(bookmark));
  724         zfs_destroy(bookmark);
  725 }
  726 
  727 static void
  728 test_get_bookmark_props(const char *bookmark)
  729 {
  730         IOC_INPUT_TEST(ZFS_IOC_GET_BOOKMARK_PROPS, bookmark, NULL, NULL, 0);
  731 }
  732 
  733 static void
  734 test_wait(const char *pool)
  735 {
  736         nvlist_t *required = fnvlist_alloc();
  737         nvlist_t *optional = fnvlist_alloc();
  738 
  739         fnvlist_add_int32(required, "wait_activity", 2);
  740         fnvlist_add_uint64(optional, "wait_tag", 0xdeadbeefdeadbeef);
  741 
  742         IOC_INPUT_TEST(ZFS_IOC_WAIT, pool, required, optional, EINVAL);
  743 
  744         nvlist_free(required);
  745         nvlist_free(optional);
  746 }
  747 
  748 static void
  749 test_wait_fs(const char *dataset)
  750 {
  751         nvlist_t *required = fnvlist_alloc();
  752 
  753         fnvlist_add_int32(required, "wait_activity", 2);
  754 
  755         IOC_INPUT_TEST(ZFS_IOC_WAIT_FS, dataset, required, NULL, EINVAL);
  756 
  757         nvlist_free(required);
  758 }
  759 
  760 static void
  761 test_get_bootenv(const char *pool)
  762 {
  763         IOC_INPUT_TEST(ZFS_IOC_GET_BOOTENV, pool, NULL, NULL, 0);
  764 }
  765 
  766 static void
  767 test_set_bootenv(const char *pool)
  768 {
  769         nvlist_t *required = fnvlist_alloc();
  770 
  771         fnvlist_add_uint64(required, "version", VB_RAW);
  772         fnvlist_add_string(required, GRUB_ENVMAP, "test");
  773 
  774         IOC_INPUT_TEST_WILD(ZFS_IOC_SET_BOOTENV, pool, required, NULL, 0);
  775 
  776         nvlist_free(required);
  777 }
  778 
  779 static void
  780 zfs_ioc_input_tests(const char *pool)
  781 {
  782         char filepath[] = "/tmp/ioc_test_file_XXXXXX";
  783         char dataset[ZFS_MAX_DATASET_NAME_LEN];
  784         char snapbase[ZFS_MAX_DATASET_NAME_LEN + 32];
  785         char snapshot[ZFS_MAX_DATASET_NAME_LEN + 32];
  786         char bookmark[ZFS_MAX_DATASET_NAME_LEN + 32];
  787         char backup[ZFS_MAX_DATASET_NAME_LEN];
  788         char clone[ZFS_MAX_DATASET_NAME_LEN];
  789         char clonesnap[ZFS_MAX_DATASET_NAME_LEN + 32];
  790         int tmpfd, err;
  791 
  792         /*
  793          * Setup names and create a working dataset
  794          */
  795         (void) snprintf(dataset, sizeof (dataset), "%s/test-fs", pool);
  796         (void) snprintf(snapbase, sizeof (snapbase), "%s@snapbase", dataset);
  797         (void) snprintf(snapshot, sizeof (snapshot), "%s@snapshot", dataset);
  798         (void) snprintf(bookmark, sizeof (bookmark), "%s#bookmark", dataset);
  799         (void) snprintf(clone, sizeof (clone), "%s/test-fs-clone", pool);
  800         (void) snprintf(clonesnap, sizeof (clonesnap), "%s@snap", clone);
  801         (void) snprintf(backup, sizeof (backup), "%s/backup", pool);
  802 
  803         err = lzc_create(dataset, LZC_DATSET_TYPE_ZFS, NULL, NULL, -1);
  804         if (err) {
  805                 (void) fprintf(stderr, "could not create '%s': %s\n",
  806                     dataset, strerror(errno));
  807                 exit(2);
  808         }
  809 
  810         tmpfd = mkstemp(filepath);
  811         if (tmpfd < 0) {
  812                 (void) fprintf(stderr, "could not create '%s': %s\n",
  813                     filepath, strerror(errno));
  814                 exit(2);
  815         }
  816 
  817         /*
  818          * run a test for each ioctl
  819          * Note that some test build on previous test operations
  820          */
  821         test_pool_sync(pool);
  822         test_pool_reopen(pool);
  823         test_pool_checkpoint(pool);
  824         test_pool_discard_checkpoint(pool);
  825         test_log_history(pool);
  826 
  827         test_create(dataset);
  828         test_snapshot(pool, snapbase);
  829         test_snapshot(pool, snapshot);
  830 
  831         test_space_snaps(snapshot);
  832         test_send_space(snapbase, snapshot);
  833         test_send_new(snapshot, tmpfd);
  834         test_recv_new(backup, tmpfd);
  835 
  836         test_bookmark(pool, snapshot, bookmark);
  837         test_get_bookmarks(dataset);
  838         test_get_bookmark_props(bookmark);
  839         test_destroy_bookmarks(pool, bookmark);
  840 
  841         test_hold(pool, snapshot);
  842         test_get_holds(snapshot);
  843         test_release(pool, snapshot);
  844 
  845         test_clone(snapshot, clone);
  846         test_snapshot(pool, clonesnap);
  847         test_redact(snapshot, clonesnap);
  848         zfs_destroy(clonesnap);
  849         zfs_destroy(clone);
  850 
  851         test_rollback(dataset, snapshot);
  852         test_destroy_snaps(pool, snapshot);
  853         test_destroy_snaps(pool, snapbase);
  854 
  855         test_remap(dataset);
  856         test_channel_program(pool);
  857 
  858         test_load_key(dataset);
  859         test_change_key(dataset);
  860         test_unload_key(dataset);
  861 
  862         test_vdev_initialize(pool);
  863         test_vdev_trim(pool);
  864 
  865         test_wait(pool);
  866         test_wait_fs(dataset);
  867 
  868         test_set_bootenv(pool);
  869         test_get_bootenv(pool);
  870 
  871         /*
  872          * cleanup
  873          */
  874         zfs_cmd_t zc = {"\0"};
  875 
  876         nvlist_t *snaps = fnvlist_alloc();
  877         fnvlist_add_boolean(snaps, snapshot);
  878         (void) lzc_destroy_snaps(snaps, B_FALSE, NULL);
  879         nvlist_free(snaps);
  880 
  881         (void) zfs_destroy(dataset);
  882         (void) zfs_destroy(backup);
  883 
  884         (void) close(tmpfd);
  885         (void) unlink(filepath);
  886 
  887         /*
  888          * All the unused slots should yield ZFS_ERR_IOC_CMD_UNAVAIL
  889          */
  890         for (int i = 0; i < ARRAY_SIZE(ioc_skip); i++) {
  891                 if (ioc_tested[ioc_skip[i] - ZFS_IOC_FIRST])
  892                         (void) fprintf(stderr, "cmd %d tested, not skipped!\n",
  893                             (int)(ioc_skip[i] - ZFS_IOC_FIRST));
  894 
  895                 ioc_tested[ioc_skip[i] - ZFS_IOC_FIRST] = B_TRUE;
  896         }
  897 
  898         (void) strlcpy(zc.zc_name, pool, sizeof (zc.zc_name));
  899         zc.zc_name[sizeof (zc.zc_name) - 1] = '\0';
  900 
  901         for (unsigned ioc = ZFS_IOC_FIRST; ioc < ZFS_IOC_LAST; ioc++) {
  902                 unsigned cmd = ioc - ZFS_IOC_FIRST;
  903 
  904                 if (ioc_tested[cmd])
  905                         continue;
  906 
  907                 if (lzc_ioctl_fd(zfs_fd, ioc, &zc) != 0 &&
  908                     errno != ZFS_ERR_IOC_CMD_UNAVAIL) {
  909                         (void) fprintf(stderr, "cmd %d is missing a test case "
  910                             "(%d)\n", cmd, errno);
  911                 }
  912         }
  913 }
  914 
  915 enum zfs_ioc_ref {
  916 #ifdef __FreeBSD__
  917         ZFS_IOC_BASE = 0,
  918 #else
  919         ZFS_IOC_BASE = ('Z' << 8),
  920 #endif
  921         ZFS_IOC_PLATFORM_BASE = ZFS_IOC_BASE + 0x80,
  922 };
  923 
  924 /*
  925  * Canonical reference check of /dev/zfs ioctl numbers.
  926  * These cannot change and new ioctl numbers must be appended.
  927  */
  928 static boolean_t
  929 validate_ioc_values(void)
  930 {
  931         boolean_t result = B_TRUE;
  932 
  933 #define CHECK(expr) do { \
  934         if (!(expr)) { \
  935                 result = B_FALSE; \
  936                 fprintf(stderr, "(%s) === FALSE\n", #expr); \
  937         } \
  938 } while (0)
  939 
  940         CHECK(ZFS_IOC_BASE + 0 == ZFS_IOC_POOL_CREATE);
  941         CHECK(ZFS_IOC_BASE + 1 == ZFS_IOC_POOL_DESTROY);
  942         CHECK(ZFS_IOC_BASE + 2 == ZFS_IOC_POOL_IMPORT);
  943         CHECK(ZFS_IOC_BASE + 3 == ZFS_IOC_POOL_EXPORT);
  944         CHECK(ZFS_IOC_BASE + 4 == ZFS_IOC_POOL_CONFIGS);
  945         CHECK(ZFS_IOC_BASE + 5 == ZFS_IOC_POOL_STATS);
  946         CHECK(ZFS_IOC_BASE + 6 == ZFS_IOC_POOL_TRYIMPORT);
  947         CHECK(ZFS_IOC_BASE + 7 == ZFS_IOC_POOL_SCAN);
  948         CHECK(ZFS_IOC_BASE + 8 == ZFS_IOC_POOL_FREEZE);
  949         CHECK(ZFS_IOC_BASE + 9 == ZFS_IOC_POOL_UPGRADE);
  950         CHECK(ZFS_IOC_BASE + 10 == ZFS_IOC_POOL_GET_HISTORY);
  951         CHECK(ZFS_IOC_BASE + 11 == ZFS_IOC_VDEV_ADD);
  952         CHECK(ZFS_IOC_BASE + 12 == ZFS_IOC_VDEV_REMOVE);
  953         CHECK(ZFS_IOC_BASE + 13 == ZFS_IOC_VDEV_SET_STATE);
  954         CHECK(ZFS_IOC_BASE + 14 == ZFS_IOC_VDEV_ATTACH);
  955         CHECK(ZFS_IOC_BASE + 15 == ZFS_IOC_VDEV_DETACH);
  956         CHECK(ZFS_IOC_BASE + 16 == ZFS_IOC_VDEV_SETPATH);
  957         CHECK(ZFS_IOC_BASE + 17 == ZFS_IOC_VDEV_SETFRU);
  958         CHECK(ZFS_IOC_BASE + 18 == ZFS_IOC_OBJSET_STATS);
  959         CHECK(ZFS_IOC_BASE + 19 == ZFS_IOC_OBJSET_ZPLPROPS);
  960         CHECK(ZFS_IOC_BASE + 20 == ZFS_IOC_DATASET_LIST_NEXT);
  961         CHECK(ZFS_IOC_BASE + 21 == ZFS_IOC_SNAPSHOT_LIST_NEXT);
  962         CHECK(ZFS_IOC_BASE + 22 == ZFS_IOC_SET_PROP);
  963         CHECK(ZFS_IOC_BASE + 23 == ZFS_IOC_CREATE);
  964         CHECK(ZFS_IOC_BASE + 24 == ZFS_IOC_DESTROY);
  965         CHECK(ZFS_IOC_BASE + 25 == ZFS_IOC_ROLLBACK);
  966         CHECK(ZFS_IOC_BASE + 26 == ZFS_IOC_RENAME);
  967         CHECK(ZFS_IOC_BASE + 27 == ZFS_IOC_RECV);
  968         CHECK(ZFS_IOC_BASE + 28 == ZFS_IOC_SEND);
  969         CHECK(ZFS_IOC_BASE + 29 == ZFS_IOC_INJECT_FAULT);
  970         CHECK(ZFS_IOC_BASE + 30 == ZFS_IOC_CLEAR_FAULT);
  971         CHECK(ZFS_IOC_BASE + 31 == ZFS_IOC_INJECT_LIST_NEXT);
  972         CHECK(ZFS_IOC_BASE + 32 == ZFS_IOC_ERROR_LOG);
  973         CHECK(ZFS_IOC_BASE + 33 == ZFS_IOC_CLEAR);
  974         CHECK(ZFS_IOC_BASE + 34 == ZFS_IOC_PROMOTE);
  975         CHECK(ZFS_IOC_BASE + 35 == ZFS_IOC_SNAPSHOT);
  976         CHECK(ZFS_IOC_BASE + 36 == ZFS_IOC_DSOBJ_TO_DSNAME);
  977         CHECK(ZFS_IOC_BASE + 37 == ZFS_IOC_OBJ_TO_PATH);
  978         CHECK(ZFS_IOC_BASE + 38 == ZFS_IOC_POOL_SET_PROPS);
  979         CHECK(ZFS_IOC_BASE + 39 == ZFS_IOC_POOL_GET_PROPS);
  980         CHECK(ZFS_IOC_BASE + 40 == ZFS_IOC_SET_FSACL);
  981         CHECK(ZFS_IOC_BASE + 41 == ZFS_IOC_GET_FSACL);
  982         CHECK(ZFS_IOC_BASE + 42 == ZFS_IOC_SHARE);
  983         CHECK(ZFS_IOC_BASE + 43 == ZFS_IOC_INHERIT_PROP);
  984         CHECK(ZFS_IOC_BASE + 44 == ZFS_IOC_SMB_ACL);
  985         CHECK(ZFS_IOC_BASE + 45 == ZFS_IOC_USERSPACE_ONE);
  986         CHECK(ZFS_IOC_BASE + 46 == ZFS_IOC_USERSPACE_MANY);
  987         CHECK(ZFS_IOC_BASE + 47 == ZFS_IOC_USERSPACE_UPGRADE);
  988         CHECK(ZFS_IOC_BASE + 48 == ZFS_IOC_HOLD);
  989         CHECK(ZFS_IOC_BASE + 49 == ZFS_IOC_RELEASE);
  990         CHECK(ZFS_IOC_BASE + 50 == ZFS_IOC_GET_HOLDS);
  991         CHECK(ZFS_IOC_BASE + 51 == ZFS_IOC_OBJSET_RECVD_PROPS);
  992         CHECK(ZFS_IOC_BASE + 52 == ZFS_IOC_VDEV_SPLIT);
  993         CHECK(ZFS_IOC_BASE + 53 == ZFS_IOC_NEXT_OBJ);
  994         CHECK(ZFS_IOC_BASE + 54 == ZFS_IOC_DIFF);
  995         CHECK(ZFS_IOC_BASE + 55 == ZFS_IOC_TMP_SNAPSHOT);
  996         CHECK(ZFS_IOC_BASE + 56 == ZFS_IOC_OBJ_TO_STATS);
  997         CHECK(ZFS_IOC_BASE + 57 == ZFS_IOC_SPACE_WRITTEN);
  998         CHECK(ZFS_IOC_BASE + 58 == ZFS_IOC_SPACE_SNAPS);
  999         CHECK(ZFS_IOC_BASE + 59 == ZFS_IOC_DESTROY_SNAPS);
 1000         CHECK(ZFS_IOC_BASE + 60 == ZFS_IOC_POOL_REGUID);
 1001         CHECK(ZFS_IOC_BASE + 61 == ZFS_IOC_POOL_REOPEN);
 1002         CHECK(ZFS_IOC_BASE + 62 == ZFS_IOC_SEND_PROGRESS);
 1003         CHECK(ZFS_IOC_BASE + 63 == ZFS_IOC_LOG_HISTORY);
 1004         CHECK(ZFS_IOC_BASE + 64 == ZFS_IOC_SEND_NEW);
 1005         CHECK(ZFS_IOC_BASE + 65 == ZFS_IOC_SEND_SPACE);
 1006         CHECK(ZFS_IOC_BASE + 66 == ZFS_IOC_CLONE);
 1007         CHECK(ZFS_IOC_BASE + 67 == ZFS_IOC_BOOKMARK);
 1008         CHECK(ZFS_IOC_BASE + 68 == ZFS_IOC_GET_BOOKMARKS);
 1009         CHECK(ZFS_IOC_BASE + 69 == ZFS_IOC_DESTROY_BOOKMARKS);
 1010         CHECK(ZFS_IOC_BASE + 70 == ZFS_IOC_RECV_NEW);
 1011         CHECK(ZFS_IOC_BASE + 71 == ZFS_IOC_POOL_SYNC);
 1012         CHECK(ZFS_IOC_BASE + 72 == ZFS_IOC_CHANNEL_PROGRAM);
 1013         CHECK(ZFS_IOC_BASE + 73 == ZFS_IOC_LOAD_KEY);
 1014         CHECK(ZFS_IOC_BASE + 74 == ZFS_IOC_UNLOAD_KEY);
 1015         CHECK(ZFS_IOC_BASE + 75 == ZFS_IOC_CHANGE_KEY);
 1016         CHECK(ZFS_IOC_BASE + 76 == ZFS_IOC_REMAP);
 1017         CHECK(ZFS_IOC_BASE + 77 == ZFS_IOC_POOL_CHECKPOINT);
 1018         CHECK(ZFS_IOC_BASE + 78 == ZFS_IOC_POOL_DISCARD_CHECKPOINT);
 1019         CHECK(ZFS_IOC_BASE + 79 == ZFS_IOC_POOL_INITIALIZE);
 1020         CHECK(ZFS_IOC_BASE + 80 == ZFS_IOC_POOL_TRIM);
 1021         CHECK(ZFS_IOC_BASE + 81 == ZFS_IOC_REDACT);
 1022         CHECK(ZFS_IOC_BASE + 82 == ZFS_IOC_GET_BOOKMARK_PROPS);
 1023         CHECK(ZFS_IOC_BASE + 83 == ZFS_IOC_WAIT);
 1024         CHECK(ZFS_IOC_BASE + 84 == ZFS_IOC_WAIT_FS);
 1025         CHECK(ZFS_IOC_PLATFORM_BASE + 1 == ZFS_IOC_EVENTS_NEXT);
 1026         CHECK(ZFS_IOC_PLATFORM_BASE + 2 == ZFS_IOC_EVENTS_CLEAR);
 1027         CHECK(ZFS_IOC_PLATFORM_BASE + 3 == ZFS_IOC_EVENTS_SEEK);
 1028         CHECK(ZFS_IOC_PLATFORM_BASE + 4 == ZFS_IOC_NEXTBOOT);
 1029         CHECK(ZFS_IOC_PLATFORM_BASE + 5 == ZFS_IOC_JAIL);
 1030         CHECK(ZFS_IOC_PLATFORM_BASE + 6 == ZFS_IOC_UNJAIL);
 1031         CHECK(ZFS_IOC_PLATFORM_BASE + 7 == ZFS_IOC_SET_BOOTENV);
 1032         CHECK(ZFS_IOC_PLATFORM_BASE + 8 == ZFS_IOC_GET_BOOTENV);
 1033 
 1034 #undef CHECK
 1035 
 1036         return (result);
 1037 }
 1038 
 1039 int
 1040 main(int argc, const char *argv[])
 1041 {
 1042         if (argc != 2) {
 1043                 (void) fprintf(stderr, "usage: %s <pool>\n", argv[0]);
 1044                 exit(2);
 1045         }
 1046 
 1047         if (!validate_ioc_values()) {
 1048                 (void) fprintf(stderr, "WARNING: zfs_ioc_t has binary "
 1049                     "incompatible command values\n");
 1050                 exit(3);
 1051         }
 1052 
 1053         (void) libzfs_core_init();
 1054         zfs_fd = open(ZFS_DEV, O_RDWR);
 1055         if (zfs_fd < 0) {
 1056                 (void) fprintf(stderr, "open: %s\n", strerror(errno));
 1057                 libzfs_core_fini();
 1058                 exit(2);
 1059         }
 1060 
 1061         zfs_ioc_input_tests(argv[1]);
 1062 
 1063         (void) close(zfs_fd);
 1064         libzfs_core_fini();
 1065 
 1066         return (unexpected_failures);
 1067 }

Cache object: 076cc4041b5f177138ec08993d9b7cdf


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.