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