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