Home | History | Annotate | Download | only in zpool
      1    789      ahrens /*
      2    789      ahrens  * CDDL HEADER START
      3    789      ahrens  *
      4    789      ahrens  * The contents of this file are subject to the terms of the
      5   1485       lling  * Common Development and Distribution License (the "License").
      6   1485       lling  * You may not use this file except in compliance with the License.
      7    789      ahrens  *
      8    789      ahrens  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
      9    789      ahrens  * or http://www.opensolaris.org/os/licensing.
     10    789      ahrens  * See the License for the specific language governing permissions
     11    789      ahrens  * and limitations under the License.
     12    789      ahrens  *
     13    789      ahrens  * When distributing Covered Code, include this CDDL HEADER in each
     14    789      ahrens  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
     15    789      ahrens  * If applicable, add the following below this CDDL HEADER, with the
     16    789      ahrens  * fields enclosed by brackets "[]" replaced with your own identifying
     17    789      ahrens  * information: Portions Copyright [yyyy] [name of copyright owner]
     18    789      ahrens  *
     19    789      ahrens  * CDDL HEADER END
     20    789      ahrens  */
     21   2082    eschrock 
     22    789      ahrens /*
     23   8525        Eric  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
     24    789      ahrens  * Use is subject to license terms.
     25    789      ahrens  */
     26    789      ahrens 
     27    789      ahrens #include <assert.h>
     28    789      ahrens #include <ctype.h>
     29    789      ahrens #include <dirent.h>
     30    789      ahrens #include <errno.h>
     31    789      ahrens #include <fcntl.h>
     32    789      ahrens #include <libgen.h>
     33    789      ahrens #include <libintl.h>
     34    789      ahrens #include <libuutil.h>
     35    789      ahrens #include <locale.h>
     36    789      ahrens #include <stdio.h>
     37    789      ahrens #include <stdlib.h>
     38    789      ahrens #include <string.h>
     39    789      ahrens #include <strings.h>
     40    789      ahrens #include <unistd.h>
     41    789      ahrens #include <priv.h>
     42   4543       marks #include <pwd.h>
     43   4543       marks #include <zone.h>
     44   3912       lling #include <sys/fs/zfs.h>
     45    789      ahrens 
     46    789      ahrens #include <sys/stat.h>
     47    789      ahrens 
     48    789      ahrens #include <libzfs.h>
     49    789      ahrens 
     50    789      ahrens #include "zpool_util.h"
     51   5913      perrin #include "zfs_comutil.h"
     52  10265  Krishnendu 
     53  10265  Krishnendu #include "statcommon.h"
     54    789      ahrens 
     55    789      ahrens static int zpool_do_create(int, char **);
     56    789      ahrens static int zpool_do_destroy(int, char **);
     57    789      ahrens 
     58    789      ahrens static int zpool_do_add(int, char **);
     59   2082    eschrock static int zpool_do_remove(int, char **);
     60    789      ahrens 
     61    789      ahrens static int zpool_do_list(int, char **);
     62    789      ahrens static int zpool_do_iostat(int, char **);
     63    789      ahrens static int zpool_do_status(int, char **);
     64    789      ahrens 
     65    789      ahrens static int zpool_do_online(int, char **);
     66    789      ahrens static int zpool_do_offline(int, char **);
     67   1544    eschrock static int zpool_do_clear(int, char **);
     68    789      ahrens 
     69    789      ahrens static int zpool_do_attach(int, char **);
     70    789      ahrens static int zpool_do_detach(int, char **);
     71    789      ahrens static int zpool_do_replace(int, char **);
     72    789      ahrens 
     73    789      ahrens static int zpool_do_scrub(int, char **);
     74    789      ahrens 
     75    789      ahrens static int zpool_do_import(int, char **);
     76    789      ahrens static int zpool_do_export(int, char **);
     77    789      ahrens 
     78   1760    eschrock static int zpool_do_upgrade(int, char **);
     79   1760    eschrock 
     80   2926    ek110237 static int zpool_do_history(int, char **);
     81   3912       lling 
     82   3912       lling static int zpool_do_get(int, char **);
     83   3912       lling static int zpool_do_set(int, char **);
     84   2926    ek110237 
     85    789      ahrens /*
     86    789      ahrens  * These libumem hooks provide a reasonable set of defaults for the allocator's
     87    789      ahrens  * debugging facilities.
     88    789      ahrens  */
     89   6865    rm160521 
     90   6865    rm160521 #ifdef DEBUG
     91    789      ahrens const char *
     92   2082    eschrock _umem_debug_init(void)
     93    789      ahrens {
     94    789      ahrens 	return ("default,verbose"); /* $UMEM_DEBUG setting */
     95    789      ahrens }
     96    789      ahrens 
     97    789      ahrens const char *
     98    789      ahrens _umem_logging_init(void)
     99    789      ahrens {
    100    789      ahrens 	return ("fail,contents"); /* $UMEM_LOGGING setting */
    101    789      ahrens }
    102   6865    rm160521 #endif
    103    789      ahrens 
    104   1387    eschrock typedef enum {
    105   1387    eschrock 	HELP_ADD,
    106   1387    eschrock 	HELP_ATTACH,
    107   1544    eschrock 	HELP_CLEAR,
    108   1387    eschrock 	HELP_CREATE,
    109   1387    eschrock 	HELP_DESTROY,
    110   1387    eschrock 	HELP_DETACH,
    111   1387    eschrock 	HELP_EXPORT,
    112   2926    ek110237 	HELP_HISTORY,
    113   1387    eschrock 	HELP_IMPORT,
    114   1387    eschrock 	HELP_IOSTAT,
    115   1387    eschrock 	HELP_LIST,
    116   1387    eschrock 	HELP_OFFLINE,
    117   1387    eschrock 	HELP_ONLINE,
    118   1387    eschrock 	HELP_REPLACE,
    119   2082    eschrock 	HELP_REMOVE,
    120   1387    eschrock 	HELP_SCRUB,
    121   1760    eschrock 	HELP_STATUS,
    122   3912       lling 	HELP_UPGRADE,
    123   3912       lling 	HELP_GET,
    124   3912       lling 	HELP_SET
    125   1387    eschrock } zpool_help_t;
    126   1387    eschrock 
    127   1387    eschrock 
    128    789      ahrens typedef struct zpool_command {
    129    789      ahrens 	const char	*name;
    130    789      ahrens 	int		(*func)(int, char **);
    131   1387    eschrock 	zpool_help_t	usage;
    132    789      ahrens } zpool_command_t;
    133    789      ahrens 
    134    789      ahrens /*
    135    789      ahrens  * Master command table.  Each ZFS command has a name, associated function, and
    136   1544    eschrock  * usage message.  The usage messages need to be internationalized, so we have
    137   1544    eschrock  * to have a function to return the usage message based on a command index.
    138   1387    eschrock  *
    139   1387    eschrock  * These commands are organized according to how they are displayed in the usage
    140   1387    eschrock  * message.  An empty command (one with a NULL name) indicates an empty line in
    141   1387    eschrock  * the generic usage message.
    142    789      ahrens  */
    143    789      ahrens static zpool_command_t command_table[] = {
    144   1387    eschrock 	{ "create",	zpool_do_create,	HELP_CREATE		},
    145   1387    eschrock 	{ "destroy",	zpool_do_destroy,	HELP_DESTROY		},
    146    789      ahrens 	{ NULL },
    147   1387    eschrock 	{ "add",	zpool_do_add,		HELP_ADD		},
    148   2082    eschrock 	{ "remove",	zpool_do_remove,	HELP_REMOVE		},
    149    789      ahrens 	{ NULL },
    150   1387    eschrock 	{ "list",	zpool_do_list,		HELP_LIST		},
    151   1387    eschrock 	{ "iostat",	zpool_do_iostat,	HELP_IOSTAT		},
    152   1387    eschrock 	{ "status",	zpool_do_status,	HELP_STATUS		},
    153    789      ahrens 	{ NULL },
    154   1387    eschrock 	{ "online",	zpool_do_online,	HELP_ONLINE		},
    155   1387    eschrock 	{ "offline",	zpool_do_offline,	HELP_OFFLINE		},
    156   1544    eschrock 	{ "clear",	zpool_do_clear,		HELP_CLEAR		},
    157    789      ahrens 	{ NULL },
    158   1387    eschrock 	{ "attach",	zpool_do_attach,	HELP_ATTACH		},
    159   1387    eschrock 	{ "detach",	zpool_do_detach,	HELP_DETACH		},
    160   1387    eschrock 	{ "replace",	zpool_do_replace,	HELP_REPLACE		},
    161    789      ahrens 	{ NULL },
    162   1387    eschrock 	{ "scrub",	zpool_do_scrub,		HELP_SCRUB		},
    163    789      ahrens 	{ NULL },
    164   1387    eschrock 	{ "import",	zpool_do_import,	HELP_IMPORT		},
    165   1387    eschrock 	{ "export",	zpool_do_export,	HELP_EXPORT		},
    166   2926    ek110237 	{ "upgrade",	zpool_do_upgrade,	HELP_UPGRADE		},
    167   2926    ek110237 	{ NULL },
    168   3912       lling 	{ "history",	zpool_do_history,	HELP_HISTORY		},
    169   3912       lling 	{ "get",	zpool_do_get,		HELP_GET		},
    170   3912       lling 	{ "set",	zpool_do_set,		HELP_SET		},
    171    789      ahrens };
    172    789      ahrens 
    173    789      ahrens #define	NCOMMAND	(sizeof (command_table) / sizeof (command_table[0]))
    174    789      ahrens 
    175    789      ahrens zpool_command_t *current_command;
    176   4988    ek110237 static char history_str[HIS_MAX_RECORD_LEN];
    177  10265  Krishnendu 
    178  10265  Krishnendu static uint_t timestamp_fmt = NODATE;
    179   1387    eschrock 
    180   1387    eschrock static const char *
    181   1387    eschrock get_usage(zpool_help_t idx) {
    182   1387    eschrock 	switch (idx) {
    183   1387    eschrock 	case HELP_ADD:
    184   1387    eschrock 		return (gettext("\tadd [-fn] <pool> <vdev> ...\n"));
    185   1387    eschrock 	case HELP_ATTACH:
    186   1387    eschrock 		return (gettext("\tattach [-f] <pool> <device> "
    187   4849      ahrens 		    "<new-device>\n"));
    188   1544    eschrock 	case HELP_CLEAR:
    189  10921         Tim 		return (gettext("\tclear [-nF] <pool> [device]\n"));
    190   1387    eschrock 	case HELP_CREATE:
    191   5094       lling 		return (gettext("\tcreate [-fn] [-o property=value] ... \n"
    192   7184        timh 		    "\t    [-O file-system-property=value] ... \n"
    193   5094       lling 		    "\t    [-m mountpoint] [-R root] <pool> <vdev> ...\n"));
    194   1387    eschrock 	case HELP_DESTROY:
    195   1387    eschrock 		return (gettext("\tdestroy [-f] <pool>\n"));
    196   1387    eschrock 	case HELP_DETACH:
    197   1387    eschrock 		return (gettext("\tdetach <pool> <device>\n"));
    198   1387    eschrock 	case HELP_EXPORT:
    199   1387    eschrock 		return (gettext("\texport [-f] <pool> ...\n"));
    200   2926    ek110237 	case HELP_HISTORY:
    201   4543       marks 		return (gettext("\thistory [-il] [<pool>] ...\n"));
    202   1387    eschrock 	case HELP_IMPORT:
    203   1631     darrenm 		return (gettext("\timport [-d dir] [-D]\n"
    204  10921         Tim 		    "\timport [-d dir | -c cachefile] [-n] -F <pool | id>\n"
    205   5363    eschrock 		    "\timport [-o mntopts] [-o property=value] ... \n"
    206   5363    eschrock 		    "\t    [-d dir | -c cachefile] [-D] [-f] [-R root] -a\n"
    207   5363    eschrock 		    "\timport [-o mntopts] [-o property=value] ... \n"
    208   5363    eschrock 		    "\t    [-d dir | -c cachefile] [-D] [-f] [-R root] "
    209   5363    eschrock 		    "<pool | id> [newpool]\n"));
    210   1387    eschrock 	case HELP_IOSTAT:
    211  10265  Krishnendu 		return (gettext("\tiostat [-v] [-T d|u] [pool] ... [interval "
    212   1387    eschrock 		    "[count]]\n"));
    213   1387    eschrock 	case HELP_LIST:
    214   5094       lling 		return (gettext("\tlist [-H] [-o property[,...]] "
    215   5094       lling 		    "[pool] ...\n"));
    216   1387    eschrock 	case HELP_OFFLINE:
    217   1485       lling 		return (gettext("\toffline [-t] <pool> <device> ...\n"));
    218   1387    eschrock 	case HELP_ONLINE:
    219   1485       lling 		return (gettext("\tonline <pool> <device> ...\n"));
    220   1387    eschrock 	case HELP_REPLACE:
    221   1387    eschrock 		return (gettext("\treplace [-f] <pool> <device> "
    222   4849      ahrens 		    "[new-device]\n"));
    223   2082    eschrock 	case HELP_REMOVE:
    224   5450     brendan 		return (gettext("\tremove <pool> <device> ...\n"));
    225   1387    eschrock 	case HELP_SCRUB:
    226   1387    eschrock 		return (gettext("\tscrub [-s] <pool> ...\n"));
    227   1387    eschrock 	case HELP_STATUS:
    228   1387    eschrock 		return (gettext("\tstatus [-vx] [pool] ...\n"));
    229   1760    eschrock 	case HELP_UPGRADE:
    230   1760    eschrock 		return (gettext("\tupgrade\n"
    231   1760    eschrock 		    "\tupgrade -v\n"
    232   5094       lling 		    "\tupgrade [-V version] <-a | pool ...>\n"));
    233   3912       lling 	case HELP_GET:
    234   4849      ahrens 		return (gettext("\tget <\"all\" | property[,...]> "
    235   3912       lling 		    "<pool> ...\n"));
    236   3912       lling 	case HELP_SET:
    237   3912       lling 		return (gettext("\tset <property=value> <pool> \n"));
    238   1387    eschrock 	}
    239   1387    eschrock 
    240   1387    eschrock 	abort();
    241   1387    eschrock 	/* NOTREACHED */
    242   1387    eschrock }
    243    789      ahrens 
    244    789      ahrens 
    245    789      ahrens /*
    246   3912       lling  * Callback routine that will print out a pool property value.
    247   3912       lling  */
    248   5094       lling static int
    249   5094       lling print_prop_cb(int prop, void *cb)
    250   3912       lling {
    251   3912       lling 	FILE *fp = cb;
    252   3912       lling 
    253  10922        Jeff 	(void) fprintf(fp, "\t%-15s  ", zpool_prop_to_name(prop));
    254   5094       lling 
    255   5094       lling 	if (zpool_prop_readonly(prop))
    256   5094       lling 		(void) fprintf(fp, "  NO   ");
    257   5094       lling 	else
    258  10922        Jeff 		(void) fprintf(fp, " YES   ");
    259   3912       lling 
    260   3912       lling 	if (zpool_prop_values(prop) == NULL)
    261   3912       lling 		(void) fprintf(fp, "-\n");
    262   3912       lling 	else
    263   3912       lling 		(void) fprintf(fp, "%s\n", zpool_prop_values(prop));
    264   3912       lling 
    265   5094       lling 	return (ZPROP_CONT);
    266   3912       lling }
    267   3912       lling 
    268   3912       lling /*
    269    789      ahrens  * Display usage message.  If we're inside a command, display only the usage for
    270    789      ahrens  * that command.  Otherwise, iterate over the entire command table and display
    271    789      ahrens  * a complete usage message.
    272    789      ahrens  */
    273    789      ahrens void
    274   2082    eschrock usage(boolean_t requested)
    275    789      ahrens {
    276    789      ahrens 	FILE *fp = requested ? stdout : stderr;
    277    789      ahrens 
    278    789      ahrens 	if (current_command == NULL) {
    279    789      ahrens 		int i;
    280    789      ahrens 
    281    789      ahrens 		(void) fprintf(fp, gettext("usage: zpool command args ...\n"));
    282    789      ahrens 		(void) fprintf(fp,
    283    789      ahrens 		    gettext("where 'command' is one of the following:\n\n"));
    284    789      ahrens 
    285    789      ahrens 		for (i = 0; i < NCOMMAND; i++) {
    286    789      ahrens 			if (command_table[i].name == NULL)
    287    789      ahrens 				(void) fprintf(fp, "\n");
    288    789      ahrens 			else
    289    789      ahrens 				(void) fprintf(fp, "%s",
    290   1387    eschrock 				    get_usage(command_table[i].usage));
    291    789      ahrens 		}
    292    789      ahrens 	} else {
    293    789      ahrens 		(void) fprintf(fp, gettext("usage:\n"));
    294   1387    eschrock 		(void) fprintf(fp, "%s", get_usage(current_command->usage));
    295   3912       lling 	}
    296   3912       lling 
    297   3912       lling 	if (current_command != NULL &&
    298   3912       lling 	    ((strcmp(current_command->name, "set") == 0) ||
    299   5094       lling 	    (strcmp(current_command->name, "get") == 0) ||
    300   5094       lling 	    (strcmp(current_command->name, "list") == 0))) {
    301   3912       lling 
    302   3912       lling 		(void) fprintf(fp,
    303   3912       lling 		    gettext("\nthe following properties are supported:\n"));
    304   3912       lling 
    305  10922        Jeff 		(void) fprintf(fp, "\n\t%-15s  %s   %s\n\n",
    306   5094       lling 		    "PROPERTY", "EDIT", "VALUES");
    307   3912       lling 
    308   3912       lling 		/* Iterate over all properties */
    309   5094       lling 		(void) zprop_iter(print_prop_cb, fp, B_FALSE, B_TRUE,
    310   5094       lling 		    ZFS_TYPE_POOL);
    311   2676    eschrock 	}
    312   2676    eschrock 
    313   2676    eschrock 	/*
    314   2676    eschrock 	 * See comments at end of main().
    315   2676    eschrock 	 */
    316   2676    eschrock 	if (getenv("ZFS_ABORT") != NULL) {
    317   2676    eschrock 		(void) printf("dumping core by request\n");
    318   2676    eschrock 		abort();
    319    789      ahrens 	}
    320    789      ahrens 
    321    789      ahrens 	exit(requested ? 0 : 2);
    322    789      ahrens }
    323    789      ahrens 
    324    789      ahrens void
    325   4527      perrin print_vdev_tree(zpool_handle_t *zhp, const char *name, nvlist_t *nv, int indent,
    326   4527      perrin     boolean_t print_logs)
    327    789      ahrens {
    328    789      ahrens 	nvlist_t **child;
    329    789      ahrens 	uint_t c, children;
    330   1171    eschrock 	char *vname;
    331    789      ahrens 
    332    789      ahrens 	if (name != NULL)
    333    789      ahrens 		(void) printf("\t%*s%s\n", indent, "", name);
    334    789      ahrens 
    335    789      ahrens 	if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
    336    789      ahrens 	    &child, &children) != 0)
    337    789      ahrens 		return;
    338    789      ahrens 
    339   1171    eschrock 	for (c = 0; c < children; c++) {
    340   4527      perrin 		uint64_t is_log = B_FALSE;
    341   4527      perrin 
    342   4527      perrin 		(void) nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_LOG,
    343   4527      perrin 		    &is_log);
    344   4527      perrin 		if ((is_log && !print_logs) || (!is_log && print_logs))
    345   4527      perrin 			continue;
    346   4527      perrin 
    347  10594      George 		vname = zpool_vdev_name(g_zfs, zhp, child[c], B_FALSE);
    348   4527      perrin 		print_vdev_tree(zhp, vname, child[c], indent + 2,
    349   4527      perrin 		    B_FALSE);
    350   1171    eschrock 		free(vname);
    351   1171    eschrock 	}
    352   5094       lling }
    353   5094       lling 
    354   5094       lling /*
    355   5094       lling  * Add a property pair (name, string-value) into a property nvlist.
    356   5094       lling  */
    357   5094       lling static int
    358   7184        timh add_prop_list(const char *propname, char *propval, nvlist_t **props,
    359   7184        timh     boolean_t poolprop)
    360   5094       lling {
    361   7184        timh 	zpool_prop_t prop = ZPROP_INVAL;
    362   7184        timh 	zfs_prop_t fprop;
    363   7184        timh 	nvlist_t *proplist;
    364   7184        timh 	const char *normnm;
    365   5094       lling 	char *strval;
    366   5094       lling 
    367   5094       lling 	if (*props == NULL &&
    368   5094       lling 	    nvlist_alloc(props, NV_UNIQUE_NAME, 0) != 0) {
    369   5094       lling 		(void) fprintf(stderr,
    370   5094       lling 		    gettext("internal error: out of memory\n"));
    371   5094       lling 		return (1);
    372   5094       lling 	}
    373   5094       lling 
    374   5094       lling 	proplist = *props;
    375   5094       lling 
    376   7184        timh 	if (poolprop) {
    377   7184        timh 		if ((prop = zpool_name_to_prop(propname)) == ZPROP_INVAL) {
    378   7184        timh 			(void) fprintf(stderr, gettext("property '%s' is "
    379   7184        timh 			    "not a valid pool property\n"), propname);
    380   7184        timh 			return (2);
    381   7184        timh 		}
    382   7184        timh 		normnm = zpool_prop_to_name(prop);
    383   7184        timh 	} else {
    384   9396     Matthew 		if ((fprop = zfs_name_to_prop(propname)) != ZPROP_INVAL) {
    385   9396     Matthew 			normnm = zfs_prop_to_name(fprop);
    386   9396     Matthew 		} else {
    387   9396     Matthew 			normnm = propname;
    388   7184        timh 		}
    389   5094       lling 	}
    390   5094       lling 
    391   7184        timh 	if (nvlist_lookup_string(proplist, normnm, &strval) == 0 &&
    392   7184        timh 	    prop != ZPOOL_PROP_CACHEFILE) {
    393   5094       lling 		(void) fprintf(stderr, gettext("property '%s' "
    394   5094       lling 		    "specified multiple times\n"), propname);
    395   5094       lling 		return (2);
    396   5094       lling 	}
    397   5094       lling 
    398   7184        timh 	if (nvlist_add_string(proplist, normnm, propval) != 0) {
    399   5094       lling 		(void) fprintf(stderr, gettext("internal "
    400   5094       lling 		    "error: out of memory\n"));
    401   5094       lling 		return (1);
    402   5094       lling 	}
    403   5094       lling 
    404   5094       lling 	return (0);
    405    789      ahrens }
    406    789      ahrens 
    407    789      ahrens /*
    408    789      ahrens  * zpool add [-fn] <pool> <vdev> ...
    409    789      ahrens  *
    410    789      ahrens  *	-f	Force addition of devices, even if they appear in use
    411    789      ahrens  *	-n	Do not add the devices, but display the resulting layout if
    412    789      ahrens  *		they were to be added.
    413    789      ahrens  *
    414    789      ahrens  * Adds the given vdevs to 'pool'.  As with create, the bulk of this work is
    415    789      ahrens  * handled by get_vdev_spec(), which constructs the nvlist needed to pass to
    416    789      ahrens  * libzfs.
    417    789      ahrens  */
    418    789      ahrens int
    419    789      ahrens zpool_do_add(int argc, char **argv)
    420    789      ahrens {
    421   2082    eschrock 	boolean_t force = B_FALSE;
    422   2082    eschrock 	boolean_t dryrun = B_FALSE;
    423    789      ahrens 	int c;
    424    789      ahrens 	nvlist_t *nvroot;
    425    789      ahrens 	char *poolname;
    426    789      ahrens 	int ret;
    427    789      ahrens 	zpool_handle_t *zhp;
    428    789      ahrens 	nvlist_t *config;
    429    789      ahrens 
    430    789      ahrens 	/* check options */
    431    789      ahrens 	while ((c = getopt(argc, argv, "fn")) != -1) {
    432    789      ahrens 		switch (c) {
    433    789      ahrens 		case 'f':
    434   2082    eschrock 			force = B_TRUE;
    435    789      ahrens 			break;
    436    789      ahrens 		case 'n':
    437   2082    eschrock 			dryrun = B_TRUE;
    438    789      ahrens 			break;
    439    789      ahrens 		case '?':
    440    789      ahrens 			(void) fprintf(stderr, gettext("invalid option '%c'\n"),
    441    789      ahrens 			    optopt);
    442   2082    eschrock 			usage(B_FALSE);
    443    789      ahrens 		}
    444    789      ahrens 	}
    445    789      ahrens 
    446    789      ahrens 	argc -= optind;
    447    789      ahrens 	argv += optind;
    448    789      ahrens 
    449    789      ahrens 	/* get pool name and check number of arguments */
    450    789      ahrens 	if (argc < 1) {
    451    789      ahrens 		(void) fprintf(stderr, gettext("missing pool name argument\n"));
    452   2082    eschrock 		usage(B_FALSE);
    453    789      ahrens 	}
    454    789      ahrens 	if (argc < 2) {
    455    789      ahrens 		(void) fprintf(stderr, gettext("missing vdev specification\n"));
    456   2082    eschrock 		usage(B_FALSE);
    457    789      ahrens 	}
    458    789      ahrens 
    459    789      ahrens 	poolname = argv[0];
    460    789      ahrens 
    461    789      ahrens 	argc--;
    462    789      ahrens 	argv++;
    463    789      ahrens 
    464   2082    eschrock 	if ((zhp = zpool_open(g_zfs, poolname)) == NULL)
    465    789      ahrens 		return (1);
    466    789      ahrens 
    467    952    eschrock 	if ((config = zpool_get_config(zhp, NULL)) == NULL) {
    468    789      ahrens 		(void) fprintf(stderr, gettext("pool '%s' is unavailable\n"),
    469    789      ahrens 		    poolname);
    470    789      ahrens 		zpool_close(zhp);
    471    789      ahrens 		return (1);
    472    789      ahrens 	}
    473    789      ahrens 
    474    789      ahrens 	/* pass off to get_vdev_spec for processing */
    475   7343        Eric 	nvroot = make_root_vdev(zhp, force, !force, B_FALSE, dryrun,
    476   7343        Eric 	    argc, argv);
    477    789      ahrens 	if (nvroot == NULL) {
    478    789      ahrens 		zpool_close(zhp);
    479    789      ahrens 		return (1);
    480    789      ahrens 	}
    481    789      ahrens 
    482    789      ahrens 	if (dryrun) {
    483    789      ahrens 		nvlist_t *poolnvroot;
    484    789      ahrens 
    485    789      ahrens 		verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
    486    789      ahrens 		    &poolnvroot) == 0);
    487    789      ahrens 
    488    789      ahrens 		(void) printf(gettext("would update '%s' to the following "
    489    789      ahrens 		    "configuration:\n"), zpool_get_name(zhp));
    490    789      ahrens 
    491   4527      perrin 		/* print original main pool and new tree */
    492   4527      perrin 		print_vdev_tree(zhp, poolname, poolnvroot, 0, B_FALSE);
    493   4527      perrin 		print_vdev_tree(zhp, NULL, nvroot, 0, B_FALSE);
    494   4527      perrin 
    495   4527      perrin 		/* Do the same for the logs */
    496   4527      perrin 		if (num_logs(poolnvroot) > 0) {
    497   4527      perrin 			print_vdev_tree(zhp, "logs", poolnvroot, 0, B_TRUE);
    498   4527      perrin 			print_vdev_tree(zhp, NULL, nvroot, 0, B_TRUE);
    499   4527      perrin 		} else if (num_logs(nvroot) > 0) {
    500   4527      perrin 			print_vdev_tree(zhp, "logs", nvroot, 0, B_TRUE);
    501   4527      perrin 		}
    502    789      ahrens 
    503    789      ahrens 		ret = 0;
    504    789      ahrens 	} else {
    505    789      ahrens 		ret = (zpool_add(zhp, nvroot) != 0);
    506    789      ahrens 	}
    507    789      ahrens 
    508   2082    eschrock 	nvlist_free(nvroot);
    509   2082    eschrock 	zpool_close(zhp);
    510   2082    eschrock 
    511   2082    eschrock 	return (ret);
    512   2082    eschrock }
    513   2082    eschrock 
    514   2082    eschrock /*
    515   5450     brendan  * zpool remove <pool> <vdev> ...
    516   2082    eschrock  *
    517   2082    eschrock  * Removes the given vdev from the pool.  Currently, this only supports removing
    518   5450     brendan  * spares and cache devices from the pool.  Eventually, we'll want to support
    519   5450     brendan  * removing leaf vdevs (as an alias for 'detach') as well as toplevel vdevs.
    520   2082    eschrock  */
    521   2082    eschrock int
    522   2082    eschrock zpool_do_remove(int argc, char **argv)
    523   2082    eschrock {
    524   2082    eschrock 	char *poolname;
    525   5450     brendan 	int i, ret = 0;
    526   2082    eschrock 	zpool_handle_t *zhp;
    527   2082    eschrock 
    528   2082    eschrock 	argc--;
    529   2082    eschrock 	argv++;
    530   2082    eschrock 
    531   2082    eschrock 	/* get pool name and check number of arguments */
    532   2082    eschrock 	if (argc < 1) {
    533   2082    eschrock 		(void) fprintf(stderr, gettext("missing pool name argument\n"));
    534   2082    eschrock 		usage(B_FALSE);
    535   2082    eschrock 	}
    536   2082    eschrock 	if (argc < 2) {
    537   2082    eschrock 		(void) fprintf(stderr, gettext("missing device\n"));
    538   2082    eschrock 		usage(B_FALSE);
    539   2082    eschrock 	}
    540   2082    eschrock 
    541   2082    eschrock 	poolname = argv[0];
    542   2082    eschrock 
    543   2082    eschrock 	if ((zhp = zpool_open(g_zfs, poolname)) == NULL)
    544   2082    eschrock 		return (1);
    545   2082    eschrock 
    546   5450     brendan 	for (i = 1; i < argc; i++) {
    547   5450     brendan 		if (zpool_vdev_remove(zhp, argv[i]) != 0)
    548   5450     brendan 			ret = 1;
    549   5450     brendan 	}
    550   2082    eschrock 
    551    789      ahrens 	return (ret);
    552    789      ahrens }
    553    789      ahrens 
    554    789      ahrens /*
    555   7184        timh  * zpool create [-fn] [-o property=value] ...
    556   7184        timh  *		[-O file-system-property=value] ...
    557   7184        timh  *		[-R root] [-m mountpoint] <pool> <dev> ...
    558    789      ahrens  *
    559    789      ahrens  *	-f	Force creation, even if devices appear in use
    560    789      ahrens  *	-n	Do not create the pool, but display the resulting layout if it
    561    789      ahrens  *		were to be created.
    562    789      ahrens  *      -R	Create a pool under an alternate root
    563    789      ahrens  *      -m	Set default mountpoint for the root dataset.  By default it's
    564    789      ahrens  *      	'/<pool>'
    565   5094       lling  *	-o	Set property=value.
    566   7184        timh  *	-O	Set fsproperty=value in the pool's root file system
    567    789      ahrens  *
    568   3912       lling  * Creates the named pool according to the given vdev specification.  The
    569    789      ahrens  * bulk of the vdev processing is done in get_vdev_spec() in zpool_vdev.c.  Once
    570    789      ahrens  * we get the nvlist back from get_vdev_spec(), we either print out the contents
    571    789      ahrens  * (if '-n' was specified), or pass it to libzfs to do the creation.
    572    789      ahrens  */
    573    789      ahrens int
    574    789      ahrens zpool_do_create(int argc, char **argv)
    575    789      ahrens {
    576   2082    eschrock 	boolean_t force = B_FALSE;
    577   2082    eschrock 	boolean_t dryrun = B_FALSE;
    578    789      ahrens 	int c;
    579   5094       lling 	nvlist_t *nvroot = NULL;
    580    789      ahrens 	char *poolname;
    581   5094       lling 	int ret = 1;
    582    789      ahrens 	char *altroot = NULL;
    583    789      ahrens 	char *mountpoint = NULL;
    584   7184        timh 	nvlist_t *fsprops = NULL;
    585   5094       lling 	nvlist_t *props = NULL;
    586   5363    eschrock 	char *propval;
    587    789      ahrens 
    588    789      ahrens 	/* check options */
    589   7184        timh 	while ((c = getopt(argc, argv, ":fnR:m:o:O:")) != -1) {
    590    789      ahrens 		switch (c) {
    591    789      ahrens 		case 'f':
    592   2082    eschrock 			force = B_TRUE;
    593    789      ahrens 			break;
    594    789      ahrens 		case 'n':
    595   2082    eschrock 			dryrun = B_TRUE;
    596    789      ahrens 			break;
    597    789      ahrens 		case 'R':
    598    789      ahrens 			altroot = optarg;
    599   5094       lling 			if (add_prop_list(zpool_prop_to_name(
    600   7184        timh 			    ZPOOL_PROP_ALTROOT), optarg, &props, B_TRUE))
    601   5094       lling 				goto errout;
    602   5363    eschrock 			if (nvlist_lookup_string(props,
    603   5363    eschrock 			    zpool_prop_to_name(ZPOOL_PROP_CACHEFILE),
    604   5363    eschrock 			    &propval) == 0)
    605   5363    eschrock 				break;
    606   5094       lling 			if (add_prop_list(zpool_prop_to_name(
    607   7184        timh 			    ZPOOL_PROP_CACHEFILE), "none", &props, B_TRUE))
    608   5094       lling 				goto errout;
    609    789      ahrens 			break;
    610    789      ahrens 		case 'm':
    611    789      ahrens 			mountpoint = optarg;
    612    789      ahrens 			break;
    613   5094       lling 		case 'o':
    614   5094       lling 			if ((propval = strchr(optarg, '=')) == NULL) {
    615   5094       lling 				(void) fprintf(stderr, gettext("missing "
    616   5094       lling 				    "'=' for -o option\n"));
    617   5094       lling 				goto errout;
    618   5094       lling 			}
    619   5094       lling 			*propval = '\0';
    620   5094       lling 			propval++;
    621   5094       lling 
    622   7184        timh 			if (add_prop_list(optarg, propval, &props, B_TRUE))
    623   7184        timh 				goto errout;
    624   7184        timh 			break;
    625   7184        timh 		case 'O':
    626   7184        timh 			if ((propval = strchr(optarg, '=')) == NULL) {
    627   7184        timh 				(void) fprintf(stderr, gettext("missing "
    628   7184        timh 				    "'=' for -O option\n"));
    629   7184        timh 				goto errout;
    630   7184        timh 			}
    631   7184        timh 			*propval = '\0';
    632   7184        timh 			propval++;
    633   7184        timh 
    634   7184        timh 			if (add_prop_list(optarg, propval, &fsprops, B_FALSE))
    635   5094       lling 				goto errout;
    636   5094       lling 			break;
    637    789      ahrens 		case ':':
    638    789      ahrens 			(void) fprintf(stderr, gettext("missing argument for "
    639    789      ahrens 			    "'%c' option\n"), optopt);
    640   5094       lling 			goto badusage;
    641    789      ahrens 		case '?':
    642    789      ahrens 			(void) fprintf(stderr, gettext("invalid option '%c'\n"),
    643    789      ahrens 			    optopt);
    644   5094       lling 			goto badusage;
    645    789      ahrens 		}
    646    789      ahrens 	}
    647    789      ahrens 
    648    789      ahrens 	argc -= optind;
    649    789      ahrens 	argv += optind;
    650    789      ahrens 
    651    789      ahrens 	/* get pool name and check number of arguments */
    652    789      ahrens 	if (argc < 1) {
    653    789      ahrens 		(void) fprintf(stderr, gettext("missing pool name argument\n"));
    654   5094       lling 		goto badusage;
    655    789      ahrens 	}
    656    789      ahrens 	if (argc < 2) {
    657    789      ahrens 		(void) fprintf(stderr, gettext("missing vdev specification\n"));
    658   5094       lling 		goto badusage;
    659    789      ahrens 	}
    660    789      ahrens 
    661    789      ahrens 	poolname = argv[0];
    662    789      ahrens 
    663    789      ahrens 	/*
    664    789      ahrens 	 * As a special case, check for use of '/' in the name, and direct the
    665    789      ahrens 	 * user to use 'zfs create' instead.
    666    789      ahrens 	 */
    667    789      ahrens 	if (strchr(poolname, '/') != NULL) {
    668    789      ahrens 		(void) fprintf(stderr, gettext("cannot create '%s': invalid "
    669    789      ahrens 		    "character '/' in pool name\n"), poolname);
    670    789      ahrens 		(void) fprintf(stderr, gettext("use 'zfs create' to "
    671    789      ahrens 		    "create a dataset\n"));
    672   5094       lling 		goto errout;
    673    789      ahrens 	}
    674    789      ahrens 
    675    789      ahrens 	/* pass off to get_vdev_spec for bulk processing */
    676   7343        Eric 	nvroot = make_root_vdev(NULL, force, !force, B_FALSE, dryrun,
    677   7343        Eric 	    argc - 1, argv + 1);
    678    789      ahrens 	if (nvroot == NULL)
    679   7184        timh 		goto errout;
    680   2082    eschrock 
    681   2082    eschrock 	/* make_root_vdev() allows 0 toplevel children if there are spares */
    682   5913      perrin 	if (!zfs_allocatable_devs(nvroot)) {
    683   2082    eschrock 		(void) fprintf(stderr, gettext("invalid vdev "
    684   2082    eschrock 		    "specification: at least one toplevel vdev must be "
    685   2082    eschrock 		    "specified\n"));
    686   5094       lling 		goto errout;
    687   2082    eschrock 	}
    688   2082    eschrock 
    689    789      ahrens 
    690    789      ahrens 	if (altroot != NULL && altroot[0] != '/') {
    691    789      ahrens 		(void) fprintf(stderr, gettext("invalid alternate root '%s': "
    692   2676    eschrock 		    "must be an absolute path\n"), altroot);
    693   5094       lling 		goto errout;
    694    789      ahrens 	}
    695    789      ahrens 
    696    789      ahrens 	/*
    697    789      ahrens 	 * Check the validity of the mountpoint and direct the user to use the
    698    789      ahrens 	 * '-m' mountpoint option if it looks like its in use.
    699    789      ahrens 	 */
    700    789      ahrens 	if (mountpoint == NULL ||
    701    789      ahrens 	    (strcmp(mountpoint, ZFS_MOUNTPOINT_LEGACY) != 0 &&
    702    789      ahrens 	    strcmp(mountpoint, ZFS_MOUNTPOINT_NONE) != 0)) {
    703    789      ahrens 		char buf[MAXPATHLEN];
    704   5904        timh 		DIR *dirp;
    705    789      ahrens 
    706    789      ahrens 		if (mountpoint && mountpoint[0] != '/') {
    707    789      ahrens 			(void) fprintf(stderr, gettext("invalid mountpoint "
    708    789      ahrens 			    "'%s': must be an absolute path, 'legacy', or "
    709    789      ahrens 			    "'none'\n"), mountpoint);
    710   5094       lling 			goto errout;
    711    789      ahrens 		}
    712    789      ahrens 
    713    789      ahrens 		if (mountpoint == NULL) {
    714    789      ahrens 			if (altroot != NULL)
    715    789      ahrens 				(void) snprintf(buf, sizeof (buf), "%s/%s",
    716    789      ahrens 				    altroot, poolname);
    717    789      ahrens 			else
    718    789      ahrens 				(void) snprintf(buf, sizeof (buf), "/%s",
    719    789      ahrens 				    poolname);
    720    789      ahrens 		} else {
    721    789      ahrens 			if (altroot != NULL)
    722    789      ahrens 				(void) snprintf(buf, sizeof (buf), "%s%s",
    723    789      ahrens 				    altroot, mountpoint);
    724    789      ahrens 			else
    725    789      ahrens 				(void) snprintf(buf, sizeof (buf), "%s",
    726    789      ahrens 				    mountpoint);
    727    789      ahrens 		}
    728    789      ahrens 
    729   5904        timh 		if ((dirp = opendir(buf)) == NULL && errno != ENOENT) {
    730   5904        timh 			(void) fprintf(stderr, gettext("mountpoint '%s' : "
    731   5904        timh 			    "%s\n"), buf, strerror(errno));
    732    789      ahrens 			(void) fprintf(stderr, gettext("use '-m' "
    733    789      ahrens 			    "option to provide a different default\n"));
    734   5094       lling 			goto errout;
    735   5904        timh 		} else if (dirp) {
    736   5904        timh 			int count = 0;
    737   5904        timh 
    738   5904        timh 			while (count < 3 && readdir(dirp) != NULL)
    739   5904        timh 				count++;
    740   5904        timh 			(void) closedir(dirp);
    741   5904        timh 
    742   5904        timh 			if (count > 2) {
    743   5904        timh 				(void) fprintf(stderr, gettext("mountpoint "
    744   5904        timh 				    "'%s' exists and is not empty\n"), buf);
    745   5904        timh 				(void) fprintf(stderr, gettext("use '-m' "
    746   5904        timh 				    "option to provide a "
    747   5904        timh 				    "different default\n"));
    748   5904        timh 				goto errout;
    749   5904        timh 			}
    750    789      ahrens 		}
    751    789      ahrens 	}
    752    789      ahrens 
    753    789      ahrens 	if (dryrun) {
    754    789      ahrens 		/*
    755    789      ahrens 		 * For a dry run invocation, print out a basic message and run
    756    789      ahrens 		 * through all the vdevs in the list and print out in an
    757    789      ahrens 		 * appropriate hierarchy.
    758    789      ahrens 		 */
    759    789      ahrens 		(void) printf(gettext("would create '%s' with the "
    760    789      ahrens 		    "following layout:\n\n"), poolname);
    761    789      ahrens 
    762   4527      perrin 		print_vdev_tree(NULL, poolname, nvroot, 0, B_FALSE);
    763   4527      perrin 		if (num_logs(nvroot) > 0)
    764   4527      perrin 			print_vdev_tree(NULL, "logs", nvroot, 0, B_TRUE);
    765    789      ahrens 
    766    789      ahrens 		ret = 0;
    767    789      ahrens 	} else {
    768    789      ahrens 		/*
    769    789      ahrens 		 * Hand off to libzfs.
    770    789      ahrens 		 */
    771   7184        timh 		if (zpool_create(g_zfs, poolname,
    772   7184        timh 		    nvroot, props, fsprops) == 0) {
    773   2082    eschrock 			zfs_handle_t *pool = zfs_open(g_zfs, poolname,
    774    789      ahrens 			    ZFS_TYPE_FILESYSTEM);
    775    789      ahrens 			if (pool != NULL) {
    776    789      ahrens 				if (mountpoint != NULL)
    777    789      ahrens 					verify(zfs_prop_set(pool,
    778   2676    eschrock 					    zfs_prop_to_name(
    779   2676    eschrock 					    ZFS_PROP_MOUNTPOINT),
    780    789      ahrens 					    mountpoint) == 0);
    781    789      ahrens 				if (zfs_mount(pool, NULL, 0) == 0)
    782   5331         amw 					ret = zfs_shareall(pool);
    783    789      ahrens 				zfs_close(pool);
    784    789      ahrens 			}
    785   2082    eschrock 		} else if (libzfs_errno(g_zfs) == EZFS_INVALIDNAME) {
    786   2082    eschrock 			(void) fprintf(stderr, gettext("pool name may have "
    787   2082    eschrock 			    "been omitted\n"));
    788    789      ahrens 		}
    789    789      ahrens 	}
    790    789      ahrens 
    791   5094       lling errout:
    792   5363    eschrock 	nvlist_free(nvroot);
    793   7184        timh 	nvlist_free(fsprops);
    794   5363    eschrock 	nvlist_free(props);
    795    789      ahrens 	return (ret);
    796   5094       lling badusage:
    797   7184        timh 	nvlist_free(fsprops);
    798   5094       lling 	nvlist_free(props);
    799   5094       lling 	usage(B_FALSE);
    800   5094       lling 	return (2);
    801    789      ahrens }
    802    789      ahrens 
    803    789      ahrens /*
    804    789      ahrens  * zpool destroy <pool>
    805    789      ahrens  *
    806    789      ahrens  * 	-f	Forcefully unmount any datasets
    807    789      ahrens  *
    808    789      ahrens  * Destroy the given pool.  Automatically unmounts any datasets in the pool.
    809    789      ahrens  */
    810    789      ahrens int
    811    789      ahrens zpool_do_destroy(int argc, char **argv)
    812    789      ahrens {
    813   2082    eschrock 	boolean_t force = B_FALSE;
    814    789      ahrens 	int c;
    815    789      ahrens 	char *pool;
    816    789      ahrens 	zpool_handle_t *zhp;
    817    789      ahrens 	int ret;
    818    789      ahrens 
    819    789      ahrens 	/* check options */
    820    789      ahrens 	while ((c = getopt(argc, argv, "f")) != -1) {
    821    789      ahrens 		switch (c) {
    822    789      ahrens 		case 'f':
    823   2082    eschrock 			force = B_TRUE;
    824    789      ahrens 			break;
    825    789      ahrens 		case '?':
    826    789      ahrens 			(void) fprintf(stderr, gettext("invalid option '%c'\n"),
    827    789      ahrens 			    optopt);
    828   2082    eschrock 			usage(B_FALSE);
    829    789      ahrens 		}
    830    789      ahrens 	}
    831    789      ahrens 
    832    789      ahrens 	argc -= optind;
    833    789      ahrens 	argv += optind;
    834    789      ahrens 
    835    789      ahrens 	/* check arguments */
    836    789      ahrens 	if (argc < 1) {
    837    789      ahrens 		(void) fprintf(stderr, gettext("missing pool argument\n"));
    838   2082    eschrock 		usage(B_FALSE);
    839    789      ahrens 	}
    840    789      ahrens 	if (argc > 1) {
    841    789      ahrens 		(void) fprintf(stderr, gettext("too many arguments\n"));
    842   2082    eschrock 		usage(B_FALSE);
    843    789      ahrens 	}
    844    789      ahrens 
    845    789      ahrens 	pool = argv[0];
    846    789      ahrens 
    847   2082    eschrock 	if ((zhp = zpool_open_canfail(g_zfs, pool)) == NULL) {
    848    789      ahrens 		/*
    849    789      ahrens 		 * As a special case, check for use of '/' in the name, and
    850    789      ahrens 		 * direct the user to use 'zfs destroy' instead.
    851    789      ahrens 		 */
    852    789      ahrens 		if (strchr(pool, '/') != NULL)
    853    789      ahrens 			(void) fprintf(stderr, gettext("use 'zfs destroy' to "
    854    789      ahrens 			    "destroy a dataset\n"));
    855    789      ahrens 		return (1);
    856    789      ahrens 	}
    857    789      ahrens 
    858   3126         ahl 	if (zpool_disable_datasets(zhp, force) != 0) {
    859    789      ahrens 		(void) fprintf(stderr, gettext("could not destroy '%s': "
    860    789      ahrens 		    "could not unmount datasets\n"), zpool_get_name(zhp));
    861    789      ahrens 		return (1);
    862    789      ahrens 	}
    863    789      ahrens 
    864    789      ahrens 	ret = (zpool_destroy(zhp) != 0);
    865    789      ahrens 
    866    789      ahrens 	zpool_close(zhp);
    867    789      ahrens 
    868    789      ahrens 	return (ret);
    869    789      ahrens }
    870    789      ahrens 
    871    789      ahrens /*
    872    789      ahrens  * zpool export [-f] <pool> ...
    873    789      ahrens  *
    874    789      ahrens  *	-f	Forcefully unmount datasets
    875    789      ahrens  *
    876   3912       lling  * Export the given pools.  By default, the command will attempt to cleanly
    877    789      ahrens  * unmount any active datasets within the pool.  If the '-f' flag is specified,
    878    789      ahrens  * then the datasets will be forcefully unmounted.
    879    789      ahrens  */
    880    789      ahrens int
    881    789      ahrens zpool_do_export(int argc, char **argv)
    882    789      ahrens {
    883   2082    eschrock 	boolean_t force = B_FALSE;
    884   8211      George 	boolean_t hardforce = B_FALSE;
    885    789      ahrens 	int c;
    886    789      ahrens 	zpool_handle_t *zhp;
    887    789      ahrens 	int ret;
    888    789      ahrens 	int i;
    889    789      ahrens 
    890    789      ahrens 	/* check options */
    891   8211      George 	while ((c = getopt(argc, argv, "fF")) != -1) {
    892    789      ahrens 		switch (c) {
    893    789      ahrens 		case 'f':
    894   2082    eschrock 			force = B_TRUE;
    895   8211      George 			break;
    896   8211      George 		case 'F':
    897   8211      George 			hardforce = B_TRUE;
    898    789      ahrens 			break;
    899    789      ahrens 		case '?':
    900    789      ahrens 			(void) fprintf(stderr, gettext("invalid option '%c'\n"),
    901    789      ahrens 			    optopt);
    902   2082    eschrock 			usage(B_FALSE);
    903    789      ahrens 		}
    904    789      ahrens 	}
    905    789      ahrens 
    906    789      ahrens 	argc -= optind;
    907    789      ahrens 	argv += optind;
    908    789      ahrens 
    909    789      ahrens 	/* check arguments */
    910    789      ahrens 	if (argc < 1) {
    911    789      ahrens 		(void) fprintf(stderr, gettext("missing pool argument\n"));
    912   2082    eschrock 		usage(B_FALSE);
    913    789      ahrens 	}
    914    789      ahrens 
    915    789      ahrens 	ret = 0;
    916    789      ahrens 	for (i = 0; i < argc; i++) {
    917   2082    eschrock 		if ((zhp = zpool_open_canfail(g_zfs, argv[i])) == NULL) {
    918    789      ahrens 			ret = 1;
    919    789      ahrens 			continue;
    920    789      ahrens 		}
    921    789      ahrens 
    922   3126         ahl 		if (zpool_disable_datasets(zhp, force) != 0) {
    923    789      ahrens 			ret = 1;
    924    789      ahrens 			zpool_close(zhp);
    925    789      ahrens 			continue;
    926    789      ahrens 		}
    927    789      ahrens 
    928   8211      George 		if (hardforce) {
    929   8211      George 			if (zpool_export_force(zhp) != 0)
    930   8211      George 				ret = 1;
    931   8211      George 		} else if (zpool_export(zhp, force) != 0) {
    932    789      ahrens 			ret = 1;
    933   8211      George 		}
    934    789      ahrens 
    935    789      ahrens 		zpool_close(zhp);
    936    789      ahrens 	}
    937    789      ahrens 
    938    789      ahrens 	return (ret);
    939    789      ahrens }
    940    789      ahrens 
    941    789      ahrens /*
    942    789      ahrens  * Given a vdev configuration, determine the maximum width needed for the device
    943    789      ahrens  * name column.
    944    789      ahrens  */
    945    789      ahrens static int
    946   1354    eschrock max_width(zpool_handle_t *zhp, nvlist_t *nv, int depth, int max)
    947    789      ahrens {
    948  10594      George 	char *name = zpool_vdev_name(g_zfs, zhp, nv, B_TRUE);
    949    789      ahrens 	nvlist_t **child;
    950    789      ahrens 	uint_t c, children;
    951    789      ahrens 	int ret;
    952    789      ahrens 
    953    789      ahrens 	if (strlen(name) + depth > max)
    954    789      ahrens 		max = strlen(name) + depth;
    955   1171    eschrock 
    956   1171    eschrock 	free(name);
    957    789      ahrens 
    958   2082    eschrock 	if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_SPARES,
    959   2082    eschrock 	    &child, &children) == 0) {
    960   2082    eschrock 		for (c = 0; c < children; c++)
    961   2082    eschrock 			if ((ret = max_width(zhp, child[c], depth + 2,
    962   2082    eschrock 			    max)) > max)
    963   2082    eschrock 				max = ret;
    964   2082    eschrock 	}
    965   2082    eschrock 
    966   5450     brendan 	if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_L2CACHE,
    967   5450     brendan 	    &child, &children) == 0) {
    968   5450     brendan 		for (c = 0; c < children; c++)
    969   5450     brendan 			if ((ret = max_width(zhp, child[c], depth + 2,
    970   5450     brendan 			    max)) > max)
    971   5450     brendan 				max = ret;
    972   5450     brendan 	}
    973   5450     brendan 
    974    789      ahrens 	if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
    975   2082    eschrock 	    &child, &children) == 0) {
    976   2082    eschrock 		for (c = 0; c < children; c++)
    977   2082    eschrock 			if ((ret = max_width(zhp, child[c], depth + 2,
    978   2082    eschrock 			    max)) > max)
    979   2082    eschrock 				max = ret;
    980   2082    eschrock 	}
    981    789      ahrens 
    982    789      ahrens 
    983    789      ahrens 	return (max);
    984    789      ahrens }
    985    789      ahrens 
    986   9701      George typedef struct spare_cbdata {
    987   9701      George 	uint64_t	cb_guid;
    988   9701      George 	zpool_handle_t	*cb_zhp;
    989   9701      George } spare_cbdata_t;
    990   9701      George 
    991   9701      George static boolean_t
    992   9701      George find_vdev(nvlist_t *nv, uint64_t search)
    993   9701      George {
    994   9701      George 	uint64_t guid;
    995   9701      George 	nvlist_t **child;
    996   9701      George 	uint_t c, children;
    997   9701      George 
    998   9701      George 	if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_GUID, &guid) == 0 &&
    999   9701      George 	    search == guid)
   1000   9701      George 		return (B_TRUE);
   1001   9701      George 
   1002   9701      George 	if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
   1003   9701      George 	    &child, &children) == 0) {
   1004   9701      George 		for (c = 0; c < children; c++)
   1005   9701      George 			if (find_vdev(child[c], search))
   1006   9701      George 				return (B_TRUE);
   1007   9701      George 	}
   1008   9701      George 
   1009   9701      George 	return (B_FALSE);
   1010   9701      George }
   1011   9701      George 
   1012   9701      George static int
   1013   9701      George find_spare(zpool_handle_t *zhp, void *data)
   1014   9701      George {
   1015   9701      George 	spare_cbdata_t *cbp = data;
   1016   9701      George 	nvlist_t *config, *nvroot;
   1017   9701      George 
   1018   9701      George 	config = zpool_get_config(zhp, NULL);
   1019   9701      George 	verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
   1020   9701      George 	    &nvroot) == 0);
   1021   9701      George 
   1022   9701      George 	if (find_vdev(nvroot, cbp->cb_guid)) {
   1023   9701      George 		cbp->cb_zhp = zhp;
   1024   9701      George 		return (1);
   1025   9701      George 	}
   1026   9701      George 
   1027   9701      George 	zpool_close(zhp);
   1028   9701      George 	return (0);
   1029   9701      George }
   1030   9701      George 
   1031   9701      George /*
   1032   9701      George  * Print out configuration state as requested by status_callback.
   1033   9701      George  */
   1034   9701      George void
   1035   9701      George print_status_config(zpool_handle_t *zhp, const char *name, nvlist_t *nv,
   1036   9701      George     int namewidth, int depth, boolean_t isspare)
   1037   9701      George {
   1038   9701      George 	nvlist_t **child;
   1039   9701      George 	uint_t c, children;
   1040   9701      George 	vdev_stat_t *vs;
   1041   9701      George 	char rbuf[6], wbuf[6], cbuf[6], repaired[7];
   1042   9701      George 	char *vname;
   1043   9701      George 	uint64_t notpresent;
   1044   9701      George 	spare_cbdata_t cb;
   1045   9701      George 	char *state;
   1046   9701      George 
   1047   9701      George 	verify(nvlist_lookup_uint64_array(nv, ZPOOL_CONFIG_STATS,
   1048   9701      George 	    (uint64_t **)&vs, &c) == 0);
   1049   9701      George 
   1050   9701      George 	if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
   1051   9701      George 	    &child, &children) != 0)
   1052   9701      George 		children = 0;
   1053   9701      George 
   1054   9701      George 	state = zpool_state_to_name(vs->vs_state, vs->vs_aux);
   1055   9701      George 	if (isspare) {
   1056   9701      George 		/*
   1057   9701      George 		 * For hot spares, we use the terms 'INUSE' and 'AVAILABLE' for
   1058   9701      George 		 * online drives.
   1059   9701      George 		 */
   1060   9701      George 		if (vs->vs_aux == VDEV_AUX_SPARED)
   1061   9701      George 			state = "INUSE";
   1062   9701      George 		else if (vs->vs_state == VDEV_STATE_HEALTHY)
   1063   9701      George 			state = "AVAIL";
   1064   9701      George 	}
   1065   9701      George 
   1066   9701      George 	(void) printf("\t%*s%-*s  %-8s", depth, "", namewidth - depth,
   1067   9701      George 	    name, state);
   1068   9701      George 
   1069   9701      George 	if (!isspare) {
   1070   9701      George 		zfs_nicenum(vs->vs_read_errors, rbuf, sizeof (rbuf));
   1071   9701      George 		zfs_nicenum(vs->vs_write_errors, wbuf, sizeof (wbuf));
   1072   9701      George 		zfs_nicenum(vs->vs_checksum_errors, cbuf, sizeof (cbuf));
   1073   9701      George 		(void) printf(" %5s %5s %5s", rbuf, wbuf, cbuf);
   1074   9701      George 	}
   1075   9701      George 
   1076   9701      George 	if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_NOT_PRESENT,
   1077   9701      George 	    &notpresent) == 0) {
   1078   9701      George 		char *path;
   1079   9701      George 		verify(nvlist_lookup_string(nv, ZPOOL_CONFIG_PATH, &path) == 0);
   1080   9701      George 		(void) printf("  was %s", path);
   1081   9701      George 	} else if (vs->vs_aux != 0) {
   1082   9701      George 		(void) printf("  ");
   1083   9701      George 
   1084   9701      George 		switch (vs->vs_aux) {
   1085   9701      George 		case VDEV_AUX_OPEN_FAILED:
   1086   9701      George 			(void) printf(gettext("cannot open"));
   1087   9701      George 			break;
   1088   9701      George 
   1089   9701      George 		case VDEV_AUX_BAD_GUID_SUM:
   1090   9701      George 			(void) printf(gettext("missing device"));
   1091   9701      George 			break;
   1092   9701      George 
   1093   9701      George 		case VDEV_AUX_NO_REPLICAS:
   1094   9701      George 			(void) printf(gettext("insufficient replicas"));
   1095   9701      George 			break;
   1096   9701      George 
   1097   9701      George 		case VDEV_AUX_VERSION_NEWER:
   1098   9701      George 			(void) printf(gettext("newer version"));
   1099   9701      George 			break;
   1100   9701      George 
   1101   9701      George 		case VDEV_AUX_SPARED:
   1102   9701      George 			verify(nvlist_lookup_uint64(nv, ZPOOL_CONFIG_GUID,
   1103   9701      George 			    &cb.cb_guid) == 0);
   1104   9701      George 			if (zpool_iter(g_zfs, find_spare, &cb) == 1) {
   1105   9701      George 				if (strcmp(zpool_get_name(cb.cb_zhp),
   1106   9701      George 				    zpool_get_name(zhp)) == 0)
   1107   9701      George 					(void) printf(gettext("currently in "
   1108   9701      George 					    "use"));
   1109   9701      George 				else
   1110   9701      George 					(void) printf(gettext("in use by "
   1111   9701      George 					    "pool '%s'"),
   1112   9701      George 					    zpool_get_name(cb.cb_zhp));
   1113   9701      George 				zpool_close(cb.cb_zhp);
   1114   9701      George 			} else {
   1115   9701      George 				(void) printf(gettext("currently in use"));
   1116   9701      George 			}
   1117   9701      George 			break;
   1118   9701      George 
   1119   9701      George 		case VDEV_AUX_ERR_EXCEEDED:
   1120   9701      George 			(void) printf(gettext("too many errors"));
   1121   9701      George 			break;
   1122   9701      George 
   1123   9701      George 		case VDEV_AUX_IO_FAILURE:
   1124   9701      George 			(void) printf(gettext("experienced I/O failures"));
   1125   9701      George 			break;
   1126   9701      George 
   1127   9701      George 		case VDEV_AUX_BAD_LOG:
   1128   9701      George 			(void) printf(gettext("bad intent log"));
   1129   9701      George 			break;
   1130   9701      George 
   1131  10817        Eric 		case VDEV_AUX_EXTERNAL:
   1132  10817        Eric 			(void) printf(gettext("external device fault"));
   1133  10817        Eric 			break;
   1134  10817        Eric 
   1135   9701      George 		default:
   1136   9701      George 			(void) printf(gettext("corrupted data"));
   1137   9701      George 			break;
   1138   9701      George 		}
   1139   9701      George 	} else if (vs->vs_scrub_repaired != 0 && children == 0) {
   1140   9701      George 		/*
   1141   9701      George 		 * Report bytes resilvered/repaired on leaf devices.
   1142   9701      George 		 */
   1143   9701      George 		zfs_nicenum(vs->vs_scrub_repaired, repaired, sizeof (repaired));
   1144   9701      George 		(void) printf(gettext("  %s %s"), repaired,
   1145   9701      George 		    (vs->vs_scrub_type == POOL_SCRUB_RESILVER) ?
   1146   9701      George 		    "resilvered" : "repaired");
   1147   9701      George 	}
   1148   9701      George 
   1149   9701      George 	(void) printf("\n");
   1150   9701      George 
   1151   9701      George 	for (c = 0; c < children; c++) {
   1152  10594      George 		uint64_t islog = B_FALSE, ishole = B_FALSE;
   1153  10594      George 
   1154  10594      George 		/* Don't print logs or holes here */
   1155  10594      George 		(void) nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_LOG,
   1156  10594      George 		    &islog);
   1157  10594      George 		(void) nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_HOLE,
   1158  10594      George 		    &ishole);
   1159  10594      George 		if (islog || ishole)
   1160  10594      George 			continue;
   1161  10594      George 		vname = zpool_vdev_name(g_zfs, zhp, child[c], B_TRUE);
   1162  10594      George 		print_status_config(zhp, vname, child[c],
   1163  10594      George 		    namewidth, depth + 2, isspare);
   1164  10594      George 		free(vname);
   1165  10594      George 	}
   1166  10594      George }
   1167  10594      George 
   1168  10594      George 
   1169  10594      George /*
   1170  10594      George  * Print the configuration of an exported pool.  Iterate over all vdevs in the
   1171  10594      George  * pool, printing out the name and status for each one.
   1172  10594      George  */
   1173  10594      George void
   1174  10594      George print_import_config(const char *name, nvlist_t *nv, int namewidth, int depth)
   1175  10594      George {
   1176  10594      George 	nvlist_t **child;
   1177  10594      George 	uint_t c, children;
   1178  10594      George 	vdev_stat_t *vs;
   1179  10594      George 	char *type, *vname;
   1180  10594      George 
   1181  10594      George 	verify(nvlist_lookup_string(nv, ZPOOL_CONFIG_TYPE, &type) == 0);
   1182  10594      George 	if (strcmp(type, VDEV_TYPE_MISSING) == 0 ||
   1183  10594      George 	    strcmp(type, VDEV_TYPE_HOLE) == 0)
   1184  10594      George 		return;
   1185  10594      George 
   1186  10594      George 	verify(nvlist_lookup_uint64_array(nv, ZPOOL_CONFIG_STATS,
   1187  10594      George 	    (uint64_t **)&vs, &c) == 0);
   1188  10594      George 
   1189  10594      George 	(void) printf("\t%*s%-*s", depth, "", namewidth - depth, name);
   1190  10594      George 	(void) printf("  %s", zpool_state_to_name(vs->vs_state, vs->vs_aux));
   1191  10594      George 
   1192  10594      George 	if (vs->vs_aux != 0) {
   1193  10594      George 		(void) printf("  ");
   1194  10594      George 
   1195  10594      George 		switch (vs->vs_aux) {
   1196  10594      George 		case VDEV_AUX_OPEN_FAILED:
   1197  10594      George 			(void) printf(gettext("cannot open"));
   1198  10594      George 			break;
   1199  10594      George 
   1200  10594      George 		case VDEV_AUX_BAD_GUID_SUM:
   1201  10594      George 			(void) printf(gettext("missing device"));
   1202  10594      George 			break;
   1203  10594      George 
   1204  10594      George 		case VDEV_AUX_NO_REPLICAS:
   1205  10594      George 			(void) printf(gettext("insufficient replicas"));
   1206  10594      George 			break;
   1207  10594      George 
   1208  10594      George 		case VDEV_AUX_VERSION_NEWER:
   1209  10594      George 			(void) printf(gettext("newer version"));
   1210  10594      George 			break;
   1211  10594      George 
   1212  10594      George 		case VDEV_AUX_ERR_EXCEEDED:
   1213  10594      George 			(void) printf(gettext("too many errors"));
   1214  10594      George 			break;
   1215  10594      George 
   1216  10594      George 		default:
   1217  10594      George 			(void) printf(gettext("corrupted data"));
   1218  10594      George 			break;
   1219  10594      George 		}
   1220  10594      George 	}
   1221  10594      George 	(void) printf("\n");
   1222  10594      George 
   1223  10594      George 	if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
   1224  10594      George 	    &child, &children) != 0)
   1225  10594      George 		return;
   1226  10594      George 
   1227  10594      George 	for (c = 0; c < children; c++) {
   1228   9701      George 		uint64_t is_log = B_FALSE;
   1229   9701      George 
   1230   9701      George 		(void) nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_LOG,
   1231   9701      George 		    &is_log);
   1232   9701      George 		if (is_log)
   1233   9701      George 			continue;
   1234  10594      George 
   1235  10594      George 		vname = zpool_vdev_name(g_zfs, NULL, child[c], B_TRUE);
   1236   9701      George 		print_import_config(vname, child[c], namewidth, depth + 2);
   1237   2082    eschrock 		free(vname);
   1238   2082    eschrock 	}
   1239   2082    eschrock 
   1240   5450     brendan 	if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_L2CACHE,
   1241   5450     brendan 	    &child, &children) == 0) {
   1242   5450     brendan 		(void) printf(gettext("\tcache\n"));
   1243   5450     brendan 		for (c = 0; c < children; c++) {
   1244  10594      George 			vname = zpool_vdev_name(g_zfs, NULL, child[c], B_FALSE);
   1245   5450     brendan 			(void) printf("\t  %s\n", vname);
   1246   5450     brendan 			free(vname);
   1247   5450     brendan 		}
   1248   5450     brendan 	}
   1249   5450     brendan 
   1250   2082    eschrock 	if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_SPARES,
   1251   5450     brendan 	    &child, &children) == 0) {
   1252   5450     brendan 		(void) printf(gettext("\tspares\n"));
   1253   5450     brendan 		for (c = 0; c < children; c++) {
   1254  10594      George 			vname = zpool_vdev_name(g_zfs, NULL, child[c], B_FALSE);
   1255   5450     brendan 			(void) printf("\t  %s\n", vname);
   1256   5450     brendan 			free(vname);
   1257   5450     brendan 		}
   1258   1171    eschrock 	}
   1259    789      ahrens }
   1260    789      ahrens 
   1261   9701      George /*
   1262   9701      George  * Print log vdevs.
   1263   9701      George  * Logs are recorded as top level vdevs in the main pool child array
   1264   9701      George  * but with "is_log" set to 1. We use either print_status_config() or
   1265   9701      George  * print_import_config() to print the top level logs then any log
   1266   9701      George  * children (eg mirrored slogs) are printed recursively - which
   1267   9701      George  * works because only the top level vdev is marked "is_log"
   1268   9701      George  */
   1269   9701      George static void
   1270   9701      George print_logs(zpool_handle_t *zhp, nvlist_t *nv, int namewidth, boolean_t verbose)
   1271   9701      George {
   1272   9701      George 	uint_t c, children;
   1273   9701      George 	nvlist_t **child;
   1274   9701      George 
   1275   9701      George 	if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN, &child,
   1276   9701      George 	    &children) != 0)
   1277   9701      George 		return;
   1278   9701      George 
   1279   9701      George 	(void) printf(gettext("\tlogs\n"));
   1280   9701      George 
   1281   9701      George 	for (c = 0; c < children; c++) {
   1282   9701      George 		uint64_t is_log = B_FALSE;
   1283   9701      George 		char *name;
   1284   9701      George 
   1285   9701      George 		(void) nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_LOG,
   1286   9701      George 		    &is_log);
   1287   9701      George 		if (!is_log)
   1288   9701      George 			continue;
   1289  10594      George 		name = zpool_vdev_name(g_zfs, zhp, child[c], B_TRUE);
   1290   9701      George 		if (verbose)
   1291   9701      George 			print_status_config(zhp, name, child[c], namewidth,
   1292   9701      George 			    2, B_FALSE);
   1293   9701      George 		else
   1294   9701      George 			print_import_config(name, child[c], namewidth, 2);
   1295   9701      George 		free(name);
   1296   9701      George 	}
   1297   9701      George }
   1298  10921         Tim 
   1299    789      ahrens /*
   1300    789      ahrens  * Display the status for the given pool.
   1301    789      ahrens  */
   1302    789      ahrens static void
   1303    789      ahrens show_import(nvlist_t *config)
   1304    789      ahrens {
   1305    789      ahrens 	uint64_t pool_state;
   1306    789      ahrens 	vdev_stat_t *vs;
   1307    789      ahrens 	char *name;
   1308    789      ahrens 	uint64_t guid;
   1309    789      ahrens 	char *msgid;
   1310    789      ahrens 	nvlist_t *nvroot;
   1311    789      ahrens 	int reason;
   1312   3741    mmusante 	const char *health;
   1313    789      ahrens 	uint_t vsc;
   1314    789      ahrens 	int namewidth;
   1315    789      ahrens 
   1316    789      ahrens 	verify(nvlist_lookup_string(config, ZPOOL_CONFIG_POOL_NAME,
   1317    789      ahrens 	    &name) == 0);
   1318    789      ahrens 	verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_GUID,
   1319    789      ahrens 	    &guid) == 0);
   1320    789      ahrens 	verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_STATE,
   1321    789      ahrens 	    &pool_state) == 0);
   1322    789      ahrens 	verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
   1323    789      ahrens 	    &nvroot) == 0);
   1324    789      ahrens 
   1325    789      ahrens 	verify(nvlist_lookup_uint64_array(nvroot, ZPOOL_CONFIG_STATS,
   1326    789      ahrens 	    (uint64_t **)&vs, &vsc) == 0);
   1327   5094       lling 	health = zpool_state_to_name(vs->vs_state, vs->vs_aux);
   1328    789      ahrens 
   1329    789      ahrens 	reason = zpool_import_status(config, &msgid);
   1330    789      ahrens 
   1331   3741    mmusante 	(void) printf(gettext("  pool: %s\n"), name);
   1332   3741    mmusante 	(void) printf(gettext("    id: %llu\n"), (u_longlong_t)guid);
   1333   3741    mmusante 	(void) printf(gettext(" state: %s"), health);
   1334   1631     darrenm 	if (pool_state == POOL_STATE_DESTROYED)
   1335   3912       lling 		(void) printf(gettext(" (DESTROYED)"));
   1336   1631     darrenm 	(void) printf("\n");
   1337    789      ahrens 
   1338    789      ahrens 	switch (reason) {
   1339    789      ahrens 	case ZPOOL_STATUS_MISSING_DEV_R:
   1340    789      ahrens 	case ZPOOL_STATUS_MISSING_DEV_NR:
   1341    789      ahrens 	case ZPOOL_STATUS_BAD_GUID_SUM:
   1342    789      ahrens 		(void) printf(gettext("status: One or more devices are missing "
   1343    789      ahrens 		    "from the system.\n"));
   1344    789      ahrens 		break;
   1345    789      ahrens 
   1346    789      ahrens 	case ZPOOL_STATUS_CORRUPT_LABEL_R:
   1347    789      ahrens 	case ZPOOL_STATUS_CORRUPT_LABEL_NR:
   1348    789      ahrens 		(void) printf(gettext("status: One or more devices contains "
   1349    789      ahrens 		    "corrupted data.\n"));
   1350    789      ahrens 		break;
   1351    789      ahrens 
   1352    789      ahrens 	case ZPOOL_STATUS_CORRUPT_DATA:
   1353    789      ahrens 		(void) printf(gettext("status: The pool data is corrupted.\n"));
   1354   1485       lling 		break;
   1355   1485       lling 
   1356   1485       lling 	case ZPOOL_STATUS_OFFLINE_DEV:
   1357   1485       lling 		(void) printf(gettext("status: One or more devices "
   1358   1485       lling 		    "are offlined.\n"));
   1359   1544    eschrock 		break;
   1360   1544    eschrock 
   1361   1544    eschrock 	case ZPOOL_STATUS_CORRUPT_POOL:
   1362   1544    eschrock 		(void) printf(gettext("status: The pool metadata is "
   1363   1544    eschrock 		    "corrupted.\n"));
   1364    789      ahrens 		break;
   1365    789      ahrens 
   1366   1760    eschrock 	case ZPOOL_STATUS_VERSION_OLDER:
   1367   1760    eschrock 		(void) printf(gettext("status: The pool is formatted using an "
   1368   1760    eschrock 		    "older on-disk version.\n"));
   1369   1760    eschrock 		break;
   1370   1760    eschrock 
   1371   1760    eschrock 	case ZPOOL_STATUS_VERSION_NEWER:
   1372   1760    eschrock 		(void) printf(gettext("status: The pool is formatted using an "
   1373   1760    eschrock 		    "incompatible version.\n"));
   1374   1760    eschrock 		break;
   1375   7294      perrin 
   1376   3975    ek110237 	case ZPOOL_STATUS_HOSTID_MISMATCH:
   1377   3975    ek110237 		(void) printf(gettext("status: The pool was last accessed by "
   1378   3975    ek110237 		    "another system.\n"));
   1379   3975    ek110237 		break;
   1380   7294      perrin 
   1381   4451    eschrock 	case ZPOOL_STATUS_FAULTED_DEV_R:
   1382   4451    eschrock 	case ZPOOL_STATUS_FAULTED_DEV_NR:
   1383   4451    eschrock 		(void) printf(gettext("status: One or more devices are "
   1384   4451    eschrock 		    "faulted.\n"));
   1385   7294      perrin 		break;
   1386   7294      perrin 
   1387   7294      perrin 	case ZPOOL_STATUS_BAD_LOG:
   1388   7294      perrin 		(void) printf(gettext("status: An intent log record cannot be "
   1389   7294      perrin 		    "read.\n"));
   1390   4451    eschrock 		break;
   1391   4451    eschrock 
   1392    789      ahrens 	default:
   1393    789      ahrens 		/*
   1394    789      ahrens 		 * No other status can be seen when importing pools.
   1395    789      ahrens 		 */
   1396    789      ahrens 		assert(reason == ZPOOL_STATUS_OK);
   1397    789      ahrens 	}
   1398    789      ahrens 
   1399    789      ahrens 	/*
   1400    789      ahrens 	 * Print out an action according to the overall state of the pool.
   1401    789      ahrens 	 */
   1402   3741    mmusante 	if (vs->vs_state == VDEV_STATE_HEALTHY) {
   1403   1760    eschrock 		if (reason == ZPOOL_STATUS_VERSION_OLDER)
   1404   1760    eschrock 			(void) printf(gettext("action: The pool can be "
   1405   1760    eschrock 			    "imported using its name or numeric identifier, "
   1406   1760    eschrock 			    "though\n\tsome features will not be available "
   1407   1760    eschrock 			    "without an explicit 'zpool upgrade'.\n"));
   1408   3975    ek110237 		else if (reason == ZPOOL_STATUS_HOSTID_MISMATCH)
   1409   3975    ek110237 			(void) printf(gettext("action: The pool can be "
   1410   3975    ek110237 			    "imported using its name or numeric "
   1411   3975    ek110237 			    "identifier and\n\tthe '-f' flag.\n"));
   1412    789      ahrens 		else
   1413   1760    eschrock 			(void) printf(gettext("action: The pool can be "
   1414   1760    eschrock 			    "imported using its name or numeric "
   1415   1760    eschrock 			    "identifier.\n"));
   1416   3741    mmusante 	} else if (vs->vs_state == VDEV_STATE_DEGRADED) {
   1417    789      ahrens 		(void) printf(gettext("action: The pool can be imported "
   1418    789      ahrens 		    "despite missing or damaged devices.  The\n\tfault "
   1419   1760    eschrock 		    "tolerance of the pool may be compromised if imported.\n"));
   1420    789      ahrens 	} else {
   1421   1760    eschrock 		switch (reason) {
   1422   1760    eschrock 		case ZPOOL_STATUS_VERSION_NEWER:
   1423   1760    eschrock 			(void) printf(gettext("action: The pool cannot be "
   1424   1760    eschrock 			    "imported.  Access the pool on a system running "
   1425   1760    eschrock 			    "newer\n\tsoftware, or recreate the pool from "
   1426   1760    eschrock 			    "backup.\n"));
   1427   1760    eschrock 			break;
   1428   1760    eschrock 		case ZPOOL_STATUS_MISSING_DEV_R:
   1429   1760    eschrock 		case ZPOOL_STATUS_MISSING_DEV_NR:
   1430   1760    eschrock 		case ZPOOL_STATUS_BAD_GUID_SUM:
   1431    789      ahrens 			(void) printf(gettext("action: The pool cannot be "
   1432    789      ahrens 			    "imported. Attach the missing\n\tdevices and try "
   1433    789      ahrens 			    "again.\n"));
   1434   1760    eschrock 			break;
   1435   1760    eschrock 		default:
   1436    789      ahrens 			(void) printf(gettext("action: The pool cannot be "
   1437    789      ahrens 			    "imported due to damaged devices or data.\n"));
   1438   1760    eschrock 		}
   1439   1760    eschrock 	}
   1440   1760    eschrock 
   1441   3741    mmusante 	/*
   1442   3741    mmusante 	 * If the state is "closed" or "can't open", and the aux state
   1443   3741    mmusante 	 * is "corrupt data":
   1444   3741    mmusante 	 */
   1445   3741    mmusante 	if (((vs->vs_state == VDEV_STATE_CLOSED) ||
   1446   3741    mmusante 	    (vs->vs_state == VDEV_STATE_CANT_OPEN)) &&
   1447   3741    mmusante 	    (vs->vs_aux == VDEV_AUX_CORRUPT_DATA)) {
   1448   1760    eschrock 		if (pool_state == POOL_STATE_DESTROYED)
   1449   1760    eschrock 			(void) printf(gettext("\tThe pool was destroyed, "
   1450   1760    eschrock 			    "but can be imported using the '-Df' flags.\n"));
   1451   1760    eschrock 		else if (pool_state != POOL_STATE_EXPORTED)
   1452   1760    eschrock 			(void) printf(gettext("\tThe pool may be active on "
   1453   5853    ek110237 			    "another system, but can be imported using\n\t"
   1454   1760    eschrock 			    "the '-f' flag.\n"));
   1455    789      ahrens 	}
   1456    789      ahrens 
   1457    789      ahrens 	if (msgid != NULL)
   1458    789      ahrens 		(void) printf(gettext("   see: http://www.sun.com/msg/%s\n"),
   1459    789      ahrens 		    msgid);
   1460    789      ahrens 
   1461    789      ahrens 	(void) printf(gettext("config:\n\n"));
   1462    789      ahrens 
   1463   1354    eschrock 	namewidth = max_width(NULL, nvroot, 0, 0);
   1464    789      ahrens 	if (namewidth < 10)
   1465    789      ahrens 		namewidth = 10;
   1466   4527      perrin 
   1467   9701      George 	print_import_config(name, nvroot, namewidth, 0);
   1468   9701      George 	if (num_logs(nvroot) > 0)
   1469   9701      George 		print_logs(NULL, nvroot, namewidth, B_FALSE);
   1470    789      ahrens 
   1471    789      ahrens 	if (reason == ZPOOL_STATUS_BAD_GUID_SUM) {
   1472   3741    mmusante 		(void) printf(gettext("\n\tAdditional devices are known to "
   1473    789      ahrens 		    "be part of this pool, though their\n\texact "
   1474   3741    mmusante 		    "configuration cannot be determined.\n"));
   1475    789      ahrens 	}
   1476    789      ahrens }
   1477    789      ahrens 
   1478    789      ahrens /*
   1479    789      ahrens  * Perform the import for the given configuration.  This passes the heavy
   1480   5094       lling  * lifting off to zpool_import_props(), and then mounts the datasets contained
   1481   5094       lling  * within the pool.
   1482    789      ahrens  */
   1483    789      ahrens static int
   1484    789      ahrens do_import(nvlist_t *config, const char *newname, const char *mntopts,
   1485  10000      Victor     int force, nvlist_t *props, boolean_t do_verbatim)
   1486    789      ahrens {
   1487    789      ahrens 	zpool_handle_t *zhp;
   1488    789      ahrens 	char *name;
   1489    789      ahrens 	uint64_t state;
   1490   1760    eschrock 	uint64_t version;
   1491    789      ahrens 
   1492    789      ahrens 	verify(nvlist_lookup_string(config, ZPOOL_CONFIG_POOL_NAME,
   1493    789      ahrens 	    &name) == 0);
   1494    789      ahrens 
   1495    789      ahrens 	verify(nvlist_lookup_uint64(config,
   1496    789      ahrens 	    ZPOOL_CONFIG_POOL_STATE, &state) == 0);
   1497   1760    eschrock 	verify(nvlist_lookup_uint64(config,
   1498   1760    eschrock 	    ZPOOL_CONFIG_VERSION, &version) == 0);
   1499   4577      ahrens 	if (version > SPA_VERSION) {
   1500   1760    eschrock 		(void) fprintf(stderr, gettext("cannot import '%s': pool "
   1501   1760    eschrock 		    "is formatted using a newer ZFS version\n"), name);
   1502   1760    eschrock 		return (1);
   1503   1760    eschrock 	} else if (state != POOL_STATE_EXPORTED && !force) {
   1504   3975    ek110237 		uint64_t hostid;
   1505   3975    ek110237 
   1506   3975    ek110237 		if (nvlist_lookup_uint64(config, ZPOOL_CONFIG_HOSTID,
   1507   3975    ek110237 		    &hostid) == 0) {
   1508   3975    ek110237 			if ((unsigned long)hostid != gethostid()) {
   1509   3975    ek110237 				char *hostname;
   1510   3975    ek110237 				uint64_t timestamp;
   1511   3975    ek110237 				time_t t;
   1512   3975    ek110237 
   1513   3975    ek110237 				verify(nvlist_lookup_string(config,
   1514   3975    ek110237 				    ZPOOL_CONFIG_HOSTNAME, &hostname) == 0);
   1515   3975    ek110237 				verify(nvlist_lookup_uint64(config,
   1516   3975    ek110237 				    ZPOOL_CONFIG_TIMESTAMP, &timestamp) == 0);
   1517   3975    ek110237 				t = timestamp;
   1518   3975    ek110237 				(void) fprintf(stderr, gettext("cannot import "
   1519   3975    ek110237 				    "'%s': pool may be in use from other "
   1520   3975    ek110237 				    "system, it was last accessed by %s "
   1521   3975    ek110237 				    "(hostid: 0x%lx) on %s"), name, hostname,
   1522   3975    ek110237 				    (unsigned long)hostid,
   1523   3975    ek110237 				    asctime(localtime(&t)));
   1524   3975    ek110237 				(void) fprintf(stderr, gettext("use '-f' to "
   1525   3975    ek110237 				    "import anyway\n"));
   1526   3975    ek110237 				return (1);
   1527   3975    ek110237 			}
   1528   3975    ek110237 		} else {
   1529   3975    ek110237 			(void) fprintf(stderr, gettext("cannot import '%s': "
   1530   3975    ek110237 			    "pool may be in use from other system\n"), name);
   1531   3975    ek110237 			(void) fprintf(stderr, gettext("use '-f' to import "
   1532   3975    ek110237 			    "anyway\n"));
   1533   3975    ek110237 			return (1);
   1534   3975    ek110237 		}
   1535    789      ahrens 	}
   1536    789      ahrens 
   1537  10000      Victor 	if (zpool_import_props(g_zfs, config, newname, props, do_verbatim) != 0)
   1538    789      ahrens 		return (1);
   1539    789      ahrens 
   1540    789      ahrens 	if (newname != NULL)
   1541    789      ahrens 		name = (char *)newname;
   1542   2926    ek110237 
   1543  10000      Victor 	if ((zhp = zpool_open_canfail(g_zfs, name)) == NULL)
   1544  10000      Victor 		return (1);
   1545    789      ahrens 
   1546   8525        Eric 	if (zpool_get_state(zhp) != POOL_STATE_UNAVAIL &&
   1547   8525        Eric 	    zpool_enable_datasets(zhp, mntopts, 0) != 0) {
   1548    789      ahrens 		zpool_close(zhp);
   1549    789      ahrens 		return (1);
   1550    789      ahrens 	}
   1551    789      ahrens 
   1552    789      ahrens 	zpool_close(zhp);
   1553  10921         Tim 	return (0);
   1554    789      ahrens }
   1555    789      ahrens 
   1556    789      ahrens /*
   1557   1631     darrenm  * zpool import [-d dir] [-D]
   1558   5363    eschrock  *       import [-o mntopts] [-o prop=value] ... [-R root] [-D]
   1559   5363    eschrock  *              [-d dir | -c cachefile] [-f] -a
   1560   5363    eschrock  *       import [-o mntopts] [-o prop=value] ... [-R root] [-D]
   1561  10921         Tim  *              [-d dir | -c cachefile] [-f] [-n] [-F] <pool | id> [newpool]
   1562   5363    eschrock  *
   1563   5363    eschrock  *	 -c	Read pool information from a cachefile instead of searching
   1564   5363    eschrock  *		devices.
   1565    789      ahrens  *
   1566    789      ahrens  *       -d	Scan in a specific directory, other than /dev/dsk.  More than
   1567    789      ahrens  *		one directory can be specified using multiple '-d' options.
   1568   1631     darrenm  *
   1569   1631     darrenm  *       -D     Scan for previously destroyed pools or import all or only
   1570   1631     darrenm  *              specified destroyed pools.
   1571    789      ahrens  *
   1572    789      ahrens  *       -R	Temporarily import the pool, with all mountpoints relative to
   1573    789      ahrens  *		the given root.  The pool will remain exported when the machine
   1574    789      ahrens  *		is rebooted.
   1575    789      ahrens  *
   1576  10921         Tim  *       -V	Import even in the presence of faulted vdevs.  This is an
   1577   6643    eschrock  *       	intentionally undocumented option for testing purposes, and
   1578   6643    eschrock  *       	treats the pool configuration as complete, leaving any bad
   1579  10000      Victor  *		vdevs in the FAULTED state. In other words, it does verbatim
   1580  10000      Victor  *		import.
   1581  10921         Tim  *
   1582  10921         Tim  *       -f	Force import, even if it appears that the pool is active.
   1583  10921         Tim  *
   1584  10921         Tim  *       -F     Attempt rewind if necessary.
   1585  10921         Tim  *
   1586  10921         Tim  *       -n     See if rewind would work, but don't actually rewind.
   1587   6643    eschrock  *
   1588    789      ahrens  *       -a	Import all pools found.
   1589    789      ahrens  *
   1590   5094       lling  *       -o	Set property=value and/or temporary mount options (without '=').
   1591   4543       marks  *
   1592    789      ahrens  * The import command scans for pools to import, and import pools based on pool
   1593    789      ahrens  * name and GUID.  The pool can also be renamed as part of the import process.
   1594    789      ahrens  */
   1595    789      ahrens int
   1596    789      ahrens zpool_do_import(int argc, char **argv)
   1597    789      ahrens {
   1598    789      ahrens 	char **searchdirs = NULL;
   1599    789      ahrens 	int nsearch = 0;
   1600    789      ahrens 	int c;
   1601    789      ahrens 	int err;
   1602   5363    eschrock 	nvlist_t *pools = NULL;
   1603   2082    eschrock 	boolean_t do_all = B_FALSE;
   1604   2082    eschrock 	boolean_t do_destroyed = B_FALSE;
   1605    789      ahrens 	char *mntopts = NULL;
   1606   2082    eschrock 	boolean_t do_force = B_FALSE;
   1607    789      ahrens 	nvpair_t *elem;
   1608    789      ahrens 	nvlist_t *config;
   1609   6807    ck153898 	uint64_t searchguid = 0;
   1610   6807    ck153898 	char *searchname = NULL;
   1611   5094       lling 	char *propval;
   1612    789      ahrens 	nvlist_t *found_config;
   1613  10921         Tim 	nvlist_t *policy = NULL;
   1614   4543       marks 	nvlist_t *props = NULL;
   1615   2082    eschrock 	boolean_t first;
   1616  10000      Victor 	boolean_t do_verbatim = B_FALSE;
   1617  10921         Tim 	uint32_t rewind_policy = ZPOOL_NO_REWIND;
   1618  10921         Tim 	boolean_t dryrun = B_FALSE;
   1619  10921         Tim 	boolean_t do_rewind = B_FALSE;
   1620  10921         Tim 	boolean_t xtreme_rewind = B_FALSE;
   1621   1631     darrenm 	uint64_t pool_state;
   1622   5363    eschrock 	char *cachefile = NULL;
   1623    789      ahrens 
   1624    789      ahrens 	/* check options */
   1625  10921         Tim 	while ((c = getopt(argc, argv, ":aCc:d:DEfFno:p:rR:VX")) != -1) {
   1626    789      ahrens 		switch (c) {
   1627    789      ahrens 		case 'a':
   1628   2082    eschrock 			do_all = B_TRUE;
   1629   5363    eschrock 			break;
   1630   5363    eschrock 		case 'c':
   1631   5363    eschrock 			cachefile = optarg;
   1632    789      ahrens 			break;
   1633    789      ahrens 		case 'd':
   1634    789      ahrens 			if (searchdirs == NULL) {
   1635    789      ahrens 				searchdirs = safe_malloc(sizeof (char *));
   1636    789      ahrens 			} else {
   1637    789      ahrens 				char **tmp = safe_malloc((nsearch + 1) *
   1638    789      ahrens 				    sizeof (char *));
   1639    789      ahrens 				bcopy(searchdirs, tmp, nsearch *
   1640    789      ahrens 				    sizeof (char *));
   1641    789      ahrens 				free(searchdirs);
   1642    789      ahrens 				searchdirs = tmp;
   1643    789      ahrens 			}
   1644    789      ahrens 			searchdirs[nsearch++] = optarg;
   1645   1631     darrenm 			break;
   1646   1631     darrenm 		case 'D':
   1647   2082    eschrock 			do_destroyed = B_TRUE;
   1648    789      ahrens 			break;
   1649    789      ahrens 		case 'f':
   1650   2082    eschrock 			do_force = B_TRUE;
   1651   6643    eschrock 			break;
   1652   6643    eschrock 		case 'F':
   1653  10921         Tim 			do_rewind = B_TRUE;
   1654  10921         Tim 			break;
   1655  10921         Tim 		case 'n':
   1656  10921         Tim 			dryrun = B_TRUE;
   1657    789      ahrens 			break;
   1658    789      ahrens 		case 'o':
   1659   5094       lling 			if ((propval = strchr(optarg, '=')) != NULL) {
   1660   5094       lling 				*propval = '\0';
   1661   5094       lling 				propval++;
   1662   7184        timh 				if (add_prop_list(optarg, propval,
   1663   7184        timh 				    &props, B_TRUE))
   1664   5094       lling 					goto error;
   1665   5094       lling 			} else {
   1666   5094       lling 				mntopts = optarg;
   1667   5094       lling 			}
   1668    789      ahrens 			break;
   1669    789      ahrens 		case 'R':
   1670   5094       lling 			if (add_prop_list(zpool_prop_to_name(
   1671   7184        timh 			    ZPOOL_PROP_ALTROOT), optarg, &props, B_TRUE))
   1672   5094       lling 				goto error;
   1673   5363    eschrock 			if (nvlist_lookup_string(props,
   1674   5363    eschrock 			    zpool_prop_to_name(ZPOOL_PROP_CACHEFILE),
   1675   5363    eschrock 			    &propval) == 0)
   1676   5363    eschrock 				break;
   1677   5094       lling 			if (add_prop_list(zpool_prop_to_name(
   1678   7184        timh 			    ZPOOL_PROP_CACHEFILE), "none", &props, B_TRUE))
   1679   5094       lling 				goto error;
   1680    789      ahrens 			break;
   1681  10921         Tim 		case 'V':
   1682  10921         Tim 			do_verbatim = B_TRUE;
   1683  10921         Tim 			break;
   1684  10921         Tim 		case 'X':
   1685  10921         Tim 			xtreme_rewind = B_TRUE;
   1686  10921         Tim 			break;
   1687    789      ahrens 		case ':':
   1688    789      ahrens 			(void) fprintf(stderr, gettext("missing argument for "
   1689    789      ahrens 			    "'%c' option\n"), optopt);
   1690   2082    eschrock 			usage(B_FALSE);
   1691    789      ahrens 			break;
   1692    789      ahrens 		case '?':
   1693    789      ahrens 			(void) fprintf(stderr, gettext("invalid option '%c'\n"),
   1694    789      ahrens 			    optopt);
   1695   2082    eschrock 			usage(B_FALSE);
   1696    789      ahrens 		}
   1697    789      ahrens 	}
   1698    789      ahrens 
   1699    789      ahrens 	argc -= optind;
   1700    789      ahrens 	argv += optind;
   1701   5363    eschrock 
   1702   5363    eschrock 	if (cachefile && nsearch != 0) {
   1703   5363    eschrock 		(void) fprintf(stderr, gettext("-c is incompatible with -d\n"));
   1704   5363    eschrock 		usage(B_FALSE);
   1705   5363    eschrock 	}
   1706  10921         Tim 
   1707  10921         Tim 	if ((dryrun || xtreme_rewind) && !do_rewind) {
   1708  10921         Tim 		(void) fprintf(stderr,
   1709  10921         Tim 		    gettext("-n or -X only meaningful with -F\n"));
   1710  10921         Tim 		usage(B_FALSE);
   1711  10921         Tim 	}
   1712  10921         Tim 	if (dryrun)
   1713  10921         Tim 		rewind_policy = ZPOOL_TRY_REWIND;
   1714  10921         Tim 	else if (do_rewind)
   1715  10921         Tim 		rewind_policy = ZPOOL_DO_REWIND;
   1716  10921         Tim 	if (xtreme_rewind)
   1717  10921         Tim 		rewind_policy |= ZPOOL_EXTREME_REWIND;
   1718  10921         Tim 
   1719  10921         Tim 	/* In the future, we can capture further policy and include it here */
   1720  10921         Tim 	if (nvlist_alloc(&policy, NV_UNIQUE_NAME, 0) != 0 ||
   1721  10921         Tim 	    nvlist_add_uint32(policy, ZPOOL_REWIND_REQUEST, rewind_policy) != 0)
   1722  10921         Tim 		goto error;
   1723    789      ahrens 
   1724    789      ahrens 	if (searchdirs == NULL) {
   1725    789      ahrens 		searchdirs = safe_malloc(sizeof (char *));
   1726    789      ahrens 		searchdirs[0] = "/dev/dsk";
   1727    789      ahrens 		nsearch = 1;
   1728    789      ahrens 	}
   1729    789      ahrens 
   1730    789      ahrens 	/* check argument count */
   1731    789      ahrens 	if (do_all) {
   1732    789      ahrens 		if (argc != 0) {
   1733    789      ahrens 			(void) fprintf(stderr, gettext("too many arguments\n"));
   1734   2082    eschrock 			usage(B_FALSE);
   1735    789      ahrens 		}
   1736    789      ahrens 	} else {
   1737    789      ahrens 		if (argc > 2) {
   1738    789      ahrens 			(void) fprintf(stderr, gettext("too many arguments\n"));
   1739   2082    eschrock 			usage(B_FALSE);
   1740    789      ahrens 		}
   1741    789      ahrens 
   1742    789      ahrens 		/*
   1743    789      ahrens 		 * Check for the SYS_CONFIG privilege.  We do this explicitly
   1744    789      ahrens 		 * here because otherwise any attempt to discover pools will
   1745    789      ahrens 		 * silently fail.
   1746    789      ahrens 		 */
   1747    789      ahrens 		if (argc == 0 && !priv_ineffect(PRIV_SYS_CONFIG)) {
   1748    789      ahrens 			(void) fprintf(stderr, gettext("cannot "
   1749    789      ahrens 			    "discover pools: permission denied\n"));
   1750   2082    eschrock 			free(searchdirs);
   1751  10921         Tim 			nvlist_free(policy);
   1752    789      ahrens 			return (1);
   1753    789      ahrens 		}
   1754    789      ahrens 	}
   1755    789      ahrens 
   1756    789      ahrens 	/*
   1757    789      ahrens 	 * Depending on the arguments given, we do one of the following:
   1758    789      ahrens 	 *
   1759    789      ahrens 	 *	<none>	Iterate through all pools and display information about
   1760    789      ahrens 	 *		each one.
   1761    789      ahrens 	 *
   1762    789      ahrens 	 *	-a	Iterate through all pools and try to import each one.
   1763    789      ahrens 	 *
   1764    789      ahrens 	 *	<id>	Find the pool that corresponds to the given GUID/pool
   1765    789      ahrens 	 *		name and import that one.
   1766   1631     darrenm 	 *
   1767   1631     darrenm 	 *	-D	Above options applies only to destroyed pools.
   1768    789      ahrens 	 */
   1769    789      ahrens 	if (argc != 0) {
   1770    789      ahrens 		char *endptr;
   1771    789      ahrens 
   1772    789      ahrens 		errno = 0;
   1773    789      ahrens 		searchguid = strtoull(argv[0], &endptr, 10);
   1774    789      ahrens 		if (errno != 0 || *endptr != '\0')
   1775    789      ahrens 			searchname = argv[0];
   1776    789      ahrens 		found_config = NULL;
   1777    789      ahrens 	}
   1778    789      ahrens 
   1779   6807    ck153898 	if (cachefile) {
   1780   6957    ck153898 		pools = zpool_find_import_cached(g_zfs, cachefile, searchname,
   1781   6957    ck153898 		    searchguid);
   1782   6807    ck153898 	} else if (searchname != NULL) {
   1783   6807    ck153898 		pools = zpool_find_import_byname(g_zfs, nsearch, searchdirs,
   1784   6807    ck153898 		    searchname);
   1785   6807    ck153898 	} else {
   1786   6807    ck153898 		/*
   1787   6807    ck153898 		 * It's OK to search by guid even if searchguid is 0.
   1788   6807    ck153898 		 */
   1789   6807    ck153898 		pools = zpool_find_import_byguid(g_zfs, nsearch, searchdirs,
   1790   6807    ck153898 		    searchguid);
   1791   6807    ck153898 	}
   1792   6807    ck153898 
   1793   6807    ck153898 	if (pools == NULL) {
   1794   6807    ck153898 		if (argc != 0) {
   1795   6807    ck153898 			(void) fprintf(stderr, gettext("cannot import '%s': "
   1796   6807    ck153898 			    "no such pool available\n"), argv[0]);
   1797   6807    ck153898 		}
   1798   6807    ck153898 		free(searchdirs);
   1799  10921         Tim 		nvlist_free(policy);
   1800   6807    ck153898 		return (1);
   1801   6807    ck153898 	}
   1802   6807    ck153898 
   1803   6807    ck153898 	/*
   1804   6807    ck153898 	 * At this point we have a list of import candidate configs. Even if
   1805   6807    ck153898 	 * we were searching by pool name or guid, we still need to
   1806   6807    ck153898 	 * post-process the list to deal with pool state and possible
   1807   6807    ck153898 	 * duplicate names.
   1808   6807    ck153898 	 */
   1809    789      ahrens 	err = 0;
   1810    789      ahrens 	elem = NULL;
   1811   2082    eschrock 	first = B_TRUE;
   1812    789      ahrens 	while ((elem = nvlist_next_nvpair(pools, elem)) != NULL) {
   1813    789      ahrens 
   1814    789      ahrens 		verify(nvpair_value_nvlist(elem, &config) == 0);
   1815   1631     darrenm 
   1816   1631     darrenm 		verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_STATE,
   1817   1631     darrenm 		    &pool_state) == 0);
   1818   1631     darrenm 		if (!do_destroyed && pool_state == POOL_STATE_DESTROYED)
   1819   1631     darrenm 			continue;
   1820   1631     darrenm 		if (do_destroyed && pool_state != POOL_STATE_DESTROYED)
   1821   1631     darrenm 			continue;
   1822  10921         Tim 
   1823  10921         Tim 		verify(nvlist_add_nvlist(config, ZPOOL_REWIND_POLICY,
   1824  10921         Tim 		    policy) == 0);
   1825    789      ahrens 
   1826    789      ahrens 		if (argc == 0) {
   1827    789      ahrens 			if (first)
   1828   2082    eschrock 				first = B_FALSE;
   1829   2474    eschrock 			else if (!do_all)
   1830    789      ahrens 				(void) printf("\n");
   1831    789      ahrens 
   1832  10921         Tim 			if (do_all) {
   1833    789      ahrens 				err |= do_import(config, NULL, mntopts,
   1834  10000      Victor 				    do_force, props, do_verbatim);
   1835  10921         Tim 			} else {
   1836    789      ahrens 				show_import(config);
   1837  10921         Tim 			}
   1838    789      ahrens 		} else if (searchname != NULL) {
   1839    789      ahrens 			char *name;
   1840    789      ahrens 
   1841    789      ahrens 			/*
   1842    789      ahrens 			 * We are searching for a pool based on name.
   1843    789      ahrens 			 */
   1844    789      ahrens 			verify(nvlist_lookup_string(config,
   1845    789      ahrens 			    ZPOOL_CONFIG_POOL_NAME, &name) == 0);
   1846    789      ahrens 
   1847    789      ahrens 			if (strcmp(name, searchname) == 0) {
   1848    789      ahrens 				if (found_config != NULL) {
   1849    789      ahrens 					(void) fprintf(stderr, gettext(
   1850    789      ahrens 					    "cannot import '%s': more than "
   1851    789      ahrens 					    "one matching pool\n"), searchname);
   1852    789      ahrens 					(void) fprintf(stderr, gettext(
   1853    789      ahrens 					    "import by numeric ID instead\n"));
   1854   2082    eschrock 					err = B_TRUE;
   1855    789      ahrens 				}
   1856    789      ahrens 				found_config = config;
   1857    789      ahrens 			}
   1858    789      ahrens 		} else {
   1859    789      ahrens 			uint64_t guid;
   1860    789      ahrens 
   1861    789      ahrens 			/*
   1862    789      ahrens 			 * Search for a pool by guid.
   1863    789      ahrens 			 */
   1864    789      ahrens 			verify(nvlist_lookup_uint64(config,
   1865    789      ahrens 			    ZPOOL_CONFIG_POOL_GUID, &guid) == 0);
   1866    789      ahrens 
   1867    789      ahrens 			if (guid == searchguid)
   1868    789      ahrens 				found_config = config;
   1869    789      ahrens 		}
   1870    789      ahrens 	}
   1871    789      ahrens 
   1872    789      ahrens 	/*
   1873    789      ahrens 	 * If we were searching for a specific pool, verify that we found a
   1874    789      ahrens 	 * pool, and then do the import.
   1875    789      ahrens 	 */
   1876    789      ahrens 	if (argc != 0 && err == 0) {
   1877    789      ahrens 		if (found_config == NULL) {
   1878    789      ahrens 			(void) fprintf(stderr, gettext("cannot import '%s': "
   1879    789      ahrens 			    "no such pool available\n"), argv[0]);
   1880   2082    eschrock 			err = B_TRUE;
   1881    789      ahrens 		} else {
   1882    789      ahrens 			err |= do_import(found_config, argc == 1 ? NULL :
   1883  10000      Victor 			    argv[1], mntopts, do_force, props, do_verbatim);
   1884    789      ahrens 		}
   1885    789      ahrens 	}
   1886    789      ahrens 
   1887    789      ahrens 	/*
   1888    789      ahrens 	 * If we were just looking for pools, report an error if none were
   1889    789      ahrens 	 * found.
   1890    789      ahrens 	 */
   1891    789      ahrens 	if (argc == 0 && first)
   1892    789      ahrens 		(void) fprintf(stderr,
   1893    789      ahrens 		    gettext("no pools available to import\n"));
   1894    789      ahrens 
   1895   4543       marks error:
   1896   5363    eschrock 	nvlist_free(props);
   1897    789      ahrens 	nvlist_free(pools);
   1898  10921         Tim 	nvlist_free(policy);
   1899   2082    eschrock 	free(searchdirs);
   1900    789      ahrens 
   1901    789      ahrens 	return (err ? 1 : 0);
   1902    789      ahrens }
   1903    789      ahrens 
   1904    789      ahrens typedef struct iostat_cbdata {
   1905    789      ahrens 	zpool_list_t *cb_list;
   1906    789      ahrens 	int cb_verbose;
   1907    789      ahrens 	int cb_iteration;
   1908    789      ahrens 	int cb_namewidth;
   1909    789      ahrens } iostat_cbdata_t;
   1910    789      ahrens 
   1911    789      ahrens static void
   1912    789      ahrens print_iostat_separator(iostat_cbdata_t *cb)
   1913    789      ahrens {
   1914    789      ahrens 	int i = 0;
   1915    789      ahrens 
   1916    789      ahrens 	for (i = 0; i < cb->cb_namewidth; i++)
   1917    789      ahrens 		(void) printf("-");
   1918    789      ahrens 	(void) printf("  -----  -----  -----  -----  -----  -----\n");
   1919    789      ahrens }
   1920    789      ahrens 
   1921    789      ahrens static void
   1922    789      ahrens print_iostat_header(iostat_cbdata_t *cb)
   1923    789      ahrens {
   1924    789      ahrens 	(void) printf("%*s     capacity     operations    bandwidth\n",
   1925    789      ahrens 	    cb->cb_namewidth, "");
   1926  10956      George 	(void) printf("%-*s  alloc   free   read  write   read  write\n",
   1927    789      ahrens 	    cb->cb_namewidth, "pool");
   1928    789      ahrens 	print_iostat_separator(cb);
   1929    789      ahrens }
   1930    789      ahrens 
   1931    789      ahrens /*
   1932    789      ahrens  * Display a single statistic.
   1933    789      ahrens  */
   1934   5094       lling static void
   1935    789      ahrens print_one_stat(uint64_t value)
   1936    789      ahrens {
   1937    789      ahrens 	char buf[64];
   1938    789      ahrens 
   1939    789      ahrens 	zfs_nicenum(value, buf, sizeof (buf));
   1940    789      ahrens 	(void) printf("  %5s", buf);
   1941    789      ahrens }
   1942    789      ahrens 
   1943    789      ahrens /*
   1944    789      ahrens  * Print out all the statistics for the given vdev.  This can either be the
   1945    789      ahrens  * toplevel configuration, or called recursively.  If 'name' is NULL, then this
   1946    789      ahrens  * is a verbose output, and we don't want to display the toplevel pool stats.
   1947    789      ahrens  */
   1948    789      ahrens void
   1949   1354    eschrock print_vdev_stats(zpool_handle_t *zhp, const char *name, nvlist_t *oldnv,
   1950   1354    eschrock     nvlist_t *newnv, iostat_cbdata_t *cb, int depth)
   1951    789      ahrens {
   1952    789      ahrens 	nvlist_t **oldchild, **newchild;
   1953    789      ahrens 	uint_t c, children;
   1954    789      ahrens 	vdev_stat_t *oldvs, *newvs;
   1955    789      ahrens 	vdev_stat_t zerovs = { 0 };
   1956    789      ahrens 	uint64_t tdelta;
   1957    789      ahrens 	double scale;
   1958   1171    eschrock 	char *vname;
   1959    789      ahrens 
   1960    789      ahrens 	if (oldnv != NULL) {
   1961    789      ahrens 		verify(nvlist_lookup_uint64_array(oldnv, ZPOOL_CONFIG_STATS,
   1962    789      ahrens 		    (uint64_t **)&oldvs, &c) == 0);
   1963    789      ahrens 	} else {
   1964    789      ahrens 		oldvs = &zerovs;
   1965    789      ahrens 	}
   1966    789      ahrens 
   1967    789      ahrens 	verify(nvlist_lookup_uint64_array(newnv, ZPOOL_CONFIG_STATS,
   1968    789      ahrens 	    (uint64_t **)&newvs, &c) == 0);
   1969    789      ahrens 
   1970    789      ahrens 	if (strlen(name) + depth > cb->cb_namewidth)
   1971    789      ahrens 		(void) printf("%*s%s", depth, "", name);
   1972    789      ahrens 	else
   1973    789      ahrens 		(void) printf("%*s%s%*s", depth, "", name,
   1974    789      ahrens 		    (int)(cb->cb_namewidth - strlen(name) - depth), "");
   1975    789      ahrens 
   1976    789      ahrens 	tdelta = newvs->vs_timestamp - oldvs->vs_timestamp;
   1977    789      ahrens 
   1978    789      ahrens 	if (tdelta == 0)
   1979    789      ahrens 		scale = 1.0;
   1980    789      ahrens 	else
   1981    789      ahrens 		scale = (double)NANOSEC / tdelta;
   1982    789      ahrens 
   1983    789      ahrens 	/* only toplevel vdevs have capacity stats */
   1984    789      ahrens 	if (newvs->vs_space == 0) {
   1985    789      ahrens 		(void) printf("      -      -");
   1986    789      ahrens 	} else {
   1987    789      ahrens 		print_one_stat(newvs->vs_alloc);
   1988    789      ahrens 		print_one_stat(newvs->vs_space - newvs->vs_alloc);
   1989    789      ahrens 	}
   1990    789      ahrens 
   1991    789      ahrens 	print_one_stat((uint64_t)(scale * (newvs->vs_ops[ZIO_TYPE_READ] -
   1992    789      ahrens 	    oldvs->vs_ops[ZIO_TYPE_READ])));
   1993    789      ahrens 
   1994    789      ahrens 	print_one_stat((uint64_t)(scale * (newvs->vs_ops[ZIO_TYPE_WRITE] -
   1995    789      ahrens 	    oldvs->vs_ops[ZIO_TYPE_WRITE])));
   1996    789      ahrens 
   1997    789      ahrens 	print_one_stat((uint64_t)(scale * (newvs->vs_bytes[ZIO_TYPE_READ] -
   1998    789      ahrens 	    oldvs->vs_bytes[ZIO_TYPE_READ])));
   1999    789      ahrens 
   2000    789      ahrens 	print_one_stat((uint64_t)(scale * (newvs->vs_bytes[ZIO_TYPE_WRITE] -
   2001    789      ahrens 	    oldvs->vs_bytes[ZIO_TYPE_WRITE])));
   2002    789      ahrens 
   2003    789      ahrens 	(void) printf("\n");
   2004    789      ahrens 
   2005    789      ahrens 	if (!cb->cb_verbose)
   2006    789      ahrens 		return;
   2007    789      ahrens 
   2008    789      ahrens 	if (nvlist_lookup_nvlist_array(newnv, ZPOOL_CONFIG_CHILDREN,
   2009    789      ahrens 	    &newchild, &children) != 0)
   2010    789      ahrens 		return;
   2011    789      ahrens 
   2012    789      ahrens 	if (oldnv && nvlist_lookup_nvlist_array(oldnv, ZPOOL_CONFIG_CHILDREN,
   2013    789      ahrens 	    &oldchild, &c) != 0)
   2014    789      ahrens 		return;
   2015    789      ahrens 
   2016   1171    eschrock 	for (c = 0; c < children; c++) {
   2017  10594      George 		vname = zpool_vdev_name(g_zfs, zhp, newchild[c], B_FALSE);
   2018   1354    eschrock 		print_vdev_stats(zhp, vname, oldnv ? oldchild[c] : NULL,
   2019   1171    eschrock 		    newchild[c], cb, depth + 2);
   2020   1171    eschrock 		free(vname);
   2021   5450     brendan 	}
   2022   5450     brendan 
   2023   5450     brendan 	/*
   2024   5450     brendan 	 * Include level 2 ARC devices in iostat output
   2025   5450     brendan 	 */
   2026   5450     brendan 	if (nvlist_lookup_nvlist_array(newnv, ZPOOL_CONFIG_L2CACHE,
   2027   5450     brendan 	    &newchild, &children) != 0)
   2028   5450     brendan 		return;
   2029   5450     brendan 
   2030   5450     brendan 	if (oldnv && nvlist_lookup_nvlist_array(oldnv, ZPOOL_CONFIG_L2CACHE,
   2031   5450     brendan 	    &oldchild, &c) != 0)
   2032   5450     brendan 		return;
   2033   5450     brendan 
   2034   5450     brendan 	if (children > 0) {
   2035   5450     brendan 		(void) printf("%-*s      -      -      -      -      -      "
   2036   5450     brendan 		    "-\n", cb->cb_namewidth, "cache");
   2037   5450     brendan 		for (c = 0; c < children; c++) {
   2038  10594      George 			vname = zpool_vdev_name(g_zfs, zhp, newchild[c],
   2039  10594      George 			    B_FALSE);
   2040   5450     brendan 			print_vdev_stats(zhp, vname, oldnv ? oldchild[c] : NULL,
   2041   5450     brendan 			    newchild[c], cb, depth + 2);
   2042   5450     brendan 			free(vname);
   2043   5450     brendan 		}
   2044   1171    eschrock 	}
   2045    789      ahrens }
   2046    789      ahrens 
   2047    952    eschrock static int
   2048    952    eschrock refresh_iostat(zpool_handle_t *zhp, void *data)
   2049    952    eschrock {
   2050    952    eschrock 	iostat_cbdata_t *cb = data;
   2051   2142    eschrock 	boolean_t missing;
   2052    952    eschrock 
   2053    952    eschrock 	/*
   2054    952    eschrock 	 * If the pool has disappeared, remove it from the list and continue.
   2055    952    eschrock 	 */
   2056   2142    eschrock 	if (zpool_refresh_stats(zhp, &missing) != 0)
   2057   2142    eschrock 		return (-1);
   2058   2142    eschrock 
   2059   2142    eschrock 	if (missing)
   2060    952    eschrock 		pool_list_remove(cb->cb_list, zhp);
   2061    952    eschrock 
   2062    952    eschrock 	return (0);
   2063    952    eschrock }
   2064    952    eschrock 
   2065    789      ahrens /*
   2066    789      ahrens  * Callback to print out the iostats for the given pool.
   2067    789      ahrens  */
   2068    789      ahrens int
   2069    789      ahrens print_iostat(zpool_handle_t *zhp, void *data)
   2070    789      ahrens {
   2071    789      ahrens 	iostat_cbdata_t *cb = data;
   2072    789      ahrens 	nvlist_t *oldconfig, *newconfig;
   2073    789      ahrens 	nvlist_t *oldnvroot, *newnvroot;
   2074    789      ahrens 
   2075    952    eschrock 	newconfig = zpool_get_config(zhp, &oldconfig);
   2076    789      ahrens 
   2077    952    eschrock 	if (cb->cb_iteration == 1)
   2078    789      ahrens 		oldconfig = NULL;
   2079    789      ahrens 
   2080    789      ahrens 	verify(nvlist_lookup_nvlist(newconfig, ZPOOL_CONFIG_VDEV_TREE,
   2081    789      ahrens 	    &newnvroot) == 0);
   2082    789      ahrens 
   2083    952    eschrock 	if (oldconfig == NULL)
   2084    789      ahrens 		oldnvroot = NULL;
   2085    952    eschrock 	else
   2086    952    eschrock 		verify(nvlist_lookup_nvlist(oldconfig, ZPOOL_CONFIG_VDEV_TREE,
   2087    952    eschrock 		    &oldnvroot) == 0);
   2088    789      ahrens 
   2089    789      ahrens 	/*
   2090    789      ahrens 	 * Print out the statistics for the pool.
   2091    789      ahrens 	 */
   2092   1354    eschrock 	print_vdev_stats(zhp, zpool_get_name(zhp), oldnvroot, newnvroot, cb, 0);
   2093    789      ahrens 
   2094    789      ahrens 	if (cb->cb_verbose)
   2095    789      ahrens 		print_iostat_separator(cb);
   2096    789      ahrens 
   2097    789      ahrens 	return (0);
   2098    789      ahrens }
   2099    789      ahrens 
   2100    789      ahrens int
   2101    789      ahrens get_namewidth(zpool_handle_t *zhp, void *data)
   2102    789      ahrens {
   2103    789      ahrens 	iostat_cbdata_t *cb = data;
   2104    789      ahrens 	nvlist_t *config, *nvroot;
   2105    789      ahrens 
   2106    952    eschrock 	if ((config = zpool_get_config(zhp, NULL)) != NULL) {
   2107    789      ahrens 		verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
   2108    789      ahrens 		    &nvroot) == 0);
   2109    789      ahrens 		if (!cb->cb_verbose)
   2110    789      ahrens 			cb->cb_namewidth = strlen(zpool_get_name(zhp));
   2111    789      ahrens 		else
   2112   1354    eschrock 			cb->cb_namewidth = max_width(zhp, nvroot, 0, 0);
   2113    789      ahrens 	}
   2114    789      ahrens 
   2115    789      ahrens 	/*
   2116    789      ahrens 	 * The width must fall into the range [10,38].  The upper limit is the
   2117    789      ahrens 	 * maximum we can have and still fit in 80 columns.
   2118    789      ahrens 	 */
   2119    789      ahrens 	if (cb->cb_namewidth < 10)
   2120    789      ahrens 		cb->cb_namewidth = 10;
   2121    789      ahrens 	if (cb->cb_namewidth > 38)
   2122    789      ahrens 		cb->cb_namewidth = 38;
   2123    789      ahrens 
   2124    789      ahrens 	return (0);
   2125    789      ahrens }
   2126    789      ahrens 
   2127    789      ahrens /*
   2128  10265  Krishnendu  * zpool iostat [-T d|u] [-v] [pool] ... [interval [count]]
   2129  10265  Krishnendu  *
   2130  10265  Krishnendu  *	-T	Display a timestamp in date(1) or Unix format
   2131    789      ahrens  *	-v	Display statistics for individual vdevs
   2132    789      ahrens  *
   2133    789      ahrens  * This command can be tricky because we want to be able to deal with pool
   2134    789      ahrens  * creation/destruction as well as vdev configuration changes.  The bulk of this
   2135    789      ahrens  * processing is handled by the pool_list_* routines in zpool_iter.c.  We rely
   2136    789      ahrens  * on pool_list_update() to detect the addition of new pools.  Configuration
   2137    789      ahrens  * changes are all handled within libzfs.
   2138    789      ahrens  */
   2139    789      ahrens int
   2140    789      ahrens zpool_do_iostat(int argc, char **argv)
   2141    789      ahrens {
   2142    789      ahrens 	int c;
   2143    789      ahrens 	int ret;
   2144    789      ahrens 	int npools;
   2145    789      ahrens 	unsigned long interval = 0, count = 0;
   2146    789      ahrens 	zpool_list_t *list;
   2147   2082    eschrock 	boolean_t verbose = B_FALSE;
   2148    789      ahrens 	iostat_cbdata_t cb;
   2149    789      ahrens 
   2150    789      ahrens 	/* check options */
   2151  10265  Krishnendu 	while ((c = getopt(argc, argv, "T:v")) != -1) {
   2152  10265  Krishnendu 		switch (c) {
   2153  10265  Krishnendu 		case 'T':
   2154  10265  Krishnendu 			if (optarg) {
   2155  10265  Krishnendu 				if (*optarg == 'u')
   2156  10265  Krishnendu 					timestamp_fmt = UDATE;
   2157  10265  Krishnendu 				else if (*optarg == 'd')
   2158  10265  Krishnendu 					timestamp_fmt = DDATE;
   2159  10265  Krishnendu 				else
   2160  10265  Krishnendu 					usage(B_FALSE);
   2161  10265  Krishnendu 			} else {
   2162  10265  Krishnendu 				usage(B_FALSE);
   2163  10265  Krishnendu 			}
   2164  10265  Krishnendu 			break;
   2165    789      ahrens 		case 'v':
   2166   2082    eschrock 			verbose = B_TRUE;
   2167    789      ahrens 			break;
   2168    789      ahrens 		case '?':
   2169    789      ahrens 			(void) fprintf(stderr, gettext("invalid option '%c'\n"),
   2170    789      ahrens 			    optopt);
   2171   2082    eschrock 			usage(B_FALSE);
   2172    789      ahrens 		}
   2173    789      ahrens 	}
   2174    789      ahrens 
   2175    789      ahrens 	argc -= optind;
   2176    789      ahrens 	argv += optind;
   2177    789      ahrens 
   2178    789      ahrens 	/*
   2179    789      ahrens 	 * Determine if the last argument is an integer or a pool name
   2180    789      ahrens 	 */
   2181    789      ahrens 	if (argc > 0 && isdigit(argv[argc - 1][0])) {
   2182    789      ahrens 		char *end;
   2183    789      ahrens 
   2184    789      ahrens 		errno = 0;
   2185    789      ahrens 		interval = strtoul(argv[argc - 1], &end, 10);
   2186    789      ahrens 
   2187    789      ahrens 		if (*end == '\0' && errno == 0) {
   2188    789      ahrens 			if (interval == 0) {
   2189    789      ahrens 				(void) fprintf(stderr, gettext("interval "
   2190    789      ahrens 				    "cannot be zero\n"));
   2191   2082    eschrock 				usage(B_FALSE);
   2192    789      ahrens 			}
   2193    789      ahrens 
   2194    789      ahrens 			/*
   2195    789      ahrens 			 * Ignore the last parameter
   2196    789      ahrens 			 */
   2197    789      ahrens 			argc--;
   2198    789      ahrens 		} else {
   2199    789      ahrens 			/*
   2200    789      ahrens 			 * If this is not a valid number, just plow on.  The
   2201    789      ahrens 			 * user will get a more informative error message later
   2202    789      ahrens 			 * on.
   2203    789      ahrens 			 */
   2204    789      ahrens 			interval = 0;
   2205    789      ahrens 		}
   2206    789      ahrens 	}
   2207    789      ahrens 
   2208    789      ahrens 	/*
   2209    789      ahrens 	 * If the last argument is also an integer, then we have both a count
   2210    789      ahrens 	 * and an integer.
   2211    789      ahrens 	 */
   2212    789      ahrens 	if (argc > 0 && isdigit(argv[argc - 1][0])) {
   2213    789      ahrens 		char *end;
   2214    789      ahrens 
   2215    789      ahrens 		errno = 0;
   2216    789      ahrens 		count = interval;
   2217    789      ahrens 		interval = strtoul(argv[argc - 1], &end, 10);
   2218    789      ahrens 
   2219    789      ahrens 		if (*end == '\0' && errno == 0) {
   2220    789      ahrens 			if (interval == 0) {
   2221    789      ahrens 				(void) fprintf(stderr, gettext("interval "
   2222    789      ahrens 				    "cannot be zero\n"));
   2223   2082    eschrock 				usage(B_FALSE);
   2224    789      ahrens 			}
   2225    789      ahrens 
   2226    789      ahrens 			/*
   2227    789      ahrens 			 * Ignore the last parameter
   2228    789      ahrens 			 */
   2229    789      ahrens 			argc--;
   2230    789      ahrens 		} else {
   2231    789      ahrens 			interval = 0;
   2232    789      ahrens 		}
   2233    789      ahrens 	}
   2234    789      ahrens 
   2235    789      ahrens 	/*
   2236    789      ahrens 	 * Construct the list of all interesting pools.
   2237    789      ahrens 	 */
   2238    789      ahrens 	ret = 0;
   2239   3912       lling 	if ((list = pool_list_get(argc, argv, NULL, &ret)) == NULL)
   2240    789      ahrens 		return (1);
   2241    789      ahrens 
   2242   2082    eschrock 	if (pool_list_count(list) == 0 && argc != 0) {
   2243   2082    eschrock 		pool_list_free(list);
   2244    789      ahrens 		return (1);
   2245   2082    eschrock 	}
   2246    789      ahrens 
   2247    789      ahrens 	if (pool_list_count(list) == 0 && interval == 0) {
   2248   2082    eschrock 		pool_list_free(list);
   2249    789      ahrens 		(void) fprintf(stderr, gettext("no pools available\n"));
   2250    789      ahrens 		return (1);
   2251    789      ahrens 	}
   2252    789      ahrens 
   2253    789      ahrens 	/*
   2254    789      ahrens 	 * Enter the main iostat loop.
   2255    789      ahrens 	 */
   2256    789      ahrens 	cb.cb_list = list;
   2257    789      ahrens 	cb.cb_verbose = verbose;
   2258    789      ahrens 	cb.cb_iteration = 0;
   2259    789      ahrens 	cb.cb_namewidth = 0;
   2260    789      ahrens 
   2261    789      ahrens 	for (;;) {
   2262    789      ahrens 		pool_list_update(list);
   2263    789      ahrens 
   2264    789      ahrens 		if ((npools = pool_list_count(list)) == 0)
   2265    789      ahrens 			break;
   2266    789      ahrens 
   2267    789      ahrens 		/*
   2268    952    eschrock 		 * Refresh all statistics.  This is done as an explicit step
   2269    952    eschrock 		 * before calculating the maximum name width, so that any
   2270    952    eschrock 		 * configuration changes are properly accounted for.
   2271    952    eschrock 		 */
   2272   2082    eschrock 		(void) pool_list_iter(list, B_FALSE, refresh_iostat, &cb);
   2273    952    eschrock 
   2274    952    eschrock 		/*
   2275    789      ahrens 		 * Iterate over all pools to determine the maximum width
   2276    789      ahrens 		 * for the pool / device name column across all pools.
   2277    789      ahrens 		 */
   2278    789      ahrens 		cb.cb_namewidth = 0;
   2279   2082    eschrock 		(void) pool_list_iter(list, B_FALSE, get_namewidth, &cb);
   2280  10265  Krishnendu 
   2281  10265  Krishnendu 		if (timestamp_fmt != NODATE)
   2282  10265  Krishnendu 			print_timestamp(timestamp_fmt);
   2283    789      ahrens 
   2284    789      ahrens 		/*
   2285    789      ahrens 		 * If it's the first time, or verbose mode, print the header.
   2286    789      ahrens 		 */
   2287    789      ahrens 		if (++cb.cb_iteration == 1 || verbose)
   2288    789      ahrens 			print_iostat_header(&cb);
   2289    789      ahrens 
   2290   2082    eschrock 		(void) pool_list_iter(list, B_FALSE, print_iostat, &cb);
   2291    789      ahrens 
   2292    789      ahrens 		/*
   2293    789      ahrens 		 * If there's more than one pool, and we're not in verbose mode
   2294    789      ahrens 		 * (which prints a separator for us), then print a separator.
   2295    789      ahrens 		 */
   2296    789      ahrens 		if (npools > 1 && !verbose)
   2297    789      ahrens 			print_iostat_separator(&cb);
   2298    789      ahrens 
   2299    789      ahrens 		if (verbose)
   2300    789      ahrens 			(void) printf("\n");
   2301   3377    eschrock 
   2302   3377    eschrock 		/*
   2303   3377    eschrock 		 * Flush the output so that redirection to a file isn't buffered
   2304   3377    eschrock 		 * indefinitely.
   2305   3377    eschrock 		 */
   2306   3377    eschrock 		(void) fflush(stdout);
   2307    789      ahrens 
   2308    789      ahrens 		if (interval == 0)
   2309    789      ahrens 			break;
   2310    789      ahrens 
   2311    789      ahrens 		if (count != 0 && --count == 0)
   2312    789      ahrens 			break;
   2313    789      ahrens 
   2314    789      ahrens 		(void) sleep(interval);
   2315    789      ahrens 	}
   2316    789      ahrens 
   2317    789      ahrens 	pool_list_free(list);
   2318    789      ahrens 
   2319    789      ahrens 	return (ret);
   2320    789      ahrens }
   2321    789      ahrens 
   2322    789      ahrens typedef struct list_cbdata {
   2323   2082    eschrock 	boolean_t	cb_scripted;
   2324   2082    eschrock 	boolean_t	cb_first;
   2325   5094       lling 	zprop_list_t	*cb_proplist;
   2326    789      ahrens } list_cbdata_t;
   2327    789      ahrens 
   2328    789      ahrens /*
   2329    789      ahrens  * Given a list of columns to display, output appropriate headers for each one.
   2330    789      ahrens  */
   2331   5094       lling static void
   2332   5094       lling print_header(zprop_list_t *pl)
   2333    789      ahrens {
   2334   5094       lling 	const char *header;
   2335   5094       lling 	boolean_t first = B_TRUE;
   2336   5094       lling 	boolean_t right_justify;
   2337    789      ahrens 
   2338   5094       lling 	for (; pl != NULL; pl = pl->pl_next) {
   2339   5094       lling 		if (pl->pl_prop == ZPROP_INVAL)
   2340   5094       lling 			continue;
   2341   5094       lling 
   2342   5094       lling 		if (!first)
   2343    789      ahrens 			(void) printf("  ");
   2344    789      ahrens 		else
   2345   5094       lling 			first = B_FALSE;
   2346    789      ahrens 
   2347   5094       lling 		header = zpool_prop_column_name(pl->pl_prop);
   2348   5094       lling 		right_justify = zpool_prop_align_right(pl->pl_prop);
   2349   5094       lling 
   2350   5094       lling 		if (pl->pl_next == NULL && !right_justify)
   2351   5094       lling 			(void) printf("%s", header);
   2352   5094       lling 		else if (right_justify)
   2353   5094       lling 			(void) printf("%*s", pl->pl_width, header);
   2354   5094       lling 		else
   2355   5094       lling 			(void) printf("%-*s", pl->pl_width, header);
   2356    789      ahrens 	}
   2357    789      ahrens 
   2358    789      ahrens 	(void) printf("\n");
   2359    789      ahrens }
   2360    789      ahrens 
   2361   5094       lling /*
   2362   5094       lling  * Given a pool and a list of properties, print out all the properties according
   2363   5094       lling  * to the described layout.
   2364   5094       lling  */
   2365   5094       lling static void
   2366   5094       lling print_pool(zpool_handle_t *zhp, zprop_list_t *pl, int scripted)
   2367   5094       lling {
   2368   5094       lling 	boolean_t first = B_TRUE;
   2369   5094       lling 	char property[ZPOOL_MAXPROPLEN];
   2370   5094       lling 	char *propstr;
   2371   5094       lling 	boolean_t right_justify;
   2372   5094       lling 	int width;
   2373   5094       lling 
   2374   5094       lling 	for (; pl != NULL; pl = pl->pl_next) {
   2375   5094       lling 		if (!first) {
   2376   5094       lling 			if (scripted)
   2377   5094       lling 				(void) printf("\t");
   2378   5094       lling 			else
   2379   5094       lling 				(void) printf("  ");
   2380   5094       lling 		} else {
   2381   5094       lling 			first = B_FALSE;
   2382   5094       lling 		}
   2383   5094       lling 
   2384   5094       lling 		right_justify = B_FALSE;
   2385   5094       lling 		if (pl->pl_prop != ZPROP_INVAL) {
   2386   5094       lling 			if (zpool_get_prop(zhp, pl->pl_prop, property,
   2387   5094       lling 			    sizeof (property), NULL) != 0)
   2388   5094       lling 				propstr = "-";
   2389   5094       lling 			else
   2390   5094       lling 				propstr = property;
   2391   5094       lling 
   2392   5094       lling 			right_justify = zpool_prop_align_right(pl->pl_prop);
   2393   5094       lling 		} else {
   2394   5094       lling 			propstr = "-";
   2395   5094       lling 		}
   2396   5094       lling 
   2397   5094       lling 		width = pl->pl_width;
   2398   5094       lling 
   2399   5094       lling 		/*
   2400   5094       lling 		 * If this is being called in scripted mode, or if this is the
   2401   5094       lling 		 * last column and it is left-justified, don't include a width
   2402   5094       lling 		 * format specifier.
   2403   5094       lling 		 */
   2404   5094       lling 		if (scripted || (pl->pl_next == NULL && !right_justify))
   2405   5094       lling 			(void) printf("%s", propstr);
   2406   5094       lling 		else if (right_justify)
   2407   5094       lling 			(void) printf("%*s", width, propstr);
   2408   5094       lling 		else
   2409   5094       lling 			(void) printf("%-*s", width, propstr);
   2410   5094       lling 	}
   2411   5094       lling 
   2412   5094       lling 	(void) printf("\n");
   2413   5094       lling }
   2414   5094       lling 
   2415   5094       lling /*
   2416   5094       lling  * Generic callback function to list a pool.
   2417   5094       lling  */
   2418    789      ahrens int
   2419    789      ahrens list_callback(zpool_handle_t *zhp, void *data)
   2420    789      ahrens {
   2421    789      ahrens 	list_cbdata_t *cbp = data;
   2422    789      ahrens 
   2423    789      ahrens 	if (cbp->cb_first) {
   2424    789      ahrens 		if (!cbp->cb_scripted)
   2425   5094       lling 			print_header(cbp->cb_proplist);
   2426   2082    eschrock 		cbp->cb_first = B_FALSE;
   2427    789      ahrens 	}
   2428    789      ahrens 
   2429   5094       lling 	print_pool(zhp, cbp->cb_proplist, cbp->cb_scripted);
   2430    789      ahrens 
   2431    789      ahrens 	return (0);
   2432    789      ahrens }
   2433    789      ahrens 
   2434    789      ahrens /*
   2435   5094       lling  * zpool list [-H] [-o prop[,prop]*] [pool] ...
   2436    789      ahrens  *
   2437   5094       lling  *	-H	Scripted mode.  Don't display headers, and separate properties
   2438   5094       lling  *		by a single tab.
   2439   5094       lling  *	-o	List of properties to display.  Defaults to
   2440  10956      George  *		"name,size,allocated,free,capacity,health,altroot"
   2441    789      ahrens  *
   2442    789      ahrens  * List all pools in the system, whether or not they're healthy.  Output space
   2443    789      ahrens  * statistics for each one, as well as health status summary.
   2444    789      ahrens  */
   2445    789      ahrens int
   2446    789      ahrens zpool_do_list(int argc, char **argv)
   2447    789      ahrens {
   2448    789      ahrens 	int c;
   2449    789      ahrens 	int ret;
   2450    789      ahrens 	list_cbdata_t cb = { 0 };
   2451   5094       lling 	static char default_props[] =
   2452  10956      George 	    "name,size,allocated,free,capacity,dedupratio,health,altroot";
   2453   5094       lling 	char *props = default_props;
   2454    789      ahrens 
   2455    789      ahrens 	/* check options */
   2456    789      ahrens 	while ((c = getopt(argc, argv, ":Ho:")) != -1) {
   2457    789      ahrens 		switch (c) {
   2458    789      ahrens 		case 'H':
   2459   2082    eschrock 			cb.cb_scripted = B_TRUE;
   2460    789      ahrens 			break;
   2461    789      ahrens 		case 'o':
   2462   5094       lling 			props = optarg;
   2463    789      ahrens 			break;
   2464    789      ahrens 		case ':':
   2465    789      ahrens 			(void) fprintf(stderr, gettext("missing argument for "
   2466    789      ahrens 			    "'%c' option\n"), optopt);
   2467   2082    eschrock 			usage(B_FALSE);
   2468    789      ahrens 			break;
   2469    789      ahrens 		case '?':
   2470    789      ahrens 			(void) fprintf(stderr, gettext("invalid option '%c'\n"),
   2471    789      ahrens 			    optopt);
   2472   2082    eschrock 			usage(B_FALSE);
   2473    789      ahrens 		}
   2474    789      ahrens 	}
   2475    789      ahrens 
   2476    789      ahrens 	argc -= optind;
   2477    789      ahrens 	argv += optind;
   2478    789      ahrens 
   2479   5094       lling 	if (zprop_get_list(g_zfs, props, &cb.cb_proplist, ZFS_TYPE_POOL) != 0)
   2480   5094       lling 		usage(B_FALSE);
   2481    789      ahrens 
   2482   2082    eschrock 	cb.cb_first = B_TRUE;
   2483    789      ahrens 
   2484   5094       lling 	ret = for_each_pool(argc, argv, B_TRUE, &cb.cb_proplist,
   2485   5094       lling 	    list_callback, &cb);
   2486   5094       lling 
   2487   5094       lling 	zprop_free_list(cb.cb_proplist);
   2488    789      ahrens 
   2489   4221    mmusante 	if (argc == 0 && cb.cb_first && !cb.cb_scripted) {
   2490    789      ahrens 		(void) printf(gettext("no pools available\n"));
   2491    789      ahrens 		return (0);
   2492    789      ahrens 	}
   2493    789      ahrens 
   2494    789      ahrens 	return (ret);
   2495    789      ahrens }
   2496    789      ahrens 
   2497    789      ahrens static nvlist_t *
   2498    789      ahrens zpool_get_vdev_by_name(nvlist_t *nv, char *name)
   2499    789      ahrens {
   2500    789      ahrens 	nvlist_t **child;
   2501    789      ahrens 	uint_t c, children;
   2502    789      ahrens 	nvlist_t *match;
   2503    789      ahrens 	char *path;
   2504    789      ahrens 
   2505    789      ahrens 	if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
   2506    789      ahrens 	    &child, &children) != 0) {
   2507    789      ahrens 		verify(nvlist_lookup_string(nv, ZPOOL_CONFIG_PATH, &path) == 0);
   2508    789      ahrens 		if (strncmp(name, "/dev/dsk/", 9) == 0)
   2509    789      ahrens 			name += 9;
   2510    789      ahrens 		if (strncmp(path, "/dev/dsk/", 9) == 0)
   2511    789      ahrens 			path += 9;
   2512    789      ahrens 		if (strcmp(name, path) == 0)
   2513    789      ahrens 			return (nv);
   2514    789      ahrens 		return (NULL);
   2515    789      ahrens 	}
   2516    789      ahrens 
   2517    789      ahrens 	for (c = 0; c < children; c++)
   2518    789      ahrens 		if ((match = zpool_get_vdev_by_name(child[c], name)) != NULL)
   2519    789      ahrens 			return (match);
   2520    789      ahrens 
   2521    789      ahrens 	return (NULL);
   2522    789      ahrens }
   2523    789      ahrens 
   2524    789      ahrens static int
   2525    789      ahrens zpool_do_attach_or_replace(int argc, char **argv, int replacing)
   2526    789      ahrens {
   2527   2082    eschrock 	boolean_t force = B_FALSE;
   2528    789      ahrens 	int c;
   2529    789      ahrens 	nvlist_t *nvroot;
   2530    789      ahrens 	char *poolname, *old_disk, *new_disk;
   2531    789      ahrens 	zpool_handle_t *zhp;
   2532   2082    eschrock 	int ret;
   2533    789      ahrens 
   2534    789      ahrens 	/* check options */
   2535    789      ahrens 	while ((c = getopt(argc, argv, "f")) != -1) {
   2536    789      ahrens 		switch (c) {
   2537    789      ahrens 		case 'f':
   2538   2082    eschrock 			force = B_TRUE;
   2539    789      ahrens 			break;
   2540    789      ahrens 		case '?':
   2541    789      ahrens 			(void) fprintf(stderr, gettext("invalid option '%c'\n"),
   2542    789      ahrens 			    optopt);
   2543   2082    eschrock 			usage(B_FALSE);
   2544    789      ahrens 		}
   2545    789      ahrens 	}
   2546    789      ahrens 
   2547    789      ahrens 	argc -= optind;
   2548    789      ahrens 	argv += optind;
   2549    789      ahrens 
   2550    789      ahrens 	/* get pool name and check number of arguments */
   2551    789      ahrens 	if (argc < 1) {
   2552    789      ahrens 		(void) fprintf(stderr, gettext("missing pool name argument\n"));
   2553   2082    eschrock 		usage(B_FALSE);
   2554    789      ahrens 	}
   2555    789      ahrens 
   2556    789      ahrens 	poolname = argv[0];
   2557    789      ahrens 
   2558    789      ahrens 	if (argc < 2) {
   2559    789      ahrens 		(void) fprintf(stderr,
   2560    789      ahrens 		    gettext("missing <device> specification\n"));
   2561   2082    eschrock 		usage(B_FALSE);
   2562    789      ahrens 	}
   2563    789      ahrens 
   2564    789      ahrens 	old_disk = argv[1];
   2565    789      ahrens 
   2566    789      ahrens 	if (argc < 3) {
   2567    789      ahrens 		if (!replacing) {
   2568    789      ahrens 			(void) fprintf(stderr,
   2569    789      ahrens 			    gettext("missing <new_device> specification\n"));
   2570   2082    eschrock 			usage(B_FALSE);
   2571    789      ahrens 		}
   2572    789      ahrens 		new_disk = old_disk;
   2573    789      ahrens 		argc -= 1;
   2574    789      ahrens 		argv += 1;
   2575    789      ahrens 	} else {
   2576    789      ahrens 		new_disk = argv[2];
   2577    789      ahrens 		argc -= 2;
   2578    789      ahrens 		argv += 2;
   2579    789      ahrens 	}
   2580    789      ahrens 
   2581    789      ahrens 	if (argc > 1) {
   2582    789      ahrens 		(void) fprintf(stderr, gettext("too many arguments\n"));
   2583   2082    eschrock 		usage(B_FALSE);
   2584    789      ahrens 	}
   2585    789      ahrens 
   2586   2082    eschrock 	if ((zhp = zpool_open(g_zfs, poolname)) == NULL)
   2587    789      ahrens 		return (1);
   2588    789      ahrens 
   2589   4276      taylor 	if (zpool_get_config(zhp, NULL) == NULL) {
   2590    789      ahrens 		(void) fprintf(stderr, gettext("pool '%s' is unavailable\n"),
   2591    789      ahrens 		    poolname);
   2592    789      ahrens 		zpool_close(zhp);
   2593    789      ahrens 		return (1);
   2594    789      ahrens 	}
   2595    789      ahrens 
   2596   7343        Eric 	nvroot = make_root_vdev(zhp, force, B_FALSE, replacing, B_FALSE,
   2597   7343        Eric 	    argc, argv);
   2598    789      ahrens 	if (nvroot == NULL) {
   2599    789      ahrens 		zpool_close(zhp);
   2600    789      ahrens 		return (1);
   2601    789      ahrens 	}
   2602    789      ahrens 
   2603   2082    eschrock 	ret = zpool_vdev_attach(zhp, old_disk, new_disk, nvroot, replacing);
   2604   2082    eschrock 
   2605   2082    eschrock 	nvlist_free(nvroot);
   2606   2082    eschrock 	zpool_close(zhp);
   2607   2082    eschrock 
   2608   2082    eschrock 	return (ret);
   2609    789      ahrens }
   2610    789      ahrens 
   2611    789      ahrens /*
   2612    789      ahrens  * zpool replace [-f] <pool> <device> <new_device>
   2613    789      ahrens  *
   2614    789      ahrens  *	-f	Force attach, even if <new_device> appears to be in use.
   2615    789      ahrens  *
   2616    789      ahrens  * Replace <device> with <new_device>.
   2617    789      ahrens  */
   2618    789      ahrens /* ARGSUSED */
   2619    789      ahrens int
   2620    789      ahrens zpool_do_replace(int argc, char **argv)
   2621    789      ahrens {
   2622    789      ahrens 	return (zpool_do_attach_or_replace(argc, argv, B_TRUE));
   2623    789      ahrens }
   2624    789      ahrens 
   2625    789      ahrens /*
   2626    789      ahrens  * zpool attach [-f] <pool> <device> <new_device>
   2627    789      ahrens  *
   2628    789      ahrens  *	-f	Force attach, even if <new_device> appears to be in use.
   2629    789      ahrens  *
   2630    789      ahrens  * Attach <new_device> to the mirror containing <device>.  If <device> is not
   2631    789      ahrens  * part of a mirror, then <device> will be transformed into a mirror of
   2632    789      ahrens  * <device> and <new_device>.  In either case, <new_device> will begin life
   2633    789      ahrens  * with a DTL of [0, now], and will immediately begin to resilver itself.
   2634    789      ahrens  */
   2635    789      ahrens int
   2636    789      ahrens zpool_do_attach(int argc, char **argv)
   2637    789      ahrens {
   2638    789      ahrens 	return (zpool_do_attach_or_replace(argc, argv, B_FALSE));
   2639    789      ahrens }
   2640    789      ahrens 
   2641    789      ahrens /*
   2642    789      ahrens  * zpool detach [-f] <pool> <device>
   2643    789      ahrens  *
   2644    789      ahrens  *	-f	Force detach of <device>, even if DTLs argue against it
   2645    789      ahrens  *		(not supported yet)
   2646    789      ahrens  *
   2647    789      ahrens  * Detach a device from a mirror.  The operation will be refused if <device>
   2648    789      ahrens  * is the last device in the mirror, or if the DTLs indicate that this device
   2649    789      ahrens  * has the only valid copy of some data.
   2650    789      ahrens  */
   2651    789      ahrens /* ARGSUSED */
   2652    789      ahrens int
   2653    789      ahrens zpool_do_detach(int argc, char **argv)
   2654    789      ahrens {
   2655    789      ahrens 	int c;
   2656    789      ahrens 	char *poolname, *path;
   2657    789      ahrens 	zpool_handle_t *zhp;
   2658   2082    eschrock 	int ret;
   2659    789      ahrens 
   2660    789      ahrens 	/* check options */
   2661    789      ahrens 	while ((c = getopt(argc, argv, "f")) != -1) {
   2662    789      ahrens 		switch (c) {
   2663    789      ahrens 		case 'f':
   2664    789      ahrens 		case '?':
   2665    789      ahrens 			(void) fprintf(stderr, gettext("invalid option '%c'\n"),
   2666    789      ahrens 			    optopt);
   2667   2082    eschrock 			usage(B_FALSE);
   2668    789      ahrens 		}
   2669    789      ahrens 	}
   2670    789      ahrens 
   2671    789      ahrens 	argc -= optind;
   2672    789      ahrens 	argv += optind;
   2673    789      ahrens 
   2674    789      ahrens 	/* get pool name and check number of arguments */
   2675    789      ahrens 	if (argc < 1) {
   2676    789      ahrens 		(void) fprintf(stderr, gettext("missing pool name argument\n"));
   2677   2082    eschrock 		usage(B_FALSE);
   2678    789      ahrens 	}
   2679    789      ahrens 
   2680    789      ahrens 	if (argc < 2) {
   2681    789      ahrens 		(void) fprintf(stderr,
   2682    789      ahrens 		    gettext("missing <device> specification\n"));
   2683   2082    eschrock 		usage(B_FALSE);
   2684    789      ahrens 	}
   2685    789      ahrens 
   2686    789      ahrens 	poolname = argv[0];
   2687    789      ahrens 	path = argv[1];
   2688    789      ahrens 
   2689   2082    eschrock 	if ((zhp = zpool_open(g_zfs, poolname)) == NULL)
   2690    789      ahrens 		return (1);
   2691    789      ahrens 
   2692   2082    eschrock 	ret = zpool_vdev_detach(zhp, path);
   2693   2082    eschrock 
   2694   2082    eschrock 	zpool_close(zhp);
   2695   2082    eschrock 
   2696   2082    eschrock 	return (ret);
   2697    789      ahrens }
   2698    789      ahrens 
   2699    789      ahrens /*
   2700   1485       lling  * zpool online <pool> <device> ...
   2701    789      ahrens  */
   2702    789      ahrens int
   2703    789      ahrens zpool_do_online(int argc, char **argv)
   2704    789      ahrens {
   2705    789      ahrens 	int c, i;
   2706    789      ahrens 	char *poolname;
   2707    789      ahrens 	zpool_handle_t *zhp;
   2708    789      ahrens 	int ret = 0;
   2709   4451    eschrock 	vdev_state_t newstate;
   2710   9816      George 	int flags = 0;
   2711   9816      George 
   2712   9816      George 	/* check options */
   2713   9816      George 	while ((c = getopt(argc, argv, "et")) != -1) {
   2714   9816      George 		switch (c) {
   2715   9816      George 		case 'e':
   2716   9816      George 			flags |= ZFS_ONLINE_EXPAND;
   2717   9816      George 			break;
   2718    789      ahrens 		case 't':
   2719    789      ahrens 		case '?':
   2720    789      ahrens 			(void) fprintf(stderr, gettext("invalid option '%c'\n"),
   2721    789      ahrens 			    optopt);
   2722   2082    eschrock 			usage(B_FALSE);
   2723    789      ahrens 		}
   2724    789      ahrens 	}
   2725    789      ahrens 
   2726    789      ahrens 	argc -= optind;
   2727    789      ahrens 	argv += optind;
   2728    789      ahrens 
   2729    789      ahrens 	/* get pool name and check number of arguments */
   2730    789      ahrens 	if (argc < 1) {
   2731    789      ahrens 		(void) fprintf(stderr, gettext("missing pool name\n"));
   2732   2082    eschrock 		usage(B_FALSE);
   2733    789      ahrens 	}
   2734    789      ahrens 	if (argc < 2) {
   2735    789      ahrens 		(void) fprintf(stderr, gettext("missing device name\n"));
   2736   2082    eschrock 		usage(B_FALSE);
   2737    789      ahrens 	}
   2738    789      ahrens 
   2739    789      ahrens 	poolname = argv[0];
   2740    789      ahrens 
   2741   2082    eschrock 	if ((zhp = zpool_open(g_zfs, poolname)) == NULL)
   2742    789      ahrens 		return (1);
   2743    789      ahrens 
   2744   4451    eschrock 	for (i = 1; i < argc; i++) {
   2745   9816      George 		if (zpool_vdev_online(zhp, argv[i], flags, &newstate) == 0) {
   2746   4451    eschrock 			if (newstate != VDEV_STATE_HEALTHY) {
   2747   4451    eschrock 				(void) printf(gettext("warning: device '%s' "
   2748   4451    eschrock 				    "onlined, but remains in faulted state\n"),
   2749   4451    eschrock 				    argv[i]);
   2750   4451    eschrock 				if (newstate == VDEV_STATE_FAULTED)
   2751   4451    eschrock 					(void) printf(gettext("use 'zpool "
   2752   4451    eschrock 					    "clear' to restore a faulted "
   2753   4451    eschrock 					    "device\n"));
   2754   4451    eschrock 				else
   2755   4451    eschrock 					(void) printf(gettext("use 'zpool "
   2756   4451    eschrock 					    "replace' to replace devices "
   2757   4451    eschrock 					    "that are no longer present\n"));
   2758   4451    eschrock 			}
   2759   4451    eschrock 		} else {
   2760    789      ahrens 			ret = 1;
   2761   4451    eschrock 		}
   2762   4451    eschrock 	}
   2763   2082    eschrock 
   2764   2082    eschrock 	zpool_close(zhp);
   2765    789      ahrens 
   2766    789      ahrens 	return (ret);
   2767    789      ahrens }
   2768    789      ahrens 
   2769    789      ahrens /*
   2770   1485       lling  * zpool offline [-ft] <pool> <device> ...
   2771    789      ahrens  *
   2772    789      ahrens  *	-f	Force the device into the offline state, even if doing
   2773    789      ahrens  *		so would appear to compromise pool availability.
   2774    789      ahrens  *		(not supported yet)
   2775    789      ahrens  *
   2776    789      ahrens  *	-t	Only take the device off-line temporarily.  The offline
   2777    789      ahrens  *		state will not be persistent across reboots.
   2778    789      ahrens  */
   2779    789      ahrens /* ARGSUSED */
   2780    789      ahrens int
   2781    789      ahrens zpool_do_offline(int argc, char **argv)
   2782    789      ahrens {
   2783    789      ahrens 	int c, i;
   2784    789      ahrens 	char *poolname;
   2785    789      ahrens 	zpool_handle_t *zhp;
   2786   2082    eschrock 	int ret = 0;
   2787   2082    eschrock 	boolean_t istmp = B_FALSE;
   2788    789      ahrens 
   2789    789      ahrens 	/* check options */
   2790    789      ahrens 	while ((c = getopt(argc, argv, "ft")) != -1) {
   2791    789      ahrens 		switch (c) {
   2792   1485       lling 		case 't':
   2793   2082    eschrock 			istmp = B_TRUE;
   2794   1485       lling 			break;
   2795    789      ahrens 		case 'f':
   2796    789      ahrens 		case '?':
   2797    789      ahrens 			(void) fprintf(stderr, gettext("invalid option '%c'\n"),
   2798    789      ahrens 			    optopt);
   2799   2082    eschrock 			usage(B_FALSE);
   2800    789      ahrens 		}
   2801    789      ahrens 	}
   2802    789      ahrens 
   2803    789      ahrens 	argc -= optind;
   2804    789      ahrens 	argv += optind;
   2805    789      ahrens 
   2806    789      ahrens 	/* get pool name and check number of arguments */
   2807    789      ahrens 	if (argc < 1) {
   2808    789      ahrens 		(void) fprintf(stderr, gettext("missing pool name\n"));
   2809   2082    eschrock 		usage(B_FALSE);
   2810    789      ahrens 	}
   2811    789      ahrens 	if (argc < 2) {
   2812    789      ahrens 		(void) fprintf(stderr, gettext("missing device name\n"));
   2813   2082    eschrock 		usage(B_FALSE);
   2814    789      ahrens 	}
   2815    789      ahrens 
   2816    789      ahrens 	poolname = argv[0];
   2817    789      ahrens 
   2818   2082    eschrock 	if ((zhp = zpool_open(g_zfs, poolname)) == NULL)
   2819    789      ahrens 		return (1);
   2820    789      ahrens 
   2821   4451    eschrock 	for (i = 1; i < argc; i++) {
   2822   4451    eschrock 		if (zpool_vdev_offline(zhp, argv[i], istmp) != 0)
   2823    789      ahrens 			ret = 1;
   2824   4451    eschrock 	}
   2825   2082    eschrock 
   2826   2082    eschrock 	zpool_close(zhp);
   2827    789      ahrens 
   2828    789      ahrens 	return (ret);
   2829    789      ahrens }
   2830    789      ahrens 
   2831   1544    eschrock /*
   2832   1544    eschrock  * zpool clear <pool> [device]
   2833   1544    eschrock  *
   2834   1544    eschrock  * Clear all errors associated with a pool or a particular device.
   2835   1544    eschrock  */
   2836   1544    eschrock int
   2837   1544    eschrock zpool_do_clear(int argc, char **argv)
   2838   1544    eschrock {
   2839  10921         Tim 	int c;
   2840  10921         Tim 	int ret = 0;
   2841  10921         Tim 	boolean_t dryrun = B_FALSE;
   2842  10921         Tim 	boolean_t do_rewind = B_FALSE;
   2843  10921         Tim 	boolean_t xtreme_rewind = B_FALSE;
   2844  10921         Tim 	uint32_t rewind_policy = ZPOOL_NO_REWIND;
   2845  10921         Tim 	nvlist_t *policy = NULL;
   2846   1544    eschrock 	zpool_handle_t *zhp;
   2847   1544    eschrock 	char *pool, *device;
   2848   1544    eschrock 
   2849  10921         Tim 	/* check options */
   2850  10921         Tim 	while ((c = getopt(argc, argv, "FnX")) != -1) {
   2851  10921         Tim 		switch (c) {
   2852  10921         Tim 		case 'F':
   2853  10921         Tim 			do_rewind = B_TRUE;
   2854  10921         Tim 			break;
   2855  10921         Tim 		case 'n':
   2856  10921         Tim 			dryrun = B_TRUE;
   2857  10921         Tim 			break;
   2858  10921         Tim 		case 'X':
   2859  10921         Tim 			xtreme_rewind = B_TRUE;
   2860  10921         Tim 			break;
   2861  10921         Tim 		case '?':
   2862  10921         Tim 			(void) fprintf(stderr, gettext("invalid option '%c'\n"),
   2863  10921         Tim 			    optopt);
   2864  10921         Tim 			usage(B_FALSE);
   2865  10921         Tim 		}
   2866  10921         Tim 	}
   2867  10921         Tim 
   2868  10921         Tim 	argc -= optind;
   2869  10921         Tim 	argv += optind;
   2870  10921         Tim 
   2871  10921         Tim 	if (argc < 1) {
   2872   1544    eschrock 		(void) fprintf(stderr, gettext("missing pool name\n"));
   2873   2082    eschrock 		usage(B_FALSE);
   2874   1544    eschrock 	}
   2875   1544    eschrock 
   2876  10921         Tim 	if (argc > 2) {
   2877   1544    eschrock 		(void) fprintf(stderr, gettext("too many arguments\n"));
   2878   2082    eschrock 		usage(B_FALSE);
   2879   1544    eschrock 	}
   2880   1544    eschrock 
   2881  10921         Tim 	if ((dryrun || xtreme_rewind) && !do_rewind) {
   2882  10921         Tim 		(void) fprintf(stderr,
   2883  10921         Tim 		    gettext("-n or -X only meaningful with -F\n"));
   2884  10921         Tim 		usage(B_FALSE);
   2885  10921         Tim 	}
   2886  10921         Tim 	if (dryrun)
   2887  10921         Tim 		rewind_policy = ZPOOL_TRY_REWIND;
   2888  10921         Tim 	else if (do_rewind)
   2889  10921         Tim 		rewind_policy = ZPOOL_DO_REWIND;
   2890  10921         Tim 	if (xtreme_rewind)
   2891  10921         Tim 		rewind_policy |= ZPOOL_EXTREME_REWIND;
   2892  10921         Tim 
   2893  10921         Tim 	/* In future, further rewind policy choices can be passed along here */
   2894  10921         Tim 	if (nvlist_alloc(&policy, NV_UNIQUE_NAME, 0) != 0 ||
   2895  10921         Tim 	    nvlist_add_uint32(policy, ZPOOL_REWIND_REQUEST, rewind_policy) != 0)
   2896  10921         Tim 		return (1);
   2897  10921         Tim 
   2898  10921         Tim 	pool = argv[0];
   2899  10921         Tim 	device = argc == 2 ? argv[1] : NULL;
   2900  10921         Tim 
   2901  10921         Tim 	if ((zhp = zpool_open_canfail(g_zfs, pool)) == NULL) {
   2902  10921         Tim 		nvlist_free(policy);
   2903  10921         Tim 		return (1);
   2904  10921         Tim 	}
   2905  10921         Tim 
   2906  10921         Tim 	if (zpool_clear(zhp, device, policy) != 0)
   2907   1544    eschrock 		ret = 1;
   2908   1544    eschrock 
   2909   1544    eschrock 	zpool_close(zhp);
   2910  10921         Tim 
   2911  10921         Tim 	nvlist_free(policy);
   2912   1544    eschrock 
   2913   1544    eschrock 	return (ret);
   2914   1544    eschrock }
   2915   1544    eschrock 
   2916    789      ahrens typedef struct scrub_cbdata {
   2917    789      ahrens 	int	cb_type;
   2918   2926    ek110237 	int	cb_argc;
   2919   2926    ek110237 	char	**cb_argv;
   2920    789      ahrens } scrub_cbdata_t;
   2921    789      ahrens 
   2922    789      ahrens int
   2923    789      ahrens scrub_callback(zpool_handle_t *zhp, void *data)
   2924    789      ahrens {
   2925    789      ahrens 	scrub_cbdata_t *cb = data;
   2926   2926    ek110237 	int err;
   2927   1544    eschrock 
   2928   1544    eschrock 	/*
   2929   1544    eschrock 	 * Ignore faulted pools.
   2930   1544    eschrock 	 */
   2931   1544    eschrock 	if (zpool_get_state(zhp) == POOL_STATE_UNAVAIL) {
   2932   1544    eschrock 		(void) fprintf(stderr, gettext("cannot scrub '%s': pool is "
   2933   1544    eschrock 		    "currently unavailable\n"), zpool_get_name(zhp));
   2934   1544    eschrock 		return (1);
   2935   1544    eschrock 	}
   2936    789      ahrens 
   2937   2926    ek110237 	err = zpool_scrub(zhp, cb->cb_type);
   2938   2926    ek110237 
   2939   2926    ek110237 	return (err != 0);
   2940    789      ahrens }
   2941    789      ahrens 
   2942    789      ahrens /*
   2943    789      ahrens  * zpool scrub [-s] <pool> ...
   2944    789      ahrens  *
   2945    789      ahrens  *	-s	Stop.  Stops any in-progress scrub.
   2946    789      ahrens  */
   2947    789      ahrens int
   2948    789      ahrens zpool_do_scrub(int argc, char **argv)
   2949    789      ahrens {
   2950    789      ahrens 	int c;
   2951    789      ahrens 	scrub_cbdata_t cb;
   2952    789      ahrens 
   2953    789      ahrens 	cb.cb_type = POOL_SCRUB_EVERYTHING;
   2954    789      ahrens 
   2955    789      ahrens 	/* check options */
   2956    789      ahrens 	while ((c = getopt(argc, argv, "s")) != -1) {
   2957    789      ahrens 		switch (c) {
   2958    789      ahrens 		case 's':
   2959    789      ahrens 			cb.cb_type = POOL_SCRUB_NONE;
   2960    789      ahrens 			break;
   2961    789      ahrens 		case '?':
   2962    789      ahrens 			(void) fprintf(stderr, gettext("invalid option '%c'\n"),
   2963    789      ahrens 			    optopt);
   2964   2082    eschrock 			usage(B_FALSE);
   2965    789      ahrens 		}
   2966    789      ahrens 	}
   2967    789      ahrens 
   2968   2926    ek110237 	cb.cb_argc = argc;
   2969   2926    ek110237 	cb.cb_argv = argv;
   2970    789      ahrens 	argc -= optind;
   2971    789      ahrens 	argv += optind;
   2972    789      ahrens 
   2973    789      ahrens 	if (argc < 1) {
   2974    789      ahrens 		(void) fprintf(stderr, gettext("missing pool name argument\n"));
   2975   2082    eschrock 		usage(B_FALSE);
   2976    789      ahrens 	}
   2977    789      ahrens 
   2978   3912       lling 	return (for_each_pool(argc, argv, B_TRUE, NULL, scrub_callback, &cb));
   2979    789      ahrens }
   2980    789      ahrens 
   2981    789      ahrens typedef struct status_cbdata {
   2982   2082    eschrock 	int		cb_count;
   2983   2676    eschrock 	boolean_t	cb_allpools;
   2984   2082    eschrock 	boolean_t	cb_verbose;
   2985   2082    eschrock 	boolean_t	cb_explain;
   2986   2082    eschrock 	boolean_t	cb_first;
   2987  11149      George 	boolean_t	cb_dedup_stats;
   2988    789      ahrens } status_cbdata_t;
   2989    789      ahrens 
   2990    789      ahrens /*
   2991    789      ahrens  * Print out detailed scrub status.
   2992    789      ahrens  */
   2993    789      ahrens void
   2994    789      ahrens print_scrub_status(nvlist_t *nvroot)
   2995    789      ahrens {
   2996    789      ahrens 	vdev_stat_t *vs;
   2997    789      ahrens 	uint_t vsc;
   2998    789      ahrens 	time_t start, end, now;
   2999    789      ahrens 	double fraction_done;
   3000   5853    ek110237 	uint64_t examined, total, minutes_left, minutes_taken;
   3001    789      ahrens 	char *scrub_type;
   3002    789      ahrens 
   3003    789      ahrens 	verify(nvlist_lookup_uint64_array(nvroot, ZPOOL_CONFIG_STATS,
   3004    789      ahrens 	    (uint64_t **)&vs, &vsc) == 0);
   3005    789      ahrens 
   3006    789      ahrens 	/*
   3007    789      ahrens 	 * If there's never been a scrub, there's not much to say.
   3008    789      ahrens 	 */
   3009    789      ahrens 	if (vs->vs_scrub_end == 0 && vs->vs_scrub_type == POOL_SCRUB_NONE) {
   3010    789      ahrens 		(void) printf(gettext("none requested\n"));
   3011    789      ahrens 		return;
   3012    789      ahrens 	}
   3013    789      ahrens 
   3014    789      ahrens 	scrub_type = (vs->vs_scrub_type == POOL_SCRUB_RESILVER) ?
   3015    789      ahrens 	    "resilver" : "scrub";
   3016    789      ahrens 
   3017    789      ahrens 	start = vs->vs_scrub_start;
   3018    789      ahrens 	end = vs->vs_scrub_end;
   3019    789      ahrens 	now = time(NULL);
   3020    789      ahrens 	examined = vs->vs_scrub_examined;
   3021    789      ahrens 	total = vs->vs_alloc;
   3022    789      ahrens 
   3023    789      ahrens 	if (end != 0) {
   3024   5853    ek110237 		minutes_taken = (uint64_t)((end - start) / 60);
   3025   5853    ek110237 
   3026   5853    ek110237 		(void) printf(gettext("%s %s after %lluh%um with %llu errors "
   3027   5853    ek110237 		    "on %s"),
   3028    789      ahrens 		    scrub_type, vs->vs_scrub_complete ? "completed" : "stopped",
   3029   5853    ek110237 		    (u_longlong_t)(minutes_taken / 60),
   3030   5853    ek110237 		    (uint_t)(minutes_taken % 60),
   3031    789      ahrens 		    (u_longlong_t)vs->vs_scrub_errors, ctime(&end));
   3032    789      ahrens 		return;
   3033    789      ahrens 	}
   3034    789      ahrens 
   3035    789      ahrens 	if (examined == 0)
   3036    789      ahrens 		examined = 1;
   3037    789      ahrens 	if (examined > total)
   3038    789      ahrens 		total = examined;
   3039    789      ahrens 
   3040    789      ahrens 	fraction_done = (double)examined / total;
   3041    789      ahrens 	minutes_left = (uint64_t)((now - start) *
   3042    789      ahrens 	    (1 - fraction_done) / fraction_done / 60);
   3043   5853    ek110237 	minutes_taken = (uint64_t)((now - start) / 60);
   3044    789      ahrens 
   3045   5853    ek110237 	(void) printf(gettext("%s in progress for %lluh%um, %.2f%% done, "
   3046   5853    ek110237 	    "%lluh%um to go\n"),
   3047   5853    ek110237 	    scrub_type, (u_longlong_t)(minutes_taken / 60),
   3048   5853    ek110237 	    (uint_t)(minutes_taken % 60), 100 * fraction_done,
   3049    789      ahrens 	    (u_longlong_t)(minutes_left / 60), (uint_t)(minutes_left % 60));
   3050    789      ahrens }
   3051    789      ahrens 
   3052   1544    eschrock static void
   3053   1544    eschrock print_error_log(zpool_handle_t *zhp)
   3054   1544    eschrock {
   3055   4820    ek110237 	nvlist_t *nverrlist = NULL;
   3056   3444    ek110237 	nvpair_t *elem;
   3057   3444    ek110237 	char *pathname;
   3058   3444    ek110237 	size_t len = MAXPATHLEN * 2;
   3059   1544    eschrock 
   3060   3444    ek110237 	if (zpool_get_errlog(zhp, &nverrlist) != 0) {
   3061   1544    eschrock 		(void) printf("errors: List of errors unavailable "
   3062   1544    eschrock 		    "(insufficient privileges)\n");
   3063   1544    eschrock 		return;
   3064   1544    eschrock 	}
   3065   1544    eschrock 
   3066   3444    ek110237 	(void) printf("errors: Permanent errors have been "
   3067   3444    ek110237 	    "detected in the following files:\n\n");
   3068   1544    eschrock 
   3069   3444    ek110237 	pathname = safe_malloc(len);
   3070   3444    ek110237 	elem = NULL;
   3071   3444    ek110237 	while ((elem = nvlist_next_nvpair(nverrlist, elem)) != NULL) {
   3072   3444    ek110237 		nvlist_t *nv;
   3073   3444    ek110237 		uint64_t dsobj, obj;
   3074   1544    eschrock 
   3075   3444    ek110237 		verify(nvpair_value_nvlist(elem, &nv) == 0);
   3076   3444    ek110237 		verify(nvlist_lookup_uint64(nv, ZPOOL_ERR_DATASET,
   3077   3444    ek110237 		    &dsobj) == 0);
   3078   3444    ek110237 		verify(nvlist_lookup_uint64(nv, ZPOOL_ERR_OBJECT,
   3079   3444    ek110237 		    &obj) == 0);
   3080   3444    ek110237 		zpool_obj_to_path(zhp, dsobj, obj, pathname, len);
   3081   3444    ek110237 		(void) printf("%7s %s\n", "", pathname);
   3082   1544    eschrock 	}
   3083   3444    ek110237 	free(pathname);
   3084   3444    ek110237 	nvlist_free(nverrlist);
   3085   1544    eschrock }
   3086   1544    eschrock 
   3087   2082    eschrock static void
   3088   2082    eschrock print_spares(zpool_handle_t *zhp, nvlist_t **spares, uint_t nspares,
   3089   2082    eschrock     int namewidth)
   3090   2082    eschrock {
   3091   2082    eschrock 	uint_t i;
   3092   2082    eschrock 	char *name;
   3093   2082    eschrock 
   3094   2082    eschrock 	if (nspares == 0)
   3095   2082    eschrock 		return;
   3096   2082    eschrock 
   3097   2082    eschrock 	(void) printf(gettext("\tspares\n"));
   3098   2082    eschrock 
   3099   2082    eschrock 	for (i = 0; i < nspares; i++) {
   3100  10594      George 		name = zpool_vdev_name(g_zfs, zhp, spares[i], B_FALSE);
   3101   2082    eschrock 		print_status_config(zhp, name, spares[i],
   3102   9391