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