xref: /titanic_44/usr/src/cmd/zpool/zpool_main.c (revision a417a0e00dcfc46716fd95c676b5017c7923e382)
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)
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) != 0)
1271 		return (1);
1272 
1273 	if (newname != NULL)
1274 		name = (char *)newname;
1275 
1276 	verify((zhp = zpool_open(g_zfs, name)) != NULL);
1277 
1278 	if (zpool_enable_datasets(zhp, mntopts, 0) != 0) {
1279 		zpool_close(zhp);
1280 		return (1);
1281 	}
1282 
1283 	zpool_close(zhp);
1284 	return (error);
1285 }
1286 
1287 /*
1288  * zpool import [-d dir] [-D]
1289  *       import [-o mntopts] [-o prop=value] ... [-R root] [-D]
1290  *              [-d dir | -c cachefile] [-f] -a
1291  *       import [-o mntopts] [-o prop=value] ... [-R root] [-D]
1292  *              [-d dir | -c cachefile] [-f] <pool | id> [newpool]
1293  *
1294  *	 -c	Read pool information from a cachefile instead of searching
1295  *		devices.
1296  *
1297  *       -d	Scan in a specific directory, other than /dev/dsk.  More than
1298  *		one directory can be specified using multiple '-d' options.
1299  *
1300  *       -D     Scan for previously destroyed pools or import all or only
1301  *              specified destroyed pools.
1302  *
1303  *       -R	Temporarily import the pool, with all mountpoints relative to
1304  *		the given root.  The pool will remain exported when the machine
1305  *		is rebooted.
1306  *
1307  *       -f	Force import, even if it appears that the pool is active.
1308  *
1309  *       -a	Import all pools found.
1310  *
1311  *       -o	Set property=value and/or temporary mount options (without '=').
1312  *
1313  * The import command scans for pools to import, and import pools based on pool
1314  * name and GUID.  The pool can also be renamed as part of the import process.
1315  */
1316 int
1317 zpool_do_import(int argc, char **argv)
1318 {
1319 	char **searchdirs = NULL;
1320 	int nsearch = 0;
1321 	int c;
1322 	int err;
1323 	nvlist_t *pools = NULL;
1324 	boolean_t do_all = B_FALSE;
1325 	boolean_t do_destroyed = B_FALSE;
1326 	char *mntopts = NULL;
1327 	boolean_t do_force = B_FALSE;
1328 	nvpair_t *elem;
1329 	nvlist_t *config;
1330 	uint64_t searchguid;
1331 	char *searchname;
1332 	char *propval;
1333 	nvlist_t *found_config;
1334 	nvlist_t *props = NULL;
1335 	boolean_t first;
1336 	uint64_t pool_state;
1337 	char *cachefile = NULL;
1338 
1339 	/* check options */
1340 	while ((c = getopt(argc, argv, ":afc:d:Do:p:R:")) != -1) {
1341 		switch (c) {
1342 		case 'a':
1343 			do_all = B_TRUE;
1344 			break;
1345 		case 'c':
1346 			cachefile = optarg;
1347 			break;
1348 		case 'd':
1349 			if (searchdirs == NULL) {
1350 				searchdirs = safe_malloc(sizeof (char *));
1351 			} else {
1352 				char **tmp = safe_malloc((nsearch + 1) *
1353 				    sizeof (char *));
1354 				bcopy(searchdirs, tmp, nsearch *
1355 				    sizeof (char *));
1356 				free(searchdirs);
1357 				searchdirs = tmp;
1358 			}
1359 			searchdirs[nsearch++] = optarg;
1360 			break;
1361 		case 'D':
1362 			do_destroyed = B_TRUE;
1363 			break;
1364 		case 'f':
1365 			do_force = B_TRUE;
1366 			break;
1367 		case 'o':
1368 			if ((propval = strchr(optarg, '=')) != NULL) {
1369 				*propval = '\0';
1370 				propval++;
1371 				if (add_prop_list(optarg, propval, &props))
1372 					goto error;
1373 			} else {
1374 				mntopts = optarg;
1375 			}
1376 			break;
1377 		case 'R':
1378 			if (add_prop_list(zpool_prop_to_name(
1379 			    ZPOOL_PROP_ALTROOT), optarg, &props))
1380 				goto error;
1381 			if (nvlist_lookup_string(props,
1382 			    zpool_prop_to_name(ZPOOL_PROP_CACHEFILE),
1383 			    &propval) == 0)
1384 				break;
1385 			if (add_prop_list(zpool_prop_to_name(
1386 			    ZPOOL_PROP_CACHEFILE), "none", &props))
1387 				goto error;
1388 			break;
1389 		case ':':
1390 			(void) fprintf(stderr, gettext("missing argument for "
1391 			    "'%c' option\n"), optopt);
1392 			usage(B_FALSE);
1393 			break;
1394 		case '?':
1395 			(void) fprintf(stderr, gettext("invalid option '%c'\n"),
1396 			    optopt);
1397 			usage(B_FALSE);
1398 		}
1399 	}
1400 
1401 	argc -= optind;
1402 	argv += optind;
1403 
1404 	if (cachefile && nsearch != 0) {
1405 		(void) fprintf(stderr, gettext("-c is incompatible with -d\n"));
1406 		usage(B_FALSE);
1407 	}
1408 
1409 	if (searchdirs == NULL) {
1410 		searchdirs = safe_malloc(sizeof (char *));
1411 		searchdirs[0] = "/dev/dsk";
1412 		nsearch = 1;
1413 	}
1414 
1415 	/* check argument count */
1416 	if (do_all) {
1417 		if (argc != 0) {
1418 			(void) fprintf(stderr, gettext("too many arguments\n"));
1419 			usage(B_FALSE);
1420 		}
1421 	} else {
1422 		if (argc > 2) {
1423 			(void) fprintf(stderr, gettext("too many arguments\n"));
1424 			usage(B_FALSE);
1425 		}
1426 
1427 		/*
1428 		 * Check for the SYS_CONFIG privilege.  We do this explicitly
1429 		 * here because otherwise any attempt to discover pools will
1430 		 * silently fail.
1431 		 */
1432 		if (argc == 0 && !priv_ineffect(PRIV_SYS_CONFIG)) {
1433 			(void) fprintf(stderr, gettext("cannot "
1434 			    "discover pools: permission denied\n"));
1435 			free(searchdirs);
1436 			return (1);
1437 		}
1438 	}
1439 
1440 	if (cachefile)
1441 		pools = zpool_find_import_cached(g_zfs, cachefile, B_FALSE);
1442 	else
1443 		pools = zpool_find_import(g_zfs, nsearch, searchdirs, B_FALSE);
1444 
1445 	if (pools == NULL) {
1446 		free(searchdirs);
1447 		return (1);
1448 	}
1449 
1450 	/*
1451 	 * We now have a list of all available pools in the given directories.
1452 	 * Depending on the arguments given, we do one of the following:
1453 	 *
1454 	 *	<none>	Iterate through all pools and display information about
1455 	 *		each one.
1456 	 *
1457 	 *	-a	Iterate through all pools and try to import each one.
1458 	 *
1459 	 *	<id>	Find the pool that corresponds to the given GUID/pool
1460 	 *		name and import that one.
1461 	 *
1462 	 *	-D	Above options applies only to destroyed pools.
1463 	 */
1464 	if (argc != 0) {
1465 		char *endptr;
1466 
1467 		errno = 0;
1468 		searchguid = strtoull(argv[0], &endptr, 10);
1469 		if (errno != 0 || *endptr != '\0')
1470 			searchname = argv[0];
1471 		else
1472 			searchname = NULL;
1473 		found_config = NULL;
1474 	}
1475 
1476 	err = 0;
1477 	elem = NULL;
1478 	first = B_TRUE;
1479 	while ((elem = nvlist_next_nvpair(pools, elem)) != NULL) {
1480 
1481 		verify(nvpair_value_nvlist(elem, &config) == 0);
1482 
1483 		verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_STATE,
1484 		    &pool_state) == 0);
1485 		if (!do_destroyed && pool_state == POOL_STATE_DESTROYED)
1486 			continue;
1487 		if (do_destroyed && pool_state != POOL_STATE_DESTROYED)
1488 			continue;
1489 
1490 		if (argc == 0) {
1491 			if (first)
1492 				first = B_FALSE;
1493 			else if (!do_all)
1494 				(void) printf("\n");
1495 
1496 			if (do_all)
1497 				err |= do_import(config, NULL, mntopts,
1498 				    do_force, props);
1499 			else
1500 				show_import(config);
1501 		} else if (searchname != NULL) {
1502 			char *name;
1503 
1504 			/*
1505 			 * We are searching for a pool based on name.
1506 			 */
1507 			verify(nvlist_lookup_string(config,
1508 			    ZPOOL_CONFIG_POOL_NAME, &name) == 0);
1509 
1510 			if (strcmp(name, searchname) == 0) {
1511 				if (found_config != NULL) {
1512 					(void) fprintf(stderr, gettext(
1513 					    "cannot import '%s': more than "
1514 					    "one matching pool\n"), searchname);
1515 					(void) fprintf(stderr, gettext(
1516 					    "import by numeric ID instead\n"));
1517 					err = B_TRUE;
1518 				}
1519 				found_config = config;
1520 			}
1521 		} else {
1522 			uint64_t guid;
1523 
1524 			/*
1525 			 * Search for a pool by guid.
1526 			 */
1527 			verify(nvlist_lookup_uint64(config,
1528 			    ZPOOL_CONFIG_POOL_GUID, &guid) == 0);
1529 
1530 			if (guid == searchguid)
1531 				found_config = config;
1532 		}
1533 	}
1534 
1535 	/*
1536 	 * If we were searching for a specific pool, verify that we found a
1537 	 * pool, and then do the import.
1538 	 */
1539 	if (argc != 0 && err == 0) {
1540 		if (found_config == NULL) {
1541 			(void) fprintf(stderr, gettext("cannot import '%s': "
1542 			    "no such pool available\n"), argv[0]);
1543 			err = B_TRUE;
1544 		} else {
1545 			err |= do_import(found_config, argc == 1 ? NULL :
1546 			    argv[1], mntopts, do_force, props);
1547 		}
1548 	}
1549 
1550 	/*
1551 	 * If we were just looking for pools, report an error if none were
1552 	 * found.
1553 	 */
1554 	if (argc == 0 && first)
1555 		(void) fprintf(stderr,
1556 		    gettext("no pools available to import\n"));
1557 
1558 error:
1559 	nvlist_free(props);
1560 	nvlist_free(pools);
1561 	free(searchdirs);
1562 
1563 	return (err ? 1 : 0);
1564 }
1565 
1566 typedef struct iostat_cbdata {
1567 	zpool_list_t *cb_list;
1568 	int cb_verbose;
1569 	int cb_iteration;
1570 	int cb_namewidth;
1571 } iostat_cbdata_t;
1572 
1573 static void
1574 print_iostat_separator(iostat_cbdata_t *cb)
1575 {
1576 	int i = 0;
1577 
1578 	for (i = 0; i < cb->cb_namewidth; i++)
1579 		(void) printf("-");
1580 	(void) printf("  -----  -----  -----  -----  -----  -----\n");
1581 }
1582 
1583 static void
1584 print_iostat_header(iostat_cbdata_t *cb)
1585 {
1586 	(void) printf("%*s     capacity     operations    bandwidth\n",
1587 	    cb->cb_namewidth, "");
1588 	(void) printf("%-*s   used  avail   read  write   read  write\n",
1589 	    cb->cb_namewidth, "pool");
1590 	print_iostat_separator(cb);
1591 }
1592 
1593 /*
1594  * Display a single statistic.
1595  */
1596 static void
1597 print_one_stat(uint64_t value)
1598 {
1599 	char buf[64];
1600 
1601 	zfs_nicenum(value, buf, sizeof (buf));
1602 	(void) printf("  %5s", buf);
1603 }
1604 
1605 /*
1606  * Print out all the statistics for the given vdev.  This can either be the
1607  * toplevel configuration, or called recursively.  If 'name' is NULL, then this
1608  * is a verbose output, and we don't want to display the toplevel pool stats.
1609  */
1610 void
1611 print_vdev_stats(zpool_handle_t *zhp, const char *name, nvlist_t *oldnv,
1612     nvlist_t *newnv, iostat_cbdata_t *cb, int depth)
1613 {
1614 	nvlist_t **oldchild, **newchild;
1615 	uint_t c, children;
1616 	vdev_stat_t *oldvs, *newvs;
1617 	vdev_stat_t zerovs = { 0 };
1618 	uint64_t tdelta;
1619 	double scale;
1620 	char *vname;
1621 
1622 	if (oldnv != NULL) {
1623 		verify(nvlist_lookup_uint64_array(oldnv, ZPOOL_CONFIG_STATS,
1624 		    (uint64_t **)&oldvs, &c) == 0);
1625 	} else {
1626 		oldvs = &zerovs;
1627 	}
1628 
1629 	verify(nvlist_lookup_uint64_array(newnv, ZPOOL_CONFIG_STATS,
1630 	    (uint64_t **)&newvs, &c) == 0);
1631 
1632 	if (strlen(name) + depth > cb->cb_namewidth)
1633 		(void) printf("%*s%s", depth, "", name);
1634 	else
1635 		(void) printf("%*s%s%*s", depth, "", name,
1636 		    (int)(cb->cb_namewidth - strlen(name) - depth), "");
1637 
1638 	tdelta = newvs->vs_timestamp - oldvs->vs_timestamp;
1639 
1640 	if (tdelta == 0)
1641 		scale = 1.0;
1642 	else
1643 		scale = (double)NANOSEC / tdelta;
1644 
1645 	/* only toplevel vdevs have capacity stats */
1646 	if (newvs->vs_space == 0) {
1647 		(void) printf("      -      -");
1648 	} else {
1649 		print_one_stat(newvs->vs_alloc);
1650 		print_one_stat(newvs->vs_space - newvs->vs_alloc);
1651 	}
1652 
1653 	print_one_stat((uint64_t)(scale * (newvs->vs_ops[ZIO_TYPE_READ] -
1654 	    oldvs->vs_ops[ZIO_TYPE_READ])));
1655 
1656 	print_one_stat((uint64_t)(scale * (newvs->vs_ops[ZIO_TYPE_WRITE] -
1657 	    oldvs->vs_ops[ZIO_TYPE_WRITE])));
1658 
1659 	print_one_stat((uint64_t)(scale * (newvs->vs_bytes[ZIO_TYPE_READ] -
1660 	    oldvs->vs_bytes[ZIO_TYPE_READ])));
1661 
1662 	print_one_stat((uint64_t)(scale * (newvs->vs_bytes[ZIO_TYPE_WRITE] -
1663 	    oldvs->vs_bytes[ZIO_TYPE_WRITE])));
1664 
1665 	(void) printf("\n");
1666 
1667 	if (!cb->cb_verbose)
1668 		return;
1669 
1670 	if (nvlist_lookup_nvlist_array(newnv, ZPOOL_CONFIG_CHILDREN,
1671 	    &newchild, &children) != 0)
1672 		return;
1673 
1674 	if (oldnv && nvlist_lookup_nvlist_array(oldnv, ZPOOL_CONFIG_CHILDREN,
1675 	    &oldchild, &c) != 0)
1676 		return;
1677 
1678 	for (c = 0; c < children; c++) {
1679 		vname = zpool_vdev_name(g_zfs, zhp, newchild[c]);
1680 		print_vdev_stats(zhp, vname, oldnv ? oldchild[c] : NULL,
1681 		    newchild[c], cb, depth + 2);
1682 		free(vname);
1683 	}
1684 
1685 	/*
1686 	 * Include level 2 ARC devices in iostat output
1687 	 */
1688 	if (nvlist_lookup_nvlist_array(newnv, ZPOOL_CONFIG_L2CACHE,
1689 	    &newchild, &children) != 0)
1690 		return;
1691 
1692 	if (oldnv && nvlist_lookup_nvlist_array(oldnv, ZPOOL_CONFIG_L2CACHE,
1693 	    &oldchild, &c) != 0)
1694 		return;
1695 
1696 	if (children > 0) {
1697 		(void) printf("%-*s      -      -      -      -      -      "
1698 		    "-\n", cb->cb_namewidth, "cache");
1699 		for (c = 0; c < children; c++) {
1700 			vname = zpool_vdev_name(g_zfs, zhp, newchild[c]);
1701 			print_vdev_stats(zhp, vname, oldnv ? oldchild[c] : NULL,
1702 			    newchild[c], cb, depth + 2);
1703 			free(vname);
1704 		}
1705 	}
1706 }
1707 
1708 static int
1709 refresh_iostat(zpool_handle_t *zhp, void *data)
1710 {
1711 	iostat_cbdata_t *cb = data;
1712 	boolean_t missing;
1713 
1714 	/*
1715 	 * If the pool has disappeared, remove it from the list and continue.
1716 	 */
1717 	if (zpool_refresh_stats(zhp, &missing) != 0)
1718 		return (-1);
1719 
1720 	if (missing)
1721 		pool_list_remove(cb->cb_list, zhp);
1722 
1723 	return (0);
1724 }
1725 
1726 /*
1727  * Callback to print out the iostats for the given pool.
1728  */
1729 int
1730 print_iostat(zpool_handle_t *zhp, void *data)
1731 {
1732 	iostat_cbdata_t *cb = data;
1733 	nvlist_t *oldconfig, *newconfig;
1734 	nvlist_t *oldnvroot, *newnvroot;
1735 
1736 	newconfig = zpool_get_config(zhp, &oldconfig);
1737 
1738 	if (cb->cb_iteration == 1)
1739 		oldconfig = NULL;
1740 
1741 	verify(nvlist_lookup_nvlist(newconfig, ZPOOL_CONFIG_VDEV_TREE,
1742 	    &newnvroot) == 0);
1743 
1744 	if (oldconfig == NULL)
1745 		oldnvroot = NULL;
1746 	else
1747 		verify(nvlist_lookup_nvlist(oldconfig, ZPOOL_CONFIG_VDEV_TREE,
1748 		    &oldnvroot) == 0);
1749 
1750 	/*
1751 	 * Print out the statistics for the pool.
1752 	 */
1753 	print_vdev_stats(zhp, zpool_get_name(zhp), oldnvroot, newnvroot, cb, 0);
1754 
1755 	if (cb->cb_verbose)
1756 		print_iostat_separator(cb);
1757 
1758 	return (0);
1759 }
1760 
1761 int
1762 get_namewidth(zpool_handle_t *zhp, void *data)
1763 {
1764 	iostat_cbdata_t *cb = data;
1765 	nvlist_t *config, *nvroot;
1766 
1767 	if ((config = zpool_get_config(zhp, NULL)) != NULL) {
1768 		verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
1769 		    &nvroot) == 0);
1770 		if (!cb->cb_verbose)
1771 			cb->cb_namewidth = strlen(zpool_get_name(zhp));
1772 		else
1773 			cb->cb_namewidth = max_width(zhp, nvroot, 0, 0);
1774 	}
1775 
1776 	/*
1777 	 * The width must fall into the range [10,38].  The upper limit is the
1778 	 * maximum we can have and still fit in 80 columns.
1779 	 */
1780 	if (cb->cb_namewidth < 10)
1781 		cb->cb_namewidth = 10;
1782 	if (cb->cb_namewidth > 38)
1783 		cb->cb_namewidth = 38;
1784 
1785 	return (0);
1786 }
1787 
1788 /*
1789  * zpool iostat [-v] [pool] ... [interval [count]]
1790  *
1791  *	-v	Display statistics for individual vdevs
1792  *
1793  * This command can be tricky because we want to be able to deal with pool
1794  * creation/destruction as well as vdev configuration changes.  The bulk of this
1795  * processing is handled by the pool_list_* routines in zpool_iter.c.  We rely
1796  * on pool_list_update() to detect the addition of new pools.  Configuration
1797  * changes are all handled within libzfs.
1798  */
1799 int
1800 zpool_do_iostat(int argc, char **argv)
1801 {
1802 	int c;
1803 	int ret;
1804 	int npools;
1805 	unsigned long interval = 0, count = 0;
1806 	zpool_list_t *list;
1807 	boolean_t verbose = B_FALSE;
1808 	iostat_cbdata_t cb;
1809 
1810 	/* check options */
1811 	while ((c = getopt(argc, argv, "v")) != -1) {
1812 		switch (c) {
1813 		case 'v':
1814 			verbose = B_TRUE;
1815 			break;
1816 		case '?':
1817 			(void) fprintf(stderr, gettext("invalid option '%c'\n"),
1818 			    optopt);
1819 			usage(B_FALSE);
1820 		}
1821 	}
1822 
1823 	argc -= optind;
1824 	argv += optind;
1825 
1826 	/*
1827 	 * Determine if the last argument is an integer or a pool name
1828 	 */
1829 	if (argc > 0 && isdigit(argv[argc - 1][0])) {
1830 		char *end;
1831 
1832 		errno = 0;
1833 		interval = strtoul(argv[argc - 1], &end, 10);
1834 
1835 		if (*end == '\0' && errno == 0) {
1836 			if (interval == 0) {
1837 				(void) fprintf(stderr, gettext("interval "
1838 				    "cannot be zero\n"));
1839 				usage(B_FALSE);
1840 			}
1841 
1842 			/*
1843 			 * Ignore the last parameter
1844 			 */
1845 			argc--;
1846 		} else {
1847 			/*
1848 			 * If this is not a valid number, just plow on.  The
1849 			 * user will get a more informative error message later
1850 			 * on.
1851 			 */
1852 			interval = 0;
1853 		}
1854 	}
1855 
1856 	/*
1857 	 * If the last argument is also an integer, then we have both a count
1858 	 * and an integer.
1859 	 */
1860 	if (argc > 0 && isdigit(argv[argc - 1][0])) {
1861 		char *end;
1862 
1863 		errno = 0;
1864 		count = interval;
1865 		interval = strtoul(argv[argc - 1], &end, 10);
1866 
1867 		if (*end == '\0' && errno == 0) {
1868 			if (interval == 0) {
1869 				(void) fprintf(stderr, gettext("interval "
1870 				    "cannot be zero\n"));
1871 				usage(B_FALSE);
1872 			}
1873 
1874 			/*
1875 			 * Ignore the last parameter
1876 			 */
1877 			argc--;
1878 		} else {
1879 			interval = 0;
1880 		}
1881 	}
1882 
1883 	/*
1884 	 * Construct the list of all interesting pools.
1885 	 */
1886 	ret = 0;
1887 	if ((list = pool_list_get(argc, argv, NULL, &ret)) == NULL)
1888 		return (1);
1889 
1890 	if (pool_list_count(list) == 0 && argc != 0) {
1891 		pool_list_free(list);
1892 		return (1);
1893 	}
1894 
1895 	if (pool_list_count(list) == 0 && interval == 0) {
1896 		pool_list_free(list);
1897 		(void) fprintf(stderr, gettext("no pools available\n"));
1898 		return (1);
1899 	}
1900 
1901 	/*
1902 	 * Enter the main iostat loop.
1903 	 */
1904 	cb.cb_list = list;
1905 	cb.cb_verbose = verbose;
1906 	cb.cb_iteration = 0;
1907 	cb.cb_namewidth = 0;
1908 
1909 	for (;;) {
1910 		pool_list_update(list);
1911 
1912 		if ((npools = pool_list_count(list)) == 0)
1913 			break;
1914 
1915 		/*
1916 		 * Refresh all statistics.  This is done as an explicit step
1917 		 * before calculating the maximum name width, so that any
1918 		 * configuration changes are properly accounted for.
1919 		 */
1920 		(void) pool_list_iter(list, B_FALSE, refresh_iostat, &cb);
1921 
1922 		/*
1923 		 * Iterate over all pools to determine the maximum width
1924 		 * for the pool / device name column across all pools.
1925 		 */
1926 		cb.cb_namewidth = 0;
1927 		(void) pool_list_iter(list, B_FALSE, get_namewidth, &cb);
1928 
1929 		/*
1930 		 * If it's the first time, or verbose mode, print the header.
1931 		 */
1932 		if (++cb.cb_iteration == 1 || verbose)
1933 			print_iostat_header(&cb);
1934 
1935 		(void) pool_list_iter(list, B_FALSE, print_iostat, &cb);
1936 
1937 		/*
1938 		 * If there's more than one pool, and we're not in verbose mode
1939 		 * (which prints a separator for us), then print a separator.
1940 		 */
1941 		if (npools > 1 && !verbose)
1942 			print_iostat_separator(&cb);
1943 
1944 		if (verbose)
1945 			(void) printf("\n");
1946 
1947 		/*
1948 		 * Flush the output so that redirection to a file isn't buffered
1949 		 * indefinitely.
1950 		 */
1951 		(void) fflush(stdout);
1952 
1953 		if (interval == 0)
1954 			break;
1955 
1956 		if (count != 0 && --count == 0)
1957 			break;
1958 
1959 		(void) sleep(interval);
1960 	}
1961 
1962 	pool_list_free(list);
1963 
1964 	return (ret);
1965 }
1966 
1967 typedef struct list_cbdata {
1968 	boolean_t	cb_scripted;
1969 	boolean_t	cb_first;
1970 	zprop_list_t	*cb_proplist;
1971 } list_cbdata_t;
1972 
1973 /*
1974  * Given a list of columns to display, output appropriate headers for each one.
1975  */
1976 static void
1977 print_header(zprop_list_t *pl)
1978 {
1979 	const char *header;
1980 	boolean_t first = B_TRUE;
1981 	boolean_t right_justify;
1982 
1983 	for (; pl != NULL; pl = pl->pl_next) {
1984 		if (pl->pl_prop == ZPROP_INVAL)
1985 			continue;
1986 
1987 		if (!first)
1988 			(void) printf("  ");
1989 		else
1990 			first = B_FALSE;
1991 
1992 		header = zpool_prop_column_name(pl->pl_prop);
1993 		right_justify = zpool_prop_align_right(pl->pl_prop);
1994 
1995 		if (pl->pl_next == NULL && !right_justify)
1996 			(void) printf("%s", header);
1997 		else if (right_justify)
1998 			(void) printf("%*s", pl->pl_width, header);
1999 		else
2000 			(void) printf("%-*s", pl->pl_width, header);
2001 	}
2002 
2003 	(void) printf("\n");
2004 }
2005 
2006 /*
2007  * Given a pool and a list of properties, print out all the properties according
2008  * to the described layout.
2009  */
2010 static void
2011 print_pool(zpool_handle_t *zhp, zprop_list_t *pl, int scripted)
2012 {
2013 	boolean_t first = B_TRUE;
2014 	char property[ZPOOL_MAXPROPLEN];
2015 	char *propstr;
2016 	boolean_t right_justify;
2017 	int width;
2018 
2019 	for (; pl != NULL; pl = pl->pl_next) {
2020 		if (!first) {
2021 			if (scripted)
2022 				(void) printf("\t");
2023 			else
2024 				(void) printf("  ");
2025 		} else {
2026 			first = B_FALSE;
2027 		}
2028 
2029 		right_justify = B_FALSE;
2030 		if (pl->pl_prop != ZPROP_INVAL) {
2031 			if (zpool_get_prop(zhp, pl->pl_prop, property,
2032 			    sizeof (property), NULL) != 0)
2033 				propstr = "-";
2034 			else
2035 				propstr = property;
2036 
2037 			right_justify = zpool_prop_align_right(pl->pl_prop);
2038 		} else {
2039 			propstr = "-";
2040 		}
2041 
2042 		width = pl->pl_width;
2043 
2044 		/*
2045 		 * If this is being called in scripted mode, or if this is the
2046 		 * last column and it is left-justified, don't include a width
2047 		 * format specifier.
2048 		 */
2049 		if (scripted || (pl->pl_next == NULL && !right_justify))
2050 			(void) printf("%s", propstr);
2051 		else if (right_justify)
2052 			(void) printf("%*s", width, propstr);
2053 		else
2054 			(void) printf("%-*s", width, propstr);
2055 	}
2056 
2057 	(void) printf("\n");
2058 }
2059 
2060 /*
2061  * Generic callback function to list a pool.
2062  */
2063 int
2064 list_callback(zpool_handle_t *zhp, void *data)
2065 {
2066 	list_cbdata_t *cbp = data;
2067 
2068 	if (cbp->cb_first) {
2069 		if (!cbp->cb_scripted)
2070 			print_header(cbp->cb_proplist);
2071 		cbp->cb_first = B_FALSE;
2072 	}
2073 
2074 	print_pool(zhp, cbp->cb_proplist, cbp->cb_scripted);
2075 
2076 	return (0);
2077 }
2078 
2079 /*
2080  * zpool list [-H] [-o prop[,prop]*] [pool] ...
2081  *
2082  *	-H	Scripted mode.  Don't display headers, and separate properties
2083  *		by a single tab.
2084  *	-o	List of properties to display.  Defaults to
2085  *		"name,size,used,available,capacity,health,altroot"
2086  *
2087  * List all pools in the system, whether or not they're healthy.  Output space
2088  * statistics for each one, as well as health status summary.
2089  */
2090 int
2091 zpool_do_list(int argc, char **argv)
2092 {
2093 	int c;
2094 	int ret;
2095 	list_cbdata_t cb = { 0 };
2096 	static char default_props[] =
2097 	    "name,size,used,available,capacity,health,altroot";
2098 	char *props = default_props;
2099 
2100 	/* check options */
2101 	while ((c = getopt(argc, argv, ":Ho:")) != -1) {
2102 		switch (c) {
2103 		case 'H':
2104 			cb.cb_scripted = B_TRUE;
2105 			break;
2106 		case 'o':
2107 			props = optarg;
2108 			break;
2109 		case ':':
2110 			(void) fprintf(stderr, gettext("missing argument for "
2111 			    "'%c' option\n"), optopt);
2112 			usage(B_FALSE);
2113 			break;
2114 		case '?':
2115 			(void) fprintf(stderr, gettext("invalid option '%c'\n"),
2116 			    optopt);
2117 			usage(B_FALSE);
2118 		}
2119 	}
2120 
2121 	argc -= optind;
2122 	argv += optind;
2123 
2124 	if (zprop_get_list(g_zfs, props, &cb.cb_proplist, ZFS_TYPE_POOL) != 0)
2125 		usage(B_FALSE);
2126 
2127 	cb.cb_first = B_TRUE;
2128 
2129 	ret = for_each_pool(argc, argv, B_TRUE, &cb.cb_proplist,
2130 	    list_callback, &cb);
2131 
2132 	zprop_free_list(cb.cb_proplist);
2133 
2134 	if (argc == 0 && cb.cb_first && !cb.cb_scripted) {
2135 		(void) printf(gettext("no pools available\n"));
2136 		return (0);
2137 	}
2138 
2139 	return (ret);
2140 }
2141 
2142 static nvlist_t *
2143 zpool_get_vdev_by_name(nvlist_t *nv, char *name)
2144 {
2145 	nvlist_t **child;
2146 	uint_t c, children;
2147 	nvlist_t *match;
2148 	char *path;
2149 
2150 	if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
2151 	    &child, &children) != 0) {
2152 		verify(nvlist_lookup_string(nv, ZPOOL_CONFIG_PATH, &path) == 0);
2153 		if (strncmp(name, "/dev/dsk/", 9) == 0)
2154 			name += 9;
2155 		if (strncmp(path, "/dev/dsk/", 9) == 0)
2156 			path += 9;
2157 		if (strcmp(name, path) == 0)
2158 			return (nv);
2159 		return (NULL);
2160 	}
2161 
2162 	for (c = 0; c < children; c++)
2163 		if ((match = zpool_get_vdev_by_name(child[c], name)) != NULL)
2164 			return (match);
2165 
2166 	return (NULL);
2167 }
2168 
2169 static int
2170 zpool_do_attach_or_replace(int argc, char **argv, int replacing)
2171 {
2172 	boolean_t force = B_FALSE;
2173 	int c;
2174 	nvlist_t *nvroot;
2175 	char *poolname, *old_disk, *new_disk;
2176 	zpool_handle_t *zhp;
2177 	int ret;
2178 
2179 	/* check options */
2180 	while ((c = getopt(argc, argv, "f")) != -1) {
2181 		switch (c) {
2182 		case 'f':
2183 			force = B_TRUE;
2184 			break;
2185 		case '?':
2186 			(void) fprintf(stderr, gettext("invalid option '%c'\n"),
2187 			    optopt);
2188 			usage(B_FALSE);
2189 		}
2190 	}
2191 
2192 	argc -= optind;
2193 	argv += optind;
2194 
2195 	/* get pool name and check number of arguments */
2196 	if (argc < 1) {
2197 		(void) fprintf(stderr, gettext("missing pool name argument\n"));
2198 		usage(B_FALSE);
2199 	}
2200 
2201 	poolname = argv[0];
2202 
2203 	if (argc < 2) {
2204 		(void) fprintf(stderr,
2205 		    gettext("missing <device> specification\n"));
2206 		usage(B_FALSE);
2207 	}
2208 
2209 	old_disk = argv[1];
2210 
2211 	if (argc < 3) {
2212 		if (!replacing) {
2213 			(void) fprintf(stderr,
2214 			    gettext("missing <new_device> specification\n"));
2215 			usage(B_FALSE);
2216 		}
2217 		new_disk = old_disk;
2218 		argc -= 1;
2219 		argv += 1;
2220 	} else {
2221 		new_disk = argv[2];
2222 		argc -= 2;
2223 		argv += 2;
2224 	}
2225 
2226 	if (argc > 1) {
2227 		(void) fprintf(stderr, gettext("too many arguments\n"));
2228 		usage(B_FALSE);
2229 	}
2230 
2231 	if ((zhp = zpool_open(g_zfs, poolname)) == NULL)
2232 		return (1);
2233 
2234 	if (zpool_get_config(zhp, NULL) == NULL) {
2235 		(void) fprintf(stderr, gettext("pool '%s' is unavailable\n"),
2236 		    poolname);
2237 		zpool_close(zhp);
2238 		return (1);
2239 	}
2240 
2241 	nvroot = make_root_vdev(zhp, force, B_FALSE, replacing, argc, argv);
2242 	if (nvroot == NULL) {
2243 		zpool_close(zhp);
2244 		return (1);
2245 	}
2246 
2247 	ret = zpool_vdev_attach(zhp, old_disk, new_disk, nvroot, replacing);
2248 
2249 	nvlist_free(nvroot);
2250 	zpool_close(zhp);
2251 
2252 	return (ret);
2253 }
2254 
2255 /*
2256  * zpool replace [-f] <pool> <device> <new_device>
2257  *
2258  *	-f	Force attach, even if <new_device> appears to be in use.
2259  *
2260  * Replace <device> with <new_device>.
2261  */
2262 /* ARGSUSED */
2263 int
2264 zpool_do_replace(int argc, char **argv)
2265 {
2266 	return (zpool_do_attach_or_replace(argc, argv, B_TRUE));
2267 }
2268 
2269 /*
2270  * zpool attach [-f] <pool> <device> <new_device>
2271  *
2272  *	-f	Force attach, even if <new_device> appears to be in use.
2273  *
2274  * Attach <new_device> to the mirror containing <device>.  If <device> is not
2275  * part of a mirror, then <device> will be transformed into a mirror of
2276  * <device> and <new_device>.  In either case, <new_device> will begin life
2277  * with a DTL of [0, now], and will immediately begin to resilver itself.
2278  */
2279 int
2280 zpool_do_attach(int argc, char **argv)
2281 {
2282 	return (zpool_do_attach_or_replace(argc, argv, B_FALSE));
2283 }
2284 
2285 /*
2286  * zpool detach [-f] <pool> <device>
2287  *
2288  *	-f	Force detach of <device>, even if DTLs argue against it
2289  *		(not supported yet)
2290  *
2291  * Detach a device from a mirror.  The operation will be refused if <device>
2292  * is the last device in the mirror, or if the DTLs indicate that this device
2293  * has the only valid copy of some data.
2294  */
2295 /* ARGSUSED */
2296 int
2297 zpool_do_detach(int argc, char **argv)
2298 {
2299 	int c;
2300 	char *poolname, *path;
2301 	zpool_handle_t *zhp;
2302 	int ret;
2303 
2304 	/* check options */
2305 	while ((c = getopt(argc, argv, "f")) != -1) {
2306 		switch (c) {
2307 		case 'f':
2308 		case '?':
2309 			(void) fprintf(stderr, gettext("invalid option '%c'\n"),
2310 			    optopt);
2311 			usage(B_FALSE);
2312 		}
2313 	}
2314 
2315 	argc -= optind;
2316 	argv += optind;
2317 
2318 	/* get pool name and check number of arguments */
2319 	if (argc < 1) {
2320 		(void) fprintf(stderr, gettext("missing pool name argument\n"));
2321 		usage(B_FALSE);
2322 	}
2323 
2324 	if (argc < 2) {
2325 		(void) fprintf(stderr,
2326 		    gettext("missing <device> specification\n"));
2327 		usage(B_FALSE);
2328 	}
2329 
2330 	poolname = argv[0];
2331 	path = argv[1];
2332 
2333 	if ((zhp = zpool_open(g_zfs, poolname)) == NULL)
2334 		return (1);
2335 
2336 	ret = zpool_vdev_detach(zhp, path);
2337 
2338 	zpool_close(zhp);
2339 
2340 	return (ret);
2341 }
2342 
2343 /*
2344  * zpool online <pool> <device> ...
2345  */
2346 int
2347 zpool_do_online(int argc, char **argv)
2348 {
2349 	int c, i;
2350 	char *poolname;
2351 	zpool_handle_t *zhp;
2352 	int ret = 0;
2353 	vdev_state_t newstate;
2354 
2355 	/* check options */
2356 	while ((c = getopt(argc, argv, "t")) != -1) {
2357 		switch (c) {
2358 		case 't':
2359 		case '?':
2360 			(void) fprintf(stderr, gettext("invalid option '%c'\n"),
2361 			    optopt);
2362 			usage(B_FALSE);
2363 		}
2364 	}
2365 
2366 	argc -= optind;
2367 	argv += optind;
2368 
2369 	/* get pool name and check number of arguments */
2370 	if (argc < 1) {
2371 		(void) fprintf(stderr, gettext("missing pool name\n"));
2372 		usage(B_FALSE);
2373 	}
2374 	if (argc < 2) {
2375 		(void) fprintf(stderr, gettext("missing device name\n"));
2376 		usage(B_FALSE);
2377 	}
2378 
2379 	poolname = argv[0];
2380 
2381 	if ((zhp = zpool_open(g_zfs, poolname)) == NULL)
2382 		return (1);
2383 
2384 	for (i = 1; i < argc; i++) {
2385 		if (zpool_vdev_online(zhp, argv[i], 0, &newstate) == 0) {
2386 			if (newstate != VDEV_STATE_HEALTHY) {
2387 				(void) printf(gettext("warning: device '%s' "
2388 				    "onlined, but remains in faulted state\n"),
2389 				    argv[i]);
2390 				if (newstate == VDEV_STATE_FAULTED)
2391 					(void) printf(gettext("use 'zpool "
2392 					    "clear' to restore a faulted "
2393 					    "device\n"));
2394 				else
2395 					(void) printf(gettext("use 'zpool "
2396 					    "replace' to replace devices "
2397 					    "that are no longer present\n"));
2398 			}
2399 		} else {
2400 			ret = 1;
2401 		}
2402 	}
2403 
2404 	zpool_close(zhp);
2405 
2406 	return (ret);
2407 }
2408 
2409 /*
2410  * zpool offline [-ft] <pool> <device> ...
2411  *
2412  *	-f	Force the device into the offline state, even if doing
2413  *		so would appear to compromise pool availability.
2414  *		(not supported yet)
2415  *
2416  *	-t	Only take the device off-line temporarily.  The offline
2417  *		state will not be persistent across reboots.
2418  */
2419 /* ARGSUSED */
2420 int
2421 zpool_do_offline(int argc, char **argv)
2422 {
2423 	int c, i;
2424 	char *poolname;
2425 	zpool_handle_t *zhp;
2426 	int ret = 0;
2427 	boolean_t istmp = B_FALSE;
2428 
2429 	/* check options */
2430 	while ((c = getopt(argc, argv, "ft")) != -1) {
2431 		switch (c) {
2432 		case 't':
2433 			istmp = B_TRUE;
2434 			break;
2435 		case 'f':
2436 		case '?':
2437 			(void) fprintf(stderr, gettext("invalid option '%c'\n"),
2438 			    optopt);
2439 			usage(B_FALSE);
2440 		}
2441 	}
2442 
2443 	argc -= optind;
2444 	argv += optind;
2445 
2446 	/* get pool name and check number of arguments */
2447 	if (argc < 1) {
2448 		(void) fprintf(stderr, gettext("missing pool name\n"));
2449 		usage(B_FALSE);
2450 	}
2451 	if (argc < 2) {
2452 		(void) fprintf(stderr, gettext("missing device name\n"));
2453 		usage(B_FALSE);
2454 	}
2455 
2456 	poolname = argv[0];
2457 
2458 	if ((zhp = zpool_open(g_zfs, poolname)) == NULL)
2459 		return (1);
2460 
2461 	for (i = 1; i < argc; i++) {
2462 		if (zpool_vdev_offline(zhp, argv[i], istmp) != 0)
2463 			ret = 1;
2464 	}
2465 
2466 	zpool_close(zhp);
2467 
2468 	return (ret);
2469 }
2470 
2471 /*
2472  * zpool clear <pool> [device]
2473  *
2474  * Clear all errors associated with a pool or a particular device.
2475  */
2476 int
2477 zpool_do_clear(int argc, char **argv)
2478 {
2479 	int ret = 0;
2480 	zpool_handle_t *zhp;
2481 	char *pool, *device;
2482 
2483 	if (argc < 2) {
2484 		(void) fprintf(stderr, gettext("missing pool name\n"));
2485 		usage(B_FALSE);
2486 	}
2487 
2488 	if (argc > 3) {
2489 		(void) fprintf(stderr, gettext("too many arguments\n"));
2490 		usage(B_FALSE);
2491 	}
2492 
2493 	pool = argv[1];
2494 	device = argc == 3 ? argv[2] : NULL;
2495 
2496 	if ((zhp = zpool_open(g_zfs, pool)) == NULL)
2497 		return (1);
2498 
2499 	if (zpool_clear(zhp, device) != 0)
2500 		ret = 1;
2501 
2502 	zpool_close(zhp);
2503 
2504 	return (ret);
2505 }
2506 
2507 typedef struct scrub_cbdata {
2508 	int	cb_type;
2509 	int	cb_argc;
2510 	char	**cb_argv;
2511 } scrub_cbdata_t;
2512 
2513 int
2514 scrub_callback(zpool_handle_t *zhp, void *data)
2515 {
2516 	scrub_cbdata_t *cb = data;
2517 	int err;
2518 
2519 	/*
2520 	 * Ignore faulted pools.
2521 	 */
2522 	if (zpool_get_state(zhp) == POOL_STATE_UNAVAIL) {
2523 		(void) fprintf(stderr, gettext("cannot scrub '%s': pool is "
2524 		    "currently unavailable\n"), zpool_get_name(zhp));
2525 		return (1);
2526 	}
2527 
2528 	err = zpool_scrub(zhp, cb->cb_type);
2529 
2530 	return (err != 0);
2531 }
2532 
2533 /*
2534  * zpool scrub [-s] <pool> ...
2535  *
2536  *	-s	Stop.  Stops any in-progress scrub.
2537  */
2538 int
2539 zpool_do_scrub(int argc, char **argv)
2540 {
2541 	int c;
2542 	scrub_cbdata_t cb;
2543 
2544 	cb.cb_type = POOL_SCRUB_EVERYTHING;
2545 
2546 	/* check options */
2547 	while ((c = getopt(argc, argv, "s")) != -1) {
2548 		switch (c) {
2549 		case 's':
2550 			cb.cb_type = POOL_SCRUB_NONE;
2551 			break;
2552 		case '?':
2553 			(void) fprintf(stderr, gettext("invalid option '%c'\n"),
2554 			    optopt);
2555 			usage(B_FALSE);
2556 		}
2557 	}
2558 
2559 	cb.cb_argc = argc;
2560 	cb.cb_argv = argv;
2561 	argc -= optind;
2562 	argv += optind;
2563 
2564 	if (argc < 1) {
2565 		(void) fprintf(stderr, gettext("missing pool name argument\n"));
2566 		usage(B_FALSE);
2567 	}
2568 
2569 	return (for_each_pool(argc, argv, B_TRUE, NULL, scrub_callback, &cb));
2570 }
2571 
2572 typedef struct status_cbdata {
2573 	int		cb_count;
2574 	boolean_t	cb_allpools;
2575 	boolean_t	cb_verbose;
2576 	boolean_t	cb_explain;
2577 	boolean_t	cb_first;
2578 } status_cbdata_t;
2579 
2580 /*
2581  * Print out detailed scrub status.
2582  */
2583 void
2584 print_scrub_status(nvlist_t *nvroot)
2585 {
2586 	vdev_stat_t *vs;
2587 	uint_t vsc;
2588 	time_t start, end, now;
2589 	double fraction_done;
2590 	uint64_t examined, total, minutes_left, minutes_taken;
2591 	char *scrub_type;
2592 
2593 	verify(nvlist_lookup_uint64_array(nvroot, ZPOOL_CONFIG_STATS,
2594 	    (uint64_t **)&vs, &vsc) == 0);
2595 
2596 	/*
2597 	 * If there's never been a scrub, there's not much to say.
2598 	 */
2599 	if (vs->vs_scrub_end == 0 && vs->vs_scrub_type == POOL_SCRUB_NONE) {
2600 		(void) printf(gettext("none requested\n"));
2601 		return;
2602 	}
2603 
2604 	scrub_type = (vs->vs_scrub_type == POOL_SCRUB_RESILVER) ?
2605 	    "resilver" : "scrub";
2606 
2607 	start = vs->vs_scrub_start;
2608 	end = vs->vs_scrub_end;
2609 	now = time(NULL);
2610 	examined = vs->vs_scrub_examined;
2611 	total = vs->vs_alloc;
2612 
2613 	if (end != 0) {
2614 		minutes_taken = (uint64_t)((end - start) / 60);
2615 
2616 		(void) printf(gettext("%s %s after %lluh%um with %llu errors "
2617 		    "on %s"),
2618 		    scrub_type, vs->vs_scrub_complete ? "completed" : "stopped",
2619 		    (u_longlong_t)(minutes_taken / 60),
2620 		    (uint_t)(minutes_taken % 60),
2621 		    (u_longlong_t)vs->vs_scrub_errors, ctime(&end));
2622 		return;
2623 	}
2624 
2625 	if (examined == 0)
2626 		examined = 1;
2627 	if (examined > total)
2628 		total = examined;
2629 
2630 	fraction_done = (double)examined / total;
2631 	minutes_left = (uint64_t)((now - start) *
2632 	    (1 - fraction_done) / fraction_done / 60);
2633 	minutes_taken = (uint64_t)((now - start) / 60);
2634 
2635 	(void) printf(gettext("%s in progress for %lluh%um, %.2f%% done, "
2636 	    "%lluh%um to go\n"),
2637 	    scrub_type, (u_longlong_t)(minutes_taken / 60),
2638 	    (uint_t)(minutes_taken % 60), 100 * fraction_done,
2639 	    (u_longlong_t)(minutes_left / 60), (uint_t)(minutes_left % 60));
2640 }
2641 
2642 typedef struct spare_cbdata {
2643 	uint64_t	cb_guid;
2644 	zpool_handle_t	*cb_zhp;
2645 } spare_cbdata_t;
2646 
2647 static boolean_t
2648 find_vdev(nvlist_t *nv, uint64_t search)
2649 {
2650 	uint64_t guid;
2651 	nvlist_t **child;
2652 	uint_t c, children;
2653 
2654 	if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_GUID, &guid) == 0 &&
2655 	    search == guid)
2656 		return (B_TRUE);
2657 
2658 	if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
2659 	    &child, &children) == 0) {
2660 		for (c = 0; c < children; c++)
2661 			if (find_vdev(child[c], search))
2662 				return (B_TRUE);
2663 	}
2664 
2665 	return (B_FALSE);
2666 }
2667 
2668 static int
2669 find_spare(zpool_handle_t *zhp, void *data)
2670 {
2671 	spare_cbdata_t *cbp = data;
2672 	nvlist_t *config, *nvroot;
2673 
2674 	config = zpool_get_config(zhp, NULL);
2675 	verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
2676 	    &nvroot) == 0);
2677 
2678 	if (find_vdev(nvroot, cbp->cb_guid)) {
2679 		cbp->cb_zhp = zhp;
2680 		return (1);
2681 	}
2682 
2683 	zpool_close(zhp);
2684 	return (0);
2685 }
2686 
2687 /*
2688  * Print out configuration state as requested by status_callback.
2689  */
2690 void
2691 print_status_config(zpool_handle_t *zhp, const char *name, nvlist_t *nv,
2692     int namewidth, int depth, boolean_t isspare, boolean_t print_logs)
2693 {
2694 	nvlist_t **child;
2695 	uint_t c, children;
2696 	vdev_stat_t *vs;
2697 	char rbuf[6], wbuf[6], cbuf[6], repaired[7];
2698 	char *vname;
2699 	uint64_t notpresent;
2700 	spare_cbdata_t cb;
2701 	char *state;
2702 
2703 	verify(nvlist_lookup_uint64_array(nv, ZPOOL_CONFIG_STATS,
2704 	    (uint64_t **)&vs, &c) == 0);
2705 
2706 	if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
2707 	    &child, &children) != 0)
2708 		children = 0;
2709 
2710 	state = zpool_state_to_name(vs->vs_state, vs->vs_aux);
2711 	if (isspare) {
2712 		/*
2713 		 * For hot spares, we use the terms 'INUSE' and 'AVAILABLE' for
2714 		 * online drives.
2715 		 */
2716 		if (vs->vs_aux == VDEV_AUX_SPARED)
2717 			state = "INUSE";
2718 		else if (vs->vs_state == VDEV_STATE_HEALTHY)
2719 			state = "AVAIL";
2720 	}
2721 
2722 	(void) printf("\t%*s%-*s  %-8s", depth, "", namewidth - depth,
2723 	    name, state);
2724 
2725 	if (!isspare) {
2726 		zfs_nicenum(vs->vs_read_errors, rbuf, sizeof (rbuf));
2727 		zfs_nicenum(vs->vs_write_errors, wbuf, sizeof (wbuf));
2728 		zfs_nicenum(vs->vs_checksum_errors, cbuf, sizeof (cbuf));
2729 		(void) printf(" %5s %5s %5s", rbuf, wbuf, cbuf);
2730 	}
2731 
2732 	if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_NOT_PRESENT,
2733 	    &notpresent) == 0) {
2734 		char *path;
2735 		verify(nvlist_lookup_string(nv, ZPOOL_CONFIG_PATH, &path) == 0);
2736 		(void) printf("  was %s", path);
2737 	} else if (vs->vs_aux != 0) {
2738 		(void) printf("  ");
2739 
2740 		switch (vs->vs_aux) {
2741 		case VDEV_AUX_OPEN_FAILED:
2742 			(void) printf(gettext("cannot open"));
2743 			break;
2744 
2745 		case VDEV_AUX_BAD_GUID_SUM:
2746 			(void) printf(gettext("missing device"));
2747 			break;
2748 
2749 		case VDEV_AUX_NO_REPLICAS:
2750 			(void) printf(gettext("insufficient replicas"));
2751 			break;
2752 
2753 		case VDEV_AUX_VERSION_NEWER:
2754 			(void) printf(gettext("newer version"));
2755 			break;
2756 
2757 		case VDEV_AUX_SPARED:
2758 			verify(nvlist_lookup_uint64(nv, ZPOOL_CONFIG_GUID,
2759 			    &cb.cb_guid) == 0);
2760 			if (zpool_iter(g_zfs, find_spare, &cb) == 1) {
2761 				if (strcmp(zpool_get_name(cb.cb_zhp),
2762 				    zpool_get_name(zhp)) == 0)
2763 					(void) printf(gettext("currently in "
2764 					    "use"));
2765 				else
2766 					(void) printf(gettext("in use by "
2767 					    "pool '%s'"),
2768 					    zpool_get_name(cb.cb_zhp));
2769 				zpool_close(cb.cb_zhp);
2770 			} else {
2771 				(void) printf(gettext("currently in use"));
2772 			}
2773 			break;
2774 
2775 		case VDEV_AUX_ERR_EXCEEDED:
2776 			(void) printf(gettext("too many errors"));
2777 			break;
2778 
2779 		default:
2780 			(void) printf(gettext("corrupted data"));
2781 			break;
2782 		}
2783 	} else if (vs->vs_scrub_repaired != 0 && children == 0) {
2784 		/*
2785 		 * Report bytes resilvered/repaired on leaf devices.
2786 		 */
2787 		zfs_nicenum(vs->vs_scrub_repaired, repaired, sizeof (repaired));
2788 		(void) printf(gettext("  %s %s"), repaired,
2789 		    (vs->vs_scrub_type == POOL_SCRUB_RESILVER) ?
2790 		    "resilvered" : "repaired");
2791 	}
2792 
2793 	(void) printf("\n");
2794 
2795 	for (c = 0; c < children; c++) {
2796 		uint64_t is_log = B_FALSE;
2797 
2798 		(void) nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_LOG,
2799 		    &is_log);
2800 		if ((is_log && !print_logs) || (!is_log && print_logs))
2801 			continue;
2802 		vname = zpool_vdev_name(g_zfs, zhp, child[c]);
2803 		print_status_config(zhp, vname, child[c],
2804 		    namewidth, depth + 2, isspare, B_FALSE);
2805 		free(vname);
2806 	}
2807 }
2808 
2809 static void
2810 print_error_log(zpool_handle_t *zhp)
2811 {
2812 	nvlist_t *nverrlist = NULL;
2813 	nvpair_t *elem;
2814 	char *pathname;
2815 	size_t len = MAXPATHLEN * 2;
2816 
2817 	if (zpool_get_errlog(zhp, &nverrlist) != 0) {
2818 		(void) printf("errors: List of errors unavailable "
2819 		    "(insufficient privileges)\n");
2820 		return;
2821 	}
2822 
2823 	(void) printf("errors: Permanent errors have been "
2824 	    "detected in the following files:\n\n");
2825 
2826 	pathname = safe_malloc(len);
2827 	elem = NULL;
2828 	while ((elem = nvlist_next_nvpair(nverrlist, elem)) != NULL) {
2829 		nvlist_t *nv;
2830 		uint64_t dsobj, obj;
2831 
2832 		verify(nvpair_value_nvlist(elem, &nv) == 0);
2833 		verify(nvlist_lookup_uint64(nv, ZPOOL_ERR_DATASET,
2834 		    &dsobj) == 0);
2835 		verify(nvlist_lookup_uint64(nv, ZPOOL_ERR_OBJECT,
2836 		    &obj) == 0);
2837 		zpool_obj_to_path(zhp, dsobj, obj, pathname, len);
2838 		(void) printf("%7s %s\n", "", pathname);
2839 	}
2840 	free(pathname);
2841 	nvlist_free(nverrlist);
2842 }
2843 
2844 static void
2845 print_spares(zpool_handle_t *zhp, nvlist_t **spares, uint_t nspares,
2846     int namewidth)
2847 {
2848 	uint_t i;
2849 	char *name;
2850 
2851 	if (nspares == 0)
2852 		return;
2853 
2854 	(void) printf(gettext("\tspares\n"));
2855 
2856 	for (i = 0; i < nspares; i++) {
2857 		name = zpool_vdev_name(g_zfs, zhp, spares[i]);
2858 		print_status_config(zhp, name, spares[i],
2859 		    namewidth, 2, B_TRUE, B_FALSE);
2860 		free(name);
2861 	}
2862 }
2863 
2864 static void
2865 print_l2cache(zpool_handle_t *zhp, nvlist_t **l2cache, uint_t nl2cache,
2866     int namewidth)
2867 {
2868 	uint_t i;
2869 	char *name;
2870 
2871 	if (nl2cache == 0)
2872 		return;
2873 
2874 	(void) printf(gettext("\tcache\n"));
2875 
2876 	for (i = 0; i < nl2cache; i++) {
2877 		name = zpool_vdev_name(g_zfs, zhp, l2cache[i]);
2878 		print_status_config(zhp, name, l2cache[i],
2879 		    namewidth, 2, B_FALSE, B_FALSE);
2880 		free(name);
2881 	}
2882 }
2883 
2884 /*
2885  * Display a summary of pool status.  Displays a summary such as:
2886  *
2887  *        pool: tank
2888  *	status: DEGRADED
2889  *	reason: One or more devices ...
2890  *         see: http://www.sun.com/msg/ZFS-xxxx-01
2891  *	config:
2892  *		mirror		DEGRADED
2893  *                c1t0d0	OK
2894  *                c2t0d0	UNAVAIL
2895  *
2896  * When given the '-v' option, we print out the complete config.  If the '-e'
2897  * option is specified, then we print out error rate information as well.
2898  */
2899 int
2900 status_callback(zpool_handle_t *zhp, void *data)
2901 {
2902 	status_cbdata_t *cbp = data;
2903 	nvlist_t *config, *nvroot;
2904 	char *msgid;
2905 	int reason;
2906 	const char *health;
2907 	uint_t c;
2908 	vdev_stat_t *vs;
2909 
2910 	config = zpool_get_config(zhp, NULL);
2911 	reason = zpool_get_status(zhp, &msgid);
2912 
2913 	cbp->cb_count++;
2914 
2915 	/*
2916 	 * If we were given 'zpool status -x', only report those pools with
2917 	 * problems.
2918 	 */
2919 	if (reason == ZPOOL_STATUS_OK && cbp->cb_explain) {
2920 		if (!cbp->cb_allpools) {
2921 			(void) printf(gettext("pool '%s' is healthy\n"),
2922 			    zpool_get_name(zhp));
2923 			if (cbp->cb_first)
2924 				cbp->cb_first = B_FALSE;
2925 		}
2926 		return (0);
2927 	}
2928 
2929 	if (cbp->cb_first)
2930 		cbp->cb_first = B_FALSE;
2931 	else
2932 		(void) printf("\n");
2933 
2934 	verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
2935 	    &nvroot) == 0);
2936 	verify(nvlist_lookup_uint64_array(nvroot, ZPOOL_CONFIG_STATS,
2937 	    (uint64_t **)&vs, &c) == 0);
2938 	health = zpool_state_to_name(vs->vs_state, vs->vs_aux);
2939 
2940 	(void) printf(gettext("  pool: %s\n"), zpool_get_name(zhp));
2941 	(void) printf(gettext(" state: %s\n"), health);
2942 
2943 	switch (reason) {
2944 	case ZPOOL_STATUS_MISSING_DEV_R:
2945 		(void) printf(gettext("status: One or more devices could not "
2946 		    "be opened.  Sufficient replicas exist for\n\tthe pool to "
2947 		    "continue functioning in a degraded state.\n"));
2948 		(void) printf(gettext("action: Attach the missing device and "
2949 		    "online it using 'zpool online'.\n"));
2950 		break;
2951 
2952 	case ZPOOL_STATUS_MISSING_DEV_NR:
2953 		(void) printf(gettext("status: One or more devices could not "
2954 		    "be opened.  There are insufficient\n\treplicas for the "
2955 		    "pool to continue functioning.\n"));
2956 		(void) printf(gettext("action: Attach the missing device and "
2957 		    "online it using 'zpool online'.\n"));
2958 		break;
2959 
2960 	case ZPOOL_STATUS_CORRUPT_LABEL_R:
2961 		(void) printf(gettext("status: One or more devices could not "
2962 		    "be used because the label is missing or\n\tinvalid.  "
2963 		    "Sufficient replicas exist for the pool to continue\n\t"
2964 		    "functioning in a degraded state.\n"));
2965 		(void) printf(gettext("action: Replace the device using "
2966 		    "'zpool replace'.\n"));
2967 		break;
2968 
2969 	case ZPOOL_STATUS_CORRUPT_LABEL_NR:
2970 		(void) printf(gettext("status: One or more devices could not "
2971 		    "be used because the label is missing \n\tor invalid.  "
2972 		    "There are insufficient replicas for the pool to "
2973 		    "continue\n\tfunctioning.\n"));
2974 		(void) printf(gettext("action: Destroy and re-create the pool "
2975 		    "from a backup source.\n"));
2976 		break;
2977 
2978 	case ZPOOL_STATUS_FAILING_DEV:
2979 		(void) printf(gettext("status: One or more devices has "
2980 		    "experienced an unrecoverable error.  An\n\tattempt was "
2981 		    "made to correct the error.  Applications are "
2982 		    "unaffected.\n"));
2983 		(void) printf(gettext("action: Determine if the device needs "
2984 		    "to be replaced, and clear the errors\n\tusing "
2985 		    "'zpool clear' or replace the device with 'zpool "
2986 		    "replace'.\n"));
2987 		break;
2988 
2989 	case ZPOOL_STATUS_OFFLINE_DEV:
2990 		(void) printf(gettext("status: One or more devices has "
2991 		    "been taken offline by the administrator.\n\tSufficient "
2992 		    "replicas exist for the pool to continue functioning in "
2993 		    "a\n\tdegraded state.\n"));
2994 		(void) printf(gettext("action: Online the device using "
2995 		    "'zpool online' or replace the device with\n\t'zpool "
2996 		    "replace'.\n"));
2997 		break;
2998 
2999 	case ZPOOL_STATUS_RESILVERING:
3000 		(void) printf(gettext("status: One or more devices is "
3001 		    "currently being resilvered.  The pool will\n\tcontinue "
3002 		    "to function, possibly in a degraded state.\n"));
3003 		(void) printf(gettext("action: Wait for the resilver to "
3004 		    "complete.\n"));
3005 		break;
3006 
3007 	case ZPOOL_STATUS_CORRUPT_DATA:
3008 		(void) printf(gettext("status: One or more devices has "
3009 		    "experienced an error resulting in data\n\tcorruption.  "
3010 		    "Applications may be affected.\n"));
3011 		(void) printf(gettext("action: Restore the file in question "
3012 		    "if possible.  Otherwise restore the\n\tentire pool from "
3013 		    "backup.\n"));
3014 		break;
3015 
3016 	case ZPOOL_STATUS_CORRUPT_POOL:
3017 		(void) printf(gettext("status: The pool metadata is corrupted "
3018 		    "and the pool cannot be opened.\n"));
3019 		(void) printf(gettext("action: Destroy and re-create the pool "
3020 		    "from a backup source.\n"));
3021 		break;
3022 
3023 	case ZPOOL_STATUS_VERSION_OLDER:
3024 		(void) printf(gettext("status: The pool is formatted using an "
3025 		    "older on-disk format.  The pool can\n\tstill be used, but "
3026 		    "some features are unavailable.\n"));
3027 		(void) printf(gettext("action: Upgrade the pool using 'zpool "
3028 		    "upgrade'.  Once this is done, the\n\tpool will no longer "
3029 		    "be accessible on older software versions.\n"));
3030 		break;
3031 
3032 	case ZPOOL_STATUS_VERSION_NEWER:
3033 		(void) printf(gettext("status: The pool has been upgraded to a "
3034 		    "newer, incompatible on-disk version.\n\tThe pool cannot "
3035 		    "be accessed on this system.\n"));
3036 		(void) printf(gettext("action: Access the pool from a system "
3037 		    "running more recent software, or\n\trestore the pool from "
3038 		    "backup.\n"));
3039 		break;
3040 
3041 	case ZPOOL_STATUS_FAULTED_DEV_R:
3042 		(void) printf(gettext("status: One or more devices are "
3043 		    "faulted in response to persistent errors.\n\tSufficient "
3044 		    "replicas exist for the pool to continue functioning "
3045 		    "in a\n\tdegraded state.\n"));
3046 		(void) printf(gettext("action: Replace the faulted device, "
3047 		    "or use 'zpool clear' to mark the device\n\trepaired.\n"));
3048 		break;
3049 
3050 	case ZPOOL_STATUS_FAULTED_DEV_NR:
3051 		(void) printf(gettext("status: One or more devices are "
3052 		    "faulted in response to persistent errors.  There are "
3053 		    "insufficient replicas for the pool to\n\tcontinue "
3054 		    "functioning.\n"));
3055 		(void) printf(gettext("action: Destroy and re-create the pool "
3056 		    "from a backup source.  Manually marking the device\n"
3057 		    "\trepaired using 'zpool clear' may allow some data "
3058 		    "to be recovered.\n"));
3059 		break;
3060 
3061 	default:
3062 		/*
3063 		 * The remaining errors can't actually be generated, yet.
3064 		 */
3065 		assert(reason == ZPOOL_STATUS_OK);
3066 	}
3067 
3068 	if (msgid != NULL)
3069 		(void) printf(gettext("   see: http://www.sun.com/msg/%s\n"),
3070 		    msgid);
3071 
3072 	if (config != NULL) {
3073 		int namewidth;
3074 		uint64_t nerr;
3075 		nvlist_t **spares, **l2cache;
3076 		uint_t nspares, nl2cache;
3077 
3078 
3079 		(void) printf(gettext(" scrub: "));
3080 		print_scrub_status(nvroot);
3081 
3082 		namewidth = max_width(zhp, nvroot, 0, 0);
3083 		if (namewidth < 10)
3084 			namewidth = 10;
3085 
3086 		(void) printf(gettext("config:\n\n"));
3087 		(void) printf(gettext("\t%-*s  %-8s %5s %5s %5s\n"), namewidth,
3088 		    "NAME", "STATE", "READ", "WRITE", "CKSUM");
3089 		print_status_config(zhp, zpool_get_name(zhp), nvroot,
3090 		    namewidth, 0, B_FALSE, B_FALSE);
3091 		if (num_logs(nvroot) > 0)
3092 			print_status_config(zhp, "logs", nvroot, namewidth, 0,
3093 			    B_FALSE, B_TRUE);
3094 
3095 		if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_L2CACHE,
3096 		    &l2cache, &nl2cache) == 0)
3097 			print_l2cache(zhp, l2cache, nl2cache, namewidth);
3098 
3099 		if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_SPARES,
3100 		    &spares, &nspares) == 0)
3101 			print_spares(zhp, spares, nspares, namewidth);
3102 
3103 		if (nvlist_lookup_uint64(config, ZPOOL_CONFIG_ERRCOUNT,
3104 		    &nerr) == 0) {
3105 			nvlist_t *nverrlist = NULL;
3106 
3107 			/*
3108 			 * If the approximate error count is small, get a
3109 			 * precise count by fetching the entire log and
3110 			 * uniquifying the results.
3111 			 */
3112 			if (nerr > 0 && nerr < 100 && !cbp->cb_verbose &&
3113 			    zpool_get_errlog(zhp, &nverrlist) == 0) {
3114 				nvpair_t *elem;
3115 
3116 				elem = NULL;
3117 				nerr = 0;
3118 				while ((elem = nvlist_next_nvpair(nverrlist,
3119 				    elem)) != NULL) {
3120 					nerr++;
3121 				}
3122 			}
3123 			nvlist_free(nverrlist);
3124 
3125 			(void) printf("\n");
3126 
3127 			if (nerr == 0)
3128 				(void) printf(gettext("errors: No known data "
3129 				    "errors\n"));
3130 			else if (!cbp->cb_verbose)
3131 				(void) printf(gettext("errors: %llu data "
3132 				    "errors, use '-v' for a list\n"),
3133 				    (u_longlong_t)nerr);
3134 			else
3135 				print_error_log(zhp);
3136 		}
3137 	} else {
3138 		(void) printf(gettext("config: The configuration cannot be "
3139 		    "determined.\n"));
3140 	}
3141 
3142 	return (0);
3143 }
3144 
3145 /*
3146  * zpool status [-vx] [pool] ...
3147  *
3148  *	-v	Display complete error logs
3149  *	-x	Display only pools with potential problems
3150  *
3151  * Describes the health status of all pools or some subset.
3152  */
3153 int
3154 zpool_do_status(int argc, char **argv)
3155 {
3156 	int c;
3157 	int ret;
3158 	status_cbdata_t cb = { 0 };
3159 
3160 	/* check options */
3161 	while ((c = getopt(argc, argv, "vx")) != -1) {
3162 		switch (c) {
3163 		case 'v':
3164 			cb.cb_verbose = B_TRUE;
3165 			break;
3166 		case 'x':
3167 			cb.cb_explain = B_TRUE;
3168 			break;
3169 		case '?':
3170 			(void) fprintf(stderr, gettext("invalid option '%c'\n"),
3171 			    optopt);
3172 			usage(B_FALSE);
3173 		}
3174 	}
3175 
3176 	argc -= optind;
3177 	argv += optind;
3178 
3179 	cb.cb_first = B_TRUE;
3180 
3181 	if (argc == 0)
3182 		cb.cb_allpools = B_TRUE;
3183 
3184 	ret = for_each_pool(argc, argv, B_TRUE, NULL, status_callback, &cb);
3185 
3186 	if (argc == 0 && cb.cb_count == 0)
3187 		(void) printf(gettext("no pools available\n"));
3188 	else if (cb.cb_explain && cb.cb_first && cb.cb_allpools)
3189 		(void) printf(gettext("all pools are healthy\n"));
3190 
3191 	return (ret);
3192 }
3193 
3194 typedef struct upgrade_cbdata {
3195 	int	cb_all;
3196 	int	cb_first;
3197 	int	cb_newer;
3198 	int	cb_argc;
3199 	uint64_t cb_version;
3200 	char	**cb_argv;
3201 } upgrade_cbdata_t;
3202 
3203 static int
3204 upgrade_cb(zpool_handle_t *zhp, void *arg)
3205 {
3206 	upgrade_cbdata_t *cbp = arg;
3207 	nvlist_t *config;
3208 	uint64_t version;
3209 	int ret = 0;
3210 
3211 	config = zpool_get_config(zhp, NULL);
3212 	verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION,
3213 	    &version) == 0);
3214 
3215 	if (!cbp->cb_newer && version < SPA_VERSION) {
3216 		if (!cbp->cb_all) {
3217 			if (cbp->cb_first) {
3218 				(void) printf(gettext("The following pools are "
3219 				    "out of date, and can be upgraded.  After "
3220 				    "being\nupgraded, these pools will no "
3221 				    "longer be accessible by older software "
3222 				    "versions.\n\n"));
3223 				(void) printf(gettext("VER  POOL\n"));
3224 				(void) printf(gettext("---  ------------\n"));
3225 				cbp->cb_first = B_FALSE;
3226 			}
3227 
3228 			(void) printf("%2llu   %s\n", (u_longlong_t)version,
3229 			    zpool_get_name(zhp));
3230 		} else {
3231 			cbp->cb_first = B_FALSE;
3232 			ret = zpool_upgrade(zhp, cbp->cb_version);
3233 			if (!ret) {
3234 				(void) printf(gettext("Successfully upgraded "
3235 				    "'%s'\n\n"), zpool_get_name(zhp));
3236 			}
3237 		}
3238 	} else if (cbp->cb_newer && version > SPA_VERSION) {
3239 		assert(!cbp->cb_all);
3240 
3241 		if (cbp->cb_first) {
3242 			(void) printf(gettext("The following pools are "
3243 			    "formatted using a newer software version and\n"
3244 			    "cannot be accessed on the current system.\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 	}
3253 
3254 	zpool_close(zhp);
3255 	return (ret);
3256 }
3257 
3258 /* ARGSUSED */
3259 static int
3260 upgrade_one(zpool_handle_t *zhp, void *data)
3261 {
3262 	upgrade_cbdata_t *cbp = data;
3263 	uint64_t cur_version;
3264 	int ret;
3265 
3266 	if (strcmp("log", zpool_get_name(zhp)) == 0) {
3267 		(void) printf(gettext("'log' is now a reserved word\n"
3268 		    "Pool 'log' must be renamed using export and import"
3269 		    " to upgrade.\n"));
3270 		return (1);
3271 	}
3272 
3273 	cur_version = zpool_get_prop_int(zhp, ZPOOL_PROP_VERSION, NULL);
3274 	if (cur_version > cbp->cb_version) {
3275 		(void) printf(gettext("Pool '%s' is already formatted "
3276 		    "using more current version '%llu'.\n"),
3277 		    zpool_get_name(zhp), cur_version);
3278 		return (0);
3279 	}
3280 	if (cur_version == cbp->cb_version) {
3281 		(void) printf(gettext("Pool '%s' is already formatted "
3282 		    "using the current version.\n"), zpool_get_name(zhp));
3283 		return (0);
3284 	}
3285 
3286 	ret = zpool_upgrade(zhp, cbp->cb_version);
3287 
3288 	if (!ret) {
3289 		(void) printf(gettext("Successfully upgraded '%s' "
3290 		    "from version %llu to version %llu\n\n"),
3291 		    zpool_get_name(zhp), (u_longlong_t)cur_version,
3292 		    (u_longlong_t)cbp->cb_version);
3293 	}
3294 
3295 	return (ret != 0);
3296 }
3297 
3298 /*
3299  * zpool upgrade
3300  * zpool upgrade -v
3301  * zpool upgrade [-V version] <-a | pool ...>
3302  *
3303  * With no arguments, display downrev'd ZFS pool available for upgrade.
3304  * Individual pools can be upgraded by specifying the pool, and '-a' will
3305  * upgrade all pools.
3306  */
3307 int
3308 zpool_do_upgrade(int argc, char **argv)
3309 {
3310 	int c;
3311 	upgrade_cbdata_t cb = { 0 };
3312 	int ret = 0;
3313 	boolean_t showversions = B_FALSE;
3314 	char *end;
3315 
3316 
3317 	/* check options */
3318 	while ((c = getopt(argc, argv, "avV:")) != -1) {
3319 		switch (c) {
3320 		case 'a':
3321 			cb.cb_all = B_TRUE;
3322 			break;
3323 		case 'v':
3324 			showversions = B_TRUE;
3325 			break;
3326 		case 'V':
3327 			cb.cb_version = strtoll(optarg, &end, 10);
3328 			if (*end != '\0' || cb.cb_version > SPA_VERSION ||
3329 			    cb.cb_version < SPA_VERSION_1) {
3330 				(void) fprintf(stderr,
3331 				    gettext("invalid version '%s'\n"), optarg);
3332 				usage(B_FALSE);
3333 			}
3334 			break;
3335 		case '?':
3336 			(void) fprintf(stderr, gettext("invalid option '%c'\n"),
3337 			    optopt);
3338 			usage(B_FALSE);
3339 		}
3340 	}
3341 
3342 	cb.cb_argc = argc;
3343 	cb.cb_argv = argv;
3344 	argc -= optind;
3345 	argv += optind;
3346 
3347 	if (cb.cb_version == 0) {
3348 		cb.cb_version = SPA_VERSION;
3349 	} else if (!cb.cb_all && argc == 0) {
3350 		(void) fprintf(stderr, gettext("-V option is "
3351 		    "incompatible with other arguments\n"));
3352 		usage(B_FALSE);
3353 	}
3354 
3355 	if (showversions) {
3356 		if (cb.cb_all || argc != 0) {
3357 			(void) fprintf(stderr, gettext("-v option is "
3358 			    "incompatible with other arguments\n"));
3359 			usage(B_FALSE);
3360 		}
3361 	} else if (cb.cb_all) {
3362 		if (argc != 0) {
3363 			(void) fprintf(stderr, gettext("-a option should not "
3364 			    "be used along with a pool name\n"));
3365 			usage(B_FALSE);
3366 		}
3367 	}
3368 
3369 	(void) printf(gettext("This system is currently running "
3370 	    "ZFS pool version %llu.\n\n"), SPA_VERSION);
3371 	cb.cb_first = B_TRUE;
3372 	if (showversions) {
3373 		(void) printf(gettext("The following versions are "
3374 		    "supported:\n\n"));
3375 		(void) printf(gettext("VER  DESCRIPTION\n"));
3376 		(void) printf("---  -----------------------------------------"
3377 		    "---------------\n");
3378 		(void) printf(gettext(" 1   Initial ZFS version\n"));
3379 		(void) printf(gettext(" 2   Ditto blocks "
3380 		    "(replicated metadata)\n"));
3381 		(void) printf(gettext(" 3   Hot spares and double parity "
3382 		    "RAID-Z\n"));
3383 		(void) printf(gettext(" 4   zpool history\n"));
3384 		(void) printf(gettext(" 5   Compression using the gzip "
3385 		    "algorithm\n"));
3386 		(void) printf(gettext(" 6   bootfs pool property\n"));
3387 		(void) printf(gettext(" 7   Separate intent log devices\n"));
3388 		(void) printf(gettext(" 8   Delegated administration\n"));
3389 		(void) printf(gettext(" 9   refquota and refreservation "
3390 		    "properties\n"));
3391 		(void) printf(gettext(" 10  Cache devices\n"));
3392 		(void) printf(gettext("For more information on a particular "
3393 		    "version, including supported releases, see:\n\n"));
3394 		(void) printf("http://www.opensolaris.org/os/community/zfs/"
3395 		    "version/N\n\n");
3396 		(void) printf(gettext("Where 'N' is the version number.\n"));
3397 	} else if (argc == 0) {
3398 		int notfound;
3399 
3400 		ret = zpool_iter(g_zfs, upgrade_cb, &cb);
3401 		notfound = cb.cb_first;
3402 
3403 		if (!cb.cb_all && ret == 0) {
3404 			if (!cb.cb_first)
3405 				(void) printf("\n");
3406 			cb.cb_first = B_TRUE;
3407 			cb.cb_newer = B_TRUE;
3408 			ret = zpool_iter(g_zfs, upgrade_cb, &cb);
3409 			if (!cb.cb_first) {
3410 				notfound = B_FALSE;
3411 				(void) printf("\n");
3412 			}
3413 		}
3414 
3415 		if (ret == 0) {
3416 			if (notfound)
3417 				(void) printf(gettext("All pools are formatted "
3418 				    "using this version.\n"));
3419 			else if (!cb.cb_all)
3420 				(void) printf(gettext("Use 'zpool upgrade -v' "
3421 				    "for a list of available versions and "
3422 				    "their associated\nfeatures.\n"));
3423 		}
3424 	} else {
3425 		ret = for_each_pool(argc, argv, B_FALSE, NULL,
3426 		    upgrade_one, &cb);
3427 	}
3428 
3429 	return (ret);
3430 }
3431 
3432 typedef struct hist_cbdata {
3433 	boolean_t first;
3434 	int longfmt;
3435 	int internal;
3436 } hist_cbdata_t;
3437 
3438 char *hist_event_table[LOG_END] = {
3439 	"invalid event",
3440 	"pool create",
3441 	"vdev add",
3442 	"pool remove",
3443 	"pool destroy",
3444 	"pool export",
3445 	"pool import",
3446 	"vdev attach",
3447 	"vdev replace",
3448 	"vdev detach",
3449 	"vdev online",
3450 	"vdev offline",
3451 	"vdev upgrade",
3452 	"pool clear",
3453 	"pool scrub",
3454 	"pool property set",
3455 	"create",
3456 	"clone",
3457 	"destroy",
3458 	"destroy_begin_sync",
3459 	"inherit",
3460 	"property set",
3461 	"quota set",
3462 	"permission update",
3463 	"permission remove",
3464 	"permission who remove",
3465 	"promote",
3466 	"receive",
3467 	"rename",
3468 	"reservation set",
3469 	"replay_inc_sync",
3470 	"replay_full_sync",
3471 	"rollback",
3472 	"snapshot",
3473 	"filesystem version upgrade",
3474 	"refquota set",
3475 	"refreservation set",
3476 };
3477 
3478 /*
3479  * Print out the command history for a specific pool.
3480  */
3481 static int
3482 get_history_one(zpool_handle_t *zhp, void *data)
3483 {
3484 	nvlist_t *nvhis;
3485 	nvlist_t **records;
3486 	uint_t numrecords;
3487 	char *cmdstr;
3488 	char *pathstr;
3489 	uint64_t dst_time;
3490 	time_t tsec;
3491 	struct tm t;
3492 	char tbuf[30];
3493 	int ret, i;
3494 	uint64_t who;
3495 	struct passwd *pwd;
3496 	char *hostname;
3497 	char *zonename;
3498 	char internalstr[MAXPATHLEN];
3499 	hist_cbdata_t *cb = (hist_cbdata_t *)data;
3500 	uint64_t txg;
3501 	uint64_t ievent;
3502 
3503 	cb->first = B_FALSE;
3504 
3505 	(void) printf(gettext("History for '%s':\n"), zpool_get_name(zhp));
3506 
3507 	if ((ret = zpool_get_history(zhp, &nvhis)) != 0)
3508 		return (ret);
3509 
3510 	verify(nvlist_lookup_nvlist_array(nvhis, ZPOOL_HIST_RECORD,
3511 	    &records, &numrecords) == 0);
3512 	for (i = 0; i < numrecords; i++) {
3513 		if (nvlist_lookup_uint64(records[i], ZPOOL_HIST_TIME,
3514 		    &dst_time) != 0)
3515 			continue;
3516 
3517 		/* is it an internal event or a standard event? */
3518 		if (nvlist_lookup_string(records[i], ZPOOL_HIST_CMD,
3519 		    &cmdstr) != 0) {
3520 			if (cb->internal == 0)
3521 				continue;
3522 
3523 			if (nvlist_lookup_uint64(records[i],
3524 			    ZPOOL_HIST_INT_EVENT, &ievent) != 0)
3525 				continue;
3526 			verify(nvlist_lookup_uint64(records[i],
3527 			    ZPOOL_HIST_TXG, &txg) == 0);
3528 			verify(nvlist_lookup_string(records[i],
3529 			    ZPOOL_HIST_INT_STR, &pathstr) == 0);
3530 			if (ievent > LOG_END)
3531 				continue;
3532 			(void) snprintf(internalstr,
3533 			    sizeof (internalstr),
3534 			    "[internal %s txg:%lld] %s",
3535 			    hist_event_table[ievent], txg,
3536 			    pathstr);
3537 			cmdstr = internalstr;
3538 		}
3539 		tsec = dst_time;
3540 		(void) localtime_r(&tsec, &t);
3541 		(void) strftime(tbuf, sizeof (tbuf), "%F.%T", &t);
3542 		(void) printf("%s %s", tbuf, cmdstr);
3543 
3544 		if (!cb->longfmt) {
3545 			(void) printf("\n");
3546 			continue;
3547 		}
3548 		(void) printf(" [");
3549 		if (nvlist_lookup_uint64(records[i],
3550 		    ZPOOL_HIST_WHO, &who) == 0) {
3551 			pwd = getpwuid((uid_t)who);
3552 			if (pwd)
3553 				(void) printf("user %s on",
3554 				    pwd->pw_name);
3555 			else
3556 				(void) printf("user %d on",
3557 				    (int)who);
3558 		} else {
3559 			(void) printf(gettext("no info]\n"));
3560 			continue;
3561 		}
3562 		if (nvlist_lookup_string(records[i],
3563 		    ZPOOL_HIST_HOST, &hostname) == 0) {
3564 			(void) printf(" %s", hostname);
3565 		}
3566 		if (nvlist_lookup_string(records[i],
3567 		    ZPOOL_HIST_ZONE, &zonename) == 0) {
3568 			(void) printf(":%s", zonename);
3569 		}
3570 
3571 		(void) printf("]");
3572 		(void) printf("\n");
3573 	}
3574 	(void) printf("\n");
3575 	nvlist_free(nvhis);
3576 
3577 	return (ret);
3578 }
3579 
3580 /*
3581  * zpool history <pool>
3582  *
3583  * Displays the history of commands that modified pools.
3584  */
3585 
3586 
3587 int
3588 zpool_do_history(int argc, char **argv)
3589 {
3590 	hist_cbdata_t cbdata = { 0 };
3591 	int ret;
3592 	int c;
3593 
3594 	cbdata.first = B_TRUE;
3595 	/* check options */
3596 	while ((c = getopt(argc, argv, "li")) != -1) {
3597 		switch (c) {
3598 		case 'l':
3599 			cbdata.longfmt = 1;
3600 			break;
3601 		case 'i':
3602 			cbdata.internal = 1;
3603 			break;
3604 		case '?':
3605 			(void) fprintf(stderr, gettext("invalid option '%c'\n"),
3606 			    optopt);
3607 			usage(B_FALSE);
3608 		}
3609 	}
3610 	argc -= optind;
3611 	argv += optind;
3612 
3613 	ret = for_each_pool(argc, argv, B_FALSE,  NULL, get_history_one,
3614 	    &cbdata);
3615 
3616 	if (argc == 0 && cbdata.first == B_TRUE) {
3617 		(void) printf(gettext("no pools available\n"));
3618 		return (0);
3619 	}
3620 
3621 	return (ret);
3622 }
3623 
3624 static int
3625 get_callback(zpool_handle_t *zhp, void *data)
3626 {
3627 	zprop_get_cbdata_t *cbp = (zprop_get_cbdata_t *)data;
3628 	char value[MAXNAMELEN];
3629 	zprop_source_t srctype;
3630 	zprop_list_t *pl;
3631 
3632 	for (pl = cbp->cb_proplist; pl != NULL; pl = pl->pl_next) {
3633 
3634 		/*
3635 		 * Skip the special fake placeholder. This will also skip
3636 		 * over the name property when 'all' is specified.
3637 		 */
3638 		if (pl->pl_prop == ZPOOL_PROP_NAME &&
3639 		    pl == cbp->cb_proplist)
3640 			continue;
3641 
3642 		if (zpool_get_prop(zhp, pl->pl_prop,
3643 		    value, sizeof (value), &srctype) != 0)
3644 			continue;
3645 
3646 		zprop_print_one_property(zpool_get_name(zhp), cbp,
3647 		    zpool_prop_to_name(pl->pl_prop), value, srctype, NULL);
3648 	}
3649 	return (0);
3650 }
3651 
3652 int
3653 zpool_do_get(int argc, char **argv)
3654 {
3655 	zprop_get_cbdata_t cb = { 0 };
3656 	zprop_list_t fake_name = { 0 };
3657 	int ret;
3658 
3659 	if (argc < 3)
3660 		usage(B_FALSE);
3661 
3662 	cb.cb_first = B_TRUE;
3663 	cb.cb_sources = ZPROP_SRC_ALL;
3664 	cb.cb_columns[0] = GET_COL_NAME;
3665 	cb.cb_columns[1] = GET_COL_PROPERTY;
3666 	cb.cb_columns[2] = GET_COL_VALUE;
3667 	cb.cb_columns[3] = GET_COL_SOURCE;
3668 	cb.cb_type = ZFS_TYPE_POOL;
3669 
3670 	if (zprop_get_list(g_zfs, argv[1],  &cb.cb_proplist,
3671 	    ZFS_TYPE_POOL) != 0)
3672 		usage(B_FALSE);
3673 
3674 	if (cb.cb_proplist != NULL) {
3675 		fake_name.pl_prop = ZPOOL_PROP_NAME;
3676 		fake_name.pl_width = strlen(gettext("NAME"));
3677 		fake_name.pl_next = cb.cb_proplist;
3678 		cb.cb_proplist = &fake_name;
3679 	}
3680 
3681 	ret = for_each_pool(argc - 2, argv + 2, B_TRUE, &cb.cb_proplist,
3682 	    get_callback, &cb);
3683 
3684 	if (cb.cb_proplist == &fake_name)
3685 		zprop_free_list(fake_name.pl_next);
3686 	else
3687 		zprop_free_list(cb.cb_proplist);
3688 
3689 	return (ret);
3690 }
3691 
3692 typedef struct set_cbdata {
3693 	char *cb_propname;
3694 	char *cb_value;
3695 	boolean_t cb_any_successful;
3696 } set_cbdata_t;
3697 
3698 int
3699 set_callback(zpool_handle_t *zhp, void *data)
3700 {
3701 	int error;
3702 	set_cbdata_t *cb = (set_cbdata_t *)data;
3703 
3704 	error = zpool_set_prop(zhp, cb->cb_propname, cb->cb_value);
3705 
3706 	if (!error)
3707 		cb->cb_any_successful = B_TRUE;
3708 
3709 	return (error);
3710 }
3711 
3712 int
3713 zpool_do_set(int argc, char **argv)
3714 {
3715 	set_cbdata_t cb = { 0 };
3716 	int error;
3717 
3718 	if (argc > 1 && argv[1][0] == '-') {
3719 		(void) fprintf(stderr, gettext("invalid option '%c'\n"),
3720 		    argv[1][1]);
3721 		usage(B_FALSE);
3722 	}
3723 
3724 	if (argc < 2) {
3725 		(void) fprintf(stderr, gettext("missing property=value "
3726 		    "argument\n"));
3727 		usage(B_FALSE);
3728 	}
3729 
3730 	if (argc < 3) {
3731 		(void) fprintf(stderr, gettext("missing pool name\n"));
3732 		usage(B_FALSE);
3733 	}
3734 
3735 	if (argc > 3) {
3736 		(void) fprintf(stderr, gettext("too many pool names\n"));
3737 		usage(B_FALSE);
3738 	}
3739 
3740 	cb.cb_propname = argv[1];
3741 	cb.cb_value = strchr(cb.cb_propname, '=');
3742 	if (cb.cb_value == NULL) {
3743 		(void) fprintf(stderr, gettext("missing value in "
3744 		    "property=value argument\n"));
3745 		usage(B_FALSE);
3746 	}
3747 
3748 	*(cb.cb_value) = '\0';
3749 	cb.cb_value++;
3750 
3751 	error = for_each_pool(argc - 2, argv + 2, B_TRUE, NULL,
3752 	    set_callback, &cb);
3753 
3754 	return (error);
3755 }
3756 
3757 static int
3758 find_command_idx(char *command, int *idx)
3759 {
3760 	int i;
3761 
3762 	for (i = 0; i < NCOMMAND; i++) {
3763 		if (command_table[i].name == NULL)
3764 			continue;
3765 
3766 		if (strcmp(command, command_table[i].name) == 0) {
3767 			*idx = i;
3768 			return (0);
3769 		}
3770 	}
3771 	return (1);
3772 }
3773 
3774 int
3775 main(int argc, char **argv)
3776 {
3777 	int ret;
3778 	int i;
3779 	char *cmdname;
3780 
3781 	(void) setlocale(LC_ALL, "");
3782 	(void) textdomain(TEXT_DOMAIN);
3783 
3784 	if ((g_zfs = libzfs_init()) == NULL) {
3785 		(void) fprintf(stderr, gettext("internal error: failed to "
3786 		    "initialize ZFS library\n"));
3787 		return (1);
3788 	}
3789 
3790 	libzfs_print_on_error(g_zfs, B_TRUE);
3791 
3792 	opterr = 0;
3793 
3794 	/*
3795 	 * Make sure the user has specified some command.
3796 	 */
3797 	if (argc < 2) {
3798 		(void) fprintf(stderr, gettext("missing command\n"));
3799 		usage(B_FALSE);
3800 	}
3801 
3802 	cmdname = argv[1];
3803 
3804 	/*
3805 	 * Special case '-?'
3806 	 */
3807 	if (strcmp(cmdname, "-?") == 0)
3808 		usage(B_TRUE);
3809 
3810 	zpool_set_history_str("zpool", argc, argv, history_str);
3811 	verify(zpool_stage_history(g_zfs, history_str) == 0);
3812 
3813 	/*
3814 	 * Run the appropriate command.
3815 	 */
3816 	if (find_command_idx(cmdname, &i) == 0) {
3817 		current_command = &command_table[i];
3818 		ret = command_table[i].func(argc - 1, argv + 1);
3819 	} else if (strchr(cmdname, '=')) {
3820 		verify(find_command_idx("set", &i) == 0);
3821 		current_command = &command_table[i];
3822 		ret = command_table[i].func(argc, argv);
3823 	} else if (strcmp(cmdname, "freeze") == 0 && argc == 3) {
3824 		/*
3825 		 * 'freeze' is a vile debugging abomination, so we treat
3826 		 * it as such.
3827 		 */
3828 		char buf[16384];
3829 		int fd = open(ZFS_DEV, O_RDWR);
3830 		(void) strcpy((void *)buf, argv[2]);
3831 		return (!!ioctl(fd, ZFS_IOC_POOL_FREEZE, buf));
3832 	} else {
3833 		(void) fprintf(stderr, gettext("unrecognized "
3834 		    "command '%s'\n"), cmdname);
3835 		usage(B_FALSE);
3836 	}
3837 
3838 	libzfs_fini(g_zfs);
3839 
3840 	/*
3841 	 * The 'ZFS_ABORT' environment variable causes us to dump core on exit
3842 	 * for the purposes of running ::findleaks.
3843 	 */
3844 	if (getenv("ZFS_ABORT") != NULL) {
3845 		(void) printf("dumping core by request\n");
3846 		abort();
3847 	}
3848 
3849 	return (ret);
3850 }
3851