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