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