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