xref: /illumos-gate/usr/src/cmd/zpool/zpool_main.c (revision edc8ef7d921c96b23969898aeb766cb24960bda7)
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 (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
24  * Copyright (c) 2011, 2018 by Delphix. All rights reserved.
25  * Copyright (c) 2012 by Frederik Wessels. All rights reserved.
26  * Copyright (c) 2013 by Prasad Joshi (sTec). All rights reserved.
27  * Copyright 2016 Igor Kozhukhov <ikozhukhov@gmail.com>.
28  * Copyright 2016 Nexenta Systems, Inc.
29  * Copyright (c) 2017 Datto Inc.
30  */
31 
32 #include <assert.h>
33 #include <ctype.h>
34 #include <dirent.h>
35 #include <errno.h>
36 #include <fcntl.h>
37 #include <libgen.h>
38 #include <libintl.h>
39 #include <libuutil.h>
40 #include <locale.h>
41 #include <stdio.h>
42 #include <stdlib.h>
43 #include <string.h>
44 #include <strings.h>
45 #include <unistd.h>
46 #include <priv.h>
47 #include <pwd.h>
48 #include <zone.h>
49 #include <zfs_prop.h>
50 #include <sys/fs/zfs.h>
51 #include <sys/stat.h>
52 
53 #include <libzfs.h>
54 
55 #include "zpool_util.h"
56 #include "zfs_comutil.h"
57 #include "zfeature_common.h"
58 
59 #include "statcommon.h"
60 
61 static int zpool_do_create(int, char **);
62 static int zpool_do_destroy(int, char **);
63 
64 static int zpool_do_add(int, char **);
65 static int zpool_do_remove(int, char **);
66 static int zpool_do_labelclear(int, char **);
67 
68 static int zpool_do_list(int, char **);
69 static int zpool_do_iostat(int, char **);
70 static int zpool_do_status(int, char **);
71 
72 static int zpool_do_online(int, char **);
73 static int zpool_do_offline(int, char **);
74 static int zpool_do_clear(int, char **);
75 static int zpool_do_reopen(int, char **);
76 
77 static int zpool_do_reguid(int, char **);
78 
79 static int zpool_do_attach(int, char **);
80 static int zpool_do_detach(int, char **);
81 static int zpool_do_replace(int, char **);
82 static int zpool_do_split(int, char **);
83 
84 static int zpool_do_scrub(int, char **);
85 
86 static int zpool_do_import(int, char **);
87 static int zpool_do_export(int, char **);
88 
89 static int zpool_do_upgrade(int, char **);
90 
91 static int zpool_do_history(int, char **);
92 
93 static int zpool_do_get(int, char **);
94 static int zpool_do_set(int, char **);
95 
96 /*
97  * These libumem hooks provide a reasonable set of defaults for the allocator's
98  * debugging facilities.
99  */
100 
101 #ifdef DEBUG
102 const char *
103 _umem_debug_init(void)
104 {
105 	return ("default,verbose"); /* $UMEM_DEBUG setting */
106 }
107 
108 const char *
109 _umem_logging_init(void)
110 {
111 	return ("fail,contents"); /* $UMEM_LOGGING setting */
112 }
113 #endif
114 
115 typedef enum {
116 	HELP_ADD,
117 	HELP_ATTACH,
118 	HELP_CLEAR,
119 	HELP_CREATE,
120 	HELP_DESTROY,
121 	HELP_DETACH,
122 	HELP_EXPORT,
123 	HELP_HISTORY,
124 	HELP_IMPORT,
125 	HELP_IOSTAT,
126 	HELP_LABELCLEAR,
127 	HELP_LIST,
128 	HELP_OFFLINE,
129 	HELP_ONLINE,
130 	HELP_REPLACE,
131 	HELP_REMOVE,
132 	HELP_SCRUB,
133 	HELP_STATUS,
134 	HELP_UPGRADE,
135 	HELP_GET,
136 	HELP_SET,
137 	HELP_SPLIT,
138 	HELP_REGUID,
139 	HELP_REOPEN
140 } zpool_help_t;
141 
142 
143 typedef struct zpool_command {
144 	const char	*name;
145 	int		(*func)(int, char **);
146 	zpool_help_t	usage;
147 } zpool_command_t;
148 
149 /*
150  * Master command table.  Each ZFS command has a name, associated function, and
151  * usage message.  The usage messages need to be internationalized, so we have
152  * to have a function to return the usage message based on a command index.
153  *
154  * These commands are organized according to how they are displayed in the usage
155  * message.  An empty command (one with a NULL name) indicates an empty line in
156  * the generic usage message.
157  */
158 static zpool_command_t command_table[] = {
159 	{ "create",	zpool_do_create,	HELP_CREATE		},
160 	{ "destroy",	zpool_do_destroy,	HELP_DESTROY		},
161 	{ NULL },
162 	{ "add",	zpool_do_add,		HELP_ADD		},
163 	{ "remove",	zpool_do_remove,	HELP_REMOVE		},
164 	{ NULL },
165 	{ "labelclear",	zpool_do_labelclear,	HELP_LABELCLEAR		},
166 	{ NULL },
167 	{ "list",	zpool_do_list,		HELP_LIST		},
168 	{ "iostat",	zpool_do_iostat,	HELP_IOSTAT		},
169 	{ "status",	zpool_do_status,	HELP_STATUS		},
170 	{ NULL },
171 	{ "online",	zpool_do_online,	HELP_ONLINE		},
172 	{ "offline",	zpool_do_offline,	HELP_OFFLINE		},
173 	{ "clear",	zpool_do_clear,		HELP_CLEAR		},
174 	{ "reopen",	zpool_do_reopen,	HELP_REOPEN		},
175 	{ NULL },
176 	{ "attach",	zpool_do_attach,	HELP_ATTACH		},
177 	{ "detach",	zpool_do_detach,	HELP_DETACH		},
178 	{ "replace",	zpool_do_replace,	HELP_REPLACE		},
179 	{ "split",	zpool_do_split,		HELP_SPLIT		},
180 	{ NULL },
181 	{ "scrub",	zpool_do_scrub,		HELP_SCRUB		},
182 	{ NULL },
183 	{ "import",	zpool_do_import,	HELP_IMPORT		},
184 	{ "export",	zpool_do_export,	HELP_EXPORT		},
185 	{ "upgrade",	zpool_do_upgrade,	HELP_UPGRADE		},
186 	{ "reguid",	zpool_do_reguid,	HELP_REGUID		},
187 	{ NULL },
188 	{ "history",	zpool_do_history,	HELP_HISTORY		},
189 	{ "get",	zpool_do_get,		HELP_GET		},
190 	{ "set",	zpool_do_set,		HELP_SET		},
191 };
192 
193 #define	NCOMMAND	(sizeof (command_table) / sizeof (command_table[0]))
194 
195 static zpool_command_t *current_command;
196 static char history_str[HIS_MAX_RECORD_LEN];
197 static boolean_t log_history = B_TRUE;
198 static uint_t timestamp_fmt = NODATE;
199 
200 static const char *
201 get_usage(zpool_help_t idx)
202 {
203 	switch (idx) {
204 	case HELP_ADD:
205 		return (gettext("\tadd [-fn] <pool> <vdev> ...\n"));
206 	case HELP_ATTACH:
207 		return (gettext("\tattach [-f] <pool> <device> "
208 		    "<new-device>\n"));
209 	case HELP_CLEAR:
210 		return (gettext("\tclear [-nF] <pool> [device]\n"));
211 	case HELP_CREATE:
212 		return (gettext("\tcreate [-fnd] [-B] "
213 		    "[-o property=value] ... \n"
214 		    "\t    [-O file-system-property=value] ... \n"
215 		    "\t    [-m mountpoint] [-R root] <pool> <vdev> ...\n"));
216 	case HELP_DESTROY:
217 		return (gettext("\tdestroy [-f] <pool>\n"));
218 	case HELP_DETACH:
219 		return (gettext("\tdetach <pool> <device>\n"));
220 	case HELP_EXPORT:
221 		return (gettext("\texport [-f] <pool> ...\n"));
222 	case HELP_HISTORY:
223 		return (gettext("\thistory [-il] [<pool>] ...\n"));
224 	case HELP_IMPORT:
225 		return (gettext("\timport [-d dir] [-D]\n"
226 		    "\timport [-d dir | -c cachefile] [-F [-n]] <pool | id>\n"
227 		    "\timport [-o mntopts] [-o property=value] ... \n"
228 		    "\t    [-d dir | -c cachefile] [-D] [-f] [-m] [-N] "
229 		    "[-R root] [-F [-n]] -a\n"
230 		    "\timport [-o mntopts] [-o property=value] ... \n"
231 		    "\t    [-d dir | -c cachefile] [-D] [-f] [-m] [-N] "
232 		    "[-R root] [-F [-n]]\n"
233 		    "\t    <pool | id> [newpool]\n"));
234 	case HELP_IOSTAT:
235 		return (gettext("\tiostat [-v] [-T d|u] [pool] ... [interval "
236 		    "[count]]\n"));
237 	case HELP_LABELCLEAR:
238 		return (gettext("\tlabelclear [-f] <vdev>\n"));
239 	case HELP_LIST:
240 		return (gettext("\tlist [-Hp] [-o property[,...]] "
241 		    "[-T d|u] [pool] ... [interval [count]]\n"));
242 	case HELP_OFFLINE:
243 		return (gettext("\toffline [-t] <pool> <device> ...\n"));
244 	case HELP_ONLINE:
245 		return (gettext("\tonline <pool> <device> ...\n"));
246 	case HELP_REPLACE:
247 		return (gettext("\treplace [-f] <pool> <device> "
248 		    "[new-device]\n"));
249 	case HELP_REMOVE:
250 		return (gettext("\tremove [-nps] <pool> <device> ...\n"));
251 	case HELP_REOPEN:
252 		return (gettext("\treopen <pool>\n"));
253 	case HELP_SCRUB:
254 		return (gettext("\tscrub [-s | -p] <pool> ...\n"));
255 	case HELP_STATUS:
256 		return (gettext("\tstatus [-vx] [-T d|u] [pool] ... [interval "
257 		    "[count]]\n"));
258 	case HELP_UPGRADE:
259 		return (gettext("\tupgrade\n"
260 		    "\tupgrade -v\n"
261 		    "\tupgrade [-V version] <-a | pool ...>\n"));
262 	case HELP_GET:
263 		return (gettext("\tget [-Hp] [-o \"all\" | field[,...]] "
264 		    "<\"all\" | property[,...]> <pool> ...\n"));
265 	case HELP_SET:
266 		return (gettext("\tset <property=value> <pool> \n"));
267 	case HELP_SPLIT:
268 		return (gettext("\tsplit [-n] [-R altroot] [-o mntopts]\n"
269 		    "\t    [-o property=value] <pool> <newpool> "
270 		    "[<device> ...]\n"));
271 	case HELP_REGUID:
272 		return (gettext("\treguid <pool>\n"));
273 	}
274 
275 	abort();
276 	/* NOTREACHED */
277 }
278 
279 
280 /*
281  * Callback routine that will print out a pool property value.
282  */
283 static int
284 print_prop_cb(int prop, void *cb)
285 {
286 	FILE *fp = cb;
287 
288 	(void) fprintf(fp, "\t%-15s  ", zpool_prop_to_name(prop));
289 
290 	if (zpool_prop_readonly(prop))
291 		(void) fprintf(fp, "  NO   ");
292 	else
293 		(void) fprintf(fp, " YES   ");
294 
295 	if (zpool_prop_values(prop) == NULL)
296 		(void) fprintf(fp, "-\n");
297 	else
298 		(void) fprintf(fp, "%s\n", zpool_prop_values(prop));
299 
300 	return (ZPROP_CONT);
301 }
302 
303 /*
304  * Display usage message.  If we're inside a command, display only the usage for
305  * that command.  Otherwise, iterate over the entire command table and display
306  * a complete usage message.
307  */
308 void
309 usage(boolean_t requested)
310 {
311 	FILE *fp = requested ? stdout : stderr;
312 
313 	if (current_command == NULL) {
314 		int i;
315 
316 		(void) fprintf(fp, gettext("usage: zpool command args ...\n"));
317 		(void) fprintf(fp,
318 		    gettext("where 'command' is one of the following:\n\n"));
319 
320 		for (i = 0; i < NCOMMAND; i++) {
321 			if (command_table[i].name == NULL)
322 				(void) fprintf(fp, "\n");
323 			else
324 				(void) fprintf(fp, "%s",
325 				    get_usage(command_table[i].usage));
326 		}
327 	} else {
328 		(void) fprintf(fp, gettext("usage:\n"));
329 		(void) fprintf(fp, "%s", get_usage(current_command->usage));
330 	}
331 
332 	if (current_command != NULL &&
333 	    ((strcmp(current_command->name, "set") == 0) ||
334 	    (strcmp(current_command->name, "get") == 0) ||
335 	    (strcmp(current_command->name, "list") == 0))) {
336 
337 		(void) fprintf(fp,
338 		    gettext("\nthe following properties are supported:\n"));
339 
340 		(void) fprintf(fp, "\n\t%-15s  %s   %s\n\n",
341 		    "PROPERTY", "EDIT", "VALUES");
342 
343 		/* Iterate over all properties */
344 		(void) zprop_iter(print_prop_cb, fp, B_FALSE, B_TRUE,
345 		    ZFS_TYPE_POOL);
346 
347 		(void) fprintf(fp, "\t%-15s   ", "feature@...");
348 		(void) fprintf(fp, "YES   disabled | enabled | active\n");
349 
350 		(void) fprintf(fp, gettext("\nThe feature@ properties must be "
351 		    "appended with a feature name.\nSee zpool-features(5).\n"));
352 	}
353 
354 	/*
355 	 * See comments at end of main().
356 	 */
357 	if (getenv("ZFS_ABORT") != NULL) {
358 		(void) printf("dumping core by request\n");
359 		abort();
360 	}
361 
362 	exit(requested ? 0 : 2);
363 }
364 
365 void
366 print_vdev_tree(zpool_handle_t *zhp, const char *name, nvlist_t *nv, int indent,
367     boolean_t print_logs)
368 {
369 	nvlist_t **child;
370 	uint_t c, children;
371 	char *vname;
372 
373 	if (name != NULL)
374 		(void) printf("\t%*s%s\n", indent, "", name);
375 
376 	if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
377 	    &child, &children) != 0)
378 		return;
379 
380 	for (c = 0; c < children; c++) {
381 		uint64_t is_log = B_FALSE;
382 
383 		(void) nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_LOG,
384 		    &is_log);
385 		if ((is_log && !print_logs) || (!is_log && print_logs))
386 			continue;
387 
388 		vname = zpool_vdev_name(g_zfs, zhp, child[c], B_FALSE);
389 		print_vdev_tree(zhp, vname, child[c], indent + 2,
390 		    B_FALSE);
391 		free(vname);
392 	}
393 }
394 
395 static boolean_t
396 prop_list_contains_feature(nvlist_t *proplist)
397 {
398 	nvpair_t *nvp;
399 	for (nvp = nvlist_next_nvpair(proplist, NULL); NULL != nvp;
400 	    nvp = nvlist_next_nvpair(proplist, nvp)) {
401 		if (zpool_prop_feature(nvpair_name(nvp)))
402 			return (B_TRUE);
403 	}
404 	return (B_FALSE);
405 }
406 
407 /*
408  * Add a property pair (name, string-value) into a property nvlist.
409  */
410 static int
411 add_prop_list(const char *propname, char *propval, nvlist_t **props,
412     boolean_t poolprop)
413 {
414 	zpool_prop_t prop = ZPOOL_PROP_INVAL;
415 	zfs_prop_t fprop;
416 	nvlist_t *proplist;
417 	const char *normnm;
418 	char *strval;
419 
420 	if (*props == NULL &&
421 	    nvlist_alloc(props, NV_UNIQUE_NAME, 0) != 0) {
422 		(void) fprintf(stderr,
423 		    gettext("internal error: out of memory\n"));
424 		return (1);
425 	}
426 
427 	proplist = *props;
428 
429 	if (poolprop) {
430 		const char *vname = zpool_prop_to_name(ZPOOL_PROP_VERSION);
431 
432 		if ((prop = zpool_name_to_prop(propname)) == ZPOOL_PROP_INVAL &&
433 		    !zpool_prop_feature(propname)) {
434 			(void) fprintf(stderr, gettext("property '%s' is "
435 			    "not a valid pool property\n"), propname);
436 			return (2);
437 		}
438 
439 		/*
440 		 * feature@ properties and version should not be specified
441 		 * at the same time.
442 		 */
443 		if ((prop == ZPOOL_PROP_INVAL && zpool_prop_feature(propname) &&
444 		    nvlist_exists(proplist, vname)) ||
445 		    (prop == ZPOOL_PROP_VERSION &&
446 		    prop_list_contains_feature(proplist))) {
447 			(void) fprintf(stderr, gettext("'feature@' and "
448 			    "'version' properties cannot be specified "
449 			    "together\n"));
450 			return (2);
451 		}
452 
453 
454 		if (zpool_prop_feature(propname))
455 			normnm = propname;
456 		else
457 			normnm = zpool_prop_to_name(prop);
458 	} else {
459 		if ((fprop = zfs_name_to_prop(propname)) != ZPROP_INVAL) {
460 			normnm = zfs_prop_to_name(fprop);
461 		} else {
462 			normnm = propname;
463 		}
464 	}
465 
466 	if (nvlist_lookup_string(proplist, normnm, &strval) == 0 &&
467 	    prop != ZPOOL_PROP_CACHEFILE) {
468 		(void) fprintf(stderr, gettext("property '%s' "
469 		    "specified multiple times\n"), propname);
470 		return (2);
471 	}
472 
473 	if (nvlist_add_string(proplist, normnm, propval) != 0) {
474 		(void) fprintf(stderr, gettext("internal "
475 		    "error: out of memory\n"));
476 		return (1);
477 	}
478 
479 	return (0);
480 }
481 
482 /*
483  * zpool add [-fn] <pool> <vdev> ...
484  *
485  *	-f	Force addition of devices, even if they appear in use
486  *	-n	Do not add the devices, but display the resulting layout if
487  *		they were to be added.
488  *
489  * Adds the given vdevs to 'pool'.  As with create, the bulk of this work is
490  * handled by get_vdev_spec(), which constructs the nvlist needed to pass to
491  * libzfs.
492  */
493 int
494 zpool_do_add(int argc, char **argv)
495 {
496 	boolean_t force = B_FALSE;
497 	boolean_t dryrun = B_FALSE;
498 	int c;
499 	nvlist_t *nvroot;
500 	char *poolname;
501 	zpool_boot_label_t boot_type;
502 	uint64_t boot_size;
503 	int ret;
504 	zpool_handle_t *zhp;
505 	nvlist_t *config;
506 
507 	/* check options */
508 	while ((c = getopt(argc, argv, "fn")) != -1) {
509 		switch (c) {
510 		case 'f':
511 			force = B_TRUE;
512 			break;
513 		case 'n':
514 			dryrun = B_TRUE;
515 			break;
516 		case '?':
517 			(void) fprintf(stderr, gettext("invalid option '%c'\n"),
518 			    optopt);
519 			usage(B_FALSE);
520 		}
521 	}
522 
523 	argc -= optind;
524 	argv += optind;
525 
526 	/* get pool name and check number of arguments */
527 	if (argc < 1) {
528 		(void) fprintf(stderr, gettext("missing pool name argument\n"));
529 		usage(B_FALSE);
530 	}
531 	if (argc < 2) {
532 		(void) fprintf(stderr, gettext("missing vdev specification\n"));
533 		usage(B_FALSE);
534 	}
535 
536 	poolname = argv[0];
537 
538 	argc--;
539 	argv++;
540 
541 	if ((zhp = zpool_open(g_zfs, poolname)) == NULL)
542 		return (1);
543 
544 	if ((config = zpool_get_config(zhp, NULL)) == NULL) {
545 		(void) fprintf(stderr, gettext("pool '%s' is unavailable\n"),
546 		    poolname);
547 		zpool_close(zhp);
548 		return (1);
549 	}
550 
551 	if (zpool_is_bootable(zhp))
552 		boot_type = ZPOOL_COPY_BOOT_LABEL;
553 	else
554 		boot_type = ZPOOL_NO_BOOT_LABEL;
555 
556 	/* pass off to get_vdev_spec for processing */
557 	boot_size = zpool_get_prop_int(zhp, ZPOOL_PROP_BOOTSIZE, NULL);
558 	nvroot = make_root_vdev(zhp, force, !force, B_FALSE, dryrun,
559 	    boot_type, boot_size, argc, argv);
560 	if (nvroot == NULL) {
561 		zpool_close(zhp);
562 		return (1);
563 	}
564 
565 	if (dryrun) {
566 		nvlist_t *poolnvroot;
567 
568 		verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
569 		    &poolnvroot) == 0);
570 
571 		(void) printf(gettext("would update '%s' to the following "
572 		    "configuration:\n"), zpool_get_name(zhp));
573 
574 		/* print original main pool and new tree */
575 		print_vdev_tree(zhp, poolname, poolnvroot, 0, B_FALSE);
576 		print_vdev_tree(zhp, NULL, nvroot, 0, B_FALSE);
577 
578 		/* Do the same for the logs */
579 		if (num_logs(poolnvroot) > 0) {
580 			print_vdev_tree(zhp, "logs", poolnvroot, 0, B_TRUE);
581 			print_vdev_tree(zhp, NULL, nvroot, 0, B_TRUE);
582 		} else if (num_logs(nvroot) > 0) {
583 			print_vdev_tree(zhp, "logs", nvroot, 0, B_TRUE);
584 		}
585 
586 		ret = 0;
587 	} else {
588 		ret = (zpool_add(zhp, nvroot) != 0);
589 	}
590 
591 	nvlist_free(nvroot);
592 	zpool_close(zhp);
593 
594 	return (ret);
595 }
596 
597 /*
598  * zpool remove  <pool> <vdev> ...
599  *
600  * Removes the given vdev from the pool.
601  */
602 int
603 zpool_do_remove(int argc, char **argv)
604 {
605 	char *poolname;
606 	int i, ret = 0;
607 	zpool_handle_t *zhp;
608 	boolean_t stop = B_FALSE;
609 	boolean_t noop = B_FALSE;
610 	boolean_t parsable = B_FALSE;
611 	char c;
612 
613 	/* check options */
614 	while ((c = getopt(argc, argv, "nps")) != -1) {
615 		switch (c) {
616 		case 'n':
617 			noop = B_TRUE;
618 			break;
619 		case 'p':
620 			parsable = B_TRUE;
621 			break;
622 		case 's':
623 			stop = B_TRUE;
624 			break;
625 		case '?':
626 			(void) fprintf(stderr, gettext("invalid option '%c'\n"),
627 			    optopt);
628 			usage(B_FALSE);
629 		}
630 	}
631 
632 	argc -= optind;
633 	argv += optind;
634 
635 	/* get pool name and check number of arguments */
636 	if (argc < 1) {
637 		(void) fprintf(stderr, gettext("missing pool name argument\n"));
638 		usage(B_FALSE);
639 	}
640 
641 	poolname = argv[0];
642 
643 	if ((zhp = zpool_open(g_zfs, poolname)) == NULL)
644 		return (1);
645 
646 	if (stop && noop) {
647 		(void) fprintf(stderr, gettext("stop request ignored\n"));
648 		return (0);
649 	}
650 
651 	if (stop) {
652 		if (argc > 1) {
653 			(void) fprintf(stderr, gettext("too many arguments\n"));
654 			usage(B_FALSE);
655 		}
656 		if (zpool_vdev_remove_cancel(zhp) != 0)
657 			ret = 1;
658 	} else {
659 		if (argc < 2) {
660 			(void) fprintf(stderr, gettext("missing device\n"));
661 			usage(B_FALSE);
662 		}
663 
664 		for (i = 1; i < argc; i++) {
665 			if (noop) {
666 				uint64_t size;
667 
668 				if (zpool_vdev_indirect_size(zhp, argv[i],
669 				    &size) != 0) {
670 					ret = 1;
671 					break;
672 				}
673 				if (parsable) {
674 					(void) printf("%s %llu\n",
675 					    argv[i], size);
676 				} else {
677 					char valstr[32];
678 					zfs_nicenum(size, valstr,
679 					    sizeof (valstr));
680 					(void) printf("Memory that will be "
681 					    "used after removing %s: %s\n",
682 					    argv[i], valstr);
683 				}
684 			} else {
685 				if (zpool_vdev_remove(zhp, argv[i]) != 0)
686 					ret = 1;
687 			}
688 		}
689 	}
690 
691 	return (ret);
692 }
693 
694 /*
695  * zpool labelclear [-f] <vdev>
696  *
697  *	-f	Force clearing the label for the vdevs which are members of
698  *		the exported or foreign pools.
699  *
700  * Verifies that the vdev is not active and zeros out the label information
701  * on the device.
702  */
703 int
704 zpool_do_labelclear(int argc, char **argv)
705 {
706 	char vdev[MAXPATHLEN];
707 	char *name = NULL;
708 	struct stat st;
709 	int c, fd, ret = 0;
710 	nvlist_t *config;
711 	pool_state_t state;
712 	boolean_t inuse = B_FALSE;
713 	boolean_t force = B_FALSE;
714 
715 	/* check options */
716 	while ((c = getopt(argc, argv, "f")) != -1) {
717 		switch (c) {
718 		case 'f':
719 			force = B_TRUE;
720 			break;
721 		default:
722 			(void) fprintf(stderr, gettext("invalid option '%c'\n"),
723 			    optopt);
724 			usage(B_FALSE);
725 		}
726 	}
727 
728 	argc -= optind;
729 	argv += optind;
730 
731 	/* get vdev name */
732 	if (argc < 1) {
733 		(void) fprintf(stderr, gettext("missing vdev name\n"));
734 		usage(B_FALSE);
735 	}
736 	if (argc > 1) {
737 		(void) fprintf(stderr, gettext("too many arguments\n"));
738 		usage(B_FALSE);
739 	}
740 
741 	/*
742 	 * Check if we were given absolute path and use it as is.
743 	 * Otherwise if the provided vdev name doesn't point to a file,
744 	 * try prepending dsk path and appending s0.
745 	 */
746 	(void) strlcpy(vdev, argv[0], sizeof (vdev));
747 	if (vdev[0] != '/' && stat(vdev, &st) != 0) {
748 		char *s;
749 
750 		(void) snprintf(vdev, sizeof (vdev), "%s/%s",
751 		    ZFS_DISK_ROOT, argv[0]);
752 		if ((s = strrchr(argv[0], 's')) == NULL ||
753 		    !isdigit(*(s + 1)))
754 			(void) strlcat(vdev, "s0", sizeof (vdev));
755 		if (stat(vdev, &st) != 0) {
756 			(void) fprintf(stderr, gettext(
757 			    "failed to find device %s, try specifying absolute "
758 			    "path instead\n"), argv[0]);
759 			return (1);
760 		}
761 	}
762 
763 	if ((fd = open(vdev, O_RDWR)) < 0) {
764 		(void) fprintf(stderr, gettext("failed to open %s: %s\n"),
765 		    vdev, strerror(errno));
766 		return (1);
767 	}
768 
769 	if (zpool_read_label(fd, &config) != 0) {
770 		(void) fprintf(stderr,
771 		    gettext("failed to read label from %s\n"), vdev);
772 		return (1);
773 	}
774 	nvlist_free(config);
775 
776 	ret = zpool_in_use(g_zfs, fd, &state, &name, &inuse);
777 	if (ret != 0) {
778 		(void) fprintf(stderr,
779 		    gettext("failed to check state for %s\n"), vdev);
780 		return (1);
781 	}
782 
783 	if (!inuse)
784 		goto wipe_label;
785 
786 	switch (state) {
787 	default:
788 	case POOL_STATE_ACTIVE:
789 	case POOL_STATE_SPARE:
790 	case POOL_STATE_L2CACHE:
791 		(void) fprintf(stderr, gettext(
792 		    "%s is a member (%s) of pool \"%s\"\n"),
793 		    vdev, zpool_pool_state_to_name(state), name);
794 		ret = 1;
795 		goto errout;
796 
797 	case POOL_STATE_EXPORTED:
798 		if (force)
799 			break;
800 		(void) fprintf(stderr, gettext(
801 		    "use '-f' to override the following error:\n"
802 		    "%s is a member of exported pool \"%s\"\n"),
803 		    vdev, name);
804 		ret = 1;
805 		goto errout;
806 
807 	case POOL_STATE_POTENTIALLY_ACTIVE:
808 		if (force)
809 			break;
810 		(void) fprintf(stderr, gettext(
811 		    "use '-f' to override the following error:\n"
812 		    "%s is a member of potentially active pool \"%s\"\n"),
813 		    vdev, name);
814 		ret = 1;
815 		goto errout;
816 
817 	case POOL_STATE_DESTROYED:
818 		/* inuse should never be set for a destroyed pool */
819 		assert(0);
820 		break;
821 	}
822 
823 wipe_label:
824 	ret = zpool_clear_label(fd);
825 	if (ret != 0) {
826 		(void) fprintf(stderr,
827 		    gettext("failed to clear label for %s\n"), vdev);
828 	}
829 
830 errout:
831 	free(name);
832 	(void) close(fd);
833 
834 	return (ret);
835 }
836 
837 /*
838  * zpool create [-fnd] [-B] [-o property=value] ...
839  *		[-O file-system-property=value] ...
840  *		[-R root] [-m mountpoint] <pool> <dev> ...
841  *
842  *	-B	Create boot partition.
843  *	-f	Force creation, even if devices appear in use
844  *	-n	Do not create the pool, but display the resulting layout if it
845  *		were to be created.
846  *      -R	Create a pool under an alternate root
847  *      -m	Set default mountpoint for the root dataset.  By default it's
848  *		'/<pool>'
849  *	-o	Set property=value.
850  *	-d	Don't automatically enable all supported pool features
851  *		(individual features can be enabled with -o).
852  *	-O	Set fsproperty=value in the pool's root file system
853  *
854  * Creates the named pool according to the given vdev specification.  The
855  * bulk of the vdev processing is done in get_vdev_spec() in zpool_vdev.c.  Once
856  * we get the nvlist back from get_vdev_spec(), we either print out the contents
857  * (if '-n' was specified), or pass it to libzfs to do the creation.
858  */
859 
860 #define	SYSTEM256	(256 * 1024 * 1024)
861 int
862 zpool_do_create(int argc, char **argv)
863 {
864 	boolean_t force = B_FALSE;
865 	boolean_t dryrun = B_FALSE;
866 	boolean_t enable_all_pool_feat = B_TRUE;
867 	zpool_boot_label_t boot_type = ZPOOL_NO_BOOT_LABEL;
868 	uint64_t boot_size = 0;
869 	int c;
870 	nvlist_t *nvroot = NULL;
871 	char *poolname;
872 	int ret = 1;
873 	char *altroot = NULL;
874 	char *mountpoint = NULL;
875 	nvlist_t *fsprops = NULL;
876 	nvlist_t *props = NULL;
877 	char *propval;
878 
879 	/* check options */
880 	while ((c = getopt(argc, argv, ":fndBR:m:o:O:")) != -1) {
881 		switch (c) {
882 		case 'f':
883 			force = B_TRUE;
884 			break;
885 		case 'n':
886 			dryrun = B_TRUE;
887 			break;
888 		case 'd':
889 			enable_all_pool_feat = B_FALSE;
890 			break;
891 		case 'B':
892 			/*
893 			 * We should create the system partition.
894 			 * Also make sure the size is set.
895 			 */
896 			boot_type = ZPOOL_CREATE_BOOT_LABEL;
897 			if (boot_size == 0)
898 				boot_size = SYSTEM256;
899 			break;
900 		case 'R':
901 			altroot = optarg;
902 			if (add_prop_list(zpool_prop_to_name(
903 			    ZPOOL_PROP_ALTROOT), optarg, &props, B_TRUE))
904 				goto errout;
905 			if (nvlist_lookup_string(props,
906 			    zpool_prop_to_name(ZPOOL_PROP_CACHEFILE),
907 			    &propval) == 0)
908 				break;
909 			if (add_prop_list(zpool_prop_to_name(
910 			    ZPOOL_PROP_CACHEFILE), "none", &props, B_TRUE))
911 				goto errout;
912 			break;
913 		case 'm':
914 			/* Equivalent to -O mountpoint=optarg */
915 			mountpoint = optarg;
916 			break;
917 		case 'o':
918 			if ((propval = strchr(optarg, '=')) == NULL) {
919 				(void) fprintf(stderr, gettext("missing "
920 				    "'=' for -o option\n"));
921 				goto errout;
922 			}
923 			*propval = '\0';
924 			propval++;
925 
926 			if (add_prop_list(optarg, propval, &props, B_TRUE))
927 				goto errout;
928 
929 			/*
930 			 * Get bootsize value for make_root_vdev().
931 			 */
932 			if (zpool_name_to_prop(optarg) == ZPOOL_PROP_BOOTSIZE) {
933 				if (zfs_nicestrtonum(g_zfs, propval,
934 				    &boot_size) < 0 || boot_size == 0) {
935 					(void) fprintf(stderr,
936 					    gettext("bad boot partition size "
937 					    "'%s': %s\n"),  propval,
938 					    libzfs_error_description(g_zfs));
939 					goto errout;
940 				}
941 			}
942 
943 			/*
944 			 * If the user is creating a pool that doesn't support
945 			 * feature flags, don't enable any features.
946 			 */
947 			if (zpool_name_to_prop(optarg) == ZPOOL_PROP_VERSION) {
948 				char *end;
949 				u_longlong_t ver;
950 
951 				ver = strtoull(propval, &end, 10);
952 				if (*end == '\0' &&
953 				    ver < SPA_VERSION_FEATURES) {
954 					enable_all_pool_feat = B_FALSE;
955 				}
956 			}
957 			if (zpool_name_to_prop(optarg) == ZPOOL_PROP_ALTROOT)
958 				altroot = propval;
959 			break;
960 		case 'O':
961 			if ((propval = strchr(optarg, '=')) == NULL) {
962 				(void) fprintf(stderr, gettext("missing "
963 				    "'=' for -O option\n"));
964 				goto errout;
965 			}
966 			*propval = '\0';
967 			propval++;
968 
969 			/*
970 			 * Mountpoints are checked and then added later.
971 			 * Uniquely among properties, they can be specified
972 			 * more than once, to avoid conflict with -m.
973 			 */
974 			if (0 == strcmp(optarg,
975 			    zfs_prop_to_name(ZFS_PROP_MOUNTPOINT))) {
976 				mountpoint = propval;
977 			} else if (add_prop_list(optarg, propval, &fsprops,
978 			    B_FALSE)) {
979 				goto errout;
980 			}
981 			break;
982 		case ':':
983 			(void) fprintf(stderr, gettext("missing argument for "
984 			    "'%c' option\n"), optopt);
985 			goto badusage;
986 		case '?':
987 			(void) fprintf(stderr, gettext("invalid option '%c'\n"),
988 			    optopt);
989 			goto badusage;
990 		}
991 	}
992 
993 	argc -= optind;
994 	argv += optind;
995 
996 	/* get pool name and check number of arguments */
997 	if (argc < 1) {
998 		(void) fprintf(stderr, gettext("missing pool name argument\n"));
999 		goto badusage;
1000 	}
1001 	if (argc < 2) {
1002 		(void) fprintf(stderr, gettext("missing vdev specification\n"));
1003 		goto badusage;
1004 	}
1005 
1006 	poolname = argv[0];
1007 
1008 	/*
1009 	 * As a special case, check for use of '/' in the name, and direct the
1010 	 * user to use 'zfs create' instead.
1011 	 */
1012 	if (strchr(poolname, '/') != NULL) {
1013 		(void) fprintf(stderr, gettext("cannot create '%s': invalid "
1014 		    "character '/' in pool name\n"), poolname);
1015 		(void) fprintf(stderr, gettext("use 'zfs create' to "
1016 		    "create a dataset\n"));
1017 		goto errout;
1018 	}
1019 
1020 	/*
1021 	 * Make sure the bootsize is set when ZPOOL_CREATE_BOOT_LABEL is used,
1022 	 * and not set otherwise.
1023 	 */
1024 	if (boot_type == ZPOOL_CREATE_BOOT_LABEL) {
1025 		const char *propname;
1026 		char *strptr, *buf = NULL;
1027 		int rv;
1028 
1029 		propname = zpool_prop_to_name(ZPOOL_PROP_BOOTSIZE);
1030 		if (nvlist_lookup_string(props, propname, &strptr) != 0) {
1031 			(void) asprintf(&buf, "%" PRIu64, boot_size);
1032 			if (buf == NULL) {
1033 				(void) fprintf(stderr,
1034 				    gettext("internal error: out of memory\n"));
1035 				goto errout;
1036 			}
1037 			rv = add_prop_list(propname, buf, &props, B_TRUE);
1038 			free(buf);
1039 			if (rv != 0)
1040 				goto errout;
1041 		}
1042 	} else {
1043 		const char *propname;
1044 		char *strptr;
1045 
1046 		propname = zpool_prop_to_name(ZPOOL_PROP_BOOTSIZE);
1047 		if (nvlist_lookup_string(props, propname, &strptr) == 0) {
1048 			(void) fprintf(stderr, gettext("error: setting boot "
1049 			    "partition size requires option '-B'\n"));
1050 			goto errout;
1051 		}
1052 	}
1053 
1054 	/* pass off to get_vdev_spec for bulk processing */
1055 	nvroot = make_root_vdev(NULL, force, !force, B_FALSE, dryrun,
1056 	    boot_type, boot_size, argc - 1, argv + 1);
1057 	if (nvroot == NULL)
1058 		goto errout;
1059 
1060 	/* make_root_vdev() allows 0 toplevel children if there are spares */
1061 	if (!zfs_allocatable_devs(nvroot)) {
1062 		(void) fprintf(stderr, gettext("invalid vdev "
1063 		    "specification: at least one toplevel vdev must be "
1064 		    "specified\n"));
1065 		goto errout;
1066 	}
1067 
1068 	if (altroot != NULL && altroot[0] != '/') {
1069 		(void) fprintf(stderr, gettext("invalid alternate root '%s': "
1070 		    "must be an absolute path\n"), altroot);
1071 		goto errout;
1072 	}
1073 
1074 	/*
1075 	 * Check the validity of the mountpoint and direct the user to use the
1076 	 * '-m' mountpoint option if it looks like its in use.
1077 	 */
1078 	if (mountpoint == NULL ||
1079 	    (strcmp(mountpoint, ZFS_MOUNTPOINT_LEGACY) != 0 &&
1080 	    strcmp(mountpoint, ZFS_MOUNTPOINT_NONE) != 0)) {
1081 		char buf[MAXPATHLEN];
1082 		DIR *dirp;
1083 
1084 		if (mountpoint && mountpoint[0] != '/') {
1085 			(void) fprintf(stderr, gettext("invalid mountpoint "
1086 			    "'%s': must be an absolute path, 'legacy', or "
1087 			    "'none'\n"), mountpoint);
1088 			goto errout;
1089 		}
1090 
1091 		if (mountpoint == NULL) {
1092 			if (altroot != NULL)
1093 				(void) snprintf(buf, sizeof (buf), "%s/%s",
1094 				    altroot, poolname);
1095 			else
1096 				(void) snprintf(buf, sizeof (buf), "/%s",
1097 				    poolname);
1098 		} else {
1099 			if (altroot != NULL)
1100 				(void) snprintf(buf, sizeof (buf), "%s%s",
1101 				    altroot, mountpoint);
1102 			else
1103 				(void) snprintf(buf, sizeof (buf), "%s",
1104 				    mountpoint);
1105 		}
1106 
1107 		if ((dirp = opendir(buf)) == NULL && errno != ENOENT) {
1108 			(void) fprintf(stderr, gettext("mountpoint '%s' : "
1109 			    "%s\n"), buf, strerror(errno));
1110 			(void) fprintf(stderr, gettext("use '-m' "
1111 			    "option to provide a different default\n"));
1112 			goto errout;
1113 		} else if (dirp) {
1114 			int count = 0;
1115 
1116 			while (count < 3 && readdir(dirp) != NULL)
1117 				count++;
1118 			(void) closedir(dirp);
1119 
1120 			if (count > 2) {
1121 				(void) fprintf(stderr, gettext("mountpoint "
1122 				    "'%s' exists and is not empty\n"), buf);
1123 				(void) fprintf(stderr, gettext("use '-m' "
1124 				    "option to provide a "
1125 				    "different default\n"));
1126 				goto errout;
1127 			}
1128 		}
1129 	}
1130 
1131 	/*
1132 	 * Now that the mountpoint's validity has been checked, ensure that
1133 	 * the property is set appropriately prior to creating the pool.
1134 	 */
1135 	if (mountpoint != NULL) {
1136 		ret = add_prop_list(zfs_prop_to_name(ZFS_PROP_MOUNTPOINT),
1137 		    mountpoint, &fsprops, B_FALSE);
1138 		if (ret != 0)
1139 			goto errout;
1140 	}
1141 
1142 	ret = 1;
1143 	if (dryrun) {
1144 		/*
1145 		 * For a dry run invocation, print out a basic message and run
1146 		 * through all the vdevs in the list and print out in an
1147 		 * appropriate hierarchy.
1148 		 */
1149 		(void) printf(gettext("would create '%s' with the "
1150 		    "following layout:\n\n"), poolname);
1151 
1152 		print_vdev_tree(NULL, poolname, nvroot, 0, B_FALSE);
1153 		if (num_logs(nvroot) > 0)
1154 			print_vdev_tree(NULL, "logs", nvroot, 0, B_TRUE);
1155 
1156 		ret = 0;
1157 	} else {
1158 		/*
1159 		 * Hand off to libzfs.
1160 		 */
1161 		if (enable_all_pool_feat) {
1162 			spa_feature_t i;
1163 			for (i = 0; i < SPA_FEATURES; i++) {
1164 				char propname[MAXPATHLEN];
1165 				zfeature_info_t *feat = &spa_feature_table[i];
1166 
1167 				(void) snprintf(propname, sizeof (propname),
1168 				    "feature@%s", feat->fi_uname);
1169 
1170 				/*
1171 				 * Skip feature if user specified it manually
1172 				 * on the command line.
1173 				 */
1174 				if (nvlist_exists(props, propname))
1175 					continue;
1176 
1177 				ret = add_prop_list(propname,
1178 				    ZFS_FEATURE_ENABLED, &props, B_TRUE);
1179 				if (ret != 0)
1180 					goto errout;
1181 			}
1182 		}
1183 
1184 		ret = 1;
1185 		if (zpool_create(g_zfs, poolname,
1186 		    nvroot, props, fsprops) == 0) {
1187 			zfs_handle_t *pool = zfs_open(g_zfs, poolname,
1188 			    ZFS_TYPE_FILESYSTEM);
1189 			if (pool != NULL) {
1190 				if (zfs_mount(pool, NULL, 0) == 0)
1191 					ret = zfs_shareall(pool);
1192 				zfs_close(pool);
1193 			}
1194 		} else if (libzfs_errno(g_zfs) == EZFS_INVALIDNAME) {
1195 			(void) fprintf(stderr, gettext("pool name may have "
1196 			    "been omitted\n"));
1197 		}
1198 	}
1199 
1200 errout:
1201 	nvlist_free(nvroot);
1202 	nvlist_free(fsprops);
1203 	nvlist_free(props);
1204 	return (ret);
1205 badusage:
1206 	nvlist_free(fsprops);
1207 	nvlist_free(props);
1208 	usage(B_FALSE);
1209 	return (2);
1210 }
1211 
1212 /*
1213  * zpool destroy <pool>
1214  *
1215  * 	-f	Forcefully unmount any datasets
1216  *
1217  * Destroy the given pool.  Automatically unmounts any datasets in the pool.
1218  */
1219 int
1220 zpool_do_destroy(int argc, char **argv)
1221 {
1222 	boolean_t force = B_FALSE;
1223 	int c;
1224 	char *pool;
1225 	zpool_handle_t *zhp;
1226 	int ret;
1227 
1228 	/* check options */
1229 	while ((c = getopt(argc, argv, "f")) != -1) {
1230 		switch (c) {
1231 		case 'f':
1232 			force = B_TRUE;
1233 			break;
1234 		case '?':
1235 			(void) fprintf(stderr, gettext("invalid option '%c'\n"),
1236 			    optopt);
1237 			usage(B_FALSE);
1238 		}
1239 	}
1240 
1241 	argc -= optind;
1242 	argv += optind;
1243 
1244 	/* check arguments */
1245 	if (argc < 1) {
1246 		(void) fprintf(stderr, gettext("missing pool argument\n"));
1247 		usage(B_FALSE);
1248 	}
1249 	if (argc > 1) {
1250 		(void) fprintf(stderr, gettext("too many arguments\n"));
1251 		usage(B_FALSE);
1252 	}
1253 
1254 	pool = argv[0];
1255 
1256 	if ((zhp = zpool_open_canfail(g_zfs, pool)) == NULL) {
1257 		/*
1258 		 * As a special case, check for use of '/' in the name, and
1259 		 * direct the user to use 'zfs destroy' instead.
1260 		 */
1261 		if (strchr(pool, '/') != NULL)
1262 			(void) fprintf(stderr, gettext("use 'zfs destroy' to "
1263 			    "destroy a dataset\n"));
1264 		return (1);
1265 	}
1266 
1267 	if (zpool_disable_datasets(zhp, force) != 0) {
1268 		(void) fprintf(stderr, gettext("could not destroy '%s': "
1269 		    "could not unmount datasets\n"), zpool_get_name(zhp));
1270 		return (1);
1271 	}
1272 
1273 	/* The history must be logged as part of the export */
1274 	log_history = B_FALSE;
1275 
1276 	ret = (zpool_destroy(zhp, history_str) != 0);
1277 
1278 	zpool_close(zhp);
1279 
1280 	return (ret);
1281 }
1282 
1283 /*
1284  * zpool export [-f] <pool> ...
1285  *
1286  *	-f	Forcefully unmount datasets
1287  *
1288  * Export the given pools.  By default, the command will attempt to cleanly
1289  * unmount any active datasets within the pool.  If the '-f' flag is specified,
1290  * then the datasets will be forcefully unmounted.
1291  */
1292 int
1293 zpool_do_export(int argc, char **argv)
1294 {
1295 	boolean_t force = B_FALSE;
1296 	boolean_t hardforce = B_FALSE;
1297 	int c;
1298 	zpool_handle_t *zhp;
1299 	int ret;
1300 	int i;
1301 
1302 	/* check options */
1303 	while ((c = getopt(argc, argv, "fF")) != -1) {
1304 		switch (c) {
1305 		case 'f':
1306 			force = B_TRUE;
1307 			break;
1308 		case 'F':
1309 			hardforce = B_TRUE;
1310 			break;
1311 		case '?':
1312 			(void) fprintf(stderr, gettext("invalid option '%c'\n"),
1313 			    optopt);
1314 			usage(B_FALSE);
1315 		}
1316 	}
1317 
1318 	argc -= optind;
1319 	argv += optind;
1320 
1321 	/* check arguments */
1322 	if (argc < 1) {
1323 		(void) fprintf(stderr, gettext("missing pool argument\n"));
1324 		usage(B_FALSE);
1325 	}
1326 
1327 	ret = 0;
1328 	for (i = 0; i < argc; i++) {
1329 		if ((zhp = zpool_open_canfail(g_zfs, argv[i])) == NULL) {
1330 			ret = 1;
1331 			continue;
1332 		}
1333 
1334 		if (zpool_disable_datasets(zhp, force) != 0) {
1335 			ret = 1;
1336 			zpool_close(zhp);
1337 			continue;
1338 		}
1339 
1340 		/* The history must be logged as part of the export */
1341 		log_history = B_FALSE;
1342 
1343 		if (hardforce) {
1344 			if (zpool_export_force(zhp, history_str) != 0)
1345 				ret = 1;
1346 		} else if (zpool_export(zhp, force, history_str) != 0) {
1347 			ret = 1;
1348 		}
1349 
1350 		zpool_close(zhp);
1351 	}
1352 
1353 	return (ret);
1354 }
1355 
1356 /*
1357  * Given a vdev configuration, determine the maximum width needed for the device
1358  * name column.
1359  */
1360 static int
1361 max_width(zpool_handle_t *zhp, nvlist_t *nv, int depth, int max)
1362 {
1363 	char *name = zpool_vdev_name(g_zfs, zhp, nv, B_TRUE);
1364 	nvlist_t **child;
1365 	uint_t c, children;
1366 	int ret;
1367 
1368 	if (strlen(name) + depth > max)
1369 		max = strlen(name) + depth;
1370 
1371 	free(name);
1372 
1373 	if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_SPARES,
1374 	    &child, &children) == 0) {
1375 		for (c = 0; c < children; c++)
1376 			if ((ret = max_width(zhp, child[c], depth + 2,
1377 			    max)) > max)
1378 				max = ret;
1379 	}
1380 
1381 	if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_L2CACHE,
1382 	    &child, &children) == 0) {
1383 		for (c = 0; c < children; c++)
1384 			if ((ret = max_width(zhp, child[c], depth + 2,
1385 			    max)) > max)
1386 				max = ret;
1387 	}
1388 
1389 	if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
1390 	    &child, &children) == 0) {
1391 		for (c = 0; c < children; c++)
1392 			if ((ret = max_width(zhp, child[c], depth + 2,
1393 			    max)) > max)
1394 				max = ret;
1395 	}
1396 
1397 
1398 	return (max);
1399 }
1400 
1401 typedef struct spare_cbdata {
1402 	uint64_t	cb_guid;
1403 	zpool_handle_t	*cb_zhp;
1404 } spare_cbdata_t;
1405 
1406 static boolean_t
1407 find_vdev(nvlist_t *nv, uint64_t search)
1408 {
1409 	uint64_t guid;
1410 	nvlist_t **child;
1411 	uint_t c, children;
1412 
1413 	if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_GUID, &guid) == 0 &&
1414 	    search == guid)
1415 		return (B_TRUE);
1416 
1417 	if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
1418 	    &child, &children) == 0) {
1419 		for (c = 0; c < children; c++)
1420 			if (find_vdev(child[c], search))
1421 				return (B_TRUE);
1422 	}
1423 
1424 	return (B_FALSE);
1425 }
1426 
1427 static int
1428 find_spare(zpool_handle_t *zhp, void *data)
1429 {
1430 	spare_cbdata_t *cbp = data;
1431 	nvlist_t *config, *nvroot;
1432 
1433 	config = zpool_get_config(zhp, NULL);
1434 	verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
1435 	    &nvroot) == 0);
1436 
1437 	if (find_vdev(nvroot, cbp->cb_guid)) {
1438 		cbp->cb_zhp = zhp;
1439 		return (1);
1440 	}
1441 
1442 	zpool_close(zhp);
1443 	return (0);
1444 }
1445 
1446 /*
1447  * Print out configuration state as requested by status_callback.
1448  */
1449 void
1450 print_status_config(zpool_handle_t *zhp, const char *name, nvlist_t *nv,
1451     int namewidth, int depth, boolean_t isspare)
1452 {
1453 	nvlist_t **child;
1454 	uint_t c, children;
1455 	pool_scan_stat_t *ps = NULL;
1456 	vdev_stat_t *vs;
1457 	char rbuf[6], wbuf[6], cbuf[6];
1458 	char *vname;
1459 	uint64_t notpresent;
1460 	spare_cbdata_t cb;
1461 	const char *state;
1462 	char *type;
1463 
1464 	if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
1465 	    &child, &children) != 0)
1466 		children = 0;
1467 
1468 	verify(nvlist_lookup_uint64_array(nv, ZPOOL_CONFIG_VDEV_STATS,
1469 	    (uint64_t **)&vs, &c) == 0);
1470 
1471 	verify(nvlist_lookup_string(nv, ZPOOL_CONFIG_TYPE, &type) == 0);
1472 
1473 	if (strcmp(type, VDEV_TYPE_INDIRECT) == 0)
1474 		return;
1475 
1476 	state = zpool_state_to_name(vs->vs_state, vs->vs_aux);
1477 	if (isspare) {
1478 		/*
1479 		 * For hot spares, we use the terms 'INUSE' and 'AVAILABLE' for
1480 		 * online drives.
1481 		 */
1482 		if (vs->vs_aux == VDEV_AUX_SPARED)
1483 			state = "INUSE";
1484 		else if (vs->vs_state == VDEV_STATE_HEALTHY)
1485 			state = "AVAIL";
1486 	}
1487 
1488 	(void) printf("\t%*s%-*s  %-8s", depth, "", namewidth - depth,
1489 	    name, state);
1490 
1491 	if (!isspare) {
1492 		zfs_nicenum(vs->vs_read_errors, rbuf, sizeof (rbuf));
1493 		zfs_nicenum(vs->vs_write_errors, wbuf, sizeof (wbuf));
1494 		zfs_nicenum(vs->vs_checksum_errors, cbuf, sizeof (cbuf));
1495 		(void) printf(" %5s %5s %5s", rbuf, wbuf, cbuf);
1496 	}
1497 
1498 	if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_NOT_PRESENT,
1499 	    &notpresent) == 0) {
1500 		char *path;
1501 		verify(nvlist_lookup_string(nv, ZPOOL_CONFIG_PATH, &path) == 0);
1502 		(void) printf("  was %s", path);
1503 	} else if (vs->vs_aux != 0) {
1504 		(void) printf("  ");
1505 
1506 		switch (vs->vs_aux) {
1507 		case VDEV_AUX_OPEN_FAILED:
1508 			(void) printf(gettext("cannot open"));
1509 			break;
1510 
1511 		case VDEV_AUX_BAD_GUID_SUM:
1512 			(void) printf(gettext("missing device"));
1513 			break;
1514 
1515 		case VDEV_AUX_NO_REPLICAS:
1516 			(void) printf(gettext("insufficient replicas"));
1517 			break;
1518 
1519 		case VDEV_AUX_VERSION_NEWER:
1520 			(void) printf(gettext("newer version"));
1521 			break;
1522 
1523 		case VDEV_AUX_UNSUP_FEAT:
1524 			(void) printf(gettext("unsupported feature(s)"));
1525 			break;
1526 
1527 		case VDEV_AUX_SPARED:
1528 			verify(nvlist_lookup_uint64(nv, ZPOOL_CONFIG_GUID,
1529 			    &cb.cb_guid) == 0);
1530 			if (zpool_iter(g_zfs, find_spare, &cb) == 1) {
1531 				if (strcmp(zpool_get_name(cb.cb_zhp),
1532 				    zpool_get_name(zhp)) == 0)
1533 					(void) printf(gettext("currently in "
1534 					    "use"));
1535 				else
1536 					(void) printf(gettext("in use by "
1537 					    "pool '%s'"),
1538 					    zpool_get_name(cb.cb_zhp));
1539 				zpool_close(cb.cb_zhp);
1540 			} else {
1541 				(void) printf(gettext("currently in use"));
1542 			}
1543 			break;
1544 
1545 		case VDEV_AUX_ERR_EXCEEDED:
1546 			(void) printf(gettext("too many errors"));
1547 			break;
1548 
1549 		case VDEV_AUX_IO_FAILURE:
1550 			(void) printf(gettext("experienced I/O failures"));
1551 			break;
1552 
1553 		case VDEV_AUX_BAD_LOG:
1554 			(void) printf(gettext("bad intent log"));
1555 			break;
1556 
1557 		case VDEV_AUX_EXTERNAL:
1558 			(void) printf(gettext("external device fault"));
1559 			break;
1560 
1561 		case VDEV_AUX_SPLIT_POOL:
1562 			(void) printf(gettext("split into new pool"));
1563 			break;
1564 
1565 		case VDEV_AUX_CHILDREN_OFFLINE:
1566 			(void) printf(gettext("all children offline"));
1567 			break;
1568 
1569 		default:
1570 			(void) printf(gettext("corrupted data"));
1571 			break;
1572 		}
1573 	}
1574 
1575 	(void) nvlist_lookup_uint64_array(nv, ZPOOL_CONFIG_SCAN_STATS,
1576 	    (uint64_t **)&ps, &c);
1577 
1578 	if (ps && ps->pss_state == DSS_SCANNING &&
1579 	    vs->vs_scan_processed != 0 && children == 0) {
1580 		(void) printf(gettext("  (%s)"),
1581 		    (ps->pss_func == POOL_SCAN_RESILVER) ?
1582 		    "resilvering" : "repairing");
1583 	}
1584 
1585 	(void) printf("\n");
1586 
1587 	for (c = 0; c < children; c++) {
1588 		uint64_t islog = B_FALSE, ishole = B_FALSE;
1589 
1590 		/* Don't print logs or holes here */
1591 		(void) nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_LOG,
1592 		    &islog);
1593 		(void) nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_HOLE,
1594 		    &ishole);
1595 		if (islog || ishole)
1596 			continue;
1597 		vname = zpool_vdev_name(g_zfs, zhp, child[c], B_TRUE);
1598 		print_status_config(zhp, vname, child[c],
1599 		    namewidth, depth + 2, isspare);
1600 		free(vname);
1601 	}
1602 }
1603 
1604 
1605 /*
1606  * Print the configuration of an exported pool.  Iterate over all vdevs in the
1607  * pool, printing out the name and status for each one.
1608  */
1609 void
1610 print_import_config(const char *name, nvlist_t *nv, int namewidth, int depth)
1611 {
1612 	nvlist_t **child;
1613 	uint_t c, children;
1614 	vdev_stat_t *vs;
1615 	char *type, *vname;
1616 
1617 	verify(nvlist_lookup_string(nv, ZPOOL_CONFIG_TYPE, &type) == 0);
1618 	if (strcmp(type, VDEV_TYPE_MISSING) == 0 ||
1619 	    strcmp(type, VDEV_TYPE_HOLE) == 0)
1620 		return;
1621 
1622 	verify(nvlist_lookup_uint64_array(nv, ZPOOL_CONFIG_VDEV_STATS,
1623 	    (uint64_t **)&vs, &c) == 0);
1624 
1625 	(void) printf("\t%*s%-*s", depth, "", namewidth - depth, name);
1626 	(void) printf("  %s", zpool_state_to_name(vs->vs_state, vs->vs_aux));
1627 
1628 	if (vs->vs_aux != 0) {
1629 		(void) printf("  ");
1630 
1631 		switch (vs->vs_aux) {
1632 		case VDEV_AUX_OPEN_FAILED:
1633 			(void) printf(gettext("cannot open"));
1634 			break;
1635 
1636 		case VDEV_AUX_BAD_GUID_SUM:
1637 			(void) printf(gettext("missing device"));
1638 			break;
1639 
1640 		case VDEV_AUX_NO_REPLICAS:
1641 			(void) printf(gettext("insufficient replicas"));
1642 			break;
1643 
1644 		case VDEV_AUX_VERSION_NEWER:
1645 			(void) printf(gettext("newer version"));
1646 			break;
1647 
1648 		case VDEV_AUX_UNSUP_FEAT:
1649 			(void) printf(gettext("unsupported feature(s)"));
1650 			break;
1651 
1652 		case VDEV_AUX_ERR_EXCEEDED:
1653 			(void) printf(gettext("too many errors"));
1654 			break;
1655 
1656 		case VDEV_AUX_CHILDREN_OFFLINE:
1657 			(void) printf(gettext("all children offline"));
1658 			break;
1659 
1660 		default:
1661 			(void) printf(gettext("corrupted data"));
1662 			break;
1663 		}
1664 	}
1665 	(void) printf("\n");
1666 
1667 	if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
1668 	    &child, &children) != 0)
1669 		return;
1670 
1671 	for (c = 0; c < children; c++) {
1672 		uint64_t is_log = B_FALSE;
1673 
1674 		(void) nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_LOG,
1675 		    &is_log);
1676 		if (is_log)
1677 			continue;
1678 
1679 		vname = zpool_vdev_name(g_zfs, NULL, child[c], B_TRUE);
1680 		print_import_config(vname, child[c], namewidth, depth + 2);
1681 		free(vname);
1682 	}
1683 
1684 	if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_L2CACHE,
1685 	    &child, &children) == 0) {
1686 		(void) printf(gettext("\tcache\n"));
1687 		for (c = 0; c < children; c++) {
1688 			vname = zpool_vdev_name(g_zfs, NULL, child[c], B_FALSE);
1689 			(void) printf("\t  %s\n", vname);
1690 			free(vname);
1691 		}
1692 	}
1693 
1694 	if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_SPARES,
1695 	    &child, &children) == 0) {
1696 		(void) printf(gettext("\tspares\n"));
1697 		for (c = 0; c < children; c++) {
1698 			vname = zpool_vdev_name(g_zfs, NULL, child[c], B_FALSE);
1699 			(void) printf("\t  %s\n", vname);
1700 			free(vname);
1701 		}
1702 	}
1703 }
1704 
1705 /*
1706  * Print log vdevs.
1707  * Logs are recorded as top level vdevs in the main pool child array
1708  * but with "is_log" set to 1. We use either print_status_config() or
1709  * print_import_config() to print the top level logs then any log
1710  * children (eg mirrored slogs) are printed recursively - which
1711  * works because only the top level vdev is marked "is_log"
1712  */
1713 static void
1714 print_logs(zpool_handle_t *zhp, nvlist_t *nv, int namewidth, boolean_t verbose)
1715 {
1716 	uint_t c, children;
1717 	nvlist_t **child;
1718 
1719 	if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN, &child,
1720 	    &children) != 0)
1721 		return;
1722 
1723 	(void) printf(gettext("\tlogs\n"));
1724 
1725 	for (c = 0; c < children; c++) {
1726 		uint64_t is_log = B_FALSE;
1727 		char *name;
1728 
1729 		(void) nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_LOG,
1730 		    &is_log);
1731 		if (!is_log)
1732 			continue;
1733 		name = zpool_vdev_name(g_zfs, zhp, child[c], B_TRUE);
1734 		if (verbose)
1735 			print_status_config(zhp, name, child[c], namewidth,
1736 			    2, B_FALSE);
1737 		else
1738 			print_import_config(name, child[c], namewidth, 2);
1739 		free(name);
1740 	}
1741 }
1742 
1743 /*
1744  * Display the status for the given pool.
1745  */
1746 static void
1747 show_import(nvlist_t *config)
1748 {
1749 	uint64_t pool_state;
1750 	vdev_stat_t *vs;
1751 	char *name;
1752 	uint64_t guid;
1753 	char *msgid;
1754 	nvlist_t *nvroot;
1755 	int reason;
1756 	const char *health;
1757 	uint_t vsc;
1758 	int namewidth;
1759 	char *comment;
1760 
1761 	verify(nvlist_lookup_string(config, ZPOOL_CONFIG_POOL_NAME,
1762 	    &name) == 0);
1763 	verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_GUID,
1764 	    &guid) == 0);
1765 	verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_STATE,
1766 	    &pool_state) == 0);
1767 	verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
1768 	    &nvroot) == 0);
1769 
1770 	verify(nvlist_lookup_uint64_array(nvroot, ZPOOL_CONFIG_VDEV_STATS,
1771 	    (uint64_t **)&vs, &vsc) == 0);
1772 	health = zpool_state_to_name(vs->vs_state, vs->vs_aux);
1773 
1774 	reason = zpool_import_status(config, &msgid);
1775 
1776 	(void) printf(gettext("   pool: %s\n"), name);
1777 	(void) printf(gettext("     id: %llu\n"), (u_longlong_t)guid);
1778 	(void) printf(gettext("  state: %s"), health);
1779 	if (pool_state == POOL_STATE_DESTROYED)
1780 		(void) printf(gettext(" (DESTROYED)"));
1781 	(void) printf("\n");
1782 
1783 	switch (reason) {
1784 	case ZPOOL_STATUS_MISSING_DEV_R:
1785 	case ZPOOL_STATUS_MISSING_DEV_NR:
1786 	case ZPOOL_STATUS_BAD_GUID_SUM:
1787 		(void) printf(gettext(" status: One or more devices are "
1788 		    "missing from the system.\n"));
1789 		break;
1790 
1791 	case ZPOOL_STATUS_CORRUPT_LABEL_R:
1792 	case ZPOOL_STATUS_CORRUPT_LABEL_NR:
1793 		(void) printf(gettext(" status: One or more devices contains "
1794 		    "corrupted data.\n"));
1795 		break;
1796 
1797 	case ZPOOL_STATUS_CORRUPT_DATA:
1798 		(void) printf(
1799 		    gettext(" status: The pool data is corrupted.\n"));
1800 		break;
1801 
1802 	case ZPOOL_STATUS_OFFLINE_DEV:
1803 		(void) printf(gettext(" status: One or more devices "
1804 		    "are offlined.\n"));
1805 		break;
1806 
1807 	case ZPOOL_STATUS_CORRUPT_POOL:
1808 		(void) printf(gettext(" status: The pool metadata is "
1809 		    "corrupted.\n"));
1810 		break;
1811 
1812 	case ZPOOL_STATUS_VERSION_OLDER:
1813 		(void) printf(gettext(" status: The pool is formatted using a "
1814 		    "legacy on-disk version.\n"));
1815 		break;
1816 
1817 	case ZPOOL_STATUS_VERSION_NEWER:
1818 		(void) printf(gettext(" status: The pool is formatted using an "
1819 		    "incompatible version.\n"));
1820 		break;
1821 
1822 	case ZPOOL_STATUS_FEAT_DISABLED:
1823 		(void) printf(gettext(" status: Some supported features are "
1824 		    "not enabled on the pool.\n"));
1825 		break;
1826 
1827 	case ZPOOL_STATUS_UNSUP_FEAT_READ:
1828 		(void) printf(gettext("status: The pool uses the following "
1829 		    "feature(s) not supported on this system:\n"));
1830 		zpool_print_unsup_feat(config);
1831 		break;
1832 
1833 	case ZPOOL_STATUS_UNSUP_FEAT_WRITE:
1834 		(void) printf(gettext("status: The pool can only be accessed "
1835 		    "in read-only mode on this system. It\n\tcannot be "
1836 		    "accessed in read-write mode because it uses the "
1837 		    "following\n\tfeature(s) not supported on this system:\n"));
1838 		zpool_print_unsup_feat(config);
1839 		break;
1840 
1841 	case ZPOOL_STATUS_HOSTID_MISMATCH:
1842 		(void) printf(gettext(" status: The pool was last accessed by "
1843 		    "another system.\n"));
1844 		break;
1845 
1846 	case ZPOOL_STATUS_FAULTED_DEV_R:
1847 	case ZPOOL_STATUS_FAULTED_DEV_NR:
1848 		(void) printf(gettext(" status: One or more devices are "
1849 		    "faulted.\n"));
1850 		break;
1851 
1852 	case ZPOOL_STATUS_BAD_LOG:
1853 		(void) printf(gettext(" status: An intent log record cannot be "
1854 		    "read.\n"));
1855 		break;
1856 
1857 	case ZPOOL_STATUS_RESILVERING:
1858 		(void) printf(gettext(" status: One or more devices were being "
1859 		    "resilvered.\n"));
1860 		break;
1861 
1862 	default:
1863 		/*
1864 		 * No other status can be seen when importing pools.
1865 		 */
1866 		assert(reason == ZPOOL_STATUS_OK);
1867 	}
1868 
1869 	/*
1870 	 * Print out an action according to the overall state of the pool.
1871 	 */
1872 	if (vs->vs_state == VDEV_STATE_HEALTHY) {
1873 		if (reason == ZPOOL_STATUS_VERSION_OLDER ||
1874 		    reason == ZPOOL_STATUS_FEAT_DISABLED) {
1875 			(void) printf(gettext(" action: The pool can be "
1876 			    "imported using its name or numeric identifier, "
1877 			    "though\n\tsome features will not be available "
1878 			    "without an explicit 'zpool upgrade'.\n"));
1879 		} else if (reason == ZPOOL_STATUS_HOSTID_MISMATCH) {
1880 			(void) printf(gettext(" action: The pool can be "
1881 			    "imported using its name or numeric "
1882 			    "identifier and\n\tthe '-f' flag.\n"));
1883 		} else {
1884 			(void) printf(gettext(" action: The pool can be "
1885 			    "imported using its name or numeric "
1886 			    "identifier.\n"));
1887 		}
1888 	} else if (vs->vs_state == VDEV_STATE_DEGRADED) {
1889 		(void) printf(gettext(" action: The pool can be imported "
1890 		    "despite missing or damaged devices.  The\n\tfault "
1891 		    "tolerance of the pool may be compromised if imported.\n"));
1892 	} else {
1893 		switch (reason) {
1894 		case ZPOOL_STATUS_VERSION_NEWER:
1895 			(void) printf(gettext(" action: The pool cannot be "
1896 			    "imported.  Access the pool on a system running "
1897 			    "newer\n\tsoftware, or recreate the pool from "
1898 			    "backup.\n"));
1899 			break;
1900 		case ZPOOL_STATUS_UNSUP_FEAT_READ:
1901 			(void) printf(gettext("action: The pool cannot be "
1902 			    "imported. Access the pool on a system that "
1903 			    "supports\n\tthe required feature(s), or recreate "
1904 			    "the pool from backup.\n"));
1905 			break;
1906 		case ZPOOL_STATUS_UNSUP_FEAT_WRITE:
1907 			(void) printf(gettext("action: The pool cannot be "
1908 			    "imported in read-write mode. Import the pool "
1909 			    "with\n"
1910 			    "\t\"-o readonly=on\", access the pool on a system "
1911 			    "that supports the\n\trequired feature(s), or "
1912 			    "recreate the pool from backup.\n"));
1913 			break;
1914 		case ZPOOL_STATUS_MISSING_DEV_R:
1915 		case ZPOOL_STATUS_MISSING_DEV_NR:
1916 		case ZPOOL_STATUS_BAD_GUID_SUM:
1917 			(void) printf(gettext(" action: The pool cannot be "
1918 			    "imported. Attach the missing\n\tdevices and try "
1919 			    "again.\n"));
1920 			break;
1921 		default:
1922 			(void) printf(gettext(" action: The pool cannot be "
1923 			    "imported due to damaged devices or data.\n"));
1924 		}
1925 	}
1926 
1927 	/* Print the comment attached to the pool. */
1928 	if (nvlist_lookup_string(config, ZPOOL_CONFIG_COMMENT, &comment) == 0)
1929 		(void) printf(gettext("comment: %s\n"), comment);
1930 
1931 	/*
1932 	 * If the state is "closed" or "can't open", and the aux state
1933 	 * is "corrupt data":
1934 	 */
1935 	if (((vs->vs_state == VDEV_STATE_CLOSED) ||
1936 	    (vs->vs_state == VDEV_STATE_CANT_OPEN)) &&
1937 	    (vs->vs_aux == VDEV_AUX_CORRUPT_DATA)) {
1938 		if (pool_state == POOL_STATE_DESTROYED)
1939 			(void) printf(gettext("\tThe pool was destroyed, "
1940 			    "but can be imported using the '-Df' flags.\n"));
1941 		else if (pool_state != POOL_STATE_EXPORTED)
1942 			(void) printf(gettext("\tThe pool may be active on "
1943 			    "another system, but can be imported using\n\t"
1944 			    "the '-f' flag.\n"));
1945 	}
1946 
1947 	if (msgid != NULL)
1948 		(void) printf(gettext("   see: http://illumos.org/msg/%s\n"),
1949 		    msgid);
1950 
1951 	(void) printf(gettext(" config:\n\n"));
1952 
1953 	namewidth = max_width(NULL, nvroot, 0, 0);
1954 	if (namewidth < 10)
1955 		namewidth = 10;
1956 
1957 	print_import_config(name, nvroot, namewidth, 0);
1958 	if (num_logs(nvroot) > 0)
1959 		print_logs(NULL, nvroot, namewidth, B_FALSE);
1960 
1961 	if (reason == ZPOOL_STATUS_BAD_GUID_SUM) {
1962 		(void) printf(gettext("\n\tAdditional devices are known to "
1963 		    "be part of this pool, though their\n\texact "
1964 		    "configuration cannot be determined.\n"));
1965 	}
1966 }
1967 
1968 /*
1969  * Perform the import for the given configuration.  This passes the heavy
1970  * lifting off to zpool_import_props(), and then mounts the datasets contained
1971  * within the pool.
1972  */
1973 static int
1974 do_import(nvlist_t *config, const char *newname, const char *mntopts,
1975     nvlist_t *props, int flags)
1976 {
1977 	zpool_handle_t *zhp;
1978 	char *name;
1979 	uint64_t state;
1980 	uint64_t version;
1981 
1982 	verify(nvlist_lookup_string(config, ZPOOL_CONFIG_POOL_NAME,
1983 	    &name) == 0);
1984 
1985 	verify(nvlist_lookup_uint64(config,
1986 	    ZPOOL_CONFIG_POOL_STATE, &state) == 0);
1987 	verify(nvlist_lookup_uint64(config,
1988 	    ZPOOL_CONFIG_VERSION, &version) == 0);
1989 	if (!SPA_VERSION_IS_SUPPORTED(version)) {
1990 		(void) fprintf(stderr, gettext("cannot import '%s': pool "
1991 		    "is formatted using an unsupported ZFS version\n"), name);
1992 		return (1);
1993 	} else if (state != POOL_STATE_EXPORTED &&
1994 	    !(flags & ZFS_IMPORT_ANY_HOST)) {
1995 		uint64_t hostid;
1996 
1997 		if (nvlist_lookup_uint64(config, ZPOOL_CONFIG_HOSTID,
1998 		    &hostid) == 0) {
1999 			if ((unsigned long)hostid != gethostid()) {
2000 				char *hostname;
2001 				uint64_t timestamp;
2002 				time_t t;
2003 
2004 				verify(nvlist_lookup_string(config,
2005 				    ZPOOL_CONFIG_HOSTNAME, &hostname) == 0);
2006 				verify(nvlist_lookup_uint64(config,
2007 				    ZPOOL_CONFIG_TIMESTAMP, &timestamp) == 0);
2008 				t = timestamp;
2009 				(void) fprintf(stderr, gettext("cannot import "
2010 				    "'%s': pool may be in use from other "
2011 				    "system, it was last accessed by %s "
2012 				    "(hostid: 0x%lx) on %s"), name, hostname,
2013 				    (unsigned long)hostid,
2014 				    asctime(localtime(&t)));
2015 				(void) fprintf(stderr, gettext("use '-f' to "
2016 				    "import anyway\n"));
2017 				return (1);
2018 			}
2019 		} else {
2020 			(void) fprintf(stderr, gettext("cannot import '%s': "
2021 			    "pool may be in use from other system\n"), name);
2022 			(void) fprintf(stderr, gettext("use '-f' to import "
2023 			    "anyway\n"));
2024 			return (1);
2025 		}
2026 	}
2027 
2028 	if (zpool_import_props(g_zfs, config, newname, props, flags) != 0)
2029 		return (1);
2030 
2031 	if (newname != NULL)
2032 		name = (char *)newname;
2033 
2034 	if ((zhp = zpool_open_canfail(g_zfs, name)) == NULL)
2035 		return (1);
2036 
2037 	if (zpool_get_state(zhp) != POOL_STATE_UNAVAIL &&
2038 	    !(flags & ZFS_IMPORT_ONLY) &&
2039 	    zpool_enable_datasets(zhp, mntopts, 0) != 0) {
2040 		zpool_close(zhp);
2041 		return (1);
2042 	}
2043 
2044 	zpool_close(zhp);
2045 	return (0);
2046 }
2047 
2048 /*
2049  * zpool import [-d dir] [-D]
2050  *       import [-o mntopts] [-o prop=value] ... [-R root] [-D]
2051  *              [-d dir | -c cachefile] [-f] -a
2052  *       import [-o mntopts] [-o prop=value] ... [-R root] [-D]
2053  *              [-d dir | -c cachefile] [-f] [-n] [-F] <pool | id> [newpool]
2054  *
2055  *	 -c	Read pool information from a cachefile instead of searching
2056  *		devices.
2057  *
2058  *       -d	Scan in a specific directory, other than /dev/dsk.  More than
2059  *		one directory can be specified using multiple '-d' options.
2060  *
2061  *       -D     Scan for previously destroyed pools or import all or only
2062  *              specified destroyed pools.
2063  *
2064  *       -R	Temporarily import the pool, with all mountpoints relative to
2065  *		the given root.  The pool will remain exported when the machine
2066  *		is rebooted.
2067  *
2068  *       -V	Import even in the presence of faulted vdevs.  This is an
2069  *       	intentionally undocumented option for testing purposes, and
2070  *       	treats the pool configuration as complete, leaving any bad
2071  *		vdevs in the FAULTED state. In other words, it does verbatim
2072  *		import.
2073  *
2074  *       -f	Force import, even if it appears that the pool is active.
2075  *
2076  *       -F     Attempt rewind if necessary.
2077  *
2078  *       -n     See if rewind would work, but don't actually rewind.
2079  *
2080  *       -N     Import the pool but don't mount datasets.
2081  *
2082  *       -T     Specify a starting txg to use for import. This option is
2083  *       	intentionally undocumented option for testing purposes.
2084  *
2085  *       -a	Import all pools found.
2086  *
2087  *       -o	Set property=value and/or temporary mount options (without '=').
2088  *
2089  * The import command scans for pools to import, and import pools based on pool
2090  * name and GUID.  The pool can also be renamed as part of the import process.
2091  */
2092 int
2093 zpool_do_import(int argc, char **argv)
2094 {
2095 	char **searchdirs = NULL;
2096 	int nsearch = 0;
2097 	int c;
2098 	int err = 0;
2099 	nvlist_t *pools = NULL;
2100 	boolean_t do_all = B_FALSE;
2101 	boolean_t do_destroyed = B_FALSE;
2102 	char *mntopts = NULL;
2103 	nvpair_t *elem;
2104 	nvlist_t *config;
2105 	uint64_t searchguid = 0;
2106 	char *searchname = NULL;
2107 	char *propval;
2108 	nvlist_t *found_config;
2109 	nvlist_t *policy = NULL;
2110 	nvlist_t *props = NULL;
2111 	boolean_t first;
2112 	int flags = ZFS_IMPORT_NORMAL;
2113 	uint32_t rewind_policy = ZPOOL_NO_REWIND;
2114 	boolean_t dryrun = B_FALSE;
2115 	boolean_t do_rewind = B_FALSE;
2116 	boolean_t xtreme_rewind = B_FALSE;
2117 	uint64_t pool_state, txg = -1ULL;
2118 	char *cachefile = NULL;
2119 	importargs_t idata = { 0 };
2120 	char *endptr;
2121 
2122 	/* check options */
2123 	while ((c = getopt(argc, argv, ":aCc:d:DEfFmnNo:rR:T:VX")) != -1) {
2124 		switch (c) {
2125 		case 'a':
2126 			do_all = B_TRUE;
2127 			break;
2128 		case 'c':
2129 			cachefile = optarg;
2130 			break;
2131 		case 'd':
2132 			if (searchdirs == NULL) {
2133 				searchdirs = safe_malloc(sizeof (char *));
2134 			} else {
2135 				char **tmp = safe_malloc((nsearch + 1) *
2136 				    sizeof (char *));
2137 				bcopy(searchdirs, tmp, nsearch *
2138 				    sizeof (char *));
2139 				free(searchdirs);
2140 				searchdirs = tmp;
2141 			}
2142 			searchdirs[nsearch++] = optarg;
2143 			break;
2144 		case 'D':
2145 			do_destroyed = B_TRUE;
2146 			break;
2147 		case 'f':
2148 			flags |= ZFS_IMPORT_ANY_HOST;
2149 			break;
2150 		case 'F':
2151 			do_rewind = B_TRUE;
2152 			break;
2153 		case 'm':
2154 			flags |= ZFS_IMPORT_MISSING_LOG;
2155 			break;
2156 		case 'n':
2157 			dryrun = B_TRUE;
2158 			break;
2159 		case 'N':
2160 			flags |= ZFS_IMPORT_ONLY;
2161 			break;
2162 		case 'o':
2163 			if ((propval = strchr(optarg, '=')) != NULL) {
2164 				*propval = '\0';
2165 				propval++;
2166 				if (add_prop_list(optarg, propval,
2167 				    &props, B_TRUE))
2168 					goto error;
2169 			} else {
2170 				mntopts = optarg;
2171 			}
2172 			break;
2173 		case 'R':
2174 			if (add_prop_list(zpool_prop_to_name(
2175 			    ZPOOL_PROP_ALTROOT), optarg, &props, B_TRUE))
2176 				goto error;
2177 			if (nvlist_lookup_string(props,
2178 			    zpool_prop_to_name(ZPOOL_PROP_CACHEFILE),
2179 			    &propval) == 0)
2180 				break;
2181 			if (add_prop_list(zpool_prop_to_name(
2182 			    ZPOOL_PROP_CACHEFILE), "none", &props, B_TRUE))
2183 				goto error;
2184 			break;
2185 		case 'T':
2186 			errno = 0;
2187 			txg = strtoull(optarg, &endptr, 0);
2188 			if (errno != 0 || *endptr != '\0') {
2189 				(void) fprintf(stderr,
2190 				    gettext("invalid txg value\n"));
2191 				usage(B_FALSE);
2192 			}
2193 			rewind_policy = ZPOOL_DO_REWIND | ZPOOL_EXTREME_REWIND;
2194 			break;
2195 		case 'V':
2196 			flags |= ZFS_IMPORT_VERBATIM;
2197 			break;
2198 		case 'X':
2199 			xtreme_rewind = B_TRUE;
2200 			break;
2201 		case ':':
2202 			(void) fprintf(stderr, gettext("missing argument for "
2203 			    "'%c' option\n"), optopt);
2204 			usage(B_FALSE);
2205 			break;
2206 		case '?':
2207 			(void) fprintf(stderr, gettext("invalid option '%c'\n"),
2208 			    optopt);
2209 			usage(B_FALSE);
2210 		}
2211 	}
2212 
2213 	argc -= optind;
2214 	argv += optind;
2215 
2216 	if (cachefile && nsearch != 0) {
2217 		(void) fprintf(stderr, gettext("-c is incompatible with -d\n"));
2218 		usage(B_FALSE);
2219 	}
2220 
2221 	if ((dryrun || xtreme_rewind) && !do_rewind) {
2222 		(void) fprintf(stderr,
2223 		    gettext("-n or -X only meaningful with -F\n"));
2224 		usage(B_FALSE);
2225 	}
2226 	if (dryrun)
2227 		rewind_policy = ZPOOL_TRY_REWIND;
2228 	else if (do_rewind)
2229 		rewind_policy = ZPOOL_DO_REWIND;
2230 	if (xtreme_rewind)
2231 		rewind_policy |= ZPOOL_EXTREME_REWIND;
2232 
2233 	/* In the future, we can capture further policy and include it here */
2234 	if (nvlist_alloc(&policy, NV_UNIQUE_NAME, 0) != 0 ||
2235 	    nvlist_add_uint64(policy, ZPOOL_REWIND_REQUEST_TXG, txg) != 0 ||
2236 	    nvlist_add_uint32(policy, ZPOOL_REWIND_REQUEST, rewind_policy) != 0)
2237 		goto error;
2238 
2239 	if (searchdirs == NULL) {
2240 		searchdirs = safe_malloc(sizeof (char *));
2241 		searchdirs[0] = ZFS_DISK_ROOT;
2242 		nsearch = 1;
2243 	}
2244 
2245 	/* check argument count */
2246 	if (do_all) {
2247 		if (argc != 0) {
2248 			(void) fprintf(stderr, gettext("too many arguments\n"));
2249 			usage(B_FALSE);
2250 		}
2251 	} else {
2252 		if (argc > 2) {
2253 			(void) fprintf(stderr, gettext("too many arguments\n"));
2254 			usage(B_FALSE);
2255 		}
2256 
2257 		/*
2258 		 * Check for the SYS_CONFIG privilege.  We do this explicitly
2259 		 * here because otherwise any attempt to discover pools will
2260 		 * silently fail.
2261 		 */
2262 		if (argc == 0 && !priv_ineffect(PRIV_SYS_CONFIG)) {
2263 			(void) fprintf(stderr, gettext("cannot "
2264 			    "discover pools: permission denied\n"));
2265 			free(searchdirs);
2266 			nvlist_free(policy);
2267 			return (1);
2268 		}
2269 	}
2270 
2271 	/*
2272 	 * Depending on the arguments given, we do one of the following:
2273 	 *
2274 	 *	<none>	Iterate through all pools and display information about
2275 	 *		each one.
2276 	 *
2277 	 *	-a	Iterate through all pools and try to import each one.
2278 	 *
2279 	 *	<id>	Find the pool that corresponds to the given GUID/pool
2280 	 *		name and import that one.
2281 	 *
2282 	 *	-D	Above options applies only to destroyed pools.
2283 	 */
2284 	if (argc != 0) {
2285 		char *endptr;
2286 
2287 		errno = 0;
2288 		searchguid = strtoull(argv[0], &endptr, 10);
2289 		if (errno != 0 || *endptr != '\0') {
2290 			searchname = argv[0];
2291 			searchguid = 0;
2292 		}
2293 		found_config = NULL;
2294 
2295 		/*
2296 		 * User specified a name or guid.  Ensure it's unique.
2297 		 */
2298 		idata.unique = B_TRUE;
2299 	}
2300 
2301 
2302 	idata.path = searchdirs;
2303 	idata.paths = nsearch;
2304 	idata.poolname = searchname;
2305 	idata.guid = searchguid;
2306 	idata.cachefile = cachefile;
2307 	idata.policy = policy;
2308 
2309 	pools = zpool_search_import(g_zfs, &idata);
2310 
2311 	if (pools != NULL && idata.exists &&
2312 	    (argc == 1 || strcmp(argv[0], argv[1]) == 0)) {
2313 		(void) fprintf(stderr, gettext("cannot import '%s': "
2314 		    "a pool with that name already exists\n"),
2315 		    argv[0]);
2316 		(void) fprintf(stderr, gettext("use the form '%s "
2317 		    "<pool | id> <newpool>' to give it a new name\n"),
2318 		    "zpool import");
2319 		err = 1;
2320 	} else if (pools == NULL && idata.exists) {
2321 		(void) fprintf(stderr, gettext("cannot import '%s': "
2322 		    "a pool with that name is already created/imported,\n"),
2323 		    argv[0]);
2324 		(void) fprintf(stderr, gettext("and no additional pools "
2325 		    "with that name were found\n"));
2326 		err = 1;
2327 	} else if (pools == NULL) {
2328 		if (argc != 0) {
2329 			(void) fprintf(stderr, gettext("cannot import '%s': "
2330 			    "no such pool available\n"), argv[0]);
2331 		}
2332 		err = 1;
2333 	}
2334 
2335 	if (err == 1) {
2336 		free(searchdirs);
2337 		nvlist_free(policy);
2338 		return (1);
2339 	}
2340 
2341 	/*
2342 	 * At this point we have a list of import candidate configs. Even if
2343 	 * we were searching by pool name or guid, we still need to
2344 	 * post-process the list to deal with pool state and possible
2345 	 * duplicate names.
2346 	 */
2347 	err = 0;
2348 	elem = NULL;
2349 	first = B_TRUE;
2350 	while ((elem = nvlist_next_nvpair(pools, elem)) != NULL) {
2351 
2352 		verify(nvpair_value_nvlist(elem, &config) == 0);
2353 
2354 		verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_STATE,
2355 		    &pool_state) == 0);
2356 		if (!do_destroyed && pool_state == POOL_STATE_DESTROYED)
2357 			continue;
2358 		if (do_destroyed && pool_state != POOL_STATE_DESTROYED)
2359 			continue;
2360 
2361 		verify(nvlist_add_nvlist(config, ZPOOL_REWIND_POLICY,
2362 		    policy) == 0);
2363 
2364 		if (argc == 0) {
2365 			if (first)
2366 				first = B_FALSE;
2367 			else if (!do_all)
2368 				(void) printf("\n");
2369 
2370 			if (do_all) {
2371 				err |= do_import(config, NULL, mntopts,
2372 				    props, flags);
2373 			} else {
2374 				show_import(config);
2375 			}
2376 		} else if (searchname != NULL) {
2377 			char *name;
2378 
2379 			/*
2380 			 * We are searching for a pool based on name.
2381 			 */
2382 			verify(nvlist_lookup_string(config,
2383 			    ZPOOL_CONFIG_POOL_NAME, &name) == 0);
2384 
2385 			if (strcmp(name, searchname) == 0) {
2386 				if (found_config != NULL) {
2387 					(void) fprintf(stderr, gettext(
2388 					    "cannot import '%s': more than "
2389 					    "one matching pool\n"), searchname);
2390 					(void) fprintf(stderr, gettext(
2391 					    "import by numeric ID instead\n"));
2392 					err = B_TRUE;
2393 				}
2394 				found_config = config;
2395 			}
2396 		} else {
2397 			uint64_t guid;
2398 
2399 			/*
2400 			 * Search for a pool by guid.
2401 			 */
2402 			verify(nvlist_lookup_uint64(config,
2403 			    ZPOOL_CONFIG_POOL_GUID, &guid) == 0);
2404 
2405 			if (guid == searchguid)
2406 				found_config = config;
2407 		}
2408 	}
2409 
2410 	/*
2411 	 * If we were searching for a specific pool, verify that we found a
2412 	 * pool, and then do the import.
2413 	 */
2414 	if (argc != 0 && err == 0) {
2415 		if (found_config == NULL) {
2416 			(void) fprintf(stderr, gettext("cannot import '%s': "
2417 			    "no such pool available\n"), argv[0]);
2418 			err = B_TRUE;
2419 		} else {
2420 			err |= do_import(found_config, argc == 1 ? NULL :
2421 			    argv[1], mntopts, props, flags);
2422 		}
2423 	}
2424 
2425 	/*
2426 	 * If we were just looking for pools, report an error if none were
2427 	 * found.
2428 	 */
2429 	if (argc == 0 && first)
2430 		(void) fprintf(stderr,
2431 		    gettext("no pools available to import\n"));
2432 
2433 error:
2434 	nvlist_free(props);
2435 	nvlist_free(pools);
2436 	nvlist_free(policy);
2437 	free(searchdirs);
2438 
2439 	return (err ? 1 : 0);
2440 }
2441 
2442 typedef struct iostat_cbdata {
2443 	boolean_t cb_verbose;
2444 	int cb_namewidth;
2445 	int cb_iteration;
2446 	zpool_list_t *cb_list;
2447 } iostat_cbdata_t;
2448 
2449 static void
2450 print_iostat_separator(iostat_cbdata_t *cb)
2451 {
2452 	int i = 0;
2453 
2454 	for (i = 0; i < cb->cb_namewidth; i++)
2455 		(void) printf("-");
2456 	(void) printf("  -----  -----  -----  -----  -----  -----\n");
2457 }
2458 
2459 static void
2460 print_iostat_header(iostat_cbdata_t *cb)
2461 {
2462 	(void) printf("%*s     capacity     operations    bandwidth\n",
2463 	    cb->cb_namewidth, "");
2464 	(void) printf("%-*s  alloc   free   read  write   read  write\n",
2465 	    cb->cb_namewidth, "pool");
2466 	print_iostat_separator(cb);
2467 }
2468 
2469 /*
2470  * Display a single statistic.
2471  */
2472 static void
2473 print_one_stat(uint64_t value)
2474 {
2475 	char buf[64];
2476 
2477 	zfs_nicenum(value, buf, sizeof (buf));
2478 	(void) printf("  %5s", buf);
2479 }
2480 
2481 /*
2482  * Print out all the statistics for the given vdev.  This can either be the
2483  * toplevel configuration, or called recursively.  If 'name' is NULL, then this
2484  * is a verbose output, and we don't want to display the toplevel pool stats.
2485  */
2486 void
2487 print_vdev_stats(zpool_handle_t *zhp, const char *name, nvlist_t *oldnv,
2488     nvlist_t *newnv, iostat_cbdata_t *cb, int depth)
2489 {
2490 	nvlist_t **oldchild, **newchild;
2491 	uint_t c, children;
2492 	vdev_stat_t *oldvs, *newvs;
2493 	vdev_stat_t zerovs = { 0 };
2494 	uint64_t tdelta;
2495 	double scale;
2496 	char *vname;
2497 
2498 	if (strcmp(name, VDEV_TYPE_INDIRECT) == 0)
2499 		return;
2500 
2501 	if (oldnv != NULL) {
2502 		verify(nvlist_lookup_uint64_array(oldnv,
2503 		    ZPOOL_CONFIG_VDEV_STATS, (uint64_t **)&oldvs, &c) == 0);
2504 	} else {
2505 		oldvs = &zerovs;
2506 	}
2507 
2508 	verify(nvlist_lookup_uint64_array(newnv, ZPOOL_CONFIG_VDEV_STATS,
2509 	    (uint64_t **)&newvs, &c) == 0);
2510 
2511 	if (strlen(name) + depth > cb->cb_namewidth)
2512 		(void) printf("%*s%s", depth, "", name);
2513 	else
2514 		(void) printf("%*s%s%*s", depth, "", name,
2515 		    (int)(cb->cb_namewidth - strlen(name) - depth), "");
2516 
2517 	tdelta = newvs->vs_timestamp - oldvs->vs_timestamp;
2518 
2519 	if (tdelta == 0)
2520 		scale = 1.0;
2521 	else
2522 		scale = (double)NANOSEC / tdelta;
2523 
2524 	/* only toplevel vdevs have capacity stats */
2525 	if (newvs->vs_space == 0) {
2526 		(void) printf("      -      -");
2527 	} else {
2528 		print_one_stat(newvs->vs_alloc);
2529 		print_one_stat(newvs->vs_space - newvs->vs_alloc);
2530 	}
2531 
2532 	print_one_stat((uint64_t)(scale * (newvs->vs_ops[ZIO_TYPE_READ] -
2533 	    oldvs->vs_ops[ZIO_TYPE_READ])));
2534 
2535 	print_one_stat((uint64_t)(scale * (newvs->vs_ops[ZIO_TYPE_WRITE] -
2536 	    oldvs->vs_ops[ZIO_TYPE_WRITE])));
2537 
2538 	print_one_stat((uint64_t)(scale * (newvs->vs_bytes[ZIO_TYPE_READ] -
2539 	    oldvs->vs_bytes[ZIO_TYPE_READ])));
2540 
2541 	print_one_stat((uint64_t)(scale * (newvs->vs_bytes[ZIO_TYPE_WRITE] -
2542 	    oldvs->vs_bytes[ZIO_TYPE_WRITE])));
2543 
2544 	(void) printf("\n");
2545 
2546 	if (!cb->cb_verbose)
2547 		return;
2548 
2549 	if (nvlist_lookup_nvlist_array(newnv, ZPOOL_CONFIG_CHILDREN,
2550 	    &newchild, &children) != 0)
2551 		return;
2552 
2553 	if (oldnv && nvlist_lookup_nvlist_array(oldnv, ZPOOL_CONFIG_CHILDREN,
2554 	    &oldchild, &c) != 0)
2555 		return;
2556 
2557 	for (c = 0; c < children; c++) {
2558 		uint64_t ishole = B_FALSE, islog = B_FALSE;
2559 
2560 		(void) nvlist_lookup_uint64(newchild[c], ZPOOL_CONFIG_IS_HOLE,
2561 		    &ishole);
2562 
2563 		(void) nvlist_lookup_uint64(newchild[c], ZPOOL_CONFIG_IS_LOG,
2564 		    &islog);
2565 
2566 		if (ishole || islog)
2567 			continue;
2568 
2569 		vname = zpool_vdev_name(g_zfs, zhp, newchild[c], B_FALSE);
2570 		print_vdev_stats(zhp, vname, oldnv ? oldchild[c] : NULL,
2571 		    newchild[c], cb, depth + 2);
2572 		free(vname);
2573 	}
2574 
2575 	/*
2576 	 * Log device section
2577 	 */
2578 
2579 	if (num_logs(newnv) > 0) {
2580 		(void) printf("%-*s      -      -      -      -      -      "
2581 		    "-\n", cb->cb_namewidth, "logs");
2582 
2583 		for (c = 0; c < children; c++) {
2584 			uint64_t islog = B_FALSE;
2585 			(void) nvlist_lookup_uint64(newchild[c],
2586 			    ZPOOL_CONFIG_IS_LOG, &islog);
2587 
2588 			if (islog) {
2589 				vname = zpool_vdev_name(g_zfs, zhp, newchild[c],
2590 				    B_FALSE);
2591 				print_vdev_stats(zhp, vname, oldnv ?
2592 				    oldchild[c] : NULL, newchild[c],
2593 				    cb, depth + 2);
2594 				free(vname);
2595 			}
2596 		}
2597 
2598 	}
2599 
2600 	/*
2601 	 * Include level 2 ARC devices in iostat output
2602 	 */
2603 	if (nvlist_lookup_nvlist_array(newnv, ZPOOL_CONFIG_L2CACHE,
2604 	    &newchild, &children) != 0)
2605 		return;
2606 
2607 	if (oldnv && nvlist_lookup_nvlist_array(oldnv, ZPOOL_CONFIG_L2CACHE,
2608 	    &oldchild, &c) != 0)
2609 		return;
2610 
2611 	if (children > 0) {
2612 		(void) printf("%-*s      -      -      -      -      -      "
2613 		    "-\n", cb->cb_namewidth, "cache");
2614 		for (c = 0; c < children; c++) {
2615 			vname = zpool_vdev_name(g_zfs, zhp, newchild[c],
2616 			    B_FALSE);
2617 			print_vdev_stats(zhp, vname, oldnv ? oldchild[c] : NULL,
2618 			    newchild[c], cb, depth + 2);
2619 			free(vname);
2620 		}
2621 	}
2622 }
2623 
2624 static int
2625 refresh_iostat(zpool_handle_t *zhp, void *data)
2626 {
2627 	iostat_cbdata_t *cb = data;
2628 	boolean_t missing;
2629 
2630 	/*
2631 	 * If the pool has disappeared, remove it from the list and continue.
2632 	 */
2633 	if (zpool_refresh_stats(zhp, &missing) != 0)
2634 		return (-1);
2635 
2636 	if (missing)
2637 		pool_list_remove(cb->cb_list, zhp);
2638 
2639 	return (0);
2640 }
2641 
2642 /*
2643  * Callback to print out the iostats for the given pool.
2644  */
2645 int
2646 print_iostat(zpool_handle_t *zhp, void *data)
2647 {
2648 	iostat_cbdata_t *cb = data;
2649 	nvlist_t *oldconfig, *newconfig;
2650 	nvlist_t *oldnvroot, *newnvroot;
2651 
2652 	newconfig = zpool_get_config(zhp, &oldconfig);
2653 
2654 	if (cb->cb_iteration == 1)
2655 		oldconfig = NULL;
2656 
2657 	verify(nvlist_lookup_nvlist(newconfig, ZPOOL_CONFIG_VDEV_TREE,
2658 	    &newnvroot) == 0);
2659 
2660 	if (oldconfig == NULL)
2661 		oldnvroot = NULL;
2662 	else
2663 		verify(nvlist_lookup_nvlist(oldconfig, ZPOOL_CONFIG_VDEV_TREE,
2664 		    &oldnvroot) == 0);
2665 
2666 	/*
2667 	 * Print out the statistics for the pool.
2668 	 */
2669 	print_vdev_stats(zhp, zpool_get_name(zhp), oldnvroot, newnvroot, cb, 0);
2670 
2671 	if (cb->cb_verbose)
2672 		print_iostat_separator(cb);
2673 
2674 	return (0);
2675 }
2676 
2677 int
2678 get_namewidth(zpool_handle_t *zhp, void *data)
2679 {
2680 	iostat_cbdata_t *cb = data;
2681 	nvlist_t *config, *nvroot;
2682 
2683 	if ((config = zpool_get_config(zhp, NULL)) != NULL) {
2684 		verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
2685 		    &nvroot) == 0);
2686 		if (!cb->cb_verbose)
2687 			cb->cb_namewidth = strlen(zpool_get_name(zhp));
2688 		else
2689 			cb->cb_namewidth = max_width(zhp, nvroot, 0,
2690 			    cb->cb_namewidth);
2691 	}
2692 
2693 	/*
2694 	 * The width must fall into the range [10,38].  The upper limit is the
2695 	 * maximum we can have and still fit in 80 columns.
2696 	 */
2697 	if (cb->cb_namewidth < 10)
2698 		cb->cb_namewidth = 10;
2699 	if (cb->cb_namewidth > 38)
2700 		cb->cb_namewidth = 38;
2701 
2702 	return (0);
2703 }
2704 
2705 /*
2706  * Parse the input string, get the 'interval' and 'count' value if there is one.
2707  */
2708 static void
2709 get_interval_count(int *argcp, char **argv, unsigned long *iv,
2710     unsigned long *cnt)
2711 {
2712 	unsigned long interval = 0, count = 0;
2713 	int argc = *argcp, errno;
2714 
2715 	/*
2716 	 * Determine if the last argument is an integer or a pool name
2717 	 */
2718 	if (argc > 0 && isdigit(argv[argc - 1][0])) {
2719 		char *end;
2720 
2721 		errno = 0;
2722 		interval = strtoul(argv[argc - 1], &end, 10);
2723 
2724 		if (*end == '\0' && errno == 0) {
2725 			if (interval == 0) {
2726 				(void) fprintf(stderr, gettext("interval "
2727 				    "cannot be zero\n"));
2728 				usage(B_FALSE);
2729 			}
2730 			/*
2731 			 * Ignore the last parameter
2732 			 */
2733 			argc--;
2734 		} else {
2735 			/*
2736 			 * If this is not a valid number, just plow on.  The
2737 			 * user will get a more informative error message later
2738 			 * on.
2739 			 */
2740 			interval = 0;
2741 		}
2742 	}
2743 
2744 	/*
2745 	 * If the last argument is also an integer, then we have both a count
2746 	 * and an interval.
2747 	 */
2748 	if (argc > 0 && isdigit(argv[argc - 1][0])) {
2749 		char *end;
2750 
2751 		errno = 0;
2752 		count = interval;
2753 		interval = strtoul(argv[argc - 1], &end, 10);
2754 
2755 		if (*end == '\0' && errno == 0) {
2756 			if (interval == 0) {
2757 				(void) fprintf(stderr, gettext("interval "
2758 				    "cannot be zero\n"));
2759 				usage(B_FALSE);
2760 			}
2761 
2762 			/*
2763 			 * Ignore the last parameter
2764 			 */
2765 			argc--;
2766 		} else {
2767 			interval = 0;
2768 		}
2769 	}
2770 
2771 	*iv = interval;
2772 	*cnt = count;
2773 	*argcp = argc;
2774 }
2775 
2776 static void
2777 get_timestamp_arg(char c)
2778 {
2779 	if (c == 'u')
2780 		timestamp_fmt = UDATE;
2781 	else if (c == 'd')
2782 		timestamp_fmt = DDATE;
2783 	else
2784 		usage(B_FALSE);
2785 }
2786 
2787 /*
2788  * zpool iostat [-v] [-T d|u] [pool] ... [interval [count]]
2789  *
2790  *	-v	Display statistics for individual vdevs
2791  *	-T	Display a timestamp in date(1) or Unix format
2792  *
2793  * This command can be tricky because we want to be able to deal with pool
2794  * creation/destruction as well as vdev configuration changes.  The bulk of this
2795  * processing is handled by the pool_list_* routines in zpool_iter.c.  We rely
2796  * on pool_list_update() to detect the addition of new pools.  Configuration
2797  * changes are all handled within libzfs.
2798  */
2799 int
2800 zpool_do_iostat(int argc, char **argv)
2801 {
2802 	int c;
2803 	int ret;
2804 	int npools;
2805 	unsigned long interval = 0, count = 0;
2806 	zpool_list_t *list;
2807 	boolean_t verbose = B_FALSE;
2808 	iostat_cbdata_t cb;
2809 
2810 	/* check options */
2811 	while ((c = getopt(argc, argv, "T:v")) != -1) {
2812 		switch (c) {
2813 		case 'T':
2814 			get_timestamp_arg(*optarg);
2815 			break;
2816 		case 'v':
2817 			verbose = B_TRUE;
2818 			break;
2819 		case '?':
2820 			(void) fprintf(stderr, gettext("invalid option '%c'\n"),
2821 			    optopt);
2822 			usage(B_FALSE);
2823 		}
2824 	}
2825 
2826 	argc -= optind;
2827 	argv += optind;
2828 
2829 	get_interval_count(&argc, argv, &interval, &count);
2830 
2831 	/*
2832 	 * Construct the list of all interesting pools.
2833 	 */
2834 	ret = 0;
2835 	if ((list = pool_list_get(argc, argv, NULL, &ret)) == NULL)
2836 		return (1);
2837 
2838 	if (pool_list_count(list) == 0 && argc != 0) {
2839 		pool_list_free(list);
2840 		return (1);
2841 	}
2842 
2843 	if (pool_list_count(list) == 0 && interval == 0) {
2844 		pool_list_free(list);
2845 		(void) fprintf(stderr, gettext("no pools available\n"));
2846 		return (1);
2847 	}
2848 
2849 	/*
2850 	 * Enter the main iostat loop.
2851 	 */
2852 	cb.cb_list = list;
2853 	cb.cb_verbose = verbose;
2854 	cb.cb_iteration = 0;
2855 	cb.cb_namewidth = 0;
2856 
2857 	for (;;) {
2858 		pool_list_update(list);
2859 
2860 		if ((npools = pool_list_count(list)) == 0)
2861 			break;
2862 
2863 		/*
2864 		 * Refresh all statistics.  This is done as an explicit step
2865 		 * before calculating the maximum name width, so that any
2866 		 * configuration changes are properly accounted for.
2867 		 */
2868 		(void) pool_list_iter(list, B_FALSE, refresh_iostat, &cb);
2869 
2870 		/*
2871 		 * Iterate over all pools to determine the maximum width
2872 		 * for the pool / device name column across all pools.
2873 		 */
2874 		cb.cb_namewidth = 0;
2875 		(void) pool_list_iter(list, B_FALSE, get_namewidth, &cb);
2876 
2877 		if (timestamp_fmt != NODATE)
2878 			print_timestamp(timestamp_fmt);
2879 
2880 		/*
2881 		 * If it's the first time, or verbose mode, print the header.
2882 		 */
2883 		if (++cb.cb_iteration == 1 || verbose)
2884 			print_iostat_header(&cb);
2885 
2886 		(void) pool_list_iter(list, B_FALSE, print_iostat, &cb);
2887 
2888 		/*
2889 		 * If there's more than one pool, and we're not in verbose mode
2890 		 * (which prints a separator for us), then print a separator.
2891 		 */
2892 		if (npools > 1 && !verbose)
2893 			print_iostat_separator(&cb);
2894 
2895 		if (verbose)
2896 			(void) printf("\n");
2897 
2898 		/*
2899 		 * Flush the output so that redirection to a file isn't buffered
2900 		 * indefinitely.
2901 		 */
2902 		(void) fflush(stdout);
2903 
2904 		if (interval == 0)
2905 			break;
2906 
2907 		if (count != 0 && --count == 0)
2908 			break;
2909 
2910 		(void) sleep(interval);
2911 	}
2912 
2913 	pool_list_free(list);
2914 
2915 	return (ret);
2916 }
2917 
2918 typedef struct list_cbdata {
2919 	boolean_t	cb_verbose;
2920 	int		cb_namewidth;
2921 	boolean_t	cb_scripted;
2922 	zprop_list_t	*cb_proplist;
2923 	boolean_t	cb_literal;
2924 } list_cbdata_t;
2925 
2926 /*
2927  * Given a list of columns to display, output appropriate headers for each one.
2928  */
2929 static void
2930 print_header(list_cbdata_t *cb)
2931 {
2932 	zprop_list_t *pl = cb->cb_proplist;
2933 	char headerbuf[ZPOOL_MAXPROPLEN];
2934 	const char *header;
2935 	boolean_t first = B_TRUE;
2936 	boolean_t right_justify;
2937 	size_t width = 0;
2938 
2939 	for (; pl != NULL; pl = pl->pl_next) {
2940 		width = pl->pl_width;
2941 		if (first && cb->cb_verbose) {
2942 			/*
2943 			 * Reset the width to accommodate the verbose listing
2944 			 * of devices.
2945 			 */
2946 			width = cb->cb_namewidth;
2947 		}
2948 
2949 		if (!first)
2950 			(void) printf("  ");
2951 		else
2952 			first = B_FALSE;
2953 
2954 		right_justify = B_FALSE;
2955 		if (pl->pl_prop != ZPROP_INVAL) {
2956 			header = zpool_prop_column_name(pl->pl_prop);
2957 			right_justify = zpool_prop_align_right(pl->pl_prop);
2958 		} else {
2959 			int i;
2960 
2961 			for (i = 0; pl->pl_user_prop[i] != '\0'; i++)
2962 				headerbuf[i] = toupper(pl->pl_user_prop[i]);
2963 			headerbuf[i] = '\0';
2964 			header = headerbuf;
2965 		}
2966 
2967 		if (pl->pl_next == NULL && !right_justify)
2968 			(void) printf("%s", header);
2969 		else if (right_justify)
2970 			(void) printf("%*s", width, header);
2971 		else
2972 			(void) printf("%-*s", width, header);
2973 
2974 	}
2975 
2976 	(void) printf("\n");
2977 }
2978 
2979 /*
2980  * Given a pool and a list of properties, print out all the properties according
2981  * to the described layout.
2982  */
2983 static void
2984 print_pool(zpool_handle_t *zhp, list_cbdata_t *cb)
2985 {
2986 	zprop_list_t *pl = cb->cb_proplist;
2987 	boolean_t first = B_TRUE;
2988 	char property[ZPOOL_MAXPROPLEN];
2989 	char *propstr;
2990 	boolean_t right_justify;
2991 	size_t width;
2992 
2993 	for (; pl != NULL; pl = pl->pl_next) {
2994 
2995 		width = pl->pl_width;
2996 		if (first && cb->cb_verbose) {
2997 			/*
2998 			 * Reset the width to accommodate the verbose listing
2999 			 * of devices.
3000 			 */
3001 			width = cb->cb_namewidth;
3002 		}
3003 
3004 		if (!first) {
3005 			if (cb->cb_scripted)
3006 				(void) printf("\t");
3007 			else
3008 				(void) printf("  ");
3009 		} else {
3010 			first = B_FALSE;
3011 		}
3012 
3013 		right_justify = B_FALSE;
3014 		if (pl->pl_prop != ZPROP_INVAL) {
3015 			if (zpool_get_prop(zhp, pl->pl_prop, property,
3016 			    sizeof (property), NULL, cb->cb_literal) != 0)
3017 				propstr = "-";
3018 			else
3019 				propstr = property;
3020 
3021 			right_justify = zpool_prop_align_right(pl->pl_prop);
3022 		} else if ((zpool_prop_feature(pl->pl_user_prop) ||
3023 		    zpool_prop_unsupported(pl->pl_user_prop)) &&
3024 		    zpool_prop_get_feature(zhp, pl->pl_user_prop, property,
3025 		    sizeof (property)) == 0) {
3026 			propstr = property;
3027 		} else {
3028 			propstr = "-";
3029 		}
3030 
3031 
3032 		/*
3033 		 * If this is being called in scripted mode, or if this is the
3034 		 * last column and it is left-justified, don't include a width
3035 		 * format specifier.
3036 		 */
3037 		if (cb->cb_scripted || (pl->pl_next == NULL && !right_justify))
3038 			(void) printf("%s", propstr);
3039 		else if (right_justify)
3040 			(void) printf("%*s", width, propstr);
3041 		else
3042 			(void) printf("%-*s", width, propstr);
3043 	}
3044 
3045 	(void) printf("\n");
3046 }
3047 
3048 static void
3049 print_one_column(zpool_prop_t prop, uint64_t value, boolean_t scripted,
3050     boolean_t valid)
3051 {
3052 	char propval[64];
3053 	boolean_t fixed;
3054 	size_t width = zprop_width(prop, &fixed, ZFS_TYPE_POOL);
3055 
3056 	switch (prop) {
3057 	case ZPOOL_PROP_EXPANDSZ:
3058 		if (value == 0)
3059 			(void) strlcpy(propval, "-", sizeof (propval));
3060 		else
3061 			zfs_nicenum(value, propval, sizeof (propval));
3062 		break;
3063 	case ZPOOL_PROP_FRAGMENTATION:
3064 		if (value == ZFS_FRAG_INVALID) {
3065 			(void) strlcpy(propval, "-", sizeof (propval));
3066 		} else {
3067 			(void) snprintf(propval, sizeof (propval), "%llu%%",
3068 			    value);
3069 		}
3070 		break;
3071 	case ZPOOL_PROP_CAPACITY:
3072 		(void) snprintf(propval, sizeof (propval), "%llu%%", value);
3073 		break;
3074 	default:
3075 		zfs_nicenum(value, propval, sizeof (propval));
3076 	}
3077 
3078 	if (!valid)
3079 		(void) strlcpy(propval, "-", sizeof (propval));
3080 
3081 	if (scripted)
3082 		(void) printf("\t%s", propval);
3083 	else
3084 		(void) printf("  %*s", width, propval);
3085 }
3086 
3087 void
3088 print_list_stats(zpool_handle_t *zhp, const char *name, nvlist_t *nv,
3089     list_cbdata_t *cb, int depth)
3090 {
3091 	nvlist_t **child;
3092 	vdev_stat_t *vs;
3093 	uint_t c, children;
3094 	char *vname;
3095 	boolean_t scripted = cb->cb_scripted;
3096 	uint64_t islog = B_FALSE;
3097 	boolean_t haslog = B_FALSE;
3098 	char *dashes = "%-*s      -      -      -         -      -      -\n";
3099 
3100 	verify(nvlist_lookup_uint64_array(nv, ZPOOL_CONFIG_VDEV_STATS,
3101 	    (uint64_t **)&vs, &c) == 0);
3102 
3103 	if (name != NULL) {
3104 		boolean_t toplevel = (vs->vs_space != 0);
3105 		uint64_t cap;
3106 
3107 		if (strcmp(name, VDEV_TYPE_INDIRECT) == 0)
3108 			return;
3109 
3110 		if (scripted)
3111 			(void) printf("\t%s", name);
3112 		else if (strlen(name) + depth > cb->cb_namewidth)
3113 			(void) printf("%*s%s", depth, "", name);
3114 		else
3115 			(void) printf("%*s%s%*s", depth, "", name,
3116 			    (int)(cb->cb_namewidth - strlen(name) - depth), "");
3117 
3118 		/*
3119 		 * Print the properties for the individual vdevs. Some
3120 		 * properties are only applicable to toplevel vdevs. The
3121 		 * 'toplevel' boolean value is passed to the print_one_column()
3122 		 * to indicate that the value is valid.
3123 		 */
3124 		print_one_column(ZPOOL_PROP_SIZE, vs->vs_space, scripted,
3125 		    toplevel);
3126 		print_one_column(ZPOOL_PROP_ALLOCATED, vs->vs_alloc, scripted,
3127 		    toplevel);
3128 		print_one_column(ZPOOL_PROP_FREE, vs->vs_space - vs->vs_alloc,
3129 		    scripted, toplevel);
3130 		print_one_column(ZPOOL_PROP_EXPANDSZ, vs->vs_esize, scripted,
3131 		    B_TRUE);
3132 		print_one_column(ZPOOL_PROP_FRAGMENTATION,
3133 		    vs->vs_fragmentation, scripted,
3134 		    (vs->vs_fragmentation != ZFS_FRAG_INVALID && toplevel));
3135 		cap = (vs->vs_space == 0) ? 0 :
3136 		    (vs->vs_alloc * 100 / vs->vs_space);
3137 		print_one_column(ZPOOL_PROP_CAPACITY, cap, scripted, toplevel);
3138 		(void) printf("\n");
3139 	}
3140 
3141 	if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
3142 	    &child, &children) != 0)
3143 		return;
3144 
3145 	for (c = 0; c < children; c++) {
3146 		uint64_t ishole = B_FALSE;
3147 
3148 		if (nvlist_lookup_uint64(child[c],
3149 		    ZPOOL_CONFIG_IS_HOLE, &ishole) == 0 && ishole)
3150 			continue;
3151 
3152 		if (nvlist_lookup_uint64(child[c],
3153 		    ZPOOL_CONFIG_IS_LOG, &islog) == 0 && islog) {
3154 			haslog = B_TRUE;
3155 			continue;
3156 		}
3157 
3158 		vname = zpool_vdev_name(g_zfs, zhp, child[c], B_FALSE);
3159 		print_list_stats(zhp, vname, child[c], cb, depth + 2);
3160 		free(vname);
3161 	}
3162 
3163 	if (haslog == B_TRUE) {
3164 		/* LINTED E_SEC_PRINTF_VAR_FMT */
3165 		(void) printf(dashes, cb->cb_namewidth, "log");
3166 		for (c = 0; c < children; c++) {
3167 			if (nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_LOG,
3168 			    &islog) != 0 || !islog)
3169 				continue;
3170 			vname = zpool_vdev_name(g_zfs, zhp, child[c], B_FALSE);
3171 			print_list_stats(zhp, vname, child[c], cb, depth + 2);
3172 			free(vname);
3173 		}
3174 	}
3175 
3176 	if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_L2CACHE,
3177 	    &child, &children) == 0 && children > 0) {
3178 		/* LINTED E_SEC_PRINTF_VAR_FMT */
3179 		(void) printf(dashes, cb->cb_namewidth, "cache");
3180 		for (c = 0; c < children; c++) {
3181 			vname = zpool_vdev_name(g_zfs, zhp, child[c], B_FALSE);
3182 			print_list_stats(zhp, vname, child[c], cb, depth + 2);
3183 			free(vname);
3184 		}
3185 	}
3186 
3187 	if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_SPARES, &child,
3188 	    &children) == 0 && children > 0) {
3189 		/* LINTED E_SEC_PRINTF_VAR_FMT */
3190 		(void) printf(dashes, cb->cb_namewidth, "spare");
3191 		for (c = 0; c < children; c++) {
3192 			vname = zpool_vdev_name(g_zfs, zhp, child[c], B_FALSE);
3193 			print_list_stats(zhp, vname, child[c], cb, depth + 2);
3194 			free(vname);
3195 		}
3196 	}
3197 }
3198 
3199 
3200 /*
3201  * Generic callback function to list a pool.
3202  */
3203 int
3204 list_callback(zpool_handle_t *zhp, void *data)
3205 {
3206 	list_cbdata_t *cbp = data;
3207 	nvlist_t *config;
3208 	nvlist_t *nvroot;
3209 
3210 	config = zpool_get_config(zhp, NULL);
3211 
3212 	print_pool(zhp, cbp);
3213 	if (!cbp->cb_verbose)
3214 		return (0);
3215 
3216 	verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
3217 	    &nvroot) == 0);
3218 	print_list_stats(zhp, NULL, nvroot, cbp, 0);
3219 
3220 	return (0);
3221 }
3222 
3223 /*
3224  * zpool list [-Hp] [-o prop[,prop]*] [-T d|u] [pool] ... [interval [count]]
3225  *
3226  *	-H	Scripted mode.  Don't display headers, and separate properties
3227  *		by a single tab.
3228  *	-o	List of properties to display.  Defaults to
3229  *		"name,size,allocated,free,expandsize,fragmentation,capacity,"
3230  *		"dedupratio,health,altroot"
3231  * 	-p	Diplay values in parsable (exact) format.
3232  *	-T	Display a timestamp in date(1) or Unix format
3233  *
3234  * List all pools in the system, whether or not they're healthy.  Output space
3235  * statistics for each one, as well as health status summary.
3236  */
3237 int
3238 zpool_do_list(int argc, char **argv)
3239 {
3240 	int c;
3241 	int ret;
3242 	list_cbdata_t cb = { 0 };
3243 	static char default_props[] =
3244 	    "name,size,allocated,free,expandsize,fragmentation,capacity,"
3245 	    "dedupratio,health,altroot";
3246 	char *props = default_props;
3247 	unsigned long interval = 0, count = 0;
3248 	zpool_list_t *list;
3249 	boolean_t first = B_TRUE;
3250 
3251 	/* check options */
3252 	while ((c = getopt(argc, argv, ":Ho:pT:v")) != -1) {
3253 		switch (c) {
3254 		case 'H':
3255 			cb.cb_scripted = B_TRUE;
3256 			break;
3257 		case 'o':
3258 			props = optarg;
3259 			break;
3260 		case 'p':
3261 			cb.cb_literal = B_TRUE;
3262 			break;
3263 		case 'T':
3264 			get_timestamp_arg(*optarg);
3265 			break;
3266 		case 'v':
3267 			cb.cb_verbose = B_TRUE;
3268 			break;
3269 		case ':':
3270 			(void) fprintf(stderr, gettext("missing argument for "
3271 			    "'%c' option\n"), optopt);
3272 			usage(B_FALSE);
3273 			break;
3274 		case '?':
3275 			(void) fprintf(stderr, gettext("invalid option '%c'\n"),
3276 			    optopt);
3277 			usage(B_FALSE);
3278 		}
3279 	}
3280 
3281 	argc -= optind;
3282 	argv += optind;
3283 
3284 	get_interval_count(&argc, argv, &interval, &count);
3285 
3286 	if (zprop_get_list(g_zfs, props, &cb.cb_proplist, ZFS_TYPE_POOL) != 0)
3287 		usage(B_FALSE);
3288 
3289 	for (;;) {
3290 		if ((list = pool_list_get(argc, argv, &cb.cb_proplist,
3291 		    &ret)) == NULL)
3292 			return (1);
3293 
3294 		if (pool_list_count(list) == 0)
3295 			break;
3296 
3297 		cb.cb_namewidth = 0;
3298 		(void) pool_list_iter(list, B_FALSE, get_namewidth, &cb);
3299 
3300 		if (timestamp_fmt != NODATE)
3301 			print_timestamp(timestamp_fmt);
3302 
3303 		if (!cb.cb_scripted && (first || cb.cb_verbose)) {
3304 			print_header(&cb);
3305 			first = B_FALSE;
3306 		}
3307 		ret = pool_list_iter(list, B_TRUE, list_callback, &cb);
3308 
3309 		if (interval == 0)
3310 			break;
3311 
3312 		if (count != 0 && --count == 0)
3313 			break;
3314 
3315 		pool_list_free(list);
3316 		(void) sleep(interval);
3317 	}
3318 
3319 	if (argc == 0 && !cb.cb_scripted && pool_list_count(list) == 0) {
3320 		(void) printf(gettext("no pools available\n"));
3321 		ret = 0;
3322 	}
3323 
3324 	pool_list_free(list);
3325 	zprop_free_list(cb.cb_proplist);
3326 	return (ret);
3327 }
3328 
3329 static int
3330 zpool_do_attach_or_replace(int argc, char **argv, int replacing)
3331 {
3332 	boolean_t force = B_FALSE;
3333 	int c;
3334 	nvlist_t *nvroot;
3335 	char *poolname, *old_disk, *new_disk;
3336 	zpool_handle_t *zhp;
3337 	zpool_boot_label_t boot_type;
3338 	uint64_t boot_size;
3339 	int ret;
3340 
3341 	/* check options */
3342 	while ((c = getopt(argc, argv, "f")) != -1) {
3343 		switch (c) {
3344 		case 'f':
3345 			force = B_TRUE;
3346 			break;
3347 		case '?':
3348 			(void) fprintf(stderr, gettext("invalid option '%c'\n"),
3349 			    optopt);
3350 			usage(B_FALSE);
3351 		}
3352 	}
3353 
3354 	argc -= optind;
3355 	argv += optind;
3356 
3357 	/* get pool name and check number of arguments */
3358 	if (argc < 1) {
3359 		(void) fprintf(stderr, gettext("missing pool name argument\n"));
3360 		usage(B_FALSE);
3361 	}
3362 
3363 	poolname = argv[0];
3364 
3365 	if (argc < 2) {
3366 		(void) fprintf(stderr,
3367 		    gettext("missing <device> specification\n"));
3368 		usage(B_FALSE);
3369 	}
3370 
3371 	old_disk = argv[1];
3372 
3373 	if (argc < 3) {
3374 		if (!replacing) {
3375 			(void) fprintf(stderr,
3376 			    gettext("missing <new_device> specification\n"));
3377 			usage(B_FALSE);
3378 		}
3379 		new_disk = old_disk;
3380 		argc -= 1;
3381 		argv += 1;
3382 	} else {
3383 		new_disk = argv[2];
3384 		argc -= 2;
3385 		argv += 2;
3386 	}
3387 
3388 	if (argc > 1) {
3389 		(void) fprintf(stderr, gettext("too many arguments\n"));
3390 		usage(B_FALSE);
3391 	}
3392 
3393 	if ((zhp = zpool_open(g_zfs, poolname)) == NULL)
3394 		return (1);
3395 
3396 	if (zpool_get_config(zhp, NULL) == NULL) {
3397 		(void) fprintf(stderr, gettext("pool '%s' is unavailable\n"),
3398 		    poolname);
3399 		zpool_close(zhp);
3400 		return (1);
3401 	}
3402 
3403 	if (zpool_is_bootable(zhp))
3404 		boot_type = ZPOOL_COPY_BOOT_LABEL;
3405 	else
3406 		boot_type = ZPOOL_NO_BOOT_LABEL;
3407 
3408 	boot_size = zpool_get_prop_int(zhp, ZPOOL_PROP_BOOTSIZE, NULL);
3409 	nvroot = make_root_vdev(zhp, force, B_FALSE, replacing, B_FALSE,
3410 	    boot_type, boot_size, argc, argv);
3411 	if (nvroot == NULL) {
3412 		zpool_close(zhp);
3413 		return (1);
3414 	}
3415 
3416 	ret = zpool_vdev_attach(zhp, old_disk, new_disk, nvroot, replacing);
3417 
3418 	nvlist_free(nvroot);
3419 	zpool_close(zhp);
3420 
3421 	return (ret);
3422 }
3423 
3424 /*
3425  * zpool replace [-f] <pool> <device> <new_device>
3426  *
3427  *	-f	Force attach, even if <new_device> appears to be in use.
3428  *
3429  * Replace <device> with <new_device>.
3430  */
3431 /* ARGSUSED */
3432 int
3433 zpool_do_replace(int argc, char **argv)
3434 {
3435 	return (zpool_do_attach_or_replace(argc, argv, B_TRUE));
3436 }
3437 
3438 /*
3439  * zpool attach [-f] <pool> <device> <new_device>
3440  *
3441  *	-f	Force attach, even if <new_device> appears to be in use.
3442  *
3443  * Attach <new_device> to the mirror containing <device>.  If <device> is not
3444  * part of a mirror, then <device> will be transformed into a mirror of
3445  * <device> and <new_device>.  In either case, <new_device> will begin life
3446  * with a DTL of [0, now], and will immediately begin to resilver itself.
3447  */
3448 int
3449 zpool_do_attach(int argc, char **argv)
3450 {
3451 	return (zpool_do_attach_or_replace(argc, argv, B_FALSE));
3452 }
3453 
3454 /*
3455  * zpool detach [-f] <pool> <device>
3456  *
3457  *	-f	Force detach of <device>, even if DTLs argue against it
3458  *		(not supported yet)
3459  *
3460  * Detach a device from a mirror.  The operation will be refused if <device>
3461  * is the last device in the mirror, or if the DTLs indicate that this device
3462  * has the only valid copy of some data.
3463  */
3464 /* ARGSUSED */
3465 int
3466 zpool_do_detach(int argc, char **argv)
3467 {
3468 	int c;
3469 	char *poolname, *path;
3470 	zpool_handle_t *zhp;
3471 	int ret;
3472 
3473 	/* check options */
3474 	while ((c = getopt(argc, argv, "f")) != -1) {
3475 		switch (c) {
3476 		case 'f':
3477 		case '?':
3478 			(void) fprintf(stderr, gettext("invalid option '%c'\n"),
3479 			    optopt);
3480 			usage(B_FALSE);
3481 		}
3482 	}
3483 
3484 	argc -= optind;
3485 	argv += optind;
3486 
3487 	/* get pool name and check number of arguments */
3488 	if (argc < 1) {
3489 		(void) fprintf(stderr, gettext("missing pool name argument\n"));
3490 		usage(B_FALSE);
3491 	}
3492 
3493 	if (argc < 2) {
3494 		(void) fprintf(stderr,
3495 		    gettext("missing <device> specification\n"));
3496 		usage(B_FALSE);
3497 	}
3498 
3499 	poolname = argv[0];
3500 	path = argv[1];
3501 
3502 	if ((zhp = zpool_open(g_zfs, poolname)) == NULL)
3503 		return (1);
3504 
3505 	ret = zpool_vdev_detach(zhp, path);
3506 
3507 	zpool_close(zhp);
3508 
3509 	return (ret);
3510 }
3511 
3512 /*
3513  * zpool split [-n] [-o prop=val] ...
3514  *		[-o mntopt] ...
3515  *		[-R altroot] <pool> <newpool> [<device> ...]
3516  *
3517  *	-n	Do not split the pool, but display the resulting layout if
3518  *		it were to be split.
3519  *	-o	Set property=value, or set mount options.
3520  *	-R	Mount the split-off pool under an alternate root.
3521  *
3522  * Splits the named pool and gives it the new pool name.  Devices to be split
3523  * off may be listed, provided that no more than one device is specified
3524  * per top-level vdev mirror.  The newly split pool is left in an exported
3525  * state unless -R is specified.
3526  *
3527  * Restrictions: the top-level of the pool pool must only be made up of
3528  * mirrors; all devices in the pool must be healthy; no device may be
3529  * undergoing a resilvering operation.
3530  */
3531 int
3532 zpool_do_split(int argc, char **argv)
3533 {
3534 	char *srcpool, *newpool, *propval;
3535 	char *mntopts = NULL;
3536 	splitflags_t flags;
3537 	int c, ret = 0;
3538 	zpool_handle_t *zhp;
3539 	nvlist_t *config, *props = NULL;
3540 
3541 	flags.dryrun = B_FALSE;
3542 	flags.import = B_FALSE;
3543 
3544 	/* check options */
3545 	while ((c = getopt(argc, argv, ":R:no:")) != -1) {
3546 		switch (c) {
3547 		case 'R':
3548 			flags.import = B_TRUE;
3549 			if (add_prop_list(
3550 			    zpool_prop_to_name(ZPOOL_PROP_ALTROOT), optarg,
3551 			    &props, B_TRUE) != 0) {
3552 				nvlist_free(props);
3553 				usage(B_FALSE);
3554 			}
3555 			break;
3556 		case 'n':
3557 			flags.dryrun = B_TRUE;
3558 			break;
3559 		case 'o':
3560 			if ((propval = strchr(optarg, '=')) != NULL) {
3561 				*propval = '\0';
3562 				propval++;
3563 				if (add_prop_list(optarg, propval,
3564 				    &props, B_TRUE) != 0) {
3565 					nvlist_free(props);
3566 					usage(B_FALSE);
3567 				}
3568 			} else {
3569 				mntopts = optarg;
3570 			}
3571 			break;
3572 		case ':':
3573 			(void) fprintf(stderr, gettext("missing argument for "
3574 			    "'%c' option\n"), optopt);
3575 			usage(B_FALSE);
3576 			break;
3577 		case '?':
3578 			(void) fprintf(stderr, gettext("invalid option '%c'\n"),
3579 			    optopt);
3580 			usage(B_FALSE);
3581 			break;
3582 		}
3583 	}
3584 
3585 	if (!flags.import && mntopts != NULL) {
3586 		(void) fprintf(stderr, gettext("setting mntopts is only "
3587 		    "valid when importing the pool\n"));
3588 		usage(B_FALSE);
3589 	}
3590 
3591 	argc -= optind;
3592 	argv += optind;
3593 
3594 	if (argc < 1) {
3595 		(void) fprintf(stderr, gettext("Missing pool name\n"));
3596 		usage(B_FALSE);
3597 	}
3598 	if (argc < 2) {
3599 		(void) fprintf(stderr, gettext("Missing new pool name\n"));
3600 		usage(B_FALSE);
3601 	}
3602 
3603 	srcpool = argv[0];
3604 	newpool = argv[1];
3605 
3606 	argc -= 2;
3607 	argv += 2;
3608 
3609 	if ((zhp = zpool_open(g_zfs, srcpool)) == NULL)
3610 		return (1);
3611 
3612 	config = split_mirror_vdev(zhp, newpool, props, flags, argc, argv);
3613 	if (config == NULL) {
3614 		ret = 1;
3615 	} else {
3616 		if (flags.dryrun) {
3617 			(void) printf(gettext("would create '%s' with the "
3618 			    "following layout:\n\n"), newpool);
3619 			print_vdev_tree(NULL, newpool, config, 0, B_FALSE);
3620 		}
3621 		nvlist_free(config);
3622 	}
3623 
3624 	zpool_close(zhp);
3625 
3626 	if (ret != 0 || flags.dryrun || !flags.import)
3627 		return (ret);
3628 
3629 	/*
3630 	 * The split was successful. Now we need to open the new
3631 	 * pool and import it.
3632 	 */
3633 	if ((zhp = zpool_open_canfail(g_zfs, newpool)) == NULL)
3634 		return (1);
3635 	if (zpool_get_state(zhp) != POOL_STATE_UNAVAIL &&
3636 	    zpool_enable_datasets(zhp, mntopts, 0) != 0) {
3637 		ret = 1;
3638 		(void) fprintf(stderr, gettext("Split was successful, but "
3639 		    "the datasets could not all be mounted\n"));
3640 		(void) fprintf(stderr, gettext("Try doing '%s' with a "
3641 		    "different altroot\n"), "zpool import");
3642 	}
3643 	zpool_close(zhp);
3644 
3645 	return (ret);
3646 }
3647 
3648 
3649 
3650 /*
3651  * zpool online <pool> <device> ...
3652  */
3653 int
3654 zpool_do_online(int argc, char **argv)
3655 {
3656 	int c, i;
3657 	char *poolname;
3658 	zpool_handle_t *zhp;
3659 	int ret = 0;
3660 	vdev_state_t newstate;
3661 	int flags = 0;
3662 
3663 	/* check options */
3664 	while ((c = getopt(argc, argv, "et")) != -1) {
3665 		switch (c) {
3666 		case 'e':
3667 			flags |= ZFS_ONLINE_EXPAND;
3668 			break;
3669 		case 't':
3670 		case '?':
3671 			(void) fprintf(stderr, gettext("invalid option '%c'\n"),
3672 			    optopt);
3673 			usage(B_FALSE);
3674 		}
3675 	}
3676 
3677 	argc -= optind;
3678 	argv += optind;
3679 
3680 	/* get pool name and check number of arguments */
3681 	if (argc < 1) {
3682 		(void) fprintf(stderr, gettext("missing pool name\n"));
3683 		usage(B_FALSE);
3684 	}
3685 	if (argc < 2) {
3686 		(void) fprintf(stderr, gettext("missing device name\n"));
3687 		usage(B_FALSE);
3688 	}
3689 
3690 	poolname = argv[0];
3691 
3692 	if ((zhp = zpool_open(g_zfs, poolname)) == NULL)
3693 		return (1);
3694 
3695 	for (i = 1; i < argc; i++) {
3696 		if (zpool_vdev_online(zhp, argv[i], flags, &newstate) == 0) {
3697 			if (newstate != VDEV_STATE_HEALTHY) {
3698 				(void) printf(gettext("warning: device '%s' "
3699 				    "onlined, but remains in faulted state\n"),
3700 				    argv[i]);
3701 				if (newstate == VDEV_STATE_FAULTED)
3702 					(void) printf(gettext("use 'zpool "
3703 					    "clear' to restore a faulted "
3704 					    "device\n"));
3705 				else
3706 					(void) printf(gettext("use 'zpool "
3707 					    "replace' to replace devices "
3708 					    "that are no longer present\n"));
3709 			}
3710 		} else {
3711 			ret = 1;
3712 		}
3713 	}
3714 
3715 	zpool_close(zhp);
3716 
3717 	return (ret);
3718 }
3719 
3720 /*
3721  * zpool offline [-ft] <pool> <device> ...
3722  *
3723  *	-f	Force the device into the offline state, even if doing
3724  *		so would appear to compromise pool availability.
3725  *		(not supported yet)
3726  *
3727  *	-t	Only take the device off-line temporarily.  The offline
3728  *		state will not be persistent across reboots.
3729  */
3730 /* ARGSUSED */
3731 int
3732 zpool_do_offline(int argc, char **argv)
3733 {
3734 	int c, i;
3735 	char *poolname;
3736 	zpool_handle_t *zhp;
3737 	int ret = 0;
3738 	boolean_t istmp = B_FALSE;
3739 
3740 	/* check options */
3741 	while ((c = getopt(argc, argv, "ft")) != -1) {
3742 		switch (c) {
3743 		case 't':
3744 			istmp = B_TRUE;
3745 			break;
3746 		case 'f':
3747 		case '?':
3748 			(void) fprintf(stderr, gettext("invalid option '%c'\n"),
3749 			    optopt);
3750 			usage(B_FALSE);
3751 		}
3752 	}
3753 
3754 	argc -= optind;
3755 	argv += optind;
3756 
3757 	/* get pool name and check number of arguments */
3758 	if (argc < 1) {
3759 		(void) fprintf(stderr, gettext("missing pool name\n"));
3760 		usage(B_FALSE);
3761 	}
3762 	if (argc < 2) {
3763 		(void) fprintf(stderr, gettext("missing device name\n"));
3764 		usage(B_FALSE);
3765 	}
3766 
3767 	poolname = argv[0];
3768 
3769 	if ((zhp = zpool_open(g_zfs, poolname)) == NULL)
3770 		return (1);
3771 
3772 	for (i = 1; i < argc; i++) {
3773 		if (zpool_vdev_offline(zhp, argv[i], istmp) != 0)
3774 			ret = 1;
3775 	}
3776 
3777 	zpool_close(zhp);
3778 
3779 	return (ret);
3780 }
3781 
3782 /*
3783  * zpool clear <pool> [device]
3784  *
3785  * Clear all errors associated with a pool or a particular device.
3786  */
3787 int
3788 zpool_do_clear(int argc, char **argv)
3789 {
3790 	int c;
3791 	int ret = 0;
3792 	boolean_t dryrun = B_FALSE;
3793 	boolean_t do_rewind = B_FALSE;
3794 	boolean_t xtreme_rewind = B_FALSE;
3795 	uint32_t rewind_policy = ZPOOL_NO_REWIND;
3796 	nvlist_t *policy = NULL;
3797 	zpool_handle_t *zhp;
3798 	char *pool, *device;
3799 
3800 	/* check options */
3801 	while ((c = getopt(argc, argv, "FnX")) != -1) {
3802 		switch (c) {
3803 		case 'F':
3804 			do_rewind = B_TRUE;
3805 			break;
3806 		case 'n':
3807 			dryrun = B_TRUE;
3808 			break;
3809 		case 'X':
3810 			xtreme_rewind = B_TRUE;
3811 			break;
3812 		case '?':
3813 			(void) fprintf(stderr, gettext("invalid option '%c'\n"),
3814 			    optopt);
3815 			usage(B_FALSE);
3816 		}
3817 	}
3818 
3819 	argc -= optind;
3820 	argv += optind;
3821 
3822 	if (argc < 1) {
3823 		(void) fprintf(stderr, gettext("missing pool name\n"));
3824 		usage(B_FALSE);
3825 	}
3826 
3827 	if (argc > 2) {
3828 		(void) fprintf(stderr, gettext("too many arguments\n"));
3829 		usage(B_FALSE);
3830 	}
3831 
3832 	if ((dryrun || xtreme_rewind) && !do_rewind) {
3833 		(void) fprintf(stderr,
3834 		    gettext("-n or -X only meaningful with -F\n"));
3835 		usage(B_FALSE);
3836 	}
3837 	if (dryrun)
3838 		rewind_policy = ZPOOL_TRY_REWIND;
3839 	else if (do_rewind)
3840 		rewind_policy = ZPOOL_DO_REWIND;
3841 	if (xtreme_rewind)
3842 		rewind_policy |= ZPOOL_EXTREME_REWIND;
3843 
3844 	/* In future, further rewind policy choices can be passed along here */
3845 	if (nvlist_alloc(&policy, NV_UNIQUE_NAME, 0) != 0 ||
3846 	    nvlist_add_uint32(policy, ZPOOL_REWIND_REQUEST, rewind_policy) != 0)
3847 		return (1);
3848 
3849 	pool = argv[0];
3850 	device = argc == 2 ? argv[1] : NULL;
3851 
3852 	if ((zhp = zpool_open_canfail(g_zfs, pool)) == NULL) {
3853 		nvlist_free(policy);
3854 		return (1);
3855 	}
3856 
3857 	if (zpool_clear(zhp, device, policy) != 0)
3858 		ret = 1;
3859 
3860 	zpool_close(zhp);
3861 
3862 	nvlist_free(policy);
3863 
3864 	return (ret);
3865 }
3866 
3867 /*
3868  * zpool reguid <pool>
3869  */
3870 int
3871 zpool_do_reguid(int argc, char **argv)
3872 {
3873 	int c;
3874 	char *poolname;
3875 	zpool_handle_t *zhp;
3876 	int ret = 0;
3877 
3878 	/* check options */
3879 	while ((c = getopt(argc, argv, "")) != -1) {
3880 		switch (c) {
3881 		case '?':
3882 			(void) fprintf(stderr, gettext("invalid option '%c'\n"),
3883 			    optopt);
3884 			usage(B_FALSE);
3885 		}
3886 	}
3887 
3888 	argc -= optind;
3889 	argv += optind;
3890 
3891 	/* get pool name and check number of arguments */
3892 	if (argc < 1) {
3893 		(void) fprintf(stderr, gettext("missing pool name\n"));
3894 		usage(B_FALSE);
3895 	}
3896 
3897 	if (argc > 1) {
3898 		(void) fprintf(stderr, gettext("too many arguments\n"));
3899 		usage(B_FALSE);
3900 	}
3901 
3902 	poolname = argv[0];
3903 	if ((zhp = zpool_open(g_zfs, poolname)) == NULL)
3904 		return (1);
3905 
3906 	ret = zpool_reguid(zhp);
3907 
3908 	zpool_close(zhp);
3909 	return (ret);
3910 }
3911 
3912 
3913 /*
3914  * zpool reopen <pool>
3915  *
3916  * Reopen the pool so that the kernel can update the sizes of all vdevs.
3917  */
3918 int
3919 zpool_do_reopen(int argc, char **argv)
3920 {
3921 	int c;
3922 	int ret = 0;
3923 	zpool_handle_t *zhp;
3924 	char *pool;
3925 
3926 	/* check options */
3927 	while ((c = getopt(argc, argv, "")) != -1) {
3928 		switch (c) {
3929 		case '?':
3930 			(void) fprintf(stderr, gettext("invalid option '%c'\n"),
3931 			    optopt);
3932 			usage(B_FALSE);
3933 		}
3934 	}
3935 
3936 	argc--;
3937 	argv++;
3938 
3939 	if (argc < 1) {
3940 		(void) fprintf(stderr, gettext("missing pool name\n"));
3941 		usage(B_FALSE);
3942 	}
3943 
3944 	if (argc > 1) {
3945 		(void) fprintf(stderr, gettext("too many arguments\n"));
3946 		usage(B_FALSE);
3947 	}
3948 
3949 	pool = argv[0];
3950 	if ((zhp = zpool_open_canfail(g_zfs, pool)) == NULL)
3951 		return (1);
3952 
3953 	ret = zpool_reopen(zhp);
3954 	zpool_close(zhp);
3955 	return (ret);
3956 }
3957 
3958 typedef struct scrub_cbdata {
3959 	int	cb_type;
3960 	int	cb_argc;
3961 	char	**cb_argv;
3962 	pool_scrub_cmd_t cb_scrub_cmd;
3963 } scrub_cbdata_t;
3964 
3965 int
3966 scrub_callback(zpool_handle_t *zhp, void *data)
3967 {
3968 	scrub_cbdata_t *cb = data;
3969 	int err;
3970 
3971 	/*
3972 	 * Ignore faulted pools.
3973 	 */
3974 	if (zpool_get_state(zhp) == POOL_STATE_UNAVAIL) {
3975 		(void) fprintf(stderr, gettext("cannot scrub '%s': pool is "
3976 		    "currently unavailable\n"), zpool_get_name(zhp));
3977 		return (1);
3978 	}
3979 
3980 	err = zpool_scan(zhp, cb->cb_type, cb->cb_scrub_cmd);
3981 
3982 	return (err != 0);
3983 }
3984 
3985 /*
3986  * zpool scrub [-s | -p] <pool> ...
3987  *
3988  *	-s	Stop.  Stops any in-progress scrub.
3989  *	-p	Pause. Pause in-progress scrub.
3990  */
3991 int
3992 zpool_do_scrub(int argc, char **argv)
3993 {
3994 	int c;
3995 	scrub_cbdata_t cb;
3996 
3997 	cb.cb_type = POOL_SCAN_SCRUB;
3998 	cb.cb_scrub_cmd = POOL_SCRUB_NORMAL;
3999 
4000 	/* check options */
4001 	while ((c = getopt(argc, argv, "sp")) != -1) {
4002 		switch (c) {
4003 		case 's':
4004 			cb.cb_type = POOL_SCAN_NONE;
4005 			break;
4006 		case 'p':
4007 			cb.cb_scrub_cmd = POOL_SCRUB_PAUSE;
4008 			break;
4009 		case '?':
4010 			(void) fprintf(stderr, gettext("invalid option '%c'\n"),
4011 			    optopt);
4012 			usage(B_FALSE);
4013 		}
4014 	}
4015 
4016 	if (cb.cb_type == POOL_SCAN_NONE &&
4017 	    cb.cb_scrub_cmd == POOL_SCRUB_PAUSE) {
4018 		(void) fprintf(stderr, gettext("invalid option combination: "
4019 		    "-s and -p are mutually exclusive\n"));
4020 		usage(B_FALSE);
4021 	}
4022 
4023 	cb.cb_argc = argc;
4024 	cb.cb_argv = argv;
4025 	argc -= optind;
4026 	argv += optind;
4027 
4028 	if (argc < 1) {
4029 		(void) fprintf(stderr, gettext("missing pool name argument\n"));
4030 		usage(B_FALSE);
4031 	}
4032 
4033 	return (for_each_pool(argc, argv, B_TRUE, NULL, scrub_callback, &cb));
4034 }
4035 
4036 typedef struct status_cbdata {
4037 	int		cb_count;
4038 	boolean_t	cb_allpools;
4039 	boolean_t	cb_verbose;
4040 	boolean_t	cb_explain;
4041 	boolean_t	cb_first;
4042 	boolean_t	cb_dedup_stats;
4043 } status_cbdata_t;
4044 
4045 /*
4046  * Print out detailed scrub status.
4047  */
4048 static void
4049 print_scan_status(pool_scan_stat_t *ps)
4050 {
4051 	time_t start, end, pause;
4052 	uint64_t elapsed, mins_left, hours_left;
4053 	uint64_t pass_exam, examined, total;
4054 	uint_t rate;
4055 	double fraction_done;
4056 	char processed_buf[7], examined_buf[7], total_buf[7], rate_buf[7];
4057 
4058 	(void) printf(gettext("  scan: "));
4059 
4060 	/* If there's never been a scan, there's not much to say. */
4061 	if (ps == NULL || ps->pss_func == POOL_SCAN_NONE ||
4062 	    ps->pss_func >= POOL_SCAN_FUNCS) {
4063 		(void) printf(gettext("none requested\n"));
4064 		return;
4065 	}
4066 
4067 	start = ps->pss_start_time;
4068 	end = ps->pss_end_time;
4069 	pause = ps->pss_pass_scrub_pause;
4070 	zfs_nicenum(ps->pss_processed, processed_buf, sizeof (processed_buf));
4071 
4072 	assert(ps->pss_func == POOL_SCAN_SCRUB ||
4073 	    ps->pss_func == POOL_SCAN_RESILVER);
4074 	/*
4075 	 * Scan is finished or canceled.
4076 	 */
4077 	if (ps->pss_state == DSS_FINISHED) {
4078 		uint64_t minutes_taken = (end - start) / 60;
4079 		char *fmt = NULL;
4080 
4081 		if (ps->pss_func == POOL_SCAN_SCRUB) {
4082 			fmt = gettext("scrub repaired %s in %lluh%um with "
4083 			    "%llu errors on %s");
4084 		} else if (ps->pss_func == POOL_SCAN_RESILVER) {
4085 			fmt = gettext("resilvered %s in %lluh%um with "
4086 			    "%llu errors on %s");
4087 		}
4088 		/* LINTED */
4089 		(void) printf(fmt, processed_buf,
4090 		    (u_longlong_t)(minutes_taken / 60),
4091 		    (uint_t)(minutes_taken % 60),
4092 		    (u_longlong_t)ps->pss_errors,
4093 		    ctime((time_t *)&end));
4094 		return;
4095 	} else if (ps->pss_state == DSS_CANCELED) {
4096 		if (ps->pss_func == POOL_SCAN_SCRUB) {
4097 			(void) printf(gettext("scrub canceled on %s"),
4098 			    ctime(&end));
4099 		} else if (ps->pss_func == POOL_SCAN_RESILVER) {
4100 			(void) printf(gettext("resilver canceled on %s"),
4101 			    ctime(&end));
4102 		}
4103 		return;
4104 	}
4105 
4106 	assert(ps->pss_state == DSS_SCANNING);
4107 
4108 	/*
4109 	 * Scan is in progress.
4110 	 */
4111 	if (ps->pss_func == POOL_SCAN_SCRUB) {
4112 		if (pause == 0) {
4113 			(void) printf(gettext("scrub in progress since %s"),
4114 			    ctime(&start));
4115 		} else {
4116 			char buf[32];
4117 			struct tm *p = localtime(&pause);
4118 			(void) strftime(buf, sizeof (buf), "%a %b %e %T %Y", p);
4119 			(void) printf(gettext("scrub paused since %s\n"), buf);
4120 			(void) printf(gettext("\tscrub started on   %s"),
4121 			    ctime(&start));
4122 		}
4123 	} else if (ps->pss_func == POOL_SCAN_RESILVER) {
4124 		(void) printf(gettext("resilver in progress since %s"),
4125 		    ctime(&start));
4126 	}
4127 
4128 	examined = ps->pss_examined ? ps->pss_examined : 1;
4129 	total = ps->pss_to_examine;
4130 	fraction_done = (double)examined / total;
4131 
4132 	/* elapsed time for this pass */
4133 	elapsed = time(NULL) - ps->pss_pass_start;
4134 	elapsed -= ps->pss_pass_scrub_spent_paused;
4135 	elapsed = elapsed ? elapsed : 1;
4136 	pass_exam = ps->pss_pass_exam ? ps->pss_pass_exam : 1;
4137 	rate = pass_exam / elapsed;
4138 	rate = rate ? rate : 1;
4139 	mins_left = ((total - examined) / rate) / 60;
4140 	hours_left = mins_left / 60;
4141 
4142 	zfs_nicenum(examined, examined_buf, sizeof (examined_buf));
4143 	zfs_nicenum(total, total_buf, sizeof (total_buf));
4144 
4145 	/*
4146 	 * do not print estimated time if hours_left is more than 30 days
4147 	 * or we have a paused scrub
4148 	 */
4149 	if (pause == 0) {
4150 		zfs_nicenum(rate, rate_buf, sizeof (rate_buf));
4151 		(void) printf(gettext("\t%s scanned out of %s at %s/s"),
4152 		    examined_buf, total_buf, rate_buf);
4153 		if (hours_left < (30 * 24)) {
4154 			(void) printf(gettext(", %lluh%um to go\n"),
4155 			    (u_longlong_t)hours_left, (uint_t)(mins_left % 60));
4156 		} else {
4157 			(void) printf(gettext(
4158 			    ", (scan is slow, no estimated time)\n"));
4159 		}
4160 	} else {
4161 		(void) printf(gettext("\t%s scanned out of %s\n"),
4162 		    examined_buf, total_buf);
4163 	}
4164 
4165 	if (ps->pss_func == POOL_SCAN_RESILVER) {
4166 		(void) printf(gettext("    %s resilvered, %.2f%% done\n"),
4167 		    processed_buf, 100 * fraction_done);
4168 	} else if (ps->pss_func == POOL_SCAN_SCRUB) {
4169 		(void) printf(gettext("    %s repaired, %.2f%% done\n"),
4170 		    processed_buf, 100 * fraction_done);
4171 	}
4172 }
4173 
4174 /*
4175  * Print out detailed removal status.
4176  */
4177 static void
4178 print_removal_status(zpool_handle_t *zhp, pool_removal_stat_t *prs)
4179 {
4180 	char copied_buf[7], examined_buf[7], total_buf[7], rate_buf[7];
4181 	time_t start, end;
4182 	nvlist_t *config, *nvroot;
4183 	nvlist_t **child;
4184 	uint_t children;
4185 	char *vdev_name;
4186 
4187 	if (prs == NULL || prs->prs_state == DSS_NONE)
4188 		return;
4189 
4190 	/*
4191 	 * Determine name of vdev.
4192 	 */
4193 	config = zpool_get_config(zhp, NULL);
4194 	nvroot = fnvlist_lookup_nvlist(config,
4195 	    ZPOOL_CONFIG_VDEV_TREE);
4196 	verify(nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_CHILDREN,
4197 	    &child, &children) == 0);
4198 	assert(prs->prs_removing_vdev < children);
4199 	vdev_name = zpool_vdev_name(g_zfs, zhp,
4200 	    child[prs->prs_removing_vdev], B_TRUE);
4201 
4202 	(void) printf(gettext("remove: "));
4203 
4204 	start = prs->prs_start_time;
4205 	end = prs->prs_end_time;
4206 	zfs_nicenum(prs->prs_copied, copied_buf, sizeof (copied_buf));
4207 
4208 	/*
4209 	 * Removal is finished or canceled.
4210 	 */
4211 	if (prs->prs_state == DSS_FINISHED) {
4212 		uint64_t minutes_taken = (end - start) / 60;
4213 
4214 		(void) printf(gettext("Removal of vdev %llu copied %s "
4215 		    "in %lluh%um, completed on %s"),
4216 		    (longlong_t)prs->prs_removing_vdev,
4217 		    copied_buf,
4218 		    (u_longlong_t)(minutes_taken / 60),
4219 		    (uint_t)(minutes_taken % 60),
4220 		    ctime((time_t *)&end));
4221 	} else if (prs->prs_state == DSS_CANCELED) {
4222 		(void) printf(gettext("Removal of %s canceled on %s"),
4223 		    vdev_name, ctime(&end));
4224 	} else {
4225 		uint64_t copied, total, elapsed, mins_left, hours_left;
4226 		double fraction_done;
4227 		uint_t rate;
4228 
4229 		assert(prs->prs_state == DSS_SCANNING);
4230 
4231 		/*
4232 		 * Removal is in progress.
4233 		 */
4234 		(void) printf(gettext(
4235 		    "Evacuation of %s in progress since %s"),
4236 		    vdev_name, ctime(&start));
4237 
4238 		copied = prs->prs_copied > 0 ? prs->prs_copied : 1;
4239 		total = prs->prs_to_copy;
4240 		fraction_done = (double)copied / total;
4241 
4242 		/* elapsed time for this pass */
4243 		elapsed = time(NULL) - prs->prs_start_time;
4244 		elapsed = elapsed > 0 ? elapsed : 1;
4245 		rate = copied / elapsed;
4246 		rate = rate > 0 ? rate : 1;
4247 		mins_left = ((total - copied) / rate) / 60;
4248 		hours_left = mins_left / 60;
4249 
4250 		zfs_nicenum(copied, examined_buf, sizeof (examined_buf));
4251 		zfs_nicenum(total, total_buf, sizeof (total_buf));
4252 		zfs_nicenum(rate, rate_buf, sizeof (rate_buf));
4253 
4254 		/*
4255 		 * do not print estimated time if hours_left is more than
4256 		 * 30 days
4257 		 */
4258 		(void) printf(gettext("    %s copied out of %s at %s/s, "
4259 		    "%.2f%% done"),
4260 		    examined_buf, total_buf, rate_buf, 100 * fraction_done);
4261 		if (hours_left < (30 * 24)) {
4262 			(void) printf(gettext(", %lluh%um to go\n"),
4263 			    (u_longlong_t)hours_left, (uint_t)(mins_left % 60));
4264 		} else {
4265 			(void) printf(gettext(
4266 			    ", (copy is slow, no estimated time)\n"));
4267 		}
4268 	}
4269 
4270 	if (prs->prs_mapping_memory > 0) {
4271 		char mem_buf[7];
4272 		zfs_nicenum(prs->prs_mapping_memory, mem_buf, sizeof (mem_buf));
4273 		(void) printf(gettext("    %s memory used for "
4274 		    "removed device mappings\n"),
4275 		    mem_buf);
4276 	}
4277 }
4278 
4279 static void
4280 print_error_log(zpool_handle_t *zhp)
4281 {
4282 	nvlist_t *nverrlist = NULL;
4283 	nvpair_t *elem;
4284 	char *pathname;
4285 	size_t len = MAXPATHLEN * 2;
4286 
4287 	if (zpool_get_errlog(zhp, &nverrlist) != 0) {
4288 		(void) printf("errors: List of errors unavailable "
4289 		    "(insufficient privileges)\n");
4290 		return;
4291 	}
4292 
4293 	(void) printf("errors: Permanent errors have been "
4294 	    "detected in the following files:\n\n");
4295 
4296 	pathname = safe_malloc(len);
4297 	elem = NULL;
4298 	while ((elem = nvlist_next_nvpair(nverrlist, elem)) != NULL) {
4299 		nvlist_t *nv;
4300 		uint64_t dsobj, obj;
4301 
4302 		verify(nvpair_value_nvlist(elem, &nv) == 0);
4303 		verify(nvlist_lookup_uint64(nv, ZPOOL_ERR_DATASET,
4304 		    &dsobj) == 0);
4305 		verify(nvlist_lookup_uint64(nv, ZPOOL_ERR_OBJECT,
4306 		    &obj) == 0);
4307 		zpool_obj_to_path(zhp, dsobj, obj, pathname, len);
4308 		(void) printf("%7s %s\n", "", pathname);
4309 	}
4310 	free(pathname);
4311 	nvlist_free(nverrlist);
4312 }
4313 
4314 static void
4315 print_spares(zpool_handle_t *zhp, nvlist_t **spares, uint_t nspares,
4316     int namewidth)
4317 {
4318 	uint_t i;
4319 	char *name;
4320 
4321 	if (nspares == 0)
4322 		return;
4323 
4324 	(void) printf(gettext("\tspares\n"));
4325 
4326 	for (i = 0; i < nspares; i++) {
4327 		name = zpool_vdev_name(g_zfs, zhp, spares[i], B_FALSE);
4328 		print_status_config(zhp, name, spares[i],
4329 		    namewidth, 2, B_TRUE);
4330 		free(name);
4331 	}
4332 }
4333 
4334 static void
4335 print_l2cache(zpool_handle_t *zhp, nvlist_t **l2cache, uint_t nl2cache,
4336     int namewidth)
4337 {
4338 	uint_t i;
4339 	char *name;
4340 
4341 	if (nl2cache == 0)
4342 		return;
4343 
4344 	(void) printf(gettext("\tcache\n"));
4345 
4346 	for (i = 0; i < nl2cache; i++) {
4347 		name = zpool_vdev_name(g_zfs, zhp, l2cache[i], B_FALSE);
4348 		print_status_config(zhp, name, l2cache[i],
4349 		    namewidth, 2, B_FALSE);
4350 		free(name);
4351 	}
4352 }
4353 
4354 static void
4355 print_dedup_stats(nvlist_t *config)
4356 {
4357 	ddt_histogram_t *ddh;
4358 	ddt_stat_t *dds;
4359 	ddt_object_t *ddo;
4360 	uint_t c;
4361 
4362 	/*
4363 	 * If the pool was faulted then we may not have been able to
4364 	 * obtain the config. Otherwise, if we have anything in the dedup
4365 	 * table continue processing the stats.
4366 	 */
4367 	if (nvlist_lookup_uint64_array(config, ZPOOL_CONFIG_DDT_OBJ_STATS,
4368 	    (uint64_t **)&ddo, &c) != 0)
4369 		return;
4370 
4371 	(void) printf("\n");
4372 	(void) printf(gettext(" dedup: "));
4373 	if (ddo->ddo_count == 0) {
4374 		(void) printf(gettext("no DDT entries\n"));
4375 		return;
4376 	}
4377 
4378 	(void) printf("DDT entries %llu, size %llu on disk, %llu in core\n",
4379 	    (u_longlong_t)ddo->ddo_count,
4380 	    (u_longlong_t)ddo->ddo_dspace,
4381 	    (u_longlong_t)ddo->ddo_mspace);
4382 
4383 	verify(nvlist_lookup_uint64_array(config, ZPOOL_CONFIG_DDT_STATS,
4384 	    (uint64_t **)&dds, &c) == 0);
4385 	verify(nvlist_lookup_uint64_array(config, ZPOOL_CONFIG_DDT_HISTOGRAM,
4386 	    (uint64_t **)&ddh, &c) == 0);
4387 	zpool_dump_ddt(dds, ddh);
4388 }
4389 
4390 /*
4391  * Display a summary of pool status.  Displays a summary such as:
4392  *
4393  *        pool: tank
4394  *	status: DEGRADED
4395  *	reason: One or more devices ...
4396  *         see: http://illumos.org/msg/ZFS-xxxx-01
4397  *	config:
4398  *		mirror		DEGRADED
4399  *                c1t0d0	OK
4400  *                c2t0d0	UNAVAIL
4401  *
4402  * When given the '-v' option, we print out the complete config.  If the '-e'
4403  * option is specified, then we print out error rate information as well.
4404  */
4405 int
4406 status_callback(zpool_handle_t *zhp, void *data)
4407 {
4408 	status_cbdata_t *cbp = data;
4409 	nvlist_t *config, *nvroot;
4410 	char *msgid;
4411 	int reason;
4412 	const char *health;
4413 	uint_t c;
4414 	vdev_stat_t *vs;
4415 
4416 	config = zpool_get_config(zhp, NULL);
4417 	reason = zpool_get_status(zhp, &msgid);
4418 
4419 	cbp->cb_count++;
4420 
4421 	/*
4422 	 * If we were given 'zpool status -x', only report those pools with
4423 	 * problems.
4424 	 */
4425 	if (cbp->cb_explain &&
4426 	    (reason == ZPOOL_STATUS_OK ||
4427 	    reason == ZPOOL_STATUS_VERSION_OLDER ||
4428 	    reason == ZPOOL_STATUS_FEAT_DISABLED)) {
4429 		if (!cbp->cb_allpools) {
4430 			(void) printf(gettext("pool '%s' is healthy\n"),
4431 			    zpool_get_name(zhp));
4432 			if (cbp->cb_first)
4433 				cbp->cb_first = B_FALSE;
4434 		}
4435 		return (0);
4436 	}
4437 
4438 	if (cbp->cb_first)
4439 		cbp->cb_first = B_FALSE;
4440 	else
4441 		(void) printf("\n");
4442 
4443 	nvroot = fnvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE);
4444 	verify(nvlist_lookup_uint64_array(nvroot, ZPOOL_CONFIG_VDEV_STATS,
4445 	    (uint64_t **)&vs, &c) == 0);
4446 	health = zpool_state_to_name(vs->vs_state, vs->vs_aux);
4447 
4448 	(void) printf(gettext("  pool: %s\n"), zpool_get_name(zhp));
4449 	(void) printf(gettext(" state: %s\n"), health);
4450 
4451 	switch (reason) {
4452 	case ZPOOL_STATUS_MISSING_DEV_R:
4453 		(void) printf(gettext("status: One or more devices could not "
4454 		    "be opened.  Sufficient replicas exist for\n\tthe pool to "
4455 		    "continue functioning in a degraded state.\n"));
4456 		(void) printf(gettext("action: Attach the missing device and "
4457 		    "online it using 'zpool online'.\n"));
4458 		break;
4459 
4460 	case ZPOOL_STATUS_MISSING_DEV_NR:
4461 		(void) printf(gettext("status: One or more devices could not "
4462 		    "be opened.  There are insufficient\n\treplicas for the "
4463 		    "pool to continue functioning.\n"));
4464 		(void) printf(gettext("action: Attach the missing device and "
4465 		    "online it using 'zpool online'.\n"));
4466 		break;
4467 
4468 	case ZPOOL_STATUS_CORRUPT_LABEL_R:
4469 		(void) printf(gettext("status: One or more devices could not "
4470 		    "be used because the label is missing or\n\tinvalid.  "
4471 		    "Sufficient replicas exist for the pool to continue\n\t"
4472 		    "functioning in a degraded state.\n"));
4473 		(void) printf(gettext("action: Replace the device using "
4474 		    "'zpool replace'.\n"));
4475 		break;
4476 
4477 	case ZPOOL_STATUS_CORRUPT_LABEL_NR:
4478 		(void) printf(gettext("status: One or more devices could not "
4479 		    "be used because the label is missing \n\tor invalid.  "
4480 		    "There are insufficient replicas for the pool to "
4481 		    "continue\n\tfunctioning.\n"));
4482 		zpool_explain_recover(zpool_get_handle(zhp),
4483 		    zpool_get_name(zhp), reason, config);
4484 		break;
4485 
4486 	case ZPOOL_STATUS_FAILING_DEV:
4487 		(void) printf(gettext("status: One or more devices has "
4488 		    "experienced an unrecoverable error.  An\n\tattempt was "
4489 		    "made to correct the error.  Applications are "
4490 		    "unaffected.\n"));
4491 		(void) printf(gettext("action: Determine if the device needs "
4492 		    "to be replaced, and clear the errors\n\tusing "
4493 		    "'zpool clear' or replace the device with 'zpool "
4494 		    "replace'.\n"));
4495 		break;
4496 
4497 	case ZPOOL_STATUS_OFFLINE_DEV:
4498 		(void) printf(gettext("status: One or more devices has "
4499 		    "been taken offline by the administrator.\n\tSufficient "
4500 		    "replicas exist for the pool to continue functioning in "
4501 		    "a\n\tdegraded state.\n"));
4502 		(void) printf(gettext("action: Online the device using "
4503 		    "'zpool online' or replace the device with\n\t'zpool "
4504 		    "replace'.\n"));
4505 		break;
4506 
4507 	case ZPOOL_STATUS_REMOVED_DEV:
4508 		(void) printf(gettext("status: One or more devices has "
4509 		    "been removed by the administrator.\n\tSufficient "
4510 		    "replicas exist for the pool to continue functioning in "
4511 		    "a\n\tdegraded state.\n"));
4512 		(void) printf(gettext("action: Online the device using "
4513 		    "'zpool online' or replace the device with\n\t'zpool "
4514 		    "replace'.\n"));
4515 		break;
4516 
4517 	case ZPOOL_STATUS_RESILVERING:
4518 		(void) printf(gettext("status: One or more devices is "
4519 		    "currently being resilvered.  The pool will\n\tcontinue "
4520 		    "to function, possibly in a degraded state.\n"));
4521 		(void) printf(gettext("action: Wait for the resilver to "
4522 		    "complete.\n"));
4523 		break;
4524 
4525 	case ZPOOL_STATUS_CORRUPT_DATA:
4526 		(void) printf(gettext("status: One or more devices has "
4527 		    "experienced an error resulting in data\n\tcorruption.  "
4528 		    "Applications may be affected.\n"));
4529 		(void) printf(gettext("action: Restore the file in question "
4530 		    "if possible.  Otherwise restore the\n\tentire pool from "
4531 		    "backup.\n"));
4532 		break;
4533 
4534 	case ZPOOL_STATUS_CORRUPT_POOL:
4535 		(void) printf(gettext("status: The pool metadata is corrupted "
4536 		    "and the pool cannot be opened.\n"));
4537 		zpool_explain_recover(zpool_get_handle(zhp),
4538 		    zpool_get_name(zhp), reason, config);
4539 		break;
4540 
4541 	case ZPOOL_STATUS_VERSION_OLDER:
4542 		(void) printf(gettext("status: The pool is formatted using a "
4543 		    "legacy on-disk format.  The pool can\n\tstill be used, "
4544 		    "but some features are unavailable.\n"));
4545 		(void) printf(gettext("action: Upgrade the pool using 'zpool "
4546 		    "upgrade'.  Once this is done, the\n\tpool will no longer "
4547 		    "be accessible on software that does not support feature\n"
4548 		    "\tflags.\n"));
4549 		break;
4550 
4551 	case ZPOOL_STATUS_VERSION_NEWER:
4552 		(void) printf(gettext("status: The pool has been upgraded to a "
4553 		    "newer, incompatible on-disk version.\n\tThe pool cannot "
4554 		    "be accessed on this system.\n"));
4555 		(void) printf(gettext("action: Access the pool from a system "
4556 		    "running more recent software, or\n\trestore the pool from "
4557 		    "backup.\n"));
4558 		break;
4559 
4560 	case ZPOOL_STATUS_FEAT_DISABLED:
4561 		(void) printf(gettext("status: Some supported features are not "
4562 		    "enabled on the pool. The pool can\n\tstill be used, but "
4563 		    "some features are unavailable.\n"));
4564 		(void) printf(gettext("action: Enable all features using "
4565 		    "'zpool upgrade'. Once this is done,\n\tthe pool may no "
4566 		    "longer be accessible by software that does not support\n\t"
4567 		    "the features. See zpool-features(5) for details.\n"));
4568 		break;
4569 
4570 	case ZPOOL_STATUS_UNSUP_FEAT_READ:
4571 		(void) printf(gettext("status: The pool cannot be accessed on "
4572 		    "this system because it uses the\n\tfollowing feature(s) "
4573 		    "not supported on this system:\n"));
4574 		zpool_print_unsup_feat(config);
4575 		(void) printf("\n");
4576 		(void) printf(gettext("action: Access the pool from a system "
4577 		    "that supports the required feature(s),\n\tor restore the "
4578 		    "pool from backup.\n"));
4579 		break;
4580 
4581 	case ZPOOL_STATUS_UNSUP_FEAT_WRITE:
4582 		(void) printf(gettext("status: The pool can only be accessed "
4583 		    "in read-only mode on this system. It\n\tcannot be "
4584 		    "accessed in read-write mode because it uses the "
4585 		    "following\n\tfeature(s) not supported on this system:\n"));
4586 		zpool_print_unsup_feat(config);
4587 		(void) printf("\n");
4588 		(void) printf(gettext("action: The pool cannot be accessed in "
4589 		    "read-write mode. Import the pool with\n"
4590 		    "\t\"-o readonly=on\", access the pool from a system that "
4591 		    "supports the\n\trequired feature(s), or restore the "
4592 		    "pool from backup.\n"));
4593 		break;
4594 
4595 	case ZPOOL_STATUS_FAULTED_DEV_R:
4596 		(void) printf(gettext("status: One or more devices are "
4597 		    "faulted in response to persistent errors.\n\tSufficient "
4598 		    "replicas exist for the pool to continue functioning "
4599 		    "in a\n\tdegraded state.\n"));
4600 		(void) printf(gettext("action: Replace the faulted device, "
4601 		    "or use 'zpool clear' to mark the device\n\trepaired.\n"));
4602 		break;
4603 
4604 	case ZPOOL_STATUS_FAULTED_DEV_NR:
4605 		(void) printf(gettext("status: One or more devices are "
4606 		    "faulted in response to persistent errors.  There are "
4607 		    "insufficient replicas for the pool to\n\tcontinue "
4608 		    "functioning.\n"));
4609 		(void) printf(gettext("action: Destroy and re-create the pool "
4610 		    "from a backup source.  Manually marking the device\n"
4611 		    "\trepaired using 'zpool clear' may allow some data "
4612 		    "to be recovered.\n"));
4613 		break;
4614 
4615 	case ZPOOL_STATUS_IO_FAILURE_WAIT:
4616 	case ZPOOL_STATUS_IO_FAILURE_CONTINUE:
4617 		(void) printf(gettext("status: One or more devices are "
4618 		    "faulted in response to IO failures.\n"));
4619 		(void) printf(gettext("action: Make sure the affected devices "
4620 		    "are connected, then run 'zpool clear'.\n"));
4621 		break;
4622 
4623 	case ZPOOL_STATUS_BAD_LOG:
4624 		(void) printf(gettext("status: An intent log record "
4625 		    "could not be read.\n"
4626 		    "\tWaiting for adminstrator intervention to fix the "
4627 		    "faulted pool.\n"));
4628 		(void) printf(gettext("action: Either restore the affected "
4629 		    "device(s) and run 'zpool online',\n"
4630 		    "\tor ignore the intent log records by running "
4631 		    "'zpool clear'.\n"));
4632 		break;
4633 
4634 	default:
4635 		/*
4636 		 * The remaining errors can't actually be generated, yet.
4637 		 */
4638 		assert(reason == ZPOOL_STATUS_OK);
4639 	}
4640 
4641 	if (msgid != NULL)
4642 		(void) printf(gettext("   see: http://illumos.org/msg/%s\n"),
4643 		    msgid);
4644 
4645 	if (config != NULL) {
4646 		int namewidth;
4647 		uint64_t nerr;
4648 		nvlist_t **spares, **l2cache;
4649 		uint_t nspares, nl2cache;
4650 		pool_scan_stat_t *ps = NULL;
4651 		pool_removal_stat_t *prs = NULL;
4652 
4653 		(void) nvlist_lookup_uint64_array(nvroot,
4654 		    ZPOOL_CONFIG_SCAN_STATS, (uint64_t **)&ps, &c);
4655 		print_scan_status(ps);
4656 
4657 		(void) nvlist_lookup_uint64_array(nvroot,
4658 		    ZPOOL_CONFIG_REMOVAL_STATS, (uint64_t **)&prs, &c);
4659 		print_removal_status(zhp, prs);
4660 
4661 		namewidth = max_width(zhp, nvroot, 0, 0);
4662 		if (namewidth < 10)
4663 			namewidth = 10;
4664 
4665 		(void) printf(gettext("config:\n\n"));
4666 		(void) printf(gettext("\t%-*s  %-8s %5s %5s %5s\n"), namewidth,
4667 		    "NAME", "STATE", "READ", "WRITE", "CKSUM");
4668 		print_status_config(zhp, zpool_get_name(zhp), nvroot,
4669 		    namewidth, 0, B_FALSE);
4670 
4671 		if (num_logs(nvroot) > 0)
4672 			print_logs(zhp, nvroot, namewidth, B_TRUE);
4673 		if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_L2CACHE,
4674 		    &l2cache, &nl2cache) == 0)
4675 			print_l2cache(zhp, l2cache, nl2cache, namewidth);
4676 
4677 		if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_SPARES,
4678 		    &spares, &nspares) == 0)
4679 			print_spares(zhp, spares, nspares, namewidth);
4680 
4681 		if (nvlist_lookup_uint64(config, ZPOOL_CONFIG_ERRCOUNT,
4682 		    &nerr) == 0) {
4683 			nvlist_t *nverrlist = NULL;
4684 
4685 			/*
4686 			 * If the approximate error count is small, get a
4687 			 * precise count by fetching the entire log and
4688 			 * uniquifying the results.
4689 			 */
4690 			if (nerr > 0 && nerr < 100 && !cbp->cb_verbose &&
4691 			    zpool_get_errlog(zhp, &nverrlist) == 0) {
4692 				nvpair_t *elem;
4693 
4694 				elem = NULL;
4695 				nerr = 0;
4696 				while ((elem = nvlist_next_nvpair(nverrlist,
4697 				    elem)) != NULL) {
4698 					nerr++;
4699 				}
4700 			}
4701 			nvlist_free(nverrlist);
4702 
4703 			(void) printf("\n");
4704 
4705 			if (nerr == 0)
4706 				(void) printf(gettext("errors: No known data "
4707 				    "errors\n"));
4708 			else if (!cbp->cb_verbose)
4709 				(void) printf(gettext("errors: %llu data "
4710 				    "errors, use '-v' for a list\n"),
4711 				    (u_longlong_t)nerr);
4712 			else
4713 				print_error_log(zhp);
4714 		}
4715 
4716 		if (cbp->cb_dedup_stats)
4717 			print_dedup_stats(config);
4718 	} else {
4719 		(void) printf(gettext("config: The configuration cannot be "
4720 		    "determined.\n"));
4721 	}
4722 
4723 	return (0);
4724 }
4725 
4726 /*
4727  * zpool status [-vx] [-T d|u] [pool] ... [interval [count]]
4728  *
4729  *	-v	Display complete error logs
4730  *	-x	Display only pools with potential problems
4731  *	-D	Display dedup status (undocumented)
4732  *	-T	Display a timestamp in date(1) or Unix format
4733  *
4734  * Describes the health status of all pools or some subset.
4735  */
4736 int
4737 zpool_do_status(int argc, char **argv)
4738 {
4739 	int c;
4740 	int ret;
4741 	unsigned long interval = 0, count = 0;
4742 	status_cbdata_t cb = { 0 };
4743 
4744 	/* check options */
4745 	while ((c = getopt(argc, argv, "vxDT:")) != -1) {
4746 		switch (c) {
4747 		case 'v':
4748 			cb.cb_verbose = B_TRUE;
4749 			break;
4750 		case 'x':
4751 			cb.cb_explain = B_TRUE;
4752 			break;
4753 		case 'D':
4754 			cb.cb_dedup_stats = B_TRUE;
4755 			break;
4756 		case 'T':
4757 			get_timestamp_arg(*optarg);
4758 			break;
4759 		case '?':
4760 			(void) fprintf(stderr, gettext("invalid option '%c'\n"),
4761 			    optopt);
4762 			usage(B_FALSE);
4763 		}
4764 	}
4765 
4766 	argc -= optind;
4767 	argv += optind;
4768 
4769 	get_interval_count(&argc, argv, &interval, &count);
4770 
4771 	if (argc == 0)
4772 		cb.cb_allpools = B_TRUE;
4773 
4774 	cb.cb_first = B_TRUE;
4775 
4776 	for (;;) {
4777 		if (timestamp_fmt != NODATE)
4778 			print_timestamp(timestamp_fmt);
4779 
4780 		ret = for_each_pool(argc, argv, B_TRUE, NULL,
4781 		    status_callback, &cb);
4782 
4783 		if (argc == 0 && cb.cb_count == 0)
4784 			(void) printf(gettext("no pools available\n"));
4785 		else if (cb.cb_explain && cb.cb_first && cb.cb_allpools)
4786 			(void) printf(gettext("all pools are healthy\n"));
4787 
4788 		if (ret != 0)
4789 			return (ret);
4790 
4791 		if (interval == 0)
4792 			break;
4793 
4794 		if (count != 0 && --count == 0)
4795 			break;
4796 
4797 		(void) sleep(interval);
4798 	}
4799 
4800 	return (0);
4801 }
4802 
4803 typedef struct upgrade_cbdata {
4804 	int	cb_first;
4805 	int	cb_argc;
4806 	uint64_t cb_version;
4807 	char	**cb_argv;
4808 } upgrade_cbdata_t;
4809 
4810 static int
4811 upgrade_version(zpool_handle_t *zhp, uint64_t version)
4812 {
4813 	int ret;
4814 	nvlist_t *config;
4815 	uint64_t oldversion;
4816 
4817 	config = zpool_get_config(zhp, NULL);
4818 	verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION,
4819 	    &oldversion) == 0);
4820 
4821 	assert(SPA_VERSION_IS_SUPPORTED(oldversion));
4822 	assert(oldversion < version);
4823 
4824 	ret = zpool_upgrade(zhp, version);
4825 	if (ret != 0)
4826 		return (ret);
4827 
4828 	if (version >= SPA_VERSION_FEATURES) {
4829 		(void) printf(gettext("Successfully upgraded "
4830 		    "'%s' from version %llu to feature flags.\n"),
4831 		    zpool_get_name(zhp), oldversion);
4832 	} else {
4833 		(void) printf(gettext("Successfully upgraded "
4834 		    "'%s' from version %llu to version %llu.\n"),
4835 		    zpool_get_name(zhp), oldversion, version);
4836 	}
4837 
4838 	return (0);
4839 }
4840 
4841 static int
4842 upgrade_enable_all(zpool_handle_t *zhp, int *countp)
4843 {
4844 	int i, ret, count;
4845 	boolean_t firstff = B_TRUE;
4846 	nvlist_t *enabled = zpool_get_features(zhp);
4847 
4848 	count = 0;
4849 	for (i = 0; i < SPA_FEATURES; i++) {
4850 		const char *fname = spa_feature_table[i].fi_uname;
4851 		const char *fguid = spa_feature_table[i].fi_guid;
4852 		if (!nvlist_exists(enabled, fguid)) {
4853 			char *propname;
4854 			verify(-1 != asprintf(&propname, "feature@%s", fname));
4855 			ret = zpool_set_prop(zhp, propname,
4856 			    ZFS_FEATURE_ENABLED);
4857 			if (ret != 0) {
4858 				free(propname);
4859 				return (ret);
4860 			}
4861 			count++;
4862 
4863 			if (firstff) {
4864 				(void) printf(gettext("Enabled the "
4865 				    "following features on '%s':\n"),
4866 				    zpool_get_name(zhp));
4867 				firstff = B_FALSE;
4868 			}
4869 			(void) printf(gettext("  %s\n"), fname);
4870 			free(propname);
4871 		}
4872 	}
4873 
4874 	if (countp != NULL)
4875 		*countp = count;
4876 	return (0);
4877 }
4878 
4879 static int
4880 upgrade_cb(zpool_handle_t *zhp, void *arg)
4881 {
4882 	upgrade_cbdata_t *cbp = arg;
4883 	nvlist_t *config;
4884 	uint64_t version;
4885 	boolean_t printnl = B_FALSE;
4886 	int ret;
4887 
4888 	config = zpool_get_config(zhp, NULL);
4889 	verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION,
4890 	    &version) == 0);
4891 
4892 	assert(SPA_VERSION_IS_SUPPORTED(version));
4893 
4894 	if (version < cbp->cb_version) {
4895 		cbp->cb_first = B_FALSE;
4896 		ret = upgrade_version(zhp, cbp->cb_version);
4897 		if (ret != 0)
4898 			return (ret);
4899 		printnl = B_TRUE;
4900 
4901 		/*
4902 		 * If they did "zpool upgrade -a", then we could
4903 		 * be doing ioctls to different pools.  We need
4904 		 * to log this history once to each pool, and bypass
4905 		 * the normal history logging that happens in main().
4906 		 */
4907 		(void) zpool_log_history(g_zfs, history_str);
4908 		log_history = B_FALSE;
4909 	}
4910 
4911 	if (cbp->cb_version >= SPA_VERSION_FEATURES) {
4912 		int count;
4913 		ret = upgrade_enable_all(zhp, &count);
4914 		if (ret != 0)
4915 			return (ret);
4916 
4917 		if (count > 0) {
4918 			cbp->cb_first = B_FALSE;
4919 			printnl = B_TRUE;
4920 		}
4921 	}
4922 
4923 	if (printnl) {
4924 		(void) printf(gettext("\n"));
4925 	}
4926 
4927 	return (0);
4928 }
4929 
4930 static int
4931 upgrade_list_older_cb(zpool_handle_t *zhp, void *arg)
4932 {
4933 	upgrade_cbdata_t *cbp = arg;
4934 	nvlist_t *config;
4935 	uint64_t version;
4936 
4937 	config = zpool_get_config(zhp, NULL);
4938 	verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION,
4939 	    &version) == 0);
4940 
4941 	assert(SPA_VERSION_IS_SUPPORTED(version));
4942 
4943 	if (version < SPA_VERSION_FEATURES) {
4944 		if (cbp->cb_first) {
4945 			(void) printf(gettext("The following pools are "
4946 			    "formatted with legacy version numbers and can\n"
4947 			    "be upgraded to use feature flags.  After "
4948 			    "being upgraded, these pools\nwill no "
4949 			    "longer be accessible by software that does not "
4950 			    "support feature\nflags.\n\n"));
4951 			(void) printf(gettext("VER  POOL\n"));
4952 			(void) printf(gettext("---  ------------\n"));
4953 			cbp->cb_first = B_FALSE;
4954 		}
4955 
4956 		(void) printf("%2llu   %s\n", (u_longlong_t)version,
4957 		    zpool_get_name(zhp));
4958 	}
4959 
4960 	return (0);
4961 }
4962 
4963 static int
4964 upgrade_list_disabled_cb(zpool_handle_t *zhp, void *arg)
4965 {
4966 	upgrade_cbdata_t *cbp = arg;
4967 	nvlist_t *config;
4968 	uint64_t version;
4969 
4970 	config = zpool_get_config(zhp, NULL);
4971 	verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION,
4972 	    &version) == 0);
4973 
4974 	if (version >= SPA_VERSION_FEATURES) {
4975 		int i;
4976 		boolean_t poolfirst = B_TRUE;
4977 		nvlist_t *enabled = zpool_get_features(zhp);
4978 
4979 		for (i = 0; i < SPA_FEATURES; i++) {
4980 			const char *fguid = spa_feature_table[i].fi_guid;
4981 			const char *fname = spa_feature_table[i].fi_uname;
4982 			if (!nvlist_exists(enabled, fguid)) {
4983 				if (cbp->cb_first) {
4984 					(void) printf(gettext("\nSome "
4985 					    "supported features are not "
4986 					    "enabled on the following pools. "
4987 					    "Once a\nfeature is enabled the "
4988 					    "pool may become incompatible with "
4989 					    "software\nthat does not support "
4990 					    "the feature. See "
4991 					    "zpool-features(5) for "
4992 					    "details.\n\n"));
4993 					(void) printf(gettext("POOL  "
4994 					    "FEATURE\n"));
4995 					(void) printf(gettext("------"
4996 					    "---------\n"));
4997 					cbp->cb_first = B_FALSE;
4998 				}
4999 
5000 				if (poolfirst) {
5001 					(void) printf(gettext("%s\n"),
5002 					    zpool_get_name(zhp));
5003 					poolfirst = B_FALSE;
5004 				}
5005 
5006 				(void) printf(gettext("      %s\n"), fname);
5007 			}
5008 		}
5009 	}
5010 
5011 	return (0);
5012 }
5013 
5014 /* ARGSUSED */
5015 static int
5016 upgrade_one(zpool_handle_t *zhp, void *data)
5017 {
5018 	boolean_t printnl = B_FALSE;
5019 	upgrade_cbdata_t *cbp = data;
5020 	uint64_t cur_version;
5021 	int ret;
5022 
5023 	if (strcmp("log", zpool_get_name(zhp)) == 0) {
5024 		(void) printf(gettext("'log' is now a reserved word\n"
5025 		    "Pool 'log' must be renamed using export and import"
5026 		    " to upgrade.\n"));
5027 		return (1);
5028 	}
5029 
5030 	cur_version = zpool_get_prop_int(zhp, ZPOOL_PROP_VERSION, NULL);
5031 	if (cur_version > cbp->cb_version) {
5032 		(void) printf(gettext("Pool '%s' is already formatted "
5033 		    "using more current version '%llu'.\n\n"),
5034 		    zpool_get_name(zhp), cur_version);
5035 		return (0);
5036 	}
5037 
5038 	if (cbp->cb_version != SPA_VERSION && cur_version == cbp->cb_version) {
5039 		(void) printf(gettext("Pool '%s' is already formatted "
5040 		    "using version %llu.\n\n"), zpool_get_name(zhp),
5041 		    cbp->cb_version);
5042 		return (0);
5043 	}
5044 
5045 	if (cur_version != cbp->cb_version) {
5046 		printnl = B_TRUE;
5047 		ret = upgrade_version(zhp, cbp->cb_version);
5048 		if (ret != 0)
5049 			return (ret);
5050 	}
5051 
5052 	if (cbp->cb_version >= SPA_VERSION_FEATURES) {
5053 		int count = 0;
5054 		ret = upgrade_enable_all(zhp, &count);
5055 		if (ret != 0)
5056 			return (ret);
5057 
5058 		if (count != 0) {
5059 			printnl = B_TRUE;
5060 		} else if (cur_version == SPA_VERSION) {
5061 			(void) printf(gettext("Pool '%s' already has all "
5062 			    "supported features enabled.\n"),
5063 			    zpool_get_name(zhp));
5064 		}
5065 	}
5066 
5067 	if (printnl) {
5068 		(void) printf(gettext("\n"));
5069 	}
5070 
5071 	return (0);
5072 }
5073 
5074 /*
5075  * zpool upgrade
5076  * zpool upgrade -v
5077  * zpool upgrade [-V version] <-a | pool ...>
5078  *
5079  * With no arguments, display downrev'd ZFS pool available for upgrade.
5080  * Individual pools can be upgraded by specifying the pool, and '-a' will
5081  * upgrade all pools.
5082  */
5083 int
5084 zpool_do_upgrade(int argc, char **argv)
5085 {
5086 	int c;
5087 	upgrade_cbdata_t cb = { 0 };
5088 	int ret = 0;
5089 	boolean_t showversions = B_FALSE;
5090 	boolean_t upgradeall = B_FALSE;
5091 	char *end;
5092 
5093 
5094 	/* check options */
5095 	while ((c = getopt(argc, argv, ":avV:")) != -1) {
5096 		switch (c) {
5097 		case 'a':
5098 			upgradeall = B_TRUE;
5099 			break;
5100 		case 'v':
5101 			showversions = B_TRUE;
5102 			break;
5103 		case 'V':
5104 			cb.cb_version = strtoll(optarg, &end, 10);
5105 			if (*end != '\0' ||
5106 			    !SPA_VERSION_IS_SUPPORTED(cb.cb_version)) {
5107 				(void) fprintf(stderr,
5108 				    gettext("invalid version '%s'\n"), optarg);
5109 				usage(B_FALSE);
5110 			}
5111 			break;
5112 		case ':':
5113 			(void) fprintf(stderr, gettext("missing argument for "
5114 			    "'%c' option\n"), optopt);
5115 			usage(B_FALSE);
5116 			break;
5117 		case '?':
5118 			(void) fprintf(stderr, gettext("invalid option '%c'\n"),
5119 			    optopt);
5120 			usage(B_FALSE);
5121 		}
5122 	}
5123 
5124 	cb.cb_argc = argc;
5125 	cb.cb_argv = argv;
5126 	argc -= optind;
5127 	argv += optind;
5128 
5129 	if (cb.cb_version == 0) {
5130 		cb.cb_version = SPA_VERSION;
5131 	} else if (!upgradeall && argc == 0) {
5132 		(void) fprintf(stderr, gettext("-V option is "
5133 		    "incompatible with other arguments\n"));
5134 		usage(B_FALSE);
5135 	}
5136 
5137 	if (showversions) {
5138 		if (upgradeall || argc != 0) {
5139 			(void) fprintf(stderr, gettext("-v option is "
5140 			    "incompatible with other arguments\n"));
5141 			usage(B_FALSE);
5142 		}
5143 	} else if (upgradeall) {
5144 		if (argc != 0) {
5145 			(void) fprintf(stderr, gettext("-a option should not "
5146 			    "be used along with a pool name\n"));
5147 			usage(B_FALSE);
5148 		}
5149 	}
5150 
5151 	(void) printf(gettext("This system supports ZFS pool feature "
5152 	    "flags.\n\n"));
5153 	if (showversions) {
5154 		int i;
5155 
5156 		(void) printf(gettext("The following features are "
5157 		    "supported:\n\n"));
5158 		(void) printf(gettext("FEAT DESCRIPTION\n"));
5159 		(void) printf("----------------------------------------------"
5160 		    "---------------\n");
5161 		for (i = 0; i < SPA_FEATURES; i++) {
5162 			zfeature_info_t *fi = &spa_feature_table[i];
5163 			const char *ro =
5164 			    (fi->fi_flags & ZFEATURE_FLAG_READONLY_COMPAT) ?
5165 			    " (read-only compatible)" : "";
5166 
5167 			(void) printf("%-37s%s\n", fi->fi_uname, ro);
5168 			(void) printf("     %s\n", fi->fi_desc);
5169 		}
5170 		(void) printf("\n");
5171 
5172 		(void) printf(gettext("The following legacy versions are also "
5173 		    "supported:\n\n"));
5174 		(void) printf(gettext("VER  DESCRIPTION\n"));
5175 		(void) printf("---  -----------------------------------------"
5176 		    "---------------\n");
5177 		(void) printf(gettext(" 1   Initial ZFS version\n"));
5178 		(void) printf(gettext(" 2   Ditto blocks "
5179 		    "(replicated metadata)\n"));
5180 		(void) printf(gettext(" 3   Hot spares and double parity "
5181 		    "RAID-Z\n"));
5182 		(void) printf(gettext(" 4   zpool history\n"));
5183 		(void) printf(gettext(" 5   Compression using the gzip "
5184 		    "algorithm\n"));
5185 		(void) printf(gettext(" 6   bootfs pool property\n"));
5186 		(void) printf(gettext(" 7   Separate intent log devices\n"));
5187 		(void) printf(gettext(" 8   Delegated administration\n"));
5188 		(void) printf(gettext(" 9   refquota and refreservation "
5189 		    "properties\n"));
5190 		(void) printf(gettext(" 10  Cache devices\n"));
5191 		(void) printf(gettext(" 11  Improved scrub performance\n"));
5192 		(void) printf(gettext(" 12  Snapshot properties\n"));
5193 		(void) printf(gettext(" 13  snapused property\n"));
5194 		(void) printf(gettext(" 14  passthrough-x aclinherit\n"));
5195 		(void) printf(gettext(" 15  user/group space accounting\n"));
5196 		(void) printf(gettext(" 16  stmf property support\n"));
5197 		(void) printf(gettext(" 17  Triple-parity RAID-Z\n"));
5198 		(void) printf(gettext(" 18  Snapshot user holds\n"));
5199 		(void) printf(gettext(" 19  Log device removal\n"));
5200 		(void) printf(gettext(" 20  Compression using zle "
5201 		    "(zero-length encoding)\n"));
5202 		(void) printf(gettext(" 21  Deduplication\n"));
5203 		(void) printf(gettext(" 22  Received properties\n"));
5204 		(void) printf(gettext(" 23  Slim ZIL\n"));
5205 		(void) printf(gettext(" 24  System attributes\n"));
5206 		(void) printf(gettext(" 25  Improved scrub stats\n"));
5207 		(void) printf(gettext(" 26  Improved snapshot deletion "
5208 		    "performance\n"));
5209 		(void) printf(gettext(" 27  Improved snapshot creation "
5210 		    "performance\n"));
5211 		(void) printf(gettext(" 28  Multiple vdev replacements\n"));
5212 		(void) printf(gettext("\nFor more information on a particular "
5213 		    "version, including supported releases,\n"));
5214 		(void) printf(gettext("see the ZFS Administration Guide.\n\n"));
5215 	} else if (argc == 0 && upgradeall) {
5216 		cb.cb_first = B_TRUE;
5217 		ret = zpool_iter(g_zfs, upgrade_cb, &cb);
5218 		if (ret == 0 && cb.cb_first) {
5219 			if (cb.cb_version == SPA_VERSION) {
5220 				(void) printf(gettext("All pools are already "
5221 				    "formatted using feature flags.\n\n"));
5222 				(void) printf(gettext("Every feature flags "
5223 				    "pool already has all supported features "
5224 				    "enabled.\n"));
5225 			} else {
5226 				(void) printf(gettext("All pools are already "
5227 				    "formatted with version %llu or higher.\n"),
5228 				    cb.cb_version);
5229 			}
5230 		}
5231 	} else if (argc == 0) {
5232 		cb.cb_first = B_TRUE;
5233 		ret = zpool_iter(g_zfs, upgrade_list_older_cb, &cb);
5234 		assert(ret == 0);
5235 
5236 		if (cb.cb_first) {
5237 			(void) printf(gettext("All pools are formatted "
5238 			    "using feature flags.\n\n"));
5239 		} else {
5240 			(void) printf(gettext("\nUse 'zpool upgrade -v' "
5241 			    "for a list of available legacy versions.\n"));
5242 		}
5243 
5244 		cb.cb_first = B_TRUE;
5245 		ret = zpool_iter(g_zfs, upgrade_list_disabled_cb, &cb);
5246 		assert(ret == 0);
5247 
5248 		if (cb.cb_first) {
5249 			(void) printf(gettext("Every feature flags pool has "
5250 			    "all supported features enabled.\n"));
5251 		} else {
5252 			(void) printf(gettext("\n"));
5253 		}
5254 	} else {
5255 		ret = for_each_pool(argc, argv, B_FALSE, NULL,
5256 		    upgrade_one, &cb);
5257 	}
5258 
5259 	return (ret);
5260 }
5261 
5262 typedef struct hist_cbdata {
5263 	boolean_t first;
5264 	boolean_t longfmt;
5265 	boolean_t internal;
5266 } hist_cbdata_t;
5267 
5268 /*
5269  * Print out the command history for a specific pool.
5270  */
5271 static int
5272 get_history_one(zpool_handle_t *zhp, void *data)
5273 {
5274 	nvlist_t *nvhis;
5275 	nvlist_t **records;
5276 	uint_t numrecords;
5277 	int ret, i;
5278 	hist_cbdata_t *cb = (hist_cbdata_t *)data;
5279 
5280 	cb->first = B_FALSE;
5281 
5282 	(void) printf(gettext("History for '%s':\n"), zpool_get_name(zhp));
5283 
5284 	if ((ret = zpool_get_history(zhp, &nvhis)) != 0)
5285 		return (ret);
5286 
5287 	verify(nvlist_lookup_nvlist_array(nvhis, ZPOOL_HIST_RECORD,
5288 	    &records, &numrecords) == 0);
5289 	for (i = 0; i < numrecords; i++) {
5290 		nvlist_t *rec = records[i];
5291 		char tbuf[30] = "";
5292 
5293 		if (nvlist_exists(rec, ZPOOL_HIST_TIME)) {
5294 			time_t tsec;
5295 			struct tm t;
5296 
5297 			tsec = fnvlist_lookup_uint64(records[i],
5298 			    ZPOOL_HIST_TIME);
5299 			(void) localtime_r(&tsec, &t);
5300 			(void) strftime(tbuf, sizeof (tbuf), "%F.%T", &t);
5301 		}
5302 
5303 		if (nvlist_exists(rec, ZPOOL_HIST_CMD)) {
5304 			(void) printf("%s %s", tbuf,
5305 			    fnvlist_lookup_string(rec, ZPOOL_HIST_CMD));
5306 		} else if (nvlist_exists(rec, ZPOOL_HIST_INT_EVENT)) {
5307 			int ievent =
5308 			    fnvlist_lookup_uint64(rec, ZPOOL_HIST_INT_EVENT);
5309 			if (!cb->internal)
5310 				continue;
5311 			if (ievent >= ZFS_NUM_LEGACY_HISTORY_EVENTS) {
5312 				(void) printf("%s unrecognized record:\n",
5313 				    tbuf);
5314 				dump_nvlist(rec, 4);
5315 				continue;
5316 			}
5317 			(void) printf("%s [internal %s txg:%lld] %s", tbuf,
5318 			    zfs_history_event_names[ievent],
5319 			    fnvlist_lookup_uint64(rec, ZPOOL_HIST_TXG),
5320 			    fnvlist_lookup_string(rec, ZPOOL_HIST_INT_STR));
5321 		} else if (nvlist_exists(rec, ZPOOL_HIST_INT_NAME)) {
5322 			if (!cb->internal)
5323 				continue;
5324 			(void) printf("%s [txg:%lld] %s", tbuf,
5325 			    fnvlist_lookup_uint64(rec, ZPOOL_HIST_TXG),
5326 			    fnvlist_lookup_string(rec, ZPOOL_HIST_INT_NAME));
5327 			if (nvlist_exists(rec, ZPOOL_HIST_DSNAME)) {
5328 				(void) printf(" %s (%llu)",
5329 				    fnvlist_lookup_string(rec,
5330 				    ZPOOL_HIST_DSNAME),
5331 				    fnvlist_lookup_uint64(rec,
5332 				    ZPOOL_HIST_DSID));
5333 			}
5334 			(void) printf(" %s", fnvlist_lookup_string(rec,
5335 			    ZPOOL_HIST_INT_STR));
5336 		} else if (nvlist_exists(rec, ZPOOL_HIST_IOCTL)) {
5337 			if (!cb->internal)
5338 				continue;
5339 			(void) printf("%s ioctl %s\n", tbuf,
5340 			    fnvlist_lookup_string(rec, ZPOOL_HIST_IOCTL));
5341 			if (nvlist_exists(rec, ZPOOL_HIST_INPUT_NVL)) {
5342 				(void) printf("    input:\n");
5343 				dump_nvlist(fnvlist_lookup_nvlist(rec,
5344 				    ZPOOL_HIST_INPUT_NVL), 8);
5345 			}
5346 			if (nvlist_exists(rec, ZPOOL_HIST_OUTPUT_NVL)) {
5347 				(void) printf("    output:\n");
5348 				dump_nvlist(fnvlist_lookup_nvlist(rec,
5349 				    ZPOOL_HIST_OUTPUT_NVL), 8);
5350 			}
5351 			if (nvlist_exists(rec, ZPOOL_HIST_ERRNO)) {
5352 				(void) printf("    errno: %lld\n",
5353 				    fnvlist_lookup_int64(rec,
5354 				    ZPOOL_HIST_ERRNO));
5355 			}
5356 		} else {
5357 			if (!cb->internal)
5358 				continue;
5359 			(void) printf("%s unrecognized record:\n", tbuf);
5360 			dump_nvlist(rec, 4);
5361 		}
5362 
5363 		if (!cb->longfmt) {
5364 			(void) printf("\n");
5365 			continue;
5366 		}
5367 		(void) printf(" [");
5368 		if (nvlist_exists(rec, ZPOOL_HIST_WHO)) {
5369 			uid_t who = fnvlist_lookup_uint64(rec, ZPOOL_HIST_WHO);
5370 			struct passwd *pwd = getpwuid(who);
5371 			(void) printf("user %d ", (int)who);
5372 			if (pwd != NULL)
5373 				(void) printf("(%s) ", pwd->pw_name);
5374 		}
5375 		if (nvlist_exists(rec, ZPOOL_HIST_HOST)) {
5376 			(void) printf("on %s",
5377 			    fnvlist_lookup_string(rec, ZPOOL_HIST_HOST));
5378 		}
5379 		if (nvlist_exists(rec, ZPOOL_HIST_ZONE)) {
5380 			(void) printf(":%s",
5381 			    fnvlist_lookup_string(rec, ZPOOL_HIST_ZONE));
5382 		}
5383 		(void) printf("]");
5384 		(void) printf("\n");
5385 	}
5386 	(void) printf("\n");
5387 	nvlist_free(nvhis);
5388 
5389 	return (ret);
5390 }
5391 
5392 /*
5393  * zpool history <pool>
5394  *
5395  * Displays the history of commands that modified pools.
5396  */
5397 int
5398 zpool_do_history(int argc, char **argv)
5399 {
5400 	hist_cbdata_t cbdata = { 0 };
5401 	int ret;
5402 	int c;
5403 
5404 	cbdata.first = B_TRUE;
5405 	/* check options */
5406 	while ((c = getopt(argc, argv, "li")) != -1) {
5407 		switch (c) {
5408 		case 'l':
5409 			cbdata.longfmt = B_TRUE;
5410 			break;
5411 		case 'i':
5412 			cbdata.internal = B_TRUE;
5413 			break;
5414 		case '?':
5415 			(void) fprintf(stderr, gettext("invalid option '%c'\n"),
5416 			    optopt);
5417 			usage(B_FALSE);
5418 		}
5419 	}
5420 	argc -= optind;
5421 	argv += optind;
5422 
5423 	ret = for_each_pool(argc, argv, B_FALSE,  NULL, get_history_one,
5424 	    &cbdata);
5425 
5426 	if (argc == 0 && cbdata.first == B_TRUE) {
5427 		(void) printf(gettext("no pools available\n"));
5428 		return (0);
5429 	}
5430 
5431 	return (ret);
5432 }
5433 
5434 static int
5435 get_callback(zpool_handle_t *zhp, void *data)
5436 {
5437 	zprop_get_cbdata_t *cbp = (zprop_get_cbdata_t *)data;
5438 	char value[MAXNAMELEN];
5439 	zprop_source_t srctype;
5440 	zprop_list_t *pl;
5441 
5442 	for (pl = cbp->cb_proplist; pl != NULL; pl = pl->pl_next) {
5443 
5444 		/*
5445 		 * Skip the special fake placeholder. This will also skip
5446 		 * over the name property when 'all' is specified.
5447 		 */
5448 		if (pl->pl_prop == ZPOOL_PROP_NAME &&
5449 		    pl == cbp->cb_proplist)
5450 			continue;
5451 
5452 		if (pl->pl_prop == ZPROP_INVAL &&
5453 		    (zpool_prop_feature(pl->pl_user_prop) ||
5454 		    zpool_prop_unsupported(pl->pl_user_prop))) {
5455 			srctype = ZPROP_SRC_LOCAL;
5456 
5457 			if (zpool_prop_get_feature(zhp, pl->pl_user_prop,
5458 			    value, sizeof (value)) == 0) {
5459 				zprop_print_one_property(zpool_get_name(zhp),
5460 				    cbp, pl->pl_user_prop, value, srctype,
5461 				    NULL, NULL);
5462 			}
5463 		} else {
5464 			if (zpool_get_prop(zhp, pl->pl_prop, value,
5465 			    sizeof (value), &srctype, cbp->cb_literal) != 0)
5466 				continue;
5467 
5468 			zprop_print_one_property(zpool_get_name(zhp), cbp,
5469 			    zpool_prop_to_name(pl->pl_prop), value, srctype,
5470 			    NULL, NULL);
5471 		}
5472 	}
5473 	return (0);
5474 }
5475 
5476 /*
5477  * zpool get [-Hp] [-o "all" | field[,...]] <"all" | property[,...]> <pool> ...
5478  *
5479  *	-H	Scripted mode.  Don't display headers, and separate properties
5480  *		by a single tab.
5481  *	-o	List of columns to display.  Defaults to
5482  *		"name,property,value,source".
5483  * 	-p	Diplay values in parsable (exact) format.
5484  *
5485  * Get properties of pools in the system. Output space statistics
5486  * for each one as well as other attributes.
5487  */
5488 int
5489 zpool_do_get(int argc, char **argv)
5490 {
5491 	zprop_get_cbdata_t cb = { 0 };
5492 	zprop_list_t fake_name = { 0 };
5493 	int ret;
5494 	int c, i;
5495 	char *value;
5496 
5497 	cb.cb_first = B_TRUE;
5498 
5499 	/*
5500 	 * Set up default columns and sources.
5501 	 */
5502 	cb.cb_sources = ZPROP_SRC_ALL;
5503 	cb.cb_columns[0] = GET_COL_NAME;
5504 	cb.cb_columns[1] = GET_COL_PROPERTY;
5505 	cb.cb_columns[2] = GET_COL_VALUE;
5506 	cb.cb_columns[3] = GET_COL_SOURCE;
5507 	cb.cb_type = ZFS_TYPE_POOL;
5508 
5509 	/* check options */
5510 	while ((c = getopt(argc, argv, ":Hpo:")) != -1) {
5511 		switch (c) {
5512 		case 'p':
5513 			cb.cb_literal = B_TRUE;
5514 			break;
5515 		case 'H':
5516 			cb.cb_scripted = B_TRUE;
5517 			break;
5518 		case 'o':
5519 			bzero(&cb.cb_columns, sizeof (cb.cb_columns));
5520 			i = 0;
5521 			while (*optarg != '\0') {
5522 				static char *col_subopts[] =
5523 				{ "name", "property", "value", "source",
5524 				"all", NULL };
5525 
5526 				if (i == ZFS_GET_NCOLS) {
5527 					(void) fprintf(stderr, gettext("too "
5528 					"many fields given to -o "
5529 					"option\n"));
5530 					usage(B_FALSE);
5531 				}
5532 
5533 				switch (getsubopt(&optarg, col_subopts,
5534 				    &value)) {
5535 				case 0:
5536 					cb.cb_columns[i++] = GET_COL_NAME;
5537 					break;
5538 				case 1:
5539 					cb.cb_columns[i++] = GET_COL_PROPERTY;
5540 					break;
5541 				case 2:
5542 					cb.cb_columns[i++] = GET_COL_VALUE;
5543 					break;
5544 				case 3:
5545 					cb.cb_columns[i++] = GET_COL_SOURCE;
5546 					break;
5547 				case 4:
5548 					if (i > 0) {
5549 						(void) fprintf(stderr,
5550 						    gettext("\"all\" conflicts "
5551 						    "with specific fields "
5552 						    "given to -o option\n"));
5553 						usage(B_FALSE);
5554 					}
5555 					cb.cb_columns[0] = GET_COL_NAME;
5556 					cb.cb_columns[1] = GET_COL_PROPERTY;
5557 					cb.cb_columns[2] = GET_COL_VALUE;
5558 					cb.cb_columns[3] = GET_COL_SOURCE;
5559 					i = ZFS_GET_NCOLS;
5560 					break;
5561 				default:
5562 					(void) fprintf(stderr,
5563 					    gettext("invalid column name "
5564 					    "'%s'\n"), value);
5565 					usage(B_FALSE);
5566 				}
5567 			}
5568 			break;
5569 		case '?':
5570 			(void) fprintf(stderr, gettext("invalid option '%c'\n"),
5571 			    optopt);
5572 			usage(B_FALSE);
5573 		}
5574 	}
5575 
5576 	argc -= optind;
5577 	argv += optind;
5578 
5579 	if (argc < 1) {
5580 		(void) fprintf(stderr, gettext("missing property "
5581 		    "argument\n"));
5582 		usage(B_FALSE);
5583 	}
5584 
5585 	if (zprop_get_list(g_zfs, argv[0], &cb.cb_proplist,
5586 	    ZFS_TYPE_POOL) != 0)
5587 		usage(B_FALSE);
5588 
5589 	argc--;
5590 	argv++;
5591 
5592 	if (cb.cb_proplist != NULL) {
5593 		fake_name.pl_prop = ZPOOL_PROP_NAME;
5594 		fake_name.pl_width = strlen(gettext("NAME"));
5595 		fake_name.pl_next = cb.cb_proplist;
5596 		cb.cb_proplist = &fake_name;
5597 	}
5598 
5599 	ret = for_each_pool(argc, argv, B_TRUE, &cb.cb_proplist,
5600 	    get_callback, &cb);
5601 
5602 	if (cb.cb_proplist == &fake_name)
5603 		zprop_free_list(fake_name.pl_next);
5604 	else
5605 		zprop_free_list(cb.cb_proplist);
5606 
5607 	return (ret);
5608 }
5609 
5610 typedef struct set_cbdata {
5611 	char *cb_propname;
5612 	char *cb_value;
5613 	boolean_t cb_any_successful;
5614 } set_cbdata_t;
5615 
5616 int
5617 set_callback(zpool_handle_t *zhp, void *data)
5618 {
5619 	int error;
5620 	set_cbdata_t *cb = (set_cbdata_t *)data;
5621 
5622 	error = zpool_set_prop(zhp, cb->cb_propname, cb->cb_value);
5623 
5624 	if (!error)
5625 		cb->cb_any_successful = B_TRUE;
5626 
5627 	return (error);
5628 }
5629 
5630 int
5631 zpool_do_set(int argc, char **argv)
5632 {
5633 	set_cbdata_t cb = { 0 };
5634 	int error;
5635 
5636 	if (argc > 1 && argv[1][0] == '-') {
5637 		(void) fprintf(stderr, gettext("invalid option '%c'\n"),
5638 		    argv[1][1]);
5639 		usage(B_FALSE);
5640 	}
5641 
5642 	if (argc < 2) {
5643 		(void) fprintf(stderr, gettext("missing property=value "
5644 		    "argument\n"));
5645 		usage(B_FALSE);
5646 	}
5647 
5648 	if (argc < 3) {
5649 		(void) fprintf(stderr, gettext("missing pool name\n"));
5650 		usage(B_FALSE);
5651 	}
5652 
5653 	if (argc > 3) {
5654 		(void) fprintf(stderr, gettext("too many pool names\n"));
5655 		usage(B_FALSE);
5656 	}
5657 
5658 	cb.cb_propname = argv[1];
5659 	cb.cb_value = strchr(cb.cb_propname, '=');
5660 	if (cb.cb_value == NULL) {
5661 		(void) fprintf(stderr, gettext("missing value in "
5662 		    "property=value argument\n"));
5663 		usage(B_FALSE);
5664 	}
5665 
5666 	*(cb.cb_value) = '\0';
5667 	cb.cb_value++;
5668 
5669 	error = for_each_pool(argc - 2, argv + 2, B_TRUE, NULL,
5670 	    set_callback, &cb);
5671 
5672 	return (error);
5673 }
5674 
5675 static int
5676 find_command_idx(char *command, int *idx)
5677 {
5678 	int i;
5679 
5680 	for (i = 0; i < NCOMMAND; i++) {
5681 		if (command_table[i].name == NULL)
5682 			continue;
5683 
5684 		if (strcmp(command, command_table[i].name) == 0) {
5685 			*idx = i;
5686 			return (0);
5687 		}
5688 	}
5689 	return (1);
5690 }
5691 
5692 int
5693 main(int argc, char **argv)
5694 {
5695 	int ret = 0;
5696 	int i;
5697 	char *cmdname;
5698 
5699 	(void) setlocale(LC_ALL, "");
5700 	(void) textdomain(TEXT_DOMAIN);
5701 
5702 	if ((g_zfs = libzfs_init()) == NULL) {
5703 		(void) fprintf(stderr, gettext("internal error: failed to "
5704 		    "initialize ZFS library\n"));
5705 		return (1);
5706 	}
5707 
5708 	libzfs_print_on_error(g_zfs, B_TRUE);
5709 
5710 	opterr = 0;
5711 
5712 	/*
5713 	 * Make sure the user has specified some command.
5714 	 */
5715 	if (argc < 2) {
5716 		(void) fprintf(stderr, gettext("missing command\n"));
5717 		usage(B_FALSE);
5718 	}
5719 
5720 	cmdname = argv[1];
5721 
5722 	/*
5723 	 * Special case '-?'
5724 	 */
5725 	if (strcmp(cmdname, "-?") == 0)
5726 		usage(B_TRUE);
5727 
5728 	zfs_save_arguments(argc, argv, history_str, sizeof (history_str));
5729 
5730 	/*
5731 	 * Run the appropriate command.
5732 	 */
5733 	if (find_command_idx(cmdname, &i) == 0) {
5734 		current_command = &command_table[i];
5735 		ret = command_table[i].func(argc - 1, argv + 1);
5736 	} else if (strchr(cmdname, '=')) {
5737 		verify(find_command_idx("set", &i) == 0);
5738 		current_command = &command_table[i];
5739 		ret = command_table[i].func(argc, argv);
5740 	} else if (strcmp(cmdname, "freeze") == 0 && argc == 3) {
5741 		/*
5742 		 * 'freeze' is a vile debugging abomination, so we treat
5743 		 * it as such.
5744 		 */
5745 		char buf[16384];
5746 		int fd = open(ZFS_DEV, O_RDWR);
5747 		(void) strcpy((void *)buf, argv[2]);
5748 		return (!!ioctl(fd, ZFS_IOC_POOL_FREEZE, buf));
5749 	} else {
5750 		(void) fprintf(stderr, gettext("unrecognized "
5751 		    "command '%s'\n"), cmdname);
5752 		usage(B_FALSE);
5753 	}
5754 
5755 	if (ret == 0 && log_history)
5756 		(void) zpool_log_history(g_zfs, history_str);
5757 
5758 	libzfs_fini(g_zfs);
5759 
5760 	/*
5761 	 * The 'ZFS_ABORT' environment variable causes us to dump core on exit
5762 	 * for the purposes of running ::findleaks.
5763 	 */
5764 	if (getenv("ZFS_ABORT") != NULL) {
5765 		(void) printf("dumping core by request\n");
5766 		abort();
5767 	}
5768 
5769 	return (ret);
5770 }
5771