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