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