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