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