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