zpool_main.c revision 207672
1280288Sjkim/*
2280288Sjkim * CDDL HEADER START
3280288Sjkim *
4280288Sjkim * The contents of this file are subject to the terms of the
5280288Sjkim * Common Development and Distribution License (the "License").
6280288Sjkim * You may not use this file except in compliance with the License.
7280288Sjkim *
8280288Sjkim * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9280288Sjkim * or http://www.opensolaris.org/os/licensing.
10280288Sjkim * See the License for the specific language governing permissions
11280288Sjkim * and limitations under the License.
12280288Sjkim *
13280288Sjkim * When distributing Covered Code, include this CDDL HEADER in each
14280288Sjkim * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15280288Sjkim * If applicable, add the following below this CDDL HEADER, with the
16280288Sjkim * fields enclosed by brackets "[]" replaced with your own identifying
17280288Sjkim * information: Portions Copyright [yyyy] [name of copyright owner]
18280288Sjkim *
19280288Sjkim * CDDL HEADER END
20280288Sjkim */
21280288Sjkim
22280288Sjkim/*
23280288Sjkim * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
24280288Sjkim * Use is subject to license terms.
25280288Sjkim */
26280288Sjkim
27280288Sjkim#include <solaris.h>
28280288Sjkim#include <assert.h>
29280288Sjkim#include <ctype.h>
30280288Sjkim#include <dirent.h>
31280288Sjkim#include <errno.h>
32280288Sjkim#include <fcntl.h>
33280288Sjkim#include <libgen.h>
34280288Sjkim#include <libintl.h>
35280288Sjkim#include <libuutil.h>
36280288Sjkim#include <locale.h>
37280288Sjkim#include <stdio.h>
38280288Sjkim#include <stdlib.h>
39280288Sjkim#include <string.h>
40280288Sjkim#include <strings.h>
41280288Sjkim#include <unistd.h>
42280288Sjkim#include <priv.h>
43280288Sjkim#include <pwd.h>
44280288Sjkim#include <zone.h>
45280288Sjkim#include <sys/time.h>
46280288Sjkim#include <sys/fs/zfs.h>
47280288Sjkim
48280288Sjkim#include <sys/stat.h>
49280288Sjkim
50280288Sjkim#include <libzfs.h>
51280288Sjkim
52280288Sjkim#include "zpool_util.h"
53280288Sjkim#include "zfs_comutil.h"
54280288Sjkim
55280288Sjkimstatic int zpool_do_create(int, char **);
56280288Sjkimstatic int zpool_do_destroy(int, char **);
57280288Sjkim
58280288Sjkimstatic int zpool_do_add(int, char **);
59280288Sjkimstatic int zpool_do_remove(int, char **);
60280288Sjkim
61280288Sjkimstatic int zpool_do_list(int, char **);
62280288Sjkimstatic int zpool_do_iostat(int, char **);
63280288Sjkimstatic int zpool_do_status(int, char **);
64280288Sjkim
65280288Sjkimstatic int zpool_do_online(int, char **);
66280288Sjkimstatic int zpool_do_offline(int, char **);
67280288Sjkimstatic int zpool_do_clear(int, char **);
68280288Sjkim
69280288Sjkimstatic int zpool_do_attach(int, char **);
70280288Sjkimstatic int zpool_do_detach(int, char **);
71280288Sjkimstatic int zpool_do_replace(int, char **);
72280288Sjkim
73280288Sjkimstatic int zpool_do_scrub(int, char **);
74280288Sjkim
75280288Sjkimstatic int zpool_do_import(int, char **);
76280288Sjkimstatic int zpool_do_export(int, char **);
77280288Sjkim
78280288Sjkimstatic int zpool_do_upgrade(int, char **);
79280288Sjkim
80280288Sjkimstatic int zpool_do_history(int, char **);
81280288Sjkim
82280288Sjkimstatic int zpool_do_get(int, char **);
83280288Sjkimstatic int zpool_do_set(int, char **);
84280288Sjkim
85280288Sjkim/*
86280288Sjkim * These libumem hooks provide a reasonable set of defaults for the allocator's
87280288Sjkim * debugging facilities.
88280288Sjkim */
89280288Sjkim
90280288Sjkim#ifdef DEBUG
91280288Sjkimconst char *
92280288Sjkim_umem_debug_init(void)
93280288Sjkim{
94280288Sjkim	return ("default,verbose"); /* $UMEM_DEBUG setting */
95280288Sjkim}
96280288Sjkim
97280288Sjkimconst char *
98280288Sjkim_umem_logging_init(void)
99280288Sjkim{
100280288Sjkim	return ("fail,contents"); /* $UMEM_LOGGING setting */
101280288Sjkim}
102280288Sjkim#endif
103280288Sjkim
104280288Sjkimtypedef enum {
105280288Sjkim	HELP_ADD,
106280288Sjkim	HELP_ATTACH,
107280288Sjkim	HELP_CLEAR,
108280288Sjkim	HELP_CREATE,
109280288Sjkim	HELP_DESTROY,
110280288Sjkim	HELP_DETACH,
111280288Sjkim	HELP_EXPORT,
112280288Sjkim	HELP_HISTORY,
113280288Sjkim	HELP_IMPORT,
114280288Sjkim	HELP_IOSTAT,
115280288Sjkim	HELP_LIST,
116280288Sjkim	HELP_OFFLINE,
117280288Sjkim	HELP_ONLINE,
118280288Sjkim	HELP_REPLACE,
119280288Sjkim	HELP_REMOVE,
120280288Sjkim	HELP_SCRUB,
121280288Sjkim	HELP_STATUS,
122280288Sjkim	HELP_UPGRADE,
123280288Sjkim	HELP_GET,
124280288Sjkim	HELP_SET
125280288Sjkim} zpool_help_t;
126280288Sjkim
127280288Sjkim
128280288Sjkimtypedef struct zpool_command {
129280288Sjkim	const char	*name;
130280288Sjkim	int		(*func)(int, char **);
131280288Sjkim	zpool_help_t	usage;
132280288Sjkim} zpool_command_t;
133280288Sjkim
134280288Sjkim/*
135280288Sjkim * Master command table.  Each ZFS command has a name, associated function, and
136280288Sjkim * usage message.  The usage messages need to be internationalized, so we have
137280288Sjkim * to have a function to return the usage message based on a command index.
138280288Sjkim *
139280288Sjkim * These commands are organized according to how they are displayed in the usage
140280288Sjkim * message.  An empty command (one with a NULL name) indicates an empty line in
141280288Sjkim * the generic usage message.
142280288Sjkim */
143280288Sjkimstatic zpool_command_t command_table[] = {
144280288Sjkim	{ "create",	zpool_do_create,	HELP_CREATE		},
145280288Sjkim	{ "destroy",	zpool_do_destroy,	HELP_DESTROY		},
146280288Sjkim	{ NULL },
147280288Sjkim	{ "add",	zpool_do_add,		HELP_ADD		},
148280288Sjkim	{ "remove",	zpool_do_remove,	HELP_REMOVE		},
149280288Sjkim	{ NULL },
150280288Sjkim	{ "list",	zpool_do_list,		HELP_LIST		},
151280288Sjkim	{ "iostat",	zpool_do_iostat,	HELP_IOSTAT		},
152280288Sjkim	{ "status",	zpool_do_status,	HELP_STATUS		},
153280288Sjkim	{ NULL },
154280288Sjkim	{ "online",	zpool_do_online,	HELP_ONLINE		},
155280288Sjkim	{ "offline",	zpool_do_offline,	HELP_OFFLINE		},
156280288Sjkim	{ "clear",	zpool_do_clear,		HELP_CLEAR		},
157280288Sjkim	{ NULL },
158280288Sjkim	{ "attach",	zpool_do_attach,	HELP_ATTACH		},
159280288Sjkim	{ "detach",	zpool_do_detach,	HELP_DETACH		},
160280288Sjkim	{ "replace",	zpool_do_replace,	HELP_REPLACE		},
161280288Sjkim	{ NULL },
162280288Sjkim	{ "scrub",	zpool_do_scrub,		HELP_SCRUB		},
163280288Sjkim	{ NULL },
164280288Sjkim	{ "import",	zpool_do_import,	HELP_IMPORT		},
165280288Sjkim	{ "export",	zpool_do_export,	HELP_EXPORT		},
166280288Sjkim	{ "upgrade",	zpool_do_upgrade,	HELP_UPGRADE		},
167280288Sjkim	{ NULL },
168280288Sjkim	{ "history",	zpool_do_history,	HELP_HISTORY		},
169280288Sjkim	{ "get",	zpool_do_get,		HELP_GET		},
170280288Sjkim	{ "set",	zpool_do_set,		HELP_SET		},
171280288Sjkim};
172280288Sjkim
173280288Sjkim#define	NCOMMAND	(sizeof (command_table) / sizeof (command_table[0]))
174280288Sjkim
175280288Sjkimzpool_command_t *current_command;
176280288Sjkimstatic char history_str[HIS_MAX_RECORD_LEN];
177280288Sjkim
178280288Sjkimstatic const char *
179280288Sjkimget_usage(zpool_help_t idx) {
180280288Sjkim	switch (idx) {
181280288Sjkim	case HELP_ADD:
182280288Sjkim		return (gettext("\tadd [-fn] <pool> <vdev> ...\n"));
183280288Sjkim	case HELP_ATTACH:
184280288Sjkim		return (gettext("\tattach [-f] <pool> <device> "
185280288Sjkim		    "<new-device>\n"));
186280288Sjkim	case HELP_CLEAR:
187280288Sjkim		return (gettext("\tclear <pool> [device]\n"));
188280288Sjkim	case HELP_CREATE:
189280288Sjkim		return (gettext("\tcreate [-fn] [-o property=value] ... \n"
190280288Sjkim		    "\t    [-O file-system-property=value] ... \n"
191280288Sjkim		    "\t    [-m mountpoint] [-R root] <pool> <vdev> ...\n"));
192280288Sjkim	case HELP_DESTROY:
193280288Sjkim		return (gettext("\tdestroy [-f] <pool>\n"));
194280288Sjkim	case HELP_DETACH:
195280288Sjkim		return (gettext("\tdetach <pool> <device>\n"));
196280288Sjkim	case HELP_EXPORT:
197280288Sjkim		return (gettext("\texport [-f] <pool> ...\n"));
198280288Sjkim	case HELP_HISTORY:
199280288Sjkim		return (gettext("\thistory [-il] [<pool>] ...\n"));
200280288Sjkim	case HELP_IMPORT:
201280288Sjkim		return (gettext("\timport [-d dir] [-D]\n"
202280288Sjkim		    "\timport [-o mntopts] [-o property=value] ... \n"
203280288Sjkim		    "\t    [-d dir | -c cachefile] [-D] [-f] [-R root] -a\n"
204280288Sjkim		    "\timport [-o mntopts] [-o property=value] ... \n"
205280288Sjkim		    "\t    [-d dir | -c cachefile] [-D] [-f] [-R root] "
206280288Sjkim		    "<pool | id> [newpool]\n"));
207280288Sjkim	case HELP_IOSTAT:
208280288Sjkim		return (gettext("\tiostat [-v] [pool] ... [interval "
209280288Sjkim		    "[count]]\n"));
210280288Sjkim	case HELP_LIST:
211280288Sjkim		return (gettext("\tlist [-H] [-o property[,...]] "
212280288Sjkim		    "[pool] ...\n"));
213280288Sjkim	case HELP_OFFLINE:
214280288Sjkim		return (gettext("\toffline [-t] <pool> <device> ...\n"));
215280288Sjkim	case HELP_ONLINE:
216280288Sjkim		return (gettext("\tonline <pool> <device> ...\n"));
217280288Sjkim	case HELP_REPLACE:
218280288Sjkim		return (gettext("\treplace [-f] <pool> <device> "
219280288Sjkim		    "[new-device]\n"));
220280288Sjkim	case HELP_REMOVE:
221280288Sjkim		return (gettext("\tremove <pool> <device> ...\n"));
222280288Sjkim	case HELP_SCRUB:
223280288Sjkim		return (gettext("\tscrub [-s] <pool> ...\n"));
224280288Sjkim	case HELP_STATUS:
225280288Sjkim		return (gettext("\tstatus [-vx] [pool] ...\n"));
226280288Sjkim	case HELP_UPGRADE:
227280288Sjkim		return (gettext("\tupgrade\n"
228280288Sjkim		    "\tupgrade -v\n"
229280288Sjkim		    "\tupgrade [-V version] <-a | pool ...>\n"));
230280288Sjkim	case HELP_GET:
231280288Sjkim		return (gettext("\tget <\"all\" | property[,...]> "
232280288Sjkim		    "<pool> ...\n"));
233280288Sjkim	case HELP_SET:
234280288Sjkim		return (gettext("\tset <property=value> <pool> \n"));
235280288Sjkim	}
236280288Sjkim
237280288Sjkim	abort();
238280288Sjkim	/* NOTREACHED */
239280288Sjkim}
240280288Sjkim
241280288Sjkim
242280288Sjkim/*
243280288Sjkim * Callback routine that will print out a pool property value.
244280288Sjkim */
245280288Sjkimstatic int
246280288Sjkimprint_prop_cb(int prop, void *cb)
247280288Sjkim{
248280288Sjkim	FILE *fp = cb;
249280288Sjkim
250280288Sjkim	(void) fprintf(fp, "\t%-13s  ", zpool_prop_to_name(prop));
251280288Sjkim
252280288Sjkim	if (zpool_prop_readonly(prop))
253280288Sjkim		(void) fprintf(fp, "  NO   ");
254280288Sjkim	else
255280288Sjkim		(void) fprintf(fp, " YES    ");
256280288Sjkim
257280288Sjkim	if (zpool_prop_values(prop) == NULL)
258280288Sjkim		(void) fprintf(fp, "-\n");
259280288Sjkim	else
260280288Sjkim		(void) fprintf(fp, "%s\n", zpool_prop_values(prop));
261280288Sjkim
262280288Sjkim	return (ZPROP_CONT);
263280288Sjkim}
264280288Sjkim
265280288Sjkim/*
266280288Sjkim * Display usage message.  If we're inside a command, display only the usage for
267280288Sjkim * that command.  Otherwise, iterate over the entire command table and display
268280288Sjkim * a complete usage message.
269280288Sjkim */
270280288Sjkimvoid
271280288Sjkimusage(boolean_t requested)
272280288Sjkim{
273280288Sjkim	FILE *fp = requested ? stdout : stderr;
274280288Sjkim
275280288Sjkim	if (current_command == NULL) {
276280288Sjkim		int i;
277280288Sjkim
278280288Sjkim		(void) fprintf(fp, gettext("usage: zpool command args ...\n"));
279280288Sjkim		(void) fprintf(fp,
280280288Sjkim		    gettext("where 'command' is one of the following:\n\n"));
281280288Sjkim
282280288Sjkim		for (i = 0; i < NCOMMAND; i++) {
283280288Sjkim			if (command_table[i].name == NULL)
284280288Sjkim				(void) fprintf(fp, "\n");
285280288Sjkim			else
286280288Sjkim				(void) fprintf(fp, "%s",
287280288Sjkim				    get_usage(command_table[i].usage));
288280288Sjkim		}
289280288Sjkim	} else {
290280288Sjkim		(void) fprintf(fp, gettext("usage:\n"));
291280288Sjkim		(void) fprintf(fp, "%s", get_usage(current_command->usage));
292280288Sjkim	}
293280288Sjkim
294280288Sjkim	if (current_command != NULL &&
295280288Sjkim	    ((strcmp(current_command->name, "set") == 0) ||
296280288Sjkim	    (strcmp(current_command->name, "get") == 0) ||
297280288Sjkim	    (strcmp(current_command->name, "list") == 0))) {
298280288Sjkim
299280288Sjkim		(void) fprintf(fp,
300280288Sjkim		    gettext("\nthe following properties are supported:\n"));
301280288Sjkim
302280288Sjkim		(void) fprintf(fp, "\n\t%-13s  %s  %s\n\n",
303280288Sjkim		    "PROPERTY", "EDIT", "VALUES");
304280288Sjkim
305280288Sjkim		/* Iterate over all properties */
306280288Sjkim		(void) zprop_iter(print_prop_cb, fp, B_FALSE, B_TRUE,
307280288Sjkim		    ZFS_TYPE_POOL);
308280288Sjkim	}
309280288Sjkim
310280288Sjkim	/*
311280288Sjkim	 * See comments at end of main().
312280288Sjkim	 */
313280288Sjkim	if (getenv("ZFS_ABORT") != NULL) {
314280288Sjkim		(void) printf("dumping core by request\n");
315280288Sjkim		abort();
316280288Sjkim	}
317280288Sjkim
318280288Sjkim	exit(requested ? 0 : 2);
319280288Sjkim}
320280288Sjkim
321280288Sjkimvoid
322280288Sjkimprint_vdev_tree(zpool_handle_t *zhp, const char *name, nvlist_t *nv, int indent,
323280288Sjkim    boolean_t print_logs)
324280288Sjkim{
325280288Sjkim	nvlist_t **child;
326280288Sjkim	uint_t c, children;
327280288Sjkim	char *vname;
328280288Sjkim
329280288Sjkim	if (name != NULL)
330280288Sjkim		(void) printf("\t%*s%s\n", indent, "", name);
331280288Sjkim
332280288Sjkim	if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
333280288Sjkim	    &child, &children) != 0)
334280288Sjkim		return;
335280288Sjkim
336280288Sjkim	for (c = 0; c < children; c++) {
337280288Sjkim		uint64_t is_log = B_FALSE;
338280288Sjkim
339280288Sjkim		(void) nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_LOG,
340280288Sjkim		    &is_log);
341280288Sjkim		if ((is_log && !print_logs) || (!is_log && print_logs))
342280288Sjkim			continue;
343280288Sjkim
344280288Sjkim		vname = zpool_vdev_name(g_zfs, zhp, child[c]);
345280288Sjkim		print_vdev_tree(zhp, vname, child[c], indent + 2,
346280288Sjkim		    B_FALSE);
347280288Sjkim		free(vname);
348280288Sjkim	}
349280288Sjkim}
350280288Sjkim
351280288Sjkim/*
352280288Sjkim * Add a property pair (name, string-value) into a property nvlist.
353280288Sjkim */
354280288Sjkimstatic int
355280288Sjkimadd_prop_list(const char *propname, char *propval, nvlist_t **props,
356280288Sjkim    boolean_t poolprop)
357280288Sjkim{
358280288Sjkim	zpool_prop_t prop = ZPROP_INVAL;
359280288Sjkim	zfs_prop_t fprop;
360280288Sjkim	nvlist_t *proplist;
361280288Sjkim	const char *normnm;
362280288Sjkim	char *strval;
363280288Sjkim
364280288Sjkim	if (*props == NULL &&
365280288Sjkim	    nvlist_alloc(props, NV_UNIQUE_NAME, 0) != 0) {
366280288Sjkim		(void) fprintf(stderr,
367280288Sjkim		    gettext("internal error: out of memory\n"));
368280288Sjkim		return (1);
369280288Sjkim	}
370280288Sjkim
371280288Sjkim	proplist = *props;
372280288Sjkim
373280288Sjkim	if (poolprop) {
374280288Sjkim		if ((prop = zpool_name_to_prop(propname)) == ZPROP_INVAL) {
375280288Sjkim			(void) fprintf(stderr, gettext("property '%s' is "
376280288Sjkim			    "not a valid pool property\n"), propname);
377280288Sjkim			return (2);
378280288Sjkim		}
379280288Sjkim		normnm = zpool_prop_to_name(prop);
380280288Sjkim	} else {
381280288Sjkim		if ((fprop = zfs_name_to_prop(propname)) == ZPROP_INVAL) {
382280288Sjkim			(void) fprintf(stderr, gettext("property '%s' is "
383280288Sjkim			    "not a valid file system property\n"), propname);
384280288Sjkim			return (2);
385280288Sjkim		}
386280288Sjkim		normnm = zfs_prop_to_name(fprop);
387280288Sjkim	}
388280288Sjkim
389280288Sjkim	if (nvlist_lookup_string(proplist, normnm, &strval) == 0 &&
390280288Sjkim	    prop != ZPOOL_PROP_CACHEFILE) {
391280288Sjkim		(void) fprintf(stderr, gettext("property '%s' "
392280288Sjkim		    "specified multiple times\n"), propname);
393280288Sjkim		return (2);
394280288Sjkim	}
395280288Sjkim
396280288Sjkim	if (nvlist_add_string(proplist, normnm, propval) != 0) {
397280288Sjkim		(void) fprintf(stderr, gettext("internal "
398280288Sjkim		    "error: out of memory\n"));
399280288Sjkim		return (1);
400280288Sjkim	}
401280288Sjkim
402280288Sjkim	return (0);
403280288Sjkim}
404280288Sjkim
405280288Sjkim/*
406280288Sjkim * zpool add [-fn] <pool> <vdev> ...
407280288Sjkim *
408280288Sjkim *	-f	Force addition of devices, even if they appear in use
409280288Sjkim *	-n	Do not add the devices, but display the resulting layout if
410280288Sjkim *		they were to be added.
411280288Sjkim *
412280288Sjkim * Adds the given vdevs to 'pool'.  As with create, the bulk of this work is
413280288Sjkim * handled by get_vdev_spec(), which constructs the nvlist needed to pass to
414280288Sjkim * libzfs.
415280288Sjkim */
416280288Sjkimint
417280288Sjkimzpool_do_add(int argc, char **argv)
418280288Sjkim{
419280288Sjkim	boolean_t force = B_FALSE;
420280288Sjkim	boolean_t dryrun = B_FALSE;
421280288Sjkim	int c;
422280288Sjkim	nvlist_t *nvroot;
423280288Sjkim	char *poolname;
424280288Sjkim	int ret;
425280288Sjkim	zpool_handle_t *zhp;
426280288Sjkim	nvlist_t *config;
427280288Sjkim
428280288Sjkim	/* check options */
429280288Sjkim	while ((c = getopt(argc, argv, "fn")) != -1) {
430280288Sjkim		switch (c) {
431280288Sjkim		case 'f':
432280288Sjkim			force = B_TRUE;
433280288Sjkim			break;
434280288Sjkim		case 'n':
435280288Sjkim			dryrun = B_TRUE;
436280288Sjkim			break;
437280288Sjkim		case '?':
438280288Sjkim			(void) fprintf(stderr, gettext("invalid option '%c'\n"),
439280288Sjkim			    optopt);
440280288Sjkim			usage(B_FALSE);
441280288Sjkim		}
442280288Sjkim	}
443280288Sjkim
444280288Sjkim	argc -= optind;
445280288Sjkim	argv += optind;
446280288Sjkim
447280288Sjkim	/* get pool name and check number of arguments */
448280288Sjkim	if (argc < 1) {
449280288Sjkim		(void) fprintf(stderr, gettext("missing pool name argument\n"));
450280288Sjkim		usage(B_FALSE);
451280288Sjkim	}
452280288Sjkim	if (argc < 2) {
453280288Sjkim		(void) fprintf(stderr, gettext("missing vdev specification\n"));
454280288Sjkim		usage(B_FALSE);
455280288Sjkim	}
456280288Sjkim
457280288Sjkim	poolname = argv[0];
458280288Sjkim
459280288Sjkim	argc--;
460280288Sjkim	argv++;
461280288Sjkim
462280288Sjkim	if ((zhp = zpool_open(g_zfs, poolname)) == NULL)
463280288Sjkim		return (1);
464280288Sjkim
465280288Sjkim	if ((config = zpool_get_config(zhp, NULL)) == NULL) {
466280288Sjkim		(void) fprintf(stderr, gettext("pool '%s' is unavailable\n"),
467280288Sjkim		    poolname);
468280288Sjkim		zpool_close(zhp);
469280288Sjkim		return (1);
470280288Sjkim	}
471280288Sjkim
472280288Sjkim	/* pass off to get_vdev_spec for processing */
473280288Sjkim	nvroot = make_root_vdev(zhp, force, !force, B_FALSE, dryrun,
474280288Sjkim	    argc, argv);
475280288Sjkim	if (nvroot == NULL) {
476280288Sjkim		zpool_close(zhp);
477280288Sjkim		return (1);
478280288Sjkim	}
479280288Sjkim
480280288Sjkim	if (dryrun) {
481280288Sjkim		nvlist_t *poolnvroot;
482280288Sjkim
483280288Sjkim		verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
484280288Sjkim		    &poolnvroot) == 0);
485280288Sjkim
486280288Sjkim		(void) printf(gettext("would update '%s' to the following "
487280288Sjkim		    "configuration:\n"), zpool_get_name(zhp));
488280288Sjkim
489280288Sjkim		/* print original main pool and new tree */
490		print_vdev_tree(zhp, poolname, poolnvroot, 0, B_FALSE);
491		print_vdev_tree(zhp, NULL, nvroot, 0, B_FALSE);
492
493		/* Do the same for the logs */
494		if (num_logs(poolnvroot) > 0) {
495			print_vdev_tree(zhp, "logs", poolnvroot, 0, B_TRUE);
496			print_vdev_tree(zhp, NULL, nvroot, 0, B_TRUE);
497		} else if (num_logs(nvroot) > 0) {
498			print_vdev_tree(zhp, "logs", nvroot, 0, B_TRUE);
499		}
500
501		ret = 0;
502	} else {
503		ret = (zpool_add(zhp, nvroot) != 0);
504	}
505
506	nvlist_free(nvroot);
507	zpool_close(zhp);
508
509	return (ret);
510}
511
512/*
513 * zpool remove <pool> <vdev> ...
514 *
515 * Removes the given vdev from the pool.  Currently, this only supports removing
516 * spares and cache devices from the pool.  Eventually, we'll want to support
517 * removing leaf vdevs (as an alias for 'detach') as well as toplevel vdevs.
518 */
519int
520zpool_do_remove(int argc, char **argv)
521{
522	char *poolname;
523	int i, ret = 0;
524	zpool_handle_t *zhp;
525
526	argc--;
527	argv++;
528
529	/* get pool name and check number of arguments */
530	if (argc < 1) {
531		(void) fprintf(stderr, gettext("missing pool name argument\n"));
532		usage(B_FALSE);
533	}
534	if (argc < 2) {
535		(void) fprintf(stderr, gettext("missing device\n"));
536		usage(B_FALSE);
537	}
538
539	poolname = argv[0];
540
541	if ((zhp = zpool_open(g_zfs, poolname)) == NULL)
542		return (1);
543
544	for (i = 1; i < argc; i++) {
545		if (zpool_vdev_remove(zhp, argv[i]) != 0)
546			ret = 1;
547	}
548
549	return (ret);
550}
551
552/*
553 * zpool create [-fn] [-o property=value] ...
554 *		[-O file-system-property=value] ...
555 *		[-R root] [-m mountpoint] <pool> <dev> ...
556 *
557 *	-f	Force creation, even if devices appear in use
558 *	-n	Do not create the pool, but display the resulting layout if it
559 *		were to be created.
560 *      -R	Create a pool under an alternate root
561 *      -m	Set default mountpoint for the root dataset.  By default it's
562 *      	'/<pool>'
563 *	-o	Set property=value.
564 *	-O	Set fsproperty=value in the pool's root file system
565 *
566 * Creates the named pool according to the given vdev specification.  The
567 * bulk of the vdev processing is done in get_vdev_spec() in zpool_vdev.c.  Once
568 * we get the nvlist back from get_vdev_spec(), we either print out the contents
569 * (if '-n' was specified), or pass it to libzfs to do the creation.
570 */
571int
572zpool_do_create(int argc, char **argv)
573{
574	boolean_t force = B_FALSE;
575	boolean_t dryrun = B_FALSE;
576	int c;
577	nvlist_t *nvroot = NULL;
578	char *poolname;
579	int ret = 1;
580	char *altroot = NULL;
581	char *mountpoint = NULL;
582	nvlist_t *fsprops = NULL;
583	nvlist_t *props = NULL;
584	char *propval;
585
586	/* check options */
587	while ((c = getopt(argc, argv, ":fnR:m:o:O:")) != -1) {
588		switch (c) {
589		case 'f':
590			force = B_TRUE;
591			break;
592		case 'n':
593			dryrun = B_TRUE;
594			break;
595		case 'R':
596			altroot = optarg;
597			if (add_prop_list(zpool_prop_to_name(
598			    ZPOOL_PROP_ALTROOT), optarg, &props, B_TRUE))
599				goto errout;
600			if (nvlist_lookup_string(props,
601			    zpool_prop_to_name(ZPOOL_PROP_CACHEFILE),
602			    &propval) == 0)
603				break;
604			if (add_prop_list(zpool_prop_to_name(
605			    ZPOOL_PROP_CACHEFILE), "none", &props, B_TRUE))
606				goto errout;
607			break;
608		case 'm':
609			mountpoint = optarg;
610			break;
611		case 'o':
612			if ((propval = strchr(optarg, '=')) == NULL) {
613				(void) fprintf(stderr, gettext("missing "
614				    "'=' for -o option\n"));
615				goto errout;
616			}
617			*propval = '\0';
618			propval++;
619
620			if (add_prop_list(optarg, propval, &props, B_TRUE))
621				goto errout;
622			break;
623		case 'O':
624			if ((propval = strchr(optarg, '=')) == NULL) {
625				(void) fprintf(stderr, gettext("missing "
626				    "'=' for -O option\n"));
627				goto errout;
628			}
629			*propval = '\0';
630			propval++;
631
632			if (add_prop_list(optarg, propval, &fsprops, B_FALSE))
633				goto errout;
634			break;
635		case ':':
636			(void) fprintf(stderr, gettext("missing argument for "
637			    "'%c' option\n"), optopt);
638			goto badusage;
639		case '?':
640			(void) fprintf(stderr, gettext("invalid option '%c'\n"),
641			    optopt);
642			goto badusage;
643		}
644	}
645
646	argc -= optind;
647	argv += optind;
648
649	/* get pool name and check number of arguments */
650	if (argc < 1) {
651		(void) fprintf(stderr, gettext("missing pool name argument\n"));
652		goto badusage;
653	}
654	if (argc < 2) {
655		(void) fprintf(stderr, gettext("missing vdev specification\n"));
656		goto badusage;
657	}
658
659	poolname = argv[0];
660
661	/*
662	 * As a special case, check for use of '/' in the name, and direct the
663	 * user to use 'zfs create' instead.
664	 */
665	if (strchr(poolname, '/') != NULL) {
666		(void) fprintf(stderr, gettext("cannot create '%s': invalid "
667		    "character '/' in pool name\n"), poolname);
668		(void) fprintf(stderr, gettext("use 'zfs create' to "
669		    "create a dataset\n"));
670		goto errout;
671	}
672
673	/* pass off to get_vdev_spec for bulk processing */
674	nvroot = make_root_vdev(NULL, force, !force, B_FALSE, dryrun,
675	    argc - 1, argv + 1);
676	if (nvroot == NULL)
677		goto errout;
678
679	/* make_root_vdev() allows 0 toplevel children if there are spares */
680	if (!zfs_allocatable_devs(nvroot)) {
681		(void) fprintf(stderr, gettext("invalid vdev "
682		    "specification: at least one toplevel vdev must be "
683		    "specified\n"));
684		goto errout;
685	}
686
687
688	if (altroot != NULL && altroot[0] != '/') {
689		(void) fprintf(stderr, gettext("invalid alternate root '%s': "
690		    "must be an absolute path\n"), altroot);
691		goto errout;
692	}
693
694	/*
695	 * Check the validity of the mountpoint and direct the user to use the
696	 * '-m' mountpoint option if it looks like its in use.
697	 */
698	if (mountpoint == NULL ||
699	    (strcmp(mountpoint, ZFS_MOUNTPOINT_LEGACY) != 0 &&
700	    strcmp(mountpoint, ZFS_MOUNTPOINT_NONE) != 0)) {
701		char buf[MAXPATHLEN];
702		DIR *dirp;
703
704		if (mountpoint && mountpoint[0] != '/') {
705			(void) fprintf(stderr, gettext("invalid mountpoint "
706			    "'%s': must be an absolute path, 'legacy', or "
707			    "'none'\n"), mountpoint);
708			goto errout;
709		}
710
711		if (mountpoint == NULL) {
712			if (altroot != NULL)
713				(void) snprintf(buf, sizeof (buf), "%s/%s",
714				    altroot, poolname);
715			else
716				(void) snprintf(buf, sizeof (buf), "/%s",
717				    poolname);
718		} else {
719			if (altroot != NULL)
720				(void) snprintf(buf, sizeof (buf), "%s%s",
721				    altroot, mountpoint);
722			else
723				(void) snprintf(buf, sizeof (buf), "%s",
724				    mountpoint);
725		}
726
727		if ((dirp = opendir(buf)) == NULL && errno != ENOENT) {
728			(void) fprintf(stderr, gettext("mountpoint '%s' : "
729			    "%s\n"), buf, strerror(errno));
730			(void) fprintf(stderr, gettext("use '-m' "
731			    "option to provide a different default\n"));
732			goto errout;
733		} else if (dirp) {
734			int count = 0;
735
736			while (count < 3 && readdir(dirp) != NULL)
737				count++;
738			(void) closedir(dirp);
739
740			if (count > 2) {
741				(void) fprintf(stderr, gettext("mountpoint "
742				    "'%s' exists and is not empty\n"), buf);
743				(void) fprintf(stderr, gettext("use '-m' "
744				    "option to provide a "
745				    "different default\n"));
746				goto errout;
747			}
748		}
749	}
750
751	if (dryrun) {
752		/*
753		 * For a dry run invocation, print out a basic message and run
754		 * through all the vdevs in the list and print out in an
755		 * appropriate hierarchy.
756		 */
757		(void) printf(gettext("would create '%s' with the "
758		    "following layout:\n\n"), poolname);
759
760		print_vdev_tree(NULL, poolname, nvroot, 0, B_FALSE);
761		if (num_logs(nvroot) > 0)
762			print_vdev_tree(NULL, "logs", nvroot, 0, B_TRUE);
763
764		ret = 0;
765	} else {
766		/*
767		 * Hand off to libzfs.
768		 */
769		if (zpool_create(g_zfs, poolname,
770		    nvroot, props, fsprops) == 0) {
771			zfs_handle_t *pool = zfs_open(g_zfs, poolname,
772			    ZFS_TYPE_FILESYSTEM);
773			if (pool != NULL) {
774				if (mountpoint != NULL)
775					verify(zfs_prop_set(pool,
776					    zfs_prop_to_name(
777					    ZFS_PROP_MOUNTPOINT),
778					    mountpoint) == 0);
779				if (zfs_mount(pool, NULL, 0) == 0)
780					ret = zfs_shareall(pool);
781				zfs_close(pool);
782			}
783		} else if (libzfs_errno(g_zfs) == EZFS_INVALIDNAME) {
784			(void) fprintf(stderr, gettext("pool name may have "
785			    "been omitted\n"));
786		}
787	}
788
789errout:
790	nvlist_free(nvroot);
791	nvlist_free(fsprops);
792	nvlist_free(props);
793	return (ret);
794badusage:
795	nvlist_free(fsprops);
796	nvlist_free(props);
797	usage(B_FALSE);
798	return (2);
799}
800
801/*
802 * zpool destroy <pool>
803 *
804 * 	-f	Forcefully unmount any datasets
805 *
806 * Destroy the given pool.  Automatically unmounts any datasets in the pool.
807 */
808int
809zpool_do_destroy(int argc, char **argv)
810{
811	boolean_t force = B_FALSE;
812	int c;
813	char *pool;
814	zpool_handle_t *zhp;
815	int ret;
816
817	/* check options */
818	while ((c = getopt(argc, argv, "f")) != -1) {
819		switch (c) {
820		case 'f':
821			force = B_TRUE;
822			break;
823		case '?':
824			(void) fprintf(stderr, gettext("invalid option '%c'\n"),
825			    optopt);
826			usage(B_FALSE);
827		}
828	}
829
830	argc -= optind;
831	argv += optind;
832
833	/* check arguments */
834	if (argc < 1) {
835		(void) fprintf(stderr, gettext("missing pool argument\n"));
836		usage(B_FALSE);
837	}
838	if (argc > 1) {
839		(void) fprintf(stderr, gettext("too many arguments\n"));
840		usage(B_FALSE);
841	}
842
843	pool = argv[0];
844
845	if ((zhp = zpool_open_canfail(g_zfs, pool)) == NULL) {
846		/*
847		 * As a special case, check for use of '/' in the name, and
848		 * direct the user to use 'zfs destroy' instead.
849		 */
850		if (strchr(pool, '/') != NULL)
851			(void) fprintf(stderr, gettext("use 'zfs destroy' to "
852			    "destroy a dataset\n"));
853		return (1);
854	}
855
856	if (zpool_disable_datasets(zhp, force) != 0) {
857		(void) fprintf(stderr, gettext("could not destroy '%s': "
858		    "could not unmount datasets\n"), zpool_get_name(zhp));
859		return (1);
860	}
861
862	ret = (zpool_destroy(zhp) != 0);
863
864	zpool_close(zhp);
865
866	return (ret);
867}
868
869/*
870 * zpool export [-f] <pool> ...
871 *
872 *	-f	Forcefully unmount datasets
873 *
874 * Export the given pools.  By default, the command will attempt to cleanly
875 * unmount any active datasets within the pool.  If the '-f' flag is specified,
876 * then the datasets will be forcefully unmounted.
877 */
878int
879zpool_do_export(int argc, char **argv)
880{
881	boolean_t force = B_FALSE;
882	boolean_t hardforce = B_FALSE;
883	int c;
884	zpool_handle_t *zhp;
885	int ret;
886	int i;
887
888	/* check options */
889	while ((c = getopt(argc, argv, "fF")) != -1) {
890		switch (c) {
891		case 'f':
892			force = B_TRUE;
893			break;
894		case 'F':
895			hardforce = B_TRUE;
896			break;
897		case '?':
898			(void) fprintf(stderr, gettext("invalid option '%c'\n"),
899			    optopt);
900			usage(B_FALSE);
901		}
902	}
903
904	argc -= optind;
905	argv += optind;
906
907	/* check arguments */
908	if (argc < 1) {
909		(void) fprintf(stderr, gettext("missing pool argument\n"));
910		usage(B_FALSE);
911	}
912
913	ret = 0;
914	for (i = 0; i < argc; i++) {
915		if ((zhp = zpool_open_canfail(g_zfs, argv[i])) == NULL) {
916			ret = 1;
917			continue;
918		}
919
920		if (zpool_disable_datasets(zhp, force) != 0) {
921			ret = 1;
922			zpool_close(zhp);
923			continue;
924		}
925
926		if (hardforce) {
927			if (zpool_export_force(zhp) != 0)
928				ret = 1;
929		} else if (zpool_export(zhp, force) != 0) {
930			ret = 1;
931		}
932
933		zpool_close(zhp);
934	}
935
936	return (ret);
937}
938
939/*
940 * Given a vdev configuration, determine the maximum width needed for the device
941 * name column.
942 */
943static int
944max_width(zpool_handle_t *zhp, nvlist_t *nv, int depth, int max)
945{
946	char *name = zpool_vdev_name(g_zfs, zhp, nv);
947	nvlist_t **child;
948	uint_t c, children;
949	int ret;
950
951	if (strlen(name) + depth > max)
952		max = strlen(name) + depth;
953
954	free(name);
955
956	if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_SPARES,
957	    &child, &children) == 0) {
958		for (c = 0; c < children; c++)
959			if ((ret = max_width(zhp, child[c], depth + 2,
960			    max)) > max)
961				max = ret;
962	}
963
964	if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_L2CACHE,
965	    &child, &children) == 0) {
966		for (c = 0; c < children; c++)
967			if ((ret = max_width(zhp, child[c], depth + 2,
968			    max)) > max)
969				max = ret;
970	}
971
972	if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
973	    &child, &children) == 0) {
974		for (c = 0; c < children; c++)
975			if ((ret = max_width(zhp, child[c], depth + 2,
976			    max)) > max)
977				max = ret;
978	}
979
980
981	return (max);
982}
983
984
985/*
986 * Print the configuration of an exported pool.  Iterate over all vdevs in the
987 * pool, printing out the name and status for each one.
988 */
989void
990print_import_config(const char *name, nvlist_t *nv, int namewidth, int depth,
991    boolean_t print_logs)
992{
993	nvlist_t **child;
994	uint_t c, children;
995	vdev_stat_t *vs;
996	char *type, *vname;
997
998	verify(nvlist_lookup_string(nv, ZPOOL_CONFIG_TYPE, &type) == 0);
999	if (strcmp(type, VDEV_TYPE_MISSING) == 0)
1000		return;
1001
1002	verify(nvlist_lookup_uint64_array(nv, ZPOOL_CONFIG_STATS,
1003	    (uint64_t **)&vs, &c) == 0);
1004
1005	(void) printf("\t%*s%-*s", depth, "", namewidth - depth, name);
1006	(void) printf("  %s", zpool_state_to_name(vs->vs_state, vs->vs_aux));
1007
1008	if (vs->vs_aux != 0) {
1009		(void) printf("  ");
1010
1011		switch (vs->vs_aux) {
1012		case VDEV_AUX_OPEN_FAILED:
1013			(void) printf(gettext("cannot open"));
1014			break;
1015
1016		case VDEV_AUX_BAD_GUID_SUM:
1017			(void) printf(gettext("missing device"));
1018			break;
1019
1020		case VDEV_AUX_NO_REPLICAS:
1021			(void) printf(gettext("insufficient replicas"));
1022			break;
1023
1024		case VDEV_AUX_VERSION_NEWER:
1025			(void) printf(gettext("newer version"));
1026			break;
1027
1028		case VDEV_AUX_ERR_EXCEEDED:
1029			(void) printf(gettext("too many errors"));
1030			break;
1031
1032		default:
1033			(void) printf(gettext("corrupted data"));
1034			break;
1035		}
1036	}
1037	(void) printf("\n");
1038
1039	if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
1040	    &child, &children) != 0)
1041		return;
1042
1043	for (c = 0; c < children; c++) {
1044		uint64_t is_log = B_FALSE;
1045
1046		(void) nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_LOG,
1047		    &is_log);
1048		if ((is_log && !print_logs) || (!is_log && print_logs))
1049			continue;
1050
1051		vname = zpool_vdev_name(g_zfs, NULL, child[c]);
1052		print_import_config(vname, child[c],
1053		    namewidth, depth + 2, B_FALSE);
1054		free(vname);
1055	}
1056
1057	if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_L2CACHE,
1058	    &child, &children) == 0) {
1059		(void) printf(gettext("\tcache\n"));
1060		for (c = 0; c < children; c++) {
1061			vname = zpool_vdev_name(g_zfs, NULL, child[c]);
1062			(void) printf("\t  %s\n", vname);
1063			free(vname);
1064		}
1065	}
1066
1067	if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_SPARES,
1068	    &child, &children) == 0) {
1069		(void) printf(gettext("\tspares\n"));
1070		for (c = 0; c < children; c++) {
1071			vname = zpool_vdev_name(g_zfs, NULL, child[c]);
1072			(void) printf("\t  %s\n", vname);
1073			free(vname);
1074		}
1075	}
1076}
1077
1078/*
1079 * Display the status for the given pool.
1080 */
1081static void
1082show_import(nvlist_t *config)
1083{
1084	uint64_t pool_state;
1085	vdev_stat_t *vs;
1086	char *name;
1087	uint64_t guid;
1088	char *msgid;
1089	nvlist_t *nvroot;
1090	int reason;
1091	const char *health;
1092	uint_t vsc;
1093	int namewidth;
1094
1095	verify(nvlist_lookup_string(config, ZPOOL_CONFIG_POOL_NAME,
1096	    &name) == 0);
1097	verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_GUID,
1098	    &guid) == 0);
1099	verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_STATE,
1100	    &pool_state) == 0);
1101	verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
1102	    &nvroot) == 0);
1103
1104	verify(nvlist_lookup_uint64_array(nvroot, ZPOOL_CONFIG_STATS,
1105	    (uint64_t **)&vs, &vsc) == 0);
1106	health = zpool_state_to_name(vs->vs_state, vs->vs_aux);
1107
1108	reason = zpool_import_status(config, &msgid);
1109
1110	(void) printf(gettext("  pool: %s\n"), name);
1111	(void) printf(gettext("    id: %llu\n"), (u_longlong_t)guid);
1112	(void) printf(gettext(" state: %s"), health);
1113	if (pool_state == POOL_STATE_DESTROYED)
1114		(void) printf(gettext(" (DESTROYED)"));
1115	(void) printf("\n");
1116
1117	switch (reason) {
1118	case ZPOOL_STATUS_MISSING_DEV_R:
1119	case ZPOOL_STATUS_MISSING_DEV_NR:
1120	case ZPOOL_STATUS_BAD_GUID_SUM:
1121		(void) printf(gettext("status: One or more devices are missing "
1122		    "from the system.\n"));
1123		break;
1124
1125	case ZPOOL_STATUS_CORRUPT_LABEL_R:
1126	case ZPOOL_STATUS_CORRUPT_LABEL_NR:
1127		(void) printf(gettext("status: One or more devices contains "
1128		    "corrupted data.\n"));
1129		break;
1130
1131	case ZPOOL_STATUS_CORRUPT_DATA:
1132		(void) printf(gettext("status: The pool data is corrupted.\n"));
1133		break;
1134
1135	case ZPOOL_STATUS_OFFLINE_DEV:
1136		(void) printf(gettext("status: One or more devices "
1137		    "are offlined.\n"));
1138		break;
1139
1140	case ZPOOL_STATUS_CORRUPT_POOL:
1141		(void) printf(gettext("status: The pool metadata is "
1142		    "corrupted.\n"));
1143		break;
1144
1145	case ZPOOL_STATUS_VERSION_OLDER:
1146		(void) printf(gettext("status: The pool is formatted using an "
1147		    "older on-disk version.\n"));
1148		break;
1149
1150	case ZPOOL_STATUS_VERSION_NEWER:
1151		(void) printf(gettext("status: The pool is formatted using an "
1152		    "incompatible version.\n"));
1153		break;
1154
1155	case ZPOOL_STATUS_HOSTID_MISMATCH:
1156		(void) printf(gettext("status: The pool was last accessed by "
1157		    "another system.\n"));
1158		break;
1159
1160	case ZPOOL_STATUS_FAULTED_DEV_R:
1161	case ZPOOL_STATUS_FAULTED_DEV_NR:
1162		(void) printf(gettext("status: One or more devices are "
1163		    "faulted.\n"));
1164		break;
1165
1166	case ZPOOL_STATUS_BAD_LOG:
1167		(void) printf(gettext("status: An intent log record cannot be "
1168		    "read.\n"));
1169		break;
1170
1171	default:
1172		/*
1173		 * No other status can be seen when importing pools.
1174		 */
1175		assert(reason == ZPOOL_STATUS_OK);
1176	}
1177
1178	/*
1179	 * Print out an action according to the overall state of the pool.
1180	 */
1181	if (vs->vs_state == VDEV_STATE_HEALTHY) {
1182		if (reason == ZPOOL_STATUS_VERSION_OLDER)
1183			(void) printf(gettext("action: The pool can be "
1184			    "imported using its name or numeric identifier, "
1185			    "though\n\tsome features will not be available "
1186			    "without an explicit 'zpool upgrade'.\n"));
1187		else if (reason == ZPOOL_STATUS_HOSTID_MISMATCH)
1188			(void) printf(gettext("action: The pool can be "
1189			    "imported using its name or numeric "
1190			    "identifier and\n\tthe '-f' flag.\n"));
1191		else
1192			(void) printf(gettext("action: The pool can be "
1193			    "imported using its name or numeric "
1194			    "identifier.\n"));
1195	} else if (vs->vs_state == VDEV_STATE_DEGRADED) {
1196		(void) printf(gettext("action: The pool can be imported "
1197		    "despite missing or damaged devices.  The\n\tfault "
1198		    "tolerance of the pool may be compromised if imported.\n"));
1199	} else {
1200		switch (reason) {
1201		case ZPOOL_STATUS_VERSION_NEWER:
1202			(void) printf(gettext("action: The pool cannot be "
1203			    "imported.  Access the pool on a system running "
1204			    "newer\n\tsoftware, or recreate the pool from "
1205			    "backup.\n"));
1206			break;
1207		case ZPOOL_STATUS_MISSING_DEV_R:
1208		case ZPOOL_STATUS_MISSING_DEV_NR:
1209		case ZPOOL_STATUS_BAD_GUID_SUM:
1210			(void) printf(gettext("action: The pool cannot be "
1211			    "imported. Attach the missing\n\tdevices and try "
1212			    "again.\n"));
1213			break;
1214		default:
1215			(void) printf(gettext("action: The pool cannot be "
1216			    "imported due to damaged devices or data.\n"));
1217		}
1218	}
1219
1220	/*
1221	 * If the state is "closed" or "can't open", and the aux state
1222	 * is "corrupt data":
1223	 */
1224	if (((vs->vs_state == VDEV_STATE_CLOSED) ||
1225	    (vs->vs_state == VDEV_STATE_CANT_OPEN)) &&
1226	    (vs->vs_aux == VDEV_AUX_CORRUPT_DATA)) {
1227		if (pool_state == POOL_STATE_DESTROYED)
1228			(void) printf(gettext("\tThe pool was destroyed, "
1229			    "but can be imported using the '-Df' flags.\n"));
1230		else if (pool_state != POOL_STATE_EXPORTED)
1231			(void) printf(gettext("\tThe pool may be active on "
1232			    "another system, but can be imported using\n\t"
1233			    "the '-f' flag.\n"));
1234	}
1235
1236	if (msgid != NULL)
1237		(void) printf(gettext("   see: http://www.sun.com/msg/%s\n"),
1238		    msgid);
1239
1240	(void) printf(gettext("config:\n\n"));
1241
1242	namewidth = max_width(NULL, nvroot, 0, 0);
1243	if (namewidth < 10)
1244		namewidth = 10;
1245
1246	print_import_config(name, nvroot, namewidth, 0, B_FALSE);
1247	if (num_logs(nvroot) > 0) {
1248		(void) printf(gettext("\tlogs\n"));
1249		print_import_config(name, nvroot, namewidth, 0, B_TRUE);
1250	}
1251
1252	if (reason == ZPOOL_STATUS_BAD_GUID_SUM) {
1253		(void) printf(gettext("\n\tAdditional devices are known to "
1254		    "be part of this pool, though their\n\texact "
1255		    "configuration cannot be determined.\n"));
1256	}
1257}
1258
1259/*
1260 * Perform the import for the given configuration.  This passes the heavy
1261 * lifting off to zpool_import_props(), and then mounts the datasets contained
1262 * within the pool.
1263 */
1264static int
1265do_import(nvlist_t *config, const char *newname, const char *mntopts,
1266    int force, nvlist_t *props, boolean_t allowfaulted)
1267{
1268	zpool_handle_t *zhp;
1269	char *name;
1270	uint64_t state;
1271	uint64_t version;
1272	int error = 0;
1273
1274	verify(nvlist_lookup_string(config, ZPOOL_CONFIG_POOL_NAME,
1275	    &name) == 0);
1276
1277	verify(nvlist_lookup_uint64(config,
1278	    ZPOOL_CONFIG_POOL_STATE, &state) == 0);
1279	verify(nvlist_lookup_uint64(config,
1280	    ZPOOL_CONFIG_VERSION, &version) == 0);
1281	if (version > SPA_VERSION) {
1282		(void) fprintf(stderr, gettext("cannot import '%s': pool "
1283		    "is formatted using a newer ZFS version\n"), name);
1284		return (1);
1285	} else if (state != POOL_STATE_EXPORTED && !force) {
1286		uint64_t hostid;
1287
1288		if (nvlist_lookup_uint64(config, ZPOOL_CONFIG_HOSTID,
1289		    &hostid) == 0) {
1290			if ((unsigned long)hostid != gethostid()) {
1291				char *hostname;
1292				uint64_t timestamp;
1293				time_t t;
1294
1295				verify(nvlist_lookup_string(config,
1296				    ZPOOL_CONFIG_HOSTNAME, &hostname) == 0);
1297				verify(nvlist_lookup_uint64(config,
1298				    ZPOOL_CONFIG_TIMESTAMP, &timestamp) == 0);
1299				t = timestamp;
1300				(void) fprintf(stderr, gettext("cannot import "
1301				    "'%s': pool may be in use from other "
1302				    "system, it was last accessed by %s "
1303				    "(hostid: 0x%lx) on %s"), name, hostname,
1304				    (unsigned long)hostid,
1305				    asctime(localtime(&t)));
1306				(void) fprintf(stderr, gettext("use '-f' to "
1307				    "import anyway\n"));
1308				return (1);
1309			}
1310		} else {
1311			(void) fprintf(stderr, gettext("cannot import '%s': "
1312			    "pool may be in use from other system\n"), name);
1313			(void) fprintf(stderr, gettext("use '-f' to import "
1314			    "anyway\n"));
1315			return (1);
1316		}
1317	}
1318
1319	if (zpool_import_props(g_zfs, config, newname, props,
1320	    allowfaulted) != 0)
1321		return (1);
1322
1323	if (newname != NULL)
1324		name = (char *)newname;
1325
1326	verify((zhp = zpool_open_canfail(g_zfs, name)) != NULL);
1327
1328	if (zpool_enable_datasets(zhp, mntopts, 0) != 0) {
1329		zpool_close(zhp);
1330		return (1);
1331	}
1332
1333	zpool_close(zhp);
1334	return (error);
1335}
1336
1337/*
1338 * zpool import [-d dir] [-D]
1339 *       import [-o mntopts] [-o prop=value] ... [-R root] [-D]
1340 *              [-d dir | -c cachefile] [-f] -a
1341 *       import [-o mntopts] [-o prop=value] ... [-R root] [-D]
1342 *              [-d dir | -c cachefile] [-f] <pool | id> [newpool]
1343 *
1344 *	 -c	Read pool information from a cachefile instead of searching
1345 *		devices.
1346 *
1347 *       -d	Scan in a specific directory, other than /dev/dsk.  More than
1348 *		one directory can be specified using multiple '-d' options.
1349 *
1350 *       -D     Scan for previously destroyed pools or import all or only
1351 *              specified destroyed pools.
1352 *
1353 *       -R	Temporarily import the pool, with all mountpoints relative to
1354 *		the given root.  The pool will remain exported when the machine
1355 *		is rebooted.
1356 *
1357 *       -f	Force import, even if it appears that the pool is active.
1358 *
1359 *       -F	Import even in the presence of faulted vdevs.  This is an
1360 *       	intentionally undocumented option for testing purposes, and
1361 *       	treats the pool configuration as complete, leaving any bad
1362 *		vdevs in the FAULTED state.
1363 *
1364 *       -a	Import all pools found.
1365 *
1366 *       -o	Set property=value and/or temporary mount options (without '=').
1367 *
1368 * The import command scans for pools to import, and import pools based on pool
1369 * name and GUID.  The pool can also be renamed as part of the import process.
1370 */
1371int
1372zpool_do_import(int argc, char **argv)
1373{
1374	char **searchdirs = NULL;
1375	int nsearch = 0;
1376	int c;
1377	int err;
1378	nvlist_t *pools = NULL;
1379	boolean_t do_all = B_FALSE;
1380	boolean_t do_destroyed = B_FALSE;
1381	char *mntopts = NULL;
1382	boolean_t do_force = B_FALSE;
1383	nvpair_t *elem;
1384	nvlist_t *config;
1385	uint64_t searchguid = 0;
1386	char *searchname = NULL;
1387	char *propval;
1388	nvlist_t *found_config;
1389	nvlist_t *props = NULL;
1390	boolean_t first;
1391	boolean_t allow_faulted = B_FALSE;
1392	uint64_t pool_state;
1393	char *cachefile = NULL;
1394
1395	/* check options */
1396	while ((c = getopt(argc, argv, ":ac:d:DfFo:p:R:")) != -1) {
1397		switch (c) {
1398		case 'a':
1399			do_all = B_TRUE;
1400			break;
1401		case 'c':
1402			cachefile = optarg;
1403			break;
1404		case 'd':
1405			if (searchdirs == NULL) {
1406				searchdirs = safe_malloc(sizeof (char *));
1407			} else {
1408				char **tmp = safe_malloc((nsearch + 1) *
1409				    sizeof (char *));
1410				bcopy(searchdirs, tmp, nsearch *
1411				    sizeof (char *));
1412				free(searchdirs);
1413				searchdirs = tmp;
1414			}
1415			searchdirs[nsearch++] = optarg;
1416			break;
1417		case 'D':
1418			do_destroyed = B_TRUE;
1419			break;
1420		case 'f':
1421			do_force = B_TRUE;
1422			break;
1423		case 'F':
1424			allow_faulted = B_TRUE;
1425			break;
1426		case 'o':
1427			if ((propval = strchr(optarg, '=')) != NULL) {
1428				*propval = '\0';
1429				propval++;
1430				if (add_prop_list(optarg, propval,
1431				    &props, B_TRUE))
1432					goto error;
1433			} else {
1434				mntopts = optarg;
1435			}
1436			break;
1437		case 'R':
1438			if (add_prop_list(zpool_prop_to_name(
1439			    ZPOOL_PROP_ALTROOT), optarg, &props, B_TRUE))
1440				goto error;
1441			if (nvlist_lookup_string(props,
1442			    zpool_prop_to_name(ZPOOL_PROP_CACHEFILE),
1443			    &propval) == 0)
1444				break;
1445			if (add_prop_list(zpool_prop_to_name(
1446			    ZPOOL_PROP_CACHEFILE), "none", &props, B_TRUE))
1447				goto error;
1448			break;
1449		case ':':
1450			(void) fprintf(stderr, gettext("missing argument for "
1451			    "'%c' option\n"), optopt);
1452			usage(B_FALSE);
1453			break;
1454		case '?':
1455			(void) fprintf(stderr, gettext("invalid option '%c'\n"),
1456			    optopt);
1457			usage(B_FALSE);
1458		}
1459	}
1460
1461	argc -= optind;
1462	argv += optind;
1463
1464	if (cachefile && nsearch != 0) {
1465		(void) fprintf(stderr, gettext("-c is incompatible with -d\n"));
1466		usage(B_FALSE);
1467	}
1468
1469	if (searchdirs == NULL) {
1470		searchdirs = safe_malloc(sizeof (char *));
1471		searchdirs[0] = "/dev/dsk";
1472		nsearch = 1;
1473	}
1474
1475	/* check argument count */
1476	if (do_all) {
1477		if (argc != 0) {
1478			(void) fprintf(stderr, gettext("too many arguments\n"));
1479			usage(B_FALSE);
1480		}
1481	} else {
1482		if (argc > 2) {
1483			(void) fprintf(stderr, gettext("too many arguments\n"));
1484			usage(B_FALSE);
1485		}
1486
1487		/*
1488		 * Check for the SYS_CONFIG privilege.  We do this explicitly
1489		 * here because otherwise any attempt to discover pools will
1490		 * silently fail.
1491		 */
1492		if (argc == 0 && !priv_ineffect(PRIV_SYS_CONFIG)) {
1493			(void) fprintf(stderr, gettext("cannot "
1494			    "discover pools: permission denied\n"));
1495			free(searchdirs);
1496			return (1);
1497		}
1498	}
1499
1500	/*
1501	 * Depending on the arguments given, we do one of the following:
1502	 *
1503	 *	<none>	Iterate through all pools and display information about
1504	 *		each one.
1505	 *
1506	 *	-a	Iterate through all pools and try to import each one.
1507	 *
1508	 *	<id>	Find the pool that corresponds to the given GUID/pool
1509	 *		name and import that one.
1510	 *
1511	 *	-D	Above options applies only to destroyed pools.
1512	 */
1513	if (argc != 0) {
1514		char *endptr;
1515
1516		errno = 0;
1517		searchguid = strtoull(argv[0], &endptr, 10);
1518		if (errno != 0 || *endptr != '\0')
1519			searchname = argv[0];
1520		found_config = NULL;
1521	}
1522
1523	if (cachefile) {
1524		pools = zpool_find_import_cached(g_zfs, cachefile, searchname,
1525		    searchguid);
1526	} else if (searchname != NULL) {
1527		pools = zpool_find_import_byname(g_zfs, nsearch, searchdirs,
1528		    searchname);
1529	} else {
1530		/*
1531		 * It's OK to search by guid even if searchguid is 0.
1532		 */
1533		pools = zpool_find_import_byguid(g_zfs, nsearch, searchdirs,
1534		    searchguid);
1535	}
1536
1537	if (pools == NULL) {
1538		if (argc != 0) {
1539			(void) fprintf(stderr, gettext("cannot import '%s': "
1540			    "no such pool available\n"), argv[0]);
1541		}
1542		free(searchdirs);
1543		return (1);
1544	}
1545
1546	/*
1547	 * At this point we have a list of import candidate configs. Even if
1548	 * we were searching by pool name or guid, we still need to
1549	 * post-process the list to deal with pool state and possible
1550	 * duplicate names.
1551	 */
1552	err = 0;
1553	elem = NULL;
1554	first = B_TRUE;
1555	while ((elem = nvlist_next_nvpair(pools, elem)) != NULL) {
1556
1557		verify(nvpair_value_nvlist(elem, &config) == 0);
1558
1559		verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_STATE,
1560		    &pool_state) == 0);
1561		if (!do_destroyed && pool_state == POOL_STATE_DESTROYED)
1562			continue;
1563		if (do_destroyed && pool_state != POOL_STATE_DESTROYED)
1564			continue;
1565
1566		if (argc == 0) {
1567			if (first)
1568				first = B_FALSE;
1569			else if (!do_all)
1570				(void) printf("\n");
1571
1572			if (do_all)
1573				err |= do_import(config, NULL, mntopts,
1574				    do_force, props, allow_faulted);
1575			else
1576				show_import(config);
1577		} else if (searchname != NULL) {
1578			char *name;
1579
1580			/*
1581			 * We are searching for a pool based on name.
1582			 */
1583			verify(nvlist_lookup_string(config,
1584			    ZPOOL_CONFIG_POOL_NAME, &name) == 0);
1585
1586			if (strcmp(name, searchname) == 0) {
1587				if (found_config != NULL) {
1588					(void) fprintf(stderr, gettext(
1589					    "cannot import '%s': more than "
1590					    "one matching pool\n"), searchname);
1591					(void) fprintf(stderr, gettext(
1592					    "import by numeric ID instead\n"));
1593					err = B_TRUE;
1594				}
1595				found_config = config;
1596			}
1597		} else {
1598			uint64_t guid;
1599
1600			/*
1601			 * Search for a pool by guid.
1602			 */
1603			verify(nvlist_lookup_uint64(config,
1604			    ZPOOL_CONFIG_POOL_GUID, &guid) == 0);
1605
1606			if (guid == searchguid)
1607				found_config = config;
1608		}
1609	}
1610
1611	/*
1612	 * If we were searching for a specific pool, verify that we found a
1613	 * pool, and then do the import.
1614	 */
1615	if (argc != 0 && err == 0) {
1616		if (found_config == NULL) {
1617			(void) fprintf(stderr, gettext("cannot import '%s': "
1618			    "no such pool available\n"), argv[0]);
1619			err = B_TRUE;
1620		} else {
1621			err |= do_import(found_config, argc == 1 ? NULL :
1622			    argv[1], mntopts, do_force, props, allow_faulted);
1623		}
1624	}
1625
1626	/*
1627	 * If we were just looking for pools, report an error if none were
1628	 * found.
1629	 */
1630	if (argc == 0 && first)
1631		(void) fprintf(stderr,
1632		    gettext("no pools available to import\n"));
1633
1634error:
1635	nvlist_free(props);
1636	nvlist_free(pools);
1637	free(searchdirs);
1638
1639	return (err ? 1 : 0);
1640}
1641
1642typedef struct iostat_cbdata {
1643	zpool_list_t *cb_list;
1644	int cb_verbose;
1645	int cb_iteration;
1646	int cb_namewidth;
1647} iostat_cbdata_t;
1648
1649static void
1650print_iostat_separator(iostat_cbdata_t *cb)
1651{
1652	int i = 0;
1653
1654	for (i = 0; i < cb->cb_namewidth; i++)
1655		(void) printf("-");
1656	(void) printf("  -----  -----  -----  -----  -----  -----\n");
1657}
1658
1659static void
1660print_iostat_header(iostat_cbdata_t *cb)
1661{
1662	(void) printf("%*s     capacity     operations    bandwidth\n",
1663	    cb->cb_namewidth, "");
1664	(void) printf("%-*s   used  avail   read  write   read  write\n",
1665	    cb->cb_namewidth, "pool");
1666	print_iostat_separator(cb);
1667}
1668
1669/*
1670 * Display a single statistic.
1671 */
1672static void
1673print_one_stat(uint64_t value)
1674{
1675	char buf[64];
1676
1677	zfs_nicenum(value, buf, sizeof (buf));
1678	(void) printf("  %5s", buf);
1679}
1680
1681/*
1682 * Print out all the statistics for the given vdev.  This can either be the
1683 * toplevel configuration, or called recursively.  If 'name' is NULL, then this
1684 * is a verbose output, and we don't want to display the toplevel pool stats.
1685 */
1686void
1687print_vdev_stats(zpool_handle_t *zhp, const char *name, nvlist_t *oldnv,
1688    nvlist_t *newnv, iostat_cbdata_t *cb, int depth)
1689{
1690	nvlist_t **oldchild, **newchild;
1691	uint_t c, children;
1692	vdev_stat_t *oldvs, *newvs;
1693	vdev_stat_t zerovs = { 0 };
1694	uint64_t tdelta;
1695	double scale;
1696	char *vname;
1697
1698	if (oldnv != NULL) {
1699		verify(nvlist_lookup_uint64_array(oldnv, ZPOOL_CONFIG_STATS,
1700		    (uint64_t **)&oldvs, &c) == 0);
1701	} else {
1702		oldvs = &zerovs;
1703	}
1704
1705	verify(nvlist_lookup_uint64_array(newnv, ZPOOL_CONFIG_STATS,
1706	    (uint64_t **)&newvs, &c) == 0);
1707
1708	if (strlen(name) + depth > cb->cb_namewidth)
1709		(void) printf("%*s%s", depth, "", name);
1710	else
1711		(void) printf("%*s%s%*s", depth, "", name,
1712		    (int)(cb->cb_namewidth - strlen(name) - depth), "");
1713
1714	tdelta = newvs->vs_timestamp - oldvs->vs_timestamp;
1715
1716	if (tdelta == 0)
1717		scale = 1.0;
1718	else
1719		scale = (double)NANOSEC / tdelta;
1720
1721	/* only toplevel vdevs have capacity stats */
1722	if (newvs->vs_space == 0) {
1723		(void) printf("      -      -");
1724	} else {
1725		print_one_stat(newvs->vs_alloc);
1726		print_one_stat(newvs->vs_space - newvs->vs_alloc);
1727	}
1728
1729	print_one_stat((uint64_t)(scale * (newvs->vs_ops[ZIO_TYPE_READ] -
1730	    oldvs->vs_ops[ZIO_TYPE_READ])));
1731
1732	print_one_stat((uint64_t)(scale * (newvs->vs_ops[ZIO_TYPE_WRITE] -
1733	    oldvs->vs_ops[ZIO_TYPE_WRITE])));
1734
1735	print_one_stat((uint64_t)(scale * (newvs->vs_bytes[ZIO_TYPE_READ] -
1736	    oldvs->vs_bytes[ZIO_TYPE_READ])));
1737
1738	print_one_stat((uint64_t)(scale * (newvs->vs_bytes[ZIO_TYPE_WRITE] -
1739	    oldvs->vs_bytes[ZIO_TYPE_WRITE])));
1740
1741	(void) printf("\n");
1742
1743	if (!cb->cb_verbose)
1744		return;
1745
1746	if (nvlist_lookup_nvlist_array(newnv, ZPOOL_CONFIG_CHILDREN,
1747	    &newchild, &children) != 0)
1748		return;
1749
1750	if (oldnv && nvlist_lookup_nvlist_array(oldnv, ZPOOL_CONFIG_CHILDREN,
1751	    &oldchild, &c) != 0)
1752		return;
1753
1754	for (c = 0; c < children; c++) {
1755		vname = zpool_vdev_name(g_zfs, zhp, newchild[c]);
1756		print_vdev_stats(zhp, vname, oldnv ? oldchild[c] : NULL,
1757		    newchild[c], cb, depth + 2);
1758		free(vname);
1759	}
1760
1761	/*
1762	 * Include level 2 ARC devices in iostat output
1763	 */
1764	if (nvlist_lookup_nvlist_array(newnv, ZPOOL_CONFIG_L2CACHE,
1765	    &newchild, &children) != 0)
1766		return;
1767
1768	if (oldnv && nvlist_lookup_nvlist_array(oldnv, ZPOOL_CONFIG_L2CACHE,
1769	    &oldchild, &c) != 0)
1770		return;
1771
1772	if (children > 0) {
1773		(void) printf("%-*s      -      -      -      -      -      "
1774		    "-\n", cb->cb_namewidth, "cache");
1775		for (c = 0; c < children; c++) {
1776			vname = zpool_vdev_name(g_zfs, zhp, newchild[c]);
1777			print_vdev_stats(zhp, vname, oldnv ? oldchild[c] : NULL,
1778			    newchild[c], cb, depth + 2);
1779			free(vname);
1780		}
1781	}
1782}
1783
1784static int
1785refresh_iostat(zpool_handle_t *zhp, void *data)
1786{
1787	iostat_cbdata_t *cb = data;
1788	boolean_t missing;
1789
1790	/*
1791	 * If the pool has disappeared, remove it from the list and continue.
1792	 */
1793	if (zpool_refresh_stats(zhp, &missing) != 0)
1794		return (-1);
1795
1796	if (missing)
1797		pool_list_remove(cb->cb_list, zhp);
1798
1799	return (0);
1800}
1801
1802/*
1803 * Callback to print out the iostats for the given pool.
1804 */
1805int
1806print_iostat(zpool_handle_t *zhp, void *data)
1807{
1808	iostat_cbdata_t *cb = data;
1809	nvlist_t *oldconfig, *newconfig;
1810	nvlist_t *oldnvroot, *newnvroot;
1811
1812	newconfig = zpool_get_config(zhp, &oldconfig);
1813
1814	if (cb->cb_iteration == 1)
1815		oldconfig = NULL;
1816
1817	verify(nvlist_lookup_nvlist(newconfig, ZPOOL_CONFIG_VDEV_TREE,
1818	    &newnvroot) == 0);
1819
1820	if (oldconfig == NULL)
1821		oldnvroot = NULL;
1822	else
1823		verify(nvlist_lookup_nvlist(oldconfig, ZPOOL_CONFIG_VDEV_TREE,
1824		    &oldnvroot) == 0);
1825
1826	/*
1827	 * Print out the statistics for the pool.
1828	 */
1829	print_vdev_stats(zhp, zpool_get_name(zhp), oldnvroot, newnvroot, cb, 0);
1830
1831	if (cb->cb_verbose)
1832		print_iostat_separator(cb);
1833
1834	return (0);
1835}
1836
1837int
1838get_namewidth(zpool_handle_t *zhp, void *data)
1839{
1840	iostat_cbdata_t *cb = data;
1841	nvlist_t *config, *nvroot;
1842
1843	if ((config = zpool_get_config(zhp, NULL)) != NULL) {
1844		verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
1845		    &nvroot) == 0);
1846		if (!cb->cb_verbose)
1847			cb->cb_namewidth = strlen(zpool_get_name(zhp));
1848		else
1849			cb->cb_namewidth = max_width(zhp, nvroot, 0, 0);
1850	}
1851
1852	/*
1853	 * The width must fall into the range [10,38].  The upper limit is the
1854	 * maximum we can have and still fit in 80 columns.
1855	 */
1856	if (cb->cb_namewidth < 10)
1857		cb->cb_namewidth = 10;
1858	if (cb->cb_namewidth > 38)
1859		cb->cb_namewidth = 38;
1860
1861	return (0);
1862}
1863
1864/*
1865 * zpool iostat [-v] [pool] ... [interval [count]]
1866 *
1867 *	-v	Display statistics for individual vdevs
1868 *
1869 * This command can be tricky because we want to be able to deal with pool
1870 * creation/destruction as well as vdev configuration changes.  The bulk of this
1871 * processing is handled by the pool_list_* routines in zpool_iter.c.  We rely
1872 * on pool_list_update() to detect the addition of new pools.  Configuration
1873 * changes are all handled within libzfs.
1874 */
1875int
1876zpool_do_iostat(int argc, char **argv)
1877{
1878	int c;
1879	int ret;
1880	int npools;
1881	unsigned long interval = 0, count = 0;
1882	zpool_list_t *list;
1883	boolean_t verbose = B_FALSE;
1884	iostat_cbdata_t cb;
1885
1886	/* check options */
1887	while ((c = getopt(argc, argv, "v")) != -1) {
1888		switch (c) {
1889		case 'v':
1890			verbose = B_TRUE;
1891			break;
1892		case '?':
1893			(void) fprintf(stderr, gettext("invalid option '%c'\n"),
1894			    optopt);
1895			usage(B_FALSE);
1896		}
1897	}
1898
1899	argc -= optind;
1900	argv += optind;
1901
1902	/*
1903	 * Determine if the last argument is an integer or a pool name
1904	 */
1905	if (argc > 0 && isdigit(argv[argc - 1][0])) {
1906		char *end;
1907
1908		errno = 0;
1909		interval = strtoul(argv[argc - 1], &end, 10);
1910
1911		if (*end == '\0' && errno == 0) {
1912			if (interval == 0) {
1913				(void) fprintf(stderr, gettext("interval "
1914				    "cannot be zero\n"));
1915				usage(B_FALSE);
1916			}
1917
1918			/*
1919			 * Ignore the last parameter
1920			 */
1921			argc--;
1922		} else {
1923			/*
1924			 * If this is not a valid number, just plow on.  The
1925			 * user will get a more informative error message later
1926			 * on.
1927			 */
1928			interval = 0;
1929		}
1930	}
1931
1932	/*
1933	 * If the last argument is also an integer, then we have both a count
1934	 * and an integer.
1935	 */
1936	if (argc > 0 && isdigit(argv[argc - 1][0])) {
1937		char *end;
1938
1939		errno = 0;
1940		count = interval;
1941		interval = strtoul(argv[argc - 1], &end, 10);
1942
1943		if (*end == '\0' && errno == 0) {
1944			if (interval == 0) {
1945				(void) fprintf(stderr, gettext("interval "
1946				    "cannot be zero\n"));
1947				usage(B_FALSE);
1948			}
1949
1950			/*
1951			 * Ignore the last parameter
1952			 */
1953			argc--;
1954		} else {
1955			interval = 0;
1956		}
1957	}
1958
1959	/*
1960	 * Construct the list of all interesting pools.
1961	 */
1962	ret = 0;
1963	if ((list = pool_list_get(argc, argv, NULL, &ret)) == NULL)
1964		return (1);
1965
1966	if (pool_list_count(list) == 0 && argc != 0) {
1967		pool_list_free(list);
1968		return (1);
1969	}
1970
1971	if (pool_list_count(list) == 0 && interval == 0) {
1972		pool_list_free(list);
1973		(void) fprintf(stderr, gettext("no pools available\n"));
1974		return (1);
1975	}
1976
1977	/*
1978	 * Enter the main iostat loop.
1979	 */
1980	cb.cb_list = list;
1981	cb.cb_verbose = verbose;
1982	cb.cb_iteration = 0;
1983	cb.cb_namewidth = 0;
1984
1985	for (;;) {
1986		pool_list_update(list);
1987
1988		if ((npools = pool_list_count(list)) == 0)
1989			break;
1990
1991		/*
1992		 * Refresh all statistics.  This is done as an explicit step
1993		 * before calculating the maximum name width, so that any
1994		 * configuration changes are properly accounted for.
1995		 */
1996		(void) pool_list_iter(list, B_FALSE, refresh_iostat, &cb);
1997
1998		/*
1999		 * Iterate over all pools to determine the maximum width
2000		 * for the pool / device name column across all pools.
2001		 */
2002		cb.cb_namewidth = 0;
2003		(void) pool_list_iter(list, B_FALSE, get_namewidth, &cb);
2004
2005		/*
2006		 * If it's the first time, or verbose mode, print the header.
2007		 */
2008		if (++cb.cb_iteration == 1 || verbose)
2009			print_iostat_header(&cb);
2010
2011		(void) pool_list_iter(list, B_FALSE, print_iostat, &cb);
2012
2013		/*
2014		 * If there's more than one pool, and we're not in verbose mode
2015		 * (which prints a separator for us), then print a separator.
2016		 */
2017		if (npools > 1 && !verbose)
2018			print_iostat_separator(&cb);
2019
2020		if (verbose)
2021			(void) printf("\n");
2022
2023		/*
2024		 * Flush the output so that redirection to a file isn't buffered
2025		 * indefinitely.
2026		 */
2027		(void) fflush(stdout);
2028
2029		if (interval == 0)
2030			break;
2031
2032		if (count != 0 && --count == 0)
2033			break;
2034
2035		(void) sleep(interval);
2036	}
2037
2038	pool_list_free(list);
2039
2040	return (ret);
2041}
2042
2043typedef struct list_cbdata {
2044	boolean_t	cb_scripted;
2045	boolean_t	cb_first;
2046	zprop_list_t	*cb_proplist;
2047} list_cbdata_t;
2048
2049/*
2050 * Given a list of columns to display, output appropriate headers for each one.
2051 */
2052static void
2053print_header(zprop_list_t *pl)
2054{
2055	const char *header;
2056	boolean_t first = B_TRUE;
2057	boolean_t right_justify;
2058
2059	for (; pl != NULL; pl = pl->pl_next) {
2060		if (pl->pl_prop == ZPROP_INVAL)
2061			continue;
2062
2063		if (!first)
2064			(void) printf("  ");
2065		else
2066			first = B_FALSE;
2067
2068		header = zpool_prop_column_name(pl->pl_prop);
2069		right_justify = zpool_prop_align_right(pl->pl_prop);
2070
2071		if (pl->pl_next == NULL && !right_justify)
2072			(void) printf("%s", header);
2073		else if (right_justify)
2074			(void) printf("%*s", pl->pl_width, header);
2075		else
2076			(void) printf("%-*s", pl->pl_width, header);
2077	}
2078
2079	(void) printf("\n");
2080}
2081
2082/*
2083 * Given a pool and a list of properties, print out all the properties according
2084 * to the described layout.
2085 */
2086static void
2087print_pool(zpool_handle_t *zhp, zprop_list_t *pl, int scripted)
2088{
2089	boolean_t first = B_TRUE;
2090	char property[ZPOOL_MAXPROPLEN];
2091	char *propstr;
2092	boolean_t right_justify;
2093	int width;
2094
2095	for (; pl != NULL; pl = pl->pl_next) {
2096		if (!first) {
2097			if (scripted)
2098				(void) printf("\t");
2099			else
2100				(void) printf("  ");
2101		} else {
2102			first = B_FALSE;
2103		}
2104
2105		right_justify = B_FALSE;
2106		if (pl->pl_prop != ZPROP_INVAL) {
2107			if (zpool_get_prop(zhp, pl->pl_prop, property,
2108			    sizeof (property), NULL) != 0)
2109				propstr = "-";
2110			else
2111				propstr = property;
2112
2113			right_justify = zpool_prop_align_right(pl->pl_prop);
2114		} else {
2115			propstr = "-";
2116		}
2117
2118		width = pl->pl_width;
2119
2120		/*
2121		 * If this is being called in scripted mode, or if this is the
2122		 * last column and it is left-justified, don't include a width
2123		 * format specifier.
2124		 */
2125		if (scripted || (pl->pl_next == NULL && !right_justify))
2126			(void) printf("%s", propstr);
2127		else if (right_justify)
2128			(void) printf("%*s", width, propstr);
2129		else
2130			(void) printf("%-*s", width, propstr);
2131	}
2132
2133	(void) printf("\n");
2134}
2135
2136/*
2137 * Generic callback function to list a pool.
2138 */
2139int
2140list_callback(zpool_handle_t *zhp, void *data)
2141{
2142	list_cbdata_t *cbp = data;
2143
2144	if (cbp->cb_first) {
2145		if (!cbp->cb_scripted)
2146			print_header(cbp->cb_proplist);
2147		cbp->cb_first = B_FALSE;
2148	}
2149
2150	print_pool(zhp, cbp->cb_proplist, cbp->cb_scripted);
2151
2152	return (0);
2153}
2154
2155/*
2156 * zpool list [-H] [-o prop[,prop]*] [pool] ...
2157 *
2158 *	-H	Scripted mode.  Don't display headers, and separate properties
2159 *		by a single tab.
2160 *	-o	List of properties to display.  Defaults to
2161 *		"name,size,used,available,capacity,health,altroot"
2162 *
2163 * List all pools in the system, whether or not they're healthy.  Output space
2164 * statistics for each one, as well as health status summary.
2165 */
2166int
2167zpool_do_list(int argc, char **argv)
2168{
2169	int c;
2170	int ret;
2171	list_cbdata_t cb = { 0 };
2172	static char default_props[] =
2173	    "name,size,used,available,capacity,health,altroot";
2174	char *props = default_props;
2175
2176	/* check options */
2177	while ((c = getopt(argc, argv, ":Ho:")) != -1) {
2178		switch (c) {
2179		case 'H':
2180			cb.cb_scripted = B_TRUE;
2181			break;
2182		case 'o':
2183			props = optarg;
2184			break;
2185		case ':':
2186			(void) fprintf(stderr, gettext("missing argument for "
2187			    "'%c' option\n"), optopt);
2188			usage(B_FALSE);
2189			break;
2190		case '?':
2191			(void) fprintf(stderr, gettext("invalid option '%c'\n"),
2192			    optopt);
2193			usage(B_FALSE);
2194		}
2195	}
2196
2197	argc -= optind;
2198	argv += optind;
2199
2200	if (zprop_get_list(g_zfs, props, &cb.cb_proplist, ZFS_TYPE_POOL) != 0)
2201		usage(B_FALSE);
2202
2203	cb.cb_first = B_TRUE;
2204
2205	ret = for_each_pool(argc, argv, B_TRUE, &cb.cb_proplist,
2206	    list_callback, &cb);
2207
2208	zprop_free_list(cb.cb_proplist);
2209
2210	if (argc == 0 && cb.cb_first && !cb.cb_scripted) {
2211		(void) printf(gettext("no pools available\n"));
2212		return (0);
2213	}
2214
2215	return (ret);
2216}
2217
2218static nvlist_t *
2219zpool_get_vdev_by_name(nvlist_t *nv, char *name)
2220{
2221	nvlist_t **child;
2222	uint_t c, children;
2223	nvlist_t *match;
2224	char *path;
2225
2226	if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
2227	    &child, &children) != 0) {
2228		verify(nvlist_lookup_string(nv, ZPOOL_CONFIG_PATH, &path) == 0);
2229		if (strncmp(name, _PATH_DEV, sizeof(_PATH_DEV)-1) == 0)
2230			name += sizeof(_PATH_DEV)-1;
2231		if (strncmp(path, _PATH_DEV, sizeof(_PATH_DEV)-1) == 0)
2232			path += sizeof(_PATH_DEV)-1;
2233		if (strcmp(name, path) == 0)
2234			return (nv);
2235		return (NULL);
2236	}
2237
2238	for (c = 0; c < children; c++)
2239		if ((match = zpool_get_vdev_by_name(child[c], name)) != NULL)
2240			return (match);
2241
2242	return (NULL);
2243}
2244
2245static int
2246zpool_do_attach_or_replace(int argc, char **argv, int replacing)
2247{
2248	boolean_t force = B_FALSE;
2249	int c;
2250	nvlist_t *nvroot;
2251	char *poolname, *old_disk, *new_disk;
2252	zpool_handle_t *zhp;
2253	int ret;
2254
2255	/* check options */
2256	while ((c = getopt(argc, argv, "f")) != -1) {
2257		switch (c) {
2258		case 'f':
2259			force = B_TRUE;
2260			break;
2261		case '?':
2262			(void) fprintf(stderr, gettext("invalid option '%c'\n"),
2263			    optopt);
2264			usage(B_FALSE);
2265		}
2266	}
2267
2268	argc -= optind;
2269	argv += optind;
2270
2271	/* get pool name and check number of arguments */
2272	if (argc < 1) {
2273		(void) fprintf(stderr, gettext("missing pool name argument\n"));
2274		usage(B_FALSE);
2275	}
2276
2277	poolname = argv[0];
2278
2279	if (argc < 2) {
2280		(void) fprintf(stderr,
2281		    gettext("missing <device> specification\n"));
2282		usage(B_FALSE);
2283	}
2284
2285	old_disk = argv[1];
2286
2287	if (argc < 3) {
2288		if (!replacing) {
2289			(void) fprintf(stderr,
2290			    gettext("missing <new_device> specification\n"));
2291			usage(B_FALSE);
2292		}
2293		new_disk = old_disk;
2294		argc -= 1;
2295		argv += 1;
2296	} else {
2297		new_disk = argv[2];
2298		argc -= 2;
2299		argv += 2;
2300	}
2301
2302	if (argc > 1) {
2303		(void) fprintf(stderr, gettext("too many arguments\n"));
2304		usage(B_FALSE);
2305	}
2306
2307	if ((zhp = zpool_open(g_zfs, poolname)) == NULL)
2308		return (1);
2309
2310	if (zpool_get_config(zhp, NULL) == NULL) {
2311		(void) fprintf(stderr, gettext("pool '%s' is unavailable\n"),
2312		    poolname);
2313		zpool_close(zhp);
2314		return (1);
2315	}
2316
2317	nvroot = make_root_vdev(zhp, force, B_FALSE, replacing, B_FALSE,
2318	    argc, argv);
2319	if (nvroot == NULL) {
2320		zpool_close(zhp);
2321		return (1);
2322	}
2323
2324	ret = zpool_vdev_attach(zhp, old_disk, new_disk, nvroot, replacing);
2325
2326	nvlist_free(nvroot);
2327	zpool_close(zhp);
2328
2329	return (ret);
2330}
2331
2332/*
2333 * zpool replace [-f] <pool> <device> <new_device>
2334 *
2335 *	-f	Force attach, even if <new_device> appears to be in use.
2336 *
2337 * Replace <device> with <new_device>.
2338 */
2339/* ARGSUSED */
2340int
2341zpool_do_replace(int argc, char **argv)
2342{
2343	return (zpool_do_attach_or_replace(argc, argv, B_TRUE));
2344}
2345
2346/*
2347 * zpool attach [-f] <pool> <device> <new_device>
2348 *
2349 *	-f	Force attach, even if <new_device> appears to be in use.
2350 *
2351 * Attach <new_device> to the mirror containing <device>.  If <device> is not
2352 * part of a mirror, then <device> will be transformed into a mirror of
2353 * <device> and <new_device>.  In either case, <new_device> will begin life
2354 * with a DTL of [0, now], and will immediately begin to resilver itself.
2355 */
2356int
2357zpool_do_attach(int argc, char **argv)
2358{
2359	return (zpool_do_attach_or_replace(argc, argv, B_FALSE));
2360}
2361
2362/*
2363 * zpool detach [-f] <pool> <device>
2364 *
2365 *	-f	Force detach of <device>, even if DTLs argue against it
2366 *		(not supported yet)
2367 *
2368 * Detach a device from a mirror.  The operation will be refused if <device>
2369 * is the last device in the mirror, or if the DTLs indicate that this device
2370 * has the only valid copy of some data.
2371 */
2372/* ARGSUSED */
2373int
2374zpool_do_detach(int argc, char **argv)
2375{
2376	int c;
2377	char *poolname, *path;
2378	zpool_handle_t *zhp;
2379	int ret;
2380
2381	/* check options */
2382	while ((c = getopt(argc, argv, "f")) != -1) {
2383		switch (c) {
2384		case 'f':
2385		case '?':
2386			(void) fprintf(stderr, gettext("invalid option '%c'\n"),
2387			    optopt);
2388			usage(B_FALSE);
2389		}
2390	}
2391
2392	argc -= optind;
2393	argv += optind;
2394
2395	/* get pool name and check number of arguments */
2396	if (argc < 1) {
2397		(void) fprintf(stderr, gettext("missing pool name argument\n"));
2398		usage(B_FALSE);
2399	}
2400
2401	if (argc < 2) {
2402		(void) fprintf(stderr,
2403		    gettext("missing <device> specification\n"));
2404		usage(B_FALSE);
2405	}
2406
2407	poolname = argv[0];
2408	path = argv[1];
2409
2410	if ((zhp = zpool_open(g_zfs, poolname)) == NULL)
2411		return (1);
2412
2413	ret = zpool_vdev_detach(zhp, path);
2414
2415	zpool_close(zhp);
2416
2417	return (ret);
2418}
2419
2420/*
2421 * zpool online <pool> <device> ...
2422 */
2423int
2424zpool_do_online(int argc, char **argv)
2425{
2426	int c, i;
2427	char *poolname;
2428	zpool_handle_t *zhp;
2429	int ret = 0;
2430	vdev_state_t newstate;
2431
2432	/* check options */
2433	while ((c = getopt(argc, argv, "t")) != -1) {
2434		switch (c) {
2435		case 't':
2436		case '?':
2437			(void) fprintf(stderr, gettext("invalid option '%c'\n"),
2438			    optopt);
2439			usage(B_FALSE);
2440		}
2441	}
2442
2443	argc -= optind;
2444	argv += optind;
2445
2446	/* get pool name and check number of arguments */
2447	if (argc < 1) {
2448		(void) fprintf(stderr, gettext("missing pool name\n"));
2449		usage(B_FALSE);
2450	}
2451	if (argc < 2) {
2452		(void) fprintf(stderr, gettext("missing device name\n"));
2453		usage(B_FALSE);
2454	}
2455
2456	poolname = argv[0];
2457
2458	if ((zhp = zpool_open(g_zfs, poolname)) == NULL)
2459		return (1);
2460
2461	for (i = 1; i < argc; i++) {
2462		if (zpool_vdev_online(zhp, argv[i], 0, &newstate) == 0) {
2463			if (newstate != VDEV_STATE_HEALTHY) {
2464				(void) printf(gettext("warning: device '%s' "
2465				    "onlined, but remains in faulted state\n"),
2466				    argv[i]);
2467				if (newstate == VDEV_STATE_FAULTED)
2468					(void) printf(gettext("use 'zpool "
2469					    "clear' to restore a faulted "
2470					    "device\n"));
2471				else
2472					(void) printf(gettext("use 'zpool "
2473					    "replace' to replace devices "
2474					    "that are no longer present\n"));
2475			}
2476		} else {
2477			ret = 1;
2478		}
2479	}
2480
2481	zpool_close(zhp);
2482
2483	return (ret);
2484}
2485
2486/*
2487 * zpool offline [-ft] <pool> <device> ...
2488 *
2489 *	-f	Force the device into the offline state, even if doing
2490 *		so would appear to compromise pool availability.
2491 *		(not supported yet)
2492 *
2493 *	-t	Only take the device off-line temporarily.  The offline
2494 *		state will not be persistent across reboots.
2495 */
2496/* ARGSUSED */
2497int
2498zpool_do_offline(int argc, char **argv)
2499{
2500	int c, i;
2501	char *poolname;
2502	zpool_handle_t *zhp;
2503	int ret = 0;
2504	boolean_t istmp = B_FALSE;
2505
2506	/* check options */
2507	while ((c = getopt(argc, argv, "ft")) != -1) {
2508		switch (c) {
2509		case 't':
2510			istmp = B_TRUE;
2511			break;
2512		case 'f':
2513		case '?':
2514			(void) fprintf(stderr, gettext("invalid option '%c'\n"),
2515			    optopt);
2516			usage(B_FALSE);
2517		}
2518	}
2519
2520	argc -= optind;
2521	argv += optind;
2522
2523	/* get pool name and check number of arguments */
2524	if (argc < 1) {
2525		(void) fprintf(stderr, gettext("missing pool name\n"));
2526		usage(B_FALSE);
2527	}
2528	if (argc < 2) {
2529		(void) fprintf(stderr, gettext("missing device name\n"));
2530		usage(B_FALSE);
2531	}
2532
2533	poolname = argv[0];
2534
2535	if ((zhp = zpool_open(g_zfs, poolname)) == NULL)
2536		return (1);
2537
2538	for (i = 1; i < argc; i++) {
2539		if (zpool_vdev_offline(zhp, argv[i], istmp) != 0)
2540			ret = 1;
2541	}
2542
2543	zpool_close(zhp);
2544
2545	return (ret);
2546}
2547
2548/*
2549 * zpool clear <pool> [device]
2550 *
2551 * Clear all errors associated with a pool or a particular device.
2552 */
2553int
2554zpool_do_clear(int argc, char **argv)
2555{
2556	int ret = 0;
2557	zpool_handle_t *zhp;
2558	char *pool, *device;
2559
2560	if (argc < 2) {
2561		(void) fprintf(stderr, gettext("missing pool name\n"));
2562		usage(B_FALSE);
2563	}
2564
2565	if (argc > 3) {
2566		(void) fprintf(stderr, gettext("too many arguments\n"));
2567		usage(B_FALSE);
2568	}
2569
2570	pool = argv[1];
2571	device = argc == 3 ? argv[2] : NULL;
2572
2573	if ((zhp = zpool_open_canfail(g_zfs, pool)) == NULL)
2574		return (1);
2575
2576	if (zpool_clear(zhp, device) != 0)
2577		ret = 1;
2578
2579	zpool_close(zhp);
2580
2581	return (ret);
2582}
2583
2584typedef struct scrub_cbdata {
2585	int	cb_type;
2586	int	cb_argc;
2587	char	**cb_argv;
2588} scrub_cbdata_t;
2589
2590int
2591scrub_callback(zpool_handle_t *zhp, void *data)
2592{
2593	scrub_cbdata_t *cb = data;
2594	int err;
2595
2596	/*
2597	 * Ignore faulted pools.
2598	 */
2599	if (zpool_get_state(zhp) == POOL_STATE_UNAVAIL) {
2600		(void) fprintf(stderr, gettext("cannot scrub '%s': pool is "
2601		    "currently unavailable\n"), zpool_get_name(zhp));
2602		return (1);
2603	}
2604
2605	err = zpool_scrub(zhp, cb->cb_type);
2606
2607	return (err != 0);
2608}
2609
2610/*
2611 * zpool scrub [-s] <pool> ...
2612 *
2613 *	-s	Stop.  Stops any in-progress scrub.
2614 */
2615int
2616zpool_do_scrub(int argc, char **argv)
2617{
2618	int c;
2619	scrub_cbdata_t cb;
2620
2621	cb.cb_type = POOL_SCRUB_EVERYTHING;
2622
2623	/* check options */
2624	while ((c = getopt(argc, argv, "s")) != -1) {
2625		switch (c) {
2626		case 's':
2627			cb.cb_type = POOL_SCRUB_NONE;
2628			break;
2629		case '?':
2630			(void) fprintf(stderr, gettext("invalid option '%c'\n"),
2631			    optopt);
2632			usage(B_FALSE);
2633		}
2634	}
2635
2636	cb.cb_argc = argc;
2637	cb.cb_argv = argv;
2638	argc -= optind;
2639	argv += optind;
2640
2641	if (argc < 1) {
2642		(void) fprintf(stderr, gettext("missing pool name argument\n"));
2643		usage(B_FALSE);
2644	}
2645
2646	return (for_each_pool(argc, argv, B_TRUE, NULL, scrub_callback, &cb));
2647}
2648
2649typedef struct status_cbdata {
2650	int		cb_count;
2651	boolean_t	cb_allpools;
2652	boolean_t	cb_verbose;
2653	boolean_t	cb_explain;
2654	boolean_t	cb_first;
2655} status_cbdata_t;
2656
2657/*
2658 * Print out detailed scrub status.
2659 */
2660void
2661print_scrub_status(nvlist_t *nvroot)
2662{
2663	vdev_stat_t *vs;
2664	uint_t vsc;
2665	time_t start, end, now;
2666	double fraction_done;
2667	uint64_t examined, total, minutes_left, minutes_taken;
2668	char *scrub_type;
2669
2670	verify(nvlist_lookup_uint64_array(nvroot, ZPOOL_CONFIG_STATS,
2671	    (uint64_t **)&vs, &vsc) == 0);
2672
2673	/*
2674	 * If there's never been a scrub, there's not much to say.
2675	 */
2676	if (vs->vs_scrub_end == 0 && vs->vs_scrub_type == POOL_SCRUB_NONE) {
2677		(void) printf(gettext("none requested\n"));
2678		return;
2679	}
2680
2681	scrub_type = (vs->vs_scrub_type == POOL_SCRUB_RESILVER) ?
2682	    "resilver" : "scrub";
2683
2684	start = vs->vs_scrub_start;
2685	end = vs->vs_scrub_end;
2686	now = time(NULL);
2687	examined = vs->vs_scrub_examined;
2688	total = vs->vs_alloc;
2689
2690	if (end != 0) {
2691		minutes_taken = (uint64_t)((end - start) / 60);
2692
2693		(void) printf(gettext("%s %s after %lluh%um with %llu errors "
2694		    "on %s"),
2695		    scrub_type, vs->vs_scrub_complete ? "completed" : "stopped",
2696		    (u_longlong_t)(minutes_taken / 60),
2697		    (uint_t)(minutes_taken % 60),
2698		    (u_longlong_t)vs->vs_scrub_errors, ctime(&end));
2699		return;
2700	}
2701
2702	if (examined == 0)
2703		examined = 1;
2704	if (examined > total)
2705		total = examined;
2706
2707	fraction_done = (double)examined / total;
2708	minutes_left = (uint64_t)((now - start) *
2709	    (1 - fraction_done) / fraction_done / 60);
2710	minutes_taken = (uint64_t)((now - start) / 60);
2711
2712	(void) printf(gettext("%s in progress for %lluh%um, %.2f%% done, "
2713	    "%lluh%um to go\n"),
2714	    scrub_type, (u_longlong_t)(minutes_taken / 60),
2715	    (uint_t)(minutes_taken % 60), 100 * fraction_done,
2716	    (u_longlong_t)(minutes_left / 60), (uint_t)(minutes_left % 60));
2717}
2718
2719typedef struct spare_cbdata {
2720	uint64_t	cb_guid;
2721	zpool_handle_t	*cb_zhp;
2722} spare_cbdata_t;
2723
2724static boolean_t
2725find_vdev(nvlist_t *nv, uint64_t search)
2726{
2727	uint64_t guid;
2728	nvlist_t **child;
2729	uint_t c, children;
2730
2731	if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_GUID, &guid) == 0 &&
2732	    search == guid)
2733		return (B_TRUE);
2734
2735	if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
2736	    &child, &children) == 0) {
2737		for (c = 0; c < children; c++)
2738			if (find_vdev(child[c], search))
2739				return (B_TRUE);
2740	}
2741
2742	return (B_FALSE);
2743}
2744
2745static int
2746find_spare(zpool_handle_t *zhp, void *data)
2747{
2748	spare_cbdata_t *cbp = data;
2749	nvlist_t *config, *nvroot;
2750
2751	config = zpool_get_config(zhp, NULL);
2752	verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
2753	    &nvroot) == 0);
2754
2755	if (find_vdev(nvroot, cbp->cb_guid)) {
2756		cbp->cb_zhp = zhp;
2757		return (1);
2758	}
2759
2760	zpool_close(zhp);
2761	return (0);
2762}
2763
2764/*
2765 * Print out configuration state as requested by status_callback.
2766 */
2767void
2768print_status_config(zpool_handle_t *zhp, const char *name, nvlist_t *nv,
2769    int namewidth, int depth, boolean_t isspare, boolean_t print_logs)
2770{
2771	nvlist_t **child;
2772	uint_t c, children;
2773	vdev_stat_t *vs;
2774	char rbuf[6], wbuf[6], cbuf[6], repaired[7];
2775	char *vname;
2776	uint64_t notpresent;
2777	spare_cbdata_t cb;
2778	char *state;
2779
2780	verify(nvlist_lookup_uint64_array(nv, ZPOOL_CONFIG_STATS,
2781	    (uint64_t **)&vs, &c) == 0);
2782
2783	if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
2784	    &child, &children) != 0)
2785		children = 0;
2786
2787	state = zpool_state_to_name(vs->vs_state, vs->vs_aux);
2788	if (isspare) {
2789		/*
2790		 * For hot spares, we use the terms 'INUSE' and 'AVAILABLE' for
2791		 * online drives.
2792		 */
2793		if (vs->vs_aux == VDEV_AUX_SPARED)
2794			state = "INUSE";
2795		else if (vs->vs_state == VDEV_STATE_HEALTHY)
2796			state = "AVAIL";
2797	}
2798
2799	(void) printf("\t%*s%-*s  %-8s", depth, "", namewidth - depth,
2800	    name, state);
2801
2802	if (!isspare) {
2803		zfs_nicenum(vs->vs_read_errors, rbuf, sizeof (rbuf));
2804		zfs_nicenum(vs->vs_write_errors, wbuf, sizeof (wbuf));
2805		zfs_nicenum(vs->vs_checksum_errors, cbuf, sizeof (cbuf));
2806		(void) printf(" %5s %5s %5s", rbuf, wbuf, cbuf);
2807	}
2808
2809	if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_NOT_PRESENT,
2810	    &notpresent) == 0) {
2811		char *path;
2812		verify(nvlist_lookup_string(nv, ZPOOL_CONFIG_PATH, &path) == 0);
2813		(void) printf("  was %s", path);
2814	} else if (vs->vs_aux != 0) {
2815		(void) printf("  ");
2816
2817		switch (vs->vs_aux) {
2818		case VDEV_AUX_OPEN_FAILED:
2819			(void) printf(gettext("cannot open"));
2820			break;
2821
2822		case VDEV_AUX_BAD_GUID_SUM:
2823			(void) printf(gettext("missing device"));
2824			break;
2825
2826		case VDEV_AUX_NO_REPLICAS:
2827			(void) printf(gettext("insufficient replicas"));
2828			break;
2829
2830		case VDEV_AUX_VERSION_NEWER:
2831			(void) printf(gettext("newer version"));
2832			break;
2833
2834		case VDEV_AUX_SPARED:
2835			verify(nvlist_lookup_uint64(nv, ZPOOL_CONFIG_GUID,
2836			    &cb.cb_guid) == 0);
2837			if (zpool_iter(g_zfs, find_spare, &cb) == 1) {
2838				if (strcmp(zpool_get_name(cb.cb_zhp),
2839				    zpool_get_name(zhp)) == 0)
2840					(void) printf(gettext("currently in "
2841					    "use"));
2842				else
2843					(void) printf(gettext("in use by "
2844					    "pool '%s'"),
2845					    zpool_get_name(cb.cb_zhp));
2846				zpool_close(cb.cb_zhp);
2847			} else {
2848				(void) printf(gettext("currently in use"));
2849			}
2850			break;
2851
2852		case VDEV_AUX_ERR_EXCEEDED:
2853			(void) printf(gettext("too many errors"));
2854			break;
2855
2856		case VDEV_AUX_IO_FAILURE:
2857			(void) printf(gettext("experienced I/O failures"));
2858			break;
2859
2860		case VDEV_AUX_BAD_LOG:
2861			(void) printf(gettext("bad intent log"));
2862			break;
2863
2864		default:
2865			(void) printf(gettext("corrupted data"));
2866			break;
2867		}
2868	} else if (vs->vs_scrub_repaired != 0 && children == 0) {
2869		/*
2870		 * Report bytes resilvered/repaired on leaf devices.
2871		 */
2872		zfs_nicenum(vs->vs_scrub_repaired, repaired, sizeof (repaired));
2873		(void) printf(gettext("  %s %s"), repaired,
2874		    (vs->vs_scrub_type == POOL_SCRUB_RESILVER) ?
2875		    "resilvered" : "repaired");
2876	}
2877
2878	(void) printf("\n");
2879
2880	for (c = 0; c < children; c++) {
2881		uint64_t is_log = B_FALSE;
2882
2883		(void) nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_LOG,
2884		    &is_log);
2885		if ((is_log && !print_logs) || (!is_log && print_logs))
2886			continue;
2887		vname = zpool_vdev_name(g_zfs, zhp, child[c]);
2888		print_status_config(zhp, vname, child[c],
2889		    namewidth, depth + 2, isspare, B_FALSE);
2890		free(vname);
2891	}
2892}
2893
2894static void
2895print_error_log(zpool_handle_t *zhp)
2896{
2897	nvlist_t *nverrlist = NULL;
2898	nvpair_t *elem;
2899	char *pathname;
2900	size_t len = MAXPATHLEN * 2;
2901
2902	if (zpool_get_errlog(zhp, &nverrlist) != 0) {
2903		(void) printf("errors: List of errors unavailable "
2904		    "(insufficient privileges)\n");
2905		return;
2906	}
2907
2908	(void) printf("errors: Permanent errors have been "
2909	    "detected in the following files:\n\n");
2910
2911	pathname = safe_malloc(len);
2912	elem = NULL;
2913	while ((elem = nvlist_next_nvpair(nverrlist, elem)) != NULL) {
2914		nvlist_t *nv;
2915		uint64_t dsobj, obj;
2916
2917		verify(nvpair_value_nvlist(elem, &nv) == 0);
2918		verify(nvlist_lookup_uint64(nv, ZPOOL_ERR_DATASET,
2919		    &dsobj) == 0);
2920		verify(nvlist_lookup_uint64(nv, ZPOOL_ERR_OBJECT,
2921		    &obj) == 0);
2922		zpool_obj_to_path(zhp, dsobj, obj, pathname, len);
2923		(void) printf("%7s %s\n", "", pathname);
2924	}
2925	free(pathname);
2926	nvlist_free(nverrlist);
2927}
2928
2929static void
2930print_spares(zpool_handle_t *zhp, nvlist_t **spares, uint_t nspares,
2931    int namewidth)
2932{
2933	uint_t i;
2934	char *name;
2935
2936	if (nspares == 0)
2937		return;
2938
2939	(void) printf(gettext("\tspares\n"));
2940
2941	for (i = 0; i < nspares; i++) {
2942		name = zpool_vdev_name(g_zfs, zhp, spares[i]);
2943		print_status_config(zhp, name, spares[i],
2944		    namewidth, 2, B_TRUE, B_FALSE);
2945		free(name);
2946	}
2947}
2948
2949static void
2950print_l2cache(zpool_handle_t *zhp, nvlist_t **l2cache, uint_t nl2cache,
2951    int namewidth)
2952{
2953	uint_t i;
2954	char *name;
2955
2956	if (nl2cache == 0)
2957		return;
2958
2959	(void) printf(gettext("\tcache\n"));
2960
2961	for (i = 0; i < nl2cache; i++) {
2962		name = zpool_vdev_name(g_zfs, zhp, l2cache[i]);
2963		print_status_config(zhp, name, l2cache[i],
2964		    namewidth, 2, B_FALSE, B_FALSE);
2965		free(name);
2966	}
2967}
2968
2969/*
2970 * Display a summary of pool status.  Displays a summary such as:
2971 *
2972 *        pool: tank
2973 *	status: DEGRADED
2974 *	reason: One or more devices ...
2975 *         see: http://www.sun.com/msg/ZFS-xxxx-01
2976 *	config:
2977 *		mirror		DEGRADED
2978 *                c1t0d0	OK
2979 *                c2t0d0	UNAVAIL
2980 *
2981 * When given the '-v' option, we print out the complete config.  If the '-e'
2982 * option is specified, then we print out error rate information as well.
2983 */
2984int
2985status_callback(zpool_handle_t *zhp, void *data)
2986{
2987	status_cbdata_t *cbp = data;
2988	nvlist_t *config, *nvroot;
2989	char *msgid;
2990	int reason;
2991	const char *health;
2992	uint_t c;
2993	vdev_stat_t *vs;
2994
2995	config = zpool_get_config(zhp, NULL);
2996	reason = zpool_get_status(zhp, &msgid);
2997
2998	cbp->cb_count++;
2999
3000	/*
3001	 * If we were given 'zpool status -x', only report those pools with
3002	 * problems.
3003	 */
3004	if (reason == ZPOOL_STATUS_OK && cbp->cb_explain) {
3005		if (!cbp->cb_allpools) {
3006			(void) printf(gettext("pool '%s' is healthy\n"),
3007			    zpool_get_name(zhp));
3008			if (cbp->cb_first)
3009				cbp->cb_first = B_FALSE;
3010		}
3011		return (0);
3012	}
3013
3014	if (cbp->cb_first)
3015		cbp->cb_first = B_FALSE;
3016	else
3017		(void) printf("\n");
3018
3019	verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
3020	    &nvroot) == 0);
3021	verify(nvlist_lookup_uint64_array(nvroot, ZPOOL_CONFIG_STATS,
3022	    (uint64_t **)&vs, &c) == 0);
3023	health = zpool_state_to_name(vs->vs_state, vs->vs_aux);
3024
3025	(void) printf(gettext("  pool: %s\n"), zpool_get_name(zhp));
3026	(void) printf(gettext(" state: %s\n"), health);
3027
3028	switch (reason) {
3029	case ZPOOL_STATUS_MISSING_DEV_R:
3030		(void) printf(gettext("status: One or more devices could not "
3031		    "be opened.  Sufficient replicas exist for\n\tthe pool to "
3032		    "continue functioning in a degraded state.\n"));
3033		(void) printf(gettext("action: Attach the missing device and "
3034		    "online it using 'zpool online'.\n"));
3035		break;
3036
3037	case ZPOOL_STATUS_MISSING_DEV_NR:
3038		(void) printf(gettext("status: One or more devices could not "
3039		    "be opened.  There are insufficient\n\treplicas for the "
3040		    "pool to continue functioning.\n"));
3041		(void) printf(gettext("action: Attach the missing device and "
3042		    "online it using 'zpool online'.\n"));
3043		break;
3044
3045	case ZPOOL_STATUS_CORRUPT_LABEL_R:
3046		(void) printf(gettext("status: One or more devices could not "
3047		    "be used because the label is missing or\n\tinvalid.  "
3048		    "Sufficient replicas exist for the pool to continue\n\t"
3049		    "functioning in a degraded state.\n"));
3050		(void) printf(gettext("action: Replace the device using "
3051		    "'zpool replace'.\n"));
3052		break;
3053
3054	case ZPOOL_STATUS_CORRUPT_LABEL_NR:
3055		(void) printf(gettext("status: One or more devices could not "
3056		    "be used because the label is missing \n\tor invalid.  "
3057		    "There are insufficient replicas for the pool to "
3058		    "continue\n\tfunctioning.\n"));
3059		(void) printf(gettext("action: Destroy and re-create the pool "
3060		    "from a backup source.\n"));
3061		break;
3062
3063	case ZPOOL_STATUS_FAILING_DEV:
3064		(void) printf(gettext("status: One or more devices has "
3065		    "experienced an unrecoverable error.  An\n\tattempt was "
3066		    "made to correct the error.  Applications are "
3067		    "unaffected.\n"));
3068		(void) printf(gettext("action: Determine if the device needs "
3069		    "to be replaced, and clear the errors\n\tusing "
3070		    "'zpool clear' or replace the device with 'zpool "
3071		    "replace'.\n"));
3072		break;
3073
3074	case ZPOOL_STATUS_OFFLINE_DEV:
3075		(void) printf(gettext("status: One or more devices has "
3076		    "been taken offline by the administrator.\n\tSufficient "
3077		    "replicas exist for the pool to continue functioning in "
3078		    "a\n\tdegraded state.\n"));
3079		(void) printf(gettext("action: Online the device using "
3080		    "'zpool online' or replace the device with\n\t'zpool "
3081		    "replace'.\n"));
3082		break;
3083
3084	case ZPOOL_STATUS_RESILVERING:
3085		(void) printf(gettext("status: One or more devices is "
3086		    "currently being resilvered.  The pool will\n\tcontinue "
3087		    "to function, possibly in a degraded state.\n"));
3088		(void) printf(gettext("action: Wait for the resilver to "
3089		    "complete.\n"));
3090		break;
3091
3092	case ZPOOL_STATUS_CORRUPT_DATA:
3093		(void) printf(gettext("status: One or more devices has "
3094		    "experienced an error resulting in data\n\tcorruption.  "
3095		    "Applications may be affected.\n"));
3096		(void) printf(gettext("action: Restore the file in question "
3097		    "if possible.  Otherwise restore the\n\tentire pool from "
3098		    "backup.\n"));
3099		break;
3100
3101	case ZPOOL_STATUS_CORRUPT_POOL:
3102		(void) printf(gettext("status: The pool metadata is corrupted "
3103		    "and the pool cannot be opened.\n"));
3104		(void) printf(gettext("action: Destroy and re-create the pool "
3105		    "from a backup source.\n"));
3106		break;
3107
3108	case ZPOOL_STATUS_VERSION_OLDER:
3109		(void) printf(gettext("status: The pool is formatted using an "
3110		    "older on-disk format.  The pool can\n\tstill be used, but "
3111		    "some features are unavailable.\n"));
3112		(void) printf(gettext("action: Upgrade the pool using 'zpool "
3113		    "upgrade'.  Once this is done, the\n\tpool will no longer "
3114		    "be accessible on older software versions.\n"));
3115		break;
3116
3117	case ZPOOL_STATUS_VERSION_NEWER:
3118		(void) printf(gettext("status: The pool has been upgraded to a "
3119		    "newer, incompatible on-disk version.\n\tThe pool cannot "
3120		    "be accessed on this system.\n"));
3121		(void) printf(gettext("action: Access the pool from a system "
3122		    "running more recent software, or\n\trestore the pool from "
3123		    "backup.\n"));
3124		break;
3125
3126	case ZPOOL_STATUS_FAULTED_DEV_R:
3127		(void) printf(gettext("status: One or more devices are "
3128		    "faulted in response to persistent errors.\n\tSufficient "
3129		    "replicas exist for the pool to continue functioning "
3130		    "in a\n\tdegraded state.\n"));
3131		(void) printf(gettext("action: Replace the faulted device, "
3132		    "or use 'zpool clear' to mark the device\n\trepaired.\n"));
3133		break;
3134
3135	case ZPOOL_STATUS_FAULTED_DEV_NR:
3136		(void) printf(gettext("status: One or more devices are "
3137		    "faulted in response to persistent errors.  There are "
3138		    "insufficient replicas for the pool to\n\tcontinue "
3139		    "functioning.\n"));
3140		(void) printf(gettext("action: Destroy and re-create the pool "
3141		    "from a backup source.  Manually marking the device\n"
3142		    "\trepaired using 'zpool clear' may allow some data "
3143		    "to be recovered.\n"));
3144		break;
3145
3146	case ZPOOL_STATUS_IO_FAILURE_WAIT:
3147	case ZPOOL_STATUS_IO_FAILURE_CONTINUE:
3148		(void) printf(gettext("status: One or more devices are "
3149		    "faulted in response to IO failures.\n"));
3150		(void) printf(gettext("action: Make sure the affected devices "
3151		    "are connected, then run 'zpool clear'.\n"));
3152		break;
3153
3154	case ZPOOL_STATUS_BAD_LOG:
3155		(void) printf(gettext("status: An intent log record "
3156		    "could not be read.\n"
3157		    "\tWaiting for adminstrator intervention to fix the "
3158		    "faulted pool.\n"));
3159		(void) printf(gettext("action: Either restore the affected "
3160		    "device(s) and run 'zpool online',\n"
3161		    "\tor ignore the intent log records by running "
3162		    "'zpool clear'.\n"));
3163		break;
3164
3165	default:
3166		/*
3167		 * The remaining errors can't actually be generated, yet.
3168		 */
3169		assert(reason == ZPOOL_STATUS_OK);
3170	}
3171
3172	if (msgid != NULL)
3173		(void) printf(gettext("   see: http://www.sun.com/msg/%s\n"),
3174		    msgid);
3175
3176	if (config != NULL) {
3177		int namewidth;
3178		uint64_t nerr;
3179		nvlist_t **spares, **l2cache;
3180		uint_t nspares, nl2cache;
3181
3182
3183		(void) printf(gettext(" scrub: "));
3184		print_scrub_status(nvroot);
3185
3186		namewidth = max_width(zhp, nvroot, 0, 0);
3187		if (namewidth < 10)
3188			namewidth = 10;
3189
3190		(void) printf(gettext("config:\n\n"));
3191		(void) printf(gettext("\t%-*s  %-8s %5s %5s %5s\n"), namewidth,
3192		    "NAME", "STATE", "READ", "WRITE", "CKSUM");
3193		print_status_config(zhp, zpool_get_name(zhp), nvroot,
3194		    namewidth, 0, B_FALSE, B_FALSE);
3195		if (num_logs(nvroot) > 0)
3196			print_status_config(zhp, "logs", nvroot, namewidth, 0,
3197			    B_FALSE, B_TRUE);
3198
3199		if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_L2CACHE,
3200		    &l2cache, &nl2cache) == 0)
3201			print_l2cache(zhp, l2cache, nl2cache, namewidth);
3202
3203		if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_SPARES,
3204		    &spares, &nspares) == 0)
3205			print_spares(zhp, spares, nspares, namewidth);
3206
3207		if (nvlist_lookup_uint64(config, ZPOOL_CONFIG_ERRCOUNT,
3208		    &nerr) == 0) {
3209			nvlist_t *nverrlist = NULL;
3210
3211			/*
3212			 * If the approximate error count is small, get a
3213			 * precise count by fetching the entire log and
3214			 * uniquifying the results.
3215			 */
3216			if (nerr > 0 && nerr < 100 && !cbp->cb_verbose &&
3217			    zpool_get_errlog(zhp, &nverrlist) == 0) {
3218				nvpair_t *elem;
3219
3220				elem = NULL;
3221				nerr = 0;
3222				while ((elem = nvlist_next_nvpair(nverrlist,
3223				    elem)) != NULL) {
3224					nerr++;
3225				}
3226			}
3227			nvlist_free(nverrlist);
3228
3229			(void) printf("\n");
3230
3231			if (nerr == 0)
3232				(void) printf(gettext("errors: No known data "
3233				    "errors\n"));
3234			else if (!cbp->cb_verbose)
3235				(void) printf(gettext("errors: %llu data "
3236				    "errors, use '-v' for a list\n"),
3237				    (u_longlong_t)nerr);
3238			else
3239				print_error_log(zhp);
3240		}
3241	} else {
3242		(void) printf(gettext("config: The configuration cannot be "
3243		    "determined.\n"));
3244	}
3245
3246	return (0);
3247}
3248
3249/*
3250 * zpool status [-vx] [pool] ...
3251 *
3252 *	-v	Display complete error logs
3253 *	-x	Display only pools with potential problems
3254 *
3255 * Describes the health status of all pools or some subset.
3256 */
3257int
3258zpool_do_status(int argc, char **argv)
3259{
3260	int c;
3261	int ret;
3262	status_cbdata_t cb = { 0 };
3263
3264	/* check options */
3265	while ((c = getopt(argc, argv, "vx")) != -1) {
3266		switch (c) {
3267		case 'v':
3268			cb.cb_verbose = B_TRUE;
3269			break;
3270		case 'x':
3271			cb.cb_explain = B_TRUE;
3272			break;
3273		case '?':
3274			(void) fprintf(stderr, gettext("invalid option '%c'\n"),
3275			    optopt);
3276			usage(B_FALSE);
3277		}
3278	}
3279
3280	argc -= optind;
3281	argv += optind;
3282
3283	cb.cb_first = B_TRUE;
3284
3285	if (argc == 0)
3286		cb.cb_allpools = B_TRUE;
3287
3288	ret = for_each_pool(argc, argv, B_TRUE, NULL, status_callback, &cb);
3289
3290	if (argc == 0 && cb.cb_count == 0)
3291		(void) printf(gettext("no pools available\n"));
3292	else if (cb.cb_explain && cb.cb_first && cb.cb_allpools)
3293		(void) printf(gettext("all pools are healthy\n"));
3294
3295	return (ret);
3296}
3297
3298typedef struct upgrade_cbdata {
3299	int	cb_all;
3300	int	cb_first;
3301	int	cb_newer;
3302	int	cb_argc;
3303	uint64_t cb_version;
3304	char	**cb_argv;
3305} upgrade_cbdata_t;
3306
3307static int
3308upgrade_cb(zpool_handle_t *zhp, void *arg)
3309{
3310	upgrade_cbdata_t *cbp = arg;
3311	nvlist_t *config;
3312	uint64_t version;
3313	int ret = 0;
3314
3315	config = zpool_get_config(zhp, NULL);
3316	verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION,
3317	    &version) == 0);
3318
3319	if (!cbp->cb_newer && version < SPA_VERSION) {
3320		if (!cbp->cb_all) {
3321			if (cbp->cb_first) {
3322				(void) printf(gettext("The following pools are "
3323				    "out of date, and can be upgraded.  After "
3324				    "being\nupgraded, these pools will no "
3325				    "longer be accessible by older software "
3326				    "versions.\n\n"));
3327				(void) printf(gettext("VER  POOL\n"));
3328				(void) printf(gettext("---  ------------\n"));
3329				cbp->cb_first = B_FALSE;
3330			}
3331
3332			(void) printf("%2llu   %s\n", (u_longlong_t)version,
3333			    zpool_get_name(zhp));
3334		} else {
3335			cbp->cb_first = B_FALSE;
3336			ret = zpool_upgrade(zhp, cbp->cb_version);
3337			if (!ret) {
3338				(void) printf(gettext("Successfully upgraded "
3339				    "'%s'\n\n"), zpool_get_name(zhp));
3340			}
3341		}
3342	} else if (cbp->cb_newer && version > SPA_VERSION) {
3343		assert(!cbp->cb_all);
3344
3345		if (cbp->cb_first) {
3346			(void) printf(gettext("The following pools are "
3347			    "formatted using a newer software version and\n"
3348			    "cannot be accessed on the current system.\n\n"));
3349			(void) printf(gettext("VER  POOL\n"));
3350			(void) printf(gettext("---  ------------\n"));
3351			cbp->cb_first = B_FALSE;
3352		}
3353
3354		(void) printf("%2llu   %s\n", (u_longlong_t)version,
3355		    zpool_get_name(zhp));
3356	}
3357
3358	zpool_close(zhp);
3359	return (ret);
3360}
3361
3362/* ARGSUSED */
3363static int
3364upgrade_one(zpool_handle_t *zhp, void *data)
3365{
3366	upgrade_cbdata_t *cbp = data;
3367	uint64_t cur_version;
3368	int ret;
3369
3370	if (strcmp("log", zpool_get_name(zhp)) == 0) {
3371		(void) printf(gettext("'log' is now a reserved word\n"
3372		    "Pool 'log' must be renamed using export and import"
3373		    " to upgrade.\n"));
3374		return (1);
3375	}
3376
3377	cur_version = zpool_get_prop_int(zhp, ZPOOL_PROP_VERSION, NULL);
3378	if (cur_version > cbp->cb_version) {
3379		(void) printf(gettext("Pool '%s' is already formatted "
3380		    "using more current version '%llu'.\n"),
3381		    zpool_get_name(zhp), cur_version);
3382		return (0);
3383	}
3384	if (cur_version == cbp->cb_version) {
3385		(void) printf(gettext("Pool '%s' is already formatted "
3386		    "using the current version.\n"), zpool_get_name(zhp));
3387		return (0);
3388	}
3389
3390	ret = zpool_upgrade(zhp, cbp->cb_version);
3391
3392	if (!ret) {
3393		(void) printf(gettext("Successfully upgraded '%s' "
3394		    "from version %llu to version %llu\n\n"),
3395		    zpool_get_name(zhp), (u_longlong_t)cur_version,
3396		    (u_longlong_t)cbp->cb_version);
3397	}
3398
3399	return (ret != 0);
3400}
3401
3402/*
3403 * zpool upgrade
3404 * zpool upgrade -v
3405 * zpool upgrade [-V version] <-a | pool ...>
3406 *
3407 * With no arguments, display downrev'd ZFS pool available for upgrade.
3408 * Individual pools can be upgraded by specifying the pool, and '-a' will
3409 * upgrade all pools.
3410 */
3411int
3412zpool_do_upgrade(int argc, char **argv)
3413{
3414	int c;
3415	upgrade_cbdata_t cb = { 0 };
3416	int ret = 0;
3417	boolean_t showversions = B_FALSE;
3418	char *end;
3419
3420
3421	/* check options */
3422	while ((c = getopt(argc, argv, "avV:")) != -1) {
3423		switch (c) {
3424		case 'a':
3425			cb.cb_all = B_TRUE;
3426			break;
3427		case 'v':
3428			showversions = B_TRUE;
3429			break;
3430		case 'V':
3431			cb.cb_version = strtoll(optarg, &end, 10);
3432			if (*end != '\0' || cb.cb_version > SPA_VERSION ||
3433			    cb.cb_version < SPA_VERSION_1) {
3434				(void) fprintf(stderr,
3435				    gettext("invalid version '%s'\n"), optarg);
3436				usage(B_FALSE);
3437			}
3438			break;
3439		case '?':
3440			(void) fprintf(stderr, gettext("invalid option '%c'\n"),
3441			    optopt);
3442			usage(B_FALSE);
3443		}
3444	}
3445
3446	cb.cb_argc = argc;
3447	cb.cb_argv = argv;
3448	argc -= optind;
3449	argv += optind;
3450
3451	if (cb.cb_version == 0) {
3452		cb.cb_version = SPA_VERSION;
3453	} else if (!cb.cb_all && argc == 0) {
3454		(void) fprintf(stderr, gettext("-V option is "
3455		    "incompatible with other arguments\n"));
3456		usage(B_FALSE);
3457	}
3458
3459	if (showversions) {
3460		if (cb.cb_all || argc != 0) {
3461			(void) fprintf(stderr, gettext("-v option is "
3462			    "incompatible with other arguments\n"));
3463			usage(B_FALSE);
3464		}
3465	} else if (cb.cb_all) {
3466		if (argc != 0) {
3467			(void) fprintf(stderr, gettext("-a option should not "
3468			    "be used along with a pool name\n"));
3469			usage(B_FALSE);
3470		}
3471	}
3472
3473	(void) printf(gettext("This system is currently running "
3474	    "ZFS pool version %llu.\n\n"), SPA_VERSION);
3475	cb.cb_first = B_TRUE;
3476	if (showversions) {
3477		(void) printf(gettext("The following versions are "
3478		    "supported:\n\n"));
3479		(void) printf(gettext("VER  DESCRIPTION\n"));
3480		(void) printf("---  -----------------------------------------"
3481		    "---------------\n");
3482		(void) printf(gettext(" 1   Initial ZFS version\n"));
3483		(void) printf(gettext(" 2   Ditto blocks "
3484		    "(replicated metadata)\n"));
3485		(void) printf(gettext(" 3   Hot spares and double parity "
3486		    "RAID-Z\n"));
3487		(void) printf(gettext(" 4   zpool history\n"));
3488		(void) printf(gettext(" 5   Compression using the gzip "
3489		    "algorithm\n"));
3490		(void) printf(gettext(" 6   bootfs pool property\n"));
3491		(void) printf(gettext(" 7   Separate intent log devices\n"));
3492		(void) printf(gettext(" 8   Delegated administration\n"));
3493		(void) printf(gettext(" 9   refquota and refreservation "
3494		    "properties\n"));
3495		(void) printf(gettext(" 10  Cache devices\n"));
3496		(void) printf(gettext(" 11  Improved scrub performance\n"));
3497		(void) printf(gettext(" 12  Snapshot properties\n"));
3498		(void) printf(gettext(" 13  snapused property\n"));
3499		(void) printf(gettext(" 14  passthrough-x aclinherit "
3500		    "support\n"));
3501		(void) printf(gettext("For more information on a particular "
3502		    "version, including supported releases, see:\n\n"));
3503		(void) printf("http://www.opensolaris.org/os/community/zfs/"
3504		    "version/N\n\n");
3505		(void) printf(gettext("Where 'N' is the version number.\n"));
3506	} else if (argc == 0) {
3507		int notfound;
3508
3509		ret = zpool_iter(g_zfs, upgrade_cb, &cb);
3510		notfound = cb.cb_first;
3511
3512		if (!cb.cb_all && ret == 0) {
3513			if (!cb.cb_first)
3514				(void) printf("\n");
3515			cb.cb_first = B_TRUE;
3516			cb.cb_newer = B_TRUE;
3517			ret = zpool_iter(g_zfs, upgrade_cb, &cb);
3518			if (!cb.cb_first) {
3519				notfound = B_FALSE;
3520				(void) printf("\n");
3521			}
3522		}
3523
3524		if (ret == 0) {
3525			if (notfound)
3526				(void) printf(gettext("All pools are formatted "
3527				    "using this version.\n"));
3528			else if (!cb.cb_all)
3529				(void) printf(gettext("Use 'zpool upgrade -v' "
3530				    "for a list of available versions and "
3531				    "their associated\nfeatures.\n"));
3532		}
3533	} else {
3534		ret = for_each_pool(argc, argv, B_FALSE, NULL,
3535		    upgrade_one, &cb);
3536	}
3537
3538	return (ret);
3539}
3540
3541typedef struct hist_cbdata {
3542	boolean_t first;
3543	int longfmt;
3544	int internal;
3545} hist_cbdata_t;
3546
3547char *hist_event_table[LOG_END] = {
3548	"invalid event",
3549	"pool create",
3550	"vdev add",
3551	"pool remove",
3552	"pool destroy",
3553	"pool export",
3554	"pool import",
3555	"vdev attach",
3556	"vdev replace",
3557	"vdev detach",
3558	"vdev online",
3559	"vdev offline",
3560	"vdev upgrade",
3561	"pool clear",
3562	"pool scrub",
3563	"pool property set",
3564	"create",
3565	"clone",
3566	"destroy",
3567	"destroy_begin_sync",
3568	"inherit",
3569	"property set",
3570	"quota set",
3571	"permission update",
3572	"permission remove",
3573	"permission who remove",
3574	"promote",
3575	"receive",
3576	"rename",
3577	"reservation set",
3578	"replay_inc_sync",
3579	"replay_full_sync",
3580	"rollback",
3581	"snapshot",
3582	"filesystem version upgrade",
3583	"refquota set",
3584	"refreservation set",
3585	"pool scrub done",
3586};
3587
3588/*
3589 * Print out the command history for a specific pool.
3590 */
3591static int
3592get_history_one(zpool_handle_t *zhp, void *data)
3593{
3594	nvlist_t *nvhis;
3595	nvlist_t **records;
3596	uint_t numrecords;
3597	char *cmdstr;
3598	char *pathstr;
3599	uint64_t dst_time;
3600	time_t tsec;
3601	struct tm t;
3602	char tbuf[30];
3603	int ret, i;
3604	uint64_t who;
3605	struct passwd *pwd;
3606	char *hostname;
3607	char *zonename;
3608	char internalstr[MAXPATHLEN];
3609	hist_cbdata_t *cb = (hist_cbdata_t *)data;
3610	uint64_t txg;
3611	uint64_t ievent;
3612
3613	cb->first = B_FALSE;
3614
3615	(void) printf(gettext("History for '%s':\n"), zpool_get_name(zhp));
3616
3617	if ((ret = zpool_get_history(zhp, &nvhis)) != 0)
3618		return (ret);
3619
3620	verify(nvlist_lookup_nvlist_array(nvhis, ZPOOL_HIST_RECORD,
3621	    &records, &numrecords) == 0);
3622	for (i = 0; i < numrecords; i++) {
3623		if (nvlist_lookup_uint64(records[i], ZPOOL_HIST_TIME,
3624		    &dst_time) != 0)
3625			continue;
3626
3627		/* is it an internal event or a standard event? */
3628		if (nvlist_lookup_string(records[i], ZPOOL_HIST_CMD,
3629		    &cmdstr) != 0) {
3630			if (cb->internal == 0)
3631				continue;
3632
3633			if (nvlist_lookup_uint64(records[i],
3634			    ZPOOL_HIST_INT_EVENT, &ievent) != 0)
3635				continue;
3636			verify(nvlist_lookup_uint64(records[i],
3637			    ZPOOL_HIST_TXG, &txg) == 0);
3638			verify(nvlist_lookup_string(records[i],
3639			    ZPOOL_HIST_INT_STR, &pathstr) == 0);
3640			if (ievent >= LOG_END)
3641				continue;
3642			(void) snprintf(internalstr,
3643			    sizeof (internalstr),
3644			    "[internal %s txg:%lld] %s",
3645			    hist_event_table[ievent], txg,
3646			    pathstr);
3647			cmdstr = internalstr;
3648		}
3649		tsec = dst_time;
3650		(void) localtime_r(&tsec, &t);
3651		(void) strftime(tbuf, sizeof (tbuf), "%F.%T", &t);
3652		(void) printf("%s %s", tbuf, cmdstr);
3653
3654		if (!cb->longfmt) {
3655			(void) printf("\n");
3656			continue;
3657		}
3658		(void) printf(" [");
3659		if (nvlist_lookup_uint64(records[i],
3660		    ZPOOL_HIST_WHO, &who) == 0) {
3661			pwd = getpwuid((uid_t)who);
3662			if (pwd)
3663				(void) printf("user %s on",
3664				    pwd->pw_name);
3665			else
3666				(void) printf("user %d on",
3667				    (int)who);
3668		} else {
3669			(void) printf(gettext("no info]\n"));
3670			continue;
3671		}
3672		if (nvlist_lookup_string(records[i],
3673		    ZPOOL_HIST_HOST, &hostname) == 0) {
3674			(void) printf(" %s", hostname);
3675		}
3676		if (nvlist_lookup_string(records[i],
3677		    ZPOOL_HIST_ZONE, &zonename) == 0) {
3678			(void) printf(":%s", zonename);
3679		}
3680
3681		(void) printf("]");
3682		(void) printf("\n");
3683	}
3684	(void) printf("\n");
3685	nvlist_free(nvhis);
3686
3687	return (ret);
3688}
3689
3690/*
3691 * zpool history <pool>
3692 *
3693 * Displays the history of commands that modified pools.
3694 */
3695
3696
3697int
3698zpool_do_history(int argc, char **argv)
3699{
3700	hist_cbdata_t cbdata = { 0 };
3701	int ret;
3702	int c;
3703
3704	cbdata.first = B_TRUE;
3705	/* check options */
3706	while ((c = getopt(argc, argv, "li")) != -1) {
3707		switch (c) {
3708		case 'l':
3709			cbdata.longfmt = 1;
3710			break;
3711		case 'i':
3712			cbdata.internal = 1;
3713			break;
3714		case '?':
3715			(void) fprintf(stderr, gettext("invalid option '%c'\n"),
3716			    optopt);
3717			usage(B_FALSE);
3718		}
3719	}
3720	argc -= optind;
3721	argv += optind;
3722
3723	ret = for_each_pool(argc, argv, B_FALSE,  NULL, get_history_one,
3724	    &cbdata);
3725
3726	if (argc == 0 && cbdata.first == B_TRUE) {
3727		(void) printf(gettext("no pools available\n"));
3728		return (0);
3729	}
3730
3731	return (ret);
3732}
3733
3734static int
3735get_callback(zpool_handle_t *zhp, void *data)
3736{
3737	zprop_get_cbdata_t *cbp = (zprop_get_cbdata_t *)data;
3738	char value[MAXNAMELEN];
3739	zprop_source_t srctype;
3740	zprop_list_t *pl;
3741
3742	for (pl = cbp->cb_proplist; pl != NULL; pl = pl->pl_next) {
3743
3744		/*
3745		 * Skip the special fake placeholder. This will also skip
3746		 * over the name property when 'all' is specified.
3747		 */
3748		if (pl->pl_prop == ZPOOL_PROP_NAME &&
3749		    pl == cbp->cb_proplist)
3750			continue;
3751
3752		if (zpool_get_prop(zhp, pl->pl_prop,
3753		    value, sizeof (value), &srctype) != 0)
3754			continue;
3755
3756		zprop_print_one_property(zpool_get_name(zhp), cbp,
3757		    zpool_prop_to_name(pl->pl_prop), value, srctype, NULL);
3758	}
3759	return (0);
3760}
3761
3762int
3763zpool_do_get(int argc, char **argv)
3764{
3765	zprop_get_cbdata_t cb = { 0 };
3766	zprop_list_t fake_name = { 0 };
3767	int ret;
3768
3769	if (argc < 3)
3770		usage(B_FALSE);
3771
3772	cb.cb_first = B_TRUE;
3773	cb.cb_sources = ZPROP_SRC_ALL;
3774	cb.cb_columns[0] = GET_COL_NAME;
3775	cb.cb_columns[1] = GET_COL_PROPERTY;
3776	cb.cb_columns[2] = GET_COL_VALUE;
3777	cb.cb_columns[3] = GET_COL_SOURCE;
3778	cb.cb_type = ZFS_TYPE_POOL;
3779
3780	if (zprop_get_list(g_zfs, argv[1],  &cb.cb_proplist,
3781	    ZFS_TYPE_POOL) != 0)
3782		usage(B_FALSE);
3783
3784	if (cb.cb_proplist != NULL) {
3785		fake_name.pl_prop = ZPOOL_PROP_NAME;
3786		fake_name.pl_width = strlen(gettext("NAME"));
3787		fake_name.pl_next = cb.cb_proplist;
3788		cb.cb_proplist = &fake_name;
3789	}
3790
3791	ret = for_each_pool(argc - 2, argv + 2, B_TRUE, &cb.cb_proplist,
3792	    get_callback, &cb);
3793
3794	if (cb.cb_proplist == &fake_name)
3795		zprop_free_list(fake_name.pl_next);
3796	else
3797		zprop_free_list(cb.cb_proplist);
3798
3799	return (ret);
3800}
3801
3802typedef struct set_cbdata {
3803	char *cb_propname;
3804	char *cb_value;
3805	boolean_t cb_any_successful;
3806} set_cbdata_t;
3807
3808int
3809set_callback(zpool_handle_t *zhp, void *data)
3810{
3811	int error;
3812	set_cbdata_t *cb = (set_cbdata_t *)data;
3813
3814	error = zpool_set_prop(zhp, cb->cb_propname, cb->cb_value);
3815
3816	if (!error)
3817		cb->cb_any_successful = B_TRUE;
3818
3819	return (error);
3820}
3821
3822int
3823zpool_do_set(int argc, char **argv)
3824{
3825	set_cbdata_t cb = { 0 };
3826	int error;
3827
3828	if (argc > 1 && argv[1][0] == '-') {
3829		(void) fprintf(stderr, gettext("invalid option '%c'\n"),
3830		    argv[1][1]);
3831		usage(B_FALSE);
3832	}
3833
3834	if (argc < 2) {
3835		(void) fprintf(stderr, gettext("missing property=value "
3836		    "argument\n"));
3837		usage(B_FALSE);
3838	}
3839
3840	if (argc < 3) {
3841		(void) fprintf(stderr, gettext("missing pool name\n"));
3842		usage(B_FALSE);
3843	}
3844
3845	if (argc > 3) {
3846		(void) fprintf(stderr, gettext("too many pool names\n"));
3847		usage(B_FALSE);
3848	}
3849
3850	cb.cb_propname = argv[1];
3851	cb.cb_value = strchr(cb.cb_propname, '=');
3852	if (cb.cb_value == NULL) {
3853		(void) fprintf(stderr, gettext("missing value in "
3854		    "property=value argument\n"));
3855		usage(B_FALSE);
3856	}
3857
3858	*(cb.cb_value) = '\0';
3859	cb.cb_value++;
3860
3861	error = for_each_pool(argc - 2, argv + 2, B_TRUE, NULL,
3862	    set_callback, &cb);
3863
3864	return (error);
3865}
3866
3867static int
3868find_command_idx(char *command, int *idx)
3869{
3870	int i;
3871
3872	for (i = 0; i < NCOMMAND; i++) {
3873		if (command_table[i].name == NULL)
3874			continue;
3875
3876		if (strcmp(command, command_table[i].name) == 0) {
3877			*idx = i;
3878			return (0);
3879		}
3880	}
3881	return (1);
3882}
3883
3884int
3885main(int argc, char **argv)
3886{
3887	int ret;
3888	int i;
3889	char *cmdname;
3890
3891	(void) setlocale(LC_ALL, "");
3892	(void) textdomain(TEXT_DOMAIN);
3893
3894	if ((g_zfs = libzfs_init()) == NULL) {
3895		(void) fprintf(stderr, gettext("internal error: failed to "
3896		    "initialize ZFS library\n"));
3897		return (1);
3898	}
3899
3900	libzfs_print_on_error(g_zfs, B_TRUE);
3901
3902	opterr = 0;
3903
3904	/*
3905	 * Make sure the user has specified some command.
3906	 */
3907	if (argc < 2) {
3908		(void) fprintf(stderr, gettext("missing command\n"));
3909		usage(B_FALSE);
3910	}
3911
3912	cmdname = argv[1];
3913
3914	/*
3915	 * Special case '-?'
3916	 */
3917	if (strcmp(cmdname, "-?") == 0)
3918		usage(B_TRUE);
3919
3920	zpool_set_history_str("zpool", argc, argv, history_str);
3921	verify(zpool_stage_history(g_zfs, history_str) == 0);
3922
3923	/*
3924	 * Run the appropriate command.
3925	 */
3926	if (find_command_idx(cmdname, &i) == 0) {
3927		current_command = &command_table[i];
3928		ret = command_table[i].func(argc - 1, argv + 1);
3929	} else if (strchr(cmdname, '=')) {
3930		verify(find_command_idx("set", &i) == 0);
3931		current_command = &command_table[i];
3932		ret = command_table[i].func(argc, argv);
3933	} else if (strcmp(cmdname, "freeze") == 0 && argc == 3) {
3934		/*
3935		 * 'freeze' is a vile debugging abomination, so we treat
3936		 * it as such.
3937		 */
3938		char buf[16384];
3939		int fd = open(ZFS_DEV, O_RDWR);
3940		(void) strcpy((void *)buf, argv[2]);
3941		return (!!ioctl(fd, ZFS_IOC_POOL_FREEZE, buf));
3942	} else {
3943		(void) fprintf(stderr, gettext("unrecognized "
3944		    "command '%s'\n"), cmdname);
3945		usage(B_FALSE);
3946	}
3947
3948	libzfs_fini(g_zfs);
3949
3950	/*
3951	 * The 'ZFS_ABORT' environment variable causes us to dump core on exit
3952	 * for the purposes of running ::findleaks.
3953	 */
3954	if (getenv("ZFS_ABORT") != NULL) {
3955		(void) printf("dumping core by request\n");
3956		abort();
3957	}
3958
3959	return (ret);
3960}
3961