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