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