Home | History | Annotate | Download | only in common
      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 <ctype.h>
     28    789    ahrens #include <errno.h>
     29    789    ahrens #include <devid.h>
     30    789    ahrens #include <fcntl.h>
     31    789    ahrens #include <libintl.h>
     32    789    ahrens #include <stdio.h>
     33    789    ahrens #include <stdlib.h>
     34   3126       ahl #include <strings.h>
     35    789    ahrens #include <unistd.h>
     36   4276    taylor #include <sys/efi_partition.h>
     37   4276    taylor #include <sys/vtoc.h>
     38    789    ahrens #include <sys/zfs_ioctl.h>
     39   9816    George #include <dlfcn.h>
     40    789    ahrens 
     41    789    ahrens #include "zfs_namecheck.h"
     42   3912     lling #include "zfs_prop.h"
     43    789    ahrens #include "libzfs_impl.h"
     44  10921       Tim #include "zfs_comutil.h"
     45  10685    George 
     46  10685    George const char *hist_event_table[LOG_END] = {
     47  10685    George 	"invalid event",
     48  10685    George 	"pool create",
     49  10685    George 	"vdev add",
     50  10685    George 	"pool remove",
     51  10685    George 	"pool destroy",
     52  10685    George 	"pool export",
     53  10685    George 	"pool import",
     54  10685    George 	"vdev attach",
     55  10685    George 	"vdev replace",
     56  10685    George 	"vdev detach",
     57  10685    George 	"vdev online",
     58  10685    George 	"vdev offline",
     59  10685    George 	"vdev upgrade",
     60  10685    George 	"pool clear",
     61  10685    George 	"pool scrub",
     62  10685    George 	"pool property set",
     63  10685    George 	"create",
     64  10685    George 	"clone",
     65  10685    George 	"destroy",
     66  10685    George 	"destroy_begin_sync",
     67  10685    George 	"inherit",
     68  10685    George 	"property set",
     69  10685    George 	"quota set",
     70  10685    George 	"permission update",
     71  10685    George 	"permission remove",
     72  10685    George 	"permission who remove",
     73  10685    George 	"promote",
     74  10685    George 	"receive",
     75  10685    George 	"rename",
     76  10685    George 	"reservation set",
     77  10685    George 	"replay_inc_sync",
     78  10685    George 	"replay_full_sync",
     79  10685    George 	"rollback",
     80  10685    George 	"snapshot",
     81  10685    George 	"filesystem version upgrade",
     82  10685    George 	"refquota set",
     83  10685    George 	"refreservation set",
     84  10685    George 	"pool scrub done",
     85  10685    George 	"user hold",
     86  10685    George 	"user release",
     87  10685    George };
     88   5094     lling 
     89   7042   gw25295 static int read_efi_label(nvlist_t *config, diskaddr_t *sb);
     90   7965    George 
     91   7965    George #if defined(__i386) || defined(__amd64)
     92   7965    George #define	BOOTCMD	"installgrub(1M)"
     93   7965    George #else
     94   7965    George #define	BOOTCMD	"installboot(1M)"
     95   7965    George #endif
     96   9816    George 
     97   9816    George #define	DISK_ROOT	"/dev/dsk"
     98   9816    George #define	RDISK_ROOT	"/dev/rdsk"
     99   9816    George #define	BACKUP_SLICE	"s2"
    100   5094     lling 
    101   5094     lling /*
    102   5094     lling  * ====================================================================
    103   5094     lling  *   zpool property functions
    104   5094     lling  * ====================================================================
    105   5094     lling  */
    106   5094     lling 
    107   5094     lling static int
    108   5094     lling zpool_get_all_props(zpool_handle_t *zhp)
    109   5094     lling {
    110   5094     lling 	zfs_cmd_t zc = { 0 };
    111   5094     lling 	libzfs_handle_t *hdl = zhp->zpool_hdl;
    112   5094     lling 
    113   5094     lling 	(void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
    114   5094     lling 
    115   5094     lling 	if (zcmd_alloc_dst_nvlist(hdl, &zc, 0) != 0)
    116   5094     lling 		return (-1);
    117   5094     lling 
    118   5094     lling 	while (ioctl(hdl->libzfs_fd, ZFS_IOC_POOL_GET_PROPS, &zc) != 0) {
    119   5094     lling 		if (errno == ENOMEM) {
    120   5094     lling 			if (zcmd_expand_dst_nvlist(hdl, &zc) != 0) {
    121   5094     lling 				zcmd_free_nvlists(&zc);
    122   5094     lling 				return (-1);
    123   5094     lling 			}
    124   5094     lling 		} else {
    125   5094     lling 			zcmd_free_nvlists(&zc);
    126   5094     lling 			return (-1);
    127   5094     lling 		}
    128   5094     lling 	}
    129   5094     lling 
    130   5094     lling 	if (zcmd_read_dst_nvlist(hdl, &zc, &zhp->zpool_props) != 0) {
    131   5094     lling 		zcmd_free_nvlists(&zc);
    132   5094     lling 		return (-1);
    133   5094     lling 	}
    134   5094     lling 
    135   5094     lling 	zcmd_free_nvlists(&zc);
    136   5094     lling 
    137   5094     lling 	return (0);
    138   5094     lling }
    139   5094     lling 
    140   5094     lling static int
    141   5094     lling zpool_props_refresh(zpool_handle_t *zhp)
    142   5094     lling {
    143   5094     lling 	nvlist_t *old_props;
    144   5094     lling 
    145   5094     lling 	old_props = zhp->zpool_props;
    146   5094     lling 
    147   5094     lling 	if (zpool_get_all_props(zhp) != 0)
    148   5094     lling 		return (-1);
    149   5094     lling 
    150   5094     lling 	nvlist_free(old_props);
    151   5094     lling 	return (0);
    152   5094     lling }
    153   5094     lling 
    154   5094     lling static char *
    155   5094     lling zpool_get_prop_string(zpool_handle_t *zhp, zpool_prop_t prop,
    156   5094     lling     zprop_source_t *src)
    157   5094     lling {
    158   5094     lling 	nvlist_t *nv, *nvl;
    159   5094     lling 	uint64_t ival;
    160   5094     lling 	char *value;
    161   5094     lling 	zprop_source_t source;
    162   5094     lling 
    163   5094     lling 	nvl = zhp->zpool_props;
    164   5094     lling 	if (nvlist_lookup_nvlist(nvl, zpool_prop_to_name(prop), &nv) == 0) {
    165   5094     lling 		verify(nvlist_lookup_uint64(nv, ZPROP_SOURCE, &ival) == 0);
    166   5094     lling 		source = ival;
    167   5094     lling 		verify(nvlist_lookup_string(nv, ZPROP_VALUE, &value) == 0);
    168   5094     lling 	} else {
    169   5094     lling 		source = ZPROP_SRC_DEFAULT;
    170   5094     lling 		if ((value = (char *)zpool_prop_default_string(prop)) == NULL)
    171   5094     lling 			value = "-";
    172   5094     lling 	}
    173   5094     lling 
    174   5094     lling 	if (src)
    175   5094     lling 		*src = source;
    176   5094     lling 
    177   5094     lling 	return (value);
    178   5094     lling }
    179   5094     lling 
    180   5094     lling uint64_t
    181   5094     lling zpool_get_prop_int(zpool_handle_t *zhp, zpool_prop_t prop, zprop_source_t *src)
    182   5094     lling {
    183   5094     lling 	nvlist_t *nv, *nvl;
    184   5094     lling 	uint64_t value;
    185   5094     lling 	zprop_source_t source;
    186   5094     lling 
    187   7294    perrin 	if (zhp->zpool_props == NULL && zpool_get_all_props(zhp)) {
    188   7294    perrin 		/*
    189   7294    perrin 		 * zpool_get_all_props() has most likely failed because
    190   7294    perrin 		 * the pool is faulted, but if all we need is the top level
    191   7294    perrin 		 * vdev's guid then get it from the zhp config nvlist.
    192   7294    perrin 		 */
    193   7294    perrin 		if ((prop == ZPOOL_PROP_GUID) &&
    194   7294    perrin 		    (nvlist_lookup_nvlist(zhp->zpool_config,
    195   7294    perrin 		    ZPOOL_CONFIG_VDEV_TREE, &nv) == 0) &&
    196   7294    perrin 		    (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_GUID, &value)
    197   7294    perrin 		    == 0)) {
    198   7294    perrin 			return (value);
    199   7294    perrin 		}
    200   5094     lling 		return (zpool_prop_default_numeric(prop));
    201   7294    perrin 	}
    202   5094     lling 
    203   5094     lling 	nvl = zhp->zpool_props;
    204   5094     lling 	if (nvlist_lookup_nvlist(nvl, zpool_prop_to_name(prop), &nv) == 0) {
    205   5094     lling 		verify(nvlist_lookup_uint64(nv, ZPROP_SOURCE, &value) == 0);
    206   5094     lling 		source = value;
    207   5094     lling 		verify(nvlist_lookup_uint64(nv, ZPROP_VALUE, &value) == 0);
    208   5094     lling 	} else {
    209   5094     lling 		source = ZPROP_SRC_DEFAULT;
    210   5094     lling 		value = zpool_prop_default_numeric(prop);
    211   5094     lling 	}
    212   5094     lling 
    213   5094     lling 	if (src)
    214   5094     lling 		*src = source;
    215   5094     lling 
    216   5094     lling 	return (value);
    217   5094     lling }
    218   5094     lling 
    219   5094     lling /*
    220   5094     lling  * Map VDEV STATE to printed strings.
    221   5094     lling  */
    222   5094     lling char *
    223   5094     lling zpool_state_to_name(vdev_state_t state, vdev_aux_t aux)
    224   5094     lling {
    225   5094     lling 	switch (state) {
    226   5094     lling 	case VDEV_STATE_CLOSED:
    227   5094     lling 	case VDEV_STATE_OFFLINE:
    228   5094     lling 		return (gettext("OFFLINE"));
    229   5094     lling 	case VDEV_STATE_REMOVED:
    230   5094     lling 		return (gettext("REMOVED"));
    231   5094     lling 	case VDEV_STATE_CANT_OPEN:
    232   7294    perrin 		if (aux == VDEV_AUX_CORRUPT_DATA || aux == VDEV_AUX_BAD_LOG)
    233   5094     lling 			return (gettext("FAULTED"));
    234   5094     lling 		else
    235   5094     lling 			return (gettext("UNAVAIL"));
    236   5094     lling 	case VDEV_STATE_FAULTED:
    237   5094     lling 		return (gettext("FAULTED"));
    238   5094     lling 	case VDEV_STATE_DEGRADED:
    239   5094     lling 		return (gettext("DEGRADED"));
    240   5094     lling 	case VDEV_STATE_HEALTHY:
    241   5094     lling 		return (gettext("ONLINE"));
    242   5094     lling 	}
    243   5094     lling 
    244   5094     lling 	return (gettext("UNKNOWN"));
    245   5094     lling }
    246   5094     lling 
    247   5094     lling /*
    248   5094     lling  * Get a zpool property value for 'prop' and return the value in
    249   5094     lling  * a pre-allocated buffer.
    250   5094     lling  */
    251   5094     lling int
    252   5094     lling zpool_get_prop(zpool_handle_t *zhp, zpool_prop_t prop, char *buf, size_t len,
    253   5094     lling     zprop_source_t *srctype)
    254   5094     lling {
    255   5094     lling 	uint64_t intval;
    256   5094     lling 	const char *strval;
    257   5094     lling 	zprop_source_t src = ZPROP_SRC_NONE;
    258   5094     lling 	nvlist_t *nvroot;
    259   5094     lling 	vdev_stat_t *vs;
    260   5094     lling 	uint_t vsc;
    261   5094     lling 
    262   5094     lling 	if (zpool_get_state(zhp) == POOL_STATE_UNAVAIL) {
    263   8525      Eric 		switch (prop) {
    264   8525      Eric 		case ZPOOL_PROP_NAME:
    265   5094     lling 			(void) strlcpy(buf, zpool_get_name(zhp), len);
    266   8525      Eric 			break;
    267   8525      Eric 
    268   8525      Eric 		case ZPOOL_PROP_HEALTH:
    269   5094     lling 			(void) strlcpy(buf, "FAULTED", len);
    270   8525      Eric 			break;
    271   8525      Eric 
    272   8525      Eric 		case ZPOOL_PROP_GUID:
    273   8525      Eric 			intval = zpool_get_prop_int(zhp, prop, &src);
    274   8525      Eric 			(void) snprintf(buf, len, "%llu", intval);
    275   8525      Eric 			break;
    276   8525      Eric 
    277   8525      Eric 		case ZPOOL_PROP_ALTROOT:
    278   8525      Eric 		case ZPOOL_PROP_CACHEFILE:
    279   8525      Eric 			if (zhp->zpool_props != NULL ||
    280   8525      Eric 			    zpool_get_all_props(zhp) == 0) {
    281   8525      Eric 				(void) strlcpy(buf,
    282   8525      Eric 				    zpool_get_prop_string(zhp, prop, &src),
    283   8525      Eric 				    len);
    284   8525      Eric 				if (srctype != NULL)
    285   8525      Eric 					*srctype = src;
    286   8525      Eric 				return (0);
    287   8525      Eric 			}
    288   8525      Eric 			/* FALLTHROUGH */
    289   8525      Eric 		default:
    290   5094     lling 			(void) strlcpy(buf, "-", len);
    291   8525      Eric 			break;
    292   8525      Eric 		}
    293   8525      Eric 
    294   8525      Eric 		if (srctype != NULL)
    295   8525      Eric 			*srctype = src;
    296   5094     lling 		return (0);
    297   5094     lling 	}
    298   5094     lling 
    299   5094     lling 	if (zhp->zpool_props == NULL && zpool_get_all_props(zhp) &&
    300   5094     lling 	    prop != ZPOOL_PROP_NAME)
    301   5094     lling 		return (-1);
    302   5094     lling 
    303   5094     lling 	switch (zpool_prop_get_type(prop)) {
    304   5094     lling 	case PROP_TYPE_STRING:
    305   5094     lling 		(void) strlcpy(buf, zpool_get_prop_string(zhp, prop, &src),
    306   5094     lling 		    len);
    307   5094     lling 		break;
    308   5094     lling 
    309   5094     lling 	case PROP_TYPE_NUMBER:
    310   5094     lling 		intval = zpool_get_prop_int(zhp, prop, &src);
    311   5094     lling 
    312   5094     lling 		switch (prop) {
    313   5094     lling 		case ZPOOL_PROP_SIZE:
    314  10956    George 		case ZPOOL_PROP_ALLOCATED:
    315  10956    George 		case ZPOOL_PROP_FREE:
    316   5094     lling 			(void) zfs_nicenum(intval, buf, len);
    317   5094     lling 			break;
    318   5094     lling 
    319   5094     lling 		case ZPOOL_PROP_CAPACITY:
    320   5094     lling 			(void) snprintf(buf, len, "%llu%%",
    321   5094     lling 			    (u_longlong_t)intval);
    322  10922      Jeff 			break;
    323  10922      Jeff 
    324  10922      Jeff 		case ZPOOL_PROP_DEDUPRATIO:
    325  10922      Jeff 			(void) snprintf(buf, len, "%llu.%02llux",
    326  10922      Jeff 			    (u_longlong_t)(intval / 100),
    327  10922      Jeff 			    (u_longlong_t)(intval % 100));
    328   5094     lling 			break;
    329   5094     lling 
    330   5094     lling 		case ZPOOL_PROP_HEALTH:
    331   5094     lling 			verify(nvlist_lookup_nvlist(zpool_get_config(zhp, NULL),
    332   5094     lling 			    ZPOOL_CONFIG_VDEV_TREE, &nvroot) == 0);
    333   5094     lling 			verify(nvlist_lookup_uint64_array(nvroot,
    334   5094     lling 			    ZPOOL_CONFIG_STATS, (uint64_t **)&vs, &vsc) == 0);
    335   5094     lling 
    336   5094     lling 			(void) strlcpy(buf, zpool_state_to_name(intval,
    337   5094     lling 			    vs->vs_aux), len);
    338   5094     lling 			break;
    339   5094     lling 		default:
    340   5094     lling 			(void) snprintf(buf, len, "%llu", intval);
    341   5094     lling 		}
    342   5094     lling 		break;
    343   5094     lling 
    344   5094     lling 	case PROP_TYPE_INDEX:
    345   5094     lling 		intval = zpool_get_prop_int(zhp, prop, &src);
    346   5094     lling 		if (zpool_prop_index_to_string(prop, intval, &strval)
    347   5094     lling 		    != 0)
    348   5094     lling 			return (-1);
    349   5094     lling 		(void) strlcpy(buf, strval, len);
    350   5094     lling 		break;
    351   5094     lling 
    352   5094     lling 	default:
    353   5094     lling 		abort();
    354   5094     lling 	}
    355   5094     lling 
    356   5094     lling 	if (srctype)
    357   5094     lling 		*srctype = src;
    358   5094     lling 
    359   5094     lling 	return (0);
    360   5094     lling }
    361   5094     lling 
    362   5094     lling /*
    363   5094     lling  * Check if the bootfs name has the same pool name as it is set to.
    364   5094     lling  * Assuming bootfs is a valid dataset name.
    365   5094     lling  */
    366   5094     lling static boolean_t
    367   5094     lling bootfs_name_valid(const char *pool, char *bootfs)
    368   5094     lling {
    369   5094     lling 	int len = strlen(pool);
    370   5094     lling 
    371   7300      Eric 	if (!zfs_name_valid(bootfs, ZFS_TYPE_FILESYSTEM|ZFS_TYPE_SNAPSHOT))
    372   5094     lling 		return (B_FALSE);
    373   5094     lling 
    374   5094     lling 	if (strncmp(pool, bootfs, len) == 0 &&
    375   5094     lling 	    (bootfs[len] == '/' || bootfs[len] == '\0'))
    376   5094     lling 		return (B_TRUE);
    377   5094     lling 
    378   5094     lling 	return (B_FALSE);
    379   5094     lling }
    380   5094     lling 
    381   5094     lling /*
    382   7042   gw25295  * Inspect the configuration to determine if any of the devices contain
    383   7042   gw25295  * an EFI label.
    384   7042   gw25295  */
    385   7042   gw25295 static boolean_t
    386   7042   gw25295 pool_uses_efi(nvlist_t *config)
    387   7042   gw25295 {
    388   7042   gw25295 	nvlist_t **child;
    389   7042   gw25295 	uint_t c, children;
    390   7042   gw25295 
    391   7042   gw25295 	if (nvlist_lookup_nvlist_array(config, ZPOOL_CONFIG_CHILDREN,
    392   7042   gw25295 	    &child, &children) != 0)
    393   7042   gw25295 		return (read_efi_label(config, NULL) >= 0);
    394   7042   gw25295 
    395   7042   gw25295 	for (c = 0; c < children; c++) {
    396   7042   gw25295 		if (pool_uses_efi(child[c]))
    397   7042   gw25295 			return (B_TRUE);
    398   7042   gw25295 	}
    399   7042   gw25295 	return (B_FALSE);
    400   7042   gw25295 }
    401   7042   gw25295 
    402   7965    George static boolean_t
    403   7965    George pool_is_bootable(zpool_handle_t *zhp)
    404   7965    George {
    405   7965    George 	char bootfs[ZPOOL_MAXNAMELEN];
    406   7965    George 
    407   7965    George 	return (zpool_get_prop(zhp, ZPOOL_PROP_BOOTFS, bootfs,
    408   7965    George 	    sizeof (bootfs), NULL) == 0 && strncmp(bootfs, "-",
    409   7965    George 	    sizeof (bootfs)) != 0);
    410   7965    George }
    411   7965    George 
    412   7965    George 
    413   7042   gw25295 /*
    414   5094     lling  * Given an nvlist of zpool properties to be set, validate that they are
    415   5094     lling  * correct, and parse any numeric properties (index, boolean, etc) if they are
    416   5094     lling  * specified as strings.
    417   5094     lling  */
    418   5094     lling static nvlist_t *
    419   7184      timh zpool_valid_proplist(libzfs_handle_t *hdl, const char *poolname,
    420   5094     lling     nvlist_t *props, uint64_t version, boolean_t create_or_import, char *errbuf)
    421   5094     lling {
    422   5094     lling 	nvpair_t *elem;
    423   5094     lling 	nvlist_t *retprops;
    424   5094     lling 	zpool_prop_t prop;
    425   5094     lling 	char *strval;
    426   5094     lling 	uint64_t intval;
    427   5363  eschrock 	char *slash;
    428   5363  eschrock 	struct stat64 statbuf;
    429   7042   gw25295 	zpool_handle_t *zhp;
    430   7042   gw25295 	nvlist_t *nvroot;
    431   5094     lling 
    432   5094     lling 	if (nvlist_alloc(&retprops, NV_UNIQUE_NAME, 0) != 0) {
    433   5094     lling 		(void) no_memory(hdl);
    434   5094     lling 		return (NULL);
    435   5094     lling 	}
    436   5094     lling 
    437   5094     lling 	elem = NULL;
    438   5094     lling 	while ((elem = nvlist_next_nvpair(props, elem)) != NULL) {
    439   5094     lling 		const char *propname = nvpair_name(elem);
    440   5094     lling 
    441   5094     lling 		/*
    442   5094     lling 		 * Make sure this property is valid and applies to this type.
    443   5094     lling 		 */
    444   5094     lling 		if ((prop = zpool_name_to_prop(propname)) == ZPROP_INVAL) {
    445   5094     lling 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
    446   5094     lling 			    "invalid property '%s'"), propname);
    447   5094     lling 			(void) zfs_error(hdl, EZFS_BADPROP, errbuf);
    448   5094     lling 			goto error;
    449   5094     lling 		}
    450   5094     lling 
    451   5094     lling 		if (zpool_prop_readonly(prop)) {
    452   5094     lling 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "'%s' "
    453   5094     lling 			    "is readonly"), propname);
    454   5094     lling 			(void) zfs_error(hdl, EZFS_PROPREADONLY, errbuf);
    455   5094     lling 			goto error;
    456   5094     lling 		}
    457   5094     lling 
    458   5094     lling 		if (zprop_parse_value(hdl, elem, prop, ZFS_TYPE_POOL, retprops,
    459   5094     lling 		    &strval, &intval, errbuf) != 0)
    460   5094     lling 			goto error;
    461   5094     lling 
    462   5094     lling 		/*
    463   5094     lling 		 * Perform additional checking for specific properties.
    464   5094     lling 		 */
    465   5094     lling 		switch (prop) {
    466   5094     lling 		case ZPOOL_PROP_VERSION:
    467   5094     lling 			if (intval < version || intval > SPA_VERSION) {
    468   5094     lling 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
    469   5094     lling 				    "property '%s' number %d is invalid."),
    470   5094     lling 				    propname, intval);
    471   5094     lling 				(void) zfs_error(hdl, EZFS_BADVERSION, errbuf);
    472   5094     lling 				goto error;
    473   5094     lling 			}
    474   5094     lling 			break;
    475   5094     lling 
    476   5094     lling 		case ZPOOL_PROP_BOOTFS:
    477   5094     lling 			if (create_or_import) {
    478   5094     lling 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
    479   5094     lling 				    "property '%s' cannot be set at creation "
    480   5094     lling 				    "or import time"), propname);
    481   5094     lling 				(void) zfs_error(hdl, EZFS_BADPROP, errbuf);
    482   5094     lling 				goto error;
    483   5094     lling 			}
    484   5094     lling 
    485   5094     lling 			if (version < SPA_VERSION_BOOTFS) {
    486   5094     lling 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
    487   5094     lling 				    "pool must be upgraded to support "
    488   5094     lling 				    "'%s' property"), propname);
    489   5094     lling 				(void) zfs_error(hdl, EZFS_BADVERSION, errbuf);
    490   5094     lling 				goto error;
    491   5094     lling 			}
    492   5094     lling 
    493   5094     lling 			/*
    494   5094     lling 			 * bootfs property value has to be a dataset name and
    495   5094     lling 			 * the dataset has to be in the same pool as it sets to.
    496   5094     lling 			 */
    497   5094     lling 			if (strval[0] != '\0' && !bootfs_name_valid(poolname,
    498   5094     lling 			    strval)) {
    499   5094     lling 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "'%s' "
    500   5094     lling 				    "is an invalid name"), strval);
    501   5094     lling 				(void) zfs_error(hdl, EZFS_INVALIDNAME, errbuf);
    502   5094     lling 				goto error;
    503   5094     lling 			}
    504   7042   gw25295 
    505   7042   gw25295 			if ((zhp = zpool_open_canfail(hdl, poolname)) == NULL) {
    506   7042   gw25295 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
    507   7042   gw25295 				    "could not open pool '%s'"), poolname);
    508   7042   gw25295 				(void) zfs_error(hdl, EZFS_OPENFAILED, errbuf);
    509   7042   gw25295 				goto error;
    510   7042   gw25295 			}
    511   7042   gw25295 			verify(nvlist_lookup_nvlist(zpool_get_config(zhp, NULL),
    512   7042   gw25295 			    ZPOOL_CONFIG_VDEV_TREE, &nvroot) == 0);
    513   7042   gw25295 
    514   7042   gw25295 			/*
    515   7042   gw25295 			 * bootfs property cannot be set on a disk which has
    516   7042   gw25295 			 * been EFI labeled.
    517   7042   gw25295 			 */
    518   7042   gw25295 			if (pool_uses_efi(nvroot)) {
    519   7042   gw25295 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
    520   7042   gw25295 				    "property '%s' not supported on "
    521   7042   gw25295 				    "EFI labeled devices"), propname);
    522   7042   gw25295 				(void) zfs_error(hdl, EZFS_POOL_NOTSUP, errbuf);
    523   7042   gw25295 				zpool_close(zhp);
    524   7042   gw25295 				goto error;
    525   7042   gw25295 			}
    526   7042   gw25295 			zpool_close(zhp);
    527   5094     lling 			break;
    528   5094     lling 
    529   5094     lling 		case ZPOOL_PROP_ALTROOT:
    530   5094     lling 			if (!create_or_import) {
    531   5094     lling 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
    532   5094     lling 				    "property '%s' can only be set during pool "
    533   5094     lling 				    "creation or import"), propname);
    534   5094     lling 				(void) zfs_error(hdl, EZFS_BADPROP, errbuf);
    535   5094     lling 				goto error;
    536   5094     lling 			}
    537   5094     lling 
    538   5094     lling 			if (strval[0] != '/') {
    539   5094     lling 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
    540   5094     lling 				    "bad alternate root '%s'"), strval);
    541   5094     lling 				(void) zfs_error(hdl, EZFS_BADPATH, errbuf);
    542   5094     lling 				goto error;
    543   5094     lling 			}
    544   5363  eschrock 			break;
    545   5094     lling 
    546   5363  eschrock 		case ZPOOL_PROP_CACHEFILE:
    547   5363  eschrock 			if (strval[0] == '\0')
    548   5363  eschrock 				break;
    549   5363  eschrock 
    550   5363  eschrock 			if (strcmp(strval, "none") == 0)
    551   5363  eschrock 				break;
    552   5363  eschrock 
    553   5363  eschrock 			if (strval[0] != '/') {
    554   5363  eschrock 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
    555   5363  eschrock 				    "property '%s' must be empty, an "
    556   5363  eschrock 				    "absolute path, or 'none'"), propname);
    557   5363  eschrock 				(void) zfs_error(hdl, EZFS_BADPATH, errbuf);
    558   5363  eschrock 				goto error;
    559   5363  eschrock 			}
    560   5363  eschrock 
    561   5363  eschrock 			slash = strrchr(strval, '/');
    562   5363  eschrock 
    563   5363  eschrock 			if (slash[1] == '\0' || strcmp(slash, "/.") == 0 ||
    564   5363  eschrock 			    strcmp(slash, "/..") == 0) {
    565   5363  eschrock 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
    566   5363  eschrock 				    "'%s' is not a valid file"), strval);
    567   5363  eschrock 				(void) zfs_error(hdl, EZFS_BADPATH, errbuf);
    568   5363  eschrock 				goto error;
    569   5363  eschrock 			}
    570   5363  eschrock 
    571   5363  eschrock 			*slash = '\0';
    572   5363  eschrock 
    573   5621  eschrock 			if (strval[0] != '\0' &&
    574   5621  eschrock 			    (stat64(strval, &statbuf) != 0 ||
    575   5621  eschrock 			    !S_ISDIR(statbuf.st_mode))) {
    576   5363  eschrock 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
    577   5363  eschrock 				    "'%s' is not a valid directory"),
    578   5363  eschrock 				    strval);
    579   5363  eschrock 				(void) zfs_error(hdl, EZFS_BADPATH, errbuf);
    580   5363  eschrock 				goto error;
    581   5363  eschrock 			}
    582   5363  eschrock 
    583   5363  eschrock 			*slash = '/';
    584   5094     lling 			break;
    585   5094     lling 		}
    586   5094     lling 	}
    587   5094     lling 
    588   5094     lling 	return (retprops);
    589   5094     lling error:
    590   5094     lling 	nvlist_free(retprops);
    591   5094     lling 	return (NULL);
    592   5094     lling }
    593   5094     lling 
    594   5094     lling /*
    595   5094     lling  * Set zpool property : propname=propval.
    596   5094     lling  */
    597   5094     lling int
    598   5094     lling zpool_set_prop(zpool_handle_t *zhp, const char *propname, const char *propval)
    599   5094     lling {
    600   5094     lling 	zfs_cmd_t zc = { 0 };
    601   5094     lling 	int ret = -1;
    602   5094     lling 	char errbuf[1024];
    603   5094     lling 	nvlist_t *nvl = NULL;
    604   5094     lling 	nvlist_t *realprops;
    605   5094     lling 	uint64_t version;
    606   5094     lling 
    607   5094     lling 	(void) snprintf(errbuf, sizeof (errbuf),
    608   5094     lling 	    dgettext(TEXT_DOMAIN, "cannot set property for '%s'"),
    609   5094     lling 	    zhp->zpool_name);
    610   5094     lling 
    611   5094     lling 	if (nvlist_alloc(&nvl, NV_UNIQUE_NAME, 0) != 0)
    612   5094     lling 		return (no_memory(zhp->zpool_hdl));
    613   5094     lling 
    614   5094     lling 	if (nvlist_add_string(nvl, propname, propval) != 0) {
    615   5094     lling 		nvlist_free(nvl);
    616   5094     lling 		return (no_memory(zhp->zpool_hdl));
    617   5094     lling 	}
    618   5094     lling 
    619   5094     lling 	version = zpool_get_prop_int(zhp, ZPOOL_PROP_VERSION, NULL);
    620   7184      timh 	if ((realprops = zpool_valid_proplist(zhp->zpool_hdl,
    621   5094     lling 	    zhp->zpool_name, nvl, version, B_FALSE, errbuf)) == NULL) {
    622   5094     lling 		nvlist_free(nvl);
    623   5094     lling 		return (-1);
    624   5094     lling 	}
    625   5094     lling 
    626   5094     lling 	nvlist_free(nvl);
    627   5094     lling 	nvl = realprops;
    628   5094     lling 
    629   5094     lling 	/*
    630   5094     lling 	 * Execute the corresponding ioctl() to set this property.
    631   5094     lling 	 */
    632   5094     lling 	(void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
    633   5094     lling 
    634   5094     lling 	if (zcmd_write_src_nvlist(zhp->zpool_hdl, &zc, nvl) != 0) {
    635   5094     lling 		nvlist_free(nvl);
    636   5094     lling 		return (-1);
    637   5094     lling 	}
    638   5094     lling 
    639   5094     lling 	ret = zfs_ioctl(zhp->zpool_hdl, ZFS_IOC_POOL_SET_PROPS, &zc);
    640   5094     lling 
    641   5094     lling 	zcmd_free_nvlists(&zc);
    642   5094     lling 	nvlist_free(nvl);
    643   5094     lling 
    644   5094     lling 	if (ret)
    645   5094     lling 		(void) zpool_standard_error(zhp->zpool_hdl, errno, errbuf);
    646   5094     lling 	else
    647   5094     lling 		(void) zpool_props_refresh(zhp);
    648   5094     lling 
    649   5094     lling 	return (ret);
    650   5094     lling }
    651   5094     lling 
    652   5094     lling int
    653   5094     lling zpool_expand_proplist(zpool_handle_t *zhp, zprop_list_t **plp)
    654   5094     lling {
    655   5094     lling 	libzfs_handle_t *hdl = zhp->zpool_hdl;
    656   5094     lling 	zprop_list_t *entry;
    657   5094     lling 	char buf[ZFS_MAXPROPLEN];
    658   5094     lling 
    659   5094     lling 	if (zprop_expand_list(hdl, plp, ZFS_TYPE_POOL) != 0)
    660   5094     lling 		return (-1);
    661   5094     lling 
    662   5094     lling 	for (entry = *plp; entry != NULL; entry = entry->pl_next) {
    663   5094     lling 
    664   5094     lling 		if (entry->pl_fixed)
    665   5094     lling 			continue;
    666   5094     lling 
    667   5094     lling 		if (entry->pl_prop != ZPROP_INVAL &&
    668   5094     lling 		    zpool_get_prop(zhp, entry->pl_prop, buf, sizeof (buf),
    669   5094     lling 		    NULL) == 0) {
    670   5094     lling 			if (strlen(buf) > entry->pl_width)
    671   5094     lling 				entry->pl_width = strlen(buf);
    672   5094     lling 		}
    673   5094     lling 	}
    674   5094     lling 
    675   5094     lling 	return (0);
    676   5094     lling }
    677   5094     lling 
    678   9816    George 
    679   9816    George /*
    680   9816    George  * Don't start the slice at the default block of 34; many storage
    681   9816    George  * devices will use a stripe width of 128k, so start there instead.
    682   9816    George  */
    683   9816    George #define	NEW_START_BLOCK	256
    684    789    ahrens 
    685    789    ahrens /*
    686    789    ahrens  * Validate the given pool name, optionally putting an extended error message in
    687    789    ahrens  * 'buf'.
    688    789    ahrens  */
    689   6423   gw25295 boolean_t
    690   2082  eschrock zpool_name_valid(libzfs_handle_t *hdl, boolean_t isopen, const char *pool)
    691    789    ahrens {
    692    789    ahrens 	namecheck_err_t why;
    693    789    ahrens 	char what;
    694   1773  eschrock 	int ret;
    695    789    ahrens 
    696   1773  eschrock 	ret = pool_namecheck(pool, &why, &what);
    697   1773  eschrock 
    698   1773  eschrock 	/*
    699   1773  eschrock 	 * The rules for reserved pool names were extended at a later point.
    700   1773  eschrock 	 * But we need to support users with existing pools that may now be
    701   1773  eschrock 	 * invalid.  So we only check for this expanded set of names during a
    702   1773  eschrock 	 * create (or import), and only in userland.
    703   1773  eschrock 	 */
    704   1773  eschrock 	if (ret == 0 && !isopen &&
    705   1773  eschrock 	    (strncmp(pool, "mirror", 6) == 0 ||
    706   1773  eschrock 	    strncmp(pool, "raidz", 5) == 0 ||
    707   4527    perrin 	    strncmp(pool, "spare", 5) == 0 ||
    708   4527    perrin 	    strcmp(pool, "log") == 0)) {
    709   6423   gw25295 		if (hdl != NULL)
    710   6423   gw25295 			zfs_error_aux(hdl,
    711   6423   gw25295 			    dgettext(TEXT_DOMAIN, "name is reserved"));
    712   2082  eschrock 		return (B_FALSE);
    713   1773  eschrock 	}
    714   1773  eschrock 
    715   1773  eschrock 
    716   1773  eschrock 	if (ret != 0) {
    717   2082  eschrock 		if (hdl != NULL) {
    718    789    ahrens 			switch (why) {
    719   1003     lling 			case NAME_ERR_TOOLONG:
    720   2082  eschrock 				zfs_error_aux(hdl,
    721   1003     lling 				    dgettext(TEXT_DOMAIN, "name is too long"));
    722   1003     lling 				break;
    723   1003     lling 
    724    789    ahrens 			case NAME_ERR_INVALCHAR:
    725   2082  eschrock 				zfs_error_aux(hdl,
    726    789    ahrens 				    dgettext(TEXT_DOMAIN, "invalid character "
    727    789    ahrens 				    "'%c' in pool name"), what);
    728    789    ahrens 				break;
    729    789    ahrens 
    730    789    ahrens 			case NAME_ERR_NOLETTER:
    731   2082  eschrock 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
    732   2082  eschrock 				    "name must begin with a letter"));
    733    789    ahrens 				break;
    734    789    ahrens 
    735    789    ahrens 			case NAME_ERR_RESERVED:
    736   2082  eschrock 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
    737   2082  eschrock 				    "name is reserved"));
    738    789    ahrens 				break;
    739    789    ahrens 
    740    789    ahrens 			case NAME_ERR_DISKLIKE:
    741   2082  eschrock 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
    742   2082  eschrock 				    "pool name is reserved"));
    743    789    ahrens 				break;
    744   2856  nd150628 
    745   2856  nd150628 			case NAME_ERR_LEADING_SLASH:
    746   2856  nd150628 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
    747   2856  nd150628 				    "leading slash in name"));
    748   2856  nd150628 				break;
    749   2856  nd150628 
    750   2856  nd150628 			case NAME_ERR_EMPTY_COMPONENT:
    751   2856  nd150628 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
    752   2856  nd150628 				    "empty component in name"));
    753   2856  nd150628 				break;
    754   2856  nd150628 
    755   2856  nd150628 			case NAME_ERR_TRAILING_SLASH:
    756   2856  nd150628 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
    757   2856  nd150628 				    "trailing slash in name"));
    758   2856  nd150628 				break;
    759   2856  nd150628 
    760   2856  nd150628 			case NAME_ERR_MULTIPLE_AT:
    761   2856  nd150628 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
    762   2856  nd150628 				    "multiple '@' delimiters in name"));
    763   2856  nd150628 				break;
    764   2856  nd150628 
    765    789    ahrens 			}
    766    789    ahrens 		}
    767   2082  eschrock 		return (B_FALSE);
    768    789    ahrens 	}
    769    789    ahrens 
    770   2082  eschrock 	return (B_TRUE);
    771   3912     lling }
    772   3912     lling 
    773    789    ahrens /*
    774    789    ahrens  * Open a handle to the given pool, even if the pool is currently in the FAULTED
    775    789    ahrens  * state.
    776    789    ahrens  */
    777    789    ahrens zpool_handle_t *
    778   2082  eschrock zpool_open_canfail(libzfs_handle_t *hdl, const char *pool)
    779    789    ahrens {
    780    789    ahrens 	zpool_handle_t *zhp;
    781   2142  eschrock 	boolean_t missing;
    782    789    ahrens 
    783    789    ahrens 	/*
    784    789    ahrens 	 * Make sure the pool name is valid.
    785    789    ahrens 	 */
    786   2082  eschrock 	if (!zpool_name_valid(hdl, B_TRUE, pool)) {
    787   3237     lling 		(void) zfs_error_fmt(hdl, EZFS_INVALIDNAME,
    788   2082  eschrock 		    dgettext(TEXT_DOMAIN, "cannot open '%s'"),
    789   2082  eschrock 		    pool);
    790    789    ahrens 		return (NULL);
    791    789    ahrens 	}
    792    789    ahrens 
    793   2082  eschrock 	if ((zhp = zfs_alloc(hdl, sizeof (zpool_handle_t))) == NULL)
    794   2082  eschrock 		return (NULL);
    795    789    ahrens 
    796   2082  eschrock 	zhp->zpool_hdl = hdl;
    797    789    ahrens 	(void) strlcpy(zhp->zpool_name, pool, sizeof (zhp->zpool_name));
    798    789    ahrens 
    799   2142  eschrock 	if (zpool_refresh_stats(zhp, &missing) != 0) {
    800   2142  eschrock 		zpool_close(zhp);
    801   2142  eschrock 		return (NULL);
    802   2142  eschrock 	}
    803   2142  eschrock 
    804   2142  eschrock 	if (missing) {
    805   5094     lling 		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "no such pool"));
    806   3237     lling 		(void) zfs_error_fmt(hdl, EZFS_NOENT,
    807   5094     lling 		    dgettext(TEXT_DOMAIN, "cannot open '%s'"), pool);
    808   2142  eschrock 		zpool_close(zhp);
    809   2142  eschrock 		return (NULL);
    810    789    ahrens 	}
    811    789    ahrens 
    812    789    ahrens 	return (zhp);
    813    789    ahrens }
    814    789    ahrens 
    815    789    ahrens /*
    816    789    ahrens  * Like the above, but silent on error.  Used when iterating over pools (because
    817    789    ahrens  * the configuration cache may be out of date).
    818    789    ahrens  */
    819   2142  eschrock int
    820   2142  eschrock zpool_open_silent(libzfs_handle_t *hdl, const char *pool, zpool_handle_t **ret)
    821    789    ahrens {
    822    789    ahrens 	zpool_handle_t *zhp;
    823   2142  eschrock 	boolean_t missing;
    824    789    ahrens 
    825   2142  eschrock 	if ((zhp = zfs_alloc(hdl, sizeof (zpool_handle_t))) == NULL)
    826   2142  eschrock 		return (-1);
    827    789    ahrens 
    828   2082  eschrock 	zhp->zpool_hdl = hdl;
    829    789    ahrens 	(void) strlcpy(zhp->zpool_name, pool, sizeof (zhp->zpool_name));
    830    789    ahrens 
    831   2142  eschrock 	if (zpool_refresh_stats(zhp, &missing) != 0) {
    832   2142  eschrock 		zpool_close(zhp);
    833   2142  eschrock 		return (-1);
    834    789    ahrens 	}
    835    789    ahrens 
    836   2142  eschrock 	if (missing) {
    837   2142  eschrock 		zpool_close(zhp);
    838   2142  eschrock 		*ret = NULL;
    839   2142  eschrock 		return (0);
    840   2142  eschrock 	}
    841   2142  eschrock 
    842   2142  eschrock 	*ret = zhp;
    843   2142  eschrock 	return (0);
    844    789    ahrens }
    845    789    ahrens 
    846    789    ahrens /*
    847    789    ahrens  * Similar to zpool_open_canfail(), but refuses to open pools in the faulted
    848    789    ahrens  * state.
    849    789    ahrens  */
    850    789    ahrens zpool_handle_t *
    851   2082  eschrock zpool_open(libzfs_handle_t *hdl, const char *pool)
    852    789    ahrens {
    853    789    ahrens 	zpool_handle_t *zhp;
    854    789    ahrens 
    855   2082  eschrock 	if ((zhp = zpool_open_canfail(hdl, pool)) == NULL)
    856    789    ahrens 		return (NULL);
    857    789    ahrens 
    858    789    ahrens 	if (zhp->zpool_state == POOL_STATE_UNAVAIL) {
    859   3237     lling 		(void) zfs_error_fmt(hdl, EZFS_POOLUNAVAIL,
    860   2082  eschrock 		    dgettext(TEXT_DOMAIN, "cannot open '%s'"), zhp->zpool_name);
    861    789    ahrens 		zpool_close(zhp);
    862    789    ahrens 		return (NULL);
    863    789    ahrens 	}
    864    789    ahrens 
    865    789    ahrens 	return (zhp);
    866    789    ahrens }
    867    789    ahrens 
    868    789    ahrens /*
    869    789    ahrens  * Close the handle.  Simply frees the memory associated with the handle.
    870    789    ahrens  */
    871    789    ahrens void
    872    789    ahrens zpool_close(zpool_handle_t *zhp)
    873    789    ahrens {
    874    789    ahrens 	if (zhp->zpool_config)
    875    789    ahrens 		nvlist_free(zhp->zpool_config);
    876    952  eschrock 	if (zhp->zpool_old_config)
    877    952  eschrock 		nvlist_free(zhp->zpool_old_config);
    878   3912     lling 	if (zhp->zpool_props)
    879   3912     lling 		nvlist_free(zhp->zpool_props);
    880    789    ahrens 	free(zhp);
    881    789    ahrens }
    882    789    ahrens 
    883    789    ahrens /*
    884    789    ahrens  * Return the name of the pool.
    885    789    ahrens  */
    886    789    ahrens const char *
    887    789    ahrens zpool_get_name(zpool_handle_t *zhp)
    888    789    ahrens {
    889    789    ahrens 	return (zhp->zpool_name);
    890    789    ahrens }
    891    789    ahrens 
    892    789    ahrens 
    893    789    ahrens /*
    894    789    ahrens  * Return the state of the pool (ACTIVE or UNAVAILABLE)
    895    789    ahrens  */
    896    789    ahrens int
    897    789    ahrens zpool_get_state(zpool_handle_t *zhp)
    898    789    ahrens {
    899    789    ahrens 	return (zhp->zpool_state);
    900    789    ahrens }
    901    789    ahrens 
    902    789    ahrens /*
    903    789    ahrens  * Create the named pool, using the provided vdev list.  It is assumed
    904    789    ahrens  * that the consumer has already validated the contents of the nvlist, so we
    905    789    ahrens  * don't have to worry about error semantics.
    906    789    ahrens  */
    907    789    ahrens int
    908   2082  eschrock zpool_create(libzfs_handle_t *hdl, const char *pool, nvlist_t *nvroot,
    909   7184      timh     nvlist_t *props, nvlist_t *fsprops)
    910    789    ahrens {
    911    789    ahrens 	zfs_cmd_t zc = { 0 };
    912   7184      timh 	nvlist_t *zc_fsprops = NULL;
    913   7184      timh 	nvlist_t *zc_props = NULL;
    914   2082  eschrock 	char msg[1024];
    915   5094     lling 	char *altroot;
    916   7184      timh 	int ret = -1;
    917    789    ahrens 
    918   2082  eschrock 	(void) snprintf(msg, sizeof (msg), dgettext(TEXT_DOMAIN,
    919   2082  eschrock 	    "cannot create '%s'"), pool);
    920   2082  eschrock 
    921   2082  eschrock 	if (!zpool_name_valid(hdl, B_FALSE, pool))
    922   2082  eschrock 		return (zfs_error(hdl, EZFS_INVALIDNAME, msg));
    923   2082  eschrock 
    924   5320     lling 	if (zcmd_write_conf_nvlist(hdl, &zc, nvroot) != 0)
    925   5320     lling 		return (-1);
    926   5320     lling 
    927   7184      timh 	if (props) {
    928   7184      timh 		if ((zc_props = zpool_valid_proplist(hdl, pool, props,
    929   7184      timh 		    SPA_VERSION_1, B_TRUE, msg)) == NULL) {
    930   7184      timh 			goto create_failed;
    931   7184      timh 		}
    932   7184      timh 	}
    933   2082  eschrock 
    934   7184      timh 	if (fsprops) {
    935   7184      timh 		uint64_t zoned;
    936   7184      timh 		char *zonestr;
    937   7184      timh 
    938   7184      timh 		zoned = ((nvlist_lookup_string(fsprops,
    939   7184      timh 		    zfs_prop_to_name(ZFS_PROP_ZONED), &zonestr) == 0) &&
    940   7184      timh 		    strcmp(zonestr, "on") == 0);
    941   7184      timh 
    942   7184      timh 		if ((zc_fsprops = zfs_valid_proplist(hdl,
    943   7184      timh 		    ZFS_TYPE_FILESYSTEM, fsprops, zoned, NULL, msg)) == NULL) {
    944   7184      timh 			goto create_failed;
    945   7184      timh 		}
    946   7184      timh 		if (!zc_props &&
    947   7184      timh 		    (nvlist_alloc(&zc_props, NV_UNIQUE_NAME, 0) != 0)) {
    948   7184      timh 			goto create_failed;
    949   7184      timh 		}
    950   7184      timh 		if (nvlist_add_nvlist(zc_props,
    951   7184      timh 		    ZPOOL_ROOTFS_PROPS, zc_fsprops) != 0) {
    952   7184      timh 			goto create_failed;
    953   7184      timh 		}
    954   5320     lling 	}
    955   7184      timh 
    956   7184      timh 	if (zc_props && zcmd_write_src_nvlist(hdl, &zc, zc_props) != 0)
    957   7184      timh 		goto create_failed;
    958   2082  eschrock 
    959    789    ahrens 	(void) strlcpy(zc.zc_name, pool, sizeof (zc.zc_name));
    960    789    ahrens 
    961   7184      timh 	if ((ret = zfs_ioctl(hdl, ZFS_IOC_POOL_CREATE, &zc)) != 0) {
    962   5320     lling 
    963   2676  eschrock 		zcmd_free_nvlists(&zc);
    964   7184      timh 		nvlist_free(zc_props);
    965   7184      timh 		nvlist_free(zc_fsprops);
    966   2082  eschrock 
    967    789    ahrens 		switch (errno) {
    968    789    ahrens 		case EBUSY:
    969    789    ahrens 			/*
    970    789    ahrens 			 * This can happen if the user has specified the same
    971    789    ahrens 			 * device multiple times.  We can't reliably detect this
    972    789    ahrens 			 * until we try to add it and see we already have a
    973    789    ahrens 			 * label.
    974    789    ahrens 			 */
    975   2082  eschrock 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
    976   2082  eschrock 			    "one or more vdevs refer to the same device"));
    977   2082  eschrock 			return (zfs_error(hdl, EZFS_BADDEV, msg));
    978    789    ahrens 
    979    789    ahrens 		case EOVERFLOW:
    980    789    ahrens 			/*
    981   2082  eschrock 			 * This occurs when one of the devices is below
    982    789    ahrens 			 * SPA_MINDEVSIZE.  Unfortunately, we can't detect which
    983    789    ahrens 			 * device was the problem device since there's no
    984    789    ahrens 			 * reliable way to determine device size from userland.
    985    789    ahrens 			 */
    986    789    ahrens 			{
    987    789    ahrens 				char buf[64];
    988    789    ahrens 
    989    789    ahrens 				zfs_nicenum(SPA_MINDEVSIZE, buf, sizeof (buf));
    990    789    ahrens 
    991   2082  eschrock 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
    992   2082  eschrock 				    "one or more devices is less than the "
    993   2082  eschrock 				    "minimum size (%s)"), buf);
    994    789    ahrens 			}
    995   2082  eschrock 			return (zfs_error(hdl, EZFS_BADDEV, msg));
    996    789    ahrens 
    997    789    ahrens 		case ENOSPC:
    998   2082  eschrock 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
    999   2082  eschrock 			    "one or more devices is out of space"));
   1000   2082  eschrock 			return (zfs_error(hdl, EZFS_BADDEV, msg));
   1001    789    ahrens 
   1002   5450   brendan 		case ENOTBLK:
   1003   5450   brendan 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
   1004   5450   brendan 			    "cache device must be a disk or disk slice"));
   1005   5450   brendan 			return (zfs_error(hdl, EZFS_BADDEV, msg));
   1006   5450   brendan 
   1007    789    ahrens 		default:
   1008   2082  eschrock 			return (zpool_standard_error(hdl, errno, msg));
   1009    789    ahrens 		}
   1010    789    ahrens 	}
   1011    789    ahrens 
   1012    789    ahrens 	/*
   1013    789    ahrens 	 * If this is an alternate root pool, then we automatically set the
   1014   2676  eschrock 	 * mountpoint of the root dataset to be '/'.
   1015    789    ahrens 	 */
   1016   5094     lling 	if (nvlist_lookup_string(props, zpool_prop_to_name(ZPOOL_PROP_ALTROOT),
   1017   5094     lling 	    &altroot) == 0) {
   1018    789    ahrens 		zfs_handle_t *zhp;
   1019    789    ahrens 
   1020   5094     lling 		verify((zhp = zfs_open(hdl, pool, ZFS_TYPE_DATASET)) != NULL);
   1021   2676  eschrock 		verify(zfs_prop_set(zhp, zfs_prop_to_name(ZFS_PROP_MOUNTPOINT),
   1022   2676  eschrock 		    "/") == 0);
   1023    789    ahrens 
   1024    789    ahrens 		zfs_close(zhp);
   1025    789    ahrens 	}
   1026    789    ahrens 
   1027   7184      timh create_failed:
   1028   5320     lling 	zcmd_free_nvlists(&zc);
   1029   7184      timh 	nvlist_free(zc_props);
   1030   7184      timh 	nvlist_free(zc_fsprops);
   1031   7184      timh 	return (ret);
   1032    789    ahrens }
   1033    789    ahrens 
   1034    789    ahrens /*
   1035    789    ahrens  * Destroy the given pool.  It is up to the caller to ensure that there are no
   1036    789    ahrens  * datasets left in the pool.
   1037    789    ahrens  */
   1038    789    ahrens int
   1039    789    ahrens zpool_destroy(zpool_handle_t *zhp)
   1040    789    ahrens {
   1041    789    ahrens 	zfs_cmd_t zc = { 0 };
   1042    789    ahrens 	zfs_handle_t *zfp = NULL;
   1043   2082  eschrock 	libzfs_handle_t *hdl = zhp->zpool_hdl;
   1044   2082  eschrock 	char msg[1024];
   1045    789    ahrens 
   1046    789    ahrens 	if (zhp->zpool_state == POOL_STATE_ACTIVE &&
   1047   2082  eschrock 	    (zfp = zfs_open(zhp->zpool_hdl, zhp->zpool_name,
   1048   2082  eschrock 	    ZFS_TYPE_FILESYSTEM)) == NULL)
   1049    789    ahrens 		return (-1);
   1050    789    ahrens 
   1051    789    ahrens 	(void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
   1052    789    ahrens 
   1053   4543     marks 	if (zfs_ioctl(zhp->zpool_hdl, ZFS_IOC_POOL_DESTROY, &zc) != 0) {
   1054   2082  eschrock 		(void) snprintf(msg, sizeof (msg), dgettext(TEXT_DOMAIN,
   1055   2082  eschrock 		    "cannot destroy '%s'"), zhp->zpool_name);
   1056    789    ahrens 
   1057   2082  eschrock 		if (errno == EROFS) {
   1058   2082  eschrock 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
   1059   2082  eschrock 			    "one or more devices is read only"));
   1060   2082  eschrock 			(void) zfs_error(hdl, EZFS_BADDEV, msg);
   1061   2082  eschrock 		} else {
   1062   2082  eschrock 			(void) zpool_standard_error(hdl, errno, msg);
   1063    789    ahrens 		}
   1064    789    ahrens 
   1065    789    ahrens 		if (zfp)
   1066    789    ahrens 			zfs_close(zfp);
   1067    789    ahrens 		return (-1);
   1068    789    ahrens 	}
   1069    789    ahrens 
   1070    789    ahrens 	if (zfp) {
   1071    789    ahrens 		remove_mountpoint(zfp);
   1072    789    ahrens 		zfs_close(zfp);
   1073    789    ahrens 	}
   1074    789    ahrens 
   1075    789    ahrens 	return (0);
   1076    789    ahrens }
   1077    789    ahrens 
   1078    789    ahrens /*
   1079    789    ahrens  * Add the given vdevs to the pool.  The caller must have already performed the
   1080    789    ahrens  * necessary verification to ensure that the vdev specification is well-formed.
   1081    789    ahrens  */
   1082    789    ahrens int
   1083    789    ahrens zpool_add(zpool_handle_t *zhp, nvlist_t *nvroot)
   1084    789    ahrens {
   1085   2676  eschrock 	zfs_cmd_t zc = { 0 };
   1086   2082  eschrock 	int ret;
   1087   2082  eschrock 	libzfs_handle_t *hdl = zhp->zpool_hdl;
   1088   2082  eschrock 	char msg[1024];
   1089   5450   brendan 	nvlist_t **spares, **l2cache;
   1090   5450   brendan 	uint_t nspares, nl2cache;
   1091   2082  eschrock 
   1092   2082  eschrock 	(void) snprintf(msg, sizeof (msg), dgettext(TEXT_DOMAIN,
   1093   2082  eschrock 	    "cannot add to '%s'"), zhp->zpool_name);
   1094   2082  eschrock 
   1095   5450   brendan 	if (zpool_get_prop_int(zhp, ZPOOL_PROP_VERSION, NULL) <
   1096   5450   brendan 	    SPA_VERSION_SPARES &&
   1097   2082  eschrock 	    nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_SPARES,
   1098   2082  eschrock 	    &spares, &nspares) == 0) {
   1099   2082  eschrock 		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "pool must be "
   1100   2082  eschrock 		    "upgraded to add hot spares"));
   1101   5450   brendan 		return (zfs_error(hdl, EZFS_BADVERSION, msg));
   1102   7965    George 	}
   1103   7965    George 
   1104   7965    George 	if (pool_is_bootable(zhp) && nvlist_lookup_nvlist_array(nvroot,
   1105   7965    George 	    ZPOOL_CONFIG_SPARES, &spares, &nspares) == 0) {
   1106   7965    George 		uint64_t s;
   1107   7965    George 
   1108   7965    George 		for (s = 0; s < nspares; s++) {
   1109   7965    George 			char *path;
   1110   7965    George 
   1111   7965    George 			if (nvlist_lookup_string(spares[s], ZPOOL_CONFIG_PATH,
   1112   7965    George 			    &path) == 0 && pool_uses_efi(spares[s])) {
   1113   7965    George 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
   1114   7965    George 				    "device '%s' contains an EFI label and "
   1115   7965    George 				    "cannot be used on root pools."),
   1116  10594    George 				    zpool_vdev_name(hdl, NULL, spares[s],
   1117  10594    George 				    B_FALSE));
   1118   7965    George 				return (zfs_error(hdl, EZFS_POOL_NOTSUP, msg));
   1119   7965    George 			}
   1120   7965    George 		}
   1121   5450   brendan 	}
   1122   5450   brendan 
   1123   5450   brendan 	if (zpool_get_prop_int(zhp, ZPOOL_PROP_VERSION, NULL) <
   1124   5450   brendan 	    SPA_VERSION_L2CACHE &&
   1125   5450   brendan 	    nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_L2CACHE,
   1126   5450   brendan 	    &l2cache, &nl2cache) == 0) {
   1127   5450   brendan 		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "pool must be "
   1128   5450   brendan 		    "upgraded to add cache devices"));
   1129   2082  eschrock 		return (zfs_error(hdl, EZFS_BADVERSION, msg));
   1130   2082  eschrock 	}
   1131    789    ahrens 
   1132   5094     lling 	if (zcmd_write_conf_nvlist(hdl, &zc, nvroot) != 0)
   1133   2082  eschrock 		return (-1);
   1134    789    ahrens 	(void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
   1135    789    ahrens 
   1136   4543     marks 	if (zfs_ioctl(zhp->zpool_hdl, ZFS_IOC_VDEV_ADD, &zc) != 0) {
   1137    789    ahrens 		switch (errno) {
   1138    789    ahrens 		case EBUSY:
   1139    789    ahrens 			/*
   1140    789    ahrens 			 * This can happen if the user has specified the same
   1141    789    ahrens 			 * device multiple times.  We can't reliably detect this
   1142    789    ahrens 			 * until we try to add it and see we already have a
   1143    789    ahrens 			 * label.
   1144    789    ahrens 			 */
   1145   2082  eschrock 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
   1146   2082  eschrock 			    "one or more vdevs refer to the same device"));
   1147   2082  eschrock 			(void) zfs_error(hdl, EZFS_BADDEV, msg);
   1148    789    ahrens 			break;
   1149    789    ahrens 
   1150    789    ahrens 		case EOVERFLOW:
   1151    789    ahrens 			/*
   1152    789    ahrens 			 * This occurrs when one of the devices is below
   1153    789    ahrens 			 * SPA_MINDEVSIZE.  Unfortunately, we can't detect which
   1154    789    ahrens 			 * device was the problem device since there's no
   1155    789    ahrens 			 * reliable way to determine device size from userland.
   1156    789    ahrens 			 */
   1157    789    ahrens 			{
   1158    789    ahrens 				char buf[64];
   1159    789    ahrens 
   1160    789    ahrens 				zfs_nicenum(SPA_MINDEVSIZE, buf, sizeof (buf));
   1161    789    ahrens 
   1162   2082  eschrock 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
   1163   2082  eschrock 				    "device is less than the minimum "
   1164   2082  eschrock 				    "size (%s)"), buf);
   1165    789    ahrens 			}
   1166   2082  eschrock 			(void) zfs_error(hdl, EZFS_BADDEV, msg);
   1167   2082  eschrock 			break;
   1168   2082  eschrock 
   1169   2082  eschrock 		case ENOTSUP:
   1170   2082  eschrock 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
   1171   4527    perrin 			    "pool must be upgraded to add these vdevs"));
   1172   2082  eschrock 			(void) zfs_error(hdl, EZFS_BADVERSION, msg);
   1173    789    ahrens 			break;
   1174    789    ahrens 
   1175   3912     lling 		case EDOM:
   1176   3912     lling 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
   1177   4527    perrin 			    "root pool can not have multiple vdevs"
   1178   4527    perrin 			    " or separate logs"));
   1179   3912     lling 			(void) zfs_error(hdl, EZFS_POOL_NOTSUP, msg);
   1180   5450   brendan 			break;
   1181   5450   brendan 
   1182   5450   brendan 		case ENOTBLK:
   1183   5450   brendan 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
   1184   5450   brendan 			    "cache device must be a disk or disk slice"));
   1185   5450   brendan 			(void) zfs_error(hdl, EZFS_BADDEV, msg);
   1186   3912     lling 			break;
   1187   3912     lling 
   1188    789    ahrens 		default:
   1189   2082  eschrock 			(void) zpool_standard_error(hdl, errno, msg);
   1190    789    ahrens 		}
   1191    789    ahrens 
   1192   2082  eschrock 		ret = -1;
   1193   2082  eschrock 	} else {
   1194   2082  eschrock 		ret = 0;
   1195    789    ahrens 	}
   1196    789    ahrens 
   1197   2676  eschrock 	zcmd_free_nvlists(&zc);
   1198    789    ahrens 
   1199   2082  eschrock 	return (ret);
   1200    789    ahrens }
   1201    789    ahrens 
   1202    789    ahrens /*
   1203    789    ahrens  * Exports the pool from the system.  The caller must ensure that there are no
   1204    789    ahrens  * mounted datasets in the pool.
   1205    789    ahrens  */
   1206    789    ahrens int
   1207   8211    George zpool_export_common(zpool_handle_t *zhp, boolean_t force, boolean_t hardforce)
   1208    789    ahrens {
   1209    789    ahrens 	zfs_cmd_t zc = { 0 };
   1210   7214     lling 	char msg[1024];
   1211    789    ahrens 
   1212   7214     lling 	(void) snprintf(msg, sizeof (msg), dgettext(TEXT_DOMAIN,
   1213   7214     lling 	    "cannot export '%s'"), zhp->zpool_name);
   1214   7214     lling 
   1215    789    ahrens 	(void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
   1216   7214     lling 	zc.zc_cookie = force;
   1217   8211    George 	zc.zc_guid = hardforce;
   1218    789    ahrens 
   1219   7214     lling 	if (zfs_ioctl(zhp->zpool_hdl, ZFS_IOC_POOL_EXPORT, &zc) != 0) {
   1220   7214     lling 		switch (errno) {
   1221   7214     lling 		case EXDEV:
   1222   7214     lling 			zfs_error_aux(zhp->zpool_hdl, dgettext(TEXT_DOMAIN,
   1223   7214     lling 			    "use '-f' to override the following errors:\n"
   1224   7214     lling 			    "'%s' has an active shared spare which could be"
   1225   7214     lling 			    " used by other pools once '%s' is exported."),
   1226   7214     lling 			    zhp->zpool_name, zhp->zpool_name);
   1227   7214     lling 			return (zfs_error(zhp->zpool_hdl, EZFS_ACTIVE_SPARE,
   1228   7214     lling 			    msg));
   1229   7214     lling 		default:
   1230   7214     lling 			return (zpool_standard_error_fmt(zhp->zpool_hdl, errno,
   1231   7214     lling 			    msg));
   1232   7214     lling 		}
   1233   7214     lling 	}
   1234   7214     lling 
   1235    789    ahrens 	return (0);
   1236   8211    George }
   1237   8211    George 
   1238   8211    George int
   1239   8211    George zpool_export(zpool_handle_t *zhp, boolean_t force)
   1240   8211    George {
   1241   8211    George 	return (zpool_export_common(zhp, force, B_FALSE));
   1242   8211    George }
   1243   8211    George 
   1244   8211    George int
   1245   8211    George zpool_export_force(zpool_handle_t *zhp)
   1246   8211    George {
   1247   8211    George 	return (zpool_export_common(zhp, B_TRUE, B_TRUE));
   1248    789    ahrens }
   1249    789    ahrens 
   1250  10921       Tim static void
   1251  10921       Tim zpool_rewind_exclaim(libzfs_handle_t *hdl, const char *name, boolean_t dryrun,
   1252  10921       Tim     nvlist_t *rbi)
   1253  10921       Tim {
   1254  10921       Tim 	uint64_t rewindto;
   1255  10921       Tim 	int64_t loss = -1;
   1256  10921       Tim 	struct tm t;
   1257  10921       Tim 	char timestr[128];
   1258  10921       Tim 
   1259  10921       Tim 	if (!hdl->libzfs_printerr || rbi == NULL)
   1260  10921       Tim 		return;
   1261  10921       Tim 
   1262  10921       Tim 	if (nvlist_lookup_uint64(rbi, ZPOOL_CONFIG_LOAD_TIME, &rewindto) != 0)
   1263  10921       Tim 		return;
   1264  10921       Tim 	(void) nvlist_lookup_int64(rbi, ZPOOL_CONFIG_REWIND_TIME, &loss);
   1265  10921       Tim 
   1266  10921       Tim 	if (localtime_r((time_t *)&rewindto, &t) != NULL &&
   1267  10921       Tim 	    strftime(timestr, 128, 0, &t) != 0) {
   1268  10921       Tim 		if (dryrun) {
   1269  10921       Tim 			(void) printf(dgettext(TEXT_DOMAIN,
   1270  10921       Tim 			    "Would be able to return %s "
   1271  10921       Tim 			    "to its state as of %s.\n"),
   1272  10921       Tim 			    name, timestr);
   1273  10921       Tim 		} else {
   1274  10921       Tim 			(void) printf(dgettext(TEXT_DOMAIN,
   1275  10921       Tim 			    "Pool %s returned to its state as of %s.\n"),
   1276  10921       Tim 			    name, timestr);
   1277  10921       Tim 		}
   1278  10921       Tim 		if (loss > 120) {
   1279  10921       Tim 			(void) printf(dgettext(TEXT_DOMAIN,
   1280  10921       Tim 			    "%s approximately %lld "),
   1281  10921       Tim 			    dryrun ? "Would discard" : "Discarded",
   1282  10921       Tim 			    (loss + 30) / 60);
   1283  10921       Tim 			(void) printf(dgettext(TEXT_DOMAIN,
   1284  10921       Tim 			    "minutes of transactions.\n"));
   1285  10921       Tim 		} else if (loss > 0) {
   1286  10921       Tim 			(void) printf(dgettext(TEXT_DOMAIN,
   1287  10921       Tim 			    "%s approximately %lld "),
   1288  10921       Tim 			    dryrun ? "Would discard" : "Discarded", loss);
   1289  10921       Tim 			(void) printf(dgettext(TEXT_DOMAIN,
   1290  10921       Tim 			    "seconds of transactions.\n"));
   1291  10921       Tim 		}
   1292  10921       Tim 	}
   1293  10921       Tim }
   1294  10921       Tim 
   1295  10921       Tim void
   1296  10921       Tim zpool_explain_recover(libzfs_handle_t *hdl, const char *name, int reason,
   1297  10921       Tim     nvlist_t *config)
   1298  10921       Tim {
   1299  10921       Tim 	int64_t loss = -1;
   1300  10921       Tim 	uint64_t edata = UINT64_MAX;
   1301  10921       Tim 	uint64_t rewindto;
   1302  10921       Tim 	struct tm t;
   1303  10921       Tim 	char timestr[128];
   1304  10921       Tim 
   1305  10921       Tim 	if (!hdl->libzfs_printerr)
   1306  10921       Tim 		return;
   1307  10921       Tim 
   1308  10921       Tim 	if (reason >= 0)
   1309  10921       Tim 		(void) printf(dgettext(TEXT_DOMAIN, "action: "));
   1310  10921       Tim 	else
   1311  10921       Tim 		(void) printf(dgettext(TEXT_DOMAIN, "\t"));
   1312  10921       Tim 
   1313  10921       Tim 	/* All attempted rewinds failed if ZPOOL_CONFIG_LOAD_TIME missing */
   1314  10921       Tim 	if (nvlist_lookup_uint64(config,
   1315  10921       Tim 	    ZPOOL_CONFIG_LOAD_TIME, &rewindto) != 0)
   1316  10921       Tim 		goto no_info;
   1317  10921       Tim 
   1318  10921       Tim 	(void) nvlist_lookup_int64(config, ZPOOL_CONFIG_REWIND_TIME, &loss);
   1319  10921       Tim 	(void) nvlist_lookup_uint64(config, ZPOOL_CONFIG_LOAD_DATA_ERRORS,
   1320  10921       Tim 	    &edata);
   1321  10921       Tim 
   1322  10921       Tim 	(void) printf(dgettext(TEXT_DOMAIN,
   1323  10921       Tim 	    "Recovery is possible, but will result in some data loss.\n"));
   1324  10921       Tim 
   1325  10921       Tim 	if (localtime_r((time_t *)&rewindto, &t) != NULL &&
   1326  10921       Tim 	    strftime(timestr, 128, 0, &t) != 0) {
   1327  10921       Tim 		(void) printf(dgettext(TEXT_DOMAIN,
   1328  10921       Tim 		    "\tReturning the pool to its state as of %s\n"
   1329  10921       Tim 		    "\tshould correct the problem.  "),
   1330  10921       Tim 		    timestr);
   1331  10921       Tim 	} else {
   1332  10921       Tim 		(void) printf(dgettext(TEXT_DOMAIN,
   1333  10921       Tim 		    "\tReverting the pool to an earlier state "
   1334  10921       Tim 		    "should correct the problem.\n\t"));
   1335  10921       Tim 	}
   1336  10921       Tim 
   1337  10921       Tim 	if (loss > 120) {
   1338  10921       Tim 		(void) printf(dgettext(TEXT_DOMAIN,
   1339  10921       Tim 		    "Approximately %lld minutes of data\n"
   1340  10921       Tim 		    "\tmust be discarded, irreversibly.  "), (loss + 30) / 60);
   1341  10921       Tim 	} else if (loss > 0) {
   1342  10921       Tim 		(void) printf(dgettext(TEXT_DOMAIN,
   1343  10921       Tim 		    "Approximately %lld seconds of data\n"
   1344  10921       Tim 		    "\tmust be discarded, irreversibly.  "), loss);
   1345  10921       Tim 	}
   1346  10921       Tim 	if (edata != 0 && edata != UINT64_MAX) {
   1347  10921       Tim 		if (edata == 1) {
   1348  10921       Tim 			(void) printf(dgettext(TEXT_DOMAIN,
   1349  10921       Tim 			    "After rewind, at least\n"
   1350  10921       Tim 			    "\tone persistent user-data error will remain.  "));
   1351  10921       Tim 		} else {
   1352  10921       Tim 			(void) printf(dgettext(TEXT_DOMAIN,
   1353  10921       Tim 			    "After rewind, several\n"
   1354  10921       Tim 			    "\tpersistent user-data errors will remain.  "));
   1355  10921       Tim 		}
   1356  10921       Tim 	}
   1357  10921       Tim 	(void) printf(dgettext(TEXT_DOMAIN,
   1358  11026       Tim 	    "Recovery can be attempted\n\tby executing 'zpool %s -F %s'.  "),
   1359  11026       Tim 	    reason >= 0 ? "clear" : "import", name);
   1360  10921       Tim 
   1361  10921       Tim 	(void) printf(dgettext(TEXT_DOMAIN,
   1362  10921       Tim 	    "A scrub of the pool\n"
   1363  10921       Tim 	    "\tis strongly recommended after recovery.\n"));
   1364  10921       Tim 	return;
   1365  10921       Tim 
   1366  10921       Tim no_info:
   1367  10921       Tim 	(void) printf(dgettext(TEXT_DOMAIN,
   1368  10921       Tim 	    "Destroy and re-create the pool from\n\ta backup source.\n"));
   1369  10921       Tim }
   1370  10921       Tim 
   1371    789    ahrens /*
   1372   5094     lling  * zpool_import() is a contracted interface. Should be kept the same
   1373   5094     lling  * if possible.
   1374   5094     lling  *
   1375   5094     lling  * Applications should use zpool_import_props() to import a pool with
   1376   5094     lling  * new properties value to be set.
   1377    789    ahrens  */
   1378    789    ahrens int
   1379   2082  eschrock zpool_import(libzfs_handle_t *hdl, nvlist_t *config, const char *newname,
   1380   5094     lling     char *altroot)
   1381   5094     lling {
   1382   5094     lling 	nvlist_t *props = NULL;
   1383   5094     lling 	int ret;
   1384   5094     lling 
   1385   5094     lling 	if (altroot != NULL) {
   1386   5094     lling 		if (nvlist_alloc(&props, NV_UNIQUE_NAME, 0) != 0) {
   1387   5094     lling 			return (zfs_error_fmt(hdl, EZFS_NOMEM,
   1388   5094     lling 			    dgettext(TEXT_DOMAIN, "cannot import '%s'"),
   1389   5094     lling 			    newname));
   1390   5094     lling 		}
   1391   5094     lling 
   1392   5094     lling 		if (nvlist_add_string(props,
   1393   8084    George 		    zpool_prop_to_name(ZPOOL_PROP_ALTROOT), altroot) != 0 ||
   1394   8084    George 		    nvlist_add_string(props,
   1395   8084    George 		    zpool_prop_to_name(ZPOOL_PROP_CACHEFILE), "none") != 0) {
   1396   5094     lling 			nvlist_free(props);
   1397   5094     lling 			return (zfs_error_fmt(hdl, EZFS_NOMEM,
   1398   5094     lling 			    dgettext(TEXT_DOMAIN, "cannot import '%s'"),
   1399   5094     lling 			    newname));
   1400   5094     lling 		}
   1401   5094     lling 	}
   1402   5094     lling 
   1403   6643  eschrock 	ret = zpool_import_props(hdl, config, newname, props, B_FALSE);
   1404   5094     lling 	if (props)
   1405   5094     lling 		nvlist_free(props);
   1406   5094     lling 	return (ret);
   1407   5094     lling }
   1408   5094     lling 
   1409   5094     lling /*
   1410   5094     lling  * Import the given pool using the known configuration and a list of
   1411   5094     lling  * properties to be set. The configuration should have come from
   1412   5094     lling  * zpool_find_import(). The 'newname' parameters control whether the pool
   1413   5094     lling  * is imported with a different name.
   1414   5094     lling  */
   1415   5094     lling int
   1416   5094     lling zpool_import_props(libzfs_handle_t *hdl, nvlist_t *config, const char *newname,
   1417   6643  eschrock     nvlist_t *props, boolean_t importfaulted)
   1418    789    ahrens {
   1419   2676  eschrock 	zfs_cmd_t zc = { 0 };
   1420  10921       Tim 	zpool_rewind_policy_t policy;
   1421  10921       Tim 	nvlist_t *nvi = NULL;
   1422    789    ahrens 	char *thename;
   1423    789    ahrens 	char *origname;
   1424  10921       Tim 	uint64_t returned_size;
   1425    789    ahrens 	int ret;
   1426   5094     lling 	char errbuf[1024];
   1427    789    ahrens 
   1428    789    ahrens 	verify(nvlist_lookup_string(config, ZPOOL_CONFIG_POOL_NAME,
   1429    789    ahrens 	    &origname) == 0);
   1430   5094     lling 
   1431   5094     lling 	(void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
   1432   5094     lling 	    "cannot import pool '%s'"), origname);
   1433    789    ahrens 
   1434    789    ahrens 	if (newname != NULL) {
   1435   2082  eschrock 		if (!zpool_name_valid(hdl, B_FALSE, newname))
   1436   3237     lling 			return (zfs_error_fmt(hdl, EZFS_INVALIDNAME,
   1437   2082  eschrock 			    dgettext(TEXT_DOMAIN, "cannot import '%s'"),
   1438   2082  eschrock 			    newname));
   1439    789    ahrens 		thename = (char *)newname;
   1440    789    ahrens 	} else {
   1441    789    ahrens 		thename = origname;
   1442    789    ahrens 	}
   1443    789    ahrens 
   1444   5094     lling 	if (props) {
   1445   5094     lling 		uint64_t version;
   1446   5094     lling 
   1447   5094     lling 		verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION,
   1448   5094     lling 		    &version) == 0);
   1449   5094     lling 
   1450   7184      timh 		if ((props = zpool_valid_proplist(hdl, origname,
   1451   5320     lling 		    props, version, B_TRUE, errbuf)) == NULL) {
   1452   5094     lling 			return (-1);
   1453   5320     lling 		} else if (zcmd_write_src_nvlist(hdl, &zc, props) != 0) {
   1454   5320     lling 			nvlist_free(props);
   1455   5094     lling 			return (-1);
   1456   5320     lling 		}
   1457   5094     lling 	}
   1458    789    ahrens 
   1459    789    ahrens 	(void) strlcpy(zc.zc_name, thename, sizeof (zc.zc_name));
   1460    789    ahrens 
   1461    789    ahrens 	verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_GUID,
   1462   1544  eschrock 	    &zc.zc_guid) == 0);
   1463    789    ahrens 
   1464   5320     lling 	if (zcmd_write_conf_nvlist(hdl, &zc, config) != 0) {
   1465   5320     lling 		nvlist_free(props);
   1466   2082  eschrock 		return (-1);
   1467   5320     lling 	}
   1468  10921       Tim 	returned_size =  zc.zc_nvlist_conf_size + 512;
   1469  10921       Tim 	if (zcmd_alloc_dst_nvlist(hdl, &zc, returned_size) != 0) {
   1470  10921       Tim 		nvlist_free(props);
   1471  10921       Tim 		return (-1);
   1472  10921       Tim 	}
   1473    789    ahrens 
   1474   6643  eschrock 	zc.zc_cookie = (uint64_t)importfaulted;
   1475    789    ahrens 	ret = 0;
   1476   4543     marks 	if (zfs_ioctl(hdl, ZFS_IOC_POOL_IMPORT, &zc) != 0) {
   1477    789    ahrens 		char desc[1024];
   1478  10921       Tim 
   1479  10921       Tim 		(void) zcmd_read_dst_nvlist(hdl, &zc, &nvi);
   1480  10921       Tim 		zpool_get_rewind_policy(config, &policy);
   1481  10921       Tim 		/*
   1482  10921       Tim 		 * Dry-run failed, but we print out what success
   1483  10921       Tim 		 * looks like if we found a best txg
   1484  10921       Tim 		 */
   1485  10921       Tim 		if ((policy.zrp_request & ZPOOL_TRY_REWIND) && nvi) {
   1486  10921       Tim 			zpool_rewind_exclaim(hdl, newname ? origname : thename,
   1487  10921       Tim 			    B_TRUE, nvi);
   1488  10921       Tim 			nvlist_free(nvi);
   1489  10921       Tim 			return (-1);
   1490  10921       Tim 		}
   1491  10921       Tim 
   1492    789    ahrens 		if (newname == NULL)
   1493    789    ahrens 			(void) snprintf(desc, sizeof (desc),
   1494    789    ahrens 			    dgettext(TEXT_DOMAIN, "cannot import '%s'"),
   1495    789    ahrens 			    thename);
   1496    789    ahrens 		else
   1497    789    ahrens 			(void) snprintf(desc, sizeof (desc),
   1498    789    ahrens 			    dgettext(TEXT_DOMAIN, "cannot import '%s' as '%s'"),
   1499    789    ahrens 			    origname, thename);
   1500    789    ahrens 
   1501    789    ahrens 		switch (errno) {
   1502   1544  eschrock 		case ENOTSUP:
   1503   1544  eschrock 			/*
   1504   1544  eschrock 			 * Unsupported version.
   1505   1544  eschrock 			 */
   1506   2082  eschrock 			(void) zfs_error(hdl, EZFS_BADVERSION, desc);
   1507   2174  eschrock 			break;
   1508   2174  eschrock 
   1509   2174  eschrock 		case EINVAL:
   1510   2174  eschrock 			(void) zfs_error(hdl, EZFS_INVALCONFIG, desc);
   1511   1544  eschrock 			break;
   1512   1544  eschrock 
   1513    789    ahrens 		default:
   1514  10921       Tim 			(void) zcmd_read_dst_nvlist(hdl, &zc, &nvi);
   1515   2082  eschrock 			(void) zpool_standard_error(hdl, errno, desc);
   1516  10921       Tim 			zpool_explain_recover(hdl,
   1517  10921       Tim 			    newname ? origname : thename, -errno, nvi);
   1518  10921       Tim 			nvlist_free(nvi);
   1519  10921       Tim 			break;
   1520    789    ahrens 		}
   1521    789    ahrens 
   1522    789    ahrens 		ret = -1;
   1523    789    ahrens 	} else {
   1524    789    ahrens 		zpool_handle_t *zhp;
   1525   4543     marks 
   1526    789    ahrens 		/*
   1527    789    ahrens 		 * This should never fail, but play it safe anyway.
   1528    789    ahrens 		 */
   1529  10588      Eric 		if (zpool_open_silent(hdl, thename, &zhp) != 0)
   1530   2142  eschrock 			ret = -1;
   1531  10588      Eric 		else if (zhp != NULL)
   1532    789    ahrens 			zpool_close(zhp);
   1533  10921       Tim 		(void) zcmd_read_dst_nvlist(hdl, &zc, &nvi);
   1534  10921       Tim 		zpool_get_rewind_policy(config, &policy);
   1535  10921       Tim 		if (policy.zrp_request &
   1536  10921       Tim 		    (ZPOOL_DO_REWIND | ZPOOL_TRY_REWIND)) {
   1537  10921       Tim 			zpool_rewind_exclaim(hdl, newname ? origname : thename,
   1538  10921       Tim 			    ((policy.zrp_request & ZPOOL_TRY_REWIND) != 0),
   1539  10921       Tim 			    nvi);
   1540  10921       Tim 		}
   1541  10921       Tim 		nvlist_free(nvi);
   1542  10921       Tim 		return (0);
   1543    789    ahrens 	}
   1544   4543     marks 
   1545   5320     lling 	zcmd_free_nvlists(&zc);
   1546   5320     lling 	nvlist_free(props);
   1547    789    ahrens 
   1548    789    ahrens 	return (ret);
   1549    789    ahrens }
   1550    789    ahrens 
   1551    789    ahrens /*
   1552    789    ahrens  * Scrub the pool.
   1553    789    ahrens  */
   1554    789    ahrens int
   1555    789    ahrens zpool_scrub(zpool_handle_t *zhp, pool_scrub_type_t type)
   1556    789    ahrens {
   1557    789    ahrens 	zfs_cmd_t zc = { 0 };
   1558    789    ahrens 	char msg[1024];
   1559   2082  eschrock 	libzfs_handle_t *hdl = zhp->zpool_hdl;
   1560    789    ahrens 
   1561    789    ahrens 	(void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
   1562    789    ahrens 	zc.zc_cookie = type;
   1563    789    ahrens 
   1564   4543     marks 	if (zfs_ioctl(zhp->zpool_hdl, ZFS_IOC_POOL_SCRUB, &zc) == 0)
   1565    789    ahrens 		return (0);
   1566    789    ahrens 
   1567    789    ahrens 	(void) snprintf(msg, sizeof (msg),
   1568    789    ahrens 	    dgettext(TEXT_DOMAIN, "cannot scrub %s"), zc.zc_name);
   1569    789    ahrens 
   1570   2082  eschrock 	if (errno == EBUSY)
   1571   2082  eschrock 		return (zfs_error(hdl, EZFS_RESILVERING, msg));
   1572   2082  eschrock 	else
   1573   2082  eschrock 		return (zpool_standard_error(hdl, errno, msg));
   1574    789    ahrens }
   1575    789    ahrens 
   1576   2468  ek110237 /*
   1577   9816    George  * Find a vdev that matches the search criteria specified. We use the
   1578   9816    George  * the nvpair name to determine how we should look for the device.
   1579   2468  ek110237  * 'avail_spare' is set to TRUE if the provided guid refers to an AVAIL
   1580   2468  ek110237  * spare; but FALSE if its an INUSE spare.
   1581   2468  ek110237  */
   1582   2082  eschrock static nvlist_t *
   1583   9816    George vdev_to_nvlist_iter(nvlist_t *nv, nvlist_t *search, boolean_t *avail_spare,
   1584   9816    George     boolean_t *l2cache, boolean_t *log)
   1585   1544  eschrock {
   1586   1544  eschrock 	uint_t c, children;
   1587   1544  eschrock 	nvlist_t **child;
   1588   2082  eschrock 	nvlist_t *ret;
   1589   7326      Eric 	uint64_t is_log;
   1590   9816    George 	char *srchkey;
   1591   9816    George 	nvpair_t *pair = nvlist_next_nvpair(search, NULL);
   1592   1544  eschrock 
   1593   9816    George 	/* Nothing to look for */
   1594   9816    George 	if (search == NULL || pair == NULL)
   1595   9816    George 		return (NULL);
   1596   1544  eschrock 
   1597   9816    George 	/* Obtain the key we will use to search */
   1598   9816    George 	srchkey = nvpair_name(pair);
   1599   9816    George 
   1600   9816    George 	switch (nvpair_type(pair)) {
   1601   9816    George 	case DATA_TYPE_UINT64: {
   1602   9816    George 		uint64_t srchval, theguid, present;
   1603   9816    George 
   1604   9816    George 		verify(nvpair_value_uint64(pair, &srchval) == 0);
   1605   9816    George 		if (strcmp(srchkey, ZPOOL_CONFIG_GUID) == 0) {
   1606   9816    George 			if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_NOT_PRESENT,
   1607   9816    George 			    &present) == 0) {
   1608   9816    George 				/*
   1609   9816    George 				 * If the device has never been present since
   1610   9816    George 				 * import, the only reliable way to match the
   1611   9816    George 				 * vdev is by GUID.
   1612   9816    George 				 */
   1613   9816    George 				verify(nvlist_lookup_uint64(nv,
   1614   9816    George 				    ZPOOL_CONFIG_GUID, &theguid) == 0);
   1615   9816    George 				if (theguid == srchval)
   1616   9816    George 					return (nv);
   1617   9816    George 			}
   1618   9816    George 		}
   1619   9816    George 		break;
   1620   9816    George 	}
   1621   9816    George 
   1622   9816    George 	case DATA_TYPE_STRING: {
   1623   9816    George 		char *srchval, *val;
   1624   9816    George 
   1625   9816    George 		verify(nvpair_value_string(pair, &srchval) == 0);
   1626   9816    George 		if (nvlist_lookup_string(nv, srchkey, &val) != 0)
   1627   9816    George 			break;
   1628   9816    George 
   1629   1544  eschrock 		/*
   1630   9816    George 		 * Search for the requested value. We special case the search
   1631  10594    George 		 * for ZPOOL_CONFIG_PATH when it's a wholedisk and when
   1632  10594    George 		 * Looking for a top-level vdev name (i.e. ZPOOL_CONFIG_TYPE).
   1633  10594    George 		 * Otherwise, all other searches are simple string compares.
   1634   1544  eschrock 		 */
   1635   9816    George 		if (strcmp(srchkey, ZPOOL_CONFIG_PATH) == 0 && val) {
   1636   9816    George 			uint64_t wholedisk = 0;
   1637   9816    George 
   1638   9816    George 			(void) nvlist_lookup_uint64(nv, ZPOOL_CONFIG_WHOLE_DISK,
   1639   9816    George 			    &wholedisk);
   1640   9816    George 			if (wholedisk) {
   1641   9816    George 				/*
   1642   9816    George 				 * For whole disks, the internal path has 's0',
   1643   9816    George 				 * but the path passed in by the user doesn't.
   1644   9816    George 				 */
   1645   9816    George 				if (strlen(srchval) == strlen(val) - 2 &&
   1646   9816    George 				    strncmp(srchval, val, strlen(srchval)) == 0)
   1647   9816    George 					return (nv);
   1648   9816    George 				break;
   1649   9816    George 			}
   1650  10594    George 		} else if (strcmp(srchkey, ZPOOL_CONFIG_TYPE) == 0 && val) {
   1651  10594    George 			char *type, *idx, *end, *p;
   1652  10594    George 			uint64_t id, vdev_id;
   1653  10594    George 
   1654  10594    George 			/*
   1655  10594    George 			 * Determine our vdev type, keeping in mind
   1656  10594    George 			 * that the srchval is composed of a type and
   1657  10594    George 			 * vdev id pair (i.e. mirror-4).
   1658  10594    George 			 */
   1659  10594    George 			if ((type = strdup(srchval)) == NULL)
   1660  10594    George 				return (NULL);
   1661  10594    George 
   1662  10594    George 			if ((p = strrchr(type, '-')) == NULL) {
   1663  10594    George 				free(type);
   1664  10594    George 				break;
   1665  10594    George 			}
   1666  10594    George 			idx = p + 1;
   1667  10594    George 			*p = '\0';
   1668  10594    George 
   1669  10594    George 			/*
   1670  10594    George 			 * If the types don't match then keep looking.
   1671  10594    George 			 */
   1672  10594    George 			if (strncmp(val, type, strlen(val)) != 0) {
   1673  10594    George 				free(type);
   1674  10594    George 				break;
   1675  10594    George 			}
   1676  10594    George 
   1677  10594    George 			verify(strncmp(type, VDEV_TYPE_RAIDZ,
   1678  10594    George 			    strlen(VDEV_TYPE_RAIDZ)) == 0 ||
   1679  10594    George 			    strncmp(type, VDEV_TYPE_MIRROR,
   1680  10594    George 			    strlen(VDEV_TYPE_MIRROR)) == 0);
   1681  10594    George 			verify(nvlist_lookup_uint64(nv, ZPOOL_CONFIG_ID,
   1682  10594    George 			    &id) == 0);
   1683  10594    George 
   1684  10594    George 			errno = 0;
   1685  10594    George 			vdev_id = strtoull(idx, &end, 10);
   1686  10594    George 
   1687  10594    George 			free(type);
   1688  10594    George 			if (errno != 0)
   1689  10594    George 				return (NULL);
   1690  10594    George 
   1691  10594    George 			/*
   1692  10594    George 			 * Now verify that we have the correct vdev id.
   1693  10594    George 			 */
   1694  10594    George 			if (vdev_id == id)
   1695  10594    George 				return (nv);
   1696   9816    George 		}
   1697   9816    George 
   1698   9816    George 		/*
   1699   9816    George 		 * Common case
   1700   9816    George 		 */
   1701   9816    George 		if (strcmp(srchval, val) == 0)
   1702   2082  eschrock 			return (nv);
   1703   9816    George 		break;
   1704   9816    George 	}
   1705   9816    George 
   1706   9816    George 	default:
   1707   9816    George 		break;
   1708   1544  eschrock 	}
   1709   1544  eschrock 
   1710   1544  eschrock 	if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
   1711   1544  eschrock 	    &child, &children) != 0)
   1712   2082  eschrock 		return (NULL);
   1713   1544  eschrock 
   1714   7326      Eric 	for (c = 0; c < children; c++) {
   1715   9816    George 		if ((ret = vdev_to_nvlist_iter(child[c], search,
   1716   7326      Eric 		    avail_spare, l2cache, NULL)) != NULL) {
   1717   7326      Eric 			/*
   1718   7326      Eric 			 * The 'is_log' value is only set for the toplevel
   1719   7326      Eric 			 * vdev, not the leaf vdevs.  So we always lookup the
   1720   7326      Eric 			 * log device from the root of the vdev tree (where
   1721   7326      Eric 			 * 'log' is non-NULL).
   1722   7326      Eric 			 */
   1723   7326      Eric 			if (log != NULL &&
   1724   7326      Eric 			    nvlist_lookup_uint64(child[c],
   1725   7326      Eric 			    ZPOOL_CONFIG_IS_LOG, &is_log) == 0 &&
   1726   7326      Eric 			    is_log) {
   1727   7326      Eric 				*log = B_TRUE;
   1728   7326      Eric 			}
   1729   1544  eschrock 			return (ret);
   1730   7326      Eric 		}
   1731   7326      Eric 	}
   1732   1544  eschrock 
   1733   2082  eschrock 	if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_SPARES,
   1734   2082  eschrock 	    &child, &children) == 0) {
   1735   2082  eschrock 		for (c = 0; c < children; c++) {
   1736   9816    George 			if ((ret = vdev_to_nvlist_iter(child[c], search,
   1737   7326      Eric 			    avail_spare, l2cache, NULL)) != NULL) {
   1738   2468  ek110237 				*avail_spare = B_TRUE;
   1739   5450   brendan 				return (ret);
   1740   5450   brendan 			}
   1741   5450   brendan 		}
   1742   5450   brendan 	}
   1743   5450   brendan 
   1744   5450   brendan 	if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_L2CACHE,
   1745   5450   brendan 	    &child, &children) == 0) {
   1746   5450   brendan 		for (c = 0; c < children; c++) {
   1747   9816    George 			if ((ret = vdev_to_nvlist_iter(child[c], search,
   1748   7326      Eric 			    avail_spare, l2cache, NULL)) != NULL) {
   1749   5450   brendan 				*l2cache = B_TRUE;
   1750   2082  eschrock 				return (ret);
   1751   2082  eschrock 			}
   1752   2082  eschrock 		}
   1753   2082  eschrock 	}
   1754   2082  eschrock 
   1755   2082  eschrock 	return (NULL);
   1756   1544  eschrock }
   1757   1544  eschrock 
   1758   9816    George /*
   1759   9816    George  * Given a physical path (minus the "/devices" prefix), find the
   1760   9816    George  * associated vdev.
   1761   9816    George  */
   1762   9816    George nvlist_t *
   1763   9816    George zpool_find_vdev_by_physpath(zpool_handle_t *zhp, const char *ppath,
   1764   9816    George     boolean_t *avail_spare, boolean_t *l2cache, boolean_t *log)
   1765   9816    George {
   1766   9816    George 	nvlist_t *search, *nvroot, *ret;
   1767   9816    George 
   1768   9816    George 	verify(nvlist_alloc(&search, NV_UNIQUE_NAME, KM_SLEEP) == 0);
   1769   9816    George 	verify(nvlist_add_string(search, ZPOOL_CONFIG_PHYS_PATH, ppath) == 0);
   1770   9816    George 
   1771   9816    George 	verify(nvlist_lookup_nvlist(zhp->zpool_config, ZPOOL_CONFIG_VDEV_TREE,
   1772   9816    George 	    &nvroot) == 0);
   1773   9816    George 
   1774   9816    George 	*avail_spare = B_FALSE;
   1775   9816    George 	ret = vdev_to_nvlist_iter(nvroot, search, avail_spare, l2cache, log);
   1776   9816    George 	nvlist_free(search);
   1777   9816    George 
   1778   9816    George 	return (ret);
   1779   9816    George }
   1780   9816    George 
   1781  10594    George /*
   1782  10594    George  * Determine if we have an "interior" top-level vdev (i.e mirror/raidz).
   1783  10594    George  */
   1784  10594    George boolean_t
   1785  10594    George zpool_vdev_is_interior(const char *name)
   1786  10594    George {
   1787  10594    George 	if (strncmp(name, VDEV_TYPE_RAIDZ, strlen(VDEV_TYPE_RAIDZ)) == 0 ||
   1788  10594    George 	    strncmp(name, VDEV_TYPE_MIRROR, strlen(VDEV_TYPE_MIRROR)) == 0)
   1789  10594    George 		return (B_TRUE);
   1790  10594    George 	return (B_FALSE);
   1791  10594    George }
   1792  10594    George 
   1793   2082  eschrock nvlist_t *
   1794   5450   brendan zpool_find_vdev(zpool_handle_t *zhp, const char *path, boolean_t *avail_spare,
   1795   7326      Eric     boolean_t *l2cache, boolean_t *log)
   1796   1544  eschrock {
   1797   1544  eschrock 	char buf[MAXPATHLEN];
   1798   1544  eschrock 	char *end;
   1799   9816    George 	nvlist_t *nvroot, *search, *ret;
   1800   1544  eschrock 	uint64_t guid;
   1801   9816    George 
   1802   9816    George 	verify(nvlist_alloc(&search, NV_UNIQUE_NAME, KM_SLEEP) == 0);
   1803   1544  eschrock 
   1804   1613  eschrock 	guid = strtoull(path, &end, 10);
   1805   1544  eschrock 	if (guid != 0 && *end == '\0') {
   1806   9816    George 		verify(nvlist_add_uint64(search, ZPOOL_CONFIG_GUID, guid) == 0);
   1807  10594    George 	} else if (zpool_vdev_is_interior(path)) {
   1808  10594    George 		verify(nvlist_add_string(search, ZPOOL_CONFIG_TYPE, path) == 0);
   1809   1544  eschrock 	} else if (path[0] != '/') {
   1810   1544  eschrock 		(void) snprintf(buf, sizeof (buf), "%s%s", "/dev/dsk/", path);
   1811   9816    George 		verify(nvlist_add_string(search, ZPOOL_CONFIG_PATH, buf) == 0);
   1812   1544  eschrock 	} else {
   1813   9816    George 		verify(nvlist_add_string(search, ZPOOL_CONFIG_PATH, path) == 0);
   1814   1544  eschrock 	}
   1815   1544  eschrock 
   1816   1544  eschrock 	verify(nvlist_lookup_nvlist(zhp->zpool_config, ZPOOL_CONFIG_VDEV_TREE,
   1817   1544  eschrock 	    &nvroot) == 0);
   1818   1544  eschrock 
   1819   2468  ek110237 	*avail_spare = B_FALSE;
   1820   5450   brendan 	*l2cache = B_FALSE;
   1821   7326      Eric 	if (log != NULL)
   1822   7326      Eric 		*log = B_FALSE;
   1823   9816    George 	ret = vdev_to_nvlist_iter(nvroot, search, avail_spare, l2cache, log);
   1824   9816    George 	nvlist_free(search);
   1825   9816    George 
   1826   9816    George 	return (ret);
   1827   7656    Sherry }
   1828   7656    Sherry 
   1829   7656    Sherry static int
   1830   7656    Sherry vdev_online(nvlist_t *nv)
   1831   7656    Sherry {
   1832   7656    Sherry 	uint64_t ival;
   1833   7656    Sherry 
   1834   7656    Sherry 	if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_OFFLINE, &ival) == 0 ||
   1835   7656    Sherry 	    nvlist_lookup_uint64(nv, ZPOOL_CONFIG_FAULTED, &ival) == 0 ||
   1836   7656    Sherry 	    nvlist_lookup_uint64(nv, ZPOOL_CONFIG_REMOVED, &ival) == 0)
   1837   7656    Sherry 		return (0);
   1838   7656    Sherry 
   1839   7656    Sherry 	return (1);
   1840   7656    Sherry }
   1841   7656    Sherry 
   1842   7656    Sherry /*
   1843   9790       Lin  * Helper function for zpool_get_physpaths().
   1844   9160    Sherry  */
   1845   9160    Sherry static int
   1846   9790       Lin vdev_get_one_physpath(nvlist_t *config, char *physpath, size_t physpath_size,
   1847   9160    Sherry     size_t *bytes_written)
   1848   9160    Sherry {
   1849   9160    Sherry 	size_t bytes_left, pos, rsz;
   1850   9160    Sherry 	char *tmppath;
   1851   9160    Sherry 	const char *format;
   1852   9160    Sherry 
   1853   9160    Sherry 	if (nvlist_lookup_string(config, ZPOOL_CONFIG_PHYS_PATH,
   1854   9160    Sherry 	    &tmppath) != 0)
   1855   9160    Sherry 		return (EZFS_NODEVICE);
   1856   9160    Sherry 
   1857   9160    Sherry 	pos = *bytes_written;
   1858   9160    Sherry 	bytes_left = physpath_size - pos;
   1859   9160    Sherry 	format = (pos == 0) ? "%s" : " %s";
   1860   9160    Sherry 
   1861   9160    Sherry 	rsz = snprintf(physpath + pos, bytes_left, format, tmppath);
   1862   9160    Sherry 	*bytes_written += rsz;
   1863   9160    Sherry 
   1864   9160    Sherry 	if (rsz >= bytes_left) {
   1865   9160    Sherry 		/* if physpath was not copied properly, clear it */
   1866   9160    Sherry 		if (bytes_left != 0) {
   1867   9160    Sherry 			physpath[pos] = 0;
   1868   9160    Sherry 		}
   1869   9160    Sherry 		return (EZFS_NOSPC);
   1870   9160    Sherry 	}
   1871   9160    Sherry 	return (0);
   1872   9160    Sherry }
   1873   9160    Sherry 
   1874   9790       Lin static int
   1875   9790       Lin vdev_get_physpaths(nvlist_t *nv, char *physpath, size_t phypath_size,
   1876   9790       Lin     size_t *rsz, boolean_t is_spare)
   1877   9790       Lin {
   1878   9790       Lin 	char *type;
   1879   9790       Lin 	int ret;
   1880   9790       Lin 
   1881   9790       Lin 	if (nvlist_lookup_string(nv, ZPOOL_CONFIG_TYPE, &type) != 0)
   1882   9790       Lin 		return (EZFS_INVALCONFIG);
   1883   9790       Lin 
   1884   9790       Lin 	if (strcmp(type, VDEV_TYPE_DISK) == 0) {
   1885   9790       Lin 		/*
   1886   9790       Lin 		 * An active spare device has ZPOOL_CONFIG_IS_SPARE set.
   1887   9790       Lin 		 * For a spare vdev, we only want to boot from the active
   1888   9790       Lin 		 * spare device.
   1889   9790       Lin 		 */
   1890   9790       Lin 		if (is_spare) {
   1891   9790       Lin 			uint64_t spare = 0;
   1892   9790       Lin 			(void) nvlist_lookup_uint64(nv, ZPOOL_CONFIG_IS_SPARE,
   1893   9790       Lin 			    &spare);
   1894   9790       Lin 			if (!spare)
   1895   9790       Lin 				return (EZFS_INVALCONFIG);
   1896   9790       Lin 		}
   1897   9790       Lin 
   1898   9790       Lin 		if (vdev_online(nv)) {
   1899   9790       Lin 			if ((ret = vdev_get_one_physpath(nv, physpath,
   1900   9790       Lin 			    phypath_size, rsz)) != 0)
   1901   9790       Lin 				return (ret);
   1902   9790       Lin 		}
   1903   9790       Lin 	} else if (strcmp(type, VDEV_TYPE_MIRROR) == 0 ||
   1904   9790       Lin 	    strcmp(type, VDEV_TYPE_REPLACING) == 0 ||
   1905   9790       Lin 	    (is_spare = (strcmp(type, VDEV_TYPE_SPARE) == 0))) {
   1906   9790       Lin 		nvlist_t **child;
   1907   9790       Lin 		uint_t count;
   1908   9790       Lin 		int i, ret;
   1909   9790       Lin 
   1910   9790       Lin 		if (nvlist_lookup_nvlist_array(nv,
   1911   9790       Lin 		    ZPOOL_CONFIG_CHILDREN, &child, &count) != 0)
   1912   9790       Lin 			return (EZFS_INVALCONFIG);
   1913   9790       Lin 
   1914   9790       Lin 		for (i = 0; i < count; i++) {
   1915   9790       Lin 			ret = vdev_get_physpaths(child[i], physpath,
   1916   9790       Lin 			    phypath_size, rsz, is_spare);
   1917   9790       Lin 			if (ret == EZFS_NOSPC)
   1918   9790       Lin 				return (ret);
   1919   9790       Lin 		}
   1920   9790       Lin 	}
   1921   9790       Lin 
   1922   9790       Lin 	return (EZFS_POOL_INVALARG);
   1923   9790       Lin }
   1924   9790       Lin 
   1925   9160    Sherry /*
   1926   9160    Sherry  * Get phys_path for a root pool config.
   1927   9160    Sherry  * Return 0 on success; non-zero on failure.
   1928   9160    Sherry  */
   1929   9160    Sherry static int
   1930   9160    Sherry zpool_get_config_physpath(nvlist_t *config, char *physpath, size_t phypath_size)
   1931   9160    Sherry {
   1932   9160    Sherry 	size_t rsz;
   1933   9160    Sherry 	nvlist_t *vdev_root;
   1934   9160    Sherry 	nvlist_t **child;
   1935   9160    Sherry 	uint_t count;
   1936   9160    Sherry 	char *type;
   1937   9160    Sherry 
   1938   9160    Sherry 	rsz = 0;
   1939   9160    Sherry 
   1940   9160    Sherry 	if (nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
   1941   9160    Sherry 	    &vdev_root) != 0)
   1942   9160    Sherry 		return (EZFS_INVALCONFIG);
   1943   9160    Sherry 
   1944   9160    Sherry 	if (nvlist_lookup_string(vdev_root, ZPOOL_CONFIG_TYPE, &type) != 0 ||
   1945   9160    Sherry 	    nvlist_lookup_nvlist_array(vdev_root, ZPOOL_CONFIG_CHILDREN,
   1946   9160    Sherry 	    &child, &count) != 0)
   1947   9160    Sherry 		return (EZFS_INVALCONFIG);
   1948   9160    Sherry 
   1949   9160    Sherry 	/*
   1950   9160    Sherry 	 * root pool can not have EFI labeled disks and can only have
   1951   9160    Sherry 	 * a single top-level vdev.
   1952   9160    Sherry 	 */
   1953   9160    Sherry 	if (strcmp(type, VDEV_TYPE_ROOT) != 0 || count != 1 ||
   1954   9160    Sherry 	    pool_uses_efi(vdev_root))
   1955   9160    Sherry 		return (EZFS_POOL_INVALARG);
   1956   9160    Sherry 
   1957   9790       Lin 	(void) vdev_get_physpaths(child[0], physpath, phypath_size, &rsz,
   1958   9790       Lin 	    B_FALSE);
   1959   9160    Sherry 
   1960   9160    Sherry 	/* No online devices */
   1961   9160    Sherry 	if (rsz == 0)
   1962   9160    Sherry 		return (EZFS_NODEVICE);
   1963   9160    Sherry 
   1964   9160    Sherry 	return (0);
   1965   9160    Sherry }
   1966   9160    Sherry 
   1967   9160    Sherry /*
   1968   7656    Sherry  * Get phys_path for a root pool
   1969   9160    Sherry  * Return 0 on success; non-zero on failure.
   1970   7656    Sherry  */
   1971   7656    Sherry int
   1972   9160    Sherry zpool_get_physpath(zpool_handle_t *zhp, char *physpath, size_t phypath_size)
   1973   7656    Sherry {
   1974   9160    Sherry 	return (zpool_get_config_physpath(zhp->zpool_config, physpath,
   1975   9160    Sherry 	    phypath_size));
   1976   2468  ek110237 }
   1977   2468  ek110237 
   1978   2468  ek110237 /*
   1979   9816    George  * If the device has being dynamically expanded then we need to relabel
   1980   9816    George  * the disk to use the new unallocated space.
   1981   9816    George  */
   1982   9816    George static int
   1983   9816    George zpool_relabel_disk(libzfs_handle_t *hdl, const char *name)
   1984   9816    George {
   1985   9816    George 	char path[MAXPATHLEN];
   1986   9816    George 	char errbuf[1024];
   1987   9816    George 	int fd, error;
   1988   9816    George 	int (*_efi_use_whole_disk)(int);
   1989   9816    George 
   1990   9816    George 	if ((_efi_use_whole_disk = (int (*)(int))dlsym(RTLD_DEFAULT,
   1991   9816    George 	    "efi_use_whole_disk")) == NULL)
   1992   9816    George 		return (-1);
   1993   9816    George 
   1994   9816    George 	(void) snprintf(path, sizeof (path), "%s/%s", RDISK_ROOT, name);
   1995   9816    George 
   1996   9816    George 	if ((fd = open(path, O_RDWR | O_NDELAY)) < 0) {
   1997   9816    George 		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "cannot "
   1998   9816    George 		    "relabel '%s': unable to open device"), name);
   1999   9816    George 		return (zfs_error(hdl, EZFS_OPENFAILED, errbuf));
   2000   9816    George 	}
   2001   9816    George 
   2002   9816    George 	/*
   2003   9816    George 	 * It's possible that we might encounter an error if the device
   2004   9816    George 	 * does not have any unallocated space left. If so, we simply
   2005   9816    George 	 * ignore that error and continue on.
   2006   9816    George 	 */
   2007   9816    George 	error = _efi_use_whole_disk(fd);
   2008   9816    George 	(void) close(fd);
   2009   9816    George 	if (error && error != VT_ENOSPC) {
   2010   9816    George 		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "cannot "
   2011   9816    George 		    "relabel '%s': unable to read disk capacity"), name);
   2012   9816    George 		return (zfs_error(hdl, EZFS_NOCAP, errbuf));
   2013   9816    George 	}
   2014   9816    George 	return (0);
   2015   9816    George }
   2016   9816    George 
   2017   9816    George /*
   2018   4451  eschrock  * Bring the specified vdev online.   The 'flags' parameter is a set of the
   2019   4451  eschrock  * ZFS_ONLINE_* flags.
   2020    789    ahrens  */
   2021    789    ahrens int
   2022   4451  eschrock zpool_vdev_online(zpool_handle_t *zhp, const char *path, int flags,
   2023   4451  eschrock     vdev_state_t *newstate)
   2024    789    ahrens {
   2025    789    ahrens 	zfs_cmd_t zc = { 0 };
   2026    789    ahrens 	char msg[1024];
   2027   2082  eschrock 	nvlist_t *tgt;
   2028   9816    George 	boolean_t avail_spare, l2cache, islog;
   2029   2082  eschrock 	libzfs_handle_t *hdl = zhp->zpool_hdl;
   2030    789    ahrens 
   2031   9816    George 	if (flags & ZFS_ONLINE_EXPAND) {
   2032   9816    George 		(void) snprintf(msg, sizeof (msg),
   2033   9816    George 		    dgettext(TEXT_DOMAIN, "cannot expand %s"), path);
   2034   9816    George 	} else {
   2035   9816    George 		(void) snprintf(msg, sizeof (msg),
   2036   9816    George 		    dgettext(TEXT_DOMAIN, "cannot online %s"), path);
   2037   9816    George 	}
   2038   1544  eschrock 
   2039    789    ahrens 	(void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
   2040   7326      Eric 	if ((tgt = zpool_find_vdev(zhp, path, &avail_spare, &l2cache,
   2041   9816    George 	    &islog)) == NULL)
   2042   2082  eschrock 		return (zfs_error(hdl, EZFS_NODEVICE, msg));
   2043    789    ahrens 
   2044   2468  ek110237 	verify(nvlist_lookup_uint64(tgt, ZPOOL_CONFIG_GUID, &zc.zc_guid) == 0);
   2045   2468  ek110237 
   2046  10817      Eric 	if (avail_spare)
   2047   2082  eschrock 		return (zfs_error(hdl, EZFS_ISSPARE, msg));
   2048   9816    George 
   2049   9816    George 	if (flags & ZFS_ONLINE_EXPAND ||
   2050   9816    George 	    zpool_get_prop_int(zhp, ZPOOL_PROP_AUTOEXPAND, NULL)) {
   2051   9816    George 		char *pathname = NULL;
   2052   9816    George 		uint64_t wholedisk = 0;
   2053   9816    George 
   2054   9816    George 		(void) nvlist_lookup_uint64(tgt, ZPOOL_CONFIG_WHOLE_DISK,
   2055   9816    George 		    &wholedisk);
   2056   9816    George 		verify(nvlist_lookup_string(tgt, ZPOOL_CONFIG_PATH,
   2057   9816    George 		    &pathname) == 0);
   2058   9816    George 
   2059   9816    George 		/*
   2060   9816    George 		 * XXX - L2ARC 1.0 devices can't support expansion.
   2061   9816    George 		 */
   2062   9816    George 		if (l2cache) {
   2063   9816    George 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
   2064   9816    George 			    "cannot expand cache devices"));
   2065   9816    George 			return (zfs_error(hdl, EZFS_VDEVNOTSUP, msg));
   2066   9816    George 		}
   2067   9816    George 
   2068   9816    George 		if (wholedisk) {
   2069   9816    George 			pathname += strlen(DISK_ROOT) + 1;
   2070   9816    George 			(void) zpool_relabel_disk(zhp->zpool_hdl, pathname);
   2071   9816    George 		}
   2072   9816    George 	}
   2073   5450   brendan 
   2074   4451  eschrock 	zc.zc_cookie = VDEV_STATE_ONLINE;
   2075   4451  eschrock 	zc.zc_obj = flags;
   2076   4451  eschrock 
   2077   4543     marks 	if (zfs_ioctl(zhp->zpool_hdl, ZFS_IOC_VDEV_SET_STATE, &zc) != 0)
   2078   4451  eschrock 		return (zpool_standard_error(hdl, errno, msg));
   2079   4451  eschrock 
   2080   4451  eschrock 	*newstate = zc.zc_cookie;
   2081   4451  eschrock 	return (0);
   2082    789    ahrens }
   2083    789    ahrens 
   2084    789    ahrens /*
   2085    789    ahrens  * Take the specified vdev offline
   2086    789    ahrens  */
   2087    789    ahrens int
   2088   4451  eschrock zpool_vdev_offline(zpool_handle_t *zhp, const char *path, boolean_t istmp)
   2089    789    ahrens {
   2090    789    ahrens 	zfs_cmd_t zc = { 0 };
   2091    789    ahrens 	char msg[1024];
   2092   2082  eschrock 	nvlist_t *tgt;
   2093   5450   brendan 	boolean_t avail_spare, l2cache;
   2094   2082  eschrock 	libzfs_handle_t *hdl = zhp->zpool_hdl;
   2095    789    ahrens 
   2096   1544  eschrock 	(void) snprintf(msg, sizeof (msg),
   2097   1544  eschrock 	    dgettext(TEXT_DOMAIN, "cannot offline %s"), path);
   2098   1544  eschrock 
   2099    789    ahrens 	(void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
   2100   7326      Eric 	if ((tgt = zpool_find_vdev(zhp, path, &avail_spare, &l2cache,
   2101   7326      Eric 	    NULL)) == NULL)
   2102   2082  eschrock 		return (zfs_error(hdl, EZFS_NODEVICE, msg));
   2103   2082  eschrock 
   2104   2468  ek110237 	verify(nvlist_lookup_uint64(tgt, ZPOOL_CONFIG_GUID, &zc.zc_guid) == 0);
   2105   2468  ek110237 
   2106  10817      Eric 	if (avail_spare)
   2107   2082  eschrock 		return (zfs_error(hdl, EZFS_ISSPARE, msg));
   2108   1485     lling 
   2109   4451  eschrock 	zc.zc_cookie = VDEV_STATE_OFFLINE;
   2110   4451  eschrock 	zc.zc_obj = istmp ? ZFS_OFFLINE_TEMPORARY : 0;
   2111    789    ahrens 
   2112   4543     marks 	if (zfs_ioctl(zhp->zpool_hdl, ZFS_IOC_VDEV_SET_STATE, &zc) == 0)
   2113    789    ahrens 		return (0);
   2114    789    ahrens 
   2115    789    ahrens 	switch (errno) {
   2116   2082  eschrock 	case EBUSY:
   2117    789    ahrens 
   2118    789    ahrens 		/*
   2119    789    ahrens 		 * There are no other replicas of this device.
   2120    789    ahrens 		 */
   2121   2082  eschrock 		return (zfs_error(hdl, EZFS_NOREPLICAS, msg));
   2122   9701    George 
   2123   9701    George 	case EEXIST:
   2124   9701    George 		/*
   2125   9701    George 		 * The log device has unplayed logs
   2126   9701    George 		 */
   2127   9701    George 		return (zfs_error(hdl, EZFS_UNPLAYED_LOGS, msg));
   2128    789    ahrens 
   2129   2082  eschrock 	default:
   2130   2082  eschrock 		return (zpool_standard_error(hdl, errno, msg));
   2131    789    ahrens 	}
   2132   4451  eschrock }
   2133   4451  eschrock 
   2134   4451  eschrock /*
   2135   4451  eschrock  * Mark the given vdev faulted.
   2136   4451  eschrock  */
   2137   4451  eschrock int
   2138  10817      Eric zpool_vdev_fault(zpool_handle_t *zhp, uint64_t guid, vdev_aux_t aux)
   2139   4451  eschrock {
   2140   4451  eschrock 	zfs_cmd_t zc = { 0 };
   2141   4451  eschrock 	char msg[1024];
   2142   4451  eschrock 	libzfs_handle_t *hdl = zhp->zpool_hdl;
   2143   4451  eschrock 
   2144   4451  eschrock 	(void) snprintf(msg, sizeof (msg),
   2145   4451  eschrock 	    dgettext(TEXT_DOMAIN, "cannot fault %llu"), guid);
   2146   4451  eschrock 
   2147   4451  eschrock 	(void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
   2148   4451  eschrock 	zc.zc_guid = guid;
   2149   4451  eschrock 	zc.zc_cookie = VDEV_STATE_FAULTED;
   2150  10817      Eric 	zc.zc_obj = aux;
   2151   4451  eschrock 
   2152   4451  eschrock 	if (ioctl(zhp->zpool_hdl->libzfs_fd, ZFS_IOC_VDEV_SET_STATE, &zc) == 0)
   2153   4451  eschrock 		return (0);
   2154   4451  eschrock 
   2155   4451  eschrock 	switch (errno) {
   2156   4451  eschrock 	case EBUSY:
   2157   4451  eschrock 
   2158   4451  eschrock 		/*
   2159   4451  eschrock 		 * There are no other replicas of this device.
   2160   4451  eschrock 		 */
   2161   4451  eschrock 		return (zfs_error(hdl, EZFS_NOREPLICAS, msg));
   2162   4451  eschrock 
   2163   4451  eschrock 	default:
   2164   4451  eschrock 		return (zpool_standard_error(hdl, errno, msg));
   2165   4451  eschrock 	}
   2166   4451  eschrock 
   2167   4451  eschrock }
   2168   4451  eschrock 
   2169   4451  eschrock /*
   2170   4451  eschrock  * Mark the given vdev degraded.
   2171   4451  eschrock  */
   2172   4451  eschrock int
   2173  10817      Eric zpool_vdev_degrade(zpool_handle_t *zhp, uint64_t guid, vdev_aux_t aux)
   2174   4451  eschrock {
   2175   4451  eschrock 	zfs_cmd_t zc = { 0 };
   2176   4451  eschrock 	char msg[1024];
   2177   4451  eschrock 	libzfs_handle_t *hdl = zhp->zpool_hdl;
   2178   4451  eschrock 
   2179   4451  eschrock 	(void) snprintf(msg, sizeof (msg),
   2180   4451  eschrock 	    dgettext(TEXT_DOMAIN, "cannot degrade %llu"), guid);
   2181   4451  eschrock 
   2182   4451  eschrock 	(void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
   2183   4451  eschrock 	zc.zc_guid = guid;
   2184   4451  eschrock 	zc.zc_cookie = VDEV_STATE_DEGRADED;
   2185  10817      Eric 	zc.zc_obj = aux;
   2186   4451  eschrock 
   2187   4451  eschrock 	if (ioctl(zhp->zpool_hdl->libzfs_fd, ZFS_IOC_VDEV_SET_STATE, &zc) == 0)
   2188   4451  eschrock 		return (0);
   2189   4451  eschrock 
   2190   4451  eschrock 	return (zpool_standard_error(hdl, errno, msg));
   2191   2082  eschrock }
   2192   2082  eschrock 
   2193   2082  eschrock /*
   2194   2082  eschrock  * Returns TRUE if the given nvlist is a vdev that was originally swapped in as
   2195   2082  eschrock  * a hot spare.
   2196   2082  eschrock  */
   2197   2082  eschrock static boolean_t
   2198   2082  eschrock is_replacing_spare(nvlist_t *search, nvlist_t *tgt, int which)
   2199   2082  eschrock {
   2200   2082  eschrock 	nvlist_t **child;
   2201   2082  eschrock 	uint_t c, children;
   2202   2082  eschrock 	char *type;
   2203   2082  eschrock 
   2204   2082  eschrock 	if (nvlist_lookup_nvlist_array(search, ZPOOL_CONFIG_CHILDREN, &child,
   2205   2082  eschrock 	    &children) == 0) {
   2206   2082  eschrock 		verify(nvlist_lookup_string(search, ZPOOL_CONFIG_TYPE,
   2207   2082  eschrock 		    &type) == 0);
   2208   2082  eschrock 
   2209   2082  eschrock 		if (strcmp(type, VDEV_TYPE_SPARE) == 0 &&
   2210   2082  eschrock 		    children == 2 && child[which] == tgt)
   2211   2082  eschrock 			return (B_TRUE);
   2212   2082  eschrock 
   2213   2082  eschrock 		for (c = 0; c < children; c++)
   2214   2082  eschrock 			if (is_replacing_spare(child[c], tgt, which))
   2215   2082  eschrock 				return (B_TRUE);
   2216   2082  eschrock 	}
   2217   2082  eschrock 
   2218   2082  eschrock 	return (B_FALSE);
   2219    789    ahrens }
   2220    789    ahrens 
   2221    789    ahrens /*
   2222    789    ahrens  * Attach new_disk (fully described by nvroot) to old_disk.
   2223   4527    perrin  * If 'replacing' is specified, the new disk will replace the old one.
   2224    789    ahrens  */
   2225    789    ahrens int
   2226    789    ahrens zpool_vdev_attach(zpool_handle_t *zhp,
   2227    789    ahrens     const char *old_disk, const char *new_disk, nvlist_t *nvroot, int replacing)
   2228    789    ahrens {
   2229    789    ahrens 	zfs_cmd_t zc = { 0 };
   2230    789    ahrens 	char msg[1024];
   2231    789    ahrens 	int ret;
   2232   2082  eschrock 	nvlist_t *tgt;
   2233   7326      Eric 	boolean_t avail_spare, l2cache, islog;
   2234   7326      Eric 	uint64_t val;
   2235   7041  eschrock 	char *path, *newname;
   2236   2082  eschrock 	nvlist_t **child;
   2237   2082  eschrock 	uint_t children;
   2238   2082  eschrock 	nvlist_t *config_root;
   2239   2082  eschrock 	libzfs_handle_t *hdl = zhp->zpool_hdl;
   2240   7965    George 	boolean_t rootpool = pool_is_bootable(zhp);
   2241    789    ahrens 
   2242   1544  eschrock 	if (replacing)
   2243   1544  eschrock 		(void) snprintf(msg, sizeof (msg), dgettext(TEXT_DOMAIN,
   2244   1544  eschrock 		    "cannot replace %s with %s"), old_disk, new_disk);
   2245   1544  eschrock 	else
   2246   1544  eschrock 		(void) snprintf(msg, sizeof (msg), dgettext(TEXT_DOMAIN,
   2247   1544  eschrock 		    "cannot attach %s to %s"), new_disk, old_disk);
   2248   7965    George 
   2249   7965    George 	/*
   2250   7965    George 	 * If this is a root pool, make sure that we're not attaching an
   2251   7965    George 	 * EFI labeled device.
   2252   7965    George 	 */
   2253   7965    George 	if (rootpool && pool_uses_efi(nvroot)) {
   2254   7965    George 		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
   2255   7965    George 		    "EFI labeled devices are not supported on root pools."));
   2256   7965    George 		return (zfs_error(hdl, EZFS_POOL_NOTSUP, msg));
   2257   7965    George 	}
   2258   1544  eschrock 
   2259    789    ahrens 	(void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
   2260   7326      Eric 	if ((tgt = zpool_find_vdev(zhp, old_disk, &avail_spare, &l2cache,
   2261   7326      Eric 	    &islog)) == 0)
   2262   2082  eschrock 		return (zfs_error(hdl, EZFS_NODEVICE, msg));
   2263   2082  eschrock 
   2264   2468  ek110237 	if (avail_spare)
   2265   2082  eschrock 		return (zfs_error(hdl, EZFS_ISSPARE, msg));
   2266   5450   brendan 
   2267   5450   brendan 	if (l2cache)
   2268   5450   brendan 		return (zfs_error(hdl, EZFS_ISL2CACHE, msg));
   2269   2082  eschrock 
   2270   2082  eschrock 	verify(nvlist_lookup_uint64(tgt, ZPOOL_CONFIG_GUID, &zc.zc_guid) == 0);
   2271   2082  eschrock 	zc.zc_cookie = replacing;
   2272   2082  eschrock 
   2273   2082  eschrock 	if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_CHILDREN,
   2274   2082  eschrock 	    &child, &children) != 0 || children != 1) {
   2275   2082  eschrock 		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
   2276   2082  eschrock 		    "new device must be a single disk"));
   2277   2082  eschrock 		return (zfs_error(hdl, EZFS_INVALCONFIG, msg));
   2278   1544  eschrock 	}
   2279   2082  eschrock 
   2280   2082  eschrock 	verify(nvlist_lookup_nvlist(zpool_get_config(zhp, NULL),
   2281   2082  eschrock 	    ZPOOL_CONFIG_VDEV_TREE, &config_root) == 0);
   2282   2082  eschrock 
   2283  10594    George 	if ((newname = zpool_vdev_name(NULL, NULL, child[0], B_FALSE)) == NULL)
   2284   7041  eschrock 		return (-1);
   2285   7041  eschrock 
   2286   2082  eschrock 	/*
   2287   2082  eschrock 	 * If the target is a hot spare that has been swapped in, we can only
   2288   2082  eschrock 	 * replace it with another hot spare.
   2289   2082  eschrock 	 */
   2290   2082  eschrock 	if (replacing &&
   2291   2082  eschrock 	    nvlist_lookup_uint64(tgt, ZPOOL_CONFIG_IS_SPARE, &val) == 0 &&
   2292   7326      Eric 	    (zpool_find_vdev(zhp, newname, &avail_spare, &l2cache,
   2293   7326      Eric 	    NULL) == NULL || !avail_spare) &&
   2294   7326      Eric 	    is_replacing_spare(config_root, tgt, 1)) {
   2295   2082  eschrock 		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
   2296   2082  eschrock 		    "can only be replaced by another hot spare"));
   2297   7041  eschrock 		free(newname);
   2298   2082  eschrock 		return (zfs_error(hdl, EZFS_BADTARGET, msg));
   2299   2082  eschrock 	}
   2300   2082  eschrock 
   2301   2082  eschrock 	/*
   2302   2082  eschrock 	 * If we are attempting to replace a spare, it canot be applied to an
   2303   2082  eschrock 	 * already spared device.
   2304   2082  eschrock 	 */
   2305   2082  eschrock 	if (replacing &&
   2306   2082  eschrock 	    nvlist_lookup_string(child[0], ZPOOL_CONFIG_PATH, &path) == 0 &&
   2307   7326      Eric 	    zpool_find_vdev(zhp, newname, &avail_spare,
   2308   7326      Eric 	    &l2cache, NULL) != NULL && avail_spare &&
   2309   7326      Eric 	    is_replacing_spare(config_root, tgt, 0)) {
   2310   2082  eschrock 		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
   2311   2082  eschrock 		    "device has already been replaced with a spare"));
   2312   7041  eschrock 		free(newname);
   2313   2082  eschrock 		return (zfs_error(hdl, EZFS_BADTARGET, msg));
   2314   2082  eschrock 	}
   2315   7041  eschrock 
   2316   7041  eschrock 	free(newname);
   2317    789    ahrens 
   2318   5094     lling 	if (zcmd_write_conf_nvlist(hdl, &zc, nvroot) != 0)
   2319   2082  eschrock 		return (-1);
   2320    789    ahrens 
   2321   4543     marks 	ret = zfs_ioctl(zhp->zpool_hdl, ZFS_IOC_VDEV_ATTACH, &zc);
   2322    789    ahrens 
   2323   2676  eschrock 	zcmd_free_nvlists(&zc);
   2324    789    ahrens 
   2325   7965    George 	if (ret == 0) {
   2326   7965    George 		if (rootpool) {
   2327   7965    George 			/*
   2328   7965    George 			 * XXX - This should be removed once we can
   2329   7965    George 			 * automatically install the bootblocks on the
   2330   7965    George 			 * newly attached disk.
   2331   7965    George 			 */
   2332   7965    George 			(void) fprintf(stderr, dgettext(TEXT_DOMAIN, "Please "
   2333   7965    George 			    "be sure to invoke %s to make '%s' bootable.\n"),
   2334   7965    George 			    BOOTCMD, new_disk);
   2335   9790       Lin 
   2336   9790       Lin 			/*
   2337   9790       Lin 			 * XXX need a better way to prevent user from
   2338   9790       Lin 			 * booting up a half-baked vdev.
   2339   9790       Lin 			 */
   2340   9790       Lin 			(void) fprintf(stderr, dgettext(TEXT_DOMAIN, "Make "
   2341   9790       Lin 			    "sure to wait until resilver is done "
   2342   9790       Lin 			    "before rebooting.\n"));
   2343   7965    George 		}
   2344    789    ahrens 		return (0);
   2345   7965    George 	}
   2346    789    ahrens 
   2347    789    ahrens 	switch (errno) {
   2348   1544  eschrock 	case ENOTSUP:
   2349    789    ahrens 		/*
   2350    789    ahrens 		 * Can't attach to or replace this type of vdev.
   2351    789    ahrens 		 */
   2352   4527    perrin 		if (replacing) {
   2353   7326      Eric 			if (islog)
   2354   4527    perrin 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
   2355   4527    perrin 				    "cannot replace a log with a spare"));
   2356   4527    perrin 			else
   2357   4527    perrin 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
   2358   4527    perrin 				    "cannot replace a replacing device"));
   2359   4527    perrin 		} else {
   2360   2082  eschrock 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
   2361   2082  eschrock 			    "can only attach to mirrors and top-level "
   2362   2082  eschrock 			    "disks"));
   2363   4527    perrin 		}
   2364   2082  eschrock 		(void) zfs_error(hdl, EZFS_BADTARGET, msg);
   2365    789    ahrens 		break;
   2366    789    ahrens 
   2367   1544  eschrock 	case EINVAL:
   2368    789    ahrens 		/*
   2369    789    ahrens 		 * The new device must be a single disk.
   2370    789    ahrens 		 */
   2371   2082  eschrock 		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
   2372   2082  eschrock 		    "new device must be a single disk"));
   2373   2082  eschrock 		(void) zfs_error(hdl, EZFS_INVALCONFIG, msg);
   2374    789    ahrens 		break;
   2375    789    ahrens 
   2376   1544  eschrock 	case EBUSY:
   2377   2082  eschrock 		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "%s is busy"),
   2378   2082  eschrock 		    new_disk);
   2379   2082  eschrock 		(void) zfs_error(hdl, EZFS_BADDEV, msg);
   2380    789    ahrens 		break;
   2381    789    ahrens 
   2382   1544  eschrock 	case EOVERFLOW:
   2383    789    ahrens 		/*
   2384    789    ahrens 		 * The new device is too small.
   2385    789    ahrens 		 */
   2386   2082  eschrock 		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
   2387   2082  eschrock 		    "device is too small"));
   2388   2082  eschrock 		(void) zfs_error(hdl, EZFS_BADDEV, msg);
   2389    789    ahrens 		break;
   2390    789    ahrens 
   2391   1544  eschrock 	case EDOM:
   2392    789    ahrens 		/*
   2393    789    ahrens 		 * The new device has a different alignment requirement.
   2394    789    ahrens 		 */
   2395   2082  eschrock 		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
   2396   2082  eschrock 		    "devices have different sector alignment"));
   2397   2082  eschrock 		(void) zfs_error(hdl, EZFS_BADDEV, msg);
   2398    789    ahrens 		break;
   2399    789    ahrens 
   2400   1544  eschrock 	case ENAMETOOLONG:
   2401    789    ahrens 		/*
   2402    789    ahrens 		 * The resulting top-level vdev spec won't fit in the label.
   2403    789    ahrens 		 */
   2404   2082  eschrock 		(void) zfs_error(hdl, EZFS_DEVOVERFLOW, msg);
   2405    789    ahrens 		break;
   2406    789    ahrens 
   2407   1544  eschrock 	default:
   2408   2082  eschrock 		(void) zpool_standard_error(hdl, errno, msg);
   2409    789    ahrens 	}
   2410    789    ahrens 
   2411   2082  eschrock 	return (-1);
   2412    789    ahrens }
   2413    789    ahrens 
   2414    789    ahrens /*
   2415    789    ahrens  * Detach the specified device.
   2416    789    ahrens  */
   2417    789    ahrens int
   2418    789    ahrens zpool_vdev_detach(zpool_handle_t *zhp, const char *path)
   2419    789    ahrens {
   2420    789    ahrens 	zfs_cmd_t zc = { 0 };
   2421    789    ahrens 	char msg[1024];
   2422   2082  eschrock 	nvlist_t *tgt;
   2423   5450   brendan 	boolean_t avail_spare, l2cache;
   2424   2082  eschrock 	libzfs_handle_t *hdl = zhp->zpool_hdl;
   2425    789    ahrens 
   2426   1544  eschrock 	(void) snprintf(msg, sizeof (msg),
   2427   1544  eschrock 	    dgettext(TEXT_DOMAIN, "cannot detach %s"), path);
   2428   1544  eschrock 
   2429    789    ahrens 	(void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
   2430   7326      Eric 	if ((tgt = zpool_find_vdev(zhp, path, &avail_spare, &l2cache,
   2431   7326      Eric 	    NULL)) == 0)
   2432   2082  eschrock 		return (zfs_error(hdl, EZFS_NODEVICE, msg));
   2433    789    ahrens 
   2434   2468  ek110237 	if (avail_spare)
   2435   2082  eschrock 		return (zfs_error(hdl, EZFS_ISSPARE, msg));
   2436   5450   brendan 
   2437   5450   brendan 	if (l2cache)
   2438   5450   brendan 		return (zfs_error(hdl, EZFS_ISL2CACHE, msg));
   2439   2082  eschrock 
   2440   2082  eschrock 	verify(nvlist_lookup_uint64(tgt, ZPOOL_CONFIG_GUID, &zc.zc_guid) == 0);
   2441   2082  eschrock 
   2442   4543     marks 	if (zfs_ioctl(hdl, ZFS_IOC_VDEV_DETACH, &zc) == 0)
   2443    789    ahrens 		return (0);
   2444    789    ahrens 
   2445    789    ahrens 	switch (errno) {
   2446    789    ahrens 
   2447   1544  eschrock 	case ENOTSUP:
   2448    789    ahrens 		/*
   2449    789    ahrens 		 * Can't detach from this type of vdev.
   2450    789    ahrens 		 */
   2451   2082  eschrock 		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "only "
   2452   2082  eschrock 		    "applicable to mirror and replacing vdevs"));
   2453   2082  eschrock 		(void) zfs_error(zhp->zpool_hdl, EZFS_BADTARGET, msg);
   2454    789    ahrens 		break;
   2455    789    ahrens 
   2456   1544  eschrock 	case EBUSY:
   2457    789    ahrens 		/*
   2458    789    ahrens 		 * There are no other replicas of this device.
   2459    789    ahrens 		 */
   2460   2082  eschrock 		(void) zfs_error(hdl, EZFS_NOREPLICAS, msg);
   2461    789    ahrens 		break;
   2462    789    ahrens 
   2463   1544  eschrock 	default:
   2464   2082  eschrock 		(void) zpool_standard_error(hdl, errno, msg);
   2465   1544  eschrock 	}
   2466   1544  eschrock 
   2467   2082  eschrock 	return (-1);
   2468   2082  eschrock }
   2469   2082  eschrock 
   2470   2082  eschrock /*
   2471   5450   brendan  * Remove the given device.  Currently, this is supported only for hot spares
   2472   5450   brendan  * and level 2 cache devices.
   2473   2082  eschrock  */
   2474   2082  eschrock int
   2475   2082  eschrock zpool_vdev_remove(zpool_handle_t *zhp, const char *path)
   2476   2082  eschrock {
   2477   2082  eschrock 	zfs_cmd_t zc = { 0 };
   2478   2082  eschrock 	char msg[1024];
   2479   2082  eschrock 	nvlist_t *tgt;
   2480  10594    George 	boolean_t avail_spare, l2cache, islog;
   2481   2082  eschrock 	libzfs_handle_t *hdl = zhp->zpool_hdl;
   2482  10594    George 	uint64_t version;
   2483   2082  eschrock 
   2484   2082  eschrock 	(void) snprintf(msg, sizeof (msg),
   2485   2082  eschrock 	    dgettext(TEXT_DOMAIN, "cannot remove %s"), path);
   2486   2082  eschrock 
   2487   2082  eschrock 	(void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
   2488   7326      Eric 	if ((tgt = zpool_find_vdev(zhp, path, &avail_spare, &l2cache,
   2489  10594    George 	    &islog)) == 0)
   2490   2082  eschrock 		return (zfs_error(hdl, EZFS_NODEVICE, msg));
   2491  10594    George 	/*
   2492  10594    George 	 * XXX - this should just go away.
   2493  10594    George 	 */
   2494  10594    George 	if (!avail_spare && !l2cache && !islog) {
   2495  10594    George 		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
   2496  10594    George 		    "only inactive hot spares, cache, top-level, "
   2497  10594    George 		    "or log devices can be removed"));
   2498  10594    George 		return (zfs_error(hdl, EZFS_NODEVICE, msg));
   2499  10594    George 	}
   2500   2082  eschrock 
   2501  10594    George 	version = zpool_get_prop_int(zhp, ZPOOL_PROP_VERSION, NULL);
   2502  10594    George 	if (islog && version < SPA_VERSION_HOLES) {
   2503   2082  eschrock 		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
   2504  10594    George 		    "pool must be upgrade to support log removal"));
   2505  10594    George 		return (zfs_error(hdl, EZFS_BADVERSION, msg));
   2506   2082  eschrock 	}
   2507   2082  eschrock 
   2508   2082  eschrock 	verify(nvlist_lookup_uint64(tgt, ZPOOL_CONFIG_GUID, &zc.zc_guid) == 0);
   2509   2082  eschrock 
   2510   4543     marks 	if (zfs_ioctl(hdl, ZFS_IOC_VDEV_REMOVE, &zc) == 0)
   2511   2082  eschrock 		return (0);
   2512   2082  eschrock 
   2513   2082  eschrock 	return (zpool_standard_error(hdl, errno, msg));
   2514   1544  eschrock }
   2515   1544  eschrock 
   2516   1544  eschrock /*
   2517   1544  eschrock  * Clear the errors for the pool, or the particular device if specified.
   2518   1544  eschrock  */
   2519   1544  eschrock int
   2520  10921       Tim zpool_clear(zpool_handle_t *zhp, const char *path, nvlist_t *rewindnvl)
   2521   1544  eschrock {
   2522   1544  eschrock 	zfs_cmd_t zc = { 0 };
   2523   1544  eschrock 	char msg[1024];
   2524   2082  eschrock 	nvlist_t *tgt;
   2525  10921       Tim 	zpool_rewind_policy_t policy;
   2526   5450   brendan 	boolean_t avail_spare, l2cache;
   2527   2082  eschrock 	libzfs_handle_t *hdl = zhp->zpool_hdl;
   2528  10921       Tim 	nvlist_t *nvi = NULL;
   2529   1544  eschrock 
   2530   1544  eschrock 	if (path)
   2531   1544  eschrock 		(void) snprintf(msg, sizeof (msg),
   2532   1544  eschrock 		    dgettext(TEXT_DOMAIN, "cannot clear errors for %s"),
   2533   2676  eschrock 		    path);
   2534   1544  eschrock 	else
   2535   1544  eschrock 		(void) snprintf(msg, sizeof (msg),
   2536   1544  eschrock 		    dgettext(TEXT_DOMAIN, "cannot clear errors for %s"),
   2537   1544  eschrock 		    zhp->zpool_name);
   2538   1544  eschrock 
   2539   1544  eschrock 	(void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
   2540   2082  eschrock 	if (path) {
   2541   5450   brendan 		if ((tgt = zpool_find_vdev(zhp, path, &avail_spare,
   2542   7326      Eric 		    &l2cache, NULL)) == 0)
   2543   2082  eschrock 			return (zfs_error(hdl, EZFS_NODEVICE, msg));
   2544   2082  eschrock 
   2545   5450   brendan 		/*
   2546   5450   brendan 		 * Don't allow error clearing for hot spares.  Do allow
   2547   5450   brendan 		 * error clearing for l2cache devices.
   2548   5450   brendan 		 */
   2549   2468  ek110237 		if (avail_spare)
   2550   2082  eschrock 			return (zfs_error(hdl, EZFS_ISSPARE, msg));
   2551   2082  eschrock 
   2552   2082  eschrock 		verify(nvlist_lookup_uint64(tgt, ZPOOL_CONFIG_GUID,
   2553   2082  eschrock 		    &zc.zc_guid) == 0);
   2554   1544  eschrock 	}
   2555   1544  eschrock 
   2556  10921       Tim 	zpool_get_rewind_policy(rewindnvl, &policy);
   2557  10921       Tim 	zc.zc_cookie = policy.zrp_request;
   2558  10921       Tim 
   2559  10921       Tim 	if (zcmd_alloc_dst_nvlist(hdl, &zc, 8192) != 0)
   2560  10921       Tim 		return (-1);
   2561  10921       Tim 
   2562  10921       Tim 	if (zcmd_write_src_nvlist(zhp->zpool_hdl, &zc, rewindnvl) != 0)
   2563  10921       Tim 		return (-1);
   2564  10921       Tim 
   2565  10921       Tim 	if (zfs_ioctl(hdl, ZFS_IOC_CLEAR, &zc) == 0 ||
   2566  10921       Tim 	    ((policy.zrp_request & ZPOOL_TRY_REWIND) &&
   2567  10921       Tim 	    errno != EPERM && errno != EACCES)) {
   2568  10921       Tim 		if (policy.zrp_request &
   2569  10921       Tim 		    (ZPOOL_DO_REWIND | ZPOOL_TRY_REWIND)) {
   2570  10921       Tim 			(void) zcmd_read_dst_nvlist(hdl, &zc, &nvi);
   2571  10921       Tim 			zpool_rewind_exclaim(hdl, zc.zc_name,
   2572  10921       Tim 			    ((policy.zrp_request & ZPOOL_TRY_REWIND) != 0),
   2573  10921       Tim 			    nvi);
   2574  10921       Tim 			nvlist_free(nvi);
   2575  10921       Tim 		}
   2576  10921       Tim 		zcmd_free_nvlists(&zc);
   2577   1544  eschrock 		return (0);
   2578  10921       Tim 	}
   2579   1544  eschrock 
   2580  10921       Tim 	zcmd_free_nvlists(&zc);
   2581   2082  eschrock 	return (zpool_standard_error(hdl, errno, msg));
   2582    789    ahrens }
   2583    789    ahrens 
   2584   3126       ahl /*
   2585   4451  eschrock  * Similar to zpool_clear(), but takes a GUID (used by fmd).
   2586   4451  eschrock  */
   2587   4451  eschrock int
   2588   4451  eschrock zpool_vdev_clear(zpool_handle_t *zhp, uint64_t guid)
   2589   4451  eschrock {
   2590   4451  eschrock 	zfs_cmd_t zc = { 0 };
   2591   4451  eschrock 	char msg[1024];
   2592   4451  eschrock 	libzfs_handle_t *hdl = zhp->zpool_hdl;
   2593   4451  eschrock 
   2594   4451  eschrock 	(void) snprintf(msg, sizeof (msg),
   2595   4451  eschrock 	    dgettext(TEXT_DOMAIN, "cannot clear errors for %llx"),
   2596   4451  eschrock 	    guid);
   2597   4451  eschrock 
   2598   4451  eschrock 	(void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
   2599   4451  eschrock 	zc.zc_guid = guid;
   2600   4451  eschrock 
   2601   4451  eschrock 	if (ioctl(hdl->libzfs_fd, ZFS_IOC_CLEAR, &zc) == 0)
   2602   4451  eschrock 		return (0);
   2603   4451  eschrock 
   2604   4451  eschrock 	return (zpool_standard_error(hdl, errno, msg));
   2605   4451  eschrock }
   2606   4451  eschrock 
   2607   4451  eschrock /*
   2608   1354  eschrock  * Convert from a devid string to a path.
   2609   1354  eschrock  */
   2610   1354  eschrock static char *
   2611   1354  eschrock devid_to_path(char *devid_str)
   2612   1354  eschrock {
   2613   1354  eschrock 	ddi_devid_t devid;
   2614   1354  eschrock 	char *minor;
   2615   1354  eschrock 	char *path;
   2616   1354  eschrock 	devid_nmlist_t *list = NULL;
   2617   1354  eschrock 	int ret;
   2618   1354  eschrock 
   2619   1354  eschrock 	if (devid_str_decode(devid_str, &devid, &minor) != 0)
   2620   1354  eschrock 		return (NULL);
   2621   1354  eschrock 
   2622   1354  eschrock 	ret = devid_deviceid_to_nmlist("/dev", devid, minor, &list);
   2623   1354  eschrock 
   2624   1354  eschrock 	devid_str_free(minor);
   2625   1354  eschrock 	devid_free(devid);
   2626   1354  eschrock 
   2627   1354  eschrock 	if (ret != 0)
   2628   1354  eschrock 		return (NULL);
   2629   1354  eschrock 
   2630   2082  eschrock 	if ((path = strdup(list[0].devname)) == NULL)
   2631   2082  eschrock 		return (NULL);
   2632   2082  eschrock 
   2633   1354  eschrock 	devid_free_nmlist(list);
   2634   1354  eschrock 
   2635   1354  eschrock 	return (path);
   2636   1354  eschrock }
   2637   1354  eschrock 
   2638   1354  eschrock /*
   2639   1354  eschrock  * Convert from a path to a devid string.
   2640   1354  eschrock  */
   2641   1354  eschrock static char *
   2642   1354  eschrock path_to_devid(const char *path)
   2643   1354  eschrock {
   2644   1354  eschrock 	int fd;
   2645   1354  eschrock 	ddi_devid_t devid;
   2646   1354  eschrock 	char *minor, *ret;
   2647   1354  eschrock 
   2648   1354  eschrock 	if ((fd = open(path, O_RDONLY)) < 0)
   2649   1354  eschrock 		return (NULL);
   2650   1354  eschrock 
   2651   1354  eschrock 	minor = NULL;
   2652   1354  eschrock 	ret = NULL;
   2653   1354  eschrock 	if (devid_get(fd, &devid) == 0) {
   2654   1354  eschrock 		if (devid_get_minor_name(fd, &minor) == 0)
   2655   1354  eschrock 			ret = devid_str_encode(devid, minor);
   2656   1354  eschrock 		if (minor != NULL)
   2657   1354  eschrock 			devid_str_free(minor);
   2658   1354  eschrock 		devid_free(devid);
   2659   1354  eschrock 	}
   2660   1354  eschrock 	(void) close(fd);
   2661   1354  eschrock 
   2662   1354  eschrock 	return (ret);
   2663   1354  eschrock }
   2664   1354  eschrock 
   2665   1354  eschrock /*
   2666   1354  eschrock  * Issue the necessary ioctl() to update the stored path value for the vdev.  We
   2667   1354  eschrock  * ignore any failure here, since a common case is for an unprivileged user to
   2668   1354  eschrock  * type 'zpool status', and we'll display the correct information anyway.
   2669   1354  eschrock  */
   2670   1354  eschrock static void
   2671   1354  eschrock set_path(zpool_handle_t *zhp, nvlist_t *nv, const char *path)
   2672   1354  eschrock {
   2673   1354  eschrock 	zfs_cmd_t zc = { 0 };
   2674   1354  eschrock 
   2675   1354  eschrock 	(void) strncpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
   2676   2676  eschrock 	(void) strncpy(zc.zc_value, path, sizeof (zc.zc_value));
   2677   1354  eschrock 	verify(nvlist_lookup_uint64(nv, ZPOOL_CONFIG_GUID,
   2678   1544  eschrock 	    &zc.zc_guid) == 0);
   2679   1354  eschrock 
   2680   2082  eschrock 	(void) ioctl(zhp->zpool_hdl->libzfs_fd, ZFS_IOC_VDEV_SETPATH, &zc);
   2681   1354  eschrock }
   2682   1354  eschrock 
   2683   1354  eschrock /*
   2684   1354  eschrock  * Given a vdev, return the name to display in iostat.  If the vdev has a path,
   2685   1354  eschrock  * we use that, stripping off any leading "/dev/dsk/"; if not, we use the type.
   2686   1354  eschrock  * We also check if this is a whole disk, in which case we strip off the
   2687   1354  eschrock  * trailing 's0' slice name.
   2688   1354  eschrock  *
   2689   1354  eschrock  * This routine is also responsible for identifying when disks have been
   2690   1354  eschrock  * reconfigured in a new location.  The kernel will have opened the device by
   2691   1354  eschrock  * devid, but the path will still refer to the old location.  To catch this, we
   2692   1354  eschrock  * first do a path -> devid translation (which is fast for the common case).  If
   2693   1354  eschrock  * the devid matches, we're done.  If not, we do a reverse devid -> path
   2694   1354  eschrock  * translation and issue the appropriate ioctl() to update the path of the vdev.
   2695   1354  eschrock  * If 'zhp' is NULL, then this is an exported pool, and we don't need to do any
   2696   1354  eschrock  * of these checks.
   2697   1354  eschrock  */
   2698   1354  eschrock char *
   2699  10594    George zpool_vdev_name(libzfs_handle_t *hdl, zpool_handle_t *zhp, nvlist_t *nv,
   2700  10594    George     boolean_t verbose)
   2701   1354  eschrock {
   2702   1354  eschrock 	char *path, *devid;
   2703   1544  eschrock 	uint64_t value;
   2704   1544  eschrock 	char buf[64];
   2705   4451  eschrock 	vdev_stat_t *vs;
   2706   4451  eschrock 	uint_t vsc;
   2707   1354  eschrock 
   2708   1544  eschrock 	if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_NOT_PRESENT,
   2709   1544  eschrock 	    &value) == 0) {
   2710   1544  eschrock 		verify(nvlist_lookup_uint64(nv, ZPOOL_CONFIG_GUID,
   2711   1544  eschrock 		    &value) == 0);
   2712   2856  nd150628 		(void) snprintf(buf, sizeof (buf), "%llu",
   2713   2856  nd150628 		    (u_longlong_t)value);
   2714   1544  eschrock 		path = buf;
   2715   1544  eschrock 	} else if (nvlist_lookup_string(nv, ZPOOL_CONFIG_PATH, &path) == 0) {
   2716   1354  eschrock 
   2717   4451  eschrock 		/*
   2718   4451  eschrock 		 * If the device is dead (faulted, offline, etc) then don't
   2719   4451  eschrock 		 * bother opening it.  Otherwise we may be forcing the user to
   2720   4451  eschrock 		 * open a misbehaving device, which can have undesirable
   2721   4451  eschrock 		 * effects.
   2722   4451  eschrock 		 */
   2723   4451  eschrock 		if ((nvlist_lookup_uint64_array(nv, ZPOOL_CONFIG_STATS,
   2724   4451  eschrock 		    (uint64_t **)&vs, &vsc) != 0 ||
   2725   4451  eschrock 		    vs->vs_state >= VDEV_STATE_DEGRADED) &&
   2726   4451  eschrock 		    zhp != NULL &&
   2727   1354  eschrock 		    nvlist_lookup_string(nv, ZPOOL_CONFIG_DEVID, &devid) == 0) {
   2728   1354  eschrock 			/*
   2729   1354  eschrock 			 * Determine if the current path is correct.
   2730   1354  eschrock 			 */
   2731   1354  eschrock 			char *newdevid = path_to_devid(path);
   2732   1354  eschrock 
   2733   1354  eschrock 			if (newdevid == NULL ||
   2734   1354  eschrock 			    strcmp(devid, newdevid) != 0) {
   2735   1354  eschrock 				char *newpath;
   2736   1354  eschrock 
   2737   1354  eschrock 				if ((newpath = devid_to_path(devid)) != NULL) {
   2738   1354  eschrock 					/*
   2739   1354  eschrock 					 * Update the path appropriately.
   2740   1354  eschrock 					 */
   2741   1354  eschrock 					set_path(zhp, nv, newpath);
   2742   2082  eschrock 					if (nvlist_add_string(nv,
   2743   2082  eschrock 					    ZPOOL_CONFIG_PATH, newpath) == 0)
   2744   2082  eschrock 						verify(nvlist_lookup_string(nv,
   2745   2082  eschrock 						    ZPOOL_CONFIG_PATH,
   2746   2082  eschrock 						    &path) == 0);
   2747   1354  eschrock 					free(newpath);
   2748   1354  eschrock 				}
   2749   1354  eschrock 			}
   2750   1354  eschrock 
   2751   2082  eschrock 			if (newdevid)
   2752   2082  eschrock 				devid_str_free(newdevid);
   2753   1354  eschrock 		}
   2754   1354  eschrock 
   2755   1354  eschrock 		if (strncmp(path, "/dev/dsk/", 9) == 0)
   2756   1354  eschrock 			path += 9;
   2757   1354  eschrock 
   2758   1354  eschrock 		if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_WHOLE_DISK,
   2759   1544  eschrock 		    &value) == 0 && value) {
   2760   2082  eschrock 			char *tmp = zfs_strdup(hdl, path);
   2761   2082  eschrock 			if (tmp == NULL)
   2762   2082  eschrock 				return (NULL);
   2763   1354  eschrock 			tmp[strlen(path) - 2] = '\0';
   2764   1354  eschrock 			return (tmp);
   2765   1354  eschrock 		}
   2766   1354  eschrock 	} else {
   2767   1354  eschrock 		verify(nvlist_lookup_string(nv, ZPOOL_CONFIG_TYPE, &path) == 0);
   2768   2082  eschrock 
   2769   2082  eschrock 		/*
   2770   2082  eschrock 		 * If it's a raidz device, we need to stick in the parity level.
   2771   2082  eschrock 		 */
   2772   2082  eschrock 		if (strcmp(path, VDEV_TYPE_RAIDZ) == 0) {
   2773   2082  eschrock 			verify(nvlist_lookup_uint64(nv, ZPOOL_CONFIG_NPARITY,
   2774   2082  eschrock 			    &value) == 0);
   2775   2082  eschrock 			(void) snprintf(buf, sizeof (buf), "%s%llu", path,
   2776   2856  nd150628 			    (u_longlong_t)value);
   2777  10594    George 			path = buf;
   2778  10594    George 		}
   2779  10594    George 
   2780  10594    George 		/*
   2781  10594    George 		 * We identify each top-level vdev by using a <type-id>
   2782  10594    George 		 * naming convention.
   2783  10594    George 		 */
   2784  10594    George 		if (verbose) {
   2785  10594    George 			uint64_t id;
   2786  10594    George 
   2787  10594    George 			verify(nvlist_lookup_uint64(nv, ZPOOL_CONFIG_ID,
   2788  10594    George 			    &id) == 0);
   2789  10594    George 			(void) snprintf(buf, sizeof (buf), "%s-%llu", path,
   2790  10594    George 			    (u_longlong_t)id);
   2791   2082  eschrock 			path = buf;
   2792   2082  eschrock 		}
   2793   1354  eschrock 	}
   2794   1354  eschrock 
   2795   2082  eschrock 	return (zfs_strdup(hdl, path));
   2796   1354  eschrock }
   2797   1544  eschrock 
   2798   1544  eschrock static int
   2799   1544  eschrock zbookmark_compare(const void *a, const void *b)
   2800   1544  eschrock {
   2801   1544  eschrock 	return (memcmp(a, b, sizeof (zbookmark_t)));
   2802   1544  eschrock }
   2803   1544  eschrock 
   2804   1544  eschrock /*
   2805   1544  eschrock  * Retrieve the persistent error log, uniquify the members, and return to the
   2806   1544  eschrock  * caller.
   2807   1544  eschrock  */
   2808   1544  eschrock int
   2809   3444  ek110237 zpool_get_errlog(zpool_handle_t *zhp, nvlist_t **nverrlistp)
   2810   1544  eschrock {
   2811   1544  eschrock 	zfs_cmd_t zc = { 0 };
   2812   1544  eschrock 	uint64_t count;
   2813   2676  eschrock 	zbookmark_t *zb = NULL;
   2814   3444  ek110237 	int i;
   2815   1544  eschrock 
   2816   1544  eschrock 	/*
   2817   1544  eschrock 	 * Retrieve the raw error list from the kernel.  If the number of errors
   2818   1544  eschrock 	 * has increased, allocate more space and continue until we get the
   2819   1544  eschrock 	 * entire list.
   2820   1544  eschrock 	 */
   2821   1544  eschrock 	verify(nvlist_lookup_uint64(zhp->zpool_config, ZPOOL_CONFIG_ERRCOUNT,
   2822   1544  eschrock 	    &count) == 0);
   2823   4820  ek110237 	if (count == 0)
   2824   4820  ek110237 		return (0);
   2825   2676  eschrock 	if ((zc.zc_nvlist_dst = (uintptr_t)zfs_alloc(zhp->zpool_hdl,
   2826   2856  nd150628 	    count * sizeof (zbookmark_t))) == (uintptr_t)NULL)
   2827   2082  eschrock 		return (-1);
   2828   2676  eschrock 	zc.zc_nvlist_dst_size = count;
   2829   1544  eschrock 	(void) strcpy(zc.zc_name, zhp->zpool_name);
   2830   1544  eschrock 	for (;;) {
   2831   2082  eschrock 		if (ioctl(zhp->zpool_hdl->libzfs_fd, ZFS_IOC_ERROR_LOG,
   2832   2082  eschrock 		    &zc) != 0) {
   2833   2676  eschrock 			free((void *)(uintptr_t)zc.zc_nvlist_dst);
   2834   1544  eschrock 			if (errno == ENOMEM) {
   2835   3823  vb160487 				count = zc.zc_nvlist_dst_size;
   2836   2676  eschrock 				if ((zc.zc_nvlist_dst = (uintptr_t)
   2837   3823  vb160487 				    zfs_alloc(zhp->zpool_hdl, count *
   2838   3823  vb160487 				    sizeof (zbookmark_t))) == (uintptr_t)NULL)
   2839   2082  eschrock 					return (-1);
   2840   1544  eschrock 			} else {
   2841   1544  eschrock 				return (-1);
   2842   1544  eschrock 			}
   2843   1544  eschrock 		} else {
   2844   1544  eschrock 			break;
   2845   1544  eschrock 		}
   2846   1544  eschrock 	}
   2847   1544  eschrock 
   2848   1544  eschrock 	/*
   2849   1544  eschrock 	 * Sort the resulting bookmarks.  This is a little confusing due to the
   2850   1544  eschrock 	 * implementation of ZFS_IOC_ERROR_LOG.  The bookmarks are copied last
   2851   2676  eschrock 	 * to first, and 'zc_nvlist_dst_size' indicates the number of boomarks
   2852   1544  eschrock 	 * _not_ copied as part of the process.  So we point the start of our
   2853   1544  eschrock 	 * array appropriate and decrement the total number of elements.
   2854   1544  eschrock 	 */
   2855   2676  eschrock 	zb = ((zbookmark_t *)(uintptr_t)zc.zc_nvlist_dst) +
   2856   2676  eschrock 	    zc.zc_nvlist_dst_size;
   2857   2676  eschrock 	count -= zc.zc_nvlist_dst_size;
   2858   1544  eschrock 
   2859   1544  eschrock 	qsort(zb, count, sizeof (zbookmark_t), zbookmark_compare);
   2860   1544  eschrock 
   2861   3444  ek110237 	verify(nvlist_alloc(nverrlistp, 0, KM_SLEEP) == 0);
   2862   1544  eschrock 
   2863   1544  eschrock 	/*
   2864   3444  ek110237 	 * Fill in the nverrlistp with nvlist's of dataset and object numbers.
   2865   1544  eschrock 	 */
   2866   1544  eschrock 	for (i = 0; i < count; i++) {
   2867   1544  eschrock 		nvlist_t *nv;
   2868   1544  eschrock 
   2869   3700  ek110237 		/* ignoring zb_blkid and zb_level for now */
   2870   3700  ek110237 		if (i > 0 && zb[i-1].zb_objset == zb[i].zb_objset &&
   2871   3700  ek110237 		    zb[i-1].zb_object == zb[i].zb_object)
   2872   1544  eschrock 			continue;
   2873   1544  eschrock 
   2874   3444  ek110237 		if (nvlist_alloc(&nv, NV_UNIQUE_NAME, KM_SLEEP) != 0)
   2875   2082  eschrock 			goto nomem;
   2876   3444  ek110237 		if (nvlist_add_uint64(nv, ZPOOL_ERR_DATASET,
   2877   3444  ek110237 		    zb[i].zb_objset) != 0) {
   2878   3444  ek110237 			nvlist_free(nv);
   2879   3444  ek110237 			goto nomem;
   2880   1544  eschrock 		}
   2881   3444  ek110237 		if (nvlist_add_uint64(nv, ZPOOL_ERR_OBJECT,
   2882   3444  ek110237 		    zb[i].zb_object) != 0) {
   2883   3444  ek110237 			nvlist_free(nv);
   2884   3444  ek110237 			goto nomem;
   2885   3444  ek110237 		}
   2886   3444  ek110237 		if (nvlist_add_nvlist(*nverrlistp, "ejk", nv) != 0) {
   2887   3444  ek110237 			nvlist_free(nv);
   2888   3444  ek110237 			goto nomem;
   2889   3444  ek110237 		}
   2890   3444  ek110237 		nvlist_free(nv);
   2891   1544  eschrock 	}
   2892   1544  eschrock 
   2893   3265    ahrens 	free((void *)(uintptr_t)zc.zc_nvlist_dst);
   2894   1544  eschrock 	return (0);
   2895   2082  eschrock 
   2896   2082  eschrock nomem:
   2897   2676  eschrock 	free((void *)(uintptr_t)zc.zc_nvlist_dst);
   2898   2082  eschrock 	return (no_memory(zhp->zpool_hdl));
   2899   1544  eschrock }
   2900   1760  eschrock 
   2901   1760  eschrock /*
   2902   1760  eschrock  * Upgrade a ZFS pool to the latest on-disk version.
   2903   1760  eschrock  */
   2904   1760  eschrock int
   2905   5094     lling zpool_upgrade(zpool_handle_t *zhp, uint64_t new_version)
   2906   1760  eschrock {
   2907   1760  eschrock 	zfs_cmd_t zc = { 0 };
   2908   2082  eschrock 	libzfs_handle_t *hdl = zhp->zpool_hdl;
   2909   1760  eschrock 
   2910   1760  eschrock 	(void) strcpy(zc.zc_name, zhp->zpool_name);
   2911   5094     lling 	zc.zc_cookie = new_version;
   2912   5094     lling 
   2913   4543     marks 	if (zfs_ioctl(hdl, ZFS_IOC_POOL_UPGRADE, &zc) != 0)
   2914   3237     lling 		return (zpool_standard_error_fmt(hdl, errno,
   2915   2082  eschrock 		    dgettext(TEXT_DOMAIN, "cannot upgrade '%s'"),
   2916   2082  eschrock 		    zhp->zpool_name));
   2917   1760  eschrock 	return (0);
   2918   1760  eschrock }
   2919   2926  ek110237 
   2920   4988  ek110237 void
   2921   4988  ek110237 zpool_set_history_str(const char *subcommand, int argc, char **argv,
   2922   4988  ek110237     char *history_str)
   2923   4988  ek110237 {
   2924   4988  ek110237 	int i;
   2925   4988  ek110237 
   2926   4988  ek110237 	(void) strlcpy(history_str, subcommand, HIS_MAX_RECORD_LEN);
   2927   4988  ek110237 	for (i = 1; i < argc; i++) {
   2928   4988  ek110237 		if (strlen(history_str) + 1 + strlen(argv[i]) >
   2929   4988  ek110237 		    HIS_MAX_RECORD_LEN)
   2930   4988  ek110237 			break;
   2931   4988  ek110237 		(void) strlcat(history_str, " ", HIS_MAX_RECORD_LEN);
   2932   4988  ek110237 		(void) strlcat(history_str, argv[i], HIS_MAX_RECORD_LEN);
   2933   4988  ek110237 	}
   2934   4988  ek110237 }
   2935   4988  ek110237 
   2936   2926  ek110237 /*
   2937   4988  ek110237  * Stage command history for logging.
   2938   2926  ek110237  */
   2939   4988  ek110237 int
   2940   4988  ek110237 zpool_stage_history(libzfs_handle_t *hdl, const char *history_str)
   2941   2926  ek110237 {
   2942   4988  ek110237 	if (history_str == NULL)
   2943   4988  ek110237 		return (EINVAL);
   2944   4988  ek110237 
   2945   4988  ek110237 	if (strlen(history_str) > HIS_MAX_RECORD_LEN)
   2946   4988  ek110237 		return (EINVAL);
   2947   2926  ek110237 
   2948   4715  ek110237 	if (hdl->libzfs_log_str != NULL)
   2949   4543     marks 		free(hdl->libzfs_log_str);
   2950   4543     marks 
   2951   4988  ek110237 	if ((hdl->libzfs_log_str = strdup(history_str)) == NULL)
   2952   4988  ek110237 		return (no_memory(hdl));
   2953   4543     marks 
   2954   4988  ek110237 	return (0);
   2955   2926  ek110237 }
   2956   2926  ek110237 
   2957   2926  ek110237 /*
   2958   2926  ek110237  * Perform ioctl to get some command history of a pool.
   2959   2926  ek110237  *
   2960   2926  ek110237  * 'buf' is the buffer to fill up to 'len' bytes.  'off' is the
   2961   2926  ek110237  * logical offset of the history buffer to start reading from.
   2962   2926  ek110237  *
   2963   2926  ek110237  * Upon return, 'off' is the next logical offset to read from and
   2964   2926  ek110237  * 'len' is the actual amount of bytes read into 'buf'.
   2965   2926  ek110237  */
   2966   2926  ek110237 static int
   2967   2926  ek110237 get_history(zpool_handle_t *zhp, char *buf, uint64_t *off, uint64_t *len)
   2968   2926  ek110237 {
   2969   2926  ek110237 	zfs_cmd_t zc = { 0 };
   2970   2926  ek110237 	libzfs_handle_t *hdl = zhp->zpool_hdl;
   2971   2926  ek110237 
   2972   2926  ek110237 	(void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
   2973   2926  ek110237 
   2974   2926  ek110237 	zc.zc_history = (uint64_t)(uintptr_t)buf;
   2975   2926  ek110237 	zc.zc_history_len = *len;
   2976   2926  ek110237 	zc.zc_history_offset = *off;
   2977   2926  ek110237 
   2978   2926  ek110237 	if (ioctl(hdl->libzfs_fd, ZFS_IOC_POOL_GET_HISTORY, &zc) != 0) {
   2979   2926  ek110237 		switch (errno) {
   2980   2926  ek110237 		case EPERM:
   2981   3237     lling 			return (zfs_error_fmt(hdl, EZFS_PERM,
   2982   3237     lling 			    dgettext(TEXT_DOMAIN,
   2983   2926  ek110237 			    "cannot show history for pool '%s'"),
   2984   2926  ek110237 			    zhp->zpool_name));
   2985   2926  ek110237 		case ENOENT:
   2986   3237     lling 			return (zfs_error_fmt(hdl, EZFS_NOHISTORY,
   2987   2926  ek110237 			    dgettext(TEXT_DOMAIN, "cannot get history for pool "
   2988   2926  ek110237 			    "'%s'"), zhp->zpool_name));
   2989   3863  ek110237 		case ENOTSUP:
   2990   3863  ek110237 			return (zfs_error_fmt(hdl, EZFS_BADVERSION,
   2991   3863  ek110237 			    dgettext(TEXT_DOMAIN, "cannot get history for pool "
   2992   3863  ek110237 			    "'%s', pool must be upgraded"), zhp->zpool_name));
   2993   2926  ek110237 		default:
   2994   3237     lling 			return (zpool_standard_error_fmt(hdl, errno,
   2995   2926  ek110237 			    dgettext(TEXT_DOMAIN,
   2996   2926  ek110237 			    "cannot get history for '%s'"), zhp->zpool_name));
   2997   2926  ek110237 		}
   2998   2926  ek110237 	}
   2999   2926  ek110237 
   3000   2926  ek110237 	*len = zc.zc_history_len;
   3001   2926  ek110237 	*off = zc.zc_history_offset;
   3002   2926  ek110237 
   3003   2926  ek110237 	return (0);
   3004   2926  ek110237 }
   3005   2926  ek110237 
   3006   2926  ek110237 /*
   3007   2926  ek110237  * Process the buffer of nvlists, unpacking and storing each nvlist record
   3008   2926  ek110237  * into 'records'.  'leftover' is set to the number of bytes that weren't
   3009   2926  ek110237  * processed as there wasn't a complete record.
   3010   2926  ek110237  */
   3011  10685    George int
   3012   2926  ek110237