1*789Sahrens /*
2*789Sahrens  * CDDL HEADER START
3*789Sahrens  *
4*789Sahrens  * The contents of this file are subject to the terms of the
5*789Sahrens  * Common Development and Distribution License, Version 1.0 only
6*789Sahrens  * (the "License").  You may not use this file except in compliance
7*789Sahrens  * with the License.
8*789Sahrens  *
9*789Sahrens  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*789Sahrens  * or http://www.opensolaris.org/os/licensing.
11*789Sahrens  * See the License for the specific language governing permissions
12*789Sahrens  * and limitations under the License.
13*789Sahrens  *
14*789Sahrens  * When distributing Covered Code, include this CDDL HEADER in each
15*789Sahrens  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*789Sahrens  * If applicable, add the following below this CDDL HEADER, with the
17*789Sahrens  * fields enclosed by brackets "[]" replaced with your own identifying
18*789Sahrens  * information: Portions Copyright [yyyy] [name of copyright owner]
19*789Sahrens  *
20*789Sahrens  * CDDL HEADER END
21*789Sahrens  */
22*789Sahrens /*
23*789Sahrens  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
24*789Sahrens  * Use is subject to license terms.
25*789Sahrens  */
26*789Sahrens 
27*789Sahrens #pragma ident	"%Z%%M%	%I%	%E% SMI"
28*789Sahrens 
29*789Sahrens #include <assert.h>
30*789Sahrens #include <ctype.h>
31*789Sahrens #include <errno.h>
32*789Sahrens #include <devid.h>
33*789Sahrens #include <fcntl.h>
34*789Sahrens #include <libintl.h>
35*789Sahrens #include <stdio.h>
36*789Sahrens #include <stdlib.h>
37*789Sahrens #include <string.h>
38*789Sahrens #include <unistd.h>
39*789Sahrens #include <sys/zfs_ioctl.h>
40*789Sahrens 
41*789Sahrens #include "zfs_namecheck.h"
42*789Sahrens #include "libzfs_impl.h"
43*789Sahrens 
44*789Sahrens /*
45*789Sahrens  * Validate the given pool name, optionally putting an extended error message in
46*789Sahrens  * 'buf'.
47*789Sahrens  */
48*789Sahrens static int
49*789Sahrens zpool_name_valid(const char *pool, char *buf, size_t buflen)
50*789Sahrens {
51*789Sahrens 	namecheck_err_t why;
52*789Sahrens 	char what;
53*789Sahrens 
54*789Sahrens 	if (strlen(pool) >= ZPOOL_MAXNAMELEN) {
55*789Sahrens 		if (buf)
56*789Sahrens 			(void) snprintf(buf, buflen,
57*789Sahrens 			    dgettext(TEXT_DOMAIN, "name is too long"));
58*789Sahrens 		return (FALSE);
59*789Sahrens 	}
60*789Sahrens 
61*789Sahrens 	if (pool_namecheck(pool, &why, &what) != 0) {
62*789Sahrens 		if (buf != NULL) {
63*789Sahrens 			switch (why) {
64*789Sahrens 			case NAME_ERR_INVALCHAR:
65*789Sahrens 				(void) snprintf(buf, buflen,
66*789Sahrens 				    dgettext(TEXT_DOMAIN, "invalid character "
67*789Sahrens 				    "'%c' in pool name"), what);
68*789Sahrens 				break;
69*789Sahrens 
70*789Sahrens 			case NAME_ERR_NOLETTER:
71*789Sahrens 				(void) strlcpy(buf, dgettext(TEXT_DOMAIN,
72*789Sahrens 				    "name must begin with a letter"), buflen);
73*789Sahrens 				break;
74*789Sahrens 
75*789Sahrens 			case NAME_ERR_RESERVED:
76*789Sahrens 				(void) strlcpy(buf, dgettext(TEXT_DOMAIN,
77*789Sahrens 				    "name is reserved\n"
78*789Sahrens 				    "pool name may have been omitted"), buflen);
79*789Sahrens 				break;
80*789Sahrens 
81*789Sahrens 			case NAME_ERR_DISKLIKE:
82*789Sahrens 				(void) strlcpy(buf, dgettext(TEXT_DOMAIN,
83*789Sahrens 				    "pool name is reserved\n"
84*789Sahrens 				    "pool name may have been omitted"), buflen);
85*789Sahrens 				break;
86*789Sahrens 			}
87*789Sahrens 		}
88*789Sahrens 		return (FALSE);
89*789Sahrens 	}
90*789Sahrens 
91*789Sahrens 	return (TRUE);
92*789Sahrens }
93*789Sahrens 
94*789Sahrens /*
95*789Sahrens  * Set the pool-wide health based on the vdev state of the root vdev.
96*789Sahrens  */
97*789Sahrens void
98*789Sahrens set_pool_health(nvlist_t *config)
99*789Sahrens {
100*789Sahrens 	nvlist_t *nvroot;
101*789Sahrens 	vdev_stat_t *vs;
102*789Sahrens 	uint_t vsc;
103*789Sahrens 	char *health;
104*789Sahrens 
105*789Sahrens 	verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
106*789Sahrens 	    &nvroot) == 0);
107*789Sahrens 	verify(nvlist_lookup_uint64_array(nvroot, ZPOOL_CONFIG_STATS,
108*789Sahrens 	    (uint64_t **)&vs, &vsc) == 0);
109*789Sahrens 
110*789Sahrens 	switch (vs->vs_state) {
111*789Sahrens 
112*789Sahrens 	case VDEV_STATE_CLOSED:
113*789Sahrens 	case VDEV_STATE_CANT_OPEN:
114*789Sahrens 	case VDEV_STATE_OFFLINE:
115*789Sahrens 		health = dgettext(TEXT_DOMAIN, "FAULTED");
116*789Sahrens 		break;
117*789Sahrens 
118*789Sahrens 	case VDEV_STATE_DEGRADED:
119*789Sahrens 		health = dgettext(TEXT_DOMAIN, "DEGRADED");
120*789Sahrens 		break;
121*789Sahrens 
122*789Sahrens 	case VDEV_STATE_HEALTHY:
123*789Sahrens 		health = dgettext(TEXT_DOMAIN, "ONLINE");
124*789Sahrens 		break;
125*789Sahrens 
126*789Sahrens 	default:
127*789Sahrens 		zfs_baderror(vs->vs_state);
128*789Sahrens 	}
129*789Sahrens 
130*789Sahrens 	verify(nvlist_add_string(config, ZPOOL_CONFIG_POOL_HEALTH,
131*789Sahrens 	    health) == 0);
132*789Sahrens }
133*789Sahrens 
134*789Sahrens /*
135*789Sahrens  * Open a handle to the given pool, even if the pool is currently in the FAULTED
136*789Sahrens  * state.
137*789Sahrens  */
138*789Sahrens zpool_handle_t *
139*789Sahrens zpool_open_canfail(const char *pool)
140*789Sahrens {
141*789Sahrens 	zpool_handle_t *zhp;
142*789Sahrens 	nvlist_t *newconfig;
143*789Sahrens 	int error;
144*789Sahrens 
145*789Sahrens 	/*
146*789Sahrens 	 * Make sure the pool name is valid.
147*789Sahrens 	 */
148*789Sahrens 	if (!zpool_name_valid(pool, NULL, 0)) {
149*789Sahrens 		zfs_error(dgettext(TEXT_DOMAIN, "cannot open '%s': invalid "
150*789Sahrens 		    "pool name"), pool);
151*789Sahrens 		return (NULL);
152*789Sahrens 	}
153*789Sahrens 
154*789Sahrens 	zhp = zfs_malloc(sizeof (zpool_handle_t));
155*789Sahrens 
156*789Sahrens 	(void) strlcpy(zhp->zpool_name, pool, sizeof (zhp->zpool_name));
157*789Sahrens 
158*789Sahrens 	if ((error = zpool_refresh_stats(zhp, NULL, &newconfig)) != 0) {
159*789Sahrens 		if (error == ENOENT || error == EINVAL) {
160*789Sahrens 			zfs_error(dgettext(TEXT_DOMAIN, "cannot open '%s': no "
161*789Sahrens 			    "such pool"), pool);
162*789Sahrens 			free(zhp);
163*789Sahrens 			return (NULL);
164*789Sahrens 		} else {
165*789Sahrens 			zhp->zpool_state = POOL_STATE_UNAVAIL;
166*789Sahrens 		}
167*789Sahrens 	} else {
168*789Sahrens 		zhp->zpool_state = POOL_STATE_ACTIVE;
169*789Sahrens 	}
170*789Sahrens 
171*789Sahrens 	return (zhp);
172*789Sahrens }
173*789Sahrens 
174*789Sahrens /*
175*789Sahrens  * Like the above, but silent on error.  Used when iterating over pools (because
176*789Sahrens  * the configuration cache may be out of date).
177*789Sahrens  */
178*789Sahrens zpool_handle_t *
179*789Sahrens zpool_open_silent(const char *pool)
180*789Sahrens {
181*789Sahrens 	zpool_handle_t *zhp;
182*789Sahrens 	nvlist_t *newconfig;
183*789Sahrens 	int error;
184*789Sahrens 
185*789Sahrens 	zhp = zfs_malloc(sizeof (zpool_handle_t));
186*789Sahrens 
187*789Sahrens 	(void) strlcpy(zhp->zpool_name, pool, sizeof (zhp->zpool_name));
188*789Sahrens 
189*789Sahrens 	if ((error = zpool_refresh_stats(zhp, NULL, &newconfig)) != 0) {
190*789Sahrens 		if (error == ENOENT || error == EINVAL) {
191*789Sahrens 			free(zhp);
192*789Sahrens 			return (NULL);
193*789Sahrens 		} else {
194*789Sahrens 			zhp->zpool_state = POOL_STATE_UNAVAIL;
195*789Sahrens 		}
196*789Sahrens 	} else {
197*789Sahrens 		zhp->zpool_state = POOL_STATE_ACTIVE;
198*789Sahrens 	}
199*789Sahrens 
200*789Sahrens 	return (zhp);
201*789Sahrens }
202*789Sahrens 
203*789Sahrens /*
204*789Sahrens  * Similar to zpool_open_canfail(), but refuses to open pools in the faulted
205*789Sahrens  * state.
206*789Sahrens  */
207*789Sahrens zpool_handle_t *
208*789Sahrens zpool_open(const char *pool)
209*789Sahrens {
210*789Sahrens 	zpool_handle_t *zhp;
211*789Sahrens 
212*789Sahrens 	if ((zhp = zpool_open_canfail(pool)) == NULL)
213*789Sahrens 		return (NULL);
214*789Sahrens 
215*789Sahrens 	if (zhp->zpool_state == POOL_STATE_UNAVAIL) {
216*789Sahrens 		zfs_error(dgettext(TEXT_DOMAIN, "cannot open ' %s': pool is "
217*789Sahrens 		    "currently unavailable\n"), zhp->zpool_name);
218*789Sahrens 		zfs_error(dgettext(TEXT_DOMAIN, "run 'zpool status -v %s' for "
219*789Sahrens 		    "detailed information\n"), zhp->zpool_name);
220*789Sahrens 		zpool_close(zhp);
221*789Sahrens 		return (NULL);
222*789Sahrens 	}
223*789Sahrens 
224*789Sahrens 	return (zhp);
225*789Sahrens }
226*789Sahrens 
227*789Sahrens /*
228*789Sahrens  * Close the handle.  Simply frees the memory associated with the handle.
229*789Sahrens  */
230*789Sahrens void
231*789Sahrens zpool_close(zpool_handle_t *zhp)
232*789Sahrens {
233*789Sahrens 	if (zhp->zpool_config)
234*789Sahrens 		nvlist_free(zhp->zpool_config);
235*789Sahrens 	free(zhp);
236*789Sahrens }
237*789Sahrens 
238*789Sahrens /*
239*789Sahrens  * Return the name of the pool.
240*789Sahrens  */
241*789Sahrens const char *
242*789Sahrens zpool_get_name(zpool_handle_t *zhp)
243*789Sahrens {
244*789Sahrens 	return (zhp->zpool_name);
245*789Sahrens }
246*789Sahrens 
247*789Sahrens /*
248*789Sahrens  * Return the GUID of the pool.
249*789Sahrens  */
250*789Sahrens uint64_t
251*789Sahrens zpool_get_guid(zpool_handle_t *zhp)
252*789Sahrens {
253*789Sahrens 	uint64_t guid;
254*789Sahrens 
255*789Sahrens 	verify(nvlist_lookup_uint64(zhp->zpool_config, ZPOOL_CONFIG_POOL_GUID,
256*789Sahrens 	    &guid) == 0);
257*789Sahrens 	return (guid);
258*789Sahrens }
259*789Sahrens 
260*789Sahrens /*
261*789Sahrens  * Return the amount of space currently consumed by the pool.
262*789Sahrens  */
263*789Sahrens uint64_t
264*789Sahrens zpool_get_space_used(zpool_handle_t *zhp)
265*789Sahrens {
266*789Sahrens 	nvlist_t *nvroot;
267*789Sahrens 	vdev_stat_t *vs;
268*789Sahrens 	uint_t vsc;
269*789Sahrens 
270*789Sahrens 	verify(nvlist_lookup_nvlist(zhp->zpool_config, ZPOOL_CONFIG_VDEV_TREE,
271*789Sahrens 	    &nvroot) == 0);
272*789Sahrens 	verify(nvlist_lookup_uint64_array(nvroot, ZPOOL_CONFIG_STATS,
273*789Sahrens 	    (uint64_t **)&vs, &vsc) == 0);
274*789Sahrens 
275*789Sahrens 	return (vs->vs_alloc);
276*789Sahrens }
277*789Sahrens 
278*789Sahrens /*
279*789Sahrens  * Return the total space in the pool.
280*789Sahrens  */
281*789Sahrens uint64_t
282*789Sahrens zpool_get_space_total(zpool_handle_t *zhp)
283*789Sahrens {
284*789Sahrens 	nvlist_t *nvroot;
285*789Sahrens 	vdev_stat_t *vs;
286*789Sahrens 	uint_t vsc;
287*789Sahrens 
288*789Sahrens 	verify(nvlist_lookup_nvlist(zhp->zpool_config, ZPOOL_CONFIG_VDEV_TREE,
289*789Sahrens 	    &nvroot) == 0);
290*789Sahrens 	verify(nvlist_lookup_uint64_array(nvroot, ZPOOL_CONFIG_STATS,
291*789Sahrens 	    (uint64_t **)&vs, &vsc) == 0);
292*789Sahrens 
293*789Sahrens 	return (vs->vs_space);
294*789Sahrens }
295*789Sahrens 
296*789Sahrens /*
297*789Sahrens  * Return the alternate root for this pool, if any.
298*789Sahrens  */
299*789Sahrens int
300*789Sahrens zpool_get_root(zpool_handle_t *zhp, char *buf, size_t buflen)
301*789Sahrens {
302*789Sahrens 	zfs_cmd_t zc = { 0 };
303*789Sahrens 
304*789Sahrens 	(void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
305*789Sahrens 	if (ioctl(zfs_fd, ZFS_IOC_OBJSET_STATS, &zc) != 0 ||
306*789Sahrens 	    zc.zc_objset_stats.dds_altroot[0] == '\0')
307*789Sahrens 		return (-1);
308*789Sahrens 
309*789Sahrens 	(void) strlcpy(buf, zc.zc_objset_stats.dds_altroot, buflen);
310*789Sahrens 
311*789Sahrens 	return (0);
312*789Sahrens }
313*789Sahrens 
314*789Sahrens /*
315*789Sahrens  * Return the state of the pool (ACTIVE or UNAVAILABLE)
316*789Sahrens  */
317*789Sahrens int
318*789Sahrens zpool_get_state(zpool_handle_t *zhp)
319*789Sahrens {
320*789Sahrens 	return (zhp->zpool_state);
321*789Sahrens }
322*789Sahrens 
323*789Sahrens /*
324*789Sahrens  * Create the named pool, using the provided vdev list.  It is assumed
325*789Sahrens  * that the consumer has already validated the contents of the nvlist, so we
326*789Sahrens  * don't have to worry about error semantics.
327*789Sahrens  */
328*789Sahrens int
329*789Sahrens zpool_create(const char *pool, nvlist_t *nvroot, const char *altroot)
330*789Sahrens {
331*789Sahrens 	zfs_cmd_t zc = { 0 };
332*789Sahrens 	char *packed;
333*789Sahrens 	size_t len;
334*789Sahrens 	int err;
335*789Sahrens 	char reason[64];
336*789Sahrens 
337*789Sahrens 	if (!zpool_name_valid(pool, reason, sizeof (reason))) {
338*789Sahrens 		zfs_error(dgettext(TEXT_DOMAIN, "cannot create '%s': %s"),
339*789Sahrens 		    pool, reason);
340*789Sahrens 		return (-1);
341*789Sahrens 	}
342*789Sahrens 
343*789Sahrens 	if (altroot != NULL && altroot[0] != '/') {
344*789Sahrens 		zfs_error(dgettext(TEXT_DOMAIN, "cannot create '%s': alternate "
345*789Sahrens 		    "root '%s' must be a complete path"), pool, altroot);
346*789Sahrens 		return (-1);
347*789Sahrens 	}
348*789Sahrens 
349*789Sahrens 	if ((err = nvlist_size(nvroot, &len, NV_ENCODE_NATIVE)) != 0)
350*789Sahrens 		zfs_baderror(err);
351*789Sahrens 
352*789Sahrens 	packed = zfs_malloc(len);
353*789Sahrens 
354*789Sahrens 	if ((err = nvlist_pack(nvroot, &packed, &len,
355*789Sahrens 	    NV_ENCODE_NATIVE, 0)) != 0)
356*789Sahrens 		zfs_baderror(err);
357*789Sahrens 
358*789Sahrens 	(void) strlcpy(zc.zc_name, pool, sizeof (zc.zc_name));
359*789Sahrens 	zc.zc_config_src = (uint64_t)(uintptr_t)packed;
360*789Sahrens 	zc.zc_config_src_size = len;
361*789Sahrens 
362*789Sahrens 	if (altroot != NULL)
363*789Sahrens 		(void) strlcpy(zc.zc_root, altroot, sizeof (zc.zc_root));
364*789Sahrens 
365*789Sahrens 	if (ioctl(zfs_fd, ZFS_IOC_POOL_CREATE, &zc) != 0) {
366*789Sahrens 		switch (errno) {
367*789Sahrens 		case EEXIST:
368*789Sahrens 			zfs_error(dgettext(TEXT_DOMAIN, "cannot create '%s': "
369*789Sahrens 			    "pool exists"), pool);
370*789Sahrens 			break;
371*789Sahrens 
372*789Sahrens 		case EPERM:
373*789Sahrens 			zfs_error(dgettext(TEXT_DOMAIN, "cannot create '%s': "
374*789Sahrens 			    "permission denied"), pool);
375*789Sahrens 			break;
376*789Sahrens 
377*789Sahrens 		case EBUSY:
378*789Sahrens 			/*
379*789Sahrens 			 * This can happen if the user has specified the same
380*789Sahrens 			 * device multiple times.  We can't reliably detect this
381*789Sahrens 			 * until we try to add it and see we already have a
382*789Sahrens 			 * label.
383*789Sahrens 			 */
384*789Sahrens 			zfs_error(dgettext(TEXT_DOMAIN, "cannot create '%s': "
385*789Sahrens 			    "one or more vdevs refer to the same device"),
386*789Sahrens 			    pool);
387*789Sahrens 			break;
388*789Sahrens 
389*789Sahrens 		case EOVERFLOW:
390*789Sahrens 			/*
391*789Sahrens 			 * This occurrs when one of the devices is below
392*789Sahrens 			 * SPA_MINDEVSIZE.  Unfortunately, we can't detect which
393*789Sahrens 			 * device was the problem device since there's no
394*789Sahrens 			 * reliable way to determine device size from userland.
395*789Sahrens 			 */
396*789Sahrens 			{
397*789Sahrens 				char buf[64];
398*789Sahrens 
399*789Sahrens 				zfs_nicenum(SPA_MINDEVSIZE, buf, sizeof (buf));
400*789Sahrens 
401*789Sahrens 				zfs_error(dgettext(TEXT_DOMAIN, "cannot "
402*789Sahrens 				    "create '%s': one or more devices is less "
403*789Sahrens 				    "than the minimum size (%s)"), pool,
404*789Sahrens 				    buf);
405*789Sahrens 			}
406*789Sahrens 			break;
407*789Sahrens 
408*789Sahrens 		case ENAMETOOLONG:
409*789Sahrens 			/*
410*789Sahrens 			 * One of the vdevs has exceeded VDEV_SPEC_MAX length in
411*789Sahrens 			 * its plaintext representation.
412*789Sahrens 			 */
413*789Sahrens 			zfs_error(dgettext(TEXT_DOMAIN, "cannot create '%s': "
414*789Sahrens 			    "too many devices in a single vdev"), pool);
415*789Sahrens 			break;
416*789Sahrens 
417*789Sahrens 		case EIO:
418*789Sahrens 			zfs_error(dgettext(TEXT_DOMAIN, "cannot create '%s': "
419*789Sahrens 			    "I/O error on one or more devices"), pool);
420*789Sahrens 			break;
421*789Sahrens 
422*789Sahrens 		case ENXIO:
423*789Sahrens 			/*
424*789Sahrens 			 * This is unlikely to happen since we've verified that
425*789Sahrens 			 * all the devices can be opened from userland, but it's
426*789Sahrens 			 * still possible in some circumstances.
427*789Sahrens 			 */
428*789Sahrens 			zfs_error(dgettext(TEXT_DOMAIN, "cannot create '%s': "
429*789Sahrens 			    "one or more devices is unavailable"), pool);
430*789Sahrens 			break;
431*789Sahrens 
432*789Sahrens 		case ENOSPC:
433*789Sahrens 			/*
434*789Sahrens 			 * This can occur if we were incapable of writing to a
435*789Sahrens 			 * file vdev because the underlying filesystem is out of
436*789Sahrens 			 * space.  This is very similar to EOVERFLOW, but we'll
437*789Sahrens 			 * produce a slightly different message.
438*789Sahrens 			 */
439*789Sahrens 			zfs_error(dgettext(TEXT_DOMAIN, "cannot create '%s': "
440*789Sahrens 			    "one or more devices is out of space"), pool);
441*789Sahrens 			break;
442*789Sahrens 
443*789Sahrens 		default:
444*789Sahrens 			zfs_baderror(errno);
445*789Sahrens 		}
446*789Sahrens 
447*789Sahrens 		return (-1);
448*789Sahrens 	}
449*789Sahrens 
450*789Sahrens 	free(packed);
451*789Sahrens 
452*789Sahrens 	/*
453*789Sahrens 	 * If this is an alternate root pool, then we automatically set the
454*789Sahrens 	 * moutnpoint of the root dataset to be '/'.
455*789Sahrens 	 */
456*789Sahrens 	if (altroot != NULL) {
457*789Sahrens 		zfs_handle_t *zhp;
458*789Sahrens 
459*789Sahrens 		verify((zhp = zfs_open(pool, ZFS_TYPE_ANY)) != NULL);
460*789Sahrens 		verify(zfs_prop_set(zhp, ZFS_PROP_MOUNTPOINT, "/") == 0);
461*789Sahrens 
462*789Sahrens 		zfs_close(zhp);
463*789Sahrens 	}
464*789Sahrens 
465*789Sahrens 	return (0);
466*789Sahrens }
467*789Sahrens 
468*789Sahrens /*
469*789Sahrens  * Destroy the given pool.  It is up to the caller to ensure that there are no
470*789Sahrens  * datasets left in the pool.
471*789Sahrens  */
472*789Sahrens int
473*789Sahrens zpool_destroy(zpool_handle_t *zhp)
474*789Sahrens {
475*789Sahrens 	zfs_cmd_t zc = { 0 };
476*789Sahrens 	zfs_handle_t *zfp = NULL;
477*789Sahrens 
478*789Sahrens 	if (zhp->zpool_state == POOL_STATE_ACTIVE &&
479*789Sahrens 	    (zfp = zfs_open(zhp->zpool_name, ZFS_TYPE_FILESYSTEM)) == NULL)
480*789Sahrens 		return (-1);
481*789Sahrens 
482*789Sahrens 	if (zpool_remove_zvol_links(zhp) != NULL)
483*789Sahrens 		return (-1);
484*789Sahrens 
485*789Sahrens 	(void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
486*789Sahrens 
487*789Sahrens 	if (ioctl(zfs_fd, ZFS_IOC_POOL_DESTROY, &zc) != 0) {
488*789Sahrens 		switch (errno) {
489*789Sahrens 		case EPERM:
490*789Sahrens 			zfs_error(dgettext(TEXT_DOMAIN,
491*789Sahrens 			    "cannot destroy '%s': permission denied"),
492*789Sahrens 			    zhp->zpool_name);
493*789Sahrens 			break;
494*789Sahrens 
495*789Sahrens 		case EBUSY:
496*789Sahrens 			zfs_error(dgettext(TEXT_DOMAIN,
497*789Sahrens 			    "cannot destroy '%s': pool busy"),
498*789Sahrens 			    zhp->zpool_name);
499*789Sahrens 			break;
500*789Sahrens 
501*789Sahrens 		case ENOENT:
502*789Sahrens 			zfs_error(dgettext(TEXT_DOMAIN,
503*789Sahrens 			    "cannot destroy '%s': no such pool"),
504*789Sahrens 			    zhp->zpool_name);
505*789Sahrens 			break;
506*789Sahrens 
507*789Sahrens 		case EROFS:
508*789Sahrens 			zfs_error(dgettext(TEXT_DOMAIN,
509*789Sahrens 			    "cannot destroy '%s': one or more devices is "
510*789Sahrens 			    "read only, or '/' is mounted read only"),
511*789Sahrens 			    zhp->zpool_name);
512*789Sahrens 			break;
513*789Sahrens 
514*789Sahrens 		default:
515*789Sahrens 			zfs_baderror(errno);
516*789Sahrens 		}
517*789Sahrens 
518*789Sahrens 		if (zfp)
519*789Sahrens 			zfs_close(zfp);
520*789Sahrens 		return (-1);
521*789Sahrens 	}
522*789Sahrens 
523*789Sahrens 	if (zfp) {
524*789Sahrens 		remove_mountpoint(zfp);
525*789Sahrens 		zfs_close(zfp);
526*789Sahrens 	}
527*789Sahrens 
528*789Sahrens 	return (0);
529*789Sahrens }
530*789Sahrens 
531*789Sahrens /*
532*789Sahrens  * Add the given vdevs to the pool.  The caller must have already performed the
533*789Sahrens  * necessary verification to ensure that the vdev specification is well-formed.
534*789Sahrens  */
535*789Sahrens int
536*789Sahrens zpool_add(zpool_handle_t *zhp, nvlist_t *nvroot)
537*789Sahrens {
538*789Sahrens 	char *packed;
539*789Sahrens 	size_t len;
540*789Sahrens 	zfs_cmd_t zc;
541*789Sahrens 
542*789Sahrens 	verify(nvlist_size(nvroot, &len, NV_ENCODE_NATIVE) == 0);
543*789Sahrens 
544*789Sahrens 	packed = zfs_malloc(len);
545*789Sahrens 
546*789Sahrens 	verify(nvlist_pack(nvroot, &packed, &len, NV_ENCODE_NATIVE, 0) == 0);
547*789Sahrens 
548*789Sahrens 	(void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
549*789Sahrens 	zc.zc_config_src = (uint64_t)(uintptr_t)packed;
550*789Sahrens 	zc.zc_config_src_size = len;
551*789Sahrens 
552*789Sahrens 	if (ioctl(zfs_fd, ZFS_IOC_VDEV_ADD, &zc) != 0) {
553*789Sahrens 		switch (errno) {
554*789Sahrens 		case EPERM:
555*789Sahrens 			zfs_error(dgettext(TEXT_DOMAIN, "cannot add to '%s': "
556*789Sahrens 			    "permission denied"), zhp->zpool_name);
557*789Sahrens 			break;
558*789Sahrens 
559*789Sahrens 		case EBUSY:
560*789Sahrens 			/*
561*789Sahrens 			 * This can happen if the user has specified the same
562*789Sahrens 			 * device multiple times.  We can't reliably detect this
563*789Sahrens 			 * until we try to add it and see we already have a
564*789Sahrens 			 * label.
565*789Sahrens 			 */
566*789Sahrens 			zfs_error(dgettext(TEXT_DOMAIN, "cannot add to '%s': "
567*789Sahrens 			    "one or more vdevs refer to the same device"),
568*789Sahrens 			    zhp->zpool_name);
569*789Sahrens 			break;
570*789Sahrens 
571*789Sahrens 		case ENAMETOOLONG:
572*789Sahrens 			/*
573*789Sahrens 			 * One of the vdevs has exceeded VDEV_SPEC_MAX length in
574*789Sahrens 			 * its plaintext representation.
575*789Sahrens 			 */
576*789Sahrens 			zfs_error(dgettext(TEXT_DOMAIN, "cannot add to '%s': "
577*789Sahrens 			    "too many devices in a single vdev"),
578*789Sahrens 			    zhp->zpool_name);
579*789Sahrens 			break;
580*789Sahrens 
581*789Sahrens 		case ENXIO:
582*789Sahrens 			/*
583*789Sahrens 			 * This is unlikely to happen since we've verified that
584*789Sahrens 			 * all the devices can be opened from userland, but it's
585*789Sahrens 			 * still possible in some circumstances.
586*789Sahrens 			 */
587*789Sahrens 			zfs_error(dgettext(TEXT_DOMAIN, "cannot add to '%s': "
588*789Sahrens 			    "one or more devices is unavailable"),
589*789Sahrens 			    zhp->zpool_name);
590*789Sahrens 			break;
591*789Sahrens 
592*789Sahrens 		case EOVERFLOW:
593*789Sahrens 			/*
594*789Sahrens 			 * This occurrs when one of the devices is below
595*789Sahrens 			 * SPA_MINDEVSIZE.  Unfortunately, we can't detect which
596*789Sahrens 			 * device was the problem device since there's no
597*789Sahrens 			 * reliable way to determine device size from userland.
598*789Sahrens 			 */
599*789Sahrens 			{
600*789Sahrens 				char buf[64];
601*789Sahrens 
602*789Sahrens 				zfs_nicenum(SPA_MINDEVSIZE, buf, sizeof (buf));
603*789Sahrens 
604*789Sahrens 				zfs_error(dgettext(TEXT_DOMAIN, "cannot "
605*789Sahrens 				    "add to '%s': one or more devices is less "
606*789Sahrens 				    "than the minimum size (%s)"),
607*789Sahrens 				    zhp->zpool_name, buf);
608*789Sahrens 			}
609*789Sahrens 			break;
610*789Sahrens 
611*789Sahrens 		default:
612*789Sahrens 			zfs_baderror(errno);
613*789Sahrens 		}
614*789Sahrens 
615*789Sahrens 		return (-1);
616*789Sahrens 	}
617*789Sahrens 
618*789Sahrens 	free(packed);
619*789Sahrens 
620*789Sahrens 	return (0);
621*789Sahrens }
622*789Sahrens 
623*789Sahrens /*
624*789Sahrens  * Exports the pool from the system.  The caller must ensure that there are no
625*789Sahrens  * mounted datasets in the pool.
626*789Sahrens  */
627*789Sahrens int
628*789Sahrens zpool_export(zpool_handle_t *zhp)
629*789Sahrens {
630*789Sahrens 	zfs_cmd_t zc = { 0 };
631*789Sahrens 
632*789Sahrens 	if (zpool_remove_zvol_links(zhp) != 0)
633*789Sahrens 		return (-1);
634*789Sahrens 
635*789Sahrens 	(void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
636*789Sahrens 
637*789Sahrens 	if (ioctl(zfs_fd, ZFS_IOC_POOL_EXPORT, &zc) != 0) {
638*789Sahrens 		switch (errno) {
639*789Sahrens 		case EPERM:
640*789Sahrens 			zfs_error(dgettext(TEXT_DOMAIN,
641*789Sahrens 			    "cannot export '%s': permission denied"),
642*789Sahrens 			    zhp->zpool_name);
643*789Sahrens 			break;
644*789Sahrens 
645*789Sahrens 		case EBUSY:
646*789Sahrens 			zfs_error(dgettext(TEXT_DOMAIN,
647*789Sahrens 			    "cannot export '%s': pool is in use"),
648*789Sahrens 			    zhp->zpool_name);
649*789Sahrens 			break;
650*789Sahrens 
651*789Sahrens 		case ENOENT:
652*789Sahrens 			zfs_error(dgettext(TEXT_DOMAIN,
653*789Sahrens 			    "cannot export '%s': no such pool"),
654*789Sahrens 			    zhp->zpool_name);
655*789Sahrens 			break;
656*789Sahrens 
657*789Sahrens 		default:
658*789Sahrens 			zfs_baderror(errno);
659*789Sahrens 		}
660*789Sahrens 
661*789Sahrens 		return (-1);
662*789Sahrens 	}
663*789Sahrens 
664*789Sahrens 	return (0);
665*789Sahrens }
666*789Sahrens 
667*789Sahrens /*
668*789Sahrens  * Import the given pool using the known configuration.  The configuration
669*789Sahrens  * should have come from zpool_find_import().  The 'newname' and 'altroot'
670*789Sahrens  * parameters control whether the pool is imported with a different name or with
671*789Sahrens  * an alternate root, respectively.
672*789Sahrens  */
673*789Sahrens int
674*789Sahrens zpool_import(nvlist_t *config, const char *newname, const char *altroot)
675*789Sahrens {
676*789Sahrens 	zfs_cmd_t zc;
677*789Sahrens 	char *packed;
678*789Sahrens 	size_t len;
679*789Sahrens 	char *thename;
680*789Sahrens 	char *origname;
681*789Sahrens 	int ret;
682*789Sahrens 
683*789Sahrens 	verify(nvlist_lookup_string(config, ZPOOL_CONFIG_POOL_NAME,
684*789Sahrens 	    &origname) == 0);
685*789Sahrens 
686*789Sahrens 	if (newname != NULL) {
687*789Sahrens 		if (!zpool_name_valid(newname, NULL, 0)) {
688*789Sahrens 			zfs_error(dgettext(TEXT_DOMAIN, "cannot import '%s': "
689*789Sahrens 			    "invalid pool name"), newname);
690*789Sahrens 			return (-1);
691*789Sahrens 		}
692*789Sahrens 		thename = (char *)newname;
693*789Sahrens 	} else {
694*789Sahrens 		thename = origname;
695*789Sahrens 	}
696*789Sahrens 
697*789Sahrens 	if (altroot != NULL && altroot[0] != '/') {
698*789Sahrens 		zfs_error(dgettext(TEXT_DOMAIN, "cannot import '%s': alternate "
699*789Sahrens 		    "root '%s' must be a complete path"), thename,
700*789Sahrens 		    altroot);
701*789Sahrens 		return (-1);
702*789Sahrens 	}
703*789Sahrens 
704*789Sahrens 	(void) strlcpy(zc.zc_name, thename, sizeof (zc.zc_name));
705*789Sahrens 
706*789Sahrens 	if (altroot != NULL)
707*789Sahrens 		(void) strlcpy(zc.zc_root, altroot, sizeof (zc.zc_root));
708*789Sahrens 	else
709*789Sahrens 		zc.zc_root[0] = '\0';
710*789Sahrens 
711*789Sahrens 	verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_GUID,
712*789Sahrens 	    &zc.zc_pool_guid) == 0);
713*789Sahrens 
714*789Sahrens 	verify(nvlist_size(config, &len, NV_ENCODE_NATIVE) == 0);
715*789Sahrens 
716*789Sahrens 	packed = zfs_malloc(len);
717*789Sahrens 
718*789Sahrens 	verify(nvlist_pack(config, &packed, &len, NV_ENCODE_NATIVE, 0) == 0);
719*789Sahrens 
720*789Sahrens 	zc.zc_config_src = (uint64_t)(uintptr_t)packed;
721*789Sahrens 	zc.zc_config_src_size = len;
722*789Sahrens 
723*789Sahrens 	ret = 0;
724*789Sahrens 	if (ioctl(zfs_fd, ZFS_IOC_POOL_IMPORT, &zc) != 0) {
725*789Sahrens 		char desc[1024];
726*789Sahrens 		if (newname == NULL)
727*789Sahrens 			(void) snprintf(desc, sizeof (desc),
728*789Sahrens 			    dgettext(TEXT_DOMAIN, "cannot import '%s'"),
729*789Sahrens 			    thename);
730*789Sahrens 		else
731*789Sahrens 			(void) snprintf(desc, sizeof (desc),
732*789Sahrens 			    dgettext(TEXT_DOMAIN, "cannot import '%s' as '%s'"),
733*789Sahrens 			    origname, thename);
734*789Sahrens 
735*789Sahrens 		switch (errno) {
736*789Sahrens 		case EEXIST:
737*789Sahrens 			/*
738*789Sahrens 			 * A pool with that name already exists.
739*789Sahrens 			 */
740*789Sahrens 			zfs_error(dgettext(TEXT_DOMAIN, "%s: pool exists"),
741*789Sahrens 			    desc);
742*789Sahrens 			break;
743*789Sahrens 
744*789Sahrens 		case EPERM:
745*789Sahrens 			/*
746*789Sahrens 			 * The user doesn't have permission to create pools.
747*789Sahrens 			 */
748*789Sahrens 			zfs_error(dgettext(TEXT_DOMAIN, "%s: permission "
749*789Sahrens 			    "denied"), desc);
750*789Sahrens 			break;
751*789Sahrens 
752*789Sahrens 		case ENXIO:
753*789Sahrens 		case EDOM:
754*789Sahrens 			/*
755*789Sahrens 			 * Device is unavailable, or vdev sum didn't match.
756*789Sahrens 			 */
757*789Sahrens 			zfs_error(dgettext(TEXT_DOMAIN, "%s: one or more "
758*789Sahrens 			    "devices is unavailable"),
759*789Sahrens 			    desc);
760*789Sahrens 			break;
761*789Sahrens 
762*789Sahrens 		default:
763*789Sahrens 			zfs_baderror(errno);
764*789Sahrens 		}
765*789Sahrens 
766*789Sahrens 		ret = -1;
767*789Sahrens 	} else {
768*789Sahrens 		zpool_handle_t *zhp;
769*789Sahrens 		/*
770*789Sahrens 		 * This should never fail, but play it safe anyway.
771*789Sahrens 		 */
772*789Sahrens 		if ((zhp = zpool_open_silent(thename)) != NULL) {
773*789Sahrens 			ret = zpool_create_zvol_links(zhp);
774*789Sahrens 			zpool_close(zhp);
775*789Sahrens 		}
776*789Sahrens 	}
777*789Sahrens 
778*789Sahrens 	free(packed);
779*789Sahrens 	return (ret);
780*789Sahrens }
781*789Sahrens 
782*789Sahrens /*
783*789Sahrens  * Scrub the pool.
784*789Sahrens  */
785*789Sahrens int
786*789Sahrens zpool_scrub(zpool_handle_t *zhp, pool_scrub_type_t type)
787*789Sahrens {
788*789Sahrens 	zfs_cmd_t zc = { 0 };
789*789Sahrens 	char msg[1024];
790*789Sahrens 
791*789Sahrens 	(void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
792*789Sahrens 	zc.zc_cookie = type;
793*789Sahrens 
794*789Sahrens 	if (ioctl(zfs_fd, ZFS_IOC_POOL_SCRUB, &zc) == 0)
795*789Sahrens 		return (0);
796*789Sahrens 
797*789Sahrens 	(void) snprintf(msg, sizeof (msg),
798*789Sahrens 	    dgettext(TEXT_DOMAIN, "cannot scrub %s"), zc.zc_name);
799*789Sahrens 
800*789Sahrens 	switch (errno) {
801*789Sahrens 	    case EPERM:
802*789Sahrens 		/*
803*789Sahrens 		 * No permission to scrub this pool.
804*789Sahrens 		 */
805*789Sahrens 		zfs_error(dgettext(TEXT_DOMAIN, "%s: permission denied"), msg);
806*789Sahrens 		break;
807*789Sahrens 
808*789Sahrens 	    case EBUSY:
809*789Sahrens 		/*
810*789Sahrens 		 * Resilver in progress.
811*789Sahrens 		 */
812*789Sahrens 		zfs_error(dgettext(TEXT_DOMAIN, "%s: currently resilvering"),
813*789Sahrens 		    msg);
814*789Sahrens 		break;
815*789Sahrens 
816*789Sahrens 	    default:
817*789Sahrens 		zfs_baderror(errno);
818*789Sahrens 	}
819*789Sahrens 	return (-1);
820*789Sahrens }
821*789Sahrens 
822*789Sahrens /*
823*789Sahrens  * Bring the specified vdev online
824*789Sahrens  */
825*789Sahrens int
826*789Sahrens zpool_vdev_online(zpool_handle_t *zhp, const char *path)
827*789Sahrens {
828*789Sahrens 	zfs_cmd_t zc = { 0 };
829*789Sahrens 	char msg[1024];
830*789Sahrens 
831*789Sahrens 	(void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
832*789Sahrens 	(void) snprintf(zc.zc_prop_value, sizeof (zc.zc_prop_value),
833*789Sahrens 	    "%s%s", path[0] == '/' ? "" : "/dev/dsk/", path);
834*789Sahrens 
835*789Sahrens 	if (ioctl(zfs_fd, ZFS_IOC_VDEV_ONLINE, &zc) == 0)
836*789Sahrens 		return (0);
837*789Sahrens 
838*789Sahrens 	(void) snprintf(msg, sizeof (msg),
839*789Sahrens 	    dgettext(TEXT_DOMAIN, "cannot online %s"), zc.zc_prop_value);
840*789Sahrens 
841*789Sahrens 	switch (errno) {
842*789Sahrens 	    case ENODEV:
843*789Sahrens 		/*
844*789Sahrens 		 * Device doesn't exist
845*789Sahrens 		 */
846*789Sahrens 		zfs_error(dgettext(TEXT_DOMAIN, "%s: device not in pool"), msg);
847*789Sahrens 		break;
848*789Sahrens 
849*789Sahrens 	    case EPERM:
850*789Sahrens 		/*
851*789Sahrens 		 * No permission to bring this vdev online.
852*789Sahrens 		 */
853*789Sahrens 		zfs_error(dgettext(TEXT_DOMAIN, "%s: permission denied"), msg);
854*789Sahrens 		break;
855*789Sahrens 
856*789Sahrens 	    default:
857*789Sahrens 		zfs_baderror(errno);
858*789Sahrens 	}
859*789Sahrens 	return (-1);
860*789Sahrens }
861*789Sahrens 
862*789Sahrens /*
863*789Sahrens  * Take the specified vdev offline
864*789Sahrens  */
865*789Sahrens int
866*789Sahrens zpool_vdev_offline(zpool_handle_t *zhp, const char *path)
867*789Sahrens {
868*789Sahrens 	zfs_cmd_t zc = { 0 };
869*789Sahrens 	char msg[1024];
870*789Sahrens 
871*789Sahrens 	(void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
872*789Sahrens 	(void) snprintf(zc.zc_prop_value, sizeof (zc.zc_prop_value),
873*789Sahrens 	    "%s%s", path[0] == '/' ? "" : "/dev/dsk/", path);
874*789Sahrens 
875*789Sahrens 	if (ioctl(zfs_fd, ZFS_IOC_VDEV_OFFLINE, &zc) == 0)
876*789Sahrens 		return (0);
877*789Sahrens 
878*789Sahrens 	(void) snprintf(msg, sizeof (msg),
879*789Sahrens 	    dgettext(TEXT_DOMAIN, "cannot offline %s"), zc.zc_prop_value);
880*789Sahrens 
881*789Sahrens 	switch (errno) {
882*789Sahrens 	    case ENODEV:
883*789Sahrens 		/*
884*789Sahrens 		 * Device doesn't exist
885*789Sahrens 		 */
886*789Sahrens 		zfs_error(dgettext(TEXT_DOMAIN, "%s: device not in pool"), msg);
887*789Sahrens 		break;
888*789Sahrens 
889*789Sahrens 	    case EPERM:
890*789Sahrens 		/*
891*789Sahrens 		 * No permission to take this vdev offline.
892*789Sahrens 		 */
893*789Sahrens 		zfs_error(dgettext(TEXT_DOMAIN, "%s: permission denied"), msg);
894*789Sahrens 		break;
895*789Sahrens 
896*789Sahrens 	    case EBUSY:
897*789Sahrens 		/*
898*789Sahrens 		 * There are no other replicas of this device.
899*789Sahrens 		 */
900*789Sahrens 		zfs_error(dgettext(TEXT_DOMAIN, "%s: no valid replicas"), msg);
901*789Sahrens 		break;
902*789Sahrens 
903*789Sahrens 	    default:
904*789Sahrens 		zfs_baderror(errno);
905*789Sahrens 	}
906*789Sahrens 	return (-1);
907*789Sahrens }
908*789Sahrens 
909*789Sahrens /*
910*789Sahrens  * Attach new_disk (fully described by nvroot) to old_disk.
911*789Sahrens  * If 'replacing' is specified, tne new disk will replace the old one.
912*789Sahrens  */
913*789Sahrens int
914*789Sahrens zpool_vdev_attach(zpool_handle_t *zhp,
915*789Sahrens     const char *old_disk, const char *new_disk, nvlist_t *nvroot, int replacing)
916*789Sahrens {
917*789Sahrens 	zfs_cmd_t zc = { 0 };
918*789Sahrens 	char msg[1024];
919*789Sahrens 	char *packed;
920*789Sahrens 	int ret;
921*789Sahrens 	size_t len;
922*789Sahrens 
923*789Sahrens 	(void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
924*789Sahrens 	(void) snprintf(zc.zc_prop_value, sizeof (zc.zc_prop_value),
925*789Sahrens 	    "%s%s", old_disk[0] == '/' ? "" : "/dev/dsk/", old_disk);
926*789Sahrens 	zc.zc_cookie = replacing;
927*789Sahrens 
928*789Sahrens 	verify(nvlist_size(nvroot, &len, NV_ENCODE_NATIVE) == 0);
929*789Sahrens 
930*789Sahrens 	packed = zfs_malloc(len);
931*789Sahrens 
932*789Sahrens 	verify(nvlist_pack(nvroot, &packed, &len, NV_ENCODE_NATIVE, 0) == 0);
933*789Sahrens 
934*789Sahrens 	zc.zc_config_src = (uint64_t)(uintptr_t)packed;
935*789Sahrens 	zc.zc_config_src_size = len;
936*789Sahrens 
937*789Sahrens 	ret = ioctl(zfs_fd, ZFS_IOC_VDEV_ATTACH, &zc);
938*789Sahrens 
939*789Sahrens 	free(packed);
940*789Sahrens 
941*789Sahrens 	if (ret == 0)
942*789Sahrens 		return (0);
943*789Sahrens 
944*789Sahrens 	if (replacing)
945*789Sahrens 		(void) snprintf(msg, sizeof (msg), dgettext(TEXT_DOMAIN,
946*789Sahrens 		    "cannot replace %s with %s"), old_disk, new_disk);
947*789Sahrens 	else
948*789Sahrens 		(void) snprintf(msg, sizeof (msg), dgettext(TEXT_DOMAIN,
949*789Sahrens 		    "cannot attach %s to %s"), new_disk, old_disk);
950*789Sahrens 
951*789Sahrens 	switch (errno) {
952*789Sahrens 	    case EPERM:
953*789Sahrens 		/*
954*789Sahrens 		 * No permission to mess with the config.
955*789Sahrens 		 */
956*789Sahrens 		zfs_error(dgettext(TEXT_DOMAIN, "%s: permission denied"), msg);
957*789Sahrens 		break;
958*789Sahrens 
959*789Sahrens 	    case ENODEV:
960*789Sahrens 		/*
961*789Sahrens 		 * Device doesn't exist.
962*789Sahrens 		 */
963*789Sahrens 		zfs_error(dgettext(TEXT_DOMAIN, "%s: %s not in pool"),
964*789Sahrens 		    msg, old_disk);
965*789Sahrens 		break;
966*789Sahrens 
967*789Sahrens 	    case ENOTSUP:
968*789Sahrens 		/*
969*789Sahrens 		 * Can't attach to or replace this type of vdev.
970*789Sahrens 		 */
971*789Sahrens 		if (replacing)
972*789Sahrens 			zfs_error(dgettext(TEXT_DOMAIN,
973*789Sahrens 			    "%s: cannot replace a replacing device"), msg);
974*789Sahrens 		else
975*789Sahrens 			zfs_error(dgettext(TEXT_DOMAIN,
976*789Sahrens 			    "%s: attach is only applicable to mirrors"), msg);
977*789Sahrens 		break;
978*789Sahrens 
979*789Sahrens 	    case EINVAL:
980*789Sahrens 		/*
981*789Sahrens 		 * The new device must be a single disk.
982*789Sahrens 		 */
983*789Sahrens 		zfs_error(dgettext(TEXT_DOMAIN,
984*789Sahrens 		    "%s: <new_device> must be a single disk"), msg);
985*789Sahrens 		break;
986*789Sahrens 
987*789Sahrens 	    case ENXIO:
988*789Sahrens 		/*
989*789Sahrens 		 * This is unlikely to happen since we've verified that
990*789Sahrens 		 * all the devices can be opened from userland, but it's
991*789Sahrens 		 * still possible in some circumstances.
992*789Sahrens 		 */
993*789Sahrens 		zfs_error(dgettext(TEXT_DOMAIN, "%s: %s is unavailable"),
994*789Sahrens 		    msg, new_disk);
995*789Sahrens 		break;
996*789Sahrens 
997*789Sahrens 	    case EBUSY:
998*789Sahrens 		/*
999*789Sahrens 		 * The new device is is use.
1000*789Sahrens 		 */
1001*789Sahrens 		zfs_error(dgettext(TEXT_DOMAIN, "%s: %s busy"), msg, new_disk);
1002*789Sahrens 		break;
1003*789Sahrens 
1004*789Sahrens 	    case EOVERFLOW:
1005*789Sahrens 		/*
1006*789Sahrens 		 * The new device is too small.
1007*789Sahrens 		 */
1008*789Sahrens 		zfs_error(dgettext(TEXT_DOMAIN, "%s: %s is too small"),
1009*789Sahrens 		    msg, new_disk);
1010*789Sahrens 		break;
1011*789Sahrens 
1012*789Sahrens 	    case EDOM:
1013*789Sahrens 		/*
1014*789Sahrens 		 * The new device has a different alignment requirement.
1015*789Sahrens 		 */
1016*789Sahrens 		zfs_error(dgettext(TEXT_DOMAIN,
1017*789Sahrens 		    "%s: devices have different sector alignment"), msg);
1018*789Sahrens 		break;
1019*789Sahrens 
1020*789Sahrens 	    case ENAMETOOLONG:
1021*789Sahrens 		/*
1022*789Sahrens 		 * The resulting top-level vdev spec won't fit in the label.
1023*789Sahrens 		 */
1024*789Sahrens 		zfs_error(dgettext(TEXT_DOMAIN,
1025*789Sahrens 		    "%s: too many devices in a single vdev"), msg);
1026*789Sahrens 		break;
1027*789Sahrens 
1028*789Sahrens 	    default:
1029*789Sahrens 		zfs_baderror(errno);
1030*789Sahrens 	}
1031*789Sahrens 
1032*789Sahrens 	return (1);
1033*789Sahrens }
1034*789Sahrens 
1035*789Sahrens /*
1036*789Sahrens  * Detach the specified device.
1037*789Sahrens  */
1038*789Sahrens int
1039*789Sahrens zpool_vdev_detach(zpool_handle_t *zhp, const char *path)
1040*789Sahrens {
1041*789Sahrens 	zfs_cmd_t zc = { 0 };
1042*789Sahrens 	char msg[1024];
1043*789Sahrens 
1044*789Sahrens 	(void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
1045*789Sahrens 	(void) snprintf(zc.zc_prop_value, sizeof (zc.zc_prop_value),
1046*789Sahrens 	    "%s%s", path[0] == '/' ? "" : "/dev/dsk/", path);
1047*789Sahrens 
1048*789Sahrens 	if (ioctl(zfs_fd, ZFS_IOC_VDEV_DETACH, &zc) == 0)
1049*789Sahrens 		return (0);
1050*789Sahrens 
1051*789Sahrens 	(void) snprintf(msg, sizeof (msg),
1052*789Sahrens 	    dgettext(TEXT_DOMAIN, "cannot detach %s"), zc.zc_prop_value);
1053*789Sahrens 
1054*789Sahrens 	switch (errno) {
1055*789Sahrens 	    case EPERM:
1056*789Sahrens 		/*
1057*789Sahrens 		 * No permission to mess with the config.
1058*789Sahrens 		 */
1059*789Sahrens 		zfs_error(dgettext(TEXT_DOMAIN, "%s: permission denied"), msg);
1060*789Sahrens 		break;
1061*789Sahrens 
1062*789Sahrens 	    case ENODEV:
1063*789Sahrens 		/*
1064*789Sahrens 		 * Device doesn't exist.
1065*789Sahrens 		 */
1066*789Sahrens 		zfs_error(dgettext(TEXT_DOMAIN, "%s: device not in pool"), msg);
1067*789Sahrens 		break;
1068*789Sahrens 
1069*789Sahrens 	    case ENOTSUP:
1070*789Sahrens 		/*
1071*789Sahrens 		 * Can't detach from this type of vdev.
1072*789Sahrens 		 */
1073*789Sahrens 		zfs_error(dgettext(TEXT_DOMAIN,
1074*789Sahrens 		    "%s: only applicable to mirror and replacing vdevs"), msg);
1075*789Sahrens 		break;
1076*789Sahrens 
1077*789Sahrens 	    case EBUSY:
1078*789Sahrens 		/*
1079*789Sahrens 		 * There are no other replicas of this device.
1080*789Sahrens 		 */
1081*789Sahrens 		zfs_error(dgettext(TEXT_DOMAIN, "%s: no valid replicas"), msg);
1082*789Sahrens 		break;
1083*789Sahrens 
1084*789Sahrens 	    default:
1085*789Sahrens 		zfs_baderror(errno);
1086*789Sahrens 	}
1087*789Sahrens 
1088*789Sahrens 	return (1);
1089*789Sahrens }
1090*789Sahrens 
1091*789Sahrens static int
1092*789Sahrens do_zvol(zfs_handle_t *zhp, void *data)
1093*789Sahrens {
1094*789Sahrens 	int linktype = (int)(uintptr_t)data;
1095*789Sahrens 	int ret;
1096*789Sahrens 
1097*789Sahrens 	/*
1098*789Sahrens 	 * We check for volblocksize intead of ZFS_TYPE_VOLUME so that we
1099*789Sahrens 	 * correctly handle snapshots of volumes.
1100*789Sahrens 	 */
1101*789Sahrens 	if (zhp->zfs_volblocksize != 0) {
1102*789Sahrens 		if (linktype)
1103*789Sahrens 			ret = zvol_create_link(zhp->zfs_name);
1104*789Sahrens 		else
1105*789Sahrens 			ret = zvol_remove_link(zhp->zfs_name);
1106*789Sahrens 	}
1107*789Sahrens 
1108*789Sahrens 	ret = zfs_iter_children(zhp, do_zvol, data);
1109*789Sahrens 
1110*789Sahrens 	zfs_close(zhp);
1111*789Sahrens 	return (ret);
1112*789Sahrens }
1113*789Sahrens 
1114*789Sahrens /*
1115*789Sahrens  * Iterate over all zvols in the pool and make any necessary minor nodes.
1116*789Sahrens  */
1117*789Sahrens int
1118*789Sahrens zpool_create_zvol_links(zpool_handle_t *zhp)
1119*789Sahrens {
1120*789Sahrens 	zfs_handle_t *zfp;
1121*789Sahrens 	int ret;
1122*789Sahrens 
1123*789Sahrens 	/*
1124*789Sahrens 	 * If the pool is unavailable, just return success.
1125*789Sahrens 	 */
1126*789Sahrens 	if ((zfp = make_dataset_handle(zhp->zpool_name)) == NULL)
1127*789Sahrens 		return (0);
1128*789Sahrens 
1129*789Sahrens 	ret = zfs_iter_children(zfp, do_zvol, (void *)TRUE);
1130*789Sahrens 
1131*789Sahrens 	zfs_close(zfp);
1132*789Sahrens 	return (ret);
1133*789Sahrens }
1134*789Sahrens 
1135*789Sahrens /*
1136*789Sahrens  * Iterate over all zvols in the poool and remove any minor nodes.
1137*789Sahrens  */
1138*789Sahrens int
1139*789Sahrens zpool_remove_zvol_links(zpool_handle_t *zhp)
1140*789Sahrens {
1141*789Sahrens 	zfs_handle_t *zfp;
1142*789Sahrens 	int ret;
1143*789Sahrens 
1144*789Sahrens 	/*
1145*789Sahrens 	 * If the pool is unavailable, just return success.
1146*789Sahrens 	 */
1147*789Sahrens 	if ((zfp = make_dataset_handle(zhp->zpool_name)) == NULL)
1148*789Sahrens 		return (0);
1149*789Sahrens 
1150*789Sahrens 	ret = zfs_iter_children(zfp, do_zvol, (void *)FALSE);
1151*789Sahrens 
1152*789Sahrens 	zfs_close(zfp);
1153*789Sahrens 	return (ret);
1154*789Sahrens }
1155