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