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