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