zpool_main.c revision 219089
113547Sjulian/*
213547Sjulian * CDDL HEADER START
313547Sjulian *
413547Sjulian * The contents of this file are subject to the terms of the
513547Sjulian * Common Development and Distribution License (the "License").
613547Sjulian * You may not use this file except in compliance with the License.
713547Sjulian *
813547Sjulian * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
913547Sjulian * or http://www.opensolaris.org/os/licensing.
1013547Sjulian * See the License for the specific language governing permissions
1113547Sjulian * and limitations under the License.
1213547Sjulian *
1313547Sjulian * When distributing Covered Code, include this CDDL HEADER in each
1413547Sjulian * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
1513547Sjulian * If applicable, add the following below this CDDL HEADER, with the
1613547Sjulian * fields enclosed by brackets "[]" replaced with your own identifying
1713547Sjulian * information: Portions Copyright [yyyy] [name of copyright owner]
1813547Sjulian *
1913547Sjulian * CDDL HEADER END
2013547Sjulian */
2113547Sjulian
2213547Sjulian/*
2313547Sjulian * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
2413547Sjulian */
2513547Sjulian
2613547Sjulian#include <solaris.h>
2713547Sjulian#include <assert.h>
2813547Sjulian#include <ctype.h>
2913547Sjulian#include <dirent.h>
3013547Sjulian#include <errno.h>
3113547Sjulian#include <fcntl.h>
3250473Speter#include <libgen.h>
3313547Sjulian#include <libintl.h>
3413547Sjulian#include <libuutil.h>
3513547Sjulian#include <locale.h>
3613547Sjulian#include <stdio.h>
3713547Sjulian#include <stdlib.h>
3813547Sjulian#include <string.h>
3913547Sjulian#include <strings.h>
4013547Sjulian#include <unistd.h>
4113547Sjulian#include <priv.h>
4213547Sjulian#include <pwd.h>
4313547Sjulian#include <zone.h>
4413547Sjulian#include <sys/time.h>
4513547Sjulian#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	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		char *path;
1089		verify(nvlist_lookup_string(nv, ZPOOL_CONFIG_PATH, &path) == 0);
1090		(void) printf("  was %s", path);
1091	} else if (vs->vs_aux != 0) {
1092		(void) printf("  ");
1093
1094		switch (vs->vs_aux) {
1095		case VDEV_AUX_OPEN_FAILED:
1096			(void) printf(gettext("cannot open"));
1097			break;
1098
1099		case VDEV_AUX_BAD_GUID_SUM:
1100			(void) printf(gettext("missing device"));
1101			break;
1102
1103		case VDEV_AUX_NO_REPLICAS:
1104			(void) printf(gettext("insufficient replicas"));
1105			break;
1106
1107		case VDEV_AUX_VERSION_NEWER:
1108			(void) printf(gettext("newer version"));
1109			break;
1110
1111		case VDEV_AUX_SPARED:
1112			verify(nvlist_lookup_uint64(nv, ZPOOL_CONFIG_GUID,
1113			    &cb.cb_guid) == 0);
1114			if (zpool_iter(g_zfs, find_spare, &cb) == 1) {
1115				if (strcmp(zpool_get_name(cb.cb_zhp),
1116				    zpool_get_name(zhp)) == 0)
1117					(void) printf(gettext("currently in "
1118					    "use"));
1119				else
1120					(void) printf(gettext("in use by "
1121					    "pool '%s'"),
1122					    zpool_get_name(cb.cb_zhp));
1123				zpool_close(cb.cb_zhp);
1124			} else {
1125				(void) printf(gettext("currently in use"));
1126			}
1127			break;
1128
1129		case VDEV_AUX_ERR_EXCEEDED:
1130			(void) printf(gettext("too many errors"));
1131			break;
1132
1133		case VDEV_AUX_IO_FAILURE:
1134			(void) printf(gettext("experienced I/O failures"));
1135			break;
1136
1137		case VDEV_AUX_BAD_LOG:
1138			(void) printf(gettext("bad intent log"));
1139			break;
1140
1141		case VDEV_AUX_EXTERNAL:
1142			(void) printf(gettext("external device fault"));
1143			break;
1144
1145		case VDEV_AUX_SPLIT_POOL:
1146			(void) printf(gettext("split into new pool"));
1147			break;
1148
1149		default:
1150			(void) printf(gettext("corrupted data"));
1151			break;
1152		}
1153	}
1154
1155	(void) nvlist_lookup_uint64_array(nv, ZPOOL_CONFIG_SCAN_STATS,
1156	    (uint64_t **)&ps, &c);
1157
1158	if (ps && ps->pss_state == DSS_SCANNING &&
1159	    vs->vs_scan_processed != 0 && children == 0) {
1160		(void) printf(gettext("  (%s)"),
1161		    (ps->pss_func == POOL_SCAN_RESILVER) ?
1162		    "resilvering" : "repairing");
1163	}
1164
1165	(void) printf("\n");
1166
1167	for (c = 0; c < children; c++) {
1168		uint64_t islog = B_FALSE, ishole = B_FALSE;
1169
1170		/* Don't print logs or holes here */
1171		(void) nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_LOG,
1172		    &islog);
1173		(void) nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_HOLE,
1174		    &ishole);
1175		if (islog || ishole)
1176			continue;
1177		vname = zpool_vdev_name(g_zfs, zhp, child[c], B_TRUE);
1178		print_status_config(zhp, vname, child[c],
1179		    namewidth, depth + 2, isspare);
1180		free(vname);
1181	}
1182}
1183
1184
1185/*
1186 * Print the configuration of an exported pool.  Iterate over all vdevs in the
1187 * pool, printing out the name and status for each one.
1188 */
1189void
1190print_import_config(const char *name, nvlist_t *nv, int namewidth, int depth)
1191{
1192	nvlist_t **child;
1193	uint_t c, children;
1194	vdev_stat_t *vs;
1195	char *type, *vname;
1196
1197	verify(nvlist_lookup_string(nv, ZPOOL_CONFIG_TYPE, &type) == 0);
1198	if (strcmp(type, VDEV_TYPE_MISSING) == 0 ||
1199	    strcmp(type, VDEV_TYPE_HOLE) == 0)
1200		return;
1201
1202	verify(nvlist_lookup_uint64_array(nv, ZPOOL_CONFIG_VDEV_STATS,
1203	    (uint64_t **)&vs, &c) == 0);
1204
1205	(void) printf("\t%*s%-*s", depth, "", namewidth - depth, name);
1206	(void) printf("  %s", zpool_state_to_name(vs->vs_state, vs->vs_aux));
1207
1208	if (vs->vs_aux != 0) {
1209		(void) printf("  ");
1210
1211		switch (vs->vs_aux) {
1212		case VDEV_AUX_OPEN_FAILED:
1213			(void) printf(gettext("cannot open"));
1214			break;
1215
1216		case VDEV_AUX_BAD_GUID_SUM:
1217			(void) printf(gettext("missing device"));
1218			break;
1219
1220		case VDEV_AUX_NO_REPLICAS:
1221			(void) printf(gettext("insufficient replicas"));
1222			break;
1223
1224		case VDEV_AUX_VERSION_NEWER:
1225			(void) printf(gettext("newer version"));
1226			break;
1227
1228		case VDEV_AUX_ERR_EXCEEDED:
1229			(void) printf(gettext("too many errors"));
1230			break;
1231
1232		default:
1233			(void) printf(gettext("corrupted data"));
1234			break;
1235		}
1236	}
1237	(void) printf("\n");
1238
1239	if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
1240	    &child, &children) != 0)
1241		return;
1242
1243	for (c = 0; c < children; c++) {
1244		uint64_t is_log = B_FALSE;
1245
1246		(void) nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_LOG,
1247		    &is_log);
1248		if (is_log)
1249			continue;
1250
1251		vname = zpool_vdev_name(g_zfs, NULL, child[c], B_TRUE);
1252		print_import_config(vname, child[c], namewidth, depth + 2);
1253		free(vname);
1254	}
1255
1256	if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_L2CACHE,
1257	    &child, &children) == 0) {
1258		(void) printf(gettext("\tcache\n"));
1259		for (c = 0; c < children; c++) {
1260			vname = zpool_vdev_name(g_zfs, NULL, child[c], B_FALSE);
1261			(void) printf("\t  %s\n", vname);
1262			free(vname);
1263		}
1264	}
1265
1266	if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_SPARES,
1267	    &child, &children) == 0) {
1268		(void) printf(gettext("\tspares\n"));
1269		for (c = 0; c < children; c++) {
1270			vname = zpool_vdev_name(g_zfs, NULL, child[c], B_FALSE);
1271			(void) printf("\t  %s\n", vname);
1272			free(vname);
1273		}
1274	}
1275}
1276
1277/*
1278 * Print log vdevs.
1279 * Logs are recorded as top level vdevs in the main pool child array
1280 * but with "is_log" set to 1. We use either print_status_config() or
1281 * print_import_config() to print the top level logs then any log
1282 * children (eg mirrored slogs) are printed recursively - which
1283 * works because only the top level vdev is marked "is_log"
1284 */
1285static void
1286print_logs(zpool_handle_t *zhp, nvlist_t *nv, int namewidth, boolean_t verbose)
1287{
1288	uint_t c, children;
1289	nvlist_t **child;
1290
1291	if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN, &child,
1292	    &children) != 0)
1293		return;
1294
1295	(void) printf(gettext("\tlogs\n"));
1296
1297	for (c = 0; c < children; c++) {
1298		uint64_t is_log = B_FALSE;
1299		char *name;
1300
1301		(void) nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_LOG,
1302		    &is_log);
1303		if (!is_log)
1304			continue;
1305		name = zpool_vdev_name(g_zfs, zhp, child[c], B_TRUE);
1306		if (verbose)
1307			print_status_config(zhp, name, child[c], namewidth,
1308			    2, B_FALSE);
1309		else
1310			print_import_config(name, child[c], namewidth, 2);
1311		free(name);
1312	}
1313}
1314
1315/*
1316 * Display the status for the given pool.
1317 */
1318static void
1319show_import(nvlist_t *config)
1320{
1321	uint64_t pool_state;
1322	vdev_stat_t *vs;
1323	char *name;
1324	uint64_t guid;
1325	char *msgid;
1326	nvlist_t *nvroot;
1327	int reason;
1328	const char *health;
1329	uint_t vsc;
1330	int namewidth;
1331
1332	verify(nvlist_lookup_string(config, ZPOOL_CONFIG_POOL_NAME,
1333	    &name) == 0);
1334	verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_GUID,
1335	    &guid) == 0);
1336	verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_STATE,
1337	    &pool_state) == 0);
1338	verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
1339	    &nvroot) == 0);
1340
1341	verify(nvlist_lookup_uint64_array(nvroot, ZPOOL_CONFIG_VDEV_STATS,
1342	    (uint64_t **)&vs, &vsc) == 0);
1343	health = zpool_state_to_name(vs->vs_state, vs->vs_aux);
1344
1345	reason = zpool_import_status(config, &msgid);
1346
1347	(void) printf(gettext("  pool: %s\n"), name);
1348	(void) printf(gettext("    id: %llu\n"), (u_longlong_t)guid);
1349	(void) printf(gettext(" state: %s"), health);
1350	if (pool_state == POOL_STATE_DESTROYED)
1351		(void) printf(gettext(" (DESTROYED)"));
1352	(void) printf("\n");
1353
1354	switch (reason) {
1355	case ZPOOL_STATUS_MISSING_DEV_R:
1356	case ZPOOL_STATUS_MISSING_DEV_NR:
1357	case ZPOOL_STATUS_BAD_GUID_SUM:
1358		(void) printf(gettext("status: One or more devices are missing "
1359		    "from the system.\n"));
1360		break;
1361
1362	case ZPOOL_STATUS_CORRUPT_LABEL_R:
1363	case ZPOOL_STATUS_CORRUPT_LABEL_NR:
1364		(void) printf(gettext("status: One or more devices contains "
1365		    "corrupted data.\n"));
1366		break;
1367
1368	case ZPOOL_STATUS_CORRUPT_DATA:
1369		(void) printf(gettext("status: The pool data is corrupted.\n"));
1370		break;
1371
1372	case ZPOOL_STATUS_OFFLINE_DEV:
1373		(void) printf(gettext("status: One or more devices "
1374		    "are offlined.\n"));
1375		break;
1376
1377	case ZPOOL_STATUS_CORRUPT_POOL:
1378		(void) printf(gettext("status: The pool metadata is "
1379		    "corrupted.\n"));
1380		break;
1381
1382	case ZPOOL_STATUS_VERSION_OLDER:
1383		(void) printf(gettext("status: The pool is formatted using an "
1384		    "older on-disk version.\n"));
1385		break;
1386
1387	case ZPOOL_STATUS_VERSION_NEWER:
1388		(void) printf(gettext("status: The pool is formatted using an "
1389		    "incompatible version.\n"));
1390		break;
1391
1392	case ZPOOL_STATUS_HOSTID_MISMATCH:
1393		(void) printf(gettext("status: The pool was last accessed by "
1394		    "another system.\n"));
1395		break;
1396
1397	case ZPOOL_STATUS_FAULTED_DEV_R:
1398	case ZPOOL_STATUS_FAULTED_DEV_NR:
1399		(void) printf(gettext("status: One or more devices are "
1400		    "faulted.\n"));
1401		break;
1402
1403	case ZPOOL_STATUS_BAD_LOG:
1404		(void) printf(gettext("status: An intent log record cannot be "
1405		    "read.\n"));
1406		break;
1407
1408	case ZPOOL_STATUS_RESILVERING:
1409		(void) printf(gettext("status: One or more devices were being "
1410		    "resilvered.\n"));
1411		break;
1412
1413	default:
1414		/*
1415		 * No other status can be seen when importing pools.
1416		 */
1417		assert(reason == ZPOOL_STATUS_OK);
1418	}
1419
1420	/*
1421	 * Print out an action according to the overall state of the pool.
1422	 */
1423	if (vs->vs_state == VDEV_STATE_HEALTHY) {
1424		if (reason == ZPOOL_STATUS_VERSION_OLDER)
1425			(void) printf(gettext("action: The pool can be "
1426			    "imported using its name or numeric identifier, "
1427			    "though\n\tsome features will not be available "
1428			    "without an explicit 'zpool upgrade'.\n"));
1429		else if (reason == ZPOOL_STATUS_HOSTID_MISMATCH)
1430			(void) printf(gettext("action: The pool can be "
1431			    "imported using its name or numeric "
1432			    "identifier and\n\tthe '-f' flag.\n"));
1433		else
1434			(void) printf(gettext("action: The pool can be "
1435			    "imported using its name or numeric "
1436			    "identifier.\n"));
1437	} else if (vs->vs_state == VDEV_STATE_DEGRADED) {
1438		(void) printf(gettext("action: The pool can be imported "
1439		    "despite missing or damaged devices.  The\n\tfault "
1440		    "tolerance of the pool may be compromised if imported.\n"));
1441	} else {
1442		switch (reason) {
1443		case ZPOOL_STATUS_VERSION_NEWER:
1444			(void) printf(gettext("action: The pool cannot be "
1445			    "imported.  Access the pool on a system running "
1446			    "newer\n\tsoftware, or recreate the pool from "
1447			    "backup.\n"));
1448			break;
1449		case ZPOOL_STATUS_MISSING_DEV_R:
1450		case ZPOOL_STATUS_MISSING_DEV_NR:
1451		case ZPOOL_STATUS_BAD_GUID_SUM:
1452			(void) printf(gettext("action: The pool cannot be "
1453			    "imported. Attach the missing\n\tdevices and try "
1454			    "again.\n"));
1455			break;
1456		default:
1457			(void) printf(gettext("action: The pool cannot be "
1458			    "imported due to damaged devices or data.\n"));
1459		}
1460	}
1461
1462	/*
1463	 * If the state is "closed" or "can't open", and the aux state
1464	 * is "corrupt data":
1465	 */
1466	if (((vs->vs_state == VDEV_STATE_CLOSED) ||
1467	    (vs->vs_state == VDEV_STATE_CANT_OPEN)) &&
1468	    (vs->vs_aux == VDEV_AUX_CORRUPT_DATA)) {
1469		if (pool_state == POOL_STATE_DESTROYED)
1470			(void) printf(gettext("\tThe pool was destroyed, "
1471			    "but can be imported using the '-Df' flags.\n"));
1472		else if (pool_state != POOL_STATE_EXPORTED)
1473			(void) printf(gettext("\tThe pool may be active on "
1474			    "another system, but can be imported using\n\t"
1475			    "the '-f' flag.\n"));
1476	}
1477
1478	if (msgid != NULL)
1479		(void) printf(gettext("   see: http://www.sun.com/msg/%s\n"),
1480		    msgid);
1481
1482	(void) printf(gettext("config:\n\n"));
1483
1484	namewidth = max_width(NULL, nvroot, 0, 0);
1485	if (namewidth < 10)
1486		namewidth = 10;
1487
1488	print_import_config(name, nvroot, namewidth, 0);
1489	if (num_logs(nvroot) > 0)
1490		print_logs(NULL, nvroot, namewidth, B_FALSE);
1491
1492	if (reason == ZPOOL_STATUS_BAD_GUID_SUM) {
1493		(void) printf(gettext("\n\tAdditional devices are known to "
1494		    "be part of this pool, though their\n\texact "
1495		    "configuration cannot be determined.\n"));
1496	}
1497}
1498
1499/*
1500 * Perform the import for the given configuration.  This passes the heavy
1501 * lifting off to zpool_import_props(), and then mounts the datasets contained
1502 * within the pool.
1503 */
1504static int
1505do_import(nvlist_t *config, const char *newname, const char *mntopts,
1506    nvlist_t *props, int flags)
1507{
1508	zpool_handle_t *zhp;
1509	char *name;
1510	uint64_t state;
1511	uint64_t version;
1512
1513	verify(nvlist_lookup_string(config, ZPOOL_CONFIG_POOL_NAME,
1514	    &name) == 0);
1515
1516	verify(nvlist_lookup_uint64(config,
1517	    ZPOOL_CONFIG_POOL_STATE, &state) == 0);
1518	verify(nvlist_lookup_uint64(config,
1519	    ZPOOL_CONFIG_VERSION, &version) == 0);
1520	if (version > SPA_VERSION) {
1521		(void) fprintf(stderr, gettext("cannot import '%s': pool "
1522		    "is formatted using a newer ZFS version\n"), name);
1523		return (1);
1524	} else if (state != POOL_STATE_EXPORTED &&
1525	    !(flags & ZFS_IMPORT_ANY_HOST)) {
1526		uint64_t hostid;
1527
1528		if (nvlist_lookup_uint64(config, ZPOOL_CONFIG_HOSTID,
1529		    &hostid) == 0) {
1530			if ((unsigned long)hostid != gethostid()) {
1531				char *hostname;
1532				uint64_t timestamp;
1533				time_t t;
1534
1535				verify(nvlist_lookup_string(config,
1536				    ZPOOL_CONFIG_HOSTNAME, &hostname) == 0);
1537				verify(nvlist_lookup_uint64(config,
1538				    ZPOOL_CONFIG_TIMESTAMP, &timestamp) == 0);
1539				t = timestamp;
1540				(void) fprintf(stderr, gettext("cannot import "
1541				    "'%s': pool may be in use from other "
1542				    "system, it was last accessed by %s "
1543				    "(hostid: 0x%lx) on %s"), name, hostname,
1544				    (unsigned long)hostid,
1545				    asctime(localtime(&t)));
1546				(void) fprintf(stderr, gettext("use '-f' to "
1547				    "import anyway\n"));
1548				return (1);
1549			}
1550		} else {
1551			(void) fprintf(stderr, gettext("cannot import '%s': "
1552			    "pool may be in use from other system\n"), name);
1553			(void) fprintf(stderr, gettext("use '-f' to import "
1554			    "anyway\n"));
1555			return (1);
1556		}
1557	}
1558
1559	if (zpool_import_props(g_zfs, config, newname, props, flags) != 0)
1560		return (1);
1561
1562	if (newname != NULL)
1563		name = (char *)newname;
1564
1565	if ((zhp = zpool_open_canfail(g_zfs, name)) == NULL)
1566		return (1);
1567
1568	if (zpool_get_state(zhp) != POOL_STATE_UNAVAIL &&
1569	    !(flags & ZFS_IMPORT_ONLY) &&
1570	    zpool_enable_datasets(zhp, mntopts, 0) != 0) {
1571		zpool_close(zhp);
1572		return (1);
1573	}
1574
1575	zpool_close(zhp);
1576	return (0);
1577}
1578
1579/*
1580 * zpool import [-d dir] [-D]
1581 *       import [-o mntopts] [-o prop=value] ... [-R root] [-D]
1582 *              [-d dir | -c cachefile] [-f] -a
1583 *       import [-o mntopts] [-o prop=value] ... [-R root] [-D]
1584 *              [-d dir | -c cachefile] [-f] [-n] [-F] <pool | id> [newpool]
1585 *
1586 *	 -c	Read pool information from a cachefile instead of searching
1587 *		devices.
1588 *
1589 *       -d	Scan in a specific directory, other than /dev/dsk.  More than
1590 *		one directory can be specified using multiple '-d' options.
1591 *
1592 *       -D     Scan for previously destroyed pools or import all or only
1593 *              specified destroyed pools.
1594 *
1595 *       -R	Temporarily import the pool, with all mountpoints relative to
1596 *		the given root.  The pool will remain exported when the machine
1597 *		is rebooted.
1598 *
1599 *       -V	Import even in the presence of faulted vdevs.  This is an
1600 *       	intentionally undocumented option for testing purposes, and
1601 *       	treats the pool configuration as complete, leaving any bad
1602 *		vdevs in the FAULTED state. In other words, it does verbatim
1603 *		import.
1604 *
1605 *       -f	Force import, even if it appears that the pool is active.
1606 *
1607 *       -F     Attempt rewind if necessary.
1608 *
1609 *       -n     See if rewind would work, but don't actually rewind.
1610 *
1611 *       -N     Import the pool but don't mount datasets.
1612 *
1613 *       -T     Specify a starting txg to use for import. This option is
1614 *       	intentionally undocumented option for testing purposes.
1615 *
1616 *       -a	Import all pools found.
1617 *
1618 *       -o	Set property=value and/or temporary mount options (without '=').
1619 *
1620 * The import command scans for pools to import, and import pools based on pool
1621 * name and GUID.  The pool can also be renamed as part of the import process.
1622 */
1623int
1624zpool_do_import(int argc, char **argv)
1625{
1626	char **searchdirs = NULL;
1627	int nsearch = 0;
1628	int c;
1629	int err = 0;
1630	nvlist_t *pools = NULL;
1631	boolean_t do_all = B_FALSE;
1632	boolean_t do_destroyed = B_FALSE;
1633	char *mntopts = NULL;
1634	nvpair_t *elem;
1635	nvlist_t *config;
1636	uint64_t searchguid = 0;
1637	char *searchname = NULL;
1638	char *propval;
1639	nvlist_t *found_config;
1640	nvlist_t *policy = NULL;
1641	nvlist_t *props = NULL;
1642	boolean_t first;
1643	int flags = ZFS_IMPORT_NORMAL;
1644	uint32_t rewind_policy = ZPOOL_NO_REWIND;
1645	boolean_t dryrun = B_FALSE;
1646	boolean_t do_rewind = B_FALSE;
1647	boolean_t xtreme_rewind = B_FALSE;
1648	uint64_t pool_state, txg = -1ULL;
1649	char *cachefile = NULL;
1650	importargs_t idata = { 0 };
1651	char *endptr;
1652
1653	/* check options */
1654	while ((c = getopt(argc, argv, ":aCc:d:DEfFmnNo:rR:T:VX")) != -1) {
1655		switch (c) {
1656		case 'a':
1657			do_all = B_TRUE;
1658			break;
1659		case 'c':
1660			cachefile = optarg;
1661			break;
1662		case 'd':
1663			if (searchdirs == NULL) {
1664				searchdirs = safe_malloc(sizeof (char *));
1665			} else {
1666				char **tmp = safe_malloc((nsearch + 1) *
1667				    sizeof (char *));
1668				bcopy(searchdirs, tmp, nsearch *
1669				    sizeof (char *));
1670				free(searchdirs);
1671				searchdirs = tmp;
1672			}
1673			searchdirs[nsearch++] = optarg;
1674			break;
1675		case 'D':
1676			do_destroyed = B_TRUE;
1677			break;
1678		case 'f':
1679			flags |= ZFS_IMPORT_ANY_HOST;
1680			break;
1681		case 'F':
1682			do_rewind = B_TRUE;
1683			break;
1684		case 'm':
1685			flags |= ZFS_IMPORT_MISSING_LOG;
1686			break;
1687		case 'n':
1688			dryrun = B_TRUE;
1689			break;
1690		case 'N':
1691			flags |= ZFS_IMPORT_ONLY;
1692			break;
1693		case 'o':
1694			if ((propval = strchr(optarg, '=')) != NULL) {
1695				*propval = '\0';
1696				propval++;
1697				if (add_prop_list(optarg, propval,
1698				    &props, B_TRUE))
1699					goto error;
1700			} else {
1701				mntopts = optarg;
1702			}
1703			break;
1704		case 'R':
1705			if (add_prop_list(zpool_prop_to_name(
1706			    ZPOOL_PROP_ALTROOT), optarg, &props, B_TRUE))
1707				goto error;
1708			if (nvlist_lookup_string(props,
1709			    zpool_prop_to_name(ZPOOL_PROP_CACHEFILE),
1710			    &propval) == 0)
1711				break;
1712			if (add_prop_list(zpool_prop_to_name(
1713			    ZPOOL_PROP_CACHEFILE), "none", &props, B_TRUE))
1714				goto error;
1715			break;
1716		case 'T':
1717			errno = 0;
1718			txg = strtoull(optarg, &endptr, 10);
1719			if (errno != 0 || *endptr != '\0') {
1720				(void) fprintf(stderr,
1721				    gettext("invalid txg value\n"));
1722				usage(B_FALSE);
1723			}
1724			rewind_policy = ZPOOL_DO_REWIND | ZPOOL_EXTREME_REWIND;
1725			break;
1726		case 'V':
1727			flags |= ZFS_IMPORT_VERBATIM;
1728			break;
1729		case 'X':
1730			xtreme_rewind = B_TRUE;
1731			break;
1732		case ':':
1733			(void) fprintf(stderr, gettext("missing argument for "
1734			    "'%c' option\n"), optopt);
1735			usage(B_FALSE);
1736			break;
1737		case '?':
1738			(void) fprintf(stderr, gettext("invalid option '%c'\n"),
1739			    optopt);
1740			usage(B_FALSE);
1741		}
1742	}
1743
1744	argc -= optind;
1745	argv += optind;
1746
1747	if (cachefile && nsearch != 0) {
1748		(void) fprintf(stderr, gettext("-c is incompatible with -d\n"));
1749		usage(B_FALSE);
1750	}
1751
1752	if ((dryrun || xtreme_rewind) && !do_rewind) {
1753		(void) fprintf(stderr,
1754		    gettext("-n or -X only meaningful with -F\n"));
1755		usage(B_FALSE);
1756	}
1757	if (dryrun)
1758		rewind_policy = ZPOOL_TRY_REWIND;
1759	else if (do_rewind)
1760		rewind_policy = ZPOOL_DO_REWIND;
1761	if (xtreme_rewind)
1762		rewind_policy |= ZPOOL_EXTREME_REWIND;
1763
1764	/* In the future, we can capture further policy and include it here */
1765	if (nvlist_alloc(&policy, NV_UNIQUE_NAME, 0) != 0 ||
1766	    nvlist_add_uint64(policy, ZPOOL_REWIND_REQUEST_TXG, txg) != 0 ||
1767	    nvlist_add_uint32(policy, ZPOOL_REWIND_REQUEST, rewind_policy) != 0)
1768		goto error;
1769
1770	if (searchdirs == NULL) {
1771		searchdirs = safe_malloc(sizeof (char *));
1772		searchdirs[0] = "/dev/dsk";
1773		nsearch = 1;
1774	}
1775
1776	/* check argument count */
1777	if (do_all) {
1778		if (argc != 0) {
1779			(void) fprintf(stderr, gettext("too many arguments\n"));
1780			usage(B_FALSE);
1781		}
1782	} else {
1783		if (argc > 2) {
1784			(void) fprintf(stderr, gettext("too many arguments\n"));
1785			usage(B_FALSE);
1786		}
1787
1788		/*
1789		 * Check for the SYS_CONFIG privilege.  We do this explicitly
1790		 * here because otherwise any attempt to discover pools will
1791		 * silently fail.
1792		 */
1793		if (argc == 0 && !priv_ineffect(PRIV_SYS_CONFIG)) {
1794			(void) fprintf(stderr, gettext("cannot "
1795			    "discover pools: permission denied\n"));
1796			free(searchdirs);
1797			nvlist_free(policy);
1798			return (1);
1799		}
1800	}
1801
1802	/*
1803	 * Depending on the arguments given, we do one of the following:
1804	 *
1805	 *	<none>	Iterate through all pools and display information about
1806	 *		each one.
1807	 *
1808	 *	-a	Iterate through all pools and try to import each one.
1809	 *
1810	 *	<id>	Find the pool that corresponds to the given GUID/pool
1811	 *		name and import that one.
1812	 *
1813	 *	-D	Above options applies only to destroyed pools.
1814	 */
1815	if (argc != 0) {
1816		char *endptr;
1817
1818		errno = 0;
1819		searchguid = strtoull(argv[0], &endptr, 10);
1820		if (errno != 0 || *endptr != '\0')
1821			searchname = argv[0];
1822		found_config = NULL;
1823
1824		/*
1825		 * User specified a name or guid.  Ensure it's unique.
1826		 */
1827		idata.unique = B_TRUE;
1828	}
1829
1830
1831	idata.path = searchdirs;
1832	idata.paths = nsearch;
1833	idata.poolname = searchname;
1834	idata.guid = searchguid;
1835	idata.cachefile = cachefile;
1836
1837	pools = zpool_search_import(g_zfs, &idata);
1838
1839	if (pools != NULL && idata.exists &&
1840	    (argc == 1 || strcmp(argv[0], argv[1]) == 0)) {
1841		(void) fprintf(stderr, gettext("cannot import '%s': "
1842		    "a pool with that name already exists\n"),
1843		    argv[0]);
1844		(void) fprintf(stderr, gettext("use the form '%s "
1845		    "<pool | id> <newpool>' to give it a new name\n"),
1846		    "zpool import");
1847		err = 1;
1848	} else if (pools == NULL && idata.exists) {
1849		(void) fprintf(stderr, gettext("cannot import '%s': "
1850		    "a pool with that name is already created/imported,\n"),
1851		    argv[0]);
1852		(void) fprintf(stderr, gettext("and no additional pools "
1853		    "with that name were found\n"));
1854		err = 1;
1855	} else if (pools == NULL) {
1856		if (argc != 0) {
1857			(void) fprintf(stderr, gettext("cannot import '%s': "
1858			    "no such pool available\n"), argv[0]);
1859		}
1860		err = 1;
1861	}
1862
1863	if (err == 1) {
1864		free(searchdirs);
1865		nvlist_free(policy);
1866		return (1);
1867	}
1868
1869	/*
1870	 * At this point we have a list of import candidate configs. Even if
1871	 * we were searching by pool name or guid, we still need to
1872	 * post-process the list to deal with pool state and possible
1873	 * duplicate names.
1874	 */
1875	err = 0;
1876	elem = NULL;
1877	first = B_TRUE;
1878	while ((elem = nvlist_next_nvpair(pools, elem)) != NULL) {
1879
1880		verify(nvpair_value_nvlist(elem, &config) == 0);
1881
1882		verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_STATE,
1883		    &pool_state) == 0);
1884		if (!do_destroyed && pool_state == POOL_STATE_DESTROYED)
1885			continue;
1886		if (do_destroyed && pool_state != POOL_STATE_DESTROYED)
1887			continue;
1888
1889		verify(nvlist_add_nvlist(config, ZPOOL_REWIND_POLICY,
1890		    policy) == 0);
1891
1892		if (argc == 0) {
1893			if (first)
1894				first = B_FALSE;
1895			else if (!do_all)
1896				(void) printf("\n");
1897
1898			if (do_all) {
1899				err |= do_import(config, NULL, mntopts,
1900				    props, flags);
1901			} else {
1902				show_import(config);
1903			}
1904		} else if (searchname != NULL) {
1905			char *name;
1906
1907			/*
1908			 * We are searching for a pool based on name.
1909			 */
1910			verify(nvlist_lookup_string(config,
1911			    ZPOOL_CONFIG_POOL_NAME, &name) == 0);
1912
1913			if (strcmp(name, searchname) == 0) {
1914				if (found_config != NULL) {
1915					(void) fprintf(stderr, gettext(
1916					    "cannot import '%s': more than "
1917					    "one matching pool\n"), searchname);
1918					(void) fprintf(stderr, gettext(
1919					    "import by numeric ID instead\n"));
1920					err = B_TRUE;
1921				}
1922				found_config = config;
1923			}
1924		} else {
1925			uint64_t guid;
1926
1927			/*
1928			 * Search for a pool by guid.
1929			 */
1930			verify(nvlist_lookup_uint64(config,
1931			    ZPOOL_CONFIG_POOL_GUID, &guid) == 0);
1932
1933			if (guid == searchguid)
1934				found_config = config;
1935		}
1936	}
1937
1938	/*
1939	 * If we were searching for a specific pool, verify that we found a
1940	 * pool, and then do the import.
1941	 */
1942	if (argc != 0 && err == 0) {
1943		if (found_config == NULL) {
1944			(void) fprintf(stderr, gettext("cannot import '%s': "
1945			    "no such pool available\n"), argv[0]);
1946			err = B_TRUE;
1947		} else {
1948			err |= do_import(found_config, argc == 1 ? NULL :
1949			    argv[1], mntopts, props, flags);
1950		}
1951	}
1952
1953	/*
1954	 * If we were just looking for pools, report an error if none were
1955	 * found.
1956	 */
1957	if (argc == 0 && first)
1958		(void) fprintf(stderr,
1959		    gettext("no pools available to import\n"));
1960
1961error:
1962	nvlist_free(props);
1963	nvlist_free(pools);
1964	nvlist_free(policy);
1965	free(searchdirs);
1966
1967	return (err ? 1 : 0);
1968}
1969
1970typedef struct iostat_cbdata {
1971	zpool_list_t *cb_list;
1972	int cb_verbose;
1973	int cb_iteration;
1974	int cb_namewidth;
1975} iostat_cbdata_t;
1976
1977static void
1978print_iostat_separator(iostat_cbdata_t *cb)
1979{
1980	int i = 0;
1981
1982	for (i = 0; i < cb->cb_namewidth; i++)
1983		(void) printf("-");
1984	(void) printf("  -----  -----  -----  -----  -----  -----\n");
1985}
1986
1987static void
1988print_iostat_header(iostat_cbdata_t *cb)
1989{
1990	(void) printf("%*s     capacity     operations    bandwidth\n",
1991	    cb->cb_namewidth, "");
1992	(void) printf("%-*s  alloc   free   read  write   read  write\n",
1993	    cb->cb_namewidth, "pool");
1994	print_iostat_separator(cb);
1995}
1996
1997/*
1998 * Display a single statistic.
1999 */
2000static void
2001print_one_stat(uint64_t value)
2002{
2003	char buf[64];
2004
2005	zfs_nicenum(value, buf, sizeof (buf));
2006	(void) printf("  %5s", buf);
2007}
2008
2009/*
2010 * Print out all the statistics for the given vdev.  This can either be the
2011 * toplevel configuration, or called recursively.  If 'name' is NULL, then this
2012 * is a verbose output, and we don't want to display the toplevel pool stats.
2013 */
2014void
2015print_vdev_stats(zpool_handle_t *zhp, const char *name, nvlist_t *oldnv,
2016    nvlist_t *newnv, iostat_cbdata_t *cb, int depth)
2017{
2018	nvlist_t **oldchild, **newchild;
2019	uint_t c, children;
2020	vdev_stat_t *oldvs, *newvs;
2021	vdev_stat_t zerovs = { 0 };
2022	uint64_t tdelta;
2023	double scale;
2024	char *vname;
2025
2026	if (oldnv != NULL) {
2027		verify(nvlist_lookup_uint64_array(oldnv,
2028		    ZPOOL_CONFIG_VDEV_STATS, (uint64_t **)&oldvs, &c) == 0);
2029	} else {
2030		oldvs = &zerovs;
2031	}
2032
2033	verify(nvlist_lookup_uint64_array(newnv, ZPOOL_CONFIG_VDEV_STATS,
2034	    (uint64_t **)&newvs, &c) == 0);
2035
2036	if (strlen(name) + depth > cb->cb_namewidth)
2037		(void) printf("%*s%s", depth, "", name);
2038	else
2039		(void) printf("%*s%s%*s", depth, "", name,
2040		    (int)(cb->cb_namewidth - strlen(name) - depth), "");
2041
2042	tdelta = newvs->vs_timestamp - oldvs->vs_timestamp;
2043
2044	if (tdelta == 0)
2045		scale = 1.0;
2046	else
2047		scale = (double)NANOSEC / tdelta;
2048
2049	/* only toplevel vdevs have capacity stats */
2050	if (newvs->vs_space == 0) {
2051		(void) printf("      -      -");
2052	} else {
2053		print_one_stat(newvs->vs_alloc);
2054		print_one_stat(newvs->vs_space - newvs->vs_alloc);
2055	}
2056
2057	print_one_stat((uint64_t)(scale * (newvs->vs_ops[ZIO_TYPE_READ] -
2058	    oldvs->vs_ops[ZIO_TYPE_READ])));
2059
2060	print_one_stat((uint64_t)(scale * (newvs->vs_ops[ZIO_TYPE_WRITE] -
2061	    oldvs->vs_ops[ZIO_TYPE_WRITE])));
2062
2063	print_one_stat((uint64_t)(scale * (newvs->vs_bytes[ZIO_TYPE_READ] -
2064	    oldvs->vs_bytes[ZIO_TYPE_READ])));
2065
2066	print_one_stat((uint64_t)(scale * (newvs->vs_bytes[ZIO_TYPE_WRITE] -
2067	    oldvs->vs_bytes[ZIO_TYPE_WRITE])));
2068
2069	(void) printf("\n");
2070
2071	if (!cb->cb_verbose)
2072		return;
2073
2074	if (nvlist_lookup_nvlist_array(newnv, ZPOOL_CONFIG_CHILDREN,
2075	    &newchild, &children) != 0)
2076		return;
2077
2078	if (oldnv && nvlist_lookup_nvlist_array(oldnv, ZPOOL_CONFIG_CHILDREN,
2079	    &oldchild, &c) != 0)
2080		return;
2081
2082	for (c = 0; c < children; c++) {
2083		uint64_t ishole = B_FALSE;
2084
2085		if (nvlist_lookup_uint64(newchild[c],
2086		    ZPOOL_CONFIG_IS_HOLE, &ishole) == 0 && ishole)
2087			continue;
2088
2089		vname = zpool_vdev_name(g_zfs, zhp, newchild[c], B_FALSE);
2090		print_vdev_stats(zhp, vname, oldnv ? oldchild[c] : NULL,
2091		    newchild[c], cb, depth + 2);
2092		free(vname);
2093	}
2094
2095	/*
2096	 * Include level 2 ARC devices in iostat output
2097	 */
2098	if (nvlist_lookup_nvlist_array(newnv, ZPOOL_CONFIG_L2CACHE,
2099	    &newchild, &children) != 0)
2100		return;
2101
2102	if (oldnv && nvlist_lookup_nvlist_array(oldnv, ZPOOL_CONFIG_L2CACHE,
2103	    &oldchild, &c) != 0)
2104		return;
2105
2106	if (children > 0) {
2107		(void) printf("%-*s      -      -      -      -      -      "
2108		    "-\n", cb->cb_namewidth, "cache");
2109		for (c = 0; c < children; c++) {
2110			vname = zpool_vdev_name(g_zfs, zhp, newchild[c],
2111			    B_FALSE);
2112			print_vdev_stats(zhp, vname, oldnv ? oldchild[c] : NULL,
2113			    newchild[c], cb, depth + 2);
2114			free(vname);
2115		}
2116	}
2117}
2118
2119static int
2120refresh_iostat(zpool_handle_t *zhp, void *data)
2121{
2122	iostat_cbdata_t *cb = data;
2123	boolean_t missing;
2124
2125	/*
2126	 * If the pool has disappeared, remove it from the list and continue.
2127	 */
2128	if (zpool_refresh_stats(zhp, &missing) != 0)
2129		return (-1);
2130
2131	if (missing)
2132		pool_list_remove(cb->cb_list, zhp);
2133
2134	return (0);
2135}
2136
2137/*
2138 * Callback to print out the iostats for the given pool.
2139 */
2140int
2141print_iostat(zpool_handle_t *zhp, void *data)
2142{
2143	iostat_cbdata_t *cb = data;
2144	nvlist_t *oldconfig, *newconfig;
2145	nvlist_t *oldnvroot, *newnvroot;
2146
2147	newconfig = zpool_get_config(zhp, &oldconfig);
2148
2149	if (cb->cb_iteration == 1)
2150		oldconfig = NULL;
2151
2152	verify(nvlist_lookup_nvlist(newconfig, ZPOOL_CONFIG_VDEV_TREE,
2153	    &newnvroot) == 0);
2154
2155	if (oldconfig == NULL)
2156		oldnvroot = NULL;
2157	else
2158		verify(nvlist_lookup_nvlist(oldconfig, ZPOOL_CONFIG_VDEV_TREE,
2159		    &oldnvroot) == 0);
2160
2161	/*
2162	 * Print out the statistics for the pool.
2163	 */
2164	print_vdev_stats(zhp, zpool_get_name(zhp), oldnvroot, newnvroot, cb, 0);
2165
2166	if (cb->cb_verbose)
2167		print_iostat_separator(cb);
2168
2169	return (0);
2170}
2171
2172int
2173get_namewidth(zpool_handle_t *zhp, void *data)
2174{
2175	iostat_cbdata_t *cb = data;
2176	nvlist_t *config, *nvroot;
2177
2178	if ((config = zpool_get_config(zhp, NULL)) != NULL) {
2179		verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
2180		    &nvroot) == 0);
2181		if (!cb->cb_verbose)
2182			cb->cb_namewidth = strlen(zpool_get_name(zhp));
2183		else
2184			cb->cb_namewidth = max_width(zhp, nvroot, 0, 0);
2185	}
2186
2187	/*
2188	 * The width must fall into the range [10,38].  The upper limit is the
2189	 * maximum we can have and still fit in 80 columns.
2190	 */
2191	if (cb->cb_namewidth < 10)
2192		cb->cb_namewidth = 10;
2193	if (cb->cb_namewidth > 38)
2194		cb->cb_namewidth = 38;
2195
2196	return (0);
2197}
2198
2199/*
2200 * Parse the input string, get the 'interval' and 'count' value if there is one.
2201 */
2202static void
2203get_interval_count(int *argcp, char **argv, unsigned long *iv,
2204    unsigned long *cnt)
2205{
2206	unsigned long interval = 0, count = 0;
2207	int argc = *argcp, errno;
2208
2209	/*
2210	 * Determine if the last argument is an integer or a pool name
2211	 */
2212	if (argc > 0 && isdigit(argv[argc - 1][0])) {
2213		char *end;
2214
2215		errno = 0;
2216		interval = strtoul(argv[argc - 1], &end, 10);
2217
2218		if (*end == '\0' && errno == 0) {
2219			if (interval == 0) {
2220				(void) fprintf(stderr, gettext("interval "
2221				    "cannot be zero\n"));
2222				usage(B_FALSE);
2223			}
2224			/*
2225			 * Ignore the last parameter
2226			 */
2227			argc--;
2228		} else {
2229			/*
2230			 * If this is not a valid number, just plow on.  The
2231			 * user will get a more informative error message later
2232			 * on.
2233			 */
2234			interval = 0;
2235		}
2236	}
2237
2238	/*
2239	 * If the last argument is also an integer, then we have both a count
2240	 * and an interval.
2241	 */
2242	if (argc > 0 && isdigit(argv[argc - 1][0])) {
2243		char *end;
2244
2245		errno = 0;
2246		count = interval;
2247		interval = strtoul(argv[argc - 1], &end, 10);
2248
2249		if (*end == '\0' && errno == 0) {
2250			if (interval == 0) {
2251				(void) fprintf(stderr, gettext("interval "
2252				    "cannot be zero\n"));
2253				usage(B_FALSE);
2254			}
2255
2256			/*
2257			 * Ignore the last parameter
2258			 */
2259			argc--;
2260		} else {
2261			interval = 0;
2262		}
2263	}
2264
2265	*iv = interval;
2266	*cnt = count;
2267	*argcp = argc;
2268}
2269
2270static void
2271get_timestamp_arg(char c)
2272{
2273	if (c == 'u')
2274		timestamp_fmt = UDATE;
2275	else if (c == 'd')
2276		timestamp_fmt = DDATE;
2277	else
2278		usage(B_FALSE);
2279}
2280
2281/*
2282 * zpool iostat [-v] [-T d|u] [pool] ... [interval [count]]
2283 *
2284 *	-v	Display statistics for individual vdevs
2285 *	-T	Display a timestamp in date(1) or Unix format
2286 *
2287 * This command can be tricky because we want to be able to deal with pool
2288 * creation/destruction as well as vdev configuration changes.  The bulk of this
2289 * processing is handled by the pool_list_* routines in zpool_iter.c.  We rely
2290 * on pool_list_update() to detect the addition of new pools.  Configuration
2291 * changes are all handled within libzfs.
2292 */
2293int
2294zpool_do_iostat(int argc, char **argv)
2295{
2296	int c;
2297	int ret;
2298	int npools;
2299	unsigned long interval = 0, count = 0;
2300	zpool_list_t *list;
2301	boolean_t verbose = B_FALSE;
2302	iostat_cbdata_t cb;
2303
2304	/* check options */
2305	while ((c = getopt(argc, argv, "T:v")) != -1) {
2306		switch (c) {
2307		case 'T':
2308			get_timestamp_arg(*optarg);
2309			break;
2310		case 'v':
2311			verbose = B_TRUE;
2312			break;
2313		case '?':
2314			(void) fprintf(stderr, gettext("invalid option '%c'\n"),
2315			    optopt);
2316			usage(B_FALSE);
2317		}
2318	}
2319
2320	argc -= optind;
2321	argv += optind;
2322
2323	get_interval_count(&argc, argv, &interval, &count);
2324
2325	/*
2326	 * Construct the list of all interesting pools.
2327	 */
2328	ret = 0;
2329	if ((list = pool_list_get(argc, argv, NULL, &ret)) == NULL)
2330		return (1);
2331
2332	if (pool_list_count(list) == 0 && argc != 0) {
2333		pool_list_free(list);
2334		return (1);
2335	}
2336
2337	if (pool_list_count(list) == 0 && interval == 0) {
2338		pool_list_free(list);
2339		(void) fprintf(stderr, gettext("no pools available\n"));
2340		return (1);
2341	}
2342
2343	/*
2344	 * Enter the main iostat loop.
2345	 */
2346	cb.cb_list = list;
2347	cb.cb_verbose = verbose;
2348	cb.cb_iteration = 0;
2349	cb.cb_namewidth = 0;
2350
2351	for (;;) {
2352		pool_list_update(list);
2353
2354		if ((npools = pool_list_count(list)) == 0)
2355			break;
2356
2357		/*
2358		 * Refresh all statistics.  This is done as an explicit step
2359		 * before calculating the maximum name width, so that any
2360		 * configuration changes are properly accounted for.
2361		 */
2362		(void) pool_list_iter(list, B_FALSE, refresh_iostat, &cb);
2363
2364		/*
2365		 * Iterate over all pools to determine the maximum width
2366		 * for the pool / device name column across all pools.
2367		 */
2368		cb.cb_namewidth = 0;
2369		(void) pool_list_iter(list, B_FALSE, get_namewidth, &cb);
2370
2371		if (timestamp_fmt != NODATE)
2372			print_timestamp(timestamp_fmt);
2373
2374		/*
2375		 * If it's the first time, or verbose mode, print the header.
2376		 */
2377		if (++cb.cb_iteration == 1 || verbose)
2378			print_iostat_header(&cb);
2379
2380		(void) pool_list_iter(list, B_FALSE, print_iostat, &cb);
2381
2382		/*
2383		 * If there's more than one pool, and we're not in verbose mode
2384		 * (which prints a separator for us), then print a separator.
2385		 */
2386		if (npools > 1 && !verbose)
2387			print_iostat_separator(&cb);
2388
2389		if (verbose)
2390			(void) printf("\n");
2391
2392		/*
2393		 * Flush the output so that redirection to a file isn't buffered
2394		 * indefinitely.
2395		 */
2396		(void) fflush(stdout);
2397
2398		if (interval == 0)
2399			break;
2400
2401		if (count != 0 && --count == 0)
2402			break;
2403
2404		(void) sleep(interval);
2405	}
2406
2407	pool_list_free(list);
2408
2409	return (ret);
2410}
2411
2412typedef struct list_cbdata {
2413	boolean_t	cb_scripted;
2414	boolean_t	cb_first;
2415	zprop_list_t	*cb_proplist;
2416} list_cbdata_t;
2417
2418/*
2419 * Given a list of columns to display, output appropriate headers for each one.
2420 */
2421static void
2422print_header(zprop_list_t *pl)
2423{
2424	const char *header;
2425	boolean_t first = B_TRUE;
2426	boolean_t right_justify;
2427
2428	for (; pl != NULL; pl = pl->pl_next) {
2429		if (pl->pl_prop == ZPROP_INVAL)
2430			continue;
2431
2432		if (!first)
2433			(void) printf("  ");
2434		else
2435			first = B_FALSE;
2436
2437		header = zpool_prop_column_name(pl->pl_prop);
2438		right_justify = zpool_prop_align_right(pl->pl_prop);
2439
2440		if (pl->pl_next == NULL && !right_justify)
2441			(void) printf("%s", header);
2442		else if (right_justify)
2443			(void) printf("%*s", pl->pl_width, header);
2444		else
2445			(void) printf("%-*s", pl->pl_width, header);
2446	}
2447
2448	(void) printf("\n");
2449}
2450
2451/*
2452 * Given a pool and a list of properties, print out all the properties according
2453 * to the described layout.
2454 */
2455static void
2456print_pool(zpool_handle_t *zhp, zprop_list_t *pl, int scripted)
2457{
2458	boolean_t first = B_TRUE;
2459	char property[ZPOOL_MAXPROPLEN];
2460	char *propstr;
2461	boolean_t right_justify;
2462	int width;
2463
2464	for (; pl != NULL; pl = pl->pl_next) {
2465		if (!first) {
2466			if (scripted)
2467				(void) printf("\t");
2468			else
2469				(void) printf("  ");
2470		} else {
2471			first = B_FALSE;
2472		}
2473
2474		right_justify = B_FALSE;
2475		if (pl->pl_prop != ZPROP_INVAL) {
2476			if (zpool_get_prop(zhp, pl->pl_prop, property,
2477			    sizeof (property), NULL) != 0)
2478				propstr = "-";
2479			else
2480				propstr = property;
2481
2482			right_justify = zpool_prop_align_right(pl->pl_prop);
2483		} else {
2484			propstr = "-";
2485		}
2486
2487		width = pl->pl_width;
2488
2489		/*
2490		 * If this is being called in scripted mode, or if this is the
2491		 * last column and it is left-justified, don't include a width
2492		 * format specifier.
2493		 */
2494		if (scripted || (pl->pl_next == NULL && !right_justify))
2495			(void) printf("%s", propstr);
2496		else if (right_justify)
2497			(void) printf("%*s", width, propstr);
2498		else
2499			(void) printf("%-*s", width, propstr);
2500	}
2501
2502	(void) printf("\n");
2503}
2504
2505/*
2506 * Generic callback function to list a pool.
2507 */
2508int
2509list_callback(zpool_handle_t *zhp, void *data)
2510{
2511	list_cbdata_t *cbp = data;
2512
2513	if (cbp->cb_first) {
2514		if (!cbp->cb_scripted)
2515			print_header(cbp->cb_proplist);
2516		cbp->cb_first = B_FALSE;
2517	}
2518
2519	print_pool(zhp, cbp->cb_proplist, cbp->cb_scripted);
2520
2521	return (0);
2522}
2523
2524/*
2525 * zpool list [-H] [-o prop[,prop]*] [-T d|u] [pool] ... [interval [count]]
2526 *
2527 *	-H	Scripted mode.  Don't display headers, and separate properties
2528 *		by a single tab.
2529 *	-o	List of properties to display.  Defaults to
2530 *		"name,size,allocated,free,capacity,health,altroot"
2531 *	-T	Display a timestamp in date(1) or Unix format
2532 *
2533 * List all pools in the system, whether or not they're healthy.  Output space
2534 * statistics for each one, as well as health status summary.
2535 */
2536int
2537zpool_do_list(int argc, char **argv)
2538{
2539	int c;
2540	int ret;
2541	list_cbdata_t cb = { 0 };
2542	static char default_props[] =
2543	    "name,size,allocated,free,capacity,dedupratio,health,altroot";
2544	char *props = default_props;
2545	unsigned long interval = 0, count = 0;
2546
2547	/* check options */
2548	while ((c = getopt(argc, argv, ":Ho:T:")) != -1) {
2549		switch (c) {
2550		case 'H':
2551			cb.cb_scripted = B_TRUE;
2552			break;
2553		case 'o':
2554			props = optarg;
2555			break;
2556		case 'T':
2557			get_timestamp_arg(*optarg);
2558			break;
2559		case ':':
2560			(void) fprintf(stderr, gettext("missing argument for "
2561			    "'%c' option\n"), optopt);
2562			usage(B_FALSE);
2563			break;
2564		case '?':
2565			(void) fprintf(stderr, gettext("invalid option '%c'\n"),
2566			    optopt);
2567			usage(B_FALSE);
2568		}
2569	}
2570
2571	argc -= optind;
2572	argv += optind;
2573
2574	get_interval_count(&argc, argv, &interval, &count);
2575
2576	if (zprop_get_list(g_zfs, props, &cb.cb_proplist, ZFS_TYPE_POOL) != 0)
2577		usage(B_FALSE);
2578
2579	cb.cb_first = B_TRUE;
2580
2581	for (;;) {
2582
2583		if (timestamp_fmt != NODATE)
2584			print_timestamp(timestamp_fmt);
2585
2586		ret = for_each_pool(argc, argv, B_TRUE, &cb.cb_proplist,
2587		    list_callback, &cb);
2588
2589		if (argc == 0 && cb.cb_first && !cb.cb_scripted) {
2590			(void) printf(gettext("no pools available\n"));
2591			zprop_free_list(cb.cb_proplist);
2592			return (0);
2593		}
2594
2595		if (interval == 0)
2596			break;
2597
2598		if (count != 0 && --count == 0)
2599			break;
2600
2601		(void) sleep(interval);
2602	}
2603
2604	zprop_free_list(cb.cb_proplist);
2605	return (ret);
2606}
2607
2608static nvlist_t *
2609zpool_get_vdev_by_name(nvlist_t *nv, char *name)
2610{
2611	nvlist_t **child;
2612	uint_t c, children;
2613	nvlist_t *match;
2614	char *path;
2615
2616	if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
2617	    &child, &children) != 0) {
2618		verify(nvlist_lookup_string(nv, ZPOOL_CONFIG_PATH, &path) == 0);
2619		if (strncmp(name, _PATH_DEV, sizeof(_PATH_DEV) - 1) == 0)
2620			name += sizeof(_PATH_DEV) - 1;
2621		if (strncmp(path, _PATH_DEV, sizeof(_PATH_DEV) - 1) == 0)
2622			path += sizeof(_PATH_DEV) - 1;
2623		if (strcmp(name, path) == 0)
2624			return (nv);
2625		return (NULL);
2626	}
2627
2628	for (c = 0; c < children; c++)
2629		if ((match = zpool_get_vdev_by_name(child[c], name)) != NULL)
2630			return (match);
2631
2632	return (NULL);
2633}
2634
2635static int
2636zpool_do_attach_or_replace(int argc, char **argv, int replacing)
2637{
2638	boolean_t force = B_FALSE;
2639	int c;
2640	nvlist_t *nvroot;
2641	char *poolname, *old_disk, *new_disk;
2642	zpool_handle_t *zhp;
2643	int ret;
2644
2645	/* check options */
2646	while ((c = getopt(argc, argv, "f")) != -1) {
2647		switch (c) {
2648		case 'f':
2649			force = B_TRUE;
2650			break;
2651		case '?':
2652			(void) fprintf(stderr, gettext("invalid option '%c'\n"),
2653			    optopt);
2654			usage(B_FALSE);
2655		}
2656	}
2657
2658	argc -= optind;
2659	argv += optind;
2660
2661	/* get pool name and check number of arguments */
2662	if (argc < 1) {
2663		(void) fprintf(stderr, gettext("missing pool name argument\n"));
2664		usage(B_FALSE);
2665	}
2666
2667	poolname = argv[0];
2668
2669	if (argc < 2) {
2670		(void) fprintf(stderr,
2671		    gettext("missing <device> specification\n"));
2672		usage(B_FALSE);
2673	}
2674
2675	old_disk = argv[1];
2676
2677	if (argc < 3) {
2678		if (!replacing) {
2679			(void) fprintf(stderr,
2680			    gettext("missing <new_device> specification\n"));
2681			usage(B_FALSE);
2682		}
2683		new_disk = old_disk;
2684		argc -= 1;
2685		argv += 1;
2686	} else {
2687		new_disk = argv[2];
2688		argc -= 2;
2689		argv += 2;
2690	}
2691
2692	if (argc > 1) {
2693		(void) fprintf(stderr, gettext("too many arguments\n"));
2694		usage(B_FALSE);
2695	}
2696
2697	if ((zhp = zpool_open(g_zfs, poolname)) == NULL)
2698		return (1);
2699
2700	if (zpool_get_config(zhp, NULL) == NULL) {
2701		(void) fprintf(stderr, gettext("pool '%s' is unavailable\n"),
2702		    poolname);
2703		zpool_close(zhp);
2704		return (1);
2705	}
2706
2707	nvroot = make_root_vdev(zhp, force, B_FALSE, replacing, B_FALSE,
2708	    argc, argv);
2709	if (nvroot == NULL) {
2710		zpool_close(zhp);
2711		return (1);
2712	}
2713
2714	ret = zpool_vdev_attach(zhp, old_disk, new_disk, nvroot, replacing);
2715
2716	nvlist_free(nvroot);
2717	zpool_close(zhp);
2718
2719	return (ret);
2720}
2721
2722/*
2723 * zpool replace [-f] <pool> <device> <new_device>
2724 *
2725 *	-f	Force attach, even if <new_device> appears to be in use.
2726 *
2727 * Replace <device> with <new_device>.
2728 */
2729/* ARGSUSED */
2730int
2731zpool_do_replace(int argc, char **argv)
2732{
2733	return (zpool_do_attach_or_replace(argc, argv, B_TRUE));
2734}
2735
2736/*
2737 * zpool attach [-f] <pool> <device> <new_device>
2738 *
2739 *	-f	Force attach, even if <new_device> appears to be in use.
2740 *
2741 * Attach <new_device> to the mirror containing <device>.  If <device> is not
2742 * part of a mirror, then <device> will be transformed into a mirror of
2743 * <device> and <new_device>.  In either case, <new_device> will begin life
2744 * with a DTL of [0, now], and will immediately begin to resilver itself.
2745 */
2746int
2747zpool_do_attach(int argc, char **argv)
2748{
2749	return (zpool_do_attach_or_replace(argc, argv, B_FALSE));
2750}
2751
2752/*
2753 * zpool detach [-f] <pool> <device>
2754 *
2755 *	-f	Force detach of <device>, even if DTLs argue against it
2756 *		(not supported yet)
2757 *
2758 * Detach a device from a mirror.  The operation will be refused if <device>
2759 * is the last device in the mirror, or if the DTLs indicate that this device
2760 * has the only valid copy of some data.
2761 */
2762/* ARGSUSED */
2763int
2764zpool_do_detach(int argc, char **argv)
2765{
2766	int c;
2767	char *poolname, *path;
2768	zpool_handle_t *zhp;
2769	int ret;
2770
2771	/* check options */
2772	while ((c = getopt(argc, argv, "f")) != -1) {
2773		switch (c) {
2774		case 'f':
2775		case '?':
2776			(void) fprintf(stderr, gettext("invalid option '%c'\n"),
2777			    optopt);
2778			usage(B_FALSE);
2779		}
2780	}
2781
2782	argc -= optind;
2783	argv += optind;
2784
2785	/* get pool name and check number of arguments */
2786	if (argc < 1) {
2787		(void) fprintf(stderr, gettext("missing pool name argument\n"));
2788		usage(B_FALSE);
2789	}
2790
2791	if (argc < 2) {
2792		(void) fprintf(stderr,
2793		    gettext("missing <device> specification\n"));
2794		usage(B_FALSE);
2795	}
2796
2797	poolname = argv[0];
2798	path = argv[1];
2799
2800	if ((zhp = zpool_open(g_zfs, poolname)) == NULL)
2801		return (1);
2802
2803	ret = zpool_vdev_detach(zhp, path);
2804
2805	zpool_close(zhp);
2806
2807	return (ret);
2808}
2809
2810/*
2811 * zpool split [-n] [-o prop=val] ...
2812 *		[-o mntopt] ...
2813 *		[-R altroot] <pool> <newpool> [<device> ...]
2814 *
2815 *	-n	Do not split the pool, but display the resulting layout if
2816 *		it were to be split.
2817 *	-o	Set property=value, or set mount options.
2818 *	-R	Mount the split-off pool under an alternate root.
2819 *
2820 * Splits the named pool and gives it the new pool name.  Devices to be split
2821 * off may be listed, provided that no more than one device is specified
2822 * per top-level vdev mirror.  The newly split pool is left in an exported
2823 * state unless -R is specified.
2824 *
2825 * Restrictions: the top-level of the pool pool must only be made up of
2826 * mirrors; all devices in the pool must be healthy; no device may be
2827 * undergoing a resilvering operation.
2828 */
2829int
2830zpool_do_split(int argc, char **argv)
2831{
2832	char *srcpool, *newpool, *propval;
2833	char *mntopts = NULL;
2834	splitflags_t flags;
2835	int c, ret = 0;
2836	zpool_handle_t *zhp;
2837	nvlist_t *config, *props = NULL;
2838
2839	flags.dryrun = B_FALSE;
2840	flags.import = B_FALSE;
2841
2842	/* check options */
2843	while ((c = getopt(argc, argv, ":R:no:")) != -1) {
2844		switch (c) {
2845		case 'R':
2846			flags.import = B_TRUE;
2847			if (add_prop_list(
2848			    zpool_prop_to_name(ZPOOL_PROP_ALTROOT), optarg,
2849			    &props, B_TRUE) != 0) {
2850				if (props)
2851					nvlist_free(props);
2852				usage(B_FALSE);
2853			}
2854			break;
2855		case 'n':
2856			flags.dryrun = B_TRUE;
2857			break;
2858		case 'o':
2859			if ((propval = strchr(optarg, '=')) != NULL) {
2860				*propval = '\0';
2861				propval++;
2862				if (add_prop_list(optarg, propval,
2863				    &props, B_TRUE) != 0) {
2864					if (props)
2865						nvlist_free(props);
2866					usage(B_FALSE);
2867				}
2868			} else {
2869				mntopts = optarg;
2870			}
2871			break;
2872		case ':':
2873			(void) fprintf(stderr, gettext("missing argument for "
2874			    "'%c' option\n"), optopt);
2875			usage(B_FALSE);
2876			break;
2877		case '?':
2878			(void) fprintf(stderr, gettext("invalid option '%c'\n"),
2879			    optopt);
2880			usage(B_FALSE);
2881			break;
2882		}
2883	}
2884
2885	if (!flags.import && mntopts != NULL) {
2886		(void) fprintf(stderr, gettext("setting mntopts is only "
2887		    "valid when importing the pool\n"));
2888		usage(B_FALSE);
2889	}
2890
2891	argc -= optind;
2892	argv += optind;
2893
2894	if (argc < 1) {
2895		(void) fprintf(stderr, gettext("Missing pool name\n"));
2896		usage(B_FALSE);
2897	}
2898	if (argc < 2) {
2899		(void) fprintf(stderr, gettext("Missing new pool name\n"));
2900		usage(B_FALSE);
2901	}
2902
2903	srcpool = argv[0];
2904	newpool = argv[1];
2905
2906	argc -= 2;
2907	argv += 2;
2908
2909	if ((zhp = zpool_open(g_zfs, srcpool)) == NULL)
2910		return (1);
2911
2912	config = split_mirror_vdev(zhp, newpool, props, flags, argc, argv);
2913	if (config == NULL) {
2914		ret = 1;
2915	} else {
2916		if (flags.dryrun) {
2917			(void) printf(gettext("would create '%s' with the "
2918			    "following layout:\n\n"), newpool);
2919			print_vdev_tree(NULL, newpool, config, 0, B_FALSE);
2920		}
2921		nvlist_free(config);
2922	}
2923
2924	zpool_close(zhp);
2925
2926	if (ret != 0 || flags.dryrun || !flags.import)
2927		return (ret);
2928
2929	/*
2930	 * The split was successful. Now we need to open the new
2931	 * pool and import it.
2932	 */
2933	if ((zhp = zpool_open_canfail(g_zfs, newpool)) == NULL)
2934		return (1);
2935	if (zpool_get_state(zhp) != POOL_STATE_UNAVAIL &&
2936	    zpool_enable_datasets(zhp, mntopts, 0) != 0) {
2937		ret = 1;
2938		(void) fprintf(stderr, gettext("Split was succssful, but "
2939		    "the datasets could not all be mounted\n"));
2940		(void) fprintf(stderr, gettext("Try doing '%s' with a "
2941		    "different altroot\n"), "zpool import");
2942	}
2943	zpool_close(zhp);
2944
2945	return (ret);
2946}
2947
2948
2949
2950/*
2951 * zpool online <pool> <device> ...
2952 */
2953int
2954zpool_do_online(int argc, char **argv)
2955{
2956	int c, i;
2957	char *poolname;
2958	zpool_handle_t *zhp;
2959	int ret = 0;
2960	vdev_state_t newstate;
2961	int flags = 0;
2962
2963	/* check options */
2964	while ((c = getopt(argc, argv, "et")) != -1) {
2965		switch (c) {
2966		case 'e':
2967			flags |= ZFS_ONLINE_EXPAND;
2968			break;
2969		case 't':
2970		case '?':
2971			(void) fprintf(stderr, gettext("invalid option '%c'\n"),
2972			    optopt);
2973			usage(B_FALSE);
2974		}
2975	}
2976
2977	argc -= optind;
2978	argv += optind;
2979
2980	/* get pool name and check number of arguments */
2981	if (argc < 1) {
2982		(void) fprintf(stderr, gettext("missing pool name\n"));
2983		usage(B_FALSE);
2984	}
2985	if (argc < 2) {
2986		(void) fprintf(stderr, gettext("missing device name\n"));
2987		usage(B_FALSE);
2988	}
2989
2990	poolname = argv[0];
2991
2992	if ((zhp = zpool_open(g_zfs, poolname)) == NULL)
2993		return (1);
2994
2995	for (i = 1; i < argc; i++) {
2996		if (zpool_vdev_online(zhp, argv[i], flags, &newstate) == 0) {
2997			if (newstate != VDEV_STATE_HEALTHY) {
2998				(void) printf(gettext("warning: device '%s' "
2999				    "onlined, but remains in faulted state\n"),
3000				    argv[i]);
3001				if (newstate == VDEV_STATE_FAULTED)
3002					(void) printf(gettext("use 'zpool "
3003					    "clear' to restore a faulted "
3004					    "device\n"));
3005				else
3006					(void) printf(gettext("use 'zpool "
3007					    "replace' to replace devices "
3008					    "that are no longer present\n"));
3009			}
3010		} else {
3011			ret = 1;
3012		}
3013	}
3014
3015	zpool_close(zhp);
3016
3017	return (ret);
3018}
3019
3020/*
3021 * zpool offline [-ft] <pool> <device> ...
3022 *
3023 *	-f	Force the device into the offline state, even if doing
3024 *		so would appear to compromise pool availability.
3025 *		(not supported yet)
3026 *
3027 *	-t	Only take the device off-line temporarily.  The offline
3028 *		state will not be persistent across reboots.
3029 */
3030/* ARGSUSED */
3031int
3032zpool_do_offline(int argc, char **argv)
3033{
3034	int c, i;
3035	char *poolname;
3036	zpool_handle_t *zhp;
3037	int ret = 0;
3038	boolean_t istmp = B_FALSE;
3039
3040	/* check options */
3041	while ((c = getopt(argc, argv, "ft")) != -1) {
3042		switch (c) {
3043		case 't':
3044			istmp = B_TRUE;
3045			break;
3046		case 'f':
3047		case '?':
3048			(void) fprintf(stderr, gettext("invalid option '%c'\n"),
3049			    optopt);
3050			usage(B_FALSE);
3051		}
3052	}
3053
3054	argc -= optind;
3055	argv += optind;
3056
3057	/* get pool name and check number of arguments */
3058	if (argc < 1) {
3059		(void) fprintf(stderr, gettext("missing pool name\n"));
3060		usage(B_FALSE);
3061	}
3062	if (argc < 2) {
3063		(void) fprintf(stderr, gettext("missing device name\n"));
3064		usage(B_FALSE);
3065	}
3066
3067	poolname = argv[0];
3068
3069	if ((zhp = zpool_open(g_zfs, poolname)) == NULL)
3070		return (1);
3071
3072	for (i = 1; i < argc; i++) {
3073		if (zpool_vdev_offline(zhp, argv[i], istmp) != 0)
3074			ret = 1;
3075	}
3076
3077	zpool_close(zhp);
3078
3079	return (ret);
3080}
3081
3082/*
3083 * zpool clear <pool> [device]
3084 *
3085 * Clear all errors associated with a pool or a particular device.
3086 */
3087int
3088zpool_do_clear(int argc, char **argv)
3089{
3090	int c;
3091	int ret = 0;
3092	boolean_t dryrun = B_FALSE;
3093	boolean_t do_rewind = B_FALSE;
3094	boolean_t xtreme_rewind = B_FALSE;
3095	uint32_t rewind_policy = ZPOOL_NO_REWIND;
3096	nvlist_t *policy = NULL;
3097	zpool_handle_t *zhp;
3098	char *pool, *device;
3099
3100	/* check options */
3101	while ((c = getopt(argc, argv, "FnX")) != -1) {
3102		switch (c) {
3103		case 'F':
3104			do_rewind = B_TRUE;
3105			break;
3106		case 'n':
3107			dryrun = B_TRUE;
3108			break;
3109		case 'X':
3110			xtreme_rewind = B_TRUE;
3111			break;
3112		case '?':
3113			(void) fprintf(stderr, gettext("invalid option '%c'\n"),
3114			    optopt);
3115			usage(B_FALSE);
3116		}
3117	}
3118
3119	argc -= optind;
3120	argv += optind;
3121
3122	if (argc < 1) {
3123		(void) fprintf(stderr, gettext("missing pool name\n"));
3124		usage(B_FALSE);
3125	}
3126
3127	if (argc > 2) {
3128		(void) fprintf(stderr, gettext("too many arguments\n"));
3129		usage(B_FALSE);
3130	}
3131
3132	if ((dryrun || xtreme_rewind) && !do_rewind) {
3133		(void) fprintf(stderr,
3134		    gettext("-n or -X only meaningful with -F\n"));
3135		usage(B_FALSE);
3136	}
3137	if (dryrun)
3138		rewind_policy = ZPOOL_TRY_REWIND;
3139	else if (do_rewind)
3140		rewind_policy = ZPOOL_DO_REWIND;
3141	if (xtreme_rewind)
3142		rewind_policy |= ZPOOL_EXTREME_REWIND;
3143
3144	/* In future, further rewind policy choices can be passed along here */
3145	if (nvlist_alloc(&policy, NV_UNIQUE_NAME, 0) != 0 ||
3146	    nvlist_add_uint32(policy, ZPOOL_REWIND_REQUEST, rewind_policy) != 0)
3147		return (1);
3148
3149	pool = argv[0];
3150	device = argc == 2 ? argv[1] : NULL;
3151
3152	if ((zhp = zpool_open_canfail(g_zfs, pool)) == NULL) {
3153		nvlist_free(policy);
3154		return (1);
3155	}
3156
3157	if (zpool_clear(zhp, device, policy) != 0)
3158		ret = 1;
3159
3160	zpool_close(zhp);
3161
3162	nvlist_free(policy);
3163
3164	return (ret);
3165}
3166
3167typedef struct scrub_cbdata {
3168	int	cb_type;
3169	int	cb_argc;
3170	char	**cb_argv;
3171} scrub_cbdata_t;
3172
3173int
3174scrub_callback(zpool_handle_t *zhp, void *data)
3175{
3176	scrub_cbdata_t *cb = data;
3177	int err;
3178
3179	/*
3180	 * Ignore faulted pools.
3181	 */
3182	if (zpool_get_state(zhp) == POOL_STATE_UNAVAIL) {
3183		(void) fprintf(stderr, gettext("cannot scrub '%s': pool is "
3184		    "currently unavailable\n"), zpool_get_name(zhp));
3185		return (1);
3186	}
3187
3188	err = zpool_scan(zhp, cb->cb_type);
3189
3190	return (err != 0);
3191}
3192
3193/*
3194 * zpool scrub [-s] <pool> ...
3195 *
3196 *	-s	Stop.  Stops any in-progress scrub.
3197 */
3198int
3199zpool_do_scrub(int argc, char **argv)
3200{
3201	int c;
3202	scrub_cbdata_t cb;
3203
3204	cb.cb_type = POOL_SCAN_SCRUB;
3205
3206	/* check options */
3207	while ((c = getopt(argc, argv, "s")) != -1) {
3208		switch (c) {
3209		case 's':
3210			cb.cb_type = POOL_SCAN_NONE;
3211			break;
3212		case '?':
3213			(void) fprintf(stderr, gettext("invalid option '%c'\n"),
3214			    optopt);
3215			usage(B_FALSE);
3216		}
3217	}
3218
3219	cb.cb_argc = argc;
3220	cb.cb_argv = argv;
3221	argc -= optind;
3222	argv += optind;
3223
3224	if (argc < 1) {
3225		(void) fprintf(stderr, gettext("missing pool name argument\n"));
3226		usage(B_FALSE);
3227	}
3228
3229	return (for_each_pool(argc, argv, B_TRUE, NULL, scrub_callback, &cb));
3230}
3231
3232typedef struct status_cbdata {
3233	int		cb_count;
3234	boolean_t	cb_allpools;
3235	boolean_t	cb_verbose;
3236	boolean_t	cb_explain;
3237	boolean_t	cb_first;
3238	boolean_t	cb_dedup_stats;
3239} status_cbdata_t;
3240
3241/*
3242 * Print out detailed scrub status.
3243 */
3244void
3245print_scan_status(pool_scan_stat_t *ps)
3246{
3247	time_t start, end;
3248	uint64_t elapsed, mins_left, hours_left;
3249	uint64_t pass_exam, examined, total;
3250	uint_t rate;
3251	double fraction_done;
3252	char processed_buf[7], examined_buf[7], total_buf[7], rate_buf[7];
3253
3254	(void) printf(gettext(" scan: "));
3255
3256	/* If there's never been a scan, there's not much to say. */
3257	if (ps == NULL || ps->pss_func == POOL_SCAN_NONE ||
3258	    ps->pss_func >= POOL_SCAN_FUNCS) {
3259		(void) printf(gettext("none requested\n"));
3260		return;
3261	}
3262
3263	start = ps->pss_start_time;
3264	end = ps->pss_end_time;
3265	zfs_nicenum(ps->pss_processed, processed_buf, sizeof (processed_buf));
3266
3267	assert(ps->pss_func == POOL_SCAN_SCRUB ||
3268	    ps->pss_func == POOL_SCAN_RESILVER);
3269	/*
3270	 * Scan is finished or canceled.
3271	 */
3272	if (ps->pss_state == DSS_FINISHED) {
3273		uint64_t minutes_taken = (end - start) / 60;
3274		char *fmt;
3275
3276		if (ps->pss_func == POOL_SCAN_SCRUB) {
3277			fmt = gettext("scrub repaired %s in %lluh%um with "
3278			    "%llu errors on %s");
3279		} else if (ps->pss_func == POOL_SCAN_RESILVER) {
3280			fmt = gettext("resilvered %s in %lluh%um with "
3281			    "%llu errors on %s");
3282		}
3283		/* LINTED */
3284		(void) printf(fmt, processed_buf,
3285		    (u_longlong_t)(minutes_taken / 60),
3286		    (uint_t)(minutes_taken % 60),
3287		    (u_longlong_t)ps->pss_errors,
3288		    ctime((time_t *)&end));
3289		return;
3290	} else if (ps->pss_state == DSS_CANCELED) {
3291		if (ps->pss_func == POOL_SCAN_SCRUB) {
3292			(void) printf(gettext("scrub canceled on %s"),
3293			    ctime(&end));
3294		} else if (ps->pss_func == POOL_SCAN_RESILVER) {
3295			(void) printf(gettext("resilver canceled on %s"),
3296			    ctime(&end));
3297		}
3298		return;
3299	}
3300
3301	assert(ps->pss_state == DSS_SCANNING);
3302
3303	/*
3304	 * Scan is in progress.
3305	 */
3306	if (ps->pss_func == POOL_SCAN_SCRUB) {
3307		(void) printf(gettext("scrub in progress since %s"),
3308		    ctime(&start));
3309	} else if (ps->pss_func == POOL_SCAN_RESILVER) {
3310		(void) printf(gettext("resilver in progress since %s"),
3311		    ctime(&start));
3312	}
3313
3314	examined = ps->pss_examined ? ps->pss_examined : 1;
3315	total = ps->pss_to_examine;
3316	fraction_done = (double)examined / total;
3317
3318	/* elapsed time for this pass */
3319	elapsed = time(NULL) - ps->pss_pass_start;
3320	elapsed = elapsed ? elapsed : 1;
3321	pass_exam = ps->pss_pass_exam ? ps->pss_pass_exam : 1;
3322	rate = pass_exam / elapsed;
3323	rate = rate ? rate : 1;
3324	mins_left = ((total - examined) / rate) / 60;
3325	hours_left = mins_left / 60;
3326
3327	zfs_nicenum(examined, examined_buf, sizeof (examined_buf));
3328	zfs_nicenum(total, total_buf, sizeof (total_buf));
3329	zfs_nicenum(rate, rate_buf, sizeof (rate_buf));
3330
3331	/*
3332	 * do not print estimated time if hours_left is more than 30 days
3333	 */
3334	(void) printf(gettext("    %s scanned out of %s at %s/s"),
3335	    examined_buf, total_buf, rate_buf);
3336	if (hours_left < (30 * 24)) {
3337		(void) printf(gettext(", %lluh%um to go\n"),
3338		    (u_longlong_t)hours_left, (uint_t)(mins_left % 60));
3339	} else {
3340		(void) printf(gettext(
3341		    ", (scan is slow, no estimated time)\n"));
3342	}
3343
3344	if (ps->pss_func == POOL_SCAN_RESILVER) {
3345		(void) printf(gettext("    %s resilvered, %.2f%% done\n"),
3346		    processed_buf, 100 * fraction_done);
3347	} else if (ps->pss_func == POOL_SCAN_SCRUB) {
3348		(void) printf(gettext("    %s repaired, %.2f%% done\n"),
3349		    processed_buf, 100 * fraction_done);
3350	}
3351}
3352
3353static void
3354print_error_log(zpool_handle_t *zhp)
3355{
3356	nvlist_t *nverrlist = NULL;
3357	nvpair_t *elem;
3358	char *pathname;
3359	size_t len = MAXPATHLEN * 2;
3360
3361	if (zpool_get_errlog(zhp, &nverrlist) != 0) {
3362		(void) printf("errors: List of errors unavailable "
3363		    "(insufficient privileges)\n");
3364		return;
3365	}
3366
3367	(void) printf("errors: Permanent errors have been "
3368	    "detected in the following files:\n\n");
3369
3370	pathname = safe_malloc(len);
3371	elem = NULL;
3372	while ((elem = nvlist_next_nvpair(nverrlist, elem)) != NULL) {
3373		nvlist_t *nv;
3374		uint64_t dsobj, obj;
3375
3376		verify(nvpair_value_nvlist(elem, &nv) == 0);
3377		verify(nvlist_lookup_uint64(nv, ZPOOL_ERR_DATASET,
3378		    &dsobj) == 0);
3379		verify(nvlist_lookup_uint64(nv, ZPOOL_ERR_OBJECT,
3380		    &obj) == 0);
3381		zpool_obj_to_path(zhp, dsobj, obj, pathname, len);
3382		(void) printf("%7s %s\n", "", pathname);
3383	}
3384	free(pathname);
3385	nvlist_free(nverrlist);
3386}
3387
3388static void
3389print_spares(zpool_handle_t *zhp, nvlist_t **spares, uint_t nspares,
3390    int namewidth)
3391{
3392	uint_t i;
3393	char *name;
3394
3395	if (nspares == 0)
3396		return;
3397
3398	(void) printf(gettext("\tspares\n"));
3399
3400	for (i = 0; i < nspares; i++) {
3401		name = zpool_vdev_name(g_zfs, zhp, spares[i], B_FALSE);
3402		print_status_config(zhp, name, spares[i],
3403		    namewidth, 2, B_TRUE);
3404		free(name);
3405	}
3406}
3407
3408static void
3409print_l2cache(zpool_handle_t *zhp, nvlist_t **l2cache, uint_t nl2cache,
3410    int namewidth)
3411{
3412	uint_t i;
3413	char *name;
3414
3415	if (nl2cache == 0)
3416		return;
3417
3418	(void) printf(gettext("\tcache\n"));
3419
3420	for (i = 0; i < nl2cache; i++) {
3421		name = zpool_vdev_name(g_zfs, zhp, l2cache[i], B_FALSE);
3422		print_status_config(zhp, name, l2cache[i],
3423		    namewidth, 2, B_FALSE);
3424		free(name);
3425	}
3426}
3427
3428static void
3429print_dedup_stats(nvlist_t *config)
3430{
3431	ddt_histogram_t *ddh;
3432	ddt_stat_t *dds;
3433	ddt_object_t *ddo;
3434	uint_t c;
3435
3436	/*
3437	 * If the pool was faulted then we may not have been able to
3438	 * obtain the config. Otherwise, if have anything in the dedup
3439	 * table continue processing the stats.
3440	 */
3441	if (nvlist_lookup_uint64_array(config, ZPOOL_CONFIG_DDT_OBJ_STATS,
3442	    (uint64_t **)&ddo, &c) != 0 || ddo->ddo_count == 0)
3443		return;
3444
3445	(void) printf("\n");
3446	(void) printf("DDT entries %llu, size %llu on disk, %llu in core\n",
3447	    (u_longlong_t)ddo->ddo_count,
3448	    (u_longlong_t)ddo->ddo_dspace,
3449	    (u_longlong_t)ddo->ddo_mspace);
3450
3451	verify(nvlist_lookup_uint64_array(config, ZPOOL_CONFIG_DDT_STATS,
3452	    (uint64_t **)&dds, &c) == 0);
3453	verify(nvlist_lookup_uint64_array(config, ZPOOL_CONFIG_DDT_HISTOGRAM,
3454	    (uint64_t **)&ddh, &c) == 0);
3455	zpool_dump_ddt(dds, ddh);
3456}
3457
3458/*
3459 * Display a summary of pool status.  Displays a summary such as:
3460 *
3461 *        pool: tank
3462 *	status: DEGRADED
3463 *	reason: One or more devices ...
3464 *         see: http://www.sun.com/msg/ZFS-xxxx-01
3465 *	config:
3466 *		mirror		DEGRADED
3467 *                c1t0d0	OK
3468 *                c2t0d0	UNAVAIL
3469 *
3470 * When given the '-v' option, we print out the complete config.  If the '-e'
3471 * option is specified, then we print out error rate information as well.
3472 */
3473int
3474status_callback(zpool_handle_t *zhp, void *data)
3475{
3476	status_cbdata_t *cbp = data;
3477	nvlist_t *config, *nvroot;
3478	char *msgid;
3479	int reason;
3480	const char *health;
3481	uint_t c;
3482	vdev_stat_t *vs;
3483
3484	config = zpool_get_config(zhp, NULL);
3485	reason = zpool_get_status(zhp, &msgid);
3486
3487	cbp->cb_count++;
3488
3489	/*
3490	 * If we were given 'zpool status -x', only report those pools with
3491	 * problems.
3492	 */
3493	if (reason == ZPOOL_STATUS_OK && cbp->cb_explain) {
3494		if (!cbp->cb_allpools) {
3495			(void) printf(gettext("pool '%s' is healthy\n"),
3496			    zpool_get_name(zhp));
3497			if (cbp->cb_first)
3498				cbp->cb_first = B_FALSE;
3499		}
3500		return (0);
3501	}
3502
3503	if (cbp->cb_first)
3504		cbp->cb_first = B_FALSE;
3505	else
3506		(void) printf("\n");
3507
3508	verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
3509	    &nvroot) == 0);
3510	verify(nvlist_lookup_uint64_array(nvroot, ZPOOL_CONFIG_VDEV_STATS,
3511	    (uint64_t **)&vs, &c) == 0);
3512	health = zpool_state_to_name(vs->vs_state, vs->vs_aux);
3513
3514	(void) printf(gettext("  pool: %s\n"), zpool_get_name(zhp));
3515	(void) printf(gettext(" state: %s\n"), health);
3516
3517	switch (reason) {
3518	case ZPOOL_STATUS_MISSING_DEV_R:
3519		(void) printf(gettext("status: One or more devices could not "
3520		    "be opened.  Sufficient replicas exist for\n\tthe pool to "
3521		    "continue functioning in a degraded state.\n"));
3522		(void) printf(gettext("action: Attach the missing device and "
3523		    "online it using 'zpool online'.\n"));
3524		break;
3525
3526	case ZPOOL_STATUS_MISSING_DEV_NR:
3527		(void) printf(gettext("status: One or more devices could not "
3528		    "be opened.  There are insufficient\n\treplicas for the "
3529		    "pool to continue functioning.\n"));
3530		(void) printf(gettext("action: Attach the missing device and "
3531		    "online it using 'zpool online'.\n"));
3532		break;
3533
3534	case ZPOOL_STATUS_CORRUPT_LABEL_R:
3535		(void) printf(gettext("status: One or more devices could not "
3536		    "be used because the label is missing or\n\tinvalid.  "
3537		    "Sufficient replicas exist for the pool to continue\n\t"
3538		    "functioning in a degraded state.\n"));
3539		(void) printf(gettext("action: Replace the device using "
3540		    "'zpool replace'.\n"));
3541		break;
3542
3543	case ZPOOL_STATUS_CORRUPT_LABEL_NR:
3544		(void) printf(gettext("status: One or more devices could not "
3545		    "be used because the label is missing \n\tor invalid.  "
3546		    "There are insufficient replicas for the pool to "
3547		    "continue\n\tfunctioning.\n"));
3548		zpool_explain_recover(zpool_get_handle(zhp),
3549		    zpool_get_name(zhp), reason, config);
3550		break;
3551
3552	case ZPOOL_STATUS_FAILING_DEV:
3553		(void) printf(gettext("status: One or more devices has "
3554		    "experienced an unrecoverable error.  An\n\tattempt was "
3555		    "made to correct the error.  Applications are "
3556		    "unaffected.\n"));
3557		(void) printf(gettext("action: Determine if the device needs "
3558		    "to be replaced, and clear the errors\n\tusing "
3559		    "'zpool clear' or replace the device with 'zpool "
3560		    "replace'.\n"));
3561		break;
3562
3563	case ZPOOL_STATUS_OFFLINE_DEV:
3564		(void) printf(gettext("status: One or more devices has "
3565		    "been taken offline by the administrator.\n\tSufficient "
3566		    "replicas exist for the pool to continue functioning in "
3567		    "a\n\tdegraded state.\n"));
3568		(void) printf(gettext("action: Online the device using "
3569		    "'zpool online' or replace the device with\n\t'zpool "
3570		    "replace'.\n"));
3571		break;
3572
3573	case ZPOOL_STATUS_REMOVED_DEV:
3574		(void) printf(gettext("status: One or more devices has "
3575		    "been removed by the administrator.\n\tSufficient "
3576		    "replicas exist for the pool to continue functioning in "
3577		    "a\n\tdegraded state.\n"));
3578		(void) printf(gettext("action: Online the device using "
3579		    "'zpool online' or replace the device with\n\t'zpool "
3580		    "replace'.\n"));
3581		break;
3582
3583	case ZPOOL_STATUS_RESILVERING:
3584		(void) printf(gettext("status: One or more devices is "
3585		    "currently being resilvered.  The pool will\n\tcontinue "
3586		    "to function, possibly in a degraded state.\n"));
3587		(void) printf(gettext("action: Wait for the resilver to "
3588		    "complete.\n"));
3589		break;
3590
3591	case ZPOOL_STATUS_CORRUPT_DATA:
3592		(void) printf(gettext("status: One or more devices has "
3593		    "experienced an error resulting in data\n\tcorruption.  "
3594		    "Applications may be affected.\n"));
3595		(void) printf(gettext("action: Restore the file in question "
3596		    "if possible.  Otherwise restore the\n\tentire pool from "
3597		    "backup.\n"));
3598		break;
3599
3600	case ZPOOL_STATUS_CORRUPT_POOL:
3601		(void) printf(gettext("status: The pool metadata is corrupted "
3602		    "and the pool cannot be opened.\n"));
3603		zpool_explain_recover(zpool_get_handle(zhp),
3604		    zpool_get_name(zhp), reason, config);
3605		break;
3606
3607	case ZPOOL_STATUS_VERSION_OLDER:
3608		(void) printf(gettext("status: The pool is formatted using an "
3609		    "older on-disk format.  The pool can\n\tstill be used, but "
3610		    "some features are unavailable.\n"));
3611		(void) printf(gettext("action: Upgrade the pool using 'zpool "
3612		    "upgrade'.  Once this is done, the\n\tpool will no longer "
3613		    "be accessible on older software versions.\n"));
3614		break;
3615
3616	case ZPOOL_STATUS_VERSION_NEWER:
3617		(void) printf(gettext("status: The pool has been upgraded to a "
3618		    "newer, incompatible on-disk version.\n\tThe pool cannot "
3619		    "be accessed on this system.\n"));
3620		(void) printf(gettext("action: Access the pool from a system "
3621		    "running more recent software, or\n\trestore the pool from "
3622		    "backup.\n"));
3623		break;
3624
3625	case ZPOOL_STATUS_FAULTED_DEV_R:
3626		(void) printf(gettext("status: One or more devices are "
3627		    "faulted in response to persistent errors.\n\tSufficient "
3628		    "replicas exist for the pool to continue functioning "
3629		    "in a\n\tdegraded state.\n"));
3630		(void) printf(gettext("action: Replace the faulted device, "
3631		    "or use 'zpool clear' to mark the device\n\trepaired.\n"));
3632		break;
3633
3634	case ZPOOL_STATUS_FAULTED_DEV_NR:
3635		(void) printf(gettext("status: One or more devices are "
3636		    "faulted in response to persistent errors.  There are "
3637		    "insufficient replicas for the pool to\n\tcontinue "
3638		    "functioning.\n"));
3639		(void) printf(gettext("action: Destroy and re-create the pool "
3640		    "from a backup source.  Manually marking the device\n"
3641		    "\trepaired using 'zpool clear' may allow some data "
3642		    "to be recovered.\n"));
3643		break;
3644
3645	case ZPOOL_STATUS_IO_FAILURE_WAIT:
3646	case ZPOOL_STATUS_IO_FAILURE_CONTINUE:
3647		(void) printf(gettext("status: One or more devices are "
3648		    "faulted in response to IO failures.\n"));
3649		(void) printf(gettext("action: Make sure the affected devices "
3650		    "are connected, then run 'zpool clear'.\n"));
3651		break;
3652
3653	case ZPOOL_STATUS_BAD_LOG:
3654		(void) printf(gettext("status: An intent log record "
3655		    "could not be read.\n"
3656		    "\tWaiting for adminstrator intervention to fix the "
3657		    "faulted pool.\n"));
3658		(void) printf(gettext("action: Either restore the affected "
3659		    "device(s) and run 'zpool online',\n"
3660		    "\tor ignore the intent log records by running "
3661		    "'zpool clear'.\n"));
3662		break;
3663
3664	default:
3665		/*
3666		 * The remaining errors can't actually be generated, yet.
3667		 */
3668		assert(reason == ZPOOL_STATUS_OK);
3669	}
3670
3671	if (msgid != NULL)
3672		(void) printf(gettext("   see: http://www.sun.com/msg/%s\n"),
3673		    msgid);
3674
3675	if (config != NULL) {
3676		int namewidth;
3677		uint64_t nerr;
3678		nvlist_t **spares, **l2cache;
3679		uint_t nspares, nl2cache;
3680		pool_scan_stat_t *ps = NULL;
3681
3682		(void) nvlist_lookup_uint64_array(nvroot,
3683		    ZPOOL_CONFIG_SCAN_STATS, (uint64_t **)&ps, &c);
3684		print_scan_status(ps);
3685
3686		namewidth = max_width(zhp, nvroot, 0, 0);
3687		if (namewidth < 10)
3688			namewidth = 10;
3689
3690		(void) printf(gettext("config:\n\n"));
3691		(void) printf(gettext("\t%-*s  %-8s %5s %5s %5s\n"), namewidth,
3692		    "NAME", "STATE", "READ", "WRITE", "CKSUM");
3693		print_status_config(zhp, zpool_get_name(zhp), nvroot,
3694		    namewidth, 0, B_FALSE);
3695
3696		if (num_logs(nvroot) > 0)
3697			print_logs(zhp, nvroot, namewidth, B_TRUE);
3698		if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_L2CACHE,
3699		    &l2cache, &nl2cache) == 0)
3700			print_l2cache(zhp, l2cache, nl2cache, namewidth);
3701
3702		if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_SPARES,
3703		    &spares, &nspares) == 0)
3704			print_spares(zhp, spares, nspares, namewidth);
3705
3706		if (nvlist_lookup_uint64(config, ZPOOL_CONFIG_ERRCOUNT,
3707		    &nerr) == 0) {
3708			nvlist_t *nverrlist = NULL;
3709
3710			/*
3711			 * If the approximate error count is small, get a
3712			 * precise count by fetching the entire log and
3713			 * uniquifying the results.
3714			 */
3715			if (nerr > 0 && nerr < 100 && !cbp->cb_verbose &&
3716			    zpool_get_errlog(zhp, &nverrlist) == 0) {
3717				nvpair_t *elem;
3718
3719				elem = NULL;
3720				nerr = 0;
3721				while ((elem = nvlist_next_nvpair(nverrlist,
3722				    elem)) != NULL) {
3723					nerr++;
3724				}
3725			}
3726			nvlist_free(nverrlist);
3727
3728			(void) printf("\n");
3729
3730			if (nerr == 0)
3731				(void) printf(gettext("errors: No known data "
3732				    "errors\n"));
3733			else if (!cbp->cb_verbose)
3734				(void) printf(gettext("errors: %llu data "
3735				    "errors, use '-v' for a list\n"),
3736				    (u_longlong_t)nerr);
3737			else
3738				print_error_log(zhp);
3739		}
3740
3741		if (cbp->cb_dedup_stats)
3742			print_dedup_stats(config);
3743	} else {
3744		(void) printf(gettext("config: The configuration cannot be "
3745		    "determined.\n"));
3746	}
3747
3748	return (0);
3749}
3750
3751/*
3752 * zpool status [-vx] [-T d|u] [pool] ... [interval [count]]
3753 *
3754 *	-v	Display complete error logs
3755 *	-x	Display only pools with potential problems
3756 *	-D	Display dedup status (undocumented)
3757 *	-T	Display a timestamp in date(1) or Unix format
3758 *
3759 * Describes the health status of all pools or some subset.
3760 */
3761int
3762zpool_do_status(int argc, char **argv)
3763{
3764	int c;
3765	int ret;
3766	unsigned long interval = 0, count = 0;
3767	status_cbdata_t cb = { 0 };
3768
3769	/* check options */
3770	while ((c = getopt(argc, argv, "vxDT:")) != -1) {
3771		switch (c) {
3772		case 'v':
3773			cb.cb_verbose = B_TRUE;
3774			break;
3775		case 'x':
3776			cb.cb_explain = B_TRUE;
3777			break;
3778		case 'D':
3779			cb.cb_dedup_stats = B_TRUE;
3780			break;
3781		case 'T':
3782			get_timestamp_arg(*optarg);
3783			break;
3784		case '?':
3785			(void) fprintf(stderr, gettext("invalid option '%c'\n"),
3786			    optopt);
3787			usage(B_FALSE);
3788		}
3789	}
3790
3791	argc -= optind;
3792	argv += optind;
3793
3794	get_interval_count(&argc, argv, &interval, &count);
3795
3796	if (argc == 0)
3797		cb.cb_allpools = B_TRUE;
3798
3799	cb.cb_first = B_TRUE;
3800
3801	for (;;) {
3802		if (timestamp_fmt != NODATE)
3803			print_timestamp(timestamp_fmt);
3804
3805		ret = for_each_pool(argc, argv, B_TRUE, NULL,
3806		    status_callback, &cb);
3807
3808		if (argc == 0 && cb.cb_count == 0)
3809			(void) printf(gettext("no pools available\n"));
3810		else if (cb.cb_explain && cb.cb_first && cb.cb_allpools)
3811			(void) printf(gettext("all pools are healthy\n"));
3812
3813		if (ret != 0)
3814			return (ret);
3815
3816		if (interval == 0)
3817			break;
3818
3819		if (count != 0 && --count == 0)
3820			break;
3821
3822		(void) sleep(interval);
3823	}
3824
3825	return (0);
3826}
3827
3828typedef struct upgrade_cbdata {
3829	int	cb_all;
3830	int	cb_first;
3831	int	cb_newer;
3832	char	cb_poolname[ZPOOL_MAXNAMELEN];
3833	int	cb_argc;
3834	uint64_t cb_version;
3835	char	**cb_argv;
3836} upgrade_cbdata_t;
3837
3838static int
3839is_root_pool(zpool_handle_t *zhp)
3840{
3841	static struct statfs sfs;
3842	static char *poolname = NULL;
3843	static boolean_t stated = B_FALSE;
3844	char *slash;
3845
3846	if (!stated) {
3847		stated = B_TRUE;
3848		if (statfs("/", &sfs) == -1) {
3849			(void) fprintf(stderr,
3850			    "Unable to stat root file system: %s.\n",
3851			    strerror(errno));
3852			return (0);
3853		}
3854		if (strcmp(sfs.f_fstypename, "zfs") != 0)
3855			return (0);
3856		poolname = sfs.f_mntfromname;
3857		if ((slash = strchr(poolname, '/')) != NULL)
3858			*slash = '\0';
3859	}
3860	return (poolname != NULL && strcmp(poolname, zpool_get_name(zhp)) == 0);
3861}
3862
3863static int
3864upgrade_cb(zpool_handle_t *zhp, void *arg)
3865{
3866	upgrade_cbdata_t *cbp = arg;
3867	nvlist_t *config;
3868	uint64_t version;
3869	int ret = 0;
3870
3871	config = zpool_get_config(zhp, NULL);
3872	verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION,
3873	    &version) == 0);
3874
3875	if (!cbp->cb_newer && version < SPA_VERSION) {
3876		if (!cbp->cb_all) {
3877			if (cbp->cb_first) {
3878				(void) printf(gettext("The following pools are "
3879				    "out of date, and can be upgraded.  After "
3880				    "being\nupgraded, these pools will no "
3881				    "longer be accessible by older software "
3882				    "versions.\n\n"));
3883				(void) printf(gettext("VER  POOL\n"));
3884				(void) printf(gettext("---  ------------\n"));
3885				cbp->cb_first = B_FALSE;
3886			}
3887
3888			(void) printf("%2llu   %s\n", (u_longlong_t)version,
3889			    zpool_get_name(zhp));
3890		} else {
3891			cbp->cb_first = B_FALSE;
3892			ret = zpool_upgrade(zhp, cbp->cb_version);
3893			if (!ret) {
3894				(void) printf(gettext("Successfully upgraded "
3895				    "'%s'\n\n"), zpool_get_name(zhp));
3896				if (cbp->cb_poolname[0] == '\0' &&
3897				    is_root_pool(zhp)) {
3898					(void) strlcpy(cbp->cb_poolname,
3899					    zpool_get_name(zhp),
3900					    sizeof(cbp->cb_poolname));
3901				}
3902			}
3903		}
3904	} else if (cbp->cb_newer && version > SPA_VERSION) {
3905		assert(!cbp->cb_all);
3906
3907		if (cbp->cb_first) {
3908			(void) printf(gettext("The following pools are "
3909			    "formatted using a newer software version and\n"
3910			    "cannot be accessed on the current system.\n\n"));
3911			(void) printf(gettext("VER  POOL\n"));
3912			(void) printf(gettext("---  ------------\n"));
3913			cbp->cb_first = B_FALSE;
3914		}
3915
3916		(void) printf("%2llu   %s\n", (u_longlong_t)version,
3917		    zpool_get_name(zhp));
3918	}
3919
3920	zpool_close(zhp);
3921	return (ret);
3922}
3923
3924/* ARGSUSED */
3925static int
3926upgrade_one(zpool_handle_t *zhp, void *data)
3927{
3928	upgrade_cbdata_t *cbp = data;
3929	uint64_t cur_version;
3930	int ret;
3931
3932	if (strcmp("log", zpool_get_name(zhp)) == 0) {
3933		(void) printf(gettext("'log' is now a reserved word\n"
3934		    "Pool 'log' must be renamed using export and import"
3935		    " to upgrade.\n"));
3936		return (1);
3937	}
3938
3939	cur_version = zpool_get_prop_int(zhp, ZPOOL_PROP_VERSION, NULL);
3940	if (cur_version > cbp->cb_version) {
3941		(void) printf(gettext("Pool '%s' is already formatted "
3942		    "using more current version '%llu'.\n"),
3943		    zpool_get_name(zhp), cur_version);
3944		return (0);
3945	}
3946	if (cur_version == cbp->cb_version) {
3947		(void) printf(gettext("Pool '%s' is already formatted "
3948		    "using the current version.\n"), zpool_get_name(zhp));
3949		return (0);
3950	}
3951
3952	ret = zpool_upgrade(zhp, cbp->cb_version);
3953
3954	if (!ret) {
3955		(void) printf(gettext("Successfully upgraded '%s' "
3956		    "from version %llu to version %llu\n\n"),
3957		    zpool_get_name(zhp), (u_longlong_t)cur_version,
3958		    (u_longlong_t)cbp->cb_version);
3959		if (cbp->cb_poolname[0] == '\0' && is_root_pool(zhp)) {
3960			(void) strlcpy(cbp->cb_poolname, zpool_get_name(zhp),
3961			    sizeof(cbp->cb_poolname));
3962		}
3963	}
3964
3965	return (ret != 0);
3966}
3967
3968/*
3969 * zpool upgrade
3970 * zpool upgrade -v
3971 * zpool upgrade [-V version] <-a | pool ...>
3972 *
3973 * With no arguments, display downrev'd ZFS pool available for upgrade.
3974 * Individual pools can be upgraded by specifying the pool, and '-a' will
3975 * upgrade all pools.
3976 */
3977int
3978zpool_do_upgrade(int argc, char **argv)
3979{
3980	int c;
3981	upgrade_cbdata_t cb = { 0 };
3982	int ret = 0;
3983	boolean_t showversions = B_FALSE;
3984	char *end;
3985
3986
3987	/* check options */
3988	while ((c = getopt(argc, argv, ":avV:")) != -1) {
3989		switch (c) {
3990		case 'a':
3991			cb.cb_all = B_TRUE;
3992			break;
3993		case 'v':
3994			showversions = B_TRUE;
3995			break;
3996		case 'V':
3997			cb.cb_version = strtoll(optarg, &end, 10);
3998			if (*end != '\0' || cb.cb_version > SPA_VERSION ||
3999			    cb.cb_version < SPA_VERSION_1) {
4000				(void) fprintf(stderr,
4001				    gettext("invalid version '%s'\n"), optarg);
4002				usage(B_FALSE);
4003			}
4004			break;
4005		case ':':
4006			(void) fprintf(stderr, gettext("missing argument for "
4007			    "'%c' option\n"), optopt);
4008			usage(B_FALSE);
4009			break;
4010		case '?':
4011			(void) fprintf(stderr, gettext("invalid option '%c'\n"),
4012			    optopt);
4013			usage(B_FALSE);
4014		}
4015	}
4016
4017	cb.cb_argc = argc;
4018	cb.cb_argv = argv;
4019	argc -= optind;
4020	argv += optind;
4021
4022	if (cb.cb_version == 0) {
4023		cb.cb_version = SPA_VERSION;
4024	} else if (!cb.cb_all && argc == 0) {
4025		(void) fprintf(stderr, gettext("-V option is "
4026		    "incompatible with other arguments\n"));
4027		usage(B_FALSE);
4028	}
4029
4030	if (showversions) {
4031		if (cb.cb_all || argc != 0) {
4032			(void) fprintf(stderr, gettext("-v option is "
4033			    "incompatible with other arguments\n"));
4034			usage(B_FALSE);
4035		}
4036	} else if (cb.cb_all) {
4037		if (argc != 0) {
4038			(void) fprintf(stderr, gettext("-a option should not "
4039			    "be used along with a pool name\n"));
4040			usage(B_FALSE);
4041		}
4042	}
4043
4044	(void) printf(gettext("This system is currently running "
4045	    "ZFS pool version %llu.\n\n"), SPA_VERSION);
4046	cb.cb_first = B_TRUE;
4047	if (showversions) {
4048		(void) printf(gettext("The following versions are "
4049		    "supported:\n\n"));
4050		(void) printf(gettext("VER  DESCRIPTION\n"));
4051		(void) printf("---  -----------------------------------------"
4052		    "---------------\n");
4053		(void) printf(gettext(" 1   Initial ZFS version\n"));
4054		(void) printf(gettext(" 2   Ditto blocks "
4055		    "(replicated metadata)\n"));
4056		(void) printf(gettext(" 3   Hot spares and double parity "
4057		    "RAID-Z\n"));
4058		(void) printf(gettext(" 4   zpool history\n"));
4059		(void) printf(gettext(" 5   Compression using the gzip "
4060		    "algorithm\n"));
4061		(void) printf(gettext(" 6   bootfs pool property\n"));
4062		(void) printf(gettext(" 7   Separate intent log devices\n"));
4063		(void) printf(gettext(" 8   Delegated administration\n"));
4064		(void) printf(gettext(" 9   refquota and refreservation "
4065		    "properties\n"));
4066		(void) printf(gettext(" 10  Cache devices\n"));
4067		(void) printf(gettext(" 11  Improved scrub performance\n"));
4068		(void) printf(gettext(" 12  Snapshot properties\n"));
4069		(void) printf(gettext(" 13  snapused property\n"));
4070		(void) printf(gettext(" 14  passthrough-x aclinherit\n"));
4071		(void) printf(gettext(" 15  user/group space accounting\n"));
4072		(void) printf(gettext(" 16  stmf property support\n"));
4073		(void) printf(gettext(" 17  Triple-parity RAID-Z\n"));
4074		(void) printf(gettext(" 18  Snapshot user holds\n"));
4075		(void) printf(gettext(" 19  Log device removal\n"));
4076		(void) printf(gettext(" 20  Compression using zle "
4077		    "(zero-length encoding)\n"));
4078		(void) printf(gettext(" 21  Deduplication\n"));
4079		(void) printf(gettext(" 22  Received properties\n"));
4080		(void) printf(gettext(" 23  Slim ZIL\n"));
4081		(void) printf(gettext(" 24  System attributes\n"));
4082		(void) printf(gettext(" 25  Improved scrub stats\n"));
4083		(void) printf(gettext(" 26  Improved snapshot deletion "
4084		    "performance\n"));
4085		(void) printf(gettext(" 27  Improved snapshot creation "
4086		    "performance\n"));
4087		(void) printf(gettext(" 28  Multiple vdev replacements\n"));
4088		(void) printf(gettext("\nFor more information on a particular "
4089		    "version, including supported releases,\n"));
4090		(void) printf(gettext("see the ZFS Administration Guide.\n\n"));
4091	} else if (argc == 0) {
4092		int notfound;
4093
4094		ret = zpool_iter(g_zfs, upgrade_cb, &cb);
4095		notfound = cb.cb_first;
4096
4097		if (!cb.cb_all && ret == 0) {
4098			if (!cb.cb_first)
4099				(void) printf("\n");
4100			cb.cb_first = B_TRUE;
4101			cb.cb_newer = B_TRUE;
4102			ret = zpool_iter(g_zfs, upgrade_cb, &cb);
4103			if (!cb.cb_first) {
4104				notfound = B_FALSE;
4105				(void) printf("\n");
4106			}
4107		}
4108
4109		if (ret == 0) {
4110			if (notfound)
4111				(void) printf(gettext("All pools are formatted "
4112				    "using this version.\n"));
4113			else if (!cb.cb_all)
4114				(void) printf(gettext("Use 'zpool upgrade -v' "
4115				    "for a list of available versions and "
4116				    "their associated\nfeatures.\n"));
4117		}
4118	} else {
4119		ret = for_each_pool(argc, argv, B_FALSE, NULL,
4120		    upgrade_one, &cb);
4121	}
4122
4123	if (cb.cb_poolname[0] != '\0') {
4124		(void) printf(
4125		    "If you boot from pool '%s', don't forget to update boot code.\n"
4126		    "Assuming you use GPT partitioning and da0 is your boot disk\n"
4127		    "the following command will do it:\n"
4128		    "\n"
4129		    "\tgpart bootcode -b /boot/pmbr -p /boot/gptzfsboot -i 1 da0\n\n",
4130		    cb.cb_poolname);
4131	}
4132
4133	return (ret);
4134}
4135
4136typedef struct hist_cbdata {
4137	boolean_t first;
4138	int longfmt;
4139	int internal;
4140} hist_cbdata_t;
4141
4142/*
4143 * Print out the command history for a specific pool.
4144 */
4145static int
4146get_history_one(zpool_handle_t *zhp, void *data)
4147{
4148	nvlist_t *nvhis;
4149	nvlist_t **records;
4150	uint_t numrecords;
4151	char *cmdstr;
4152	char *pathstr;
4153	uint64_t dst_time;
4154	time_t tsec;
4155	struct tm t;
4156	char tbuf[30];
4157	int ret, i;
4158	uint64_t who;
4159	struct passwd *pwd;
4160	char *hostname;
4161	char *zonename;
4162	char internalstr[MAXPATHLEN];
4163	hist_cbdata_t *cb = (hist_cbdata_t *)data;
4164	uint64_t txg;
4165	uint64_t ievent;
4166
4167	cb->first = B_FALSE;
4168
4169	(void) printf(gettext("History for '%s':\n"), zpool_get_name(zhp));
4170
4171	if ((ret = zpool_get_history(zhp, &nvhis)) != 0)
4172		return (ret);
4173
4174	verify(nvlist_lookup_nvlist_array(nvhis, ZPOOL_HIST_RECORD,
4175	    &records, &numrecords) == 0);
4176	for (i = 0; i < numrecords; i++) {
4177		if (nvlist_lookup_uint64(records[i], ZPOOL_HIST_TIME,
4178		    &dst_time) != 0)
4179			continue;
4180
4181		/* is it an internal event or a standard event? */
4182		if (nvlist_lookup_string(records[i], ZPOOL_HIST_CMD,
4183		    &cmdstr) != 0) {
4184			if (cb->internal == 0)
4185				continue;
4186
4187			if (nvlist_lookup_uint64(records[i],
4188			    ZPOOL_HIST_INT_EVENT, &ievent) != 0)
4189				continue;
4190			verify(nvlist_lookup_uint64(records[i],
4191			    ZPOOL_HIST_TXG, &txg) == 0);
4192			verify(nvlist_lookup_string(records[i],
4193			    ZPOOL_HIST_INT_STR, &pathstr) == 0);
4194			if (ievent >= LOG_END)
4195				continue;
4196			(void) snprintf(internalstr,
4197			    sizeof (internalstr),
4198			    "[internal %s txg:%lld] %s",
4199			    zfs_history_event_names[ievent], txg,
4200			    pathstr);
4201			cmdstr = internalstr;
4202		}
4203		tsec = dst_time;
4204		(void) localtime_r(&tsec, &t);
4205		(void) strftime(tbuf, sizeof (tbuf), "%F.%T", &t);
4206		(void) printf("%s %s", tbuf, cmdstr);
4207
4208		if (!cb->longfmt) {
4209			(void) printf("\n");
4210			continue;
4211		}
4212		(void) printf(" [");
4213		if (nvlist_lookup_uint64(records[i],
4214		    ZPOOL_HIST_WHO, &who) == 0) {
4215			pwd = getpwuid((uid_t)who);
4216			if (pwd)
4217				(void) printf("user %s on",
4218				    pwd->pw_name);
4219			else
4220				(void) printf("user %d on",
4221				    (int)who);
4222		} else {
4223			(void) printf(gettext("no info]\n"));
4224			continue;
4225		}
4226		if (nvlist_lookup_string(records[i],
4227		    ZPOOL_HIST_HOST, &hostname) == 0) {
4228			(void) printf(" %s", hostname);
4229		}
4230		if (nvlist_lookup_string(records[i],
4231		    ZPOOL_HIST_ZONE, &zonename) == 0) {
4232			(void) printf(":%s", zonename);
4233		}
4234
4235		(void) printf("]");
4236		(void) printf("\n");
4237	}
4238	(void) printf("\n");
4239	nvlist_free(nvhis);
4240
4241	return (ret);
4242}
4243
4244/*
4245 * zpool history <pool>
4246 *
4247 * Displays the history of commands that modified pools.
4248 */
4249
4250
4251int
4252zpool_do_history(int argc, char **argv)
4253{
4254	hist_cbdata_t cbdata = { 0 };
4255	int ret;
4256	int c;
4257
4258	cbdata.first = B_TRUE;
4259	/* check options */
4260	while ((c = getopt(argc, argv, "li")) != -1) {
4261		switch (c) {
4262		case 'l':
4263			cbdata.longfmt = 1;
4264			break;
4265		case 'i':
4266			cbdata.internal = 1;
4267			break;
4268		case '?':
4269			(void) fprintf(stderr, gettext("invalid option '%c'\n"),
4270			    optopt);
4271			usage(B_FALSE);
4272		}
4273	}
4274	argc -= optind;
4275	argv += optind;
4276
4277	ret = for_each_pool(argc, argv, B_FALSE,  NULL, get_history_one,
4278	    &cbdata);
4279
4280	if (argc == 0 && cbdata.first == B_TRUE) {
4281		(void) printf(gettext("no pools available\n"));
4282		return (0);
4283	}
4284
4285	return (ret);
4286}
4287
4288static int
4289get_callback(zpool_handle_t *zhp, void *data)
4290{
4291	zprop_get_cbdata_t *cbp = (zprop_get_cbdata_t *)data;
4292	char value[MAXNAMELEN];
4293	zprop_source_t srctype;
4294	zprop_list_t *pl;
4295
4296	for (pl = cbp->cb_proplist; pl != NULL; pl = pl->pl_next) {
4297
4298		/*
4299		 * Skip the special fake placeholder. This will also skip
4300		 * over the name property when 'all' is specified.
4301		 */
4302		if (pl->pl_prop == ZPOOL_PROP_NAME &&
4303		    pl == cbp->cb_proplist)
4304			continue;
4305
4306		if (zpool_get_prop(zhp, pl->pl_prop,
4307		    value, sizeof (value), &srctype) != 0)
4308			continue;
4309
4310		zprop_print_one_property(zpool_get_name(zhp), cbp,
4311		    zpool_prop_to_name(pl->pl_prop), value, srctype, NULL,
4312		    NULL);
4313	}
4314	return (0);
4315}
4316
4317int
4318zpool_do_get(int argc, char **argv)
4319{
4320	zprop_get_cbdata_t cb = { 0 };
4321	zprop_list_t fake_name = { 0 };
4322	int ret;
4323
4324	if (argc < 3)
4325		usage(B_FALSE);
4326
4327	cb.cb_first = B_TRUE;
4328	cb.cb_sources = ZPROP_SRC_ALL;
4329	cb.cb_columns[0] = GET_COL_NAME;
4330	cb.cb_columns[1] = GET_COL_PROPERTY;
4331	cb.cb_columns[2] = GET_COL_VALUE;
4332	cb.cb_columns[3] = GET_COL_SOURCE;
4333	cb.cb_type = ZFS_TYPE_POOL;
4334
4335	if (zprop_get_list(g_zfs, argv[1],  &cb.cb_proplist,
4336	    ZFS_TYPE_POOL) != 0)
4337		usage(B_FALSE);
4338
4339	if (cb.cb_proplist != NULL) {
4340		fake_name.pl_prop = ZPOOL_PROP_NAME;
4341		fake_name.pl_width = strlen(gettext("NAME"));
4342		fake_name.pl_next = cb.cb_proplist;
4343		cb.cb_proplist = &fake_name;
4344	}
4345
4346	ret = for_each_pool(argc - 2, argv + 2, B_TRUE, &cb.cb_proplist,
4347	    get_callback, &cb);
4348
4349	if (cb.cb_proplist == &fake_name)
4350		zprop_free_list(fake_name.pl_next);
4351	else
4352		zprop_free_list(cb.cb_proplist);
4353
4354	return (ret);
4355}
4356
4357typedef struct set_cbdata {
4358	char *cb_propname;
4359	char *cb_value;
4360	boolean_t cb_any_successful;
4361} set_cbdata_t;
4362
4363int
4364set_callback(zpool_handle_t *zhp, void *data)
4365{
4366	int error;
4367	set_cbdata_t *cb = (set_cbdata_t *)data;
4368
4369	error = zpool_set_prop(zhp, cb->cb_propname, cb->cb_value);
4370
4371	if (!error)
4372		cb->cb_any_successful = B_TRUE;
4373
4374	return (error);
4375}
4376
4377int
4378zpool_do_set(int argc, char **argv)
4379{
4380	set_cbdata_t cb = { 0 };
4381	int error;
4382
4383	if (argc > 1 && argv[1][0] == '-') {
4384		(void) fprintf(stderr, gettext("invalid option '%c'\n"),
4385		    argv[1][1]);
4386		usage(B_FALSE);
4387	}
4388
4389	if (argc < 2) {
4390		(void) fprintf(stderr, gettext("missing property=value "
4391		    "argument\n"));
4392		usage(B_FALSE);
4393	}
4394
4395	if (argc < 3) {
4396		(void) fprintf(stderr, gettext("missing pool name\n"));
4397		usage(B_FALSE);
4398	}
4399
4400	if (argc > 3) {
4401		(void) fprintf(stderr, gettext("too many pool names\n"));
4402		usage(B_FALSE);
4403	}
4404
4405	cb.cb_propname = argv[1];
4406	cb.cb_value = strchr(cb.cb_propname, '=');
4407	if (cb.cb_value == NULL) {
4408		(void) fprintf(stderr, gettext("missing value in "
4409		    "property=value argument\n"));
4410		usage(B_FALSE);
4411	}
4412
4413	*(cb.cb_value) = '\0';
4414	cb.cb_value++;
4415
4416	error = for_each_pool(argc - 2, argv + 2, B_TRUE, NULL,
4417	    set_callback, &cb);
4418
4419	return (error);
4420}
4421
4422static int
4423find_command_idx(char *command, int *idx)
4424{
4425	int i;
4426
4427	for (i = 0; i < NCOMMAND; i++) {
4428		if (command_table[i].name == NULL)
4429			continue;
4430
4431		if (strcmp(command, command_table[i].name) == 0) {
4432			*idx = i;
4433			return (0);
4434		}
4435	}
4436	return (1);
4437}
4438
4439int
4440main(int argc, char **argv)
4441{
4442	int ret;
4443	int i;
4444	char *cmdname;
4445
4446	(void) setlocale(LC_ALL, "");
4447	(void) textdomain(TEXT_DOMAIN);
4448
4449	if ((g_zfs = libzfs_init()) == NULL) {
4450		(void) fprintf(stderr, gettext("internal error: failed to "
4451		    "initialize ZFS library\n"));
4452		return (1);
4453	}
4454
4455	libzfs_print_on_error(g_zfs, B_TRUE);
4456
4457	opterr = 0;
4458
4459	/*
4460	 * Make sure the user has specified some command.
4461	 */
4462	if (argc < 2) {
4463		(void) fprintf(stderr, gettext("missing command\n"));
4464		usage(B_FALSE);
4465	}
4466
4467	cmdname = argv[1];
4468
4469	/*
4470	 * Special case '-?'
4471	 */
4472	if (strcmp(cmdname, "-?") == 0)
4473		usage(B_TRUE);
4474
4475	zpool_set_history_str("zpool", argc, argv, history_str);
4476	verify(zpool_stage_history(g_zfs, history_str) == 0);
4477
4478	/*
4479	 * Run the appropriate command.
4480	 */
4481	if (find_command_idx(cmdname, &i) == 0) {
4482		current_command = &command_table[i];
4483		ret = command_table[i].func(argc - 1, argv + 1);
4484	} else if (strchr(cmdname, '=')) {
4485		verify(find_command_idx("set", &i) == 0);
4486		current_command = &command_table[i];
4487		ret = command_table[i].func(argc, argv);
4488	} else if (strcmp(cmdname, "freeze") == 0 && argc == 3) {
4489		/*
4490		 * 'freeze' is a vile debugging abomination, so we treat
4491		 * it as such.
4492		 */
4493		char buf[16384];
4494		int fd = open(ZFS_DEV, O_RDWR);
4495		(void) strcpy((void *)buf, argv[2]);
4496		return (!!ioctl(fd, ZFS_IOC_POOL_FREEZE, buf));
4497	} else {
4498		(void) fprintf(stderr, gettext("unrecognized "
4499		    "command '%s'\n"), cmdname);
4500		usage(B_FALSE);
4501	}
4502
4503	libzfs_fini(g_zfs);
4504
4505	/*
4506	 * The 'ZFS_ABORT' environment variable causes us to dump core on exit
4507	 * for the purposes of running ::findleaks.
4508	 */
4509	if (getenv("ZFS_ABORT") != NULL) {
4510		(void) printf("dumping core by request\n");
4511		abort();
4512	}
4513
4514	return (ret);
4515}
4516