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