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