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