xref: /illumos-gate/usr/src/cmd/zpool/zpool_main.c (revision c6f76c3487b0d7e374ba5897fabad436f221c46e)
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 2006 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 
45 #include <sys/stat.h>
46 
47 #include <libzfs.h>
48 
49 #include "zpool_util.h"
50 
51 static int zpool_do_create(int, char **);
52 static int zpool_do_destroy(int, char **);
53 
54 static int zpool_do_add(int, char **);
55 static int zpool_do_remove(int, char **);
56 
57 static int zpool_do_list(int, char **);
58 static int zpool_do_iostat(int, char **);
59 static int zpool_do_status(int, char **);
60 
61 static int zpool_do_online(int, char **);
62 static int zpool_do_offline(int, char **);
63 static int zpool_do_clear(int, char **);
64 
65 static int zpool_do_attach(int, char **);
66 static int zpool_do_detach(int, char **);
67 static int zpool_do_replace(int, char **);
68 
69 static int zpool_do_scrub(int, char **);
70 
71 static int zpool_do_import(int, char **);
72 static int zpool_do_export(int, char **);
73 
74 static int zpool_do_upgrade(int, char **);
75 
76 /*
77  * These libumem hooks provide a reasonable set of defaults for the allocator's
78  * debugging facilities.
79  */
80 const char *
81 _umem_debug_init(void)
82 {
83 	return ("default,verbose"); /* $UMEM_DEBUG setting */
84 }
85 
86 const char *
87 _umem_logging_init(void)
88 {
89 	return ("fail,contents"); /* $UMEM_LOGGING setting */
90 }
91 
92 typedef enum {
93 	HELP_ADD,
94 	HELP_ATTACH,
95 	HELP_CLEAR,
96 	HELP_CREATE,
97 	HELP_DESTROY,
98 	HELP_DETACH,
99 	HELP_EXPORT,
100 	HELP_IMPORT,
101 	HELP_IOSTAT,
102 	HELP_LIST,
103 	HELP_OFFLINE,
104 	HELP_ONLINE,
105 	HELP_REPLACE,
106 	HELP_REMOVE,
107 	HELP_SCRUB,
108 	HELP_STATUS,
109 	HELP_UPGRADE
110 } zpool_help_t;
111 
112 
113 typedef struct zpool_command {
114 	const char	*name;
115 	int		(*func)(int, char **);
116 	zpool_help_t	usage;
117 } zpool_command_t;
118 
119 /*
120  * Master command table.  Each ZFS command has a name, associated function, and
121  * usage message.  The usage messages need to be internationalized, so we have
122  * to have a function to return the usage message based on a command index.
123  *
124  * These commands are organized according to how they are displayed in the usage
125  * message.  An empty command (one with a NULL name) indicates an empty line in
126  * the generic usage message.
127  */
128 static zpool_command_t command_table[] = {
129 	{ "create",	zpool_do_create,	HELP_CREATE		},
130 	{ "destroy",	zpool_do_destroy,	HELP_DESTROY		},
131 	{ NULL },
132 	{ "add",	zpool_do_add,		HELP_ADD		},
133 	{ "remove",	zpool_do_remove,	HELP_REMOVE		},
134 	{ NULL },
135 	{ "list",	zpool_do_list,		HELP_LIST		},
136 	{ "iostat",	zpool_do_iostat,	HELP_IOSTAT		},
137 	{ "status",	zpool_do_status,	HELP_STATUS		},
138 	{ NULL },
139 	{ "online",	zpool_do_online,	HELP_ONLINE		},
140 	{ "offline",	zpool_do_offline,	HELP_OFFLINE		},
141 	{ "clear",	zpool_do_clear,		HELP_CLEAR		},
142 	{ NULL },
143 	{ "attach",	zpool_do_attach,	HELP_ATTACH		},
144 	{ "detach",	zpool_do_detach,	HELP_DETACH		},
145 	{ "replace",	zpool_do_replace,	HELP_REPLACE		},
146 	{ NULL },
147 	{ "scrub",	zpool_do_scrub,		HELP_SCRUB		},
148 	{ NULL },
149 	{ "import",	zpool_do_import,	HELP_IMPORT		},
150 	{ "export",	zpool_do_export,	HELP_EXPORT		},
151 	{ "upgrade",	zpool_do_upgrade,	HELP_UPGRADE		}
152 };
153 
154 #define	NCOMMAND	(sizeof (command_table) / sizeof (command_table[0]))
155 
156 zpool_command_t *current_command;
157 
158 static const char *
159 get_usage(zpool_help_t idx) {
160 	switch (idx) {
161 	case HELP_ADD:
162 		return (gettext("\tadd [-fn] <pool> <vdev> ...\n"));
163 	case HELP_ATTACH:
164 		return (gettext("\tattach [-f] <pool> <device> "
165 		    "<new_device>\n"));
166 	case HELP_CLEAR:
167 		return (gettext("\tclear <pool> [device]\n"));
168 	case HELP_CREATE:
169 		return (gettext("\tcreate  [-fn] [-R root] [-m mountpoint] "
170 		    "<pool> <vdev> ...\n"));
171 	case HELP_DESTROY:
172 		return (gettext("\tdestroy [-f] <pool>\n"));
173 	case HELP_DETACH:
174 		return (gettext("\tdetach <pool> <device>\n"));
175 	case HELP_EXPORT:
176 		return (gettext("\texport [-f] <pool> ...\n"));
177 	case HELP_IMPORT:
178 		return (gettext("\timport [-d dir] [-D]\n"
179 		    "\timport [-d dir] [-D] [-f] [-o opts] [-R root] -a\n"
180 		    "\timport [-d dir] [-D] [-f] [-o opts] [-R root ]"
181 		    " <pool | id> [newpool]\n"));
182 	case HELP_IOSTAT:
183 		return (gettext("\tiostat [-v] [pool] ... [interval "
184 		    "[count]]\n"));
185 	case HELP_LIST:
186 		return (gettext("\tlist [-H] [-o field[,field]*] "
187 		    "[pool] ...\n"));
188 	case HELP_OFFLINE:
189 		return (gettext("\toffline [-t] <pool> <device> ...\n"));
190 	case HELP_ONLINE:
191 		return (gettext("\tonline <pool> <device> ...\n"));
192 	case HELP_REPLACE:
193 		return (gettext("\treplace [-f] <pool> <device> "
194 		    "[new_device]\n"));
195 	case HELP_REMOVE:
196 		return (gettext("\tremove <pool> <device>\n"));
197 	case HELP_SCRUB:
198 		return (gettext("\tscrub [-s] <pool> ...\n"));
199 	case HELP_STATUS:
200 		return (gettext("\tstatus [-vx] [pool] ...\n"));
201 	case HELP_UPGRADE:
202 		return (gettext("\tupgrade\n"
203 		    "\tupgrade -v\n"
204 		    "\tupgrade <-a | pool>\n"));
205 	}
206 
207 	abort();
208 	/* NOTREACHED */
209 }
210 
211 /*
212  * Fields available for 'zpool list'.
213  */
214 typedef enum {
215 	ZPOOL_FIELD_NAME,
216 	ZPOOL_FIELD_SIZE,
217 	ZPOOL_FIELD_USED,
218 	ZPOOL_FIELD_AVAILABLE,
219 	ZPOOL_FIELD_CAPACITY,
220 	ZPOOL_FIELD_HEALTH,
221 	ZPOOL_FIELD_ROOT
222 } zpool_field_t;
223 
224 #define	MAX_FIELDS	10
225 
226 typedef struct column_def {
227 	const char	*cd_title;
228 	size_t		cd_width;
229 	enum {
230 		left_justify,
231 		right_justify
232 	}		cd_justify;
233 } column_def_t;
234 
235 static column_def_t column_table[] = {
236 	{ "NAME",	20,	left_justify	},
237 	{ "SIZE",	6,	right_justify	},
238 	{ "USED",	6,	right_justify	},
239 	{ "AVAIL",	6,	right_justify	},
240 	{ "CAP",	5,	right_justify	},
241 	{ "HEALTH",	9,	left_justify	},
242 	{ "ALTROOT",	15,	left_justify	}
243 };
244 
245 static char *column_subopts[] = {
246 	"name",
247 	"size",
248 	"used",
249 	"available",
250 	"capacity",
251 	"health",
252 	"root",
253 	NULL
254 };
255 
256 /*
257  * Display usage message.  If we're inside a command, display only the usage for
258  * that command.  Otherwise, iterate over the entire command table and display
259  * a complete usage message.
260  */
261 void
262 usage(boolean_t requested)
263 {
264 	int i;
265 	FILE *fp = requested ? stdout : stderr;
266 
267 	if (current_command == NULL) {
268 		int i;
269 
270 		(void) fprintf(fp, gettext("usage: zpool command args ...\n"));
271 		(void) fprintf(fp,
272 		    gettext("where 'command' is one of the following:\n\n"));
273 
274 		for (i = 0; i < NCOMMAND; i++) {
275 			if (command_table[i].name == NULL)
276 				(void) fprintf(fp, "\n");
277 			else
278 				(void) fprintf(fp, "%s",
279 				    get_usage(command_table[i].usage));
280 		}
281 	} else {
282 		(void) fprintf(fp, gettext("usage:\n"));
283 		(void) fprintf(fp, "%s", get_usage(current_command->usage));
284 
285 		if (strcmp(current_command->name, "list") == 0) {
286 			(void) fprintf(fp, gettext("\nwhere 'field' is one "
287 			    "of the following:\n\n"));
288 
289 			for (i = 0; column_subopts[i] != NULL; i++)
290 				(void) fprintf(fp, "\t%s\n", column_subopts[i]);
291 		}
292 	}
293 
294 	exit(requested ? 0 : 2);
295 }
296 
297 const char *
298 state_to_name(vdev_stat_t *vs)
299 {
300 	switch (vs->vs_state) {
301 	case VDEV_STATE_CLOSED:
302 	case VDEV_STATE_CANT_OPEN:
303 		if (vs->vs_aux == VDEV_AUX_CORRUPT_DATA)
304 			return (gettext("FAULTED"));
305 		else
306 			return (gettext("UNAVAIL"));
307 	case VDEV_STATE_OFFLINE:
308 		return (gettext("OFFLINE"));
309 	case VDEV_STATE_DEGRADED:
310 		return (gettext("DEGRADED"));
311 	case VDEV_STATE_HEALTHY:
312 		return (gettext("ONLINE"));
313 	}
314 
315 	return (gettext("UNKNOWN"));
316 }
317 
318 void
319 print_vdev_tree(zpool_handle_t *zhp, const char *name, nvlist_t *nv, int indent)
320 {
321 	nvlist_t **child;
322 	uint_t c, children;
323 	char *vname;
324 
325 	if (name != NULL)
326 		(void) printf("\t%*s%s\n", indent, "", name);
327 
328 	if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
329 	    &child, &children) != 0)
330 		return;
331 
332 	for (c = 0; c < children; c++) {
333 		vname = zpool_vdev_name(g_zfs, zhp, child[c]);
334 		print_vdev_tree(zhp, vname, child[c], indent + 2);
335 		free(vname);
336 	}
337 }
338 
339 /*
340  * zpool add [-fn] <pool> <vdev> ...
341  *
342  *	-f	Force addition of devices, even if they appear in use
343  *	-n	Do not add the devices, but display the resulting layout if
344  *		they were to be added.
345  *
346  * Adds the given vdevs to 'pool'.  As with create, the bulk of this work is
347  * handled by get_vdev_spec(), which constructs the nvlist needed to pass to
348  * libzfs.
349  */
350 int
351 zpool_do_add(int argc, char **argv)
352 {
353 	boolean_t force = B_FALSE;
354 	boolean_t dryrun = B_FALSE;
355 	int c;
356 	nvlist_t *nvroot;
357 	char *poolname;
358 	int ret;
359 	zpool_handle_t *zhp;
360 	nvlist_t *config;
361 
362 	/* check options */
363 	while ((c = getopt(argc, argv, "fn")) != -1) {
364 		switch (c) {
365 		case 'f':
366 			force = B_TRUE;
367 			break;
368 		case 'n':
369 			dryrun = B_TRUE;
370 			break;
371 		case '?':
372 			(void) fprintf(stderr, gettext("invalid option '%c'\n"),
373 			    optopt);
374 			usage(B_FALSE);
375 		}
376 	}
377 
378 	argc -= optind;
379 	argv += optind;
380 
381 	/* get pool name and check number of arguments */
382 	if (argc < 1) {
383 		(void) fprintf(stderr, gettext("missing pool name argument\n"));
384 		usage(B_FALSE);
385 	}
386 	if (argc < 2) {
387 		(void) fprintf(stderr, gettext("missing vdev specification\n"));
388 		usage(B_FALSE);
389 	}
390 
391 	poolname = argv[0];
392 
393 	argc--;
394 	argv++;
395 
396 	if ((zhp = zpool_open(g_zfs, poolname)) == NULL)
397 		return (1);
398 
399 	if ((config = zpool_get_config(zhp, NULL)) == NULL) {
400 		(void) fprintf(stderr, gettext("pool '%s' is unavailable\n"),
401 		    poolname);
402 		zpool_close(zhp);
403 		return (1);
404 	}
405 
406 	/* pass off to get_vdev_spec for processing */
407 	nvroot = make_root_vdev(config, force, !force, B_FALSE, argc, argv);
408 	if (nvroot == NULL) {
409 		zpool_close(zhp);
410 		return (1);
411 	}
412 
413 	if (dryrun) {
414 		nvlist_t *poolnvroot;
415 
416 		verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
417 		    &poolnvroot) == 0);
418 
419 		(void) printf(gettext("would update '%s' to the following "
420 		    "configuration:\n"), zpool_get_name(zhp));
421 
422 		print_vdev_tree(zhp, poolname, poolnvroot, 0);
423 		print_vdev_tree(zhp, NULL, nvroot, 0);
424 
425 		ret = 0;
426 	} else {
427 		ret = (zpool_add(zhp, nvroot) != 0);
428 	}
429 
430 	nvlist_free(nvroot);
431 	zpool_close(zhp);
432 
433 	return (ret);
434 }
435 
436 /*
437  * zpool remove <pool> <vdev>
438  *
439  * Removes the given vdev from the pool.  Currently, this only supports removing
440  * spares from the pool.  Eventually, we'll want to support removing leaf vdevs
441  * (as an alias for 'detach') as well as toplevel vdevs.
442  */
443 int
444 zpool_do_remove(int argc, char **argv)
445 {
446 	char *poolname;
447 	int ret;
448 	zpool_handle_t *zhp;
449 
450 	argc--;
451 	argv++;
452 
453 	/* get pool name and check number of arguments */
454 	if (argc < 1) {
455 		(void) fprintf(stderr, gettext("missing pool name argument\n"));
456 		usage(B_FALSE);
457 	}
458 	if (argc < 2) {
459 		(void) fprintf(stderr, gettext("missing device\n"));
460 		usage(B_FALSE);
461 	}
462 
463 	poolname = argv[0];
464 
465 	if ((zhp = zpool_open(g_zfs, poolname)) == NULL)
466 		return (1);
467 
468 	ret = (zpool_vdev_remove(zhp, argv[1]) != 0);
469 
470 	return (ret);
471 }
472 
473 /*
474  * zpool create [-fn] [-R root] [-m mountpoint] <pool> <dev> ...
475  *
476  *	-f	Force creation, even if devices appear in use
477  *	-n	Do not create the pool, but display the resulting layout if it
478  *		were to be created.
479  *      -R	Create a pool under an alternate root
480  *      -m	Set default mountpoint for the root dataset.  By default it's
481  *      	'/<pool>'
482  *
483  * Creates the the named pool according to the given vdev specification.  The
484  * bulk of the vdev processing is done in get_vdev_spec() in zpool_vdev.c.  Once
485  * we get the nvlist back from get_vdev_spec(), we either print out the contents
486  * (if '-n' was specified), or pass it to libzfs to do the creation.
487  */
488 int
489 zpool_do_create(int argc, char **argv)
490 {
491 	boolean_t force = B_FALSE;
492 	boolean_t dryrun = B_FALSE;
493 	int c;
494 	nvlist_t *nvroot;
495 	char *poolname;
496 	int ret;
497 	char *altroot = NULL;
498 	char *mountpoint = NULL;
499 	nvlist_t **child;
500 	uint_t children;
501 
502 	/* check options */
503 	while ((c = getopt(argc, argv, ":fnR:m:")) != -1) {
504 		switch (c) {
505 		case 'f':
506 			force = B_TRUE;
507 			break;
508 		case 'n':
509 			dryrun = B_TRUE;
510 			break;
511 		case 'R':
512 			altroot = optarg;
513 			break;
514 		case 'm':
515 			mountpoint = optarg;
516 			break;
517 		case ':':
518 			(void) fprintf(stderr, gettext("missing argument for "
519 			    "'%c' option\n"), optopt);
520 			usage(B_FALSE);
521 			break;
522 		case '?':
523 			(void) fprintf(stderr, gettext("invalid option '%c'\n"),
524 			    optopt);
525 			usage(B_FALSE);
526 		}
527 	}
528 
529 	argc -= optind;
530 	argv += optind;
531 
532 	/* get pool name and check number of arguments */
533 	if (argc < 1) {
534 		(void) fprintf(stderr, gettext("missing pool name argument\n"));
535 		usage(B_FALSE);
536 	}
537 	if (argc < 2) {
538 		(void) fprintf(stderr, gettext("missing vdev specification\n"));
539 		usage(B_FALSE);
540 	}
541 
542 	poolname = argv[0];
543 
544 	/*
545 	 * As a special case, check for use of '/' in the name, and direct the
546 	 * user to use 'zfs create' instead.
547 	 */
548 	if (strchr(poolname, '/') != NULL) {
549 		(void) fprintf(stderr, gettext("cannot create '%s': invalid "
550 		    "character '/' in pool name\n"), poolname);
551 		(void) fprintf(stderr, gettext("use 'zfs create' to "
552 		    "create a dataset\n"));
553 		return (1);
554 	}
555 
556 	/* pass off to get_vdev_spec for bulk processing */
557 	nvroot = make_root_vdev(NULL, force, !force, B_FALSE, argc - 1,
558 	    argv + 1);
559 	if (nvroot == NULL)
560 		return (1);
561 
562 	/* make_root_vdev() allows 0 toplevel children if there are spares */
563 	verify(nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_CHILDREN,
564 	    &child, &children) == 0);
565 	if (children == 0) {
566 		(void) fprintf(stderr, gettext("invalid vdev "
567 		    "specification: at least one toplevel vdev must be "
568 		    "specified\n"));
569 		return (1);
570 	}
571 
572 
573 	if (altroot != NULL && altroot[0] != '/') {
574 		(void) fprintf(stderr, gettext("invalid alternate root '%s': "
575 		    "must be an absolute path\n"));
576 		nvlist_free(nvroot);
577 		return (1);
578 	}
579 
580 	/*
581 	 * Check the validity of the mountpoint and direct the user to use the
582 	 * '-m' mountpoint option if it looks like its in use.
583 	 */
584 	if (mountpoint == NULL ||
585 	    (strcmp(mountpoint, ZFS_MOUNTPOINT_LEGACY) != 0 &&
586 	    strcmp(mountpoint, ZFS_MOUNTPOINT_NONE) != 0)) {
587 		char buf[MAXPATHLEN];
588 		struct stat64 statbuf;
589 
590 		if (mountpoint && mountpoint[0] != '/') {
591 			(void) fprintf(stderr, gettext("invalid mountpoint "
592 			    "'%s': must be an absolute path, 'legacy', or "
593 			    "'none'\n"), mountpoint);
594 			nvlist_free(nvroot);
595 			return (1);
596 		}
597 
598 		if (mountpoint == NULL) {
599 			if (altroot != NULL)
600 				(void) snprintf(buf, sizeof (buf), "%s/%s",
601 				    altroot, poolname);
602 			else
603 				(void) snprintf(buf, sizeof (buf), "/%s",
604 				    poolname);
605 		} else {
606 			if (altroot != NULL)
607 				(void) snprintf(buf, sizeof (buf), "%s%s",
608 				    altroot, mountpoint);
609 			else
610 				(void) snprintf(buf, sizeof (buf), "%s",
611 				    mountpoint);
612 		}
613 
614 		if (stat64(buf, &statbuf) == 0 &&
615 		    statbuf.st_nlink != 2) {
616 			if (mountpoint == NULL)
617 				(void) fprintf(stderr, gettext("default "
618 				    "mountpoint '%s' exists and is not "
619 				    "empty\n"), buf);
620 			else
621 				(void) fprintf(stderr, gettext("mountpoint "
622 				    "'%s' exists and is not empty\n"), buf);
623 			(void) fprintf(stderr, gettext("use '-m' "
624 			    "option to provide a different default\n"));
625 			nvlist_free(nvroot);
626 			return (1);
627 		}
628 	}
629 
630 
631 	if (dryrun) {
632 		/*
633 		 * For a dry run invocation, print out a basic message and run
634 		 * through all the vdevs in the list and print out in an
635 		 * appropriate hierarchy.
636 		 */
637 		(void) printf(gettext("would create '%s' with the "
638 		    "following layout:\n\n"), poolname);
639 
640 		print_vdev_tree(NULL, poolname, nvroot, 0);
641 
642 		ret = 0;
643 	} else {
644 		ret = 1;
645 		/*
646 		 * Hand off to libzfs.
647 		 */
648 		if (zpool_create(g_zfs, poolname, nvroot, altroot) == 0) {
649 			zfs_handle_t *pool = zfs_open(g_zfs, poolname,
650 			    ZFS_TYPE_FILESYSTEM);
651 			if (pool != NULL) {
652 				if (mountpoint != NULL)
653 					verify(zfs_prop_set(pool,
654 					    ZFS_PROP_MOUNTPOINT,
655 					    mountpoint) == 0);
656 				if (zfs_mount(pool, NULL, 0) == 0)
657 					ret = zfs_share(pool);
658 				zfs_close(pool);
659 			}
660 		} else if (libzfs_errno(g_zfs) == EZFS_INVALIDNAME) {
661 			(void) fprintf(stderr, gettext("pool name may have "
662 			    "been omitted\n"));
663 		}
664 	}
665 
666 	nvlist_free(nvroot);
667 
668 	return (ret);
669 }
670 
671 /*
672  * zpool destroy <pool>
673  *
674  * 	-f	Forcefully unmount any datasets
675  *
676  * Destroy the given pool.  Automatically unmounts any datasets in the pool.
677  */
678 int
679 zpool_do_destroy(int argc, char **argv)
680 {
681 	boolean_t force = B_FALSE;
682 	int c;
683 	char *pool;
684 	zpool_handle_t *zhp;
685 	int ret;
686 
687 	/* check options */
688 	while ((c = getopt(argc, argv, "f")) != -1) {
689 		switch (c) {
690 		case 'f':
691 			force = B_TRUE;
692 			break;
693 		case '?':
694 			(void) fprintf(stderr, gettext("invalid option '%c'\n"),
695 			    optopt);
696 			usage(B_FALSE);
697 		}
698 	}
699 
700 	argc -= optind;
701 	argv += optind;
702 
703 	/* check arguments */
704 	if (argc < 1) {
705 		(void) fprintf(stderr, gettext("missing pool argument\n"));
706 		usage(B_FALSE);
707 	}
708 	if (argc > 1) {
709 		(void) fprintf(stderr, gettext("too many arguments\n"));
710 		usage(B_FALSE);
711 	}
712 
713 	pool = argv[0];
714 
715 	if ((zhp = zpool_open_canfail(g_zfs, pool)) == NULL) {
716 		/*
717 		 * As a special case, check for use of '/' in the name, and
718 		 * direct the user to use 'zfs destroy' instead.
719 		 */
720 		if (strchr(pool, '/') != NULL)
721 			(void) fprintf(stderr, gettext("use 'zfs destroy' to "
722 			    "destroy a dataset\n"));
723 		return (1);
724 	}
725 
726 	if (zpool_unmount_datasets(zhp, force) != 0) {
727 		(void) fprintf(stderr, gettext("could not destroy '%s': "
728 		    "could not unmount datasets\n"), zpool_get_name(zhp));
729 		return (1);
730 	}
731 
732 	ret = (zpool_destroy(zhp) != 0);
733 
734 	zpool_close(zhp);
735 
736 	return (ret);
737 }
738 
739 /*
740  * zpool export [-f] <pool> ...
741  *
742  *	-f	Forcefully unmount datasets
743  *
744  * Export the the given pools.  By default, the command will attempt to cleanly
745  * unmount any active datasets within the pool.  If the '-f' flag is specified,
746  * then the datasets will be forcefully unmounted.
747  */
748 int
749 zpool_do_export(int argc, char **argv)
750 {
751 	boolean_t force = B_FALSE;
752 	int c;
753 	zpool_handle_t *zhp;
754 	int ret;
755 	int i;
756 
757 	/* check options */
758 	while ((c = getopt(argc, argv, "f")) != -1) {
759 		switch (c) {
760 		case 'f':
761 			force = B_TRUE;
762 			break;
763 		case '?':
764 			(void) fprintf(stderr, gettext("invalid option '%c'\n"),
765 			    optopt);
766 			usage(B_FALSE);
767 		}
768 	}
769 
770 	argc -= optind;
771 	argv += optind;
772 
773 	/* check arguments */
774 	if (argc < 1) {
775 		(void) fprintf(stderr, gettext("missing pool argument\n"));
776 		usage(B_FALSE);
777 	}
778 
779 	ret = 0;
780 	for (i = 0; i < argc; i++) {
781 		if ((zhp = zpool_open_canfail(g_zfs, argv[i])) == NULL) {
782 			ret = 1;
783 			continue;
784 		}
785 
786 		if (zpool_unmount_datasets(zhp, force) != 0) {
787 			ret = 1;
788 			zpool_close(zhp);
789 			continue;
790 		}
791 
792 		if (zpool_export(zhp) != 0)
793 			ret = 1;
794 
795 		zpool_close(zhp);
796 	}
797 
798 	return (ret);
799 }
800 
801 /*
802  * Given a vdev configuration, determine the maximum width needed for the device
803  * name column.
804  */
805 static int
806 max_width(zpool_handle_t *zhp, nvlist_t *nv, int depth, int max)
807 {
808 	char *name = zpool_vdev_name(g_zfs, zhp, nv);
809 	nvlist_t **child;
810 	uint_t c, children;
811 	int ret;
812 
813 	if (strlen(name) + depth > max)
814 		max = strlen(name) + depth;
815 
816 	free(name);
817 
818 	if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_SPARES,
819 	    &child, &children) == 0) {
820 		for (c = 0; c < children; c++)
821 			if ((ret = max_width(zhp, child[c], depth + 2,
822 			    max)) > max)
823 				max = ret;
824 	}
825 
826 	if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
827 	    &child, &children) == 0) {
828 		for (c = 0; c < children; c++)
829 			if ((ret = max_width(zhp, child[c], depth + 2,
830 			    max)) > max)
831 				max = ret;
832 	}
833 
834 
835 	return (max);
836 }
837 
838 
839 /*
840  * Print the configuration of an exported pool.  Iterate over all vdevs in the
841  * pool, printing out the name and status for each one.
842  */
843 void
844 print_import_config(const char *name, nvlist_t *nv, int namewidth, int depth)
845 {
846 	nvlist_t **child;
847 	uint_t c, children;
848 	vdev_stat_t *vs;
849 	char *type, *vname;
850 
851 	verify(nvlist_lookup_string(nv, ZPOOL_CONFIG_TYPE, &type) == 0);
852 	if (strcmp(type, VDEV_TYPE_MISSING) == 0)
853 		return;
854 
855 	verify(nvlist_lookup_uint64_array(nv, ZPOOL_CONFIG_STATS,
856 	    (uint64_t **)&vs, &c) == 0);
857 
858 	(void) printf("\t%*s%-*s", depth, "", namewidth - depth, name);
859 
860 	if (vs->vs_aux != 0) {
861 		(void) printf("  %-8s  ", state_to_name(vs));
862 
863 		switch (vs->vs_aux) {
864 		case VDEV_AUX_OPEN_FAILED:
865 			(void) printf(gettext("cannot open"));
866 			break;
867 
868 		case VDEV_AUX_BAD_GUID_SUM:
869 			(void) printf(gettext("missing device"));
870 			break;
871 
872 		case VDEV_AUX_NO_REPLICAS:
873 			(void) printf(gettext("insufficient replicas"));
874 			break;
875 
876 		case VDEV_AUX_VERSION_NEWER:
877 			(void) printf(gettext("newer version"));
878 			break;
879 
880 		default:
881 			(void) printf(gettext("corrupted data"));
882 			break;
883 		}
884 	} else {
885 		(void) printf("  %s", state_to_name(vs));
886 	}
887 	(void) printf("\n");
888 
889 	if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
890 	    &child, &children) != 0)
891 		return;
892 
893 	for (c = 0; c < children; c++) {
894 		vname = zpool_vdev_name(g_zfs, NULL, child[c]);
895 		print_import_config(vname, child[c],
896 		    namewidth, depth + 2);
897 		free(vname);
898 	}
899 
900 	if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_SPARES,
901 	    &child, &children) != 0)
902 		return;
903 
904 	(void) printf(gettext("\tspares\n"));
905 	for (c = 0; c < children; c++) {
906 		vname = zpool_vdev_name(g_zfs, NULL, child[c]);
907 		(void) printf("\t  %s\n", vname);
908 		free(vname);
909 	}
910 }
911 
912 /*
913  * Display the status for the given pool.
914  */
915 static void
916 show_import(nvlist_t *config)
917 {
918 	uint64_t pool_state;
919 	vdev_stat_t *vs;
920 	char *name;
921 	uint64_t guid;
922 	char *msgid;
923 	nvlist_t *nvroot;
924 	int reason;
925 	char *health;
926 	uint_t vsc;
927 	int namewidth;
928 
929 	verify(nvlist_lookup_string(config, ZPOOL_CONFIG_POOL_NAME,
930 	    &name) == 0);
931 	verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_GUID,
932 	    &guid) == 0);
933 	verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_STATE,
934 	    &pool_state) == 0);
935 	verify(nvlist_lookup_string(config, ZPOOL_CONFIG_POOL_HEALTH,
936 	    &health) == 0);
937 	verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
938 	    &nvroot) == 0);
939 
940 	verify(nvlist_lookup_uint64_array(nvroot, ZPOOL_CONFIG_STATS,
941 	    (uint64_t **)&vs, &vsc) == 0);
942 
943 	reason = zpool_import_status(config, &msgid);
944 
945 	(void) printf("  pool: %s\n", name);
946 	(void) printf("    id: %llu\n", guid);
947 	(void) printf(" state: %s", health);
948 	if (pool_state == POOL_STATE_DESTROYED)
949 	    (void) printf(" (DESTROYED)");
950 	(void) printf("\n");
951 
952 	switch (reason) {
953 	case ZPOOL_STATUS_MISSING_DEV_R:
954 	case ZPOOL_STATUS_MISSING_DEV_NR:
955 	case ZPOOL_STATUS_BAD_GUID_SUM:
956 		(void) printf(gettext("status: One or more devices are missing "
957 		    "from the system.\n"));
958 		break;
959 
960 	case ZPOOL_STATUS_CORRUPT_LABEL_R:
961 	case ZPOOL_STATUS_CORRUPT_LABEL_NR:
962 		(void) printf(gettext("status: One or more devices contains "
963 		    "corrupted data.\n"));
964 		break;
965 
966 	case ZPOOL_STATUS_CORRUPT_DATA:
967 		(void) printf(gettext("status: The pool data is corrupted.\n"));
968 		break;
969 
970 	case ZPOOL_STATUS_OFFLINE_DEV:
971 		(void) printf(gettext("status: One or more devices "
972 		    "are offlined.\n"));
973 		break;
974 
975 	case ZPOOL_STATUS_CORRUPT_POOL:
976 		(void) printf(gettext("status: The pool metadata is "
977 		    "corrupted.\n"));
978 		break;
979 
980 	case ZPOOL_STATUS_VERSION_OLDER:
981 		(void) printf(gettext("status: The pool is formatted using an "
982 		    "older on-disk version.\n"));
983 		break;
984 
985 	case ZPOOL_STATUS_VERSION_NEWER:
986 		(void) printf(gettext("status: The pool is formatted using an "
987 		    "incompatible version.\n"));
988 		break;
989 
990 	default:
991 		/*
992 		 * No other status can be seen when importing pools.
993 		 */
994 		assert(reason == ZPOOL_STATUS_OK);
995 	}
996 
997 	/*
998 	 * Print out an action according to the overall state of the pool.
999 	 */
1000 	if (strcmp(health, gettext("ONLINE")) == 0) {
1001 		if (reason == ZPOOL_STATUS_VERSION_OLDER)
1002 			(void) printf(gettext("action: The pool can be "
1003 			    "imported using its name or numeric identifier, "
1004 			    "though\n\tsome features will not be available "
1005 			    "without an explicit 'zpool upgrade'.\n"));
1006 		else
1007 			(void) printf(gettext("action: The pool can be "
1008 			    "imported using its name or numeric "
1009 			    "identifier.\n"));
1010 	} else if (strcmp(health, gettext("DEGRADED")) == 0) {
1011 		(void) printf(gettext("action: The pool can be imported "
1012 		    "despite missing or damaged devices.  The\n\tfault "
1013 		    "tolerance of the pool may be compromised if imported.\n"));
1014 	} else {
1015 		switch (reason) {
1016 		case ZPOOL_STATUS_VERSION_NEWER:
1017 			(void) printf(gettext("action: The pool cannot be "
1018 			    "imported.  Access the pool on a system running "
1019 			    "newer\n\tsoftware, or recreate the pool from "
1020 			    "backup.\n"));
1021 			break;
1022 		case ZPOOL_STATUS_MISSING_DEV_R:
1023 		case ZPOOL_STATUS_MISSING_DEV_NR:
1024 		case ZPOOL_STATUS_BAD_GUID_SUM:
1025 			(void) printf(gettext("action: The pool cannot be "
1026 			    "imported. Attach the missing\n\tdevices and try "
1027 			    "again.\n"));
1028 			break;
1029 		default:
1030 			(void) printf(gettext("action: The pool cannot be "
1031 			    "imported due to damaged devices or data.\n"));
1032 		}
1033 	}
1034 
1035 	if (strcmp(health, gettext("FAULTED")) != 0) {
1036 		if (pool_state == POOL_STATE_DESTROYED)
1037 			(void) printf(gettext("\tThe pool was destroyed, "
1038 			    "but can be imported using the '-Df' flags.\n"));
1039 		else if (pool_state != POOL_STATE_EXPORTED)
1040 			(void) printf(gettext("\tThe pool may be active on "
1041 			    "on another system, but can be imported using\n\t"
1042 			    "the '-f' flag.\n"));
1043 	}
1044 
1045 	if (msgid != NULL)
1046 		(void) printf(gettext("   see: http://www.sun.com/msg/%s\n"),
1047 		    msgid);
1048 
1049 	(void) printf(gettext("config:\n\n"));
1050 
1051 	namewidth = max_width(NULL, nvroot, 0, 0);
1052 	if (namewidth < 10)
1053 		namewidth = 10;
1054 	print_import_config(name, nvroot, namewidth, 0);
1055 
1056 	if (reason == ZPOOL_STATUS_BAD_GUID_SUM) {
1057 		(void) printf("\n\tAdditional devices are known to "
1058 		    "be part of this pool, though their\n\texact "
1059 		    "configuration cannot be determined.\n");
1060 	}
1061 }
1062 
1063 /*
1064  * Perform the import for the given configuration.  This passes the heavy
1065  * lifting off to zpool_import(), and then mounts the datasets contained within
1066  * the pool.
1067  */
1068 static int
1069 do_import(nvlist_t *config, const char *newname, const char *mntopts,
1070     const char *altroot, int force)
1071 {
1072 	zpool_handle_t *zhp;
1073 	char *name;
1074 	uint64_t state;
1075 	uint64_t version;
1076 
1077 	verify(nvlist_lookup_string(config, ZPOOL_CONFIG_POOL_NAME,
1078 	    &name) == 0);
1079 
1080 	verify(nvlist_lookup_uint64(config,
1081 	    ZPOOL_CONFIG_POOL_STATE, &state) == 0);
1082 	verify(nvlist_lookup_uint64(config,
1083 	    ZPOOL_CONFIG_VERSION, &version) == 0);
1084 	if (version > ZFS_VERSION) {
1085 		(void) fprintf(stderr, gettext("cannot import '%s': pool "
1086 		    "is formatted using a newer ZFS version\n"), name);
1087 		return (1);
1088 	} else if (state != POOL_STATE_EXPORTED && !force) {
1089 		(void) fprintf(stderr, gettext("cannot import '%s': pool "
1090 		    "may be in use from other system\n"), name);
1091 		(void) fprintf(stderr, gettext("use '-f' to import anyway\n"));
1092 		return (1);
1093 	}
1094 
1095 	if (zpool_import(g_zfs, config, newname, altroot) != 0)
1096 		return (1);
1097 
1098 	if (newname != NULL)
1099 		name = (char *)newname;
1100 
1101 	verify((zhp = zpool_open(g_zfs, name)) != NULL);
1102 
1103 	if (zpool_mount_datasets(zhp, mntopts, 0) != 0) {
1104 		zpool_close(zhp);
1105 		return (1);
1106 	}
1107 
1108 	zpool_close(zhp);
1109 	return (0);
1110 }
1111 
1112 /*
1113  * zpool import [-d dir] [-D]
1114  *       import [-R root] [-D] [-d dir] [-f] -a
1115  *       import [-R root] [-D] [-d dir] [-f] <pool | id> [newpool]
1116  *
1117  *       -d	Scan in a specific directory, other than /dev/dsk.  More than
1118  *		one directory can be specified using multiple '-d' options.
1119  *
1120  *       -D     Scan for previously destroyed pools or import all or only
1121  *              specified destroyed pools.
1122  *
1123  *       -R	Temporarily import the pool, with all mountpoints relative to
1124  *		the given root.  The pool will remain exported when the machine
1125  *		is rebooted.
1126  *
1127  *       -f	Force import, even if it appears that the pool is active.
1128  *
1129  *       -a	Import all pools found.
1130  *
1131  * The import command scans for pools to import, and import pools based on pool
1132  * name and GUID.  The pool can also be renamed as part of the import process.
1133  */
1134 int
1135 zpool_do_import(int argc, char **argv)
1136 {
1137 	char **searchdirs = NULL;
1138 	int nsearch = 0;
1139 	int c;
1140 	int err;
1141 	nvlist_t *pools;
1142 	boolean_t do_all = B_FALSE;
1143 	boolean_t do_destroyed = B_FALSE;
1144 	char *altroot = NULL;
1145 	char *mntopts = NULL;
1146 	boolean_t do_force = B_FALSE;
1147 	nvpair_t *elem;
1148 	nvlist_t *config;
1149 	uint64_t searchguid;
1150 	char *searchname;
1151 	nvlist_t *found_config;
1152 	boolean_t first;
1153 	uint64_t pool_state;
1154 
1155 	/* check options */
1156 	while ((c = getopt(argc, argv, ":Dfd:R:ao:")) != -1) {
1157 		switch (c) {
1158 		case 'a':
1159 			do_all = B_TRUE;
1160 			break;
1161 		case 'd':
1162 			if (searchdirs == NULL) {
1163 				searchdirs = safe_malloc(sizeof (char *));
1164 			} else {
1165 				char **tmp = safe_malloc((nsearch + 1) *
1166 				    sizeof (char *));
1167 				bcopy(searchdirs, tmp, nsearch *
1168 				    sizeof (char *));
1169 				free(searchdirs);
1170 				searchdirs = tmp;
1171 			}
1172 			searchdirs[nsearch++] = optarg;
1173 			break;
1174 		case 'D':
1175 			do_destroyed = B_TRUE;
1176 			break;
1177 		case 'f':
1178 			do_force = B_TRUE;
1179 			break;
1180 		case 'o':
1181 			mntopts = optarg;
1182 			break;
1183 		case 'R':
1184 			altroot = optarg;
1185 			break;
1186 		case ':':
1187 			(void) fprintf(stderr, gettext("missing argument for "
1188 			    "'%c' option\n"), optopt);
1189 			usage(B_FALSE);
1190 			break;
1191 		case '?':
1192 			(void) fprintf(stderr, gettext("invalid option '%c'\n"),
1193 			    optopt);
1194 			usage(B_FALSE);
1195 		}
1196 	}
1197 
1198 	argc -= optind;
1199 	argv += optind;
1200 
1201 	if (searchdirs == NULL) {
1202 		searchdirs = safe_malloc(sizeof (char *));
1203 		searchdirs[0] = "/dev/dsk";
1204 		nsearch = 1;
1205 	}
1206 
1207 	/* check argument count */
1208 	if (do_all) {
1209 		if (argc != 0) {
1210 			(void) fprintf(stderr, gettext("too many arguments\n"));
1211 			usage(B_FALSE);
1212 		}
1213 	} else {
1214 		if (argc > 2) {
1215 			(void) fprintf(stderr, gettext("too many arguments\n"));
1216 			usage(B_FALSE);
1217 		}
1218 
1219 		/*
1220 		 * Check for the SYS_CONFIG privilege.  We do this explicitly
1221 		 * here because otherwise any attempt to discover pools will
1222 		 * silently fail.
1223 		 */
1224 		if (argc == 0 && !priv_ineffect(PRIV_SYS_CONFIG)) {
1225 			(void) fprintf(stderr, gettext("cannot "
1226 			    "discover pools: permission denied\n"));
1227 			free(searchdirs);
1228 			return (1);
1229 		}
1230 	}
1231 
1232 	if ((pools = zpool_find_import(g_zfs, nsearch, searchdirs)) == NULL) {
1233 		free(searchdirs);
1234 		return (1);
1235 	}
1236 
1237 	/*
1238 	 * We now have a list of all available pools in the given directories.
1239 	 * Depending on the arguments given, we do one of the following:
1240 	 *
1241 	 *	<none>	Iterate through all pools and display information about
1242 	 *		each one.
1243 	 *
1244 	 *	-a	Iterate through all pools and try to import each one.
1245 	 *
1246 	 *	<id>	Find the pool that corresponds to the given GUID/pool
1247 	 *		name and import that one.
1248 	 *
1249 	 *	-D	Above options applies only to destroyed pools.
1250 	 */
1251 	if (argc != 0) {
1252 		char *endptr;
1253 
1254 		errno = 0;
1255 		searchguid = strtoull(argv[0], &endptr, 10);
1256 		if (errno != 0 || *endptr != '\0')
1257 			searchname = argv[0];
1258 		else
1259 			searchname = NULL;
1260 		found_config = NULL;
1261 	}
1262 
1263 	err = 0;
1264 	elem = NULL;
1265 	first = B_TRUE;
1266 	while ((elem = nvlist_next_nvpair(pools, elem)) != NULL) {
1267 
1268 		verify(nvpair_value_nvlist(elem, &config) == 0);
1269 
1270 		verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_STATE,
1271 		    &pool_state) == 0);
1272 		if (!do_destroyed && pool_state == POOL_STATE_DESTROYED)
1273 			continue;
1274 		if (do_destroyed && pool_state != POOL_STATE_DESTROYED)
1275 			continue;
1276 
1277 		if (argc == 0) {
1278 			if (first)
1279 				first = B_FALSE;
1280 			else if (!do_all)
1281 				(void) printf("\n");
1282 
1283 			if (do_all)
1284 				err |= do_import(config, NULL, mntopts,
1285 				    altroot, do_force);
1286 			else
1287 				show_import(config);
1288 		} else if (searchname != NULL) {
1289 			char *name;
1290 
1291 			/*
1292 			 * We are searching for a pool based on name.
1293 			 */
1294 			verify(nvlist_lookup_string(config,
1295 			    ZPOOL_CONFIG_POOL_NAME, &name) == 0);
1296 
1297 			if (strcmp(name, searchname) == 0) {
1298 				if (found_config != NULL) {
1299 					(void) fprintf(stderr, gettext(
1300 					    "cannot import '%s': more than "
1301 					    "one matching pool\n"), searchname);
1302 					(void) fprintf(stderr, gettext(
1303 					    "import by numeric ID instead\n"));
1304 					err = B_TRUE;
1305 				}
1306 				found_config = config;
1307 			}
1308 		} else {
1309 			uint64_t guid;
1310 
1311 			/*
1312 			 * Search for a pool by guid.
1313 			 */
1314 			verify(nvlist_lookup_uint64(config,
1315 			    ZPOOL_CONFIG_POOL_GUID, &guid) == 0);
1316 
1317 			if (guid == searchguid)
1318 				found_config = config;
1319 		}
1320 	}
1321 
1322 	/*
1323 	 * If we were searching for a specific pool, verify that we found a
1324 	 * pool, and then do the import.
1325 	 */
1326 	if (argc != 0 && err == 0) {
1327 		if (found_config == NULL) {
1328 			(void) fprintf(stderr, gettext("cannot import '%s': "
1329 			    "no such pool available\n"), argv[0]);
1330 			err = B_TRUE;
1331 		} else {
1332 			err |= do_import(found_config, argc == 1 ? NULL :
1333 			    argv[1], mntopts, altroot, do_force);
1334 		}
1335 	}
1336 
1337 	/*
1338 	 * If we were just looking for pools, report an error if none were
1339 	 * found.
1340 	 */
1341 	if (argc == 0 && first)
1342 		(void) fprintf(stderr,
1343 		    gettext("no pools available to import\n"));
1344 
1345 	nvlist_free(pools);
1346 	free(searchdirs);
1347 
1348 	return (err ? 1 : 0);
1349 }
1350 
1351 typedef struct iostat_cbdata {
1352 	zpool_list_t *cb_list;
1353 	int cb_verbose;
1354 	int cb_iteration;
1355 	int cb_namewidth;
1356 } iostat_cbdata_t;
1357 
1358 static void
1359 print_iostat_separator(iostat_cbdata_t *cb)
1360 {
1361 	int i = 0;
1362 
1363 	for (i = 0; i < cb->cb_namewidth; i++)
1364 		(void) printf("-");
1365 	(void) printf("  -----  -----  -----  -----  -----  -----\n");
1366 }
1367 
1368 static void
1369 print_iostat_header(iostat_cbdata_t *cb)
1370 {
1371 	(void) printf("%*s     capacity     operations    bandwidth\n",
1372 	    cb->cb_namewidth, "");
1373 	(void) printf("%-*s   used  avail   read  write   read  write\n",
1374 	    cb->cb_namewidth, "pool");
1375 	print_iostat_separator(cb);
1376 }
1377 
1378 /*
1379  * Display a single statistic.
1380  */
1381 void
1382 print_one_stat(uint64_t value)
1383 {
1384 	char buf[64];
1385 
1386 	zfs_nicenum(value, buf, sizeof (buf));
1387 	(void) printf("  %5s", buf);
1388 }
1389 
1390 /*
1391  * Print out all the statistics for the given vdev.  This can either be the
1392  * toplevel configuration, or called recursively.  If 'name' is NULL, then this
1393  * is a verbose output, and we don't want to display the toplevel pool stats.
1394  */
1395 void
1396 print_vdev_stats(zpool_handle_t *zhp, const char *name, nvlist_t *oldnv,
1397     nvlist_t *newnv, iostat_cbdata_t *cb, int depth)
1398 {
1399 	nvlist_t **oldchild, **newchild;
1400 	uint_t c, children;
1401 	vdev_stat_t *oldvs, *newvs;
1402 	vdev_stat_t zerovs = { 0 };
1403 	uint64_t tdelta;
1404 	double scale;
1405 	char *vname;
1406 
1407 	if (oldnv != NULL) {
1408 		verify(nvlist_lookup_uint64_array(oldnv, ZPOOL_CONFIG_STATS,
1409 		    (uint64_t **)&oldvs, &c) == 0);
1410 	} else {
1411 		oldvs = &zerovs;
1412 	}
1413 
1414 	verify(nvlist_lookup_uint64_array(newnv, ZPOOL_CONFIG_STATS,
1415 	    (uint64_t **)&newvs, &c) == 0);
1416 
1417 	if (strlen(name) + depth > cb->cb_namewidth)
1418 		(void) printf("%*s%s", depth, "", name);
1419 	else
1420 		(void) printf("%*s%s%*s", depth, "", name,
1421 		    (int)(cb->cb_namewidth - strlen(name) - depth), "");
1422 
1423 	tdelta = newvs->vs_timestamp - oldvs->vs_timestamp;
1424 
1425 	if (tdelta == 0)
1426 		scale = 1.0;
1427 	else
1428 		scale = (double)NANOSEC / tdelta;
1429 
1430 	/* only toplevel vdevs have capacity stats */
1431 	if (newvs->vs_space == 0) {
1432 		(void) printf("      -      -");
1433 	} else {
1434 		print_one_stat(newvs->vs_alloc);
1435 		print_one_stat(newvs->vs_space - newvs->vs_alloc);
1436 	}
1437 
1438 	print_one_stat((uint64_t)(scale * (newvs->vs_ops[ZIO_TYPE_READ] -
1439 	    oldvs->vs_ops[ZIO_TYPE_READ])));
1440 
1441 	print_one_stat((uint64_t)(scale * (newvs->vs_ops[ZIO_TYPE_WRITE] -
1442 	    oldvs->vs_ops[ZIO_TYPE_WRITE])));
1443 
1444 	print_one_stat((uint64_t)(scale * (newvs->vs_bytes[ZIO_TYPE_READ] -
1445 	    oldvs->vs_bytes[ZIO_TYPE_READ])));
1446 
1447 	print_one_stat((uint64_t)(scale * (newvs->vs_bytes[ZIO_TYPE_WRITE] -
1448 	    oldvs->vs_bytes[ZIO_TYPE_WRITE])));
1449 
1450 	(void) printf("\n");
1451 
1452 	if (!cb->cb_verbose)
1453 		return;
1454 
1455 	if (nvlist_lookup_nvlist_array(newnv, ZPOOL_CONFIG_CHILDREN,
1456 	    &newchild, &children) != 0)
1457 		return;
1458 
1459 	if (oldnv && nvlist_lookup_nvlist_array(oldnv, ZPOOL_CONFIG_CHILDREN,
1460 	    &oldchild, &c) != 0)
1461 		return;
1462 
1463 	for (c = 0; c < children; c++) {
1464 		vname = zpool_vdev_name(g_zfs, zhp, newchild[c]);
1465 		print_vdev_stats(zhp, vname, oldnv ? oldchild[c] : NULL,
1466 		    newchild[c], cb, depth + 2);
1467 		free(vname);
1468 	}
1469 }
1470 
1471 static int
1472 refresh_iostat(zpool_handle_t *zhp, void *data)
1473 {
1474 	iostat_cbdata_t *cb = data;
1475 	boolean_t missing;
1476 
1477 	/*
1478 	 * If the pool has disappeared, remove it from the list and continue.
1479 	 */
1480 	if (zpool_refresh_stats(zhp, &missing) != 0)
1481 		return (-1);
1482 
1483 	if (missing)
1484 		pool_list_remove(cb->cb_list, zhp);
1485 
1486 	return (0);
1487 }
1488 
1489 /*
1490  * Callback to print out the iostats for the given pool.
1491  */
1492 int
1493 print_iostat(zpool_handle_t *zhp, void *data)
1494 {
1495 	iostat_cbdata_t *cb = data;
1496 	nvlist_t *oldconfig, *newconfig;
1497 	nvlist_t *oldnvroot, *newnvroot;
1498 
1499 	newconfig = zpool_get_config(zhp, &oldconfig);
1500 
1501 	if (cb->cb_iteration == 1)
1502 		oldconfig = NULL;
1503 
1504 	verify(nvlist_lookup_nvlist(newconfig, ZPOOL_CONFIG_VDEV_TREE,
1505 	    &newnvroot) == 0);
1506 
1507 	if (oldconfig == NULL)
1508 		oldnvroot = NULL;
1509 	else
1510 		verify(nvlist_lookup_nvlist(oldconfig, ZPOOL_CONFIG_VDEV_TREE,
1511 		    &oldnvroot) == 0);
1512 
1513 	/*
1514 	 * Print out the statistics for the pool.
1515 	 */
1516 	print_vdev_stats(zhp, zpool_get_name(zhp), oldnvroot, newnvroot, cb, 0);
1517 
1518 	if (cb->cb_verbose)
1519 		print_iostat_separator(cb);
1520 
1521 	return (0);
1522 }
1523 
1524 int
1525 get_namewidth(zpool_handle_t *zhp, void *data)
1526 {
1527 	iostat_cbdata_t *cb = data;
1528 	nvlist_t *config, *nvroot;
1529 
1530 	if ((config = zpool_get_config(zhp, NULL)) != NULL) {
1531 		verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
1532 		    &nvroot) == 0);
1533 		if (!cb->cb_verbose)
1534 			cb->cb_namewidth = strlen(zpool_get_name(zhp));
1535 		else
1536 			cb->cb_namewidth = max_width(zhp, nvroot, 0, 0);
1537 	}
1538 
1539 	/*
1540 	 * The width must fall into the range [10,38].  The upper limit is the
1541 	 * maximum we can have and still fit in 80 columns.
1542 	 */
1543 	if (cb->cb_namewidth < 10)
1544 		cb->cb_namewidth = 10;
1545 	if (cb->cb_namewidth > 38)
1546 		cb->cb_namewidth = 38;
1547 
1548 	return (0);
1549 }
1550 
1551 /*
1552  * zpool iostat [-v] [pool] ... [interval [count]]
1553  *
1554  *	-v	Display statistics for individual vdevs
1555  *
1556  * This command can be tricky because we want to be able to deal with pool
1557  * creation/destruction as well as vdev configuration changes.  The bulk of this
1558  * processing is handled by the pool_list_* routines in zpool_iter.c.  We rely
1559  * on pool_list_update() to detect the addition of new pools.  Configuration
1560  * changes are all handled within libzfs.
1561  */
1562 int
1563 zpool_do_iostat(int argc, char **argv)
1564 {
1565 	int c;
1566 	int ret;
1567 	int npools;
1568 	unsigned long interval = 0, count = 0;
1569 	zpool_list_t *list;
1570 	boolean_t verbose = B_FALSE;
1571 	iostat_cbdata_t cb;
1572 
1573 	/* check options */
1574 	while ((c = getopt(argc, argv, "v")) != -1) {
1575 		switch (c) {
1576 		case 'v':
1577 			verbose = B_TRUE;
1578 			break;
1579 		case '?':
1580 			(void) fprintf(stderr, gettext("invalid option '%c'\n"),
1581 			    optopt);
1582 			usage(B_FALSE);
1583 		}
1584 	}
1585 
1586 	argc -= optind;
1587 	argv += optind;
1588 
1589 	/*
1590 	 * Determine if the last argument is an integer or a pool name
1591 	 */
1592 	if (argc > 0 && isdigit(argv[argc - 1][0])) {
1593 		char *end;
1594 
1595 		errno = 0;
1596 		interval = strtoul(argv[argc - 1], &end, 10);
1597 
1598 		if (*end == '\0' && errno == 0) {
1599 			if (interval == 0) {
1600 				(void) fprintf(stderr, gettext("interval "
1601 				    "cannot be zero\n"));
1602 				usage(B_FALSE);
1603 			}
1604 
1605 			/*
1606 			 * Ignore the last parameter
1607 			 */
1608 			argc--;
1609 		} else {
1610 			/*
1611 			 * If this is not a valid number, just plow on.  The
1612 			 * user will get a more informative error message later
1613 			 * on.
1614 			 */
1615 			interval = 0;
1616 		}
1617 	}
1618 
1619 	/*
1620 	 * If the last argument is also an integer, then we have both a count
1621 	 * and an integer.
1622 	 */
1623 	if (argc > 0 && isdigit(argv[argc - 1][0])) {
1624 		char *end;
1625 
1626 		errno = 0;
1627 		count = interval;
1628 		interval = strtoul(argv[argc - 1], &end, 10);
1629 
1630 		if (*end == '\0' && errno == 0) {
1631 			if (interval == 0) {
1632 				(void) fprintf(stderr, gettext("interval "
1633 				    "cannot be zero\n"));
1634 				usage(B_FALSE);
1635 			}
1636 
1637 			/*
1638 			 * Ignore the last parameter
1639 			 */
1640 			argc--;
1641 		} else {
1642 			interval = 0;
1643 		}
1644 	}
1645 
1646 	/*
1647 	 * Construct the list of all interesting pools.
1648 	 */
1649 	ret = 0;
1650 	if ((list = pool_list_get(argc, argv, &ret)) == NULL)
1651 		return (1);
1652 
1653 	if (pool_list_count(list) == 0 && argc != 0) {
1654 		pool_list_free(list);
1655 		return (1);
1656 	}
1657 
1658 	if (pool_list_count(list) == 0 && interval == 0) {
1659 		pool_list_free(list);
1660 		(void) fprintf(stderr, gettext("no pools available\n"));
1661 		return (1);
1662 	}
1663 
1664 	/*
1665 	 * Enter the main iostat loop.
1666 	 */
1667 	cb.cb_list = list;
1668 	cb.cb_verbose = verbose;
1669 	cb.cb_iteration = 0;
1670 	cb.cb_namewidth = 0;
1671 
1672 	for (;;) {
1673 		pool_list_update(list);
1674 
1675 		if ((npools = pool_list_count(list)) == 0)
1676 			break;
1677 
1678 		/*
1679 		 * Refresh all statistics.  This is done as an explicit step
1680 		 * before calculating the maximum name width, so that any
1681 		 * configuration changes are properly accounted for.
1682 		 */
1683 		(void) pool_list_iter(list, B_FALSE, refresh_iostat, &cb);
1684 
1685 		/*
1686 		 * Iterate over all pools to determine the maximum width
1687 		 * for the pool / device name column across all pools.
1688 		 */
1689 		cb.cb_namewidth = 0;
1690 		(void) pool_list_iter(list, B_FALSE, get_namewidth, &cb);
1691 
1692 		/*
1693 		 * If it's the first time, or verbose mode, print the header.
1694 		 */
1695 		if (++cb.cb_iteration == 1 || verbose)
1696 			print_iostat_header(&cb);
1697 
1698 		(void) pool_list_iter(list, B_FALSE, print_iostat, &cb);
1699 
1700 		/*
1701 		 * If there's more than one pool, and we're not in verbose mode
1702 		 * (which prints a separator for us), then print a separator.
1703 		 */
1704 		if (npools > 1 && !verbose)
1705 			print_iostat_separator(&cb);
1706 
1707 		if (verbose)
1708 			(void) printf("\n");
1709 
1710 		if (interval == 0)
1711 			break;
1712 
1713 		if (count != 0 && --count == 0)
1714 			break;
1715 
1716 		(void) sleep(interval);
1717 	}
1718 
1719 	pool_list_free(list);
1720 
1721 	return (ret);
1722 }
1723 
1724 typedef struct list_cbdata {
1725 	boolean_t	cb_scripted;
1726 	boolean_t	cb_first;
1727 	int		cb_fields[MAX_FIELDS];
1728 	int		cb_fieldcount;
1729 } list_cbdata_t;
1730 
1731 /*
1732  * Given a list of columns to display, output appropriate headers for each one.
1733  */
1734 void
1735 print_header(int *fields, size_t count)
1736 {
1737 	int i;
1738 	column_def_t *col;
1739 	const char *fmt;
1740 
1741 	for (i = 0; i < count; i++) {
1742 		col = &column_table[fields[i]];
1743 		if (i != 0)
1744 			(void) printf("  ");
1745 		if (col->cd_justify == left_justify)
1746 			fmt = "%-*s";
1747 		else
1748 			fmt = "%*s";
1749 
1750 		(void) printf(fmt, i == count - 1 ? strlen(col->cd_title) :
1751 		    col->cd_width, col->cd_title);
1752 	}
1753 
1754 	(void) printf("\n");
1755 }
1756 
1757 int
1758 list_callback(zpool_handle_t *zhp, void *data)
1759 {
1760 	list_cbdata_t *cbp = data;
1761 	nvlist_t *config;
1762 	int i;
1763 	char buf[ZPOOL_MAXNAMELEN];
1764 	uint64_t total;
1765 	uint64_t used;
1766 	const char *fmt;
1767 	column_def_t *col;
1768 
1769 	if (cbp->cb_first) {
1770 		if (!cbp->cb_scripted)
1771 			print_header(cbp->cb_fields, cbp->cb_fieldcount);
1772 		cbp->cb_first = B_FALSE;
1773 	}
1774 
1775 	if (zpool_get_state(zhp) == POOL_STATE_UNAVAIL) {
1776 		config = NULL;
1777 	} else {
1778 		config = zpool_get_config(zhp, NULL);
1779 		total = zpool_get_space_total(zhp);
1780 		used = zpool_get_space_used(zhp);
1781 	}
1782 
1783 	for (i = 0; i < cbp->cb_fieldcount; i++) {
1784 		if (i != 0) {
1785 			if (cbp->cb_scripted)
1786 				(void) printf("\t");
1787 			else
1788 				(void) printf("  ");
1789 		}
1790 
1791 		col = &column_table[cbp->cb_fields[i]];
1792 
1793 		switch (cbp->cb_fields[i]) {
1794 		case ZPOOL_FIELD_NAME:
1795 			(void) strlcpy(buf, zpool_get_name(zhp), sizeof (buf));
1796 			break;
1797 
1798 		case ZPOOL_FIELD_SIZE:
1799 			if (config == NULL)
1800 				(void) strlcpy(buf, "-", sizeof (buf));
1801 			else
1802 				zfs_nicenum(total, buf, sizeof (buf));
1803 			break;
1804 
1805 		case ZPOOL_FIELD_USED:
1806 			if (config == NULL)
1807 				(void) strlcpy(buf, "-", sizeof (buf));
1808 			else
1809 				zfs_nicenum(used, buf, sizeof (buf));
1810 			break;
1811 
1812 		case ZPOOL_FIELD_AVAILABLE:
1813 			if (config == NULL)
1814 				(void) strlcpy(buf, "-", sizeof (buf));
1815 			else
1816 				zfs_nicenum(total - used, buf, sizeof (buf));
1817 			break;
1818 
1819 		case ZPOOL_FIELD_CAPACITY:
1820 			if (config == NULL) {
1821 				(void) strlcpy(buf, "-", sizeof (buf));
1822 			} else {
1823 				uint64_t capacity = (total == 0 ? 0 :
1824 				    (used * 100 / total));
1825 				(void) snprintf(buf, sizeof (buf), "%llu%%",
1826 				    capacity);
1827 			}
1828 			break;
1829 
1830 		case ZPOOL_FIELD_HEALTH:
1831 			if (config == NULL) {
1832 				(void) strlcpy(buf, "FAULTED", sizeof (buf));
1833 			} else {
1834 				nvlist_t *nvroot;
1835 				vdev_stat_t *vs;
1836 				uint_t vsc;
1837 
1838 				verify(nvlist_lookup_nvlist(config,
1839 				    ZPOOL_CONFIG_VDEV_TREE, &nvroot) == 0);
1840 				verify(nvlist_lookup_uint64_array(nvroot,
1841 				    ZPOOL_CONFIG_STATS, (uint64_t **)&vs,
1842 				    &vsc) == 0);
1843 				(void) strlcpy(buf, state_to_name(vs),
1844 				    sizeof (buf));
1845 			}
1846 			break;
1847 
1848 		case ZPOOL_FIELD_ROOT:
1849 			if (config == NULL)
1850 				(void) strlcpy(buf, "-", sizeof (buf));
1851 			else if (zpool_get_root(zhp, buf, sizeof (buf)) != 0)
1852 				(void) strlcpy(buf, "-", sizeof (buf));
1853 			break;
1854 		}
1855 
1856 		if (cbp->cb_scripted)
1857 			(void) printf("%s", buf);
1858 		else {
1859 			if (col->cd_justify == left_justify)
1860 				fmt = "%-*s";
1861 			else
1862 				fmt = "%*s";
1863 
1864 			(void) printf(fmt, i == cbp->cb_fieldcount - 1 ?
1865 			    strlen(buf) : col->cd_width, buf);
1866 		}
1867 	}
1868 
1869 	(void) printf("\n");
1870 
1871 	return (0);
1872 }
1873 
1874 /*
1875  * zpool list [-H] [-o field[,field]*] [pool] ...
1876  *
1877  *	-H	Scripted mode.  Don't display headers, and separate fields by
1878  *		a single tab.
1879  *	-o	List of fields to display.  Defaults to all fields, or
1880  *		"name,size,used,available,capacity,health,root"
1881  *
1882  * List all pools in the system, whether or not they're healthy.  Output space
1883  * statistics for each one, as well as health status summary.
1884  */
1885 int
1886 zpool_do_list(int argc, char **argv)
1887 {
1888 	int c;
1889 	int ret;
1890 	list_cbdata_t cb = { 0 };
1891 	static char default_fields[] =
1892 	    "name,size,used,available,capacity,health,root";
1893 	char *fields = default_fields;
1894 	char *value;
1895 
1896 	/* check options */
1897 	while ((c = getopt(argc, argv, ":Ho:")) != -1) {
1898 		switch (c) {
1899 		case 'H':
1900 			cb.cb_scripted = B_TRUE;
1901 			break;
1902 		case 'o':
1903 			fields = optarg;
1904 			break;
1905 		case ':':
1906 			(void) fprintf(stderr, gettext("missing argument for "
1907 			    "'%c' option\n"), optopt);
1908 			usage(B_FALSE);
1909 			break;
1910 		case '?':
1911 			(void) fprintf(stderr, gettext("invalid option '%c'\n"),
1912 			    optopt);
1913 			usage(B_FALSE);
1914 		}
1915 	}
1916 
1917 	argc -= optind;
1918 	argv += optind;
1919 
1920 	while (*fields != '\0') {
1921 		if (cb.cb_fieldcount == MAX_FIELDS) {
1922 			(void) fprintf(stderr, gettext("too many "
1923 			    "properties given to -o option\n"));
1924 			usage(B_FALSE);
1925 		}
1926 
1927 		if ((cb.cb_fields[cb.cb_fieldcount] = getsubopt(&fields,
1928 		    column_subopts, &value)) == -1) {
1929 			(void) fprintf(stderr, gettext("invalid property "
1930 			    "'%s'\n"), value);
1931 			usage(B_FALSE);
1932 		}
1933 
1934 		cb.cb_fieldcount++;
1935 	}
1936 
1937 
1938 	cb.cb_first = B_TRUE;
1939 
1940 	ret = for_each_pool(argc, argv, B_TRUE, list_callback, &cb);
1941 
1942 	if (argc == 0 && cb.cb_first) {
1943 		(void) printf(gettext("no pools available\n"));
1944 		return (0);
1945 	}
1946 
1947 	return (ret);
1948 }
1949 
1950 static nvlist_t *
1951 zpool_get_vdev_by_name(nvlist_t *nv, char *name)
1952 {
1953 	nvlist_t **child;
1954 	uint_t c, children;
1955 	nvlist_t *match;
1956 	char *path;
1957 
1958 	if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
1959 	    &child, &children) != 0) {
1960 		verify(nvlist_lookup_string(nv, ZPOOL_CONFIG_PATH, &path) == 0);
1961 		if (strncmp(name, "/dev/dsk/", 9) == 0)
1962 			name += 9;
1963 		if (strncmp(path, "/dev/dsk/", 9) == 0)
1964 			path += 9;
1965 		if (strcmp(name, path) == 0)
1966 			return (nv);
1967 		return (NULL);
1968 	}
1969 
1970 	for (c = 0; c < children; c++)
1971 		if ((match = zpool_get_vdev_by_name(child[c], name)) != NULL)
1972 			return (match);
1973 
1974 	return (NULL);
1975 }
1976 
1977 static int
1978 zpool_do_attach_or_replace(int argc, char **argv, int replacing)
1979 {
1980 	boolean_t force = B_FALSE;
1981 	int c;
1982 	nvlist_t *nvroot;
1983 	char *poolname, *old_disk, *new_disk;
1984 	zpool_handle_t *zhp;
1985 	nvlist_t *config;
1986 	int ret;
1987 
1988 	/* check options */
1989 	while ((c = getopt(argc, argv, "f")) != -1) {
1990 		switch (c) {
1991 		case 'f':
1992 			force = B_TRUE;
1993 			break;
1994 		case '?':
1995 			(void) fprintf(stderr, gettext("invalid option '%c'\n"),
1996 			    optopt);
1997 			usage(B_FALSE);
1998 		}
1999 	}
2000 
2001 	argc -= optind;
2002 	argv += optind;
2003 
2004 	/* get pool name and check number of arguments */
2005 	if (argc < 1) {
2006 		(void) fprintf(stderr, gettext("missing pool name argument\n"));
2007 		usage(B_FALSE);
2008 	}
2009 
2010 	poolname = argv[0];
2011 
2012 	if (argc < 2) {
2013 		(void) fprintf(stderr,
2014 		    gettext("missing <device> specification\n"));
2015 		usage(B_FALSE);
2016 	}
2017 
2018 	old_disk = argv[1];
2019 
2020 	if (argc < 3) {
2021 		if (!replacing) {
2022 			(void) fprintf(stderr,
2023 			    gettext("missing <new_device> specification\n"));
2024 			usage(B_FALSE);
2025 		}
2026 		new_disk = old_disk;
2027 		argc -= 1;
2028 		argv += 1;
2029 	} else {
2030 		new_disk = argv[2];
2031 		argc -= 2;
2032 		argv += 2;
2033 	}
2034 
2035 	if (argc > 1) {
2036 		(void) fprintf(stderr, gettext("too many arguments\n"));
2037 		usage(B_FALSE);
2038 	}
2039 
2040 	if ((zhp = zpool_open(g_zfs, poolname)) == NULL)
2041 		return (1);
2042 
2043 	if ((config = zpool_get_config(zhp, NULL)) == NULL) {
2044 		(void) fprintf(stderr, gettext("pool '%s' is unavailable\n"),
2045 		    poolname);
2046 		zpool_close(zhp);
2047 		return (1);
2048 	}
2049 
2050 	nvroot = make_root_vdev(config, force, B_FALSE, replacing, argc, argv);
2051 	if (nvroot == NULL) {
2052 		zpool_close(zhp);
2053 		return (1);
2054 	}
2055 
2056 	ret = zpool_vdev_attach(zhp, old_disk, new_disk, nvroot, replacing);
2057 
2058 	nvlist_free(nvroot);
2059 	zpool_close(zhp);
2060 
2061 	return (ret);
2062 }
2063 
2064 /*
2065  * zpool replace [-f] <pool> <device> <new_device>
2066  *
2067  *	-f	Force attach, even if <new_device> appears to be in use.
2068  *
2069  * Replace <device> with <new_device>.
2070  */
2071 /* ARGSUSED */
2072 int
2073 zpool_do_replace(int argc, char **argv)
2074 {
2075 	return (zpool_do_attach_or_replace(argc, argv, B_TRUE));
2076 }
2077 
2078 /*
2079  * zpool attach [-f] <pool> <device> <new_device>
2080  *
2081  *	-f	Force attach, even if <new_device> appears to be in use.
2082  *
2083  * Attach <new_device> to the mirror containing <device>.  If <device> is not
2084  * part of a mirror, then <device> will be transformed into a mirror of
2085  * <device> and <new_device>.  In either case, <new_device> will begin life
2086  * with a DTL of [0, now], and will immediately begin to resilver itself.
2087  */
2088 int
2089 zpool_do_attach(int argc, char **argv)
2090 {
2091 	return (zpool_do_attach_or_replace(argc, argv, B_FALSE));
2092 }
2093 
2094 /*
2095  * zpool detach [-f] <pool> <device>
2096  *
2097  *	-f	Force detach of <device>, even if DTLs argue against it
2098  *		(not supported yet)
2099  *
2100  * Detach a device from a mirror.  The operation will be refused if <device>
2101  * is the last device in the mirror, or if the DTLs indicate that this device
2102  * has the only valid copy of some data.
2103  */
2104 /* ARGSUSED */
2105 int
2106 zpool_do_detach(int argc, char **argv)
2107 {
2108 	int c;
2109 	char *poolname, *path;
2110 	zpool_handle_t *zhp;
2111 	int ret;
2112 
2113 	/* check options */
2114 	while ((c = getopt(argc, argv, "f")) != -1) {
2115 		switch (c) {
2116 		case 'f':
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 	/* get pool name and check number of arguments */
2128 	if (argc < 1) {
2129 		(void) fprintf(stderr, gettext("missing pool name argument\n"));
2130 		usage(B_FALSE);
2131 	}
2132 
2133 	if (argc < 2) {
2134 		(void) fprintf(stderr,
2135 		    gettext("missing <device> specification\n"));
2136 		usage(B_FALSE);
2137 	}
2138 
2139 	poolname = argv[0];
2140 	path = argv[1];
2141 
2142 	if ((zhp = zpool_open(g_zfs, poolname)) == NULL)
2143 		return (1);
2144 
2145 	ret = zpool_vdev_detach(zhp, path);
2146 
2147 	zpool_close(zhp);
2148 
2149 	return (ret);
2150 }
2151 
2152 /*
2153  * zpool online <pool> <device> ...
2154  */
2155 /* ARGSUSED */
2156 int
2157 zpool_do_online(int argc, char **argv)
2158 {
2159 	int c, i;
2160 	char *poolname;
2161 	zpool_handle_t *zhp;
2162 	int ret = 0;
2163 
2164 	/* check options */
2165 	while ((c = getopt(argc, argv, "t")) != -1) {
2166 		switch (c) {
2167 		case 't':
2168 		case '?':
2169 			(void) fprintf(stderr, gettext("invalid option '%c'\n"),
2170 			    optopt);
2171 			usage(B_FALSE);
2172 		}
2173 	}
2174 
2175 	argc -= optind;
2176 	argv += optind;
2177 
2178 	/* get pool name and check number of arguments */
2179 	if (argc < 1) {
2180 		(void) fprintf(stderr, gettext("missing pool name\n"));
2181 		usage(B_FALSE);
2182 	}
2183 	if (argc < 2) {
2184 		(void) fprintf(stderr, gettext("missing device name\n"));
2185 		usage(B_FALSE);
2186 	}
2187 
2188 	poolname = argv[0];
2189 
2190 	if ((zhp = zpool_open(g_zfs, poolname)) == NULL)
2191 		return (1);
2192 
2193 	for (i = 1; i < argc; i++)
2194 		if (zpool_vdev_online(zhp, argv[i]) == 0)
2195 			(void) printf(gettext("Bringing device %s online\n"),
2196 			    argv[i]);
2197 		else
2198 			ret = 1;
2199 
2200 	zpool_close(zhp);
2201 
2202 	return (ret);
2203 }
2204 
2205 /*
2206  * zpool offline [-ft] <pool> <device> ...
2207  *
2208  *	-f	Force the device into the offline state, even if doing
2209  *		so would appear to compromise pool availability.
2210  *		(not supported yet)
2211  *
2212  *	-t	Only take the device off-line temporarily.  The offline
2213  *		state will not be persistent across reboots.
2214  */
2215 /* ARGSUSED */
2216 int
2217 zpool_do_offline(int argc, char **argv)
2218 {
2219 	int c, i;
2220 	char *poolname;
2221 	zpool_handle_t *zhp;
2222 	int ret = 0;
2223 	boolean_t istmp = B_FALSE;
2224 
2225 	/* check options */
2226 	while ((c = getopt(argc, argv, "ft")) != -1) {
2227 		switch (c) {
2228 		case 't':
2229 			istmp = B_TRUE;
2230 			break;
2231 		case 'f':
2232 		case '?':
2233 			(void) fprintf(stderr, gettext("invalid option '%c'\n"),
2234 			    optopt);
2235 			usage(B_FALSE);
2236 		}
2237 	}
2238 
2239 	argc -= optind;
2240 	argv += optind;
2241 
2242 	/* get pool name and check number of arguments */
2243 	if (argc < 1) {
2244 		(void) fprintf(stderr, gettext("missing pool name\n"));
2245 		usage(B_FALSE);
2246 	}
2247 	if (argc < 2) {
2248 		(void) fprintf(stderr, gettext("missing device name\n"));
2249 		usage(B_FALSE);
2250 	}
2251 
2252 	poolname = argv[0];
2253 
2254 	if ((zhp = zpool_open(g_zfs, poolname)) == NULL)
2255 		return (1);
2256 
2257 	for (i = 1; i < argc; i++)
2258 		if (zpool_vdev_offline(zhp, argv[i], istmp) == 0)
2259 			(void) printf(gettext("Bringing device %s offline\n"),
2260 			    argv[i]);
2261 		else
2262 			ret = 1;
2263 
2264 	zpool_close(zhp);
2265 
2266 	return (ret);
2267 }
2268 
2269 /*
2270  * zpool clear <pool> [device]
2271  *
2272  * Clear all errors associated with a pool or a particular device.
2273  */
2274 int
2275 zpool_do_clear(int argc, char **argv)
2276 {
2277 	int ret = 0;
2278 	zpool_handle_t *zhp;
2279 	char *pool, *device;
2280 
2281 	if (argc < 2) {
2282 		(void) fprintf(stderr, gettext("missing pool name\n"));
2283 		usage(B_FALSE);
2284 	}
2285 
2286 	if (argc > 3) {
2287 		(void) fprintf(stderr, gettext("too many arguments\n"));
2288 		usage(B_FALSE);
2289 	}
2290 
2291 	pool = argv[1];
2292 	device = argc == 3 ? argv[2] : NULL;
2293 
2294 	if ((zhp = zpool_open(g_zfs, pool)) == NULL)
2295 		return (1);
2296 
2297 	if (zpool_clear(zhp, device) != 0)
2298 		ret = 1;
2299 
2300 	zpool_close(zhp);
2301 
2302 	return (ret);
2303 }
2304 
2305 typedef struct scrub_cbdata {
2306 	int	cb_type;
2307 } scrub_cbdata_t;
2308 
2309 int
2310 scrub_callback(zpool_handle_t *zhp, void *data)
2311 {
2312 	scrub_cbdata_t *cb = data;
2313 
2314 	/*
2315 	 * Ignore faulted pools.
2316 	 */
2317 	if (zpool_get_state(zhp) == POOL_STATE_UNAVAIL) {
2318 		(void) fprintf(stderr, gettext("cannot scrub '%s': pool is "
2319 		    "currently unavailable\n"), zpool_get_name(zhp));
2320 		return (1);
2321 	}
2322 
2323 	return (zpool_scrub(zhp, cb->cb_type) != 0);
2324 }
2325 
2326 /*
2327  * zpool scrub [-s] <pool> ...
2328  *
2329  *	-s	Stop.  Stops any in-progress scrub.
2330  */
2331 int
2332 zpool_do_scrub(int argc, char **argv)
2333 {
2334 	int c;
2335 	scrub_cbdata_t cb;
2336 
2337 	cb.cb_type = POOL_SCRUB_EVERYTHING;
2338 
2339 	/* check options */
2340 	while ((c = getopt(argc, argv, "s")) != -1) {
2341 		switch (c) {
2342 		case 's':
2343 			cb.cb_type = POOL_SCRUB_NONE;
2344 			break;
2345 		case '?':
2346 			(void) fprintf(stderr, gettext("invalid option '%c'\n"),
2347 			    optopt);
2348 			usage(B_FALSE);
2349 		}
2350 	}
2351 
2352 	argc -= optind;
2353 	argv += optind;
2354 
2355 	if (argc < 1) {
2356 		(void) fprintf(stderr, gettext("missing pool name argument\n"));
2357 		usage(B_FALSE);
2358 	}
2359 
2360 	return (for_each_pool(argc, argv, B_TRUE, scrub_callback, &cb));
2361 }
2362 
2363 typedef struct status_cbdata {
2364 	int		cb_count;
2365 	boolean_t	cb_verbose;
2366 	boolean_t	cb_explain;
2367 	boolean_t	cb_first;
2368 } status_cbdata_t;
2369 
2370 /*
2371  * Print out detailed scrub status.
2372  */
2373 void
2374 print_scrub_status(nvlist_t *nvroot)
2375 {
2376 	vdev_stat_t *vs;
2377 	uint_t vsc;
2378 	time_t start, end, now;
2379 	double fraction_done;
2380 	uint64_t examined, total, minutes_left;
2381 	char *scrub_type;
2382 
2383 	verify(nvlist_lookup_uint64_array(nvroot, ZPOOL_CONFIG_STATS,
2384 	    (uint64_t **)&vs, &vsc) == 0);
2385 
2386 	/*
2387 	 * If there's never been a scrub, there's not much to say.
2388 	 */
2389 	if (vs->vs_scrub_end == 0 && vs->vs_scrub_type == POOL_SCRUB_NONE) {
2390 		(void) printf(gettext("none requested\n"));
2391 		return;
2392 	}
2393 
2394 	scrub_type = (vs->vs_scrub_type == POOL_SCRUB_RESILVER) ?
2395 	    "resilver" : "scrub";
2396 
2397 	start = vs->vs_scrub_start;
2398 	end = vs->vs_scrub_end;
2399 	now = time(NULL);
2400 	examined = vs->vs_scrub_examined;
2401 	total = vs->vs_alloc;
2402 
2403 	if (end != 0) {
2404 		(void) printf(gettext("%s %s with %llu errors on %s"),
2405 		    scrub_type, vs->vs_scrub_complete ? "completed" : "stopped",
2406 		    (u_longlong_t)vs->vs_scrub_errors, ctime(&end));
2407 		return;
2408 	}
2409 
2410 	if (examined == 0)
2411 		examined = 1;
2412 	if (examined > total)
2413 		total = examined;
2414 
2415 	fraction_done = (double)examined / total;
2416 	minutes_left = (uint64_t)((now - start) *
2417 	    (1 - fraction_done) / fraction_done / 60);
2418 
2419 	(void) printf(gettext("%s in progress, %.2f%% done, %lluh%um to go\n"),
2420 	    scrub_type, 100 * fraction_done,
2421 	    (u_longlong_t)(minutes_left / 60), (uint_t)(minutes_left % 60));
2422 }
2423 
2424 typedef struct spare_cbdata {
2425 	uint64_t	cb_guid;
2426 	zpool_handle_t	*cb_zhp;
2427 } spare_cbdata_t;
2428 
2429 static boolean_t
2430 find_vdev(nvlist_t *nv, uint64_t search)
2431 {
2432 	uint64_t guid;
2433 	nvlist_t **child;
2434 	uint_t c, children;
2435 
2436 	if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_GUID, &guid) == 0 &&
2437 	    search == guid)
2438 		return (B_TRUE);
2439 
2440 	if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
2441 	    &child, &children) == 0) {
2442 		for (c = 0; c < children; c++)
2443 			if (find_vdev(child[c], search))
2444 				return (B_TRUE);
2445 	}
2446 
2447 	return (B_FALSE);
2448 }
2449 
2450 static int
2451 find_spare(zpool_handle_t *zhp, void *data)
2452 {
2453 	spare_cbdata_t *cbp = data;
2454 	nvlist_t *config, *nvroot;
2455 
2456 	config = zpool_get_config(zhp, NULL);
2457 	verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
2458 	    &nvroot) == 0);
2459 
2460 	if (find_vdev(nvroot, cbp->cb_guid)) {
2461 		cbp->cb_zhp = zhp;
2462 		return (1);
2463 	}
2464 
2465 	zpool_close(zhp);
2466 	return (0);
2467 }
2468 
2469 /*
2470  * Print out configuration state as requested by status_callback.
2471  */
2472 void
2473 print_status_config(zpool_handle_t *zhp, const char *name, nvlist_t *nv,
2474     int namewidth, int depth, boolean_t isspare)
2475 {
2476 	nvlist_t **child;
2477 	uint_t c, children;
2478 	vdev_stat_t *vs;
2479 	char rbuf[6], wbuf[6], cbuf[6], repaired[7];
2480 	char *vname;
2481 	uint64_t notpresent;
2482 	spare_cbdata_t cb;
2483 	const char *state;
2484 
2485 	verify(nvlist_lookup_uint64_array(nv, ZPOOL_CONFIG_STATS,
2486 	    (uint64_t **)&vs, &c) == 0);
2487 
2488 	if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
2489 	    &child, &children) != 0)
2490 		children = 0;
2491 
2492 	state = state_to_name(vs);
2493 	if (isspare) {
2494 		/*
2495 		 * For hot spares, we use the terms 'INUSE' and 'AVAILABLE' for
2496 		 * online drives.
2497 		 */
2498 		if (vs->vs_aux == VDEV_AUX_SPARED)
2499 			state = "INUSE";
2500 		else if (vs->vs_state == VDEV_STATE_HEALTHY)
2501 			state = "AVAIL";
2502 	}
2503 
2504 	(void) printf("\t%*s%-*s  %-8s", depth, "", namewidth - depth,
2505 	    name, state);
2506 
2507 	if (!isspare) {
2508 		zfs_nicenum(vs->vs_read_errors, rbuf, sizeof (rbuf));
2509 		zfs_nicenum(vs->vs_write_errors, wbuf, sizeof (wbuf));
2510 		zfs_nicenum(vs->vs_checksum_errors, cbuf, sizeof (cbuf));
2511 		(void) printf(" %5s %5s %5s", rbuf, wbuf, cbuf);
2512 	}
2513 
2514 	if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_NOT_PRESENT,
2515 	    &notpresent) == 0) {
2516 		char *path;
2517 		verify(nvlist_lookup_string(nv, ZPOOL_CONFIG_PATH, &path) == 0);
2518 		(void) printf("  was %s", path);
2519 	} else if (vs->vs_aux != 0) {
2520 		(void) printf("  ");
2521 
2522 		switch (vs->vs_aux) {
2523 		case VDEV_AUX_OPEN_FAILED:
2524 			(void) printf(gettext("cannot open"));
2525 			break;
2526 
2527 		case VDEV_AUX_BAD_GUID_SUM:
2528 			(void) printf(gettext("missing device"));
2529 			break;
2530 
2531 		case VDEV_AUX_NO_REPLICAS:
2532 			(void) printf(gettext("insufficient replicas"));
2533 			break;
2534 
2535 		case VDEV_AUX_VERSION_NEWER:
2536 			(void) printf(gettext("newer version"));
2537 			break;
2538 
2539 		case VDEV_AUX_SPARED:
2540 			verify(nvlist_lookup_uint64(nv, ZPOOL_CONFIG_GUID,
2541 			    &cb.cb_guid) == 0);
2542 			if (zpool_iter(g_zfs, find_spare, &cb) == 1) {
2543 				if (strcmp(zpool_get_name(cb.cb_zhp),
2544 				    zpool_get_name(zhp)) == 0)
2545 					(void) printf(gettext("currently in "
2546 					    "use"));
2547 				else
2548 					(void) printf(gettext("in use by "
2549 					    "pool '%s'"),
2550 					    zpool_get_name(cb.cb_zhp));
2551 				zpool_close(cb.cb_zhp);
2552 			} else {
2553 				(void) printf(gettext("currently in use"));
2554 			}
2555 			break;
2556 
2557 		default:
2558 			(void) printf(gettext("corrupted data"));
2559 			break;
2560 		}
2561 	} else if (vs->vs_scrub_repaired != 0 && children == 0) {
2562 		/*
2563 		 * Report bytes resilvered/repaired on leaf devices.
2564 		 */
2565 		zfs_nicenum(vs->vs_scrub_repaired, repaired, sizeof (repaired));
2566 		(void) printf(gettext("  %s %s"), repaired,
2567 		    (vs->vs_scrub_type == POOL_SCRUB_RESILVER) ?
2568 		    "resilvered" : "repaired");
2569 	}
2570 
2571 	(void) printf("\n");
2572 
2573 	for (c = 0; c < children; c++) {
2574 		vname = zpool_vdev_name(g_zfs, zhp, child[c]);
2575 		print_status_config(zhp, vname, child[c],
2576 		    namewidth, depth + 2, isspare);
2577 		free(vname);
2578 	}
2579 }
2580 
2581 static void
2582 print_error_log(zpool_handle_t *zhp)
2583 {
2584 	nvlist_t **log;
2585 	size_t nelem;
2586 	size_t maxdsname = sizeof ("DATASET") - 1;
2587 	size_t maxobjname = sizeof ("OBJECT") - 1;
2588 	int i;
2589 	nvlist_t *nv;
2590 	size_t len;
2591 	char *dsname, *objname, *range;
2592 
2593 	if (zpool_get_errlog(zhp, &log, &nelem) != 0) {
2594 		(void) printf("errors: List of errors unavailable "
2595 		    "(insufficient privileges)\n");
2596 		return;
2597 	}
2598 
2599 	for (i = 0; i < nelem; i++) {
2600 		nv = log[i];
2601 
2602 		verify(nvlist_lookup_string(nv, ZPOOL_ERR_DATASET,
2603 		    &dsname) == 0);
2604 		len = strlen(dsname);
2605 		if (len > maxdsname)
2606 			maxdsname = len;
2607 
2608 		verify(nvlist_lookup_string(nv, ZPOOL_ERR_OBJECT,
2609 		    &objname) == 0);
2610 		len = strlen(objname);
2611 		if (len > maxobjname)
2612 			maxobjname = len;
2613 	}
2614 
2615 	(void) printf("errors: The following persistent errors have been "
2616 	    "detected:\n\n");
2617 	(void) printf("%8s  %-*s  %-*s  %s\n", "", maxdsname, "DATASET",
2618 	    maxobjname, "OBJECT", "RANGE");
2619 
2620 	for (i = 0; i < nelem; i++) {
2621 		nv = log[i];
2622 
2623 		verify(nvlist_lookup_string(nv, ZPOOL_ERR_DATASET,
2624 		    &dsname) == 0);
2625 		verify(nvlist_lookup_string(nv, ZPOOL_ERR_OBJECT,
2626 		    &objname) == 0);
2627 		verify(nvlist_lookup_string(nv, ZPOOL_ERR_RANGE,
2628 		    &range) == 0);
2629 
2630 		(void) printf("%8s  %-*s  %-*s  %s\n", "", maxdsname,
2631 		    dsname, maxobjname, objname, range);
2632 	}
2633 }
2634 
2635 static void
2636 print_spares(zpool_handle_t *zhp, nvlist_t **spares, uint_t nspares,
2637     int namewidth)
2638 {
2639 	uint_t i;
2640 	char *name;
2641 
2642 	if (nspares == 0)
2643 		return;
2644 
2645 	(void) printf(gettext("\tspares\n"));
2646 
2647 	for (i = 0; i < nspares; i++) {
2648 		name = zpool_vdev_name(g_zfs, zhp, spares[i]);
2649 		print_status_config(zhp, name, spares[i],
2650 		    namewidth, 2, B_TRUE);
2651 		free(name);
2652 	}
2653 }
2654 
2655 /*
2656  * Display a summary of pool status.  Displays a summary such as:
2657  *
2658  *        pool: tank
2659  *	status: DEGRADED
2660  *	reason: One or more devices ...
2661  *         see: http://www.sun.com/msg/ZFS-xxxx-01
2662  *	config:
2663  *		mirror		DEGRADED
2664  *                c1t0d0	OK
2665  *                c2t0d0	UNAVAIL
2666  *
2667  * When given the '-v' option, we print out the complete config.  If the '-e'
2668  * option is specified, then we print out error rate information as well.
2669  */
2670 int
2671 status_callback(zpool_handle_t *zhp, void *data)
2672 {
2673 	status_cbdata_t *cbp = data;
2674 	nvlist_t *config, *nvroot;
2675 	char *msgid;
2676 	int reason;
2677 	char *health;
2678 
2679 	config = zpool_get_config(zhp, NULL);
2680 	reason = zpool_get_status(zhp, &msgid);
2681 
2682 	cbp->cb_count++;
2683 
2684 	/*
2685 	 * If we were given 'zpool status -x', only report those pools with
2686 	 * problems.
2687 	 */
2688 	if (reason == ZPOOL_STATUS_OK && cbp->cb_explain)
2689 		return (0);
2690 
2691 	if (cbp->cb_first)
2692 		cbp->cb_first = B_FALSE;
2693 	else
2694 		(void) printf("\n");
2695 
2696 	verify(nvlist_lookup_string(config, ZPOOL_CONFIG_POOL_HEALTH,
2697 	    &health) == 0);
2698 
2699 	(void) printf(gettext("  pool: %s\n"), zpool_get_name(zhp));
2700 	(void) printf(gettext(" state: %s\n"), health);
2701 
2702 	switch (reason) {
2703 	case ZPOOL_STATUS_MISSING_DEV_R:
2704 		(void) printf(gettext("status: One or more devices could not "
2705 		    "be opened.  Sufficient replicas exist for\n\tthe pool to "
2706 		    "continue functioning in a degraded state.\n"));
2707 		(void) printf(gettext("action: Attach the missing device and "
2708 		    "online it using 'zpool online'.\n"));
2709 		break;
2710 
2711 	case ZPOOL_STATUS_MISSING_DEV_NR:
2712 		(void) printf(gettext("status: One or more devices could not "
2713 		    "be opened.  There are insufficient\n\treplicas for the "
2714 		    "pool to continue functioning.\n"));
2715 		(void) printf(gettext("action: Attach the missing device and "
2716 		    "online it using 'zpool online'.\n"));
2717 		break;
2718 
2719 	case ZPOOL_STATUS_CORRUPT_LABEL_R:
2720 		(void) printf(gettext("status: One or more devices could not "
2721 		    "be used because the label is missing or\n\tinvalid.  "
2722 		    "Sufficient replicas exist for the pool to continue\n\t"
2723 		    "functioning in a degraded state.\n"));
2724 		(void) printf(gettext("action: Replace the device using "
2725 		    "'zpool replace'.\n"));
2726 		break;
2727 
2728 	case ZPOOL_STATUS_CORRUPT_LABEL_NR:
2729 		(void) printf(gettext("status: One or more devices could not "
2730 		    "be used because the the label is missing \n\tor invalid.  "
2731 		    "There are insufficient replicas for the pool to "
2732 		    "continue\n\tfunctioning.\n"));
2733 		(void) printf(gettext("action: Destroy and re-create the pool "
2734 		    "from a backup source.\n"));
2735 		break;
2736 
2737 	case ZPOOL_STATUS_FAILING_DEV:
2738 		(void) printf(gettext("status: One or more devices has "
2739 		    "experienced an unrecoverable error.  An\n\tattempt was "
2740 		    "made to correct the error.  Applications are "
2741 		    "unaffected.\n"));
2742 		(void) printf(gettext("action: Determine if the device needs "
2743 		    "to be replaced, and clear the errors\n\tusing "
2744 		    "'zpool clear' or replace the device with 'zpool "
2745 		    "replace'.\n"));
2746 		break;
2747 
2748 	case ZPOOL_STATUS_OFFLINE_DEV:
2749 		(void) printf(gettext("status: One or more devices has "
2750 		    "been taken offline by the adminstrator.\n\tSufficient "
2751 		    "replicas exist for the pool to continue functioning in "
2752 		    "a\n\tdegraded state.\n"));
2753 		(void) printf(gettext("action: Online the device using "
2754 		    "'zpool online' or replace the device with\n\t'zpool "
2755 		    "replace'.\n"));
2756 		break;
2757 
2758 	case ZPOOL_STATUS_RESILVERING:
2759 		(void) printf(gettext("status: One or more devices is "
2760 		    "currently being resilvered.  The pool will\n\tcontinue "
2761 		    "to function, possibly in a degraded state.\n"));
2762 		(void) printf(gettext("action: Wait for the resilver to "
2763 		    "complete.\n"));
2764 		break;
2765 
2766 	case ZPOOL_STATUS_CORRUPT_DATA:
2767 		(void) printf(gettext("status: One or more devices has "
2768 		    "experienced an error resulting in data\n\tcorruption.  "
2769 		    "Applications may be affected.\n"));
2770 		(void) printf(gettext("action: Restore the file in question "
2771 		    "if possible.  Otherwise restore the\n\tentire pool from "
2772 		    "backup.\n"));
2773 		break;
2774 
2775 	case ZPOOL_STATUS_CORRUPT_POOL:
2776 		(void) printf(gettext("status: The pool metadata is corrupted "
2777 		    "and the pool cannot be opened.\n"));
2778 		(void) printf(gettext("action: Destroy and re-create the pool "
2779 		    "from a backup source.\n"));
2780 		break;
2781 
2782 	case ZPOOL_STATUS_VERSION_OLDER:
2783 		(void) printf(gettext("status: The pool is formatted using an "
2784 		    "older on-disk format.  The pool can\n\tstill be used, but "
2785 		    "some features are unavailable.\n"));
2786 		(void) printf(gettext("action: Upgrade the pool using 'zpool "
2787 		    "upgrade'.  Once this is done, the\n\tpool will no longer "
2788 		    "be accessible on older software versions.\n"));
2789 		break;
2790 
2791 	case ZPOOL_STATUS_VERSION_NEWER:
2792 		(void) printf(gettext("status: The pool has been upgraded to a "
2793 		    "newer, incompatible on-disk version.\n\tThe pool cannot "
2794 		    "be accessed on this system.\n"));
2795 		(void) printf(gettext("action: Access the pool from a system "
2796 		    "running more recent software, or\n\trestore the pool from "
2797 		    "backup.\n"));
2798 		break;
2799 
2800 	default:
2801 		/*
2802 		 * The remaining errors can't actually be generated, yet.
2803 		 */
2804 		assert(reason == ZPOOL_STATUS_OK);
2805 	}
2806 
2807 	if (msgid != NULL)
2808 		(void) printf(gettext("   see: http://www.sun.com/msg/%s\n"),
2809 		    msgid);
2810 
2811 	if (config != NULL) {
2812 		int namewidth;
2813 		uint64_t nerr;
2814 		size_t realerr;
2815 		nvlist_t **spares;
2816 		uint_t nspares;
2817 
2818 		verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
2819 		    &nvroot) == 0);
2820 
2821 		(void) printf(gettext(" scrub: "));
2822 		print_scrub_status(nvroot);
2823 
2824 		namewidth = max_width(zhp, nvroot, 0, 0);
2825 		if (namewidth < 10)
2826 			namewidth = 10;
2827 
2828 		(void) printf(gettext("config:\n\n"));
2829 		(void) printf(gettext("\t%-*s  %-8s %5s %5s %5s\n"), namewidth,
2830 		    "NAME", "STATE", "READ", "WRITE", "CKSUM");
2831 		print_status_config(zhp, zpool_get_name(zhp), nvroot,
2832 		    namewidth, 0, B_FALSE);
2833 
2834 		if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_SPARES,
2835 		    &spares, &nspares) == 0)
2836 			print_spares(zhp, spares, nspares, namewidth);
2837 
2838 		if (nvlist_lookup_uint64(config, ZPOOL_CONFIG_ERRCOUNT,
2839 		    &nerr) == 0) {
2840 			/*
2841 			 * If the approximate error count is small, get a
2842 			 * precise count by fetching the entire log and
2843 			 * uniquifying the results.
2844 			 */
2845 			if (nerr < 100 && !cbp->cb_verbose &&
2846 			    zpool_get_errlog(zhp, NULL, &realerr) == 0)
2847 				nerr = realerr;
2848 
2849 			(void) printf("\n");
2850 
2851 			if (nerr == 0)
2852 				(void) printf(gettext("errors: No known data "
2853 				    "errors\n"));
2854 			else if (!cbp->cb_verbose)
2855 				(void) printf(gettext("errors: %d data errors, "
2856 				    "use '-v' for a list\n"), nerr);
2857 			else
2858 				print_error_log(zhp);
2859 		}
2860 	} else {
2861 		(void) printf(gettext("config: The configuration cannot be "
2862 		    "determined.\n"));
2863 	}
2864 
2865 	return (0);
2866 }
2867 
2868 /*
2869  * zpool status [-vx] [pool] ...
2870  *
2871  *	-v	Display complete error logs
2872  *	-x	Display only pools with potential problems
2873  *
2874  * Describes the health status of all pools or some subset.
2875  */
2876 int
2877 zpool_do_status(int argc, char **argv)
2878 {
2879 	int c;
2880 	int ret;
2881 	status_cbdata_t cb = { 0 };
2882 
2883 	/* check options */
2884 	while ((c = getopt(argc, argv, "vx")) != -1) {
2885 		switch (c) {
2886 		case 'v':
2887 			cb.cb_verbose = B_TRUE;
2888 			break;
2889 		case 'x':
2890 			cb.cb_explain = B_TRUE;
2891 			break;
2892 		case '?':
2893 			(void) fprintf(stderr, gettext("invalid option '%c'\n"),
2894 			    optopt);
2895 			usage(B_FALSE);
2896 		}
2897 	}
2898 
2899 	argc -= optind;
2900 	argv += optind;
2901 
2902 	cb.cb_first = B_TRUE;
2903 
2904 	ret = for_each_pool(argc, argv, B_TRUE, status_callback, &cb);
2905 
2906 	if (argc == 0 && cb.cb_count == 0)
2907 		(void) printf(gettext("no pools available\n"));
2908 	else if (cb.cb_explain && cb.cb_first) {
2909 		if (argc == 0) {
2910 			(void) printf(gettext("all pools are healthy\n"));
2911 		} else {
2912 			int i;
2913 			for (i = 0; i < argc; i++)
2914 				(void) printf(gettext("pool '%s' is healthy\n"),
2915 				    argv[i]);
2916 		}
2917 	}
2918 
2919 	return (ret);
2920 }
2921 
2922 typedef struct upgrade_cbdata {
2923 	int	cb_all;
2924 	int	cb_first;
2925 	int	cb_newer;
2926 } upgrade_cbdata_t;
2927 
2928 static int
2929 upgrade_cb(zpool_handle_t *zhp, void *arg)
2930 {
2931 	upgrade_cbdata_t *cbp = arg;
2932 	nvlist_t *config;
2933 	uint64_t version;
2934 	int ret = 0;
2935 
2936 	config = zpool_get_config(zhp, NULL);
2937 	verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION,
2938 	    &version) == 0);
2939 
2940 	if (!cbp->cb_newer && version < ZFS_VERSION) {
2941 		if (!cbp->cb_all) {
2942 			if (cbp->cb_first) {
2943 				(void) printf(gettext("The following pools are "
2944 				    "out of date, and can be upgraded.  After "
2945 				    "being\nupgraded, these pools will no "
2946 				    "longer be accessible by older software "
2947 				    "versions.\n\n"));
2948 				(void) printf(gettext("VER  POOL\n"));
2949 				(void) printf(gettext("---  ------------\n"));
2950 				cbp->cb_first = B_FALSE;
2951 			}
2952 
2953 			(void) printf("%2llu   %s\n", version,
2954 			    zpool_get_name(zhp));
2955 		} else {
2956 			cbp->cb_first = B_FALSE;
2957 			ret = zpool_upgrade(zhp);
2958 			if (ret == 0)
2959 				(void) printf(gettext("Successfully upgraded "
2960 				    "'%s'\n"), zpool_get_name(zhp));
2961 		}
2962 	} else if (cbp->cb_newer && version > ZFS_VERSION) {
2963 		assert(!cbp->cb_all);
2964 
2965 		if (cbp->cb_first) {
2966 			(void) printf(gettext("The following pools are "
2967 			    "formatted using a newer software version and\n"
2968 			    "cannot be accessed on the current system.\n\n"));
2969 			(void) printf(gettext("VER  POOL\n"));
2970 			(void) printf(gettext("---  ------------\n"));
2971 			cbp->cb_first = B_FALSE;
2972 		}
2973 
2974 		(void) printf("%2llu   %s\n", version,
2975 		    zpool_get_name(zhp));
2976 	}
2977 
2978 	zpool_close(zhp);
2979 	return (ret);
2980 }
2981 
2982 /* ARGSUSED */
2983 static int
2984 upgrade_one(zpool_handle_t *zhp, void *unused)
2985 {
2986 	nvlist_t *config;
2987 	uint64_t version;
2988 	int ret;
2989 
2990 	config = zpool_get_config(zhp, NULL);
2991 	verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION,
2992 	    &version) == 0);
2993 
2994 	if (version == ZFS_VERSION) {
2995 		(void) printf(gettext("Pool '%s' is already formatted "
2996 		    "using the current version.\n"), zpool_get_name(zhp));
2997 		return (0);
2998 	}
2999 
3000 	ret = zpool_upgrade(zhp);
3001 	if (ret == 0)
3002 		(void) printf(gettext("Successfully upgraded '%s' "
3003 		    "from version %llu to version %llu\n"), zpool_get_name(zhp),
3004 		    (u_longlong_t)version, (u_longlong_t)ZFS_VERSION);
3005 
3006 	return (ret != 0);
3007 }
3008 
3009 /*
3010  * zpool upgrade
3011  * zpool upgrade -v
3012  * zpool upgrade <-a | pool>
3013  *
3014  * With no arguments, display downrev'd ZFS pool available for upgrade.
3015  * Individual pools can be upgraded by specifying the pool, and '-a' will
3016  * upgrade all pools.
3017  */
3018 int
3019 zpool_do_upgrade(int argc, char **argv)
3020 {
3021 	int c;
3022 	upgrade_cbdata_t cb = { 0 };
3023 	int ret = 0;
3024 	boolean_t showversions = B_FALSE;
3025 
3026 	/* check options */
3027 	while ((c = getopt(argc, argv, "av")) != -1) {
3028 		switch (c) {
3029 		case 'a':
3030 			cb.cb_all = B_TRUE;
3031 			break;
3032 		case 'v':
3033 			showversions = B_TRUE;
3034 			break;
3035 		case '?':
3036 			(void) fprintf(stderr, gettext("invalid option '%c'\n"),
3037 			    optopt);
3038 			usage(B_FALSE);
3039 		}
3040 	}
3041 
3042 	argc -= optind;
3043 	argv += optind;
3044 
3045 	if (showversions) {
3046 		if (cb.cb_all || argc != 0) {
3047 			(void) fprintf(stderr, gettext("-v option is "
3048 			    "incompatible with other arguments\n"));
3049 			usage(B_FALSE);
3050 		}
3051 	} else if (cb.cb_all) {
3052 		if (argc != 0) {
3053 			(void) fprintf(stderr, gettext("-a option is "
3054 			    "incompatible with other arguments\n"));
3055 			usage(B_FALSE);
3056 		}
3057 	}
3058 
3059 	(void) printf(gettext("This system is currently running ZFS version "
3060 	    "%llu.\n\n"), ZFS_VERSION);
3061 	cb.cb_first = B_TRUE;
3062 	if (showversions) {
3063 		(void) printf(gettext("The following versions are "
3064 		    "suppored:\n\n"));
3065 		(void) printf(gettext("VER  DESCRIPTION\n"));
3066 		(void) printf("---  -----------------------------------------"
3067 		    "---------------\n");
3068 		(void) printf(gettext(" 1   Initial ZFS version\n"));
3069 		(void) printf(gettext(" 2   Ditto blocks "
3070 		    "(replicated metadata)\n"));
3071 		(void) printf(gettext(" 3   Hot spares and double parity "
3072 		    "RAID-Z\n"));
3073 		(void) printf(gettext("\nFor more information on a particular "
3074 		    "version, including supported releases, see:\n\n"));
3075 		(void) printf("http://www.opensolaris.org/os/community/zfs/"
3076 		    "version/N\n\n");
3077 		(void) printf(gettext("Where 'N' is the version number.\n"));
3078 	} else if (argc == 0) {
3079 		int notfound;
3080 
3081 		ret = zpool_iter(g_zfs, upgrade_cb, &cb);
3082 		notfound = cb.cb_first;
3083 
3084 		if (!cb.cb_all && ret == 0) {
3085 			if (!cb.cb_first)
3086 				(void) printf("\n");
3087 			cb.cb_first = B_TRUE;
3088 			cb.cb_newer = B_TRUE;
3089 			ret = zpool_iter(g_zfs, upgrade_cb, &cb);
3090 			if (!cb.cb_first) {
3091 				notfound = B_FALSE;
3092 				(void) printf("\n");
3093 			}
3094 		}
3095 
3096 		if (ret == 0) {
3097 			if (notfound)
3098 				(void) printf(gettext("All pools are formatted "
3099 				    "using this version.\n"));
3100 			else if (!cb.cb_all)
3101 				(void) printf(gettext("Use 'zpool upgrade -v' "
3102 				    "for a list of available versions and "
3103 				    "their associated\nfeatures.\n"));
3104 		}
3105 	} else {
3106 		ret = for_each_pool(argc, argv, B_FALSE, upgrade_one, NULL);
3107 	}
3108 
3109 	return (ret);
3110 }
3111 
3112 int
3113 main(int argc, char **argv)
3114 {
3115 	int ret;
3116 	int i;
3117 	char *cmdname;
3118 
3119 	(void) setlocale(LC_ALL, "");
3120 	(void) textdomain(TEXT_DOMAIN);
3121 
3122 	if ((g_zfs = libzfs_init()) == NULL) {
3123 		(void) fprintf(stderr, gettext("internal error: failed to "
3124 		    "initialize ZFS library"));
3125 		return (1);
3126 	}
3127 
3128 	libzfs_print_on_error(g_zfs, B_TRUE);
3129 
3130 	opterr = 0;
3131 
3132 	/*
3133 	 * Make sure the user has specified some command.
3134 	 */
3135 	if (argc < 2) {
3136 		(void) fprintf(stderr, gettext("missing command\n"));
3137 		usage(B_FALSE);
3138 	}
3139 
3140 	cmdname = argv[1];
3141 
3142 	/*
3143 	 * Special case '-?'
3144 	 */
3145 	if (strcmp(cmdname, "-?") == 0)
3146 		usage(B_TRUE);
3147 
3148 	/*
3149 	 * Run the appropriate command.
3150 	 */
3151 	for (i = 0; i < NCOMMAND; i++) {
3152 		if (command_table[i].name == NULL)
3153 			continue;
3154 
3155 		if (strcmp(cmdname, command_table[i].name) == 0) {
3156 			current_command = &command_table[i];
3157 			ret = command_table[i].func(argc - 1, argv + 1);
3158 			break;
3159 		}
3160 	}
3161 
3162 	/*
3163 	 * 'freeze' is a vile debugging abomination, so we treat it as such.
3164 	 */
3165 	if (strcmp(cmdname, "freeze") == 0 && argc == 3) {
3166 		char buf[16384];
3167 		int fd = open(ZFS_DEV, O_RDWR);
3168 		(void) strcpy((void *)buf, argv[2]);
3169 		return (!!ioctl(fd, ZFS_IOC_POOL_FREEZE, buf));
3170 	}
3171 
3172 	if (i == NCOMMAND) {
3173 		(void) fprintf(stderr, gettext("unrecognized "
3174 		    "command '%s'\n"), cmdname);
3175 		usage(B_FALSE);
3176 	}
3177 
3178 	libzfs_fini(g_zfs);
3179 
3180 	/*
3181 	 * The 'ZFS_ABORT' environment variable causes us to dump core on exit
3182 	 * for the purposes of running ::findleaks.
3183 	 */
3184 	if (getenv("ZFS_ABORT") != NULL) {
3185 		(void) printf("dumping core by request\n");
3186 		abort();
3187 	}
3188 
3189 	return (ret);
3190 }
3191