xref: /titanic_52/usr/src/cmd/zpool/zpool_main.c (revision 82d33c01b078ed404a986a369750cdb4743773fb)
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 (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 (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 (mount_share_datasets(zhp, mntopts) != 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
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 
1476 	/*
1477 	 * If the pool has disappeared, remove it from the list and continue.
1478 	 */
1479 	if (zpool_refresh_stats(zhp) != 0)
1480 		pool_list_remove(cb->cb_list, zhp);
1481 
1482 	return (0);
1483 }
1484 
1485 /*
1486  * Callback to print out the iostats for the given pool.
1487  */
1488 int
1489 print_iostat(zpool_handle_t *zhp, void *data)
1490 {
1491 	iostat_cbdata_t *cb = data;
1492 	nvlist_t *oldconfig, *newconfig;
1493 	nvlist_t *oldnvroot, *newnvroot;
1494 
1495 	newconfig = zpool_get_config(zhp, &oldconfig);
1496 
1497 	if (cb->cb_iteration == 1)
1498 		oldconfig = NULL;
1499 
1500 	verify(nvlist_lookup_nvlist(newconfig, ZPOOL_CONFIG_VDEV_TREE,
1501 	    &newnvroot) == 0);
1502 
1503 	if (oldconfig == NULL)
1504 		oldnvroot = NULL;
1505 	else
1506 		verify(nvlist_lookup_nvlist(oldconfig, ZPOOL_CONFIG_VDEV_TREE,
1507 		    &oldnvroot) == 0);
1508 
1509 	/*
1510 	 * Print out the statistics for the pool.
1511 	 */
1512 	print_vdev_stats(zhp, zpool_get_name(zhp), oldnvroot, newnvroot, cb, 0);
1513 
1514 	if (cb->cb_verbose)
1515 		print_iostat_separator(cb);
1516 
1517 	return (0);
1518 }
1519 
1520 int
1521 get_namewidth(zpool_handle_t *zhp, void *data)
1522 {
1523 	iostat_cbdata_t *cb = data;
1524 	nvlist_t *config, *nvroot;
1525 
1526 	if ((config = zpool_get_config(zhp, NULL)) != NULL) {
1527 		verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
1528 		    &nvroot) == 0);
1529 		if (!cb->cb_verbose)
1530 			cb->cb_namewidth = strlen(zpool_get_name(zhp));
1531 		else
1532 			cb->cb_namewidth = max_width(zhp, nvroot, 0, 0);
1533 	}
1534 
1535 	/*
1536 	 * The width must fall into the range [10,38].  The upper limit is the
1537 	 * maximum we can have and still fit in 80 columns.
1538 	 */
1539 	if (cb->cb_namewidth < 10)
1540 		cb->cb_namewidth = 10;
1541 	if (cb->cb_namewidth > 38)
1542 		cb->cb_namewidth = 38;
1543 
1544 	return (0);
1545 }
1546 
1547 /*
1548  * zpool iostat [-v] [pool] ... [interval [count]]
1549  *
1550  *	-v	Display statistics for individual vdevs
1551  *
1552  * This command can be tricky because we want to be able to deal with pool
1553  * creation/destruction as well as vdev configuration changes.  The bulk of this
1554  * processing is handled by the pool_list_* routines in zpool_iter.c.  We rely
1555  * on pool_list_update() to detect the addition of new pools.  Configuration
1556  * changes are all handled within libzfs.
1557  */
1558 int
1559 zpool_do_iostat(int argc, char **argv)
1560 {
1561 	int c;
1562 	int ret;
1563 	int npools;
1564 	unsigned long interval = 0, count = 0;
1565 	zpool_list_t *list;
1566 	boolean_t verbose = B_FALSE;
1567 	iostat_cbdata_t cb;
1568 
1569 	/* check options */
1570 	while ((c = getopt(argc, argv, "v")) != -1) {
1571 		switch (c) {
1572 		case 'v':
1573 			verbose = B_TRUE;
1574 			break;
1575 		case '?':
1576 			(void) fprintf(stderr, gettext("invalid option '%c'\n"),
1577 			    optopt);
1578 			usage(B_FALSE);
1579 		}
1580 	}
1581 
1582 	argc -= optind;
1583 	argv += optind;
1584 
1585 	/*
1586 	 * Determine if the last argument is an integer or a pool name
1587 	 */
1588 	if (argc > 0 && isdigit(argv[argc - 1][0])) {
1589 		char *end;
1590 
1591 		errno = 0;
1592 		interval = strtoul(argv[argc - 1], &end, 10);
1593 
1594 		if (*end == '\0' && errno == 0) {
1595 			if (interval == 0) {
1596 				(void) fprintf(stderr, gettext("interval "
1597 				    "cannot be zero\n"));
1598 				usage(B_FALSE);
1599 			}
1600 
1601 			/*
1602 			 * Ignore the last parameter
1603 			 */
1604 			argc--;
1605 		} else {
1606 			/*
1607 			 * If this is not a valid number, just plow on.  The
1608 			 * user will get a more informative error message later
1609 			 * on.
1610 			 */
1611 			interval = 0;
1612 		}
1613 	}
1614 
1615 	/*
1616 	 * If the last argument is also an integer, then we have both a count
1617 	 * and an integer.
1618 	 */
1619 	if (argc > 0 && isdigit(argv[argc - 1][0])) {
1620 		char *end;
1621 
1622 		errno = 0;
1623 		count = interval;
1624 		interval = strtoul(argv[argc - 1], &end, 10);
1625 
1626 		if (*end == '\0' && errno == 0) {
1627 			if (interval == 0) {
1628 				(void) fprintf(stderr, gettext("interval "
1629 				    "cannot be zero\n"));
1630 				usage(B_FALSE);
1631 			}
1632 
1633 			/*
1634 			 * Ignore the last parameter
1635 			 */
1636 			argc--;
1637 		} else {
1638 			interval = 0;
1639 		}
1640 	}
1641 
1642 	/*
1643 	 * Construct the list of all interesting pools.
1644 	 */
1645 	ret = 0;
1646 	if ((list = pool_list_get(argc, argv, &ret)) == NULL)
1647 		return (1);
1648 
1649 	if (pool_list_count(list) == 0 && argc != 0) {
1650 		pool_list_free(list);
1651 		return (1);
1652 	}
1653 
1654 	if (pool_list_count(list) == 0 && interval == 0) {
1655 		pool_list_free(list);
1656 		(void) fprintf(stderr, gettext("no pools available\n"));
1657 		return (1);
1658 	}
1659 
1660 	/*
1661 	 * Enter the main iostat loop.
1662 	 */
1663 	cb.cb_list = list;
1664 	cb.cb_verbose = verbose;
1665 	cb.cb_iteration = 0;
1666 	cb.cb_namewidth = 0;
1667 
1668 	for (;;) {
1669 		pool_list_update(list);
1670 
1671 		if ((npools = pool_list_count(list)) == 0)
1672 			break;
1673 
1674 		/*
1675 		 * Refresh all statistics.  This is done as an explicit step
1676 		 * before calculating the maximum name width, so that any
1677 		 * configuration changes are properly accounted for.
1678 		 */
1679 		(void) pool_list_iter(list, B_FALSE, refresh_iostat, &cb);
1680 
1681 		/*
1682 		 * Iterate over all pools to determine the maximum width
1683 		 * for the pool / device name column across all pools.
1684 		 */
1685 		cb.cb_namewidth = 0;
1686 		(void) pool_list_iter(list, B_FALSE, get_namewidth, &cb);
1687 
1688 		/*
1689 		 * If it's the first time, or verbose mode, print the header.
1690 		 */
1691 		if (++cb.cb_iteration == 1 || verbose)
1692 			print_iostat_header(&cb);
1693 
1694 		(void) pool_list_iter(list, B_FALSE, print_iostat, &cb);
1695 
1696 		/*
1697 		 * If there's more than one pool, and we're not in verbose mode
1698 		 * (which prints a separator for us), then print a separator.
1699 		 */
1700 		if (npools > 1 && !verbose)
1701 			print_iostat_separator(&cb);
1702 
1703 		if (verbose)
1704 			(void) printf("\n");
1705 
1706 		if (interval == 0)
1707 			break;
1708 
1709 		if (count != 0 && --count == 0)
1710 			break;
1711 
1712 		(void) sleep(interval);
1713 	}
1714 
1715 	pool_list_free(list);
1716 
1717 	return (ret);
1718 }
1719 
1720 typedef struct list_cbdata {
1721 	boolean_t	cb_scripted;
1722 	boolean_t	cb_first;
1723 	int		cb_fields[MAX_FIELDS];
1724 	int		cb_fieldcount;
1725 } list_cbdata_t;
1726 
1727 /*
1728  * Given a list of columns to display, output appropriate headers for each one.
1729  */
1730 void
1731 print_header(int *fields, size_t count)
1732 {
1733 	int i;
1734 	column_def_t *col;
1735 	const char *fmt;
1736 
1737 	for (i = 0; i < count; i++) {
1738 		col = &column_table[fields[i]];
1739 		if (i != 0)
1740 			(void) printf("  ");
1741 		if (col->cd_justify == left_justify)
1742 			fmt = "%-*s";
1743 		else
1744 			fmt = "%*s";
1745 
1746 		(void) printf(fmt, i == count - 1 ? strlen(col->cd_title) :
1747 		    col->cd_width, col->cd_title);
1748 	}
1749 
1750 	(void) printf("\n");
1751 }
1752 
1753 int
1754 list_callback(zpool_handle_t *zhp, void *data)
1755 {
1756 	list_cbdata_t *cbp = data;
1757 	nvlist_t *config;
1758 	int i;
1759 	char buf[ZPOOL_MAXNAMELEN];
1760 	uint64_t total;
1761 	uint64_t used;
1762 	const char *fmt;
1763 	column_def_t *col;
1764 
1765 	if (cbp->cb_first) {
1766 		if (!cbp->cb_scripted)
1767 			print_header(cbp->cb_fields, cbp->cb_fieldcount);
1768 		cbp->cb_first = B_FALSE;
1769 	}
1770 
1771 	if (zpool_get_state(zhp) == POOL_STATE_UNAVAIL) {
1772 		config = NULL;
1773 	} else {
1774 		config = zpool_get_config(zhp, NULL);
1775 		total = zpool_get_space_total(zhp);
1776 		used = zpool_get_space_used(zhp);
1777 	}
1778 
1779 	for (i = 0; i < cbp->cb_fieldcount; i++) {
1780 		if (i != 0) {
1781 			if (cbp->cb_scripted)
1782 				(void) printf("\t");
1783 			else
1784 				(void) printf("  ");
1785 		}
1786 
1787 		col = &column_table[cbp->cb_fields[i]];
1788 
1789 		switch (cbp->cb_fields[i]) {
1790 		case ZPOOL_FIELD_NAME:
1791 			(void) strlcpy(buf, zpool_get_name(zhp), sizeof (buf));
1792 			break;
1793 
1794 		case ZPOOL_FIELD_SIZE:
1795 			if (config == NULL)
1796 				(void) strlcpy(buf, "-", sizeof (buf));
1797 			else
1798 				zfs_nicenum(total, buf, sizeof (buf));
1799 			break;
1800 
1801 		case ZPOOL_FIELD_USED:
1802 			if (config == NULL)
1803 				(void) strlcpy(buf, "-", sizeof (buf));
1804 			else
1805 				zfs_nicenum(used, buf, sizeof (buf));
1806 			break;
1807 
1808 		case ZPOOL_FIELD_AVAILABLE:
1809 			if (config == NULL)
1810 				(void) strlcpy(buf, "-", sizeof (buf));
1811 			else
1812 				zfs_nicenum(total - used, buf, sizeof (buf));
1813 			break;
1814 
1815 		case ZPOOL_FIELD_CAPACITY:
1816 			if (config == NULL) {
1817 				(void) strlcpy(buf, "-", sizeof (buf));
1818 			} else {
1819 				uint64_t capacity = (total == 0 ? 0 :
1820 				    (used * 100 / total));
1821 				(void) snprintf(buf, sizeof (buf), "%llu%%",
1822 				    capacity);
1823 			}
1824 			break;
1825 
1826 		case ZPOOL_FIELD_HEALTH:
1827 			if (config == NULL) {
1828 				(void) strlcpy(buf, "FAULTED", sizeof (buf));
1829 			} else {
1830 				nvlist_t *nvroot;
1831 				vdev_stat_t *vs;
1832 				uint_t vsc;
1833 
1834 				verify(nvlist_lookup_nvlist(config,
1835 				    ZPOOL_CONFIG_VDEV_TREE, &nvroot) == 0);
1836 				verify(nvlist_lookup_uint64_array(nvroot,
1837 				    ZPOOL_CONFIG_STATS, (uint64_t **)&vs,
1838 				    &vsc) == 0);
1839 				(void) strlcpy(buf, state_to_name(vs),
1840 				    sizeof (buf));
1841 			}
1842 			break;
1843 
1844 		case ZPOOL_FIELD_ROOT:
1845 			if (config == NULL)
1846 				(void) strlcpy(buf, "-", sizeof (buf));
1847 			else if (zpool_get_root(zhp, buf, sizeof (buf)) != 0)
1848 				(void) strlcpy(buf, "-", sizeof (buf));
1849 			break;
1850 		}
1851 
1852 		if (cbp->cb_scripted)
1853 			(void) printf("%s", buf);
1854 		else {
1855 			if (col->cd_justify == left_justify)
1856 				fmt = "%-*s";
1857 			else
1858 				fmt = "%*s";
1859 
1860 			(void) printf(fmt, i == cbp->cb_fieldcount - 1 ?
1861 			    strlen(buf) : col->cd_width, buf);
1862 		}
1863 	}
1864 
1865 	(void) printf("\n");
1866 
1867 	return (0);
1868 }
1869 
1870 /*
1871  * zpool list [-H] [-o field[,field]*] [pool] ...
1872  *
1873  *	-H	Scripted mode.  Don't display headers, and separate fields by
1874  *		a single tab.
1875  *	-o	List of fields to display.  Defaults to all fields, or
1876  *		"name,size,used,available,capacity,health,root"
1877  *
1878  * List all pools in the system, whether or not they're healthy.  Output space
1879  * statistics for each one, as well as health status summary.
1880  */
1881 int
1882 zpool_do_list(int argc, char **argv)
1883 {
1884 	int c;
1885 	int ret;
1886 	list_cbdata_t cb = { 0 };
1887 	static char default_fields[] =
1888 	    "name,size,used,available,capacity,health,root";
1889 	char *fields = default_fields;
1890 	char *value;
1891 
1892 	/* check options */
1893 	while ((c = getopt(argc, argv, ":Ho:")) != -1) {
1894 		switch (c) {
1895 		case 'H':
1896 			cb.cb_scripted = B_TRUE;
1897 			break;
1898 		case 'o':
1899 			fields = optarg;
1900 			break;
1901 		case ':':
1902 			(void) fprintf(stderr, gettext("missing argument for "
1903 			    "'%c' option\n"), optopt);
1904 			usage(B_FALSE);
1905 			break;
1906 		case '?':
1907 			(void) fprintf(stderr, gettext("invalid option '%c'\n"),
1908 			    optopt);
1909 			usage(B_FALSE);
1910 		}
1911 	}
1912 
1913 	argc -= optind;
1914 	argv += optind;
1915 
1916 	while (*fields != '\0') {
1917 		if (cb.cb_fieldcount == MAX_FIELDS) {
1918 			(void) fprintf(stderr, gettext("too many "
1919 			    "properties given to -o option\n"));
1920 			usage(B_FALSE);
1921 		}
1922 
1923 		if ((cb.cb_fields[cb.cb_fieldcount] = getsubopt(&fields,
1924 		    column_subopts, &value)) == -1) {
1925 			(void) fprintf(stderr, gettext("invalid property "
1926 			    "'%s'\n"), value);
1927 			usage(B_FALSE);
1928 		}
1929 
1930 		cb.cb_fieldcount++;
1931 	}
1932 
1933 
1934 	cb.cb_first = B_TRUE;
1935 
1936 	ret = for_each_pool(argc, argv, B_TRUE, list_callback, &cb);
1937 
1938 	if (argc == 0 && cb.cb_first) {
1939 		(void) printf(gettext("no pools available\n"));
1940 		return (0);
1941 	}
1942 
1943 	return (ret);
1944 }
1945 
1946 static nvlist_t *
1947 zpool_get_vdev_by_name(nvlist_t *nv, char *name)
1948 {
1949 	nvlist_t **child;
1950 	uint_t c, children;
1951 	nvlist_t *match;
1952 	char *path;
1953 
1954 	if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
1955 	    &child, &children) != 0) {
1956 		verify(nvlist_lookup_string(nv, ZPOOL_CONFIG_PATH, &path) == 0);
1957 		if (strncmp(name, "/dev/dsk/", 9) == 0)
1958 			name += 9;
1959 		if (strncmp(path, "/dev/dsk/", 9) == 0)
1960 			path += 9;
1961 		if (strcmp(name, path) == 0)
1962 			return (nv);
1963 		return (NULL);
1964 	}
1965 
1966 	for (c = 0; c < children; c++)
1967 		if ((match = zpool_get_vdev_by_name(child[c], name)) != NULL)
1968 			return (match);
1969 
1970 	return (NULL);
1971 }
1972 
1973 static int
1974 zpool_do_attach_or_replace(int argc, char **argv, int replacing)
1975 {
1976 	boolean_t force = B_FALSE;
1977 	int c;
1978 	nvlist_t *nvroot;
1979 	char *poolname, *old_disk, *new_disk;
1980 	zpool_handle_t *zhp;
1981 	nvlist_t *config;
1982 	int ret;
1983 
1984 	/* check options */
1985 	while ((c = getopt(argc, argv, "f")) != -1) {
1986 		switch (c) {
1987 		case 'f':
1988 			force = B_TRUE;
1989 			break;
1990 		case '?':
1991 			(void) fprintf(stderr, gettext("invalid option '%c'\n"),
1992 			    optopt);
1993 			usage(B_FALSE);
1994 		}
1995 	}
1996 
1997 	argc -= optind;
1998 	argv += optind;
1999 
2000 	/* get pool name and check number of arguments */
2001 	if (argc < 1) {
2002 		(void) fprintf(stderr, gettext("missing pool name argument\n"));
2003 		usage(B_FALSE);
2004 	}
2005 
2006 	poolname = argv[0];
2007 
2008 	if (argc < 2) {
2009 		(void) fprintf(stderr,
2010 		    gettext("missing <device> specification\n"));
2011 		usage(B_FALSE);
2012 	}
2013 
2014 	old_disk = argv[1];
2015 
2016 	if (argc < 3) {
2017 		if (!replacing) {
2018 			(void) fprintf(stderr,
2019 			    gettext("missing <new_device> specification\n"));
2020 			usage(B_FALSE);
2021 		}
2022 		new_disk = old_disk;
2023 		argc -= 1;
2024 		argv += 1;
2025 	} else {
2026 		new_disk = argv[2];
2027 		argc -= 2;
2028 		argv += 2;
2029 	}
2030 
2031 	if (argc > 1) {
2032 		(void) fprintf(stderr, gettext("too many arguments\n"));
2033 		usage(B_FALSE);
2034 	}
2035 
2036 	if ((zhp = zpool_open(g_zfs, poolname)) == NULL)
2037 		return (1);
2038 
2039 	if ((config = zpool_get_config(zhp, NULL)) == NULL) {
2040 		(void) fprintf(stderr, gettext("pool '%s' is unavailable\n"),
2041 		    poolname);
2042 		zpool_close(zhp);
2043 		return (1);
2044 	}
2045 
2046 	nvroot = make_root_vdev(config, force, B_FALSE, replacing, argc, argv);
2047 	if (nvroot == NULL) {
2048 		zpool_close(zhp);
2049 		return (1);
2050 	}
2051 
2052 	ret = zpool_vdev_attach(zhp, old_disk, new_disk, nvroot, replacing);
2053 
2054 	nvlist_free(nvroot);
2055 	zpool_close(zhp);
2056 
2057 	return (ret);
2058 }
2059 
2060 /*
2061  * zpool replace [-f] <pool> <device> <new_device>
2062  *
2063  *	-f	Force attach, even if <new_device> appears to be in use.
2064  *
2065  * Replace <device> with <new_device>.
2066  */
2067 /* ARGSUSED */
2068 int
2069 zpool_do_replace(int argc, char **argv)
2070 {
2071 	return (zpool_do_attach_or_replace(argc, argv, B_TRUE));
2072 }
2073 
2074 /*
2075  * zpool attach [-f] <pool> <device> <new_device>
2076  *
2077  *	-f	Force attach, even if <new_device> appears to be in use.
2078  *
2079  * Attach <new_device> to the mirror containing <device>.  If <device> is not
2080  * part of a mirror, then <device> will be transformed into a mirror of
2081  * <device> and <new_device>.  In either case, <new_device> will begin life
2082  * with a DTL of [0, now], and will immediately begin to resilver itself.
2083  */
2084 int
2085 zpool_do_attach(int argc, char **argv)
2086 {
2087 	return (zpool_do_attach_or_replace(argc, argv, B_FALSE));
2088 }
2089 
2090 /*
2091  * zpool detach [-f] <pool> <device>
2092  *
2093  *	-f	Force detach of <device>, even if DTLs argue against it
2094  *		(not supported yet)
2095  *
2096  * Detach a device from a mirror.  The operation will be refused if <device>
2097  * is the last device in the mirror, or if the DTLs indicate that this device
2098  * has the only valid copy of some data.
2099  */
2100 /* ARGSUSED */
2101 int
2102 zpool_do_detach(int argc, char **argv)
2103 {
2104 	int c;
2105 	char *poolname, *path;
2106 	zpool_handle_t *zhp;
2107 	int ret;
2108 
2109 	/* check options */
2110 	while ((c = getopt(argc, argv, "f")) != -1) {
2111 		switch (c) {
2112 		case 'f':
2113 		case '?':
2114 			(void) fprintf(stderr, gettext("invalid option '%c'\n"),
2115 			    optopt);
2116 			usage(B_FALSE);
2117 		}
2118 	}
2119 
2120 	argc -= optind;
2121 	argv += optind;
2122 
2123 	/* get pool name and check number of arguments */
2124 	if (argc < 1) {
2125 		(void) fprintf(stderr, gettext("missing pool name argument\n"));
2126 		usage(B_FALSE);
2127 	}
2128 
2129 	if (argc < 2) {
2130 		(void) fprintf(stderr,
2131 		    gettext("missing <device> specification\n"));
2132 		usage(B_FALSE);
2133 	}
2134 
2135 	poolname = argv[0];
2136 	path = argv[1];
2137 
2138 	if ((zhp = zpool_open(g_zfs, poolname)) == NULL)
2139 		return (1);
2140 
2141 	ret = zpool_vdev_detach(zhp, path);
2142 
2143 	zpool_close(zhp);
2144 
2145 	return (ret);
2146 }
2147 
2148 /*
2149  * zpool online <pool> <device> ...
2150  */
2151 /* ARGSUSED */
2152 int
2153 zpool_do_online(int argc, char **argv)
2154 {
2155 	int c, i;
2156 	char *poolname;
2157 	zpool_handle_t *zhp;
2158 	int ret = 0;
2159 
2160 	/* check options */
2161 	while ((c = getopt(argc, argv, "t")) != -1) {
2162 		switch (c) {
2163 		case 't':
2164 		case '?':
2165 			(void) fprintf(stderr, gettext("invalid option '%c'\n"),
2166 			    optopt);
2167 			usage(B_FALSE);
2168 		}
2169 	}
2170 
2171 	argc -= optind;
2172 	argv += optind;
2173 
2174 	/* get pool name and check number of arguments */
2175 	if (argc < 1) {
2176 		(void) fprintf(stderr, gettext("missing pool name\n"));
2177 		usage(B_FALSE);
2178 	}
2179 	if (argc < 2) {
2180 		(void) fprintf(stderr, gettext("missing device name\n"));
2181 		usage(B_FALSE);
2182 	}
2183 
2184 	poolname = argv[0];
2185 
2186 	if ((zhp = zpool_open(g_zfs, poolname)) == NULL)
2187 		return (1);
2188 
2189 	for (i = 1; i < argc; i++)
2190 		if (zpool_vdev_online(zhp, argv[i]) == 0)
2191 			(void) printf(gettext("Bringing device %s online\n"),
2192 			    argv[i]);
2193 		else
2194 			ret = 1;
2195 
2196 	zpool_close(zhp);
2197 
2198 	return (ret);
2199 }
2200 
2201 /*
2202  * zpool offline [-ft] <pool> <device> ...
2203  *
2204  *	-f	Force the device into the offline state, even if doing
2205  *		so would appear to compromise pool availability.
2206  *		(not supported yet)
2207  *
2208  *	-t	Only take the device off-line temporarily.  The offline
2209  *		state will not be persistent across reboots.
2210  */
2211 /* ARGSUSED */
2212 int
2213 zpool_do_offline(int argc, char **argv)
2214 {
2215 	int c, i;
2216 	char *poolname;
2217 	zpool_handle_t *zhp;
2218 	int ret = 0;
2219 	boolean_t istmp = B_FALSE;
2220 
2221 	/* check options */
2222 	while ((c = getopt(argc, argv, "ft")) != -1) {
2223 		switch (c) {
2224 		case 't':
2225 			istmp = B_TRUE;
2226 			break;
2227 		case 'f':
2228 		case '?':
2229 			(void) fprintf(stderr, gettext("invalid option '%c'\n"),
2230 			    optopt);
2231 			usage(B_FALSE);
2232 		}
2233 	}
2234 
2235 	argc -= optind;
2236 	argv += optind;
2237 
2238 	/* get pool name and check number of arguments */
2239 	if (argc < 1) {
2240 		(void) fprintf(stderr, gettext("missing pool name\n"));
2241 		usage(B_FALSE);
2242 	}
2243 	if (argc < 2) {
2244 		(void) fprintf(stderr, gettext("missing device name\n"));
2245 		usage(B_FALSE);
2246 	}
2247 
2248 	poolname = argv[0];
2249 
2250 	if ((zhp = zpool_open(g_zfs, poolname)) == NULL)
2251 		return (1);
2252 
2253 	for (i = 1; i < argc; i++)
2254 		if (zpool_vdev_offline(zhp, argv[i], istmp) == 0)
2255 			(void) printf(gettext("Bringing device %s offline\n"),
2256 			    argv[i]);
2257 		else
2258 			ret = 1;
2259 
2260 	zpool_close(zhp);
2261 
2262 	return (ret);
2263 }
2264 
2265 /*
2266  * zpool clear <pool> [device]
2267  *
2268  * Clear all errors associated with a pool or a particular device.
2269  */
2270 int
2271 zpool_do_clear(int argc, char **argv)
2272 {
2273 	int ret = 0;
2274 	zpool_handle_t *zhp;
2275 	char *pool, *device;
2276 
2277 	if (argc < 2) {
2278 		(void) fprintf(stderr, gettext("missing pool name\n"));
2279 		usage(B_FALSE);
2280 	}
2281 
2282 	if (argc > 3) {
2283 		(void) fprintf(stderr, gettext("too many arguments\n"));
2284 		usage(B_FALSE);
2285 	}
2286 
2287 	pool = argv[1];
2288 	device = argc == 3 ? argv[2] : NULL;
2289 
2290 	if ((zhp = zpool_open(g_zfs, pool)) == NULL)
2291 		return (1);
2292 
2293 	if (zpool_clear(zhp, device) != 0)
2294 		ret = 1;
2295 
2296 	zpool_close(zhp);
2297 
2298 	return (ret);
2299 }
2300 
2301 typedef struct scrub_cbdata {
2302 	int	cb_type;
2303 } scrub_cbdata_t;
2304 
2305 int
2306 scrub_callback(zpool_handle_t *zhp, void *data)
2307 {
2308 	scrub_cbdata_t *cb = data;
2309 
2310 	/*
2311 	 * Ignore faulted pools.
2312 	 */
2313 	if (zpool_get_state(zhp) == POOL_STATE_UNAVAIL) {
2314 		(void) fprintf(stderr, gettext("cannot scrub '%s': pool is "
2315 		    "currently unavailable\n"), zpool_get_name(zhp));
2316 		return (1);
2317 	}
2318 
2319 	return (zpool_scrub(zhp, cb->cb_type) != 0);
2320 }
2321 
2322 /*
2323  * zpool scrub [-s] <pool> ...
2324  *
2325  *	-s	Stop.  Stops any in-progress scrub.
2326  */
2327 int
2328 zpool_do_scrub(int argc, char **argv)
2329 {
2330 	int c;
2331 	scrub_cbdata_t cb;
2332 
2333 	cb.cb_type = POOL_SCRUB_EVERYTHING;
2334 
2335 	/* check options */
2336 	while ((c = getopt(argc, argv, "s")) != -1) {
2337 		switch (c) {
2338 		case 's':
2339 			cb.cb_type = POOL_SCRUB_NONE;
2340 			break;
2341 		case '?':
2342 			(void) fprintf(stderr, gettext("invalid option '%c'\n"),
2343 			    optopt);
2344 			usage(B_FALSE);
2345 		}
2346 	}
2347 
2348 	argc -= optind;
2349 	argv += optind;
2350 
2351 	if (argc < 1) {
2352 		(void) fprintf(stderr, gettext("missing pool name argument\n"));
2353 		usage(B_FALSE);
2354 	}
2355 
2356 	return (for_each_pool(argc, argv, B_TRUE, scrub_callback, &cb));
2357 }
2358 
2359 typedef struct status_cbdata {
2360 	int		cb_count;
2361 	boolean_t	cb_verbose;
2362 	boolean_t	cb_explain;
2363 	boolean_t	cb_first;
2364 } status_cbdata_t;
2365 
2366 /*
2367  * Print out detailed scrub status.
2368  */
2369 void
2370 print_scrub_status(nvlist_t *nvroot)
2371 {
2372 	vdev_stat_t *vs;
2373 	uint_t vsc;
2374 	time_t start, end, now;
2375 	double fraction_done;
2376 	uint64_t examined, total, minutes_left;
2377 	char *scrub_type;
2378 
2379 	verify(nvlist_lookup_uint64_array(nvroot, ZPOOL_CONFIG_STATS,
2380 	    (uint64_t **)&vs, &vsc) == 0);
2381 
2382 	/*
2383 	 * If there's never been a scrub, there's not much to say.
2384 	 */
2385 	if (vs->vs_scrub_end == 0 && vs->vs_scrub_type == POOL_SCRUB_NONE) {
2386 		(void) printf(gettext("none requested\n"));
2387 		return;
2388 	}
2389 
2390 	scrub_type = (vs->vs_scrub_type == POOL_SCRUB_RESILVER) ?
2391 	    "resilver" : "scrub";
2392 
2393 	start = vs->vs_scrub_start;
2394 	end = vs->vs_scrub_end;
2395 	now = time(NULL);
2396 	examined = vs->vs_scrub_examined;
2397 	total = vs->vs_alloc;
2398 
2399 	if (end != 0) {
2400 		(void) printf(gettext("%s %s with %llu errors on %s"),
2401 		    scrub_type, vs->vs_scrub_complete ? "completed" : "stopped",
2402 		    (u_longlong_t)vs->vs_scrub_errors, ctime(&end));
2403 		return;
2404 	}
2405 
2406 	if (examined == 0)
2407 		examined = 1;
2408 	if (examined > total)
2409 		total = examined;
2410 
2411 	fraction_done = (double)examined / total;
2412 	minutes_left = (uint64_t)((now - start) *
2413 	    (1 - fraction_done) / fraction_done / 60);
2414 
2415 	(void) printf(gettext("%s in progress, %.2f%% done, %lluh%um to go\n"),
2416 	    scrub_type, 100 * fraction_done,
2417 	    (u_longlong_t)(minutes_left / 60), (uint_t)(minutes_left % 60));
2418 }
2419 
2420 typedef struct spare_cbdata {
2421 	uint64_t	cb_guid;
2422 	zpool_handle_t	*cb_zhp;
2423 } spare_cbdata_t;
2424 
2425 static boolean_t
2426 find_vdev(nvlist_t *nv, uint64_t search)
2427 {
2428 	uint64_t guid;
2429 	nvlist_t **child;
2430 	uint_t c, children;
2431 
2432 	if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_GUID, &guid) == 0 &&
2433 	    search == guid)
2434 		return (B_TRUE);
2435 
2436 	if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
2437 	    &child, &children) == 0) {
2438 		for (c = 0; c < children; c++)
2439 			if (find_vdev(child[c], search))
2440 				return (B_TRUE);
2441 	}
2442 
2443 	return (B_FALSE);
2444 }
2445 
2446 static int
2447 find_spare(zpool_handle_t *zhp, void *data)
2448 {
2449 	spare_cbdata_t *cbp = data;
2450 	nvlist_t *config, *nvroot;
2451 
2452 	config = zpool_get_config(zhp, NULL);
2453 	verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
2454 	    &nvroot) == 0);
2455 
2456 	if (find_vdev(nvroot, cbp->cb_guid)) {
2457 		cbp->cb_zhp = zhp;
2458 		return (1);
2459 	}
2460 
2461 	zpool_close(zhp);
2462 	return (0);
2463 }
2464 
2465 /*
2466  * Print out configuration state as requested by status_callback.
2467  */
2468 void
2469 print_status_config(zpool_handle_t *zhp, const char *name, nvlist_t *nv,
2470     int namewidth, int depth, boolean_t isspare)
2471 {
2472 	nvlist_t **child;
2473 	uint_t c, children;
2474 	vdev_stat_t *vs;
2475 	char rbuf[6], wbuf[6], cbuf[6], repaired[7];
2476 	char *vname;
2477 	uint64_t notpresent;
2478 	spare_cbdata_t cb;
2479 	const char *state;
2480 
2481 	verify(nvlist_lookup_uint64_array(nv, ZPOOL_CONFIG_STATS,
2482 	    (uint64_t **)&vs, &c) == 0);
2483 
2484 	if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
2485 	    &child, &children) != 0)
2486 		children = 0;
2487 
2488 	state = state_to_name(vs);
2489 	if (isspare) {
2490 		/*
2491 		 * For hot spares, we use the terms 'INUSE' and 'AVAILABLE' for
2492 		 * online drives.
2493 		 */
2494 		if (vs->vs_aux == VDEV_AUX_SPARED)
2495 			state = "INUSE";
2496 		else if (vs->vs_state == VDEV_STATE_HEALTHY)
2497 			state = "AVAIL";
2498 	}
2499 
2500 	(void) printf("\t%*s%-*s  %-8s", depth, "", namewidth - depth,
2501 	    name, state);
2502 
2503 	if (!isspare) {
2504 		zfs_nicenum(vs->vs_read_errors, rbuf, sizeof (rbuf));
2505 		zfs_nicenum(vs->vs_write_errors, wbuf, sizeof (wbuf));
2506 		zfs_nicenum(vs->vs_checksum_errors, cbuf, sizeof (cbuf));
2507 		(void) printf(" %5s %5s %5s", rbuf, wbuf, cbuf);
2508 	}
2509 
2510 	if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_NOT_PRESENT,
2511 	    &notpresent) == 0) {
2512 		char *path;
2513 		verify(nvlist_lookup_string(nv, ZPOOL_CONFIG_PATH, &path) == 0);
2514 		(void) printf("  was %s", path);
2515 	} else if (vs->vs_aux != 0) {
2516 		(void) printf("  ");
2517 
2518 		switch (vs->vs_aux) {
2519 		case VDEV_AUX_OPEN_FAILED:
2520 			(void) printf(gettext("cannot open"));
2521 			break;
2522 
2523 		case VDEV_AUX_BAD_GUID_SUM:
2524 			(void) printf(gettext("missing device"));
2525 			break;
2526 
2527 		case VDEV_AUX_NO_REPLICAS:
2528 			(void) printf(gettext("insufficient replicas"));
2529 			break;
2530 
2531 		case VDEV_AUX_VERSION_NEWER:
2532 			(void) printf(gettext("newer version"));
2533 			break;
2534 
2535 		case VDEV_AUX_SPARED:
2536 			verify(nvlist_lookup_uint64(nv, ZPOOL_CONFIG_GUID,
2537 			    &cb.cb_guid) == 0);
2538 			if (zpool_iter(g_zfs, find_spare, &cb) == 1) {
2539 				if (strcmp(zpool_get_name(cb.cb_zhp),
2540 				    zpool_get_name(zhp)) == 0)
2541 					(void) printf(gettext("currently in "
2542 					    "use"));
2543 				else
2544 					(void) printf(gettext("in use by "
2545 					    "pool '%s'"),
2546 					    zpool_get_name(cb.cb_zhp));
2547 				zpool_close(cb.cb_zhp);
2548 			} else {
2549 				(void) printf(gettext("currently in use"));
2550 			}
2551 			break;
2552 
2553 		default:
2554 			(void) printf(gettext("corrupted data"));
2555 			break;
2556 		}
2557 	} else if (vs->vs_scrub_repaired != 0 && children == 0) {
2558 		/*
2559 		 * Report bytes resilvered/repaired on leaf devices.
2560 		 */
2561 		zfs_nicenum(vs->vs_scrub_repaired, repaired, sizeof (repaired));
2562 		(void) printf(gettext("  %s %s"), repaired,
2563 		    (vs->vs_scrub_type == POOL_SCRUB_RESILVER) ?
2564 		    "resilvered" : "repaired");
2565 	}
2566 
2567 	(void) printf("\n");
2568 
2569 	for (c = 0; c < children; c++) {
2570 		vname = zpool_vdev_name(g_zfs, zhp, child[c]);
2571 		print_status_config(zhp, vname, child[c],
2572 		    namewidth, depth + 2, isspare);
2573 		free(vname);
2574 	}
2575 }
2576 
2577 static void
2578 print_error_log(zpool_handle_t *zhp)
2579 {
2580 	nvlist_t **log;
2581 	size_t nelem;
2582 	size_t maxdsname = sizeof ("DATASET") - 1;
2583 	size_t maxobjname = sizeof ("OBJECT") - 1;
2584 	int i;
2585 	nvlist_t *nv;
2586 	size_t len;
2587 	char *dsname, *objname, *range;
2588 
2589 	if (zpool_get_errlog(zhp, &log, &nelem) != 0) {
2590 		(void) printf("errors: List of errors unavailable "
2591 		    "(insufficient privileges)\n");
2592 		return;
2593 	}
2594 
2595 	for (i = 0; i < nelem; i++) {
2596 		nv = log[i];
2597 
2598 		verify(nvlist_lookup_string(nv, ZPOOL_ERR_DATASET,
2599 		    &dsname) == 0);
2600 		len = strlen(dsname);
2601 		if (len > maxdsname)
2602 			maxdsname = len;
2603 
2604 		verify(nvlist_lookup_string(nv, ZPOOL_ERR_OBJECT,
2605 		    &objname) == 0);
2606 		len = strlen(objname);
2607 		if (len > maxobjname)
2608 			maxobjname = len;
2609 	}
2610 
2611 	(void) printf("errors: The following persistent errors have been "
2612 	    "detected:\n\n");
2613 	(void) printf("%8s  %-*s  %-*s  %s\n", "", maxdsname, "DATASET",
2614 	    maxobjname, "OBJECT", "RANGE");
2615 
2616 	for (i = 0; i < nelem; i++) {
2617 		nv = log[i];
2618 
2619 		verify(nvlist_lookup_string(nv, ZPOOL_ERR_DATASET,
2620 		    &dsname) == 0);
2621 		verify(nvlist_lookup_string(nv, ZPOOL_ERR_OBJECT,
2622 		    &objname) == 0);
2623 		verify(nvlist_lookup_string(nv, ZPOOL_ERR_RANGE,
2624 		    &range) == 0);
2625 
2626 		(void) printf("%8s  %-*s  %-*s  %s\n", "", maxdsname,
2627 		    dsname, maxobjname, objname, range);
2628 	}
2629 }
2630 
2631 static void
2632 print_spares(zpool_handle_t *zhp, nvlist_t **spares, uint_t nspares,
2633     int namewidth)
2634 {
2635 	uint_t i;
2636 	char *name;
2637 
2638 	if (nspares == 0)
2639 		return;
2640 
2641 	(void) printf(gettext("\tspares\n"));
2642 
2643 	for (i = 0; i < nspares; i++) {
2644 		name = zpool_vdev_name(g_zfs, zhp, spares[i]);
2645 		print_status_config(zhp, name, spares[i],
2646 		    namewidth, 2, B_TRUE);
2647 		free(name);
2648 	}
2649 }
2650 
2651 /*
2652  * Display a summary of pool status.  Displays a summary such as:
2653  *
2654  *        pool: tank
2655  *	status: DEGRADED
2656  *	reason: One or more devices ...
2657  *         see: http://www.sun.com/msg/ZFS-xxxx-01
2658  *	config:
2659  *		mirror		DEGRADED
2660  *                c1t0d0	OK
2661  *                c2t0d0	UNAVAIL
2662  *
2663  * When given the '-v' option, we print out the complete config.  If the '-e'
2664  * option is specified, then we print out error rate information as well.
2665  */
2666 int
2667 status_callback(zpool_handle_t *zhp, void *data)
2668 {
2669 	status_cbdata_t *cbp = data;
2670 	nvlist_t *config, *nvroot;
2671 	char *msgid;
2672 	int reason;
2673 	char *health;
2674 
2675 	config = zpool_get_config(zhp, NULL);
2676 	reason = zpool_get_status(zhp, &msgid);
2677 
2678 	cbp->cb_count++;
2679 
2680 	/*
2681 	 * If we were given 'zpool status -x', only report those pools with
2682 	 * problems.
2683 	 */
2684 	if (reason == ZPOOL_STATUS_OK && cbp->cb_explain)
2685 		return (0);
2686 
2687 	if (cbp->cb_first)
2688 		cbp->cb_first = B_FALSE;
2689 	else
2690 		(void) printf("\n");
2691 
2692 	verify(nvlist_lookup_string(config, ZPOOL_CONFIG_POOL_HEALTH,
2693 	    &health) == 0);
2694 
2695 	(void) printf(gettext("  pool: %s\n"), zpool_get_name(zhp));
2696 	(void) printf(gettext(" state: %s\n"), health);
2697 
2698 	switch (reason) {
2699 	case ZPOOL_STATUS_MISSING_DEV_R:
2700 		(void) printf(gettext("status: One or more devices could not "
2701 		    "be opened.  Sufficient replicas exist for\n\tthe pool to "
2702 		    "continue functioning in a degraded state.\n"));
2703 		(void) printf(gettext("action: Attach the missing device and "
2704 		    "online it using 'zpool online'.\n"));
2705 		break;
2706 
2707 	case ZPOOL_STATUS_MISSING_DEV_NR:
2708 		(void) printf(gettext("status: One or more devices could not "
2709 		    "be opened.  There are insufficient\n\treplicas for the "
2710 		    "pool to continue functioning.\n"));
2711 		(void) printf(gettext("action: Attach the missing device and "
2712 		    "online it using 'zpool online'.\n"));
2713 		break;
2714 
2715 	case ZPOOL_STATUS_CORRUPT_LABEL_R:
2716 		(void) printf(gettext("status: One or more devices could not "
2717 		    "be used because the label is missing or\n\tinvalid.  "
2718 		    "Sufficient replicas exist for the pool to continue\n\t"
2719 		    "functioning in a degraded state.\n"));
2720 		(void) printf(gettext("action: Replace the device using "
2721 		    "'zpool replace'.\n"));
2722 		break;
2723 
2724 	case ZPOOL_STATUS_CORRUPT_LABEL_NR:
2725 		(void) printf(gettext("status: One or more devices could not "
2726 		    "be used because the the label is missing \n\tor invalid.  "
2727 		    "There are insufficient replicas for the pool to "
2728 		    "continue\n\tfunctioning.\n"));
2729 		(void) printf(gettext("action: Destroy and re-create the pool "
2730 		    "from a backup source.\n"));
2731 		break;
2732 
2733 	case ZPOOL_STATUS_FAILING_DEV:
2734 		(void) printf(gettext("status: One or more devices has "
2735 		    "experienced an unrecoverable error.  An\n\tattempt was "
2736 		    "made to correct the error.  Applications are "
2737 		    "unaffected.\n"));
2738 		(void) printf(gettext("action: Determine if the device needs "
2739 		    "to be replaced, and clear the errors\n\tusing "
2740 		    "'zpool clear' or replace the device with 'zpool "
2741 		    "replace'.\n"));
2742 		break;
2743 
2744 	case ZPOOL_STATUS_OFFLINE_DEV:
2745 		(void) printf(gettext("status: One or more devices has "
2746 		    "been taken offline by the adminstrator.\n\tSufficient "
2747 		    "replicas exist for the pool to continue functioning in "
2748 		    "a\n\tdegraded state.\n"));
2749 		(void) printf(gettext("action: Online the device using "
2750 		    "'zpool online' or replace the device with\n\t'zpool "
2751 		    "replace'.\n"));
2752 		break;
2753 
2754 	case ZPOOL_STATUS_RESILVERING:
2755 		(void) printf(gettext("status: One or more devices is "
2756 		    "currently being resilvered.  The pool will\n\tcontinue "
2757 		    "to function, possibly in a degraded state.\n"));
2758 		(void) printf(gettext("action: Wait for the resilver to "
2759 		    "complete.\n"));
2760 		break;
2761 
2762 	case ZPOOL_STATUS_CORRUPT_DATA:
2763 		(void) printf(gettext("status: One or more devices has "
2764 		    "experienced an error resulting in data\n\tcorruption.  "
2765 		    "Applications may be affected.\n"));
2766 		(void) printf(gettext("action: Restore the file in question "
2767 		    "if possible.  Otherwise restore the\n\tentire pool from "
2768 		    "backup.\n"));
2769 		break;
2770 
2771 	case ZPOOL_STATUS_CORRUPT_POOL:
2772 		(void) printf(gettext("status: The pool metadata is corrupted "
2773 		    "and the pool cannot be opened.\n"));
2774 		(void) printf(gettext("action: Destroy and re-create the pool "
2775 		    "from a backup source.\n"));
2776 		break;
2777 
2778 	case ZPOOL_STATUS_VERSION_OLDER:
2779 		(void) printf(gettext("status: The pool is formatted using an "
2780 		    "older on-disk format.  The pool can\n\tstill be used, but "
2781 		    "some features are unavailable.\n"));
2782 		(void) printf(gettext("action: Upgrade the pool using 'zpool "
2783 		    "upgrade'.  Once this is done, the\n\tpool will no longer "
2784 		    "be accessible on older software versions.\n"));
2785 		break;
2786 
2787 	case ZPOOL_STATUS_VERSION_NEWER:
2788 		(void) printf(gettext("status: The pool has been upgraded to a "
2789 		    "newer, incompatible on-disk version.\n\tThe pool cannot "
2790 		    "be accessed on this system.\n"));
2791 		(void) printf(gettext("action: Access the pool from a system "
2792 		    "running more recent software, or\n\trestore the pool from "
2793 		    "backup.\n"));
2794 		break;
2795 
2796 	default:
2797 		/*
2798 		 * The remaining errors can't actually be generated, yet.
2799 		 */
2800 		assert(reason == ZPOOL_STATUS_OK);
2801 	}
2802 
2803 	if (msgid != NULL)
2804 		(void) printf(gettext("   see: http://www.sun.com/msg/%s\n"),
2805 		    msgid);
2806 
2807 	if (config != NULL) {
2808 		int namewidth;
2809 		uint64_t nerr;
2810 		size_t realerr;
2811 		nvlist_t **spares;
2812 		uint_t nspares;
2813 
2814 		verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
2815 		    &nvroot) == 0);
2816 
2817 		(void) printf(gettext(" scrub: "));
2818 		print_scrub_status(nvroot);
2819 
2820 		namewidth = max_width(zhp, nvroot, 0, 0);
2821 		if (namewidth < 10)
2822 			namewidth = 10;
2823 
2824 		(void) printf(gettext("config:\n\n"));
2825 		(void) printf(gettext("\t%-*s  %-8s %5s %5s %5s\n"), namewidth,
2826 		    "NAME", "STATE", "READ", "WRITE", "CKSUM");
2827 		print_status_config(zhp, zpool_get_name(zhp), nvroot,
2828 		    namewidth, 0, B_FALSE);
2829 
2830 		if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_SPARES,
2831 		    &spares, &nspares) == 0)
2832 			print_spares(zhp, spares, nspares, namewidth);
2833 
2834 		if (nvlist_lookup_uint64(config, ZPOOL_CONFIG_ERRCOUNT,
2835 		    &nerr) == 0) {
2836 			/*
2837 			 * If the approximate error count is small, get a
2838 			 * precise count by fetching the entire log and
2839 			 * uniquifying the results.
2840 			 */
2841 			if (nerr < 100 && !cbp->cb_verbose &&
2842 			    zpool_get_errlog(zhp, NULL, &realerr) == 0)
2843 				nerr = realerr;
2844 
2845 			(void) printf("\n");
2846 
2847 			if (nerr == 0)
2848 				(void) printf(gettext("errors: No known data "
2849 				    "errors\n"));
2850 			else if (!cbp->cb_verbose)
2851 				(void) printf(gettext("errors: %d data errors, "
2852 				    "use '-v' for a list\n"), nerr);
2853 			else
2854 				print_error_log(zhp);
2855 		}
2856 	} else {
2857 		(void) printf(gettext("config: The configuration cannot be "
2858 		    "determined.\n"));
2859 	}
2860 
2861 	return (0);
2862 }
2863 
2864 /*
2865  * zpool status [-vx] [pool] ...
2866  *
2867  *	-v	Display complete error logs
2868  *	-x	Display only pools with potential problems
2869  *
2870  * Describes the health status of all pools or some subset.
2871  */
2872 int
2873 zpool_do_status(int argc, char **argv)
2874 {
2875 	int c;
2876 	int ret;
2877 	status_cbdata_t cb = { 0 };
2878 
2879 	/* check options */
2880 	while ((c = getopt(argc, argv, "vx")) != -1) {
2881 		switch (c) {
2882 		case 'v':
2883 			cb.cb_verbose = B_TRUE;
2884 			break;
2885 		case 'x':
2886 			cb.cb_explain = B_TRUE;
2887 			break;
2888 		case '?':
2889 			(void) fprintf(stderr, gettext("invalid option '%c'\n"),
2890 			    optopt);
2891 			usage(B_FALSE);
2892 		}
2893 	}
2894 
2895 	argc -= optind;
2896 	argv += optind;
2897 
2898 	cb.cb_first = B_TRUE;
2899 
2900 	ret = for_each_pool(argc, argv, B_TRUE, status_callback, &cb);
2901 
2902 	if (argc == 0 && cb.cb_count == 0)
2903 		(void) printf(gettext("no pools available\n"));
2904 	else if (cb.cb_explain && cb.cb_first) {
2905 		if (argc == 0) {
2906 			(void) printf(gettext("all pools are healthy\n"));
2907 		} else {
2908 			int i;
2909 			for (i = 0; i < argc; i++)
2910 				(void) printf(gettext("pool '%s' is healthy\n"),
2911 				    argv[i]);
2912 		}
2913 	}
2914 
2915 	return (ret);
2916 }
2917 
2918 typedef struct upgrade_cbdata {
2919 	int	cb_all;
2920 	int	cb_first;
2921 	int	cb_newer;
2922 } upgrade_cbdata_t;
2923 
2924 static int
2925 upgrade_cb(zpool_handle_t *zhp, void *arg)
2926 {
2927 	upgrade_cbdata_t *cbp = arg;
2928 	nvlist_t *config;
2929 	uint64_t version;
2930 	int ret = 0;
2931 
2932 	config = zpool_get_config(zhp, NULL);
2933 	verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION,
2934 	    &version) == 0);
2935 
2936 	if (!cbp->cb_newer && version < ZFS_VERSION) {
2937 		if (!cbp->cb_all) {
2938 			if (cbp->cb_first) {
2939 				(void) printf(gettext("The following pools are "
2940 				    "out of date, and can be upgraded.  After "
2941 				    "being\nupgraded, these pools will no "
2942 				    "longer be accessible by older software "
2943 				    "versions.\n\n"));
2944 				(void) printf(gettext("VER  POOL\n"));
2945 				(void) printf(gettext("---  ------------\n"));
2946 				cbp->cb_first = B_FALSE;
2947 			}
2948 
2949 			(void) printf("%2llu   %s\n", version,
2950 			    zpool_get_name(zhp));
2951 		} else {
2952 			cbp->cb_first = B_FALSE;
2953 			ret = zpool_upgrade(zhp);
2954 			if (ret == 0)
2955 				(void) printf(gettext("Successfully upgraded "
2956 				    "'%s'\n"), zpool_get_name(zhp));
2957 		}
2958 	} else if (cbp->cb_newer && version > ZFS_VERSION) {
2959 		assert(!cbp->cb_all);
2960 
2961 		if (cbp->cb_first) {
2962 			(void) printf(gettext("The following pools are "
2963 			    "formatted using a newer software version and\n"
2964 			    "cannot be accessed on the current system.\n\n"));
2965 			(void) printf(gettext("VER  POOL\n"));
2966 			(void) printf(gettext("---  ------------\n"));
2967 			cbp->cb_first = B_FALSE;
2968 		}
2969 
2970 		(void) printf("%2llu   %s\n", version,
2971 		    zpool_get_name(zhp));
2972 	}
2973 
2974 	zpool_close(zhp);
2975 	return (ret);
2976 }
2977 
2978 /* ARGSUSED */
2979 static int
2980 upgrade_one(zpool_handle_t *zhp, void *unused)
2981 {
2982 	nvlist_t *config;
2983 	uint64_t version;
2984 	int ret;
2985 
2986 	config = zpool_get_config(zhp, NULL);
2987 	verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION,
2988 	    &version) == 0);
2989 
2990 	if (version == ZFS_VERSION) {
2991 		(void) printf(gettext("Pool '%s' is already formatted "
2992 		    "using the current version.\n"), zpool_get_name(zhp));
2993 		return (0);
2994 	}
2995 
2996 	ret = zpool_upgrade(zhp);
2997 	if (ret == 0)
2998 		(void) printf(gettext("Successfully upgraded '%s' "
2999 		    "from version %llu to version %llu\n"), zpool_get_name(zhp),
3000 		    (u_longlong_t)version, (u_longlong_t)ZFS_VERSION);
3001 
3002 	return (ret != 0);
3003 }
3004 
3005 /*
3006  * zpool upgrade
3007  * zpool upgrade -v
3008  * zpool upgrade <-a | pool>
3009  *
3010  * With no arguments, display downrev'd ZFS pool available for upgrade.
3011  * Individual pools can be upgraded by specifying the pool, and '-a' will
3012  * upgrade all pools.
3013  */
3014 int
3015 zpool_do_upgrade(int argc, char **argv)
3016 {
3017 	int c;
3018 	upgrade_cbdata_t cb = { 0 };
3019 	int ret = 0;
3020 	boolean_t showversions = B_FALSE;
3021 
3022 	/* check options */
3023 	while ((c = getopt(argc, argv, "av")) != -1) {
3024 		switch (c) {
3025 		case 'a':
3026 			cb.cb_all = B_TRUE;
3027 			break;
3028 		case 'v':
3029 			showversions = B_TRUE;
3030 			break;
3031 		case '?':
3032 			(void) fprintf(stderr, gettext("invalid option '%c'\n"),
3033 			    optopt);
3034 			usage(B_FALSE);
3035 		}
3036 	}
3037 
3038 	argc -= optind;
3039 	argv += optind;
3040 
3041 	if (showversions) {
3042 		if (cb.cb_all || argc != 0) {
3043 			(void) fprintf(stderr, gettext("-v option is "
3044 			    "incompatible with other arguments\n"));
3045 			usage(B_FALSE);
3046 		}
3047 	} else if (cb.cb_all) {
3048 		if (argc != 0) {
3049 			(void) fprintf(stderr, gettext("-a option is "
3050 			    "incompatible with other arguments\n"));
3051 			usage(B_FALSE);
3052 		}
3053 	}
3054 
3055 	(void) printf(gettext("This system is currently running ZFS version "
3056 	    "%llu.\n\n"), ZFS_VERSION);
3057 	cb.cb_first = B_TRUE;
3058 	if (showversions) {
3059 		(void) printf(gettext("The following versions are "
3060 		    "suppored:\n\n"));
3061 		(void) printf(gettext("VER  DESCRIPTION\n"));
3062 		(void) printf("---  -----------------------------------------"
3063 		    "---------------\n");
3064 		(void) printf(gettext(" 1   Initial ZFS version\n"));
3065 		(void) printf(gettext(" 2   Ditto blocks "
3066 		    "(replicated metadata)\n"));
3067 		(void) printf(gettext(" 3   Hot spares and double parity "
3068 		    "RAID-Z\n"));
3069 		(void) printf(gettext("\nFor more information on a particular "
3070 		    "version, including supported releases, see:\n\n"));
3071 		(void) printf("http://www.opensolaris.org/os/community/zfs/"
3072 		    "version/N\n\n");
3073 		(void) printf(gettext("Where 'N' is the version number.\n"));
3074 	} else if (argc == 0) {
3075 		int notfound;
3076 
3077 		ret = zpool_iter(g_zfs, upgrade_cb, &cb);
3078 		notfound = cb.cb_first;
3079 
3080 		if (!cb.cb_all && ret == 0) {
3081 			if (!cb.cb_first)
3082 				(void) printf("\n");
3083 			cb.cb_first = B_TRUE;
3084 			cb.cb_newer = B_TRUE;
3085 			ret = zpool_iter(g_zfs, upgrade_cb, &cb);
3086 			if (!cb.cb_first) {
3087 				notfound = B_FALSE;
3088 				(void) printf("\n");
3089 			}
3090 		}
3091 
3092 		if (ret == 0) {
3093 			if (notfound)
3094 				(void) printf(gettext("All pools are formatted "
3095 				    "using this version.\n"));
3096 			else if (!cb.cb_all)
3097 				(void) printf(gettext("Use 'zpool upgrade -v' "
3098 				    "for a list of available versions and "
3099 				    "their associated\nfeatures.\n"));
3100 		}
3101 	} else {
3102 		ret = for_each_pool(argc, argv, B_FALSE, upgrade_one, NULL);
3103 	}
3104 
3105 	return (ret);
3106 }
3107 
3108 int
3109 main(int argc, char **argv)
3110 {
3111 	int ret;
3112 	int i;
3113 	char *cmdname;
3114 
3115 	(void) setlocale(LC_ALL, "");
3116 	(void) textdomain(TEXT_DOMAIN);
3117 
3118 	if ((g_zfs = libzfs_init()) == NULL) {
3119 		(void) fprintf(stderr, gettext("internal error: failed to "
3120 		    "initialize ZFS library"));
3121 		return (1);
3122 	}
3123 
3124 	libzfs_print_on_error(g_zfs, B_TRUE);
3125 
3126 	opterr = 0;
3127 
3128 	/*
3129 	 * Make sure the user has specified some command.
3130 	 */
3131 	if (argc < 2) {
3132 		(void) fprintf(stderr, gettext("missing command\n"));
3133 		usage(B_FALSE);
3134 	}
3135 
3136 	cmdname = argv[1];
3137 
3138 	/*
3139 	 * Special case '-?'
3140 	 */
3141 	if (strcmp(cmdname, "-?") == 0)
3142 		usage(B_TRUE);
3143 
3144 	/*
3145 	 * Run the appropriate command.
3146 	 */
3147 	for (i = 0; i < NCOMMAND; i++) {
3148 		if (command_table[i].name == NULL)
3149 			continue;
3150 
3151 		if (strcmp(cmdname, command_table[i].name) == 0) {
3152 			current_command = &command_table[i];
3153 			ret = command_table[i].func(argc - 1, argv + 1);
3154 			break;
3155 		}
3156 	}
3157 
3158 	/*
3159 	 * 'freeze' is a vile debugging abomination, so we treat it as such.
3160 	 */
3161 	if (strcmp(cmdname, "freeze") == 0 && argc == 3) {
3162 		char buf[16384];
3163 		int fd = open(ZFS_DEV, O_RDWR);
3164 		(void) strcpy((void *)buf, argv[2]);
3165 		return (!!ioctl(fd, ZFS_IOC_POOL_FREEZE, buf));
3166 	}
3167 
3168 	if (i == NCOMMAND) {
3169 		(void) fprintf(stderr, gettext("unrecognized "
3170 		    "command '%s'\n"), cmdname);
3171 		usage(B_FALSE);
3172 	}
3173 
3174 	libzfs_fini(g_zfs);
3175 
3176 	/*
3177 	 * The 'ZFS_ABORT' environment variable causes us to dump core on exit
3178 	 * for the purposes of running ::findleaks.
3179 	 */
3180 	if (getenv("ZFS_ABORT") != NULL) {
3181 		(void) printf("dumping core by request\n");
3182 		abort();
3183 	}
3184 
3185 	return (ret);
3186 }
3187