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