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