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