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