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