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