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