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