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