zpool_main.c revision 209962
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 2009 Sun Microsystems, Inc.  All rights reserved.
24 * Use is subject to license terms.
25 */
26
27#include <solaris.h>
28#include <assert.h>
29#include <ctype.h>
30#include <dirent.h>
31#include <errno.h>
32#include <fcntl.h>
33#include <libgen.h>
34#include <libintl.h>
35#include <libuutil.h>
36#include <locale.h>
37#include <stdio.h>
38#include <stdlib.h>
39#include <string.h>
40#include <strings.h>
41#include <unistd.h>
42#include <priv.h>
43#include <pwd.h>
44#include <zone.h>
45#include <sys/time.h>
46#include <sys/fs/zfs.h>
47
48#include <sys/stat.h>
49
50#include <libzfs.h>
51
52#include "zpool_util.h"
53#include "zfs_comutil.h"
54
55static int zpool_do_create(int, char **);
56static int zpool_do_destroy(int, char **);
57
58static int zpool_do_add(int, char **);
59static int zpool_do_remove(int, char **);
60
61static int zpool_do_list(int, char **);
62static int zpool_do_iostat(int, char **);
63static int zpool_do_status(int, char **);
64
65static int zpool_do_online(int, char **);
66static int zpool_do_offline(int, char **);
67static int zpool_do_clear(int, char **);
68
69static int zpool_do_attach(int, char **);
70static int zpool_do_detach(int, char **);
71static int zpool_do_replace(int, char **);
72
73static int zpool_do_scrub(int, char **);
74
75static int zpool_do_import(int, char **);
76static int zpool_do_export(int, char **);
77
78static int zpool_do_upgrade(int, char **);
79
80static int zpool_do_history(int, char **);
81
82static int zpool_do_get(int, char **);
83static int zpool_do_set(int, char **);
84
85/*
86 * These libumem hooks provide a reasonable set of defaults for the allocator's
87 * debugging facilities.
88 */
89
90#ifdef DEBUG
91const char *
92_umem_debug_init(void)
93{
94	return ("default,verbose"); /* $UMEM_DEBUG setting */
95}
96
97const char *
98_umem_logging_init(void)
99{
100	return ("fail,contents"); /* $UMEM_LOGGING setting */
101}
102#endif
103
104typedef enum {
105	HELP_ADD,
106	HELP_ATTACH,
107	HELP_CLEAR,
108	HELP_CREATE,
109	HELP_DESTROY,
110	HELP_DETACH,
111	HELP_EXPORT,
112	HELP_HISTORY,
113	HELP_IMPORT,
114	HELP_IOSTAT,
115	HELP_LIST,
116	HELP_OFFLINE,
117	HELP_ONLINE,
118	HELP_REPLACE,
119	HELP_REMOVE,
120	HELP_SCRUB,
121	HELP_STATUS,
122	HELP_UPGRADE,
123	HELP_GET,
124	HELP_SET
125} zpool_help_t;
126
127
128typedef struct zpool_command {
129	const char	*name;
130	int		(*func)(int, char **);
131	zpool_help_t	usage;
132} zpool_command_t;
133
134/*
135 * Master command table.  Each ZFS command has a name, associated function, and
136 * usage message.  The usage messages need to be internationalized, so we have
137 * to have a function to return the usage message based on a command index.
138 *
139 * These commands are organized according to how they are displayed in the usage
140 * message.  An empty command (one with a NULL name) indicates an empty line in
141 * the generic usage message.
142 */
143static zpool_command_t command_table[] = {
144	{ "create",	zpool_do_create,	HELP_CREATE		},
145	{ "destroy",	zpool_do_destroy,	HELP_DESTROY		},
146	{ NULL },
147	{ "add",	zpool_do_add,		HELP_ADD		},
148	{ "remove",	zpool_do_remove,	HELP_REMOVE		},
149	{ NULL },
150	{ "list",	zpool_do_list,		HELP_LIST		},
151	{ "iostat",	zpool_do_iostat,	HELP_IOSTAT		},
152	{ "status",	zpool_do_status,	HELP_STATUS		},
153	{ NULL },
154	{ "online",	zpool_do_online,	HELP_ONLINE		},
155	{ "offline",	zpool_do_offline,	HELP_OFFLINE		},
156	{ "clear",	zpool_do_clear,		HELP_CLEAR		},
157	{ NULL },
158	{ "attach",	zpool_do_attach,	HELP_ATTACH		},
159	{ "detach",	zpool_do_detach,	HELP_DETACH		},
160	{ "replace",	zpool_do_replace,	HELP_REPLACE		},
161	{ NULL },
162	{ "scrub",	zpool_do_scrub,		HELP_SCRUB		},
163	{ NULL },
164	{ "import",	zpool_do_import,	HELP_IMPORT		},
165	{ "export",	zpool_do_export,	HELP_EXPORT		},
166	{ "upgrade",	zpool_do_upgrade,	HELP_UPGRADE		},
167	{ NULL },
168	{ "history",	zpool_do_history,	HELP_HISTORY		},
169	{ "get",	zpool_do_get,		HELP_GET		},
170	{ "set",	zpool_do_set,		HELP_SET		},
171};
172
173#define	NCOMMAND	(sizeof (command_table) / sizeof (command_table[0]))
174
175zpool_command_t *current_command;
176static char history_str[HIS_MAX_RECORD_LEN];
177
178static const char *
179get_usage(zpool_help_t idx) {
180	switch (idx) {
181	case HELP_ADD:
182		return (gettext("\tadd [-fn] <pool> <vdev> ...\n"));
183	case HELP_ATTACH:
184		return (gettext("\tattach [-f] <pool> <device> "
185		    "<new-device>\n"));
186	case HELP_CLEAR:
187		return (gettext("\tclear <pool> [device]\n"));
188	case HELP_CREATE:
189		return (gettext("\tcreate [-fn] [-o property=value] ... \n"
190		    "\t    [-O file-system-property=value] ... \n"
191		    "\t    [-m mountpoint] [-R root] <pool> <vdev> ...\n"));
192	case HELP_DESTROY:
193		return (gettext("\tdestroy [-f] <pool>\n"));
194	case HELP_DETACH:
195		return (gettext("\tdetach <pool> <device>\n"));
196	case HELP_EXPORT:
197		return (gettext("\texport [-f] <pool> ...\n"));
198	case HELP_HISTORY:
199		return (gettext("\thistory [-il] [<pool>] ...\n"));
200	case HELP_IMPORT:
201		return (gettext("\timport [-d dir] [-D]\n"
202		    "\timport [-o mntopts] [-o property=value] ... \n"
203		    "\t    [-d dir | -c cachefile] [-D] [-f] [-R root] -a\n"
204		    "\timport [-o mntopts] [-o property=value] ... \n"
205		    "\t    [-d dir | -c cachefile] [-D] [-f] [-R root] "
206		    "<pool | id> [newpool]\n"));
207	case HELP_IOSTAT:
208		return (gettext("\tiostat [-v] [pool] ... [interval "
209		    "[count]]\n"));
210	case HELP_LIST:
211		return (gettext("\tlist [-H] [-o property[,...]] "
212		    "[pool] ...\n"));
213	case HELP_OFFLINE:
214		return (gettext("\toffline [-t] <pool> <device> ...\n"));
215	case HELP_ONLINE:
216		return (gettext("\tonline <pool> <device> ...\n"));
217	case HELP_REPLACE:
218		return (gettext("\treplace [-f] <pool> <device> "
219		    "[new-device]\n"));
220	case HELP_REMOVE:
221		return (gettext("\tremove <pool> <device> ...\n"));
222	case HELP_SCRUB:
223		return (gettext("\tscrub [-s] <pool> ...\n"));
224	case HELP_STATUS:
225		return (gettext("\tstatus [-vx] [pool] ...\n"));
226	case HELP_UPGRADE:
227		return (gettext("\tupgrade\n"
228		    "\tupgrade -v\n"
229		    "\tupgrade [-V version] <-a | pool ...>\n"));
230	case HELP_GET:
231		return (gettext("\tget <\"all\" | property[,...]> "
232		    "<pool> ...\n"));
233	case HELP_SET:
234		return (gettext("\tset <property=value> <pool> \n"));
235	}
236
237	abort();
238	/* NOTREACHED */
239}
240
241
242/*
243 * Callback routine that will print out a pool property value.
244 */
245static int
246print_prop_cb(int prop, void *cb)
247{
248	FILE *fp = cb;
249
250	(void) fprintf(fp, "\t%-13s  ", zpool_prop_to_name(prop));
251
252	if (zpool_prop_readonly(prop))
253		(void) fprintf(fp, "  NO   ");
254	else
255		(void) fprintf(fp, " YES    ");
256
257	if (zpool_prop_values(prop) == NULL)
258		(void) fprintf(fp, "-\n");
259	else
260		(void) fprintf(fp, "%s\n", zpool_prop_values(prop));
261
262	return (ZPROP_CONT);
263}
264
265/*
266 * Display usage message.  If we're inside a command, display only the usage for
267 * that command.  Otherwise, iterate over the entire command table and display
268 * a complete usage message.
269 */
270void
271usage(boolean_t requested)
272{
273	FILE *fp = requested ? stdout : stderr;
274
275	if (current_command == NULL) {
276		int i;
277
278		(void) fprintf(fp, gettext("usage: zpool command args ...\n"));
279		(void) fprintf(fp,
280		    gettext("where 'command' is one of the following:\n\n"));
281
282		for (i = 0; i < NCOMMAND; i++) {
283			if (command_table[i].name == NULL)
284				(void) fprintf(fp, "\n");
285			else
286				(void) fprintf(fp, "%s",
287				    get_usage(command_table[i].usage));
288		}
289	} else {
290		(void) fprintf(fp, gettext("usage:\n"));
291		(void) fprintf(fp, "%s", get_usage(current_command->usage));
292	}
293
294	if (current_command != NULL &&
295	    ((strcmp(current_command->name, "set") == 0) ||
296	    (strcmp(current_command->name, "get") == 0) ||
297	    (strcmp(current_command->name, "list") == 0))) {
298
299		(void) fprintf(fp,
300		    gettext("\nthe following properties are supported:\n"));
301
302		(void) fprintf(fp, "\n\t%-13s  %s  %s\n\n",
303		    "PROPERTY", "EDIT", "VALUES");
304
305		/* Iterate over all properties */
306		(void) zprop_iter(print_prop_cb, fp, B_FALSE, B_TRUE,
307		    ZFS_TYPE_POOL);
308	}
309
310	/*
311	 * See comments at end of main().
312	 */
313	if (getenv("ZFS_ABORT") != NULL) {
314		(void) printf("dumping core by request\n");
315		abort();
316	}
317
318	exit(requested ? 0 : 2);
319}
320
321void
322print_vdev_tree(zpool_handle_t *zhp, const char *name, nvlist_t *nv, int indent,
323    boolean_t print_logs)
324{
325	nvlist_t **child;
326	uint_t c, children;
327	char *vname;
328
329	if (name != NULL)
330		(void) printf("\t%*s%s\n", indent, "", name);
331
332	if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
333	    &child, &children) != 0)
334		return;
335
336	for (c = 0; c < children; c++) {
337		uint64_t is_log = B_FALSE;
338
339		(void) nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_LOG,
340		    &is_log);
341		if ((is_log && !print_logs) || (!is_log && print_logs))
342			continue;
343
344		vname = zpool_vdev_name(g_zfs, zhp, child[c]);
345		print_vdev_tree(zhp, vname, child[c], indent + 2,
346		    B_FALSE);
347		free(vname);
348	}
349}
350
351/*
352 * Add a property pair (name, string-value) into a property nvlist.
353 */
354static int
355add_prop_list(const char *propname, char *propval, nvlist_t **props,
356    boolean_t poolprop)
357{
358	zpool_prop_t prop = ZPROP_INVAL;
359	zfs_prop_t fprop;
360	nvlist_t *proplist;
361	const char *normnm;
362	char *strval;
363
364	if (*props == NULL &&
365	    nvlist_alloc(props, NV_UNIQUE_NAME, 0) != 0) {
366		(void) fprintf(stderr,
367		    gettext("internal error: out of memory\n"));
368		return (1);
369	}
370
371	proplist = *props;
372
373	if (poolprop) {
374		if ((prop = zpool_name_to_prop(propname)) == ZPROP_INVAL) {
375			(void) fprintf(stderr, gettext("property '%s' is "
376			    "not a valid pool property\n"), propname);
377			return (2);
378		}
379		normnm = zpool_prop_to_name(prop);
380	} else {
381		if ((fprop = zfs_name_to_prop(propname)) != ZPROP_INVAL) {
382			normnm = zfs_prop_to_name(fprop);
383		} else {
384			normnm = propname;
385		}
386	}
387
388	if (nvlist_lookup_string(proplist, normnm, &strval) == 0 &&
389	    prop != ZPOOL_PROP_CACHEFILE) {
390		(void) fprintf(stderr, gettext("property '%s' "
391		    "specified multiple times\n"), propname);
392		return (2);
393	}
394
395	if (nvlist_add_string(proplist, normnm, propval) != 0) {
396		(void) fprintf(stderr, gettext("internal "
397		    "error: out of memory\n"));
398		return (1);
399	}
400
401	return (0);
402}
403
404/*
405 * zpool add [-fn] <pool> <vdev> ...
406 *
407 *	-f	Force addition of devices, even if they appear in use
408 *	-n	Do not add the devices, but display the resulting layout if
409 *		they were to be added.
410 *
411 * Adds the given vdevs to 'pool'.  As with create, the bulk of this work is
412 * handled by get_vdev_spec(), which constructs the nvlist needed to pass to
413 * libzfs.
414 */
415int
416zpool_do_add(int argc, char **argv)
417{
418	boolean_t force = B_FALSE;
419	boolean_t dryrun = B_FALSE;
420	int c;
421	nvlist_t *nvroot;
422	char *poolname;
423	int ret;
424	zpool_handle_t *zhp;
425	nvlist_t *config;
426
427	/* check options */
428	while ((c = getopt(argc, argv, "fn")) != -1) {
429		switch (c) {
430		case 'f':
431			force = B_TRUE;
432			break;
433		case 'n':
434			dryrun = B_TRUE;
435			break;
436		case '?':
437			(void) fprintf(stderr, gettext("invalid option '%c'\n"),
438			    optopt);
439			usage(B_FALSE);
440		}
441	}
442
443	argc -= optind;
444	argv += optind;
445
446	/* get pool name and check number of arguments */
447	if (argc < 1) {
448		(void) fprintf(stderr, gettext("missing pool name argument\n"));
449		usage(B_FALSE);
450	}
451	if (argc < 2) {
452		(void) fprintf(stderr, gettext("missing vdev specification\n"));
453		usage(B_FALSE);
454	}
455
456	poolname = argv[0];
457
458	argc--;
459	argv++;
460
461	if ((zhp = zpool_open(g_zfs, poolname)) == NULL)
462		return (1);
463
464	if ((config = zpool_get_config(zhp, NULL)) == NULL) {
465		(void) fprintf(stderr, gettext("pool '%s' is unavailable\n"),
466		    poolname);
467		zpool_close(zhp);
468		return (1);
469	}
470
471	/* pass off to get_vdev_spec for processing */
472	nvroot = make_root_vdev(zhp, force, !force, B_FALSE, dryrun,
473	    argc, argv);
474	if (nvroot == NULL) {
475		zpool_close(zhp);
476		return (1);
477	}
478
479	if (dryrun) {
480		nvlist_t *poolnvroot;
481
482		verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
483		    &poolnvroot) == 0);
484
485		(void) printf(gettext("would update '%s' to the following "
486		    "configuration:\n"), zpool_get_name(zhp));
487
488		/* print original main pool and new tree */
489		print_vdev_tree(zhp, poolname, poolnvroot, 0, B_FALSE);
490		print_vdev_tree(zhp, NULL, nvroot, 0, B_FALSE);
491
492		/* Do the same for the logs */
493		if (num_logs(poolnvroot) > 0) {
494			print_vdev_tree(zhp, "logs", poolnvroot, 0, B_TRUE);
495			print_vdev_tree(zhp, NULL, nvroot, 0, B_TRUE);
496		} else if (num_logs(nvroot) > 0) {
497			print_vdev_tree(zhp, "logs", nvroot, 0, B_TRUE);
498		}
499
500		ret = 0;
501	} else {
502		ret = (zpool_add(zhp, nvroot) != 0);
503	}
504
505	nvlist_free(nvroot);
506	zpool_close(zhp);
507
508	return (ret);
509}
510
511/*
512 * zpool remove <pool> <vdev> ...
513 *
514 * Removes the given vdev from the pool.  Currently, this only supports removing
515 * spares and cache devices from the pool.  Eventually, we'll want to support
516 * removing leaf vdevs (as an alias for 'detach') as well as toplevel vdevs.
517 */
518int
519zpool_do_remove(int argc, char **argv)
520{
521	char *poolname;
522	int i, ret = 0;
523	zpool_handle_t *zhp;
524
525	argc--;
526	argv++;
527
528	/* get pool name and check number of arguments */
529	if (argc < 1) {
530		(void) fprintf(stderr, gettext("missing pool name argument\n"));
531		usage(B_FALSE);
532	}
533	if (argc < 2) {
534		(void) fprintf(stderr, gettext("missing device\n"));
535		usage(B_FALSE);
536	}
537
538	poolname = argv[0];
539
540	if ((zhp = zpool_open(g_zfs, poolname)) == NULL)
541		return (1);
542
543	for (i = 1; i < argc; i++) {
544		if (zpool_vdev_remove(zhp, argv[i]) != 0)
545			ret = 1;
546	}
547
548	return (ret);
549}
550
551/*
552 * zpool create [-fn] [-o property=value] ...
553 *		[-O file-system-property=value] ...
554 *		[-R root] [-m mountpoint] <pool> <dev> ...
555 *
556 *	-f	Force creation, even if devices appear in use
557 *	-n	Do not create the pool, but display the resulting layout if it
558 *		were to be created.
559 *      -R	Create a pool under an alternate root
560 *      -m	Set default mountpoint for the root dataset.  By default it's
561 *      	'/<pool>'
562 *	-o	Set property=value.
563 *	-O	Set fsproperty=value in the pool's root file system
564 *
565 * Creates the named pool according to the given vdev specification.  The
566 * bulk of the vdev processing is done in get_vdev_spec() in zpool_vdev.c.  Once
567 * we get the nvlist back from get_vdev_spec(), we either print out the contents
568 * (if '-n' was specified), or pass it to libzfs to do the creation.
569 */
570int
571zpool_do_create(int argc, char **argv)
572{
573	boolean_t force = B_FALSE;
574	boolean_t dryrun = B_FALSE;
575	int c;
576	nvlist_t *nvroot = NULL;
577	char *poolname;
578	int ret = 1;
579	char *altroot = NULL;
580	char *mountpoint = NULL;
581	nvlist_t *fsprops = NULL;
582	nvlist_t *props = NULL;
583	char *propval;
584
585	/* check options */
586	while ((c = getopt(argc, argv, ":fnR:m:o:O:")) != -1) {
587		switch (c) {
588		case 'f':
589			force = B_TRUE;
590			break;
591		case 'n':
592			dryrun = B_TRUE;
593			break;
594		case 'R':
595			altroot = optarg;
596			if (add_prop_list(zpool_prop_to_name(
597			    ZPOOL_PROP_ALTROOT), optarg, &props, B_TRUE))
598				goto errout;
599			if (nvlist_lookup_string(props,
600			    zpool_prop_to_name(ZPOOL_PROP_CACHEFILE),
601			    &propval) == 0)
602				break;
603			if (add_prop_list(zpool_prop_to_name(
604			    ZPOOL_PROP_CACHEFILE), "none", &props, B_TRUE))
605				goto errout;
606			break;
607		case 'm':
608			mountpoint = optarg;
609			break;
610		case 'o':
611			if ((propval = strchr(optarg, '=')) == NULL) {
612				(void) fprintf(stderr, gettext("missing "
613				    "'=' for -o option\n"));
614				goto errout;
615			}
616			*propval = '\0';
617			propval++;
618
619			if (add_prop_list(optarg, propval, &props, B_TRUE))
620				goto errout;
621			break;
622		case 'O':
623			if ((propval = strchr(optarg, '=')) == NULL) {
624				(void) fprintf(stderr, gettext("missing "
625				    "'=' for -O option\n"));
626				goto errout;
627			}
628			*propval = '\0';
629			propval++;
630
631			if (add_prop_list(optarg, propval, &fsprops, B_FALSE))
632				goto errout;
633			break;
634		case ':':
635			(void) fprintf(stderr, gettext("missing argument for "
636			    "'%c' option\n"), optopt);
637			goto badusage;
638		case '?':
639			(void) fprintf(stderr, gettext("invalid option '%c'\n"),
640			    optopt);
641			goto badusage;
642		}
643	}
644
645	argc -= optind;
646	argv += optind;
647
648	/* get pool name and check number of arguments */
649	if (argc < 1) {
650		(void) fprintf(stderr, gettext("missing pool name argument\n"));
651		goto badusage;
652	}
653	if (argc < 2) {
654		(void) fprintf(stderr, gettext("missing vdev specification\n"));
655		goto badusage;
656	}
657
658	poolname = argv[0];
659
660	/*
661	 * As a special case, check for use of '/' in the name, and direct the
662	 * user to use 'zfs create' instead.
663	 */
664	if (strchr(poolname, '/') != NULL) {
665		(void) fprintf(stderr, gettext("cannot create '%s': invalid "
666		    "character '/' in pool name\n"), poolname);
667		(void) fprintf(stderr, gettext("use 'zfs create' to "
668		    "create a dataset\n"));
669		goto errout;
670	}
671
672	/* pass off to get_vdev_spec for bulk processing */
673	nvroot = make_root_vdev(NULL, force, !force, B_FALSE, dryrun,
674	    argc - 1, argv + 1);
675	if (nvroot == NULL)
676		goto errout;
677
678	/* make_root_vdev() allows 0 toplevel children if there are spares */
679	if (!zfs_allocatable_devs(nvroot)) {
680		(void) fprintf(stderr, gettext("invalid vdev "
681		    "specification: at least one toplevel vdev must be "
682		    "specified\n"));
683		goto errout;
684	}
685
686
687	if (altroot != NULL && altroot[0] != '/') {
688		(void) fprintf(stderr, gettext("invalid alternate root '%s': "
689		    "must be an absolute path\n"), altroot);
690		goto errout;
691	}
692
693	/*
694	 * Check the validity of the mountpoint and direct the user to use the
695	 * '-m' mountpoint option if it looks like its in use.
696	 */
697	if (mountpoint == NULL ||
698	    (strcmp(mountpoint, ZFS_MOUNTPOINT_LEGACY) != 0 &&
699	    strcmp(mountpoint, ZFS_MOUNTPOINT_NONE) != 0)) {
700		char buf[MAXPATHLEN];
701		DIR *dirp;
702
703		if (mountpoint && mountpoint[0] != '/') {
704			(void) fprintf(stderr, gettext("invalid mountpoint "
705			    "'%s': must be an absolute path, 'legacy', or "
706			    "'none'\n"), mountpoint);
707			goto errout;
708		}
709
710		if (mountpoint == NULL) {
711			if (altroot != NULL)
712				(void) snprintf(buf, sizeof (buf), "%s/%s",
713				    altroot, poolname);
714			else
715				(void) snprintf(buf, sizeof (buf), "/%s",
716				    poolname);
717		} else {
718			if (altroot != NULL)
719				(void) snprintf(buf, sizeof (buf), "%s%s",
720				    altroot, mountpoint);
721			else
722				(void) snprintf(buf, sizeof (buf), "%s",
723				    mountpoint);
724		}
725
726		if ((dirp = opendir(buf)) == NULL && errno != ENOENT) {
727			(void) fprintf(stderr, gettext("mountpoint '%s' : "
728			    "%s\n"), buf, strerror(errno));
729			(void) fprintf(stderr, gettext("use '-m' "
730			    "option to provide a different default\n"));
731			goto errout;
732		} else if (dirp) {
733			int count = 0;
734
735			while (count < 3 && readdir(dirp) != NULL)
736				count++;
737			(void) closedir(dirp);
738
739			if (count > 2) {
740				(void) fprintf(stderr, gettext("mountpoint "
741				    "'%s' exists and is not empty\n"), buf);
742				(void) fprintf(stderr, gettext("use '-m' "
743				    "option to provide a "
744				    "different default\n"));
745				goto errout;
746			}
747		}
748	}
749
750	if (dryrun) {
751		/*
752		 * For a dry run invocation, print out a basic message and run
753		 * through all the vdevs in the list and print out in an
754		 * appropriate hierarchy.
755		 */
756		(void) printf(gettext("would create '%s' with the "
757		    "following layout:\n\n"), poolname);
758
759		print_vdev_tree(NULL, poolname, nvroot, 0, B_FALSE);
760		if (num_logs(nvroot) > 0)
761			print_vdev_tree(NULL, "logs", nvroot, 0, B_TRUE);
762
763		ret = 0;
764	} else {
765		/*
766		 * Hand off to libzfs.
767		 */
768		if (zpool_create(g_zfs, poolname,
769		    nvroot, props, fsprops) == 0) {
770			zfs_handle_t *pool = zfs_open(g_zfs, poolname,
771			    ZFS_TYPE_FILESYSTEM);
772			if (pool != NULL) {
773				if (mountpoint != NULL)
774					verify(zfs_prop_set(pool,
775					    zfs_prop_to_name(
776					    ZFS_PROP_MOUNTPOINT),
777					    mountpoint) == 0);
778				if (zfs_mount(pool, NULL, 0) == 0)
779					ret = zfs_shareall(pool);
780				zfs_close(pool);
781			}
782		} else if (libzfs_errno(g_zfs) == EZFS_INVALIDNAME) {
783			(void) fprintf(stderr, gettext("pool name may have "
784			    "been omitted\n"));
785		}
786	}
787
788errout:
789	nvlist_free(nvroot);
790	nvlist_free(fsprops);
791	nvlist_free(props);
792	return (ret);
793badusage:
794	nvlist_free(fsprops);
795	nvlist_free(props);
796	usage(B_FALSE);
797	return (2);
798}
799
800/*
801 * zpool destroy <pool>
802 *
803 * 	-f	Forcefully unmount any datasets
804 *
805 * Destroy the given pool.  Automatically unmounts any datasets in the pool.
806 */
807int
808zpool_do_destroy(int argc, char **argv)
809{
810	boolean_t force = B_FALSE;
811	int c;
812	char *pool;
813	zpool_handle_t *zhp;
814	int ret;
815
816	/* check options */
817	while ((c = getopt(argc, argv, "f")) != -1) {
818		switch (c) {
819		case 'f':
820			force = B_TRUE;
821			break;
822		case '?':
823			(void) fprintf(stderr, gettext("invalid option '%c'\n"),
824			    optopt);
825			usage(B_FALSE);
826		}
827	}
828
829	argc -= optind;
830	argv += optind;
831
832	/* check arguments */
833	if (argc < 1) {
834		(void) fprintf(stderr, gettext("missing pool argument\n"));
835		usage(B_FALSE);
836	}
837	if (argc > 1) {
838		(void) fprintf(stderr, gettext("too many arguments\n"));
839		usage(B_FALSE);
840	}
841
842	pool = argv[0];
843
844	if ((zhp = zpool_open_canfail(g_zfs, pool)) == NULL) {
845		/*
846		 * As a special case, check for use of '/' in the name, and
847		 * direct the user to use 'zfs destroy' instead.
848		 */
849		if (strchr(pool, '/') != NULL)
850			(void) fprintf(stderr, gettext("use 'zfs destroy' to "
851			    "destroy a dataset\n"));
852		return (1);
853	}
854
855	if (zpool_disable_datasets(zhp, force) != 0) {
856		(void) fprintf(stderr, gettext("could not destroy '%s': "
857		    "could not unmount datasets\n"), zpool_get_name(zhp));
858		return (1);
859	}
860
861	ret = (zpool_destroy(zhp) != 0);
862
863	zpool_close(zhp);
864
865	return (ret);
866}
867
868/*
869 * zpool export [-f] <pool> ...
870 *
871 *	-f	Forcefully unmount datasets
872 *
873 * Export the given pools.  By default, the command will attempt to cleanly
874 * unmount any active datasets within the pool.  If the '-f' flag is specified,
875 * then the datasets will be forcefully unmounted.
876 */
877int
878zpool_do_export(int argc, char **argv)
879{
880	boolean_t force = B_FALSE;
881	boolean_t hardforce = B_FALSE;
882	int c;
883	zpool_handle_t *zhp;
884	int ret;
885	int i;
886
887	/* check options */
888	while ((c = getopt(argc, argv, "fF")) != -1) {
889		switch (c) {
890		case 'f':
891			force = B_TRUE;
892			break;
893		case 'F':
894			hardforce = B_TRUE;
895			break;
896		case '?':
897			(void) fprintf(stderr, gettext("invalid option '%c'\n"),
898			    optopt);
899			usage(B_FALSE);
900		}
901	}
902
903	argc -= optind;
904	argv += optind;
905
906	/* check arguments */
907	if (argc < 1) {
908		(void) fprintf(stderr, gettext("missing pool argument\n"));
909		usage(B_FALSE);
910	}
911
912	ret = 0;
913	for (i = 0; i < argc; i++) {
914		if ((zhp = zpool_open_canfail(g_zfs, argv[i])) == NULL) {
915			ret = 1;
916			continue;
917		}
918
919		if (zpool_disable_datasets(zhp, force) != 0) {
920			ret = 1;
921			zpool_close(zhp);
922			continue;
923		}
924
925		if (hardforce) {
926			if (zpool_export_force(zhp) != 0)
927				ret = 1;
928		} else if (zpool_export(zhp, force) != 0) {
929			ret = 1;
930		}
931
932		zpool_close(zhp);
933	}
934
935	return (ret);
936}
937
938/*
939 * Given a vdev configuration, determine the maximum width needed for the device
940 * name column.
941 */
942static int
943max_width(zpool_handle_t *zhp, nvlist_t *nv, int depth, int max)
944{
945	char *name = zpool_vdev_name(g_zfs, zhp, nv);
946	nvlist_t **child;
947	uint_t c, children;
948	int ret;
949
950	if (strlen(name) + depth > max)
951		max = strlen(name) + depth;
952
953	free(name);
954
955	if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_SPARES,
956	    &child, &children) == 0) {
957		for (c = 0; c < children; c++)
958			if ((ret = max_width(zhp, child[c], depth + 2,
959			    max)) > max)
960				max = ret;
961	}
962
963	if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_L2CACHE,
964	    &child, &children) == 0) {
965		for (c = 0; c < children; c++)
966			if ((ret = max_width(zhp, child[c], depth + 2,
967			    max)) > max)
968				max = ret;
969	}
970
971	if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
972	    &child, &children) == 0) {
973		for (c = 0; c < children; c++)
974			if ((ret = max_width(zhp, child[c], depth + 2,
975			    max)) > max)
976				max = ret;
977	}
978
979
980	return (max);
981}
982
983
984/*
985 * Print the configuration of an exported pool.  Iterate over all vdevs in the
986 * pool, printing out the name and status for each one.
987 */
988void
989print_import_config(const char *name, nvlist_t *nv, int namewidth, int depth,
990    boolean_t print_logs)
991{
992	nvlist_t **child;
993	uint_t c, children;
994	vdev_stat_t *vs;
995	char *type, *vname;
996
997	verify(nvlist_lookup_string(nv, ZPOOL_CONFIG_TYPE, &type) == 0);
998	if (strcmp(type, VDEV_TYPE_MISSING) == 0)
999		return;
1000
1001	verify(nvlist_lookup_uint64_array(nv, ZPOOL_CONFIG_STATS,
1002	    (uint64_t **)&vs, &c) == 0);
1003
1004	(void) printf("\t%*s%-*s", depth, "", namewidth - depth, name);
1005	(void) printf("  %s", zpool_state_to_name(vs->vs_state, vs->vs_aux));
1006
1007	if (vs->vs_aux != 0) {
1008		(void) printf("  ");
1009
1010		switch (vs->vs_aux) {
1011		case VDEV_AUX_OPEN_FAILED:
1012			(void) printf(gettext("cannot open"));
1013			break;
1014
1015		case VDEV_AUX_BAD_GUID_SUM:
1016			(void) printf(gettext("missing device"));
1017			break;
1018
1019		case VDEV_AUX_NO_REPLICAS:
1020			(void) printf(gettext("insufficient replicas"));
1021			break;
1022
1023		case VDEV_AUX_VERSION_NEWER:
1024			(void) printf(gettext("newer version"));
1025			break;
1026
1027		case VDEV_AUX_ERR_EXCEEDED:
1028			(void) printf(gettext("too many errors"));
1029			break;
1030
1031		default:
1032			(void) printf(gettext("corrupted data"));
1033			break;
1034		}
1035	}
1036	(void) printf("\n");
1037
1038	if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
1039	    &child, &children) != 0)
1040		return;
1041
1042	for (c = 0; c < children; c++) {
1043		uint64_t is_log = B_FALSE;
1044
1045		(void) nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_LOG,
1046		    &is_log);
1047		if ((is_log && !print_logs) || (!is_log && print_logs))
1048			continue;
1049
1050		vname = zpool_vdev_name(g_zfs, NULL, child[c]);
1051		print_import_config(vname, child[c],
1052		    namewidth, depth + 2, B_FALSE);
1053		free(vname);
1054	}
1055
1056	if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_L2CACHE,
1057	    &child, &children) == 0) {
1058		(void) printf(gettext("\tcache\n"));
1059		for (c = 0; c < children; c++) {
1060			vname = zpool_vdev_name(g_zfs, NULL, child[c]);
1061			(void) printf("\t  %s\n", vname);
1062			free(vname);
1063		}
1064	}
1065
1066	if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_SPARES,
1067	    &child, &children) == 0) {
1068		(void) printf(gettext("\tspares\n"));
1069		for (c = 0; c < children; c++) {
1070			vname = zpool_vdev_name(g_zfs, NULL, child[c]);
1071			(void) printf("\t  %s\n", vname);
1072			free(vname);
1073		}
1074	}
1075}
1076
1077/*
1078 * Display the status for the given pool.
1079 */
1080static void
1081show_import(nvlist_t *config)
1082{
1083	uint64_t pool_state;
1084	vdev_stat_t *vs;
1085	char *name;
1086	uint64_t guid;
1087	char *msgid;
1088	nvlist_t *nvroot;
1089	int reason;
1090	const char *health;
1091	uint_t vsc;
1092	int namewidth;
1093
1094	verify(nvlist_lookup_string(config, ZPOOL_CONFIG_POOL_NAME,
1095	    &name) == 0);
1096	verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_GUID,
1097	    &guid) == 0);
1098	verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_STATE,
1099	    &pool_state) == 0);
1100	verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
1101	    &nvroot) == 0);
1102
1103	verify(nvlist_lookup_uint64_array(nvroot, ZPOOL_CONFIG_STATS,
1104	    (uint64_t **)&vs, &vsc) == 0);
1105	health = zpool_state_to_name(vs->vs_state, vs->vs_aux);
1106
1107	reason = zpool_import_status(config, &msgid);
1108
1109	(void) printf(gettext("  pool: %s\n"), name);
1110	(void) printf(gettext("    id: %llu\n"), (u_longlong_t)guid);
1111	(void) printf(gettext(" state: %s"), health);
1112	if (pool_state == POOL_STATE_DESTROYED)
1113		(void) printf(gettext(" (DESTROYED)"));
1114	(void) printf("\n");
1115
1116	switch (reason) {
1117	case ZPOOL_STATUS_MISSING_DEV_R:
1118	case ZPOOL_STATUS_MISSING_DEV_NR:
1119	case ZPOOL_STATUS_BAD_GUID_SUM:
1120		(void) printf(gettext("status: One or more devices are missing "
1121		    "from the system.\n"));
1122		break;
1123
1124	case ZPOOL_STATUS_CORRUPT_LABEL_R:
1125	case ZPOOL_STATUS_CORRUPT_LABEL_NR:
1126		(void) printf(gettext("status: One or more devices contains "
1127		    "corrupted data.\n"));
1128		break;
1129
1130	case ZPOOL_STATUS_CORRUPT_DATA:
1131		(void) printf(gettext("status: The pool data is corrupted.\n"));
1132		break;
1133
1134	case ZPOOL_STATUS_OFFLINE_DEV:
1135		(void) printf(gettext("status: One or more devices "
1136		    "are offlined.\n"));
1137		break;
1138
1139	case ZPOOL_STATUS_CORRUPT_POOL:
1140		(void) printf(gettext("status: The pool metadata is "
1141		    "corrupted.\n"));
1142		break;
1143
1144	case ZPOOL_STATUS_VERSION_OLDER:
1145		(void) printf(gettext("status: The pool is formatted using an "
1146		    "older on-disk version.\n"));
1147		break;
1148
1149	case ZPOOL_STATUS_VERSION_NEWER:
1150		(void) printf(gettext("status: The pool is formatted using an "
1151		    "incompatible version.\n"));
1152		break;
1153
1154	case ZPOOL_STATUS_HOSTID_MISMATCH:
1155		(void) printf(gettext("status: The pool was last accessed by "
1156		    "another system.\n"));
1157		break;
1158
1159	case ZPOOL_STATUS_FAULTED_DEV_R:
1160	case ZPOOL_STATUS_FAULTED_DEV_NR:
1161		(void) printf(gettext("status: One or more devices are "
1162		    "faulted.\n"));
1163		break;
1164
1165	case ZPOOL_STATUS_BAD_LOG:
1166		(void) printf(gettext("status: An intent log record cannot be "
1167		    "read.\n"));
1168		break;
1169
1170	default:
1171		/*
1172		 * No other status can be seen when importing pools.
1173		 */
1174		assert(reason == ZPOOL_STATUS_OK);
1175	}
1176
1177	/*
1178	 * Print out an action according to the overall state of the pool.
1179	 */
1180	if (vs->vs_state == VDEV_STATE_HEALTHY) {
1181		if (reason == ZPOOL_STATUS_VERSION_OLDER)
1182			(void) printf(gettext("action: The pool can be "
1183			    "imported using its name or numeric identifier, "
1184			    "though\n\tsome features will not be available "
1185			    "without an explicit 'zpool upgrade'.\n"));
1186		else if (reason == ZPOOL_STATUS_HOSTID_MISMATCH)
1187			(void) printf(gettext("action: The pool can be "
1188			    "imported using its name or numeric "
1189			    "identifier and\n\tthe '-f' flag.\n"));
1190		else
1191			(void) printf(gettext("action: The pool can be "
1192			    "imported using its name or numeric "
1193			    "identifier.\n"));
1194	} else if (vs->vs_state == VDEV_STATE_DEGRADED) {
1195		(void) printf(gettext("action: The pool can be imported "
1196		    "despite missing or damaged devices.  The\n\tfault "
1197		    "tolerance of the pool may be compromised if imported.\n"));
1198	} else {
1199		switch (reason) {
1200		case ZPOOL_STATUS_VERSION_NEWER:
1201			(void) printf(gettext("action: The pool cannot be "
1202			    "imported.  Access the pool on a system running "
1203			    "newer\n\tsoftware, or recreate the pool from "
1204			    "backup.\n"));
1205			break;
1206		case ZPOOL_STATUS_MISSING_DEV_R:
1207		case ZPOOL_STATUS_MISSING_DEV_NR:
1208		case ZPOOL_STATUS_BAD_GUID_SUM:
1209			(void) printf(gettext("action: The pool cannot be "
1210			    "imported. Attach the missing\n\tdevices and try "
1211			    "again.\n"));
1212			break;
1213		default:
1214			(void) printf(gettext("action: The pool cannot be "
1215			    "imported due to damaged devices or data.\n"));
1216		}
1217	}
1218
1219	/*
1220	 * If the state is "closed" or "can't open", and the aux state
1221	 * is "corrupt data":
1222	 */
1223	if (((vs->vs_state == VDEV_STATE_CLOSED) ||
1224	    (vs->vs_state == VDEV_STATE_CANT_OPEN)) &&
1225	    (vs->vs_aux == VDEV_AUX_CORRUPT_DATA)) {
1226		if (pool_state == POOL_STATE_DESTROYED)
1227			(void) printf(gettext("\tThe pool was destroyed, "
1228			    "but can be imported using the '-Df' flags.\n"));
1229		else if (pool_state != POOL_STATE_EXPORTED)
1230			(void) printf(gettext("\tThe pool may be active on "
1231			    "another system, but can be imported using\n\t"
1232			    "the '-f' flag.\n"));
1233	}
1234
1235	if (msgid != NULL)
1236		(void) printf(gettext("   see: http://www.sun.com/msg/%s\n"),
1237		    msgid);
1238
1239	(void) printf(gettext("config:\n\n"));
1240
1241	namewidth = max_width(NULL, nvroot, 0, 0);
1242	if (namewidth < 10)
1243		namewidth = 10;
1244
1245	print_import_config(name, nvroot, namewidth, 0, B_FALSE);
1246	if (num_logs(nvroot) > 0) {
1247		(void) printf(gettext("\tlogs\n"));
1248		print_import_config(name, nvroot, namewidth, 0, B_TRUE);
1249	}
1250
1251	if (reason == ZPOOL_STATUS_BAD_GUID_SUM) {
1252		(void) printf(gettext("\n\tAdditional devices are known to "
1253		    "be part of this pool, though their\n\texact "
1254		    "configuration cannot be determined.\n"));
1255	}
1256}
1257
1258/*
1259 * Perform the import for the given configuration.  This passes the heavy
1260 * lifting off to zpool_import_props(), and then mounts the datasets contained
1261 * within the pool.
1262 */
1263static int
1264do_import(nvlist_t *config, const char *newname, const char *mntopts,
1265    int force, nvlist_t *props, boolean_t do_verbatim)
1266{
1267	zpool_handle_t *zhp;
1268	char *name;
1269	uint64_t state;
1270	uint64_t version;
1271	int error = 0;
1272
1273	verify(nvlist_lookup_string(config, ZPOOL_CONFIG_POOL_NAME,
1274	    &name) == 0);
1275
1276	verify(nvlist_lookup_uint64(config,
1277	    ZPOOL_CONFIG_POOL_STATE, &state) == 0);
1278	verify(nvlist_lookup_uint64(config,
1279	    ZPOOL_CONFIG_VERSION, &version) == 0);
1280	if (version > SPA_VERSION) {
1281		(void) fprintf(stderr, gettext("cannot import '%s': pool "
1282		    "is formatted using a newer ZFS version\n"), name);
1283		return (1);
1284	} else if (state != POOL_STATE_EXPORTED && !force) {
1285		uint64_t hostid;
1286
1287		if (nvlist_lookup_uint64(config, ZPOOL_CONFIG_HOSTID,
1288		    &hostid) == 0) {
1289			if ((unsigned long)hostid != gethostid()) {
1290				char *hostname;
1291				uint64_t timestamp;
1292				time_t t;
1293
1294				verify(nvlist_lookup_string(config,
1295				    ZPOOL_CONFIG_HOSTNAME, &hostname) == 0);
1296				verify(nvlist_lookup_uint64(config,
1297				    ZPOOL_CONFIG_TIMESTAMP, &timestamp) == 0);
1298				t = timestamp;
1299				(void) fprintf(stderr, gettext("cannot import "
1300				    "'%s': pool may be in use from other "
1301				    "system, it was last accessed by %s "
1302				    "(hostid: 0x%lx) on %s"), name, hostname,
1303				    (unsigned long)hostid,
1304				    asctime(localtime(&t)));
1305				(void) fprintf(stderr, gettext("use '-f' to "
1306				    "import anyway\n"));
1307				return (1);
1308			}
1309		} else {
1310			(void) fprintf(stderr, gettext("cannot import '%s': "
1311			    "pool may be in use from other system\n"), name);
1312			(void) fprintf(stderr, gettext("use '-f' to import "
1313			    "anyway\n"));
1314			return (1);
1315		}
1316	}
1317
1318	if (zpool_import_props(g_zfs, config, newname, props, do_verbatim) != 0)
1319		return (1);
1320
1321	if (newname != NULL)
1322		name = (char *)newname;
1323
1324	if ((zhp = zpool_open_canfail(g_zfs, name)) == NULL)
1325		return (1);
1326
1327	if (zpool_get_state(zhp) != POOL_STATE_UNAVAIL &&
1328	    zpool_enable_datasets(zhp, mntopts, 0) != 0) {
1329		zpool_close(zhp);
1330		return (1);
1331	}
1332
1333	zpool_close(zhp);
1334	return (error);
1335}
1336
1337/*
1338 * zpool import [-d dir] [-D]
1339 *       import [-o mntopts] [-o prop=value] ... [-R root] [-D]
1340 *              [-d dir | -c cachefile] [-f] -a
1341 *       import [-o mntopts] [-o prop=value] ... [-R root] [-D]
1342 *              [-d dir | -c cachefile] [-f] <pool | id> [newpool]
1343 *
1344 *	 -c	Read pool information from a cachefile instead of searching
1345 *		devices.
1346 *
1347 *       -d	Scan in a specific directory, other than /dev/dsk.  More than
1348 *		one directory can be specified using multiple '-d' options.
1349 *
1350 *       -D     Scan for previously destroyed pools or import all or only
1351 *              specified destroyed pools.
1352 *
1353 *       -R	Temporarily import the pool, with all mountpoints relative to
1354 *		the given root.  The pool will remain exported when the machine
1355 *		is rebooted.
1356 *
1357 *       -f	Force import, even if it appears that the pool is active.
1358 *
1359 *       -F	Import even in the presence of faulted vdevs.  This is an
1360 *       	intentionally undocumented option for testing purposes, and
1361 *       	treats the pool configuration as complete, leaving any bad
1362 *		vdevs in the FAULTED state. In other words, it does verbatim
1363 *		import.
1364 *
1365 *       -a	Import all pools found.
1366 *
1367 *       -o	Set property=value and/or temporary mount options (without '=').
1368 *
1369 * The import command scans for pools to import, and import pools based on pool
1370 * name and GUID.  The pool can also be renamed as part of the import process.
1371 */
1372int
1373zpool_do_import(int argc, char **argv)
1374{
1375	char **searchdirs = NULL;
1376	int nsearch = 0;
1377	int c;
1378	int err;
1379	nvlist_t *pools = NULL;
1380	boolean_t do_all = B_FALSE;
1381	boolean_t do_destroyed = B_FALSE;
1382	char *mntopts = NULL;
1383	boolean_t do_force = B_FALSE;
1384	nvpair_t *elem;
1385	nvlist_t *config;
1386	uint64_t searchguid = 0;
1387	char *searchname = NULL;
1388	char *propval;
1389	nvlist_t *found_config;
1390	nvlist_t *props = NULL;
1391	boolean_t first;
1392	boolean_t do_verbatim = B_FALSE;
1393	uint64_t pool_state;
1394	char *cachefile = NULL;
1395
1396	/* check options */
1397	while ((c = getopt(argc, argv, ":ac:d:DfFo:p:R:")) != -1) {
1398		switch (c) {
1399		case 'a':
1400			do_all = B_TRUE;
1401			break;
1402		case 'c':
1403			cachefile = optarg;
1404			break;
1405		case 'd':
1406			if (searchdirs == NULL) {
1407				searchdirs = safe_malloc(sizeof (char *));
1408			} else {
1409				char **tmp = safe_malloc((nsearch + 1) *
1410				    sizeof (char *));
1411				bcopy(searchdirs, tmp, nsearch *
1412				    sizeof (char *));
1413				free(searchdirs);
1414				searchdirs = tmp;
1415			}
1416			searchdirs[nsearch++] = optarg;
1417			break;
1418		case 'D':
1419			do_destroyed = B_TRUE;
1420			break;
1421		case 'f':
1422			do_force = B_TRUE;
1423			break;
1424		case 'F':
1425			do_verbatim = B_TRUE;
1426			break;
1427		case 'o':
1428			if ((propval = strchr(optarg, '=')) != NULL) {
1429				*propval = '\0';
1430				propval++;
1431				if (add_prop_list(optarg, propval,
1432				    &props, B_TRUE))
1433					goto error;
1434			} else {
1435				mntopts = optarg;
1436			}
1437			break;
1438		case 'R':
1439			if (add_prop_list(zpool_prop_to_name(
1440			    ZPOOL_PROP_ALTROOT), optarg, &props, B_TRUE))
1441				goto error;
1442			if (nvlist_lookup_string(props,
1443			    zpool_prop_to_name(ZPOOL_PROP_CACHEFILE),
1444			    &propval) == 0)
1445				break;
1446			if (add_prop_list(zpool_prop_to_name(
1447			    ZPOOL_PROP_CACHEFILE), "none", &props, B_TRUE))
1448				goto error;
1449			break;
1450		case ':':
1451			(void) fprintf(stderr, gettext("missing argument for "
1452			    "'%c' option\n"), optopt);
1453			usage(B_FALSE);
1454			break;
1455		case '?':
1456			(void) fprintf(stderr, gettext("invalid option '%c'\n"),
1457			    optopt);
1458			usage(B_FALSE);
1459		}
1460	}
1461
1462	argc -= optind;
1463	argv += optind;
1464
1465	if (cachefile && nsearch != 0) {
1466		(void) fprintf(stderr, gettext("-c is incompatible with -d\n"));
1467		usage(B_FALSE);
1468	}
1469
1470	if (searchdirs == NULL) {
1471		searchdirs = safe_malloc(sizeof (char *));
1472		searchdirs[0] = "/dev/dsk";
1473		nsearch = 1;
1474	}
1475
1476	/* check argument count */
1477	if (do_all) {
1478		if (argc != 0) {
1479			(void) fprintf(stderr, gettext("too many arguments\n"));
1480			usage(B_FALSE);
1481		}
1482	} else {
1483		if (argc > 2) {
1484			(void) fprintf(stderr, gettext("too many arguments\n"));
1485			usage(B_FALSE);
1486		}
1487
1488		/*
1489		 * Check for the SYS_CONFIG privilege.  We do this explicitly
1490		 * here because otherwise any attempt to discover pools will
1491		 * silently fail.
1492		 */
1493		if (argc == 0 && !priv_ineffect(PRIV_SYS_CONFIG)) {
1494			(void) fprintf(stderr, gettext("cannot "
1495			    "discover pools: permission denied\n"));
1496			free(searchdirs);
1497			return (1);
1498		}
1499	}
1500
1501	/*
1502	 * Depending on the arguments given, we do one of the following:
1503	 *
1504	 *	<none>	Iterate through all pools and display information about
1505	 *		each one.
1506	 *
1507	 *	-a	Iterate through all pools and try to import each one.
1508	 *
1509	 *	<id>	Find the pool that corresponds to the given GUID/pool
1510	 *		name and import that one.
1511	 *
1512	 *	-D	Above options applies only to destroyed pools.
1513	 */
1514	if (argc != 0) {
1515		char *endptr;
1516
1517		errno = 0;
1518		searchguid = strtoull(argv[0], &endptr, 10);
1519		if (errno != 0 || *endptr != '\0')
1520			searchname = argv[0];
1521		found_config = NULL;
1522	}
1523
1524	if (cachefile) {
1525		pools = zpool_find_import_cached(g_zfs, cachefile, searchname,
1526		    searchguid);
1527	} else if (searchname != NULL) {
1528		pools = zpool_find_import_byname(g_zfs, nsearch, searchdirs,
1529		    searchname);
1530	} else {
1531		/*
1532		 * It's OK to search by guid even if searchguid is 0.
1533		 */
1534		pools = zpool_find_import_byguid(g_zfs, nsearch, searchdirs,
1535		    searchguid);
1536	}
1537
1538	if (pools == NULL) {
1539		if (argc != 0) {
1540			(void) fprintf(stderr, gettext("cannot import '%s': "
1541			    "no such pool available\n"), argv[0]);
1542		}
1543		free(searchdirs);
1544		return (1);
1545	}
1546
1547	/*
1548	 * At this point we have a list of import candidate configs. Even if
1549	 * we were searching by pool name or guid, we still need to
1550	 * post-process the list to deal with pool state and possible
1551	 * duplicate names.
1552	 */
1553	err = 0;
1554	elem = NULL;
1555	first = B_TRUE;
1556	while ((elem = nvlist_next_nvpair(pools, elem)) != NULL) {
1557
1558		verify(nvpair_value_nvlist(elem, &config) == 0);
1559
1560		verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_STATE,
1561		    &pool_state) == 0);
1562		if (!do_destroyed && pool_state == POOL_STATE_DESTROYED)
1563			continue;
1564		if (do_destroyed && pool_state != POOL_STATE_DESTROYED)
1565			continue;
1566
1567		if (argc == 0) {
1568			if (first)
1569				first = B_FALSE;
1570			else if (!do_all)
1571				(void) printf("\n");
1572
1573			if (do_all)
1574				err |= do_import(config, NULL, mntopts,
1575				    do_force, props, do_verbatim);
1576			else
1577				show_import(config);
1578		} else if (searchname != NULL) {
1579			char *name;
1580
1581			/*
1582			 * We are searching for a pool based on name.
1583			 */
1584			verify(nvlist_lookup_string(config,
1585			    ZPOOL_CONFIG_POOL_NAME, &name) == 0);
1586
1587			if (strcmp(name, searchname) == 0) {
1588				if (found_config != NULL) {
1589					(void) fprintf(stderr, gettext(
1590					    "cannot import '%s': more than "
1591					    "one matching pool\n"), searchname);
1592					(void) fprintf(stderr, gettext(
1593					    "import by numeric ID instead\n"));
1594					err = B_TRUE;
1595				}
1596				found_config = config;
1597			}
1598		} else {
1599			uint64_t guid;
1600
1601			/*
1602			 * Search for a pool by guid.
1603			 */
1604			verify(nvlist_lookup_uint64(config,
1605			    ZPOOL_CONFIG_POOL_GUID, &guid) == 0);
1606
1607			if (guid == searchguid)
1608				found_config = config;
1609		}
1610	}
1611
1612	/*
1613	 * If we were searching for a specific pool, verify that we found a
1614	 * pool, and then do the import.
1615	 */
1616	if (argc != 0 && err == 0) {
1617		if (found_config == NULL) {
1618			(void) fprintf(stderr, gettext("cannot import '%s': "
1619			    "no such pool available\n"), argv[0]);
1620			err = B_TRUE;
1621		} else {
1622			err |= do_import(found_config, argc == 1 ? NULL :
1623			    argv[1], mntopts, do_force, props, do_verbatim);
1624		}
1625	}
1626
1627	/*
1628	 * If we were just looking for pools, report an error if none were
1629	 * found.
1630	 */
1631	if (argc == 0 && first)
1632		(void) fprintf(stderr,
1633		    gettext("no pools available to import\n"));
1634
1635error:
1636	nvlist_free(props);
1637	nvlist_free(pools);
1638	free(searchdirs);
1639
1640	return (err ? 1 : 0);
1641}
1642
1643typedef struct iostat_cbdata {
1644	zpool_list_t *cb_list;
1645	int cb_verbose;
1646	int cb_iteration;
1647	int cb_namewidth;
1648} iostat_cbdata_t;
1649
1650static void
1651print_iostat_separator(iostat_cbdata_t *cb)
1652{
1653	int i = 0;
1654
1655	for (i = 0; i < cb->cb_namewidth; i++)
1656		(void) printf("-");
1657	(void) printf("  -----  -----  -----  -----  -----  -----\n");
1658}
1659
1660static void
1661print_iostat_header(iostat_cbdata_t *cb)
1662{
1663	(void) printf("%*s     capacity     operations    bandwidth\n",
1664	    cb->cb_namewidth, "");
1665	(void) printf("%-*s   used  avail   read  write   read  write\n",
1666	    cb->cb_namewidth, "pool");
1667	print_iostat_separator(cb);
1668}
1669
1670/*
1671 * Display a single statistic.
1672 */
1673static void
1674print_one_stat(uint64_t value)
1675{
1676	char buf[64];
1677
1678	zfs_nicenum(value, buf, sizeof (buf));
1679	(void) printf("  %5s", buf);
1680}
1681
1682/*
1683 * Print out all the statistics for the given vdev.  This can either be the
1684 * toplevel configuration, or called recursively.  If 'name' is NULL, then this
1685 * is a verbose output, and we don't want to display the toplevel pool stats.
1686 */
1687void
1688print_vdev_stats(zpool_handle_t *zhp, const char *name, nvlist_t *oldnv,
1689    nvlist_t *newnv, iostat_cbdata_t *cb, int depth)
1690{
1691	nvlist_t **oldchild, **newchild;
1692	uint_t c, children;
1693	vdev_stat_t *oldvs, *newvs;
1694	vdev_stat_t zerovs = { 0 };
1695	uint64_t tdelta;
1696	double scale;
1697	char *vname;
1698
1699	if (oldnv != NULL) {
1700		verify(nvlist_lookup_uint64_array(oldnv, ZPOOL_CONFIG_STATS,
1701		    (uint64_t **)&oldvs, &c) == 0);
1702	} else {
1703		oldvs = &zerovs;
1704	}
1705
1706	verify(nvlist_lookup_uint64_array(newnv, ZPOOL_CONFIG_STATS,
1707	    (uint64_t **)&newvs, &c) == 0);
1708
1709	if (strlen(name) + depth > cb->cb_namewidth)
1710		(void) printf("%*s%s", depth, "", name);
1711	else
1712		(void) printf("%*s%s%*s", depth, "", name,
1713		    (int)(cb->cb_namewidth - strlen(name) - depth), "");
1714
1715	tdelta = newvs->vs_timestamp - oldvs->vs_timestamp;
1716
1717	if (tdelta == 0)
1718		scale = 1.0;
1719	else
1720		scale = (double)NANOSEC / tdelta;
1721
1722	/* only toplevel vdevs have capacity stats */
1723	if (newvs->vs_space == 0) {
1724		(void) printf("      -      -");
1725	} else {
1726		print_one_stat(newvs->vs_alloc);
1727		print_one_stat(newvs->vs_space - newvs->vs_alloc);
1728	}
1729
1730	print_one_stat((uint64_t)(scale * (newvs->vs_ops[ZIO_TYPE_READ] -
1731	    oldvs->vs_ops[ZIO_TYPE_READ])));
1732
1733	print_one_stat((uint64_t)(scale * (newvs->vs_ops[ZIO_TYPE_WRITE] -
1734	    oldvs->vs_ops[ZIO_TYPE_WRITE])));
1735
1736	print_one_stat((uint64_t)(scale * (newvs->vs_bytes[ZIO_TYPE_READ] -
1737	    oldvs->vs_bytes[ZIO_TYPE_READ])));
1738
1739	print_one_stat((uint64_t)(scale * (newvs->vs_bytes[ZIO_TYPE_WRITE] -
1740	    oldvs->vs_bytes[ZIO_TYPE_WRITE])));
1741
1742	(void) printf("\n");
1743
1744	if (!cb->cb_verbose)
1745		return;
1746
1747	if (nvlist_lookup_nvlist_array(newnv, ZPOOL_CONFIG_CHILDREN,
1748	    &newchild, &children) != 0)
1749		return;
1750
1751	if (oldnv && nvlist_lookup_nvlist_array(oldnv, ZPOOL_CONFIG_CHILDREN,
1752	    &oldchild, &c) != 0)
1753		return;
1754
1755	for (c = 0; c < children; c++) {
1756		vname = zpool_vdev_name(g_zfs, zhp, newchild[c]);
1757		print_vdev_stats(zhp, vname, oldnv ? oldchild[c] : NULL,
1758		    newchild[c], cb, depth + 2);
1759		free(vname);
1760	}
1761
1762	/*
1763	 * Include level 2 ARC devices in iostat output
1764	 */
1765	if (nvlist_lookup_nvlist_array(newnv, ZPOOL_CONFIG_L2CACHE,
1766	    &newchild, &children) != 0)
1767		return;
1768
1769	if (oldnv && nvlist_lookup_nvlist_array(oldnv, ZPOOL_CONFIG_L2CACHE,
1770	    &oldchild, &c) != 0)
1771		return;
1772
1773	if (children > 0) {
1774		(void) printf("%-*s      -      -      -      -      -      "
1775		    "-\n", cb->cb_namewidth, "cache");
1776		for (c = 0; c < children; c++) {
1777			vname = zpool_vdev_name(g_zfs, zhp, newchild[c]);
1778			print_vdev_stats(zhp, vname, oldnv ? oldchild[c] : NULL,
1779			    newchild[c], cb, depth + 2);
1780			free(vname);
1781		}
1782	}
1783}
1784
1785static int
1786refresh_iostat(zpool_handle_t *zhp, void *data)
1787{
1788	iostat_cbdata_t *cb = data;
1789	boolean_t missing;
1790
1791	/*
1792	 * If the pool has disappeared, remove it from the list and continue.
1793	 */
1794	if (zpool_refresh_stats(zhp, &missing) != 0)
1795		return (-1);
1796
1797	if (missing)
1798		pool_list_remove(cb->cb_list, zhp);
1799
1800	return (0);
1801}
1802
1803/*
1804 * Callback to print out the iostats for the given pool.
1805 */
1806int
1807print_iostat(zpool_handle_t *zhp, void *data)
1808{
1809	iostat_cbdata_t *cb = data;
1810	nvlist_t *oldconfig, *newconfig;
1811	nvlist_t *oldnvroot, *newnvroot;
1812
1813	newconfig = zpool_get_config(zhp, &oldconfig);
1814
1815	if (cb->cb_iteration == 1)
1816		oldconfig = NULL;
1817
1818	verify(nvlist_lookup_nvlist(newconfig, ZPOOL_CONFIG_VDEV_TREE,
1819	    &newnvroot) == 0);
1820
1821	if (oldconfig == NULL)
1822		oldnvroot = NULL;
1823	else
1824		verify(nvlist_lookup_nvlist(oldconfig, ZPOOL_CONFIG_VDEV_TREE,
1825		    &oldnvroot) == 0);
1826
1827	/*
1828	 * Print out the statistics for the pool.
1829	 */
1830	print_vdev_stats(zhp, zpool_get_name(zhp), oldnvroot, newnvroot, cb, 0);
1831
1832	if (cb->cb_verbose)
1833		print_iostat_separator(cb);
1834
1835	return (0);
1836}
1837
1838int
1839get_namewidth(zpool_handle_t *zhp, void *data)
1840{
1841	iostat_cbdata_t *cb = data;
1842	nvlist_t *config, *nvroot;
1843
1844	if ((config = zpool_get_config(zhp, NULL)) != NULL) {
1845		verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
1846		    &nvroot) == 0);
1847		if (!cb->cb_verbose)
1848			cb->cb_namewidth = strlen(zpool_get_name(zhp));
1849		else
1850			cb->cb_namewidth = max_width(zhp, nvroot, 0, 0);
1851	}
1852
1853	/*
1854	 * The width must fall into the range [10,38].  The upper limit is the
1855	 * maximum we can have and still fit in 80 columns.
1856	 */
1857	if (cb->cb_namewidth < 10)
1858		cb->cb_namewidth = 10;
1859	if (cb->cb_namewidth > 38)
1860		cb->cb_namewidth = 38;
1861
1862	return (0);
1863}
1864
1865/*
1866 * zpool iostat [-v] [pool] ... [interval [count]]
1867 *
1868 *	-v	Display statistics for individual vdevs
1869 *
1870 * This command can be tricky because we want to be able to deal with pool
1871 * creation/destruction as well as vdev configuration changes.  The bulk of this
1872 * processing is handled by the pool_list_* routines in zpool_iter.c.  We rely
1873 * on pool_list_update() to detect the addition of new pools.  Configuration
1874 * changes are all handled within libzfs.
1875 */
1876int
1877zpool_do_iostat(int argc, char **argv)
1878{
1879	int c;
1880	int ret;
1881	int npools;
1882	unsigned long interval = 0, count = 0;
1883	zpool_list_t *list;
1884	boolean_t verbose = B_FALSE;
1885	iostat_cbdata_t cb;
1886
1887	/* check options */
1888	while ((c = getopt(argc, argv, "v")) != -1) {
1889		switch (c) {
1890		case 'v':
1891			verbose = B_TRUE;
1892			break;
1893		case '?':
1894			(void) fprintf(stderr, gettext("invalid option '%c'\n"),
1895			    optopt);
1896			usage(B_FALSE);
1897		}
1898	}
1899
1900	argc -= optind;
1901	argv += optind;
1902
1903	/*
1904	 * Determine if the last argument is an integer or a pool name
1905	 */
1906	if (argc > 0 && isdigit(argv[argc - 1][0])) {
1907		char *end;
1908
1909		errno = 0;
1910		interval = strtoul(argv[argc - 1], &end, 10);
1911
1912		if (*end == '\0' && errno == 0) {
1913			if (interval == 0) {
1914				(void) fprintf(stderr, gettext("interval "
1915				    "cannot be zero\n"));
1916				usage(B_FALSE);
1917			}
1918
1919			/*
1920			 * Ignore the last parameter
1921			 */
1922			argc--;
1923		} else {
1924			/*
1925			 * If this is not a valid number, just plow on.  The
1926			 * user will get a more informative error message later
1927			 * on.
1928			 */
1929			interval = 0;
1930		}
1931	}
1932
1933	/*
1934	 * If the last argument is also an integer, then we have both a count
1935	 * and an integer.
1936	 */
1937	if (argc > 0 && isdigit(argv[argc - 1][0])) {
1938		char *end;
1939
1940		errno = 0;
1941		count = interval;
1942		interval = strtoul(argv[argc - 1], &end, 10);
1943
1944		if (*end == '\0' && errno == 0) {
1945			if (interval == 0) {
1946				(void) fprintf(stderr, gettext("interval "
1947				    "cannot be zero\n"));
1948				usage(B_FALSE);
1949			}
1950
1951			/*
1952			 * Ignore the last parameter
1953			 */
1954			argc--;
1955		} else {
1956			interval = 0;
1957		}
1958	}
1959
1960	/*
1961	 * Construct the list of all interesting pools.
1962	 */
1963	ret = 0;
1964	if ((list = pool_list_get(argc, argv, NULL, &ret)) == NULL)
1965		return (1);
1966
1967	if (pool_list_count(list) == 0 && argc != 0) {
1968		pool_list_free(list);
1969		return (1);
1970	}
1971
1972	if (pool_list_count(list) == 0 && interval == 0) {
1973		pool_list_free(list);
1974		(void) fprintf(stderr, gettext("no pools available\n"));
1975		return (1);
1976	}
1977
1978	/*
1979	 * Enter the main iostat loop.
1980	 */
1981	cb.cb_list = list;
1982	cb.cb_verbose = verbose;
1983	cb.cb_iteration = 0;
1984	cb.cb_namewidth = 0;
1985
1986	for (;;) {
1987		pool_list_update(list);
1988
1989		if ((npools = pool_list_count(list)) == 0)
1990			break;
1991
1992		/*
1993		 * Refresh all statistics.  This is done as an explicit step
1994		 * before calculating the maximum name width, so that any
1995		 * configuration changes are properly accounted for.
1996		 */
1997		(void) pool_list_iter(list, B_FALSE, refresh_iostat, &cb);
1998
1999		/*
2000		 * Iterate over all pools to determine the maximum width
2001		 * for the pool / device name column across all pools.
2002		 */
2003		cb.cb_namewidth = 0;
2004		(void) pool_list_iter(list, B_FALSE, get_namewidth, &cb);
2005
2006		/*
2007		 * If it's the first time, or verbose mode, print the header.
2008		 */
2009		if (++cb.cb_iteration == 1 || verbose)
2010			print_iostat_header(&cb);
2011
2012		(void) pool_list_iter(list, B_FALSE, print_iostat, &cb);
2013
2014		/*
2015		 * If there's more than one pool, and we're not in verbose mode
2016		 * (which prints a separator for us), then print a separator.
2017		 */
2018		if (npools > 1 && !verbose)
2019			print_iostat_separator(&cb);
2020
2021		if (verbose)
2022			(void) printf("\n");
2023
2024		/*
2025		 * Flush the output so that redirection to a file isn't buffered
2026		 * indefinitely.
2027		 */
2028		(void) fflush(stdout);
2029
2030		if (interval == 0)
2031			break;
2032
2033		if (count != 0 && --count == 0)
2034			break;
2035
2036		(void) sleep(interval);
2037	}
2038
2039	pool_list_free(list);
2040
2041	return (ret);
2042}
2043
2044typedef struct list_cbdata {
2045	boolean_t	cb_scripted;
2046	boolean_t	cb_first;
2047	zprop_list_t	*cb_proplist;
2048} list_cbdata_t;
2049
2050/*
2051 * Given a list of columns to display, output appropriate headers for each one.
2052 */
2053static void
2054print_header(zprop_list_t *pl)
2055{
2056	const char *header;
2057	boolean_t first = B_TRUE;
2058	boolean_t right_justify;
2059
2060	for (; pl != NULL; pl = pl->pl_next) {
2061		if (pl->pl_prop == ZPROP_INVAL)
2062			continue;
2063
2064		if (!first)
2065			(void) printf("  ");
2066		else
2067			first = B_FALSE;
2068
2069		header = zpool_prop_column_name(pl->pl_prop);
2070		right_justify = zpool_prop_align_right(pl->pl_prop);
2071
2072		if (pl->pl_next == NULL && !right_justify)
2073			(void) printf("%s", header);
2074		else if (right_justify)
2075			(void) printf("%*s", pl->pl_width, header);
2076		else
2077			(void) printf("%-*s", pl->pl_width, header);
2078	}
2079
2080	(void) printf("\n");
2081}
2082
2083/*
2084 * Given a pool and a list of properties, print out all the properties according
2085 * to the described layout.
2086 */
2087static void
2088print_pool(zpool_handle_t *zhp, zprop_list_t *pl, int scripted)
2089{
2090	boolean_t first = B_TRUE;
2091	char property[ZPOOL_MAXPROPLEN];
2092	char *propstr;
2093	boolean_t right_justify;
2094	int width;
2095
2096	for (; pl != NULL; pl = pl->pl_next) {
2097		if (!first) {
2098			if (scripted)
2099				(void) printf("\t");
2100			else
2101				(void) printf("  ");
2102		} else {
2103			first = B_FALSE;
2104		}
2105
2106		right_justify = B_FALSE;
2107		if (pl->pl_prop != ZPROP_INVAL) {
2108			if (zpool_get_prop(zhp, pl->pl_prop, property,
2109			    sizeof (property), NULL) != 0)
2110				propstr = "-";
2111			else
2112				propstr = property;
2113
2114			right_justify = zpool_prop_align_right(pl->pl_prop);
2115		} else {
2116			propstr = "-";
2117		}
2118
2119		width = pl->pl_width;
2120
2121		/*
2122		 * If this is being called in scripted mode, or if this is the
2123		 * last column and it is left-justified, don't include a width
2124		 * format specifier.
2125		 */
2126		if (scripted || (pl->pl_next == NULL && !right_justify))
2127			(void) printf("%s", propstr);
2128		else if (right_justify)
2129			(void) printf("%*s", width, propstr);
2130		else
2131			(void) printf("%-*s", width, propstr);
2132	}
2133
2134	(void) printf("\n");
2135}
2136
2137/*
2138 * Generic callback function to list a pool.
2139 */
2140int
2141list_callback(zpool_handle_t *zhp, void *data)
2142{
2143	list_cbdata_t *cbp = data;
2144
2145	if (cbp->cb_first) {
2146		if (!cbp->cb_scripted)
2147			print_header(cbp->cb_proplist);
2148		cbp->cb_first = B_FALSE;
2149	}
2150
2151	print_pool(zhp, cbp->cb_proplist, cbp->cb_scripted);
2152
2153	return (0);
2154}
2155
2156/*
2157 * zpool list [-H] [-o prop[,prop]*] [pool] ...
2158 *
2159 *	-H	Scripted mode.  Don't display headers, and separate properties
2160 *		by a single tab.
2161 *	-o	List of properties to display.  Defaults to
2162 *		"name,size,used,available,capacity,health,altroot"
2163 *
2164 * List all pools in the system, whether or not they're healthy.  Output space
2165 * statistics for each one, as well as health status summary.
2166 */
2167int
2168zpool_do_list(int argc, char **argv)
2169{
2170	int c;
2171	int ret;
2172	list_cbdata_t cb = { 0 };
2173	static char default_props[] =
2174	    "name,size,used,available,capacity,health,altroot";
2175	char *props = default_props;
2176
2177	/* check options */
2178	while ((c = getopt(argc, argv, ":Ho:")) != -1) {
2179		switch (c) {
2180		case 'H':
2181			cb.cb_scripted = B_TRUE;
2182			break;
2183		case 'o':
2184			props = optarg;
2185			break;
2186		case ':':
2187			(void) fprintf(stderr, gettext("missing argument for "
2188			    "'%c' option\n"), optopt);
2189			usage(B_FALSE);
2190			break;
2191		case '?':
2192			(void) fprintf(stderr, gettext("invalid option '%c'\n"),
2193			    optopt);
2194			usage(B_FALSE);
2195		}
2196	}
2197
2198	argc -= optind;
2199	argv += optind;
2200
2201	if (zprop_get_list(g_zfs, props, &cb.cb_proplist, ZFS_TYPE_POOL) != 0)
2202		usage(B_FALSE);
2203
2204	cb.cb_first = B_TRUE;
2205
2206	ret = for_each_pool(argc, argv, B_TRUE, &cb.cb_proplist,
2207	    list_callback, &cb);
2208
2209	zprop_free_list(cb.cb_proplist);
2210
2211	if (argc == 0 && cb.cb_first && !cb.cb_scripted) {
2212		(void) printf(gettext("no pools available\n"));
2213		return (0);
2214	}
2215
2216	return (ret);
2217}
2218
2219static nvlist_t *
2220zpool_get_vdev_by_name(nvlist_t *nv, char *name)
2221{
2222	nvlist_t **child;
2223	uint_t c, children;
2224	nvlist_t *match;
2225	char *path;
2226
2227	if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
2228	    &child, &children) != 0) {
2229		verify(nvlist_lookup_string(nv, ZPOOL_CONFIG_PATH, &path) == 0);
2230		if (strncmp(name, _PATH_DEV, sizeof(_PATH_DEV)-1) == 0)
2231			name += sizeof(_PATH_DEV)-1;
2232		if (strncmp(path, _PATH_DEV, sizeof(_PATH_DEV)-1) == 0)
2233			path += sizeof(_PATH_DEV)-1;
2234		if (strcmp(name, path) == 0)
2235			return (nv);
2236		return (NULL);
2237	}
2238
2239	for (c = 0; c < children; c++)
2240		if ((match = zpool_get_vdev_by_name(child[c], name)) != NULL)
2241			return (match);
2242
2243	return (NULL);
2244}
2245
2246static int
2247zpool_do_attach_or_replace(int argc, char **argv, int replacing)
2248{
2249	boolean_t force = B_FALSE;
2250	int c;
2251	nvlist_t *nvroot;
2252	char *poolname, *old_disk, *new_disk;
2253	zpool_handle_t *zhp;
2254	int ret;
2255
2256	/* check options */
2257	while ((c = getopt(argc, argv, "f")) != -1) {
2258		switch (c) {
2259		case 'f':
2260			force = B_TRUE;
2261			break;
2262		case '?':
2263			(void) fprintf(stderr, gettext("invalid option '%c'\n"),
2264			    optopt);
2265			usage(B_FALSE);
2266		}
2267	}
2268
2269	argc -= optind;
2270	argv += optind;
2271
2272	/* get pool name and check number of arguments */
2273	if (argc < 1) {
2274		(void) fprintf(stderr, gettext("missing pool name argument\n"));
2275		usage(B_FALSE);
2276	}
2277
2278	poolname = argv[0];
2279
2280	if (argc < 2) {
2281		(void) fprintf(stderr,
2282		    gettext("missing <device> specification\n"));
2283		usage(B_FALSE);
2284	}
2285
2286	old_disk = argv[1];
2287
2288	if (argc < 3) {
2289		if (!replacing) {
2290			(void) fprintf(stderr,
2291			    gettext("missing <new_device> specification\n"));
2292			usage(B_FALSE);
2293		}
2294		new_disk = old_disk;
2295		argc -= 1;
2296		argv += 1;
2297	} else {
2298		new_disk = argv[2];
2299		argc -= 2;
2300		argv += 2;
2301	}
2302
2303	if (argc > 1) {
2304		(void) fprintf(stderr, gettext("too many arguments\n"));
2305		usage(B_FALSE);
2306	}
2307
2308	if ((zhp = zpool_open(g_zfs, poolname)) == NULL)
2309		return (1);
2310
2311	if (zpool_get_config(zhp, NULL) == NULL) {
2312		(void) fprintf(stderr, gettext("pool '%s' is unavailable\n"),
2313		    poolname);
2314		zpool_close(zhp);
2315		return (1);
2316	}
2317
2318	nvroot = make_root_vdev(zhp, force, B_FALSE, replacing, B_FALSE,
2319	    argc, argv);
2320	if (nvroot == NULL) {
2321		zpool_close(zhp);
2322		return (1);
2323	}
2324
2325	ret = zpool_vdev_attach(zhp, old_disk, new_disk, nvroot, replacing);
2326
2327	nvlist_free(nvroot);
2328	zpool_close(zhp);
2329
2330	return (ret);
2331}
2332
2333/*
2334 * zpool replace [-f] <pool> <device> <new_device>
2335 *
2336 *	-f	Force attach, even if <new_device> appears to be in use.
2337 *
2338 * Replace <device> with <new_device>.
2339 */
2340/* ARGSUSED */
2341int
2342zpool_do_replace(int argc, char **argv)
2343{
2344	return (zpool_do_attach_or_replace(argc, argv, B_TRUE));
2345}
2346
2347/*
2348 * zpool attach [-f] <pool> <device> <new_device>
2349 *
2350 *	-f	Force attach, even if <new_device> appears to be in use.
2351 *
2352 * Attach <new_device> to the mirror containing <device>.  If <device> is not
2353 * part of a mirror, then <device> will be transformed into a mirror of
2354 * <device> and <new_device>.  In either case, <new_device> will begin life
2355 * with a DTL of [0, now], and will immediately begin to resilver itself.
2356 */
2357int
2358zpool_do_attach(int argc, char **argv)
2359{
2360	return (zpool_do_attach_or_replace(argc, argv, B_FALSE));
2361}
2362
2363/*
2364 * zpool detach [-f] <pool> <device>
2365 *
2366 *	-f	Force detach of <device>, even if DTLs argue against it
2367 *		(not supported yet)
2368 *
2369 * Detach a device from a mirror.  The operation will be refused if <device>
2370 * is the last device in the mirror, or if the DTLs indicate that this device
2371 * has the only valid copy of some data.
2372 */
2373/* ARGSUSED */
2374int
2375zpool_do_detach(int argc, char **argv)
2376{
2377	int c;
2378	char *poolname, *path;
2379	zpool_handle_t *zhp;
2380	int ret;
2381
2382	/* check options */
2383	while ((c = getopt(argc, argv, "f")) != -1) {
2384		switch (c) {
2385		case 'f':
2386		case '?':
2387			(void) fprintf(stderr, gettext("invalid option '%c'\n"),
2388			    optopt);
2389			usage(B_FALSE);
2390		}
2391	}
2392
2393	argc -= optind;
2394	argv += optind;
2395
2396	/* get pool name and check number of arguments */
2397	if (argc < 1) {
2398		(void) fprintf(stderr, gettext("missing pool name argument\n"));
2399		usage(B_FALSE);
2400	}
2401
2402	if (argc < 2) {
2403		(void) fprintf(stderr,
2404		    gettext("missing <device> specification\n"));
2405		usage(B_FALSE);
2406	}
2407
2408	poolname = argv[0];
2409	path = argv[1];
2410
2411	if ((zhp = zpool_open(g_zfs, poolname)) == NULL)
2412		return (1);
2413
2414	ret = zpool_vdev_detach(zhp, path);
2415
2416	zpool_close(zhp);
2417
2418	return (ret);
2419}
2420
2421/*
2422 * zpool online <pool> <device> ...
2423 */
2424int
2425zpool_do_online(int argc, char **argv)
2426{
2427	int c, i;
2428	char *poolname;
2429	zpool_handle_t *zhp;
2430	int ret = 0;
2431	vdev_state_t newstate;
2432
2433	/* check options */
2434	while ((c = getopt(argc, argv, "t")) != -1) {
2435		switch (c) {
2436		case 't':
2437		case '?':
2438			(void) fprintf(stderr, gettext("invalid option '%c'\n"),
2439			    optopt);
2440			usage(B_FALSE);
2441		}
2442	}
2443
2444	argc -= optind;
2445	argv += optind;
2446
2447	/* get pool name and check number of arguments */
2448	if (argc < 1) {
2449		(void) fprintf(stderr, gettext("missing pool name\n"));
2450		usage(B_FALSE);
2451	}
2452	if (argc < 2) {
2453		(void) fprintf(stderr, gettext("missing device name\n"));
2454		usage(B_FALSE);
2455	}
2456
2457	poolname = argv[0];
2458
2459	if ((zhp = zpool_open(g_zfs, poolname)) == NULL)
2460		return (1);
2461
2462	for (i = 1; i < argc; i++) {
2463		if (zpool_vdev_online(zhp, argv[i], 0, &newstate) == 0) {
2464			if (newstate != VDEV_STATE_HEALTHY) {
2465				(void) printf(gettext("warning: device '%s' "
2466				    "onlined, but remains in faulted state\n"),
2467				    argv[i]);
2468				if (newstate == VDEV_STATE_FAULTED)
2469					(void) printf(gettext("use 'zpool "
2470					    "clear' to restore a faulted "
2471					    "device\n"));
2472				else
2473					(void) printf(gettext("use 'zpool "
2474					    "replace' to replace devices "
2475					    "that are no longer present\n"));
2476			}
2477		} else {
2478			ret = 1;
2479		}
2480	}
2481
2482	zpool_close(zhp);
2483
2484	return (ret);
2485}
2486
2487/*
2488 * zpool offline [-ft] <pool> <device> ...
2489 *
2490 *	-f	Force the device into the offline state, even if doing
2491 *		so would appear to compromise pool availability.
2492 *		(not supported yet)
2493 *
2494 *	-t	Only take the device off-line temporarily.  The offline
2495 *		state will not be persistent across reboots.
2496 */
2497/* ARGSUSED */
2498int
2499zpool_do_offline(int argc, char **argv)
2500{
2501	int c, i;
2502	char *poolname;
2503	zpool_handle_t *zhp;
2504	int ret = 0;
2505	boolean_t istmp = B_FALSE;
2506
2507	/* check options */
2508	while ((c = getopt(argc, argv, "ft")) != -1) {
2509		switch (c) {
2510		case 't':
2511			istmp = B_TRUE;
2512			break;
2513		case 'f':
2514		case '?':
2515			(void) fprintf(stderr, gettext("invalid option '%c'\n"),
2516			    optopt);
2517			usage(B_FALSE);
2518		}
2519	}
2520
2521	argc -= optind;
2522	argv += optind;
2523
2524	/* get pool name and check number of arguments */
2525	if (argc < 1) {
2526		(void) fprintf(stderr, gettext("missing pool name\n"));
2527		usage(B_FALSE);
2528	}
2529	if (argc < 2) {
2530		(void) fprintf(stderr, gettext("missing device name\n"));
2531		usage(B_FALSE);
2532	}
2533
2534	poolname = argv[0];
2535
2536	if ((zhp = zpool_open(g_zfs, poolname)) == NULL)
2537		return (1);
2538
2539	for (i = 1; i < argc; i++) {
2540		if (zpool_vdev_offline(zhp, argv[i], istmp) != 0)
2541			ret = 1;
2542	}
2543
2544	zpool_close(zhp);
2545
2546	return (ret);
2547}
2548
2549/*
2550 * zpool clear <pool> [device]
2551 *
2552 * Clear all errors associated with a pool or a particular device.
2553 */
2554int
2555zpool_do_clear(int argc, char **argv)
2556{
2557	int ret = 0;
2558	zpool_handle_t *zhp;
2559	char *pool, *device;
2560
2561	if (argc < 2) {
2562		(void) fprintf(stderr, gettext("missing pool name\n"));
2563		usage(B_FALSE);
2564	}
2565
2566	if (argc > 3) {
2567		(void) fprintf(stderr, gettext("too many arguments\n"));
2568		usage(B_FALSE);
2569	}
2570
2571	pool = argv[1];
2572	device = argc == 3 ? argv[2] : NULL;
2573
2574	if ((zhp = zpool_open_canfail(g_zfs, pool)) == NULL)
2575		return (1);
2576
2577	if (zpool_clear(zhp, device) != 0)
2578		ret = 1;
2579
2580	zpool_close(zhp);
2581
2582	return (ret);
2583}
2584
2585typedef struct scrub_cbdata {
2586	int	cb_type;
2587	int	cb_argc;
2588	char	**cb_argv;
2589} scrub_cbdata_t;
2590
2591int
2592scrub_callback(zpool_handle_t *zhp, void *data)
2593{
2594	scrub_cbdata_t *cb = data;
2595	int err;
2596
2597	/*
2598	 * Ignore faulted pools.
2599	 */
2600	if (zpool_get_state(zhp) == POOL_STATE_UNAVAIL) {
2601		(void) fprintf(stderr, gettext("cannot scrub '%s': pool is "
2602		    "currently unavailable\n"), zpool_get_name(zhp));
2603		return (1);
2604	}
2605
2606	err = zpool_scrub(zhp, cb->cb_type);
2607
2608	return (err != 0);
2609}
2610
2611/*
2612 * zpool scrub [-s] <pool> ...
2613 *
2614 *	-s	Stop.  Stops any in-progress scrub.
2615 */
2616int
2617zpool_do_scrub(int argc, char **argv)
2618{
2619	int c;
2620	scrub_cbdata_t cb;
2621
2622	cb.cb_type = POOL_SCRUB_EVERYTHING;
2623
2624	/* check options */
2625	while ((c = getopt(argc, argv, "s")) != -1) {
2626		switch (c) {
2627		case 's':
2628			cb.cb_type = POOL_SCRUB_NONE;
2629			break;
2630		case '?':
2631			(void) fprintf(stderr, gettext("invalid option '%c'\n"),
2632			    optopt);
2633			usage(B_FALSE);
2634		}
2635	}
2636
2637	cb.cb_argc = argc;
2638	cb.cb_argv = argv;
2639	argc -= optind;
2640	argv += optind;
2641
2642	if (argc < 1) {
2643		(void) fprintf(stderr, gettext("missing pool name argument\n"));
2644		usage(B_FALSE);
2645	}
2646
2647	return (for_each_pool(argc, argv, B_TRUE, NULL, scrub_callback, &cb));
2648}
2649
2650typedef struct status_cbdata {
2651	int		cb_count;
2652	boolean_t	cb_allpools;
2653	boolean_t	cb_verbose;
2654	boolean_t	cb_explain;
2655	boolean_t	cb_first;
2656} status_cbdata_t;
2657
2658/*
2659 * Print out detailed scrub status.
2660 */
2661void
2662print_scrub_status(nvlist_t *nvroot)
2663{
2664	vdev_stat_t *vs;
2665	uint_t vsc;
2666	time_t start, end, now;
2667	double fraction_done;
2668	uint64_t examined, total, minutes_left, minutes_taken;
2669	char *scrub_type;
2670
2671	verify(nvlist_lookup_uint64_array(nvroot, ZPOOL_CONFIG_STATS,
2672	    (uint64_t **)&vs, &vsc) == 0);
2673
2674	/*
2675	 * If there's never been a scrub, there's not much to say.
2676	 */
2677	if (vs->vs_scrub_end == 0 && vs->vs_scrub_type == POOL_SCRUB_NONE) {
2678		(void) printf(gettext("none requested\n"));
2679		return;
2680	}
2681
2682	scrub_type = (vs->vs_scrub_type == POOL_SCRUB_RESILVER) ?
2683	    "resilver" : "scrub";
2684
2685	start = vs->vs_scrub_start;
2686	end = vs->vs_scrub_end;
2687	now = time(NULL);
2688	examined = vs->vs_scrub_examined;
2689	total = vs->vs_alloc;
2690
2691	if (end != 0) {
2692		minutes_taken = (uint64_t)((end - start) / 60);
2693
2694		(void) printf(gettext("%s %s after %lluh%um with %llu errors "
2695		    "on %s"),
2696		    scrub_type, vs->vs_scrub_complete ? "completed" : "stopped",
2697		    (u_longlong_t)(minutes_taken / 60),
2698		    (uint_t)(minutes_taken % 60),
2699		    (u_longlong_t)vs->vs_scrub_errors, ctime(&end));
2700		return;
2701	}
2702
2703	if (examined == 0)
2704		examined = 1;
2705	if (examined > total)
2706		total = examined;
2707
2708	fraction_done = (double)examined / total;
2709	minutes_left = (uint64_t)((now - start) *
2710	    (1 - fraction_done) / fraction_done / 60);
2711	minutes_taken = (uint64_t)((now - start) / 60);
2712
2713	(void) printf(gettext("%s in progress for %lluh%um, %.2f%% done, "
2714	    "%lluh%um to go\n"),
2715	    scrub_type, (u_longlong_t)(minutes_taken / 60),
2716	    (uint_t)(minutes_taken % 60), 100 * fraction_done,
2717	    (u_longlong_t)(minutes_left / 60), (uint_t)(minutes_left % 60));
2718}
2719
2720typedef struct spare_cbdata {
2721	uint64_t	cb_guid;
2722	zpool_handle_t	*cb_zhp;
2723} spare_cbdata_t;
2724
2725static boolean_t
2726find_vdev(nvlist_t *nv, uint64_t search)
2727{
2728	uint64_t guid;
2729	nvlist_t **child;
2730	uint_t c, children;
2731
2732	if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_GUID, &guid) == 0 &&
2733	    search == guid)
2734		return (B_TRUE);
2735
2736	if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
2737	    &child, &children) == 0) {
2738		for (c = 0; c < children; c++)
2739			if (find_vdev(child[c], search))
2740				return (B_TRUE);
2741	}
2742
2743	return (B_FALSE);
2744}
2745
2746static int
2747find_spare(zpool_handle_t *zhp, void *data)
2748{
2749	spare_cbdata_t *cbp = data;
2750	nvlist_t *config, *nvroot;
2751
2752	config = zpool_get_config(zhp, NULL);
2753	verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
2754	    &nvroot) == 0);
2755
2756	if (find_vdev(nvroot, cbp->cb_guid)) {
2757		cbp->cb_zhp = zhp;
2758		return (1);
2759	}
2760
2761	zpool_close(zhp);
2762	return (0);
2763}
2764
2765/*
2766 * Print out configuration state as requested by status_callback.
2767 */
2768void
2769print_status_config(zpool_handle_t *zhp, const char *name, nvlist_t *nv,
2770    int namewidth, int depth, boolean_t isspare)
2771{
2772	nvlist_t **child;
2773	uint_t c, children;
2774	vdev_stat_t *vs;
2775	char rbuf[6], wbuf[6], cbuf[6], repaired[7];
2776	char *vname;
2777	uint64_t notpresent;
2778	spare_cbdata_t cb;
2779	char *state;
2780
2781	verify(nvlist_lookup_uint64_array(nv, ZPOOL_CONFIG_STATS,
2782	    (uint64_t **)&vs, &c) == 0);
2783
2784	if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
2785	    &child, &children) != 0)
2786		children = 0;
2787
2788	state = zpool_state_to_name(vs->vs_state, vs->vs_aux);
2789	if (isspare) {
2790		/*
2791		 * For hot spares, we use the terms 'INUSE' and 'AVAILABLE' for
2792		 * online drives.
2793		 */
2794		if (vs->vs_aux == VDEV_AUX_SPARED)
2795			state = "INUSE";
2796		else if (vs->vs_state == VDEV_STATE_HEALTHY)
2797			state = "AVAIL";
2798	}
2799
2800	(void) printf("\t%*s%-*s  %-8s", depth, "", namewidth - depth,
2801	    name, state);
2802
2803	if (!isspare) {
2804		zfs_nicenum(vs->vs_read_errors, rbuf, sizeof (rbuf));
2805		zfs_nicenum(vs->vs_write_errors, wbuf, sizeof (wbuf));
2806		zfs_nicenum(vs->vs_checksum_errors, cbuf, sizeof (cbuf));
2807		(void) printf(" %5s %5s %5s", rbuf, wbuf, cbuf);
2808	}
2809
2810	if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_NOT_PRESENT,
2811	    &notpresent) == 0) {
2812		char *path;
2813		verify(nvlist_lookup_string(nv, ZPOOL_CONFIG_PATH, &path) == 0);
2814		(void) printf("  was %s", path);
2815	} else if (vs->vs_aux != 0) {
2816		(void) printf("  ");
2817
2818		switch (vs->vs_aux) {
2819		case VDEV_AUX_OPEN_FAILED:
2820			(void) printf(gettext("cannot open"));
2821			break;
2822
2823		case VDEV_AUX_BAD_GUID_SUM:
2824			(void) printf(gettext("missing device"));
2825			break;
2826
2827		case VDEV_AUX_NO_REPLICAS:
2828			(void) printf(gettext("insufficient replicas"));
2829			break;
2830
2831		case VDEV_AUX_VERSION_NEWER:
2832			(void) printf(gettext("newer version"));
2833			break;
2834
2835		case VDEV_AUX_SPARED:
2836			verify(nvlist_lookup_uint64(nv, ZPOOL_CONFIG_GUID,
2837			    &cb.cb_guid) == 0);
2838			if (zpool_iter(g_zfs, find_spare, &cb) == 1) {
2839				if (strcmp(zpool_get_name(cb.cb_zhp),
2840				    zpool_get_name(zhp)) == 0)
2841					(void) printf(gettext("currently in "
2842					    "use"));
2843				else
2844					(void) printf(gettext("in use by "
2845					    "pool '%s'"),
2846					    zpool_get_name(cb.cb_zhp));
2847				zpool_close(cb.cb_zhp);
2848			} else {
2849				(void) printf(gettext("currently in use"));
2850			}
2851			break;
2852
2853		case VDEV_AUX_ERR_EXCEEDED:
2854			(void) printf(gettext("too many errors"));
2855			break;
2856
2857		case VDEV_AUX_IO_FAILURE:
2858			(void) printf(gettext("experienced I/O failures"));
2859			break;
2860
2861		case VDEV_AUX_BAD_LOG:
2862			(void) printf(gettext("bad intent log"));
2863			break;
2864
2865		default:
2866			(void) printf(gettext("corrupted data"));
2867			break;
2868		}
2869	} else if (vs->vs_scrub_repaired != 0 && children == 0) {
2870		/*
2871		 * Report bytes resilvered/repaired on leaf devices.
2872		 */
2873		zfs_nicenum(vs->vs_scrub_repaired, repaired, sizeof (repaired));
2874		(void) printf(gettext("  %s %s"), repaired,
2875		    (vs->vs_scrub_type == POOL_SCRUB_RESILVER) ?
2876		    "resilvered" : "repaired");
2877	}
2878
2879	(void) printf("\n");
2880
2881	for (c = 0; c < children; c++) {
2882		uint64_t is_log = B_FALSE;
2883
2884		/* Don't print logs here */
2885		(void) nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_LOG,
2886		    &is_log);
2887		if (is_log)
2888			continue;
2889		vname = zpool_vdev_name(g_zfs, zhp, child[c]);
2890		print_status_config(zhp, vname, child[c],
2891		    namewidth, depth + 2, isspare);
2892		free(vname);
2893	}
2894}
2895
2896static void
2897print_error_log(zpool_handle_t *zhp)
2898{
2899	nvlist_t *nverrlist = NULL;
2900	nvpair_t *elem;
2901	char *pathname;
2902	size_t len = MAXPATHLEN * 2;
2903
2904	if (zpool_get_errlog(zhp, &nverrlist) != 0) {
2905		(void) printf("errors: List of errors unavailable "
2906		    "(insufficient privileges)\n");
2907		return;
2908	}
2909
2910	(void) printf("errors: Permanent errors have been "
2911	    "detected in the following files:\n\n");
2912
2913	pathname = safe_malloc(len);
2914	elem = NULL;
2915	while ((elem = nvlist_next_nvpair(nverrlist, elem)) != NULL) {
2916		nvlist_t *nv;
2917		uint64_t dsobj, obj;
2918
2919		verify(nvpair_value_nvlist(elem, &nv) == 0);
2920		verify(nvlist_lookup_uint64(nv, ZPOOL_ERR_DATASET,
2921		    &dsobj) == 0);
2922		verify(nvlist_lookup_uint64(nv, ZPOOL_ERR_OBJECT,
2923		    &obj) == 0);
2924		zpool_obj_to_path(zhp, dsobj, obj, pathname, len);
2925		(void) printf("%7s %s\n", "", pathname);
2926	}
2927	free(pathname);
2928	nvlist_free(nverrlist);
2929}
2930
2931static void
2932print_spares(zpool_handle_t *zhp, nvlist_t **spares, uint_t nspares,
2933    int namewidth)
2934{
2935	uint_t i;
2936	char *name;
2937
2938	if (nspares == 0)
2939		return;
2940
2941	(void) printf(gettext("\tspares\n"));
2942
2943	for (i = 0; i < nspares; i++) {
2944		name = zpool_vdev_name(g_zfs, zhp, spares[i]);
2945		print_status_config(zhp, name, spares[i],
2946		    namewidth, 2, B_TRUE);
2947		free(name);
2948	}
2949}
2950
2951static void
2952print_l2cache(zpool_handle_t *zhp, nvlist_t **l2cache, uint_t nl2cache,
2953    int namewidth)
2954{
2955	uint_t i;
2956	char *name;
2957
2958	if (nl2cache == 0)
2959		return;
2960
2961	(void) printf(gettext("\tcache\n"));
2962
2963	for (i = 0; i < nl2cache; i++) {
2964		name = zpool_vdev_name(g_zfs, zhp, l2cache[i]);
2965		print_status_config(zhp, name, l2cache[i],
2966		    namewidth, 2, B_FALSE);
2967		free(name);
2968	}
2969}
2970
2971/*
2972 * Print log vdevs.
2973 * Logs are recorded as top level vdevs in the main pool child array but with
2974 * "is_log" set to 1. We use print_status_config() to print the top level logs
2975 * then any log children (eg mirrored slogs) are printed recursively - which
2976 * works because only the top level vdev is marked "is_log"
2977 */
2978static void
2979print_logs(zpool_handle_t *zhp, nvlist_t *nv, int namewidth)
2980{
2981	uint_t c, children;
2982	nvlist_t **child;
2983
2984	if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN, &child,
2985	    &children) != 0)
2986		return;
2987
2988	(void) printf(gettext("\tlogs\n"));
2989
2990	for (c = 0; c < children; c++) {
2991		uint64_t is_log = B_FALSE;
2992		char *name;
2993
2994		(void) nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_LOG,
2995		    &is_log);
2996		if (!is_log)
2997			continue;
2998		name = zpool_vdev_name(g_zfs, zhp, child[c]);
2999		print_status_config(zhp, name, child[c], namewidth, 2, B_FALSE);
3000		free(name);
3001	}
3002}
3003
3004/*
3005 * Display a summary of pool status.  Displays a summary such as:
3006 *
3007 *        pool: tank
3008 *	status: DEGRADED
3009 *	reason: One or more devices ...
3010 *         see: http://www.sun.com/msg/ZFS-xxxx-01
3011 *	config:
3012 *		mirror		DEGRADED
3013 *                c1t0d0	OK
3014 *                c2t0d0	UNAVAIL
3015 *
3016 * When given the '-v' option, we print out the complete config.  If the '-e'
3017 * option is specified, then we print out error rate information as well.
3018 */
3019int
3020status_callback(zpool_handle_t *zhp, void *data)
3021{
3022	status_cbdata_t *cbp = data;
3023	nvlist_t *config, *nvroot;
3024	char *msgid;
3025	int reason;
3026	const char *health;
3027	uint_t c;
3028	vdev_stat_t *vs;
3029
3030	config = zpool_get_config(zhp, NULL);
3031	reason = zpool_get_status(zhp, &msgid);
3032
3033	cbp->cb_count++;
3034
3035	/*
3036	 * If we were given 'zpool status -x', only report those pools with
3037	 * problems.
3038	 */
3039	if (reason == ZPOOL_STATUS_OK && cbp->cb_explain) {
3040		if (!cbp->cb_allpools) {
3041			(void) printf(gettext("pool '%s' is healthy\n"),
3042			    zpool_get_name(zhp));
3043			if (cbp->cb_first)
3044				cbp->cb_first = B_FALSE;
3045		}
3046		return (0);
3047	}
3048
3049	if (cbp->cb_first)
3050		cbp->cb_first = B_FALSE;
3051	else
3052		(void) printf("\n");
3053
3054	verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
3055	    &nvroot) == 0);
3056	verify(nvlist_lookup_uint64_array(nvroot, ZPOOL_CONFIG_STATS,
3057	    (uint64_t **)&vs, &c) == 0);
3058	health = zpool_state_to_name(vs->vs_state, vs->vs_aux);
3059
3060	(void) printf(gettext("  pool: %s\n"), zpool_get_name(zhp));
3061	(void) printf(gettext(" state: %s\n"), health);
3062
3063	switch (reason) {
3064	case ZPOOL_STATUS_MISSING_DEV_R:
3065		(void) printf(gettext("status: One or more devices could not "
3066		    "be opened.  Sufficient replicas exist for\n\tthe pool to "
3067		    "continue functioning in a degraded state.\n"));
3068		(void) printf(gettext("action: Attach the missing device and "
3069		    "online it using 'zpool online'.\n"));
3070		break;
3071
3072	case ZPOOL_STATUS_MISSING_DEV_NR:
3073		(void) printf(gettext("status: One or more devices could not "
3074		    "be opened.  There are insufficient\n\treplicas for the "
3075		    "pool to continue functioning.\n"));
3076		(void) printf(gettext("action: Attach the missing device and "
3077		    "online it using 'zpool online'.\n"));
3078		break;
3079
3080	case ZPOOL_STATUS_CORRUPT_LABEL_R:
3081		(void) printf(gettext("status: One or more devices could not "
3082		    "be used because the label is missing or\n\tinvalid.  "
3083		    "Sufficient replicas exist for the pool to continue\n\t"
3084		    "functioning in a degraded state.\n"));
3085		(void) printf(gettext("action: Replace the device using "
3086		    "'zpool replace'.\n"));
3087		break;
3088
3089	case ZPOOL_STATUS_CORRUPT_LABEL_NR:
3090		(void) printf(gettext("status: One or more devices could not "
3091		    "be used because the label is missing \n\tor invalid.  "
3092		    "There are insufficient replicas for the pool to "
3093		    "continue\n\tfunctioning.\n"));
3094		(void) printf(gettext("action: Destroy and re-create the pool "
3095		    "from a backup source.\n"));
3096		break;
3097
3098	case ZPOOL_STATUS_FAILING_DEV:
3099		(void) printf(gettext("status: One or more devices has "
3100		    "experienced an unrecoverable error.  An\n\tattempt was "
3101		    "made to correct the error.  Applications are "
3102		    "unaffected.\n"));
3103		(void) printf(gettext("action: Determine if the device needs "
3104		    "to be replaced, and clear the errors\n\tusing "
3105		    "'zpool clear' or replace the device with 'zpool "
3106		    "replace'.\n"));
3107		break;
3108
3109	case ZPOOL_STATUS_OFFLINE_DEV:
3110		(void) printf(gettext("status: One or more devices has "
3111		    "been taken offline by the administrator.\n\tSufficient "
3112		    "replicas exist for the pool to continue functioning in "
3113		    "a\n\tdegraded state.\n"));
3114		(void) printf(gettext("action: Online the device using "
3115		    "'zpool online' or replace the device with\n\t'zpool "
3116		    "replace'.\n"));
3117		break;
3118
3119	case ZPOOL_STATUS_RESILVERING:
3120		(void) printf(gettext("status: One or more devices is "
3121		    "currently being resilvered.  The pool will\n\tcontinue "
3122		    "to function, possibly in a degraded state.\n"));
3123		(void) printf(gettext("action: Wait for the resilver to "
3124		    "complete.\n"));
3125		break;
3126
3127	case ZPOOL_STATUS_CORRUPT_DATA:
3128		(void) printf(gettext("status: One or more devices has "
3129		    "experienced an error resulting in data\n\tcorruption.  "
3130		    "Applications may be affected.\n"));
3131		(void) printf(gettext("action: Restore the file in question "
3132		    "if possible.  Otherwise restore the\n\tentire pool from "
3133		    "backup.\n"));
3134		break;
3135
3136	case ZPOOL_STATUS_CORRUPT_POOL:
3137		(void) printf(gettext("status: The pool metadata is corrupted "
3138		    "and the pool cannot be opened.\n"));
3139		(void) printf(gettext("action: Destroy and re-create the pool "
3140		    "from a backup source.\n"));
3141		break;
3142
3143	case ZPOOL_STATUS_VERSION_OLDER:
3144		(void) printf(gettext("status: The pool is formatted using an "
3145		    "older on-disk format.  The pool can\n\tstill be used, but "
3146		    "some features are unavailable.\n"));
3147		(void) printf(gettext("action: Upgrade the pool using 'zpool "
3148		    "upgrade'.  Once this is done, the\n\tpool will no longer "
3149		    "be accessible on older software versions.\n"));
3150		break;
3151
3152	case ZPOOL_STATUS_VERSION_NEWER:
3153		(void) printf(gettext("status: The pool has been upgraded to a "
3154		    "newer, incompatible on-disk version.\n\tThe pool cannot "
3155		    "be accessed on this system.\n"));
3156		(void) printf(gettext("action: Access the pool from a system "
3157		    "running more recent software, or\n\trestore the pool from "
3158		    "backup.\n"));
3159		break;
3160
3161	case ZPOOL_STATUS_FAULTED_DEV_R:
3162		(void) printf(gettext("status: One or more devices are "
3163		    "faulted in response to persistent errors.\n\tSufficient "
3164		    "replicas exist for the pool to continue functioning "
3165		    "in a\n\tdegraded state.\n"));
3166		(void) printf(gettext("action: Replace the faulted device, "
3167		    "or use 'zpool clear' to mark the device\n\trepaired.\n"));
3168		break;
3169
3170	case ZPOOL_STATUS_FAULTED_DEV_NR:
3171		(void) printf(gettext("status: One or more devices are "
3172		    "faulted in response to persistent errors.  There are "
3173		    "insufficient replicas for the pool to\n\tcontinue "
3174		    "functioning.\n"));
3175		(void) printf(gettext("action: Destroy and re-create the pool "
3176		    "from a backup source.  Manually marking the device\n"
3177		    "\trepaired using 'zpool clear' may allow some data "
3178		    "to be recovered.\n"));
3179		break;
3180
3181	case ZPOOL_STATUS_IO_FAILURE_WAIT:
3182	case ZPOOL_STATUS_IO_FAILURE_CONTINUE:
3183		(void) printf(gettext("status: One or more devices are "
3184		    "faulted in response to IO failures.\n"));
3185		(void) printf(gettext("action: Make sure the affected devices "
3186		    "are connected, then run 'zpool clear'.\n"));
3187		break;
3188
3189	case ZPOOL_STATUS_BAD_LOG:
3190		(void) printf(gettext("status: An intent log record "
3191		    "could not be read.\n"
3192		    "\tWaiting for adminstrator intervention to fix the "
3193		    "faulted pool.\n"));
3194		(void) printf(gettext("action: Either restore the affected "
3195		    "device(s) and run 'zpool online',\n"
3196		    "\tor ignore the intent log records by running "
3197		    "'zpool clear'.\n"));
3198		break;
3199
3200	default:
3201		/*
3202		 * The remaining errors can't actually be generated, yet.
3203		 */
3204		assert(reason == ZPOOL_STATUS_OK);
3205	}
3206
3207	if (msgid != NULL)
3208		(void) printf(gettext("   see: http://www.sun.com/msg/%s\n"),
3209		    msgid);
3210
3211	if (config != NULL) {
3212		int namewidth;
3213		uint64_t nerr;
3214		nvlist_t **spares, **l2cache;
3215		uint_t nspares, nl2cache;
3216
3217
3218		(void) printf(gettext(" scrub: "));
3219		print_scrub_status(nvroot);
3220
3221		namewidth = max_width(zhp, nvroot, 0, 0);
3222		if (namewidth < 10)
3223			namewidth = 10;
3224
3225		(void) printf(gettext("config:\n\n"));
3226		(void) printf(gettext("\t%-*s  %-8s %5s %5s %5s\n"), namewidth,
3227		    "NAME", "STATE", "READ", "WRITE", "CKSUM");
3228		print_status_config(zhp, zpool_get_name(zhp), nvroot,
3229		    namewidth, 0, B_FALSE);
3230
3231		if (num_logs(nvroot) > 0)
3232			print_logs(zhp, nvroot, namewidth);
3233		if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_L2CACHE,
3234		    &l2cache, &nl2cache) == 0)
3235			print_l2cache(zhp, l2cache, nl2cache, namewidth);
3236
3237		if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_SPARES,
3238		    &spares, &nspares) == 0)
3239			print_spares(zhp, spares, nspares, namewidth);
3240
3241		if (nvlist_lookup_uint64(config, ZPOOL_CONFIG_ERRCOUNT,
3242		    &nerr) == 0) {
3243			nvlist_t *nverrlist = NULL;
3244
3245			/*
3246			 * If the approximate error count is small, get a
3247			 * precise count by fetching the entire log and
3248			 * uniquifying the results.
3249			 */
3250			if (nerr > 0 && nerr < 100 && !cbp->cb_verbose &&
3251			    zpool_get_errlog(zhp, &nverrlist) == 0) {
3252				nvpair_t *elem;
3253
3254				elem = NULL;
3255				nerr = 0;
3256				while ((elem = nvlist_next_nvpair(nverrlist,
3257				    elem)) != NULL) {
3258					nerr++;
3259				}
3260			}
3261			nvlist_free(nverrlist);
3262
3263			(void) printf("\n");
3264
3265			if (nerr == 0)
3266				(void) printf(gettext("errors: No known data "
3267				    "errors\n"));
3268			else if (!cbp->cb_verbose)
3269				(void) printf(gettext("errors: %llu data "
3270				    "errors, use '-v' for a list\n"),
3271				    (u_longlong_t)nerr);
3272			else
3273				print_error_log(zhp);
3274		}
3275	} else {
3276		(void) printf(gettext("config: The configuration cannot be "
3277		    "determined.\n"));
3278	}
3279
3280	return (0);
3281}
3282
3283/*
3284 * zpool status [-vx] [pool] ...
3285 *
3286 *	-v	Display complete error logs
3287 *	-x	Display only pools with potential problems
3288 *
3289 * Describes the health status of all pools or some subset.
3290 */
3291int
3292zpool_do_status(int argc, char **argv)
3293{
3294	int c;
3295	int ret;
3296	status_cbdata_t cb = { 0 };
3297
3298	/* check options */
3299	while ((c = getopt(argc, argv, "vx")) != -1) {
3300		switch (c) {
3301		case 'v':
3302			cb.cb_verbose = B_TRUE;
3303			break;
3304		case 'x':
3305			cb.cb_explain = B_TRUE;
3306			break;
3307		case '?':
3308			(void) fprintf(stderr, gettext("invalid option '%c'\n"),
3309			    optopt);
3310			usage(B_FALSE);
3311		}
3312	}
3313
3314	argc -= optind;
3315	argv += optind;
3316
3317	cb.cb_first = B_TRUE;
3318
3319	if (argc == 0)
3320		cb.cb_allpools = B_TRUE;
3321
3322	ret = for_each_pool(argc, argv, B_TRUE, NULL, status_callback, &cb);
3323
3324	if (argc == 0 && cb.cb_count == 0)
3325		(void) printf(gettext("no pools available\n"));
3326	else if (cb.cb_explain && cb.cb_first && cb.cb_allpools)
3327		(void) printf(gettext("all pools are healthy\n"));
3328
3329	return (ret);
3330}
3331
3332typedef struct upgrade_cbdata {
3333	int	cb_all;
3334	int	cb_first;
3335	int	cb_newer;
3336	int	cb_argc;
3337	uint64_t cb_version;
3338	char	**cb_argv;
3339} upgrade_cbdata_t;
3340
3341static int
3342upgrade_cb(zpool_handle_t *zhp, void *arg)
3343{
3344	upgrade_cbdata_t *cbp = arg;
3345	nvlist_t *config;
3346	uint64_t version;
3347	int ret = 0;
3348
3349	config = zpool_get_config(zhp, NULL);
3350	verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION,
3351	    &version) == 0);
3352
3353	if (!cbp->cb_newer && version < SPA_VERSION) {
3354		if (!cbp->cb_all) {
3355			if (cbp->cb_first) {
3356				(void) printf(gettext("The following pools are "
3357				    "out of date, and can be upgraded.  After "
3358				    "being\nupgraded, these pools will no "
3359				    "longer be accessible by older software "
3360				    "versions.\n\n"));
3361				(void) printf(gettext("VER  POOL\n"));
3362				(void) printf(gettext("---  ------------\n"));
3363				cbp->cb_first = B_FALSE;
3364			}
3365
3366			(void) printf("%2llu   %s\n", (u_longlong_t)version,
3367			    zpool_get_name(zhp));
3368		} else {
3369			cbp->cb_first = B_FALSE;
3370			ret = zpool_upgrade(zhp, cbp->cb_version);
3371			if (!ret) {
3372				(void) printf(gettext("Successfully upgraded "
3373				    "'%s'\n\n"), zpool_get_name(zhp));
3374			}
3375		}
3376	} else if (cbp->cb_newer && version > SPA_VERSION) {
3377		assert(!cbp->cb_all);
3378
3379		if (cbp->cb_first) {
3380			(void) printf(gettext("The following pools are "
3381			    "formatted using a newer software version and\n"
3382			    "cannot be accessed on the current system.\n\n"));
3383			(void) printf(gettext("VER  POOL\n"));
3384			(void) printf(gettext("---  ------------\n"));
3385			cbp->cb_first = B_FALSE;
3386		}
3387
3388		(void) printf("%2llu   %s\n", (u_longlong_t)version,
3389		    zpool_get_name(zhp));
3390	}
3391
3392	zpool_close(zhp);
3393	return (ret);
3394}
3395
3396/* ARGSUSED */
3397static int
3398upgrade_one(zpool_handle_t *zhp, void *data)
3399{
3400	upgrade_cbdata_t *cbp = data;
3401	uint64_t cur_version;
3402	int ret;
3403
3404	if (strcmp("log", zpool_get_name(zhp)) == 0) {
3405		(void) printf(gettext("'log' is now a reserved word\n"
3406		    "Pool 'log' must be renamed using export and import"
3407		    " to upgrade.\n"));
3408		return (1);
3409	}
3410
3411	cur_version = zpool_get_prop_int(zhp, ZPOOL_PROP_VERSION, NULL);
3412	if (cur_version > cbp->cb_version) {
3413		(void) printf(gettext("Pool '%s' is already formatted "
3414		    "using more current version '%llu'.\n"),
3415		    zpool_get_name(zhp), cur_version);
3416		return (0);
3417	}
3418	if (cur_version == cbp->cb_version) {
3419		(void) printf(gettext("Pool '%s' is already formatted "
3420		    "using the current version.\n"), zpool_get_name(zhp));
3421		return (0);
3422	}
3423
3424	ret = zpool_upgrade(zhp, cbp->cb_version);
3425
3426	if (!ret) {
3427		(void) printf(gettext("Successfully upgraded '%s' "
3428		    "from version %llu to version %llu\n\n"),
3429		    zpool_get_name(zhp), (u_longlong_t)cur_version,
3430		    (u_longlong_t)cbp->cb_version);
3431	}
3432
3433	return (ret != 0);
3434}
3435
3436/*
3437 * zpool upgrade
3438 * zpool upgrade -v
3439 * zpool upgrade [-V version] <-a | pool ...>
3440 *
3441 * With no arguments, display downrev'd ZFS pool available for upgrade.
3442 * Individual pools can be upgraded by specifying the pool, and '-a' will
3443 * upgrade all pools.
3444 */
3445int
3446zpool_do_upgrade(int argc, char **argv)
3447{
3448	int c;
3449	upgrade_cbdata_t cb = { 0 };
3450	int ret = 0;
3451	boolean_t showversions = B_FALSE;
3452	char *end;
3453
3454
3455	/* check options */
3456	while ((c = getopt(argc, argv, "avV:")) != -1) {
3457		switch (c) {
3458		case 'a':
3459			cb.cb_all = B_TRUE;
3460			break;
3461		case 'v':
3462			showversions = B_TRUE;
3463			break;
3464		case 'V':
3465			cb.cb_version = strtoll(optarg, &end, 10);
3466			if (*end != '\0' || cb.cb_version > SPA_VERSION ||
3467			    cb.cb_version < SPA_VERSION_1) {
3468				(void) fprintf(stderr,
3469				    gettext("invalid version '%s'\n"), optarg);
3470				usage(B_FALSE);
3471			}
3472			break;
3473		case '?':
3474			(void) fprintf(stderr, gettext("invalid option '%c'\n"),
3475			    optopt);
3476			usage(B_FALSE);
3477		}
3478	}
3479
3480	cb.cb_argc = argc;
3481	cb.cb_argv = argv;
3482	argc -= optind;
3483	argv += optind;
3484
3485	if (cb.cb_version == 0) {
3486		cb.cb_version = SPA_VERSION;
3487	} else if (!cb.cb_all && argc == 0) {
3488		(void) fprintf(stderr, gettext("-V option is "
3489		    "incompatible with other arguments\n"));
3490		usage(B_FALSE);
3491	}
3492
3493	if (showversions) {
3494		if (cb.cb_all || argc != 0) {
3495			(void) fprintf(stderr, gettext("-v option is "
3496			    "incompatible with other arguments\n"));
3497			usage(B_FALSE);
3498		}
3499	} else if (cb.cb_all) {
3500		if (argc != 0) {
3501			(void) fprintf(stderr, gettext("-a option should not "
3502			    "be used along with a pool name\n"));
3503			usage(B_FALSE);
3504		}
3505	}
3506
3507	(void) printf(gettext("This system is currently running "
3508	    "ZFS pool version %llu.\n\n"), SPA_VERSION);
3509	cb.cb_first = B_TRUE;
3510	if (showversions) {
3511		(void) printf(gettext("The following versions are "
3512		    "supported:\n\n"));
3513		(void) printf(gettext("VER  DESCRIPTION\n"));
3514		(void) printf("---  -----------------------------------------"
3515		    "---------------\n");
3516		(void) printf(gettext(" 1   Initial ZFS version\n"));
3517		(void) printf(gettext(" 2   Ditto blocks "
3518		    "(replicated metadata)\n"));
3519		(void) printf(gettext(" 3   Hot spares and double parity "
3520		    "RAID-Z\n"));
3521		(void) printf(gettext(" 4   zpool history\n"));
3522		(void) printf(gettext(" 5   Compression using the gzip "
3523		    "algorithm\n"));
3524		(void) printf(gettext(" 6   bootfs pool property\n"));
3525		(void) printf(gettext(" 7   Separate intent log devices\n"));
3526		(void) printf(gettext(" 8   Delegated administration\n"));
3527		(void) printf(gettext(" 9   refquota and refreservation "
3528		    "properties\n"));
3529		(void) printf(gettext(" 10  Cache devices\n"));
3530		(void) printf(gettext(" 11  Improved scrub performance\n"));
3531		(void) printf(gettext(" 12  Snapshot properties\n"));
3532		(void) printf(gettext(" 13  snapused property\n"));
3533		(void) printf(gettext(" 14  passthrough-x aclinherit\n"));
3534		(void) printf(gettext(" 15  user/group space accounting\n"));
3535		(void) printf(gettext("For more information on a particular "
3536		    "version, including supported releases, see:\n\n"));
3537		(void) printf("http://www.opensolaris.org/os/community/zfs/"
3538		    "version/N\n\n");
3539		(void) printf(gettext("Where 'N' is the version number.\n"));
3540	} else if (argc == 0) {
3541		int notfound;
3542
3543		ret = zpool_iter(g_zfs, upgrade_cb, &cb);
3544		notfound = cb.cb_first;
3545
3546		if (!cb.cb_all && ret == 0) {
3547			if (!cb.cb_first)
3548				(void) printf("\n");
3549			cb.cb_first = B_TRUE;
3550			cb.cb_newer = B_TRUE;
3551			ret = zpool_iter(g_zfs, upgrade_cb, &cb);
3552			if (!cb.cb_first) {
3553				notfound = B_FALSE;
3554				(void) printf("\n");
3555			}
3556		}
3557
3558		if (ret == 0) {
3559			if (notfound)
3560				(void) printf(gettext("All pools are formatted "
3561				    "using this version.\n"));
3562			else if (!cb.cb_all)
3563				(void) printf(gettext("Use 'zpool upgrade -v' "
3564				    "for a list of available versions and "
3565				    "their associated\nfeatures.\n"));
3566		}
3567	} else {
3568		ret = for_each_pool(argc, argv, B_FALSE, NULL,
3569		    upgrade_one, &cb);
3570	}
3571
3572	return (ret);
3573}
3574
3575typedef struct hist_cbdata {
3576	boolean_t first;
3577	int longfmt;
3578	int internal;
3579} hist_cbdata_t;
3580
3581char *hist_event_table[LOG_END] = {
3582	"invalid event",
3583	"pool create",
3584	"vdev add",
3585	"pool remove",
3586	"pool destroy",
3587	"pool export",
3588	"pool import",
3589	"vdev attach",
3590	"vdev replace",
3591	"vdev detach",
3592	"vdev online",
3593	"vdev offline",
3594	"vdev upgrade",
3595	"pool clear",
3596	"pool scrub",
3597	"pool property set",
3598	"create",
3599	"clone",
3600	"destroy",
3601	"destroy_begin_sync",
3602	"inherit",
3603	"property set",
3604	"quota set",
3605	"permission update",
3606	"permission remove",
3607	"permission who remove",
3608	"promote",
3609	"receive",
3610	"rename",
3611	"reservation set",
3612	"replay_inc_sync",
3613	"replay_full_sync",
3614	"rollback",
3615	"snapshot",
3616	"filesystem version upgrade",
3617	"refquota set",
3618	"refreservation set",
3619	"pool scrub done",
3620};
3621
3622/*
3623 * Print out the command history for a specific pool.
3624 */
3625static int
3626get_history_one(zpool_handle_t *zhp, void *data)
3627{
3628	nvlist_t *nvhis;
3629	nvlist_t **records;
3630	uint_t numrecords;
3631	char *cmdstr;
3632	char *pathstr;
3633	uint64_t dst_time;
3634	time_t tsec;
3635	struct tm t;
3636	char tbuf[30];
3637	int ret, i;
3638	uint64_t who;
3639	struct passwd *pwd;
3640	char *hostname;
3641	char *zonename;
3642	char internalstr[MAXPATHLEN];
3643	hist_cbdata_t *cb = (hist_cbdata_t *)data;
3644	uint64_t txg;
3645	uint64_t ievent;
3646
3647	cb->first = B_FALSE;
3648
3649	(void) printf(gettext("History for '%s':\n"), zpool_get_name(zhp));
3650
3651	if ((ret = zpool_get_history(zhp, &nvhis)) != 0)
3652		return (ret);
3653
3654	verify(nvlist_lookup_nvlist_array(nvhis, ZPOOL_HIST_RECORD,
3655	    &records, &numrecords) == 0);
3656	for (i = 0; i < numrecords; i++) {
3657		if (nvlist_lookup_uint64(records[i], ZPOOL_HIST_TIME,
3658		    &dst_time) != 0)
3659			continue;
3660
3661		/* is it an internal event or a standard event? */
3662		if (nvlist_lookup_string(records[i], ZPOOL_HIST_CMD,
3663		    &cmdstr) != 0) {
3664			if (cb->internal == 0)
3665				continue;
3666
3667			if (nvlist_lookup_uint64(records[i],
3668			    ZPOOL_HIST_INT_EVENT, &ievent) != 0)
3669				continue;
3670			verify(nvlist_lookup_uint64(records[i],
3671			    ZPOOL_HIST_TXG, &txg) == 0);
3672			verify(nvlist_lookup_string(records[i],
3673			    ZPOOL_HIST_INT_STR, &pathstr) == 0);
3674			if (ievent >= LOG_END)
3675				continue;
3676			(void) snprintf(internalstr,
3677			    sizeof (internalstr),
3678			    "[internal %s txg:%lld] %s",
3679			    hist_event_table[ievent], txg,
3680			    pathstr);
3681			cmdstr = internalstr;
3682		}
3683		tsec = dst_time;
3684		(void) localtime_r(&tsec, &t);
3685		(void) strftime(tbuf, sizeof (tbuf), "%F.%T", &t);
3686		(void) printf("%s %s", tbuf, cmdstr);
3687
3688		if (!cb->longfmt) {
3689			(void) printf("\n");
3690			continue;
3691		}
3692		(void) printf(" [");
3693		if (nvlist_lookup_uint64(records[i],
3694		    ZPOOL_HIST_WHO, &who) == 0) {
3695			pwd = getpwuid((uid_t)who);
3696			if (pwd)
3697				(void) printf("user %s on",
3698				    pwd->pw_name);
3699			else
3700				(void) printf("user %d on",
3701				    (int)who);
3702		} else {
3703			(void) printf(gettext("no info]\n"));
3704			continue;
3705		}
3706		if (nvlist_lookup_string(records[i],
3707		    ZPOOL_HIST_HOST, &hostname) == 0) {
3708			(void) printf(" %s", hostname);
3709		}
3710		if (nvlist_lookup_string(records[i],
3711		    ZPOOL_HIST_ZONE, &zonename) == 0) {
3712			(void) printf(":%s", zonename);
3713		}
3714
3715		(void) printf("]");
3716		(void) printf("\n");
3717	}
3718	(void) printf("\n");
3719	nvlist_free(nvhis);
3720
3721	return (ret);
3722}
3723
3724/*
3725 * zpool history <pool>
3726 *
3727 * Displays the history of commands that modified pools.
3728 */
3729
3730
3731int
3732zpool_do_history(int argc, char **argv)
3733{
3734	hist_cbdata_t cbdata = { 0 };
3735	int ret;
3736	int c;
3737
3738	cbdata.first = B_TRUE;
3739	/* check options */
3740	while ((c = getopt(argc, argv, "li")) != -1) {
3741		switch (c) {
3742		case 'l':
3743			cbdata.longfmt = 1;
3744			break;
3745		case 'i':
3746			cbdata.internal = 1;
3747			break;
3748		case '?':
3749			(void) fprintf(stderr, gettext("invalid option '%c'\n"),
3750			    optopt);
3751			usage(B_FALSE);
3752		}
3753	}
3754	argc -= optind;
3755	argv += optind;
3756
3757	ret = for_each_pool(argc, argv, B_FALSE,  NULL, get_history_one,
3758	    &cbdata);
3759
3760	if (argc == 0 && cbdata.first == B_TRUE) {
3761		(void) printf(gettext("no pools available\n"));
3762		return (0);
3763	}
3764
3765	return (ret);
3766}
3767
3768static int
3769get_callback(zpool_handle_t *zhp, void *data)
3770{
3771	zprop_get_cbdata_t *cbp = (zprop_get_cbdata_t *)data;
3772	char value[MAXNAMELEN];
3773	zprop_source_t srctype;
3774	zprop_list_t *pl;
3775
3776	for (pl = cbp->cb_proplist; pl != NULL; pl = pl->pl_next) {
3777
3778		/*
3779		 * Skip the special fake placeholder. This will also skip
3780		 * over the name property when 'all' is specified.
3781		 */
3782		if (pl->pl_prop == ZPOOL_PROP_NAME &&
3783		    pl == cbp->cb_proplist)
3784			continue;
3785
3786		if (zpool_get_prop(zhp, pl->pl_prop,
3787		    value, sizeof (value), &srctype) != 0)
3788			continue;
3789
3790		zprop_print_one_property(zpool_get_name(zhp), cbp,
3791		    zpool_prop_to_name(pl->pl_prop), value, srctype, NULL);
3792	}
3793	return (0);
3794}
3795
3796int
3797zpool_do_get(int argc, char **argv)
3798{
3799	zprop_get_cbdata_t cb = { 0 };
3800	zprop_list_t fake_name = { 0 };
3801	int ret;
3802
3803	if (argc < 3)
3804		usage(B_FALSE);
3805
3806	cb.cb_first = B_TRUE;
3807	cb.cb_sources = ZPROP_SRC_ALL;
3808	cb.cb_columns[0] = GET_COL_NAME;
3809	cb.cb_columns[1] = GET_COL_PROPERTY;
3810	cb.cb_columns[2] = GET_COL_VALUE;
3811	cb.cb_columns[3] = GET_COL_SOURCE;
3812	cb.cb_type = ZFS_TYPE_POOL;
3813
3814	if (zprop_get_list(g_zfs, argv[1],  &cb.cb_proplist,
3815	    ZFS_TYPE_POOL) != 0)
3816		usage(B_FALSE);
3817
3818	if (cb.cb_proplist != NULL) {
3819		fake_name.pl_prop = ZPOOL_PROP_NAME;
3820		fake_name.pl_width = strlen(gettext("NAME"));
3821		fake_name.pl_next = cb.cb_proplist;
3822		cb.cb_proplist = &fake_name;
3823	}
3824
3825	ret = for_each_pool(argc - 2, argv + 2, B_TRUE, &cb.cb_proplist,
3826	    get_callback, &cb);
3827
3828	if (cb.cb_proplist == &fake_name)
3829		zprop_free_list(fake_name.pl_next);
3830	else
3831		zprop_free_list(cb.cb_proplist);
3832
3833	return (ret);
3834}
3835
3836typedef struct set_cbdata {
3837	char *cb_propname;
3838	char *cb_value;
3839	boolean_t cb_any_successful;
3840} set_cbdata_t;
3841
3842int
3843set_callback(zpool_handle_t *zhp, void *data)
3844{
3845	int error;
3846	set_cbdata_t *cb = (set_cbdata_t *)data;
3847
3848	error = zpool_set_prop(zhp, cb->cb_propname, cb->cb_value);
3849
3850	if (!error)
3851		cb->cb_any_successful = B_TRUE;
3852
3853	return (error);
3854}
3855
3856int
3857zpool_do_set(int argc, char **argv)
3858{
3859	set_cbdata_t cb = { 0 };
3860	int error;
3861
3862	if (argc > 1 && argv[1][0] == '-') {
3863		(void) fprintf(stderr, gettext("invalid option '%c'\n"),
3864		    argv[1][1]);
3865		usage(B_FALSE);
3866	}
3867
3868	if (argc < 2) {
3869		(void) fprintf(stderr, gettext("missing property=value "
3870		    "argument\n"));
3871		usage(B_FALSE);
3872	}
3873
3874	if (argc < 3) {
3875		(void) fprintf(stderr, gettext("missing pool name\n"));
3876		usage(B_FALSE);
3877	}
3878
3879	if (argc > 3) {
3880		(void) fprintf(stderr, gettext("too many pool names\n"));
3881		usage(B_FALSE);
3882	}
3883
3884	cb.cb_propname = argv[1];
3885	cb.cb_value = strchr(cb.cb_propname, '=');
3886	if (cb.cb_value == NULL) {
3887		(void) fprintf(stderr, gettext("missing value in "
3888		    "property=value argument\n"));
3889		usage(B_FALSE);
3890	}
3891
3892	*(cb.cb_value) = '\0';
3893	cb.cb_value++;
3894
3895	error = for_each_pool(argc - 2, argv + 2, B_TRUE, NULL,
3896	    set_callback, &cb);
3897
3898	return (error);
3899}
3900
3901static int
3902find_command_idx(char *command, int *idx)
3903{
3904	int i;
3905
3906	for (i = 0; i < NCOMMAND; i++) {
3907		if (command_table[i].name == NULL)
3908			continue;
3909
3910		if (strcmp(command, command_table[i].name) == 0) {
3911			*idx = i;
3912			return (0);
3913		}
3914	}
3915	return (1);
3916}
3917
3918int
3919main(int argc, char **argv)
3920{
3921	int ret;
3922	int i;
3923	char *cmdname;
3924
3925	(void) setlocale(LC_ALL, "");
3926	(void) textdomain(TEXT_DOMAIN);
3927
3928	if ((g_zfs = libzfs_init()) == NULL) {
3929		(void) fprintf(stderr, gettext("internal error: failed to "
3930		    "initialize ZFS library\n"));
3931		return (1);
3932	}
3933
3934	libzfs_print_on_error(g_zfs, B_TRUE);
3935
3936	opterr = 0;
3937
3938	/*
3939	 * Make sure the user has specified some command.
3940	 */
3941	if (argc < 2) {
3942		(void) fprintf(stderr, gettext("missing command\n"));
3943		usage(B_FALSE);
3944	}
3945
3946	cmdname = argv[1];
3947
3948	/*
3949	 * Special case '-?'
3950	 */
3951	if (strcmp(cmdname, "-?") == 0)
3952		usage(B_TRUE);
3953
3954	zpool_set_history_str("zpool", argc, argv, history_str);
3955	verify(zpool_stage_history(g_zfs, history_str) == 0);
3956
3957	/*
3958	 * Run the appropriate command.
3959	 */
3960	if (find_command_idx(cmdname, &i) == 0) {
3961		current_command = &command_table[i];
3962		ret = command_table[i].func(argc - 1, argv + 1);
3963	} else if (strchr(cmdname, '=')) {
3964		verify(find_command_idx("set", &i) == 0);
3965		current_command = &command_table[i];
3966		ret = command_table[i].func(argc, argv);
3967	} else if (strcmp(cmdname, "freeze") == 0 && argc == 3) {
3968		/*
3969		 * 'freeze' is a vile debugging abomination, so we treat
3970		 * it as such.
3971		 */
3972		char buf[16384];
3973		int fd = open(ZFS_DEV, O_RDWR);
3974		(void) strcpy((void *)buf, argv[2]);
3975		return (!!ioctl(fd, ZFS_IOC_POOL_FREEZE, buf));
3976	} else {
3977		(void) fprintf(stderr, gettext("unrecognized "
3978		    "command '%s'\n"), cmdname);
3979		usage(B_FALSE);
3980	}
3981
3982	libzfs_fini(g_zfs);
3983
3984	/*
3985	 * The 'ZFS_ABORT' environment variable causes us to dump core on exit
3986	 * for the purposes of running ::findleaks.
3987	 */
3988	if (getenv("ZFS_ABORT") != NULL) {
3989		(void) printf("dumping core by request\n");
3990		abort();
3991	}
3992
3993	return (ret);
3994}
3995