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