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