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