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