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