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