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