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 (c) 2011, 2018 by Delphix. All rights reserved.
  25  * Copyright (c) 2012 by Frederik Wessels. All rights reserved.
  26  * Copyright (c) 2013 by Prasad Joshi (sTec). All rights reserved.
  27  * Copyright 2016 Igor Kozhukhov <ikozhukhov@gmail.com>.
  28  * Copyright 2016 Nexenta Systems, Inc.
  29  * Copyright (c) 2017 Datto Inc.
  30  * Copyright (c) 2017, Intel Corporation.
  31  * Copyright (c) 2019, loli10K <ezomori.nozomu@gmail.com>
  32  * Copyright 2020 Joyent, Inc.
  33  * Copyright (c) 2012 by Cyril Plisko. All rights reserved.
  34  * Copyright 2019 OmniOS Community Edition (OmniOSce) Association.
  35  */
  36 
  37 #include <assert.h>
  38 #include <ctype.h>
  39 #include <dirent.h>
  40 #include <errno.h>
  41 #include <fcntl.h>
  42 #include <getopt.h>
  43 #include <libgen.h>
  44 #include <libintl.h>
  45 #include <libuutil.h>
  46 #include <locale.h>
  47 #include <stdio.h>
  48 #include <stdlib.h>
  49 #include <string.h>
  50 #include <strings.h>
  51 #include <unistd.h>
  52 #include <priv.h>
  53 #include <pwd.h>
  54 #include <zone.h>
  55 #include <zfs_prop.h>
  56 #include <sys/fs/zfs.h>
  57 #include <sys/stat.h>
  58 #include <sys/debug.h>
  59 #include <math.h>
  60 #include <sys/sysmacros.h>
  61 #include <sys/termios.h>
  62 
  63 #include <libzfs.h>
  64 #include <libzutil.h>
  65 
  66 #include "zpool_util.h"
  67 #include "zfs_comutil.h"
  68 #include "zfeature_common.h"
  69 
  70 #include "statcommon.h"
  71 
  72 static int zpool_do_create(int, char **);
  73 static int zpool_do_destroy(int, char **);
  74 
  75 static int zpool_do_add(int, char **);
  76 static int zpool_do_remove(int, char **);
  77 static int zpool_do_labelclear(int, char **);
  78 
  79 static int zpool_do_checkpoint(int, char **);
  80 
  81 static int zpool_do_list(int, char **);
  82 static int zpool_do_iostat(int, char **);
  83 static int zpool_do_status(int, char **);
  84 
  85 static int zpool_do_online(int, char **);
  86 static int zpool_do_offline(int, char **);
  87 static int zpool_do_clear(int, char **);
  88 static int zpool_do_reopen(int, char **);
  89 
  90 static int zpool_do_reguid(int, char **);
  91 
  92 static int zpool_do_attach(int, char **);
  93 static int zpool_do_detach(int, char **);
  94 static int zpool_do_replace(int, char **);
  95 static int zpool_do_split(int, char **);
  96 
  97 static int zpool_do_initialize(int, char **);
  98 static int zpool_do_scrub(int, char **);
  99 static int zpool_do_resilver(int, char **);
 100 static int zpool_do_trim(int, char **);
 101 
 102 static int zpool_do_import(int, char **);
 103 static int zpool_do_export(int, char **);
 104 
 105 static int zpool_do_upgrade(int, char **);
 106 
 107 static int zpool_do_history(int, char **);
 108 
 109 static int zpool_do_get(int, char **);
 110 static int zpool_do_set(int, char **);
 111 
 112 static int zpool_do_sync(int, char **);
 113 
 114 /*
 115  * These libumem hooks provide a reasonable set of defaults for the allocator's
 116  * debugging facilities.
 117  */
 118 
 119 #ifdef DEBUG
 120 const char *
 121 _umem_debug_init(void)
 122 {
 123         return ("default,verbose"); /* $UMEM_DEBUG setting */
 124 }
 125 
 126 const char *
 127 _umem_logging_init(void)
 128 {
 129         return ("fail,contents"); /* $UMEM_LOGGING setting */
 130 }
 131 #endif
 132 
 133 typedef enum {
 134         HELP_ADD,
 135         HELP_ATTACH,
 136         HELP_CLEAR,
 137         HELP_CREATE,
 138         HELP_CHECKPOINT,
 139         HELP_DESTROY,
 140         HELP_DETACH,
 141         HELP_EXPORT,
 142         HELP_HISTORY,
 143         HELP_IMPORT,
 144         HELP_IOSTAT,
 145         HELP_LABELCLEAR,
 146         HELP_LIST,
 147         HELP_OFFLINE,
 148         HELP_ONLINE,
 149         HELP_REPLACE,
 150         HELP_REMOVE,
 151         HELP_INITIALIZE,
 152         HELP_SCRUB,
 153         HELP_RESILVER,
 154         HELP_TRIM,
 155         HELP_STATUS,
 156         HELP_UPGRADE,
 157         HELP_GET,
 158         HELP_SET,
 159         HELP_SPLIT,
 160         HELP_SYNC,
 161         HELP_REGUID,
 162         HELP_REOPEN
 163 } zpool_help_t;
 164 
 165 
 166 /*
 167  * Flags for stats to display with "zpool iostats"
 168  */
 169 enum iostat_type {
 170         IOS_DEFAULT = 0,
 171         IOS_LATENCY = 1,
 172         IOS_QUEUES = 2,
 173         IOS_L_HISTO = 3,
 174         IOS_RQ_HISTO = 4,
 175         IOS_COUNT,      /* always last element */
 176 };
 177 
 178 /* iostat_type entries as bitmasks */
 179 #define IOS_DEFAULT_M   (1ULL << IOS_DEFAULT)
 180 #define IOS_LATENCY_M   (1ULL << IOS_LATENCY)
 181 #define IOS_QUEUES_M    (1ULL << IOS_QUEUES)
 182 #define IOS_L_HISTO_M   (1ULL << IOS_L_HISTO)
 183 #define IOS_RQ_HISTO_M  (1ULL << IOS_RQ_HISTO)
 184 
 185 /* Mask of all the histo bits */
 186 #define IOS_ANYHISTO_M (IOS_L_HISTO_M | IOS_RQ_HISTO_M)
 187 
 188 /*
 189  * Lookup table for iostat flags to nvlist names.  Basically a list
 190  * of all the nvlists a flag requires.  Also specifies the order in
 191  * which data gets printed in zpool iostat.
 192  */
 193 static const char *vsx_type_to_nvlist[IOS_COUNT][13] = {
 194         [IOS_L_HISTO] = {
 195             ZPOOL_CONFIG_VDEV_TOT_R_LAT_HISTO,
 196             ZPOOL_CONFIG_VDEV_TOT_W_LAT_HISTO,
 197             ZPOOL_CONFIG_VDEV_DISK_R_LAT_HISTO,
 198             ZPOOL_CONFIG_VDEV_DISK_W_LAT_HISTO,
 199             ZPOOL_CONFIG_VDEV_SYNC_R_LAT_HISTO,
 200             ZPOOL_CONFIG_VDEV_SYNC_W_LAT_HISTO,
 201             ZPOOL_CONFIG_VDEV_ASYNC_R_LAT_HISTO,
 202             ZPOOL_CONFIG_VDEV_ASYNC_W_LAT_HISTO,
 203             ZPOOL_CONFIG_VDEV_SCRUB_LAT_HISTO,
 204             ZPOOL_CONFIG_VDEV_TRIM_LAT_HISTO,
 205             NULL},
 206         [IOS_LATENCY] = {
 207             ZPOOL_CONFIG_VDEV_TOT_R_LAT_HISTO,
 208             ZPOOL_CONFIG_VDEV_TOT_W_LAT_HISTO,
 209             ZPOOL_CONFIG_VDEV_DISK_R_LAT_HISTO,
 210             ZPOOL_CONFIG_VDEV_DISK_W_LAT_HISTO,
 211             ZPOOL_CONFIG_VDEV_TRIM_LAT_HISTO,
 212             NULL},
 213         [IOS_QUEUES] = {
 214             ZPOOL_CONFIG_VDEV_SYNC_R_ACTIVE_QUEUE,
 215             ZPOOL_CONFIG_VDEV_SYNC_W_ACTIVE_QUEUE,
 216             ZPOOL_CONFIG_VDEV_ASYNC_R_ACTIVE_QUEUE,
 217             ZPOOL_CONFIG_VDEV_ASYNC_W_ACTIVE_QUEUE,
 218             ZPOOL_CONFIG_VDEV_SCRUB_ACTIVE_QUEUE,
 219             ZPOOL_CONFIG_VDEV_TRIM_ACTIVE_QUEUE,
 220             NULL},
 221         [IOS_RQ_HISTO] = {
 222             ZPOOL_CONFIG_VDEV_SYNC_IND_R_HISTO,
 223             ZPOOL_CONFIG_VDEV_SYNC_AGG_R_HISTO,
 224             ZPOOL_CONFIG_VDEV_SYNC_IND_W_HISTO,
 225             ZPOOL_CONFIG_VDEV_SYNC_AGG_W_HISTO,
 226             ZPOOL_CONFIG_VDEV_ASYNC_IND_R_HISTO,
 227             ZPOOL_CONFIG_VDEV_ASYNC_AGG_R_HISTO,
 228             ZPOOL_CONFIG_VDEV_ASYNC_IND_W_HISTO,
 229             ZPOOL_CONFIG_VDEV_ASYNC_AGG_W_HISTO,
 230             ZPOOL_CONFIG_VDEV_IND_SCRUB_HISTO,
 231             ZPOOL_CONFIG_VDEV_AGG_SCRUB_HISTO,
 232             ZPOOL_CONFIG_VDEV_IND_TRIM_HISTO,
 233             ZPOOL_CONFIG_VDEV_AGG_TRIM_HISTO,
 234             NULL},
 235 };
 236 
 237 
 238 /*
 239  * Given a cb->cb_flags with a histogram bit set, return the iostat_type.
 240  * Right now, only one histo bit is ever set at one time, so we can
 241  * just do a highbit64(a)
 242  */
 243 #define IOS_HISTO_IDX(a)        (highbit64(a & IOS_ANYHISTO_M) - 1)
 244 
 245 typedef struct zpool_command {
 246         const char      *name;
 247         int             (*func)(int, char **);
 248         zpool_help_t    usage;
 249 } zpool_command_t;
 250 
 251 /*
 252  * Master command table.  Each ZFS command has a name, associated function, and
 253  * usage message.  The usage messages need to be internationalized, so we have
 254  * to have a function to return the usage message based on a command index.
 255  *
 256  * These commands are organized according to how they are displayed in the usage
 257  * message.  An empty command (one with a NULL name) indicates an empty line in
 258  * the generic usage message.
 259  */
 260 static zpool_command_t command_table[] = {
 261         { "create",     zpool_do_create,        HELP_CREATE             },
 262         { "destroy",    zpool_do_destroy,       HELP_DESTROY            },
 263         { NULL },
 264         { "add",        zpool_do_add,           HELP_ADD                },
 265         { "remove",     zpool_do_remove,        HELP_REMOVE             },
 266         { NULL },
 267         { "labelclear", zpool_do_labelclear,    HELP_LABELCLEAR         },
 268         { NULL },
 269         { "checkpoint", zpool_do_checkpoint,    HELP_CHECKPOINT         },
 270         { NULL },
 271         { "list",       zpool_do_list,          HELP_LIST               },
 272         { "iostat",     zpool_do_iostat,        HELP_IOSTAT             },
 273         { "status",     zpool_do_status,        HELP_STATUS             },
 274         { NULL },
 275         { "online",     zpool_do_online,        HELP_ONLINE             },
 276         { "offline",    zpool_do_offline,       HELP_OFFLINE            },
 277         { "clear",      zpool_do_clear,         HELP_CLEAR              },
 278         { "reopen",     zpool_do_reopen,        HELP_REOPEN             },
 279         { NULL },
 280         { "attach",     zpool_do_attach,        HELP_ATTACH             },
 281         { "detach",     zpool_do_detach,        HELP_DETACH             },
 282         { "replace",    zpool_do_replace,       HELP_REPLACE            },
 283         { "split",      zpool_do_split,         HELP_SPLIT              },
 284         { NULL },
 285         { "initialize", zpool_do_initialize,    HELP_INITIALIZE         },
 286         { "resilver",   zpool_do_resilver,      HELP_RESILVER           },
 287         { "scrub",      zpool_do_scrub,         HELP_SCRUB              },
 288         { "trim",       zpool_do_trim,          HELP_TRIM               },
 289         { NULL },
 290         { "import",     zpool_do_import,        HELP_IMPORT             },
 291         { "export",     zpool_do_export,        HELP_EXPORT             },
 292         { "upgrade",    zpool_do_upgrade,       HELP_UPGRADE            },
 293         { "reguid",     zpool_do_reguid,        HELP_REGUID             },
 294         { NULL },
 295         { "history",    zpool_do_history,       HELP_HISTORY            },
 296         { "get",        zpool_do_get,           HELP_GET                },
 297         { "set",        zpool_do_set,           HELP_SET                },
 298         { "sync",       zpool_do_sync,          HELP_SYNC               },
 299 };
 300 
 301 #define NCOMMAND        (ARRAY_SIZE(command_table))
 302 
 303 #define VDEV_ALLOC_CLASS_LOGS   "logs"
 304 
 305 static zpool_command_t *current_command;
 306 static char history_str[HIS_MAX_RECORD_LEN];
 307 static boolean_t log_history = B_TRUE;
 308 static uint_t timestamp_fmt = NODATE;
 309 
 310 static const char *
 311 get_usage(zpool_help_t idx)
 312 {
 313         switch (idx) {
 314         case HELP_ADD:
 315                 return (gettext("\tadd [-fgLnP] [-o property=value] "
 316                     "<pool> <vdev> ...\n"));
 317         case HELP_ATTACH:
 318                 return (gettext("\tattach [-f] [-o property=value] "
 319                     "<pool> <device> <new-device>\n"));
 320         case HELP_CLEAR:
 321                 return (gettext("\tclear [-nF] <pool> [device]\n"));
 322         case HELP_CREATE:
 323                 return (gettext("\tcreate [-fnd] [-B] "
 324                     "[-o property=value] ... \n"
 325                     "\t    [-O file-system-property=value] ...\n"
 326                     "\t    [-m mountpoint] [-R root] [-t tempname] "
 327                     "<pool> <vdev> ...\n"));
 328         case HELP_CHECKPOINT:
 329                 return (gettext("\tcheckpoint [--discard] <pool> ...\n"));
 330         case HELP_DESTROY:
 331                 return (gettext("\tdestroy [-f] <pool>\n"));
 332         case HELP_DETACH:
 333                 return (gettext("\tdetach <pool> <device>\n"));
 334         case HELP_EXPORT:
 335                 return (gettext("\texport [-f] <pool> ...\n"));
 336         case HELP_HISTORY:
 337                 return (gettext("\thistory [-il] [<pool>] ...\n"));
 338         case HELP_IMPORT:
 339                 return (gettext("\timport [-d dir] [-D]\n"
 340                     "\timport [-d dir | -c cachefile] [-F [-n]] [-l] "
 341                     "<pool | id>\n"
 342                     "\timport [-o mntopts] [-o property=value] ... \n"
 343                     "\t    [-d dir | -c cachefile] [-D] [-l] [-f] [-m] [-N] "
 344                     "[-R root] [-F [-n]] -a\n"
 345                     "\timport [-o mntopts] [-o property=value] ... \n"
 346                     "\t    [-d dir | -c cachefile] [-D] [-l] [-f] [-m] [-N] "
 347                     "[-R root] [-F [-n]] [-t]\n"
 348                     "\t    [--rewind-to-checkpoint] <pool | id> [newpool]\n"));
 349         case HELP_IOSTAT:
 350                 return (gettext("\tiostat "
 351                     "[[-lq]|[-rw]] [-T d | u] [-ghHLpPvy]\n"
 352                     "\t    [[pool] ...]|[pool vdev ...]|[vdev ...]]"
 353                     " [[-n] interval [count]]\n"));
 354         case HELP_LABELCLEAR:
 355                 return (gettext("\tlabelclear [-f] <vdev>\n"));
 356         case HELP_LIST:
 357                 return (gettext("\tlist [-gHLpPv] [-o property[,...]] "
 358                     "[-T d|u] [pool] ... [interval [count]]\n"));
 359         case HELP_OFFLINE:
 360                 return (gettext("\toffline [-t] <pool> <device> ...\n"));
 361         case HELP_ONLINE:
 362                 return (gettext("\tonline <pool> <device> ...\n"));
 363         case HELP_REPLACE:
 364                 return (gettext("\treplace [-f] <pool> <device> "
 365                     "[new-device]\n"));
 366         case HELP_REMOVE:
 367                 return (gettext("\tremove [-nps] <pool> <device> ...\n"));
 368         case HELP_REOPEN:
 369                 return (gettext("\treopen <pool>\n"));
 370         case HELP_INITIALIZE:
 371                 return (gettext("\tinitialize [-c | -s] <pool> "
 372                     "[<device> ...]\n"));
 373         case HELP_SCRUB:
 374                 return (gettext("\tscrub [-s | -p] <pool> ...\n"));
 375         case HELP_RESILVER:
 376                 return (gettext("\tresilver <pool> ...\n"));
 377         case HELP_TRIM:
 378                 return (gettext("\ttrim [-d] [-r <rate>] [-c | -s] <pool> "
 379                     "[<device> ...]\n"));
 380         case HELP_STATUS:
 381                 return (gettext("\tstatus "
 382                     "[-igLpPsvxD] [-T d|u] [pool] ... "
 383                     "[interval [count]]\n"));
 384         case HELP_UPGRADE:
 385                 return (gettext("\tupgrade\n"
 386                     "\tupgrade -v\n"
 387                     "\tupgrade [-V version] <-a | pool ...>\n"));
 388         case HELP_GET:
 389                 return (gettext("\tget [-Hp] [-o \"all\" | field[,...]] "
 390                     "<\"all\" | property[,...]> <pool> ...\n"));
 391         case HELP_SET:
 392                 return (gettext("\tset <property=value> <pool> \n"));
 393         case HELP_SPLIT:
 394                 return (gettext("\tsplit [-gLlnP] [-R altroot] [-o mntopts]\n"
 395                     "\t    [-o property=value] <pool> <newpool> "
 396                     "[<device> ...]\n"));
 397         case HELP_REGUID:
 398                 return (gettext("\treguid <pool>\n"));
 399         case HELP_SYNC:
 400                 return (gettext("\tsync [pool] ...\n"));
 401         }
 402 
 403         abort();
 404         /* NOTREACHED */
 405 }
 406 
 407 static void
 408 zpool_collect_leaves(zpool_handle_t *zhp, nvlist_t *nvroot, nvlist_t *res)
 409 {
 410         uint_t children = 0;
 411         nvlist_t **child;
 412         uint_t i;
 413 
 414         (void) nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_CHILDREN,
 415             &child, &children);
 416 
 417         if (children == 0) {
 418                 char *path = zpool_vdev_name(g_zfs, zhp, nvroot, 0);
 419 
 420                 if (strcmp(path, VDEV_TYPE_INDIRECT) != 0 &&
 421                     strcmp(path, VDEV_TYPE_HOLE) != 0)
 422                         fnvlist_add_boolean(res, path);
 423 
 424                 free(path);
 425                 return;
 426         }
 427 
 428         for (i = 0; i < children; i++) {
 429                 zpool_collect_leaves(zhp, child[i], res);
 430         }
 431 }
 432 
 433 /*
 434  * Callback routine that will print out a pool property value.
 435  */
 436 static int
 437 print_prop_cb(int prop, void *cb)
 438 {
 439         FILE *fp = cb;
 440 
 441         (void) fprintf(fp, "\t%-19s  ", zpool_prop_to_name(prop));
 442 
 443         if (zpool_prop_readonly(prop))
 444                 (void) fprintf(fp, "  NO   ");
 445         else
 446                 (void) fprintf(fp, " YES   ");
 447 
 448         if (zpool_prop_values(prop) == NULL)
 449                 (void) fprintf(fp, "-\n");
 450         else
 451                 (void) fprintf(fp, "%s\n", zpool_prop_values(prop));
 452 
 453         return (ZPROP_CONT);
 454 }
 455 
 456 /*
 457  * Display usage message.  If we're inside a command, display only the usage for
 458  * that command.  Otherwise, iterate over the entire command table and display
 459  * a complete usage message.
 460  */
 461 void
 462 usage(boolean_t requested)
 463 {
 464         FILE *fp = requested ? stdout : stderr;
 465 
 466         if (current_command == NULL) {
 467                 int i;
 468 
 469                 (void) fprintf(fp, gettext("usage: zpool command args ...\n"));
 470                 (void) fprintf(fp,
 471                     gettext("where 'command' is one of the following:\n\n"));
 472 
 473                 for (i = 0; i < NCOMMAND; i++) {
 474                         if (command_table[i].name == NULL)
 475                                 (void) fprintf(fp, "\n");
 476                         else
 477                                 (void) fprintf(fp, "%s",
 478                                     get_usage(command_table[i].usage));
 479                 }
 480         } else {
 481                 (void) fprintf(fp, gettext("usage:\n"));
 482                 (void) fprintf(fp, "%s", get_usage(current_command->usage));
 483         }
 484 
 485         if (current_command != NULL &&
 486             ((strcmp(current_command->name, "set") == 0) ||
 487             (strcmp(current_command->name, "get") == 0) ||
 488             (strcmp(current_command->name, "list") == 0))) {
 489 
 490                 (void) fprintf(fp,
 491                     gettext("\nthe following properties are supported:\n"));
 492 
 493                 (void) fprintf(fp, "\n\t%-19s  %s   %s\n\n",
 494                     "PROPERTY", "EDIT", "VALUES");
 495 
 496                 /* Iterate over all properties */
 497                 (void) zprop_iter(print_prop_cb, fp, B_FALSE, B_TRUE,
 498                     ZFS_TYPE_POOL);
 499 
 500                 (void) fprintf(fp, "\t%-19s   ", "feature@...");
 501                 (void) fprintf(fp, "YES   disabled | enabled | active\n");
 502 
 503                 (void) fprintf(fp, gettext("\nThe feature@ properties must be "
 504                     "appended with a feature name.\nSee zpool-features(5).\n"));
 505         }
 506 
 507         /*
 508          * See comments at end of main().
 509          */
 510         if (getenv("ZFS_ABORT") != NULL) {
 511                 (void) printf("dumping core by request\n");
 512                 abort();
 513         }
 514 
 515         exit(requested ? 0 : 2);
 516 }
 517 
 518 /*
 519  * print a pool vdev config for dry runs
 520  */
 521 static void
 522 print_vdev_tree(zpool_handle_t *zhp, const char *name, nvlist_t *nv, int indent,
 523     const char *match, int name_flags)
 524 {
 525         nvlist_t **child;
 526         uint_t c, children;
 527         char *vname;
 528         boolean_t printed = B_FALSE;
 529 
 530         if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
 531             &child, &children) != 0) {
 532                 if (name != NULL)
 533                         (void) printf("\t%*s%s\n", indent, "", name);
 534                 return;
 535         }
 536 
 537         for (c = 0; c < children; c++) {
 538                 uint64_t is_log = B_FALSE;
 539                 char *class = "";
 540 
 541                 (void) nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_LOG,
 542                     &is_log);
 543                 if (is_log)
 544                         class = VDEV_ALLOC_BIAS_LOG;
 545                 (void) nvlist_lookup_string(child[c],
 546                     ZPOOL_CONFIG_ALLOCATION_BIAS, &class);
 547                 if (strcmp(match, class) != 0)
 548                         continue;
 549 
 550                 if (!printed && name != NULL) {
 551                         (void) printf("\t%*s%s\n", indent, "", name);
 552                         printed = B_TRUE;
 553                 }
 554                 vname = zpool_vdev_name(g_zfs, zhp, child[c], name_flags);
 555                 print_vdev_tree(zhp, vname, child[c], indent + 2, "",
 556                     name_flags);
 557                 free(vname);
 558         }
 559 }
 560 
 561 static boolean_t
 562 prop_list_contains_feature(nvlist_t *proplist)
 563 {
 564         nvpair_t *nvp;
 565         for (nvp = nvlist_next_nvpair(proplist, NULL); NULL != nvp;
 566             nvp = nvlist_next_nvpair(proplist, nvp)) {
 567                 if (zpool_prop_feature(nvpair_name(nvp)))
 568                         return (B_TRUE);
 569         }
 570         return (B_FALSE);
 571 }
 572 
 573 /*
 574  * Add a property pair (name, string-value) into a property nvlist.
 575  */
 576 static int
 577 add_prop_list(const char *propname, char *propval, nvlist_t **props,
 578     boolean_t poolprop)
 579 {
 580         zpool_prop_t prop = ZPOOL_PROP_INVAL;
 581         zfs_prop_t fprop;
 582         nvlist_t *proplist;
 583         const char *normnm;
 584         char *strval;
 585 
 586         if (*props == NULL &&
 587             nvlist_alloc(props, NV_UNIQUE_NAME, 0) != 0) {
 588                 (void) fprintf(stderr,
 589                     gettext("internal error: out of memory\n"));
 590                 return (1);
 591         }
 592 
 593         proplist = *props;
 594 
 595         if (poolprop) {
 596                 const char *vname = zpool_prop_to_name(ZPOOL_PROP_VERSION);
 597 
 598                 if ((prop = zpool_name_to_prop(propname)) == ZPOOL_PROP_INVAL &&
 599                     !zpool_prop_feature(propname)) {
 600                         (void) fprintf(stderr, gettext("property '%s' is "
 601                             "not a valid pool property\n"), propname);
 602                         return (2);
 603                 }
 604 
 605                 /*
 606                  * feature@ properties and version should not be specified
 607                  * at the same time.
 608                  */
 609                 if ((prop == ZPOOL_PROP_INVAL && zpool_prop_feature(propname) &&
 610                     nvlist_exists(proplist, vname)) ||
 611                     (prop == ZPOOL_PROP_VERSION &&
 612                     prop_list_contains_feature(proplist))) {
 613                         (void) fprintf(stderr, gettext("'feature@' and "
 614                             "'version' properties cannot be specified "
 615                             "together\n"));
 616                         return (2);
 617                 }
 618 
 619 
 620                 if (zpool_prop_feature(propname))
 621                         normnm = propname;
 622                 else
 623                         normnm = zpool_prop_to_name(prop);
 624         } else {
 625                 if ((fprop = zfs_name_to_prop(propname)) != ZPROP_INVAL) {
 626                         normnm = zfs_prop_to_name(fprop);
 627                 } else {
 628                         normnm = propname;
 629                 }
 630         }
 631 
 632         if (nvlist_lookup_string(proplist, normnm, &strval) == 0 &&
 633             prop != ZPOOL_PROP_CACHEFILE) {
 634                 (void) fprintf(stderr, gettext("property '%s' "
 635                     "specified multiple times\n"), propname);
 636                 return (2);
 637         }
 638 
 639         if (nvlist_add_string(proplist, normnm, propval) != 0) {
 640                 (void) fprintf(stderr, gettext("internal "
 641                     "error: out of memory\n"));
 642                 return (1);
 643         }
 644 
 645         return (0);
 646 }
 647 
 648 /*
 649  * Set a default property pair (name, string-value) in a property nvlist
 650  */
 651 static int
 652 add_prop_list_default(const char *propname, char *propval, nvlist_t **props,
 653     boolean_t poolprop)
 654 {
 655         char *pval;
 656 
 657         if (nvlist_lookup_string(*props, propname, &pval) == 0)
 658                 return (0);
 659 
 660         return (add_prop_list(propname, propval, props, poolprop));
 661 }
 662 
 663 /*
 664  * zpool add [-fgLnP] [-o property=value] <pool> <vdev> ...
 665  *
 666  *      -f      Force addition of devices, even if they appear in use
 667  *      -g      Display guid for individual vdev name.
 668  *      -L      Follow links when resolving vdev path name.
 669  *      -n      Do not add the devices, but display the resulting layout if
 670  *              they were to be added.
 671  *      -P      Display full path for vdev name.
 672  *      -o      Set property=value.
 673  *
 674  * Adds the given vdevs to 'pool'.  As with create, the bulk of this work is
 675  * handled by get_vdev_spec(), which constructs the nvlist needed to pass to
 676  * libzfs.
 677  */
 678 int
 679 zpool_do_add(int argc, char **argv)
 680 {
 681         boolean_t force = B_FALSE;
 682         boolean_t dryrun = B_FALSE;
 683         int name_flags = 0;
 684         int c;
 685         nvlist_t *nvroot;
 686         char *poolname;
 687         zpool_boot_label_t boot_type;
 688         uint64_t boot_size;
 689         int ret;
 690         zpool_handle_t *zhp;
 691         nvlist_t *config;
 692         nvlist_t *props = NULL;
 693         char *propval;
 694 
 695         /* check options */
 696         while ((c = getopt(argc, argv, "fgLnPo:")) != -1) {
 697                 switch (c) {
 698                 case 'f':
 699                         force = B_TRUE;
 700                         break;
 701                 case 'g':
 702                         name_flags |= VDEV_NAME_GUID;
 703                         break;
 704                 case 'L':
 705                         name_flags |= VDEV_NAME_FOLLOW_LINKS;
 706                         break;
 707                 case 'n':
 708                         dryrun = B_TRUE;
 709                         break;
 710                 case 'P':
 711                         name_flags |= VDEV_NAME_PATH;
 712                         break;
 713                 case 'o':
 714                         if ((propval = strchr(optarg, '=')) == NULL) {
 715                                 (void) fprintf(stderr, gettext("missing "
 716                                     "'=' for -o option\n"));
 717                                 usage(B_FALSE);
 718                         }
 719                         *propval = '\0';
 720                         propval++;
 721 
 722                         if ((strcmp(optarg, ZPOOL_CONFIG_ASHIFT) != 0) ||
 723                             (add_prop_list(optarg, propval, &props, B_TRUE)))
 724                                 usage(B_FALSE);
 725                         break;
 726                 case '?':
 727                         (void) fprintf(stderr, gettext("invalid option '%c'\n"),
 728                             optopt);
 729                         usage(B_FALSE);
 730                 }
 731         }
 732 
 733         argc -= optind;
 734         argv += optind;
 735 
 736         /* get pool name and check number of arguments */
 737         if (argc < 1) {
 738                 (void) fprintf(stderr, gettext("missing pool name argument\n"));
 739                 usage(B_FALSE);
 740         }
 741         if (argc < 2) {
 742                 (void) fprintf(stderr, gettext("missing vdev specification\n"));
 743                 usage(B_FALSE);
 744         }
 745 
 746         poolname = argv[0];
 747 
 748         argc--;
 749         argv++;
 750 
 751         if ((zhp = zpool_open(g_zfs, poolname)) == NULL)
 752                 return (1);
 753 
 754         if ((config = zpool_get_config(zhp, NULL)) == NULL) {
 755                 (void) fprintf(stderr, gettext("pool '%s' is unavailable\n"),
 756                     poolname);
 757                 zpool_close(zhp);
 758                 return (1);
 759         }
 760 
 761         if (zpool_is_bootable(zhp))
 762                 boot_type = ZPOOL_COPY_BOOT_LABEL;
 763         else
 764                 boot_type = ZPOOL_NO_BOOT_LABEL;
 765 
 766         /* unless manually specified use "ashift" pool property (if set) */
 767         if (!nvlist_exists(props, ZPOOL_CONFIG_ASHIFT)) {
 768                 int intval;
 769                 zprop_source_t src;
 770                 char strval[ZPOOL_MAXPROPLEN];
 771 
 772                 intval = zpool_get_prop_int(zhp, ZPOOL_PROP_ASHIFT, &src);
 773                 if (src != ZPROP_SRC_DEFAULT) {
 774                         (void) sprintf(strval, "%" PRId32, intval);
 775                         verify(add_prop_list(ZPOOL_CONFIG_ASHIFT, strval,
 776                             &props, B_TRUE) == 0);
 777                 }
 778         }
 779 
 780         /* pass off to get_vdev_spec for processing */
 781         boot_size = zpool_get_prop_int(zhp, ZPOOL_PROP_BOOTSIZE, NULL);
 782         nvroot = make_root_vdev(zhp, props, force, !force, B_FALSE, dryrun,
 783             boot_type, boot_size, argc, argv);
 784         if (nvroot == NULL) {
 785                 zpool_close(zhp);
 786                 return (1);
 787         }
 788 
 789         if (dryrun) {
 790                 nvlist_t *poolnvroot;
 791 
 792                 verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
 793                     &poolnvroot) == 0);
 794 
 795                 (void) printf(gettext("would update '%s' to the following "
 796                     "configuration:\n"), zpool_get_name(zhp));
 797 
 798                 /* print original main pool and new tree */
 799                 print_vdev_tree(zhp, poolname, poolnvroot, 0, "",
 800                     name_flags | VDEV_NAME_TYPE_ID);
 801                 print_vdev_tree(zhp, NULL, nvroot, 0, "", name_flags);
 802 
 803                 /* print other classes: 'dedup', 'special', and 'log' */
 804                 print_vdev_tree(zhp, "dedup", poolnvroot, 0,
 805                     VDEV_ALLOC_BIAS_DEDUP, name_flags);
 806                 print_vdev_tree(zhp, NULL, nvroot, 0, VDEV_ALLOC_BIAS_DEDUP,
 807                     name_flags);
 808 
 809                 print_vdev_tree(zhp, "special", poolnvroot, 0,
 810                     VDEV_ALLOC_BIAS_SPECIAL, name_flags);
 811                 print_vdev_tree(zhp, NULL, nvroot, 0, VDEV_ALLOC_BIAS_SPECIAL,
 812                     name_flags);
 813 
 814                 print_vdev_tree(zhp, "logs", poolnvroot, 0, VDEV_ALLOC_BIAS_LOG,
 815                     name_flags);
 816                 print_vdev_tree(zhp, NULL, nvroot, 0, VDEV_ALLOC_BIAS_LOG,
 817                     name_flags);
 818 
 819                 ret = 0;
 820         } else {
 821                 ret = (zpool_add(zhp, nvroot) != 0);
 822         }
 823 
 824         nvlist_free(props);
 825         nvlist_free(nvroot);
 826         zpool_close(zhp);
 827 
 828         return (ret);
 829 }
 830 
 831 /*
 832  * zpool remove  <pool> <vdev> ...
 833  *
 834  * Removes the given vdev from the pool.
 835  */
 836 int
 837 zpool_do_remove(int argc, char **argv)
 838 {
 839         char *poolname;
 840         int i, ret = 0;
 841         zpool_handle_t *zhp;
 842         boolean_t stop = B_FALSE;
 843         boolean_t noop = B_FALSE;
 844         boolean_t parsable = B_FALSE;
 845         char c;
 846 
 847         /* check options */
 848         while ((c = getopt(argc, argv, "nps")) != -1) {
 849                 switch (c) {
 850                 case 'n':
 851                         noop = B_TRUE;
 852                         break;
 853                 case 'p':
 854                         parsable = B_TRUE;
 855                         break;
 856                 case 's':
 857                         stop = B_TRUE;
 858                         break;
 859                 case '?':
 860                         (void) fprintf(stderr, gettext("invalid option '%c'\n"),
 861                             optopt);
 862                         usage(B_FALSE);
 863                 }
 864         }
 865 
 866         argc -= optind;
 867         argv += optind;
 868 
 869         /* get pool name and check number of arguments */
 870         if (argc < 1) {
 871                 (void) fprintf(stderr, gettext("missing pool name argument\n"));
 872                 usage(B_FALSE);
 873         }
 874 
 875         poolname = argv[0];
 876 
 877         if ((zhp = zpool_open(g_zfs, poolname)) == NULL)
 878                 return (1);
 879 
 880         if (stop && noop) {
 881                 (void) fprintf(stderr, gettext("stop request ignored\n"));
 882                 return (0);
 883         }
 884 
 885         if (stop) {
 886                 if (argc > 1) {
 887                         (void) fprintf(stderr, gettext("too many arguments\n"));
 888                         usage(B_FALSE);
 889                 }
 890                 if (zpool_vdev_remove_cancel(zhp) != 0)
 891                         ret = 1;
 892         } else {
 893                 if (argc < 2) {
 894                         (void) fprintf(stderr, gettext("missing device\n"));
 895                         usage(B_FALSE);
 896                 }
 897 
 898                 for (i = 1; i < argc; i++) {
 899                         if (noop) {
 900                                 uint64_t size;
 901 
 902                                 if (zpool_vdev_indirect_size(zhp, argv[i],
 903                                     &size) != 0) {
 904                                         ret = 1;
 905                                         break;
 906                                 }
 907                                 if (parsable) {
 908                                         (void) printf("%s %llu\n",
 909                                             argv[i], size);
 910                                 } else {
 911                                         char valstr[32];
 912                                         zfs_nicenum(size, valstr,
 913                                             sizeof (valstr));
 914                                         (void) printf("Memory that will be "
 915                                             "used after removing %s: %s\n",
 916                                             argv[i], valstr);
 917                                 }
 918                         } else {
 919                                 if (zpool_vdev_remove(zhp, argv[i]) != 0)
 920                                         ret = 1;
 921                         }
 922                 }
 923         }
 924 
 925         return (ret);
 926 }
 927 
 928 /*
 929  * zpool labelclear [-f] <vdev>
 930  *
 931  *      -f      Force clearing the label for the vdevs which are members of
 932  *              the exported or foreign pools.
 933  *
 934  * Verifies that the vdev is not active and zeros out the label information
 935  * on the device.
 936  */
 937 int
 938 zpool_do_labelclear(int argc, char **argv)
 939 {
 940         char vdev[MAXPATHLEN];
 941         char *name = NULL;
 942         struct stat st;
 943         int c, fd, ret = 0;
 944         nvlist_t *config;
 945         pool_state_t state;
 946         boolean_t inuse = B_FALSE;
 947         boolean_t force = B_FALSE;
 948 
 949         /* check options */
 950         while ((c = getopt(argc, argv, "f")) != -1) {
 951                 switch (c) {
 952                 case 'f':
 953                         force = B_TRUE;
 954                         break;
 955                 default:
 956                         (void) fprintf(stderr, gettext("invalid option '%c'\n"),
 957                             optopt);
 958                         usage(B_FALSE);
 959                 }
 960         }
 961 
 962         argc -= optind;
 963         argv += optind;
 964 
 965         /* get vdev name */
 966         if (argc < 1) {
 967                 (void) fprintf(stderr, gettext("missing vdev name\n"));
 968                 usage(B_FALSE);
 969         }
 970         if (argc > 1) {
 971                 (void) fprintf(stderr, gettext("too many arguments\n"));
 972                 usage(B_FALSE);
 973         }
 974 
 975         /*
 976          * Check if we were given absolute path and use it as is.
 977          * Otherwise if the provided vdev name doesn't point to a file,
 978          * try prepending dsk path and appending s0.
 979          */
 980         (void) strlcpy(vdev, argv[0], sizeof (vdev));
 981         if (vdev[0] != '/' && stat(vdev, &st) != 0) {
 982                 char *s;
 983 
 984                 (void) snprintf(vdev, sizeof (vdev), "%s/%s",
 985                     ZFS_DISK_ROOT, argv[0]);
 986                 if ((s = strrchr(argv[0], 's')) == NULL ||
 987                     !isdigit(*(s + 1)))
 988                         (void) strlcat(vdev, "s0", sizeof (vdev));
 989                 if (stat(vdev, &st) != 0) {
 990                         (void) fprintf(stderr, gettext(
 991                             "failed to find device %s, try specifying absolute "
 992                             "path instead\n"), argv[0]);
 993                         return (1);
 994                 }
 995         }
 996 
 997         if ((fd = open(vdev, O_RDWR)) < 0) {
 998                 (void) fprintf(stderr, gettext("failed to open %s: %s\n"),
 999                     vdev, strerror(errno));
1000                 return (1);
1001         }
1002 
1003         if (zpool_read_label(fd, &config, NULL) != 0) {
1004                 (void) fprintf(stderr,
1005                     gettext("failed to read label from %s\n"), vdev);
1006                 return (1);
1007         }
1008         nvlist_free(config);
1009 
1010         ret = zpool_in_use(g_zfs, fd, &state, &name, &inuse);
1011         if (ret != 0) {
1012                 (void) fprintf(stderr,
1013                     gettext("failed to check state for %s\n"), vdev);
1014                 return (1);
1015         }
1016 
1017         if (!inuse)
1018                 goto wipe_label;
1019 
1020         switch (state) {
1021         default:
1022         case POOL_STATE_ACTIVE:
1023         case POOL_STATE_SPARE:
1024         case POOL_STATE_L2CACHE:
1025                 (void) fprintf(stderr, gettext(
1026                     "%s is a member (%s) of pool \"%s\"\n"),
1027                     vdev, zpool_pool_state_to_name(state), name);
1028                 ret = 1;
1029                 goto errout;
1030 
1031         case POOL_STATE_EXPORTED:
1032                 if (force)
1033                         break;
1034                 (void) fprintf(stderr, gettext(
1035                     "use '-f' to override the following error:\n"
1036                     "%s is a member of exported pool \"%s\"\n"),
1037                     vdev, name);
1038                 ret = 1;
1039                 goto errout;
1040 
1041         case POOL_STATE_POTENTIALLY_ACTIVE:
1042                 if (force)
1043                         break;
1044                 (void) fprintf(stderr, gettext(
1045                     "use '-f' to override the following error:\n"
1046                     "%s is a member of potentially active pool \"%s\"\n"),
1047                     vdev, name);
1048                 ret = 1;
1049                 goto errout;
1050 
1051         case POOL_STATE_DESTROYED:
1052                 /* inuse should never be set for a destroyed pool */
1053                 assert(0);
1054                 break;
1055         }
1056 
1057 wipe_label:
1058         ret = zpool_clear_label(fd);
1059         if (ret != 0) {
1060                 (void) fprintf(stderr,
1061                     gettext("failed to clear label for %s\n"), vdev);
1062         }
1063 
1064 errout:
1065         free(name);
1066         (void) close(fd);
1067 
1068         return (ret);
1069 }
1070 
1071 /*
1072  * zpool create [-fnd] [-B] [-o property=value] ...
1073  *              [-O file-system-property=value] ...
1074  *              [-R root] [-m mountpoint] [-t tempname] <pool> <dev> ...
1075  *
1076  *      -B      Create boot partition.
1077  *      -f      Force creation, even if devices appear in use
1078  *      -n      Do not create the pool, but display the resulting layout if it
1079  *              were to be created.
1080  *      -R      Create a pool under an alternate root
1081  *      -m      Set default mountpoint for the root dataset.  By default it's
1082  *              '/<pool>'
1083  *      -t      Use the temporary name until the pool is exported.
1084  *      -o      Set property=value.
1085  *      -o      Set feature@feature=enabled|disabled.
1086  *      -d      Don't automatically enable all supported pool features
1087  *              (individual features can be enabled with -o).
1088  *      -O      Set fsproperty=value in the pool's root file system
1089  *
1090  * Creates the named pool according to the given vdev specification.  The
1091  * bulk of the vdev processing is done in get_vdev_spec() in zpool_vdev.c.  Once
1092  * we get the nvlist back from get_vdev_spec(), we either print out the contents
1093  * (if '-n' was specified), or pass it to libzfs to do the creation.
1094  */
1095 
1096 #define SYSTEM256       (256 * 1024 * 1024)
1097 int
1098 zpool_do_create(int argc, char **argv)
1099 {
1100         boolean_t force = B_FALSE;
1101         boolean_t dryrun = B_FALSE;
1102         boolean_t enable_all_pool_feat = B_TRUE;
1103         zpool_boot_label_t boot_type = ZPOOL_NO_BOOT_LABEL;
1104         uint64_t boot_size = 0;
1105         int c;
1106         nvlist_t *nvroot = NULL;
1107         char *poolname;
1108         char *tname = NULL;
1109         int ret = 1;
1110         char *altroot = NULL;
1111         char *mountpoint = NULL;
1112         nvlist_t *fsprops = NULL;
1113         nvlist_t *props = NULL;
1114         char *propval;
1115 
1116         /* check options */
1117         while ((c = getopt(argc, argv, ":fndBR:m:o:O:t:")) != -1) {
1118                 switch (c) {
1119                 case 'f':
1120                         force = B_TRUE;
1121                         break;
1122                 case 'n':
1123                         dryrun = B_TRUE;
1124                         break;
1125                 case 'd':
1126                         enable_all_pool_feat = B_FALSE;
1127                         break;
1128                 case 'B':
1129                         /*
1130                          * We should create the system partition.
1131                          * Also make sure the size is set.
1132                          */
1133                         boot_type = ZPOOL_CREATE_BOOT_LABEL;
1134                         if (boot_size == 0)
1135                                 boot_size = SYSTEM256;
1136                         break;
1137                 case 'R':
1138                         altroot = optarg;
1139                         if (add_prop_list(zpool_prop_to_name(
1140                             ZPOOL_PROP_ALTROOT), optarg, &props, B_TRUE))
1141                                 goto errout;
1142                         if (add_prop_list_default(zpool_prop_to_name(
1143                             ZPOOL_PROP_CACHEFILE), "none", &props, B_TRUE))
1144                                 goto errout;
1145                         break;
1146                 case 'm':
1147                         /* Equivalent to -O mountpoint=optarg */
1148                         mountpoint = optarg;
1149                         break;
1150                 case 'o':
1151                         if ((propval = strchr(optarg, '=')) == NULL) {
1152                                 (void) fprintf(stderr, gettext("missing "
1153                                     "'=' for -o option\n"));
1154                                 goto errout;
1155                         }
1156                         *propval = '\0';
1157                         propval++;
1158 
1159                         if (add_prop_list(optarg, propval, &props, B_TRUE))
1160                                 goto errout;
1161 
1162                         /*
1163                          * Get bootsize value for make_root_vdev().
1164                          */
1165                         if (zpool_name_to_prop(optarg) == ZPOOL_PROP_BOOTSIZE) {
1166                                 if (zfs_nicestrtonum(g_zfs, propval,
1167                                     &boot_size) < 0 || boot_size == 0) {
1168                                         (void) fprintf(stderr,
1169                                             gettext("bad boot partition size "
1170                                             "'%s': %s\n"),  propval,
1171                                             libzfs_error_description(g_zfs));
1172                                         goto errout;
1173                                 }
1174                         }
1175 
1176                         /*
1177                          * If the user is creating a pool that doesn't support
1178                          * feature flags, don't enable any features.
1179                          */
1180                         if (zpool_name_to_prop(optarg) == ZPOOL_PROP_VERSION) {
1181                                 char *end;
1182                                 u_longlong_t ver;
1183 
1184                                 ver = strtoull(propval, &end, 10);
1185                                 if (*end == '\0' &&
1186                                     ver < SPA_VERSION_FEATURES) {
1187                                         enable_all_pool_feat = B_FALSE;
1188                                 }
1189                         }
1190                         if (zpool_name_to_prop(optarg) == ZPOOL_PROP_ALTROOT)
1191                                 altroot = propval;
1192                         break;
1193                 case 'O':
1194                         if ((propval = strchr(optarg, '=')) == NULL) {
1195                                 (void) fprintf(stderr, gettext("missing "
1196                                     "'=' for -O option\n"));
1197                                 goto errout;
1198                         }
1199                         *propval = '\0';
1200                         propval++;
1201 
1202                         /*
1203                          * Mountpoints are checked and then added later.
1204                          * Uniquely among properties, they can be specified
1205                          * more than once, to avoid conflict with -m.
1206                          */
1207                         if (0 == strcmp(optarg,
1208                             zfs_prop_to_name(ZFS_PROP_MOUNTPOINT))) {
1209                                 mountpoint = propval;
1210                         } else if (add_prop_list(optarg, propval, &fsprops,
1211                             B_FALSE)) {
1212                                 goto errout;
1213                         }
1214                         break;
1215                 case 't':
1216                         /*
1217                          * Sanity check temporary pool name.
1218                          */
1219                         if (strchr(optarg, '/') != NULL) {
1220                                 (void) fprintf(stderr, gettext("cannot create "
1221                                     "'%s': invalid character '/' in temporary "
1222                                     "name\n"), optarg);
1223                                 (void) fprintf(stderr, gettext("use 'zfs "
1224                                     "create' to create a dataset\n"));
1225                                 goto errout;
1226                         }
1227 
1228                         if (add_prop_list(zpool_prop_to_name(
1229                             ZPOOL_PROP_TNAME), optarg, &props, B_TRUE))
1230                                 goto errout;
1231                         if (add_prop_list_default(zpool_prop_to_name(
1232                             ZPOOL_PROP_CACHEFILE), "none", &props, B_TRUE))
1233                                 goto errout;
1234                         tname = optarg;
1235                         break;
1236                 case ':':
1237                         (void) fprintf(stderr, gettext("missing argument for "
1238                             "'%c' option\n"), optopt);
1239                         goto badusage;
1240                 case '?':
1241                         (void) fprintf(stderr, gettext("invalid option '%c'\n"),
1242                             optopt);
1243                         goto badusage;
1244                 }
1245         }
1246 
1247         argc -= optind;
1248         argv += optind;
1249 
1250         /* get pool name and check number of arguments */
1251         if (argc < 1) {
1252                 (void) fprintf(stderr, gettext("missing pool name argument\n"));
1253                 goto badusage;
1254         }
1255         if (argc < 2) {
1256                 (void) fprintf(stderr, gettext("missing vdev specification\n"));
1257                 goto badusage;
1258         }
1259 
1260         poolname = argv[0];
1261 
1262         /*
1263          * As a special case, check for use of '/' in the name, and direct the
1264          * user to use 'zfs create' instead.
1265          */
1266         if (strchr(poolname, '/') != NULL) {
1267                 (void) fprintf(stderr, gettext("cannot create '%s': invalid "
1268                     "character '/' in pool name\n"), poolname);
1269                 (void) fprintf(stderr, gettext("use 'zfs create' to "
1270                     "create a dataset\n"));
1271                 goto errout;
1272         }
1273 
1274         /*
1275          * Make sure the bootsize is set when ZPOOL_CREATE_BOOT_LABEL is used,
1276          * and not set otherwise.
1277          */
1278         if (boot_type == ZPOOL_CREATE_BOOT_LABEL) {
1279                 const char *propname;
1280                 char *strptr, *buf = NULL;
1281                 int rv;
1282 
1283                 propname = zpool_prop_to_name(ZPOOL_PROP_BOOTSIZE);
1284                 if (nvlist_lookup_string(props, propname, &strptr) != 0) {
1285                         (void) asprintf(&buf, "%" PRIu64, boot_size);
1286                         if (buf == NULL) {
1287                                 (void) fprintf(stderr,
1288                                     gettext("internal error: out of memory\n"));
1289                                 goto errout;
1290                         }
1291                         rv = add_prop_list(propname, buf, &props, B_TRUE);
1292                         free(buf);
1293                         if (rv != 0)
1294                                 goto errout;
1295                 }
1296         } else {
1297                 const char *propname;
1298                 char *strptr;
1299 
1300                 propname = zpool_prop_to_name(ZPOOL_PROP_BOOTSIZE);
1301                 if (nvlist_lookup_string(props, propname, &strptr) == 0) {
1302                         (void) fprintf(stderr, gettext("error: setting boot "
1303                             "partition size requires option '-B'\n"));
1304                         goto errout;
1305                 }
1306         }
1307 
1308         /* pass off to get_vdev_spec for bulk processing */
1309         nvroot = make_root_vdev(NULL, props, force, !force, B_FALSE, dryrun,
1310             boot_type, boot_size, argc - 1, argv + 1);
1311         if (nvroot == NULL)
1312                 goto errout;
1313 
1314         /* make_root_vdev() allows 0 toplevel children if there are spares */
1315         if (!zfs_allocatable_devs(nvroot)) {
1316                 (void) fprintf(stderr, gettext("invalid vdev "
1317                     "specification: at least one toplevel vdev must be "
1318                     "specified\n"));
1319                 goto errout;
1320         }
1321 
1322         if (altroot != NULL && altroot[0] != '/') {
1323                 (void) fprintf(stderr, gettext("invalid alternate root '%s': "
1324                     "must be an absolute path\n"), altroot);
1325                 goto errout;
1326         }
1327 
1328         /*
1329          * Check the validity of the mountpoint and direct the user to use the
1330          * '-m' mountpoint option if it looks like its in use.
1331          */
1332         if (mountpoint == NULL ||
1333             (strcmp(mountpoint, ZFS_MOUNTPOINT_LEGACY) != 0 &&
1334             strcmp(mountpoint, ZFS_MOUNTPOINT_NONE) != 0)) {
1335                 char buf[MAXPATHLEN];
1336                 DIR *dirp;
1337 
1338                 if (mountpoint && mountpoint[0] != '/') {
1339                         (void) fprintf(stderr, gettext("invalid mountpoint "
1340                             "'%s': must be an absolute path, 'legacy', or "
1341                             "'none'\n"), mountpoint);
1342                         goto errout;
1343                 }
1344 
1345                 if (mountpoint == NULL) {
1346                         if (altroot != NULL)
1347                                 (void) snprintf(buf, sizeof (buf), "%s/%s",
1348                                     altroot, poolname);
1349                         else
1350                                 (void) snprintf(buf, sizeof (buf), "/%s",
1351                                     poolname);
1352                 } else {
1353                         if (altroot != NULL)
1354                                 (void) snprintf(buf, sizeof (buf), "%s%s",
1355                                     altroot, mountpoint);
1356                         else
1357                                 (void) snprintf(buf, sizeof (buf), "%s",
1358                                     mountpoint);
1359                 }
1360 
1361                 if ((dirp = opendir(buf)) == NULL && errno != ENOENT) {
1362                         (void) fprintf(stderr, gettext("mountpoint '%s' : "
1363                             "%s\n"), buf, strerror(errno));
1364                         (void) fprintf(stderr, gettext("use '-m' "
1365                             "option to provide a different default\n"));
1366                         goto errout;
1367                 } else if (dirp) {
1368                         int count = 0;
1369 
1370                         while (count < 3 && readdir(dirp) != NULL)
1371                                 count++;
1372                         (void) closedir(dirp);
1373 
1374                         if (count > 2) {
1375                                 (void) fprintf(stderr, gettext("mountpoint "
1376                                     "'%s' exists and is not empty\n"), buf);
1377                                 (void) fprintf(stderr, gettext("use '-m' "
1378                                     "option to provide a "
1379                                     "different default\n"));
1380                                 goto errout;
1381                         }
1382                 }
1383         }
1384 
1385         /*
1386          * Now that the mountpoint's validity has been checked, ensure that
1387          * the property is set appropriately prior to creating the pool.
1388          */
1389         if (mountpoint != NULL) {
1390                 ret = add_prop_list(zfs_prop_to_name(ZFS_PROP_MOUNTPOINT),
1391                     mountpoint, &fsprops, B_FALSE);
1392                 if (ret != 0)
1393                         goto errout;
1394         }
1395 
1396         ret = 1;
1397         if (dryrun) {
1398                 /*
1399                  * For a dry run invocation, print out a basic message and run
1400                  * through all the vdevs in the list and print out in an
1401                  * appropriate hierarchy.
1402                  */
1403                 (void) printf(gettext("would create '%s' with the "
1404                     "following layout:\n\n"), poolname);
1405 
1406                 print_vdev_tree(NULL, poolname, nvroot, 0, "", 0);
1407                 print_vdev_tree(NULL, "dedup", nvroot, 0,
1408                     VDEV_ALLOC_BIAS_DEDUP, 0);
1409                 print_vdev_tree(NULL, "special", nvroot, 0,
1410                     VDEV_ALLOC_BIAS_SPECIAL, 0);
1411                 print_vdev_tree(NULL, "logs", nvroot, 0,
1412                     VDEV_ALLOC_BIAS_LOG, 0);
1413 
1414                 ret = 0;
1415         } else {
1416                 /*
1417                  * Hand off to libzfs.
1418                  */
1419 
1420                 spa_feature_t i;
1421                 for (i = 0; i < SPA_FEATURES; i++) {
1422                         char propname[MAXPATHLEN];
1423                         char *propval;
1424                         zfeature_info_t *feat = &spa_feature_table[i];
1425                         (void) snprintf(propname, sizeof (propname),
1426                             "feature@%s", feat->fi_uname);
1427 
1428                         /*
1429                          * Only features contained in props will be enabled:
1430                          * remove from the nvlist every ZFS_FEATURE_DISABLED
1431                          * value and add every missing ZFS_FEATURE_ENABLED if
1432                          * enable_all_pool_feat is set.
1433                          */
1434                         if (!nvlist_lookup_string(props, propname, &propval)) {
1435                                 if (strcmp(propval, ZFS_FEATURE_DISABLED) == 0)
1436                                         (void) nvlist_remove_all(props,
1437                                             propname);
1438                         } else if (enable_all_pool_feat) {
1439                                 ret = add_prop_list(propname,
1440                                     ZFS_FEATURE_ENABLED, &props, B_TRUE);
1441                                 if (ret != 0)
1442                                         goto errout;
1443                         }
1444                 }
1445 
1446                 ret = 1;
1447                 if (zpool_create(g_zfs, poolname,
1448                     nvroot, props, fsprops) == 0) {
1449                         zfs_handle_t *pool = zfs_open(g_zfs,
1450                             tname ? tname : poolname, ZFS_TYPE_FILESYSTEM);
1451                         if (pool != NULL) {
1452                                 if (zfs_mount(pool, NULL, 0) == 0)
1453                                         ret = zfs_shareall(pool);
1454                                 zfs_close(pool);
1455                         }
1456                 } else if (libzfs_errno(g_zfs) == EZFS_INVALIDNAME) {
1457                         (void) fprintf(stderr, gettext("pool name may have "
1458                             "been omitted\n"));
1459                 }
1460         }
1461 
1462 errout:
1463         nvlist_free(nvroot);
1464         nvlist_free(fsprops);
1465         nvlist_free(props);
1466         return (ret);
1467 badusage:
1468         nvlist_free(fsprops);
1469         nvlist_free(props);
1470         usage(B_FALSE);
1471         return (2);
1472 }
1473 
1474 /*
1475  * zpool destroy <pool>
1476  *
1477  *      -f      Forcefully unmount any datasets
1478  *
1479  * Destroy the given pool.  Automatically unmounts any datasets in the pool.
1480  */
1481 int
1482 zpool_do_destroy(int argc, char **argv)
1483 {
1484         boolean_t force = B_FALSE;
1485         int c;
1486         char *pool;
1487         zpool_handle_t *zhp;
1488         int ret;
1489 
1490         /* check options */
1491         while ((c = getopt(argc, argv, "f")) != -1) {
1492                 switch (c) {
1493                 case 'f':
1494                         force = B_TRUE;
1495                         break;
1496                 case '?':
1497                         (void) fprintf(stderr, gettext("invalid option '%c'\n"),
1498                             optopt);
1499                         usage(B_FALSE);
1500                 }
1501         }
1502 
1503         argc -= optind;
1504         argv += optind;
1505 
1506         /* check arguments */
1507         if (argc < 1) {
1508                 (void) fprintf(stderr, gettext("missing pool argument\n"));
1509                 usage(B_FALSE);
1510         }
1511         if (argc > 1) {
1512                 (void) fprintf(stderr, gettext("too many arguments\n"));
1513                 usage(B_FALSE);
1514         }
1515 
1516         pool = argv[0];
1517 
1518         if ((zhp = zpool_open_canfail(g_zfs, pool)) == NULL) {
1519                 /*
1520                  * As a special case, check for use of '/' in the name, and
1521                  * direct the user to use 'zfs destroy' instead.
1522                  */
1523                 if (strchr(pool, '/') != NULL)
1524                         (void) fprintf(stderr, gettext("use 'zfs destroy' to "
1525                             "destroy a dataset\n"));
1526                 return (1);
1527         }
1528 
1529         if (zpool_disable_datasets(zhp, force) != 0) {
1530                 (void) fprintf(stderr, gettext("could not destroy '%s': "
1531                     "could not unmount datasets\n"), zpool_get_name(zhp));
1532                 return (1);
1533         }
1534 
1535         /* The history must be logged as part of the export */
1536         log_history = B_FALSE;
1537 
1538         ret = (zpool_destroy(zhp, history_str) != 0);
1539 
1540         zpool_close(zhp);
1541 
1542         return (ret);
1543 }
1544 
1545 /*
1546  * zpool export [-f] <pool> ...
1547  *
1548  *      -f      Forcefully unmount datasets
1549  *
1550  * Export the given pools.  By default, the command will attempt to cleanly
1551  * unmount any active datasets within the pool.  If the '-f' flag is specified,
1552  * then the datasets will be forcefully unmounted.
1553  */
1554 int
1555 zpool_do_export(int argc, char **argv)
1556 {
1557         boolean_t force = B_FALSE;
1558         boolean_t hardforce = B_FALSE;
1559         int c;
1560         zpool_handle_t *zhp;
1561         int ret;
1562         int i;
1563 
1564         /* check options */
1565         while ((c = getopt(argc, argv, "fF")) != -1) {
1566                 switch (c) {
1567                 case 'f':
1568                         force = B_TRUE;
1569                         break;
1570                 case 'F':
1571                         hardforce = B_TRUE;
1572                         break;
1573                 case '?':
1574                         (void) fprintf(stderr, gettext("invalid option '%c'\n"),
1575                             optopt);
1576                         usage(B_FALSE);
1577                 }
1578         }
1579 
1580         argc -= optind;
1581         argv += optind;
1582 
1583         /* check arguments */
1584         if (argc < 1) {
1585                 (void) fprintf(stderr, gettext("missing pool argument\n"));
1586                 usage(B_FALSE);
1587         }
1588 
1589         ret = 0;
1590         for (i = 0; i < argc; i++) {
1591                 if ((zhp = zpool_open_canfail(g_zfs, argv[i])) == NULL) {
1592                         ret = 1;
1593                         continue;
1594                 }
1595 
1596                 if (zpool_disable_datasets(zhp, force) != 0) {
1597                         ret = 1;
1598                         zpool_close(zhp);
1599                         continue;
1600                 }
1601 
1602                 /* The history must be logged as part of the export */
1603                 log_history = B_FALSE;
1604 
1605                 if (hardforce) {
1606                         if (zpool_export_force(zhp, history_str) != 0)
1607                                 ret = 1;
1608                 } else if (zpool_export(zhp, force, history_str) != 0) {
1609                         ret = 1;
1610                 }
1611 
1612                 zpool_close(zhp);
1613         }
1614 
1615         return (ret);
1616 }
1617 
1618 /*
1619  * Given a vdev configuration, determine the maximum width needed for the device
1620  * name column.
1621  */
1622 static int
1623 max_width(zpool_handle_t *zhp, nvlist_t *nv, int depth, int max,
1624     int name_flags)
1625 {
1626         char *name;
1627         nvlist_t **child;
1628         uint_t c, children;
1629         int ret;
1630 
1631         name = zpool_vdev_name(g_zfs, zhp, nv, name_flags | VDEV_NAME_TYPE_ID);
1632         if (strlen(name) + depth > max)
1633                 max = strlen(name) + depth;
1634 
1635         free(name);
1636 
1637         if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_SPARES,
1638             &child, &children) == 0) {
1639                 for (c = 0; c < children; c++)
1640                         if ((ret = max_width(zhp, child[c], depth + 2,
1641                             max, name_flags)) > max)
1642                                 max = ret;
1643         }
1644 
1645         if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_L2CACHE,
1646             &child, &children) == 0) {
1647                 for (c = 0; c < children; c++)
1648                         if ((ret = max_width(zhp, child[c], depth + 2,
1649                             max, name_flags)) > max)
1650                                 max = ret;
1651         }
1652 
1653         if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
1654             &child, &children) == 0) {
1655                 for (c = 0; c < children; c++)
1656                         if ((ret = max_width(zhp, child[c], depth + 2,
1657                             max, name_flags)) > max)
1658                                 max = ret;
1659         }
1660 
1661         return (max);
1662 }
1663 
1664 typedef struct spare_cbdata {
1665         uint64_t        cb_guid;
1666         zpool_handle_t  *cb_zhp;
1667 } spare_cbdata_t;
1668 
1669 static boolean_t
1670 find_vdev(nvlist_t *nv, uint64_t search)
1671 {
1672         uint64_t guid;
1673         nvlist_t **child;
1674         uint_t c, children;
1675 
1676         if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_GUID, &guid) == 0 &&
1677             search == guid)
1678                 return (B_TRUE);
1679 
1680         if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
1681             &child, &children) == 0) {
1682                 for (c = 0; c < children; c++)
1683                         if (find_vdev(child[c], search))
1684                                 return (B_TRUE);
1685         }
1686 
1687         return (B_FALSE);
1688 }
1689 
1690 static int
1691 find_spare(zpool_handle_t *zhp, void *data)
1692 {
1693         spare_cbdata_t *cbp = data;
1694         nvlist_t *config, *nvroot;
1695 
1696         config = zpool_get_config(zhp, NULL);
1697         verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
1698             &nvroot) == 0);
1699 
1700         if (find_vdev(nvroot, cbp->cb_guid)) {
1701                 cbp->cb_zhp = zhp;
1702                 return (1);
1703         }
1704 
1705         zpool_close(zhp);
1706         return (0);
1707 }
1708 
1709 typedef struct status_cbdata {
1710         int             cb_count;
1711         int             cb_name_flags;
1712         int             cb_namewidth;
1713         boolean_t       cb_allpools;
1714         boolean_t       cb_verbose;
1715         boolean_t       cb_literal;
1716         boolean_t       cb_explain;
1717         boolean_t       cb_first;
1718         boolean_t       cb_dedup_stats;
1719         boolean_t       cb_print_status;
1720         boolean_t       cb_print_slow_ios;
1721         boolean_t       cb_print_vdev_init;
1722         boolean_t       cb_print_vdev_trim;
1723 } status_cbdata_t;
1724 
1725 /*
1726  * Print vdev initialization status for leaves
1727  */
1728 static void
1729 print_status_initialize(vdev_stat_t *vs, boolean_t verbose)
1730 {
1731         if (verbose) {
1732                 if ((vs->vs_initialize_state == VDEV_INITIALIZE_ACTIVE ||
1733                     vs->vs_initialize_state == VDEV_INITIALIZE_SUSPENDED ||
1734                     vs->vs_initialize_state == VDEV_INITIALIZE_COMPLETE) &&
1735                     !vs->vs_scan_removing) {
1736                         char zbuf[1024];
1737                         char tbuf[256];
1738                         struct tm zaction_ts;
1739 
1740                         time_t t = vs->vs_initialize_action_time;
1741                         int initialize_pct = 100;
1742                         if (vs->vs_initialize_state !=
1743                             VDEV_INITIALIZE_COMPLETE) {
1744                                 initialize_pct = (vs->vs_initialize_bytes_done *
1745                                     100 / (vs->vs_initialize_bytes_est + 1));
1746                         }
1747 
1748                         (void) localtime_r(&t, &zaction_ts);
1749                         (void) strftime(tbuf, sizeof (tbuf), "%c", &zaction_ts);
1750 
1751                         switch (vs->vs_initialize_state) {
1752                         case VDEV_INITIALIZE_SUSPENDED:
1753                                 (void) snprintf(zbuf, sizeof (zbuf), ", %s %s",
1754                                     gettext("suspended, started at"), tbuf);
1755                                 break;
1756                         case VDEV_INITIALIZE_ACTIVE:
1757                                 (void) snprintf(zbuf, sizeof (zbuf), ", %s %s",
1758                                     gettext("started at"), tbuf);
1759                                 break;
1760                         case VDEV_INITIALIZE_COMPLETE:
1761                                 (void) snprintf(zbuf, sizeof (zbuf), ", %s %s",
1762                                     gettext("completed at"), tbuf);
1763                                 break;
1764                         }
1765 
1766                         (void) printf(gettext("  (%d%% initialized%s)"),
1767                             initialize_pct, zbuf);
1768                 } else {
1769                         (void) printf(gettext("  (uninitialized)"));
1770                 }
1771         } else if (vs->vs_initialize_state == VDEV_INITIALIZE_ACTIVE) {
1772                 (void) printf(gettext("  (initializing)"));
1773         }
1774 }
1775 
1776 /*
1777  * Print vdev TRIM status for leaves
1778  */
1779 static void
1780 print_status_trim(vdev_stat_t *vs, boolean_t verbose)
1781 {
1782         if (verbose) {
1783                 if ((vs->vs_trim_state == VDEV_TRIM_ACTIVE ||
1784                     vs->vs_trim_state == VDEV_TRIM_SUSPENDED ||
1785                     vs->vs_trim_state == VDEV_TRIM_COMPLETE) &&
1786                     !vs->vs_scan_removing) {
1787                         char zbuf[1024];
1788                         char tbuf[256];
1789                         struct tm zaction_ts;
1790 
1791                         time_t t = vs->vs_trim_action_time;
1792                         int trim_pct = 100;
1793                         if (vs->vs_trim_state != VDEV_TRIM_COMPLETE) {
1794                                 trim_pct = (vs->vs_trim_bytes_done *
1795                                     100 / (vs->vs_trim_bytes_est + 1));
1796                         }
1797 
1798                         (void) localtime_r(&t, &zaction_ts);
1799                         (void) strftime(tbuf, sizeof (tbuf), "%c", &zaction_ts);
1800 
1801                         switch (vs->vs_trim_state) {
1802                         case VDEV_TRIM_SUSPENDED:
1803                                 (void) snprintf(zbuf, sizeof (zbuf), ", %s %s",
1804                                     gettext("suspended, started at"), tbuf);
1805                                 break;
1806                         case VDEV_TRIM_ACTIVE:
1807                                 (void) snprintf(zbuf, sizeof (zbuf), ", %s %s",
1808                                     gettext("started at"), tbuf);
1809                                 break;
1810                         case VDEV_TRIM_COMPLETE:
1811                                 (void) snprintf(zbuf, sizeof (zbuf), ", %s %s",
1812                                     gettext("completed at"), tbuf);
1813                                 break;
1814                         }
1815 
1816                         (void) printf(gettext("  (%d%% trimmed%s)"),
1817                             trim_pct, zbuf);
1818                 } else if (vs->vs_trim_notsup) {
1819                         (void) printf(gettext("  (trim unsupported)"));
1820                 } else {
1821                         (void) printf(gettext("  (untrimmed)"));
1822                 }
1823         } else if (vs->vs_trim_state == VDEV_TRIM_ACTIVE) {
1824                 (void) printf(gettext("  (trimming)"));
1825         }
1826 }
1827 
1828 /*
1829  * Print out configuration state as requested by status_callback.
1830  */
1831 static void
1832 print_status_config(zpool_handle_t *zhp, status_cbdata_t *cb, const char *name,
1833     nvlist_t *nv, int depth, boolean_t isspare)
1834 {
1835         nvlist_t **child, *root;
1836         uint_t c, children;
1837         pool_scan_stat_t *ps = NULL;
1838         vdev_stat_t *vs;
1839         char rbuf[6], wbuf[6], cbuf[6];
1840         char *vname;
1841         uint64_t notpresent;
1842         spare_cbdata_t spare_cb;
1843         const char *state;
1844         char *type;
1845 
1846         if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
1847             &child, &children) != 0)
1848                 children = 0;
1849 
1850         verify(nvlist_lookup_uint64_array(nv, ZPOOL_CONFIG_VDEV_STATS,
1851             (uint64_t **)&vs, &c) == 0);
1852 
1853         verify(nvlist_lookup_string(nv, ZPOOL_CONFIG_TYPE, &type) == 0);
1854 
1855         if (strcmp(type, VDEV_TYPE_INDIRECT) == 0)
1856                 return;
1857 
1858         state = zpool_state_to_name(vs->vs_state, vs->vs_aux);
1859         if (isspare) {
1860                 /*
1861                  * For hot spares, we use the terms 'INUSE' and 'AVAILABLE' for
1862                  * online drives.
1863                  */
1864                 if (vs->vs_aux == VDEV_AUX_SPARED)
1865                         state = "INUSE";
1866                 else if (vs->vs_state == VDEV_STATE_HEALTHY)
1867                         state = "AVAIL";
1868         }
1869 
1870         (void) printf("\t%*s%-*s  %-8s", depth, "", cb->cb_namewidth - depth,
1871             name, state);
1872 
1873         if (!isspare) {
1874                 if (cb->cb_literal) {
1875                         printf(" %5llu %5llu %5llu",
1876                             (u_longlong_t)vs->vs_read_errors,
1877                             (u_longlong_t)vs->vs_write_errors,
1878                             (u_longlong_t)vs->vs_checksum_errors);
1879                 } else {
1880                         zfs_nicenum(vs->vs_read_errors, rbuf, sizeof (rbuf));
1881                         zfs_nicenum(vs->vs_write_errors, wbuf, sizeof (wbuf));
1882                         zfs_nicenum(vs->vs_checksum_errors, cbuf,
1883                             sizeof (cbuf));
1884                         printf(" %5s %5s %5s", rbuf, wbuf, cbuf);
1885                 }
1886 
1887                 if (cb->cb_print_slow_ios) {
1888                         if (children == 0)  {
1889                                 /* Only leafs vdevs have slow IOs */
1890                                 zfs_nicenum(vs->vs_slow_ios, rbuf,
1891                                     sizeof (rbuf));
1892                         } else {
1893                                 (void) snprintf(rbuf, sizeof (rbuf), "-");
1894                         }
1895 
1896                         if (cb->cb_literal)
1897                                 printf(" %5llu", (u_longlong_t)vs->vs_slow_ios);
1898                         else
1899                                 printf(" %5s", rbuf);
1900                 }
1901 
1902         }
1903 
1904         if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_NOT_PRESENT,
1905             &notpresent) == 0) {
1906                 char *path;
1907                 verify(nvlist_lookup_string(nv, ZPOOL_CONFIG_PATH, &path) == 0);
1908                 (void) printf("  was %s", path);
1909         } else if (vs->vs_aux != 0) {
1910                 (void) printf("  ");
1911 
1912                 switch (vs->vs_aux) {
1913                 case VDEV_AUX_OPEN_FAILED:
1914                         (void) printf(gettext("cannot open"));
1915                         break;
1916 
1917                 case VDEV_AUX_BAD_GUID_SUM:
1918                         (void) printf(gettext("missing device"));
1919                         break;
1920 
1921                 case VDEV_AUX_NO_REPLICAS:
1922                         (void) printf(gettext("insufficient replicas"));
1923                         break;
1924 
1925                 case VDEV_AUX_VERSION_NEWER:
1926                         (void) printf(gettext("newer version"));
1927                         break;
1928 
1929                 case VDEV_AUX_UNSUP_FEAT:
1930                         (void) printf(gettext("unsupported feature(s)"));
1931                         break;
1932 
1933                 case VDEV_AUX_SPARED:
1934                         verify(nvlist_lookup_uint64(nv, ZPOOL_CONFIG_GUID,
1935                             &spare_cb.cb_guid) == 0);
1936                         if (zpool_iter(g_zfs, find_spare, &spare_cb) == 1) {
1937                                 if (strcmp(zpool_get_name(spare_cb.cb_zhp),
1938                                     zpool_get_name(zhp)) == 0)
1939                                         (void) printf(gettext("currently in "
1940                                             "use"));
1941                                 else
1942                                         (void) printf(gettext("in use by "
1943                                             "pool '%s'"),
1944                                             zpool_get_name(spare_cb.cb_zhp));
1945                                 zpool_close(spare_cb.cb_zhp);
1946                         } else {
1947                                 (void) printf(gettext("currently in use"));
1948                         }
1949                         break;
1950 
1951                 case VDEV_AUX_ERR_EXCEEDED:
1952                         (void) printf(gettext("too many errors"));
1953                         break;
1954 
1955                 case VDEV_AUX_IO_FAILURE:
1956                         (void) printf(gettext("experienced I/O failures"));
1957                         break;
1958 
1959                 case VDEV_AUX_BAD_LOG:
1960                         (void) printf(gettext("bad intent log"));
1961                         break;
1962 
1963                 case VDEV_AUX_EXTERNAL:
1964                         (void) printf(gettext("external device fault"));
1965                         break;
1966 
1967                 case VDEV_AUX_SPLIT_POOL:
1968                         (void) printf(gettext("split into new pool"));
1969                         break;
1970 
1971                 case VDEV_AUX_ACTIVE:
1972                         (void) printf(gettext("currently in use"));
1973                         break;
1974 
1975                 case VDEV_AUX_CHILDREN_OFFLINE:
1976                         (void) printf(gettext("all children offline"));
1977                         break;
1978 
1979                 default:
1980                         (void) printf(gettext("corrupted data"));
1981                         break;
1982                 }
1983         }
1984 
1985         /* The root vdev has the scrub/resilver stats */
1986         root = fnvlist_lookup_nvlist(zpool_get_config(zhp, NULL),
1987             ZPOOL_CONFIG_VDEV_TREE);
1988         (void) nvlist_lookup_uint64_array(root, ZPOOL_CONFIG_SCAN_STATS,
1989             (uint64_t **)&ps, &c);
1990 
1991         if (ps != NULL && ps->pss_state == DSS_SCANNING && children == 0) {
1992                 if (vs->vs_scan_processed != 0) {
1993                         (void) printf(gettext("  (%s)"),
1994                             (ps->pss_func == POOL_SCAN_RESILVER) ?
1995                             "resilvering" : "repairing");
1996                 } else if (vs->vs_resilver_deferred) {
1997                         (void) printf(gettext("  (awaiting resilver)"));
1998                 }
1999         }
2000 
2001         /* Display vdev initialization and trim status for leaves */
2002         if (children == 0) {
2003                 print_status_initialize(vs, cb->cb_print_vdev_init);
2004                 print_status_trim(vs, cb->cb_print_vdev_trim);
2005         }
2006 
2007         (void) printf("\n");
2008 
2009         for (c = 0; c < children; c++) {
2010                 uint64_t islog = B_FALSE, ishole = B_FALSE;
2011 
2012                 /* Don't print logs or holes here */
2013                 (void) nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_LOG,
2014                     &islog);
2015                 (void) nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_HOLE,
2016                     &ishole);
2017                 if (islog || ishole)
2018                         continue;
2019                 /* Only print normal classes here */
2020                 if (nvlist_exists(child[c], ZPOOL_CONFIG_ALLOCATION_BIAS))
2021                         continue;
2022 
2023                 vname = zpool_vdev_name(g_zfs, zhp, child[c],
2024                     cb->cb_name_flags | VDEV_NAME_TYPE_ID);
2025 
2026                 print_status_config(zhp, cb, vname, child[c], depth + 2,
2027                     isspare);
2028                 free(vname);
2029         }
2030 }
2031 
2032 /*
2033  * Print the configuration of an exported pool.  Iterate over all vdevs in the
2034  * pool, printing out the name and status for each one.
2035  */
2036 static void
2037 print_import_config(status_cbdata_t *cb, const char *name, nvlist_t *nv,
2038     int depth)
2039 {
2040         nvlist_t **child;
2041         uint_t c, children;
2042         vdev_stat_t *vs;
2043         char *type, *vname;
2044 
2045         verify(nvlist_lookup_string(nv, ZPOOL_CONFIG_TYPE, &type) == 0);
2046         if (strcmp(type, VDEV_TYPE_MISSING) == 0 ||
2047             strcmp(type, VDEV_TYPE_HOLE) == 0)
2048                 return;
2049 
2050         verify(nvlist_lookup_uint64_array(nv, ZPOOL_CONFIG_VDEV_STATS,
2051             (uint64_t **)&vs, &c) == 0);
2052 
2053         (void) printf("\t%*s%-*s", depth, "", cb->cb_namewidth - depth, name);
2054         (void) printf("  %s", zpool_state_to_name(vs->vs_state, vs->vs_aux));
2055 
2056         if (vs->vs_aux != 0) {
2057                 (void) printf("  ");
2058 
2059                 switch (vs->vs_aux) {
2060                 case VDEV_AUX_OPEN_FAILED:
2061                         (void) printf(gettext("cannot open"));
2062                         break;
2063 
2064                 case VDEV_AUX_BAD_GUID_SUM:
2065                         (void) printf(gettext("missing device"));
2066                         break;
2067 
2068                 case VDEV_AUX_NO_REPLICAS:
2069                         (void) printf(gettext("insufficient replicas"));
2070                         break;
2071 
2072                 case VDEV_AUX_VERSION_NEWER:
2073                         (void) printf(gettext("newer version"));
2074                         break;
2075 
2076                 case VDEV_AUX_UNSUP_FEAT:
2077                         (void) printf(gettext("unsupported feature(s)"));
2078                         break;
2079 
2080                 case VDEV_AUX_ERR_EXCEEDED:
2081                         (void) printf(gettext("too many errors"));
2082                         break;
2083 
2084                 case VDEV_AUX_ACTIVE:
2085                         (void) printf(gettext("currently in use"));
2086                         break;
2087 
2088                 case VDEV_AUX_CHILDREN_OFFLINE:
2089                         (void) printf(gettext("all children offline"));
2090                         break;
2091 
2092                 default:
2093                         (void) printf(gettext("corrupted data"));
2094                         break;
2095                 }
2096         }
2097         (void) printf("\n");
2098 
2099         if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
2100             &child, &children) != 0)
2101                 return;
2102 
2103         for (c = 0; c < children; c++) {
2104                 uint64_t is_log = B_FALSE;
2105 
2106                 (void) nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_LOG,
2107                     &is_log);
2108                 if (is_log)
2109                         continue;
2110                 if (nvlist_exists(child[c], ZPOOL_CONFIG_ALLOCATION_BIAS))
2111                         continue;
2112 
2113                 vname = zpool_vdev_name(g_zfs, NULL, child[c],
2114                     cb->cb_name_flags | VDEV_NAME_TYPE_ID);
2115                 print_import_config(cb, vname, child[c], depth + 2);
2116                 free(vname);
2117         }
2118 
2119         if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_L2CACHE,
2120             &child, &children) == 0) {
2121                 (void) printf(gettext("\tcache\n"));
2122                 for (c = 0; c < children; c++) {
2123                         vname = zpool_vdev_name(g_zfs, NULL, child[c],
2124                             cb->cb_name_flags);
2125                         (void) printf("\t  %s\n", vname);
2126                         free(vname);
2127                 }
2128         }
2129 
2130         if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_SPARES,
2131             &child, &children) == 0) {
2132                 (void) printf(gettext("\tspares\n"));
2133                 for (c = 0; c < children; c++) {
2134                         vname = zpool_vdev_name(g_zfs, NULL, child[c],
2135                             cb->cb_name_flags);
2136                         (void) printf("\t  %s\n", vname);
2137                         free(vname);
2138                 }
2139         }
2140 }
2141 
2142 /*
2143  * Print specialized class vdevs.
2144  *
2145  * These are recorded as top level vdevs in the main pool child array
2146  * but with "is_log" set to 1 or an "alloc_bias" string. We use either
2147  * print_status_config() or print_import_config() to print the top level
2148  * class vdevs then any of their children (eg mirrored slogs) are printed
2149  * recursively - which works because only the top level vdev is marked.
2150  */
2151 static void
2152 print_class_vdevs(zpool_handle_t *zhp, status_cbdata_t *cb, nvlist_t *nv,
2153     const char *class)
2154 {
2155         uint_t c, children;
2156         nvlist_t **child;
2157         boolean_t printed = B_FALSE;
2158 
2159         assert(zhp != NULL || !cb->cb_verbose);
2160 
2161         if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN, &child,
2162             &children) != 0)
2163                 return;
2164 
2165         for (c = 0; c < children; c++) {
2166                 uint64_t is_log = B_FALSE;
2167                 char *bias = NULL;
2168                 char *type = NULL;
2169 
2170                 (void) nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_LOG,
2171                     &is_log);
2172 
2173                 if (is_log) {
2174                         bias = VDEV_ALLOC_CLASS_LOGS;
2175                 } else {
2176                         (void) nvlist_lookup_string(child[c],
2177                             ZPOOL_CONFIG_ALLOCATION_BIAS, &bias);
2178                         (void) nvlist_lookup_string(child[c],
2179                             ZPOOL_CONFIG_TYPE, &type);
2180                 }
2181 
2182                 if (bias == NULL || strcmp(bias, class) != 0)
2183                         continue;
2184                 if (!is_log && strcmp(type, VDEV_TYPE_INDIRECT) == 0)
2185                         continue;
2186 
2187                 if (!printed) {
2188                         (void) printf("\t%s\t\n", gettext(class));
2189                         printed = B_TRUE;
2190                 }
2191 
2192                 char *name = zpool_vdev_name(g_zfs, zhp, child[c],
2193                     cb->cb_name_flags | VDEV_NAME_TYPE_ID);
2194                 if (cb->cb_print_status)
2195                         print_status_config(zhp, cb, name, child[c], 2,
2196                             B_FALSE);
2197                 else
2198                         print_import_config(cb, name, child[c], 2);
2199                 free(name);
2200         }
2201 }
2202 
2203 /*
2204  * Display the status for the given pool.
2205  */
2206 static void
2207 show_import(nvlist_t *config)
2208 {
2209         uint64_t pool_state;
2210         vdev_stat_t *vs;
2211         char *name;
2212         uint64_t guid;
2213         uint64_t hostid = 0;
2214         char *msgid;
2215         char *hostname = "unknown";
2216         nvlist_t *nvroot, *nvinfo;
2217         int reason;
2218         zpool_errata_t errata;
2219         const char *health;
2220         uint_t vsc;
2221         char *comment;
2222         status_cbdata_t cb = { 0 };
2223 
2224         verify(nvlist_lookup_string(config, ZPOOL_CONFIG_POOL_NAME,
2225             &name) == 0);
2226         verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_GUID,
2227             &guid) == 0);
2228         verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_STATE,
2229             &pool_state) == 0);
2230         verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
2231             &nvroot) == 0);
2232 
2233         verify(nvlist_lookup_uint64_array(nvroot, ZPOOL_CONFIG_VDEV_STATS,
2234             (uint64_t **)&vs, &vsc) == 0);
2235         health = zpool_state_to_name(vs->vs_state, vs->vs_aux);
2236 
2237         reason = zpool_import_status(config, &msgid, &errata);
2238 
2239         (void) printf(gettext("   pool: %s\n"), name);
2240         (void) printf(gettext("     id: %llu\n"), (u_longlong_t)guid);
2241         (void) printf(gettext("  state: %s"), health);
2242         if (pool_state == POOL_STATE_DESTROYED)
2243                 (void) printf(gettext(" (DESTROYED)"));
2244         (void) printf("\n");
2245 
2246         switch (reason) {
2247         case ZPOOL_STATUS_MISSING_DEV_R:
2248         case ZPOOL_STATUS_MISSING_DEV_NR:
2249         case ZPOOL_STATUS_BAD_GUID_SUM:
2250                 (void) printf(gettext(" status: One or more devices are "
2251                     "missing from the system.\n"));
2252                 break;
2253 
2254         case ZPOOL_STATUS_CORRUPT_LABEL_R:
2255         case ZPOOL_STATUS_CORRUPT_LABEL_NR:
2256                 (void) printf(gettext(" status: One or more devices contains "
2257                     "corrupted data.\n"));
2258                 break;
2259 
2260         case ZPOOL_STATUS_CORRUPT_DATA:
2261                 (void) printf(
2262                     gettext(" status: The pool data is corrupted.\n"));
2263                 break;
2264 
2265         case ZPOOL_STATUS_OFFLINE_DEV:
2266                 (void) printf(gettext(" status: One or more devices "
2267                     "are offlined.\n"));
2268                 break;
2269 
2270         case ZPOOL_STATUS_CORRUPT_POOL:
2271                 (void) printf(gettext(" status: The pool metadata is "
2272                     "corrupted.\n"));
2273                 break;
2274 
2275         case ZPOOL_STATUS_VERSION_OLDER:
2276                 (void) printf(gettext(" status: The pool is formatted using a "
2277                     "legacy on-disk version.\n"));
2278                 break;
2279 
2280         case ZPOOL_STATUS_VERSION_NEWER:
2281                 (void) printf(gettext(" status: The pool is formatted using an "
2282                     "incompatible version.\n"));
2283                 break;
2284 
2285         case ZPOOL_STATUS_FEAT_DISABLED:
2286                 (void) printf(gettext(" status: Some supported features are "
2287                     "not enabled on the pool.\n"));
2288                 break;
2289 
2290         case ZPOOL_STATUS_UNSUP_FEAT_READ:
2291                 (void) printf(gettext("status: The pool uses the following "
2292                     "feature(s) not supported on this system:\n"));
2293                 zpool_print_unsup_feat(config);
2294                 break;
2295 
2296         case ZPOOL_STATUS_UNSUP_FEAT_WRITE:
2297                 (void) printf(gettext("status: The pool can only be accessed "
2298                     "in read-only mode on this system. It\n\tcannot be "
2299                     "accessed in read-write mode because it uses the "
2300                     "following\n\tfeature(s) not supported on this system:\n"));
2301                 zpool_print_unsup_feat(config);
2302                 break;
2303 
2304         case ZPOOL_STATUS_HOSTID_ACTIVE:
2305                 (void) printf(gettext(" status: The pool is currently "
2306                     "imported by another system.\n"));
2307                 break;
2308 
2309         case ZPOOL_STATUS_HOSTID_REQUIRED:
2310                 (void) printf(gettext(" status: The pool has the "
2311                     "multihost property on.  It cannot\n\tbe safely imported "
2312                     "when the system hostid is not set.\n"));
2313                 break;
2314 
2315         case ZPOOL_STATUS_HOSTID_MISMATCH:
2316                 (void) printf(gettext(" status: The pool was last accessed by "
2317                     "another system.\n"));
2318                 break;
2319 
2320         case ZPOOL_STATUS_FAULTED_DEV_R:
2321         case ZPOOL_STATUS_FAULTED_DEV_NR:
2322                 (void) printf(gettext(" status: One or more devices are "
2323                     "faulted.\n"));
2324                 break;
2325 
2326         case ZPOOL_STATUS_BAD_LOG:
2327                 (void) printf(gettext(" status: An intent log record cannot be "
2328                     "read.\n"));
2329                 break;
2330 
2331         case ZPOOL_STATUS_RESILVERING:
2332                 (void) printf(gettext(" status: One or more devices were being "
2333                     "resilvered.\n"));
2334                 break;
2335 
2336         case ZPOOL_STATUS_ERRATA:
2337                 (void) printf(gettext(" status: Errata #%d detected.\n"),
2338                     errata);
2339                 break;
2340 
2341         default:
2342                 /*
2343                  * No other status can be seen when importing pools.
2344                  */
2345                 assert(reason == ZPOOL_STATUS_OK);
2346         }
2347 
2348         /*
2349          * Print out an action according to the overall state of the pool.
2350          */
2351         if (vs->vs_state == VDEV_STATE_HEALTHY) {
2352                 if (reason == ZPOOL_STATUS_VERSION_OLDER ||
2353                     reason == ZPOOL_STATUS_FEAT_DISABLED) {
2354                         (void) printf(gettext(" action: The pool can be "
2355                             "imported using its name or numeric identifier, "
2356                             "though\n\tsome features will not be available "
2357                             "without an explicit 'zpool upgrade'.\n"));
2358                 } else if (reason == ZPOOL_STATUS_HOSTID_MISMATCH) {
2359                         (void) printf(gettext(" action: The pool can be "
2360                             "imported using its name or numeric "
2361                             "identifier and\n\tthe '-f' flag.\n"));
2362                 } else if (reason == ZPOOL_STATUS_ERRATA) {
2363                         switch (errata) {
2364                         case ZPOOL_ERRATA_NONE:
2365                                 break;
2366 
2367                         case ZPOOL_ERRATA_ZOL_2094_SCRUB:
2368                                 (void) printf(gettext(" action: The pool can "
2369                                     "be imported using its name or numeric "
2370                                     "identifier,\n\thowever there is a compat"
2371                                     "ibility issue which should be corrected"
2372                                     "\n\tby running 'zpool scrub'\n"));
2373                                 break;
2374 
2375                         case ZPOOL_ERRATA_ZOL_2094_ASYNC_DESTROY:
2376                                 (void) printf(gettext(" action: The pool can"
2377                                     "not be imported with this version of ZFS "
2378                                     "due to\n\tan active asynchronous destroy. "
2379                                     "Revert to an earlier version\n\tand "
2380                                     "allow the destroy to complete before "
2381                                     "updating.\n"));
2382                                 break;
2383 
2384                         case ZPOOL_ERRATA_ZOL_6845_ENCRYPTION:
2385                                 (void) printf(gettext(" action: Existing "
2386                                     "encrypted datasets contain an on-disk "
2387                                     "incompatibility, which\n\tneeds to be "
2388                                     "corrected. Backup these datasets to new "
2389                                     "encrypted datasets\n\tand destroy the "
2390                                     "old ones.\n"));
2391                                 break;
2392                         case ZPOOL_ERRATA_ZOL_8308_ENCRYPTION:
2393                                 (void) printf(gettext(" action: Any existing "
2394                                     "encrypted datasets contain an on-disk "
2395                                     "incompatibility which\n\tmay cause "
2396                                     "on-disk corruption with 'zfs recv' and "
2397                                     "which needs to be\n\tcorrected. Enable "
2398                                     "the bookmark_v2 feature and backup "
2399                                     "these datasets to new encrypted "
2400                                     "datasets and\n\tdestroy the old ones. "
2401                                     "If this pool does not contain any "
2402                                     "encrypted datasets, simply enable\n\t"
2403                                     "the bookmark_v2 feature.\n"));
2404                                 break;
2405                         default:
2406                                 /*
2407                                  * All errata must contain an action message.
2408                                  */
2409                                 assert(0);
2410                         }
2411                 } else {
2412                         (void) printf(gettext(" action: The pool can be "
2413                             "imported using its name or numeric "
2414                             "identifier.\n"));
2415                 }
2416         } else if (vs->vs_state == VDEV_STATE_DEGRADED) {
2417                 (void) printf(gettext(" action: The pool can be imported "
2418                     "despite missing or damaged devices.  The\n\tfault "
2419                     "tolerance of the pool may be compromised if imported.\n"));
2420         } else {
2421                 switch (reason) {
2422                 case ZPOOL_STATUS_VERSION_NEWER:
2423                         (void) printf(gettext(" action: The pool cannot be "
2424                             "imported.  Access the pool on a system running "
2425                             "newer\n\tsoftware, or recreate the pool from "
2426                             "backup.\n"));
2427                         break;
2428                 case ZPOOL_STATUS_UNSUP_FEAT_READ:
2429                         (void) printf(gettext("action: The pool cannot be "
2430                             "imported. Access the pool on a system that "
2431                             "supports\n\tthe required feature(s), or recreate "
2432                             "the pool from backup.\n"));
2433                         break;
2434                 case ZPOOL_STATUS_UNSUP_FEAT_WRITE:
2435                         (void) printf(gettext("action: The pool cannot be "
2436                             "imported in read-write mode. Import the pool "
2437                             "with\n"
2438                             "\t\"-o readonly=on\", access the pool on a system "
2439                             "that supports the\n\trequired feature(s), or "
2440                             "recreate the pool from backup.\n"));
2441                         break;
2442                 case ZPOOL_STATUS_MISSING_DEV_R:
2443                 case ZPOOL_STATUS_MISSING_DEV_NR:
2444                 case ZPOOL_STATUS_BAD_GUID_SUM:
2445                         (void) printf(gettext(" action: The pool cannot be "
2446                             "imported. Attach the missing\n\tdevices and try "
2447                             "again.\n"));
2448                         break;
2449                 case ZPOOL_STATUS_HOSTID_ACTIVE:
2450                         VERIFY0(nvlist_lookup_nvlist(config,
2451                             ZPOOL_CONFIG_LOAD_INFO, &nvinfo));
2452 
2453                         if (nvlist_exists(nvinfo, ZPOOL_CONFIG_MMP_HOSTNAME))
2454                                 hostname = fnvlist_lookup_string(nvinfo,
2455                                     ZPOOL_CONFIG_MMP_HOSTNAME);
2456 
2457                         if (nvlist_exists(nvinfo, ZPOOL_CONFIG_MMP_HOSTID))
2458                                 hostid = fnvlist_lookup_uint64(nvinfo,
2459                                     ZPOOL_CONFIG_MMP_HOSTID);
2460 
2461                         (void) printf(gettext(" action: The pool must be "
2462                             "exported from %s (hostid=%lx)\n\tbefore it "
2463                             "can be safely imported.\n"), hostname,
2464                             (unsigned long) hostid);
2465                         break;
2466                 case ZPOOL_STATUS_HOSTID_REQUIRED:
2467                         (void) printf(gettext(" action: Check the SMF "
2468                             "svc:/system/hostid service.\n"));
2469                         break;
2470                 default:
2471                         (void) printf(gettext(" action: The pool cannot be "
2472                             "imported due to damaged devices or data.\n"));
2473                 }
2474         }
2475 
2476         /* Print the comment attached to the pool. */
2477         if (nvlist_lookup_string(config, ZPOOL_CONFIG_COMMENT, &comment) == 0)
2478                 (void) printf(gettext("comment: %s\n"), comment);
2479 
2480         /*
2481          * If the state is "closed" or "can't open", and the aux state
2482          * is "corrupt data":
2483          */
2484         if (((vs->vs_state == VDEV_STATE_CLOSED) ||
2485             (vs->vs_state == VDEV_STATE_CANT_OPEN)) &&
2486             (vs->vs_aux == VDEV_AUX_CORRUPT_DATA)) {
2487                 if (pool_state == POOL_STATE_DESTROYED)
2488                         (void) printf(gettext("\tThe pool was destroyed, "
2489                             "but can be imported using the '-Df' flags.\n"));
2490                 else if (pool_state != POOL_STATE_EXPORTED)
2491                         (void) printf(gettext("\tThe pool may be active on "
2492                             "another system, but can be imported using\n\t"
2493                             "the '-f' flag.\n"));
2494         }
2495 
2496         if (msgid != NULL)
2497                 (void) printf(gettext("   see: http://illumos.org/msg/%s\n"),
2498                     msgid);
2499 
2500         (void) printf(gettext(" config:\n\n"));
2501 
2502         cb.cb_namewidth = max_width(NULL, nvroot, 0, strlen(name),
2503             VDEV_NAME_TYPE_ID);
2504         if (cb.cb_namewidth < 10)
2505                 cb.cb_namewidth = 10;
2506 
2507         print_import_config(&cb, name, nvroot, 0);
2508 
2509         print_class_vdevs(NULL, &cb, nvroot, VDEV_ALLOC_BIAS_DEDUP);
2510         print_class_vdevs(NULL, &cb, nvroot, VDEV_ALLOC_BIAS_SPECIAL);
2511         print_class_vdevs(NULL, &cb, nvroot, VDEV_ALLOC_CLASS_LOGS);
2512 
2513         if (reason == ZPOOL_STATUS_BAD_GUID_SUM) {
2514                 (void) printf(gettext("\n\tAdditional devices are known to "
2515                     "be part of this pool, though their\n\texact "
2516                     "configuration cannot be determined.\n"));
2517         }
2518 }
2519 
2520 static boolean_t
2521 zfs_force_import_required(nvlist_t *config)
2522 {
2523         uint64_t state;
2524         uint64_t hostid = 0;
2525         nvlist_t *nvinfo;
2526 
2527         state = fnvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_STATE);
2528         (void) nvlist_lookup_uint64(config, ZPOOL_CONFIG_HOSTID, &hostid);
2529 
2530         if (state != POOL_STATE_EXPORTED && hostid != get_system_hostid())
2531                 return (B_TRUE);
2532 
2533         nvinfo = fnvlist_lookup_nvlist(config, ZPOOL_CONFIG_LOAD_INFO);
2534         if (nvlist_exists(nvinfo, ZPOOL_CONFIG_MMP_STATE)) {
2535                 mmp_state_t mmp_state = fnvlist_lookup_uint64(nvinfo,
2536                     ZPOOL_CONFIG_MMP_STATE);
2537 
2538                 if (mmp_state != MMP_STATE_INACTIVE)
2539                         return (B_TRUE);
2540         }
2541 
2542         return (B_FALSE);
2543 }
2544 
2545 /*
2546  * Perform the import for the given configuration.  This passes the heavy
2547  * lifting off to zpool_import_props(), and then mounts the datasets contained
2548  * within the pool.
2549  */
2550 static int
2551 do_import(nvlist_t *config, const char *newname, const char *mntopts,
2552     nvlist_t *props, int flags)
2553 {
2554         int ret = 0;
2555         zpool_handle_t *zhp;
2556         char *name;
2557         uint64_t version;
2558 
2559         name = fnvlist_lookup_string(config, ZPOOL_CONFIG_POOL_NAME);
2560         version = fnvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION);
2561 
2562         if (!SPA_VERSION_IS_SUPPORTED(version)) {
2563                 (void) fprintf(stderr, gettext("cannot import '%s': pool "
2564                     "is formatted using an unsupported ZFS version\n"), name);
2565                 return (1);
2566         } else if (zfs_force_import_required(config) &&
2567             !(flags & ZFS_IMPORT_ANY_HOST)) {
2568                 mmp_state_t mmp_state = MMP_STATE_INACTIVE;
2569                 nvlist_t *nvinfo;
2570 
2571                 nvinfo = fnvlist_lookup_nvlist(config, ZPOOL_CONFIG_LOAD_INFO);
2572                 if (nvlist_exists(nvinfo, ZPOOL_CONFIG_MMP_STATE))
2573                         mmp_state = fnvlist_lookup_uint64(nvinfo,
2574                             ZPOOL_CONFIG_MMP_STATE);
2575 
2576                 if (mmp_state == MMP_STATE_ACTIVE) {
2577                         char *hostname = "<unknown>";
2578                         uint64_t hostid = 0;
2579 
2580                         if (nvlist_exists(nvinfo, ZPOOL_CONFIG_MMP_HOSTNAME))
2581                                 hostname = fnvlist_lookup_string(nvinfo,
2582                                     ZPOOL_CONFIG_MMP_HOSTNAME);
2583 
2584                         if (nvlist_exists(nvinfo, ZPOOL_CONFIG_MMP_HOSTID))
2585                                 hostid = fnvlist_lookup_uint64(nvinfo,
2586                                     ZPOOL_CONFIG_MMP_HOSTID);
2587 
2588                         (void) fprintf(stderr, gettext("cannot import '%s': "
2589                             "pool is imported on %s (hostid: "
2590                             "0x%lx)\nExport the pool on the other system, "
2591                             "then run 'zpool import'.\n"),
2592                             name, hostname, (unsigned long) hostid);
2593                 } else if (mmp_state == MMP_STATE_NO_HOSTID) {
2594                         (void) fprintf(stderr, gettext("Cannot import '%s': "
2595                             "pool has the multihost property on and the\n"
2596                             "system's hostid is not set.\n"), name);
2597                 } else {
2598                         char *hostname = "<unknown>";
2599                         uint64_t timestamp = 0;
2600                         uint64_t hostid = 0;
2601 
2602                         if (nvlist_exists(config, ZPOOL_CONFIG_HOSTNAME))
2603                                 hostname = fnvlist_lookup_string(config,
2604                                     ZPOOL_CONFIG_HOSTNAME);
2605 
2606                         if (nvlist_exists(config, ZPOOL_CONFIG_TIMESTAMP))
2607                                 timestamp = fnvlist_lookup_uint64(config,
2608                                     ZPOOL_CONFIG_TIMESTAMP);
2609 
2610                         if (nvlist_exists(config, ZPOOL_CONFIG_HOSTID))
2611                                 hostid = fnvlist_lookup_uint64(config,
2612                                     ZPOOL_CONFIG_HOSTID);
2613 
2614                         (void) fprintf(stderr, gettext("cannot import '%s': "
2615                             "pool was previously in use from another system.\n"
2616                             "Last accessed by %s (hostid=%lx) at %s"
2617                             "The pool can be imported, use 'zpool import -f' "
2618                             "to import the pool.\n"), name, hostname,
2619                             (unsigned long)hostid, ctime((time_t *)&timestamp));
2620 
2621                 }
2622 
2623                 return (1);
2624         }
2625 
2626         if (zpool_import_props(g_zfs, config, newname, props, flags) != 0)
2627                 return (1);
2628 
2629         if (newname != NULL)
2630                 name = (char *)newname;
2631 
2632         if ((zhp = zpool_open_canfail(g_zfs, name)) == NULL)
2633                 return (1);
2634 
2635         /*
2636          * Loading keys is best effort. We don't want to return immediately
2637          * if it fails but we do want to give the error to the caller.
2638          */
2639         if (flags & ZFS_IMPORT_LOAD_KEYS) {
2640                 ret = zfs_crypto_attempt_load_keys(g_zfs, name);
2641                 if (ret != 0)
2642                         ret = 1;
2643         }
2644 
2645         if (zpool_get_state(zhp) != POOL_STATE_UNAVAIL &&
2646             !(flags & ZFS_IMPORT_ONLY) &&
2647             zpool_enable_datasets(zhp, mntopts, 0) != 0) {
2648                 zpool_close(zhp);
2649                 return (1);
2650         }
2651 
2652         zpool_close(zhp);
2653         return (ret);
2654 }
2655 
2656 typedef struct target_exists_args {
2657         const char      *poolname;
2658         uint64_t        poolguid;
2659 } target_exists_args_t;
2660 
2661 static int
2662 name_or_guid_exists(zpool_handle_t *zhp, void *data)
2663 {
2664         target_exists_args_t *args = data;
2665         nvlist_t *config = zpool_get_config(zhp, NULL);
2666         int found = 0;
2667 
2668         if (config == NULL)
2669                 return (0);
2670 
2671         if (args->poolname != NULL) {
2672                 char *pool_name;
2673 
2674                 verify(nvlist_lookup_string(config, ZPOOL_CONFIG_POOL_NAME,
2675                     &pool_name) == 0);
2676                 if (strcmp(pool_name, args->poolname) == 0)
2677                         found = 1;
2678         } else {
2679                 uint64_t pool_guid;
2680 
2681                 verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_GUID,
2682                     &pool_guid) == 0);
2683                 if (pool_guid == args->poolguid)
2684                         found = 1;
2685         }
2686         zpool_close(zhp);
2687 
2688         return (found);
2689 }
2690 /*
2691  * zpool checkpoint <pool>
2692  *       checkpoint --discard <pool>
2693  *
2694  *      -d      Discard the checkpoint from a checkpointed
2695  *      --discard  pool.
2696  *
2697  * Checkpoints the specified pool, by taking a "snapshot" of its
2698  * current state. A pool can only have one checkpoint at a time.
2699  */
2700 int
2701 zpool_do_checkpoint(int argc, char **argv)
2702 {
2703         boolean_t discard;
2704         char *pool;
2705         zpool_handle_t *zhp;
2706         int c, err;
2707 
2708         struct option long_options[] = {
2709                 {"discard", no_argument, NULL, 'd'},
2710                 {0, 0, 0, 0}
2711         };
2712 
2713         discard = B_FALSE;
2714         while ((c = getopt_long(argc, argv, ":d", long_options, NULL)) != -1) {
2715                 switch (c) {
2716                 case 'd':
2717                         discard = B_TRUE;
2718                         break;
2719                 case '?':
2720                         (void) fprintf(stderr, gettext("invalid option '%c'\n"),
2721                             optopt);
2722                         usage(B_FALSE);
2723                 }
2724         }
2725 
2726         argc -= optind;
2727         argv += optind;
2728 
2729         if (argc < 1) {
2730                 (void) fprintf(stderr, gettext("missing pool argument\n"));
2731                 usage(B_FALSE);
2732         }
2733 
2734         if (argc > 1) {
2735                 (void) fprintf(stderr, gettext("too many arguments\n"));
2736                 usage(B_FALSE);
2737         }
2738 
2739         pool = argv[0];
2740 
2741         if ((zhp = zpool_open(g_zfs, pool)) == NULL) {
2742                 /* As a special case, check for use of '/' in the name */
2743                 if (strchr(pool, '/') != NULL)
2744                         (void) fprintf(stderr, gettext("'zpool checkpoint' "
2745                             "doesn't work on datasets. To save the state "
2746                             "of a dataset from a specific point in time "
2747                             "please use 'zfs snapshot'\n"));
2748                 return (1);
2749         }
2750 
2751         if (discard)
2752                 err = (zpool_discard_checkpoint(zhp) != 0);
2753         else
2754                 err = (zpool_checkpoint(zhp) != 0);
2755 
2756         zpool_close(zhp);
2757 
2758         return (err);
2759 }
2760 
2761 #define CHECKPOINT_OPT  1024
2762 
2763 /*
2764  * zpool import [-d dir] [-D]
2765  *       import [-o mntopts] [-o prop=value] ... [-R root] [-D] [-l]
2766  *              [-d dir | -c cachefile] [-f] -a
2767  *       import [-o mntopts] [-o prop=value] ... [-R root] [-D] [-l]
2768  *              [-d dir | -c cachefile] [-f] [-n] [-F] [-t]
2769  *              <pool | id> [newpool]
2770  *
2771  *      -c      Read pool information from a cachefile instead of searching
2772  *              devices.
2773  *
2774  *      -d      Scan in a specific directory, other than /dev/dsk.  More than
2775  *              one directory can be specified using multiple '-d' options.
2776  *
2777  *      -D      Scan for previously destroyed pools or import all or only
2778  *              specified destroyed pools.
2779  *
2780  *      -R      Temporarily import the pool, with all mountpoints relative to
2781  *              the given root.  The pool will remain exported when the machine
2782  *              is rebooted.
2783  *
2784  *      -V      Import even in the presence of faulted vdevs.  This is an
2785  *              intentionally undocumented option for testing purposes, and
2786  *              treats the pool configuration as complete, leaving any bad
2787  *              vdevs in the FAULTED state. In other words, it does verbatim
2788  *              import.
2789  *
2790  *      -f      Force import, even if it appears that the pool is active.
2791  *
2792  *      -F      Attempt rewind if necessary.
2793  *
2794  *      -n      See if rewind would work, but don't actually rewind.
2795  *
2796  *      -N      Import the pool but don't mount datasets.
2797  *
2798  *      -t      Use newpool as a temporary pool name instead of renaming
2799  *              the pool.
2800  *
2801  *      -T      Specify a starting txg to use for import. This option is
2802  *              intentionally undocumented option for testing purposes.
2803  *
2804  *      -a      Import all pools found.
2805  *
2806  *      -o      Set property=value and/or temporary mount options (without '=').
2807  *  -l  Load encryption keys while importing.
2808  *
2809  *      --rewind-to-checkpoint
2810  *              Import the pool and revert back to the checkpoint.
2811  *
2812  * The import command scans for pools to import, and import pools based on pool
2813  * name and GUID.  The pool can also be renamed as part of the import process.
2814  */
2815 int
2816 zpool_do_import(int argc, char **argv)
2817 {
2818         char **searchdirs = NULL;
2819         int nsearch = 0;
2820         int c;
2821         int err = 0;
2822         nvlist_t *pools = NULL;
2823         boolean_t do_all = B_FALSE;
2824         boolean_t do_destroyed = B_FALSE;
2825         char *mntopts = NULL;
2826         nvpair_t *elem;
2827         nvlist_t *config;
2828         uint64_t searchguid = 0;
2829         char *searchname = NULL;
2830         char *propval;
2831         nvlist_t *found_config;
2832         nvlist_t *policy = NULL;
2833         nvlist_t *props = NULL;
2834         boolean_t first;
2835         int flags = ZFS_IMPORT_NORMAL;
2836         uint32_t rewind_policy = ZPOOL_NO_REWIND;
2837         boolean_t dryrun = B_FALSE;
2838         boolean_t do_rewind = B_FALSE;
2839         boolean_t xtreme_rewind = B_FALSE;
2840         boolean_t pool_exists = B_FALSE;
2841         uint64_t pool_state, txg = -1ULL;
2842         char *cachefile = NULL;
2843         importargs_t idata = { 0 };
2844         char *endptr;
2845 
2846 
2847         struct option long_options[] = {
2848                 {"rewind-to-checkpoint", no_argument, NULL, CHECKPOINT_OPT},
2849                 {0, 0, 0, 0}
2850         };
2851 
2852         /* check options */
2853         while ((c = getopt_long(argc, argv, ":aCc:d:DEfFlmnNo:rR:tT:VX",
2854             long_options, NULL)) != -1) {
2855                 switch (c) {
2856                 case 'a':
2857                         do_all = B_TRUE;
2858                         break;
2859                 case 'c':
2860                         cachefile = optarg;
2861                         break;
2862                 case 'd':
2863                         if (searchdirs == NULL) {
2864                                 searchdirs = safe_malloc(sizeof (char *));
2865                         } else {
2866                                 char **tmp = safe_malloc((nsearch + 1) *
2867                                     sizeof (char *));
2868                                 bcopy(searchdirs, tmp, nsearch *
2869                                     sizeof (char *));
2870                                 free(searchdirs);
2871                                 searchdirs = tmp;
2872                         }
2873                         searchdirs[nsearch++] = optarg;
2874                         break;
2875                 case 'D':
2876                         do_destroyed = B_TRUE;
2877                         break;
2878                 case 'f':
2879                         flags |= ZFS_IMPORT_ANY_HOST;
2880                         break;
2881                 case 'F':
2882                         do_rewind = B_TRUE;
2883                         break;
2884                 case 'l':
2885                         flags |= ZFS_IMPORT_LOAD_KEYS;
2886                         break;
2887                 case 'm':
2888                         flags |= ZFS_IMPORT_MISSING_LOG;
2889                         break;
2890                 case 'n':
2891                         dryrun = B_TRUE;
2892                         break;
2893                 case 'N':
2894                         flags |= ZFS_IMPORT_ONLY;
2895                         break;
2896                 case 'o':
2897                         if ((propval = strchr(optarg, '=')) != NULL) {
2898                                 *propval = '\0';
2899                                 propval++;
2900                                 if (add_prop_list(optarg, propval,
2901                                     &props, B_TRUE))
2902                                         goto error;
2903                         } else {
2904                                 mntopts = optarg;
2905                         }
2906                         break;
2907                 case 'R':
2908                         if (add_prop_list(zpool_prop_to_name(
2909                             ZPOOL_PROP_ALTROOT), optarg, &props, B_TRUE))
2910                                 goto error;
2911                         if (add_prop_list_default(zpool_prop_to_name(
2912                             ZPOOL_PROP_CACHEFILE), "none", &props, B_TRUE))
2913                                 goto error;
2914                         break;
2915                 case 't':
2916                         flags |= ZFS_IMPORT_TEMP_NAME;
2917                         if (add_prop_list_default(zpool_prop_to_name(
2918                             ZPOOL_PROP_CACHEFILE), "none", &props, B_TRUE))
2919                                 goto error;
2920                         break;
2921                 case 'T':
2922                         errno = 0;
2923                         txg = strtoull(optarg, &endptr, 0);
2924                         if (errno != 0 || *endptr != '\0') {
2925                                 (void) fprintf(stderr,
2926                                     gettext("invalid txg value\n"));
2927                                 usage(B_FALSE);
2928                         }
2929                         rewind_policy = ZPOOL_DO_REWIND | ZPOOL_EXTREME_REWIND;
2930                         break;
2931                 case 'V':
2932                         flags |= ZFS_IMPORT_VERBATIM;
2933                         break;
2934                 case 'X':
2935                         xtreme_rewind = B_TRUE;
2936                         break;
2937                 case CHECKPOINT_OPT:
2938                         flags |= ZFS_IMPORT_CHECKPOINT;
2939                         break;
2940                 case ':':
2941                         (void) fprintf(stderr, gettext("missing argument for "
2942                             "'%c' option\n"), optopt);
2943                         usage(B_FALSE);
2944                         break;
2945                 case '?':
2946                         (void) fprintf(stderr, gettext("invalid option '%c'\n"),
2947                             optopt);
2948                         usage(B_FALSE);
2949                 }
2950         }
2951 
2952         argc -= optind;
2953         argv += optind;
2954 
2955         if (cachefile && nsearch != 0) {
2956                 (void) fprintf(stderr, gettext("-c is incompatible with -d\n"));
2957                 usage(B_FALSE);
2958         }
2959 
2960         if ((flags & ZFS_IMPORT_LOAD_KEYS) && (flags & ZFS_IMPORT_ONLY)) {
2961                 (void) fprintf(stderr, gettext("-l is incompatible with -N\n"));
2962                 usage(B_FALSE);
2963         }
2964 
2965         if ((flags & ZFS_IMPORT_LOAD_KEYS) && !do_all && argc == 0) {
2966                 (void) fprintf(stderr, gettext("-l is only meaningful during "
2967                     "an import\n"));
2968                 usage(B_FALSE);
2969         }
2970 
2971         if ((dryrun || xtreme_rewind) && !do_rewind) {
2972                 (void) fprintf(stderr,
2973                     gettext("-n or -X only meaningful with -F\n"));
2974                 usage(B_FALSE);
2975         }
2976         if (dryrun)
2977                 rewind_policy = ZPOOL_TRY_REWIND;
2978         else if (do_rewind)
2979                 rewind_policy = ZPOOL_DO_REWIND;
2980         if (xtreme_rewind)
2981                 rewind_policy |= ZPOOL_EXTREME_REWIND;
2982 
2983         /* In the future, we can capture further policy and include it here */
2984         if (nvlist_alloc(&policy, NV_UNIQUE_NAME, 0) != 0 ||
2985             nvlist_add_uint64(policy, ZPOOL_LOAD_REQUEST_TXG, txg) != 0 ||
2986             nvlist_add_uint32(policy, ZPOOL_LOAD_REWIND_POLICY,
2987             rewind_policy) != 0)
2988                 goto error;
2989 
2990         if (searchdirs == NULL) {
2991                 searchdirs = safe_malloc(sizeof (char *));
2992                 searchdirs[0] = ZFS_DISK_ROOT;
2993                 nsearch = 1;
2994         }
2995 
2996         /* check argument count */
2997         if (do_all) {
2998                 if (argc != 0) {
2999                         (void) fprintf(stderr, gettext("too many arguments\n"));
3000                         usage(B_FALSE);
3001                 }
3002         } else {
3003                 if (argc > 2) {
3004                         (void) fprintf(stderr, gettext("too many arguments\n"));
3005                         usage(B_FALSE);
3006                 }
3007 
3008                 /*
3009                  * Check for the SYS_CONFIG privilege.  We do this explicitly
3010                  * here because otherwise any attempt to discover pools will
3011                  * silently fail.
3012                  */
3013                 if (argc == 0 && !priv_ineffect(PRIV_SYS_CONFIG)) {
3014                         (void) fprintf(stderr, gettext("cannot "
3015                             "discover pools: permission denied\n"));
3016                         free(searchdirs);
3017                         nvlist_free(policy);
3018                         return (1);
3019                 }
3020         }
3021 
3022         /*
3023          * Depending on the arguments given, we do one of the following:
3024          *
3025          *      <none>    Iterate through all pools and display information about
3026          *              each one.
3027          *
3028          *      -a      Iterate through all pools and try to import each one.
3029          *
3030          *      <id>      Find the pool that corresponds to the given GUID/pool
3031          *              name and import that one.
3032          *
3033          *      -D      Above options applies only to destroyed pools.
3034          */
3035         if (argc != 0) {
3036                 char *endptr;
3037 
3038                 errno = 0;
3039                 searchguid = strtoull(argv[0], &endptr, 10);
3040                 if (errno != 0 || *endptr != '\0') {
3041                         searchname = argv[0];
3042                         searchguid = 0;
3043                 }
3044                 found_config = NULL;
3045 
3046                 /*
3047                  * User specified a name or guid.  Ensure it's unique.
3048                  */
3049                 target_exists_args_t search = {searchname, searchguid};
3050                 pool_exists = zpool_iter(g_zfs, name_or_guid_exists, &search);
3051         }
3052 
3053         idata.path = searchdirs;
3054         idata.paths = nsearch;
3055         idata.poolname = searchname;
3056         idata.guid = searchguid;
3057         idata.cachefile = cachefile;
3058         idata.policy = policy;
3059 
3060         pools = zpool_search_import(g_zfs, &idata, &libzfs_config_ops);
3061 
3062         if (pools != NULL && pool_exists &&
3063             (argc == 1 || strcmp(argv[0], argv[1]) == 0)) {
3064                 (void) fprintf(stderr, gettext("cannot import '%s': "
3065                     "a pool with that name already exists\n"),
3066                     argv[0]);
3067                 (void) fprintf(stderr, gettext("use the form 'zpool import "
3068                     "[-t] <pool | id> <newpool>' to give it a new temporary "
3069                     "or permanent name\n"));
3070                 err = 1;
3071         } else if (pools == NULL && pool_exists) {
3072                 (void) fprintf(stderr, gettext("cannot import '%s': "
3073                     "a pool with that name is already created/imported,\n"),
3074                     argv[0]);
3075                 (void) fprintf(stderr, gettext("and no additional pools "
3076                     "with that name were found\n"));
3077                 err = 1;
3078         } else if (pools == NULL) {
3079                 if (argc != 0) {
3080                         (void) fprintf(stderr, gettext("cannot import '%s': "
3081                             "no such pool available\n"), argv[0]);
3082                 }
3083                 err = 1;
3084         }
3085 
3086         if (err == 1) {
3087                 free(searchdirs);
3088                 nvlist_free(policy);
3089                 return (1);
3090         }
3091 
3092         /*
3093          * At this point we have a list of import candidate configs. Even if
3094          * we were searching by pool name or guid, we still need to
3095          * post-process the list to deal with pool state and possible
3096          * duplicate names.
3097          */
3098         err = 0;
3099         elem = NULL;
3100         first = B_TRUE;
3101         while ((elem = nvlist_next_nvpair(pools, elem)) != NULL) {
3102 
3103                 verify(nvpair_value_nvlist(elem, &config) == 0);
3104 
3105                 verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_STATE,
3106                     &pool_state) == 0);
3107                 if (!do_destroyed && pool_state == POOL_STATE_DESTROYED)
3108                         continue;
3109                 if (do_destroyed && pool_state != POOL_STATE_DESTROYED)
3110                         continue;
3111 
3112                 verify(nvlist_add_nvlist(config, ZPOOL_LOAD_POLICY,
3113                     policy) == 0);
3114 
3115                 if (argc == 0) {
3116                         if (first)
3117                                 first = B_FALSE;
3118                         else if (!do_all)
3119                                 (void) printf("\n");
3120 
3121                         if (do_all) {
3122                                 err |= do_import(config, NULL, mntopts,
3123                                     props, flags);
3124                         } else {
3125                                 show_import(config);
3126                         }
3127                 } else if (searchname != NULL) {
3128                         char *name;
3129 
3130                         /*
3131                          * We are searching for a pool based on name.
3132                          */
3133                         verify(nvlist_lookup_string(config,
3134                             ZPOOL_CONFIG_POOL_NAME, &name) == 0);
3135 
3136                         if (strcmp(name, searchname) == 0) {
3137                                 if (found_config != NULL) {
3138                                         (void) fprintf(stderr, gettext(
3139                                             "cannot import '%s': more than "
3140                                             "one matching pool\n"), searchname);
3141                                         (void) fprintf(stderr, gettext(
3142                                             "import by numeric ID instead\n"));
3143                                         err = B_TRUE;
3144                                 }
3145                                 found_config = config;
3146                         }
3147                 } else {
3148                         uint64_t guid;
3149 
3150                         /*
3151                          * Search for a pool by guid.
3152                          */
3153                         verify(nvlist_lookup_uint64(config,
3154                             ZPOOL_CONFIG_POOL_GUID, &guid) == 0);
3155 
3156                         if (guid == searchguid)
3157                                 found_config = config;
3158                 }
3159         }
3160 
3161         /*
3162          * If we were searching for a specific pool, verify that we found a
3163          * pool, and then do the import.
3164          */
3165         if (argc != 0 && err == 0) {
3166                 if (found_config == NULL) {
3167                         (void) fprintf(stderr, gettext("cannot import '%s': "
3168                             "no such pool available\n"), argv[0]);
3169                         err = B_TRUE;
3170                 } else {
3171                         err |= do_import(found_config, argc == 1 ? NULL :
3172                             argv[1], mntopts, props, flags);
3173                 }
3174         }
3175 
3176         /*
3177          * If we were just looking for pools, report an error if none were
3178          * found.
3179          */
3180         if (argc == 0 && first)
3181                 (void) fprintf(stderr,
3182                     gettext("no pools available to import\n"));
3183 
3184 error:
3185         nvlist_free(props);
3186         nvlist_free(pools);
3187         nvlist_free(policy);
3188         free(searchdirs);
3189 
3190         return (err ? 1 : 0);
3191 }
3192 
3193 /*
3194  * zpool sync [-f] [pool] ...
3195  *
3196  * -f (undocumented) force uberblock (and config including zpool cache file)
3197  *    update.
3198  *
3199  * Sync the specified pool(s).
3200  * Without arguments "zpool sync" will sync all pools.
3201  * This command initiates TXG sync(s) and will return after the TXG(s) commit.
3202  *
3203  */
3204 static int
3205 zpool_do_sync(int argc, char **argv)
3206 {
3207         int ret;
3208         boolean_t force = B_FALSE;
3209 
3210         /* check options */
3211         while ((ret  = getopt(argc, argv, "f")) != -1) {
3212                 switch (ret) {
3213                 case 'f':
3214                         force = B_TRUE;
3215                         break;
3216                 case '?':
3217                         (void) fprintf(stderr, gettext("invalid option '%c'\n"),
3218                             optopt);
3219                         usage(B_FALSE);
3220                 }
3221         }
3222 
3223         argc -= optind;
3224         argv += optind;
3225 
3226         /* if argc == 0 we will execute zpool_sync_one on all pools */
3227         ret = for_each_pool(argc, argv, B_FALSE, NULL, zpool_sync_one, &force);
3228 
3229         return (ret);
3230 }
3231 
3232 typedef struct iostat_cbdata {
3233         uint64_t cb_flags;
3234         int cb_name_flags;
3235         int cb_namewidth;
3236         int cb_iteration;
3237         char **cb_vdev_names; /* Only show these vdevs */
3238         unsigned int cb_vdev_names_count;
3239         boolean_t cb_verbose;
3240         boolean_t cb_literal;
3241         boolean_t cb_scripted;
3242         zpool_list_t *cb_list;
3243 } iostat_cbdata_t;
3244 
3245 /*  iostat labels */
3246 typedef struct name_and_columns {
3247         const char *name;       /* Column name */
3248         unsigned int columns;   /* Center name to this number of columns */
3249 } name_and_columns_t;
3250 
3251 #define IOSTAT_MAX_LABELS       13      /* Max number of labels on one line */
3252 
3253 static const name_and_columns_t iostat_top_labels[][IOSTAT_MAX_LABELS] =
3254 {
3255         [IOS_DEFAULT] = {{"capacity", 2}, {"operations", 2}, {"bandwidth", 2},
3256             {NULL}},
3257         [IOS_LATENCY] = {{"total_wait", 2}, {"disk_wait", 2}, {"syncq_wait", 2},
3258             {"asyncq_wait", 2}, {"scrub"}, {"trim", 1}, {NULL}},
3259         [IOS_QUEUES] = {{"syncq_read", 2}, {"syncq_write", 2},
3260             {"asyncq_read", 2}, {"asyncq_write", 2}, {"scrubq_read", 2},
3261             {"trimq_write", 2}, {NULL}},
3262         [IOS_L_HISTO] = {{"total_wait", 2}, {"disk_wait", 2}, {"syncq_wait", 2},
3263             {"asyncq_wait", 2}, {NULL}},
3264         [IOS_RQ_HISTO] = {{"sync_read", 2}, {"sync_write", 2},
3265             {"async_read", 2}, {"async_write", 2}, {"scrub", 2},
3266             {"trim", 2}, {NULL}},
3267 
3268 };
3269 
3270 /* Shorthand - if "columns" field not set, default to 1 column */
3271 static const name_and_columns_t iostat_bottom_labels[][IOSTAT_MAX_LABELS] =
3272 {
3273         [IOS_DEFAULT] = {{"alloc"}, {"free"}, {"read"}, {"write"}, {"read"},
3274             {"write"}, {NULL}},
3275         [IOS_LATENCY] = {{"read"}, {"write"}, {"read"}, {"write"}, {"read"},
3276             {"write"}, {"read"}, {"write"}, {"wait"}, {"wait"}, {NULL}},
3277         [IOS_QUEUES] = {{"pend"}, {"activ"}, {"pend"}, {"activ"}, {"pend"},
3278             {"activ"}, {"pend"}, {"activ"}, {"pend"}, {"activ"},
3279             {"pend"}, {"activ"}, {NULL}},
3280         [IOS_L_HISTO] = {{"read"}, {"write"}, {"read"}, {"write"}, {"read"},
3281             {"write"}, {"read"}, {"write"}, {"scrub"}, {"trim"}, {NULL}},
3282         [IOS_RQ_HISTO] = {{"ind"}, {"agg"}, {"ind"}, {"agg"}, {"ind"}, {"agg"},
3283             {"ind"}, {"agg"}, {"ind"}, {"agg"}, {"ind"}, {"agg"}, {NULL}},
3284 };
3285 
3286 static const char *histo_to_title[] = {
3287         [IOS_L_HISTO] = "latency",
3288         [IOS_RQ_HISTO] = "req_size",
3289 };
3290 
3291 /*
3292  * Return the number of labels in a null-terminated name_and_columns_t
3293  * array.
3294  *
3295  */
3296 static unsigned int
3297 label_array_len(const name_and_columns_t *labels)
3298 {
3299         int i = 0;
3300 
3301         while (labels[i].name)
3302                 i++;
3303 
3304         return (i);
3305 }
3306 
3307 /*
3308  * Return the number of strings in a null-terminated string array.
3309  * For example:
3310  *
3311  *     const char foo[] = {"bar", "baz", NULL}
3312  *
3313  * returns 2
3314  */
3315 static uint64_t
3316 str_array_len(const char *array[])
3317 {
3318         uint64_t i = 0;
3319         while (array[i])
3320                 i++;
3321 
3322         return (i);
3323 }
3324 
3325 
3326 /*
3327  * Return a default column width for default/latency/queue columns. This does
3328  * not include histograms, which have their columns autosized.
3329  */
3330 static unsigned int
3331 default_column_width(iostat_cbdata_t *cb, enum iostat_type type)
3332 {
3333         unsigned long column_width = 5; /* Normal niceprint */
3334         static unsigned long widths[] = {
3335                 /*
3336                  * Choose some sane default column sizes for printing the
3337                  * raw numbers.
3338                  */
3339                 [IOS_DEFAULT] = 15, /* 1PB capacity */
3340                 [IOS_LATENCY] = 10, /* 1B ns = 10sec */
3341                 [IOS_QUEUES] = 6,   /* 1M queue entries */
3342                 [IOS_L_HISTO] = 10, /* 1B ns = 10sec */
3343                 [IOS_RQ_HISTO] = 6, /* 1M queue entries */
3344         };
3345 
3346         if (cb->cb_literal)
3347                 column_width = widths[type];
3348 
3349         return (column_width);
3350 }
3351 
3352 /*
3353  * Print the column labels, i.e:
3354  *
3355  *   capacity     operations     bandwidth
3356  * alloc   free   read  write   read  write  ...
3357  *
3358  * If force_column_width is set, use it for the column width.  If not set, use
3359  * the default column width.
3360  */
3361 void
3362 print_iostat_labels(iostat_cbdata_t *cb, unsigned int force_column_width,
3363     const name_and_columns_t labels[][IOSTAT_MAX_LABELS])
3364 {
3365         int i, idx, s;
3366         int text_start, rw_column_width, spaces_to_end;
3367         uint64_t flags = cb->cb_flags;
3368         uint64_t f;
3369         unsigned int column_width = force_column_width;
3370 
3371         /* For each bit set in flags */
3372         for (f = flags; f; f &= ~(1ULL << idx)) {
3373                 idx = lowbit64(f) - 1;
3374                 if (!force_column_width)
3375                         column_width = default_column_width(cb, idx);
3376                 /* Print our top labels centered over "read  write" label. */
3377                 for (i = 0; i < label_array_len(labels[idx]); i++) {
3378                         const char *name = labels[idx][i].name;
3379                         /*
3380                          * We treat labels[][].columns == 0 as shorthand
3381                          * for one column.  It makes writing out the label
3382                          * tables more concise.
3383                          */
3384                         unsigned int columns = MAX(1, labels[idx][i].columns);
3385                         unsigned int slen = strlen(name);
3386 
3387                         rw_column_width = (column_width * columns) +
3388                             (2 * (columns - 1));
3389 
3390                         text_start = (int)((rw_column_width) / columns -
3391                             slen / columns);
3392                         if (text_start < 0)
3393                                 text_start = 0;
3394 
3395                         printf("  ");   /* Two spaces between columns */
3396 
3397                         /* Space from beginning of column to label */
3398                         for (s = 0; s < text_start; s++)
3399                                 printf(" ");
3400 
3401                         printf("%s", name);
3402 
3403                         /* Print space after label to end of column */
3404                         spaces_to_end = rw_column_width - text_start - slen;
3405                         if (spaces_to_end < 0)
3406                                 spaces_to_end = 0;
3407 
3408                         for (s = 0; s < spaces_to_end; s++)
3409                                 printf(" ");
3410                 }
3411         }
3412 }
3413 
3414 /*
3415  * Utility function to print out a line of dashes like:
3416  *
3417  *      --------------------------------  -----  -----  -----  -----  -----
3418  *
3419  * ...or a dashed named-row line like:
3420  *
3421  *      logs                                  -      -      -      -      -
3422  *
3423  * @cb:                         iostat data
3424  *
3425  * @force_column_width          If non-zero, use the value as the column width.
3426  *                              Otherwise use the default column widths.
3427  *
3428  * @name:                       Print a dashed named-row line starting
3429  *                              with @name.  Otherwise, print a regular
3430  *                              dashed line.
3431  */
3432 static void
3433 print_iostat_dashes(iostat_cbdata_t *cb, unsigned int force_column_width,
3434     const char *name)
3435 {
3436         int i;
3437         unsigned int namewidth;
3438         uint64_t flags = cb->cb_flags;
3439         uint64_t f;
3440         int idx;
3441         const name_and_columns_t *labels;
3442         const char *title;
3443 
3444 
3445         if (cb->cb_flags & IOS_ANYHISTO_M) {
3446                 title = histo_to_title[IOS_HISTO_IDX(cb->cb_flags)];
3447         } else if (cb->cb_vdev_names_count) {
3448                 title = "vdev";
3449         } else  {
3450                 title = "pool";
3451         }
3452 
3453         namewidth = MAX(MAX(strlen(title), cb->cb_namewidth),
3454             name ? strlen(name) : 0);
3455 
3456 
3457         if (name) {
3458                 printf("%-*s", namewidth, name);
3459         } else {
3460                 for (i = 0; i < namewidth; i++)
3461                         (void) printf("-");
3462         }
3463 
3464         /* For each bit in flags */
3465         for (f = flags; f; f &= ~(1ULL << idx)) {
3466                 unsigned int column_width;
3467                 idx = lowbit64(f) - 1;
3468                 if (force_column_width)
3469                         column_width = force_column_width;
3470                 else
3471                         column_width = default_column_width(cb, idx);
3472 
3473                 labels = iostat_bottom_labels[idx];
3474                 for (i = 0; i < label_array_len(labels); i++) {
3475                         if (name)
3476                                 printf("  %*s-", column_width - 1, " ");
3477                         else
3478                                 printf("  %.*s", column_width,
3479                                     "--------------------");
3480                 }
3481         }
3482 }
3483 
3484 
3485 static void
3486 print_iostat_separator_impl(iostat_cbdata_t *cb,
3487     unsigned int force_column_width)
3488 {
3489         print_iostat_dashes(cb, force_column_width, NULL);
3490 }
3491 
3492 static void
3493 print_iostat_separator(iostat_cbdata_t *cb)
3494 {
3495         print_iostat_separator_impl(cb, 0);
3496 }
3497 
3498 static void
3499 print_iostat_header_impl(iostat_cbdata_t *cb, unsigned int force_column_width,
3500     const char *histo_vdev_name)
3501 {
3502         unsigned int namewidth;
3503         const char *title;
3504 
3505         if (cb->cb_flags & IOS_ANYHISTO_M) {
3506                 title = histo_to_title[IOS_HISTO_IDX(cb->cb_flags)];
3507         } else if (cb->cb_vdev_names_count) {
3508                 title = "vdev";
3509         } else  {
3510                 title = "pool";
3511         }
3512 
3513         namewidth = MAX(MAX(strlen(title), cb->cb_namewidth),
3514             histo_vdev_name ? strlen(histo_vdev_name) : 0);
3515 
3516         if (histo_vdev_name)
3517                 printf("%-*s", namewidth, histo_vdev_name);
3518         else
3519                 printf("%*s", namewidth, "");
3520 
3521 
3522         print_iostat_labels(cb, force_column_width, iostat_top_labels);
3523         printf("\n");
3524 
3525         printf("%-*s", namewidth, title);
3526 
3527         print_iostat_labels(cb, force_column_width, iostat_bottom_labels);
3528 
3529         printf("\n");
3530 
3531         print_iostat_separator_impl(cb, force_column_width);
3532 
3533         printf("\n");
3534 }
3535 
3536 static void
3537 print_iostat_header(iostat_cbdata_t *cb)
3538 {
3539         print_iostat_header_impl(cb, 0, NULL);
3540 }
3541 
3542 /*
3543  * Display a single statistic.
3544  */
3545 static void
3546 print_one_stat(uint64_t value, enum zfs_nicenum_format format,
3547     unsigned int column_size, boolean_t scripted)
3548 {
3549         char buf[64];
3550 
3551         zfs_nicenum_format(value, buf, sizeof (buf), format);
3552 
3553         if (scripted)
3554                 printf("\t%s", buf);
3555         else
3556                 printf("  %*s", column_size, buf);
3557 }
3558 
3559 /*
3560  * Calculate the default vdev stats
3561  *
3562  * Subtract oldvs from newvs, apply a scaling factor, and save the resulting
3563  * stats into calcvs.
3564  */
3565 static void
3566 calc_default_iostats(vdev_stat_t *oldvs, vdev_stat_t *newvs,
3567     vdev_stat_t *calcvs)
3568 {
3569         int i;
3570 
3571         memcpy(calcvs, newvs, sizeof (*calcvs));
3572         for (i = 0; i < ARRAY_SIZE(calcvs->vs_ops); i++)
3573                 calcvs->vs_ops[i] = (newvs->vs_ops[i] - oldvs->vs_ops[i]);
3574 
3575         for (i = 0; i < ARRAY_SIZE(calcvs->vs_bytes); i++)
3576                 calcvs->vs_bytes[i] = (newvs->vs_bytes[i] - oldvs->vs_bytes[i]);
3577 }
3578 
3579 /*
3580  * Internal representation of the extended iostats data.
3581  *
3582  * The extended iostat stats are exported in nvlists as either uint64_t arrays
3583  * or single uint64_t's.  We make both look like arrays to make them easier
3584  * to process.  In order to make single uint64_t's look like arrays, we set
3585  * __data to the stat data, and then set *data = &__data with count = 1.  Then,
3586  * we can just use *data and count.
3587  */
3588 struct stat_array {
3589         uint64_t *data;
3590         uint_t count;   /* Number of entries in data[] */
3591         uint64_t __data; /* Only used when data is a single uint64_t */
3592 };
3593 
3594 static uint64_t
3595 stat_histo_max(struct stat_array *nva, unsigned int len)
3596 {
3597         uint64_t max = 0;
3598         int i;
3599         for (i = 0; i < len; i++)
3600                 max = MAX(max, array64_max(nva[i].data, nva[i].count));
3601 
3602         return (max);
3603 }
3604 
3605 /*
3606  * Helper function to lookup a uint64_t array or uint64_t value and store its
3607  * data as a stat_array.  If the nvpair is a single uint64_t value, then we make
3608  * it look like a one element array to make it easier to process.
3609  */
3610 static int
3611 nvpair64_to_stat_array(nvlist_t *nvl, const char *name,
3612     struct stat_array *nva)
3613 {
3614         nvpair_t *tmp;
3615         int ret;
3616 
3617         verify(nvlist_lookup_nvpair(nvl, name, &tmp) == 0);
3618         switch (nvpair_type(tmp)) {
3619         case DATA_TYPE_UINT64_ARRAY:
3620                 ret = nvpair_value_uint64_array(tmp, &nva->data, &nva->count);
3621                 break;
3622         case DATA_TYPE_UINT64:
3623                 ret = nvpair_value_uint64(tmp, &nva->__data);
3624                 nva->data = &nva->__data;
3625                 nva->count = 1;
3626                 break;
3627         default:
3628                 /* Not a uint64_t */
3629                 ret = EINVAL;
3630                 break;
3631         }
3632 
3633         return (ret);
3634 }
3635 
3636 /*
3637  * Given a list of nvlist names, look up the extended stats in newnv and oldnv,
3638  * subtract them, and return the results in a newly allocated stat_array.
3639  * You must free the returned array after you are done with it with
3640  * free_calc_stats().
3641  *
3642  * Additionally, you can set "oldnv" to NULL if you simply want the newnv
3643  * values.
3644  */
3645 static struct stat_array *
3646 calc_and_alloc_stats_ex(const char **names, unsigned int len, nvlist_t *oldnv,
3647     nvlist_t *newnv)
3648 {
3649         nvlist_t *oldnvx = NULL, *newnvx;
3650         struct stat_array *oldnva, *newnva, *calcnva;
3651         int i, j;
3652         unsigned int alloc_size = (sizeof (struct stat_array)) * len;
3653 
3654         /* Extract our extended stats nvlist from the main list */
3655         verify(nvlist_lookup_nvlist(newnv, ZPOOL_CONFIG_VDEV_STATS_EX,
3656             &newnvx) == 0);
3657         if (oldnv) {
3658                 verify(nvlist_lookup_nvlist(oldnv, ZPOOL_CONFIG_VDEV_STATS_EX,
3659                     &oldnvx) == 0);
3660         }
3661 
3662         newnva = safe_malloc(alloc_size);
3663         oldnva = safe_malloc(alloc_size);
3664         calcnva = safe_malloc(alloc_size);
3665 
3666         for (j = 0; j < len; j++) {
3667                 verify(nvpair64_to_stat_array(newnvx, names[j],
3668                     &newnva[j]) == 0);
3669                 calcnva[j].count = newnva[j].count;
3670                 alloc_size = calcnva[j].count * sizeof (calcnva[j].data[0]);
3671                 calcnva[j].data = safe_malloc(alloc_size);
3672                 memcpy(calcnva[j].data, newnva[j].data, alloc_size);
3673 
3674                 if (oldnvx) {
3675                         verify(nvpair64_to_stat_array(oldnvx, names[j],
3676                             &oldnva[j]) == 0);
3677                         for (i = 0; i < oldnva[j].count; i++)
3678                                 calcnva[j].data[i] -= oldnva[j].data[i];
3679                 }
3680         }
3681         free(newnva);
3682         free(oldnva);
3683         return (calcnva);
3684 }
3685 
3686 static void
3687 free_calc_stats(struct stat_array *nva, unsigned int len)
3688 {
3689         int i;
3690         for (i = 0; i < len; i++)
3691                 free(nva[i].data);
3692 
3693         free(nva);
3694 }
3695 
3696 static void
3697 print_iostat_histo(struct stat_array *nva, unsigned int len,
3698     iostat_cbdata_t *cb, unsigned int column_width, unsigned int namewidth,
3699     double scale)
3700 {
3701         int i, j;
3702         char buf[6];
3703         uint64_t val;
3704         enum zfs_nicenum_format format;
3705         unsigned int buckets;
3706         unsigned int start_bucket;
3707 
3708         if (cb->cb_literal)
3709                 format = ZFS_NICENUM_RAW;
3710         else
3711                 format = ZFS_NICENUM_1024;
3712 
3713         /* All these histos are the same size, so just use nva[0].count */
3714         buckets = nva[0].count;
3715 
3716         if (cb->cb_flags & IOS_RQ_HISTO_M) {
3717                 /* Start at 512 - req size should never be lower than this */
3718                 start_bucket = 9;
3719         } else {
3720                 start_bucket = 0;
3721         }
3722 
3723         for (j = start_bucket; j < buckets; j++) {
3724                 /* Print histogram bucket label */
3725                 if (cb->cb_flags & IOS_L_HISTO_M) {
3726                         /* Ending range of this bucket */
3727                         val = (1ULL << (j + 1)) - 1;
3728                         zfs_nicetime(val, buf, sizeof (buf));
3729                 } else {
3730                         /* Request size (starting range of bucket) */
3731                         val = (1UL << j);
3732                         zfs_nicenum(val, buf, sizeof (buf));
3733                 }
3734 
3735                 if (cb->cb_scripted)
3736                         printf("%llu", (u_longlong_t)val);
3737                 else
3738                         printf("%-*s", namewidth, buf);
3739 
3740                 /* Print the values on the line */
3741                 for (i = 0; i < len; i++) {
3742                         print_one_stat(nva[i].data[j] * scale, format,
3743                             column_width, cb->cb_scripted);
3744                 }
3745                 printf("\n");
3746         }
3747 }
3748 
3749 static void
3750 print_solid_separator(unsigned int length)
3751 {
3752         while (length--)
3753                 printf("-");
3754         printf("\n");
3755 }
3756 
3757 static void
3758 print_iostat_histos(iostat_cbdata_t *cb, nvlist_t *oldnv,
3759     nvlist_t *newnv, double scale, const char *name)
3760 {
3761         unsigned int column_width;
3762         unsigned int namewidth;
3763         unsigned int entire_width;
3764         enum iostat_type type;
3765         struct stat_array *nva;
3766         const char **names;
3767         unsigned int names_len;
3768 
3769         /* What type of histo are we? */
3770         type = IOS_HISTO_IDX(cb->cb_flags);
3771 
3772         /* Get NULL-terminated array of nvlist names for our histo */
3773         names = vsx_type_to_nvlist[type];
3774         names_len = str_array_len(names); /* num of names */
3775 
3776         nva = calc_and_alloc_stats_ex(names, names_len, oldnv, newnv);
3777 
3778         if (cb->cb_literal) {
3779                 column_width = MAX(5,
3780                     (unsigned int) log10(stat_histo_max(nva, names_len)) + 1);
3781         } else {
3782                 column_width = 5;
3783         }
3784 
3785         namewidth = MAX(cb->cb_namewidth,
3786             strlen(histo_to_title[IOS_HISTO_IDX(cb->cb_flags)]));
3787 
3788         /*
3789          * Calculate the entire line width of what we're printing.  The
3790          * +2 is for the two spaces between columns:
3791          */
3792         /*       read  write                            */
3793         /*      -----  -----                            */
3794         /*      |___|  <---------- column_width              */
3795         /*                                              */
3796         /*      |__________|  <--- entire_width              */
3797         /*                                              */
3798         entire_width = namewidth + (column_width + 2) *
3799             label_array_len(iostat_bottom_labels[type]);
3800 
3801         if (cb->cb_scripted)
3802                 printf("%s\n", name);
3803         else
3804                 print_iostat_header_impl(cb, column_width, name);
3805 
3806         print_iostat_histo(nva, names_len, cb, column_width,
3807             namewidth, scale);
3808 
3809         free_calc_stats(nva, names_len);
3810         if (!cb->cb_scripted)
3811                 print_solid_separator(entire_width);
3812 }
3813 
3814 /*
3815  * Calculate the average latency of a power-of-two latency histogram
3816  */
3817 static uint64_t
3818 single_histo_average(uint64_t *histo, unsigned int buckets)
3819 {
3820         int i;
3821         uint64_t count = 0, total = 0;
3822 
3823         for (i = 0; i < buckets; i++) {
3824                 /*
3825                  * Our buckets are power-of-two latency ranges.  Use the
3826                  * midpoint latency of each bucket to calculate the average.
3827                  * For example:
3828                  *
3829                  * Bucket       Midpoint
3830                  * 8ns-15ns:    12ns
3831                  * 16ns-31ns:   24ns
3832                  * ...
3833                  */
3834                 if (histo[i] != 0) {
3835                         total += histo[i] * (((1UL << i) + ((1UL << i)/2)));
3836                         count += histo[i];
3837                 }
3838         }
3839 
3840         /* Prevent divide by zero */
3841         return (count == 0 ? 0 : total / count);
3842 }
3843 
3844 static void
3845 print_iostat_queues(iostat_cbdata_t *cb, nvlist_t *oldnv,
3846     nvlist_t *newnv)
3847 {
3848         int i;
3849         uint64_t val;
3850         const char *names[] = {
3851                 ZPOOL_CONFIG_VDEV_SYNC_R_PEND_QUEUE,
3852                 ZPOOL_CONFIG_VDEV_SYNC_R_ACTIVE_QUEUE,
3853                 ZPOOL_CONFIG_VDEV_SYNC_W_PEND_QUEUE,
3854                 ZPOOL_CONFIG_VDEV_SYNC_W_ACTIVE_QUEUE,
3855                 ZPOOL_CONFIG_VDEV_ASYNC_R_PEND_QUEUE,
3856                 ZPOOL_CONFIG_VDEV_ASYNC_R_ACTIVE_QUEUE,
3857                 ZPOOL_CONFIG_VDEV_ASYNC_W_PEND_QUEUE,
3858                 ZPOOL_CONFIG_VDEV_ASYNC_W_ACTIVE_QUEUE,
3859                 ZPOOL_CONFIG_VDEV_SCRUB_PEND_QUEUE,
3860                 ZPOOL_CONFIG_VDEV_SCRUB_ACTIVE_QUEUE,
3861                 ZPOOL_CONFIG_VDEV_TRIM_PEND_QUEUE,
3862                 ZPOOL_CONFIG_VDEV_TRIM_ACTIVE_QUEUE,
3863         };
3864 
3865         struct stat_array *nva;
3866 
3867         unsigned int column_width = default_column_width(cb, IOS_QUEUES);
3868         enum zfs_nicenum_format format;
3869 
3870         nva = calc_and_alloc_stats_ex(names, ARRAY_SIZE(names), NULL, newnv);
3871 
3872         if (cb->cb_literal)
3873                 format = ZFS_NICENUM_RAW;
3874         else
3875                 format = ZFS_NICENUM_1024;
3876 
3877         for (i = 0; i < ARRAY_SIZE(names); i++) {
3878                 val = nva[i].data[0];
3879                 print_one_stat(val, format, column_width, cb->cb_scripted);
3880         }
3881 
3882         free_calc_stats(nva, ARRAY_SIZE(names));
3883 }
3884 
3885 static void
3886 print_iostat_latency(iostat_cbdata_t *cb, nvlist_t *oldnv,
3887     nvlist_t *newnv)
3888 {
3889         int i;
3890         uint64_t val;
3891         const char *names[] = {
3892                 ZPOOL_CONFIG_VDEV_TOT_R_LAT_HISTO,
3893                 ZPOOL_CONFIG_VDEV_TOT_W_LAT_HISTO,
3894                 ZPOOL_CONFIG_VDEV_DISK_R_LAT_HISTO,
3895                 ZPOOL_CONFIG_VDEV_DISK_W_LAT_HISTO,
3896                 ZPOOL_CONFIG_VDEV_SYNC_R_LAT_HISTO,
3897                 ZPOOL_CONFIG_VDEV_SYNC_W_LAT_HISTO,
3898                 ZPOOL_CONFIG_VDEV_ASYNC_R_LAT_HISTO,
3899                 ZPOOL_CONFIG_VDEV_ASYNC_W_LAT_HISTO,
3900                 ZPOOL_CONFIG_VDEV_SCRUB_LAT_HISTO,
3901                 ZPOOL_CONFIG_VDEV_TRIM_LAT_HISTO,
3902         };
3903         struct stat_array *nva;
3904 
3905         unsigned int column_width = default_column_width(cb, IOS_LATENCY);
3906         enum zfs_nicenum_format format;
3907 
3908         nva = calc_and_alloc_stats_ex(names, ARRAY_SIZE(names), oldnv, newnv);
3909 
3910         if (cb->cb_literal)
3911                 format = ZFS_NICENUM_RAWTIME;
3912         else
3913                 format = ZFS_NICENUM_TIME;
3914 
3915         /* Print our avg latencies on the line */
3916         for (i = 0; i < ARRAY_SIZE(names); i++) {
3917                 /* Compute average latency for a latency histo */
3918                 val = single_histo_average(nva[i].data, nva[i].count);
3919                 print_one_stat(val, format, column_width, cb->cb_scripted);
3920         }
3921         free_calc_stats(nva, ARRAY_SIZE(names));
3922 }
3923 
3924 /*
3925  * Print default statistics (capacity/operations/bandwidth)
3926  */
3927 static void
3928 print_iostat_default(vdev_stat_t *vs, iostat_cbdata_t *cb, double scale)
3929 {
3930         unsigned int column_width = default_column_width(cb, IOS_DEFAULT);
3931         enum zfs_nicenum_format format;
3932         char na;        /* char to print for "not applicable" values */
3933 
3934         if (cb->cb_literal) {
3935                 format = ZFS_NICENUM_RAW;
3936                 na = '0';
3937         } else {
3938                 format = ZFS_NICENUM_1024;
3939                 na = '-';
3940         }
3941 
3942         /* only toplevel vdevs have capacity stats */
3943         if (vs->vs_space == 0) {
3944                 if (cb->cb_scripted)
3945                         printf("\t%c\t%c", na, na);
3946                 else
3947                         printf("  %*c  %*c", column_width, na, column_width,
3948                             na);
3949         } else {
3950                 print_one_stat(vs->vs_alloc, format, column_width,
3951                     cb->cb_scripted);
3952                 print_one_stat(vs->vs_space - vs->vs_alloc, format,
3953                     column_width, cb->cb_scripted);
3954         }
3955 
3956         print_one_stat((uint64_t)(vs->vs_ops[ZIO_TYPE_READ] * scale),
3957             format, column_width, cb->cb_scripted);
3958         print_one_stat((uint64_t)(vs->vs_ops[ZIO_TYPE_WRITE] * scale),
3959             format, column_width, cb->cb_scripted);
3960         print_one_stat((uint64_t)(vs->vs_bytes[ZIO_TYPE_READ] * scale),
3961             format, column_width, cb->cb_scripted);
3962         print_one_stat((uint64_t)(vs->vs_bytes[ZIO_TYPE_WRITE] * scale),
3963             format, column_width, cb->cb_scripted);
3964 }
3965 
3966 static const char *class_name[] = {
3967         VDEV_ALLOC_BIAS_DEDUP,
3968         VDEV_ALLOC_BIAS_SPECIAL,
3969         VDEV_ALLOC_CLASS_LOGS
3970 };
3971 
3972 /*
3973  * Print out all the statistics for the given vdev.  This can either be the
3974  * toplevel configuration, or called recursively.  If 'name' is NULL, then this
3975  * is a verbose output, and we don't want to display the toplevel pool stats.
3976  *
3977  * Returns the number of stat lines printed.
3978  */
3979 unsigned int
3980 print_vdev_stats(zpool_handle_t *zhp, const char *name, nvlist_t *oldnv,
3981     nvlist_t *newnv, iostat_cbdata_t *cb, int depth)
3982 {
3983         nvlist_t **oldchild, **newchild;
3984         uint_t c, children, oldchildren;
3985         vdev_stat_t *oldvs, *newvs, *calcvs;
3986         vdev_stat_t zerovs = { 0 };
3987         char *vname;
3988         int i;
3989         int ret = 0;
3990         uint64_t tdelta;
3991         double scale;
3992 
3993         if (strcmp(name, VDEV_TYPE_INDIRECT) == 0)
3994                 return (0);
3995 
3996         calcvs = safe_malloc(sizeof (*calcvs));
3997 
3998         if (oldnv != NULL) {
3999                 verify(nvlist_lookup_uint64_array(oldnv,
4000                     ZPOOL_CONFIG_VDEV_STATS, (uint64_t **)&oldvs, &c) == 0);
4001         } else {
4002                 oldvs = &zerovs;
4003         }
4004 
4005         /* Do we only want to see a specific vdev? */
4006         for (i = 0; i < cb->cb_vdev_names_count; i++) {
4007                 /* Yes we do.  Is this the vdev? */
4008                 if (strcmp(name, cb->cb_vdev_names[i]) == 0) {
4009                         /*
4010                          * This is our vdev.  Since it is the only vdev we
4011                          * will be displaying, make depth = 0 so that it
4012                          * doesn't get indented.
4013                          */
4014                         depth = 0;
4015                         break;
4016                 }
4017         }
4018 
4019         if (cb->cb_vdev_names_count && (i == cb->cb_vdev_names_count)) {
4020                 /* Couldn't match the name */
4021                 goto children;
4022         }
4023 
4024 
4025         verify(nvlist_lookup_uint64_array(newnv, ZPOOL_CONFIG_VDEV_STATS,
4026             (uint64_t **)&newvs, &c) == 0);
4027 
4028         /*
4029          * Print the vdev name unless it's is a histogram.  Histograms
4030          * display the vdev name in the header itself.
4031          */
4032         if (!(cb->cb_flags & IOS_ANYHISTO_M)) {
4033                 if (cb->cb_scripted) {
4034                         printf("%s", name);
4035                 } else {
4036                         if (strlen(name) + depth > cb->cb_namewidth)
4037                                 (void) printf("%*s%s", depth, "", name);
4038                         else
4039                                 (void) printf("%*s%s%*s", depth, "", name,
4040                                     (int)(cb->cb_namewidth - strlen(name) -
4041                                     depth), "");
4042                 }
4043         }
4044 
4045         /* Calculate our scaling factor */
4046         tdelta = newvs->vs_timestamp - oldvs->vs_timestamp;
4047         if ((oldvs->vs_timestamp == 0) && (cb->cb_flags & IOS_ANYHISTO_M)) {
4048                 /*
4049                  * If we specify printing histograms with no time interval, then
4050                  * print the histogram numbers over the entire lifetime of the
4051                  * vdev.
4052                  */
4053                 scale = 1;
4054         } else {
4055                 if (tdelta == 0)
4056                         scale = 1.0;
4057                 else
4058                         scale = (double)NANOSEC / tdelta;
4059         }
4060 
4061         if (cb->cb_flags & IOS_DEFAULT_M) {
4062                 calc_default_iostats(oldvs, newvs, calcvs);
4063                 print_iostat_default(calcvs, cb, scale);
4064         }
4065         if (cb->cb_flags & IOS_LATENCY_M)
4066                 print_iostat_latency(cb, oldnv, newnv);
4067         if (cb->cb_flags & IOS_QUEUES_M)
4068                 print_iostat_queues(cb, oldnv, newnv);
4069         if (cb->cb_flags & IOS_ANYHISTO_M) {
4070                 printf("\n");
4071                 print_iostat_histos(cb, oldnv, newnv, scale, name);
4072         }
4073 
4074         if (!(cb->cb_flags & IOS_ANYHISTO_M))
4075                 printf("\n");
4076 
4077         ret++;
4078 
4079 children:
4080 
4081         free(calcvs);
4082 
4083         if (!cb->cb_verbose)
4084                 return (ret);
4085 
4086         if (nvlist_lookup_nvlist_array(newnv, ZPOOL_CONFIG_CHILDREN,
4087             &newchild, &children) != 0)
4088                 return (ret);
4089 
4090         if (oldnv) {
4091                 if (nvlist_lookup_nvlist_array(oldnv, ZPOOL_CONFIG_CHILDREN,
4092                     &oldchild, &oldchildren) != 0)
4093                         return (ret);
4094 
4095                 children = MIN(oldchildren, children);
4096         }
4097 
4098         /*
4099          * print normal top-level devices
4100          */
4101         for (c = 0; c < children; c++) {
4102                 uint64_t ishole = B_FALSE, islog = B_FALSE;
4103 
4104                 (void) nvlist_lookup_uint64(newchild[c], ZPOOL_CONFIG_IS_HOLE,
4105                     &ishole);
4106 
4107                 (void) nvlist_lookup_uint64(newchild[c], ZPOOL_CONFIG_IS_LOG,
4108                     &islog);
4109 
4110                 if (ishole || islog)
4111                         continue;
4112 
4113                 if (nvlist_exists(newchild[c], ZPOOL_CONFIG_ALLOCATION_BIAS))
4114                         continue;
4115 
4116                 vname = zpool_vdev_name(g_zfs, zhp, newchild[c],
4117                     cb->cb_name_flags);
4118                 ret += print_vdev_stats(zhp, vname, oldnv ? oldchild[c] : NULL,
4119                     newchild[c], cb, depth + 2);
4120                 free(vname);
4121         }
4122 
4123         /*
4124          * print all other top-level devices
4125          */
4126         for (uint_t n = 0; n < 3; n++) {
4127                 boolean_t printed = B_FALSE;
4128 
4129                 for (c = 0; c < children; c++) {
4130                         uint64_t islog = B_FALSE;
4131                         char *bias = NULL;
4132                         char *type = NULL;
4133 
4134                         (void) nvlist_lookup_uint64(newchild[c],
4135                             ZPOOL_CONFIG_IS_LOG, &islog);
4136                         if (islog) {
4137                                 bias = VDEV_ALLOC_CLASS_LOGS;
4138                         } else {
4139                                 (void) nvlist_lookup_string(newchild[c],
4140                                     ZPOOL_CONFIG_ALLOCATION_BIAS, &bias);
4141                                 (void) nvlist_lookup_string(newchild[c],
4142                                     ZPOOL_CONFIG_TYPE, &type);
4143                         }
4144                         if (bias == NULL || strcmp(bias, class_name[n]) != 0)
4145                                 continue;
4146                         if (!islog && strcmp(type, VDEV_TYPE_INDIRECT) == 0)
4147                                 continue;
4148 
4149                         if (!printed) {
4150                                 if ((!(cb->cb_flags & IOS_ANYHISTO_M)) &&
4151                                     !cb->cb_scripted && !cb->cb_vdev_names) {
4152                                         print_iostat_dashes(cb, 0,
4153                                             class_name[n]);
4154                                 }
4155                                 printf("\n");
4156                                 printed = B_TRUE;
4157                         }
4158 
4159                         vname = zpool_vdev_name(g_zfs, zhp, newchild[c],
4160                             cb->cb_name_flags);
4161                         ret += print_vdev_stats(zhp, vname, oldnv ?
4162                             oldchild[c] : NULL, newchild[c], cb, depth + 2);
4163                         free(vname);
4164                 }
4165 
4166         }
4167 
4168         /*
4169          * Include level 2 ARC devices in iostat output
4170          */
4171         if (nvlist_lookup_nvlist_array(newnv, ZPOOL_CONFIG_L2CACHE,
4172             &newchild, &children) != 0)
4173                 return (ret);
4174 
4175         if (oldnv) {
4176                 if (nvlist_lookup_nvlist_array(oldnv, ZPOOL_CONFIG_L2CACHE,
4177                     &oldchild, &oldchildren) != 0)
4178                         return (ret);
4179 
4180                 children = MIN(oldchildren, children);
4181         }
4182 
4183         if (children > 0) {
4184                 if ((!(cb->cb_flags & IOS_ANYHISTO_M)) && !cb->cb_scripted &&
4185                     !cb->cb_vdev_names) {
4186                         print_iostat_dashes(cb, 0, "cache");
4187                 }
4188                 printf("\n");
4189 
4190                 for (c = 0; c < children; c++) {
4191                         vname = zpool_vdev_name(g_zfs, zhp, newchild[c],
4192                             cb->cb_name_flags);
4193                         ret += print_vdev_stats(zhp, vname, oldnv ? oldchild[c]
4194                             : NULL, newchild[c], cb, depth + 2);
4195                         free(vname);
4196                 }
4197         }
4198 
4199         return (ret);
4200 }
4201 
4202 static int
4203 refresh_iostat(zpool_handle_t *zhp, void *data)
4204 {
4205         iostat_cbdata_t *cb = data;
4206         boolean_t missing;
4207 
4208         /*
4209          * If the pool has disappeared, remove it from the list and continue.
4210          */
4211         if (zpool_refresh_stats(zhp, &missing) != 0)
4212                 return (-1);
4213 
4214         if (missing)
4215                 pool_list_remove(cb->cb_list, zhp);
4216 
4217         return (0);
4218 }
4219 
4220 /*
4221  * Callback to print out the iostats for the given pool.
4222  */
4223 int
4224 print_iostat(zpool_handle_t *zhp, void *data)
4225 {
4226         iostat_cbdata_t *cb = data;
4227         nvlist_t *oldconfig, *newconfig;
4228         nvlist_t *oldnvroot, *newnvroot;
4229         int ret;
4230 
4231         newconfig = zpool_get_config(zhp, &oldconfig);
4232 
4233         if (cb->cb_iteration == 1)
4234                 oldconfig = NULL;
4235 
4236         verify(nvlist_lookup_nvlist(newconfig, ZPOOL_CONFIG_VDEV_TREE,
4237             &newnvroot) == 0);
4238 
4239         if (oldconfig == NULL)
4240                 oldnvroot = NULL;
4241         else
4242                 verify(nvlist_lookup_nvlist(oldconfig, ZPOOL_CONFIG_VDEV_TREE,
4243                     &oldnvroot) == 0);
4244 
4245         ret = print_vdev_stats(zhp, zpool_get_name(zhp), oldnvroot, newnvroot,
4246             cb, 0);
4247         if ((ret != 0) && !(cb->cb_flags & IOS_ANYHISTO_M) &&
4248             !cb->cb_scripted && cb->cb_verbose && !cb->cb_vdev_names_count) {
4249                 print_iostat_separator(cb);
4250                 printf("\n");
4251         }
4252 
4253         return (ret);
4254 }
4255 
4256 static int
4257 get_columns(void)
4258 {
4259         struct winsize ws;
4260         int columns = 80;
4261         int error;
4262 
4263         if (isatty(STDOUT_FILENO)) {
4264                 error = ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws);
4265                 if (error == 0)
4266                         columns = ws.ws_col;
4267         } else {
4268                 columns = 999;
4269         }
4270 
4271         return (columns);
4272 }
4273 
4274 /*
4275  * Return the required length of the pool/vdev name column.  The minimum
4276  * allowed width and output formatting flags must be provided.
4277  */
4278 static int
4279 get_namewidth(zpool_handle_t *zhp, int min_width, int flags, boolean_t verbose)
4280 {
4281         nvlist_t *config, *nvroot;
4282         int width = min_width;
4283 
4284         if ((config = zpool_get_config(zhp, NULL)) != NULL) {
4285                 verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
4286                     &nvroot) == 0);
4287                 unsigned int poolname_len = strlen(zpool_get_name(zhp));
4288                 if (verbose == B_FALSE) {
4289                         width = MAX(poolname_len, min_width);
4290                 } else {
4291                         width = MAX(poolname_len,
4292                             max_width(zhp, nvroot, 0, min_width, flags));
4293                 }
4294         }
4295 
4296         return (width);
4297 }
4298 
4299 /*
4300  * Parse the input string, get the 'interval' and 'count' value if there is one.
4301  */
4302 static void
4303 get_interval_count(int *argcp, char **argv, float *iv,
4304     unsigned long *cnt)
4305 {
4306         float interval = 0;
4307         unsigned long count = 0;
4308         int argc = *argcp, errno;
4309 
4310         /*
4311          * Determine if the last argument is an integer or a pool name
4312          */
4313         if (argc > 0 && isnumber(argv[argc - 1])) {
4314                 char *end;
4315 
4316                 errno = 0;
4317                 interval = strtof(argv[argc - 1], &end);
4318 
4319                 if (*end == '\0' && errno == 0) {
4320                         if (interval == 0) {
4321                                 (void) fprintf(stderr, gettext("interval "
4322                                     "cannot be zero\n"));
4323                                 usage(B_FALSE);
4324                         }
4325                         /*
4326                          * Ignore the last parameter
4327                          */
4328                         argc--;
4329                 } else {
4330                         /*
4331                          * If this is not a valid number, just plow on.  The
4332                          * user will get a more informative error message later
4333                          * on.
4334                          */
4335                         interval = 0;
4336                 }
4337         }
4338 
4339         /*
4340          * If the last argument is also an integer, then we have both a count
4341          * and an interval.
4342          */
4343         if (argc > 0 && isnumber(argv[argc - 1])) {
4344                 char *end;
4345 
4346                 errno = 0;
4347                 count = interval;
4348                 interval = strtof(argv[argc - 1], &end);
4349 
4350                 if (*end == '\0' && errno == 0) {
4351                         if (interval == 0) {
4352                                 (void) fprintf(stderr, gettext("interval "
4353                                     "cannot be zero\n"));
4354                                 usage(B_FALSE);
4355                         }
4356 
4357                         /*
4358                          * Ignore the last parameter
4359                          */
4360                         argc--;
4361                 } else {
4362                         interval = 0;
4363                 }
4364         }
4365 
4366         *iv = interval;
4367         *cnt = count;
4368         *argcp = argc;
4369 }
4370 
4371 static void
4372 get_timestamp_arg(char c)
4373 {
4374         if (c == 'u')
4375                 timestamp_fmt = UDATE;
4376         else if (c == 'd')
4377                 timestamp_fmt = DDATE;
4378         else
4379                 usage(B_FALSE);
4380 }
4381 
4382 /*
4383  * Return stat flags that are supported by all pools by both the module and
4384  * zpool iostat.  "*data" should be initialized to all 0xFFs before running.
4385  * It will get ANDed down until only the flags that are supported on all pools
4386  * remain.
4387  */
4388 static int
4389 get_stat_flags_cb(zpool_handle_t *zhp, void *data)
4390 {
4391         uint64_t *mask = data;
4392         nvlist_t *config, *nvroot, *nvx;
4393         uint64_t flags = 0;
4394         int i, j;
4395 
4396         config = zpool_get_config(zhp, NULL);
4397         verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
4398             &nvroot) == 0);
4399 
4400         /* Default stats are always supported, but for completeness.. */
4401         if (nvlist_exists(nvroot, ZPOOL_CONFIG_VDEV_STATS))
4402                 flags |= IOS_DEFAULT_M;
4403 
4404         /* Get our extended stats nvlist from the main list */
4405         if (nvlist_lookup_nvlist(nvroot, ZPOOL_CONFIG_VDEV_STATS_EX,
4406             &nvx) != 0) {
4407                 /*
4408                  * No extended stats; they're probably running an older
4409                  * module.  No big deal, we support that too.
4410                  */
4411                 goto end;
4412         }
4413 
4414         /* For each extended stat, make sure all its nvpairs are supported */
4415         for (j = 0; j < ARRAY_SIZE(vsx_type_to_nvlist); j++) {
4416                 if (!vsx_type_to_nvlist[j][0])
4417                         continue;
4418 
4419                 /* Start off by assuming the flag is supported, then check */
4420                 flags |= (1ULL << j);
4421                 for (i = 0; vsx_type_to_nvlist[j][i]; i++) {
4422                         if (!nvlist_exists(nvx, vsx_type_to_nvlist[j][i])) {
4423                                 /* flag isn't supported */
4424                                 flags = flags & ~(1ULL  << j);
4425                                 break;
4426                         }
4427                 }
4428         }
4429 end:
4430         *mask = *mask & flags;
4431         return (0);
4432 }
4433 
4434 /*
4435  * Return a bitmask of stats that are supported on all pools by both the module
4436  * and zpool iostat.
4437  */
4438 static uint64_t
4439 get_stat_flags(zpool_list_t *list)
4440 {
4441         uint64_t mask = -1;
4442 
4443         /*
4444          * get_stat_flags_cb() will lop off bits from "mask" until only the
4445          * flags that are supported on all pools remain.
4446          */
4447         (void) pool_list_iter(list, B_FALSE, get_stat_flags_cb, &mask);
4448         return (mask);
4449 }
4450 
4451 /*
4452  * Return 1 if cb_data->cb_vdev_names[0] is this vdev's name, 0 otherwise.
4453  */
4454 static int
4455 is_vdev_cb(zpool_handle_t *zhp, nvlist_t *nv, void *cb_data)
4456 {
4457         iostat_cbdata_t *cb = cb_data;
4458         char *name;
4459 
4460         name = zpool_vdev_name(g_zfs, zhp, nv, cb->cb_name_flags);
4461 
4462         if (strcmp(name, cb->cb_vdev_names[0]) == 0)
4463                 return (1); /* match */
4464 
4465         return (0);
4466 }
4467 
4468 /*
4469  * Returns 1 if cb_data->cb_vdev_names[0] is a vdev name, 0 otherwise.
4470  */
4471 static int
4472 is_vdev(zpool_handle_t *zhp, void *cb_data)
4473 {
4474         return (for_each_vdev(zhp, is_vdev_cb, cb_data));
4475 }
4476 
4477 /*
4478  * Check if vdevs are in a pool
4479  *
4480  * Return 1 if all argv[] strings are vdev names in pool "pool_name". Otherwise
4481  * return 0.  If pool_name is NULL, then search all pools.
4482  */
4483 static int
4484 are_vdevs_in_pool(int argc, char **argv, char *pool_name,
4485     iostat_cbdata_t *cb)
4486 {
4487         char **tmp_name;
4488         int ret = 0;
4489         int i;
4490         int pool_count = 0;
4491 
4492         if ((argc == 0) || !*argv)
4493                 return (0);
4494 
4495         if (pool_name)
4496                 pool_count = 1;
4497 
4498         /* Temporarily hijack cb_vdev_names for a second... */
4499         tmp_name = cb->cb_vdev_names;
4500 
4501         /* Go though our list of prospective vdev names */
4502         for (i = 0; i < argc; i++) {
4503                 cb->cb_vdev_names = argv + i;
4504 
4505                 /* Is this name a vdev in our pools? */
4506                 ret = for_each_pool(pool_count, &pool_name, B_TRUE, NULL,
4507                     is_vdev, cb);
4508                 if (!ret) {
4509                         /* No match */
4510                         break;
4511                 }
4512         }
4513 
4514         cb->cb_vdev_names = tmp_name;
4515 
4516         return (ret);
4517 }
4518 
4519 static int
4520 is_pool_cb(zpool_handle_t *zhp, void *data)
4521 {
4522         char *name = data;
4523         if (strcmp(name, zpool_get_name(zhp)) == 0)
4524                 return (1);
4525 
4526         return (0);
4527 }
4528 
4529 /*
4530  * Do we have a pool named *name?  If so, return 1, otherwise 0.
4531  */
4532 static int
4533 is_pool(char *name)
4534 {
4535         return (for_each_pool(0, NULL, B_TRUE, NULL,  is_pool_cb, name));
4536 }
4537 
4538 /* Are all our argv[] strings pool names?  If so return 1, 0 otherwise. */
4539 static int
4540 are_all_pools(int argc, char **argv)
4541 {
4542         if ((argc == 0) || !*argv)
4543                 return (0);
4544 
4545         while (--argc >= 0)
4546                 if (!is_pool(argv[argc]))
4547                         return (0);
4548 
4549         return (1);
4550 }
4551 
4552 /*
4553  * Helper function to print out vdev/pool names we can't resolve.  Used for an
4554  * error message.
4555  */
4556 static void
4557 error_list_unresolved_vdevs(int argc, char **argv, char *pool_name,
4558     iostat_cbdata_t *cb)
4559 {
4560         int i;
4561         char *name;
4562         char *str;
4563         for (i = 0; i < argc; i++) {
4564                 name = argv[i];
4565 
4566                 if (is_pool(name))
4567                         str = gettext("pool");
4568                 else if (are_vdevs_in_pool(1, &name, pool_name, cb))
4569                         str = gettext("vdev in this pool");
4570                 else if (are_vdevs_in_pool(1, &name, NULL, cb))
4571                         str = gettext("vdev in another pool");
4572                 else
4573                         str = gettext("unknown");
4574 
4575                 fprintf(stderr, "\t%s (%s)\n", name, str);
4576         }
4577 }
4578 
4579 /*
4580  * Same as get_interval_count(), but with additional checks to not misinterpret
4581  * guids as interval/count values.  Assumes VDEV_NAME_GUID is set in
4582  * cb.cb_name_flags.
4583  */
4584 static void
4585 get_interval_count_filter_guids(int *argc, char **argv, float *interval,
4586     unsigned long *count, iostat_cbdata_t *cb)
4587 {
4588         char **tmpargv = argv;
4589         int argc_for_interval = 0;
4590 
4591         /* Is the last arg an interval value?  Or a guid? */
4592         if (*argc >= 1 && !are_vdevs_in_pool(1, &argv[*argc - 1], NULL, cb)) {
4593                 /*
4594                  * The last arg is not a guid, so it's probably an
4595                  * interval value.
4596                  */
4597                 argc_for_interval++;
4598 
4599                 if (*argc >= 2 &&
4600                     !are_vdevs_in_pool(1, &argv[*argc - 2], NULL, cb)) {
4601                         /*
4602                          * The 2nd to last arg is not a guid, so it's probably
4603                          * an interval value.
4604                          */
4605                         argc_for_interval++;
4606                 }
4607         }
4608 
4609         /* Point to our list of possible intervals */
4610         tmpargv = &argv[*argc - argc_for_interval];
4611 
4612         *argc = *argc - argc_for_interval;
4613         get_interval_count(&argc_for_interval, tmpargv,
4614             interval, count);
4615 }
4616 
4617 /*
4618  * Floating point sleep().  Allows you to pass in a floating point value for
4619  * seconds.
4620  */
4621 static void
4622 fsleep(float sec)
4623 {
4624         struct timespec req;
4625         req.tv_sec = floor(sec);
4626         req.tv_nsec = (sec - (float)req.tv_sec) * NANOSEC;
4627         (void) nanosleep(&req, NULL);
4628 }
4629 
4630 /*
4631  * Set the minimum pool/vdev name column width.  The width must be at least 10,
4632  * but may be as large as the column width - 42 so it still fits on one line.
4633  */
4634 static int
4635 get_namewidth_iostat(zpool_handle_t *zhp, void *data)
4636 {
4637         iostat_cbdata_t *cb = data;
4638         int width, columns;
4639 
4640         width = get_namewidth(zhp, cb->cb_namewidth, cb->cb_name_flags,
4641             cb->cb_verbose);
4642         columns = get_columns();
4643 
4644         if (width < 10)
4645                 width = 10;
4646         if (width > columns - 42)
4647                 width = columns - 42;
4648 
4649         cb->cb_namewidth = width;
4650 
4651         return (0);
4652 }
4653 
4654 /*
4655  * zpool iostat [-ghHLpPvy] [[-lq]|[-r|-w]] [-n name] [-T d|u]
4656  *              [[ pool ...]|[pool vdev ...]|[vdev ...]]
4657  *              [interval [count]]
4658  *
4659  *      -g      Display guid for individual vdev name.
4660  *      -L      Follow links when resolving vdev path name.
4661  *      -P      Display full path for vdev name.
4662  *      -v      Display statistics for individual vdevs
4663  *      -h      Display help
4664  *      -p      Display values in parsable (exact) format.
4665  *      -H      Scripted mode.  Don't display headers, and separate properties
4666  *              by a single tab.
4667  *      -l      Display average latency
4668  *      -q      Display queue depths
4669  *      -w      Display latency histograms
4670  *      -r      Display request size histogram
4671  *      -T      Display a timestamp in date(1) or Unix format
4672  *      -n      Only print headers once
4673  *
4674  * This command can be tricky because we want to be able to deal with pool
4675  * creation/destruction as well as vdev configuration changes.  The bulk of this
4676  * processing is handled by the pool_list_* routines in zpool_iter.c.  We rely
4677  * on pool_list_update() to detect the addition of new pools.  Configuration
4678  * changes are all handled within libzfs.
4679  */
4680 int
4681 zpool_do_iostat(int argc, char **argv)
4682 {
4683         int c;
4684         int ret;
4685         int npools;
4686         float interval = 0;
4687         unsigned long count = 0;
4688         int winheight = 24;
4689         struct winsize win;
4690         zpool_list_t *list;
4691         boolean_t verbose = B_FALSE;
4692         boolean_t latency = B_FALSE, l_histo = B_FALSE, rq_histo = B_FALSE;
4693         boolean_t queues = B_FALSE, parseable = B_FALSE, scripted = B_FALSE;
4694         boolean_t omit_since_boot = B_FALSE;
4695         boolean_t guid = B_FALSE;
4696         boolean_t follow_links = B_FALSE;
4697         boolean_t full_name = B_FALSE;
4698         boolean_t headers_once = B_FALSE;
4699         iostat_cbdata_t cb = { 0 };
4700 
4701         /* Used for printing error message */
4702         const char flag_to_arg[] = {[IOS_LATENCY] = 'l', [IOS_QUEUES] = 'q',
4703             [IOS_L_HISTO] = 'w', [IOS_RQ_HISTO] = 'r'};
4704 
4705         uint64_t unsupported_flags;
4706 
4707         /* check options */
4708         while ((c = getopt(argc, argv, "gLPT:vyhplqrwnH")) != -1) {
4709                 switch (c) {
4710                 case 'g':
4711                         guid = B_TRUE;
4712                         break;
4713                 case 'L':
4714                         follow_links = B_TRUE;
4715                         break;
4716                 case 'P':
4717                         full_name = B_TRUE;
4718                         break;
4719                 case 'T':
4720                         get_timestamp_arg(*optarg);
4721                         break;
4722                 case 'v':
4723                         verbose = B_TRUE;
4724                         break;
4725                 case 'p':
4726                         parseable = B_TRUE;
4727                         break;
4728                 case 'l':
4729                         latency = B_TRUE;
4730                         break;
4731                 case 'q':
4732                         queues = B_TRUE;
4733                         break;
4734                 case 'H':
4735                         scripted = B_TRUE;
4736                         break;
4737                 case 'w':
4738                         l_histo = B_TRUE;
4739                         break;
4740                 case 'r':
4741                         rq_histo = B_TRUE;
4742                         break;
4743                 case 'y':
4744                         omit_since_boot = B_TRUE;
4745                         break;
4746                 case 'n':
4747                         headers_once = B_TRUE;
4748                         break;
4749                 case 'h':
4750                         usage(B_FALSE);
4751                         break;
4752                 case '?':
4753                         (void) fprintf(stderr, gettext("invalid option '%c'\n"),
4754                             optopt);
4755                         usage(B_FALSE);
4756                 }
4757         }
4758 
4759         argc -= optind;
4760         argv += optind;
4761 
4762         cb.cb_literal = parseable;
4763         cb.cb_scripted = scripted;
4764 
4765         if (guid)
4766                 cb.cb_name_flags |= VDEV_NAME_GUID;
4767         if (follow_links)
4768                 cb.cb_name_flags |= VDEV_NAME_FOLLOW_LINKS;
4769         if (full_name)
4770                 cb.cb_name_flags |= VDEV_NAME_PATH;
4771         cb.cb_iteration = 0;
4772         cb.cb_namewidth = 0;
4773         cb.cb_verbose = verbose;
4774 
4775         /* Get our interval and count values (if any) */
4776         if (guid) {
4777                 get_interval_count_filter_guids(&argc, argv, &interval,
4778                     &count, &cb);
4779         } else {
4780                 get_interval_count(&argc, argv, &interval, &count);
4781         }
4782 
4783         if (argc == 0) {
4784                 /* No args, so just print the defaults. */
4785         } else if (are_all_pools(argc, argv)) {
4786                 /* All the args are pool names */
4787         } else if (are_vdevs_in_pool(argc, argv, NULL, &cb)) {
4788                 /* All the args are vdevs */
4789                 cb.cb_vdev_names = argv;
4790                 cb.cb_vdev_names_count = argc;
4791                 argc = 0; /* No pools to process */
4792         } else if (are_all_pools(1, argv)) {
4793                 /* The first arg is a pool name */
4794                 if (are_vdevs_in_pool(argc - 1, argv + 1, argv[0], &cb)) {
4795                         /* ...and the rest are vdev names */
4796                         cb.cb_vdev_names = argv + 1;
4797                         cb.cb_vdev_names_count = argc - 1;
4798                         argc = 1; /* One pool to process */
4799                 } else {
4800                         fprintf(stderr, gettext("Expected either a list of "));
4801                         fprintf(stderr, gettext("pools, or list of vdevs in"));
4802                         fprintf(stderr, " \"%s\", ", argv[0]);
4803                         fprintf(stderr, gettext("but got:\n"));
4804                         error_list_unresolved_vdevs(argc - 1, argv + 1,
4805                             argv[0], &cb);
4806                         fprintf(stderr, "\n");
4807                         usage(B_FALSE);
4808                         return (1);
4809                 }
4810         } else {
4811                 /*
4812                  * The args don't make sense. The first arg isn't a pool name,
4813                  * nor are all the args vdevs.
4814                  */
4815                 fprintf(stderr, gettext("Unable to parse pools/vdevs list.\n"));
4816                 fprintf(stderr, "\n");
4817                 return (1);
4818         }
4819 
4820         if (cb.cb_vdev_names_count != 0) {
4821                 /*
4822                  * If user specified vdevs, it implies verbose.
4823                  */
4824                 cb.cb_verbose = B_TRUE;
4825         }
4826 
4827         /*
4828          * Construct the list of all interesting pools.
4829          */
4830         ret = 0;
4831         if ((list = pool_list_get(argc, argv, NULL, &ret)) == NULL)
4832                 return (1);
4833 
4834         if (pool_list_count(list) == 0 && argc != 0) {
4835                 pool_list_free(list);
4836                 return (1);
4837         }
4838 
4839         if (pool_list_count(list) == 0 && interval == 0) {
4840                 pool_list_free(list);
4841                 (void) fprintf(stderr, gettext("no pools available\n"));
4842                 return (1);
4843         }
4844 
4845         if ((l_histo || rq_histo) && (queues || latency)) {
4846                 pool_list_free(list);
4847                 (void) fprintf(stderr,
4848                     gettext("[-r|-w] isn't allowed with [-q|-l]\n"));
4849                 usage(B_FALSE);
4850                 return (1);
4851         }
4852 
4853         if (l_histo && rq_histo) {
4854                 pool_list_free(list);
4855                 (void) fprintf(stderr,
4856                     gettext("Only one of [-r|-w] can be passed at a time\n"));
4857                 usage(B_FALSE);
4858                 return (1);
4859         }
4860 
4861         /*
4862          * Enter the main iostat loop.
4863          */
4864         cb.cb_list = list;
4865 
4866         if (l_histo) {
4867                 /*
4868                  * Histograms tables look out of place when you try to display
4869                  * them with the other stats, so make a rule that you can only
4870                  * print histograms by themselves.
4871                  */
4872                 cb.cb_flags = IOS_L_HISTO_M;
4873         } else if (rq_histo) {
4874                 cb.cb_flags = IOS_RQ_HISTO_M;
4875         } else {
4876                 cb.cb_flags = IOS_DEFAULT_M;
4877                 if (latency)
4878                         cb.cb_flags |= IOS_LATENCY_M;
4879                 if (queues)
4880                         cb.cb_flags |= IOS_QUEUES_M;
4881         }
4882 
4883         /*
4884          * See if the module supports all the stats we want to display.
4885          */
4886         unsupported_flags = cb.cb_flags & ~get_stat_flags(list);
4887         if (unsupported_flags) {
4888                 uint64_t f;
4889                 int idx;
4890                 fprintf(stderr,
4891                     gettext("The loaded zfs module doesn't support:"));
4892 
4893                 /* for each bit set in unsupported_flags */
4894                 for (f = unsupported_flags; f; f &= ~(1ULL << idx)) {
4895                         idx = lowbit64(f) - 1;
4896                         fprintf(stderr, " -%c", flag_to_arg[idx]);
4897                 }
4898 
4899                 fprintf(stderr, ".  Try running a newer module.\n"),
4900                     pool_list_free(list);
4901 
4902                 return (1);
4903         }
4904 
4905         for (;;) {
4906                 if ((npools = pool_list_count(list)) == 0)
4907                         (void) fprintf(stderr, gettext("no pools available\n"));
4908                 else {
4909                         /*
4910                          * If this is the first iteration and -y was supplied
4911                          * we skip any printing.
4912                          */
4913                         boolean_t skip = (omit_since_boot &&
4914                             cb.cb_iteration == 0);
4915 
4916                         /*
4917                          * Refresh all statistics.  This is done as an
4918                          * explicit step before calculating the maximum name
4919                          * width, so that any configuration changes are
4920                          * properly accounted for.
4921                          */
4922                         (void) pool_list_iter(list, B_FALSE, refresh_iostat,
4923                             &cb);
4924 
4925                         /*
4926                          * Iterate over all pools to determine the maximum width
4927                          * for the pool / device name column across all pools.
4928                          */
4929                         cb.cb_namewidth = 0;
4930                         (void) pool_list_iter(list, B_FALSE,
4931                             get_namewidth_iostat, &cb);
4932 
4933                         if (timestamp_fmt != NODATE)
4934                                 print_timestamp(timestamp_fmt);
4935 
4936                         /*
4937                          * Check terminal size so we can print headers
4938                          * even when terminal window has its height
4939                          * changed.
4940                          */
4941                         if (headers_once == B_FALSE) {
4942                                 if (ioctl(1, TIOCGWINSZ, &win) != -1) {
4943                                         if (win.ws_row <= 0) {
4944                                                 headers_once = B_TRUE;
4945                                         } else {
4946                                                 winheight = win.ws_row;
4947                                         }
4948                                 }
4949                         }
4950                         /*
4951                          * Are we connected to TTY? If not, headers_once
4952                          * should be true, to avoid breaking scripts.
4953                          */
4954                         if (isatty(fileno(stdout)) == 0)
4955                                 headers_once = B_TRUE;
4956 
4957                         /*
4958                          * If it's the first time and we're not skipping it,
4959                          * or either skip or verbose mode, print the header.
4960                          *
4961                          * The histogram code explicitly prints its header on
4962                          * every vdev, so skip this for histograms.
4963                          */
4964                         if (((++cb.cb_iteration == 1 && !skip) ||
4965                             (skip != verbose) ||
4966                             (!headers_once &&
4967                             (cb.cb_iteration % winheight) == 0)) &&
4968                             (!(cb.cb_flags & IOS_ANYHISTO_M)) &&
4969                             !cb.cb_scripted)
4970                                 print_iostat_header(&cb);
4971 
4972                         if (skip) {
4973                                 (void) fsleep(interval);
4974                                 continue;
4975                         }
4976 
4977                         (void) pool_list_iter(list, B_FALSE, print_iostat, &cb);
4978 
4979                         /*
4980                          * If there's more than one pool, and we're not in
4981                          * verbose mode (which prints a separator for us),
4982                          * then print a separator.
4983                          *
4984                          * In addition, if we're printing specific vdevs then
4985                          * we also want an ending separator.
4986                          */
4987                         if (((npools > 1 && !verbose &&
4988                             !(cb.cb_flags & IOS_ANYHISTO_M)) ||
4989                             (!(cb.cb_flags & IOS_ANYHISTO_M) &&
4990                             cb.cb_vdev_names_count)) &&
4991                             !cb.cb_scripted) {
4992                                 print_iostat_separator(&cb);
4993                                 printf("\n");
4994                         }
4995                 }
4996 
4997                 /*
4998                  * Flush the output so that redirection to a file isn't buffered
4999                  * indefinitely.
5000                  */
5001                 (void) fflush(stdout);
5002 
5003                 if (interval == 0)
5004                         break;
5005 
5006                 if (count != 0 && --count == 0)
5007                         break;
5008 
5009                 (void) fsleep(interval);
5010         }
5011 
5012         pool_list_free(list);
5013 
5014         return (ret);
5015 }
5016 
5017 typedef struct list_cbdata {
5018         boolean_t       cb_verbose;
5019         int             cb_name_flags;
5020         int             cb_namewidth;
5021         boolean_t       cb_scripted;
5022         zprop_list_t    *cb_proplist;
5023         boolean_t       cb_literal;
5024 } list_cbdata_t;
5025 
5026 
5027 /*
5028  * Given a list of columns to display, output appropriate headers for each one.
5029  */
5030 static void
5031 print_header(list_cbdata_t *cb)
5032 {
5033         zprop_list_t *pl = cb->cb_proplist;
5034         char headerbuf[ZPOOL_MAXPROPLEN];
5035         const char *header;
5036         boolean_t first = B_TRUE;
5037         boolean_t right_justify;
5038         size_t width = 0;
5039 
5040         for (; pl != NULL; pl = pl->pl_next) {
5041                 width = pl->pl_width;
5042                 if (first && cb->cb_verbose) {
5043                         /*
5044                          * Reset the width to accommodate the verbose listing
5045                          * of devices.
5046                          */
5047                         width = cb->cb_namewidth;
5048                 }
5049 
5050                 if (!first)
5051                         (void) printf("  ");
5052                 else
5053                         first = B_FALSE;
5054 
5055                 right_justify = B_FALSE;
5056                 if (pl->pl_prop != ZPROP_INVAL) {
5057                         header = zpool_prop_column_name(pl->pl_prop);
5058                         right_justify = zpool_prop_align_right(pl->pl_prop);
5059                 } else {
5060                         int i;
5061 
5062                         for (i = 0; pl->pl_user_prop[i] != '\0'; i++)
5063                                 headerbuf[i] = toupper(pl->pl_user_prop[i]);
5064                         headerbuf[i] = '\0';
5065                         header = headerbuf;
5066                 }
5067 
5068                 if (pl->pl_next == NULL && !right_justify)
5069                         (void) printf("%s", header);
5070                 else if (right_justify)
5071                         (void) printf("%*s", width, header);
5072                 else
5073                         (void) printf("%-*s", width, header);
5074 
5075         }
5076 
5077         (void) printf("\n");
5078 }
5079 
5080 /*
5081  * Given a pool and a list of properties, print out all the properties according
5082  * to the described layout. Used by zpool_do_list().
5083  */
5084 static void
5085 print_pool(zpool_handle_t *zhp, list_cbdata_t *cb)
5086 {
5087         zprop_list_t *pl = cb->cb_proplist;
5088         boolean_t first = B_TRUE;
5089         char property[ZPOOL_MAXPROPLEN];
5090         char *propstr;
5091         boolean_t right_justify;
5092         size_t width;
5093 
5094         for (; pl != NULL; pl = pl->pl_next) {
5095 
5096                 width = pl->pl_width;
5097                 if (first && cb->cb_verbose) {
5098                         /*
5099                          * Reset the width to accommodate the verbose listing
5100                          * of devices.
5101                          */
5102                         width = cb->cb_namewidth;
5103                 }
5104 
5105                 if (!first) {
5106                         if (cb->cb_scripted)
5107                                 (void) printf("\t");
5108                         else
5109                                 (void) printf("  ");
5110                 } else {
5111                         first = B_FALSE;
5112                 }
5113 
5114                 right_justify = B_FALSE;
5115                 if (pl->pl_prop != ZPROP_INVAL) {
5116                         if (zpool_get_prop(zhp, pl->pl_prop, property,
5117                             sizeof (property), NULL, cb->cb_literal) != 0)
5118                                 propstr = "-";
5119                         else
5120                                 propstr = property;
5121 
5122                         right_justify = zpool_prop_align_right(pl->pl_prop);
5123                 } else if ((zpool_prop_feature(pl->pl_user_prop) ||
5124                     zpool_prop_unsupported(pl->pl_user_prop)) &&
5125                     zpool_prop_get_feature(zhp, pl->pl_user_prop, property,
5126                     sizeof (property)) == 0) {
5127                         propstr = property;
5128                 } else {
5129                         propstr = "-";
5130                 }
5131 
5132 
5133                 /*
5134                  * If this is being called in scripted mode, or if this is the
5135                  * last column and it is left-justified, don't include a width
5136                  * format specifier.
5137                  */
5138                 if (cb->cb_scripted || (pl->pl_next == NULL && !right_justify))
5139                         (void) printf("%s", propstr);
5140                 else if (right_justify)
5141                         (void) printf("%*s", width, propstr);
5142                 else
5143                         (void) printf("%-*s", width, propstr);
5144         }
5145 
5146         (void) printf("\n");
5147 }
5148 
5149 static void
5150 print_one_column(zpool_prop_t prop, uint64_t value, boolean_t scripted,
5151     boolean_t valid)
5152 {
5153         char propval[64];
5154         boolean_t fixed;
5155         size_t width = zprop_width(prop, &fixed, ZFS_TYPE_POOL);
5156 
5157         switch (prop) {
5158         case ZPOOL_PROP_EXPANDSZ:
5159         case ZPOOL_PROP_CHECKPOINT:
5160                 if (value == 0)
5161                         (void) strlcpy(propval, "-", sizeof (propval));
5162                 else
5163                         zfs_nicenum(value, propval, sizeof (propval));
5164                 break;
5165         case ZPOOL_PROP_FRAGMENTATION:
5166                 if (value == ZFS_FRAG_INVALID) {
5167                         (void) strlcpy(propval, "-", sizeof (propval));
5168                 } else {
5169                         (void) snprintf(propval, sizeof (propval), "%llu%%",
5170                             value);
5171                 }
5172                 break;
5173         case ZPOOL_PROP_CAPACITY:
5174                 (void) snprintf(propval, sizeof (propval),
5175                     value < 1000 ? "%1.2f%%" : value < 10000 ?
5176                     "%2.1f%%" : "%3.0f%%", value / 100.0);
5177                 break;
5178         default:
5179                 zfs_nicenum(value, propval, sizeof (propval));
5180         }
5181 
5182         if (!valid)
5183                 (void) strlcpy(propval, "-", sizeof (propval));
5184 
5185         if (scripted)
5186                 (void) printf("\t%s", propval);
5187         else
5188                 (void) printf("  %*s", width, propval);
5189 }
5190 
5191 /*
5192  * print static default line per vdev
5193  */
5194 void
5195 print_list_stats(zpool_handle_t *zhp, const char *name, nvlist_t *nv,
5196     list_cbdata_t *cb, int depth)
5197 {
5198         nvlist_t **child;
5199         vdev_stat_t *vs;
5200         uint_t c, children;
5201         char *vname;
5202         boolean_t scripted = cb->cb_scripted;
5203         uint64_t islog = B_FALSE;
5204         char *dashes = "%-*s      -      -      -         -      -      -\n";
5205 
5206         verify(nvlist_lookup_uint64_array(nv, ZPOOL_CONFIG_VDEV_STATS,
5207             (uint64_t **)&vs, &c) == 0);
5208 
5209         if (name != NULL) {
5210                 boolean_t toplevel = (vs->vs_space != 0);
5211                 uint64_t cap;
5212 
5213                 if (strcmp(name, VDEV_TYPE_INDIRECT) == 0)
5214                         return;
5215 
5216                 if (scripted)
5217                         (void) printf("\t%s", name);
5218                 else if (strlen(name) + depth > cb->cb_namewidth)
5219                         (void) printf("%*s%s", depth, "", name);
5220                 else
5221                         (void) printf("%*s%s%*s", depth, "", name,
5222                             (int)(cb->cb_namewidth - strlen(name) - depth), "");
5223 
5224                 /*
5225                  * Print the properties for the individual vdevs. Some
5226                  * properties are only applicable to toplevel vdevs. The
5227                  * 'toplevel' boolean value is passed to the print_one_column()
5228                  * to indicate that the value is valid.
5229                  */
5230                 print_one_column(ZPOOL_PROP_SIZE, vs->vs_space, scripted,
5231                     toplevel);
5232                 print_one_column(ZPOOL_PROP_ALLOCATED, vs->vs_alloc, scripted,
5233                     toplevel);
5234                 print_one_column(ZPOOL_PROP_FREE, vs->vs_space - vs->vs_alloc,
5235                     scripted, toplevel);
5236                 print_one_column(ZPOOL_PROP_CHECKPOINT,
5237                     vs->vs_checkpoint_space, scripted, toplevel);
5238                 print_one_column(ZPOOL_PROP_EXPANDSZ, vs->vs_esize, scripted,
5239                     B_TRUE);
5240                 print_one_column(ZPOOL_PROP_FRAGMENTATION,
5241                     vs->vs_fragmentation, scripted,
5242                     (vs->vs_fragmentation != ZFS_FRAG_INVALID && toplevel));
5243                 cap = (vs->vs_space == 0) ? 0 :
5244                     (vs->vs_alloc * 10000 / vs->vs_space);
5245                 print_one_column(ZPOOL_PROP_CAPACITY, cap, scripted, toplevel);
5246                 (void) printf("\n");
5247         }
5248 
5249         if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
5250             &child, &children) != 0)
5251                 return;
5252 
5253         /* list the normal vdevs first */
5254         for (c = 0; c < children; c++) {
5255                 uint64_t ishole = B_FALSE;
5256 
5257                 if (nvlist_lookup_uint64(child[c],
5258                     ZPOOL_CONFIG_IS_HOLE, &ishole) == 0 && ishole)
5259                         continue;
5260 
5261                 if (nvlist_lookup_uint64(child[c],
5262                     ZPOOL_CONFIG_IS_LOG, &islog) == 0 && islog)
5263                         continue;
5264 
5265                 if (nvlist_exists(child[c], ZPOOL_CONFIG_ALLOCATION_BIAS))
5266                         continue;
5267 
5268                 vname = zpool_vdev_name(g_zfs, zhp, child[c],
5269                     cb->cb_name_flags);
5270                 print_list_stats(zhp, vname, child[c], cb, depth + 2);
5271                 free(vname);
5272         }
5273 
5274         /* list the classes: 'logs', 'dedup', and 'special' */
5275         for (uint_t n = 0; n < 3; n++) {
5276                 boolean_t printed = B_FALSE;
5277 
5278                 for (c = 0; c < children; c++) {
5279                         char *bias = NULL;
5280                         char *type = NULL;
5281 
5282                         if (nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_LOG,
5283                             &islog) == 0 && islog) {
5284                                 bias = VDEV_ALLOC_CLASS_LOGS;
5285                         } else {
5286                                 (void) nvlist_lookup_string(child[c],
5287                                     ZPOOL_CONFIG_ALLOCATION_BIAS, &bias);
5288                                 (void) nvlist_lookup_string(child[c],
5289                                     ZPOOL_CONFIG_TYPE, &type);
5290                         }
5291                         if (bias == NULL || strcmp(bias, class_name[n]) != 0)
5292                                 continue;
5293                         if (!islog && strcmp(type, VDEV_TYPE_INDIRECT) == 0)
5294                                 continue;
5295 
5296                         if (!printed) {
5297                                 /* LINTED E_SEC_PRINTF_VAR_FMT */
5298                                 (void) printf(dashes, cb->cb_namewidth,
5299                                     class_name[n]);
5300                                 printed = B_TRUE;
5301                         }
5302                         vname = zpool_vdev_name(g_zfs, zhp, child[c],
5303                             cb->cb_name_flags);
5304                         print_list_stats(zhp, vname, child[c], cb, depth + 2);
5305                         free(vname);
5306                 }
5307         }
5308 
5309         if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_L2CACHE,
5310             &child, &children) == 0 && children > 0) {
5311                 /* LINTED E_SEC_PRINTF_VAR_FMT */
5312                 (void) printf(dashes, cb->cb_namewidth, "cache");
5313                 for (c = 0; c < children; c++) {
5314                         vname = zpool_vdev_name(g_zfs, zhp, child[c],
5315                             cb->cb_name_flags);
5316                         print_list_stats(zhp, vname, child[c], cb, depth + 2);
5317                         free(vname);
5318                 }
5319         }
5320 
5321         if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_SPARES, &child,
5322             &children) == 0 && children > 0) {
5323                 /* LINTED E_SEC_PRINTF_VAR_FMT */
5324                 (void) printf(dashes, cb->cb_namewidth, "spare");
5325                 for (c = 0; c < children; c++) {
5326                         vname = zpool_vdev_name(g_zfs, zhp, child[c],
5327                             cb->cb_name_flags);
5328                         print_list_stats(zhp, vname, child[c], cb, depth + 2);
5329                         free(vname);
5330                 }
5331         }
5332 }
5333 
5334 /*
5335  * Generic callback function to list a pool.
5336  */
5337 int
5338 list_callback(zpool_handle_t *zhp, void *data)
5339 {
5340         list_cbdata_t *cbp = data;
5341         nvlist_t *config;
5342         nvlist_t *nvroot;
5343 
5344         config = zpool_get_config(zhp, NULL);
5345 
5346         if (cbp->cb_verbose) {
5347                 config = zpool_get_config(zhp, NULL);
5348 
5349                 verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
5350                     &nvroot) == 0);
5351         }
5352 
5353         if (cbp->cb_verbose)
5354                 cbp->cb_namewidth = max_width(zhp, nvroot, 0, 0,
5355                     cbp->cb_name_flags);
5356 
5357         print_pool(zhp, cbp);
5358 
5359         if (cbp->cb_verbose)
5360                 print_list_stats(zhp, NULL, nvroot, cbp, 0);
5361 
5362         return (0);
5363 }
5364 
5365 /*
5366  * Set the minimum pool/vdev name column width.  The width must be at least 9,
5367  * but may be as large as needed.
5368  */
5369 static int
5370 get_namewidth_list(zpool_handle_t *zhp, void *data)
5371 {
5372         list_cbdata_t *cb = data;
5373         int width;
5374 
5375         width = get_namewidth(zhp, cb->cb_namewidth, cb->cb_name_flags,
5376             cb->cb_verbose);
5377 
5378         if (width < 9)
5379                 width = 9;
5380 
5381         cb->cb_namewidth = width;
5382 
5383         return (0);
5384 }
5385 
5386 /*
5387  * zpool list [-gHLP] [-o prop[,prop]*] [-T d|u] [pool] ... [interval [count]]
5388  *
5389  *      -g      Display guid for individual vdev name.
5390  *      -H      Scripted mode.  Don't display headers, and separate properties
5391  *              by a single tab.
5392  *      -L      Follow links when resolving vdev path name.
5393  *      -o      List of properties to display.  Defaults to
5394  *              "name,size,allocated,free,expandsize,fragmentation,capacity,"
5395  *              "dedupratio,health,altroot"
5396  *      -p      Diplay values in parsable (exact) format.
5397  *      -P      Display full path for vdev name.
5398  *      -T      Display a timestamp in date(1) or Unix format
5399  *
5400  * List all pools in the system, whether or not they're healthy.  Output space
5401  * statistics for each one, as well as health status summary.
5402  */
5403 int
5404 zpool_do_list(int argc, char **argv)
5405 {
5406         int c;
5407         int ret;
5408         list_cbdata_t cb = { 0 };
5409         static char default_props[] =
5410             "name,size,allocated,free,checkpoint,expandsize,fragmentation,"
5411             "capacity,dedupratio,health,altroot";
5412         char *props = default_props;
5413         float interval = 0;
5414         unsigned long count = 0;
5415         zpool_list_t *list;
5416         boolean_t first = B_TRUE;
5417 
5418         /* check options */
5419         while ((c = getopt(argc, argv, ":gHLo:pPT:v")) != -1) {
5420                 switch (c) {
5421                 case 'g':
5422                         cb.cb_name_flags |= VDEV_NAME_GUID;
5423                         break;
5424                 case 'H':
5425                         cb.cb_scripted = B_TRUE;
5426                         break;
5427                 case 'L':
5428                         cb.cb_name_flags |= VDEV_NAME_FOLLOW_LINKS;
5429                         break;
5430                 case 'o':
5431                         props = optarg;
5432                         break;
5433                 case 'P':
5434                         cb.cb_name_flags |= VDEV_NAME_PATH;
5435                         break;
5436                 case 'p':
5437                         cb.cb_literal = B_TRUE;
5438                         break;
5439                 case 'T':
5440                         get_timestamp_arg(*optarg);
5441                         break;
5442                 case 'v':
5443                         cb.cb_verbose = B_TRUE;
5444                         cb.cb_namewidth = 8;    /* 8 until precalc is avail */
5445                         break;
5446                 case ':':
5447                         (void) fprintf(stderr, gettext("missing argument for "
5448                             "'%c' option\n"), optopt);
5449                         usage(B_FALSE);
5450                         break;
5451                 case '?':
5452                         (void) fprintf(stderr, gettext("invalid option '%c'\n"),
5453                             optopt);
5454                         usage(B_FALSE);
5455                 }
5456         }
5457 
5458         argc -= optind;
5459         argv += optind;
5460 
5461         get_interval_count(&argc, argv, &interval, &count);
5462 
5463         if (zprop_get_list(g_zfs, props, &cb.cb_proplist, ZFS_TYPE_POOL) != 0)
5464                 usage(B_FALSE);
5465 
5466         for (;;) {
5467                 if ((list = pool_list_get(argc, argv, &cb.cb_proplist,
5468                     &ret)) == NULL)
5469                         return (1);
5470 
5471                 if (pool_list_count(list) == 0)
5472                         break;
5473 
5474                 cb.cb_namewidth = 0;
5475                 (void) pool_list_iter(list, B_FALSE, get_namewidth_list, &cb);
5476 
5477                 if (timestamp_fmt != NODATE)
5478                         print_timestamp(timestamp_fmt);
5479 
5480                 if (!cb.cb_scripted && (first || cb.cb_verbose)) {
5481                         print_header(&cb);
5482                         first = B_FALSE;
5483                 }
5484                 ret = pool_list_iter(list, B_TRUE, list_callback, &cb);
5485 
5486                 if (interval == 0)
5487                         break;
5488 
5489                 if (count != 0 && --count == 0)
5490                         break;
5491 
5492                 pool_list_free(list);
5493                 (void) fsleep(interval);
5494         }
5495 
5496         if (argc == 0 && !cb.cb_scripted && pool_list_count(list) == 0) {
5497                 (void) printf(gettext("no pools available\n"));
5498                 ret = 0;
5499         }
5500 
5501         pool_list_free(list);
5502         zprop_free_list(cb.cb_proplist);
5503         return (ret);
5504 }
5505 
5506 static int
5507 zpool_do_attach_or_replace(int argc, char **argv, int replacing)
5508 {
5509         boolean_t force = B_FALSE;
5510         int c;
5511         nvlist_t *nvroot;
5512         char *poolname, *old_disk, *new_disk;
5513         zpool_handle_t *zhp;
5514         zpool_boot_label_t boot_type;
5515         uint64_t boot_size;
5516         nvlist_t *props = NULL;
5517         char *propval;
5518         int ret;
5519 
5520         /* check options */
5521         while ((c = getopt(argc, argv, "fo:")) != -1) {
5522                 switch (c) {
5523                 case 'f':
5524                         force = B_TRUE;
5525                         break;
5526                 case 'o':
5527                         if ((propval = strchr(optarg, '=')) == NULL) {
5528                                 (void) fprintf(stderr, gettext("missing "
5529                                     "'=' for -o option\n"));
5530                                 usage(B_FALSE);
5531                         }
5532                         *propval = '\0';
5533                         propval++;
5534 
5535                         if ((strcmp(optarg, ZPOOL_CONFIG_ASHIFT) != 0) ||
5536                             (add_prop_list(optarg, propval, &props, B_TRUE)))
5537                                 usage(B_FALSE);
5538                         break;
5539                 case '?':
5540                         (void) fprintf(stderr, gettext("invalid option '%c'\n"),
5541                             optopt);
5542                         usage(B_FALSE);
5543                 }
5544         }
5545 
5546         argc -= optind;
5547         argv += optind;
5548 
5549         /* get pool name and check number of arguments */
5550         if (argc < 1) {
5551                 (void) fprintf(stderr, gettext("missing pool name argument\n"));
5552                 usage(B_FALSE);
5553         }
5554 
5555         poolname = argv[0];
5556 
5557         if (argc < 2) {
5558                 (void) fprintf(stderr,
5559                     gettext("missing <device> specification\n"));
5560                 usage(B_FALSE);
5561         }
5562 
5563         old_disk = argv[1];
5564 
5565         if (argc < 3) {
5566                 if (!replacing) {
5567                         (void) fprintf(stderr,
5568                             gettext("missing <new_device> specification\n"));
5569                         usage(B_FALSE);
5570                 }
5571                 new_disk = old_disk;
5572                 argc -= 1;
5573                 argv += 1;
5574         } else {
5575                 new_disk = argv[2];
5576                 argc -= 2;
5577                 argv += 2;
5578         }
5579 
5580         if (argc > 1) {
5581                 (void) fprintf(stderr, gettext("too many arguments\n"));
5582                 usage(B_FALSE);
5583         }
5584 
5585         if ((zhp = zpool_open(g_zfs, poolname)) == NULL)
5586                 return (1);
5587 
5588         if (zpool_get_config(zhp, NULL) == NULL) {
5589                 (void) fprintf(stderr, gettext("pool '%s' is unavailable\n"),
5590                     poolname);
5591                 zpool_close(zhp);
5592                 return (1);
5593         }
5594 
5595         if (zpool_is_bootable(zhp))
5596                 boot_type = ZPOOL_COPY_BOOT_LABEL;
5597         else
5598                 boot_type = ZPOOL_NO_BOOT_LABEL;
5599 
5600         boot_size = zpool_get_prop_int(zhp, ZPOOL_PROP_BOOTSIZE, NULL);
5601 
5602         /* unless manually specified use "ashift" pool property (if set) */
5603         if (!nvlist_exists(props, ZPOOL_CONFIG_ASHIFT)) {
5604                 int intval;
5605                 zprop_source_t src;
5606                 char strval[ZPOOL_MAXPROPLEN];
5607 
5608                 intval = zpool_get_prop_int(zhp, ZPOOL_PROP_ASHIFT, &src);
5609                 if (src != ZPROP_SRC_DEFAULT) {
5610                         (void) sprintf(strval, "%" PRId32, intval);
5611                         verify(add_prop_list(ZPOOL_CONFIG_ASHIFT, strval,
5612                             &props, B_TRUE) == 0);
5613                 }
5614         }
5615 
5616         nvroot = make_root_vdev(zhp, props, force, B_FALSE, replacing, B_FALSE,
5617             boot_type, boot_size, argc, argv);
5618         if (nvroot == NULL) {
5619                 zpool_close(zhp);
5620                 return (1);
5621         }
5622 
5623         ret = zpool_vdev_attach(zhp, old_disk, new_disk, nvroot, replacing);
5624 
5625         nvlist_free(nvroot);
5626         zpool_close(zhp);
5627 
5628         return (ret);
5629 }
5630 
5631 /*
5632  * zpool replace [-f] <pool> <device> <new_device>
5633  *
5634  *      -f      Force attach, even if <new_device> appears to be in use.
5635  *
5636  * Replace <device> with <new_device>.
5637  */
5638 /* ARGSUSED */
5639 int
5640 zpool_do_replace(int argc, char **argv)
5641 {
5642         return (zpool_do_attach_or_replace(argc, argv, B_TRUE));
5643 }
5644 
5645 /*
5646  * zpool attach [-f] [-o property=value] <pool> <device> <new_device>
5647  *
5648  *      -f      Force attach, even if <new_device> appears to be in use.
5649  *      -o      Set property=value.
5650  *
5651  * Attach <new_device> to the mirror containing <device>.  If <device> is not
5652  * part of a mirror, then <device> will be transformed into a mirror of
5653  * <device> and <new_device>.  In either case, <new_device> will begin life
5654  * with a DTL of [0, now], and will immediately begin to resilver itself.
5655  */
5656 int
5657 zpool_do_attach(int argc, char **argv)
5658 {
5659         return (zpool_do_attach_or_replace(argc, argv, B_FALSE));
5660 }
5661 
5662 /*
5663  * zpool detach [-f] <pool> <device>
5664  *
5665  *      -f      Force detach of <device>, even if DTLs argue against it
5666  *              (not supported yet)
5667  *
5668  * Detach a device from a mirror.  The operation will be refused if <device>
5669  * is the last device in the mirror, or if the DTLs indicate that this device
5670  * has the only valid copy of some data.
5671  */
5672 /* ARGSUSED */
5673 int
5674 zpool_do_detach(int argc, char **argv)
5675 {
5676         int c;
5677         char *poolname, *path;
5678         zpool_handle_t *zhp;
5679         int ret;
5680 
5681         /* check options */
5682         while ((c = getopt(argc, argv, "f")) != -1) {
5683                 switch (c) {
5684                 case 'f':
5685                 case '?':
5686                         (void) fprintf(stderr, gettext("invalid option '%c'\n"),
5687                             optopt);
5688                         usage(B_FALSE);
5689                 }
5690         }
5691 
5692         argc -= optind;
5693         argv += optind;
5694 
5695         /* get pool name and check number of arguments */
5696         if (argc < 1) {
5697                 (void) fprintf(stderr, gettext("missing pool name argument\n"));
5698                 usage(B_FALSE);
5699         }
5700 
5701         if (argc < 2) {
5702                 (void) fprintf(stderr,
5703                     gettext("missing <device> specification\n"));
5704                 usage(B_FALSE);
5705         }
5706 
5707         poolname = argv[0];
5708         path = argv[1];
5709 
5710         if ((zhp = zpool_open(g_zfs, poolname)) == NULL)
5711                 return (1);
5712 
5713         ret = zpool_vdev_detach(zhp, path);
5714 
5715         zpool_close(zhp);
5716 
5717         return (ret);
5718 }
5719 
5720 /*
5721  * zpool split [-gLnP] [-o prop=val] ...
5722  *              [-o mntopt] ...
5723  *              [-R altroot] <pool> <newpool> [<device> ...]
5724  *
5725  *      -g      Display guid for individual vdev name.
5726  *      -L      Follow links when resolving vdev path name.
5727  *      -n      Do not split the pool, but display the resulting layout if
5728  *              it were to be split.
5729  *      -o      Set property=value, or set mount options.
5730  *      -P      Display full path for vdev name.
5731  *      -R      Mount the split-off pool under an alternate root.
5732  *      -l      Load encryption keys while importing.
5733  *
5734  * Splits the named pool and gives it the new pool name.  Devices to be split
5735  * off may be listed, provided that no more than one device is specified
5736  * per top-level vdev mirror.  The newly split pool is left in an exported
5737  * state unless -R is specified.
5738  *
5739  * Restrictions: the top-level of the pool pool must only be made up of
5740  * mirrors; all devices in the pool must be healthy; no device may be
5741  * undergoing a resilvering operation.
5742  */
5743 int
5744 zpool_do_split(int argc, char **argv)
5745 {
5746         char *srcpool, *newpool, *propval;
5747         char *mntopts = NULL;
5748         splitflags_t flags;
5749         int c, ret = 0;
5750         boolean_t loadkeys = B_FALSE;
5751         zpool_handle_t *zhp;
5752         nvlist_t *config, *props = NULL;
5753 
5754         flags.dryrun = B_FALSE;
5755         flags.import = B_FALSE;
5756         flags.name_flags = 0;
5757 
5758         /* check options */
5759         while ((c = getopt(argc, argv, ":gLR:lno:P")) != -1) {
5760                 switch (c) {
5761                 case 'g':
5762                         flags.name_flags |= VDEV_NAME_GUID;
5763                         break;
5764                 case 'L':
5765                         flags.name_flags |= VDEV_NAME_FOLLOW_LINKS;
5766                         break;
5767                 case 'R':
5768                         flags.import = B_TRUE;
5769                         if (add_prop_list(
5770                             zpool_prop_to_name(ZPOOL_PROP_ALTROOT), optarg,
5771                             &props, B_TRUE) != 0) {
5772                                 nvlist_free(props);
5773                                 usage(B_FALSE);
5774                         }
5775                         break;
5776                 case 'l':
5777                         loadkeys = B_TRUE;
5778                         break;
5779                 case 'n':
5780                         flags.dryrun = B_TRUE;
5781                         break;
5782                 case 'o':
5783                         if ((propval = strchr(optarg, '=')) != NULL) {
5784                                 *propval = '\0';
5785                                 propval++;
5786                                 if (add_prop_list(optarg, propval,
5787                                     &props, B_TRUE) != 0) {
5788                                         nvlist_free(props);
5789                                         usage(B_FALSE);
5790                                 }
5791                         } else {
5792                                 mntopts = optarg;
5793                         }
5794                         break;
5795                 case 'P':
5796                         flags.name_flags |= VDEV_NAME_PATH;
5797                         break;
5798                 case ':':
5799                         (void) fprintf(stderr, gettext("missing argument for "
5800                             "'%c' option\n"), optopt);
5801                         usage(B_FALSE);
5802                         break;
5803                 case '?':
5804                         (void) fprintf(stderr, gettext("invalid option '%c'\n"),
5805                             optopt);
5806                         usage(B_FALSE);
5807                         break;
5808                 }
5809         }
5810 
5811         if (!flags.import && mntopts != NULL) {
5812                 (void) fprintf(stderr, gettext("setting mntopts is only "
5813                     "valid when importing the pool\n"));
5814                 usage(B_FALSE);
5815         }
5816 
5817         if (!flags.import && loadkeys) {
5818                 (void) fprintf(stderr, gettext("loading keys is only "
5819                     "valid when importing the pool\n"));
5820                 usage(B_FALSE);
5821         }
5822 
5823         argc -= optind;
5824         argv += optind;
5825 
5826         if (argc < 1) {
5827                 (void) fprintf(stderr, gettext("Missing pool name\n"));
5828                 usage(B_FALSE);
5829         }
5830         if (argc < 2) {
5831                 (void) fprintf(stderr, gettext("Missing new pool name\n"));
5832                 usage(B_FALSE);
5833         }
5834 
5835         srcpool = argv[0];
5836         newpool = argv[1];
5837 
5838         argc -= 2;
5839         argv += 2;
5840 
5841         if ((zhp = zpool_open(g_zfs, srcpool)) == NULL)
5842                 return (1);
5843 
5844         config = split_mirror_vdev(zhp, newpool, props, flags, argc, argv);
5845         if (config == NULL) {
5846                 ret = 1;
5847         } else {
5848                 if (flags.dryrun) {
5849                         (void) printf(gettext("would create '%s' with the "
5850                             "following layout:\n\n"), newpool);
5851                         print_vdev_tree(NULL, newpool, config, 0, "",
5852                             flags.name_flags);
5853                 }
5854                 nvlist_free(config);
5855         }
5856 
5857         zpool_close(zhp);
5858 
5859         if (ret != 0 || flags.dryrun || !flags.import)
5860                 return (ret);
5861 
5862         /*
5863          * The split was successful. Now we need to open the new
5864          * pool and import it.
5865          */
5866         if ((zhp = zpool_open_canfail(g_zfs, newpool)) == NULL)
5867                 return (1);
5868 
5869         if (loadkeys) {
5870                 ret = zfs_crypto_attempt_load_keys(g_zfs, newpool);
5871                 if (ret != 0)
5872                         ret = 1;
5873         }
5874 
5875         if (zpool_get_state(zhp) != POOL_STATE_UNAVAIL &&
5876             zpool_enable_datasets(zhp, mntopts, 0) != 0) {
5877                 ret = 1;
5878                 (void) fprintf(stderr, gettext("Split was successful, but "
5879                     "the datasets could not all be mounted\n"));
5880                 (void) fprintf(stderr, gettext("Try doing '%s' with a "
5881                     "different altroot\n"), "zpool import");
5882         }
5883         zpool_close(zhp);
5884 
5885         return (ret);
5886 }
5887 
5888 
5889 
5890 /*
5891  * zpool online <pool> <device> ...
5892  */
5893 int
5894 zpool_do_online(int argc, char **argv)
5895 {
5896         int c, i;
5897         char *poolname;
5898         zpool_handle_t *zhp;
5899         int ret = 0;
5900         vdev_state_t newstate;
5901         int flags = 0;
5902 
5903         /* check options */
5904         while ((c = getopt(argc, argv, "et")) != -1) {
5905                 switch (c) {
5906                 case 'e':
5907                         flags |= ZFS_ONLINE_EXPAND;
5908                         break;
5909                 case 't':
5910                 case '?':
5911                         (void) fprintf(stderr, gettext("invalid option '%c'\n"),
5912                             optopt);
5913                         usage(B_FALSE);
5914                 }
5915         }
5916 
5917         argc -= optind;
5918         argv += optind;
5919 
5920         /* get pool name and check number of arguments */
5921         if (argc < 1) {
5922                 (void) fprintf(stderr, gettext("missing pool name\n"));
5923                 usage(B_FALSE);
5924         }
5925         if (argc < 2) {
5926                 (void) fprintf(stderr, gettext("missing device name\n"));
5927                 usage(B_FALSE);
5928         }
5929 
5930         poolname = argv[0];
5931 
5932         if ((zhp = zpool_open(g_zfs, poolname)) == NULL)
5933                 return (1);
5934 
5935         for (i = 1; i < argc; i++) {
5936                 if (zpool_vdev_online(zhp, argv[i], flags, &newstate) == 0) {
5937                         if (newstate != VDEV_STATE_HEALTHY) {
5938                                 (void) printf(gettext("warning: device '%s' "
5939                                     "onlined, but remains in faulted state\n"),
5940                                     argv[i]);
5941                                 if (newstate == VDEV_STATE_FAULTED)
5942                                         (void) printf(gettext("use 'zpool "
5943                                             "clear' to restore a faulted "
5944                                             "device\n"));
5945                                 else
5946                                         (void) printf(gettext("use 'zpool "
5947                                             "replace' to replace devices "
5948                                             "that are no longer present\n"));
5949                         }
5950                 } else {
5951                         ret = 1;
5952                 }
5953         }
5954 
5955         zpool_close(zhp);
5956 
5957         return (ret);
5958 }
5959 
5960 /*
5961  * zpool offline [-ft] <pool> <device> ...
5962  *
5963  *      -f      Force the device into the offline state, even if doing
5964  *              so would appear to compromise pool availability.
5965  *              (not supported yet)
5966  *
5967  *      -t      Only take the device off-line temporarily.  The offline
5968  *              state will not be persistent across reboots.
5969  */
5970 /* ARGSUSED */
5971 int
5972 zpool_do_offline(int argc, char **argv)
5973 {
5974         int c, i;
5975         char *poolname;
5976         zpool_handle_t *zhp;
5977         int ret = 0;
5978         boolean_t istmp = B_FALSE;
5979 
5980         /* check options */
5981         while ((c = getopt(argc, argv, "ft")) != -1) {
5982                 switch (c) {
5983                 case 't':
5984                         istmp = B_TRUE;
5985                         break;
5986                 case 'f':
5987                 case '?':
5988                         (void) fprintf(stderr, gettext("invalid option '%c'\n"),
5989                             optopt);
5990                         usage(B_FALSE);
5991                 }
5992         }
5993 
5994         argc -= optind;
5995         argv += optind;
5996 
5997         /* get pool name and check number of arguments */
5998         if (argc < 1) {
5999                 (void) fprintf(stderr, gettext("missing pool name\n"));
6000                 usage(B_FALSE);
6001         }
6002         if (argc < 2) {
6003                 (void) fprintf(stderr, gettext("missing device name\n"));
6004                 usage(B_FALSE);
6005         }
6006 
6007         poolname = argv[0];
6008 
6009         if ((zhp = zpool_open(g_zfs, poolname)) == NULL)
6010                 return (1);
6011 
6012         for (i = 1; i < argc; i++) {
6013                 if (zpool_vdev_offline(zhp, argv[i], istmp) != 0)
6014                         ret = 1;
6015         }
6016 
6017         zpool_close(zhp);
6018 
6019         return (ret);
6020 }
6021 
6022 /*
6023  * zpool clear <pool> [device]
6024  *
6025  * Clear all errors associated with a pool or a particular device.
6026  */
6027 int
6028 zpool_do_clear(int argc, char **argv)
6029 {
6030         int c;
6031         int ret = 0;
6032         boolean_t dryrun = B_FALSE;
6033         boolean_t do_rewind = B_FALSE;
6034         boolean_t xtreme_rewind = B_FALSE;
6035         uint32_t rewind_policy = ZPOOL_NO_REWIND;
6036         nvlist_t *policy = NULL;
6037         zpool_handle_t *zhp;
6038         char *pool, *device;
6039 
6040         /* check options */
6041         while ((c = getopt(argc, argv, "FnX")) != -1) {
6042                 switch (c) {
6043                 case 'F':
6044                         do_rewind = B_TRUE;
6045                         break;
6046                 case 'n':
6047                         dryrun = B_TRUE;
6048                         break;
6049                 case 'X':
6050                         xtreme_rewind = B_TRUE;
6051                         break;
6052                 case '?':
6053                         (void) fprintf(stderr, gettext("invalid option '%c'\n"),
6054                             optopt);
6055                         usage(B_FALSE);
6056                 }
6057         }
6058 
6059         argc -= optind;
6060         argv += optind;
6061 
6062         if (argc < 1) {
6063                 (void) fprintf(stderr, gettext("missing pool name\n"));
6064                 usage(B_FALSE);
6065         }
6066 
6067         if (argc > 2) {
6068                 (void) fprintf(stderr, gettext("too many arguments\n"));
6069                 usage(B_FALSE);
6070         }
6071 
6072         if ((dryrun || xtreme_rewind) && !do_rewind) {
6073                 (void) fprintf(stderr,
6074                     gettext("-n or -X only meaningful with -F\n"));
6075                 usage(B_FALSE);
6076         }
6077         if (dryrun)
6078                 rewind_policy = ZPOOL_TRY_REWIND;
6079         else if (do_rewind)
6080                 rewind_policy = ZPOOL_DO_REWIND;
6081         if (xtreme_rewind)
6082                 rewind_policy |= ZPOOL_EXTREME_REWIND;
6083 
6084         /* In future, further rewind policy choices can be passed along here */
6085         if (nvlist_alloc(&policy, NV_UNIQUE_NAME, 0) != 0 ||
6086             nvlist_add_uint32(policy, ZPOOL_LOAD_REWIND_POLICY,
6087             rewind_policy) != 0) {
6088                 return (1);
6089         }
6090 
6091         pool = argv[0];
6092         device = argc == 2 ? argv[1] : NULL;
6093 
6094         if ((zhp = zpool_open_canfail(g_zfs, pool)) == NULL) {
6095                 nvlist_free(policy);
6096                 return (1);
6097         }
6098 
6099         if (zpool_clear(zhp, device, policy) != 0)
6100                 ret = 1;
6101 
6102         zpool_close(zhp);
6103 
6104         nvlist_free(policy);
6105 
6106         return (ret);
6107 }
6108 
6109 /*
6110  * zpool reguid <pool>
6111  */
6112 int
6113 zpool_do_reguid(int argc, char **argv)
6114 {
6115         int c;
6116         char *poolname;
6117         zpool_handle_t *zhp;
6118         int ret = 0;
6119 
6120         /* check options */
6121         while ((c = getopt(argc, argv, "")) != -1) {
6122                 switch (c) {
6123                 case '?':
6124                         (void) fprintf(stderr, gettext("invalid option '%c'\n"),
6125                             optopt);
6126                         usage(B_FALSE);
6127                 }
6128         }
6129 
6130         argc -= optind;
6131         argv += optind;
6132 
6133         /* get pool name and check number of arguments */
6134         if (argc < 1) {
6135                 (void) fprintf(stderr, gettext("missing pool name\n"));
6136                 usage(B_FALSE);
6137         }
6138 
6139         if (argc > 1) {
6140                 (void) fprintf(stderr, gettext("too many arguments\n"));
6141                 usage(B_FALSE);
6142         }
6143 
6144         poolname = argv[0];
6145         if ((zhp = zpool_open(g_zfs, poolname)) == NULL)
6146                 return (1);
6147 
6148         ret = zpool_reguid(zhp);
6149 
6150         zpool_close(zhp);
6151         return (ret);
6152 }
6153 
6154 
6155 /*
6156  * zpool reopen <pool>
6157  *
6158  * Reopen the pool so that the kernel can update the sizes of all vdevs.
6159  */
6160 int
6161 zpool_do_reopen(int argc, char **argv)
6162 {
6163         int c;
6164         int ret = 0;
6165         zpool_handle_t *zhp;
6166         char *pool;
6167 
6168         /* check options */
6169         while ((c = getopt(argc, argv, "")) != -1) {
6170                 switch (c) {
6171                 case '?':
6172                         (void) fprintf(stderr, gettext("invalid option '%c'\n"),
6173                             optopt);
6174                         usage(B_FALSE);
6175                 }
6176         }
6177 
6178         argc--;
6179         argv++;
6180 
6181         if (argc < 1) {
6182                 (void) fprintf(stderr, gettext("missing pool name\n"));
6183                 usage(B_FALSE);
6184         }
6185 
6186         if (argc > 1) {
6187                 (void) fprintf(stderr, gettext("too many arguments\n"));
6188                 usage(B_FALSE);
6189         }
6190 
6191         pool = argv[0];
6192         if ((zhp = zpool_open_canfail(g_zfs, pool)) == NULL)
6193                 return (1);
6194 
6195         ret = zpool_reopen(zhp);
6196         zpool_close(zhp);
6197         return (ret);
6198 }
6199 
6200 typedef struct scrub_cbdata {
6201         int     cb_type;
6202         int     cb_argc;
6203         char    **cb_argv;
6204         pool_scrub_cmd_t cb_scrub_cmd;
6205 } scrub_cbdata_t;
6206 
6207 static boolean_t
6208 zpool_has_checkpoint(zpool_handle_t *zhp)
6209 {
6210         nvlist_t *config, *nvroot;
6211 
6212         config = zpool_get_config(zhp, NULL);
6213 
6214         if (config != NULL) {
6215                 pool_checkpoint_stat_t *pcs = NULL;
6216                 uint_t c;
6217 
6218                 nvroot = fnvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE);
6219                 (void) nvlist_lookup_uint64_array(nvroot,
6220                     ZPOOL_CONFIG_CHECKPOINT_STATS, (uint64_t **)&pcs, &c);
6221 
6222                 if (pcs == NULL || pcs->pcs_state == CS_NONE)
6223                         return (B_FALSE);
6224 
6225                 assert(pcs->pcs_state == CS_CHECKPOINT_EXISTS ||
6226                     pcs->pcs_state == CS_CHECKPOINT_DISCARDING);
6227                 return (B_TRUE);
6228         }
6229 
6230         return (B_FALSE);
6231 }
6232 
6233 int
6234 scrub_callback(zpool_handle_t *zhp, void *data)
6235 {
6236         scrub_cbdata_t *cb = data;
6237         int err;
6238 
6239         /*
6240          * Ignore faulted pools.
6241          */
6242         if (zpool_get_state(zhp) == POOL_STATE_UNAVAIL) {
6243                 (void) fprintf(stderr, gettext("cannot scan '%s': pool is "
6244                     "currently unavailable\n"), zpool_get_name(zhp));
6245                 return (1);
6246         }
6247 
6248         err = zpool_scan(zhp, cb->cb_type, cb->cb_scrub_cmd);
6249 
6250         if (err == 0 && zpool_has_checkpoint(zhp) &&
6251             cb->cb_type == POOL_SCAN_SCRUB) {
6252                 (void) printf(gettext("warning: will not scrub state that "
6253                     "belongs to the checkpoint of pool '%s'\n"),
6254                     zpool_get_name(zhp));
6255         }
6256 
6257         return (err != 0);
6258 }
6259 
6260 /*
6261  * zpool scrub [-s | -p] <pool> ...
6262  *
6263  *      -s      Stop.  Stops any in-progress scrub.
6264  *      -p      Pause. Pause in-progress scrub.
6265  */
6266 int
6267 zpool_do_scrub(int argc, char **argv)
6268 {
6269         int c;
6270         scrub_cbdata_t cb;
6271 
6272         cb.cb_type = POOL_SCAN_SCRUB;
6273         cb.cb_scrub_cmd = POOL_SCRUB_NORMAL;
6274 
6275         /* check options */
6276         while ((c = getopt(argc, argv, "sp")) != -1) {
6277                 switch (c) {
6278                 case 's':
6279                         cb.cb_type = POOL_SCAN_NONE;
6280                         break;
6281                 case 'p':
6282                         cb.cb_scrub_cmd = POOL_SCRUB_PAUSE;
6283                         break;
6284                 case '?':
6285                         (void) fprintf(stderr, gettext("invalid option '%c'\n"),
6286                             optopt);
6287                         usage(B_FALSE);
6288                 }
6289         }
6290 
6291         if (cb.cb_type == POOL_SCAN_NONE &&
6292             cb.cb_scrub_cmd == POOL_SCRUB_PAUSE) {
6293                 (void) fprintf(stderr, gettext("invalid option combination: "
6294                     "-s and -p are mutually exclusive\n"));
6295                 usage(B_FALSE);
6296         }
6297 
6298         cb.cb_argc = argc;
6299         cb.cb_argv = argv;
6300         argc -= optind;
6301         argv += optind;
6302 
6303         if (argc < 1) {
6304                 (void) fprintf(stderr, gettext("missing pool name argument\n"));
6305                 usage(B_FALSE);
6306         }
6307 
6308         return (for_each_pool(argc, argv, B_TRUE, NULL, scrub_callback, &cb));
6309 }
6310 
6311 /*
6312  * zpool resilver <pool> ...
6313  *
6314  *      Restarts any in-progress resilver
6315  */
6316 int
6317 zpool_do_resilver(int argc, char **argv)
6318 {
6319         int c;
6320         scrub_cbdata_t cb;
6321 
6322         cb.cb_type = POOL_SCAN_RESILVER;
6323         cb.cb_scrub_cmd = POOL_SCRUB_NORMAL;
6324         cb.cb_argc = argc;
6325         cb.cb_argv = argv;
6326 
6327         /* check options */
6328         while ((c = getopt(argc, argv, "")) != -1) {
6329                 switch (c) {
6330                 case '?':
6331                         (void) fprintf(stderr, gettext("invalid option '%c'\n"),
6332                             optopt);
6333                         usage(B_FALSE);
6334                 }
6335         }
6336 
6337         argc -= optind;
6338         argv += optind;
6339 
6340         if (argc < 1) {
6341                 (void) fprintf(stderr, gettext("missing pool name argument\n"));
6342                 usage(B_FALSE);
6343         }
6344 
6345         return (for_each_pool(argc, argv, B_TRUE, NULL, scrub_callback, &cb));
6346 }
6347 
6348 /*
6349  * zpool trim [-d] [-r <rate>] [-c | -s] <pool> [<device> ...]
6350  *
6351  *      -c              Cancel. Ends any in-progress trim.
6352  *      -d              Secure trim.  Requires kernel and device support.
6353  *      -r <rate> Sets the TRIM rate in bytes (per second). Supports
6354  *                      adding a multiplier suffix such as 'k' or 'm'.
6355  *      -s              Suspend. TRIM can then be restarted with no flags.
6356  */
6357 int
6358 zpool_do_trim(int argc, char **argv)
6359 {
6360         struct option long_options[] = {
6361                 {"cancel",      no_argument,            NULL,   'c'},
6362                 {"secure",      no_argument,            NULL,   'd'},
6363                 {"rate",        required_argument,      NULL,   'r'},
6364                 {"suspend",     no_argument,            NULL,   's'},
6365                 {0, 0, 0, 0}
6366         };
6367 
6368         pool_trim_func_t cmd_type = POOL_TRIM_START;
6369         uint64_t rate = 0;
6370         boolean_t secure = B_FALSE;
6371 
6372         int c;
6373         while ((c = getopt_long(argc, argv, "cdr:s", long_options, NULL))
6374             != -1) {
6375                 switch (c) {
6376                 case 'c':
6377                         if (cmd_type != POOL_TRIM_START &&
6378                             cmd_type != POOL_TRIM_CANCEL) {
6379                                 (void) fprintf(stderr, gettext("-c cannot be "
6380                                     "combined with other options\n"));
6381                                 usage(B_FALSE);
6382                         }
6383                         cmd_type = POOL_TRIM_CANCEL;
6384                         break;
6385                 case 'd':
6386                         if (cmd_type != POOL_TRIM_START) {
6387                                 (void) fprintf(stderr, gettext("-d cannot be "
6388                                     "combined with the -c or -s options\n"));
6389                                 usage(B_FALSE);
6390                         }
6391                         secure = B_TRUE;
6392                         break;
6393                 case 'r':
6394                         if (cmd_type != POOL_TRIM_START) {
6395                                 (void) fprintf(stderr, gettext("-r cannot be "
6396                                     "combined with the -c or -s options\n"));
6397                                 usage(B_FALSE);
6398                         }
6399                         if (zfs_nicestrtonum(NULL, optarg, &rate) == -1) {
6400                                 (void) fprintf(stderr,
6401                                     gettext("invalid value for rate\n"));
6402                                 usage(B_FALSE);
6403                         }
6404                         break;
6405                 case 's':
6406                         if (cmd_type != POOL_TRIM_START &&
6407                             cmd_type != POOL_TRIM_SUSPEND) {
6408                                 (void) fprintf(stderr, gettext("-s cannot be "
6409                                     "combined with other options\n"));
6410                                 usage(B_FALSE);
6411                         }
6412                         cmd_type = POOL_TRIM_SUSPEND;
6413                         break;
6414                 case '?':
6415                         if (optopt != 0) {
6416                                 (void) fprintf(stderr,
6417                                     gettext("invalid option '%c'\n"), optopt);
6418                         } else {
6419                                 (void) fprintf(stderr,
6420                                     gettext("invalid option '%s'\n"),
6421                                     argv[optind - 1]);
6422                         }
6423                         usage(B_FALSE);
6424                 }
6425         }
6426 
6427         argc -= optind;
6428         argv += optind;
6429 
6430         if (argc < 1) {
6431                 (void) fprintf(stderr, gettext("missing pool name argument\n"));
6432                 usage(B_FALSE);
6433                 return (-1);
6434         }
6435 
6436         char *poolname = argv[0];
6437         zpool_handle_t *zhp = zpool_open(g_zfs, poolname);
6438         if (zhp == NULL)
6439                 return (-1);
6440 
6441         trimflags_t trim_flags = {
6442                 .secure = secure,
6443                 .rate = rate,
6444         };
6445 
6446         nvlist_t *vdevs = fnvlist_alloc();
6447         if (argc == 1) {
6448                 /* no individual leaf vdevs specified, so add them all */
6449                 nvlist_t *config = zpool_get_config(zhp, NULL);
6450                 nvlist_t *nvroot = fnvlist_lookup_nvlist(config,
6451                     ZPOOL_CONFIG_VDEV_TREE);
6452                 zpool_collect_leaves(zhp, nvroot, vdevs);
6453                 trim_flags.fullpool = B_TRUE;
6454         } else {
6455                 trim_flags.fullpool = B_FALSE;
6456                 for (int i = 1; i < argc; i++) {
6457                         fnvlist_add_boolean(vdevs, argv[i]);
6458                 }
6459         }
6460 
6461         int error = zpool_trim(zhp, cmd_type, vdevs, &trim_flags);
6462 
6463         fnvlist_free(vdevs);
6464         zpool_close(zhp);
6465 
6466         return (error);
6467 }
6468 
6469 /*
6470  * zpool initialize [-c | -s] <pool> [<vdev> ...]
6471  * Initialize all unused blocks in the specified vdevs, or all vdevs in the pool
6472  * if none specified.
6473  *
6474  *      -c      Cancel. Ends active initializing.
6475  *      -s      Suspend. Initializing can then be restarted with no flags.
6476  */
6477 int
6478 zpool_do_initialize(int argc, char **argv)
6479 {
6480         int c;
6481         char *poolname;
6482         zpool_handle_t *zhp;
6483         nvlist_t *vdevs;
6484         int err = 0;
6485 
6486         struct option long_options[] = {
6487                 {"cancel",      no_argument,            NULL, 'c'},
6488                 {"suspend",     no_argument,            NULL, 's'},
6489                 {0, 0, 0, 0}
6490         };
6491 
6492         pool_initialize_func_t cmd_type = POOL_INITIALIZE_START;
6493         while ((c = getopt_long(argc, argv, "cs", long_options, NULL)) != -1) {
6494                 switch (c) {
6495                 case 'c':
6496                         if (cmd_type != POOL_INITIALIZE_START &&
6497                             cmd_type != POOL_INITIALIZE_CANCEL) {
6498                                 (void) fprintf(stderr, gettext("-c cannot be "
6499                                     "combined with other options\n"));
6500                                 usage(B_FALSE);
6501                         }
6502                         cmd_type = POOL_INITIALIZE_CANCEL;
6503                         break;
6504                 case 's':
6505                         if (cmd_type != POOL_INITIALIZE_START &&
6506                             cmd_type != POOL_INITIALIZE_SUSPEND) {
6507                                 (void) fprintf(stderr, gettext("-s cannot be "
6508                                     "combined with other options\n"));
6509                                 usage(B_FALSE);
6510                         }
6511                         cmd_type = POOL_INITIALIZE_SUSPEND;
6512                         break;
6513                 case '?':
6514                         if (optopt != 0) {
6515                                 (void) fprintf(stderr,
6516                                     gettext("invalid option '%c'\n"), optopt);
6517                         } else {
6518                                 (void) fprintf(stderr,
6519                                     gettext("invalid option '%s'\n"),
6520                                     argv[optind - 1]);
6521                         }
6522                         usage(B_FALSE);
6523                 }
6524         }
6525 
6526         argc -= optind;
6527         argv += optind;
6528 
6529         if (argc < 1) {
6530                 (void) fprintf(stderr, gettext("missing pool name argument\n"));
6531                 usage(B_FALSE);
6532                 return (-1);
6533         }
6534 
6535         poolname = argv[0];
6536         zhp = zpool_open(g_zfs, poolname);
6537         if (zhp == NULL)
6538                 return (-1);
6539 
6540         vdevs = fnvlist_alloc();
6541         if (argc == 1) {
6542                 /* no individual leaf vdevs specified, so add them all */
6543                 nvlist_t *config = zpool_get_config(zhp, NULL);
6544                 nvlist_t *nvroot = fnvlist_lookup_nvlist(config,
6545                     ZPOOL_CONFIG_VDEV_TREE);
6546                 zpool_collect_leaves(zhp, nvroot, vdevs);
6547         } else {
6548                 for (int i = 1; i < argc; i++) {
6549                         fnvlist_add_boolean(vdevs, argv[i]);
6550                 }
6551         }
6552 
6553         err = zpool_initialize(zhp, cmd_type, vdevs);
6554 
6555         fnvlist_free(vdevs);
6556         zpool_close(zhp);
6557 
6558         return (err);
6559 }
6560 
6561 /*
6562  * Print out detailed scrub status.
6563  */
6564 static void
6565 print_scan_status(pool_scan_stat_t *ps)
6566 {
6567         time_t start, end, pause;
6568         uint64_t total_secs_left;
6569         uint64_t elapsed, secs_left, mins_left, hours_left, days_left;
6570         uint64_t pass_scanned, scanned, pass_issued, issued, total;
6571         uint_t scan_rate, issue_rate;
6572         double fraction_done;
6573         char processed_buf[7], scanned_buf[7], issued_buf[7], total_buf[7];
6574         char srate_buf[7], irate_buf[7];
6575 
6576         (void) printf(gettext("  scan: "));
6577 
6578         /* If there's never been a scan, there's not much to say. */
6579         if (ps == NULL || ps->pss_func == POOL_SCAN_NONE ||
6580             ps->pss_func >= POOL_SCAN_FUNCS) {
6581                 (void) printf(gettext("none requested\n"));
6582                 return;
6583         }
6584 
6585         start = ps->pss_start_time;
6586         end = ps->pss_end_time;
6587         pause = ps->pss_pass_scrub_pause;
6588 
6589         zfs_nicenum(ps->pss_processed, processed_buf, sizeof (processed_buf));
6590 
6591         assert(ps->pss_func == POOL_SCAN_SCRUB ||
6592             ps->pss_func == POOL_SCAN_RESILVER);
6593 
6594         /*
6595          * Scan is finished or canceled.
6596          */
6597         if (ps->pss_state == DSS_FINISHED) {
6598                 total_secs_left = end - start;
6599                 days_left = total_secs_left / 60 / 60 / 24;
6600                 hours_left = (total_secs_left / 60 / 60) % 24;
6601                 mins_left = (total_secs_left / 60) % 60;
6602                 secs_left = (total_secs_left % 60);
6603 
6604                 if (ps->pss_func == POOL_SCAN_SCRUB) {
6605                         (void) printf(gettext("scrub repaired %s "
6606                             "in %llu days %02llu:%02llu:%02llu "
6607                             "with %llu errors on %s"), processed_buf,
6608                             (u_longlong_t)days_left, (u_longlong_t)hours_left,
6609                             (u_longlong_t)mins_left, (u_longlong_t)secs_left,
6610                             (u_longlong_t)ps->pss_errors, ctime(&end));
6611                 } else if (ps->pss_func == POOL_SCAN_RESILVER) {
6612                         (void) printf(gettext("resilvered %s "
6613                             "in %llu days %02llu:%02llu:%02llu "
6614                             "with %llu errors on %s"), processed_buf,
6615                             (u_longlong_t)days_left, (u_longlong_t)hours_left,
6616                             (u_longlong_t)mins_left, (u_longlong_t)secs_left,
6617                             (u_longlong_t)ps->pss_errors, ctime(&end));
6618                 }
6619                 return;
6620         } else if (ps->pss_state == DSS_CANCELED) {
6621                 if (ps->pss_func == POOL_SCAN_SCRUB) {
6622                         (void) printf(gettext("scrub canceled on %s"),
6623                             ctime(&end));
6624                 } else if (ps->pss_func == POOL_SCAN_RESILVER) {
6625                         (void) printf(gettext("resilver canceled on %s"),
6626                             ctime(&end));
6627                 }
6628                 return;
6629         }
6630 
6631         assert(ps->pss_state == DSS_SCANNING);
6632 
6633         /* Scan is in progress. Resilvers can't be paused. */
6634         if (ps->pss_func == POOL_SCAN_SCRUB) {
6635                 if (pause == 0) {
6636                         (void) printf(gettext("scrub in progress since %s"),
6637                             ctime(&start));
6638                 } else {
6639                         (void) printf(gettext("scrub paused since %s"),
6640                             ctime(&pause));
6641                         (void) printf(gettext("\tscrub started on %s"),
6642                             ctime(&start));
6643                 }
6644         } else if (ps->pss_func == POOL_SCAN_RESILVER) {
6645                 (void) printf(gettext("resilver in progress since %s"),
6646                     ctime(&start));
6647         }
6648 
6649         scanned = ps->pss_examined;
6650         pass_scanned = ps->pss_pass_exam;
6651         issued = ps->pss_issued;
6652         pass_issued = ps->pss_pass_issued;
6653         total = ps->pss_to_examine;
6654 
6655         /* we are only done with a block once we have issued the IO for it  */
6656         fraction_done = (double)issued / total;
6657 
6658         /* elapsed time for this pass, rounding up to 1 if it's 0 */
6659         elapsed = time(NULL) - ps->pss_pass_start;
6660         elapsed -= ps->pss_pass_scrub_spent_paused;
6661         elapsed = (elapsed != 0) ? elapsed : 1;
6662 
6663         scan_rate = pass_scanned / elapsed;
6664         issue_rate = pass_issued / elapsed;
6665         total_secs_left = (issue_rate != 0 && total >= issued) ?
6666             ((total - issued) / issue_rate) : UINT64_MAX;
6667 
6668         days_left = total_secs_left / 60 / 60 / 24;
6669         hours_left = (total_secs_left / 60 / 60) % 24;
6670         mins_left = (total_secs_left / 60) % 60;
6671         secs_left = (total_secs_left % 60);
6672 
6673         /* format all of the numbers we will be reporting */
6674         zfs_nicenum(scanned, scanned_buf, sizeof (scanned_buf));
6675         zfs_nicenum(issued, issued_buf, sizeof (issued_buf));
6676         zfs_nicenum(total, total_buf, sizeof (total_buf));
6677         zfs_nicenum(scan_rate, srate_buf, sizeof (srate_buf));
6678         zfs_nicenum(issue_rate, irate_buf, sizeof (irate_buf));
6679 
6680         /* do not print estimated time if we have a paused scrub */
6681         if (pause == 0) {
6682                 (void) printf(gettext("\t%s scanned at %s/s, "
6683                     "%s issued at %s/s, %s total\n"),
6684                     scanned_buf, srate_buf, issued_buf, irate_buf, total_buf);
6685         } else {
6686                 (void) printf(gettext("\t%s scanned, %s issued, %s total\n"),
6687                     scanned_buf, issued_buf, total_buf);
6688         }
6689 
6690         if (ps->pss_func == POOL_SCAN_RESILVER) {
6691                 (void) printf(gettext("\t%s resilvered, %.2f%% done"),
6692                     processed_buf, 100 * fraction_done);
6693         } else if (ps->pss_func == POOL_SCAN_SCRUB) {
6694                 (void) printf(gettext("\t%s repaired, %.2f%% done"),
6695                     processed_buf, 100 * fraction_done);
6696         }
6697 
6698         if (pause == 0) {
6699                 if (total_secs_left != UINT64_MAX &&
6700                     issue_rate >= 10 * 1024 * 1024) {
6701                         (void) printf(gettext(", %llu days "
6702                             "%02llu:%02llu:%02llu to go\n"),
6703                             (u_longlong_t)days_left, (u_longlong_t)hours_left,
6704                             (u_longlong_t)mins_left, (u_longlong_t)secs_left);
6705                 } else {
6706                         (void) printf(gettext(", no estimated "
6707                             "completion time\n"));
6708                 }
6709         } else {
6710                 (void) printf(gettext("\n"));
6711         }
6712 }
6713 
6714 /*
6715  * As we don't scrub checkpointed blocks, we want to warn the
6716  * user that we skipped scanning some blocks if a checkpoint exists
6717  * or existed at any time during the scan.
6718  */
6719 static void
6720 print_checkpoint_scan_warning(pool_scan_stat_t *ps, pool_checkpoint_stat_t *pcs)
6721 {
6722         if (ps == NULL || pcs == NULL)
6723                 return;
6724 
6725         if (pcs->pcs_state == CS_NONE ||
6726             pcs->pcs_state == CS_CHECKPOINT_DISCARDING)
6727                 return;
6728 
6729         assert(pcs->pcs_state == CS_CHECKPOINT_EXISTS);
6730 
6731         if (ps->pss_state == DSS_NONE)
6732                 return;
6733 
6734         if ((ps->pss_state == DSS_FINISHED || ps->pss_state == DSS_CANCELED) &&
6735             ps->pss_end_time < pcs->pcs_start_time)
6736                 return;
6737 
6738         if (ps->pss_state == DSS_FINISHED || ps->pss_state == DSS_CANCELED) {
6739                 (void) printf(gettext("    scan warning: skipped blocks "
6740                     "that are only referenced by the checkpoint.\n"));
6741         } else {
6742                 assert(ps->pss_state == DSS_SCANNING);
6743                 (void) printf(gettext("    scan warning: skipping blocks "
6744                     "that are only referenced by the checkpoint.\n"));
6745         }
6746 }
6747 
6748 /*
6749  * Print out detailed removal status.
6750  */
6751 static void
6752 print_removal_status(zpool_handle_t *zhp, pool_removal_stat_t *prs)
6753 {
6754         char copied_buf[7], examined_buf[7], total_buf[7], rate_buf[7];
6755         time_t start, end;
6756         nvlist_t *config, *nvroot;
6757         nvlist_t **child;
6758         uint_t children;
6759         char *vdev_name;
6760 
6761         if (prs == NULL || prs->prs_state == DSS_NONE)
6762                 return;
6763 
6764         /*
6765          * Determine name of vdev.
6766          */
6767         config = zpool_get_config(zhp, NULL);
6768         nvroot = fnvlist_lookup_nvlist(config,
6769             ZPOOL_CONFIG_VDEV_TREE);
6770         verify(nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_CHILDREN,
6771             &child, &children) == 0);
6772         assert(prs->prs_removing_vdev < children);
6773         vdev_name = zpool_vdev_name(g_zfs, zhp,
6774             child[prs->prs_removing_vdev], B_TRUE);
6775 
6776         (void) printf(gettext("remove: "));
6777 
6778         start = prs->prs_start_time;
6779         end = prs->prs_end_time;
6780         zfs_nicenum(prs->prs_copied, copied_buf, sizeof (copied_buf));
6781 
6782         /*
6783          * Removal is finished or canceled.
6784          */
6785         if (prs->prs_state == DSS_FINISHED) {
6786                 uint64_t minutes_taken = (end - start) / 60;
6787 
6788                 (void) printf(gettext("Removal of vdev %llu copied %s "
6789                     "in %lluh%um, completed on %s"),
6790                     (longlong_t)prs->prs_removing_vdev,
6791                     copied_buf,
6792                     (u_longlong_t)(minutes_taken / 60),
6793                     (uint_t)(minutes_taken % 60),
6794                     ctime((time_t *)&end));
6795         } else if (prs->prs_state == DSS_CANCELED) {
6796                 (void) printf(gettext("Removal of %s canceled on %s"),
6797                     vdev_name, ctime(&end));
6798         } else {
6799                 uint64_t copied, total, elapsed, mins_left, hours_left;
6800                 double fraction_done;
6801                 uint_t rate;
6802 
6803                 assert(prs->prs_state == DSS_SCANNING);
6804 
6805                 /*
6806                  * Removal is in progress.
6807                  */
6808                 (void) printf(gettext(
6809                     "Evacuation of %s in progress since %s"),
6810                     vdev_name, ctime(&start));
6811 
6812                 copied = prs->prs_copied > 0 ? prs->prs_copied : 1;
6813                 total = prs->prs_to_copy;
6814                 fraction_done = (double)copied / total;
6815 
6816                 /* elapsed time for this pass */
6817                 elapsed = time(NULL) - prs->prs_start_time;
6818                 elapsed = elapsed > 0 ? elapsed : 1;
6819                 rate = copied / elapsed;
6820                 rate = rate > 0 ? rate : 1;
6821                 mins_left = ((total - copied) / rate) / 60;
6822                 hours_left = mins_left / 60;
6823 
6824                 zfs_nicenum(copied, examined_buf, sizeof (examined_buf));
6825                 zfs_nicenum(total, total_buf, sizeof (total_buf));
6826                 zfs_nicenum(rate, rate_buf, sizeof (rate_buf));
6827 
6828                 /*
6829                  * do not print estimated time if hours_left is more than
6830                  * 30 days
6831                  */
6832                 (void) printf(gettext("    %s copied out of %s at %s/s, "
6833                     "%.2f%% done"),
6834                     examined_buf, total_buf, rate_buf, 100 * fraction_done);
6835                 if (hours_left < (30 * 24)) {
6836                         (void) printf(gettext(", %lluh%um to go\n"),
6837                             (u_longlong_t)hours_left, (uint_t)(mins_left % 60));
6838                 } else {
6839                         (void) printf(gettext(
6840                             ", (copy is slow, no estimated time)\n"));
6841                 }
6842         }
6843 
6844         if (prs->prs_mapping_memory > 0) {
6845                 char mem_buf[7];
6846                 zfs_nicenum(prs->prs_mapping_memory, mem_buf, sizeof (mem_buf));
6847                 (void) printf(gettext("    %s memory used for "
6848                     "removed device mappings\n"),
6849                     mem_buf);
6850         }
6851 }
6852 
6853 static void
6854 print_checkpoint_status(pool_checkpoint_stat_t *pcs)
6855 {
6856         time_t start;
6857         char space_buf[7];
6858 
6859         if (pcs == NULL || pcs->pcs_state == CS_NONE)
6860                 return;
6861 
6862         (void) printf(gettext("checkpoint: "));
6863 
6864         start = pcs->pcs_start_time;
6865         zfs_nicenum(pcs->pcs_space, space_buf, sizeof (space_buf));
6866 
6867         if (pcs->pcs_state == CS_CHECKPOINT_EXISTS) {
6868                 char *date = ctime(&start);
6869 
6870                 /*
6871                  * ctime() adds a newline at the end of the generated
6872                  * string, thus the weird format specifier and the
6873                  * strlen() call used to chop it off from the output.
6874                  */
6875                 (void) printf(gettext("created %.*s, consumes %s\n"),
6876                     strlen(date) - 1, date, space_buf);
6877                 return;
6878         }
6879 
6880         assert(pcs->pcs_state == CS_CHECKPOINT_DISCARDING);
6881 
6882         (void) printf(gettext("discarding, %s remaining.\n"),
6883             space_buf);
6884 }
6885 
6886 static void
6887 print_error_log(zpool_handle_t *zhp)
6888 {
6889         nvlist_t *nverrlist = NULL;
6890         nvpair_t *elem;
6891         char *pathname;
6892         size_t len = MAXPATHLEN * 2;
6893 
6894         if (zpool_get_errlog(zhp, &nverrlist) != 0) {
6895                 (void) printf("errors: List of errors unavailable "
6896                     "(insufficient privileges)\n");
6897                 return;
6898         }
6899 
6900         (void) printf("errors: Permanent errors have been "
6901             "detected in the following files:\n\n");
6902 
6903         pathname = safe_malloc(len);
6904         elem = NULL;
6905         while ((elem = nvlist_next_nvpair(nverrlist, elem)) != NULL) {
6906                 nvlist_t *nv;
6907                 uint64_t dsobj, obj;
6908 
6909                 verify(nvpair_value_nvlist(elem, &nv) == 0);
6910                 verify(nvlist_lookup_uint64(nv, ZPOOL_ERR_DATASET,
6911                     &dsobj) == 0);
6912                 verify(nvlist_lookup_uint64(nv, ZPOOL_ERR_OBJECT,
6913                     &obj) == 0);
6914                 zpool_obj_to_path(zhp, dsobj, obj, pathname, len);
6915                 (void) printf("%7s %s\n", "", pathname);
6916         }
6917         free(pathname);
6918         nvlist_free(nverrlist);
6919 }
6920 
6921 static void
6922 print_spares(zpool_handle_t *zhp, status_cbdata_t *cb, nvlist_t **spares,
6923     uint_t nspares)
6924 {
6925         uint_t i;
6926         char *name;
6927 
6928         if (nspares == 0)
6929                 return;
6930 
6931         (void) printf(gettext("\tspares\n"));
6932 
6933         for (i = 0; i < nspares; i++) {
6934                 name = zpool_vdev_name(g_zfs, zhp, spares[i],
6935                     cb->cb_name_flags);
6936                 print_status_config(zhp, cb, name, spares[i], 2, B_TRUE);
6937                 free(name);
6938         }
6939 }
6940 
6941 static void
6942 print_l2cache(zpool_handle_t *zhp, status_cbdata_t *cb, nvlist_t **l2cache,
6943     uint_t nl2cache)
6944 {
6945         uint_t i;
6946         char *name;
6947 
6948         if (nl2cache == 0)
6949                 return;
6950 
6951         (void) printf(gettext("\tcache\n"));
6952 
6953         for (i = 0; i < nl2cache; i++) {
6954                 name = zpool_vdev_name(g_zfs, zhp, l2cache[i],
6955                     cb->cb_name_flags);
6956                 print_status_config(zhp, cb, name, l2cache[i], 2, B_FALSE);
6957                 free(name);
6958         }
6959 }
6960 
6961 static void
6962 print_dedup_stats(nvlist_t *config)
6963 {
6964         ddt_histogram_t *ddh;
6965         ddt_stat_t *dds;
6966         ddt_object_t *ddo;
6967         uint_t c;
6968 
6969         /*
6970          * If the pool was faulted then we may not have been able to
6971          * obtain the config. Otherwise, if we have anything in the dedup
6972          * table continue processing the stats.
6973          */
6974         if (nvlist_lookup_uint64_array(config, ZPOOL_CONFIG_DDT_OBJ_STATS,
6975             (uint64_t **)&ddo, &c) != 0)
6976                 return;
6977 
6978         (void) printf("\n");
6979         (void) printf(gettext(" dedup: "));
6980         if (ddo->ddo_count == 0) {
6981                 (void) printf(gettext("no DDT entries\n"));
6982                 return;
6983         }
6984 
6985         (void) printf("DDT entries %llu, size %llu on disk, %llu in core\n",
6986             (u_longlong_t)ddo->ddo_count,
6987             (u_longlong_t)ddo->ddo_dspace,
6988             (u_longlong_t)ddo->ddo_mspace);
6989 
6990         verify(nvlist_lookup_uint64_array(config, ZPOOL_CONFIG_DDT_STATS,
6991             (uint64_t **)&dds, &c) == 0);
6992         verify(nvlist_lookup_uint64_array(config, ZPOOL_CONFIG_DDT_HISTOGRAM,
6993             (uint64_t **)&ddh, &c) == 0);
6994         zpool_dump_ddt(dds, ddh);
6995 }
6996 
6997 /*
6998  * Display a summary of pool status.  Displays a summary such as:
6999  *
7000  *        pool: tank
7001  *      status: DEGRADED
7002  *      reason: One or more devices ...
7003  *         see: http://illumos.org/msg/ZFS-xxxx-01
7004  *      config:
7005  *              mirror          DEGRADED
7006  *                c1t0d0        OK
7007  *                c2t0d0        UNAVAIL
7008  *
7009  * When given the '-v' option, we print out the complete config.  If the '-e'
7010  * option is specified, then we print out error rate information as well.
7011  */
7012 int
7013 status_callback(zpool_handle_t *zhp, void *data)
7014 {
7015         status_cbdata_t *cbp = data;
7016         nvlist_t *config, *nvroot;
7017         char *msgid;
7018         int reason;
7019         zpool_errata_t errata;
7020         const char *health;
7021         uint_t c;
7022         vdev_stat_t *vs;
7023 
7024         config = zpool_get_config(zhp, NULL);
7025         reason = zpool_get_status(zhp, &msgid, &errata);
7026 
7027         cbp->cb_count++;
7028 
7029         /*
7030          * If we were given 'zpool status -x', only report those pools with
7031          * problems.
7032          */
7033         if (cbp->cb_explain &&
7034             (reason == ZPOOL_STATUS_OK ||
7035             reason == ZPOOL_STATUS_VERSION_OLDER ||
7036             reason == ZPOOL_STATUS_FEAT_DISABLED)) {
7037                 if (!cbp->cb_allpools) {
7038                         (void) printf(gettext("pool '%s' is healthy\n"),
7039                             zpool_get_name(zhp));
7040                         if (cbp->cb_first)
7041                                 cbp->cb_first = B_FALSE;
7042                 }
7043                 return (0);
7044         }
7045 
7046         if (cbp->cb_first)
7047                 cbp->cb_first = B_FALSE;
7048         else
7049                 (void) printf("\n");
7050 
7051         nvroot = fnvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE);
7052         verify(nvlist_lookup_uint64_array(nvroot, ZPOOL_CONFIG_VDEV_STATS,
7053             (uint64_t **)&vs, &c) == 0);
7054         health = zpool_state_to_name(vs->vs_state, vs->vs_aux);
7055 
7056         (void) printf(gettext("  pool: %s\n"), zpool_get_name(zhp));
7057         (void) printf(gettext(" state: %s\n"), health);
7058 
7059         switch (reason) {
7060         case ZPOOL_STATUS_MISSING_DEV_R:
7061                 (void) printf(gettext("status: One or more devices could not "
7062                     "be opened.  Sufficient replicas exist for\n\tthe pool to "
7063                     "continue functioning in a degraded state.\n"));
7064                 (void) printf(gettext("action: Attach the missing device and "
7065                     "online it using 'zpool online'.\n"));
7066                 break;
7067 
7068         case ZPOOL_STATUS_MISSING_DEV_NR:
7069                 (void) printf(gettext("status: One or more devices could not "
7070                     "be opened.  There are insufficient\n\treplicas for the "
7071                     "pool to continue functioning.\n"));
7072                 (void) printf(gettext("action: Attach the missing device and "
7073                     "online it using 'zpool online'.\n"));
7074                 break;
7075 
7076         case ZPOOL_STATUS_CORRUPT_LABEL_R:
7077                 (void) printf(gettext("status: One or more devices could not "
7078                     "be used because the label is missing or\n\tinvalid.  "
7079                     "Sufficient replicas exist for the pool to continue\n\t"
7080                     "functioning in a degraded state.\n"));
7081                 (void) printf(gettext("action: Replace the device using "
7082                     "'zpool replace'.\n"));
7083                 break;
7084 
7085         case ZPOOL_STATUS_CORRUPT_LABEL_NR:
7086                 (void) printf(gettext("status: One or more devices could not "
7087                     "be used because the label is missing \n\tor invalid.  "
7088                     "There are insufficient replicas for the pool to "
7089                     "continue\n\tfunctioning.\n"));
7090                 zpool_explain_recover(zpool_get_handle(zhp),
7091                     zpool_get_name(zhp), reason, config);
7092                 break;
7093 
7094         case ZPOOL_STATUS_FAILING_DEV:
7095                 (void) printf(gettext("status: One or more devices has "
7096                     "experienced an unrecoverable error.  An\n\tattempt was "
7097                     "made to correct the error.  Applications are "
7098                     "unaffected.\n"));
7099                 (void) printf(gettext("action: Determine if the device needs "
7100                     "to be replaced, and clear the errors\n\tusing "
7101                     "'zpool clear' or replace the device with 'zpool "
7102                     "replace'.\n"));
7103                 break;
7104 
7105         case ZPOOL_STATUS_OFFLINE_DEV:
7106                 (void) printf(gettext("status: One or more devices has "
7107                     "been taken offline by the administrator.\n\tSufficient "
7108                     "replicas exist for the pool to continue functioning in "
7109                     "a\n\tdegraded state.\n"));
7110                 (void) printf(gettext("action: Online the device using "
7111                     "'zpool online' or replace the device with\n\t'zpool "
7112                     "replace'.\n"));
7113                 break;
7114 
7115         case ZPOOL_STATUS_REMOVED_DEV:
7116                 (void) printf(gettext("status: One or more devices has "
7117                     "been removed by the administrator.\n\tSufficient "
7118                     "replicas exist for the pool to continue functioning in "
7119                     "a\n\tdegraded state.\n"));
7120                 (void) printf(gettext("action: Online the device using "
7121                     "'zpool online' or replace the device with\n\t'zpool "
7122                     "replace'.\n"));
7123                 break;
7124 
7125         case ZPOOL_STATUS_RESILVERING:
7126                 (void) printf(gettext("status: One or more devices is "
7127                     "currently being resilvered.  The pool will\n\tcontinue "
7128                     "to function, possibly in a degraded state.\n"));
7129                 (void) printf(gettext("action: Wait for the resilver to "
7130                     "complete.\n"));
7131                 break;
7132 
7133         case ZPOOL_STATUS_CORRUPT_DATA:
7134                 (void) printf(gettext("status: One or more devices has "
7135                     "experienced an error resulting in data\n\tcorruption.  "
7136                     "Applications may be affected.\n"));
7137                 (void) printf(gettext("action: Restore the file in question "
7138                     "if possible.  Otherwise restore the\n\tentire pool from "
7139                     "backup.\n"));
7140                 break;
7141 
7142         case ZPOOL_STATUS_CORRUPT_POOL:
7143                 (void) printf(gettext("status: The pool metadata is corrupted "
7144                     "and the pool cannot be opened.\n"));
7145                 zpool_explain_recover(zpool_get_handle(zhp),
7146                     zpool_get_name(zhp), reason, config);
7147                 break;
7148 
7149         case ZPOOL_STATUS_VERSION_OLDER:
7150                 (void) printf(gettext("status: The pool is formatted using a "
7151                     "legacy on-disk format.  The pool can\n\tstill be used, "
7152                     "but some features are unavailable.\n"));
7153                 (void) printf(gettext("action: Upgrade the pool using 'zpool "
7154                     "upgrade'.  Once this is done, the\n\tpool will no longer "
7155                     "be accessible on software that does not support feature\n"
7156                     "\tflags.\n"));
7157                 break;
7158 
7159         case ZPOOL_STATUS_VERSION_NEWER:
7160                 (void) printf(gettext("status: The pool has been upgraded to a "
7161                     "newer, incompatible on-disk version.\n\tThe pool cannot "
7162                     "be accessed on this system.\n"));
7163                 (void) printf(gettext("action: Access the pool from a system "
7164                     "running more recent software, or\n\trestore the pool from "
7165                     "backup.\n"));
7166                 break;
7167 
7168         case ZPOOL_STATUS_FEAT_DISABLED:
7169                 (void) printf(gettext("status: Some supported features are not "
7170                     "enabled on the pool. The pool can\n\tstill be used, but "
7171                     "some features are unavailable.\n"));
7172                 (void) printf(gettext("action: Enable all features using "
7173                     "'zpool upgrade'. Once this is done,\n\tthe pool may no "
7174                     "longer be accessible by software that does not support\n\t"
7175                     "the features. See zpool-features(5) for details.\n"));
7176                 break;
7177 
7178         case ZPOOL_STATUS_UNSUP_FEAT_READ:
7179                 (void) printf(gettext("status: The pool cannot be accessed on "
7180                     "this system because it uses the\n\tfollowing feature(s) "
7181                     "not supported on this system:\n"));
7182                 zpool_print_unsup_feat(config);
7183                 (void) printf("\n");
7184                 (void) printf(gettext("action: Access the pool from a system "
7185                     "that supports the required feature(s),\n\tor restore the "
7186                     "pool from backup.\n"));
7187                 break;
7188 
7189         case ZPOOL_STATUS_UNSUP_FEAT_WRITE:
7190                 (void) printf(gettext("status: The pool can only be accessed "
7191                     "in read-only mode on this system. It\n\tcannot be "
7192                     "accessed in read-write mode because it uses the "
7193                     "following\n\tfeature(s) not supported on this system:\n"));
7194                 zpool_print_unsup_feat(config);
7195                 (void) printf("\n");
7196                 (void) printf(gettext("action: The pool cannot be accessed in "
7197                     "read-write mode. Import the pool with\n"
7198                     "\t\"-o readonly=on\", access the pool from a system that "
7199                     "supports the\n\trequired feature(s), or restore the "
7200                     "pool from backup.\n"));
7201                 break;
7202 
7203         case ZPOOL_STATUS_FAULTED_DEV_R:
7204                 (void) printf(gettext("status: One or more devices are "
7205                     "faulted in response to persistent errors.\n\tSufficient "
7206                     "replicas exist for the pool to continue functioning "
7207                     "in a\n\tdegraded state.\n"));
7208                 (void) printf(gettext("action: Replace the faulted device, "
7209                     "or use 'zpool clear' to mark the device\n\trepaired.\n"));
7210                 break;
7211 
7212         case ZPOOL_STATUS_FAULTED_DEV_NR:
7213                 (void) printf(gettext("status: One or more devices are "
7214                     "faulted in response to persistent errors.  There are "
7215                     "insufficient replicas for the pool to\n\tcontinue "
7216                     "functioning.\n"));
7217                 (void) printf(gettext("action: Destroy and re-create the pool "
7218                     "from a backup source.  Manually marking the device\n"
7219                     "\trepaired using 'zpool clear' may allow some data "
7220                     "to be recovered.\n"));
7221                 break;
7222 
7223         case ZPOOL_STATUS_IO_FAILURE_MMP:
7224                 (void) printf(gettext("status: The pool is suspended because "
7225                     "multihost writes failed or were delayed;\n\tanother "
7226                     "system could import the pool undetected.\n"));
7227                 (void) printf(gettext("action: Make sure the pool's devices "
7228                     "are connected, then reboot your system and\n\timport the "
7229                     "pool.\n"));
7230                 break;
7231 
7232         case ZPOOL_STATUS_IO_FAILURE_WAIT:
7233         case ZPOOL_STATUS_IO_FAILURE_CONTINUE:
7234                 (void) printf(gettext("status: One or more devices are "
7235                     "faulted in response to IO failures.\n"));
7236                 (void) printf(gettext("action: Make sure the affected devices "
7237                     "are connected, then run 'zpool clear'.\n"));
7238                 break;
7239 
7240         case ZPOOL_STATUS_BAD_LOG:
7241                 (void) printf(gettext("status: An intent log record "
7242                     "could not be read.\n"
7243                     "\tWaiting for adminstrator intervention to fix the "
7244                     "faulted pool.\n"));
7245                 (void) printf(gettext("action: Either restore the affected "
7246                     "device(s) and run 'zpool online',\n"
7247                     "\tor ignore the intent log records by running "
7248                     "'zpool clear'.\n"));
7249                 break;
7250 
7251         case ZPOOL_STATUS_ERRATA:
7252                 (void) printf(gettext("status: Errata #%d detected.\n"),
7253                     errata);
7254 
7255                 switch (errata) {
7256                 case ZPOOL_ERRATA_NONE:
7257                         break;
7258 
7259                 case ZPOOL_ERRATA_ZOL_2094_SCRUB:
7260                         (void) printf(gettext("action: To correct the issue "
7261                             "run 'zpool scrub'.\n"));
7262                         break;
7263 
7264                 case ZPOOL_ERRATA_ZOL_6845_ENCRYPTION:
7265                         (void) printf(gettext("\tExisting encrypted datasets "
7266                             "contain an on-disk incompatibility\n\twhich "
7267                             "needs to be corrected.\n"));
7268                         (void) printf(gettext("action: To correct the issue "
7269                             "backup existing encrypted datasets to new\n\t"
7270                             "encrypted datasets and destroy the old ones. "
7271                             "'zfs mount -o ro' can\n\tbe used to temporarily "
7272                             "mount existing encrypted datasets readonly.\n"));
7273                         break;
7274 
7275                 case ZPOOL_ERRATA_ZOL_8308_ENCRYPTION:
7276                         (void) printf(gettext("\tExisting encrypted datasets "
7277                             "contain an on-disk incompatibility\n\twhich "
7278                             "needs to be corrected.\n"));
7279                         (void) printf(gettext("action: To correct the issue "
7280                             "enable the bookmark_v2 feature and "
7281                             "backup\n\tany existing encrypted datasets to "
7282                             "new encrypted datasets and\n\tdestroy the old "
7283                             "ones. If this pool does not contain any\n\t"
7284                             "encrypted datasets, simply enable the "
7285                             "bookmark_v2 feature\n"));
7286                         break;
7287 
7288                 default:
7289                         /*
7290                          * All errata which allow the pool to be imported
7291                          * must contain an action message.
7292                          */
7293                         assert(0);
7294                 }
7295                 break;
7296 
7297         default:
7298                 /*
7299                  * The remaining errors can't actually be generated, yet.
7300                  */
7301                 assert(reason == ZPOOL_STATUS_OK);
7302         }
7303 
7304         if (msgid != NULL)
7305                 (void) printf(gettext("   see: http://illumos.org/msg/%s\n"),
7306                     msgid);
7307 
7308         if (config != NULL) {
7309                 uint64_t nerr;
7310                 nvlist_t **spares, **l2cache;
7311                 uint_t nspares, nl2cache;
7312                 pool_checkpoint_stat_t *pcs = NULL;
7313                 pool_scan_stat_t *ps = NULL;
7314                 pool_removal_stat_t *prs = NULL;
7315 
7316                 (void) nvlist_lookup_uint64_array(nvroot,
7317                     ZPOOL_CONFIG_CHECKPOINT_STATS, (uint64_t **)&pcs, &c);
7318                 (void) nvlist_lookup_uint64_array(nvroot,
7319                     ZPOOL_CONFIG_SCAN_STATS, (uint64_t **)&ps, &c);
7320                 (void) nvlist_lookup_uint64_array(nvroot,
7321                     ZPOOL_CONFIG_REMOVAL_STATS, (uint64_t **)&prs, &c);
7322 
7323                 print_scan_status(ps);
7324                 print_checkpoint_scan_warning(ps, pcs);
7325                 print_removal_status(zhp, prs);
7326                 print_checkpoint_status(pcs);
7327 
7328                 cbp->cb_namewidth = max_width(zhp, nvroot, 0, 0,
7329                     cbp->cb_name_flags);
7330                 if (cbp->cb_namewidth < 10)
7331                         cbp->cb_namewidth = 10;
7332 
7333                 (void) printf(gettext("config:\n\n"));
7334                 (void) printf(gettext("\t%-*s  %-8s %5s %5s %5s\n"),
7335                     cbp->cb_namewidth, "NAME", "STATE", "READ", "WRITE",
7336                     "CKSUM");
7337 
7338                 if (cbp->cb_print_slow_ios)
7339                         (void) printf(" %5s", gettext("SLOW"));
7340 
7341                 print_status_config(zhp, cbp, zpool_get_name(zhp), nvroot, 0,
7342                     B_FALSE);
7343 
7344                 print_class_vdevs(zhp, cbp, nvroot, VDEV_ALLOC_BIAS_DEDUP);
7345                 print_class_vdevs(zhp, cbp, nvroot, VDEV_ALLOC_BIAS_SPECIAL);
7346                 print_class_vdevs(zhp, cbp, nvroot, VDEV_ALLOC_CLASS_LOGS);
7347 
7348                 if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_L2CACHE,
7349                     &l2cache, &nl2cache) == 0)
7350                         print_l2cache(zhp, cbp, l2cache, nl2cache);
7351 
7352                 if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_SPARES,
7353                     &spares, &nspares) == 0)
7354                         print_spares(zhp, cbp, spares, nspares);
7355 
7356                 if (nvlist_lookup_uint64(config, ZPOOL_CONFIG_ERRCOUNT,
7357                     &nerr) == 0) {
7358                         nvlist_t *nverrlist = NULL;
7359 
7360                         /*
7361                          * If the approximate error count is small, get a
7362                          * precise count by fetching the entire log and
7363                          * uniquifying the results.
7364                          */
7365                         if (nerr > 0 && nerr < 100 && !cbp->cb_verbose &&
7366                             zpool_get_errlog(zhp, &nverrlist) == 0) {
7367                                 nvpair_t *elem;
7368 
7369                                 elem = NULL;
7370                                 nerr = 0;
7371                                 while ((elem = nvlist_next_nvpair(nverrlist,
7372                                     elem)) != NULL) {
7373                                         nerr++;
7374                                 }
7375                         }
7376                         nvlist_free(nverrlist);
7377 
7378                         (void) printf("\n");
7379 
7380                         if (nerr == 0)
7381                                 (void) printf(gettext("errors: No known data "
7382                                     "errors\n"));
7383                         else if (!cbp->cb_verbose)
7384                                 (void) printf(gettext("errors: %llu data "
7385                                     "errors, use '-v' for a list\n"),
7386                                     (u_longlong_t)nerr);
7387                         else
7388                                 print_error_log(zhp);
7389                 }
7390 
7391                 if (cbp->cb_dedup_stats)
7392                         print_dedup_stats(config);
7393         } else {
7394                 (void) printf(gettext("config: The configuration cannot be "
7395                     "determined.\n"));
7396         }
7397 
7398         return (0);
7399 }
7400 
7401 /*
7402  * zpool status [-igLpPstvx] [-T d|u] [pool] ... [interval [count]]
7403  *
7404  *      -i      Display vdev initialization status.
7405  *      -g      Display guid for individual vdev name.
7406  *      -L      Follow links when resolving vdev path name.
7407  *      -p      Display values in parsable (exact) format.
7408  *      -P      Display full path for vdev name.
7409  *      -s      Display slow IOs column.
7410  *      -v      Display complete error logs
7411  *      -x      Display only pools with potential problems
7412  *      -D      Display dedup status (undocumented)
7413  *      -t      Display vdev TRIM status.
7414  *      -T      Display a timestamp in date(1) or Unix format
7415  *
7416  * Describes the health status of all pools or some subset.
7417  */
7418 int
7419 zpool_do_status(int argc, char **argv)
7420 {
7421         int c;
7422         int ret;
7423         float interval = 0;
7424         unsigned long count = 0;
7425         status_cbdata_t cb = { 0 };
7426 
7427         /* check options */
7428         while ((c = getopt(argc, argv, "igLpPsvxDtT:")) != -1) {
7429                 switch (c) {
7430                 case 'i':
7431                         cb.cb_print_vdev_init = B_TRUE;
7432                         break;
7433                 case 'g':
7434                         cb.cb_name_flags |= VDEV_NAME_GUID;
7435                         break;
7436                 case 'L':
7437                         cb.cb_name_flags |= VDEV_NAME_FOLLOW_LINKS;
7438                         break;
7439                 case 'p':
7440                         cb.cb_literal = B_TRUE;
7441                         break;
7442                 case 'P':
7443                         cb.cb_name_flags |= VDEV_NAME_PATH;
7444                         break;
7445                 case 's':
7446                         cb.cb_print_slow_ios = B_TRUE;
7447                         break;
7448                 case 'v':
7449                         cb.cb_verbose = B_TRUE;
7450                         break;
7451                 case 'x':
7452                         cb.cb_explain = B_TRUE;
7453                         break;
7454                 case 'D':
7455                         cb.cb_dedup_stats = B_TRUE;
7456                         break;
7457                 case 't':
7458                         cb.cb_print_vdev_trim = B_TRUE;
7459                         break;
7460                 case 'T':
7461                         get_timestamp_arg(*optarg);
7462                         break;
7463                 case '?':
7464                         (void) fprintf(stderr, gettext("invalid option '%c'\n"),
7465                             optopt);
7466                         usage(B_FALSE);
7467                 }
7468         }
7469 
7470         argc -= optind;
7471         argv += optind;
7472 
7473         get_interval_count(&argc, argv, &interval, &count);
7474 
7475         if (argc == 0)
7476                 cb.cb_allpools = B_TRUE;
7477 
7478         cb.cb_first = B_TRUE;
7479         cb.cb_print_status = B_TRUE;
7480 
7481         for (;;) {
7482                 if (timestamp_fmt != NODATE)
7483                         print_timestamp(timestamp_fmt);
7484 
7485                 ret = for_each_pool(argc, argv, B_TRUE, NULL,
7486                     status_callback, &cb);
7487 
7488                 if (argc == 0 && cb.cb_count == 0)
7489                         (void) printf(gettext("no pools available\n"));
7490                 else if (cb.cb_explain && cb.cb_first && cb.cb_allpools)
7491                         (void) printf(gettext("all pools are healthy\n"));
7492 
7493                 if (ret != 0)
7494                         return (ret);
7495 
7496                 if (interval == 0)
7497                         break;
7498 
7499                 if (count != 0 && --count == 0)
7500                         break;
7501 
7502                 (void) fsleep(interval);
7503         }
7504 
7505         return (0);
7506 }
7507 
7508 typedef struct upgrade_cbdata {
7509         int     cb_first;
7510         int     cb_argc;
7511         uint64_t cb_version;
7512         char    **cb_argv;
7513 } upgrade_cbdata_t;
7514 
7515 static int
7516 upgrade_version(zpool_handle_t *zhp, uint64_t version)
7517 {
7518         int ret;
7519         nvlist_t *config;
7520         uint64_t oldversion;
7521 
7522         config = zpool_get_config(zhp, NULL);
7523         verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION,
7524             &oldversion) == 0);
7525 
7526         assert(SPA_VERSION_IS_SUPPORTED(oldversion));
7527         assert(oldversion < version);
7528 
7529         ret = zpool_upgrade(zhp, version);
7530         if (ret != 0)
7531                 return (ret);
7532 
7533         if (version >= SPA_VERSION_FEATURES) {
7534                 (void) printf(gettext("Successfully upgraded "
7535                     "'%s' from version %llu to feature flags.\n"),
7536                     zpool_get_name(zhp), oldversion);
7537         } else {
7538                 (void) printf(gettext("Successfully upgraded "
7539                     "'%s' from version %llu to version %llu.\n"),
7540                     zpool_get_name(zhp), oldversion, version);
7541         }
7542 
7543         return (0);
7544 }
7545 
7546 static int
7547 upgrade_enable_all(zpool_handle_t *zhp, int *countp)
7548 {
7549         int i, ret, count;
7550         boolean_t firstff = B_TRUE;
7551         nvlist_t *enabled = zpool_get_features(zhp);
7552 
7553         count = 0;
7554         for (i = 0; i < SPA_FEATURES; i++) {
7555                 const char *fname = spa_feature_table[i].fi_uname;
7556                 const char *fguid = spa_feature_table[i].fi_guid;
7557                 if (!nvlist_exists(enabled, fguid)) {
7558                         char *propname;
7559                         verify(-1 != asprintf(&propname, "feature@%s", fname));
7560                         ret = zpool_set_prop(zhp, propname,
7561                             ZFS_FEATURE_ENABLED);
7562                         if (ret != 0) {
7563                                 free(propname);
7564                                 return (ret);
7565                         }
7566                         count++;
7567 
7568                         if (firstff) {
7569                                 (void) printf(gettext("Enabled the "
7570                                     "following features on '%s':\n"),
7571                                     zpool_get_name(zhp));
7572                                 firstff = B_FALSE;
7573                         }
7574                         (void) printf(gettext("  %s\n"), fname);
7575                         free(propname);
7576                 }
7577         }
7578 
7579         if (countp != NULL)
7580                 *countp = count;
7581         return (0);
7582 }
7583 
7584 static int
7585 upgrade_cb(zpool_handle_t *zhp, void *arg)
7586 {
7587         upgrade_cbdata_t *cbp = arg;
7588         nvlist_t *config;
7589         uint64_t version;
7590         boolean_t printnl = B_FALSE;
7591         int ret;
7592 
7593         config = zpool_get_config(zhp, NULL);
7594         verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION,
7595             &version) == 0);
7596 
7597         assert(SPA_VERSION_IS_SUPPORTED(version));
7598 
7599         if (version < cbp->cb_version) {
7600                 cbp->cb_first = B_FALSE;
7601                 ret = upgrade_version(zhp, cbp->cb_version);
7602                 if (ret != 0)
7603                         return (ret);
7604                 printnl = B_TRUE;
7605 
7606                 /*
7607                  * If they did "zpool upgrade -a", then we could
7608                  * be doing ioctls to different pools.  We need
7609                  * to log this history once to each pool, and bypass
7610                  * the normal history logging that happens in main().
7611                  */
7612                 (void) zpool_log_history(g_zfs, history_str);
7613                 log_history = B_FALSE;
7614         }
7615 
7616         if (cbp->cb_version >= SPA_VERSION_FEATURES) {
7617                 int count;
7618                 ret = upgrade_enable_all(zhp, &count);
7619                 if (ret != 0)
7620                         return (ret);
7621 
7622                 if (count > 0) {
7623                         cbp->cb_first = B_FALSE;
7624                         printnl = B_TRUE;
7625                 }
7626         }
7627 
7628         if (printnl) {
7629                 (void) printf(gettext("\n"));
7630         }
7631 
7632         return (0);
7633 }
7634 
7635 static int
7636 upgrade_list_older_cb(zpool_handle_t *zhp, void *arg)
7637 {
7638         upgrade_cbdata_t *cbp = arg;
7639         nvlist_t *config;
7640         uint64_t version;
7641 
7642         config = zpool_get_config(zhp, NULL);
7643         verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION,
7644             &version) == 0);
7645 
7646         assert(SPA_VERSION_IS_SUPPORTED(version));
7647 
7648         if (version < SPA_VERSION_FEATURES) {
7649                 if (cbp->cb_first) {
7650                         (void) printf(gettext("The following pools are "
7651                             "formatted with legacy version numbers and can\n"
7652                             "be upgraded to use feature flags.  After "
7653                             "being upgraded, these pools\nwill no "
7654                             "longer be accessible by software that does not "
7655                             "support feature\nflags.\n\n"));
7656                         (void) printf(gettext("VER  POOL\n"));
7657                         (void) printf(gettext("---  ------------\n"));
7658                         cbp->cb_first = B_FALSE;
7659                 }
7660 
7661                 (void) printf("%2llu   %s\n", (u_longlong_t)version,
7662                     zpool_get_name(zhp));
7663         }
7664 
7665         return (0);
7666 }
7667 
7668 static int
7669 upgrade_list_disabled_cb(zpool_handle_t *zhp, void *arg)
7670 {
7671         upgrade_cbdata_t *cbp = arg;
7672         nvlist_t *config;
7673         uint64_t version;
7674 
7675         config = zpool_get_config(zhp, NULL);
7676         verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION,
7677             &version) == 0);
7678 
7679         if (version >= SPA_VERSION_FEATURES) {
7680                 int i;
7681                 boolean_t poolfirst = B_TRUE;
7682                 nvlist_t *enabled = zpool_get_features(zhp);
7683 
7684                 for (i = 0; i < SPA_FEATURES; i++) {
7685                         const char *fguid = spa_feature_table[i].fi_guid;
7686                         const char *fname = spa_feature_table[i].fi_uname;
7687                         if (!nvlist_exists(enabled, fguid)) {
7688                                 if (cbp->cb_first) {
7689                                         (void) printf(gettext("\nSome "
7690                                             "supported features are not "
7691                                             "enabled on the following pools. "
7692                                             "Once a\nfeature is enabled the "
7693                                             "pool may become incompatible with "
7694                                             "software\nthat does not support "
7695                                             "the feature. See "
7696                                             "zpool-features(5) for "
7697                                             "details.\n\n"));
7698                                         (void) printf(gettext("POOL  "
7699                                             "FEATURE\n"));
7700                                         (void) printf(gettext("------"
7701                                             "---------\n"));
7702                                         cbp->cb_first = B_FALSE;
7703                                 }
7704 
7705                                 if (poolfirst) {
7706                                         (void) printf(gettext("%s\n"),
7707                                             zpool_get_name(zhp));
7708                                         poolfirst = B_FALSE;
7709                                 }
7710 
7711                                 (void) printf(gettext("      %s\n"), fname);
7712                         }
7713                 }
7714         }
7715 
7716         return (0);
7717 }
7718 
7719 /* ARGSUSED */
7720 static int
7721 upgrade_one(zpool_handle_t *zhp, void *data)
7722 {
7723         boolean_t printnl = B_FALSE;
7724         upgrade_cbdata_t *cbp = data;
7725         uint64_t cur_version;
7726         int ret;
7727 
7728         if (strcmp("log", zpool_get_name(zhp)) == 0) {
7729                 (void) printf(gettext("'log' is now a reserved word\n"
7730                     "Pool 'log' must be renamed using export and import"
7731                     " to upgrade.\n"));
7732                 return (1);
7733         }
7734 
7735         cur_version = zpool_get_prop_int(zhp, ZPOOL_PROP_VERSION, NULL);
7736         if (cur_version > cbp->cb_version) {
7737                 (void) printf(gettext("Pool '%s' is already formatted "
7738                     "using more current version '%llu'.\n\n"),
7739                     zpool_get_name(zhp), cur_version);
7740                 return (0);
7741         }
7742 
7743         if (cbp->cb_version != SPA_VERSION && cur_version == cbp->cb_version) {
7744                 (void) printf(gettext("Pool '%s' is already formatted "
7745                     "using version %llu.\n\n"), zpool_get_name(zhp),
7746                     cbp->cb_version);
7747                 return (0);
7748         }
7749 
7750         if (cur_version != cbp->cb_version) {
7751                 printnl = B_TRUE;
7752                 ret = upgrade_version(zhp, cbp->cb_version);
7753                 if (ret != 0)
7754                         return (ret);
7755         }
7756 
7757         if (cbp->cb_version >= SPA_VERSION_FEATURES) {
7758                 int count = 0;
7759                 ret = upgrade_enable_all(zhp, &count);
7760                 if (ret != 0)
7761                         return (ret);
7762 
7763                 if (count != 0) {
7764                         printnl = B_TRUE;
7765                 } else if (cur_version == SPA_VERSION) {
7766                         (void) printf(gettext("Pool '%s' already has all "
7767                             "supported features enabled.\n"),
7768                             zpool_get_name(zhp));
7769                 }
7770         }
7771 
7772         if (printnl) {
7773                 (void) printf(gettext("\n"));
7774         }
7775 
7776         return (0);
7777 }
7778 
7779 /*
7780  * zpool upgrade
7781  * zpool upgrade -v
7782  * zpool upgrade [-V version] <-a | pool ...>
7783  *
7784  * With no arguments, display downrev'd ZFS pool available for upgrade.
7785  * Individual pools can be upgraded by specifying the pool, and '-a' will
7786  * upgrade all pools.
7787  */
7788 int
7789 zpool_do_upgrade(int argc, char **argv)
7790 {
7791         int c;
7792         upgrade_cbdata_t cb = { 0 };
7793         int ret = 0;
7794         boolean_t showversions = B_FALSE;
7795         boolean_t upgradeall = B_FALSE;
7796         char *end;
7797 
7798 
7799         /* check options */
7800         while ((c = getopt(argc, argv, ":avV:")) != -1) {
7801                 switch (c) {
7802                 case 'a':
7803                         upgradeall = B_TRUE;
7804                         break;
7805                 case 'v':
7806                         showversions = B_TRUE;
7807                         break;
7808                 case 'V':
7809                         cb.cb_version = strtoll(optarg, &end, 10);
7810                         if (*end != '\0' ||
7811                             !SPA_VERSION_IS_SUPPORTED(cb.cb_version)) {
7812                                 (void) fprintf(stderr,
7813                                     gettext("invalid version '%s'\n"), optarg);
7814                                 usage(B_FALSE);
7815                         }
7816                         break;
7817                 case ':':
7818                         (void) fprintf(stderr, gettext("missing argument for "
7819                             "'%c' option\n"), optopt);
7820                         usage(B_FALSE);
7821                         break;
7822                 case '?':
7823                         (void) fprintf(stderr, gettext("invalid option '%c'\n"),
7824                             optopt);
7825                         usage(B_FALSE);
7826                 }
7827         }
7828 
7829         cb.cb_argc = argc;
7830         cb.cb_argv = argv;
7831         argc -= optind;
7832         argv += optind;
7833 
7834         if (cb.cb_version == 0) {
7835                 cb.cb_version = SPA_VERSION;
7836         } else if (!upgradeall && argc == 0) {
7837                 (void) fprintf(stderr, gettext("-V option is "
7838                     "incompatible with other arguments\n"));
7839                 usage(B_FALSE);
7840         }
7841 
7842         if (showversions) {
7843                 if (upgradeall || argc != 0) {
7844                         (void) fprintf(stderr, gettext("-v option is "
7845                             "incompatible with other arguments\n"));
7846                         usage(B_FALSE);
7847                 }
7848         } else if (upgradeall) {
7849                 if (argc != 0) {
7850                         (void) fprintf(stderr, gettext("-a option should not "
7851                             "be used along with a pool name\n"));
7852                         usage(B_FALSE);
7853                 }
7854         }
7855 
7856         (void) printf(gettext("This system supports ZFS pool feature "
7857             "flags.\n\n"));
7858         if (showversions) {
7859                 int i;
7860 
7861                 (void) printf(gettext("The following features are "
7862                     "supported:\n\n"));
7863                 (void) printf(gettext("FEAT DESCRIPTION\n"));
7864                 (void) printf("----------------------------------------------"
7865                     "---------------\n");
7866                 for (i = 0; i < SPA_FEATURES; i++) {
7867                         zfeature_info_t *fi = &spa_feature_table[i];
7868                         const char *ro =
7869                             (fi->fi_flags & ZFEATURE_FLAG_READONLY_COMPAT) ?
7870                             " (read-only compatible)" : "";
7871 
7872                         (void) printf("%-37s%s\n", fi->fi_uname, ro);
7873                         (void) printf("     %s\n", fi->fi_desc);
7874                 }
7875                 (void) printf("\n");
7876 
7877                 (void) printf(gettext("The following legacy versions are also "
7878                     "supported:\n\n"));
7879                 (void) printf(gettext("VER  DESCRIPTION\n"));
7880                 (void) printf("---  -----------------------------------------"
7881                     "---------------\n");
7882                 (void) printf(gettext(" 1   Initial ZFS version\n"));
7883                 (void) printf(gettext(" 2   Ditto blocks "
7884                     "(replicated metadata)\n"));
7885                 (void) printf(gettext(" 3   Hot spares and double parity "
7886                     "RAID-Z\n"));
7887                 (void) printf(gettext(" 4   zpool history\n"));
7888                 (void) printf(gettext(" 5   Compression using the gzip "
7889                     "algorithm\n"));
7890                 (void) printf(gettext(" 6   bootfs pool property\n"));
7891                 (void) printf(gettext(" 7   Separate intent log devices\n"));
7892                 (void) printf(gettext(" 8   Delegated administration\n"));
7893                 (void) printf(gettext(" 9   refquota and refreservation "
7894                     "properties\n"));
7895                 (void) printf(gettext(" 10  Cache devices\n"));
7896                 (void) printf(gettext(" 11  Improved scrub performance\n"));
7897                 (void) printf(gettext(" 12  Snapshot properties\n"));
7898                 (void) printf(gettext(" 13  snapused property\n"));
7899                 (void) printf(gettext(" 14  passthrough-x aclinherit\n"));
7900                 (void) printf(gettext(" 15  user/group space accounting\n"));
7901                 (void) printf(gettext(" 16  stmf property support\n"));
7902                 (void) printf(gettext(" 17  Triple-parity RAID-Z\n"));
7903                 (void) printf(gettext(" 18  Snapshot user holds\n"));
7904                 (void) printf(gettext(" 19  Log device removal\n"));
7905                 (void) printf(gettext(" 20  Compression using zle "
7906                     "(zero-length encoding)\n"));
7907                 (void) printf(gettext(" 21  Deduplication\n"));
7908                 (void) printf(gettext(" 22  Received properties\n"));
7909                 (void) printf(gettext(" 23  Slim ZIL\n"));
7910                 (void) printf(gettext(" 24  System attributes\n"));
7911                 (void) printf(gettext(" 25  Improved scrub stats\n"));
7912                 (void) printf(gettext(" 26  Improved snapshot deletion "
7913                     "performance\n"));
7914                 (void) printf(gettext(" 27  Improved snapshot creation "
7915                     "performance\n"));
7916                 (void) printf(gettext(" 28  Multiple vdev replacements\n"));
7917                 (void) printf(gettext("\nFor more information on a particular "
7918                     "version, including supported releases,\n"));
7919                 (void) printf(gettext("see the ZFS Administration Guide.\n\n"));
7920         } else if (argc == 0 && upgradeall) {
7921                 cb.cb_first = B_TRUE;
7922                 ret = zpool_iter(g_zfs, upgrade_cb, &cb);
7923                 if (ret == 0 && cb.cb_first) {
7924                         if (cb.cb_version == SPA_VERSION) {
7925                                 (void) printf(gettext("All pools are already "
7926                                     "formatted using feature flags.\n\n"));
7927                                 (void) printf(gettext("Every feature flags "
7928                                     "pool already has all supported features "
7929                                     "enabled.\n"));
7930                         } else {
7931                                 (void) printf(gettext("All pools are already "
7932                                     "formatted with version %llu or higher.\n"),
7933                                     cb.cb_version);
7934                         }
7935                 }
7936         } else if (argc == 0) {
7937                 cb.cb_first = B_TRUE;
7938                 ret = zpool_iter(g_zfs, upgrade_list_older_cb, &cb);
7939                 assert(ret == 0);
7940 
7941                 if (cb.cb_first) {
7942                         (void) printf(gettext("All pools are formatted "
7943                             "using feature flags.\n\n"));
7944                 } else {
7945                         (void) printf(gettext("\nUse 'zpool upgrade -v' "
7946                             "for a list of available legacy versions.\n"));
7947                 }
7948 
7949                 cb.cb_first = B_TRUE;
7950                 ret = zpool_iter(g_zfs, upgrade_list_disabled_cb, &cb);
7951                 assert(ret == 0);
7952 
7953                 if (cb.cb_first) {
7954                         (void) printf(gettext("Every feature flags pool has "
7955                             "all supported features enabled.\n"));
7956                 } else {
7957                         (void) printf(gettext("\n"));
7958                 }
7959         } else {
7960                 ret = for_each_pool(argc, argv, B_FALSE, NULL,
7961                     upgrade_one, &cb);
7962         }
7963 
7964         return (ret);
7965 }
7966 
7967 typedef struct hist_cbdata {
7968         boolean_t first;
7969         boolean_t longfmt;
7970         boolean_t internal;
7971 } hist_cbdata_t;
7972 
7973 static void
7974 print_history_records(nvlist_t *nvhis, hist_cbdata_t *cb)
7975 {
7976         nvlist_t **records;
7977         uint_t numrecords;
7978         int i;
7979 
7980         verify(nvlist_lookup_nvlist_array(nvhis, ZPOOL_HIST_RECORD,
7981             &records, &numrecords) == 0);
7982         for (i = 0; i < numrecords; i++) {
7983                 nvlist_t *rec = records[i];
7984                 char tbuf[30] = "";
7985 
7986                 if (nvlist_exists(rec, ZPOOL_HIST_TIME)) {
7987                         time_t tsec;
7988                         struct tm t;
7989 
7990                         tsec = fnvlist_lookup_uint64(records[i],
7991                             ZPOOL_HIST_TIME);
7992                         (void) localtime_r(&tsec, &t);
7993                         (void) strftime(tbuf, sizeof (tbuf), "%F.%T", &t);
7994                 }
7995 
7996                 if (nvlist_exists(rec, ZPOOL_HIST_CMD)) {
7997                         (void) printf("%s %s", tbuf,
7998                             fnvlist_lookup_string(rec, ZPOOL_HIST_CMD));
7999                 } else if (nvlist_exists(rec, ZPOOL_HIST_INT_EVENT)) {
8000                         int ievent =
8001                             fnvlist_lookup_uint64(rec, ZPOOL_HIST_INT_EVENT);
8002                         if (!cb->internal)
8003                                 continue;
8004                         if (ievent >= ZFS_NUM_LEGACY_HISTORY_EVENTS) {
8005                                 (void) printf("%s unrecognized record:\n",
8006                                     tbuf);
8007                                 dump_nvlist(rec, 4);
8008                                 continue;
8009                         }
8010                         (void) printf("%s [internal %s txg:%lld] %s", tbuf,
8011                             zfs_history_event_names[ievent],
8012                             fnvlist_lookup_uint64(rec, ZPOOL_HIST_TXG),
8013                             fnvlist_lookup_string(rec, ZPOOL_HIST_INT_STR));
8014                 } else if (nvlist_exists(rec, ZPOOL_HIST_INT_NAME)) {
8015                         if (!cb->internal)
8016                                 continue;
8017                         (void) printf("%s [txg:%lld] %s", tbuf,
8018                             fnvlist_lookup_uint64(rec, ZPOOL_HIST_TXG),
8019                             fnvlist_lookup_string(rec, ZPOOL_HIST_INT_NAME));
8020                         if (nvlist_exists(rec, ZPOOL_HIST_DSNAME)) {
8021                                 (void) printf(" %s (%llu)",
8022                                     fnvlist_lookup_string(rec,
8023                                     ZPOOL_HIST_DSNAME),
8024                                     fnvlist_lookup_uint64(rec,
8025                                     ZPOOL_HIST_DSID));
8026                         }
8027                         (void) printf(" %s", fnvlist_lookup_string(rec,
8028                             ZPOOL_HIST_INT_STR));
8029                 } else if (nvlist_exists(rec, ZPOOL_HIST_IOCTL)) {
8030                         if (!cb->internal)
8031                                 continue;
8032                         (void) printf("%s ioctl %s\n", tbuf,
8033                             fnvlist_lookup_string(rec, ZPOOL_HIST_IOCTL));
8034                         if (nvlist_exists(rec, ZPOOL_HIST_INPUT_NVL)) {
8035                                 (void) printf("    input:\n");
8036                                 dump_nvlist(fnvlist_lookup_nvlist(rec,
8037                                     ZPOOL_HIST_INPUT_NVL), 8);
8038                         }
8039                         if (nvlist_exists(rec, ZPOOL_HIST_OUTPUT_NVL)) {
8040                                 (void) printf("    output:\n");
8041                                 dump_nvlist(fnvlist_lookup_nvlist(rec,
8042                                     ZPOOL_HIST_OUTPUT_NVL), 8);
8043                         }
8044                         if (nvlist_exists(rec, ZPOOL_HIST_ERRNO)) {
8045                                 (void) printf("    errno: %lld\n",
8046                                     fnvlist_lookup_int64(rec,
8047                                     ZPOOL_HIST_ERRNO));
8048                         }
8049                 } else {
8050                         if (!cb->internal)
8051                                 continue;
8052                         (void) printf("%s unrecognized record:\n", tbuf);
8053                         dump_nvlist(rec, 4);
8054                 }
8055 
8056                 if (!cb->longfmt) {
8057                         (void) printf("\n");
8058                         continue;
8059                 }
8060                 (void) printf(" [");
8061                 if (nvlist_exists(rec, ZPOOL_HIST_WHO)) {
8062                         uid_t who = fnvlist_lookup_uint64(rec, ZPOOL_HIST_WHO);
8063                         struct passwd *pwd = getpwuid(who);
8064                         (void) printf("user %d ", (int)who);
8065                         if (pwd != NULL)
8066                                 (void) printf("(%s) ", pwd->pw_name);
8067                 }
8068                 if (nvlist_exists(rec, ZPOOL_HIST_HOST)) {
8069                         (void) printf("on %s",
8070                             fnvlist_lookup_string(rec, ZPOOL_HIST_HOST));
8071                 }
8072                 if (nvlist_exists(rec, ZPOOL_HIST_ZONE)) {
8073                         (void) printf(":%s",
8074                             fnvlist_lookup_string(rec, ZPOOL_HIST_ZONE));
8075                 }
8076                 (void) printf("]");
8077                 (void) printf("\n");
8078         }
8079 }
8080 
8081 /*
8082  * Print out the command history for a specific pool.
8083  */
8084 static int
8085 get_history_one(zpool_handle_t *zhp, void *data)
8086 {
8087         nvlist_t *nvhis;
8088         int ret;
8089         hist_cbdata_t *cb = (hist_cbdata_t *)data;
8090         uint64_t off = 0;
8091         boolean_t eof = B_FALSE;
8092 
8093         cb->first = B_FALSE;
8094 
8095         (void) printf(gettext("History for '%s':\n"), zpool_get_name(zhp));
8096 
8097         while (!eof) {
8098                 if ((ret = zpool_get_history(zhp, &nvhis, &off, &eof)) != 0)
8099                         return (ret);
8100 
8101                 print_history_records(nvhis, cb);
8102                 nvlist_free(nvhis);
8103         }
8104         (void) printf("\n");
8105 
8106         return (ret);
8107 }
8108 
8109 /*
8110  * zpool history <pool>
8111  *
8112  * Displays the history of commands that modified pools.
8113  */
8114 int
8115 zpool_do_history(int argc, char **argv)
8116 {
8117         hist_cbdata_t cbdata = { 0 };
8118         int ret;
8119         int c;
8120 
8121         cbdata.first = B_TRUE;
8122         /* check options */
8123         while ((c = getopt(argc, argv, "li")) != -1) {
8124                 switch (c) {
8125                 case 'l':
8126                         cbdata.longfmt = B_TRUE;
8127                         break;
8128                 case 'i':
8129                         cbdata.internal = B_TRUE;
8130                         break;
8131                 case '?':
8132                         (void) fprintf(stderr, gettext("invalid option '%c'\n"),
8133                             optopt);
8134                         usage(B_FALSE);
8135                 }
8136         }
8137         argc -= optind;
8138         argv += optind;
8139 
8140         ret = for_each_pool(argc, argv, B_FALSE,  NULL, get_history_one,
8141             &cbdata);
8142 
8143         if (argc == 0 && cbdata.first == B_TRUE) {
8144                 (void) printf(gettext("no pools available\n"));
8145                 return (0);
8146         }
8147 
8148         return (ret);
8149 }
8150 
8151 static int
8152 get_callback(zpool_handle_t *zhp, void *data)
8153 {
8154         zprop_get_cbdata_t *cbp = (zprop_get_cbdata_t *)data;
8155         char value[MAXNAMELEN];
8156         zprop_source_t srctype;
8157         zprop_list_t *pl;
8158 
8159         for (pl = cbp->cb_proplist; pl != NULL; pl = pl->pl_next) {
8160 
8161                 /*
8162                  * Skip the special fake placeholder. This will also skip
8163                  * over the name property when 'all' is specified.
8164                  */
8165                 if (pl->pl_prop == ZPOOL_PROP_NAME &&
8166                     pl == cbp->cb_proplist)
8167                         continue;
8168 
8169                 if (pl->pl_prop == ZPROP_INVAL &&
8170                     (zpool_prop_feature(pl->pl_user_prop) ||
8171                     zpool_prop_unsupported(pl->pl_user_prop))) {
8172                         srctype = ZPROP_SRC_LOCAL;
8173 
8174                         if (zpool_prop_get_feature(zhp, pl->pl_user_prop,
8175                             value, sizeof (value)) == 0) {
8176                                 zprop_print_one_property(zpool_get_name(zhp),
8177                                     cbp, pl->pl_user_prop, value, srctype,
8178                                     NULL, NULL);
8179                         }
8180                 } else {
8181                         if (zpool_get_prop(zhp, pl->pl_prop, value,
8182                             sizeof (value), &srctype, cbp->cb_literal) != 0)
8183                                 continue;
8184 
8185                         zprop_print_one_property(zpool_get_name(zhp), cbp,
8186                             zpool_prop_to_name(pl->pl_prop), value, srctype,
8187                             NULL, NULL);
8188                 }
8189         }
8190         return (0);
8191 }
8192 
8193 /*
8194  * zpool get [-Hp] [-o "all" | field[,...]] <"all" | property[,...]> <pool> ...
8195  *
8196  *      -H      Scripted mode.  Don't display headers, and separate properties
8197  *              by a single tab.
8198  *      -o      List of columns to display.  Defaults to
8199  *              "name,property,value,source".
8200  *      -p      Diplay values in parsable (exact) format.
8201  *
8202  * Get properties of pools in the system. Output space statistics
8203  * for each one as well as other attributes.
8204  */
8205 int
8206 zpool_do_get(int argc, char **argv)
8207 {
8208         zprop_get_cbdata_t cb = { 0 };
8209         zprop_list_t fake_name = { 0 };
8210         int ret;
8211         int c, i;
8212         char *value;
8213 
8214         cb.cb_first = B_TRUE;
8215 
8216         /*
8217          * Set up default columns and sources.
8218          */
8219         cb.cb_sources = ZPROP_SRC_ALL;
8220         cb.cb_columns[0] = GET_COL_NAME;
8221         cb.cb_columns[1] = GET_COL_PROPERTY;
8222         cb.cb_columns[2] = GET_COL_VALUE;
8223         cb.cb_columns[3] = GET_COL_SOURCE;
8224         cb.cb_type = ZFS_TYPE_POOL;
8225 
8226         /* check options */
8227         while ((c = getopt(argc, argv, ":Hpo:")) != -1) {
8228                 switch (c) {
8229                 case 'p':
8230                         cb.cb_literal = B_TRUE;
8231                         break;
8232                 case 'H':
8233                         cb.cb_scripted = B_TRUE;
8234                         break;
8235                 case 'o':
8236                         bzero(&cb.cb_columns, sizeof (cb.cb_columns));
8237                         i = 0;
8238                         while (*optarg != '\0') {
8239                                 static char *col_subopts[] =
8240                                 { "name", "property", "value", "source",
8241                                 "all", NULL };
8242 
8243                                 if (i == ZFS_GET_NCOLS) {
8244                                         (void) fprintf(stderr, gettext("too "
8245                                         "many fields given to -o "
8246                                         "option\n"));
8247                                         usage(B_FALSE);
8248                                 }
8249 
8250                                 switch (getsubopt(&optarg, col_subopts,
8251                                     &value)) {
8252                                 case 0:
8253                                         cb.cb_columns[i++] = GET_COL_NAME;
8254                                         break;
8255                                 case 1:
8256                                         cb.cb_columns[i++] = GET_COL_PROPERTY;
8257                                         break;
8258                                 case 2:
8259                                         cb.cb_columns[i++] = GET_COL_VALUE;
8260                                         break;
8261                                 case 3:
8262                                         cb.cb_columns[i++] = GET_COL_SOURCE;
8263                                         break;
8264                                 case 4:
8265                                         if (i > 0) {
8266                                                 (void) fprintf(stderr,
8267                                                     gettext("\"all\" conflicts "
8268                                                     "with specific fields "
8269                                                     "given to -o option\n"));
8270                                                 usage(B_FALSE);
8271                                         }
8272                                         cb.cb_columns[0] = GET_COL_NAME;
8273                                         cb.cb_columns[1] = GET_COL_PROPERTY;
8274                                         cb.cb_columns[2] = GET_COL_VALUE;
8275                                         cb.cb_columns[3] = GET_COL_SOURCE;
8276                                         i = ZFS_GET_NCOLS;
8277                                         break;
8278                                 default:
8279                                         (void) fprintf(stderr,
8280                                             gettext("invalid column name "
8281                                             "'%s'\n"), value);
8282                                         usage(B_FALSE);
8283                                 }
8284                         }
8285                         break;
8286                 case '?':
8287                         (void) fprintf(stderr, gettext("invalid option '%c'\n"),
8288                             optopt);
8289                         usage(B_FALSE);
8290                 }
8291         }
8292 
8293         argc -= optind;
8294         argv += optind;
8295 
8296         if (argc < 1) {
8297                 (void) fprintf(stderr, gettext("missing property "
8298                     "argument\n"));
8299                 usage(B_FALSE);
8300         }
8301 
8302         if (zprop_get_list(g_zfs, argv[0], &cb.cb_proplist,
8303             ZFS_TYPE_POOL) != 0)
8304                 usage(B_FALSE);
8305 
8306         argc--;
8307         argv++;
8308 
8309         if (cb.cb_proplist != NULL) {
8310                 fake_name.pl_prop = ZPOOL_PROP_NAME;
8311                 fake_name.pl_width = strlen(gettext("NAME"));
8312                 fake_name.pl_next = cb.cb_proplist;
8313                 cb.cb_proplist = &fake_name;
8314         }
8315 
8316         ret = for_each_pool(argc, argv, B_TRUE, &cb.cb_proplist,
8317             get_callback, &cb);
8318 
8319         if (cb.cb_proplist == &fake_name)
8320                 zprop_free_list(fake_name.pl_next);
8321         else
8322                 zprop_free_list(cb.cb_proplist);
8323 
8324         return (ret);
8325 }
8326 
8327 typedef struct set_cbdata {
8328         char *cb_propname;
8329         char *cb_value;
8330         boolean_t cb_any_successful;
8331 } set_cbdata_t;
8332 
8333 int
8334 set_callback(zpool_handle_t *zhp, void *data)
8335 {
8336         int error;
8337         set_cbdata_t *cb = (set_cbdata_t *)data;
8338 
8339         error = zpool_set_prop(zhp, cb->cb_propname, cb->cb_value);
8340 
8341         if (!error)
8342                 cb->cb_any_successful = B_TRUE;
8343 
8344         return (error);
8345 }
8346 
8347 int
8348 zpool_do_set(int argc, char **argv)
8349 {
8350         set_cbdata_t cb = { 0 };
8351         int error;
8352 
8353         if (argc > 1 && argv[1][0] == '-') {
8354                 (void) fprintf(stderr, gettext("invalid option '%c'\n"),
8355                     argv[1][1]);
8356                 usage(B_FALSE);
8357         }
8358 
8359         if (argc < 2) {
8360                 (void) fprintf(stderr, gettext("missing property=value "
8361                     "argument\n"));
8362                 usage(B_FALSE);
8363         }
8364 
8365         if (argc < 3) {
8366                 (void) fprintf(stderr, gettext("missing pool name\n"));
8367                 usage(B_FALSE);
8368         }
8369 
8370         if (argc > 3) {
8371                 (void) fprintf(stderr, gettext("too many pool names\n"));
8372                 usage(B_FALSE);
8373         }
8374 
8375         cb.cb_propname = argv[1];
8376         cb.cb_value = strchr(cb.cb_propname, '=');
8377         if (cb.cb_value == NULL) {
8378                 (void) fprintf(stderr, gettext("missing value in "
8379                     "property=value argument\n"));
8380                 usage(B_FALSE);
8381         }
8382 
8383         *(cb.cb_value) = '\0';
8384         cb.cb_value++;
8385 
8386         error = for_each_pool(argc - 2, argv + 2, B_TRUE, NULL,
8387             set_callback, &cb);
8388 
8389         return (error);
8390 }
8391 
8392 static int
8393 find_command_idx(char *command, int *idx)
8394 {
8395         int i;
8396 
8397         for (i = 0; i < NCOMMAND; i++) {
8398                 if (command_table[i].name == NULL)
8399                         continue;
8400 
8401                 if (strcmp(command, command_table[i].name) == 0) {
8402                         *idx = i;
8403                         return (0);
8404                 }
8405         }
8406         return (1);
8407 }
8408 
8409 int
8410 main(int argc, char **argv)
8411 {
8412         int ret = 0;
8413         int i;
8414         char *cmdname;
8415 
8416         (void) setlocale(LC_ALL, "");
8417         (void) textdomain(TEXT_DOMAIN);
8418 
8419         if ((g_zfs = libzfs_init()) == NULL) {
8420                 (void) fprintf(stderr, gettext("internal error: failed to "
8421                     "initialize ZFS library\n"));
8422                 return (1);
8423         }
8424 
8425         libzfs_print_on_error(g_zfs, B_TRUE);
8426 
8427         opterr = 0;
8428 
8429         /*
8430          * Make sure the user has specified some command.
8431          */
8432         if (argc < 2) {
8433                 (void) fprintf(stderr, gettext("missing command\n"));
8434                 usage(B_FALSE);
8435         }
8436 
8437         cmdname = argv[1];
8438 
8439         /*
8440          * Special case '-?'
8441          */
8442         if (strcmp(cmdname, "-?") == 0)
8443                 usage(B_TRUE);
8444 
8445         zfs_save_arguments(argc, argv, history_str, sizeof (history_str));
8446 
8447         /*
8448          * Run the appropriate command.
8449          */
8450         if (find_command_idx(cmdname, &i) == 0) {
8451                 current_command = &command_table[i];
8452                 ret = command_table[i].func(argc - 1, argv + 1);
8453         } else if (strchr(cmdname, '=')) {
8454                 verify(find_command_idx("set", &i) == 0);
8455                 current_command = &command_table[i];
8456                 ret = command_table[i].func(argc, argv);
8457         } else if (strcmp(cmdname, "freeze") == 0 && argc == 3) {
8458                 /*
8459                  * 'freeze' is a vile debugging abomination, so we treat
8460                  * it as such.
8461                  */
8462                 char buf[16384];
8463                 int fd = open(ZFS_DEV, O_RDWR);
8464                 (void) strcpy((void *)buf, argv[2]);
8465                 return (!!ioctl(fd, ZFS_IOC_POOL_FREEZE, buf));
8466         } else {
8467                 (void) fprintf(stderr, gettext("unrecognized "
8468                     "command '%s'\n"), cmdname);
8469                 usage(B_FALSE);
8470         }
8471 
8472         if (ret == 0 && log_history)
8473                 (void) zpool_log_history(g_zfs, history_str);
8474 
8475         libzfs_fini(g_zfs);
8476 
8477         /*
8478          * The 'ZFS_ABORT' environment variable causes us to dump core on exit
8479          * for the purposes of running ::findleaks.
8480          */
8481         if (getenv("ZFS_ABORT") != NULL) {
8482                 (void) printf("dumping core by request\n");
8483                 abort();
8484         }
8485 
8486         return (ret);
8487 }