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