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