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