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