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