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