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