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