1 /*
   2  * CDDL HEADER START
   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 
  22 /*
  23  * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
  24  * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
  25  * Copyright (c) 2012 by Delphix. All rights reserved.
  26  * Copyright (c) 2012 by Frederik Wessels. All rights reserved.
  27  */
  28 
  29 #include <assert.h>
  30 #include <ctype.h>
  31 #include <dirent.h>
  32 #include <errno.h>
  33 #include <fcntl.h>
  34 #include <libgen.h>
  35 #include <libintl.h>
  36 #include <libuutil.h>
  37 #include <locale.h>
  38 #include <stdio.h>
  39 #include <stdlib.h>
  40 #include <string.h>
  41 #include <strings.h>
  42 #include <unistd.h>
  43 #include <priv.h>
  44 #include <pwd.h>
  45 #include <zone.h>
  46 #include <zfs_prop.h>
  47 #include <sys/fs/zfs.h>
  48 #include <sys/stat.h>
  49 
  50 #include <libzfs.h>
  51 
  52 #include "zpool_util.h"
  53 #include "zfs_comutil.h"
  54 #include "zfeature_common.h"
  55 
  56 #include "statcommon.h"
  57 
  58 static int zpool_do_create(int, char **);
  59 static int zpool_do_destroy(int, char **);
  60 
  61 static int zpool_do_add(int, char **);
  62 static int zpool_do_remove(int, char **);
  63 
  64 static int zpool_do_list(int, char **);
  65 static int zpool_do_iostat(int, char **);
  66 static int zpool_do_status(int, char **);
  67 
  68 static int zpool_do_online(int, char **);
  69 static int zpool_do_offline(int, char **);
  70 static int zpool_do_clear(int, char **);
  71 static int zpool_do_reopen(int, char **);
  72 
  73 static int zpool_do_reguid(int, char **);
  74 
  75 static int zpool_do_attach(int, char **);
  76 static int zpool_do_detach(int, char **);
  77 static int zpool_do_replace(int, char **);
  78 static int zpool_do_split(int, char **);
  79 
  80 static int zpool_do_scrub(int, char **);
  81 
  82 static int zpool_do_import(int, char **);
  83 static int zpool_do_export(int, char **);
  84 
  85 static int zpool_do_upgrade(int, char **);
  86 
  87 static int zpool_do_history(int, char **);
  88 
  89 static int zpool_do_get(int, char **);
  90 static int zpool_do_set(int, char **);
  91 
  92 /*
  93  * These libumem hooks provide a reasonable set of defaults for the allocator's
  94  * debugging facilities.
  95  */
  96 
  97 #ifdef DEBUG
  98 const char *
  99 _umem_debug_init(void)
 100 {
 101         return ("default,verbose"); /* $UMEM_DEBUG setting */
 102 }
 103 
 104 const char *
 105 _umem_logging_init(void)
 106 {
 107         return ("fail,contents"); /* $UMEM_LOGGING setting */
 108 }
 109 #endif
 110 
 111 typedef enum {
 112         HELP_ADD,
 113         HELP_ATTACH,
 114         HELP_CLEAR,
 115         HELP_CREATE,
 116         HELP_DESTROY,
 117         HELP_DETACH,
 118         HELP_EXPORT,
 119         HELP_HISTORY,
 120         HELP_IMPORT,
 121         HELP_IOSTAT,
 122         HELP_LIST,
 123         HELP_OFFLINE,
 124         HELP_ONLINE,
 125         HELP_REPLACE,
 126         HELP_REMOVE,
 127         HELP_SCRUB,
 128         HELP_STATUS,
 129         HELP_UPGRADE,
 130         HELP_GET,
 131         HELP_SET,
 132         HELP_SPLIT,
 133         HELP_REGUID,
 134         HELP_REOPEN
 135 } zpool_help_t;
 136 
 137 
 138 typedef struct zpool_command {
 139         const char      *name;
 140         int             (*func)(int, char **);
 141         zpool_help_t    usage;
 142 } zpool_command_t;
 143 
 144 /*
 145  * Master command table.  Each ZFS command has a name, associated function, and
 146  * usage message.  The usage messages need to be internationalized, so we have
 147  * to have a function to return the usage message based on a command index.
 148  *
 149  * These commands are organized according to how they are displayed in the usage
 150  * message.  An empty command (one with a NULL name) indicates an empty line in
 151  * the generic usage message.
 152  */
 153 static zpool_command_t command_table[] = {
 154         { "create",     zpool_do_create,        HELP_CREATE             },
 155         { "destroy",    zpool_do_destroy,       HELP_DESTROY            },
 156         { NULL },
 157         { "add",        zpool_do_add,           HELP_ADD                },
 158         { "remove",     zpool_do_remove,        HELP_REMOVE             },
 159         { NULL },
 160         { "list",       zpool_do_list,          HELP_LIST               },
 161         { "iostat",     zpool_do_iostat,        HELP_IOSTAT             },
 162         { "status",     zpool_do_status,        HELP_STATUS             },
 163         { NULL },
 164         { "online",     zpool_do_online,        HELP_ONLINE             },
 165         { "offline",    zpool_do_offline,       HELP_OFFLINE            },
 166         { "clear",      zpool_do_clear,         HELP_CLEAR              },
 167         { "reopen",     zpool_do_reopen,        HELP_REOPEN             },
 168         { NULL },
 169         { "attach",     zpool_do_attach,        HELP_ATTACH             },
 170         { "detach",     zpool_do_detach,        HELP_DETACH             },
 171         { "replace",    zpool_do_replace,       HELP_REPLACE            },
 172         { "split",      zpool_do_split,         HELP_SPLIT              },
 173         { NULL },
 174         { "scrub",      zpool_do_scrub,         HELP_SCRUB              },
 175         { NULL },
 176         { "import",     zpool_do_import,        HELP_IMPORT             },
 177         { "export",     zpool_do_export,        HELP_EXPORT             },
 178         { "upgrade",    zpool_do_upgrade,       HELP_UPGRADE            },
 179         { "reguid",     zpool_do_reguid,        HELP_REGUID             },
 180         { NULL },
 181         { "history",    zpool_do_history,       HELP_HISTORY            },
 182         { "get",        zpool_do_get,           HELP_GET                },
 183         { "set",        zpool_do_set,           HELP_SET                },
 184 };
 185 
 186 #define NCOMMAND        (sizeof (command_table) / sizeof (command_table[0]))
 187 
 188 zpool_command_t *current_command;
 189 static char history_str[HIS_MAX_RECORD_LEN];
 190 
 191 static uint_t timestamp_fmt = NODATE;
 192 
 193 static const char *
 194 get_usage(zpool_help_t idx) {
 195         switch (idx) {
 196         case HELP_ADD:
 197                 return (gettext("\tadd [-fn] <pool> <vdev> ...\n"));
 198         case HELP_ATTACH:
 199                 return (gettext("\tattach [-f] <pool> <device> "
 200                     "<new-device>\n"));
 201         case HELP_CLEAR:
 202                 return (gettext("\tclear [-nF] <pool> [device]\n"));
 203         case HELP_CREATE:
 204                 return (gettext("\tcreate [-fnd] [-o property=value] ... \n"
 205                     "\t    [-O file-system-property=value] ... \n"
 206                     "\t    [-m mountpoint] [-R root] <pool> <vdev> ...\n"));
 207         case HELP_DESTROY:
 208                 return (gettext("\tdestroy [-f] <pool>\n"));
 209         case HELP_DETACH:
 210                 return (gettext("\tdetach <pool> <device>\n"));
 211         case HELP_EXPORT:
 212                 return (gettext("\texport [-f] <pool> ...\n"));
 213         case HELP_HISTORY:
 214                 return (gettext("\thistory [-il] [<pool>] ...\n"));
 215         case HELP_IMPORT:
 216                 return (gettext("\timport [-d dir] [-D]\n"
 217                     "\timport [-d dir | -c cachefile] [-F [-n]] <pool | id>\n"
 218                     "\timport [-o mntopts] [-o property=value] ... \n"
 219                     "\t    [-d dir | -c cachefile] [-D] [-f] [-m] [-N] "
 220                     "[-R root] [-F [-n]] -a\n"
 221                     "\timport [-o mntopts] [-o property=value] ... \n"
 222                     "\t    [-d dir | -c cachefile] [-D] [-f] [-m] [-N] "
 223                     "[-R root] [-F [-n]]\n"
 224                     "\t    <pool | id> [newpool]\n"));
 225         case HELP_IOSTAT:
 226                 return (gettext("\tiostat [-v] [-T d|u] [pool] ... [interval "
 227                     "[count]]\n"));
 228         case HELP_LIST:
 229                 return (gettext("\tlist [-H] [-o property[,...]] "
 230                     "[-T d|u] [pool] ... [interval [count]]\n"));
 231         case HELP_OFFLINE:
 232                 return (gettext("\toffline [-t] <pool> <device> ...\n"));
 233         case HELP_ONLINE:
 234                 return (gettext("\tonline <pool> <device> ...\n"));
 235         case HELP_REPLACE:
 236                 return (gettext("\treplace [-f] <pool> <device> "
 237                     "[new-device]\n"));
 238         case HELP_REMOVE:
 239                 return (gettext("\tremove <pool> <device> ...\n"));
 240         case HELP_REOPEN:
 241                 return (""); /* Undocumented command */
 242         case HELP_SCRUB:
 243                 return (gettext("\tscrub [-s] <pool> ...\n"));
 244         case HELP_STATUS:
 245                 return (gettext("\tstatus [-vx] [-T d|u] [pool] ... [interval "
 246                     "[count]]\n"));
 247         case HELP_UPGRADE:
 248                 return (gettext("\tupgrade\n"
 249                     "\tupgrade -v\n"
 250                     "\tupgrade [-V version] <-a | pool ...>\n"));
 251         case HELP_GET:
 252                 return (gettext("\tget <\"all\" | property[,...]> "
 253                     "<pool> ...\n"));
 254         case HELP_SET:
 255                 return (gettext("\tset <property=value> <pool> \n"));
 256         case HELP_SPLIT:
 257                 return (gettext("\tsplit [-n] [-R altroot] [-o mntopts]\n"
 258                     "\t    [-o property=value] <pool> <newpool> "
 259                     "[<device> ...]\n"));
 260         case HELP_REGUID:
 261                 return (gettext("\treguid <pool>\n"));
 262         }
 263 
 264         abort();
 265         /* NOTREACHED */
 266 }
 267 
 268 
 269 /*
 270  * Callback routine that will print out a pool property value.
 271  */
 272 static int
 273 print_prop_cb(int prop, void *cb)
 274 {
 275         FILE *fp = cb;
 276 
 277         (void) fprintf(fp, "\t%-15s  ", zpool_prop_to_name(prop));
 278 
 279         if (zpool_prop_readonly(prop))
 280                 (void) fprintf(fp, "  NO   ");
 281         else
 282                 (void) fprintf(fp, " YES   ");
 283 
 284         if (zpool_prop_values(prop) == NULL)
 285                 (void) fprintf(fp, "-\n");
 286         else
 287                 (void) fprintf(fp, "%s\n", zpool_prop_values(prop));
 288 
 289         return (ZPROP_CONT);
 290 }
 291 
 292 /*
 293  * Display usage message.  If we're inside a command, display only the usage for
 294  * that command.  Otherwise, iterate over the entire command table and display
 295  * a complete usage message.
 296  */
 297 void
 298 usage(boolean_t requested)
 299 {
 300         FILE *fp = requested ? stdout : stderr;
 301 
 302         if (current_command == NULL) {
 303                 int i;
 304 
 305                 (void) fprintf(fp, gettext("usage: zpool command args ...\n"));
 306                 (void) fprintf(fp,
 307                     gettext("where 'command' is one of the following:\n\n"));
 308 
 309                 for (i = 0; i < NCOMMAND; i++) {
 310                         if (command_table[i].name == NULL)
 311                                 (void) fprintf(fp, "\n");
 312                         else
 313                                 (void) fprintf(fp, "%s",
 314                                     get_usage(command_table[i].usage));
 315                 }
 316         } else {
 317                 (void) fprintf(fp, gettext("usage:\n"));
 318                 (void) fprintf(fp, "%s", get_usage(current_command->usage));
 319         }
 320 
 321         if (current_command != NULL &&
 322             ((strcmp(current_command->name, "set") == 0) ||
 323             (strcmp(current_command->name, "get") == 0) ||
 324             (strcmp(current_command->name, "list") == 0))) {
 325 
 326                 (void) fprintf(fp,
 327                     gettext("\nthe following properties are supported:\n"));
 328 
 329                 (void) fprintf(fp, "\n\t%-15s  %s   %s\n\n",
 330                     "PROPERTY", "EDIT", "VALUES");
 331 
 332                 /* Iterate over all properties */
 333                 (void) zprop_iter(print_prop_cb, fp, B_FALSE, B_TRUE,
 334                     ZFS_TYPE_POOL);
 335 
 336                 (void) fprintf(fp, "\t%-15s   ", "feature@...");
 337                 (void) fprintf(fp, "YES   disabled | enabled | active\n");
 338 
 339                 (void) fprintf(fp, gettext("\nThe feature@ properties must be "
 340                     "appended with a feature name.\nSee zpool-features(5).\n"));
 341         }
 342 
 343         /*
 344          * See comments at end of main().
 345          */
 346         if (getenv("ZFS_ABORT") != NULL) {
 347                 (void) printf("dumping core by request\n");
 348                 abort();
 349         }
 350 
 351         exit(requested ? 0 : 2);
 352 }
 353 
 354 void
 355 print_vdev_tree(zpool_handle_t *zhp, const char *name, nvlist_t *nv, int indent,
 356     boolean_t print_logs)
 357 {
 358         nvlist_t **child;
 359         uint_t c, children;
 360         char *vname;
 361 
 362         if (name != NULL)
 363                 (void) printf("\t%*s%s\n", indent, "", name);
 364 
 365         if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
 366             &child, &children) != 0)
 367                 return;
 368 
 369         for (c = 0; c < children; c++) {
 370                 uint64_t is_log = B_FALSE;
 371 
 372                 (void) nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_LOG,
 373                     &is_log);
 374                 if ((is_log && !print_logs) || (!is_log && print_logs))
 375                         continue;
 376 
 377                 vname = zpool_vdev_name(g_zfs, zhp, child[c], B_FALSE);
 378                 print_vdev_tree(zhp, vname, child[c], indent + 2,
 379                     B_FALSE);
 380                 free(vname);
 381         }
 382 }
 383 
 384 /*
 385  * Add a property pair (name, string-value) into a property nvlist.
 386  */
 387 static int
 388 add_prop_list(const char *propname, char *propval, nvlist_t **props,
 389     boolean_t poolprop)
 390 {
 391         zpool_prop_t prop = ZPROP_INVAL;
 392         zfs_prop_t fprop;
 393         nvlist_t *proplist;
 394         const char *normnm;
 395         char *strval;
 396 
 397         if (*props == NULL &&
 398             nvlist_alloc(props, NV_UNIQUE_NAME, 0) != 0) {
 399                 (void) fprintf(stderr,
 400                     gettext("internal error: out of memory\n"));
 401                 return (1);
 402         }
 403 
 404         proplist = *props;
 405 
 406         if (poolprop) {
 407                 if ((prop = zpool_name_to_prop(propname)) == ZPROP_INVAL &&
 408                     !zpool_prop_feature(propname)) {
 409                         (void) fprintf(stderr, gettext("property '%s' is "
 410                             "not a valid pool property\n"), propname);
 411                         return (2);
 412                 }
 413                 if (zpool_prop_feature(propname))
 414                         normnm = propname;
 415                 else
 416                         normnm = zpool_prop_to_name(prop);
 417         } else {
 418                 if ((fprop = zfs_name_to_prop(propname)) != ZPROP_INVAL) {
 419                         normnm = zfs_prop_to_name(fprop);
 420                 } else {
 421                         normnm = propname;
 422                 }
 423         }
 424 
 425         if (nvlist_lookup_string(proplist, normnm, &strval) == 0 &&
 426             prop != ZPOOL_PROP_CACHEFILE) {
 427                 (void) fprintf(stderr, gettext("property '%s' "
 428                     "specified multiple times\n"), propname);
 429                 return (2);
 430         }
 431 
 432         if (nvlist_add_string(proplist, normnm, propval) != 0) {
 433                 (void) fprintf(stderr, gettext("internal "
 434                     "error: out of memory\n"));
 435                 return (1);
 436         }
 437 
 438         return (0);
 439 }
 440 
 441 /*
 442  * zpool add [-fn] <pool> <vdev> ...
 443  *
 444  *      -f      Force addition of devices, even if they appear in use
 445  *      -n      Do not add the devices, but display the resulting layout if
 446  *              they were to be added.
 447  *
 448  * Adds the given vdevs to 'pool'.  As with create, the bulk of this work is
 449  * handled by get_vdev_spec(), which constructs the nvlist needed to pass to
 450  * libzfs.
 451  */
 452 int
 453 zpool_do_add(int argc, char **argv)
 454 {
 455         boolean_t force = B_FALSE;
 456         boolean_t dryrun = B_FALSE;
 457         int c;
 458         nvlist_t *nvroot;
 459         char *poolname;
 460         int ret;
 461         zpool_handle_t *zhp;
 462         nvlist_t *config;
 463 
 464         /* check options */
 465         while ((c = getopt(argc, argv, "fn")) != -1) {
 466                 switch (c) {
 467                 case 'f':
 468                         force = B_TRUE;
 469                         break;
 470                 case 'n':
 471                         dryrun = B_TRUE;
 472                         break;
 473                 case '?':
 474                         (void) fprintf(stderr, gettext("invalid option '%c'\n"),
 475                             optopt);
 476                         usage(B_FALSE);
 477                 }
 478         }
 479 
 480         argc -= optind;
 481         argv += optind;
 482 
 483         /* get pool name and check number of arguments */
 484         if (argc < 1) {
 485                 (void) fprintf(stderr, gettext("missing pool name argument\n"));
 486                 usage(B_FALSE);
 487         }
 488         if (argc < 2) {
 489                 (void) fprintf(stderr, gettext("missing vdev specification\n"));
 490                 usage(B_FALSE);
 491         }
 492 
 493         poolname = argv[0];
 494 
 495         argc--;
 496         argv++;
 497 
 498         if ((zhp = zpool_open(g_zfs, poolname)) == NULL)
 499                 return (1);
 500 
 501         if ((config = zpool_get_config(zhp, NULL)) == NULL) {
 502                 (void) fprintf(stderr, gettext("pool '%s' is unavailable\n"),
 503                     poolname);
 504                 zpool_close(zhp);
 505                 return (1);
 506         }
 507 
 508         /* pass off to get_vdev_spec for processing */
 509         nvroot = make_root_vdev(zhp, force, !force, B_FALSE, dryrun,
 510             argc, argv);
 511         if (nvroot == NULL) {
 512                 zpool_close(zhp);
 513                 return (1);
 514         }
 515 
 516         if (dryrun) {
 517                 nvlist_t *poolnvroot;
 518 
 519                 verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
 520                     &poolnvroot) == 0);
 521 
 522                 (void) printf(gettext("would update '%s' to the following "
 523                     "configuration:\n"), zpool_get_name(zhp));
 524 
 525                 /* print original main pool and new tree */
 526                 print_vdev_tree(zhp, poolname, poolnvroot, 0, B_FALSE);
 527                 print_vdev_tree(zhp, NULL, nvroot, 0, B_FALSE);
 528 
 529                 /* Do the same for the logs */
 530                 if (num_logs(poolnvroot) > 0) {
 531                         print_vdev_tree(zhp, "logs", poolnvroot, 0, B_TRUE);
 532                         print_vdev_tree(zhp, NULL, nvroot, 0, B_TRUE);
 533                 } else if (num_logs(nvroot) > 0) {
 534                         print_vdev_tree(zhp, "logs", nvroot, 0, B_TRUE);
 535                 }
 536 
 537                 ret = 0;
 538         } else {
 539                 ret = (zpool_add(zhp, nvroot) != 0);
 540         }
 541 
 542         nvlist_free(nvroot);
 543         zpool_close(zhp);
 544 
 545         return (ret);
 546 }
 547 
 548 /*
 549  * zpool remove  <pool> <vdev> ...
 550  *
 551  * Removes the given vdev from the pool.  Currently, this supports removing
 552  * spares, cache, and log devices from the pool.
 553  */
 554 int
 555 zpool_do_remove(int argc, char **argv)
 556 {
 557         char *poolname;
 558         int i, ret = 0;
 559         zpool_handle_t *zhp;
 560 
 561         argc--;
 562         argv++;
 563 
 564         /* get pool name and check number of arguments */
 565         if (argc < 1) {
 566                 (void) fprintf(stderr, gettext("missing pool name argument\n"));
 567                 usage(B_FALSE);
 568         }
 569         if (argc < 2) {
 570                 (void) fprintf(stderr, gettext("missing device\n"));
 571                 usage(B_FALSE);
 572         }
 573 
 574         poolname = argv[0];
 575 
 576         if ((zhp = zpool_open(g_zfs, poolname)) == NULL)
 577                 return (1);
 578 
 579         for (i = 1; i < argc; i++) {
 580                 if (zpool_vdev_remove(zhp, argv[i]) != 0)
 581                         ret = 1;
 582         }
 583 
 584         return (ret);
 585 }
 586 
 587 /*
 588  * zpool create [-fnd] [-o property=value] ...
 589  *              [-O file-system-property=value] ...
 590  *              [-R root] [-m mountpoint] <pool> <dev> ...
 591  *
 592  *      -f      Force creation, even if devices appear in use
 593  *      -n      Do not create the pool, but display the resulting layout if it
 594  *              were to be created.
 595  *      -R      Create a pool under an alternate root
 596  *      -m      Set default mountpoint for the root dataset.  By default it's
 597  *              '/<pool>'
 598  *      -o      Set property=value.
 599  *      -d      Don't automatically enable all supported pool features
 600  *              (individual features can be enabled with -o).
 601  *      -O      Set fsproperty=value in the pool's root file system
 602  *
 603  * Creates the named pool according to the given vdev specification.  The
 604  * bulk of the vdev processing is done in get_vdev_spec() in zpool_vdev.c.  Once
 605  * we get the nvlist back from get_vdev_spec(), we either print out the contents
 606  * (if '-n' was specified), or pass it to libzfs to do the creation.
 607  */
 608 int
 609 zpool_do_create(int argc, char **argv)
 610 {
 611         boolean_t force = B_FALSE;
 612         boolean_t dryrun = B_FALSE;
 613         boolean_t enable_all_pool_feat = B_TRUE;
 614         int c;
 615         nvlist_t *nvroot = NULL;
 616         char *poolname;
 617         int ret = 1;
 618         char *altroot = NULL;
 619         char *mountpoint = NULL;
 620         nvlist_t *fsprops = NULL;
 621         nvlist_t *props = NULL;
 622         char *propval;
 623 
 624         /* check options */
 625         while ((c = getopt(argc, argv, ":fndR:m:o:O:")) != -1) {
 626                 switch (c) {
 627                 case 'f':
 628                         force = B_TRUE;
 629                         break;
 630                 case 'n':
 631                         dryrun = B_TRUE;
 632                         break;
 633                 case 'd':
 634                         enable_all_pool_feat = B_FALSE;
 635                         break;
 636                 case 'R':
 637                         altroot = optarg;
 638                         if (add_prop_list(zpool_prop_to_name(
 639                             ZPOOL_PROP_ALTROOT), optarg, &props, B_TRUE))
 640                                 goto errout;
 641                         if (nvlist_lookup_string(props,
 642                             zpool_prop_to_name(ZPOOL_PROP_CACHEFILE),
 643                             &propval) == 0)
 644                                 break;
 645                         if (add_prop_list(zpool_prop_to_name(
 646                             ZPOOL_PROP_CACHEFILE), "none", &props, B_TRUE))
 647                                 goto errout;
 648                         break;
 649                 case 'm':
 650                         mountpoint = optarg;
 651                         break;
 652                 case 'o':
 653                         if ((propval = strchr(optarg, '=')) == NULL) {
 654                                 (void) fprintf(stderr, gettext("missing "
 655                                     "'=' for -o option\n"));
 656                                 goto errout;
 657                         }
 658                         *propval = '\0';
 659                         propval++;
 660 
 661                         if (add_prop_list(optarg, propval, &props, B_TRUE))
 662                                 goto errout;
 663 
 664                         /*
 665                          * If the user is creating a pool that doesn't support
 666                          * feature flags, don't enable any features.
 667                          */
 668                         if (zpool_name_to_prop(optarg) == ZPOOL_PROP_VERSION) {
 669                                 char *end;
 670                                 u_longlong_t ver;
 671 
 672                                 ver = strtoull(propval, &end, 10);
 673                                 if (*end == '\0' &&
 674                                     ver < SPA_VERSION_FEATURES) {
 675                                         enable_all_pool_feat = B_FALSE;
 676                                 }
 677                         }
 678                         break;
 679                 case 'O':
 680                         if ((propval = strchr(optarg, '=')) == NULL) {
 681                                 (void) fprintf(stderr, gettext("missing "
 682                                     "'=' for -O option\n"));
 683                                 goto errout;
 684                         }
 685                         *propval = '\0';
 686                         propval++;
 687 
 688                         if (add_prop_list(optarg, propval, &fsprops, B_FALSE))
 689                                 goto errout;
 690                         break;
 691                 case ':':
 692                         (void) fprintf(stderr, gettext("missing argument for "
 693                             "'%c' option\n"), optopt);
 694                         goto badusage;
 695                 case '?':
 696                         (void) fprintf(stderr, gettext("invalid option '%c'\n"),
 697                             optopt);
 698                         goto badusage;
 699                 }
 700         }
 701 
 702         argc -= optind;
 703         argv += optind;
 704 
 705         /* get pool name and check number of arguments */
 706         if (argc < 1) {
 707                 (void) fprintf(stderr, gettext("missing pool name argument\n"));
 708                 goto badusage;
 709         }
 710         if (argc < 2) {
 711                 (void) fprintf(stderr, gettext("missing vdev specification\n"));
 712                 goto badusage;
 713         }
 714 
 715         poolname = argv[0];
 716 
 717         /*
 718          * As a special case, check for use of '/' in the name, and direct the
 719          * user to use 'zfs create' instead.
 720          */
 721         if (strchr(poolname, '/') != NULL) {
 722                 (void) fprintf(stderr, gettext("cannot create '%s': invalid "
 723                     "character '/' in pool name\n"), poolname);
 724                 (void) fprintf(stderr, gettext("use 'zfs create' to "
 725                     "create a dataset\n"));
 726                 goto errout;
 727         }
 728 
 729         /* pass off to get_vdev_spec for bulk processing */
 730         nvroot = make_root_vdev(NULL, force, !force, B_FALSE, dryrun,
 731             argc - 1, argv + 1);
 732         if (nvroot == NULL)
 733                 goto errout;
 734 
 735         /* make_root_vdev() allows 0 toplevel children if there are spares */
 736         if (!zfs_allocatable_devs(nvroot)) {
 737                 (void) fprintf(stderr, gettext("invalid vdev "
 738                     "specification: at least one toplevel vdev must be "
 739                     "specified\n"));
 740                 goto errout;
 741         }
 742 
 743         if (altroot != NULL && altroot[0] != '/') {
 744                 (void) fprintf(stderr, gettext("invalid alternate root '%s': "
 745                     "must be an absolute path\n"), altroot);
 746                 goto errout;
 747         }
 748 
 749         /*
 750          * Check the validity of the mountpoint and direct the user to use the
 751          * '-m' mountpoint option if it looks like its in use.
 752          */
 753         if (mountpoint == NULL ||
 754             (strcmp(mountpoint, ZFS_MOUNTPOINT_LEGACY) != 0 &&
 755             strcmp(mountpoint, ZFS_MOUNTPOINT_NONE) != 0)) {
 756                 char buf[MAXPATHLEN];
 757                 DIR *dirp;
 758 
 759                 if (mountpoint && mountpoint[0] != '/') {
 760                         (void) fprintf(stderr, gettext("invalid mountpoint "
 761                             "'%s': must be an absolute path, 'legacy', or "
 762                             "'none'\n"), mountpoint);
 763                         goto errout;
 764                 }
 765 
 766                 if (mountpoint == NULL) {
 767                         if (altroot != NULL)
 768                                 (void) snprintf(buf, sizeof (buf), "%s/%s",
 769                                     altroot, poolname);
 770                         else
 771                                 (void) snprintf(buf, sizeof (buf), "/%s",
 772                                     poolname);
 773                 } else {
 774                         if (altroot != NULL)
 775                                 (void) snprintf(buf, sizeof (buf), "%s%s",
 776                                     altroot, mountpoint);
 777                         else
 778                                 (void) snprintf(buf, sizeof (buf), "%s",
 779                                     mountpoint);
 780                 }
 781 
 782                 if ((dirp = opendir(buf)) == NULL && errno != ENOENT) {
 783                         (void) fprintf(stderr, gettext("mountpoint '%s' : "
 784                             "%s\n"), buf, strerror(errno));
 785                         (void) fprintf(stderr, gettext("use '-m' "
 786                             "option to provide a different default\n"));
 787                         goto errout;
 788                 } else if (dirp) {
 789                         int count = 0;
 790 
 791                         while (count < 3 && readdir(dirp) != NULL)
 792                                 count++;
 793                         (void) closedir(dirp);
 794 
 795                         if (count > 2) {
 796                                 (void) fprintf(stderr, gettext("mountpoint "
 797                                     "'%s' exists and is not empty\n"), buf);
 798                                 (void) fprintf(stderr, gettext("use '-m' "
 799                                     "option to provide a "
 800                                     "different default\n"));
 801                                 goto errout;
 802                         }
 803                 }
 804         }
 805 
 806         if (dryrun) {
 807                 /*
 808                  * For a dry run invocation, print out a basic message and run
 809                  * through all the vdevs in the list and print out in an
 810                  * appropriate hierarchy.
 811                  */
 812                 (void) printf(gettext("would create '%s' with the "
 813                     "following layout:\n\n"), poolname);
 814 
 815                 print_vdev_tree(NULL, poolname, nvroot, 0, B_FALSE);
 816                 if (num_logs(nvroot) > 0)
 817                         print_vdev_tree(NULL, "logs", nvroot, 0, B_TRUE);
 818 
 819                 ret = 0;
 820         } else {
 821                 /*
 822                  * Hand off to libzfs.
 823                  */
 824                 if (enable_all_pool_feat) {
 825                         int i;
 826                         for (i = 0; i < SPA_FEATURES; i++) {
 827                                 char propname[MAXPATHLEN];
 828                                 zfeature_info_t *feat = &spa_feature_table[i];
 829 
 830                                 (void) snprintf(propname, sizeof (propname),
 831                                     "feature@%s", feat->fi_uname);
 832 
 833                                 /*
 834                                  * Skip feature if user specified it manually
 835                                  * on the command line.
 836                                  */
 837                                 if (nvlist_exists(props, propname))
 838                                         continue;
 839 
 840                                 if (add_prop_list(propname, ZFS_FEATURE_ENABLED,
 841                                     &props, B_TRUE) != 0)
 842                                         goto errout;
 843                         }
 844                 }
 845                 if (zpool_create(g_zfs, poolname,
 846                     nvroot, props, fsprops) == 0) {
 847                         zfs_handle_t *pool = zfs_open(g_zfs, poolname,
 848                             ZFS_TYPE_FILESYSTEM);
 849                         if (pool != NULL) {
 850                                 if (mountpoint != NULL)
 851                                         verify(zfs_prop_set(pool,
 852                                             zfs_prop_to_name(
 853                                             ZFS_PROP_MOUNTPOINT),
 854                                             mountpoint) == 0);
 855                                 if (zfs_mount(pool, NULL, 0) == 0)
 856                                         ret = zfs_shareall(pool);
 857                                 zfs_close(pool);
 858                         }
 859                 } else if (libzfs_errno(g_zfs) == EZFS_INVALIDNAME) {
 860                         (void) fprintf(stderr, gettext("pool name may have "
 861                             "been omitted\n"));
 862                 }
 863         }
 864 
 865 errout:
 866         nvlist_free(nvroot);
 867         nvlist_free(fsprops);
 868         nvlist_free(props);
 869         return (ret);
 870 badusage:
 871         nvlist_free(fsprops);
 872         nvlist_free(props);
 873         usage(B_FALSE);
 874         return (2);
 875 }
 876 
 877 /*
 878  * zpool destroy <pool>
 879  *
 880  *      -f      Forcefully unmount any datasets
 881  *
 882  * Destroy the given pool.  Automatically unmounts any datasets in the pool.
 883  */
 884 int
 885 zpool_do_destroy(int argc, char **argv)
 886 {
 887         boolean_t force = B_FALSE;
 888         int c;
 889         char *pool;
 890         zpool_handle_t *zhp;
 891         int ret;
 892 
 893         /* check options */
 894         while ((c = getopt(argc, argv, "f")) != -1) {
 895                 switch (c) {
 896                 case 'f':
 897                         force = B_TRUE;
 898                         break;
 899                 case '?':
 900                         (void) fprintf(stderr, gettext("invalid option '%c'\n"),
 901                             optopt);
 902                         usage(B_FALSE);
 903                 }
 904         }
 905 
 906         argc -= optind;
 907         argv += optind;
 908 
 909         /* check arguments */
 910         if (argc < 1) {
 911                 (void) fprintf(stderr, gettext("missing pool argument\n"));
 912                 usage(B_FALSE);
 913         }
 914         if (argc > 1) {
 915                 (void) fprintf(stderr, gettext("too many arguments\n"));
 916                 usage(B_FALSE);
 917         }
 918 
 919         pool = argv[0];
 920 
 921         if ((zhp = zpool_open_canfail(g_zfs, pool)) == NULL) {
 922                 /*
 923                  * As a special case, check for use of '/' in the name, and
 924                  * direct the user to use 'zfs destroy' instead.
 925                  */
 926                 if (strchr(pool, '/') != NULL)
 927                         (void) fprintf(stderr, gettext("use 'zfs destroy' to "
 928                             "destroy a dataset\n"));
 929                 return (1);
 930         }
 931 
 932         if (zpool_disable_datasets(zhp, force) != 0) {
 933                 (void) fprintf(stderr, gettext("could not destroy '%s': "
 934                     "could not unmount datasets\n"), zpool_get_name(zhp));
 935                 return (1);
 936         }
 937 
 938         ret = (zpool_destroy(zhp) != 0);
 939 
 940         zpool_close(zhp);
 941 
 942         return (ret);
 943 }
 944 
 945 /*
 946  * zpool export [-f] <pool> ...
 947  *
 948  *      -f      Forcefully unmount datasets
 949  *
 950  * Export the given pools.  By default, the command will attempt to cleanly
 951  * unmount any active datasets within the pool.  If the '-f' flag is specified,
 952  * then the datasets will be forcefully unmounted.
 953  */
 954 int
 955 zpool_do_export(int argc, char **argv)
 956 {
 957         boolean_t force = B_FALSE;
 958         boolean_t hardforce = B_FALSE;
 959         int c;
 960         zpool_handle_t *zhp;
 961         int ret;
 962         int i;
 963 
 964         /* check options */
 965         while ((c = getopt(argc, argv, "fF")) != -1) {
 966                 switch (c) {
 967                 case 'f':
 968                         force = B_TRUE;
 969                         break;
 970                 case 'F':
 971                         hardforce = B_TRUE;
 972                         break;
 973                 case '?':
 974                         (void) fprintf(stderr, gettext("invalid option '%c'\n"),
 975                             optopt);
 976                         usage(B_FALSE);
 977                 }
 978         }
 979 
 980         argc -= optind;
 981         argv += optind;
 982 
 983         /* check arguments */
 984         if (argc < 1) {
 985                 (void) fprintf(stderr, gettext("missing pool argument\n"));
 986                 usage(B_FALSE);
 987         }
 988 
 989         ret = 0;
 990         for (i = 0; i < argc; i++) {
 991                 if ((zhp = zpool_open_canfail(g_zfs, argv[i])) == NULL) {
 992                         ret = 1;
 993                         continue;
 994                 }
 995 
 996                 if (zpool_disable_datasets(zhp, force) != 0) {
 997                         ret = 1;
 998                         zpool_close(zhp);
 999                         continue;
1000                 }
1001 
1002                 if (hardforce) {
1003                         if (zpool_export_force(zhp) != 0)
1004                                 ret = 1;
1005                 } else if (zpool_export(zhp, force) != 0) {
1006                         ret = 1;
1007                 }
1008 
1009                 zpool_close(zhp);
1010         }
1011 
1012         return (ret);
1013 }
1014 
1015 /*
1016  * Given a vdev configuration, determine the maximum width needed for the device
1017  * name column.
1018  */
1019 static int
1020 max_width(zpool_handle_t *zhp, nvlist_t *nv, int depth, int max)
1021 {
1022         char *name = zpool_vdev_name(g_zfs, zhp, nv, B_TRUE);
1023         nvlist_t **child;
1024         uint_t c, children;
1025         int ret;
1026 
1027         if (strlen(name) + depth > max)
1028                 max = strlen(name) + depth;
1029 
1030         free(name);
1031 
1032         if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_SPARES,
1033             &child, &children) == 0) {
1034                 for (c = 0; c < children; c++)
1035                         if ((ret = max_width(zhp, child[c], depth + 2,
1036                             max)) > max)
1037                                 max = ret;
1038         }
1039 
1040         if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_L2CACHE,
1041             &child, &children) == 0) {
1042                 for (c = 0; c < children; c++)
1043                         if ((ret = max_width(zhp, child[c], depth + 2,
1044                             max)) > max)
1045                                 max = ret;
1046         }
1047 
1048         if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
1049             &child, &children) == 0) {
1050                 for (c = 0; c < children; c++)
1051                         if ((ret = max_width(zhp, child[c], depth + 2,
1052                             max)) > max)
1053                                 max = ret;
1054         }
1055 
1056 
1057         return (max);
1058 }
1059 
1060 typedef struct spare_cbdata {
1061         uint64_t        cb_guid;
1062         zpool_handle_t  *cb_zhp;
1063 } spare_cbdata_t;
1064 
1065 static boolean_t
1066 find_vdev(nvlist_t *nv, uint64_t search)
1067 {
1068         uint64_t guid;
1069         nvlist_t **child;
1070         uint_t c, children;
1071 
1072         if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_GUID, &guid) == 0 &&
1073             search == guid)
1074                 return (B_TRUE);
1075 
1076         if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
1077             &child, &children) == 0) {
1078                 for (c = 0; c < children; c++)
1079                         if (find_vdev(child[c], search))
1080                                 return (B_TRUE);
1081         }
1082 
1083         return (B_FALSE);
1084 }
1085 
1086 static int
1087 find_spare(zpool_handle_t *zhp, void *data)
1088 {
1089         spare_cbdata_t *cbp = data;
1090         nvlist_t *config, *nvroot;
1091 
1092         config = zpool_get_config(zhp, NULL);
1093         verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
1094             &nvroot) == 0);
1095 
1096         if (find_vdev(nvroot, cbp->cb_guid)) {
1097                 cbp->cb_zhp = zhp;
1098                 return (1);
1099         }
1100 
1101         zpool_close(zhp);
1102         return (0);
1103 }
1104 
1105 /*
1106  * Print out configuration state as requested by status_callback.
1107  */
1108 void
1109 print_status_config(zpool_handle_t *zhp, const char *name, nvlist_t *nv,
1110     int namewidth, int depth, boolean_t isspare)
1111 {
1112         nvlist_t **child;
1113         uint_t c, children;
1114         pool_scan_stat_t *ps = NULL;
1115         vdev_stat_t *vs;
1116         char rbuf[6], wbuf[6], cbuf[6];
1117         char *vname;
1118         uint64_t notpresent;
1119         spare_cbdata_t cb;
1120         char *state;
1121 
1122         if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
1123             &child, &children) != 0)
1124                 children = 0;
1125 
1126         verify(nvlist_lookup_uint64_array(nv, ZPOOL_CONFIG_VDEV_STATS,
1127             (uint64_t **)&vs, &c) == 0);
1128 
1129         state = zpool_state_to_name(vs->vs_state, vs->vs_aux);
1130         if (isspare) {
1131                 /*
1132                  * For hot spares, we use the terms 'INUSE' and 'AVAILABLE' for
1133                  * online drives.
1134                  */
1135                 if (vs->vs_aux == VDEV_AUX_SPARED)
1136                         state = "INUSE";
1137                 else if (vs->vs_state == VDEV_STATE_HEALTHY)
1138                         state = "AVAIL";
1139         }
1140 
1141         (void) printf("\t%*s%-*s  %-8s", depth, "", namewidth - depth,
1142             name, state);
1143 
1144         if (!isspare) {
1145                 zfs_nicenum(vs->vs_read_errors, rbuf, sizeof (rbuf));
1146                 zfs_nicenum(vs->vs_write_errors, wbuf, sizeof (wbuf));
1147                 zfs_nicenum(vs->vs_checksum_errors, cbuf, sizeof (cbuf));
1148                 (void) printf(" %5s %5s %5s", rbuf, wbuf, cbuf);
1149         }
1150 
1151         if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_NOT_PRESENT,
1152             &notpresent) == 0) {
1153                 char *path;
1154                 verify(nvlist_lookup_string(nv, ZPOOL_CONFIG_PATH, &path) == 0);
1155                 (void) printf("  was %s", path);
1156         } else if (vs->vs_aux != 0) {
1157                 (void) printf("  ");
1158 
1159                 switch (vs->vs_aux) {
1160                 case VDEV_AUX_OPEN_FAILED:
1161                         (void) printf(gettext("cannot open"));
1162                         break;
1163 
1164                 case VDEV_AUX_BAD_GUID_SUM:
1165                         (void) printf(gettext("missing device"));
1166                         break;
1167 
1168                 case VDEV_AUX_NO_REPLICAS:
1169                         (void) printf(gettext("insufficient replicas"));
1170                         break;
1171 
1172                 case VDEV_AUX_VERSION_NEWER:
1173                         (void) printf(gettext("newer version"));
1174                         break;
1175 
1176                 case VDEV_AUX_UNSUP_FEAT:
1177                         (void) printf(gettext("unsupported feature(s)"));
1178                         break;
1179 
1180                 case VDEV_AUX_SPARED:
1181                         verify(nvlist_lookup_uint64(nv, ZPOOL_CONFIG_GUID,
1182                             &cb.cb_guid) == 0);
1183                         if (zpool_iter(g_zfs, find_spare, &cb) == 1) {
1184                                 if (strcmp(zpool_get_name(cb.cb_zhp),
1185                                     zpool_get_name(zhp)) == 0)
1186                                         (void) printf(gettext("currently in "
1187                                             "use"));
1188                                 else
1189                                         (void) printf(gettext("in use by "
1190                                             "pool '%s'"),
1191                                             zpool_get_name(cb.cb_zhp));
1192                                 zpool_close(cb.cb_zhp);
1193                         } else {
1194                                 (void) printf(gettext("currently in use"));
1195                         }
1196                         break;
1197 
1198                 case VDEV_AUX_ERR_EXCEEDED:
1199                         (void) printf(gettext("too many errors"));
1200                         break;
1201 
1202                 case VDEV_AUX_IO_FAILURE:
1203                         (void) printf(gettext("experienced I/O failures"));
1204                         break;
1205 
1206                 case VDEV_AUX_BAD_LOG:
1207                         (void) printf(gettext("bad intent log"));
1208                         break;
1209 
1210                 case VDEV_AUX_EXTERNAL:
1211                         (void) printf(gettext("external device fault"));
1212                         break;
1213 
1214                 case VDEV_AUX_SPLIT_POOL:
1215                         (void) printf(gettext("split into new pool"));
1216                         break;
1217 
1218                 default:
1219                         (void) printf(gettext("corrupted data"));
1220                         break;
1221                 }
1222         }
1223 
1224         (void) nvlist_lookup_uint64_array(nv, ZPOOL_CONFIG_SCAN_STATS,
1225             (uint64_t **)&ps, &c);
1226 
1227         if (ps && ps->pss_state == DSS_SCANNING &&
1228             vs->vs_scan_processed != 0 && children == 0) {
1229                 (void) printf(gettext("  (%s)"),
1230                     (ps->pss_func == POOL_SCAN_RESILVER) ?
1231                     "resilvering" : "repairing");
1232         }
1233 
1234         (void) printf("\n");
1235 
1236         for (c = 0; c < children; c++) {
1237                 uint64_t islog = B_FALSE, ishole = B_FALSE;
1238 
1239                 /* Don't print logs or holes here */
1240                 (void) nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_LOG,
1241                     &islog);
1242                 (void) nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_HOLE,
1243                     &ishole);
1244                 if (islog || ishole)
1245                         continue;
1246                 vname = zpool_vdev_name(g_zfs, zhp, child[c], B_TRUE);
1247                 print_status_config(zhp, vname, child[c],
1248                     namewidth, depth + 2, isspare);
1249                 free(vname);
1250         }
1251 }
1252 
1253 
1254 /*
1255  * Print the configuration of an exported pool.  Iterate over all vdevs in the
1256  * pool, printing out the name and status for each one.
1257  */
1258 void
1259 print_import_config(const char *name, nvlist_t *nv, int namewidth, int depth)
1260 {
1261         nvlist_t **child;
1262         uint_t c, children;
1263         vdev_stat_t *vs;
1264         char *type, *vname;
1265 
1266         verify(nvlist_lookup_string(nv, ZPOOL_CONFIG_TYPE, &type) == 0);
1267         if (strcmp(type, VDEV_TYPE_MISSING) == 0 ||
1268             strcmp(type, VDEV_TYPE_HOLE) == 0)
1269                 return;
1270 
1271         verify(nvlist_lookup_uint64_array(nv, ZPOOL_CONFIG_VDEV_STATS,
1272             (uint64_t **)&vs, &c) == 0);
1273 
1274         (void) printf("\t%*s%-*s", depth, "", namewidth - depth, name);
1275         (void) printf("  %s", zpool_state_to_name(vs->vs_state, vs->vs_aux));
1276 
1277         if (vs->vs_aux != 0) {
1278                 (void) printf("  ");
1279 
1280                 switch (vs->vs_aux) {
1281                 case VDEV_AUX_OPEN_FAILED:
1282                         (void) printf(gettext("cannot open"));
1283                         break;
1284 
1285                 case VDEV_AUX_BAD_GUID_SUM:
1286                         (void) printf(gettext("missing device"));
1287                         break;
1288 
1289                 case VDEV_AUX_NO_REPLICAS:
1290                         (void) printf(gettext("insufficient replicas"));
1291                         break;
1292 
1293                 case VDEV_AUX_VERSION_NEWER:
1294                         (void) printf(gettext("newer version"));
1295                         break;
1296 
1297                 case VDEV_AUX_UNSUP_FEAT:
1298                         (void) printf(gettext("unsupported feature(s)"));
1299                         break;
1300 
1301                 case VDEV_AUX_ERR_EXCEEDED:
1302                         (void) printf(gettext("too many errors"));
1303                         break;
1304 
1305                 default:
1306                         (void) printf(gettext("corrupted data"));
1307                         break;
1308                 }
1309         }
1310         (void) printf("\n");
1311 
1312         if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
1313             &child, &children) != 0)
1314                 return;
1315 
1316         for (c = 0; c < children; c++) {
1317                 uint64_t is_log = B_FALSE;
1318 
1319                 (void) nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_LOG,
1320                     &is_log);
1321                 if (is_log)
1322                         continue;
1323 
1324                 vname = zpool_vdev_name(g_zfs, NULL, child[c], B_TRUE);
1325                 print_import_config(vname, child[c], namewidth, depth + 2);
1326                 free(vname);
1327         }
1328 
1329         if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_L2CACHE,
1330             &child, &children) == 0) {
1331                 (void) printf(gettext("\tcache\n"));
1332                 for (c = 0; c < children; c++) {
1333                         vname = zpool_vdev_name(g_zfs, NULL, child[c], B_FALSE);
1334                         (void) printf("\t  %s\n", vname);
1335                         free(vname);
1336                 }
1337         }
1338 
1339         if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_SPARES,
1340             &child, &children) == 0) {
1341                 (void) printf(gettext("\tspares\n"));
1342                 for (c = 0; c < children; c++) {
1343                         vname = zpool_vdev_name(g_zfs, NULL, child[c], B_FALSE);
1344                         (void) printf("\t  %s\n", vname);
1345                         free(vname);
1346                 }
1347         }
1348 }
1349 
1350 /*
1351  * Print log vdevs.
1352  * Logs are recorded as top level vdevs in the main pool child array
1353  * but with "is_log" set to 1. We use either print_status_config() or
1354  * print_import_config() to print the top level logs then any log
1355  * children (eg mirrored slogs) are printed recursively - which
1356  * works because only the top level vdev is marked "is_log"
1357  */
1358 static void
1359 print_logs(zpool_handle_t *zhp, nvlist_t *nv, int namewidth, boolean_t verbose)
1360 {
1361         uint_t c, children;
1362         nvlist_t **child;
1363 
1364         if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN, &child,
1365             &children) != 0)
1366                 return;
1367 
1368         (void) printf(gettext("\tlogs\n"));
1369 
1370         for (c = 0; c < children; c++) {
1371                 uint64_t is_log = B_FALSE;
1372                 char *name;
1373 
1374                 (void) nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_LOG,
1375                     &is_log);
1376                 if (!is_log)
1377                         continue;
1378                 name = zpool_vdev_name(g_zfs, zhp, child[c], B_TRUE);
1379                 if (verbose)
1380                         print_status_config(zhp, name, child[c], namewidth,
1381                             2, B_FALSE);
1382                 else
1383                         print_import_config(name, child[c], namewidth, 2);
1384                 free(name);
1385         }
1386 }
1387 
1388 /*
1389  * Display the status for the given pool.
1390  */
1391 static void
1392 show_import(nvlist_t *config)
1393 {
1394         uint64_t pool_state;
1395         vdev_stat_t *vs;
1396         char *name;
1397         uint64_t guid;
1398         char *msgid;
1399         nvlist_t *nvroot;
1400         int reason;
1401         const char *health;
1402         uint_t vsc;
1403         int namewidth;
1404         char *comment;
1405 
1406         verify(nvlist_lookup_string(config, ZPOOL_CONFIG_POOL_NAME,
1407             &name) == 0);
1408         verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_GUID,
1409             &guid) == 0);
1410         verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_STATE,
1411             &pool_state) == 0);
1412         verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
1413             &nvroot) == 0);
1414 
1415         verify(nvlist_lookup_uint64_array(nvroot, ZPOOL_CONFIG_VDEV_STATS,
1416             (uint64_t **)&vs, &vsc) == 0);
1417         health = zpool_state_to_name(vs->vs_state, vs->vs_aux);
1418 
1419         reason = zpool_import_status(config, &msgid);
1420 
1421         (void) printf(gettext("   pool: %s\n"), name);
1422         (void) printf(gettext("     id: %llu\n"), (u_longlong_t)guid);
1423         (void) printf(gettext("  state: %s"), health);
1424         if (pool_state == POOL_STATE_DESTROYED)
1425                 (void) printf(gettext(" (DESTROYED)"));
1426         (void) printf("\n");
1427 
1428         switch (reason) {
1429         case ZPOOL_STATUS_MISSING_DEV_R:
1430         case ZPOOL_STATUS_MISSING_DEV_NR:
1431         case ZPOOL_STATUS_BAD_GUID_SUM:
1432                 (void) printf(gettext(" status: One or more devices are "
1433                     "missing from the system.\n"));
1434                 break;
1435 
1436         case ZPOOL_STATUS_CORRUPT_LABEL_R:
1437         case ZPOOL_STATUS_CORRUPT_LABEL_NR:
1438                 (void) printf(gettext(" status: One or more devices contains "
1439                     "corrupted data.\n"));
1440                 break;
1441 
1442         case ZPOOL_STATUS_CORRUPT_DATA:
1443                 (void) printf(
1444                     gettext(" status: The pool data is corrupted.\n"));
1445                 break;
1446 
1447         case ZPOOL_STATUS_OFFLINE_DEV:
1448                 (void) printf(gettext(" status: One or more devices "
1449                     "are offlined.\n"));
1450                 break;
1451 
1452         case ZPOOL_STATUS_CORRUPT_POOL:
1453                 (void) printf(gettext(" status: The pool metadata is "
1454                     "corrupted.\n"));
1455                 break;
1456 
1457         case ZPOOL_STATUS_VERSION_OLDER:
1458                 (void) printf(gettext(" status: The pool is formatted using an "
1459                     "older on-disk version.\n"));
1460                 break;
1461 
1462         case ZPOOL_STATUS_VERSION_NEWER:
1463                 (void) printf(gettext(" status: The pool is formatted using an "
1464                     "incompatible version.\n"));
1465                 break;
1466 
1467         case ZPOOL_STATUS_UNSUP_FEAT_READ:
1468                 (void) printf(gettext("status: The pool uses the following "
1469                     "feature(s) not supported on this sytem:\n"));
1470                 zpool_print_unsup_feat(config);
1471                 break;
1472 
1473         case ZPOOL_STATUS_UNSUP_FEAT_WRITE:
1474                 (void) printf(gettext("status: The pool can only be accessed "
1475                     "in read-only mode on this system. It\n\tcannot be "
1476                     "accessed in read-write mode because it uses the "
1477                     "following\n\tfeature(s) not supported on this system:\n"));
1478                 zpool_print_unsup_feat(config);
1479                 break;
1480 
1481         case ZPOOL_STATUS_HOSTID_MISMATCH:
1482                 (void) printf(gettext(" status: The pool was last accessed by "
1483                     "another system.\n"));
1484                 break;
1485 
1486         case ZPOOL_STATUS_FAULTED_DEV_R:
1487         case ZPOOL_STATUS_FAULTED_DEV_NR:
1488                 (void) printf(gettext(" status: One or more devices are "
1489                     "faulted.\n"));
1490                 break;
1491 
1492         case ZPOOL_STATUS_BAD_LOG:
1493                 (void) printf(gettext(" status: An intent log record cannot be "
1494                     "read.\n"));
1495                 break;
1496 
1497         case ZPOOL_STATUS_RESILVERING:
1498                 (void) printf(gettext(" status: One or more devices were being "
1499                     "resilvered.\n"));
1500                 break;
1501 
1502         default:
1503                 /*
1504                  * No other status can be seen when importing pools.
1505                  */
1506                 assert(reason == ZPOOL_STATUS_OK);
1507         }
1508 
1509         /*
1510          * Print out an action according to the overall state of the pool.
1511          */
1512         if (vs->vs_state == VDEV_STATE_HEALTHY) {
1513                 if (reason == ZPOOL_STATUS_VERSION_OLDER)
1514                         (void) printf(gettext(" action: The pool can be "
1515                             "imported using its name or numeric identifier, "
1516                             "though\n\tsome features will not be available "
1517                             "without an explicit 'zpool upgrade'.\n"));
1518                 else if (reason == ZPOOL_STATUS_HOSTID_MISMATCH)
1519                         (void) printf(gettext(" action: The pool can be "
1520                             "imported using its name or numeric "
1521                             "identifier and\n\tthe '-f' flag.\n"));
1522                 else
1523                         (void) printf(gettext(" action: The pool can be "
1524                             "imported using its name or numeric "
1525                             "identifier.\n"));
1526         } else if (vs->vs_state == VDEV_STATE_DEGRADED) {
1527                 (void) printf(gettext(" action: The pool can be imported "
1528                     "despite missing or damaged devices.  The\n\tfault "
1529                     "tolerance of the pool may be compromised if imported.\n"));
1530         } else {
1531                 switch (reason) {
1532                 case ZPOOL_STATUS_VERSION_NEWER:
1533                         (void) printf(gettext(" action: The pool cannot be "
1534                             "imported.  Access the pool on a system running "
1535                             "newer\n\tsoftware, or recreate the pool from "
1536                             "backup.\n"));
1537                         break;
1538                 case ZPOOL_STATUS_UNSUP_FEAT_READ:
1539                         (void) printf(gettext("action: The pool cannot be "
1540                             "imported. Access the pool on a system that "
1541                             "supports\n\tthe required feature(s), or recreate "
1542                             "the pool from backup.\n"));
1543                         break;
1544                 case ZPOOL_STATUS_UNSUP_FEAT_WRITE:
1545                         (void) printf(gettext("action: The pool cannot be "
1546                             "imported in read-write mode. Import the pool "
1547                             "with\n"
1548                             "\t\"-o readonly=on\", access the pool on a system "
1549                             "that supports the\n\trequired feature(s), or "
1550                             "recreate the pool from backup.\n"));
1551                         break;
1552                 case ZPOOL_STATUS_MISSING_DEV_R:
1553                 case ZPOOL_STATUS_MISSING_DEV_NR:
1554                 case ZPOOL_STATUS_BAD_GUID_SUM:
1555                         (void) printf(gettext(" action: The pool cannot be "
1556                             "imported. Attach the missing\n\tdevices and try "
1557                             "again.\n"));
1558                         break;
1559                 default:
1560                         (void) printf(gettext(" action: The pool cannot be "
1561                             "imported due to damaged devices or data.\n"));
1562                 }
1563         }
1564 
1565         /* Print the comment attached to the pool. */
1566         if (nvlist_lookup_string(config, ZPOOL_CONFIG_COMMENT, &comment) == 0)
1567                 (void) printf(gettext("comment: %s\n"), comment);
1568 
1569         /*
1570          * If the state is "closed" or "can't open", and the aux state
1571          * is "corrupt data":
1572          */
1573         if (((vs->vs_state == VDEV_STATE_CLOSED) ||
1574             (vs->vs_state == VDEV_STATE_CANT_OPEN)) &&
1575             (vs->vs_aux == VDEV_AUX_CORRUPT_DATA)) {
1576                 if (pool_state == POOL_STATE_DESTROYED)
1577                         (void) printf(gettext("\tThe pool was destroyed, "
1578                             "but can be imported using the '-Df' flags.\n"));
1579                 else if (pool_state != POOL_STATE_EXPORTED)
1580                         (void) printf(gettext("\tThe pool may be active on "
1581                             "another system, but can be imported using\n\t"
1582                             "the '-f' flag.\n"));
1583         }
1584 
1585         if (msgid != NULL)
1586                 (void) printf(gettext("   see: http://illumos.org/msg/%s\n"),
1587                     msgid);
1588 
1589         (void) printf(gettext(" config:\n\n"));
1590 
1591         namewidth = max_width(NULL, nvroot, 0, 0);
1592         if (namewidth < 10)
1593                 namewidth = 10;
1594 
1595         print_import_config(name, nvroot, namewidth, 0);
1596         if (num_logs(nvroot) > 0)
1597                 print_logs(NULL, nvroot, namewidth, B_FALSE);
1598 
1599         if (reason == ZPOOL_STATUS_BAD_GUID_SUM) {
1600                 (void) printf(gettext("\n\tAdditional devices are known to "
1601                     "be part of this pool, though their\n\texact "
1602                     "configuration cannot be determined.\n"));
1603         }
1604 }
1605 
1606 /*
1607  * Perform the import for the given configuration.  This passes the heavy
1608  * lifting off to zpool_import_props(), and then mounts the datasets contained
1609  * within the pool.
1610  */
1611 static int
1612 do_import(nvlist_t *config, const char *newname, const char *mntopts,
1613     nvlist_t *props, int flags)
1614 {
1615         zpool_handle_t *zhp;
1616         char *name;
1617         uint64_t state;
1618         uint64_t version;
1619 
1620         verify(nvlist_lookup_string(config, ZPOOL_CONFIG_POOL_NAME,
1621             &name) == 0);
1622 
1623         verify(nvlist_lookup_uint64(config,
1624             ZPOOL_CONFIG_POOL_STATE, &state) == 0);
1625         verify(nvlist_lookup_uint64(config,
1626             ZPOOL_CONFIG_VERSION, &version) == 0);
1627         if (!SPA_VERSION_IS_SUPPORTED(version)) {
1628                 (void) fprintf(stderr, gettext("cannot import '%s': pool "
1629                     "is formatted using an unsupported ZFS version\n"), name);
1630                 return (1);
1631         } else if (state != POOL_STATE_EXPORTED &&
1632             !(flags & ZFS_IMPORT_ANY_HOST)) {
1633                 uint64_t hostid;
1634 
1635                 if (nvlist_lookup_uint64(config, ZPOOL_CONFIG_HOSTID,
1636                     &hostid) == 0) {
1637                         if ((unsigned long)hostid != gethostid()) {
1638                                 char *hostname;
1639                                 uint64_t timestamp;
1640                                 time_t t;
1641 
1642                                 verify(nvlist_lookup_string(config,
1643                                     ZPOOL_CONFIG_HOSTNAME, &hostname) == 0);
1644                                 verify(nvlist_lookup_uint64(config,
1645                                     ZPOOL_CONFIG_TIMESTAMP, &timestamp) == 0);
1646                                 t = timestamp;
1647                                 (void) fprintf(stderr, gettext("cannot import "
1648                                     "'%s': pool may be in use from other "
1649                                     "system, it was last accessed by %s "
1650                                     "(hostid: 0x%lx) on %s"), name, hostname,
1651                                     (unsigned long)hostid,
1652                                     asctime(localtime(&t)));
1653                                 (void) fprintf(stderr, gettext("use '-f' to "
1654                                     "import anyway\n"));
1655                                 return (1);
1656                         }
1657                 } else {
1658                         (void) fprintf(stderr, gettext("cannot import '%s': "
1659                             "pool may be in use from other system\n"), name);
1660                         (void) fprintf(stderr, gettext("use '-f' to import "
1661                             "anyway\n"));
1662                         return (1);
1663                 }
1664         }
1665 
1666         if (zpool_import_props(g_zfs, config, newname, props, flags) != 0)
1667                 return (1);
1668 
1669         if (newname != NULL)
1670                 name = (char *)newname;
1671 
1672         if ((zhp = zpool_open_canfail(g_zfs, name)) == NULL)
1673                 return (1);
1674 
1675         if (zpool_get_state(zhp) != POOL_STATE_UNAVAIL &&
1676             !(flags & ZFS_IMPORT_ONLY) &&
1677             zpool_enable_datasets(zhp, mntopts, 0) != 0) {
1678                 zpool_close(zhp);
1679                 return (1);
1680         }
1681 
1682         zpool_close(zhp);
1683         return (0);
1684 }
1685 
1686 /*
1687  * zpool import [-d dir] [-D]
1688  *       import [-o mntopts] [-o prop=value] ... [-R root] [-D]
1689  *              [-d dir | -c cachefile] [-f] -a
1690  *       import [-o mntopts] [-o prop=value] ... [-R root] [-D]
1691  *              [-d dir | -c cachefile] [-f] [-n] [-F] <pool | id> [newpool]
1692  *
1693  *       -c     Read pool information from a cachefile instead of searching
1694  *              devices.
1695  *
1696  *       -d     Scan in a specific directory, other than /dev/dsk.  More than
1697  *              one directory can be specified using multiple '-d' options.
1698  *
1699  *       -D     Scan for previously destroyed pools or import all or only
1700  *              specified destroyed pools.
1701  *
1702  *       -R     Temporarily import the pool, with all mountpoints relative to
1703  *              the given root.  The pool will remain exported when the machine
1704  *              is rebooted.
1705  *
1706  *       -V     Import even in the presence of faulted vdevs.  This is an
1707  *              intentionally undocumented option for testing purposes, and
1708  *              treats the pool configuration as complete, leaving any bad
1709  *              vdevs in the FAULTED state. In other words, it does verbatim
1710  *              import.
1711  *
1712  *       -f     Force import, even if it appears that the pool is active.
1713  *
1714  *       -F     Attempt rewind if necessary.
1715  *
1716  *       -n     See if rewind would work, but don't actually rewind.
1717  *
1718  *       -N     Import the pool but don't mount datasets.
1719  *
1720  *       -T     Specify a starting txg to use for import. This option is
1721  *              intentionally undocumented option for testing purposes.
1722  *
1723  *       -a     Import all pools found.
1724  *
1725  *       -o     Set property=value and/or temporary mount options (without '=').
1726  *
1727  * The import command scans for pools to import, and import pools based on pool
1728  * name and GUID.  The pool can also be renamed as part of the import process.
1729  */
1730 int
1731 zpool_do_import(int argc, char **argv)
1732 {
1733         char **searchdirs = NULL;
1734         int nsearch = 0;
1735         int c;
1736         int err = 0;
1737         nvlist_t *pools = NULL;
1738         boolean_t do_all = B_FALSE;
1739         boolean_t do_destroyed = B_FALSE;
1740         char *mntopts = NULL;
1741         nvpair_t *elem;
1742         nvlist_t *config;
1743         uint64_t searchguid = 0;
1744         char *searchname = NULL;
1745         char *propval;
1746         nvlist_t *found_config;
1747         nvlist_t *policy = NULL;
1748         nvlist_t *props = NULL;
1749         boolean_t first;
1750         int flags = ZFS_IMPORT_NORMAL;
1751         uint32_t rewind_policy = ZPOOL_NO_REWIND;
1752         boolean_t dryrun = B_FALSE;
1753         boolean_t do_rewind = B_FALSE;
1754         boolean_t xtreme_rewind = B_FALSE;
1755         uint64_t pool_state, txg = -1ULL;
1756         char *cachefile = NULL;
1757         importargs_t idata = { 0 };
1758         char *endptr;
1759 
1760         /* check options */
1761         while ((c = getopt(argc, argv, ":aCc:d:DEfFmnNo:rR:T:VX")) != -1) {
1762                 switch (c) {
1763                 case 'a':
1764                         do_all = B_TRUE;
1765                         break;
1766                 case 'c':
1767                         cachefile = optarg;
1768                         break;
1769                 case 'd':
1770                         if (searchdirs == NULL) {
1771                                 searchdirs = safe_malloc(sizeof (char *));
1772                         } else {
1773                                 char **tmp = safe_malloc((nsearch + 1) *
1774                                     sizeof (char *));
1775                                 bcopy(searchdirs, tmp, nsearch *
1776                                     sizeof (char *));
1777                                 free(searchdirs);
1778                                 searchdirs = tmp;
1779                         }
1780                         searchdirs[nsearch++] = optarg;
1781                         break;
1782                 case 'D':
1783                         do_destroyed = B_TRUE;
1784                         break;
1785                 case 'f':
1786                         flags |= ZFS_IMPORT_ANY_HOST;
1787                         break;
1788                 case 'F':
1789                         do_rewind = B_TRUE;
1790                         break;
1791                 case 'm':
1792                         flags |= ZFS_IMPORT_MISSING_LOG;
1793                         break;
1794                 case 'n':
1795                         dryrun = B_TRUE;
1796                         break;
1797                 case 'N':
1798                         flags |= ZFS_IMPORT_ONLY;
1799                         break;
1800                 case 'o':
1801                         if ((propval = strchr(optarg, '=')) != NULL) {
1802                                 *propval = '\0';
1803                                 propval++;
1804                                 if (add_prop_list(optarg, propval,
1805                                     &props, B_TRUE))
1806                                         goto error;
1807                         } else {
1808                                 mntopts = optarg;
1809                         }
1810                         break;
1811                 case 'R':
1812                         if (add_prop_list(zpool_prop_to_name(
1813                             ZPOOL_PROP_ALTROOT), optarg, &props, B_TRUE))
1814                                 goto error;
1815                         if (nvlist_lookup_string(props,
1816                             zpool_prop_to_name(ZPOOL_PROP_CACHEFILE),
1817                             &propval) == 0)
1818                                 break;
1819                         if (add_prop_list(zpool_prop_to_name(
1820                             ZPOOL_PROP_CACHEFILE), "none", &props, B_TRUE))
1821                                 goto error;
1822                         break;
1823                 case 'T':
1824                         errno = 0;
1825                         txg = strtoull(optarg, &endptr, 10);
1826                         if (errno != 0 || *endptr != '\0') {
1827                                 (void) fprintf(stderr,
1828                                     gettext("invalid txg value\n"));
1829                                 usage(B_FALSE);
1830                         }
1831                         rewind_policy = ZPOOL_DO_REWIND | ZPOOL_EXTREME_REWIND;
1832                         break;
1833                 case 'V':
1834                         flags |= ZFS_IMPORT_VERBATIM;
1835                         break;
1836                 case 'X':
1837                         xtreme_rewind = B_TRUE;
1838                         break;
1839                 case ':':
1840                         (void) fprintf(stderr, gettext("missing argument for "
1841                             "'%c' option\n"), optopt);
1842                         usage(B_FALSE);
1843                         break;
1844                 case '?':
1845                         (void) fprintf(stderr, gettext("invalid option '%c'\n"),
1846                             optopt);
1847                         usage(B_FALSE);
1848                 }
1849         }
1850 
1851         argc -= optind;
1852         argv += optind;
1853 
1854         if (cachefile && nsearch != 0) {
1855                 (void) fprintf(stderr, gettext("-c is incompatible with -d\n"));
1856                 usage(B_FALSE);
1857         }
1858 
1859         if ((dryrun || xtreme_rewind) && !do_rewind) {
1860                 (void) fprintf(stderr,
1861                     gettext("-n or -X only meaningful with -F\n"));
1862                 usage(B_FALSE);
1863         }
1864         if (dryrun)
1865                 rewind_policy = ZPOOL_TRY_REWIND;
1866         else if (do_rewind)
1867                 rewind_policy = ZPOOL_DO_REWIND;
1868         if (xtreme_rewind)
1869                 rewind_policy |= ZPOOL_EXTREME_REWIND;
1870 
1871         /* In the future, we can capture further policy and include it here */
1872         if (nvlist_alloc(&policy, NV_UNIQUE_NAME, 0) != 0 ||
1873             nvlist_add_uint64(policy, ZPOOL_REWIND_REQUEST_TXG, txg) != 0 ||
1874             nvlist_add_uint32(policy, ZPOOL_REWIND_REQUEST, rewind_policy) != 0)
1875                 goto error;
1876 
1877         if (searchdirs == NULL) {
1878                 searchdirs = safe_malloc(sizeof (char *));
1879                 searchdirs[0] = "/dev/dsk";
1880                 nsearch = 1;
1881         }
1882 
1883         /* check argument count */
1884         if (do_all) {
1885                 if (argc != 0) {
1886                         (void) fprintf(stderr, gettext("too many arguments\n"));
1887                         usage(B_FALSE);
1888                 }
1889         } else {
1890                 if (argc > 2) {
1891                         (void) fprintf(stderr, gettext("too many arguments\n"));
1892                         usage(B_FALSE);
1893                 }
1894 
1895                 /*
1896                  * Check for the SYS_CONFIG privilege.  We do this explicitly
1897                  * here because otherwise any attempt to discover pools will
1898                  * silently fail.
1899                  */
1900                 if (argc == 0 && !priv_ineffect(PRIV_SYS_CONFIG)) {
1901                         (void) fprintf(stderr, gettext("cannot "
1902                             "discover pools: permission denied\n"));
1903                         free(searchdirs);
1904                         nvlist_free(policy);
1905                         return (1);
1906                 }
1907         }
1908 
1909         /*
1910          * Depending on the arguments given, we do one of the following:
1911          *
1912          *      <none>    Iterate through all pools and display information about
1913          *              each one.
1914          *
1915          *      -a      Iterate through all pools and try to import each one.
1916          *
1917          *      <id>      Find the pool that corresponds to the given GUID/pool
1918          *              name and import that one.
1919          *
1920          *      -D      Above options applies only to destroyed pools.
1921          */
1922         if (argc != 0) {
1923                 char *endptr;
1924 
1925                 errno = 0;
1926                 searchguid = strtoull(argv[0], &endptr, 10);
1927                 if (errno != 0 || *endptr != '\0')
1928                         searchname = argv[0];
1929                 found_config = NULL;
1930 
1931                 /*
1932                  * User specified a name or guid.  Ensure it's unique.
1933                  */
1934                 idata.unique = B_TRUE;
1935         }
1936 
1937 
1938         idata.path = searchdirs;
1939         idata.paths = nsearch;
1940         idata.poolname = searchname;
1941         idata.guid = searchguid;
1942         idata.cachefile = cachefile;
1943 
1944         pools = zpool_search_import(g_zfs, &idata);
1945 
1946         if (pools != NULL && idata.exists &&
1947             (argc == 1 || strcmp(argv[0], argv[1]) == 0)) {
1948                 (void) fprintf(stderr, gettext("cannot import '%s': "
1949                     "a pool with that name already exists\n"),
1950                     argv[0]);
1951                 (void) fprintf(stderr, gettext("use the form '%s "
1952                     "<pool | id> <newpool>' to give it a new name\n"),
1953                     "zpool import");
1954                 err = 1;
1955         } else if (pools == NULL && idata.exists) {
1956                 (void) fprintf(stderr, gettext("cannot import '%s': "
1957                     "a pool with that name is already created/imported,\n"),
1958                     argv[0]);
1959                 (void) fprintf(stderr, gettext("and no additional pools "
1960                     "with that name were found\n"));
1961                 err = 1;
1962         } else if (pools == NULL) {
1963                 if (argc != 0) {
1964                         (void) fprintf(stderr, gettext("cannot import '%s': "
1965                             "no such pool available\n"), argv[0]);
1966                 }
1967                 err = 1;
1968         }
1969 
1970         if (err == 1) {
1971                 free(searchdirs);
1972                 nvlist_free(policy);
1973                 return (1);
1974         }
1975 
1976         /*
1977          * At this point we have a list of import candidate configs. Even if
1978          * we were searching by pool name or guid, we still need to
1979          * post-process the list to deal with pool state and possible
1980          * duplicate names.
1981          */
1982         err = 0;
1983         elem = NULL;
1984         first = B_TRUE;
1985         while ((elem = nvlist_next_nvpair(pools, elem)) != NULL) {
1986 
1987                 verify(nvpair_value_nvlist(elem, &config) == 0);
1988 
1989                 verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_STATE,
1990                     &pool_state) == 0);
1991                 if (!do_destroyed && pool_state == POOL_STATE_DESTROYED)
1992                         continue;
1993                 if (do_destroyed && pool_state != POOL_STATE_DESTROYED)
1994                         continue;
1995 
1996                 verify(nvlist_add_nvlist(config, ZPOOL_REWIND_POLICY,
1997                     policy) == 0);
1998 
1999                 if (argc == 0) {
2000                         if (first)
2001                                 first = B_FALSE;
2002                         else if (!do_all)
2003                                 (void) printf("\n");
2004 
2005                         if (do_all) {
2006                                 err |= do_import(config, NULL, mntopts,
2007                                     props, flags);
2008                         } else {
2009                                 show_import(config);
2010                         }
2011                 } else if (searchname != NULL) {
2012                         char *name;
2013 
2014                         /*
2015                          * We are searching for a pool based on name.
2016                          */
2017                         verify(nvlist_lookup_string(config,
2018                             ZPOOL_CONFIG_POOL_NAME, &name) == 0);
2019 
2020                         if (strcmp(name, searchname) == 0) {
2021                                 if (found_config != NULL) {
2022                                         (void) fprintf(stderr, gettext(
2023                                             "cannot import '%s': more than "
2024                                             "one matching pool\n"), searchname);
2025                                         (void) fprintf(stderr, gettext(
2026                                             "import by numeric ID instead\n"));
2027                                         err = B_TRUE;
2028                                 }
2029                                 found_config = config;
2030                         }
2031                 } else {
2032                         uint64_t guid;
2033 
2034                         /*
2035                          * Search for a pool by guid.
2036                          */
2037                         verify(nvlist_lookup_uint64(config,
2038                             ZPOOL_CONFIG_POOL_GUID, &guid) == 0);
2039 
2040                         if (guid == searchguid)
2041                                 found_config = config;
2042                 }
2043         }
2044 
2045         /*
2046          * If we were searching for a specific pool, verify that we found a
2047          * pool, and then do the import.
2048          */
2049         if (argc != 0 && err == 0) {
2050                 if (found_config == NULL) {
2051                         (void) fprintf(stderr, gettext("cannot import '%s': "
2052                             "no such pool available\n"), argv[0]);
2053                         err = B_TRUE;
2054                 } else {
2055                         err |= do_import(found_config, argc == 1 ? NULL :
2056                             argv[1], mntopts, props, flags);
2057                 }
2058         }
2059 
2060         /*
2061          * If we were just looking for pools, report an error if none were
2062          * found.
2063          */
2064         if (argc == 0 && first)
2065                 (void) fprintf(stderr,
2066                     gettext("no pools available to import\n"));
2067 
2068 error:
2069         nvlist_free(props);
2070         nvlist_free(pools);
2071         nvlist_free(policy);
2072         free(searchdirs);
2073 
2074         return (err ? 1 : 0);
2075 }
2076 
2077 typedef struct iostat_cbdata {
2078         boolean_t cb_verbose;
2079         int cb_namewidth;
2080         int cb_iteration;
2081         zpool_list_t *cb_list;
2082 } iostat_cbdata_t;
2083 
2084 static void
2085 print_iostat_separator(iostat_cbdata_t *cb)
2086 {
2087         int i = 0;
2088 
2089         for (i = 0; i < cb->cb_namewidth; i++)
2090                 (void) printf("-");
2091         (void) printf("  -----  -----  -----  -----  -----  -----\n");
2092 }
2093 
2094 static void
2095 print_iostat_header(iostat_cbdata_t *cb)
2096 {
2097         (void) printf("%*s     capacity     operations    bandwidth\n",
2098             cb->cb_namewidth, "");
2099         (void) printf("%-*s  alloc   free   read  write   read  write\n",
2100             cb->cb_namewidth, "pool");
2101         print_iostat_separator(cb);
2102 }
2103 
2104 /*
2105  * Display a single statistic.
2106  */
2107 static void
2108 print_one_stat(uint64_t value)
2109 {
2110         char buf[64];
2111 
2112         zfs_nicenum(value, buf, sizeof (buf));
2113         (void) printf("  %5s", buf);
2114 }
2115 
2116 /*
2117  * Print out all the statistics for the given vdev.  This can either be the
2118  * toplevel configuration, or called recursively.  If 'name' is NULL, then this
2119  * is a verbose output, and we don't want to display the toplevel pool stats.
2120  */
2121 void
2122 print_vdev_stats(zpool_handle_t *zhp, const char *name, nvlist_t *oldnv,
2123     nvlist_t *newnv, iostat_cbdata_t *cb, int depth)
2124 {
2125         nvlist_t **oldchild, **newchild;
2126         uint_t c, children;
2127         vdev_stat_t *oldvs, *newvs;
2128         vdev_stat_t zerovs = { 0 };
2129         uint64_t tdelta;
2130         double scale;
2131         char *vname;
2132 
2133         if (oldnv != NULL) {
2134                 verify(nvlist_lookup_uint64_array(oldnv,
2135                     ZPOOL_CONFIG_VDEV_STATS, (uint64_t **)&oldvs, &c) == 0);
2136         } else {
2137                 oldvs = &zerovs;
2138         }
2139 
2140         verify(nvlist_lookup_uint64_array(newnv, ZPOOL_CONFIG_VDEV_STATS,
2141             (uint64_t **)&newvs, &c) == 0);
2142 
2143         if (strlen(name) + depth > cb->cb_namewidth)
2144                 (void) printf("%*s%s", depth, "", name);
2145         else
2146                 (void) printf("%*s%s%*s", depth, "", name,
2147                     (int)(cb->cb_namewidth - strlen(name) - depth), "");
2148 
2149         tdelta = newvs->vs_timestamp - oldvs->vs_timestamp;
2150 
2151         if (tdelta == 0)
2152                 scale = 1.0;
2153         else
2154                 scale = (double)NANOSEC / tdelta;
2155 
2156         /* only toplevel vdevs have capacity stats */
2157         if (newvs->vs_space == 0) {
2158                 (void) printf("      -      -");
2159         } else {
2160                 print_one_stat(newvs->vs_alloc);
2161                 print_one_stat(newvs->vs_space - newvs->vs_alloc);
2162         }
2163 
2164         print_one_stat((uint64_t)(scale * (newvs->vs_ops[ZIO_TYPE_READ] -
2165             oldvs->vs_ops[ZIO_TYPE_READ])));
2166 
2167         print_one_stat((uint64_t)(scale * (newvs->vs_ops[ZIO_TYPE_WRITE] -
2168             oldvs->vs_ops[ZIO_TYPE_WRITE])));
2169 
2170         print_one_stat((uint64_t)(scale * (newvs->vs_bytes[ZIO_TYPE_READ] -
2171             oldvs->vs_bytes[ZIO_TYPE_READ])));
2172 
2173         print_one_stat((uint64_t)(scale * (newvs->vs_bytes[ZIO_TYPE_WRITE] -
2174             oldvs->vs_bytes[ZIO_TYPE_WRITE])));
2175 
2176         (void) printf("\n");
2177 
2178         if (!cb->cb_verbose)
2179                 return;
2180 
2181         if (nvlist_lookup_nvlist_array(newnv, ZPOOL_CONFIG_CHILDREN,
2182             &newchild, &children) != 0)
2183                 return;
2184 
2185         if (oldnv && nvlist_lookup_nvlist_array(oldnv, ZPOOL_CONFIG_CHILDREN,
2186             &oldchild, &c) != 0)
2187                 return;
2188 
2189         for (c = 0; c < children; c++) {
2190                 uint64_t ishole = B_FALSE, islog = B_FALSE;
2191 
2192                 (void) nvlist_lookup_uint64(newchild[c], ZPOOL_CONFIG_IS_HOLE,
2193                     &ishole);
2194 
2195                 (void) nvlist_lookup_uint64(newchild[c], ZPOOL_CONFIG_IS_LOG,
2196                     &islog);
2197 
2198                 if (ishole || islog)
2199                         continue;
2200 
2201                 vname = zpool_vdev_name(g_zfs, zhp, newchild[c], B_FALSE);
2202                 print_vdev_stats(zhp, vname, oldnv ? oldchild[c] : NULL,
2203                     newchild[c], cb, depth + 2);
2204                 free(vname);
2205         }
2206 
2207         /*
2208          * Log device section
2209          */
2210 
2211         if (num_logs(newnv) > 0) {
2212                 (void) printf("%-*s      -      -      -      -      -      "
2213                     "-\n", cb->cb_namewidth, "logs");
2214 
2215                 for (c = 0; c < children; c++) {
2216                         uint64_t islog = B_FALSE;
2217                         (void) nvlist_lookup_uint64(newchild[c],
2218                             ZPOOL_CONFIG_IS_LOG, &islog);
2219 
2220                         if (islog) {
2221                                 vname = zpool_vdev_name(g_zfs, zhp, newchild[c],
2222                                     B_FALSE);
2223                                 print_vdev_stats(zhp, vname, oldnv ?
2224                                     oldchild[c] : NULL, newchild[c],
2225                                     cb, depth + 2);
2226                                 free(vname);
2227                         }
2228                 }
2229 
2230         }
2231 
2232         /*
2233          * Include level 2 ARC devices in iostat output
2234          */
2235         if (nvlist_lookup_nvlist_array(newnv, ZPOOL_CONFIG_L2CACHE,
2236             &newchild, &children) != 0)
2237                 return;
2238 
2239         if (oldnv && nvlist_lookup_nvlist_array(oldnv, ZPOOL_CONFIG_L2CACHE,
2240             &oldchild, &c) != 0)
2241                 return;
2242 
2243         if (children > 0) {
2244                 (void) printf("%-*s      -      -      -      -      -      "
2245                     "-\n", cb->cb_namewidth, "cache");
2246                 for (c = 0; c < children; c++) {
2247                         vname = zpool_vdev_name(g_zfs, zhp, newchild[c],
2248                             B_FALSE);
2249                         print_vdev_stats(zhp, vname, oldnv ? oldchild[c] : NULL,
2250                             newchild[c], cb, depth + 2);
2251                         free(vname);
2252                 }
2253         }
2254 }
2255 
2256 static int
2257 refresh_iostat(zpool_handle_t *zhp, void *data)
2258 {
2259         iostat_cbdata_t *cb = data;
2260         boolean_t missing;
2261 
2262         /*
2263          * If the pool has disappeared, remove it from the list and continue.
2264          */
2265         if (zpool_refresh_stats(zhp, &missing) != 0)
2266                 return (-1);
2267 
2268         if (missing)
2269                 pool_list_remove(cb->cb_list, zhp);
2270 
2271         return (0);
2272 }
2273 
2274 /*
2275  * Callback to print out the iostats for the given pool.
2276  */
2277 int
2278 print_iostat(zpool_handle_t *zhp, void *data)
2279 {
2280         iostat_cbdata_t *cb = data;
2281         nvlist_t *oldconfig, *newconfig;
2282         nvlist_t *oldnvroot, *newnvroot;
2283 
2284         newconfig = zpool_get_config(zhp, &oldconfig);
2285 
2286         if (cb->cb_iteration == 1)
2287                 oldconfig = NULL;
2288 
2289         verify(nvlist_lookup_nvlist(newconfig, ZPOOL_CONFIG_VDEV_TREE,
2290             &newnvroot) == 0);
2291 
2292         if (oldconfig == NULL)
2293                 oldnvroot = NULL;
2294         else
2295                 verify(nvlist_lookup_nvlist(oldconfig, ZPOOL_CONFIG_VDEV_TREE,
2296                     &oldnvroot) == 0);
2297 
2298         /*
2299          * Print out the statistics for the pool.
2300          */
2301         print_vdev_stats(zhp, zpool_get_name(zhp), oldnvroot, newnvroot, cb, 0);
2302 
2303         if (cb->cb_verbose)
2304                 print_iostat_separator(cb);
2305 
2306         return (0);
2307 }
2308 
2309 int
2310 get_namewidth(zpool_handle_t *zhp, void *data)
2311 {
2312         iostat_cbdata_t *cb = data;
2313         nvlist_t *config, *nvroot;
2314 
2315         if ((config = zpool_get_config(zhp, NULL)) != NULL) {
2316                 verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
2317                     &nvroot) == 0);
2318                 if (!cb->cb_verbose)
2319                         cb->cb_namewidth = strlen(zpool_get_name(zhp));
2320                 else
2321                         cb->cb_namewidth = max_width(zhp, nvroot, 0,
2322                             cb->cb_namewidth);
2323         }
2324 
2325         /*
2326          * The width must fall into the range [10,38].  The upper limit is the
2327          * maximum we can have and still fit in 80 columns.
2328          */
2329         if (cb->cb_namewidth < 10)
2330                 cb->cb_namewidth = 10;
2331         if (cb->cb_namewidth > 38)
2332                 cb->cb_namewidth = 38;
2333 
2334         return (0);
2335 }
2336 
2337 /*
2338  * Parse the input string, get the 'interval' and 'count' value if there is one.
2339  */
2340 static void
2341 get_interval_count(int *argcp, char **argv, unsigned long *iv,
2342     unsigned long *cnt)
2343 {
2344         unsigned long interval = 0, count = 0;
2345         int argc = *argcp, errno;
2346 
2347         /*
2348          * Determine if the last argument is an integer or a pool name
2349          */
2350         if (argc > 0 && isdigit(argv[argc - 1][0])) {
2351                 char *end;
2352 
2353                 errno = 0;
2354                 interval = strtoul(argv[argc - 1], &end, 10);
2355 
2356                 if (*end == '\0' && errno == 0) {
2357                         if (interval == 0) {
2358                                 (void) fprintf(stderr, gettext("interval "
2359                                     "cannot be zero\n"));
2360                                 usage(B_FALSE);
2361                         }
2362                         /*
2363                          * Ignore the last parameter
2364                          */
2365                         argc--;
2366                 } else {
2367                         /*
2368                          * If this is not a valid number, just plow on.  The
2369                          * user will get a more informative error message later
2370                          * on.
2371                          */
2372                         interval = 0;
2373                 }
2374         }
2375 
2376         /*
2377          * If the last argument is also an integer, then we have both a count
2378          * and an interval.
2379          */
2380         if (argc > 0 && isdigit(argv[argc - 1][0])) {
2381                 char *end;
2382 
2383                 errno = 0;
2384                 count = interval;
2385                 interval = strtoul(argv[argc - 1], &end, 10);
2386 
2387                 if (*end == '\0' && errno == 0) {
2388                         if (interval == 0) {
2389                                 (void) fprintf(stderr, gettext("interval "
2390                                     "cannot be zero\n"));
2391                                 usage(B_FALSE);
2392                         }
2393 
2394                         /*
2395                          * Ignore the last parameter
2396                          */
2397                         argc--;
2398                 } else {
2399                         interval = 0;
2400                 }
2401         }
2402 
2403         *iv = interval;
2404         *cnt = count;
2405         *argcp = argc;
2406 }
2407 
2408 static void
2409 get_timestamp_arg(char c)
2410 {
2411         if (c == 'u')
2412                 timestamp_fmt = UDATE;
2413         else if (c == 'd')
2414                 timestamp_fmt = DDATE;
2415         else
2416                 usage(B_FALSE);
2417 }
2418 
2419 /*
2420  * zpool iostat [-v] [-T d|u] [pool] ... [interval [count]]
2421  *
2422  *      -v      Display statistics for individual vdevs
2423  *      -T      Display a timestamp in date(1) or Unix format
2424  *
2425  * This command can be tricky because we want to be able to deal with pool
2426  * creation/destruction as well as vdev configuration changes.  The bulk of this
2427  * processing is handled by the pool_list_* routines in zpool_iter.c.  We rely
2428  * on pool_list_update() to detect the addition of new pools.  Configuration
2429  * changes are all handled within libzfs.
2430  */
2431 int
2432 zpool_do_iostat(int argc, char **argv)
2433 {
2434         int c;
2435         int ret;
2436         int npools;
2437         unsigned long interval = 0, count = 0;
2438         zpool_list_t *list;
2439         boolean_t verbose = B_FALSE;
2440         iostat_cbdata_t cb;
2441 
2442         /* check options */
2443         while ((c = getopt(argc, argv, "T:v")) != -1) {
2444                 switch (c) {
2445                 case 'T':
2446                         get_timestamp_arg(*optarg);
2447                         break;
2448                 case 'v':
2449                         verbose = B_TRUE;
2450                         break;
2451                 case '?':
2452                         (void) fprintf(stderr, gettext("invalid option '%c'\n"),
2453                             optopt);
2454                         usage(B_FALSE);
2455                 }
2456         }
2457 
2458         argc -= optind;
2459         argv += optind;
2460 
2461         get_interval_count(&argc, argv, &interval, &count);
2462 
2463         /*
2464          * Construct the list of all interesting pools.
2465          */
2466         ret = 0;
2467         if ((list = pool_list_get(argc, argv, NULL, &ret)) == NULL)
2468                 return (1);
2469 
2470         if (pool_list_count(list) == 0 && argc != 0) {
2471                 pool_list_free(list);
2472                 return (1);
2473         }
2474 
2475         if (pool_list_count(list) == 0 && interval == 0) {
2476                 pool_list_free(list);
2477                 (void) fprintf(stderr, gettext("no pools available\n"));
2478                 return (1);
2479         }
2480 
2481         /*
2482          * Enter the main iostat loop.
2483          */
2484         cb.cb_list = list;
2485         cb.cb_verbose = verbose;
2486         cb.cb_iteration = 0;
2487         cb.cb_namewidth = 0;
2488 
2489         for (;;) {
2490                 pool_list_update(list);
2491 
2492                 if ((npools = pool_list_count(list)) == 0)
2493                         break;
2494 
2495                 /*
2496                  * Refresh all statistics.  This is done as an explicit step
2497                  * before calculating the maximum name width, so that any
2498                  * configuration changes are properly accounted for.
2499                  */
2500                 (void) pool_list_iter(list, B_FALSE, refresh_iostat, &cb);
2501 
2502                 /*
2503                  * Iterate over all pools to determine the maximum width
2504                  * for the pool / device name column across all pools.
2505                  */
2506                 cb.cb_namewidth = 0;
2507                 (void) pool_list_iter(list, B_FALSE, get_namewidth, &cb);
2508 
2509                 if (timestamp_fmt != NODATE)
2510                         print_timestamp(timestamp_fmt);
2511 
2512                 /*
2513                  * If it's the first time, or verbose mode, print the header.
2514                  */
2515                 if (++cb.cb_iteration == 1 || verbose)
2516                         print_iostat_header(&cb);
2517 
2518                 (void) pool_list_iter(list, B_FALSE, print_iostat, &cb);
2519 
2520                 /*
2521                  * If there's more than one pool, and we're not in verbose mode
2522                  * (which prints a separator for us), then print a separator.
2523                  */
2524                 if (npools > 1 && !verbose)
2525                         print_iostat_separator(&cb);
2526 
2527                 if (verbose)
2528                         (void) printf("\n");
2529 
2530                 /*
2531                  * Flush the output so that redirection to a file isn't buffered
2532                  * indefinitely.
2533                  */
2534                 (void) fflush(stdout);
2535 
2536                 if (interval == 0)
2537                         break;
2538 
2539                 if (count != 0 && --count == 0)
2540                         break;
2541 
2542                 (void) sleep(interval);
2543         }
2544 
2545         pool_list_free(list);
2546 
2547         return (ret);
2548 }
2549 
2550 typedef struct list_cbdata {
2551         boolean_t       cb_verbose;
2552         int             cb_namewidth;
2553         boolean_t       cb_scripted;
2554         zprop_list_t    *cb_proplist;
2555 } list_cbdata_t;
2556 
2557 /*
2558  * Given a list of columns to display, output appropriate headers for each one.
2559  */
2560 static void
2561 print_header(list_cbdata_t *cb)
2562 {
2563         zprop_list_t *pl = cb->cb_proplist;
2564         char headerbuf[ZPOOL_MAXPROPLEN];
2565         const char *header;
2566         boolean_t first = B_TRUE;
2567         boolean_t right_justify;
2568         size_t width = 0;
2569 
2570         for (; pl != NULL; pl = pl->pl_next) {
2571                 width = pl->pl_width;
2572                 if (first && cb->cb_verbose) {
2573                         /*
2574                          * Reset the width to accommodate the verbose listing
2575                          * of devices.
2576                          */
2577                         width = cb->cb_namewidth;
2578                 }
2579 
2580                 if (!first)
2581                         (void) printf("  ");
2582                 else
2583                         first = B_FALSE;
2584 
2585                 right_justify = B_FALSE;
2586                 if (pl->pl_prop != ZPROP_INVAL) {
2587                         header = zpool_prop_column_name(pl->pl_prop);
2588                         right_justify = zpool_prop_align_right(pl->pl_prop);
2589                 } else {
2590                         int i;
2591 
2592                         for (i = 0; pl->pl_user_prop[i] != '\0'; i++)
2593                                 headerbuf[i] = toupper(pl->pl_user_prop[i]);
2594                         headerbuf[i] = '\0';
2595                         header = headerbuf;
2596                 }
2597 
2598                 if (pl->pl_next == NULL && !right_justify)
2599                         (void) printf("%s", header);
2600                 else if (right_justify)
2601                         (void) printf("%*s", width, header);
2602                 else
2603                         (void) printf("%-*s", width, header);
2604 
2605         }
2606 
2607         (void) printf("\n");
2608 }
2609 
2610 /*
2611  * Given a pool and a list of properties, print out all the properties according
2612  * to the described layout.
2613  */
2614 static void
2615 print_pool(zpool_handle_t *zhp, list_cbdata_t *cb)
2616 {
2617         zprop_list_t *pl = cb->cb_proplist;
2618         boolean_t first = B_TRUE;
2619         char property[ZPOOL_MAXPROPLEN];
2620         char *propstr;
2621         boolean_t right_justify;
2622         size_t width;
2623 
2624         for (; pl != NULL; pl = pl->pl_next) {
2625 
2626                 width = pl->pl_width;
2627                 if (first && cb->cb_verbose) {
2628                         /*
2629                          * Reset the width to accommodate the verbose listing
2630                          * of devices.
2631                          */
2632                         width = cb->cb_namewidth;
2633                 }
2634 
2635                 if (!first) {
2636                         if (cb->cb_scripted)
2637                                 (void) printf("\t");
2638                         else
2639                                 (void) printf("  ");
2640                 } else {
2641                         first = B_FALSE;
2642                 }
2643 
2644                 right_justify = B_FALSE;
2645                 if (pl->pl_prop != ZPROP_INVAL) {
2646                         if (pl->pl_prop == ZPOOL_PROP_EXPANDSZ &&
2647                             zpool_get_prop_int(zhp, pl->pl_prop, NULL) == 0)
2648                                 propstr = "-";
2649                         else if (zpool_get_prop(zhp, pl->pl_prop, property,
2650                             sizeof (property), NULL) != 0)
2651                                 propstr = "-";
2652                         else
2653                                 propstr = property;
2654 
2655                         right_justify = zpool_prop_align_right(pl->pl_prop);
2656                 } else if ((zpool_prop_feature(pl->pl_user_prop) ||
2657                     zpool_prop_unsupported(pl->pl_user_prop)) &&
2658                     zpool_prop_get_feature(zhp, pl->pl_user_prop, property,
2659                     sizeof (property)) == 0) {
2660                         propstr = property;
2661                 } else {
2662                         propstr = "-";
2663                 }
2664 
2665 
2666                 /*
2667                  * If this is being called in scripted mode, or if this is the
2668                  * last column and it is left-justified, don't include a width
2669                  * format specifier.
2670                  */
2671                 if (cb->cb_scripted || (pl->pl_next == NULL && !right_justify))
2672                         (void) printf("%s", propstr);
2673                 else if (right_justify)
2674                         (void) printf("%*s", width, propstr);
2675                 else
2676                         (void) printf("%-*s", width, propstr);
2677         }
2678 
2679         (void) printf("\n");
2680 }
2681 
2682 static void
2683 print_one_column(zpool_prop_t prop, uint64_t value, boolean_t scripted)
2684 {
2685         char propval[64];
2686         boolean_t fixed;
2687         size_t width = zprop_width(prop, &fixed, ZFS_TYPE_POOL);
2688 
2689         zfs_nicenum(value, propval, sizeof (propval));
2690 
2691         if (prop == ZPOOL_PROP_EXPANDSZ && value == 0)
2692                 (void) strlcpy(propval, "-", sizeof (propval));
2693 
2694         if (scripted)
2695                 (void) printf("\t%s", propval);
2696         else
2697                 (void) printf("  %*s", width, propval);
2698 }
2699 
2700 void
2701 print_list_stats(zpool_handle_t *zhp, const char *name, nvlist_t *nv,
2702     list_cbdata_t *cb, int depth)
2703 {
2704         nvlist_t **child;
2705         vdev_stat_t *vs;
2706         uint_t c, children;
2707         char *vname;
2708         boolean_t scripted = cb->cb_scripted;
2709 
2710         verify(nvlist_lookup_uint64_array(nv, ZPOOL_CONFIG_VDEV_STATS,
2711             (uint64_t **)&vs, &c) == 0);
2712 
2713         if (name != NULL) {
2714                 if (scripted)
2715                         (void) printf("\t%s", name);
2716                 else if (strlen(name) + depth > cb->cb_namewidth)
2717                         (void) printf("%*s%s", depth, "", name);
2718                 else
2719                         (void) printf("%*s%s%*s", depth, "", name,
2720                             (int)(cb->cb_namewidth - strlen(name) - depth), "");
2721 
2722                 /* only toplevel vdevs have capacity stats */
2723                 if (vs->vs_space == 0) {
2724                         if (scripted)
2725                                 (void) printf("\t-\t-\t-");
2726                         else
2727                                 (void) printf("      -      -      -");
2728                 } else {
2729                         print_one_column(ZPOOL_PROP_SIZE, vs->vs_space,
2730                             scripted);
2731                         print_one_column(ZPOOL_PROP_CAPACITY, vs->vs_alloc,
2732                             scripted);
2733                         print_one_column(ZPOOL_PROP_FREE,
2734                             vs->vs_space - vs->vs_alloc, scripted);
2735                 }
2736                 print_one_column(ZPOOL_PROP_EXPANDSZ, vs->vs_esize,
2737                     scripted);
2738                 (void) printf("\n");
2739         }
2740 
2741         if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
2742             &child, &children) != 0)
2743                 return;
2744 
2745         for (c = 0; c < children; c++) {
2746                 uint64_t ishole = B_FALSE;
2747 
2748                 if (nvlist_lookup_uint64(child[c],
2749                     ZPOOL_CONFIG_IS_HOLE, &ishole) == 0 && ishole)
2750                         continue;
2751 
2752                 vname = zpool_vdev_name(g_zfs, zhp, child[c], B_FALSE);
2753                 print_list_stats(zhp, vname, child[c], cb, depth + 2);
2754                 free(vname);
2755         }
2756 
2757         /*
2758          * Include level 2 ARC devices in iostat output
2759          */
2760         if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_L2CACHE,
2761             &child, &children) != 0)
2762                 return;
2763 
2764         if (children > 0) {
2765                 (void) printf("%-*s      -      -      -      -      -      "
2766                     "-\n", cb->cb_namewidth, "cache");
2767                 for (c = 0; c < children; c++) {
2768                         vname = zpool_vdev_name(g_zfs, zhp, child[c],
2769                             B_FALSE);
2770                         print_list_stats(zhp, vname, child[c], cb, depth + 2);
2771                         free(vname);
2772                 }
2773         }
2774 }
2775 
2776 
2777 /*
2778  * Generic callback function to list a pool.
2779  */
2780 int
2781 list_callback(zpool_handle_t *zhp, void *data)
2782 {
2783         list_cbdata_t *cbp = data;
2784         nvlist_t *config;
2785         nvlist_t *nvroot;
2786 
2787         config = zpool_get_config(zhp, NULL);
2788 
2789         print_pool(zhp, cbp);
2790         if (!cbp->cb_verbose)
2791                 return (0);
2792 
2793         verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
2794             &nvroot) == 0);
2795         print_list_stats(zhp, NULL, nvroot, cbp, 0);
2796 
2797         return (0);
2798 }
2799 
2800 /*
2801  * zpool list [-H] [-o prop[,prop]*] [-T d|u] [pool] ... [interval [count]]
2802  *
2803  *      -H      Scripted mode.  Don't display headers, and separate properties
2804  *              by a single tab.
2805  *      -o      List of properties to display.  Defaults to
2806  *              "name,size,allocated,free,capacity,health,altroot"
2807  *      -T      Display a timestamp in date(1) or Unix format
2808  *
2809  * List all pools in the system, whether or not they're healthy.  Output space
2810  * statistics for each one, as well as health status summary.
2811  */
2812 int
2813 zpool_do_list(int argc, char **argv)
2814 {
2815         int c;
2816         int ret;
2817         list_cbdata_t cb = { 0 };
2818         static char default_props[] =
2819             "name,size,allocated,free,expandsize,capacity,dedupratio,"
2820             "health,altroot";
2821         char *props = default_props;
2822         unsigned long interval = 0, count = 0;
2823         zpool_list_t *list;
2824         boolean_t first = B_TRUE;
2825 
2826         /* check options */
2827         while ((c = getopt(argc, argv, ":Ho:T:v")) != -1) {
2828                 switch (c) {
2829                 case 'H':
2830                         cb.cb_scripted = B_TRUE;
2831                         break;
2832                 case 'o':
2833                         props = optarg;
2834                         break;
2835                 case 'T':
2836                         get_timestamp_arg(*optarg);
2837                         break;
2838                 case 'v':
2839                         cb.cb_verbose = B_TRUE;
2840                         break;
2841                 case ':':
2842                         (void) fprintf(stderr, gettext("missing argument for "
2843                             "'%c' option\n"), optopt);
2844                         usage(B_FALSE);
2845                         break;
2846                 case '?':
2847                         (void) fprintf(stderr, gettext("invalid option '%c'\n"),
2848                             optopt);
2849                         usage(B_FALSE);
2850                 }
2851         }
2852 
2853         argc -= optind;
2854         argv += optind;
2855 
2856         get_interval_count(&argc, argv, &interval, &count);
2857 
2858         if (zprop_get_list(g_zfs, props, &cb.cb_proplist, ZFS_TYPE_POOL) != 0)
2859                 usage(B_FALSE);
2860 
2861         if ((list = pool_list_get(argc, argv, &cb.cb_proplist, &ret)) == NULL)
2862                 return (1);
2863 
2864         if (argc == 0 && !cb.cb_scripted && pool_list_count(list) == 0) {
2865                 (void) printf(gettext("no pools available\n"));
2866                 zprop_free_list(cb.cb_proplist);
2867                 return (0);
2868         }
2869 
2870         for (;;) {
2871                 pool_list_update(list);
2872 
2873                 if (pool_list_count(list) == 0)
2874                         break;
2875 
2876                 cb.cb_namewidth = 0;
2877                 (void) pool_list_iter(list, B_FALSE, get_namewidth, &cb);
2878 
2879                 if (timestamp_fmt != NODATE)
2880                         print_timestamp(timestamp_fmt);
2881 
2882                 if (!cb.cb_scripted && (first || cb.cb_verbose)) {
2883                         print_header(&cb);
2884                         first = B_FALSE;
2885                 }
2886                 ret = pool_list_iter(list, B_TRUE, list_callback, &cb);
2887 
2888                 if (interval == 0)
2889                         break;
2890 
2891                 if (count != 0 && --count == 0)
2892                         break;
2893 
2894                 (void) sleep(interval);
2895         }
2896 
2897         zprop_free_list(cb.cb_proplist);
2898         return (ret);
2899 }
2900 
2901 static nvlist_t *
2902 zpool_get_vdev_by_name(nvlist_t *nv, char *name)
2903 {
2904         nvlist_t **child;
2905         uint_t c, children;
2906         nvlist_t *match;
2907         char *path;
2908 
2909         if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
2910             &child, &children) != 0) {
2911                 verify(nvlist_lookup_string(nv, ZPOOL_CONFIG_PATH, &path) == 0);
2912                 if (strncmp(name, "/dev/dsk/", 9) == 0)
2913                         name += 9;
2914                 if (strncmp(path, "/dev/dsk/", 9) == 0)
2915                         path += 9;
2916                 if (strcmp(name, path) == 0)
2917                         return (nv);
2918                 return (NULL);
2919         }
2920 
2921         for (c = 0; c < children; c++)
2922                 if ((match = zpool_get_vdev_by_name(child[c], name)) != NULL)
2923                         return (match);
2924 
2925         return (NULL);
2926 }
2927 
2928 static int
2929 zpool_do_attach_or_replace(int argc, char **argv, int replacing)
2930 {
2931         boolean_t force = B_FALSE;
2932         int c;
2933         nvlist_t *nvroot;
2934         char *poolname, *old_disk, *new_disk;
2935         zpool_handle_t *zhp;
2936         int ret;
2937 
2938         /* check options */
2939         while ((c = getopt(argc, argv, "f")) != -1) {
2940                 switch (c) {
2941                 case 'f':
2942                         force = B_TRUE;
2943                         break;
2944                 case '?':
2945                         (void) fprintf(stderr, gettext("invalid option '%c'\n"),
2946                             optopt);
2947                         usage(B_FALSE);
2948                 }
2949         }
2950 
2951         argc -= optind;
2952         argv += optind;
2953 
2954         /* get pool name and check number of arguments */
2955         if (argc < 1) {
2956                 (void) fprintf(stderr, gettext("missing pool name argument\n"));
2957                 usage(B_FALSE);
2958         }
2959 
2960         poolname = argv[0];
2961 
2962         if (argc < 2) {
2963                 (void) fprintf(stderr,
2964                     gettext("missing <device> specification\n"));
2965                 usage(B_FALSE);
2966         }
2967 
2968         old_disk = argv[1];
2969 
2970         if (argc < 3) {
2971                 if (!replacing) {
2972                         (void) fprintf(stderr,
2973                             gettext("missing <new_device> specification\n"));
2974                         usage(B_FALSE);
2975                 }
2976                 new_disk = old_disk;
2977                 argc -= 1;
2978                 argv += 1;
2979         } else {
2980                 new_disk = argv[2];
2981                 argc -= 2;
2982                 argv += 2;
2983         }
2984 
2985         if (argc > 1) {
2986                 (void) fprintf(stderr, gettext("too many arguments\n"));
2987                 usage(B_FALSE);
2988         }
2989 
2990         if ((zhp = zpool_open(g_zfs, poolname)) == NULL)
2991                 return (1);
2992 
2993         if (zpool_get_config(zhp, NULL) == NULL) {
2994                 (void) fprintf(stderr, gettext("pool '%s' is unavailable\n"),
2995                     poolname);
2996                 zpool_close(zhp);
2997                 return (1);
2998         }
2999 
3000         nvroot = make_root_vdev(zhp, force, B_FALSE, replacing, B_FALSE,
3001             argc, argv);
3002         if (nvroot == NULL) {
3003                 zpool_close(zhp);
3004                 return (1);
3005         }
3006 
3007         ret = zpool_vdev_attach(zhp, old_disk, new_disk, nvroot, replacing);
3008 
3009         nvlist_free(nvroot);
3010         zpool_close(zhp);
3011 
3012         return (ret);
3013 }
3014 
3015 /*
3016  * zpool replace [-f] <pool> <device> <new_device>
3017  *
3018  *      -f      Force attach, even if <new_device> appears to be in use.
3019  *
3020  * Replace <device> with <new_device>.
3021  */
3022 /* ARGSUSED */
3023 int
3024 zpool_do_replace(int argc, char **argv)
3025 {
3026         return (zpool_do_attach_or_replace(argc, argv, B_TRUE));
3027 }
3028 
3029 /*
3030  * zpool attach [-f] <pool> <device> <new_device>
3031  *
3032  *      -f      Force attach, even if <new_device> appears to be in use.
3033  *
3034  * Attach <new_device> to the mirror containing <device>.  If <device> is not
3035  * part of a mirror, then <device> will be transformed into a mirror of
3036  * <device> and <new_device>.  In either case, <new_device> will begin life
3037  * with a DTL of [0, now], and will immediately begin to resilver itself.
3038  */
3039 int
3040 zpool_do_attach(int argc, char **argv)
3041 {
3042         return (zpool_do_attach_or_replace(argc, argv, B_FALSE));
3043 }
3044 
3045 /*
3046  * zpool detach [-f] <pool> <device>
3047  *
3048  *      -f      Force detach of <device>, even if DTLs argue against it
3049  *              (not supported yet)
3050  *
3051  * Detach a device from a mirror.  The operation will be refused if <device>
3052  * is the last device in the mirror, or if the DTLs indicate that this device
3053  * has the only valid copy of some data.
3054  */
3055 /* ARGSUSED */
3056 int
3057 zpool_do_detach(int argc, char **argv)
3058 {
3059         int c;
3060         char *poolname, *path;
3061         zpool_handle_t *zhp;
3062         int ret;
3063 
3064         /* check options */
3065         while ((c = getopt(argc, argv, "f")) != -1) {
3066                 switch (c) {
3067                 case 'f':
3068                 case '?':
3069                         (void) fprintf(stderr, gettext("invalid option '%c'\n"),
3070                             optopt);
3071                         usage(B_FALSE);
3072                 }
3073         }
3074 
3075         argc -= optind;
3076         argv += optind;
3077 
3078         /* get pool name and check number of arguments */
3079         if (argc < 1) {
3080                 (void) fprintf(stderr, gettext("missing pool name argument\n"));
3081                 usage(B_FALSE);
3082         }
3083 
3084         if (argc < 2) {
3085                 (void) fprintf(stderr,
3086                     gettext("missing <device> specification\n"));
3087                 usage(B_FALSE);
3088         }
3089 
3090         poolname = argv[0];
3091         path = argv[1];
3092 
3093         if ((zhp = zpool_open(g_zfs, poolname)) == NULL)
3094                 return (1);
3095 
3096         ret = zpool_vdev_detach(zhp, path);
3097 
3098         zpool_close(zhp);
3099 
3100         return (ret);
3101 }
3102 
3103 /*
3104  * zpool split [-n] [-o prop=val] ...
3105  *              [-o mntopt] ...
3106  *              [-R altroot] <pool> <newpool> [<device> ...]
3107  *
3108  *      -n      Do not split the pool, but display the resulting layout if
3109  *              it were to be split.
3110  *      -o      Set property=value, or set mount options.
3111  *      -R      Mount the split-off pool under an alternate root.
3112  *
3113  * Splits the named pool and gives it the new pool name.  Devices to be split
3114  * off may be listed, provided that no more than one device is specified
3115  * per top-level vdev mirror.  The newly split pool is left in an exported
3116  * state unless -R is specified.
3117  *
3118  * Restrictions: the top-level of the pool pool must only be made up of
3119  * mirrors; all devices in the pool must be healthy; no device may be
3120  * undergoing a resilvering operation.
3121  */
3122 int
3123 zpool_do_split(int argc, char **argv)
3124 {
3125         char *srcpool, *newpool, *propval;
3126         char *mntopts = NULL;
3127         splitflags_t flags;
3128         int c, ret = 0;
3129         zpool_handle_t *zhp;
3130         nvlist_t *config, *props = NULL;
3131 
3132         flags.dryrun = B_FALSE;
3133         flags.import = B_FALSE;
3134 
3135         /* check options */
3136         while ((c = getopt(argc, argv, ":R:no:")) != -1) {
3137                 switch (c) {
3138                 case 'R':
3139                         flags.import = B_TRUE;
3140                         if (add_prop_list(
3141                             zpool_prop_to_name(ZPOOL_PROP_ALTROOT), optarg,
3142                             &props, B_TRUE) != 0) {
3143                                 if (props)
3144                                         nvlist_free(props);
3145                                 usage(B_FALSE);
3146                         }
3147                         break;
3148                 case 'n':
3149                         flags.dryrun = B_TRUE;
3150                         break;
3151                 case 'o':
3152                         if ((propval = strchr(optarg, '=')) != NULL) {
3153                                 *propval = '\0';
3154                                 propval++;
3155                                 if (add_prop_list(optarg, propval,
3156                                     &props, B_TRUE) != 0) {
3157                                         if (props)
3158                                                 nvlist_free(props);
3159                                         usage(B_FALSE);
3160                                 }
3161                         } else {
3162                                 mntopts = optarg;
3163                         }
3164                         break;
3165                 case ':':
3166                         (void) fprintf(stderr, gettext("missing argument for "
3167                             "'%c' option\n"), optopt);
3168                         usage(B_FALSE);
3169                         break;
3170                 case '?':
3171                         (void) fprintf(stderr, gettext("invalid option '%c'\n"),
3172                             optopt);
3173                         usage(B_FALSE);
3174                         break;
3175                 }
3176         }
3177 
3178         if (!flags.import && mntopts != NULL) {
3179                 (void) fprintf(stderr, gettext("setting mntopts is only "
3180                     "valid when importing the pool\n"));
3181                 usage(B_FALSE);
3182         }
3183 
3184         argc -= optind;
3185         argv += optind;
3186 
3187         if (argc < 1) {
3188                 (void) fprintf(stderr, gettext("Missing pool name\n"));
3189                 usage(B_FALSE);
3190         }
3191         if (argc < 2) {
3192                 (void) fprintf(stderr, gettext("Missing new pool name\n"));
3193                 usage(B_FALSE);
3194         }
3195 
3196         srcpool = argv[0];
3197         newpool = argv[1];
3198 
3199         argc -= 2;
3200         argv += 2;
3201 
3202         if ((zhp = zpool_open(g_zfs, srcpool)) == NULL)
3203                 return (1);
3204 
3205         config = split_mirror_vdev(zhp, newpool, props, flags, argc, argv);
3206         if (config == NULL) {
3207                 ret = 1;
3208         } else {
3209                 if (flags.dryrun) {
3210                         (void) printf(gettext("would create '%s' with the "
3211                             "following layout:\n\n"), newpool);
3212                         print_vdev_tree(NULL, newpool, config, 0, B_FALSE);
3213                 }
3214                 nvlist_free(config);
3215         }
3216 
3217         zpool_close(zhp);
3218 
3219         if (ret != 0 || flags.dryrun || !flags.import)
3220                 return (ret);
3221 
3222         /*
3223          * The split was successful. Now we need to open the new
3224          * pool and import it.
3225          */
3226         if ((zhp = zpool_open_canfail(g_zfs, newpool)) == NULL)
3227                 return (1);
3228         if (zpool_get_state(zhp) != POOL_STATE_UNAVAIL &&
3229             zpool_enable_datasets(zhp, mntopts, 0) != 0) {
3230                 ret = 1;
3231                 (void) fprintf(stderr, gettext("Split was succssful, but "
3232                     "the datasets could not all be mounted\n"));
3233                 (void) fprintf(stderr, gettext("Try doing '%s' with a "
3234                     "different altroot\n"), "zpool import");
3235         }
3236         zpool_close(zhp);
3237 
3238         return (ret);
3239 }
3240 
3241 
3242 
3243 /*
3244  * zpool online <pool> <device> ...
3245  */
3246 int
3247 zpool_do_online(int argc, char **argv)
3248 {
3249         int c, i;
3250         char *poolname;
3251         zpool_handle_t *zhp;
3252         int ret = 0;
3253         vdev_state_t newstate;
3254         int flags = 0;
3255 
3256         /* check options */
3257         while ((c = getopt(argc, argv, "et")) != -1) {
3258                 switch (c) {
3259                 case 'e':
3260                         flags |= ZFS_ONLINE_EXPAND;
3261                         break;
3262                 case 't':
3263                 case '?':
3264                         (void) fprintf(stderr, gettext("invalid option '%c'\n"),
3265                             optopt);
3266                         usage(B_FALSE);
3267                 }
3268         }
3269 
3270         argc -= optind;
3271         argv += optind;
3272 
3273         /* get pool name and check number of arguments */
3274         if (argc < 1) {
3275                 (void) fprintf(stderr, gettext("missing pool name\n"));
3276                 usage(B_FALSE);
3277         }
3278         if (argc < 2) {
3279                 (void) fprintf(stderr, gettext("missing device name\n"));
3280                 usage(B_FALSE);
3281         }
3282 
3283         poolname = argv[0];
3284 
3285         if ((zhp = zpool_open(g_zfs, poolname)) == NULL)
3286                 return (1);
3287 
3288         for (i = 1; i < argc; i++) {
3289                 if (zpool_vdev_online(zhp, argv[i], flags, &newstate) == 0) {
3290                         if (newstate != VDEV_STATE_HEALTHY) {
3291                                 (void) printf(gettext("warning: device '%s' "
3292                                     "onlined, but remains in faulted state\n"),
3293                                     argv[i]);
3294                                 if (newstate == VDEV_STATE_FAULTED)
3295                                         (void) printf(gettext("use 'zpool "
3296                                             "clear' to restore a faulted "
3297                                             "device\n"));
3298                                 else
3299                                         (void) printf(gettext("use 'zpool "
3300                                             "replace' to replace devices "
3301                                             "that are no longer present\n"));
3302                         }
3303                 } else {
3304                         ret = 1;
3305                 }
3306         }
3307 
3308         zpool_close(zhp);
3309 
3310         return (ret);
3311 }
3312 
3313 /*
3314  * zpool offline [-ft] <pool> <device> ...
3315  *
3316  *      -f      Force the device into the offline state, even if doing
3317  *              so would appear to compromise pool availability.
3318  *              (not supported yet)
3319  *
3320  *      -t      Only take the device off-line temporarily.  The offline
3321  *              state will not be persistent across reboots.
3322  */
3323 /* ARGSUSED */
3324 int
3325 zpool_do_offline(int argc, char **argv)
3326 {
3327         int c, i;
3328         char *poolname;
3329         zpool_handle_t *zhp;
3330         int ret = 0;
3331         boolean_t istmp = B_FALSE;
3332 
3333         /* check options */
3334         while ((c = getopt(argc, argv, "ft")) != -1) {
3335                 switch (c) {
3336                 case 't':
3337                         istmp = B_TRUE;
3338                         break;
3339                 case 'f':
3340                 case '?':
3341                         (void) fprintf(stderr, gettext("invalid option '%c'\n"),
3342                             optopt);
3343                         usage(B_FALSE);
3344                 }
3345         }
3346 
3347         argc -= optind;
3348         argv += optind;
3349 
3350         /* get pool name and check number of arguments */
3351         if (argc < 1) {
3352                 (void) fprintf(stderr, gettext("missing pool name\n"));
3353                 usage(B_FALSE);
3354         }
3355         if (argc < 2) {
3356                 (void) fprintf(stderr, gettext("missing device name\n"));
3357                 usage(B_FALSE);
3358         }
3359 
3360         poolname = argv[0];
3361 
3362         if ((zhp = zpool_open(g_zfs, poolname)) == NULL)
3363                 return (1);
3364 
3365         for (i = 1; i < argc; i++) {
3366                 if (zpool_vdev_offline(zhp, argv[i], istmp) != 0)
3367                         ret = 1;
3368         }
3369 
3370         zpool_close(zhp);
3371 
3372         return (ret);
3373 }
3374 
3375 /*
3376  * zpool clear <pool> [device]
3377  *
3378  * Clear all errors associated with a pool or a particular device.
3379  */
3380 int
3381 zpool_do_clear(int argc, char **argv)
3382 {
3383         int c;
3384         int ret = 0;
3385         boolean_t dryrun = B_FALSE;
3386         boolean_t do_rewind = B_FALSE;
3387         boolean_t xtreme_rewind = B_FALSE;
3388         uint32_t rewind_policy = ZPOOL_NO_REWIND;
3389         nvlist_t *policy = NULL;
3390         zpool_handle_t *zhp;
3391         char *pool, *device;
3392 
3393         /* check options */
3394         while ((c = getopt(argc, argv, "FnX")) != -1) {
3395                 switch (c) {
3396                 case 'F':
3397                         do_rewind = B_TRUE;
3398                         break;
3399                 case 'n':
3400                         dryrun = B_TRUE;
3401                         break;
3402                 case 'X':
3403                         xtreme_rewind = B_TRUE;
3404                         break;
3405                 case '?':
3406                         (void) fprintf(stderr, gettext("invalid option '%c'\n"),
3407                             optopt);
3408                         usage(B_FALSE);
3409                 }
3410         }
3411 
3412         argc -= optind;
3413         argv += optind;
3414 
3415         if (argc < 1) {
3416                 (void) fprintf(stderr, gettext("missing pool name\n"));
3417                 usage(B_FALSE);
3418         }
3419 
3420         if (argc > 2) {
3421                 (void) fprintf(stderr, gettext("too many arguments\n"));
3422                 usage(B_FALSE);
3423         }
3424 
3425         if ((dryrun || xtreme_rewind) && !do_rewind) {
3426                 (void) fprintf(stderr,
3427                     gettext("-n or -X only meaningful with -F\n"));
3428                 usage(B_FALSE);
3429         }
3430         if (dryrun)
3431                 rewind_policy = ZPOOL_TRY_REWIND;
3432         else if (do_rewind)
3433                 rewind_policy = ZPOOL_DO_REWIND;
3434         if (xtreme_rewind)
3435                 rewind_policy |= ZPOOL_EXTREME_REWIND;
3436 
3437         /* In future, further rewind policy choices can be passed along here */
3438         if (nvlist_alloc(&policy, NV_UNIQUE_NAME, 0) != 0 ||
3439             nvlist_add_uint32(policy, ZPOOL_REWIND_REQUEST, rewind_policy) != 0)
3440                 return (1);
3441 
3442         pool = argv[0];
3443         device = argc == 2 ? argv[1] : NULL;
3444 
3445         if ((zhp = zpool_open_canfail(g_zfs, pool)) == NULL) {
3446                 nvlist_free(policy);
3447                 return (1);
3448         }
3449 
3450         if (zpool_clear(zhp, device, policy) != 0)
3451                 ret = 1;
3452 
3453         zpool_close(zhp);
3454 
3455         nvlist_free(policy);
3456 
3457         return (ret);
3458 }
3459 
3460 /*
3461  * zpool reguid <pool>
3462  */
3463 int
3464 zpool_do_reguid(int argc, char **argv)
3465 {
3466         int c;
3467         char *poolname;
3468         zpool_handle_t *zhp;
3469         int ret = 0;
3470 
3471         /* check options */
3472         while ((c = getopt(argc, argv, "")) != -1) {
3473                 switch (c) {
3474                 case '?':
3475                         (void) fprintf(stderr, gettext("invalid option '%c'\n"),
3476                             optopt);
3477                         usage(B_FALSE);
3478                 }
3479         }
3480 
3481         argc -= optind;
3482         argv += optind;
3483 
3484         /* get pool name and check number of arguments */
3485         if (argc < 1) {
3486                 (void) fprintf(stderr, gettext("missing pool name\n"));
3487                 usage(B_FALSE);
3488         }
3489 
3490         if (argc > 1) {
3491                 (void) fprintf(stderr, gettext("too many arguments\n"));
3492                 usage(B_FALSE);
3493         }
3494 
3495         poolname = argv[0];
3496         if ((zhp = zpool_open(g_zfs, poolname)) == NULL)
3497                 return (1);
3498 
3499         ret = zpool_reguid(zhp);
3500 
3501         zpool_close(zhp);
3502         return (ret);
3503 }
3504 
3505 
3506 /*
3507  * zpool reopen <pool>
3508  *
3509  * Reopen the pool so that the kernel can update the sizes of all vdevs.
3510  *
3511  * NOTE: This command is currently undocumented.  If the command is ever
3512  * exposed then the appropriate usage() messages will need to be made.
3513  */
3514 int
3515 zpool_do_reopen(int argc, char **argv)
3516 {
3517         int ret = 0;
3518         zpool_handle_t *zhp;
3519         char *pool;
3520 
3521         argc--;
3522         argv++;
3523 
3524         if (argc != 1)
3525                 return (2);
3526 
3527         pool = argv[0];
3528         if ((zhp = zpool_open_canfail(g_zfs, pool)) == NULL)
3529                 return (1);
3530 
3531         ret = zpool_reopen(zhp);
3532         zpool_close(zhp);
3533         return (ret);
3534 }
3535 
3536 typedef struct scrub_cbdata {
3537         int     cb_type;
3538         int     cb_argc;
3539         char    **cb_argv;
3540 } scrub_cbdata_t;
3541 
3542 int
3543 scrub_callback(zpool_handle_t *zhp, void *data)
3544 {
3545         scrub_cbdata_t *cb = data;
3546         int err;
3547 
3548         /*
3549          * Ignore faulted pools.
3550          */
3551         if (zpool_get_state(zhp) == POOL_STATE_UNAVAIL) {
3552                 (void) fprintf(stderr, gettext("cannot scrub '%s': pool is "
3553                     "currently unavailable\n"), zpool_get_name(zhp));
3554                 return (1);
3555         }
3556 
3557         err = zpool_scan(zhp, cb->cb_type);
3558 
3559         return (err != 0);
3560 }
3561 
3562 /*
3563  * zpool scrub [-s] <pool> ...
3564  *
3565  *      -s      Stop.  Stops any in-progress scrub.
3566  */
3567 int
3568 zpool_do_scrub(int argc, char **argv)
3569 {
3570         int c;
3571         scrub_cbdata_t cb;
3572 
3573         cb.cb_type = POOL_SCAN_SCRUB;
3574 
3575         /* check options */
3576         while ((c = getopt(argc, argv, "s")) != -1) {
3577                 switch (c) {
3578                 case 's':
3579                         cb.cb_type = POOL_SCAN_NONE;
3580                         break;
3581                 case '?':
3582                         (void) fprintf(stderr, gettext("invalid option '%c'\n"),
3583                             optopt);
3584                         usage(B_FALSE);
3585                 }
3586         }
3587 
3588         cb.cb_argc = argc;
3589         cb.cb_argv = argv;
3590         argc -= optind;
3591         argv += optind;
3592 
3593         if (argc < 1) {
3594                 (void) fprintf(stderr, gettext("missing pool name argument\n"));
3595                 usage(B_FALSE);
3596         }
3597 
3598         return (for_each_pool(argc, argv, B_TRUE, NULL, scrub_callback, &cb));
3599 }
3600 
3601 typedef struct status_cbdata {
3602         int             cb_count;
3603         boolean_t       cb_allpools;
3604         boolean_t       cb_verbose;
3605         boolean_t       cb_explain;
3606         boolean_t       cb_first;
3607         boolean_t       cb_dedup_stats;
3608 } status_cbdata_t;
3609 
3610 /*
3611  * Print out detailed scrub status.
3612  */
3613 void
3614 print_scan_status(pool_scan_stat_t *ps)
3615 {
3616         time_t start, end;
3617         uint64_t elapsed, mins_left, hours_left;
3618         uint64_t pass_exam, examined, total;
3619         uint_t rate;
3620         double fraction_done;
3621         char processed_buf[7], examined_buf[7], total_buf[7], rate_buf[7];
3622 
3623         (void) printf(gettext("  scan: "));
3624 
3625         /* If there's never been a scan, there's not much to say. */
3626         if (ps == NULL || ps->pss_func == POOL_SCAN_NONE ||
3627             ps->pss_func >= POOL_SCAN_FUNCS) {
3628                 (void) printf(gettext("none requested\n"));
3629                 return;
3630         }
3631 
3632         start = ps->pss_start_time;
3633         end = ps->pss_end_time;
3634         zfs_nicenum(ps->pss_processed, processed_buf, sizeof (processed_buf));
3635 
3636         assert(ps->pss_func == POOL_SCAN_SCRUB ||
3637             ps->pss_func == POOL_SCAN_RESILVER);
3638         /*
3639          * Scan is finished or canceled.
3640          */
3641         if (ps->pss_state == DSS_FINISHED) {
3642                 uint64_t minutes_taken = (end - start) / 60;
3643                 char *fmt;
3644 
3645                 if (ps->pss_func == POOL_SCAN_SCRUB) {
3646                         fmt = gettext("scrub repaired %s in %lluh%um with "
3647                             "%llu errors on %s");
3648                 } else if (ps->pss_func == POOL_SCAN_RESILVER) {
3649                         fmt = gettext("resilvered %s in %lluh%um with "
3650                             "%llu errors on %s");
3651                 }
3652                 /* LINTED */
3653                 (void) printf(fmt, processed_buf,
3654                     (u_longlong_t)(minutes_taken / 60),
3655                     (uint_t)(minutes_taken % 60),
3656                     (u_longlong_t)ps->pss_errors,
3657                     ctime((time_t *)&end));
3658                 return;
3659         } else if (ps->pss_state == DSS_CANCELED) {
3660                 if (ps->pss_func == POOL_SCAN_SCRUB) {
3661                         (void) printf(gettext("scrub canceled on %s"),
3662                             ctime(&end));
3663                 } else if (ps->pss_func == POOL_SCAN_RESILVER) {
3664                         (void) printf(gettext("resilver canceled on %s"),
3665                             ctime(&end));
3666                 }
3667                 return;
3668         }
3669 
3670         assert(ps->pss_state == DSS_SCANNING);
3671 
3672         /*
3673          * Scan is in progress.
3674          */
3675         if (ps->pss_func == POOL_SCAN_SCRUB) {
3676                 (void) printf(gettext("scrub in progress since %s"),
3677                     ctime(&start));
3678         } else if (ps->pss_func == POOL_SCAN_RESILVER) {
3679                 (void) printf(gettext("resilver in progress since %s"),
3680                     ctime(&start));
3681         }
3682 
3683         examined = ps->pss_examined ? ps->pss_examined : 1;
3684         total = ps->pss_to_examine;
3685         fraction_done = (double)examined / total;
3686 
3687         /* elapsed time for this pass */
3688         elapsed = time(NULL) - ps->pss_pass_start;
3689         elapsed = elapsed ? elapsed : 1;
3690         pass_exam = ps->pss_pass_exam ? ps->pss_pass_exam : 1;
3691         rate = pass_exam / elapsed;
3692         rate = rate ? rate : 1;
3693         mins_left = ((total - examined) / rate) / 60;
3694         hours_left = mins_left / 60;
3695 
3696         zfs_nicenum(examined, examined_buf, sizeof (examined_buf));
3697         zfs_nicenum(total, total_buf, sizeof (total_buf));
3698         zfs_nicenum(rate, rate_buf, sizeof (rate_buf));
3699 
3700         /*
3701          * do not print estimated time if hours_left is more than 30 days
3702          */
3703         (void) printf(gettext("    %s scanned out of %s at %s/s"),
3704             examined_buf, total_buf, rate_buf);
3705         if (hours_left < (30 * 24)) {
3706                 (void) printf(gettext(", %lluh%um to go\n"),
3707                     (u_longlong_t)hours_left, (uint_t)(mins_left % 60));
3708         } else {
3709                 (void) printf(gettext(
3710                     ", (scan is slow, no estimated time)\n"));
3711         }
3712 
3713         if (ps->pss_func == POOL_SCAN_RESILVER) {
3714                 (void) printf(gettext("    %s resilvered, %.2f%% done\n"),
3715                     processed_buf, 100 * fraction_done);
3716         } else if (ps->pss_func == POOL_SCAN_SCRUB) {
3717                 (void) printf(gettext("    %s repaired, %.2f%% done\n"),
3718                     processed_buf, 100 * fraction_done);
3719         }
3720 }
3721 
3722 static void
3723 print_error_log(zpool_handle_t *zhp)
3724 {
3725         nvlist_t *nverrlist = NULL;
3726         nvpair_t *elem;
3727         char *pathname;
3728         size_t len = MAXPATHLEN * 2;
3729 
3730         if (zpool_get_errlog(zhp, &nverrlist) != 0) {
3731                 (void) printf("errors: List of errors unavailable "
3732                     "(insufficient privileges)\n");
3733                 return;
3734         }
3735 
3736         (void) printf("errors: Permanent errors have been "
3737             "detected in the following files:\n\n");
3738 
3739         pathname = safe_malloc(len);
3740         elem = NULL;
3741         while ((elem = nvlist_next_nvpair(nverrlist, elem)) != NULL) {
3742                 nvlist_t *nv;
3743                 uint64_t dsobj, obj;
3744 
3745                 verify(nvpair_value_nvlist(elem, &nv) == 0);
3746                 verify(nvlist_lookup_uint64(nv, ZPOOL_ERR_DATASET,
3747                     &dsobj) == 0);
3748                 verify(nvlist_lookup_uint64(nv, ZPOOL_ERR_OBJECT,
3749                     &obj) == 0);
3750                 zpool_obj_to_path(zhp, dsobj, obj, pathname, len);
3751                 (void) printf("%7s %s\n", "", pathname);
3752         }
3753         free(pathname);
3754         nvlist_free(nverrlist);
3755 }
3756 
3757 static void
3758 print_spares(zpool_handle_t *zhp, nvlist_t **spares, uint_t nspares,
3759     int namewidth)
3760 {
3761         uint_t i;
3762         char *name;
3763 
3764         if (nspares == 0)
3765                 return;
3766 
3767         (void) printf(gettext("\tspares\n"));
3768 
3769         for (i = 0; i < nspares; i++) {
3770                 name = zpool_vdev_name(g_zfs, zhp, spares[i], B_FALSE);
3771                 print_status_config(zhp, name, spares[i],
3772                     namewidth, 2, B_TRUE);
3773                 free(name);
3774         }
3775 }
3776 
3777 static void
3778 print_l2cache(zpool_handle_t *zhp, nvlist_t **l2cache, uint_t nl2cache,
3779     int namewidth)
3780 {
3781         uint_t i;
3782         char *name;
3783 
3784         if (nl2cache == 0)
3785                 return;
3786 
3787         (void) printf(gettext("\tcache\n"));
3788 
3789         for (i = 0; i < nl2cache; i++) {
3790                 name = zpool_vdev_name(g_zfs, zhp, l2cache[i], B_FALSE);
3791                 print_status_config(zhp, name, l2cache[i],
3792                     namewidth, 2, B_FALSE);
3793                 free(name);
3794         }
3795 }
3796 
3797 static void
3798 print_dedup_stats(nvlist_t *config)
3799 {
3800         ddt_histogram_t *ddh;
3801         ddt_stat_t *dds;
3802         ddt_object_t *ddo;
3803         uint_t c;
3804 
3805         /*
3806          * If the pool was faulted then we may not have been able to
3807          * obtain the config. Otherwise, if we have anything in the dedup
3808          * table continue processing the stats.
3809          */
3810         if (nvlist_lookup_uint64_array(config, ZPOOL_CONFIG_DDT_OBJ_STATS,
3811             (uint64_t **)&ddo, &c) != 0)
3812                 return;
3813 
3814         (void) printf("\n");
3815         (void) printf(gettext(" dedup: "));
3816         if (ddo->ddo_count == 0) {
3817                 (void) printf(gettext("no DDT entries\n"));
3818                 return;
3819         }
3820 
3821         (void) printf("DDT entries %llu, size %llu on disk, %llu in core\n",
3822             (u_longlong_t)ddo->ddo_count,
3823             (u_longlong_t)ddo->ddo_dspace,
3824             (u_longlong_t)ddo->ddo_mspace);
3825 
3826         verify(nvlist_lookup_uint64_array(config, ZPOOL_CONFIG_DDT_STATS,
3827             (uint64_t **)&dds, &c) == 0);
3828         verify(nvlist_lookup_uint64_array(config, ZPOOL_CONFIG_DDT_HISTOGRAM,
3829             (uint64_t **)&ddh, &c) == 0);
3830         zpool_dump_ddt(dds, ddh);
3831 }
3832 
3833 /*
3834  * Display a summary of pool status.  Displays a summary such as:
3835  *
3836  *        pool: tank
3837  *      status: DEGRADED
3838  *      reason: One or more devices ...
3839  *         see: http://illumos.org/msg/ZFS-xxxx-01
3840  *      config:
3841  *              mirror          DEGRADED
3842  *                c1t0d0        OK
3843  *                c2t0d0        UNAVAIL
3844  *
3845  * When given the '-v' option, we print out the complete config.  If the '-e'
3846  * option is specified, then we print out error rate information as well.
3847  */
3848 int
3849 status_callback(zpool_handle_t *zhp, void *data)
3850 {
3851         status_cbdata_t *cbp = data;
3852         nvlist_t *config, *nvroot;
3853         char *msgid;
3854         int reason;
3855         const char *health;
3856         uint_t c;
3857         vdev_stat_t *vs;
3858 
3859         config = zpool_get_config(zhp, NULL);
3860         reason = zpool_get_status(zhp, &msgid);
3861 
3862         cbp->cb_count++;
3863 
3864         /*
3865          * If we were given 'zpool status -x', only report those pools with
3866          * problems.
3867          */
3868         if (reason == ZPOOL_STATUS_OK && cbp->cb_explain) {
3869                 if (!cbp->cb_allpools) {
3870                         (void) printf(gettext("pool '%s' is healthy\n"),
3871                             zpool_get_name(zhp));
3872                         if (cbp->cb_first)
3873                                 cbp->cb_first = B_FALSE;
3874                 }
3875                 return (0);
3876         }
3877 
3878         if (cbp->cb_first)
3879                 cbp->cb_first = B_FALSE;
3880         else
3881                 (void) printf("\n");
3882 
3883         verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
3884             &nvroot) == 0);
3885         verify(nvlist_lookup_uint64_array(nvroot, ZPOOL_CONFIG_VDEV_STATS,
3886             (uint64_t **)&vs, &c) == 0);
3887         health = zpool_state_to_name(vs->vs_state, vs->vs_aux);
3888 
3889         (void) printf(gettext("  pool: %s\n"), zpool_get_name(zhp));
3890         (void) printf(gettext(" state: %s\n"), health);
3891 
3892         switch (reason) {
3893         case ZPOOL_STATUS_MISSING_DEV_R:
3894                 (void) printf(gettext("status: One or more devices could not "
3895                     "be opened.  Sufficient replicas exist for\n\tthe pool to "
3896                     "continue functioning in a degraded state.\n"));
3897                 (void) printf(gettext("action: Attach the missing device and "
3898                     "online it using 'zpool online'.\n"));
3899                 break;
3900 
3901         case ZPOOL_STATUS_MISSING_DEV_NR:
3902                 (void) printf(gettext("status: One or more devices could not "
3903                     "be opened.  There are insufficient\n\treplicas for the "
3904                     "pool to continue functioning.\n"));
3905                 (void) printf(gettext("action: Attach the missing device and "
3906                     "online it using 'zpool online'.\n"));
3907                 break;
3908 
3909         case ZPOOL_STATUS_CORRUPT_LABEL_R:
3910                 (void) printf(gettext("status: One or more devices could not "
3911                     "be used because the label is missing or\n\tinvalid.  "
3912                     "Sufficient replicas exist for the pool to continue\n\t"
3913                     "functioning in a degraded state.\n"));
3914                 (void) printf(gettext("action: Replace the device using "
3915                     "'zpool replace'.\n"));
3916                 break;
3917 
3918         case ZPOOL_STATUS_CORRUPT_LABEL_NR:
3919                 (void) printf(gettext("status: One or more devices could not "
3920                     "be used because the label is missing \n\tor invalid.  "
3921                     "There are insufficient replicas for the pool to "
3922                     "continue\n\tfunctioning.\n"));
3923                 zpool_explain_recover(zpool_get_handle(zhp),
3924                     zpool_get_name(zhp), reason, config);
3925                 break;
3926 
3927         case ZPOOL_STATUS_FAILING_DEV:
3928                 (void) printf(gettext("status: One or more devices has "
3929                     "experienced an unrecoverable error.  An\n\tattempt was "
3930                     "made to correct the error.  Applications are "
3931                     "unaffected.\n"));
3932                 (void) printf(gettext("action: Determine if the device needs "
3933                     "to be replaced, and clear the errors\n\tusing "
3934                     "'zpool clear' or replace the device with 'zpool "
3935                     "replace'.\n"));
3936                 break;
3937 
3938         case ZPOOL_STATUS_OFFLINE_DEV:
3939                 (void) printf(gettext("status: One or more devices has "
3940                     "been taken offline by the administrator.\n\tSufficient "
3941                     "replicas exist for the pool to continue functioning in "
3942                     "a\n\tdegraded state.\n"));
3943                 (void) printf(gettext("action: Online the device using "
3944                     "'zpool online' or replace the device with\n\t'zpool "
3945                     "replace'.\n"));
3946                 break;
3947 
3948         case ZPOOL_STATUS_REMOVED_DEV:
3949                 (void) printf(gettext("status: One or more devices has "
3950                     "been removed by the administrator.\n\tSufficient "
3951                     "replicas exist for the pool to continue functioning in "
3952                     "a\n\tdegraded state.\n"));
3953                 (void) printf(gettext("action: Online the device using "
3954                     "'zpool online' or replace the device with\n\t'zpool "
3955                     "replace'.\n"));
3956                 break;
3957 
3958         case ZPOOL_STATUS_RESILVERING:
3959                 (void) printf(gettext("status: One or more devices is "
3960                     "currently being resilvered.  The pool will\n\tcontinue "
3961                     "to function, possibly in a degraded state.\n"));
3962                 (void) printf(gettext("action: Wait for the resilver to "
3963                     "complete.\n"));
3964                 break;
3965 
3966         case ZPOOL_STATUS_CORRUPT_DATA:
3967                 (void) printf(gettext("status: One or more devices has "
3968                     "experienced an error resulting in data\n\tcorruption.  "
3969                     "Applications may be affected.\n"));
3970                 (void) printf(gettext("action: Restore the file in question "
3971                     "if possible.  Otherwise restore the\n\tentire pool from "
3972                     "backup.\n"));
3973                 break;
3974 
3975         case ZPOOL_STATUS_CORRUPT_POOL:
3976                 (void) printf(gettext("status: The pool metadata is corrupted "
3977                     "and the pool cannot be opened.\n"));
3978                 zpool_explain_recover(zpool_get_handle(zhp),
3979                     zpool_get_name(zhp), reason, config);
3980                 break;
3981 
3982         case ZPOOL_STATUS_VERSION_OLDER:
3983                 (void) printf(gettext("status: The pool is formatted using an "
3984                     "older on-disk format.  The pool can\n\tstill be used, but "
3985                     "some features are unavailable.\n"));
3986                 (void) printf(gettext("action: Upgrade the pool using 'zpool "
3987                     "upgrade'.  Once this is done, the\n\tpool will no longer "
3988                     "be accessible on older software versions.\n"));
3989                 break;
3990 
3991         case ZPOOL_STATUS_VERSION_NEWER:
3992                 (void) printf(gettext("status: The pool has been upgraded to a "
3993                     "newer, incompatible on-disk version.\n\tThe pool cannot "
3994                     "be accessed on this system.\n"));
3995                 (void) printf(gettext("action: Access the pool from a system "
3996                     "running more recent software, or\n\trestore the pool from "
3997                     "backup.\n"));
3998                 break;
3999 
4000         case ZPOOL_STATUS_UNSUP_FEAT_READ:
4001                 (void) printf(gettext("status: The pool cannot be accessed on "
4002                     "this system because it uses the\n\tfollowing feature(s) "
4003                     "not supported on this system:\n"));
4004                 zpool_print_unsup_feat(config);
4005                 (void) printf("\n");
4006                 (void) printf(gettext("action: Access the pool from a system "
4007                     "that supports the required feature(s),\n\tor restore the "
4008                     "pool from backup.\n"));
4009                 break;
4010 
4011         case ZPOOL_STATUS_UNSUP_FEAT_WRITE:
4012                 (void) printf(gettext("status: The pool can only be accessed "
4013                     "in read-only mode on this system. It\n\tcannot be "
4014                     "accessed in read-write mode because it uses the "
4015                     "following\n\tfeature(s) not supported on this system:\n"));
4016                 zpool_print_unsup_feat(config);
4017                 (void) printf("\n");
4018                 (void) printf(gettext("action: The pool cannot be accessed in "
4019                     "read-write mode. Import the pool with\n"
4020                     "\t\"-o readonly=on\", access the pool from a system that "
4021                     "supports the\n\trequired feature(s), or restore the "
4022                     "pool from backup.\n"));
4023                 break;
4024 
4025         case ZPOOL_STATUS_FAULTED_DEV_R:
4026                 (void) printf(gettext("status: One or more devices are "
4027                     "faulted in response to persistent errors.\n\tSufficient "
4028                     "replicas exist for the pool to continue functioning "
4029                     "in a\n\tdegraded state.\n"));
4030                 (void) printf(gettext("action: Replace the faulted device, "
4031                     "or use 'zpool clear' to mark the device\n\trepaired.\n"));
4032                 break;
4033 
4034         case ZPOOL_STATUS_FAULTED_DEV_NR:
4035                 (void) printf(gettext("status: One or more devices are "
4036                     "faulted in response to persistent errors.  There are "
4037                     "insufficient replicas for the pool to\n\tcontinue "
4038                     "functioning.\n"));
4039                 (void) printf(gettext("action: Destroy and re-create the pool "
4040                     "from a backup source.  Manually marking the device\n"
4041                     "\trepaired using 'zpool clear' may allow some data "
4042                     "to be recovered.\n"));
4043                 break;
4044 
4045         case ZPOOL_STATUS_IO_FAILURE_WAIT:
4046         case ZPOOL_STATUS_IO_FAILURE_CONTINUE:
4047                 (void) printf(gettext("status: One or more devices are "
4048                     "faulted in response to IO failures.\n"));
4049                 (void) printf(gettext("action: Make sure the affected devices "
4050                     "are connected, then run 'zpool clear'.\n"));
4051                 break;
4052 
4053         case ZPOOL_STATUS_BAD_LOG:
4054                 (void) printf(gettext("status: An intent log record "
4055                     "could not be read.\n"
4056                     "\tWaiting for adminstrator intervention to fix the "
4057                     "faulted pool.\n"));
4058                 (void) printf(gettext("action: Either restore the affected "
4059                     "device(s) and run 'zpool online',\n"
4060                     "\tor ignore the intent log records by running "
4061                     "'zpool clear'.\n"));
4062                 break;
4063 
4064         default:
4065                 /*
4066                  * The remaining errors can't actually be generated, yet.
4067                  */
4068                 assert(reason == ZPOOL_STATUS_OK);
4069         }
4070 
4071         if (msgid != NULL)
4072                 (void) printf(gettext("   see: http://illumos.org/msg/%s\n"),
4073                     msgid);
4074 
4075         if (config != NULL) {
4076                 int namewidth;
4077                 uint64_t nerr;
4078                 nvlist_t **spares, **l2cache;
4079                 uint_t nspares, nl2cache;
4080                 pool_scan_stat_t *ps = NULL;
4081 
4082                 (void) nvlist_lookup_uint64_array(nvroot,
4083                     ZPOOL_CONFIG_SCAN_STATS, (uint64_t **)&ps, &c);
4084                 print_scan_status(ps);
4085 
4086                 namewidth = max_width(zhp, nvroot, 0, 0);
4087                 if (namewidth < 10)
4088                         namewidth = 10;
4089 
4090                 (void) printf(gettext("config:\n\n"));
4091                 (void) printf(gettext("\t%-*s  %-8s %5s %5s %5s\n"), namewidth,
4092                     "NAME", "STATE", "READ", "WRITE", "CKSUM");
4093                 print_status_config(zhp, zpool_get_name(zhp), nvroot,
4094                     namewidth, 0, B_FALSE);
4095 
4096                 if (num_logs(nvroot) > 0)
4097                         print_logs(zhp, nvroot, namewidth, B_TRUE);
4098                 if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_L2CACHE,
4099                     &l2cache, &nl2cache) == 0)
4100                         print_l2cache(zhp, l2cache, nl2cache, namewidth);
4101 
4102                 if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_SPARES,
4103                     &spares, &nspares) == 0)
4104                         print_spares(zhp, spares, nspares, namewidth);
4105 
4106                 if (nvlist_lookup_uint64(config, ZPOOL_CONFIG_ERRCOUNT,
4107                     &nerr) == 0) {
4108                         nvlist_t *nverrlist = NULL;
4109 
4110                         /*
4111                          * If the approximate error count is small, get a
4112                          * precise count by fetching the entire log and
4113                          * uniquifying the results.
4114                          */
4115                         if (nerr > 0 && nerr < 100 && !cbp->cb_verbose &&
4116                             zpool_get_errlog(zhp, &nverrlist) == 0) {
4117                                 nvpair_t *elem;
4118 
4119                                 elem = NULL;
4120                                 nerr = 0;
4121                                 while ((elem = nvlist_next_nvpair(nverrlist,
4122                                     elem)) != NULL) {
4123                                         nerr++;
4124                                 }
4125                         }
4126                         nvlist_free(nverrlist);
4127 
4128                         (void) printf("\n");
4129 
4130                         if (nerr == 0)
4131                                 (void) printf(gettext("errors: No known data "
4132                                     "errors\n"));
4133                         else if (!cbp->cb_verbose)
4134                                 (void) printf(gettext("errors: %llu data "
4135                                     "errors, use '-v' for a list\n"),
4136                                     (u_longlong_t)nerr);
4137                         else
4138                                 print_error_log(zhp);
4139                 }
4140 
4141                 if (cbp->cb_dedup_stats)
4142                         print_dedup_stats(config);
4143         } else {
4144                 (void) printf(gettext("config: The configuration cannot be "
4145                     "determined.\n"));
4146         }
4147 
4148         return (0);
4149 }
4150 
4151 /*
4152  * zpool status [-vx] [-T d|u] [pool] ... [interval [count]]
4153  *
4154  *      -v      Display complete error logs
4155  *      -x      Display only pools with potential problems
4156  *      -D      Display dedup status (undocumented)
4157  *      -T      Display a timestamp in date(1) or Unix format
4158  *
4159  * Describes the health status of all pools or some subset.
4160  */
4161 int
4162 zpool_do_status(int argc, char **argv)
4163 {
4164         int c;
4165         int ret;
4166         unsigned long interval = 0, count = 0;
4167         status_cbdata_t cb = { 0 };
4168 
4169         /* check options */
4170         while ((c = getopt(argc, argv, "vxDT:")) != -1) {
4171                 switch (c) {
4172                 case 'v':
4173                         cb.cb_verbose = B_TRUE;
4174                         break;
4175                 case 'x':
4176                         cb.cb_explain = B_TRUE;
4177                         break;
4178                 case 'D':
4179                         cb.cb_dedup_stats = B_TRUE;
4180                         break;
4181                 case 'T':
4182                         get_timestamp_arg(*optarg);
4183                         break;
4184                 case '?':
4185                         (void) fprintf(stderr, gettext("invalid option '%c'\n"),
4186                             optopt);
4187                         usage(B_FALSE);
4188                 }
4189         }
4190 
4191         argc -= optind;
4192         argv += optind;
4193 
4194         get_interval_count(&argc, argv, &interval, &count);
4195 
4196         if (argc == 0)
4197                 cb.cb_allpools = B_TRUE;
4198 
4199         cb.cb_first = B_TRUE;
4200 
4201         for (;;) {
4202                 if (timestamp_fmt != NODATE)
4203                         print_timestamp(timestamp_fmt);
4204 
4205                 ret = for_each_pool(argc, argv, B_TRUE, NULL,
4206                     status_callback, &cb);
4207 
4208                 if (argc == 0 && cb.cb_count == 0)
4209                         (void) printf(gettext("no pools available\n"));
4210                 else if (cb.cb_explain && cb.cb_first && cb.cb_allpools)
4211                         (void) printf(gettext("all pools are healthy\n"));
4212 
4213                 if (ret != 0)
4214                         return (ret);
4215 
4216                 if (interval == 0)
4217                         break;
4218 
4219                 if (count != 0 && --count == 0)
4220                         break;
4221 
4222                 (void) sleep(interval);
4223         }
4224 
4225         return (0);
4226 }
4227 
4228 typedef struct upgrade_cbdata {
4229         int     cb_all;
4230         int     cb_first;
4231         int     cb_newer;
4232         int     cb_argc;
4233         uint64_t cb_version;
4234         char    **cb_argv;
4235 } upgrade_cbdata_t;
4236 
4237 static int
4238 upgrade_cb(zpool_handle_t *zhp, void *arg)
4239 {
4240         upgrade_cbdata_t *cbp = arg;
4241         nvlist_t *config;
4242         uint64_t version;
4243         int ret = 0;
4244 
4245         config = zpool_get_config(zhp, NULL);
4246         verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION,
4247             &version) == 0);
4248 
4249         if (!cbp->cb_newer && SPA_VERSION_IS_SUPPORTED(version) &&
4250             version != SPA_VERSION) {
4251                 if (!cbp->cb_all) {
4252                         if (cbp->cb_first) {
4253                                 (void) printf(gettext("The following pools are "
4254                                     "out of date, and can be upgraded.  After "
4255                                     "being\nupgraded, these pools will no "
4256                                     "longer be accessible by older software "
4257                                     "versions.\n\n"));
4258                                 (void) printf(gettext("VER  POOL\n"));
4259                                 (void) printf(gettext("---  ------------\n"));
4260                                 cbp->cb_first = B_FALSE;
4261                         }
4262 
4263                         (void) printf("%2llu   %s\n", (u_longlong_t)version,
4264                             zpool_get_name(zhp));
4265                 } else {
4266                         cbp->cb_first = B_FALSE;
4267                         ret = zpool_upgrade(zhp, cbp->cb_version);
4268                         if (!ret) {
4269                                 (void) printf(gettext("Successfully upgraded "
4270                                     "'%s'\n\n"), zpool_get_name(zhp));
4271                         }
4272                 }
4273         } else if (cbp->cb_newer && !SPA_VERSION_IS_SUPPORTED(version)) {
4274                 assert(!cbp->cb_all);
4275 
4276                 if (cbp->cb_first) {
4277                         (void) printf(gettext("The following pools are "
4278                             "formatted using an unsupported software version "
4279                             "and\ncannot be accessed on the current "
4280                             "system.\n\n"));
4281                         (void) printf(gettext("VER  POOL\n"));
4282                         (void) printf(gettext("---  ------------\n"));
4283                         cbp->cb_first = B_FALSE;
4284                 }
4285 
4286                 (void) printf("%2llu   %s\n", (u_longlong_t)version,
4287                     zpool_get_name(zhp));
4288         }
4289 
4290         zpool_close(zhp);
4291         return (ret);
4292 }
4293 
4294 /* ARGSUSED */
4295 static int
4296 upgrade_one(zpool_handle_t *zhp, void *data)
4297 {
4298         upgrade_cbdata_t *cbp = data;
4299         uint64_t cur_version;
4300         int ret;
4301 
4302         if (strcmp("log", zpool_get_name(zhp)) == 0) {
4303                 (void) printf(gettext("'log' is now a reserved word\n"
4304                     "Pool 'log' must be renamed using export and import"
4305                     " to upgrade.\n"));
4306                 return (1);
4307         }
4308 
4309         cur_version = zpool_get_prop_int(zhp, ZPOOL_PROP_VERSION, NULL);
4310         if (cur_version > cbp->cb_version) {
4311                 (void) printf(gettext("Pool '%s' is already formatted "
4312                     "using more current version '%llu'.\n"),
4313                     zpool_get_name(zhp), cur_version);
4314                 return (0);
4315         }
4316         if (cur_version == cbp->cb_version) {
4317                 (void) printf(gettext("Pool '%s' is already formatted "
4318                     "using the current version.\n"), zpool_get_name(zhp));
4319                 return (0);
4320         }
4321 
4322         ret = zpool_upgrade(zhp, cbp->cb_version);
4323 
4324         if (!ret) {
4325                 (void) printf(gettext("Successfully upgraded '%s' "
4326                     "from version %llu to version %llu\n\n"),
4327                     zpool_get_name(zhp), (u_longlong_t)cur_version,
4328                     (u_longlong_t)cbp->cb_version);
4329         }
4330 
4331         return (ret != 0);
4332 }
4333 
4334 /*
4335  * zpool upgrade
4336  * zpool upgrade -v
4337  * zpool upgrade [-V version] <-a | pool ...>
4338  *
4339  * With no arguments, display downrev'd ZFS pool available for upgrade.
4340  * Individual pools can be upgraded by specifying the pool, and '-a' will
4341  * upgrade all pools.
4342  */
4343 int
4344 zpool_do_upgrade(int argc, char **argv)
4345 {
4346         int c;
4347         upgrade_cbdata_t cb = { 0 };
4348         int ret = 0;
4349         boolean_t showversions = B_FALSE;
4350         char *end;
4351 
4352 
4353         /* check options */
4354         while ((c = getopt(argc, argv, ":avV:")) != -1) {
4355                 switch (c) {
4356                 case 'a':
4357                         cb.cb_all = B_TRUE;
4358                         break;
4359                 case 'v':
4360                         showversions = B_TRUE;
4361                         break;
4362                 case 'V':
4363                         cb.cb_version = strtoll(optarg, &end, 10);
4364                         if (*end != '\0' ||
4365                             !SPA_VERSION_IS_SUPPORTED(cb.cb_version)) {
4366                                 (void) fprintf(stderr,
4367                                     gettext("invalid version '%s'\n"), optarg);
4368                                 usage(B_FALSE);
4369                         }
4370                         break;
4371                 case ':':
4372                         (void) fprintf(stderr, gettext("missing argument for "
4373                             "'%c' option\n"), optopt);
4374                         usage(B_FALSE);
4375                         break;
4376                 case '?':
4377                         (void) fprintf(stderr, gettext("invalid option '%c'\n"),
4378                             optopt);
4379                         usage(B_FALSE);
4380                 }
4381         }
4382 
4383         cb.cb_argc = argc;
4384         cb.cb_argv = argv;
4385         argc -= optind;
4386         argv += optind;
4387 
4388         if (cb.cb_version == 0) {
4389                 cb.cb_version = SPA_VERSION;
4390         } else if (!cb.cb_all && argc == 0) {
4391                 (void) fprintf(stderr, gettext("-V option is "
4392                     "incompatible with other arguments\n"));
4393                 usage(B_FALSE);
4394         }
4395 
4396         if (showversions) {
4397                 if (cb.cb_all || argc != 0) {
4398                         (void) fprintf(stderr, gettext("-v option is "
4399                             "incompatible with other arguments\n"));
4400                         usage(B_FALSE);
4401                 }
4402         } else if (cb.cb_all) {
4403                 if (argc != 0) {
4404                         (void) fprintf(stderr, gettext("-a option should not "
4405                             "be used along with a pool name\n"));
4406                         usage(B_FALSE);
4407                 }
4408         }
4409 
4410         (void) printf(gettext("This system supports ZFS pool feature "
4411             "flags.\n\n"));
4412         cb.cb_first = B_TRUE;
4413         if (showversions) {
4414                 (void) printf(gettext("The following versions are "
4415                     "supported:\n\n"));
4416                 (void) printf(gettext("VER  DESCRIPTION\n"));
4417                 (void) printf("---  -----------------------------------------"
4418                     "---------------\n");
4419                 (void) printf(gettext(" 1   Initial ZFS version\n"));
4420                 (void) printf(gettext(" 2   Ditto blocks "
4421                     "(replicated metadata)\n"));
4422                 (void) printf(gettext(" 3   Hot spares and double parity "
4423                     "RAID-Z\n"));
4424                 (void) printf(gettext(" 4   zpool history\n"));
4425                 (void) printf(gettext(" 5   Compression using the gzip "
4426                     "algorithm\n"));
4427                 (void) printf(gettext(" 6   bootfs pool property\n"));
4428                 (void) printf(gettext(" 7   Separate intent log devices\n"));
4429                 (void) printf(gettext(" 8   Delegated administration\n"));
4430                 (void) printf(gettext(" 9   refquota and refreservation "
4431                     "properties\n"));
4432                 (void) printf(gettext(" 10  Cache devices\n"));
4433                 (void) printf(gettext(" 11  Improved scrub performance\n"));
4434                 (void) printf(gettext(" 12  Snapshot properties\n"));
4435                 (void) printf(gettext(" 13  snapused property\n"));
4436                 (void) printf(gettext(" 14  passthrough-x aclinherit\n"));
4437                 (void) printf(gettext(" 15  user/group space accounting\n"));
4438                 (void) printf(gettext(" 16  stmf property support\n"));
4439                 (void) printf(gettext(" 17  Triple-parity RAID-Z\n"));
4440                 (void) printf(gettext(" 18  Snapshot user holds\n"));
4441                 (void) printf(gettext(" 19  Log device removal\n"));
4442                 (void) printf(gettext(" 20  Compression using zle "
4443                     "(zero-length encoding)\n"));
4444                 (void) printf(gettext(" 21  Deduplication\n"));
4445                 (void) printf(gettext(" 22  Received properties\n"));
4446                 (void) printf(gettext(" 23  Slim ZIL\n"));
4447                 (void) printf(gettext(" 24  System attributes\n"));
4448                 (void) printf(gettext(" 25  Improved scrub stats\n"));
4449                 (void) printf(gettext(" 26  Improved snapshot deletion "
4450                     "performance\n"));
4451                 (void) printf(gettext(" 27  Improved snapshot creation "
4452                     "performance\n"));
4453                 (void) printf(gettext(" 28  Multiple vdev replacements\n"));
4454                 (void) printf(gettext("\nFor more information on a particular "
4455                     "version, including supported releases,\n"));
4456                 (void) printf(gettext("see the ZFS Administration Guide.\n\n"));
4457         } else if (argc == 0) {
4458                 int notfound;
4459 
4460                 ret = zpool_iter(g_zfs, upgrade_cb, &cb);
4461                 notfound = cb.cb_first;
4462 
4463                 if (!cb.cb_all && ret == 0) {
4464                         if (!cb.cb_first)
4465                                 (void) printf("\n");
4466                         cb.cb_first = B_TRUE;
4467                         cb.cb_newer = B_TRUE;
4468                         ret = zpool_iter(g_zfs, upgrade_cb, &cb);
4469                         if (!cb.cb_first) {
4470                                 notfound = B_FALSE;
4471                                 (void) printf("\n");
4472                         }
4473                 }
4474 
4475                 if (ret == 0) {
4476                         if (notfound)
4477                                 (void) printf(gettext("All pools are formatted "
4478                                     "using this version.\n"));
4479                         else if (!cb.cb_all)
4480                                 (void) printf(gettext("Use 'zpool upgrade -v' "
4481                                     "for a list of available versions and "
4482                                     "their associated\nfeatures.\n"));
4483                 }
4484         } else {
4485                 ret = for_each_pool(argc, argv, B_FALSE, NULL,
4486                     upgrade_one, &cb);
4487         }
4488 
4489         return (ret);
4490 }
4491 
4492 typedef struct hist_cbdata {
4493         boolean_t first;
4494         int longfmt;
4495         int internal;
4496 } hist_cbdata_t;
4497 
4498 /*
4499  * Print out the command history for a specific pool.
4500  */
4501 static int
4502 get_history_one(zpool_handle_t *zhp, void *data)
4503 {
4504         nvlist_t *nvhis;
4505         nvlist_t **records;
4506         uint_t numrecords;
4507         char *cmdstr;
4508         char *pathstr;
4509         uint64_t dst_time;
4510         time_t tsec;
4511         struct tm t;
4512         char tbuf[30];
4513         int ret, i;
4514         uint64_t who;
4515         struct passwd *pwd;
4516         char *hostname;
4517         char *zonename;
4518         char internalstr[MAXPATHLEN];
4519         hist_cbdata_t *cb = (hist_cbdata_t *)data;
4520         uint64_t txg;
4521         uint64_t ievent;
4522 
4523         cb->first = B_FALSE;
4524 
4525         (void) printf(gettext("History for '%s':\n"), zpool_get_name(zhp));
4526 
4527         if ((ret = zpool_get_history(zhp, &nvhis)) != 0)
4528                 return (ret);
4529 
4530         verify(nvlist_lookup_nvlist_array(nvhis, ZPOOL_HIST_RECORD,
4531             &records, &numrecords) == 0);
4532         for (i = 0; i < numrecords; i++) {
4533                 if (nvlist_lookup_uint64(records[i], ZPOOL_HIST_TIME,
4534                     &dst_time) != 0)
4535                         continue;
4536 
4537                 /* is it an internal event or a standard event? */
4538                 if (nvlist_lookup_string(records[i], ZPOOL_HIST_CMD,
4539                     &cmdstr) != 0) {
4540                         if (cb->internal == 0)
4541                                 continue;
4542 
4543                         if (nvlist_lookup_uint64(records[i],
4544                             ZPOOL_HIST_INT_EVENT, &ievent) != 0)
4545                                 continue;
4546                         verify(nvlist_lookup_uint64(records[i],
4547                             ZPOOL_HIST_TXG, &txg) == 0);
4548                         verify(nvlist_lookup_string(records[i],
4549                             ZPOOL_HIST_INT_STR, &pathstr) == 0);
4550                         if (ievent >= LOG_END)
4551                                 continue;
4552                         (void) snprintf(internalstr,
4553                             sizeof (internalstr),
4554                             "[internal %s txg:%lld] %s",
4555                             zfs_history_event_names[ievent], txg,
4556                             pathstr);
4557                         cmdstr = internalstr;
4558                 }
4559                 tsec = dst_time;
4560                 (void) localtime_r(&tsec, &t);
4561                 (void) strftime(tbuf, sizeof (tbuf), "%F.%T", &t);
4562                 (void) printf("%s %s", tbuf, cmdstr);
4563 
4564                 if (!cb->longfmt) {
4565                         (void) printf("\n");
4566                         continue;
4567                 }
4568                 (void) printf(" [");
4569                 if (nvlist_lookup_uint64(records[i],
4570                     ZPOOL_HIST_WHO, &who) == 0) {
4571                         pwd = getpwuid((uid_t)who);
4572                         if (pwd)
4573                                 (void) printf("user %s on",
4574                                     pwd->pw_name);
4575                         else
4576                                 (void) printf("user %d on",
4577                                     (int)who);
4578                 } else {
4579                         (void) printf(gettext("no info]\n"));
4580                         continue;
4581                 }
4582                 if (nvlist_lookup_string(records[i],
4583                     ZPOOL_HIST_HOST, &hostname) == 0) {
4584                         (void) printf(" %s", hostname);
4585                 }
4586                 if (nvlist_lookup_string(records[i],
4587                     ZPOOL_HIST_ZONE, &zonename) == 0) {
4588                         (void) printf(":%s", zonename);
4589                 }
4590 
4591                 (void) printf("]");
4592                 (void) printf("\n");
4593         }
4594         (void) printf("\n");
4595         nvlist_free(nvhis);
4596 
4597         return (ret);
4598 }
4599 
4600 /*
4601  * zpool history <pool>
4602  *
4603  * Displays the history of commands that modified pools.
4604  */
4605 
4606 
4607 int
4608 zpool_do_history(int argc, char **argv)
4609 {
4610         hist_cbdata_t cbdata = { 0 };
4611         int ret;
4612         int c;
4613 
4614         cbdata.first = B_TRUE;
4615         /* check options */
4616         while ((c = getopt(argc, argv, "li")) != -1) {
4617                 switch (c) {
4618                 case 'l':
4619                         cbdata.longfmt = 1;
4620                         break;
4621                 case 'i':
4622                         cbdata.internal = 1;
4623                         break;
4624                 case '?':
4625                         (void) fprintf(stderr, gettext("invalid option '%c'\n"),
4626                             optopt);
4627                         usage(B_FALSE);
4628                 }
4629         }
4630         argc -= optind;
4631         argv += optind;
4632 
4633         ret = for_each_pool(argc, argv, B_FALSE,  NULL, get_history_one,
4634             &cbdata);
4635 
4636         if (argc == 0 && cbdata.first == B_TRUE) {
4637                 (void) printf(gettext("no pools available\n"));
4638                 return (0);
4639         }
4640 
4641         return (ret);
4642 }
4643 
4644 static int
4645 get_callback(zpool_handle_t *zhp, void *data)
4646 {
4647         zprop_get_cbdata_t *cbp = (zprop_get_cbdata_t *)data;
4648         char value[MAXNAMELEN];
4649         zprop_source_t srctype;
4650         zprop_list_t *pl;
4651 
4652         for (pl = cbp->cb_proplist; pl != NULL; pl = pl->pl_next) {
4653 
4654                 /*
4655                  * Skip the special fake placeholder. This will also skip
4656                  * over the name property when 'all' is specified.
4657                  */
4658                 if (pl->pl_prop == ZPOOL_PROP_NAME &&
4659                     pl == cbp->cb_proplist)
4660                         continue;
4661 
4662                 if (pl->pl_prop == ZPROP_INVAL &&
4663                     (zpool_prop_feature(pl->pl_user_prop) ||
4664                     zpool_prop_unsupported(pl->pl_user_prop))) {
4665                         srctype = ZPROP_SRC_LOCAL;
4666 
4667                         if (zpool_prop_get_feature(zhp, pl->pl_user_prop,
4668                             value, sizeof (value)) == 0) {
4669                                 zprop_print_one_property(zpool_get_name(zhp),
4670                                     cbp, pl->pl_user_prop, value, srctype,
4671                                     NULL, NULL);
4672                         }
4673                 } else {
4674                         if (zpool_get_prop(zhp, pl->pl_prop, value,
4675                             sizeof (value), &srctype) != 0)
4676                                 continue;
4677 
4678                         zprop_print_one_property(zpool_get_name(zhp), cbp,
4679                             zpool_prop_to_name(pl->pl_prop), value, srctype,
4680                             NULL, NULL);
4681                 }
4682         }
4683         return (0);
4684 }
4685 
4686 int
4687 zpool_do_get(int argc, char **argv)
4688 {
4689         zprop_get_cbdata_t cb = { 0 };
4690         zprop_list_t fake_name = { 0 };
4691         int ret;
4692 
4693         if (argc < 2) {
4694                 (void) fprintf(stderr, gettext("missing property "
4695                     "argument\n"));
4696                 usage(B_FALSE);
4697         }
4698 
4699         cb.cb_first = B_TRUE;
4700         cb.cb_sources = ZPROP_SRC_ALL;
4701         cb.cb_columns[0] = GET_COL_NAME;
4702         cb.cb_columns[1] = GET_COL_PROPERTY;
4703         cb.cb_columns[2] = GET_COL_VALUE;
4704         cb.cb_columns[3] = GET_COL_SOURCE;
4705         cb.cb_type = ZFS_TYPE_POOL;
4706 
4707         if (zprop_get_list(g_zfs, argv[1], &cb.cb_proplist,
4708             ZFS_TYPE_POOL) != 0)
4709                 usage(B_FALSE);
4710 
4711         if (cb.cb_proplist != NULL) {
4712                 fake_name.pl_prop = ZPOOL_PROP_NAME;
4713                 fake_name.pl_width = strlen(gettext("NAME"));
4714                 fake_name.pl_next = cb.cb_proplist;
4715                 cb.cb_proplist = &fake_name;
4716         }
4717 
4718         ret = for_each_pool(argc - 2, argv + 2, B_TRUE, &cb.cb_proplist,
4719             get_callback, &cb);
4720 
4721         if (cb.cb_proplist == &fake_name)
4722                 zprop_free_list(fake_name.pl_next);
4723         else
4724                 zprop_free_list(cb.cb_proplist);
4725 
4726         return (ret);
4727 }
4728 
4729 typedef struct set_cbdata {
4730         char *cb_propname;
4731         char *cb_value;
4732         boolean_t cb_any_successful;
4733 } set_cbdata_t;
4734 
4735 int
4736 set_callback(zpool_handle_t *zhp, void *data)
4737 {
4738         int error;
4739         set_cbdata_t *cb = (set_cbdata_t *)data;
4740 
4741         error = zpool_set_prop(zhp, cb->cb_propname, cb->cb_value);
4742 
4743         if (!error)
4744                 cb->cb_any_successful = B_TRUE;
4745 
4746         return (error);
4747 }
4748 
4749 int
4750 zpool_do_set(int argc, char **argv)
4751 {
4752         set_cbdata_t cb = { 0 };
4753         int error;
4754 
4755         if (argc > 1 && argv[1][0] == '-') {
4756                 (void) fprintf(stderr, gettext("invalid option '%c'\n"),
4757                     argv[1][1]);
4758                 usage(B_FALSE);
4759         }
4760 
4761         if (argc < 2) {
4762                 (void) fprintf(stderr, gettext("missing property=value "
4763                     "argument\n"));
4764                 usage(B_FALSE);
4765         }
4766 
4767         if (argc < 3) {
4768                 (void) fprintf(stderr, gettext("missing pool name\n"));
4769                 usage(B_FALSE);
4770         }
4771 
4772         if (argc > 3) {
4773                 (void) fprintf(stderr, gettext("too many pool names\n"));
4774                 usage(B_FALSE);
4775         }
4776 
4777         cb.cb_propname = argv[1];
4778         cb.cb_value = strchr(cb.cb_propname, '=');
4779         if (cb.cb_value == NULL) {
4780                 (void) fprintf(stderr, gettext("missing value in "
4781                     "property=value argument\n"));
4782                 usage(B_FALSE);
4783         }
4784 
4785         *(cb.cb_value) = '\0';
4786         cb.cb_value++;
4787 
4788         error = for_each_pool(argc - 2, argv + 2, B_TRUE, NULL,
4789             set_callback, &cb);
4790 
4791         return (error);
4792 }
4793 
4794 static int
4795 find_command_idx(char *command, int *idx)
4796 {
4797         int i;
4798 
4799         for (i = 0; i < NCOMMAND; i++) {
4800                 if (command_table[i].name == NULL)
4801                         continue;
4802 
4803                 if (strcmp(command, command_table[i].name) == 0) {
4804                         *idx = i;
4805                         return (0);
4806                 }
4807         }
4808         return (1);
4809 }
4810 
4811 int
4812 main(int argc, char **argv)
4813 {
4814         int ret;
4815         int i;
4816         char *cmdname;
4817 
4818         (void) setlocale(LC_ALL, "");
4819         (void) textdomain(TEXT_DOMAIN);
4820 
4821         if ((g_zfs = libzfs_init()) == NULL) {
4822                 (void) fprintf(stderr, gettext("internal error: failed to "
4823                     "initialize ZFS library\n"));
4824                 return (1);
4825         }
4826 
4827         libzfs_print_on_error(g_zfs, B_TRUE);
4828 
4829         opterr = 0;
4830 
4831         /*
4832          * Make sure the user has specified some command.
4833          */
4834         if (argc < 2) {
4835                 (void) fprintf(stderr, gettext("missing command\n"));
4836                 usage(B_FALSE);
4837         }
4838 
4839         cmdname = argv[1];
4840 
4841         /*
4842          * Special case '-?'
4843          */
4844         if (strcmp(cmdname, "-?") == 0)
4845                 usage(B_TRUE);
4846 
4847         zpool_set_history_str("zpool", argc, argv, history_str);
4848         verify(zpool_stage_history(g_zfs, history_str) == 0);
4849 
4850         /*
4851          * Run the appropriate command.
4852          */
4853         if (find_command_idx(cmdname, &i) == 0) {
4854                 current_command = &command_table[i];
4855                 ret = command_table[i].func(argc - 1, argv + 1);
4856         } else if (strchr(cmdname, '=')) {
4857                 verify(find_command_idx("set", &i) == 0);
4858                 current_command = &command_table[i];
4859                 ret = command_table[i].func(argc, argv);
4860         } else if (strcmp(cmdname, "freeze") == 0 && argc == 3) {
4861                 /*
4862                  * 'freeze' is a vile debugging abomination, so we treat
4863                  * it as such.
4864                  */
4865                 char buf[16384];
4866                 int fd = open(ZFS_DEV, O_RDWR);
4867                 (void) strcpy((void *)buf, argv[2]);
4868                 return (!!ioctl(fd, ZFS_IOC_POOL_FREEZE, buf));
4869         } else {
4870                 (void) fprintf(stderr, gettext("unrecognized "
4871                     "command '%s'\n"), cmdname);
4872                 usage(B_FALSE);
4873         }
4874 
4875         libzfs_fini(g_zfs);
4876 
4877         /*
4878          * The 'ZFS_ABORT' environment variable causes us to dump core on exit
4879          * for the purposes of running ::findleaks.
4880          */
4881         if (getenv("ZFS_ABORT") != NULL) {
4882                 (void) printf("dumping core by request\n");
4883                 abort();
4884         }
4885 
4886         return (ret);
4887 }