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