1789Sahrens /*
2789Sahrens  * CDDL HEADER START
3789Sahrens  *
4789Sahrens  * The contents of this file are subject to the terms of the
51485Slling  * Common Development and Distribution License (the "License").
61485Slling  * You may not use this file except in compliance with the License.
7789Sahrens  *
8789Sahrens  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9789Sahrens  * or http://www.opensolaris.org/os/licensing.
10789Sahrens  * See the License for the specific language governing permissions
11789Sahrens  * and limitations under the License.
12789Sahrens  *
13789Sahrens  * When distributing Covered Code, include this CDDL HEADER in each
14789Sahrens  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15789Sahrens  * If applicable, add the following below this CDDL HEADER, with the
16789Sahrens  * fields enclosed by brackets "[]" replaced with your own identifying
17789Sahrens  * information: Portions Copyright [yyyy] [name of copyright owner]
18789Sahrens  *
19789Sahrens  * CDDL HEADER END
20789Sahrens  */
212082Seschrock 
22789Sahrens /*
233377Seschrock  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
24789Sahrens  * Use is subject to license terms.
25789Sahrens  */
26789Sahrens 
27789Sahrens #pragma ident	"%Z%%M%	%I%	%E% SMI"
28789Sahrens 
293126Sahl #include <alloca.h>
30789Sahrens #include <assert.h>
31789Sahrens #include <ctype.h>
32789Sahrens #include <errno.h>
33789Sahrens #include <devid.h>
343126Sahl #include <dirent.h>
35789Sahrens #include <fcntl.h>
36789Sahrens #include <libintl.h>
37789Sahrens #include <stdio.h>
38789Sahrens #include <stdlib.h>
393126Sahl #include <strings.h>
40789Sahrens #include <unistd.h>
41789Sahrens #include <sys/zfs_ioctl.h>
421544Seschrock #include <sys/zio.h>
432926Sek110237 #include <strings.h>
44789Sahrens 
45789Sahrens #include "zfs_namecheck.h"
46789Sahrens #include "libzfs_impl.h"
47789Sahrens 
48789Sahrens /*
49789Sahrens  * Validate the given pool name, optionally putting an extended error message in
50789Sahrens  * 'buf'.
51789Sahrens  */
522082Seschrock static boolean_t
532082Seschrock zpool_name_valid(libzfs_handle_t *hdl, boolean_t isopen, const char *pool)
54789Sahrens {
55789Sahrens 	namecheck_err_t why;
56789Sahrens 	char what;
571773Seschrock 	int ret;
58789Sahrens 
591773Seschrock 	ret = pool_namecheck(pool, &why, &what);
601773Seschrock 
611773Seschrock 	/*
621773Seschrock 	 * The rules for reserved pool names were extended at a later point.
631773Seschrock 	 * But we need to support users with existing pools that may now be
641773Seschrock 	 * invalid.  So we only check for this expanded set of names during a
651773Seschrock 	 * create (or import), and only in userland.
661773Seschrock 	 */
671773Seschrock 	if (ret == 0 && !isopen &&
681773Seschrock 	    (strncmp(pool, "mirror", 6) == 0 ||
691773Seschrock 	    strncmp(pool, "raidz", 5) == 0 ||
701773Seschrock 	    strncmp(pool, "spare", 5) == 0)) {
712082Seschrock 		zfs_error_aux(hdl,
722082Seschrock 		    dgettext(TEXT_DOMAIN, "name is reserved"));
732082Seschrock 		return (B_FALSE);
741773Seschrock 	}
751773Seschrock 
761773Seschrock 
771773Seschrock 	if (ret != 0) {
782082Seschrock 		if (hdl != NULL) {
79789Sahrens 			switch (why) {
801003Slling 			case NAME_ERR_TOOLONG:
812082Seschrock 				zfs_error_aux(hdl,
821003Slling 				    dgettext(TEXT_DOMAIN, "name is too long"));
831003Slling 				break;
841003Slling 
85789Sahrens 			case NAME_ERR_INVALCHAR:
862082Seschrock 				zfs_error_aux(hdl,
87789Sahrens 				    dgettext(TEXT_DOMAIN, "invalid character "
88789Sahrens 				    "'%c' in pool name"), what);
89789Sahrens 				break;
90789Sahrens 
91789Sahrens 			case NAME_ERR_NOLETTER:
922082Seschrock 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
932082Seschrock 				    "name must begin with a letter"));
94789Sahrens 				break;
95789Sahrens 
96789Sahrens 			case NAME_ERR_RESERVED:
972082Seschrock 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
982082Seschrock 				    "name is reserved"));
99789Sahrens 				break;
100789Sahrens 
101789Sahrens 			case NAME_ERR_DISKLIKE:
1022082Seschrock 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1032082Seschrock 				    "pool name is reserved"));
104789Sahrens 				break;
1052856Snd150628 
1062856Snd150628 			case NAME_ERR_LEADING_SLASH:
1072856Snd150628 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1082856Snd150628 				    "leading slash in name"));
1092856Snd150628 				break;
1102856Snd150628 
1112856Snd150628 			case NAME_ERR_EMPTY_COMPONENT:
1122856Snd150628 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1132856Snd150628 				    "empty component in name"));
1142856Snd150628 				break;
1152856Snd150628 
1162856Snd150628 			case NAME_ERR_TRAILING_SLASH:
1172856Snd150628 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1182856Snd150628 				    "trailing slash in name"));
1192856Snd150628 				break;
1202856Snd150628 
1212856Snd150628 			case NAME_ERR_MULTIPLE_AT:
1222856Snd150628 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1232856Snd150628 				    "multiple '@' delimiters in name"));
1242856Snd150628 				break;
1252856Snd150628 
126789Sahrens 			}
127789Sahrens 		}
1282082Seschrock 		return (B_FALSE);
129789Sahrens 	}
130789Sahrens 
1312082Seschrock 	return (B_TRUE);
132789Sahrens }
133789Sahrens 
134789Sahrens /*
135789Sahrens  * Open a handle to the given pool, even if the pool is currently in the FAULTED
136789Sahrens  * state.
137789Sahrens  */
138789Sahrens zpool_handle_t *
1392082Seschrock zpool_open_canfail(libzfs_handle_t *hdl, const char *pool)
140789Sahrens {
141789Sahrens 	zpool_handle_t *zhp;
1422142Seschrock 	boolean_t missing;
143789Sahrens 
144789Sahrens 	/*
145789Sahrens 	 * Make sure the pool name is valid.
146789Sahrens 	 */
1472082Seschrock 	if (!zpool_name_valid(hdl, B_TRUE, pool)) {
1483237Slling 		(void) zfs_error_fmt(hdl, EZFS_INVALIDNAME,
1492082Seschrock 		    dgettext(TEXT_DOMAIN, "cannot open '%s'"),
1502082Seschrock 		    pool);
151789Sahrens 		return (NULL);
152789Sahrens 	}
153789Sahrens 
1542082Seschrock 	if ((zhp = zfs_alloc(hdl, sizeof (zpool_handle_t))) == NULL)
1552082Seschrock 		return (NULL);
156789Sahrens 
1572082Seschrock 	zhp->zpool_hdl = hdl;
158789Sahrens 	(void) strlcpy(zhp->zpool_name, pool, sizeof (zhp->zpool_name));
159789Sahrens 
1602142Seschrock 	if (zpool_refresh_stats(zhp, &missing) != 0) {
1612142Seschrock 		zpool_close(zhp);
1622142Seschrock 		return (NULL);
1632142Seschrock 	}
1642142Seschrock 
1652142Seschrock 	if (missing) {
1662142Seschrock 		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1672142Seschrock 		    "no such pool"));
1683237Slling 		(void) zfs_error_fmt(hdl, EZFS_NOENT,
1692142Seschrock 		    dgettext(TEXT_DOMAIN, "cannot open '%s'"),
1702142Seschrock 		    pool);
1712142Seschrock 		zpool_close(zhp);
1722142Seschrock 		return (NULL);
173789Sahrens 	}
174789Sahrens 
175789Sahrens 	return (zhp);
176789Sahrens }
177789Sahrens 
178789Sahrens /*
179789Sahrens  * Like the above, but silent on error.  Used when iterating over pools (because
180789Sahrens  * the configuration cache may be out of date).
181789Sahrens  */
1822142Seschrock int
1832142Seschrock zpool_open_silent(libzfs_handle_t *hdl, const char *pool, zpool_handle_t **ret)
184789Sahrens {
185789Sahrens 	zpool_handle_t *zhp;
1862142Seschrock 	boolean_t missing;
187789Sahrens 
1882142Seschrock 	if ((zhp = zfs_alloc(hdl, sizeof (zpool_handle_t))) == NULL)
1892142Seschrock 		return (-1);
190789Sahrens 
1912082Seschrock 	zhp->zpool_hdl = hdl;
192789Sahrens 	(void) strlcpy(zhp->zpool_name, pool, sizeof (zhp->zpool_name));
193789Sahrens 
1942142Seschrock 	if (zpool_refresh_stats(zhp, &missing) != 0) {
1952142Seschrock 		zpool_close(zhp);
1962142Seschrock 		return (-1);
197789Sahrens 	}
198789Sahrens 
1992142Seschrock 	if (missing) {
2002142Seschrock 		zpool_close(zhp);
2012142Seschrock 		*ret = NULL;
2022142Seschrock 		return (0);
2032142Seschrock 	}
2042142Seschrock 
2052142Seschrock 	*ret = zhp;
2062142Seschrock 	return (0);
207789Sahrens }
208789Sahrens 
209789Sahrens /*
210789Sahrens  * Similar to zpool_open_canfail(), but refuses to open pools in the faulted
211789Sahrens  * state.
212789Sahrens  */
213789Sahrens zpool_handle_t *
2142082Seschrock zpool_open(libzfs_handle_t *hdl, const char *pool)
215789Sahrens {
216789Sahrens 	zpool_handle_t *zhp;
217789Sahrens 
2182082Seschrock 	if ((zhp = zpool_open_canfail(hdl, pool)) == NULL)
219789Sahrens 		return (NULL);
220789Sahrens 
221789Sahrens 	if (zhp->zpool_state == POOL_STATE_UNAVAIL) {
2223237Slling 		(void) zfs_error_fmt(hdl, EZFS_POOLUNAVAIL,
2232082Seschrock 		    dgettext(TEXT_DOMAIN, "cannot open '%s'"), zhp->zpool_name);
224789Sahrens 		zpool_close(zhp);
225789Sahrens 		return (NULL);
226789Sahrens 	}
227789Sahrens 
228789Sahrens 	return (zhp);
229789Sahrens }
230789Sahrens 
231789Sahrens /*
232789Sahrens  * Close the handle.  Simply frees the memory associated with the handle.
233789Sahrens  */
234789Sahrens void
235789Sahrens zpool_close(zpool_handle_t *zhp)
236789Sahrens {
237789Sahrens 	if (zhp->zpool_config)
238789Sahrens 		nvlist_free(zhp->zpool_config);
239952Seschrock 	if (zhp->zpool_old_config)
240952Seschrock 		nvlist_free(zhp->zpool_old_config);
241789Sahrens 	free(zhp);
242789Sahrens }
243789Sahrens 
244789Sahrens /*
245789Sahrens  * Return the name of the pool.
246789Sahrens  */
247789Sahrens const char *
248789Sahrens zpool_get_name(zpool_handle_t *zhp)
249789Sahrens {
250789Sahrens 	return (zhp->zpool_name);
251789Sahrens }
252789Sahrens 
253789Sahrens /*
254789Sahrens  * Return the GUID of the pool.
255789Sahrens  */
256789Sahrens uint64_t
257789Sahrens zpool_get_guid(zpool_handle_t *zhp)
258789Sahrens {
259789Sahrens 	uint64_t guid;
260789Sahrens 
261789Sahrens 	verify(nvlist_lookup_uint64(zhp->zpool_config, ZPOOL_CONFIG_POOL_GUID,
262789Sahrens 	    &guid) == 0);
263789Sahrens 	return (guid);
264789Sahrens }
265789Sahrens 
266789Sahrens /*
2672082Seschrock  * Return the version of the pool.
2682082Seschrock  */
2692082Seschrock uint64_t
2702082Seschrock zpool_get_version(zpool_handle_t *zhp)
2712082Seschrock {
2722082Seschrock 	uint64_t version;
2732082Seschrock 
2742082Seschrock 	verify(nvlist_lookup_uint64(zhp->zpool_config, ZPOOL_CONFIG_VERSION,
2752082Seschrock 	    &version) == 0);
2762082Seschrock 
2772082Seschrock 	return (version);
2782082Seschrock }
2792082Seschrock 
2802082Seschrock /*
281789Sahrens  * Return the amount of space currently consumed by the pool.
282789Sahrens  */
283789Sahrens uint64_t
284789Sahrens zpool_get_space_used(zpool_handle_t *zhp)
285789Sahrens {
286789Sahrens 	nvlist_t *nvroot;
287789Sahrens 	vdev_stat_t *vs;
288789Sahrens 	uint_t vsc;
289789Sahrens 
290789Sahrens 	verify(nvlist_lookup_nvlist(zhp->zpool_config, ZPOOL_CONFIG_VDEV_TREE,
291789Sahrens 	    &nvroot) == 0);
292789Sahrens 	verify(nvlist_lookup_uint64_array(nvroot, ZPOOL_CONFIG_STATS,
293789Sahrens 	    (uint64_t **)&vs, &vsc) == 0);
294789Sahrens 
295789Sahrens 	return (vs->vs_alloc);
296789Sahrens }
297789Sahrens 
298789Sahrens /*
299789Sahrens  * Return the total space in the pool.
300789Sahrens  */
301789Sahrens uint64_t
302789Sahrens zpool_get_space_total(zpool_handle_t *zhp)
303789Sahrens {
304789Sahrens 	nvlist_t *nvroot;
305789Sahrens 	vdev_stat_t *vs;
306789Sahrens 	uint_t vsc;
307789Sahrens 
308789Sahrens 	verify(nvlist_lookup_nvlist(zhp->zpool_config, ZPOOL_CONFIG_VDEV_TREE,
309789Sahrens 	    &nvroot) == 0);
310789Sahrens 	verify(nvlist_lookup_uint64_array(nvroot, ZPOOL_CONFIG_STATS,
311789Sahrens 	    (uint64_t **)&vs, &vsc) == 0);
312789Sahrens 
313789Sahrens 	return (vs->vs_space);
314789Sahrens }
315789Sahrens 
316789Sahrens /*
317789Sahrens  * Return the alternate root for this pool, if any.
318789Sahrens  */
319789Sahrens int
320789Sahrens zpool_get_root(zpool_handle_t *zhp, char *buf, size_t buflen)
321789Sahrens {
322789Sahrens 	zfs_cmd_t zc = { 0 };
323789Sahrens 
324789Sahrens 	(void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
3252082Seschrock 	if (ioctl(zhp->zpool_hdl->libzfs_fd, ZFS_IOC_OBJSET_STATS, &zc) != 0 ||
3262676Seschrock 	    zc.zc_value[0] == '\0')
327789Sahrens 		return (-1);
328789Sahrens 
3292676Seschrock 	(void) strlcpy(buf, zc.zc_value, buflen);
330789Sahrens 
331789Sahrens 	return (0);
332789Sahrens }
333789Sahrens 
334789Sahrens /*
335789Sahrens  * Return the state of the pool (ACTIVE or UNAVAILABLE)
336789Sahrens  */
337789Sahrens int
338789Sahrens zpool_get_state(zpool_handle_t *zhp)
339789Sahrens {
340789Sahrens 	return (zhp->zpool_state);
341789Sahrens }
342789Sahrens 
343789Sahrens /*
344789Sahrens  * Create the named pool, using the provided vdev list.  It is assumed
345789Sahrens  * that the consumer has already validated the contents of the nvlist, so we
346789Sahrens  * don't have to worry about error semantics.
347789Sahrens  */
348789Sahrens int
3492082Seschrock zpool_create(libzfs_handle_t *hdl, const char *pool, nvlist_t *nvroot,
3502082Seschrock     const char *altroot)
351789Sahrens {
352789Sahrens 	zfs_cmd_t zc = { 0 };
3532082Seschrock 	char msg[1024];
3542082Seschrock 
3552082Seschrock 	(void) snprintf(msg, sizeof (msg), dgettext(TEXT_DOMAIN,
3562082Seschrock 	    "cannot create '%s'"), pool);
357789Sahrens 
3582082Seschrock 	if (!zpool_name_valid(hdl, B_FALSE, pool))
3592082Seschrock 		return (zfs_error(hdl, EZFS_INVALIDNAME, msg));
3602082Seschrock 
3612082Seschrock 	if (altroot != NULL && altroot[0] != '/')
3623237Slling 		return (zfs_error_fmt(hdl, EZFS_BADPATH,
3632082Seschrock 		    dgettext(TEXT_DOMAIN, "bad alternate root '%s'"), altroot));
364789Sahrens 
3652676Seschrock 	if (zcmd_write_src_nvlist(hdl, &zc, nvroot, NULL) != 0)
366789Sahrens 		return (-1);
367789Sahrens 
368789Sahrens 	(void) strlcpy(zc.zc_name, pool, sizeof (zc.zc_name));
369789Sahrens 
370789Sahrens 	if (altroot != NULL)
3712676Seschrock 		(void) strlcpy(zc.zc_value, altroot, sizeof (zc.zc_value));
372789Sahrens 
3732082Seschrock 	if (ioctl(hdl->libzfs_fd, ZFS_IOC_POOL_CREATE, &zc) != 0) {
3742676Seschrock 		zcmd_free_nvlists(&zc);
3752082Seschrock 
376789Sahrens 		switch (errno) {
377789Sahrens 		case EBUSY:
378789Sahrens 			/*
379789Sahrens 			 * This can happen if the user has specified the same
380789Sahrens 			 * device multiple times.  We can't reliably detect this
381789Sahrens 			 * until we try to add it and see we already have a
382789Sahrens 			 * label.
383789Sahrens 			 */
3842082Seschrock 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3852082Seschrock 			    "one or more vdevs refer to the same device"));
3862082Seschrock 			return (zfs_error(hdl, EZFS_BADDEV, msg));
387789Sahrens 
388789Sahrens 		case EOVERFLOW:
389789Sahrens 			/*
3902082Seschrock 			 * This occurs when one of the devices is below
391789Sahrens 			 * SPA_MINDEVSIZE.  Unfortunately, we can't detect which
392789Sahrens 			 * device was the problem device since there's no
393789Sahrens 			 * reliable way to determine device size from userland.
394789Sahrens 			 */
395789Sahrens 			{
396789Sahrens 				char buf[64];
397789Sahrens 
398789Sahrens 				zfs_nicenum(SPA_MINDEVSIZE, buf, sizeof (buf));
399789Sahrens 
4002082Seschrock 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
4012082Seschrock 				    "one or more devices is less than the "
4022082Seschrock 				    "minimum size (%s)"), buf);
403789Sahrens 			}
4042082Seschrock 			return (zfs_error(hdl, EZFS_BADDEV, msg));
405789Sahrens 
406789Sahrens 		case ENOSPC:
4072082Seschrock 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
4082082Seschrock 			    "one or more devices is out of space"));
4092082Seschrock 			return (zfs_error(hdl, EZFS_BADDEV, msg));
410789Sahrens 
411789Sahrens 		default:
4122082Seschrock 			return (zpool_standard_error(hdl, errno, msg));
413789Sahrens 		}
414789Sahrens 	}
415789Sahrens 
4162676Seschrock 	zcmd_free_nvlists(&zc);
417789Sahrens 
418789Sahrens 	/*
419789Sahrens 	 * If this is an alternate root pool, then we automatically set the
4202676Seschrock 	 * mountpoint of the root dataset to be '/'.
421789Sahrens 	 */
422789Sahrens 	if (altroot != NULL) {
423789Sahrens 		zfs_handle_t *zhp;
424789Sahrens 
4252082Seschrock 		verify((zhp = zfs_open(hdl, pool, ZFS_TYPE_ANY)) != NULL);
4262676Seschrock 		verify(zfs_prop_set(zhp, zfs_prop_to_name(ZFS_PROP_MOUNTPOINT),
4272676Seschrock 		    "/") == 0);
428789Sahrens 
429789Sahrens 		zfs_close(zhp);
430789Sahrens 	}
431789Sahrens 
432789Sahrens 	return (0);
433789Sahrens }
434789Sahrens 
435789Sahrens /*
436789Sahrens  * Destroy the given pool.  It is up to the caller to ensure that there are no
437789Sahrens  * datasets left in the pool.
438789Sahrens  */
439789Sahrens int
440789Sahrens zpool_destroy(zpool_handle_t *zhp)
441789Sahrens {
442789Sahrens 	zfs_cmd_t zc = { 0 };
443789Sahrens 	zfs_handle_t *zfp = NULL;
4442082Seschrock 	libzfs_handle_t *hdl = zhp->zpool_hdl;
4452082Seschrock 	char msg[1024];
446789Sahrens 
447789Sahrens 	if (zhp->zpool_state == POOL_STATE_ACTIVE &&
4482082Seschrock 	    (zfp = zfs_open(zhp->zpool_hdl, zhp->zpool_name,
4492082Seschrock 	    ZFS_TYPE_FILESYSTEM)) == NULL)
450789Sahrens 		return (-1);
451789Sahrens 
4522856Snd150628 	if (zpool_remove_zvol_links(zhp) != 0)
453789Sahrens 		return (-1);
454789Sahrens 
455789Sahrens 	(void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
456789Sahrens 
4572082Seschrock 	if (ioctl(zhp->zpool_hdl->libzfs_fd, ZFS_IOC_POOL_DESTROY, &zc) != 0) {
4582082Seschrock 		(void) snprintf(msg, sizeof (msg), dgettext(TEXT_DOMAIN,
4592082Seschrock 		    "cannot destroy '%s'"), zhp->zpool_name);
460789Sahrens 
4612082Seschrock 		if (errno == EROFS) {
4622082Seschrock 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
4632082Seschrock 			    "one or more devices is read only"));
4642082Seschrock 			(void) zfs_error(hdl, EZFS_BADDEV, msg);
4652082Seschrock 		} else {
4662082Seschrock 			(void) zpool_standard_error(hdl, errno, msg);
467789Sahrens 		}
468789Sahrens 
469789Sahrens 		if (zfp)
470789Sahrens 			zfs_close(zfp);
471789Sahrens 		return (-1);
472789Sahrens 	}
473789Sahrens 
474789Sahrens 	if (zfp) {
475789Sahrens 		remove_mountpoint(zfp);
476789Sahrens 		zfs_close(zfp);
477789Sahrens 	}
478789Sahrens 
479789Sahrens 	return (0);
480789Sahrens }
481789Sahrens 
482789Sahrens /*
483789Sahrens  * Add the given vdevs to the pool.  The caller must have already performed the
484789Sahrens  * necessary verification to ensure that the vdev specification is well-formed.
485789Sahrens  */
486789Sahrens int
487789Sahrens zpool_add(zpool_handle_t *zhp, nvlist_t *nvroot)
488789Sahrens {
4892676Seschrock 	zfs_cmd_t zc = { 0 };
4902082Seschrock 	int ret;
4912082Seschrock 	libzfs_handle_t *hdl = zhp->zpool_hdl;
4922082Seschrock 	char msg[1024];
4932082Seschrock 	nvlist_t **spares;
4942082Seschrock 	uint_t nspares;
4952082Seschrock 
4962082Seschrock 	(void) snprintf(msg, sizeof (msg), dgettext(TEXT_DOMAIN,
4972082Seschrock 	    "cannot add to '%s'"), zhp->zpool_name);
4982082Seschrock 
4992082Seschrock 	if (zpool_get_version(zhp) < ZFS_VERSION_SPARES &&
5002082Seschrock 	    nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_SPARES,
5012082Seschrock 	    &spares, &nspares) == 0) {
5022082Seschrock 		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "pool must be "
5032082Seschrock 		    "upgraded to add hot spares"));
5042082Seschrock 		return (zfs_error(hdl, EZFS_BADVERSION, msg));
5052082Seschrock 	}
506789Sahrens 
5072676Seschrock 	if (zcmd_write_src_nvlist(hdl, &zc, nvroot, NULL) != 0)
5082082Seschrock 		return (-1);
509789Sahrens 	(void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
510789Sahrens 
5112082Seschrock 	if (ioctl(zhp->zpool_hdl->libzfs_fd, ZFS_IOC_VDEV_ADD, &zc) != 0) {
512789Sahrens 		switch (errno) {
513789Sahrens 		case EBUSY:
514789Sahrens 			/*
515789Sahrens 			 * This can happen if the user has specified the same
516789Sahrens 			 * device multiple times.  We can't reliably detect this
517789Sahrens 			 * until we try to add it and see we already have a
518789Sahrens 			 * label.
519789Sahrens 			 */
5202082Seschrock 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
5212082Seschrock 			    "one or more vdevs refer to the same device"));
5222082Seschrock 			(void) zfs_error(hdl, EZFS_BADDEV, msg);
523789Sahrens 			break;
524789Sahrens 
525789Sahrens 		case EOVERFLOW:
526789Sahrens 			/*
527789Sahrens 			 * This occurrs when one of the devices is below
528789Sahrens 			 * SPA_MINDEVSIZE.  Unfortunately, we can't detect which
529789Sahrens 			 * device was the problem device since there's no
530789Sahrens 			 * reliable way to determine device size from userland.
531789Sahrens 			 */
532789Sahrens 			{
533789Sahrens 				char buf[64];
534789Sahrens 
535789Sahrens 				zfs_nicenum(SPA_MINDEVSIZE, buf, sizeof (buf));
536789Sahrens 
5372082Seschrock 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
5382082Seschrock 				    "device is less than the minimum "
5392082Seschrock 				    "size (%s)"), buf);
540789Sahrens 			}
5412082Seschrock 			(void) zfs_error(hdl, EZFS_BADDEV, msg);
5422082Seschrock 			break;
5432082Seschrock 
5442082Seschrock 		case ENOTSUP:
5452082Seschrock 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
5462082Seschrock 			    "pool must be upgraded to add raidz2 vdevs"));
5472082Seschrock 			(void) zfs_error(hdl, EZFS_BADVERSION, msg);
548789Sahrens 			break;
549789Sahrens 
550789Sahrens 		default:
5512082Seschrock 			(void) zpool_standard_error(hdl, errno, msg);
552789Sahrens 		}
553789Sahrens 
5542082Seschrock 		ret = -1;
5552082Seschrock 	} else {
5562082Seschrock 		ret = 0;
557789Sahrens 	}
558789Sahrens 
5592676Seschrock 	zcmd_free_nvlists(&zc);
560789Sahrens 
5612082Seschrock 	return (ret);
562789Sahrens }
563789Sahrens 
564789Sahrens /*
565789Sahrens  * Exports the pool from the system.  The caller must ensure that there are no
566789Sahrens  * mounted datasets in the pool.
567789Sahrens  */
568789Sahrens int
569789Sahrens zpool_export(zpool_handle_t *zhp)
570789Sahrens {
571789Sahrens 	zfs_cmd_t zc = { 0 };
572789Sahrens 
573789Sahrens 	if (zpool_remove_zvol_links(zhp) != 0)
574789Sahrens 		return (-1);
575789Sahrens 
576789Sahrens 	(void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
577789Sahrens 
5782082Seschrock 	if (ioctl(zhp->zpool_hdl->libzfs_fd, ZFS_IOC_POOL_EXPORT, &zc) != 0)
5793237Slling 		return (zpool_standard_error_fmt(zhp->zpool_hdl, errno,
5802082Seschrock 		    dgettext(TEXT_DOMAIN, "cannot export '%s'"),
5812082Seschrock 		    zhp->zpool_name));
582789Sahrens 
583789Sahrens 	return (0);
584789Sahrens }
585789Sahrens 
586789Sahrens /*
587789Sahrens  * Import the given pool using the known configuration.  The configuration
588789Sahrens  * should have come from zpool_find_import().  The 'newname' and 'altroot'
589789Sahrens  * parameters control whether the pool is imported with a different name or with
590789Sahrens  * an alternate root, respectively.
591789Sahrens  */
592789Sahrens int
5932082Seschrock zpool_import(libzfs_handle_t *hdl, nvlist_t *config, const char *newname,
5942082Seschrock     const char *altroot)
595789Sahrens {
5962676Seschrock 	zfs_cmd_t zc = { 0 };
597789Sahrens 	char *thename;
598789Sahrens 	char *origname;
599789Sahrens 	int ret;
600789Sahrens 
601789Sahrens 	verify(nvlist_lookup_string(config, ZPOOL_CONFIG_POOL_NAME,
602789Sahrens 	    &origname) == 0);
603789Sahrens 
604789Sahrens 	if (newname != NULL) {
6052082Seschrock 		if (!zpool_name_valid(hdl, B_FALSE, newname))
6063237Slling 			return (zfs_error_fmt(hdl, EZFS_INVALIDNAME,
6072082Seschrock 			    dgettext(TEXT_DOMAIN, "cannot import '%s'"),
6082082Seschrock 			    newname));
609789Sahrens 		thename = (char *)newname;
610789Sahrens 	} else {
611789Sahrens 		thename = origname;
612789Sahrens 	}
613789Sahrens 
6142082Seschrock 	if (altroot != NULL && altroot[0] != '/')
6153237Slling 		return (zfs_error_fmt(hdl, EZFS_BADPATH,
6162082Seschrock 		    dgettext(TEXT_DOMAIN, "bad alternate root '%s'"),
6172082Seschrock 		    altroot));
618789Sahrens 
619789Sahrens 	(void) strlcpy(zc.zc_name, thename, sizeof (zc.zc_name));
620789Sahrens 
621789Sahrens 	if (altroot != NULL)
6222676Seschrock 		(void) strlcpy(zc.zc_value, altroot, sizeof (zc.zc_value));
623789Sahrens 	else
6242676Seschrock 		zc.zc_value[0] = '\0';
625789Sahrens 
626789Sahrens 	verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_GUID,
6271544Seschrock 	    &zc.zc_guid) == 0);
628789Sahrens 
6292676Seschrock 	if (zcmd_write_src_nvlist(hdl, &zc, config, NULL) != 0)
6302082Seschrock 		return (-1);
631789Sahrens 
632789Sahrens 	ret = 0;
6332082Seschrock 	if (ioctl(hdl->libzfs_fd, ZFS_IOC_POOL_IMPORT, &zc) != 0) {
634789Sahrens 		char desc[1024];
635789Sahrens 		if (newname == NULL)
636789Sahrens 			(void) snprintf(desc, sizeof (desc),
637789Sahrens 			    dgettext(TEXT_DOMAIN, "cannot import '%s'"),
638789Sahrens 			    thename);
639789Sahrens 		else
640789Sahrens 			(void) snprintf(desc, sizeof (desc),
641789Sahrens 			    dgettext(TEXT_DOMAIN, "cannot import '%s' as '%s'"),
642789Sahrens 			    origname, thename);
643789Sahrens 
644789Sahrens 		switch (errno) {
6451544Seschrock 		case ENOTSUP:
6461544Seschrock 			/*
6471544Seschrock 			 * Unsupported version.
6481544Seschrock 			 */
6492082Seschrock 			(void) zfs_error(hdl, EZFS_BADVERSION, desc);
6501544Seschrock 			break;
6511544Seschrock 
6522174Seschrock 		case EINVAL:
6532174Seschrock 			(void) zfs_error(hdl, EZFS_INVALCONFIG, desc);
6542174Seschrock 			break;
6552174Seschrock 
656789Sahrens 		default:
6572082Seschrock 			(void) zpool_standard_error(hdl, errno, desc);
658789Sahrens 		}
659789Sahrens 
660789Sahrens 		ret = -1;
661789Sahrens 	} else {
662789Sahrens 		zpool_handle_t *zhp;
663789Sahrens 		/*
664789Sahrens 		 * This should never fail, but play it safe anyway.
665789Sahrens 		 */
6662142Seschrock 		if (zpool_open_silent(hdl, thename, &zhp) != 0) {
6672142Seschrock 			ret = -1;
6682142Seschrock 		} else if (zhp != NULL) {
669789Sahrens 			ret = zpool_create_zvol_links(zhp);
670789Sahrens 			zpool_close(zhp);
671789Sahrens 		}
672789Sahrens 	}
673789Sahrens 
6742676Seschrock 	zcmd_free_nvlists(&zc);
675789Sahrens 	return (ret);
676789Sahrens }
677789Sahrens 
678789Sahrens /*
679789Sahrens  * Scrub the pool.
680789Sahrens  */
681789Sahrens int
682789Sahrens zpool_scrub(zpool_handle_t *zhp, pool_scrub_type_t type)
683789Sahrens {
684789Sahrens 	zfs_cmd_t zc = { 0 };
685789Sahrens 	char msg[1024];
6862082Seschrock 	libzfs_handle_t *hdl = zhp->zpool_hdl;
687789Sahrens 
688789Sahrens 	(void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
689789Sahrens 	zc.zc_cookie = type;
690789Sahrens 
6912082Seschrock 	if (ioctl(zhp->zpool_hdl->libzfs_fd, ZFS_IOC_POOL_SCRUB, &zc) == 0)
692789Sahrens 		return (0);
693789Sahrens 
694789Sahrens 	(void) snprintf(msg, sizeof (msg),
695789Sahrens 	    dgettext(TEXT_DOMAIN, "cannot scrub %s"), zc.zc_name);
696789Sahrens 
6972082Seschrock 	if (errno == EBUSY)
6982082Seschrock 		return (zfs_error(hdl, EZFS_RESILVERING, msg));
6992082Seschrock 	else
7002082Seschrock 		return (zpool_standard_error(hdl, errno, msg));
701789Sahrens }
702789Sahrens 
7032468Sek110237 /*
7042468Sek110237  * 'avail_spare' is set to TRUE if the provided guid refers to an AVAIL
7052468Sek110237  * spare; but FALSE if its an INUSE spare.
7062468Sek110237  */
7072082Seschrock static nvlist_t *
7082082Seschrock vdev_to_nvlist_iter(nvlist_t *nv, const char *search, uint64_t guid,
7092468Sek110237     boolean_t *avail_spare)
7101544Seschrock {
7111544Seschrock 	uint_t c, children;
7121544Seschrock 	nvlist_t **child;
7132082Seschrock 	uint64_t theguid, present;
7141544Seschrock 	char *path;
7151544Seschrock 	uint64_t wholedisk = 0;
7162082Seschrock 	nvlist_t *ret;
7171544Seschrock 
7182082Seschrock 	verify(nvlist_lookup_uint64(nv, ZPOOL_CONFIG_GUID, &theguid) == 0);
7191544Seschrock 
7201544Seschrock 	if (search == NULL &&
7211544Seschrock 	    nvlist_lookup_uint64(nv, ZPOOL_CONFIG_NOT_PRESENT, &present) == 0) {
7221544Seschrock 		/*
7231544Seschrock 		 * If the device has never been present since import, the only
7241544Seschrock 		 * reliable way to match the vdev is by GUID.
7251544Seschrock 		 */
7262082Seschrock 		if (theguid == guid)
7272082Seschrock 			return (nv);
7281544Seschrock 	} else if (search != NULL &&
7291544Seschrock 	    nvlist_lookup_string(nv, ZPOOL_CONFIG_PATH, &path) == 0) {
7301544Seschrock 		(void) nvlist_lookup_uint64(nv, ZPOOL_CONFIG_WHOLE_DISK,
7311544Seschrock 		    &wholedisk);
7321544Seschrock 		if (wholedisk) {
7331544Seschrock 			/*
7341544Seschrock 			 * For whole disks, the internal path has 's0', but the
7351544Seschrock 			 * path passed in by the user doesn't.
7361544Seschrock 			 */
7371544Seschrock 			if (strlen(search) == strlen(path) - 2 &&
7381544Seschrock 			    strncmp(search, path, strlen(search)) == 0)
7392082Seschrock 				return (nv);
7401544Seschrock 		} else if (strcmp(search, path) == 0) {
7412082Seschrock 			return (nv);
7421544Seschrock 		}
7431544Seschrock 	}
7441544Seschrock 
7451544Seschrock 	if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
7461544Seschrock 	    &child, &children) != 0)
7472082Seschrock 		return (NULL);
7481544Seschrock 
7491544Seschrock 	for (c = 0; c < children; c++)
7502082Seschrock 		if ((ret = vdev_to_nvlist_iter(child[c], search, guid,
7512468Sek110237 		    avail_spare)) != NULL)
7521544Seschrock 			return (ret);
7531544Seschrock 
7542082Seschrock 	if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_SPARES,
7552082Seschrock 	    &child, &children) == 0) {
7562082Seschrock 		for (c = 0; c < children; c++) {
7572082Seschrock 			if ((ret = vdev_to_nvlist_iter(child[c], search, guid,
7582468Sek110237 			    avail_spare)) != NULL) {
7592468Sek110237 				*avail_spare = B_TRUE;
7602082Seschrock 				return (ret);
7612082Seschrock 			}
7622082Seschrock 		}
7632082Seschrock 	}
7642082Seschrock 
7652082Seschrock 	return (NULL);
7661544Seschrock }
7671544Seschrock 
7682082Seschrock nvlist_t *
7692468Sek110237 zpool_find_vdev(zpool_handle_t *zhp, const char *path, boolean_t *avail_spare)
7701544Seschrock {
7711544Seschrock 	char buf[MAXPATHLEN];
7721544Seschrock 	const char *search;
7731544Seschrock 	char *end;
7741544Seschrock 	nvlist_t *nvroot;
7751544Seschrock 	uint64_t guid;
7761544Seschrock 
7771613Seschrock 	guid = strtoull(path, &end, 10);
7781544Seschrock 	if (guid != 0 && *end == '\0') {
7791544Seschrock 		search = NULL;
7801544Seschrock 	} else if (path[0] != '/') {
7811544Seschrock 		(void) snprintf(buf, sizeof (buf), "%s%s", "/dev/dsk/", path);
7821544Seschrock 		search = buf;
7831544Seschrock 	} else {
7841544Seschrock 		search = path;
7851544Seschrock 	}
7861544Seschrock 
7871544Seschrock 	verify(nvlist_lookup_nvlist(zhp->zpool_config, ZPOOL_CONFIG_VDEV_TREE,
7881544Seschrock 	    &nvroot) == 0);
7891544Seschrock 
7902468Sek110237 	*avail_spare = B_FALSE;
7912468Sek110237 	return (vdev_to_nvlist_iter(nvroot, search, guid, avail_spare));
7922468Sek110237 }
7932468Sek110237 
7942468Sek110237 /*
7952468Sek110237  * Returns TRUE if the given guid corresponds to a spare (INUSE or not).
7962468Sek110237  */
7972468Sek110237 static boolean_t
7982468Sek110237 is_spare(zpool_handle_t *zhp, uint64_t guid)
7992468Sek110237 {
8002468Sek110237 	uint64_t spare_guid;
8012468Sek110237 	nvlist_t *nvroot;
8022468Sek110237 	nvlist_t **spares;
8032468Sek110237 	uint_t nspares;
8042468Sek110237 	int i;
8052468Sek110237 
8062468Sek110237 	verify(nvlist_lookup_nvlist(zhp->zpool_config, ZPOOL_CONFIG_VDEV_TREE,
8072468Sek110237 	    &nvroot) == 0);
8082468Sek110237 	if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_SPARES,
8092468Sek110237 	    &spares, &nspares) == 0) {
8102468Sek110237 		for (i = 0; i < nspares; i++) {
8112468Sek110237 			verify(nvlist_lookup_uint64(spares[i],
8122468Sek110237 			    ZPOOL_CONFIG_GUID, &spare_guid) == 0);
8132468Sek110237 			if (guid == spare_guid)
8142468Sek110237 				return (B_TRUE);
8152468Sek110237 		}
8162468Sek110237 	}
8172468Sek110237 
8182468Sek110237 	return (B_FALSE);
8191544Seschrock }
8201544Seschrock 
821789Sahrens /*
822789Sahrens  * Bring the specified vdev online
823789Sahrens  */
824789Sahrens int
825789Sahrens zpool_vdev_online(zpool_handle_t *zhp, const char *path)
826789Sahrens {
827789Sahrens 	zfs_cmd_t zc = { 0 };
828789Sahrens 	char msg[1024];
8292082Seschrock 	nvlist_t *tgt;
8302468Sek110237 	boolean_t avail_spare;
8312082Seschrock 	libzfs_handle_t *hdl = zhp->zpool_hdl;
832789Sahrens 
8331544Seschrock 	(void) snprintf(msg, sizeof (msg),
8341544Seschrock 	    dgettext(TEXT_DOMAIN, "cannot online %s"), path);
835789Sahrens 
8361544Seschrock 	(void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
8372468Sek110237 	if ((tgt = zpool_find_vdev(zhp, path, &avail_spare)) == NULL)
8382082Seschrock 		return (zfs_error(hdl, EZFS_NODEVICE, msg));
839789Sahrens 
8402468Sek110237 	verify(nvlist_lookup_uint64(tgt, ZPOOL_CONFIG_GUID, &zc.zc_guid) == 0);
8412468Sek110237 
8422468Sek110237 	if (avail_spare || is_spare(zhp, zc.zc_guid) == B_TRUE)
8432082Seschrock 		return (zfs_error(hdl, EZFS_ISSPARE, msg));
8442082Seschrock 
8452082Seschrock 	if (ioctl(zhp->zpool_hdl->libzfs_fd, ZFS_IOC_VDEV_ONLINE, &zc) == 0)
8461544Seschrock 		return (0);
847789Sahrens 
8482082Seschrock 	return (zpool_standard_error(hdl, errno, msg));
849789Sahrens }
850789Sahrens 
851789Sahrens /*
852789Sahrens  * Take the specified vdev offline
853789Sahrens  */
854789Sahrens int
8551485Slling zpool_vdev_offline(zpool_handle_t *zhp, const char *path, int istmp)
856789Sahrens {
857789Sahrens 	zfs_cmd_t zc = { 0 };
858789Sahrens 	char msg[1024];
8592082Seschrock 	nvlist_t *tgt;
8602468Sek110237 	boolean_t avail_spare;
8612082Seschrock 	libzfs_handle_t *hdl = zhp->zpool_hdl;
862789Sahrens 
8631544Seschrock 	(void) snprintf(msg, sizeof (msg),
8641544Seschrock 	    dgettext(TEXT_DOMAIN, "cannot offline %s"), path);
8651544Seschrock 
866789Sahrens 	(void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
8672468Sek110237 	if ((tgt = zpool_find_vdev(zhp, path, &avail_spare)) == NULL)
8682082Seschrock 		return (zfs_error(hdl, EZFS_NODEVICE, msg));
8692082Seschrock 
8702468Sek110237 	verify(nvlist_lookup_uint64(tgt, ZPOOL_CONFIG_GUID, &zc.zc_guid) == 0);
8712468Sek110237 
8722468Sek110237 	if (avail_spare || is_spare(zhp, zc.zc_guid) == B_TRUE)
8732082Seschrock 		return (zfs_error(hdl, EZFS_ISSPARE, msg));
8742082Seschrock 
8751485Slling 	zc.zc_cookie = istmp;
8761485Slling 
8772082Seschrock 	if (ioctl(zhp->zpool_hdl->libzfs_fd, ZFS_IOC_VDEV_OFFLINE, &zc) == 0)
878789Sahrens 		return (0);
879789Sahrens 
880789Sahrens 	switch (errno) {
8812082Seschrock 	case EBUSY:
882789Sahrens 
883789Sahrens 		/*
884789Sahrens 		 * There are no other replicas of this device.
885789Sahrens 		 */
8862082Seschrock 		return (zfs_error(hdl, EZFS_NOREPLICAS, msg));
8872082Seschrock 
8882082Seschrock 	default:
8892082Seschrock 		return (zpool_standard_error(hdl, errno, msg));
8902082Seschrock 	}
8912082Seschrock }
892789Sahrens 
8932082Seschrock /*
8942082Seschrock  * Returns TRUE if the given nvlist is a vdev that was originally swapped in as
8952082Seschrock  * a hot spare.
8962082Seschrock  */
8972082Seschrock static boolean_t
8982082Seschrock is_replacing_spare(nvlist_t *search, nvlist_t *tgt, int which)
8992082Seschrock {
9002082Seschrock 	nvlist_t **child;
9012082Seschrock 	uint_t c, children;
9022082Seschrock 	char *type;
9032082Seschrock 
9042082Seschrock 	if (nvlist_lookup_nvlist_array(search, ZPOOL_CONFIG_CHILDREN, &child,
9052082Seschrock 	    &children) == 0) {
9062082Seschrock 		verify(nvlist_lookup_string(search, ZPOOL_CONFIG_TYPE,
9072082Seschrock 		    &type) == 0);
9082082Seschrock 
9092082Seschrock 		if (strcmp(type, VDEV_TYPE_SPARE) == 0 &&
9102082Seschrock 		    children == 2 && child[which] == tgt)
9112082Seschrock 			return (B_TRUE);
9122082Seschrock 
9132082Seschrock 		for (c = 0; c < children; c++)
9142082Seschrock 			if (is_replacing_spare(child[c], tgt, which))
9152082Seschrock 				return (B_TRUE);
916789Sahrens 	}
9172082Seschrock 
9182082Seschrock 	return (B_FALSE);
919789Sahrens }
920789Sahrens 
921789Sahrens /*
922789Sahrens  * Attach new_disk (fully described by nvroot) to old_disk.
923789Sahrens  * If 'replacing' is specified, tne new disk will replace the old one.
924789Sahrens  */
925789Sahrens int
926789Sahrens zpool_vdev_attach(zpool_handle_t *zhp,
927789Sahrens     const char *old_disk, const char *new_disk, nvlist_t *nvroot, int replacing)
928789Sahrens {
929789Sahrens 	zfs_cmd_t zc = { 0 };
930789Sahrens 	char msg[1024];
931789Sahrens 	int ret;
9322082Seschrock 	nvlist_t *tgt;
9332468Sek110237 	boolean_t avail_spare;
9342082Seschrock 	uint64_t val;
9352082Seschrock 	char *path;
9362082Seschrock 	nvlist_t **child;
9372082Seschrock 	uint_t children;
9382082Seschrock 	nvlist_t *config_root;
9392082Seschrock 	libzfs_handle_t *hdl = zhp->zpool_hdl;
940789Sahrens 
9411544Seschrock 	if (replacing)
9421544Seschrock 		(void) snprintf(msg, sizeof (msg), dgettext(TEXT_DOMAIN,
9431544Seschrock 		    "cannot replace %s with %s"), old_disk, new_disk);
9441544Seschrock 	else
9451544Seschrock 		(void) snprintf(msg, sizeof (msg), dgettext(TEXT_DOMAIN,
9461544Seschrock 		    "cannot attach %s to %s"), new_disk, old_disk);
9471544Seschrock 
948789Sahrens 	(void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
9492468Sek110237 	if ((tgt = zpool_find_vdev(zhp, old_disk, &avail_spare)) == 0)
9502082Seschrock 		return (zfs_error(hdl, EZFS_NODEVICE, msg));
9512082Seschrock 
9522468Sek110237 	if (avail_spare)
9532082Seschrock 		return (zfs_error(hdl, EZFS_ISSPARE, msg));
9542082Seschrock 
9552082Seschrock 	verify(nvlist_lookup_uint64(tgt, ZPOOL_CONFIG_GUID, &zc.zc_guid) == 0);
9562082Seschrock 	zc.zc_cookie = replacing;
9572082Seschrock 
9582082Seschrock 	if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_CHILDREN,
9592082Seschrock 	    &child, &children) != 0 || children != 1) {
9602082Seschrock 		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
9612082Seschrock 		    "new device must be a single disk"));
9622082Seschrock 		return (zfs_error(hdl, EZFS_INVALCONFIG, msg));
9631544Seschrock 	}
9642082Seschrock 
9652082Seschrock 	verify(nvlist_lookup_nvlist(zpool_get_config(zhp, NULL),
9662082Seschrock 	    ZPOOL_CONFIG_VDEV_TREE, &config_root) == 0);
9672082Seschrock 
9682082Seschrock 	/*
9692082Seschrock 	 * If the target is a hot spare that has been swapped in, we can only
9702082Seschrock 	 * replace it with another hot spare.
9712082Seschrock 	 */
9722082Seschrock 	if (replacing &&
9732082Seschrock 	    nvlist_lookup_uint64(tgt, ZPOOL_CONFIG_IS_SPARE, &val) == 0 &&
9742082Seschrock 	    nvlist_lookup_string(child[0], ZPOOL_CONFIG_PATH, &path) == 0 &&
9752468Sek110237 	    (zpool_find_vdev(zhp, path, &avail_spare) == NULL ||
9762468Sek110237 	    !avail_spare) && is_replacing_spare(config_root, tgt, 1)) {
9772082Seschrock 		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
9782082Seschrock 		    "can only be replaced by another hot spare"));
9792082Seschrock 		return (zfs_error(hdl, EZFS_BADTARGET, msg));
9802082Seschrock 	}
9812082Seschrock 
9822082Seschrock 	/*
9832082Seschrock 	 * If we are attempting to replace a spare, it canot be applied to an
9842082Seschrock 	 * already spared device.
9852082Seschrock 	 */
9862082Seschrock 	if (replacing &&
9872082Seschrock 	    nvlist_lookup_string(child[0], ZPOOL_CONFIG_PATH, &path) == 0 &&
9882468Sek110237 	    zpool_find_vdev(zhp, path, &avail_spare) != NULL && avail_spare &&
9892082Seschrock 	    is_replacing_spare(config_root, tgt, 0)) {
9902082Seschrock 		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
9912082Seschrock 		    "device has already been replaced with a spare"));
9922082Seschrock 		return (zfs_error(hdl, EZFS_BADTARGET, msg));
9932082Seschrock 	}
994789Sahrens 
9952676Seschrock 	if (zcmd_write_src_nvlist(hdl, &zc, nvroot, NULL) != 0)
9962082Seschrock 		return (-1);
997789Sahrens 
9982082Seschrock 	ret = ioctl(zhp->zpool_hdl->libzfs_fd, ZFS_IOC_VDEV_ATTACH, &zc);
999789Sahrens 
10002676Seschrock 	zcmd_free_nvlists(&zc);
1001789Sahrens 
1002789Sahrens 	if (ret == 0)
1003789Sahrens 		return (0);
1004789Sahrens 
1005789Sahrens 	switch (errno) {
10061544Seschrock 	case ENOTSUP:
1007789Sahrens 		/*
1008789Sahrens 		 * Can't attach to or replace this type of vdev.
1009789Sahrens 		 */
1010789Sahrens 		if (replacing)
10112082Seschrock 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
10122082Seschrock 			    "cannot replace a replacing device"));
1013789Sahrens 		else
10142082Seschrock 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
10152082Seschrock 			    "can only attach to mirrors and top-level "
10162082Seschrock 			    "disks"));
10172082Seschrock 		(void) zfs_error(hdl, EZFS_BADTARGET, msg);
1018789Sahrens 		break;
1019789Sahrens 
10201544Seschrock 	case EINVAL:
1021789Sahrens 		/*
1022789Sahrens 		 * The new device must be a single disk.
1023789Sahrens 		 */
10242082Seschrock 		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
10252082Seschrock 		    "new device must be a single disk"));
10262082Seschrock 		(void) zfs_error(hdl, EZFS_INVALCONFIG, msg);
1027789Sahrens 		break;
1028789Sahrens 
10291544Seschrock 	case EBUSY:
10302082Seschrock 		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "%s is busy"),
10312082Seschrock 		    new_disk);
10322082Seschrock 		(void) zfs_error(hdl, EZFS_BADDEV, msg);
1033789Sahrens 		break;
1034789Sahrens 
10351544Seschrock 	case EOVERFLOW:
1036789Sahrens 		/*
1037789Sahrens 		 * The new device is too small.
1038789Sahrens 		 */
10392082Seschrock 		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
10402082Seschrock 		    "device is too small"));
10412082Seschrock 		(void) zfs_error(hdl, EZFS_BADDEV, msg);
1042789Sahrens 		break;
1043789Sahrens 
10441544Seschrock 	case EDOM:
1045789Sahrens 		/*
1046789Sahrens 		 * The new device has a different alignment requirement.
1047789Sahrens 		 */
10482082Seschrock 		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
10492082Seschrock 		    "devices have different sector alignment"));
10502082Seschrock 		(void) zfs_error(hdl, EZFS_BADDEV, msg);
1051789Sahrens 		break;
1052789Sahrens 
10531544Seschrock 	case ENAMETOOLONG:
1054789Sahrens 		/*
1055789Sahrens 		 * The resulting top-level vdev spec won't fit in the label.
1056789Sahrens 		 */
10572082Seschrock 		(void) zfs_error(hdl, EZFS_DEVOVERFLOW, msg);
1058789Sahrens 		break;
1059789Sahrens 
10601544Seschrock 	default:
10612082Seschrock 		(void) zpool_standard_error(hdl, errno, msg);
1062789Sahrens 	}
1063789Sahrens 
10642082Seschrock 	return (-1);
1065789Sahrens }
1066789Sahrens 
1067789Sahrens /*
1068789Sahrens  * Detach the specified device.
1069789Sahrens  */
1070789Sahrens int
1071789Sahrens zpool_vdev_detach(zpool_handle_t *zhp, const char *path)
1072789Sahrens {
1073789Sahrens 	zfs_cmd_t zc = { 0 };
1074789Sahrens 	char msg[1024];
10752082Seschrock 	nvlist_t *tgt;
10762468Sek110237 	boolean_t avail_spare;
10772082Seschrock 	libzfs_handle_t *hdl = zhp->zpool_hdl;
1078789Sahrens 
10791544Seschrock 	(void) snprintf(msg, sizeof (msg),
10801544Seschrock 	    dgettext(TEXT_DOMAIN, "cannot detach %s"), path);
10811544Seschrock 
1082789Sahrens 	(void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
10832468Sek110237 	if ((tgt = zpool_find_vdev(zhp, path, &avail_spare)) == 0)
10842082Seschrock 		return (zfs_error(hdl, EZFS_NODEVICE, msg));
1085789Sahrens 
10862468Sek110237 	if (avail_spare)
10872082Seschrock 		return (zfs_error(hdl, EZFS_ISSPARE, msg));
10882082Seschrock 
10892082Seschrock 	verify(nvlist_lookup_uint64(tgt, ZPOOL_CONFIG_GUID, &zc.zc_guid) == 0);
10902082Seschrock 
10912082Seschrock 	if (ioctl(hdl->libzfs_fd, ZFS_IOC_VDEV_DETACH, &zc) == 0)
1092789Sahrens 		return (0);
1093789Sahrens 
1094789Sahrens 	switch (errno) {
1095789Sahrens 
10961544Seschrock 	case ENOTSUP:
1097789Sahrens 		/*
1098789Sahrens 		 * Can't detach from this type of vdev.
1099789Sahrens 		 */
11002082Seschrock 		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "only "
11012082Seschrock 		    "applicable to mirror and replacing vdevs"));
11022082Seschrock 		(void) zfs_error(zhp->zpool_hdl, EZFS_BADTARGET, msg);
1103789Sahrens 		break;
1104789Sahrens 
11051544Seschrock 	case EBUSY:
1106789Sahrens 		/*
1107789Sahrens 		 * There are no other replicas of this device.
1108789Sahrens 		 */
11092082Seschrock 		(void) zfs_error(hdl, EZFS_NOREPLICAS, msg);
1110789Sahrens 		break;
1111789Sahrens 
11121544Seschrock 	default:
11132082Seschrock 		(void) zpool_standard_error(hdl, errno, msg);
11141544Seschrock 	}
11151544Seschrock 
11162082Seschrock 	return (-1);
11172082Seschrock }
11182082Seschrock 
11192082Seschrock /*
11202082Seschrock  * Remove the given device.  Currently, this is supported only for hot spares.
11212082Seschrock  */
11222082Seschrock int
11232082Seschrock zpool_vdev_remove(zpool_handle_t *zhp, const char *path)
11242082Seschrock {
11252082Seschrock 	zfs_cmd_t zc = { 0 };
11262082Seschrock 	char msg[1024];
11272082Seschrock 	nvlist_t *tgt;
11282468Sek110237 	boolean_t avail_spare;
11292082Seschrock 	libzfs_handle_t *hdl = zhp->zpool_hdl;
11302082Seschrock 
11312082Seschrock 	(void) snprintf(msg, sizeof (msg),
11322082Seschrock 	    dgettext(TEXT_DOMAIN, "cannot remove %s"), path);
11332082Seschrock 
11342082Seschrock 	(void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
11352468Sek110237 	if ((tgt = zpool_find_vdev(zhp, path, &avail_spare)) == 0)
11362082Seschrock 		return (zfs_error(hdl, EZFS_NODEVICE, msg));
11372082Seschrock 
11382468Sek110237 	if (!avail_spare) {
11392082Seschrock 		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
11403377Seschrock 		    "only inactive hot spares can be removed"));
11412082Seschrock 		return (zfs_error(hdl, EZFS_NODEVICE, msg));
11422082Seschrock 	}
11432082Seschrock 
11442082Seschrock 	verify(nvlist_lookup_uint64(tgt, ZPOOL_CONFIG_GUID, &zc.zc_guid) == 0);
11452082Seschrock 
11462082Seschrock 	if (ioctl(hdl->libzfs_fd, ZFS_IOC_VDEV_REMOVE, &zc) == 0)
11472082Seschrock 		return (0);
11482082Seschrock 
11492082Seschrock 	return (zpool_standard_error(hdl, errno, msg));
11501544Seschrock }
11511544Seschrock 
11521544Seschrock /*
11531544Seschrock  * Clear the errors for the pool, or the particular device if specified.
11541544Seschrock  */
11551544Seschrock int
11561544Seschrock zpool_clear(zpool_handle_t *zhp, const char *path)
11571544Seschrock {
11581544Seschrock 	zfs_cmd_t zc = { 0 };
11591544Seschrock 	char msg[1024];
11602082Seschrock 	nvlist_t *tgt;
11612468Sek110237 	boolean_t avail_spare;
11622082Seschrock 	libzfs_handle_t *hdl = zhp->zpool_hdl;
11631544Seschrock 
11641544Seschrock 	if (path)
11651544Seschrock 		(void) snprintf(msg, sizeof (msg),
11661544Seschrock 		    dgettext(TEXT_DOMAIN, "cannot clear errors for %s"),
11672676Seschrock 		    path);
11681544Seschrock 	else
11691544Seschrock 		(void) snprintf(msg, sizeof (msg),
11701544Seschrock 		    dgettext(TEXT_DOMAIN, "cannot clear errors for %s"),
11711544Seschrock 		    zhp->zpool_name);
11721544Seschrock 
11731544Seschrock 	(void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
11742082Seschrock 	if (path) {
11752468Sek110237 		if ((tgt = zpool_find_vdev(zhp, path, &avail_spare)) == 0)
11762082Seschrock 			return (zfs_error(hdl, EZFS_NODEVICE, msg));
11772082Seschrock 
11782468Sek110237 		if (avail_spare)
11792082Seschrock 			return (zfs_error(hdl, EZFS_ISSPARE, msg));
11802082Seschrock 
11812082Seschrock 		verify(nvlist_lookup_uint64(tgt, ZPOOL_CONFIG_GUID,
11822082Seschrock 		    &zc.zc_guid) == 0);
11831544Seschrock 	}
11841544Seschrock 
11852082Seschrock 	if (ioctl(hdl->libzfs_fd, ZFS_IOC_CLEAR, &zc) == 0)
11861544Seschrock 		return (0);
11871544Seschrock 
11882082Seschrock 	return (zpool_standard_error(hdl, errno, msg));
1189789Sahrens }
1190789Sahrens 
11913126Sahl /*
11923126Sahl  * Iterate over all zvols in a given pool by walking the /dev/zvol/dsk/<pool>
11933126Sahl  * hierarchy.
11943126Sahl  */
11953126Sahl int
11963126Sahl zpool_iter_zvol(zpool_handle_t *zhp, int (*cb)(const char *, void *),
11973126Sahl     void *data)
1198789Sahrens {
11993126Sahl 	libzfs_handle_t *hdl = zhp->zpool_hdl;
12003126Sahl 	char (*paths)[MAXPATHLEN];
12013126Sahl 	size_t size = 4;
12023126Sahl 	int curr, fd, base, ret = 0;
12033126Sahl 	DIR *dirp;
12043126Sahl 	struct dirent *dp;
12053126Sahl 	struct stat st;
12063126Sahl 
12073126Sahl 	if ((base = open("/dev/zvol/dsk", O_RDONLY)) < 0)
12083126Sahl 		return (errno == ENOENT ? 0 : -1);
12093126Sahl 
12103126Sahl 	if (fstatat(base, zhp->zpool_name, &st, 0) != 0) {
12113126Sahl 		int err = errno;
12123126Sahl 		(void) close(base);
12133126Sahl 		return (err == ENOENT ? 0 : -1);
12143126Sahl 	}
1215789Sahrens 
1216789Sahrens 	/*
12173126Sahl 	 * Oddly this wasn't a directory -- ignore that failure since we
12183126Sahl 	 * know there are no links lower in the (non-existant) hierarchy.
1219789Sahrens 	 */
12203126Sahl 	if (!S_ISDIR(st.st_mode)) {
12213126Sahl 		(void) close(base);
12223126Sahl 		return (0);
12233126Sahl 	}
12243126Sahl 
12253126Sahl 	if ((paths = zfs_alloc(hdl, size * sizeof (paths[0]))) == NULL) {
12263126Sahl 		(void) close(base);
12273126Sahl 		return (-1);
1228789Sahrens 	}
1229789Sahrens 
12303126Sahl 	(void) strlcpy(paths[0], zhp->zpool_name, sizeof (paths[0]));
12313126Sahl 	curr = 0;
12323126Sahl 
12333126Sahl 	while (curr >= 0) {
12343126Sahl 		if (fstatat(base, paths[curr], &st, AT_SYMLINK_NOFOLLOW) != 0)
12353126Sahl 			goto err;
12363126Sahl 
12373126Sahl 		if (S_ISDIR(st.st_mode)) {
12383126Sahl 			if ((fd = openat(base, paths[curr], O_RDONLY)) < 0)
12393126Sahl 				goto err;
12403126Sahl 
12413126Sahl 			if ((dirp = fdopendir(fd)) == NULL) {
12423126Sahl 				(void) close(fd);
12433126Sahl 				goto err;
12443126Sahl 			}
12453126Sahl 
12463126Sahl 			while ((dp = readdir(dirp)) != NULL) {
12473126Sahl 				if (dp->d_name[0] == '.')
12483126Sahl 					continue;
12493126Sahl 
12503126Sahl 				if (curr + 1 == size) {
12513126Sahl 					paths = zfs_realloc(hdl, paths,
12523126Sahl 					    size * sizeof (paths[0]),
12533126Sahl 					    size * 2 * sizeof (paths[0]));
12543126Sahl 					if (paths == NULL) {
12553126Sahl 						(void) closedir(dirp);
12563126Sahl 						(void) close(fd);
12573126Sahl 						goto err;
12583126Sahl 					}
12593126Sahl 
12603126Sahl 					size *= 2;
12613126Sahl 				}
12623126Sahl 
12633126Sahl 				(void) strlcpy(paths[curr + 1], paths[curr],
12643126Sahl 				    sizeof (paths[curr + 1]));
12653126Sahl 				(void) strlcat(paths[curr], "/",
12663126Sahl 				    sizeof (paths[curr]));
12673126Sahl 				(void) strlcat(paths[curr], dp->d_name,
12683126Sahl 				    sizeof (paths[curr]));
12693126Sahl 				curr++;
12703126Sahl 			}
12713126Sahl 
12723126Sahl 			(void) closedir(dirp);
12733126Sahl 
12743126Sahl 		} else {
12753126Sahl 			if ((ret = cb(paths[curr], data)) != 0)
12763126Sahl 				break;
12773126Sahl 		}
12783126Sahl 
12793126Sahl 		curr--;
12803126Sahl 	}
12813126Sahl 
12823126Sahl 	free(paths);
12833126Sahl 	(void) close(base);
12843126Sahl 
12853126Sahl 	return (ret);
12863126Sahl 
12873126Sahl err:
12883126Sahl 	free(paths);
12893126Sahl 	(void) close(base);
12903126Sahl 	return (-1);
12913126Sahl }
12923126Sahl 
12933126Sahl typedef struct zvol_cb {
12943126Sahl 	zpool_handle_t *zcb_pool;
12953126Sahl 	boolean_t zcb_create;
12963126Sahl } zvol_cb_t;
12973126Sahl 
12983126Sahl /*ARGSUSED*/
12993126Sahl static int
13003126Sahl do_zvol_create(zfs_handle_t *zhp, void *data)
13013126Sahl {
13023126Sahl 	int ret;
13033126Sahl 
13043126Sahl 	if (ZFS_IS_VOLUME(zhp))
13053126Sahl 		(void) zvol_create_link(zhp->zfs_hdl, zhp->zfs_name);
13063126Sahl 
13073126Sahl 	ret = zfs_iter_children(zhp, do_zvol_create, NULL);
1308789Sahrens 
1309789Sahrens 	zfs_close(zhp);
13103126Sahl 
1311789Sahrens 	return (ret);
1312789Sahrens }
1313789Sahrens 
1314789Sahrens /*
1315789Sahrens  * Iterate over all zvols in the pool and make any necessary minor nodes.
1316789Sahrens  */
1317789Sahrens int
1318789Sahrens zpool_create_zvol_links(zpool_handle_t *zhp)
1319789Sahrens {
1320789Sahrens 	zfs_handle_t *zfp;
1321789Sahrens 	int ret;
1322789Sahrens 
1323789Sahrens 	/*
1324789Sahrens 	 * If the pool is unavailable, just return success.
1325789Sahrens 	 */
13262082Seschrock 	if ((zfp = make_dataset_handle(zhp->zpool_hdl,
13272082Seschrock 	    zhp->zpool_name)) == NULL)
1328789Sahrens 		return (0);
1329789Sahrens 
13303126Sahl 	ret = zfs_iter_children(zfp, do_zvol_create, NULL);
1331789Sahrens 
1332789Sahrens 	zfs_close(zfp);
1333789Sahrens 	return (ret);
1334789Sahrens }
1335789Sahrens 
13363126Sahl static int
13373126Sahl do_zvol_remove(const char *dataset, void *data)
13383126Sahl {
13393126Sahl 	zpool_handle_t *zhp = data;
13403126Sahl 
13413126Sahl 	return (zvol_remove_link(zhp->zpool_hdl, dataset));
13423126Sahl }
13433126Sahl 
1344789Sahrens /*
13453126Sahl  * Iterate over all zvols in the pool and remove any minor nodes.  We iterate
13463126Sahl  * by examining the /dev links so that a corrupted pool doesn't impede this
13473126Sahl  * operation.
1348789Sahrens  */
1349789Sahrens int
1350789Sahrens zpool_remove_zvol_links(zpool_handle_t *zhp)
1351789Sahrens {
13523126Sahl 	return (zpool_iter_zvol(zhp, do_zvol_remove, zhp));
1353789Sahrens }
13541354Seschrock 
13551354Seschrock /*
13561354Seschrock  * Convert from a devid string to a path.
13571354Seschrock  */
13581354Seschrock static char *
13591354Seschrock devid_to_path(char *devid_str)
13601354Seschrock {
13611354Seschrock 	ddi_devid_t devid;
13621354Seschrock 	char *minor;
13631354Seschrock 	char *path;
13641354Seschrock 	devid_nmlist_t *list = NULL;
13651354Seschrock 	int ret;
13661354Seschrock 
13671354Seschrock 	if (devid_str_decode(devid_str, &devid, &minor) != 0)
13681354Seschrock 		return (NULL);
13691354Seschrock 
13701354Seschrock 	ret = devid_deviceid_to_nmlist("/dev", devid, minor, &list);
13711354Seschrock 
13721354Seschrock 	devid_str_free(minor);
13731354Seschrock 	devid_free(devid);
13741354Seschrock 
13751354Seschrock 	if (ret != 0)
13761354Seschrock 		return (NULL);
13771354Seschrock 
13782082Seschrock 	if ((path = strdup(list[0].devname)) == NULL)
13792082Seschrock 		return (NULL);
13802082Seschrock 
13811354Seschrock 	devid_free_nmlist(list);
13821354Seschrock 
13831354Seschrock 	return (path);
13841354Seschrock }
13851354Seschrock 
13861354Seschrock /*
13871354Seschrock  * Convert from a path to a devid string.
13881354Seschrock  */
13891354Seschrock static char *
13901354Seschrock path_to_devid(const char *path)
13911354Seschrock {
13921354Seschrock 	int fd;
13931354Seschrock 	ddi_devid_t devid;
13941354Seschrock 	char *minor, *ret;
13951354Seschrock 
13961354Seschrock 	if ((fd = open(path, O_RDONLY)) < 0)
13971354Seschrock 		return (NULL);
13981354Seschrock 
13991354Seschrock 	minor = NULL;
14001354Seschrock 	ret = NULL;
14011354Seschrock 	if (devid_get(fd, &devid) == 0) {
14021354Seschrock 		if (devid_get_minor_name(fd, &minor) == 0)
14031354Seschrock 			ret = devid_str_encode(devid, minor);
14041354Seschrock 		if (minor != NULL)
14051354Seschrock 			devid_str_free(minor);
14061354Seschrock 		devid_free(devid);
14071354Seschrock 	}
14081354Seschrock 	(void) close(fd);
14091354Seschrock 
14101354Seschrock 	return (ret);
14111354Seschrock }
14121354Seschrock 
14131354Seschrock /*
14141354Seschrock  * Issue the necessary ioctl() to update the stored path value for the vdev.  We
14151354Seschrock  * ignore any failure here, since a common case is for an unprivileged user to
14161354Seschrock  * type 'zpool status', and we'll display the correct information anyway.
14171354Seschrock  */
14181354Seschrock static void
14191354Seschrock set_path(zpool_handle_t *zhp, nvlist_t *nv, const char *path)
14201354Seschrock {
14211354Seschrock 	zfs_cmd_t zc = { 0 };
14221354Seschrock 
14231354Seschrock 	(void) strncpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
14242676Seschrock 	(void) strncpy(zc.zc_value, path, sizeof (zc.zc_value));
14251354Seschrock 	verify(nvlist_lookup_uint64(nv, ZPOOL_CONFIG_GUID,
14261544Seschrock 	    &zc.zc_guid) == 0);
14271354Seschrock 
14282082Seschrock 	(void) ioctl(zhp->zpool_hdl->libzfs_fd, ZFS_IOC_VDEV_SETPATH, &zc);
14291354Seschrock }
14301354Seschrock 
14311354Seschrock /*
14321354Seschrock  * Given a vdev, return the name to display in iostat.  If the vdev has a path,
14331354Seschrock  * we use that, stripping off any leading "/dev/dsk/"; if not, we use the type.
14341354Seschrock  * We also check if this is a whole disk, in which case we strip off the
14351354Seschrock  * trailing 's0' slice name.
14361354Seschrock  *
14371354Seschrock  * This routine is also responsible for identifying when disks have been
14381354Seschrock  * reconfigured in a new location.  The kernel will have opened the device by
14391354Seschrock  * devid, but the path will still refer to the old location.  To catch this, we
14401354Seschrock  * first do a path -> devid translation (which is fast for the common case).  If
14411354Seschrock  * the devid matches, we're done.  If not, we do a reverse devid -> path
14421354Seschrock  * translation and issue the appropriate ioctl() to update the path of the vdev.
14431354Seschrock  * If 'zhp' is NULL, then this is an exported pool, and we don't need to do any
14441354Seschrock  * of these checks.
14451354Seschrock  */
14461354Seschrock char *
14472082Seschrock zpool_vdev_name(libzfs_handle_t *hdl, zpool_handle_t *zhp, nvlist_t *nv)
14481354Seschrock {
14491354Seschrock 	char *path, *devid;
14501544Seschrock 	uint64_t value;
14511544Seschrock 	char buf[64];
14521354Seschrock 
14531544Seschrock 	if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_NOT_PRESENT,
14541544Seschrock 	    &value) == 0) {
14551544Seschrock 		verify(nvlist_lookup_uint64(nv, ZPOOL_CONFIG_GUID,
14561544Seschrock 		    &value) == 0);
14572856Snd150628 		(void) snprintf(buf, sizeof (buf), "%llu",
14582856Snd150628 		    (u_longlong_t)value);
14591544Seschrock 		path = buf;
14601544Seschrock 	} else if (nvlist_lookup_string(nv, ZPOOL_CONFIG_PATH, &path) == 0) {
14611354Seschrock 
14621354Seschrock 		if (zhp != NULL &&
14631354Seschrock 		    nvlist_lookup_string(nv, ZPOOL_CONFIG_DEVID, &devid) == 0) {
14641354Seschrock 			/*
14651354Seschrock 			 * Determine if the current path is correct.
14661354Seschrock 			 */
14671354Seschrock 			char *newdevid = path_to_devid(path);
14681354Seschrock 
14691354Seschrock 			if (newdevid == NULL ||
14701354Seschrock 			    strcmp(devid, newdevid) != 0) {
14711354Seschrock 				char *newpath;
14721354Seschrock 
14731354Seschrock 				if ((newpath = devid_to_path(devid)) != NULL) {
14741354Seschrock 					/*
14751354Seschrock 					 * Update the path appropriately.
14761354Seschrock 					 */
14771354Seschrock 					set_path(zhp, nv, newpath);
14782082Seschrock 					if (nvlist_add_string(nv,
14792082Seschrock 					    ZPOOL_CONFIG_PATH, newpath) == 0)
14802082Seschrock 						verify(nvlist_lookup_string(nv,
14812082Seschrock 						    ZPOOL_CONFIG_PATH,
14822082Seschrock 						    &path) == 0);
14831354Seschrock 					free(newpath);
14841354Seschrock 				}
14851354Seschrock 			}
14861354Seschrock 
14872082Seschrock 			if (newdevid)
14882082Seschrock 				devid_str_free(newdevid);
14891354Seschrock 		}
14901354Seschrock 
14911354Seschrock 		if (strncmp(path, "/dev/dsk/", 9) == 0)
14921354Seschrock 			path += 9;
14931354Seschrock 
14941354Seschrock 		if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_WHOLE_DISK,
14951544Seschrock 		    &value) == 0 && value) {
14962082Seschrock 			char *tmp = zfs_strdup(hdl, path);
14972082Seschrock 			if (tmp == NULL)
14982082Seschrock 				return (NULL);
14991354Seschrock 			tmp[strlen(path) - 2] = '\0';
15001354Seschrock 			return (tmp);
15011354Seschrock 		}
15021354Seschrock 	} else {
15031354Seschrock 		verify(nvlist_lookup_string(nv, ZPOOL_CONFIG_TYPE, &path) == 0);
15042082Seschrock 
15052082Seschrock 		/*
15062082Seschrock 		 * If it's a raidz device, we need to stick in the parity level.
15072082Seschrock 		 */
15082082Seschrock 		if (strcmp(path, VDEV_TYPE_RAIDZ) == 0) {
15092082Seschrock 			verify(nvlist_lookup_uint64(nv, ZPOOL_CONFIG_NPARITY,
15102082Seschrock 			    &value) == 0);
15112082Seschrock 			(void) snprintf(buf, sizeof (buf), "%s%llu", path,
15122856Snd150628 			    (u_longlong_t)value);
15132082Seschrock 			path = buf;
15142082Seschrock 		}
15151354Seschrock 	}
15161354Seschrock 
15172082Seschrock 	return (zfs_strdup(hdl, path));
15181354Seschrock }
15191544Seschrock 
15201544Seschrock static int
15211544Seschrock zbookmark_compare(const void *a, const void *b)
15221544Seschrock {
15231544Seschrock 	return (memcmp(a, b, sizeof (zbookmark_t)));
15241544Seschrock }
15251544Seschrock 
15261544Seschrock /*
15271544Seschrock  * Retrieve the persistent error log, uniquify the members, and return to the
15281544Seschrock  * caller.
15291544Seschrock  */
15301544Seschrock int
15313444Sek110237 zpool_get_errlog(zpool_handle_t *zhp, nvlist_t **nverrlistp)
15321544Seschrock {
15331544Seschrock 	zfs_cmd_t zc = { 0 };
15341544Seschrock 	uint64_t count;
15352676Seschrock 	zbookmark_t *zb = NULL;
15363444Sek110237 	int i;
15371544Seschrock 
15381544Seschrock 	/*
15391544Seschrock 	 * Retrieve the raw error list from the kernel.  If the number of errors
15401544Seschrock 	 * has increased, allocate more space and continue until we get the
15411544Seschrock 	 * entire list.
15421544Seschrock 	 */
15431544Seschrock 	verify(nvlist_lookup_uint64(zhp->zpool_config, ZPOOL_CONFIG_ERRCOUNT,
15441544Seschrock 	    &count) == 0);
15452676Seschrock 	if ((zc.zc_nvlist_dst = (uintptr_t)zfs_alloc(zhp->zpool_hdl,
15462856Snd150628 	    count * sizeof (zbookmark_t))) == (uintptr_t)NULL)
15472082Seschrock 		return (-1);
15482676Seschrock 	zc.zc_nvlist_dst_size = count;
15491544Seschrock 	(void) strcpy(zc.zc_name, zhp->zpool_name);
15501544Seschrock 	for (;;) {
15512082Seschrock 		if (ioctl(zhp->zpool_hdl->libzfs_fd, ZFS_IOC_ERROR_LOG,
15522082Seschrock 		    &zc) != 0) {
15532676Seschrock 			free((void *)(uintptr_t)zc.zc_nvlist_dst);
15541544Seschrock 			if (errno == ENOMEM) {
1555*3823Svb160487 				count = zc.zc_nvlist_dst_size;
15562676Seschrock 				if ((zc.zc_nvlist_dst = (uintptr_t)
1557*3823Svb160487 				    zfs_alloc(zhp->zpool_hdl, count *
1558*3823Svb160487 				    sizeof (zbookmark_t))) == (uintptr_t)NULL)
15592082Seschrock 					return (-1);
15601544Seschrock 			} else {
15611544Seschrock 				return (-1);
15621544Seschrock 			}
15631544Seschrock 		} else {
15641544Seschrock 			break;
15651544Seschrock 		}
15661544Seschrock 	}
15671544Seschrock 
15681544Seschrock 	/*
15691544Seschrock 	 * Sort the resulting bookmarks.  This is a little confusing due to the
15701544Seschrock 	 * implementation of ZFS_IOC_ERROR_LOG.  The bookmarks are copied last
15712676Seschrock 	 * to first, and 'zc_nvlist_dst_size' indicates the number of boomarks
15721544Seschrock 	 * _not_ copied as part of the process.  So we point the start of our
15731544Seschrock 	 * array appropriate and decrement the total number of elements.
15741544Seschrock 	 */
15752676Seschrock 	zb = ((zbookmark_t *)(uintptr_t)zc.zc_nvlist_dst) +
15762676Seschrock 	    zc.zc_nvlist_dst_size;
15772676Seschrock 	count -= zc.zc_nvlist_dst_size;
15781544Seschrock 
15791544Seschrock 	qsort(zb, count, sizeof (zbookmark_t), zbookmark_compare);
15801544Seschrock 
15813444Sek110237 	verify(nvlist_alloc(nverrlistp, 0, KM_SLEEP) == 0);
15821544Seschrock 
15831544Seschrock 	/*
15843444Sek110237 	 * Fill in the nverrlistp with nvlist's of dataset and object numbers.
15851544Seschrock 	 */
15861544Seschrock 	for (i = 0; i < count; i++) {
15871544Seschrock 		nvlist_t *nv;
15881544Seschrock 
15893700Sek110237 		/* ignoring zb_blkid and zb_level for now */
15903700Sek110237 		if (i > 0 && zb[i-1].zb_objset == zb[i].zb_objset &&
15913700Sek110237 		    zb[i-1].zb_object == zb[i].zb_object)
15921544Seschrock 			continue;
15931544Seschrock 
15943444Sek110237 		if (nvlist_alloc(&nv, NV_UNIQUE_NAME, KM_SLEEP) != 0)
15953444Sek110237 			goto nomem;
15963444Sek110237 		if (nvlist_add_uint64(nv, ZPOOL_ERR_DATASET,
15973444Sek110237 		    zb[i].zb_objset) != 0) {
15983444Sek110237 			nvlist_free(nv);
15992082Seschrock 			goto nomem;
16003444Sek110237 		}
16013444Sek110237 		if (nvlist_add_uint64(nv, ZPOOL_ERR_OBJECT,
16023444Sek110237 		    zb[i].zb_object) != 0) {
16033444Sek110237 			nvlist_free(nv);
16043444Sek110237 			goto nomem;
16051544Seschrock 		}
16063444Sek110237 		if (nvlist_add_nvlist(*nverrlistp, "ejk", nv) != 0) {
16073444Sek110237 			nvlist_free(nv);
16083444Sek110237 			goto nomem;
16093444Sek110237 		}
16103444Sek110237 		nvlist_free(nv);
16111544Seschrock 	}
16121544Seschrock 
16133265Sahrens 	free((void *)(uintptr_t)zc.zc_nvlist_dst);
16141544Seschrock 	return (0);
16152082Seschrock 
16162082Seschrock nomem:
16172676Seschrock 	free((void *)(uintptr_t)zc.zc_nvlist_dst);
16182082Seschrock 	return (no_memory(zhp->zpool_hdl));
16191544Seschrock }
16201760Seschrock 
16211760Seschrock /*
16221760Seschrock  * Upgrade a ZFS pool to the latest on-disk version.
16231760Seschrock  */
16241760Seschrock int
16251760Seschrock zpool_upgrade(zpool_handle_t *zhp)
16261760Seschrock {
16271760Seschrock 	zfs_cmd_t zc = { 0 };
16282082Seschrock 	libzfs_handle_t *hdl = zhp->zpool_hdl;
16291760Seschrock 
16301760Seschrock 	(void) strcpy(zc.zc_name, zhp->zpool_name);
16312082Seschrock 	if (ioctl(hdl->libzfs_fd, ZFS_IOC_POOL_UPGRADE, &zc) != 0)
16323237Slling 		return (zpool_standard_error_fmt(hdl, errno,
16332082Seschrock 		    dgettext(TEXT_DOMAIN, "cannot upgrade '%s'"),
16342082Seschrock 		    zhp->zpool_name));
16351760Seschrock 
16361760Seschrock 	return (0);
16371760Seschrock }
16382926Sek110237 
16392926Sek110237 /*
16402926Sek110237  * Log command history.
16412926Sek110237  *
16422926Sek110237  * 'pool' is B_TRUE if we are logging a command for 'zpool'; B_FALSE
16432926Sek110237  * otherwise ('zfs').  'pool_create' is B_TRUE if we are logging the creation
16442926Sek110237  * of the pool; B_FALSE otherwise.  'path' is the pathanme containing the
16452926Sek110237  * poolname.  'argc' and 'argv' are used to construct the command string.
16462926Sek110237  */
16472926Sek110237 void
16482926Sek110237 zpool_log_history(libzfs_handle_t *hdl, int argc, char **argv, const char *path,
16492926Sek110237     boolean_t pool, boolean_t pool_create)
16502926Sek110237 {
16512926Sek110237 	char cmd_buf[HIS_MAX_RECORD_LEN];
16522926Sek110237 	char *dspath;
16532926Sek110237 	zfs_cmd_t zc = { 0 };
16542926Sek110237 	int i;
16552926Sek110237 
16562926Sek110237 	/* construct the command string */
16572926Sek110237 	(void) strcpy(cmd_buf, pool ? "zpool" : "zfs");
16582926Sek110237 	for (i = 0; i < argc; i++) {
16592926Sek110237 		if (strlen(cmd_buf) + 1 + strlen(argv[i]) > HIS_MAX_RECORD_LEN)
16602926Sek110237 			break;
16612926Sek110237 		(void) strcat(cmd_buf, " ");
16622926Sek110237 		(void) strcat(cmd_buf, argv[i]);
16632926Sek110237 	}
16642926Sek110237 
16652926Sek110237 	/* figure out the poolname */
16662926Sek110237 	dspath = strpbrk(path, "/@");
16672926Sek110237 	if (dspath == NULL) {
16682926Sek110237 		(void) strcpy(zc.zc_name, path);
16692926Sek110237 	} else {
16702926Sek110237 		(void) strncpy(zc.zc_name, path, dspath - path);
16712926Sek110237 		zc.zc_name[dspath-path] = '\0';
16722926Sek110237 	}
16732926Sek110237 
16742926Sek110237 	zc.zc_history = (uint64_t)(uintptr_t)cmd_buf;
16752926Sek110237 	zc.zc_history_len = strlen(cmd_buf);
16762926Sek110237 
16772926Sek110237 	/* overloading zc_history_offset */
16782926Sek110237 	zc.zc_history_offset = pool_create;
16792926Sek110237 
16802926Sek110237 	(void) ioctl(hdl->libzfs_fd, ZFS_IOC_POOL_LOG_HISTORY, &zc);
16812926Sek110237 }
16822926Sek110237 
16832926Sek110237 /*
16842926Sek110237  * Perform ioctl to get some command history of a pool.
16852926Sek110237  *
16862926Sek110237  * 'buf' is the buffer to fill up to 'len' bytes.  'off' is the
16872926Sek110237  * logical offset of the history buffer to start reading from.
16882926Sek110237  *
16892926Sek110237  * Upon return, 'off' is the next logical offset to read from and
16902926Sek110237  * 'len' is the actual amount of bytes read into 'buf'.
16912926Sek110237  */
16922926Sek110237 static int
16932926Sek110237 get_history(zpool_handle_t *zhp, char *buf, uint64_t *off, uint64_t *len)
16942926Sek110237 {
16952926Sek110237 	zfs_cmd_t zc = { 0 };
16962926Sek110237 	libzfs_handle_t *hdl = zhp->zpool_hdl;
16972926Sek110237 
16982926Sek110237 	(void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
16992926Sek110237 
17002926Sek110237 	zc.zc_history = (uint64_t)(uintptr_t)buf;
17012926Sek110237 	zc.zc_history_len = *len;
17022926Sek110237 	zc.zc_history_offset = *off;
17032926Sek110237 
17042926Sek110237 	if (ioctl(hdl->libzfs_fd, ZFS_IOC_POOL_GET_HISTORY, &zc) != 0) {
17052926Sek110237 		switch (errno) {
17062926Sek110237 		case EPERM:
17073237Slling 			return (zfs_error_fmt(hdl, EZFS_PERM,
17083237Slling 			    dgettext(TEXT_DOMAIN,
17092926Sek110237 			    "cannot show history for pool '%s'"),
17102926Sek110237 			    zhp->zpool_name));
17112926Sek110237 		case ENOENT:
17123237Slling 			return (zfs_error_fmt(hdl, EZFS_NOHISTORY,
17132926Sek110237 			    dgettext(TEXT_DOMAIN, "cannot get history for pool "
17142926Sek110237 			    "'%s'"), zhp->zpool_name));
17152926Sek110237 		default:
17163237Slling 			return (zpool_standard_error_fmt(hdl, errno,
17172926Sek110237 			    dgettext(TEXT_DOMAIN,
17182926Sek110237 			    "cannot get history for '%s'"), zhp->zpool_name));
17192926Sek110237 		}
17202926Sek110237 	}
17212926Sek110237 
17222926Sek110237 	*len = zc.zc_history_len;
17232926Sek110237 	*off = zc.zc_history_offset;
17242926Sek110237 
17252926Sek110237 	return (0);
17262926Sek110237 }
17272926Sek110237 
17282926Sek110237 /*
17292926Sek110237  * Process the buffer of nvlists, unpacking and storing each nvlist record
17302926Sek110237  * into 'records'.  'leftover' is set to the number of bytes that weren't
17312926Sek110237  * processed as there wasn't a complete record.
17322926Sek110237  */
17332926Sek110237 static int
17342926Sek110237 zpool_history_unpack(char *buf, uint64_t bytes_read, uint64_t *leftover,
17352926Sek110237     nvlist_t ***records, uint_t *numrecords)
17362926Sek110237 {
17372926Sek110237 	uint64_t reclen;
17382926Sek110237 	nvlist_t *nv;
17392926Sek110237 	int i;
17402926Sek110237 
17412926Sek110237 	while (bytes_read > sizeof (reclen)) {
17422926Sek110237 
17432926Sek110237 		/* get length of packed record (stored as little endian) */
17442926Sek110237 		for (i = 0, reclen = 0; i < sizeof (reclen); i++)
17452926Sek110237 			reclen += (uint64_t)(((uchar_t *)buf)[i]) << (8*i);
17462926Sek110237 
17472926Sek110237 		if (bytes_read < sizeof (reclen) + reclen)
17482926Sek110237 			break;
17492926Sek110237 
17502926Sek110237 		/* unpack record */
17512926Sek110237 		if (nvlist_unpack(buf + sizeof (reclen), reclen, &nv, 0) != 0)
17522926Sek110237 			return (ENOMEM);
17532926Sek110237 		bytes_read -= sizeof (reclen) + reclen;
17542926Sek110237 		buf += sizeof (reclen) + reclen;
17552926Sek110237 
17562926Sek110237 		/* add record to nvlist array */
17572926Sek110237 		(*numrecords)++;
17582926Sek110237 		if (ISP2(*numrecords + 1)) {
17592926Sek110237 			*records = realloc(*records,
17602926Sek110237 			    *numrecords * 2 * sizeof (nvlist_t *));
17612926Sek110237 		}
17622926Sek110237 		(*records)[*numrecords - 1] = nv;
17632926Sek110237 	}
17642926Sek110237 
17652926Sek110237 	*leftover = bytes_read;
17662926Sek110237 	return (0);
17672926Sek110237 }
17682926Sek110237 
17692926Sek110237 #define	HIS_BUF_LEN	(128*1024)
17702926Sek110237 
17712926Sek110237 /*
17722926Sek110237  * Retrieve the command history of a pool.
17732926Sek110237  */
17742926Sek110237 int
17752926Sek110237 zpool_get_history(zpool_handle_t *zhp, nvlist_t **nvhisp)
17762926Sek110237 {
17772926Sek110237 	char buf[HIS_BUF_LEN];
17782926Sek110237 	uint64_t off = 0;
17792926Sek110237 	nvlist_t **records = NULL;
17802926Sek110237 	uint_t numrecords = 0;
17812926Sek110237 	int err, i;
17822926Sek110237 
17832926Sek110237 	do {
17842926Sek110237 		uint64_t bytes_read = sizeof (buf);
17852926Sek110237 		uint64_t leftover;
17862926Sek110237 
17872926Sek110237 		if ((err = get_history(zhp, buf, &off, &bytes_read)) != 0)
17882926Sek110237 			break;
17892926Sek110237 
17902926Sek110237 		/* if nothing else was read in, we're at EOF, just return */
17912926Sek110237 		if (!bytes_read)
17922926Sek110237 			break;
17932926Sek110237 
17942926Sek110237 		if ((err = zpool_history_unpack(buf, bytes_read,
17952926Sek110237 		    &leftover, &records, &numrecords)) != 0)
17962926Sek110237 			break;
17972926Sek110237 		off -= leftover;
17982926Sek110237 
17992926Sek110237 		/* CONSTCOND */
18002926Sek110237 	} while (1);
18012926Sek110237 
18022926Sek110237 	if (!err) {
18032926Sek110237 		verify(nvlist_alloc(nvhisp, NV_UNIQUE_NAME, 0) == 0);
18042926Sek110237 		verify(nvlist_add_nvlist_array(*nvhisp, ZPOOL_HIST_RECORD,
18052926Sek110237 		    records, numrecords) == 0);
18062926Sek110237 	}
18072926Sek110237 	for (i = 0; i < numrecords; i++)
18082926Sek110237 		nvlist_free(records[i]);
18092926Sek110237 	free(records);
18102926Sek110237 
18112926Sek110237 	return (err);
18122926Sek110237 }
18133444Sek110237 
18143444Sek110237 void
18153444Sek110237 zpool_obj_to_path(zpool_handle_t *zhp, uint64_t dsobj, uint64_t obj,
18163444Sek110237     char *pathname, size_t len)
18173444Sek110237 {
18183444Sek110237 	zfs_cmd_t zc = { 0 };
18193444Sek110237 	boolean_t mounted = B_FALSE;
18203444Sek110237 	char *mntpnt = NULL;
18213444Sek110237 	char dsname[MAXNAMELEN];
18223444Sek110237 
18233444Sek110237 	if (dsobj == 0) {
18243444Sek110237 		/* special case for the MOS */
18253444Sek110237 		(void) snprintf(pathname, len, "<metadata>:<0x%llx>", obj);
18263444Sek110237 		return;
18273444Sek110237 	}
18283444Sek110237 
18293444Sek110237 	/* get the dataset's name */
18303444Sek110237 	(void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
18313444Sek110237 	zc.zc_obj = dsobj;
18323444Sek110237 	if (ioctl(zhp->zpool_hdl->libzfs_fd,
18333444Sek110237 	    ZFS_IOC_DSOBJ_TO_DSNAME, &zc) != 0) {
18343444Sek110237 		/* just write out a path of two object numbers */
18353444Sek110237 		(void) snprintf(pathname, len, "<0x%llx>:<0x%llx>",
18363444Sek110237 		    dsobj, obj);
18373444Sek110237 		return;
18383444Sek110237 	}
18393444Sek110237 	(void) strlcpy(dsname, zc.zc_value, sizeof (dsname));
18403444Sek110237 
18413444Sek110237 	/* find out if the dataset is mounted */
18423444Sek110237 	mounted = is_mounted(zhp->zpool_hdl, dsname, &mntpnt);
18433444Sek110237 
18443444Sek110237 	/* get the corrupted object's path */
18453444Sek110237 	(void) strlcpy(zc.zc_name, dsname, sizeof (zc.zc_name));
18463444Sek110237 	zc.zc_obj = obj;
18473444Sek110237 	if (ioctl(zhp->zpool_hdl->libzfs_fd, ZFS_IOC_OBJ_TO_PATH,
18483444Sek110237 	    &zc) == 0) {
18493444Sek110237 		if (mounted) {
18503444Sek110237 			(void) snprintf(pathname, len, "%s%s", mntpnt,
18513444Sek110237 			    zc.zc_value);
18523444Sek110237 		} else {
18533444Sek110237 			(void) snprintf(pathname, len, "%s:%s",
18543444Sek110237 			    dsname, zc.zc_value);
18553444Sek110237 		}
18563444Sek110237 	} else {
18573444Sek110237 		(void) snprintf(pathname, len, "%s:<0x%llx>", dsname, obj);
18583444Sek110237 	}
18593444Sek110237 	free(mntpnt);
18603444Sek110237 }
1861