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