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