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