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