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