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