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