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