xref: /illumos-gate/usr/src/lib/libzfs/common/libzfs_pool.c (revision 468c413a79615e77179e8d98f22a7e513a8135bd)
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 2009 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 #include <ctype.h>
28 #include <errno.h>
29 #include <devid.h>
30 #include <fcntl.h>
31 #include <libintl.h>
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <strings.h>
35 #include <unistd.h>
36 #include <sys/efi_partition.h>
37 #include <sys/vtoc.h>
38 #include <sys/zfs_ioctl.h>
39 #include <dlfcn.h>
40 
41 #include "zfs_namecheck.h"
42 #include "zfs_prop.h"
43 #include "libzfs_impl.h"
44 #include "zfs_comutil.h"
45 
46 const char *hist_event_table[LOG_END] = {
47 	"invalid event",
48 	"pool create",
49 	"vdev add",
50 	"pool remove",
51 	"pool destroy",
52 	"pool export",
53 	"pool import",
54 	"vdev attach",
55 	"vdev replace",
56 	"vdev detach",
57 	"vdev online",
58 	"vdev offline",
59 	"vdev upgrade",
60 	"pool clear",
61 	"pool scrub",
62 	"pool property set",
63 	"create",
64 	"clone",
65 	"destroy",
66 	"destroy_begin_sync",
67 	"inherit",
68 	"property set",
69 	"quota set",
70 	"permission update",
71 	"permission remove",
72 	"permission who remove",
73 	"promote",
74 	"receive",
75 	"rename",
76 	"reservation set",
77 	"replay_inc_sync",
78 	"replay_full_sync",
79 	"rollback",
80 	"snapshot",
81 	"filesystem version upgrade",
82 	"refquota set",
83 	"refreservation set",
84 	"pool scrub done",
85 	"user hold",
86 	"user release",
87 };
88 
89 static int read_efi_label(nvlist_t *config, diskaddr_t *sb);
90 
91 #if defined(__i386) || defined(__amd64)
92 #define	BOOTCMD	"installgrub(1M)"
93 #else
94 #define	BOOTCMD	"installboot(1M)"
95 #endif
96 
97 #define	DISK_ROOT	"/dev/dsk"
98 #define	RDISK_ROOT	"/dev/rdsk"
99 #define	BACKUP_SLICE	"s2"
100 
101 /*
102  * ====================================================================
103  *   zpool property functions
104  * ====================================================================
105  */
106 
107 static int
108 zpool_get_all_props(zpool_handle_t *zhp)
109 {
110 	zfs_cmd_t zc = { 0 };
111 	libzfs_handle_t *hdl = zhp->zpool_hdl;
112 
113 	(void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
114 
115 	if (zcmd_alloc_dst_nvlist(hdl, &zc, 0) != 0)
116 		return (-1);
117 
118 	while (ioctl(hdl->libzfs_fd, ZFS_IOC_POOL_GET_PROPS, &zc) != 0) {
119 		if (errno == ENOMEM) {
120 			if (zcmd_expand_dst_nvlist(hdl, &zc) != 0) {
121 				zcmd_free_nvlists(&zc);
122 				return (-1);
123 			}
124 		} else {
125 			zcmd_free_nvlists(&zc);
126 			return (-1);
127 		}
128 	}
129 
130 	if (zcmd_read_dst_nvlist(hdl, &zc, &zhp->zpool_props) != 0) {
131 		zcmd_free_nvlists(&zc);
132 		return (-1);
133 	}
134 
135 	zcmd_free_nvlists(&zc);
136 
137 	return (0);
138 }
139 
140 static int
141 zpool_props_refresh(zpool_handle_t *zhp)
142 {
143 	nvlist_t *old_props;
144 
145 	old_props = zhp->zpool_props;
146 
147 	if (zpool_get_all_props(zhp) != 0)
148 		return (-1);
149 
150 	nvlist_free(old_props);
151 	return (0);
152 }
153 
154 static char *
155 zpool_get_prop_string(zpool_handle_t *zhp, zpool_prop_t prop,
156     zprop_source_t *src)
157 {
158 	nvlist_t *nv, *nvl;
159 	uint64_t ival;
160 	char *value;
161 	zprop_source_t source;
162 
163 	nvl = zhp->zpool_props;
164 	if (nvlist_lookup_nvlist(nvl, zpool_prop_to_name(prop), &nv) == 0) {
165 		verify(nvlist_lookup_uint64(nv, ZPROP_SOURCE, &ival) == 0);
166 		source = ival;
167 		verify(nvlist_lookup_string(nv, ZPROP_VALUE, &value) == 0);
168 	} else {
169 		source = ZPROP_SRC_DEFAULT;
170 		if ((value = (char *)zpool_prop_default_string(prop)) == NULL)
171 			value = "-";
172 	}
173 
174 	if (src)
175 		*src = source;
176 
177 	return (value);
178 }
179 
180 uint64_t
181 zpool_get_prop_int(zpool_handle_t *zhp, zpool_prop_t prop, zprop_source_t *src)
182 {
183 	nvlist_t *nv, *nvl;
184 	uint64_t value;
185 	zprop_source_t source;
186 
187 	if (zhp->zpool_props == NULL && zpool_get_all_props(zhp)) {
188 		/*
189 		 * zpool_get_all_props() has most likely failed because
190 		 * the pool is faulted, but if all we need is the top level
191 		 * vdev's guid then get it from the zhp config nvlist.
192 		 */
193 		if ((prop == ZPOOL_PROP_GUID) &&
194 		    (nvlist_lookup_nvlist(zhp->zpool_config,
195 		    ZPOOL_CONFIG_VDEV_TREE, &nv) == 0) &&
196 		    (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_GUID, &value)
197 		    == 0)) {
198 			return (value);
199 		}
200 		return (zpool_prop_default_numeric(prop));
201 	}
202 
203 	nvl = zhp->zpool_props;
204 	if (nvlist_lookup_nvlist(nvl, zpool_prop_to_name(prop), &nv) == 0) {
205 		verify(nvlist_lookup_uint64(nv, ZPROP_SOURCE, &value) == 0);
206 		source = value;
207 		verify(nvlist_lookup_uint64(nv, ZPROP_VALUE, &value) == 0);
208 	} else {
209 		source = ZPROP_SRC_DEFAULT;
210 		value = zpool_prop_default_numeric(prop);
211 	}
212 
213 	if (src)
214 		*src = source;
215 
216 	return (value);
217 }
218 
219 /*
220  * Map VDEV STATE to printed strings.
221  */
222 char *
223 zpool_state_to_name(vdev_state_t state, vdev_aux_t aux)
224 {
225 	switch (state) {
226 	case VDEV_STATE_CLOSED:
227 	case VDEV_STATE_OFFLINE:
228 		return (gettext("OFFLINE"));
229 	case VDEV_STATE_REMOVED:
230 		return (gettext("REMOVED"));
231 	case VDEV_STATE_CANT_OPEN:
232 		if (aux == VDEV_AUX_CORRUPT_DATA || aux == VDEV_AUX_BAD_LOG)
233 			return (gettext("FAULTED"));
234 		else
235 			return (gettext("UNAVAIL"));
236 	case VDEV_STATE_FAULTED:
237 		return (gettext("FAULTED"));
238 	case VDEV_STATE_DEGRADED:
239 		return (gettext("DEGRADED"));
240 	case VDEV_STATE_HEALTHY:
241 		return (gettext("ONLINE"));
242 	}
243 
244 	return (gettext("UNKNOWN"));
245 }
246 
247 /*
248  * Get a zpool property value for 'prop' and return the value in
249  * a pre-allocated buffer.
250  */
251 int
252 zpool_get_prop(zpool_handle_t *zhp, zpool_prop_t prop, char *buf, size_t len,
253     zprop_source_t *srctype)
254 {
255 	uint64_t intval;
256 	const char *strval;
257 	zprop_source_t src = ZPROP_SRC_NONE;
258 	nvlist_t *nvroot;
259 	vdev_stat_t *vs;
260 	uint_t vsc;
261 
262 	if (zpool_get_state(zhp) == POOL_STATE_UNAVAIL) {
263 		switch (prop) {
264 		case ZPOOL_PROP_NAME:
265 			(void) strlcpy(buf, zpool_get_name(zhp), len);
266 			break;
267 
268 		case ZPOOL_PROP_HEALTH:
269 			(void) strlcpy(buf, "FAULTED", len);
270 			break;
271 
272 		case ZPOOL_PROP_GUID:
273 			intval = zpool_get_prop_int(zhp, prop, &src);
274 			(void) snprintf(buf, len, "%llu", intval);
275 			break;
276 
277 		case ZPOOL_PROP_ALTROOT:
278 		case ZPOOL_PROP_CACHEFILE:
279 			if (zhp->zpool_props != NULL ||
280 			    zpool_get_all_props(zhp) == 0) {
281 				(void) strlcpy(buf,
282 				    zpool_get_prop_string(zhp, prop, &src),
283 				    len);
284 				if (srctype != NULL)
285 					*srctype = src;
286 				return (0);
287 			}
288 			/* FALLTHROUGH */
289 		default:
290 			(void) strlcpy(buf, "-", len);
291 			break;
292 		}
293 
294 		if (srctype != NULL)
295 			*srctype = src;
296 		return (0);
297 	}
298 
299 	if (zhp->zpool_props == NULL && zpool_get_all_props(zhp) &&
300 	    prop != ZPOOL_PROP_NAME)
301 		return (-1);
302 
303 	switch (zpool_prop_get_type(prop)) {
304 	case PROP_TYPE_STRING:
305 		(void) strlcpy(buf, zpool_get_prop_string(zhp, prop, &src),
306 		    len);
307 		break;
308 
309 	case PROP_TYPE_NUMBER:
310 		intval = zpool_get_prop_int(zhp, prop, &src);
311 
312 		switch (prop) {
313 		case ZPOOL_PROP_SIZE:
314 		case ZPOOL_PROP_USED:
315 		case ZPOOL_PROP_AVAILABLE:
316 			(void) zfs_nicenum(intval, buf, len);
317 			break;
318 
319 		case ZPOOL_PROP_CAPACITY:
320 			(void) snprintf(buf, len, "%llu%%",
321 			    (u_longlong_t)intval);
322 			break;
323 
324 		case ZPOOL_PROP_HEALTH:
325 			verify(nvlist_lookup_nvlist(zpool_get_config(zhp, NULL),
326 			    ZPOOL_CONFIG_VDEV_TREE, &nvroot) == 0);
327 			verify(nvlist_lookup_uint64_array(nvroot,
328 			    ZPOOL_CONFIG_STATS, (uint64_t **)&vs, &vsc) == 0);
329 
330 			(void) strlcpy(buf, zpool_state_to_name(intval,
331 			    vs->vs_aux), len);
332 			break;
333 		default:
334 			(void) snprintf(buf, len, "%llu", intval);
335 		}
336 		break;
337 
338 	case PROP_TYPE_INDEX:
339 		intval = zpool_get_prop_int(zhp, prop, &src);
340 		if (zpool_prop_index_to_string(prop, intval, &strval)
341 		    != 0)
342 			return (-1);
343 		(void) strlcpy(buf, strval, len);
344 		break;
345 
346 	default:
347 		abort();
348 	}
349 
350 	if (srctype)
351 		*srctype = src;
352 
353 	return (0);
354 }
355 
356 /*
357  * Check if the bootfs name has the same pool name as it is set to.
358  * Assuming bootfs is a valid dataset name.
359  */
360 static boolean_t
361 bootfs_name_valid(const char *pool, char *bootfs)
362 {
363 	int len = strlen(pool);
364 
365 	if (!zfs_name_valid(bootfs, ZFS_TYPE_FILESYSTEM|ZFS_TYPE_SNAPSHOT))
366 		return (B_FALSE);
367 
368 	if (strncmp(pool, bootfs, len) == 0 &&
369 	    (bootfs[len] == '/' || bootfs[len] == '\0'))
370 		return (B_TRUE);
371 
372 	return (B_FALSE);
373 }
374 
375 /*
376  * Inspect the configuration to determine if any of the devices contain
377  * an EFI label.
378  */
379 static boolean_t
380 pool_uses_efi(nvlist_t *config)
381 {
382 	nvlist_t **child;
383 	uint_t c, children;
384 
385 	if (nvlist_lookup_nvlist_array(config, ZPOOL_CONFIG_CHILDREN,
386 	    &child, &children) != 0)
387 		return (read_efi_label(config, NULL) >= 0);
388 
389 	for (c = 0; c < children; c++) {
390 		if (pool_uses_efi(child[c]))
391 			return (B_TRUE);
392 	}
393 	return (B_FALSE);
394 }
395 
396 static boolean_t
397 pool_is_bootable(zpool_handle_t *zhp)
398 {
399 	char bootfs[ZPOOL_MAXNAMELEN];
400 
401 	return (zpool_get_prop(zhp, ZPOOL_PROP_BOOTFS, bootfs,
402 	    sizeof (bootfs), NULL) == 0 && strncmp(bootfs, "-",
403 	    sizeof (bootfs)) != 0);
404 }
405 
406 
407 /*
408  * Given an nvlist of zpool properties to be set, validate that they are
409  * correct, and parse any numeric properties (index, boolean, etc) if they are
410  * specified as strings.
411  */
412 static nvlist_t *
413 zpool_valid_proplist(libzfs_handle_t *hdl, const char *poolname,
414     nvlist_t *props, uint64_t version, boolean_t create_or_import, char *errbuf)
415 {
416 	nvpair_t *elem;
417 	nvlist_t *retprops;
418 	zpool_prop_t prop;
419 	char *strval;
420 	uint64_t intval;
421 	char *slash;
422 	struct stat64 statbuf;
423 	zpool_handle_t *zhp;
424 	nvlist_t *nvroot;
425 
426 	if (nvlist_alloc(&retprops, NV_UNIQUE_NAME, 0) != 0) {
427 		(void) no_memory(hdl);
428 		return (NULL);
429 	}
430 
431 	elem = NULL;
432 	while ((elem = nvlist_next_nvpair(props, elem)) != NULL) {
433 		const char *propname = nvpair_name(elem);
434 
435 		/*
436 		 * Make sure this property is valid and applies to this type.
437 		 */
438 		if ((prop = zpool_name_to_prop(propname)) == ZPROP_INVAL) {
439 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
440 			    "invalid property '%s'"), propname);
441 			(void) zfs_error(hdl, EZFS_BADPROP, errbuf);
442 			goto error;
443 		}
444 
445 		if (zpool_prop_readonly(prop)) {
446 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "'%s' "
447 			    "is readonly"), propname);
448 			(void) zfs_error(hdl, EZFS_PROPREADONLY, errbuf);
449 			goto error;
450 		}
451 
452 		if (zprop_parse_value(hdl, elem, prop, ZFS_TYPE_POOL, retprops,
453 		    &strval, &intval, errbuf) != 0)
454 			goto error;
455 
456 		/*
457 		 * Perform additional checking for specific properties.
458 		 */
459 		switch (prop) {
460 		case ZPOOL_PROP_VERSION:
461 			if (intval < version || intval > SPA_VERSION) {
462 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
463 				    "property '%s' number %d is invalid."),
464 				    propname, intval);
465 				(void) zfs_error(hdl, EZFS_BADVERSION, errbuf);
466 				goto error;
467 			}
468 			break;
469 
470 		case ZPOOL_PROP_BOOTFS:
471 			if (create_or_import) {
472 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
473 				    "property '%s' cannot be set at creation "
474 				    "or import time"), propname);
475 				(void) zfs_error(hdl, EZFS_BADPROP, errbuf);
476 				goto error;
477 			}
478 
479 			if (version < SPA_VERSION_BOOTFS) {
480 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
481 				    "pool must be upgraded to support "
482 				    "'%s' property"), propname);
483 				(void) zfs_error(hdl, EZFS_BADVERSION, errbuf);
484 				goto error;
485 			}
486 
487 			/*
488 			 * bootfs property value has to be a dataset name and
489 			 * the dataset has to be in the same pool as it sets to.
490 			 */
491 			if (strval[0] != '\0' && !bootfs_name_valid(poolname,
492 			    strval)) {
493 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "'%s' "
494 				    "is an invalid name"), strval);
495 				(void) zfs_error(hdl, EZFS_INVALIDNAME, errbuf);
496 				goto error;
497 			}
498 
499 			if ((zhp = zpool_open_canfail(hdl, poolname)) == NULL) {
500 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
501 				    "could not open pool '%s'"), poolname);
502 				(void) zfs_error(hdl, EZFS_OPENFAILED, errbuf);
503 				goto error;
504 			}
505 			verify(nvlist_lookup_nvlist(zpool_get_config(zhp, NULL),
506 			    ZPOOL_CONFIG_VDEV_TREE, &nvroot) == 0);
507 
508 			/*
509 			 * bootfs property cannot be set on a disk which has
510 			 * been EFI labeled.
511 			 */
512 			if (pool_uses_efi(nvroot)) {
513 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
514 				    "property '%s' not supported on "
515 				    "EFI labeled devices"), propname);
516 				(void) zfs_error(hdl, EZFS_POOL_NOTSUP, errbuf);
517 				zpool_close(zhp);
518 				goto error;
519 			}
520 			zpool_close(zhp);
521 			break;
522 
523 		case ZPOOL_PROP_ALTROOT:
524 			if (!create_or_import) {
525 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
526 				    "property '%s' can only be set during pool "
527 				    "creation or import"), propname);
528 				(void) zfs_error(hdl, EZFS_BADPROP, errbuf);
529 				goto error;
530 			}
531 
532 			if (strval[0] != '/') {
533 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
534 				    "bad alternate root '%s'"), strval);
535 				(void) zfs_error(hdl, EZFS_BADPATH, errbuf);
536 				goto error;
537 			}
538 			break;
539 
540 		case ZPOOL_PROP_CACHEFILE:
541 			if (strval[0] == '\0')
542 				break;
543 
544 			if (strcmp(strval, "none") == 0)
545 				break;
546 
547 			if (strval[0] != '/') {
548 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
549 				    "property '%s' must be empty, an "
550 				    "absolute path, or 'none'"), propname);
551 				(void) zfs_error(hdl, EZFS_BADPATH, errbuf);
552 				goto error;
553 			}
554 
555 			slash = strrchr(strval, '/');
556 
557 			if (slash[1] == '\0' || strcmp(slash, "/.") == 0 ||
558 			    strcmp(slash, "/..") == 0) {
559 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
560 				    "'%s' is not a valid file"), strval);
561 				(void) zfs_error(hdl, EZFS_BADPATH, errbuf);
562 				goto error;
563 			}
564 
565 			*slash = '\0';
566 
567 			if (strval[0] != '\0' &&
568 			    (stat64(strval, &statbuf) != 0 ||
569 			    !S_ISDIR(statbuf.st_mode))) {
570 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
571 				    "'%s' is not a valid directory"),
572 				    strval);
573 				(void) zfs_error(hdl, EZFS_BADPATH, errbuf);
574 				goto error;
575 			}
576 
577 			*slash = '/';
578 			break;
579 		}
580 	}
581 
582 	return (retprops);
583 error:
584 	nvlist_free(retprops);
585 	return (NULL);
586 }
587 
588 /*
589  * Set zpool property : propname=propval.
590  */
591 int
592 zpool_set_prop(zpool_handle_t *zhp, const char *propname, const char *propval)
593 {
594 	zfs_cmd_t zc = { 0 };
595 	int ret = -1;
596 	char errbuf[1024];
597 	nvlist_t *nvl = NULL;
598 	nvlist_t *realprops;
599 	uint64_t version;
600 
601 	(void) snprintf(errbuf, sizeof (errbuf),
602 	    dgettext(TEXT_DOMAIN, "cannot set property for '%s'"),
603 	    zhp->zpool_name);
604 
605 	if (nvlist_alloc(&nvl, NV_UNIQUE_NAME, 0) != 0)
606 		return (no_memory(zhp->zpool_hdl));
607 
608 	if (nvlist_add_string(nvl, propname, propval) != 0) {
609 		nvlist_free(nvl);
610 		return (no_memory(zhp->zpool_hdl));
611 	}
612 
613 	version = zpool_get_prop_int(zhp, ZPOOL_PROP_VERSION, NULL);
614 	if ((realprops = zpool_valid_proplist(zhp->zpool_hdl,
615 	    zhp->zpool_name, nvl, version, B_FALSE, errbuf)) == NULL) {
616 		nvlist_free(nvl);
617 		return (-1);
618 	}
619 
620 	nvlist_free(nvl);
621 	nvl = realprops;
622 
623 	/*
624 	 * Execute the corresponding ioctl() to set this property.
625 	 */
626 	(void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
627 
628 	if (zcmd_write_src_nvlist(zhp->zpool_hdl, &zc, nvl) != 0) {
629 		nvlist_free(nvl);
630 		return (-1);
631 	}
632 
633 	ret = zfs_ioctl(zhp->zpool_hdl, ZFS_IOC_POOL_SET_PROPS, &zc);
634 
635 	zcmd_free_nvlists(&zc);
636 	nvlist_free(nvl);
637 
638 	if (ret)
639 		(void) zpool_standard_error(zhp->zpool_hdl, errno, errbuf);
640 	else
641 		(void) zpool_props_refresh(zhp);
642 
643 	return (ret);
644 }
645 
646 int
647 zpool_expand_proplist(zpool_handle_t *zhp, zprop_list_t **plp)
648 {
649 	libzfs_handle_t *hdl = zhp->zpool_hdl;
650 	zprop_list_t *entry;
651 	char buf[ZFS_MAXPROPLEN];
652 
653 	if (zprop_expand_list(hdl, plp, ZFS_TYPE_POOL) != 0)
654 		return (-1);
655 
656 	for (entry = *plp; entry != NULL; entry = entry->pl_next) {
657 
658 		if (entry->pl_fixed)
659 			continue;
660 
661 		if (entry->pl_prop != ZPROP_INVAL &&
662 		    zpool_get_prop(zhp, entry->pl_prop, buf, sizeof (buf),
663 		    NULL) == 0) {
664 			if (strlen(buf) > entry->pl_width)
665 				entry->pl_width = strlen(buf);
666 		}
667 	}
668 
669 	return (0);
670 }
671 
672 
673 /*
674  * Don't start the slice at the default block of 34; many storage
675  * devices will use a stripe width of 128k, so start there instead.
676  */
677 #define	NEW_START_BLOCK	256
678 
679 /*
680  * Validate the given pool name, optionally putting an extended error message in
681  * 'buf'.
682  */
683 boolean_t
684 zpool_name_valid(libzfs_handle_t *hdl, boolean_t isopen, const char *pool)
685 {
686 	namecheck_err_t why;
687 	char what;
688 	int ret;
689 
690 	ret = pool_namecheck(pool, &why, &what);
691 
692 	/*
693 	 * The rules for reserved pool names were extended at a later point.
694 	 * But we need to support users with existing pools that may now be
695 	 * invalid.  So we only check for this expanded set of names during a
696 	 * create (or import), and only in userland.
697 	 */
698 	if (ret == 0 && !isopen &&
699 	    (strncmp(pool, "mirror", 6) == 0 ||
700 	    strncmp(pool, "raidz", 5) == 0 ||
701 	    strncmp(pool, "spare", 5) == 0 ||
702 	    strcmp(pool, "log") == 0)) {
703 		if (hdl != NULL)
704 			zfs_error_aux(hdl,
705 			    dgettext(TEXT_DOMAIN, "name is reserved"));
706 		return (B_FALSE);
707 	}
708 
709 
710 	if (ret != 0) {
711 		if (hdl != NULL) {
712 			switch (why) {
713 			case NAME_ERR_TOOLONG:
714 				zfs_error_aux(hdl,
715 				    dgettext(TEXT_DOMAIN, "name is too long"));
716 				break;
717 
718 			case NAME_ERR_INVALCHAR:
719 				zfs_error_aux(hdl,
720 				    dgettext(TEXT_DOMAIN, "invalid character "
721 				    "'%c' in pool name"), what);
722 				break;
723 
724 			case NAME_ERR_NOLETTER:
725 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
726 				    "name must begin with a letter"));
727 				break;
728 
729 			case NAME_ERR_RESERVED:
730 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
731 				    "name is reserved"));
732 				break;
733 
734 			case NAME_ERR_DISKLIKE:
735 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
736 				    "pool name is reserved"));
737 				break;
738 
739 			case NAME_ERR_LEADING_SLASH:
740 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
741 				    "leading slash in name"));
742 				break;
743 
744 			case NAME_ERR_EMPTY_COMPONENT:
745 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
746 				    "empty component in name"));
747 				break;
748 
749 			case NAME_ERR_TRAILING_SLASH:
750 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
751 				    "trailing slash in name"));
752 				break;
753 
754 			case NAME_ERR_MULTIPLE_AT:
755 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
756 				    "multiple '@' delimiters in name"));
757 				break;
758 
759 			}
760 		}
761 		return (B_FALSE);
762 	}
763 
764 	return (B_TRUE);
765 }
766 
767 /*
768  * Open a handle to the given pool, even if the pool is currently in the FAULTED
769  * state.
770  */
771 zpool_handle_t *
772 zpool_open_canfail(libzfs_handle_t *hdl, const char *pool)
773 {
774 	zpool_handle_t *zhp;
775 	boolean_t missing;
776 
777 	/*
778 	 * Make sure the pool name is valid.
779 	 */
780 	if (!zpool_name_valid(hdl, B_TRUE, pool)) {
781 		(void) zfs_error_fmt(hdl, EZFS_INVALIDNAME,
782 		    dgettext(TEXT_DOMAIN, "cannot open '%s'"),
783 		    pool);
784 		return (NULL);
785 	}
786 
787 	if ((zhp = zfs_alloc(hdl, sizeof (zpool_handle_t))) == NULL)
788 		return (NULL);
789 
790 	zhp->zpool_hdl = hdl;
791 	(void) strlcpy(zhp->zpool_name, pool, sizeof (zhp->zpool_name));
792 
793 	if (zpool_refresh_stats(zhp, &missing) != 0) {
794 		zpool_close(zhp);
795 		return (NULL);
796 	}
797 
798 	if (missing) {
799 		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "no such pool"));
800 		(void) zfs_error_fmt(hdl, EZFS_NOENT,
801 		    dgettext(TEXT_DOMAIN, "cannot open '%s'"), pool);
802 		zpool_close(zhp);
803 		return (NULL);
804 	}
805 
806 	return (zhp);
807 }
808 
809 /*
810  * Like the above, but silent on error.  Used when iterating over pools (because
811  * the configuration cache may be out of date).
812  */
813 int
814 zpool_open_silent(libzfs_handle_t *hdl, const char *pool, zpool_handle_t **ret)
815 {
816 	zpool_handle_t *zhp;
817 	boolean_t missing;
818 
819 	if ((zhp = zfs_alloc(hdl, sizeof (zpool_handle_t))) == NULL)
820 		return (-1);
821 
822 	zhp->zpool_hdl = hdl;
823 	(void) strlcpy(zhp->zpool_name, pool, sizeof (zhp->zpool_name));
824 
825 	if (zpool_refresh_stats(zhp, &missing) != 0) {
826 		zpool_close(zhp);
827 		return (-1);
828 	}
829 
830 	if (missing) {
831 		zpool_close(zhp);
832 		*ret = NULL;
833 		return (0);
834 	}
835 
836 	*ret = zhp;
837 	return (0);
838 }
839 
840 /*
841  * Similar to zpool_open_canfail(), but refuses to open pools in the faulted
842  * state.
843  */
844 zpool_handle_t *
845 zpool_open(libzfs_handle_t *hdl, const char *pool)
846 {
847 	zpool_handle_t *zhp;
848 
849 	if ((zhp = zpool_open_canfail(hdl, pool)) == NULL)
850 		return (NULL);
851 
852 	if (zhp->zpool_state == POOL_STATE_UNAVAIL) {
853 		(void) zfs_error_fmt(hdl, EZFS_POOLUNAVAIL,
854 		    dgettext(TEXT_DOMAIN, "cannot open '%s'"), zhp->zpool_name);
855 		zpool_close(zhp);
856 		return (NULL);
857 	}
858 
859 	return (zhp);
860 }
861 
862 /*
863  * Close the handle.  Simply frees the memory associated with the handle.
864  */
865 void
866 zpool_close(zpool_handle_t *zhp)
867 {
868 	if (zhp->zpool_config)
869 		nvlist_free(zhp->zpool_config);
870 	if (zhp->zpool_old_config)
871 		nvlist_free(zhp->zpool_old_config);
872 	if (zhp->zpool_props)
873 		nvlist_free(zhp->zpool_props);
874 	free(zhp);
875 }
876 
877 /*
878  * Return the name of the pool.
879  */
880 const char *
881 zpool_get_name(zpool_handle_t *zhp)
882 {
883 	return (zhp->zpool_name);
884 }
885 
886 
887 /*
888  * Return the state of the pool (ACTIVE or UNAVAILABLE)
889  */
890 int
891 zpool_get_state(zpool_handle_t *zhp)
892 {
893 	return (zhp->zpool_state);
894 }
895 
896 /*
897  * Create the named pool, using the provided vdev list.  It is assumed
898  * that the consumer has already validated the contents of the nvlist, so we
899  * don't have to worry about error semantics.
900  */
901 int
902 zpool_create(libzfs_handle_t *hdl, const char *pool, nvlist_t *nvroot,
903     nvlist_t *props, nvlist_t *fsprops)
904 {
905 	zfs_cmd_t zc = { 0 };
906 	nvlist_t *zc_fsprops = NULL;
907 	nvlist_t *zc_props = NULL;
908 	char msg[1024];
909 	char *altroot;
910 	int ret = -1;
911 
912 	(void) snprintf(msg, sizeof (msg), dgettext(TEXT_DOMAIN,
913 	    "cannot create '%s'"), pool);
914 
915 	if (!zpool_name_valid(hdl, B_FALSE, pool))
916 		return (zfs_error(hdl, EZFS_INVALIDNAME, msg));
917 
918 	if (zcmd_write_conf_nvlist(hdl, &zc, nvroot) != 0)
919 		return (-1);
920 
921 	if (props) {
922 		if ((zc_props = zpool_valid_proplist(hdl, pool, props,
923 		    SPA_VERSION_1, B_TRUE, msg)) == NULL) {
924 			goto create_failed;
925 		}
926 	}
927 
928 	if (fsprops) {
929 		uint64_t zoned;
930 		char *zonestr;
931 
932 		zoned = ((nvlist_lookup_string(fsprops,
933 		    zfs_prop_to_name(ZFS_PROP_ZONED), &zonestr) == 0) &&
934 		    strcmp(zonestr, "on") == 0);
935 
936 		if ((zc_fsprops = zfs_valid_proplist(hdl,
937 		    ZFS_TYPE_FILESYSTEM, fsprops, zoned, NULL, msg)) == NULL) {
938 			goto create_failed;
939 		}
940 		if (!zc_props &&
941 		    (nvlist_alloc(&zc_props, NV_UNIQUE_NAME, 0) != 0)) {
942 			goto create_failed;
943 		}
944 		if (nvlist_add_nvlist(zc_props,
945 		    ZPOOL_ROOTFS_PROPS, zc_fsprops) != 0) {
946 			goto create_failed;
947 		}
948 	}
949 
950 	if (zc_props && zcmd_write_src_nvlist(hdl, &zc, zc_props) != 0)
951 		goto create_failed;
952 
953 	(void) strlcpy(zc.zc_name, pool, sizeof (zc.zc_name));
954 
955 	if ((ret = zfs_ioctl(hdl, ZFS_IOC_POOL_CREATE, &zc)) != 0) {
956 
957 		zcmd_free_nvlists(&zc);
958 		nvlist_free(zc_props);
959 		nvlist_free(zc_fsprops);
960 
961 		switch (errno) {
962 		case EBUSY:
963 			/*
964 			 * This can happen if the user has specified the same
965 			 * device multiple times.  We can't reliably detect this
966 			 * until we try to add it and see we already have a
967 			 * label.
968 			 */
969 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
970 			    "one or more vdevs refer to the same device"));
971 			return (zfs_error(hdl, EZFS_BADDEV, msg));
972 
973 		case EOVERFLOW:
974 			/*
975 			 * This occurs when one of the devices is below
976 			 * SPA_MINDEVSIZE.  Unfortunately, we can't detect which
977 			 * device was the problem device since there's no
978 			 * reliable way to determine device size from userland.
979 			 */
980 			{
981 				char buf[64];
982 
983 				zfs_nicenum(SPA_MINDEVSIZE, buf, sizeof (buf));
984 
985 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
986 				    "one or more devices is less than the "
987 				    "minimum size (%s)"), buf);
988 			}
989 			return (zfs_error(hdl, EZFS_BADDEV, msg));
990 
991 		case ENOSPC:
992 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
993 			    "one or more devices is out of space"));
994 			return (zfs_error(hdl, EZFS_BADDEV, msg));
995 
996 		case ENOTBLK:
997 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
998 			    "cache device must be a disk or disk slice"));
999 			return (zfs_error(hdl, EZFS_BADDEV, msg));
1000 
1001 		default:
1002 			return (zpool_standard_error(hdl, errno, msg));
1003 		}
1004 	}
1005 
1006 	/*
1007 	 * If this is an alternate root pool, then we automatically set the
1008 	 * mountpoint of the root dataset to be '/'.
1009 	 */
1010 	if (nvlist_lookup_string(props, zpool_prop_to_name(ZPOOL_PROP_ALTROOT),
1011 	    &altroot) == 0) {
1012 		zfs_handle_t *zhp;
1013 
1014 		verify((zhp = zfs_open(hdl, pool, ZFS_TYPE_DATASET)) != NULL);
1015 		verify(zfs_prop_set(zhp, zfs_prop_to_name(ZFS_PROP_MOUNTPOINT),
1016 		    "/") == 0);
1017 
1018 		zfs_close(zhp);
1019 	}
1020 
1021 create_failed:
1022 	zcmd_free_nvlists(&zc);
1023 	nvlist_free(zc_props);
1024 	nvlist_free(zc_fsprops);
1025 	return (ret);
1026 }
1027 
1028 /*
1029  * Destroy the given pool.  It is up to the caller to ensure that there are no
1030  * datasets left in the pool.
1031  */
1032 int
1033 zpool_destroy(zpool_handle_t *zhp)
1034 {
1035 	zfs_cmd_t zc = { 0 };
1036 	zfs_handle_t *zfp = NULL;
1037 	libzfs_handle_t *hdl = zhp->zpool_hdl;
1038 	char msg[1024];
1039 
1040 	if (zhp->zpool_state == POOL_STATE_ACTIVE &&
1041 	    (zfp = zfs_open(zhp->zpool_hdl, zhp->zpool_name,
1042 	    ZFS_TYPE_FILESYSTEM)) == NULL)
1043 		return (-1);
1044 
1045 	(void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
1046 
1047 	if (zfs_ioctl(zhp->zpool_hdl, ZFS_IOC_POOL_DESTROY, &zc) != 0) {
1048 		(void) snprintf(msg, sizeof (msg), dgettext(TEXT_DOMAIN,
1049 		    "cannot destroy '%s'"), zhp->zpool_name);
1050 
1051 		if (errno == EROFS) {
1052 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1053 			    "one or more devices is read only"));
1054 			(void) zfs_error(hdl, EZFS_BADDEV, msg);
1055 		} else {
1056 			(void) zpool_standard_error(hdl, errno, msg);
1057 		}
1058 
1059 		if (zfp)
1060 			zfs_close(zfp);
1061 		return (-1);
1062 	}
1063 
1064 	if (zfp) {
1065 		remove_mountpoint(zfp);
1066 		zfs_close(zfp);
1067 	}
1068 
1069 	return (0);
1070 }
1071 
1072 /*
1073  * Add the given vdevs to the pool.  The caller must have already performed the
1074  * necessary verification to ensure that the vdev specification is well-formed.
1075  */
1076 int
1077 zpool_add(zpool_handle_t *zhp, nvlist_t *nvroot)
1078 {
1079 	zfs_cmd_t zc = { 0 };
1080 	int ret;
1081 	libzfs_handle_t *hdl = zhp->zpool_hdl;
1082 	char msg[1024];
1083 	nvlist_t **spares, **l2cache;
1084 	uint_t nspares, nl2cache;
1085 
1086 	(void) snprintf(msg, sizeof (msg), dgettext(TEXT_DOMAIN,
1087 	    "cannot add to '%s'"), zhp->zpool_name);
1088 
1089 	if (zpool_get_prop_int(zhp, ZPOOL_PROP_VERSION, NULL) <
1090 	    SPA_VERSION_SPARES &&
1091 	    nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_SPARES,
1092 	    &spares, &nspares) == 0) {
1093 		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "pool must be "
1094 		    "upgraded to add hot spares"));
1095 		return (zfs_error(hdl, EZFS_BADVERSION, msg));
1096 	}
1097 
1098 	if (pool_is_bootable(zhp) && nvlist_lookup_nvlist_array(nvroot,
1099 	    ZPOOL_CONFIG_SPARES, &spares, &nspares) == 0) {
1100 		uint64_t s;
1101 
1102 		for (s = 0; s < nspares; s++) {
1103 			char *path;
1104 
1105 			if (nvlist_lookup_string(spares[s], ZPOOL_CONFIG_PATH,
1106 			    &path) == 0 && pool_uses_efi(spares[s])) {
1107 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1108 				    "device '%s' contains an EFI label and "
1109 				    "cannot be used on root pools."),
1110 				    zpool_vdev_name(hdl, NULL, spares[s],
1111 				    B_FALSE));
1112 				return (zfs_error(hdl, EZFS_POOL_NOTSUP, msg));
1113 			}
1114 		}
1115 	}
1116 
1117 	if (zpool_get_prop_int(zhp, ZPOOL_PROP_VERSION, NULL) <
1118 	    SPA_VERSION_L2CACHE &&
1119 	    nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_L2CACHE,
1120 	    &l2cache, &nl2cache) == 0) {
1121 		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "pool must be "
1122 		    "upgraded to add cache devices"));
1123 		return (zfs_error(hdl, EZFS_BADVERSION, msg));
1124 	}
1125 
1126 	if (zcmd_write_conf_nvlist(hdl, &zc, nvroot) != 0)
1127 		return (-1);
1128 	(void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
1129 
1130 	if (zfs_ioctl(zhp->zpool_hdl, ZFS_IOC_VDEV_ADD, &zc) != 0) {
1131 		switch (errno) {
1132 		case EBUSY:
1133 			/*
1134 			 * This can happen if the user has specified the same
1135 			 * device multiple times.  We can't reliably detect this
1136 			 * until we try to add it and see we already have a
1137 			 * label.
1138 			 */
1139 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1140 			    "one or more vdevs refer to the same device"));
1141 			(void) zfs_error(hdl, EZFS_BADDEV, msg);
1142 			break;
1143 
1144 		case EOVERFLOW:
1145 			/*
1146 			 * This occurrs when one of the devices is below
1147 			 * SPA_MINDEVSIZE.  Unfortunately, we can't detect which
1148 			 * device was the problem device since there's no
1149 			 * reliable way to determine device size from userland.
1150 			 */
1151 			{
1152 				char buf[64];
1153 
1154 				zfs_nicenum(SPA_MINDEVSIZE, buf, sizeof (buf));
1155 
1156 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1157 				    "device is less than the minimum "
1158 				    "size (%s)"), buf);
1159 			}
1160 			(void) zfs_error(hdl, EZFS_BADDEV, msg);
1161 			break;
1162 
1163 		case ENOTSUP:
1164 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1165 			    "pool must be upgraded to add these vdevs"));
1166 			(void) zfs_error(hdl, EZFS_BADVERSION, msg);
1167 			break;
1168 
1169 		case EDOM:
1170 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1171 			    "root pool can not have multiple vdevs"
1172 			    " or separate logs"));
1173 			(void) zfs_error(hdl, EZFS_POOL_NOTSUP, msg);
1174 			break;
1175 
1176 		case ENOTBLK:
1177 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1178 			    "cache device must be a disk or disk slice"));
1179 			(void) zfs_error(hdl, EZFS_BADDEV, msg);
1180 			break;
1181 
1182 		default:
1183 			(void) zpool_standard_error(hdl, errno, msg);
1184 		}
1185 
1186 		ret = -1;
1187 	} else {
1188 		ret = 0;
1189 	}
1190 
1191 	zcmd_free_nvlists(&zc);
1192 
1193 	return (ret);
1194 }
1195 
1196 /*
1197  * Exports the pool from the system.  The caller must ensure that there are no
1198  * mounted datasets in the pool.
1199  */
1200 int
1201 zpool_export_common(zpool_handle_t *zhp, boolean_t force, boolean_t hardforce)
1202 {
1203 	zfs_cmd_t zc = { 0 };
1204 	char msg[1024];
1205 
1206 	(void) snprintf(msg, sizeof (msg), dgettext(TEXT_DOMAIN,
1207 	    "cannot export '%s'"), zhp->zpool_name);
1208 
1209 	(void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
1210 	zc.zc_cookie = force;
1211 	zc.zc_guid = hardforce;
1212 
1213 	if (zfs_ioctl(zhp->zpool_hdl, ZFS_IOC_POOL_EXPORT, &zc) != 0) {
1214 		switch (errno) {
1215 		case EXDEV:
1216 			zfs_error_aux(zhp->zpool_hdl, dgettext(TEXT_DOMAIN,
1217 			    "use '-f' to override the following errors:\n"
1218 			    "'%s' has an active shared spare which could be"
1219 			    " used by other pools once '%s' is exported."),
1220 			    zhp->zpool_name, zhp->zpool_name);
1221 			return (zfs_error(zhp->zpool_hdl, EZFS_ACTIVE_SPARE,
1222 			    msg));
1223 		default:
1224 			return (zpool_standard_error_fmt(zhp->zpool_hdl, errno,
1225 			    msg));
1226 		}
1227 	}
1228 
1229 	return (0);
1230 }
1231 
1232 int
1233 zpool_export(zpool_handle_t *zhp, boolean_t force)
1234 {
1235 	return (zpool_export_common(zhp, force, B_FALSE));
1236 }
1237 
1238 int
1239 zpool_export_force(zpool_handle_t *zhp)
1240 {
1241 	return (zpool_export_common(zhp, B_TRUE, B_TRUE));
1242 }
1243 
1244 static void
1245 zpool_rewind_exclaim(libzfs_handle_t *hdl, const char *name, boolean_t dryrun,
1246     nvlist_t *rbi)
1247 {
1248 	uint64_t rewindto;
1249 	int64_t loss = -1;
1250 	struct tm t;
1251 	char timestr[128];
1252 
1253 	if (!hdl->libzfs_printerr || rbi == NULL)
1254 		return;
1255 
1256 	if (nvlist_lookup_uint64(rbi, ZPOOL_CONFIG_LOAD_TIME, &rewindto) != 0)
1257 		return;
1258 	(void) nvlist_lookup_int64(rbi, ZPOOL_CONFIG_REWIND_TIME, &loss);
1259 
1260 	if (localtime_r((time_t *)&rewindto, &t) != NULL &&
1261 	    strftime(timestr, 128, 0, &t) != 0) {
1262 		if (dryrun) {
1263 			(void) printf(dgettext(TEXT_DOMAIN,
1264 			    "Would be able to return %s "
1265 			    "to its state as of %s.\n"),
1266 			    name, timestr);
1267 		} else {
1268 			(void) printf(dgettext(TEXT_DOMAIN,
1269 			    "Pool %s returned to its state as of %s.\n"),
1270 			    name, timestr);
1271 		}
1272 		if (loss > 120) {
1273 			(void) printf(dgettext(TEXT_DOMAIN,
1274 			    "%s approximately %lld "),
1275 			    dryrun ? "Would discard" : "Discarded",
1276 			    (loss + 30) / 60);
1277 			(void) printf(dgettext(TEXT_DOMAIN,
1278 			    "minutes of transactions.\n"));
1279 		} else if (loss > 0) {
1280 			(void) printf(dgettext(TEXT_DOMAIN,
1281 			    "%s approximately %lld "),
1282 			    dryrun ? "Would discard" : "Discarded", loss);
1283 			(void) printf(dgettext(TEXT_DOMAIN,
1284 			    "seconds of transactions.\n"));
1285 		}
1286 	}
1287 }
1288 
1289 void
1290 zpool_explain_recover(libzfs_handle_t *hdl, const char *name, int reason,
1291     nvlist_t *config)
1292 {
1293 	int64_t loss = -1;
1294 	uint64_t edata = UINT64_MAX;
1295 	uint64_t rewindto;
1296 	struct tm t;
1297 	char timestr[128];
1298 
1299 	if (!hdl->libzfs_printerr)
1300 		return;
1301 
1302 	if (reason >= 0)
1303 		(void) printf(dgettext(TEXT_DOMAIN, "action: "));
1304 	else
1305 		(void) printf(dgettext(TEXT_DOMAIN, "\t"));
1306 
1307 	/* All attempted rewinds failed if ZPOOL_CONFIG_LOAD_TIME missing */
1308 	if (nvlist_lookup_uint64(config,
1309 	    ZPOOL_CONFIG_LOAD_TIME, &rewindto) != 0)
1310 		goto no_info;
1311 
1312 	(void) nvlist_lookup_int64(config, ZPOOL_CONFIG_REWIND_TIME, &loss);
1313 	(void) nvlist_lookup_uint64(config, ZPOOL_CONFIG_LOAD_DATA_ERRORS,
1314 	    &edata);
1315 
1316 	(void) printf(dgettext(TEXT_DOMAIN,
1317 	    "Recovery is possible, but will result in some data loss.\n"));
1318 
1319 	if (localtime_r((time_t *)&rewindto, &t) != NULL &&
1320 	    strftime(timestr, 128, 0, &t) != 0) {
1321 		(void) printf(dgettext(TEXT_DOMAIN,
1322 		    "\tReturning the pool to its state as of %s\n"
1323 		    "\tshould correct the problem.  "),
1324 		    timestr);
1325 	} else {
1326 		(void) printf(dgettext(TEXT_DOMAIN,
1327 		    "\tReverting the pool to an earlier state "
1328 		    "should correct the problem.\n\t"));
1329 	}
1330 
1331 	if (loss > 120) {
1332 		(void) printf(dgettext(TEXT_DOMAIN,
1333 		    "Approximately %lld minutes of data\n"
1334 		    "\tmust be discarded, irreversibly.  "), (loss + 30) / 60);
1335 	} else if (loss > 0) {
1336 		(void) printf(dgettext(TEXT_DOMAIN,
1337 		    "Approximately %lld seconds of data\n"
1338 		    "\tmust be discarded, irreversibly.  "), loss);
1339 	}
1340 	if (edata != 0 && edata != UINT64_MAX) {
1341 		if (edata == 1) {
1342 			(void) printf(dgettext(TEXT_DOMAIN,
1343 			    "After rewind, at least\n"
1344 			    "\tone persistent user-data error will remain.  "));
1345 		} else {
1346 			(void) printf(dgettext(TEXT_DOMAIN,
1347 			    "After rewind, several\n"
1348 			    "\tpersistent user-data errors will remain.  "));
1349 		}
1350 	}
1351 	(void) printf(dgettext(TEXT_DOMAIN,
1352 	    "Recovery can be\n\tattempted by executing "
1353 	    "'zpool %s -F %s'.  "), reason >= 0 ? "clear" : "import", name);
1354 
1355 	(void) printf(dgettext(TEXT_DOMAIN,
1356 	    "A scrub of the pool\n"
1357 	    "\tis strongly recommended after recovery.\n"));
1358 	return;
1359 
1360 no_info:
1361 	(void) printf(dgettext(TEXT_DOMAIN,
1362 	    "Destroy and re-create the pool from\n\ta backup source.\n"));
1363 }
1364 
1365 /*
1366  * zpool_import() is a contracted interface. Should be kept the same
1367  * if possible.
1368  *
1369  * Applications should use zpool_import_props() to import a pool with
1370  * new properties value to be set.
1371  */
1372 int
1373 zpool_import(libzfs_handle_t *hdl, nvlist_t *config, const char *newname,
1374     char *altroot)
1375 {
1376 	nvlist_t *props = NULL;
1377 	int ret;
1378 
1379 	if (altroot != NULL) {
1380 		if (nvlist_alloc(&props, NV_UNIQUE_NAME, 0) != 0) {
1381 			return (zfs_error_fmt(hdl, EZFS_NOMEM,
1382 			    dgettext(TEXT_DOMAIN, "cannot import '%s'"),
1383 			    newname));
1384 		}
1385 
1386 		if (nvlist_add_string(props,
1387 		    zpool_prop_to_name(ZPOOL_PROP_ALTROOT), altroot) != 0 ||
1388 		    nvlist_add_string(props,
1389 		    zpool_prop_to_name(ZPOOL_PROP_CACHEFILE), "none") != 0) {
1390 			nvlist_free(props);
1391 			return (zfs_error_fmt(hdl, EZFS_NOMEM,
1392 			    dgettext(TEXT_DOMAIN, "cannot import '%s'"),
1393 			    newname));
1394 		}
1395 	}
1396 
1397 	ret = zpool_import_props(hdl, config, newname, props, B_FALSE);
1398 	if (props)
1399 		nvlist_free(props);
1400 	return (ret);
1401 }
1402 
1403 /*
1404  * Import the given pool using the known configuration and a list of
1405  * properties to be set. The configuration should have come from
1406  * zpool_find_import(). The 'newname' parameters control whether the pool
1407  * is imported with a different name.
1408  */
1409 int
1410 zpool_import_props(libzfs_handle_t *hdl, nvlist_t *config, const char *newname,
1411     nvlist_t *props, boolean_t importfaulted)
1412 {
1413 	zfs_cmd_t zc = { 0 };
1414 	zpool_rewind_policy_t policy;
1415 	nvlist_t *nvi = NULL;
1416 	char *thename;
1417 	char *origname;
1418 	uint64_t returned_size;
1419 	int ret;
1420 	char errbuf[1024];
1421 
1422 	verify(nvlist_lookup_string(config, ZPOOL_CONFIG_POOL_NAME,
1423 	    &origname) == 0);
1424 
1425 	(void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
1426 	    "cannot import pool '%s'"), origname);
1427 
1428 	if (newname != NULL) {
1429 		if (!zpool_name_valid(hdl, B_FALSE, newname))
1430 			return (zfs_error_fmt(hdl, EZFS_INVALIDNAME,
1431 			    dgettext(TEXT_DOMAIN, "cannot import '%s'"),
1432 			    newname));
1433 		thename = (char *)newname;
1434 	} else {
1435 		thename = origname;
1436 	}
1437 
1438 	if (props) {
1439 		uint64_t version;
1440 
1441 		verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION,
1442 		    &version) == 0);
1443 
1444 		if ((props = zpool_valid_proplist(hdl, origname,
1445 		    props, version, B_TRUE, errbuf)) == NULL) {
1446 			return (-1);
1447 		} else if (zcmd_write_src_nvlist(hdl, &zc, props) != 0) {
1448 			nvlist_free(props);
1449 			return (-1);
1450 		}
1451 	}
1452 
1453 	(void) strlcpy(zc.zc_name, thename, sizeof (zc.zc_name));
1454 
1455 	verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_GUID,
1456 	    &zc.zc_guid) == 0);
1457 
1458 	if (zcmd_write_conf_nvlist(hdl, &zc, config) != 0) {
1459 		nvlist_free(props);
1460 		return (-1);
1461 	}
1462 	returned_size =  zc.zc_nvlist_conf_size + 512;
1463 	if (zcmd_alloc_dst_nvlist(hdl, &zc, returned_size) != 0) {
1464 		nvlist_free(props);
1465 		return (-1);
1466 	}
1467 
1468 	zc.zc_cookie = (uint64_t)importfaulted;
1469 	ret = 0;
1470 	if (zfs_ioctl(hdl, ZFS_IOC_POOL_IMPORT, &zc) != 0) {
1471 		char desc[1024];
1472 
1473 		(void) zcmd_read_dst_nvlist(hdl, &zc, &nvi);
1474 		zpool_get_rewind_policy(config, &policy);
1475 		/*
1476 		 * Dry-run failed, but we print out what success
1477 		 * looks like if we found a best txg
1478 		 */
1479 		if ((policy.zrp_request & ZPOOL_TRY_REWIND) && nvi) {
1480 			zpool_rewind_exclaim(hdl, newname ? origname : thename,
1481 			    B_TRUE, nvi);
1482 			nvlist_free(nvi);
1483 			return (-1);
1484 		}
1485 
1486 		if (newname == NULL)
1487 			(void) snprintf(desc, sizeof (desc),
1488 			    dgettext(TEXT_DOMAIN, "cannot import '%s'"),
1489 			    thename);
1490 		else
1491 			(void) snprintf(desc, sizeof (desc),
1492 			    dgettext(TEXT_DOMAIN, "cannot import '%s' as '%s'"),
1493 			    origname, thename);
1494 
1495 		switch (errno) {
1496 		case ENOTSUP:
1497 			/*
1498 			 * Unsupported version.
1499 			 */
1500 			(void) zfs_error(hdl, EZFS_BADVERSION, desc);
1501 			break;
1502 
1503 		case EINVAL:
1504 			(void) zfs_error(hdl, EZFS_INVALCONFIG, desc);
1505 			break;
1506 
1507 		default:
1508 			(void) zcmd_read_dst_nvlist(hdl, &zc, &nvi);
1509 			(void) zpool_standard_error(hdl, errno, desc);
1510 			zpool_explain_recover(hdl,
1511 			    newname ? origname : thename, -errno, nvi);
1512 			nvlist_free(nvi);
1513 			break;
1514 		}
1515 
1516 		ret = -1;
1517 	} else {
1518 		zpool_handle_t *zhp;
1519 
1520 		/*
1521 		 * This should never fail, but play it safe anyway.
1522 		 */
1523 		if (zpool_open_silent(hdl, thename, &zhp) != 0)
1524 			ret = -1;
1525 		else if (zhp != NULL)
1526 			zpool_close(zhp);
1527 		(void) zcmd_read_dst_nvlist(hdl, &zc, &nvi);
1528 		zpool_get_rewind_policy(config, &policy);
1529 		if (policy.zrp_request &
1530 		    (ZPOOL_DO_REWIND | ZPOOL_TRY_REWIND)) {
1531 			zpool_rewind_exclaim(hdl, newname ? origname : thename,
1532 			    ((policy.zrp_request & ZPOOL_TRY_REWIND) != 0),
1533 			    nvi);
1534 		}
1535 		nvlist_free(nvi);
1536 		return (0);
1537 	}
1538 
1539 	zcmd_free_nvlists(&zc);
1540 	nvlist_free(props);
1541 
1542 	return (ret);
1543 }
1544 
1545 /*
1546  * Scrub the pool.
1547  */
1548 int
1549 zpool_scrub(zpool_handle_t *zhp, pool_scrub_type_t type)
1550 {
1551 	zfs_cmd_t zc = { 0 };
1552 	char msg[1024];
1553 	libzfs_handle_t *hdl = zhp->zpool_hdl;
1554 
1555 	(void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
1556 	zc.zc_cookie = type;
1557 
1558 	if (zfs_ioctl(zhp->zpool_hdl, ZFS_IOC_POOL_SCRUB, &zc) == 0)
1559 		return (0);
1560 
1561 	(void) snprintf(msg, sizeof (msg),
1562 	    dgettext(TEXT_DOMAIN, "cannot scrub %s"), zc.zc_name);
1563 
1564 	if (errno == EBUSY)
1565 		return (zfs_error(hdl, EZFS_RESILVERING, msg));
1566 	else
1567 		return (zpool_standard_error(hdl, errno, msg));
1568 }
1569 
1570 /*
1571  * Find a vdev that matches the search criteria specified. We use the
1572  * the nvpair name to determine how we should look for the device.
1573  * 'avail_spare' is set to TRUE if the provided guid refers to an AVAIL
1574  * spare; but FALSE if its an INUSE spare.
1575  */
1576 static nvlist_t *
1577 vdev_to_nvlist_iter(nvlist_t *nv, nvlist_t *search, boolean_t *avail_spare,
1578     boolean_t *l2cache, boolean_t *log)
1579 {
1580 	uint_t c, children;
1581 	nvlist_t **child;
1582 	nvlist_t *ret;
1583 	uint64_t is_log;
1584 	char *srchkey;
1585 	nvpair_t *pair = nvlist_next_nvpair(search, NULL);
1586 
1587 	/* Nothing to look for */
1588 	if (search == NULL || pair == NULL)
1589 		return (NULL);
1590 
1591 	/* Obtain the key we will use to search */
1592 	srchkey = nvpair_name(pair);
1593 
1594 	switch (nvpair_type(pair)) {
1595 	case DATA_TYPE_UINT64: {
1596 		uint64_t srchval, theguid, present;
1597 
1598 		verify(nvpair_value_uint64(pair, &srchval) == 0);
1599 		if (strcmp(srchkey, ZPOOL_CONFIG_GUID) == 0) {
1600 			if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_NOT_PRESENT,
1601 			    &present) == 0) {
1602 				/*
1603 				 * If the device has never been present since
1604 				 * import, the only reliable way to match the
1605 				 * vdev is by GUID.
1606 				 */
1607 				verify(nvlist_lookup_uint64(nv,
1608 				    ZPOOL_CONFIG_GUID, &theguid) == 0);
1609 				if (theguid == srchval)
1610 					return (nv);
1611 			}
1612 		}
1613 		break;
1614 	}
1615 
1616 	case DATA_TYPE_STRING: {
1617 		char *srchval, *val;
1618 
1619 		verify(nvpair_value_string(pair, &srchval) == 0);
1620 		if (nvlist_lookup_string(nv, srchkey, &val) != 0)
1621 			break;
1622 
1623 		/*
1624 		 * Search for the requested value. We special case the search
1625 		 * for ZPOOL_CONFIG_PATH when it's a wholedisk and when
1626 		 * Looking for a top-level vdev name (i.e. ZPOOL_CONFIG_TYPE).
1627 		 * Otherwise, all other searches are simple string compares.
1628 		 */
1629 		if (strcmp(srchkey, ZPOOL_CONFIG_PATH) == 0 && val) {
1630 			uint64_t wholedisk = 0;
1631 
1632 			(void) nvlist_lookup_uint64(nv, ZPOOL_CONFIG_WHOLE_DISK,
1633 			    &wholedisk);
1634 			if (wholedisk) {
1635 				/*
1636 				 * For whole disks, the internal path has 's0',
1637 				 * but the path passed in by the user doesn't.
1638 				 */
1639 				if (strlen(srchval) == strlen(val) - 2 &&
1640 				    strncmp(srchval, val, strlen(srchval)) == 0)
1641 					return (nv);
1642 				break;
1643 			}
1644 		} else if (strcmp(srchkey, ZPOOL_CONFIG_TYPE) == 0 && val) {
1645 			char *type, *idx, *end, *p;
1646 			uint64_t id, vdev_id;
1647 
1648 			/*
1649 			 * Determine our vdev type, keeping in mind
1650 			 * that the srchval is composed of a type and
1651 			 * vdev id pair (i.e. mirror-4).
1652 			 */
1653 			if ((type = strdup(srchval)) == NULL)
1654 				return (NULL);
1655 
1656 			if ((p = strrchr(type, '-')) == NULL) {
1657 				free(type);
1658 				break;
1659 			}
1660 			idx = p + 1;
1661 			*p = '\0';
1662 
1663 			/*
1664 			 * If the types don't match then keep looking.
1665 			 */
1666 			if (strncmp(val, type, strlen(val)) != 0) {
1667 				free(type);
1668 				break;
1669 			}
1670 
1671 			verify(strncmp(type, VDEV_TYPE_RAIDZ,
1672 			    strlen(VDEV_TYPE_RAIDZ)) == 0 ||
1673 			    strncmp(type, VDEV_TYPE_MIRROR,
1674 			    strlen(VDEV_TYPE_MIRROR)) == 0);
1675 			verify(nvlist_lookup_uint64(nv, ZPOOL_CONFIG_ID,
1676 			    &id) == 0);
1677 
1678 			errno = 0;
1679 			vdev_id = strtoull(idx, &end, 10);
1680 
1681 			free(type);
1682 			if (errno != 0)
1683 				return (NULL);
1684 
1685 			/*
1686 			 * Now verify that we have the correct vdev id.
1687 			 */
1688 			if (vdev_id == id)
1689 				return (nv);
1690 		}
1691 
1692 		/*
1693 		 * Common case
1694 		 */
1695 		if (strcmp(srchval, val) == 0)
1696 			return (nv);
1697 		break;
1698 	}
1699 
1700 	default:
1701 		break;
1702 	}
1703 
1704 	if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
1705 	    &child, &children) != 0)
1706 		return (NULL);
1707 
1708 	for (c = 0; c < children; c++) {
1709 		if ((ret = vdev_to_nvlist_iter(child[c], search,
1710 		    avail_spare, l2cache, NULL)) != NULL) {
1711 			/*
1712 			 * The 'is_log' value is only set for the toplevel
1713 			 * vdev, not the leaf vdevs.  So we always lookup the
1714 			 * log device from the root of the vdev tree (where
1715 			 * 'log' is non-NULL).
1716 			 */
1717 			if (log != NULL &&
1718 			    nvlist_lookup_uint64(child[c],
1719 			    ZPOOL_CONFIG_IS_LOG, &is_log) == 0 &&
1720 			    is_log) {
1721 				*log = B_TRUE;
1722 			}
1723 			return (ret);
1724 		}
1725 	}
1726 
1727 	if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_SPARES,
1728 	    &child, &children) == 0) {
1729 		for (c = 0; c < children; c++) {
1730 			if ((ret = vdev_to_nvlist_iter(child[c], search,
1731 			    avail_spare, l2cache, NULL)) != NULL) {
1732 				*avail_spare = B_TRUE;
1733 				return (ret);
1734 			}
1735 		}
1736 	}
1737 
1738 	if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_L2CACHE,
1739 	    &child, &children) == 0) {
1740 		for (c = 0; c < children; c++) {
1741 			if ((ret = vdev_to_nvlist_iter(child[c], search,
1742 			    avail_spare, l2cache, NULL)) != NULL) {
1743 				*l2cache = B_TRUE;
1744 				return (ret);
1745 			}
1746 		}
1747 	}
1748 
1749 	return (NULL);
1750 }
1751 
1752 /*
1753  * Given a physical path (minus the "/devices" prefix), find the
1754  * associated vdev.
1755  */
1756 nvlist_t *
1757 zpool_find_vdev_by_physpath(zpool_handle_t *zhp, const char *ppath,
1758     boolean_t *avail_spare, boolean_t *l2cache, boolean_t *log)
1759 {
1760 	nvlist_t *search, *nvroot, *ret;
1761 
1762 	verify(nvlist_alloc(&search, NV_UNIQUE_NAME, KM_SLEEP) == 0);
1763 	verify(nvlist_add_string(search, ZPOOL_CONFIG_PHYS_PATH, ppath) == 0);
1764 
1765 	verify(nvlist_lookup_nvlist(zhp->zpool_config, ZPOOL_CONFIG_VDEV_TREE,
1766 	    &nvroot) == 0);
1767 
1768 	*avail_spare = B_FALSE;
1769 	ret = vdev_to_nvlist_iter(nvroot, search, avail_spare, l2cache, log);
1770 	nvlist_free(search);
1771 
1772 	return (ret);
1773 }
1774 
1775 /*
1776  * Determine if we have an "interior" top-level vdev (i.e mirror/raidz).
1777  */
1778 boolean_t
1779 zpool_vdev_is_interior(const char *name)
1780 {
1781 	if (strncmp(name, VDEV_TYPE_RAIDZ, strlen(VDEV_TYPE_RAIDZ)) == 0 ||
1782 	    strncmp(name, VDEV_TYPE_MIRROR, strlen(VDEV_TYPE_MIRROR)) == 0)
1783 		return (B_TRUE);
1784 	return (B_FALSE);
1785 }
1786 
1787 nvlist_t *
1788 zpool_find_vdev(zpool_handle_t *zhp, const char *path, boolean_t *avail_spare,
1789     boolean_t *l2cache, boolean_t *log)
1790 {
1791 	char buf[MAXPATHLEN];
1792 	char *end;
1793 	nvlist_t *nvroot, *search, *ret;
1794 	uint64_t guid;
1795 
1796 	verify(nvlist_alloc(&search, NV_UNIQUE_NAME, KM_SLEEP) == 0);
1797 
1798 	guid = strtoull(path, &end, 10);
1799 	if (guid != 0 && *end == '\0') {
1800 		verify(nvlist_add_uint64(search, ZPOOL_CONFIG_GUID, guid) == 0);
1801 	} else if (zpool_vdev_is_interior(path)) {
1802 		verify(nvlist_add_string(search, ZPOOL_CONFIG_TYPE, path) == 0);
1803 	} else if (path[0] != '/') {
1804 		(void) snprintf(buf, sizeof (buf), "%s%s", "/dev/dsk/", path);
1805 		verify(nvlist_add_string(search, ZPOOL_CONFIG_PATH, buf) == 0);
1806 	} else {
1807 		verify(nvlist_add_string(search, ZPOOL_CONFIG_PATH, path) == 0);
1808 	}
1809 
1810 	verify(nvlist_lookup_nvlist(zhp->zpool_config, ZPOOL_CONFIG_VDEV_TREE,
1811 	    &nvroot) == 0);
1812 
1813 	*avail_spare = B_FALSE;
1814 	*l2cache = B_FALSE;
1815 	if (log != NULL)
1816 		*log = B_FALSE;
1817 	ret = vdev_to_nvlist_iter(nvroot, search, avail_spare, l2cache, log);
1818 	nvlist_free(search);
1819 
1820 	return (ret);
1821 }
1822 
1823 static int
1824 vdev_online(nvlist_t *nv)
1825 {
1826 	uint64_t ival;
1827 
1828 	if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_OFFLINE, &ival) == 0 ||
1829 	    nvlist_lookup_uint64(nv, ZPOOL_CONFIG_FAULTED, &ival) == 0 ||
1830 	    nvlist_lookup_uint64(nv, ZPOOL_CONFIG_REMOVED, &ival) == 0)
1831 		return (0);
1832 
1833 	return (1);
1834 }
1835 
1836 /*
1837  * Helper function for zpool_get_physpaths().
1838  */
1839 static int
1840 vdev_get_one_physpath(nvlist_t *config, char *physpath, size_t physpath_size,
1841     size_t *bytes_written)
1842 {
1843 	size_t bytes_left, pos, rsz;
1844 	char *tmppath;
1845 	const char *format;
1846 
1847 	if (nvlist_lookup_string(config, ZPOOL_CONFIG_PHYS_PATH,
1848 	    &tmppath) != 0)
1849 		return (EZFS_NODEVICE);
1850 
1851 	pos = *bytes_written;
1852 	bytes_left = physpath_size - pos;
1853 	format = (pos == 0) ? "%s" : " %s";
1854 
1855 	rsz = snprintf(physpath + pos, bytes_left, format, tmppath);
1856 	*bytes_written += rsz;
1857 
1858 	if (rsz >= bytes_left) {
1859 		/* if physpath was not copied properly, clear it */
1860 		if (bytes_left != 0) {
1861 			physpath[pos] = 0;
1862 		}
1863 		return (EZFS_NOSPC);
1864 	}
1865 	return (0);
1866 }
1867 
1868 static int
1869 vdev_get_physpaths(nvlist_t *nv, char *physpath, size_t phypath_size,
1870     size_t *rsz, boolean_t is_spare)
1871 {
1872 	char *type;
1873 	int ret;
1874 
1875 	if (nvlist_lookup_string(nv, ZPOOL_CONFIG_TYPE, &type) != 0)
1876 		return (EZFS_INVALCONFIG);
1877 
1878 	if (strcmp(type, VDEV_TYPE_DISK) == 0) {
1879 		/*
1880 		 * An active spare device has ZPOOL_CONFIG_IS_SPARE set.
1881 		 * For a spare vdev, we only want to boot from the active
1882 		 * spare device.
1883 		 */
1884 		if (is_spare) {
1885 			uint64_t spare = 0;
1886 			(void) nvlist_lookup_uint64(nv, ZPOOL_CONFIG_IS_SPARE,
1887 			    &spare);
1888 			if (!spare)
1889 				return (EZFS_INVALCONFIG);
1890 		}
1891 
1892 		if (vdev_online(nv)) {
1893 			if ((ret = vdev_get_one_physpath(nv, physpath,
1894 			    phypath_size, rsz)) != 0)
1895 				return (ret);
1896 		}
1897 	} else if (strcmp(type, VDEV_TYPE_MIRROR) == 0 ||
1898 	    strcmp(type, VDEV_TYPE_REPLACING) == 0 ||
1899 	    (is_spare = (strcmp(type, VDEV_TYPE_SPARE) == 0))) {
1900 		nvlist_t **child;
1901 		uint_t count;
1902 		int i, ret;
1903 
1904 		if (nvlist_lookup_nvlist_array(nv,
1905 		    ZPOOL_CONFIG_CHILDREN, &child, &count) != 0)
1906 			return (EZFS_INVALCONFIG);
1907 
1908 		for (i = 0; i < count; i++) {
1909 			ret = vdev_get_physpaths(child[i], physpath,
1910 			    phypath_size, rsz, is_spare);
1911 			if (ret == EZFS_NOSPC)
1912 				return (ret);
1913 		}
1914 	}
1915 
1916 	return (EZFS_POOL_INVALARG);
1917 }
1918 
1919 /*
1920  * Get phys_path for a root pool config.
1921  * Return 0 on success; non-zero on failure.
1922  */
1923 static int
1924 zpool_get_config_physpath(nvlist_t *config, char *physpath, size_t phypath_size)
1925 {
1926 	size_t rsz;
1927 	nvlist_t *vdev_root;
1928 	nvlist_t **child;
1929 	uint_t count;
1930 	char *type;
1931 
1932 	rsz = 0;
1933 
1934 	if (nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
1935 	    &vdev_root) != 0)
1936 		return (EZFS_INVALCONFIG);
1937 
1938 	if (nvlist_lookup_string(vdev_root, ZPOOL_CONFIG_TYPE, &type) != 0 ||
1939 	    nvlist_lookup_nvlist_array(vdev_root, ZPOOL_CONFIG_CHILDREN,
1940 	    &child, &count) != 0)
1941 		return (EZFS_INVALCONFIG);
1942 
1943 	/*
1944 	 * root pool can not have EFI labeled disks and can only have
1945 	 * a single top-level vdev.
1946 	 */
1947 	if (strcmp(type, VDEV_TYPE_ROOT) != 0 || count != 1 ||
1948 	    pool_uses_efi(vdev_root))
1949 		return (EZFS_POOL_INVALARG);
1950 
1951 	(void) vdev_get_physpaths(child[0], physpath, phypath_size, &rsz,
1952 	    B_FALSE);
1953 
1954 	/* No online devices */
1955 	if (rsz == 0)
1956 		return (EZFS_NODEVICE);
1957 
1958 	return (0);
1959 }
1960 
1961 /*
1962  * Get phys_path for a root pool
1963  * Return 0 on success; non-zero on failure.
1964  */
1965 int
1966 zpool_get_physpath(zpool_handle_t *zhp, char *physpath, size_t phypath_size)
1967 {
1968 	return (zpool_get_config_physpath(zhp->zpool_config, physpath,
1969 	    phypath_size));
1970 }
1971 
1972 /*
1973  * If the device has being dynamically expanded then we need to relabel
1974  * the disk to use the new unallocated space.
1975  */
1976 static int
1977 zpool_relabel_disk(libzfs_handle_t *hdl, const char *name)
1978 {
1979 	char path[MAXPATHLEN];
1980 	char errbuf[1024];
1981 	int fd, error;
1982 	int (*_efi_use_whole_disk)(int);
1983 
1984 	if ((_efi_use_whole_disk = (int (*)(int))dlsym(RTLD_DEFAULT,
1985 	    "efi_use_whole_disk")) == NULL)
1986 		return (-1);
1987 
1988 	(void) snprintf(path, sizeof (path), "%s/%s", RDISK_ROOT, name);
1989 
1990 	if ((fd = open(path, O_RDWR | O_NDELAY)) < 0) {
1991 		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "cannot "
1992 		    "relabel '%s': unable to open device"), name);
1993 		return (zfs_error(hdl, EZFS_OPENFAILED, errbuf));
1994 	}
1995 
1996 	/*
1997 	 * It's possible that we might encounter an error if the device
1998 	 * does not have any unallocated space left. If so, we simply
1999 	 * ignore that error and continue on.
2000 	 */
2001 	error = _efi_use_whole_disk(fd);
2002 	(void) close(fd);
2003 	if (error && error != VT_ENOSPC) {
2004 		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "cannot "
2005 		    "relabel '%s': unable to read disk capacity"), name);
2006 		return (zfs_error(hdl, EZFS_NOCAP, errbuf));
2007 	}
2008 	return (0);
2009 }
2010 
2011 /*
2012  * Bring the specified vdev online.   The 'flags' parameter is a set of the
2013  * ZFS_ONLINE_* flags.
2014  */
2015 int
2016 zpool_vdev_online(zpool_handle_t *zhp, const char *path, int flags,
2017     vdev_state_t *newstate)
2018 {
2019 	zfs_cmd_t zc = { 0 };
2020 	char msg[1024];
2021 	nvlist_t *tgt;
2022 	boolean_t avail_spare, l2cache, islog;
2023 	libzfs_handle_t *hdl = zhp->zpool_hdl;
2024 
2025 	if (flags & ZFS_ONLINE_EXPAND) {
2026 		(void) snprintf(msg, sizeof (msg),
2027 		    dgettext(TEXT_DOMAIN, "cannot expand %s"), path);
2028 	} else {
2029 		(void) snprintf(msg, sizeof (msg),
2030 		    dgettext(TEXT_DOMAIN, "cannot online %s"), path);
2031 	}
2032 
2033 	(void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
2034 	if ((tgt = zpool_find_vdev(zhp, path, &avail_spare, &l2cache,
2035 	    &islog)) == NULL)
2036 		return (zfs_error(hdl, EZFS_NODEVICE, msg));
2037 
2038 	verify(nvlist_lookup_uint64(tgt, ZPOOL_CONFIG_GUID, &zc.zc_guid) == 0);
2039 
2040 	if (avail_spare)
2041 		return (zfs_error(hdl, EZFS_ISSPARE, msg));
2042 
2043 	if (flags & ZFS_ONLINE_EXPAND ||
2044 	    zpool_get_prop_int(zhp, ZPOOL_PROP_AUTOEXPAND, NULL)) {
2045 		char *pathname = NULL;
2046 		uint64_t wholedisk = 0;
2047 
2048 		(void) nvlist_lookup_uint64(tgt, ZPOOL_CONFIG_WHOLE_DISK,
2049 		    &wholedisk);
2050 		verify(nvlist_lookup_string(tgt, ZPOOL_CONFIG_PATH,
2051 		    &pathname) == 0);
2052 
2053 		/*
2054 		 * XXX - L2ARC 1.0 devices can't support expansion.
2055 		 */
2056 		if (l2cache) {
2057 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
2058 			    "cannot expand cache devices"));
2059 			return (zfs_error(hdl, EZFS_VDEVNOTSUP, msg));
2060 		}
2061 
2062 		if (wholedisk) {
2063 			pathname += strlen(DISK_ROOT) + 1;
2064 			(void) zpool_relabel_disk(zhp->zpool_hdl, pathname);
2065 		}
2066 	}
2067 
2068 	zc.zc_cookie = VDEV_STATE_ONLINE;
2069 	zc.zc_obj = flags;
2070 
2071 	if (zfs_ioctl(zhp->zpool_hdl, ZFS_IOC_VDEV_SET_STATE, &zc) != 0)
2072 		return (zpool_standard_error(hdl, errno, msg));
2073 
2074 	*newstate = zc.zc_cookie;
2075 	return (0);
2076 }
2077 
2078 /*
2079  * Take the specified vdev offline
2080  */
2081 int
2082 zpool_vdev_offline(zpool_handle_t *zhp, const char *path, boolean_t istmp)
2083 {
2084 	zfs_cmd_t zc = { 0 };
2085 	char msg[1024];
2086 	nvlist_t *tgt;
2087 	boolean_t avail_spare, l2cache;
2088 	libzfs_handle_t *hdl = zhp->zpool_hdl;
2089 
2090 	(void) snprintf(msg, sizeof (msg),
2091 	    dgettext(TEXT_DOMAIN, "cannot offline %s"), path);
2092 
2093 	(void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
2094 	if ((tgt = zpool_find_vdev(zhp, path, &avail_spare, &l2cache,
2095 	    NULL)) == NULL)
2096 		return (zfs_error(hdl, EZFS_NODEVICE, msg));
2097 
2098 	verify(nvlist_lookup_uint64(tgt, ZPOOL_CONFIG_GUID, &zc.zc_guid) == 0);
2099 
2100 	if (avail_spare)
2101 		return (zfs_error(hdl, EZFS_ISSPARE, msg));
2102 
2103 	zc.zc_cookie = VDEV_STATE_OFFLINE;
2104 	zc.zc_obj = istmp ? ZFS_OFFLINE_TEMPORARY : 0;
2105 
2106 	if (zfs_ioctl(zhp->zpool_hdl, ZFS_IOC_VDEV_SET_STATE, &zc) == 0)
2107 		return (0);
2108 
2109 	switch (errno) {
2110 	case EBUSY:
2111 
2112 		/*
2113 		 * There are no other replicas of this device.
2114 		 */
2115 		return (zfs_error(hdl, EZFS_NOREPLICAS, msg));
2116 
2117 	case EEXIST:
2118 		/*
2119 		 * The log device has unplayed logs
2120 		 */
2121 		return (zfs_error(hdl, EZFS_UNPLAYED_LOGS, msg));
2122 
2123 	default:
2124 		return (zpool_standard_error(hdl, errno, msg));
2125 	}
2126 }
2127 
2128 /*
2129  * Mark the given vdev faulted.
2130  */
2131 int
2132 zpool_vdev_fault(zpool_handle_t *zhp, uint64_t guid, vdev_aux_t aux)
2133 {
2134 	zfs_cmd_t zc = { 0 };
2135 	char msg[1024];
2136 	libzfs_handle_t *hdl = zhp->zpool_hdl;
2137 
2138 	(void) snprintf(msg, sizeof (msg),
2139 	    dgettext(TEXT_DOMAIN, "cannot fault %llu"), guid);
2140 
2141 	(void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
2142 	zc.zc_guid = guid;
2143 	zc.zc_cookie = VDEV_STATE_FAULTED;
2144 	zc.zc_obj = aux;
2145 
2146 	if (ioctl(zhp->zpool_hdl->libzfs_fd, ZFS_IOC_VDEV_SET_STATE, &zc) == 0)
2147 		return (0);
2148 
2149 	switch (errno) {
2150 	case EBUSY:
2151 
2152 		/*
2153 		 * There are no other replicas of this device.
2154 		 */
2155 		return (zfs_error(hdl, EZFS_NOREPLICAS, msg));
2156 
2157 	default:
2158 		return (zpool_standard_error(hdl, errno, msg));
2159 	}
2160 
2161 }
2162 
2163 /*
2164  * Mark the given vdev degraded.
2165  */
2166 int
2167 zpool_vdev_degrade(zpool_handle_t *zhp, uint64_t guid, vdev_aux_t aux)
2168 {
2169 	zfs_cmd_t zc = { 0 };
2170 	char msg[1024];
2171 	libzfs_handle_t *hdl = zhp->zpool_hdl;
2172 
2173 	(void) snprintf(msg, sizeof (msg),
2174 	    dgettext(TEXT_DOMAIN, "cannot degrade %llu"), guid);
2175 
2176 	(void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
2177 	zc.zc_guid = guid;
2178 	zc.zc_cookie = VDEV_STATE_DEGRADED;
2179 	zc.zc_obj = aux;
2180 
2181 	if (ioctl(zhp->zpool_hdl->libzfs_fd, ZFS_IOC_VDEV_SET_STATE, &zc) == 0)
2182 		return (0);
2183 
2184 	return (zpool_standard_error(hdl, errno, msg));
2185 }
2186 
2187 /*
2188  * Returns TRUE if the given nvlist is a vdev that was originally swapped in as
2189  * a hot spare.
2190  */
2191 static boolean_t
2192 is_replacing_spare(nvlist_t *search, nvlist_t *tgt, int which)
2193 {
2194 	nvlist_t **child;
2195 	uint_t c, children;
2196 	char *type;
2197 
2198 	if (nvlist_lookup_nvlist_array(search, ZPOOL_CONFIG_CHILDREN, &child,
2199 	    &children) == 0) {
2200 		verify(nvlist_lookup_string(search, ZPOOL_CONFIG_TYPE,
2201 		    &type) == 0);
2202 
2203 		if (strcmp(type, VDEV_TYPE_SPARE) == 0 &&
2204 		    children == 2 && child[which] == tgt)
2205 			return (B_TRUE);
2206 
2207 		for (c = 0; c < children; c++)
2208 			if (is_replacing_spare(child[c], tgt, which))
2209 				return (B_TRUE);
2210 	}
2211 
2212 	return (B_FALSE);
2213 }
2214 
2215 /*
2216  * Attach new_disk (fully described by nvroot) to old_disk.
2217  * If 'replacing' is specified, the new disk will replace the old one.
2218  */
2219 int
2220 zpool_vdev_attach(zpool_handle_t *zhp,
2221     const char *old_disk, const char *new_disk, nvlist_t *nvroot, int replacing)
2222 {
2223 	zfs_cmd_t zc = { 0 };
2224 	char msg[1024];
2225 	int ret;
2226 	nvlist_t *tgt;
2227 	boolean_t avail_spare, l2cache, islog;
2228 	uint64_t val;
2229 	char *path, *newname;
2230 	nvlist_t **child;
2231 	uint_t children;
2232 	nvlist_t *config_root;
2233 	libzfs_handle_t *hdl = zhp->zpool_hdl;
2234 	boolean_t rootpool = pool_is_bootable(zhp);
2235 
2236 	if (replacing)
2237 		(void) snprintf(msg, sizeof (msg), dgettext(TEXT_DOMAIN,
2238 		    "cannot replace %s with %s"), old_disk, new_disk);
2239 	else
2240 		(void) snprintf(msg, sizeof (msg), dgettext(TEXT_DOMAIN,
2241 		    "cannot attach %s to %s"), new_disk, old_disk);
2242 
2243 	/*
2244 	 * If this is a root pool, make sure that we're not attaching an
2245 	 * EFI labeled device.
2246 	 */
2247 	if (rootpool && pool_uses_efi(nvroot)) {
2248 		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
2249 		    "EFI labeled devices are not supported on root pools."));
2250 		return (zfs_error(hdl, EZFS_POOL_NOTSUP, msg));
2251 	}
2252 
2253 	(void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
2254 	if ((tgt = zpool_find_vdev(zhp, old_disk, &avail_spare, &l2cache,
2255 	    &islog)) == 0)
2256 		return (zfs_error(hdl, EZFS_NODEVICE, msg));
2257 
2258 	if (avail_spare)
2259 		return (zfs_error(hdl, EZFS_ISSPARE, msg));
2260 
2261 	if (l2cache)
2262 		return (zfs_error(hdl, EZFS_ISL2CACHE, msg));
2263 
2264 	verify(nvlist_lookup_uint64(tgt, ZPOOL_CONFIG_GUID, &zc.zc_guid) == 0);
2265 	zc.zc_cookie = replacing;
2266 
2267 	if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_CHILDREN,
2268 	    &child, &children) != 0 || children != 1) {
2269 		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
2270 		    "new device must be a single disk"));
2271 		return (zfs_error(hdl, EZFS_INVALCONFIG, msg));
2272 	}
2273 
2274 	verify(nvlist_lookup_nvlist(zpool_get_config(zhp, NULL),
2275 	    ZPOOL_CONFIG_VDEV_TREE, &config_root) == 0);
2276 
2277 	if ((newname = zpool_vdev_name(NULL, NULL, child[0], B_FALSE)) == NULL)
2278 		return (-1);
2279 
2280 	/*
2281 	 * If the target is a hot spare that has been swapped in, we can only
2282 	 * replace it with another hot spare.
2283 	 */
2284 	if (replacing &&
2285 	    nvlist_lookup_uint64(tgt, ZPOOL_CONFIG_IS_SPARE, &val) == 0 &&
2286 	    (zpool_find_vdev(zhp, newname, &avail_spare, &l2cache,
2287 	    NULL) == NULL || !avail_spare) &&
2288 	    is_replacing_spare(config_root, tgt, 1)) {
2289 		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
2290 		    "can only be replaced by another hot spare"));
2291 		free(newname);
2292 		return (zfs_error(hdl, EZFS_BADTARGET, msg));
2293 	}
2294 
2295 	/*
2296 	 * If we are attempting to replace a spare, it canot be applied to an
2297 	 * already spared device.
2298 	 */
2299 	if (replacing &&
2300 	    nvlist_lookup_string(child[0], ZPOOL_CONFIG_PATH, &path) == 0 &&
2301 	    zpool_find_vdev(zhp, newname, &avail_spare,
2302 	    &l2cache, NULL) != NULL && avail_spare &&
2303 	    is_replacing_spare(config_root, tgt, 0)) {
2304 		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
2305 		    "device has already been replaced with a spare"));
2306 		free(newname);
2307 		return (zfs_error(hdl, EZFS_BADTARGET, msg));
2308 	}
2309 
2310 	free(newname);
2311 
2312 	if (zcmd_write_conf_nvlist(hdl, &zc, nvroot) != 0)
2313 		return (-1);
2314 
2315 	ret = zfs_ioctl(zhp->zpool_hdl, ZFS_IOC_VDEV_ATTACH, &zc);
2316 
2317 	zcmd_free_nvlists(&zc);
2318 
2319 	if (ret == 0) {
2320 		if (rootpool) {
2321 			/*
2322 			 * XXX - This should be removed once we can
2323 			 * automatically install the bootblocks on the
2324 			 * newly attached disk.
2325 			 */
2326 			(void) fprintf(stderr, dgettext(TEXT_DOMAIN, "Please "
2327 			    "be sure to invoke %s to make '%s' bootable.\n"),
2328 			    BOOTCMD, new_disk);
2329 
2330 			/*
2331 			 * XXX need a better way to prevent user from
2332 			 * booting up a half-baked vdev.
2333 			 */
2334 			(void) fprintf(stderr, dgettext(TEXT_DOMAIN, "Make "
2335 			    "sure to wait until resilver is done "
2336 			    "before rebooting.\n"));
2337 		}
2338 		return (0);
2339 	}
2340 
2341 	switch (errno) {
2342 	case ENOTSUP:
2343 		/*
2344 		 * Can't attach to or replace this type of vdev.
2345 		 */
2346 		if (replacing) {
2347 			if (islog)
2348 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
2349 				    "cannot replace a log with a spare"));
2350 			else
2351 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
2352 				    "cannot replace a replacing device"));
2353 		} else {
2354 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
2355 			    "can only attach to mirrors and top-level "
2356 			    "disks"));
2357 		}
2358 		(void) zfs_error(hdl, EZFS_BADTARGET, msg);
2359 		break;
2360 
2361 	case EINVAL:
2362 		/*
2363 		 * The new device must be a single disk.
2364 		 */
2365 		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
2366 		    "new device must be a single disk"));
2367 		(void) zfs_error(hdl, EZFS_INVALCONFIG, msg);
2368 		break;
2369 
2370 	case EBUSY:
2371 		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "%s is busy"),
2372 		    new_disk);
2373 		(void) zfs_error(hdl, EZFS_BADDEV, msg);
2374 		break;
2375 
2376 	case EOVERFLOW:
2377 		/*
2378 		 * The new device is too small.
2379 		 */
2380 		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
2381 		    "device is too small"));
2382 		(void) zfs_error(hdl, EZFS_BADDEV, msg);
2383 		break;
2384 
2385 	case EDOM:
2386 		/*
2387 		 * The new device has a different alignment requirement.
2388 		 */
2389 		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
2390 		    "devices have different sector alignment"));
2391 		(void) zfs_error(hdl, EZFS_BADDEV, msg);
2392 		break;
2393 
2394 	case ENAMETOOLONG:
2395 		/*
2396 		 * The resulting top-level vdev spec won't fit in the label.
2397 		 */
2398 		(void) zfs_error(hdl, EZFS_DEVOVERFLOW, msg);
2399 		break;
2400 
2401 	default:
2402 		(void) zpool_standard_error(hdl, errno, msg);
2403 	}
2404 
2405 	return (-1);
2406 }
2407 
2408 /*
2409  * Detach the specified device.
2410  */
2411 int
2412 zpool_vdev_detach(zpool_handle_t *zhp, const char *path)
2413 {
2414 	zfs_cmd_t zc = { 0 };
2415 	char msg[1024];
2416 	nvlist_t *tgt;
2417 	boolean_t avail_spare, l2cache;
2418 	libzfs_handle_t *hdl = zhp->zpool_hdl;
2419 
2420 	(void) snprintf(msg, sizeof (msg),
2421 	    dgettext(TEXT_DOMAIN, "cannot detach %s"), path);
2422 
2423 	(void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
2424 	if ((tgt = zpool_find_vdev(zhp, path, &avail_spare, &l2cache,
2425 	    NULL)) == 0)
2426 		return (zfs_error(hdl, EZFS_NODEVICE, msg));
2427 
2428 	if (avail_spare)
2429 		return (zfs_error(hdl, EZFS_ISSPARE, msg));
2430 
2431 	if (l2cache)
2432 		return (zfs_error(hdl, EZFS_ISL2CACHE, msg));
2433 
2434 	verify(nvlist_lookup_uint64(tgt, ZPOOL_CONFIG_GUID, &zc.zc_guid) == 0);
2435 
2436 	if (zfs_ioctl(hdl, ZFS_IOC_VDEV_DETACH, &zc) == 0)
2437 		return (0);
2438 
2439 	switch (errno) {
2440 
2441 	case ENOTSUP:
2442 		/*
2443 		 * Can't detach from this type of vdev.
2444 		 */
2445 		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "only "
2446 		    "applicable to mirror and replacing vdevs"));
2447 		(void) zfs_error(zhp->zpool_hdl, EZFS_BADTARGET, msg);
2448 		break;
2449 
2450 	case EBUSY:
2451 		/*
2452 		 * There are no other replicas of this device.
2453 		 */
2454 		(void) zfs_error(hdl, EZFS_NOREPLICAS, msg);
2455 		break;
2456 
2457 	default:
2458 		(void) zpool_standard_error(hdl, errno, msg);
2459 	}
2460 
2461 	return (-1);
2462 }
2463 
2464 /*
2465  * Remove the given device.  Currently, this is supported only for hot spares
2466  * and level 2 cache devices.
2467  */
2468 int
2469 zpool_vdev_remove(zpool_handle_t *zhp, const char *path)
2470 {
2471 	zfs_cmd_t zc = { 0 };
2472 	char msg[1024];
2473 	nvlist_t *tgt;
2474 	boolean_t avail_spare, l2cache, islog;
2475 	libzfs_handle_t *hdl = zhp->zpool_hdl;
2476 	uint64_t version;
2477 
2478 	(void) snprintf(msg, sizeof (msg),
2479 	    dgettext(TEXT_DOMAIN, "cannot remove %s"), path);
2480 
2481 	(void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
2482 	if ((tgt = zpool_find_vdev(zhp, path, &avail_spare, &l2cache,
2483 	    &islog)) == 0)
2484 		return (zfs_error(hdl, EZFS_NODEVICE, msg));
2485 	/*
2486 	 * XXX - this should just go away.
2487 	 */
2488 	if (!avail_spare && !l2cache && !islog) {
2489 		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
2490 		    "only inactive hot spares, cache, top-level, "
2491 		    "or log devices can be removed"));
2492 		return (zfs_error(hdl, EZFS_NODEVICE, msg));
2493 	}
2494 
2495 	version = zpool_get_prop_int(zhp, ZPOOL_PROP_VERSION, NULL);
2496 	if (islog && version < SPA_VERSION_HOLES) {
2497 		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
2498 		    "pool must be upgrade to support log removal"));
2499 		return (zfs_error(hdl, EZFS_BADVERSION, msg));
2500 	}
2501 
2502 	verify(nvlist_lookup_uint64(tgt, ZPOOL_CONFIG_GUID, &zc.zc_guid) == 0);
2503 
2504 	if (zfs_ioctl(hdl, ZFS_IOC_VDEV_REMOVE, &zc) == 0)
2505 		return (0);
2506 
2507 	return (zpool_standard_error(hdl, errno, msg));
2508 }
2509 
2510 /*
2511  * Clear the errors for the pool, or the particular device if specified.
2512  */
2513 int
2514 zpool_clear(zpool_handle_t *zhp, const char *path, nvlist_t *rewindnvl)
2515 {
2516 	zfs_cmd_t zc = { 0 };
2517 	char msg[1024];
2518 	nvlist_t *tgt;
2519 	zpool_rewind_policy_t policy;
2520 	boolean_t avail_spare, l2cache;
2521 	libzfs_handle_t *hdl = zhp->zpool_hdl;
2522 	nvlist_t *nvi = NULL;
2523 
2524 	if (path)
2525 		(void) snprintf(msg, sizeof (msg),
2526 		    dgettext(TEXT_DOMAIN, "cannot clear errors for %s"),
2527 		    path);
2528 	else
2529 		(void) snprintf(msg, sizeof (msg),
2530 		    dgettext(TEXT_DOMAIN, "cannot clear errors for %s"),
2531 		    zhp->zpool_name);
2532 
2533 	(void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
2534 	if (path) {
2535 		if ((tgt = zpool_find_vdev(zhp, path, &avail_spare,
2536 		    &l2cache, NULL)) == 0)
2537 			return (zfs_error(hdl, EZFS_NODEVICE, msg));
2538 
2539 		/*
2540 		 * Don't allow error clearing for hot spares.  Do allow
2541 		 * error clearing for l2cache devices.
2542 		 */
2543 		if (avail_spare)
2544 			return (zfs_error(hdl, EZFS_ISSPARE, msg));
2545 
2546 		verify(nvlist_lookup_uint64(tgt, ZPOOL_CONFIG_GUID,
2547 		    &zc.zc_guid) == 0);
2548 	}
2549 
2550 	zpool_get_rewind_policy(rewindnvl, &policy);
2551 	zc.zc_cookie = policy.zrp_request;
2552 
2553 	if (zcmd_alloc_dst_nvlist(hdl, &zc, 8192) != 0)
2554 		return (-1);
2555 
2556 	if (zcmd_write_src_nvlist(zhp->zpool_hdl, &zc, rewindnvl) != 0)
2557 		return (-1);
2558 
2559 	if (zfs_ioctl(hdl, ZFS_IOC_CLEAR, &zc) == 0 ||
2560 	    ((policy.zrp_request & ZPOOL_TRY_REWIND) &&
2561 	    errno != EPERM && errno != EACCES)) {
2562 		if (policy.zrp_request &
2563 		    (ZPOOL_DO_REWIND | ZPOOL_TRY_REWIND)) {
2564 			(void) zcmd_read_dst_nvlist(hdl, &zc, &nvi);
2565 			zpool_rewind_exclaim(hdl, zc.zc_name,
2566 			    ((policy.zrp_request & ZPOOL_TRY_REWIND) != 0),
2567 			    nvi);
2568 			nvlist_free(nvi);
2569 		}
2570 		zcmd_free_nvlists(&zc);
2571 		return (0);
2572 	}
2573 
2574 	zcmd_free_nvlists(&zc);
2575 	return (zpool_standard_error(hdl, errno, msg));
2576 }
2577 
2578 /*
2579  * Similar to zpool_clear(), but takes a GUID (used by fmd).
2580  */
2581 int
2582 zpool_vdev_clear(zpool_handle_t *zhp, uint64_t guid)
2583 {
2584 	zfs_cmd_t zc = { 0 };
2585 	char msg[1024];
2586 	libzfs_handle_t *hdl = zhp->zpool_hdl;
2587 
2588 	(void) snprintf(msg, sizeof (msg),
2589 	    dgettext(TEXT_DOMAIN, "cannot clear errors for %llx"),
2590 	    guid);
2591 
2592 	(void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
2593 	zc.zc_guid = guid;
2594 
2595 	if (ioctl(hdl->libzfs_fd, ZFS_IOC_CLEAR, &zc) == 0)
2596 		return (0);
2597 
2598 	return (zpool_standard_error(hdl, errno, msg));
2599 }
2600 
2601 /*
2602  * Convert from a devid string to a path.
2603  */
2604 static char *
2605 devid_to_path(char *devid_str)
2606 {
2607 	ddi_devid_t devid;
2608 	char *minor;
2609 	char *path;
2610 	devid_nmlist_t *list = NULL;
2611 	int ret;
2612 
2613 	if (devid_str_decode(devid_str, &devid, &minor) != 0)
2614 		return (NULL);
2615 
2616 	ret = devid_deviceid_to_nmlist("/dev", devid, minor, &list);
2617 
2618 	devid_str_free(minor);
2619 	devid_free(devid);
2620 
2621 	if (ret != 0)
2622 		return (NULL);
2623 
2624 	if ((path = strdup(list[0].devname)) == NULL)
2625 		return (NULL);
2626 
2627 	devid_free_nmlist(list);
2628 
2629 	return (path);
2630 }
2631 
2632 /*
2633  * Convert from a path to a devid string.
2634  */
2635 static char *
2636 path_to_devid(const char *path)
2637 {
2638 	int fd;
2639 	ddi_devid_t devid;
2640 	char *minor, *ret;
2641 
2642 	if ((fd = open(path, O_RDONLY)) < 0)
2643 		return (NULL);
2644 
2645 	minor = NULL;
2646 	ret = NULL;
2647 	if (devid_get(fd, &devid) == 0) {
2648 		if (devid_get_minor_name(fd, &minor) == 0)
2649 			ret = devid_str_encode(devid, minor);
2650 		if (minor != NULL)
2651 			devid_str_free(minor);
2652 		devid_free(devid);
2653 	}
2654 	(void) close(fd);
2655 
2656 	return (ret);
2657 }
2658 
2659 /*
2660  * Issue the necessary ioctl() to update the stored path value for the vdev.  We
2661  * ignore any failure here, since a common case is for an unprivileged user to
2662  * type 'zpool status', and we'll display the correct information anyway.
2663  */
2664 static void
2665 set_path(zpool_handle_t *zhp, nvlist_t *nv, const char *path)
2666 {
2667 	zfs_cmd_t zc = { 0 };
2668 
2669 	(void) strncpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
2670 	(void) strncpy(zc.zc_value, path, sizeof (zc.zc_value));
2671 	verify(nvlist_lookup_uint64(nv, ZPOOL_CONFIG_GUID,
2672 	    &zc.zc_guid) == 0);
2673 
2674 	(void) ioctl(zhp->zpool_hdl->libzfs_fd, ZFS_IOC_VDEV_SETPATH, &zc);
2675 }
2676 
2677 /*
2678  * Given a vdev, return the name to display in iostat.  If the vdev has a path,
2679  * we use that, stripping off any leading "/dev/dsk/"; if not, we use the type.
2680  * We also check if this is a whole disk, in which case we strip off the
2681  * trailing 's0' slice name.
2682  *
2683  * This routine is also responsible for identifying when disks have been
2684  * reconfigured in a new location.  The kernel will have opened the device by
2685  * devid, but the path will still refer to the old location.  To catch this, we
2686  * first do a path -> devid translation (which is fast for the common case).  If
2687  * the devid matches, we're done.  If not, we do a reverse devid -> path
2688  * translation and issue the appropriate ioctl() to update the path of the vdev.
2689  * If 'zhp' is NULL, then this is an exported pool, and we don't need to do any
2690  * of these checks.
2691  */
2692 char *
2693 zpool_vdev_name(libzfs_handle_t *hdl, zpool_handle_t *zhp, nvlist_t *nv,
2694     boolean_t verbose)
2695 {
2696 	char *path, *devid;
2697 	uint64_t value;
2698 	char buf[64];
2699 	vdev_stat_t *vs;
2700 	uint_t vsc;
2701 
2702 	if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_NOT_PRESENT,
2703 	    &value) == 0) {
2704 		verify(nvlist_lookup_uint64(nv, ZPOOL_CONFIG_GUID,
2705 		    &value) == 0);
2706 		(void) snprintf(buf, sizeof (buf), "%llu",
2707 		    (u_longlong_t)value);
2708 		path = buf;
2709 	} else if (nvlist_lookup_string(nv, ZPOOL_CONFIG_PATH, &path) == 0) {
2710 
2711 		/*
2712 		 * If the device is dead (faulted, offline, etc) then don't
2713 		 * bother opening it.  Otherwise we may be forcing the user to
2714 		 * open a misbehaving device, which can have undesirable
2715 		 * effects.
2716 		 */
2717 		if ((nvlist_lookup_uint64_array(nv, ZPOOL_CONFIG_STATS,
2718 		    (uint64_t **)&vs, &vsc) != 0 ||
2719 		    vs->vs_state >= VDEV_STATE_DEGRADED) &&
2720 		    zhp != NULL &&
2721 		    nvlist_lookup_string(nv, ZPOOL_CONFIG_DEVID, &devid) == 0) {
2722 			/*
2723 			 * Determine if the current path is correct.
2724 			 */
2725 			char *newdevid = path_to_devid(path);
2726 
2727 			if (newdevid == NULL ||
2728 			    strcmp(devid, newdevid) != 0) {
2729 				char *newpath;
2730 
2731 				if ((newpath = devid_to_path(devid)) != NULL) {
2732 					/*
2733 					 * Update the path appropriately.
2734 					 */
2735 					set_path(zhp, nv, newpath);
2736 					if (nvlist_add_string(nv,
2737 					    ZPOOL_CONFIG_PATH, newpath) == 0)
2738 						verify(nvlist_lookup_string(nv,
2739 						    ZPOOL_CONFIG_PATH,
2740 						    &path) == 0);
2741 					free(newpath);
2742 				}
2743 			}
2744 
2745 			if (newdevid)
2746 				devid_str_free(newdevid);
2747 		}
2748 
2749 		if (strncmp(path, "/dev/dsk/", 9) == 0)
2750 			path += 9;
2751 
2752 		if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_WHOLE_DISK,
2753 		    &value) == 0 && value) {
2754 			char *tmp = zfs_strdup(hdl, path);
2755 			if (tmp == NULL)
2756 				return (NULL);
2757 			tmp[strlen(path) - 2] = '\0';
2758 			return (tmp);
2759 		}
2760 	} else {
2761 		verify(nvlist_lookup_string(nv, ZPOOL_CONFIG_TYPE, &path) == 0);
2762 
2763 		/*
2764 		 * If it's a raidz device, we need to stick in the parity level.
2765 		 */
2766 		if (strcmp(path, VDEV_TYPE_RAIDZ) == 0) {
2767 			verify(nvlist_lookup_uint64(nv, ZPOOL_CONFIG_NPARITY,
2768 			    &value) == 0);
2769 			(void) snprintf(buf, sizeof (buf), "%s%llu", path,
2770 			    (u_longlong_t)value);
2771 			path = buf;
2772 		}
2773 
2774 		/*
2775 		 * We identify each top-level vdev by using a <type-id>
2776 		 * naming convention.
2777 		 */
2778 		if (verbose) {
2779 			uint64_t id;
2780 
2781 			verify(nvlist_lookup_uint64(nv, ZPOOL_CONFIG_ID,
2782 			    &id) == 0);
2783 			(void) snprintf(buf, sizeof (buf), "%s-%llu", path,
2784 			    (u_longlong_t)id);
2785 			path = buf;
2786 		}
2787 	}
2788 
2789 	return (zfs_strdup(hdl, path));
2790 }
2791 
2792 static int
2793 zbookmark_compare(const void *a, const void *b)
2794 {
2795 	return (memcmp(a, b, sizeof (zbookmark_t)));
2796 }
2797 
2798 /*
2799  * Retrieve the persistent error log, uniquify the members, and return to the
2800  * caller.
2801  */
2802 int
2803 zpool_get_errlog(zpool_handle_t *zhp, nvlist_t **nverrlistp)
2804 {
2805 	zfs_cmd_t zc = { 0 };
2806 	uint64_t count;
2807 	zbookmark_t *zb = NULL;
2808 	int i;
2809 
2810 	/*
2811 	 * Retrieve the raw error list from the kernel.  If the number of errors
2812 	 * has increased, allocate more space and continue until we get the
2813 	 * entire list.
2814 	 */
2815 	verify(nvlist_lookup_uint64(zhp->zpool_config, ZPOOL_CONFIG_ERRCOUNT,
2816 	    &count) == 0);
2817 	if (count == 0)
2818 		return (0);
2819 	if ((zc.zc_nvlist_dst = (uintptr_t)zfs_alloc(zhp->zpool_hdl,
2820 	    count * sizeof (zbookmark_t))) == (uintptr_t)NULL)
2821 		return (-1);
2822 	zc.zc_nvlist_dst_size = count;
2823 	(void) strcpy(zc.zc_name, zhp->zpool_name);
2824 	for (;;) {
2825 		if (ioctl(zhp->zpool_hdl->libzfs_fd, ZFS_IOC_ERROR_LOG,
2826 		    &zc) != 0) {
2827 			free((void *)(uintptr_t)zc.zc_nvlist_dst);
2828 			if (errno == ENOMEM) {
2829 				count = zc.zc_nvlist_dst_size;
2830 				if ((zc.zc_nvlist_dst = (uintptr_t)
2831 				    zfs_alloc(zhp->zpool_hdl, count *
2832 				    sizeof (zbookmark_t))) == (uintptr_t)NULL)
2833 					return (-1);
2834 			} else {
2835 				return (-1);
2836 			}
2837 		} else {
2838 			break;
2839 		}
2840 	}
2841 
2842 	/*
2843 	 * Sort the resulting bookmarks.  This is a little confusing due to the
2844 	 * implementation of ZFS_IOC_ERROR_LOG.  The bookmarks are copied last
2845 	 * to first, and 'zc_nvlist_dst_size' indicates the number of boomarks
2846 	 * _not_ copied as part of the process.  So we point the start of our
2847 	 * array appropriate and decrement the total number of elements.
2848 	 */
2849 	zb = ((zbookmark_t *)(uintptr_t)zc.zc_nvlist_dst) +
2850 	    zc.zc_nvlist_dst_size;
2851 	count -= zc.zc_nvlist_dst_size;
2852 
2853 	qsort(zb, count, sizeof (zbookmark_t), zbookmark_compare);
2854 
2855 	verify(nvlist_alloc(nverrlistp, 0, KM_SLEEP) == 0);
2856 
2857 	/*
2858 	 * Fill in the nverrlistp with nvlist's of dataset and object numbers.
2859 	 */
2860 	for (i = 0; i < count; i++) {
2861 		nvlist_t *nv;
2862 
2863 		/* ignoring zb_blkid and zb_level for now */
2864 		if (i > 0 && zb[i-1].zb_objset == zb[i].zb_objset &&
2865 		    zb[i-1].zb_object == zb[i].zb_object)
2866 			continue;
2867 
2868 		if (nvlist_alloc(&nv, NV_UNIQUE_NAME, KM_SLEEP) != 0)
2869 			goto nomem;
2870 		if (nvlist_add_uint64(nv, ZPOOL_ERR_DATASET,
2871 		    zb[i].zb_objset) != 0) {
2872 			nvlist_free(nv);
2873 			goto nomem;
2874 		}
2875 		if (nvlist_add_uint64(nv, ZPOOL_ERR_OBJECT,
2876 		    zb[i].zb_object) != 0) {
2877 			nvlist_free(nv);
2878 			goto nomem;
2879 		}
2880 		if (nvlist_add_nvlist(*nverrlistp, "ejk", nv) != 0) {
2881 			nvlist_free(nv);
2882 			goto nomem;
2883 		}
2884 		nvlist_free(nv);
2885 	}
2886 
2887 	free((void *)(uintptr_t)zc.zc_nvlist_dst);
2888 	return (0);
2889 
2890 nomem:
2891 	free((void *)(uintptr_t)zc.zc_nvlist_dst);
2892 	return (no_memory(zhp->zpool_hdl));
2893 }
2894 
2895 /*
2896  * Upgrade a ZFS pool to the latest on-disk version.
2897  */
2898 int
2899 zpool_upgrade(zpool_handle_t *zhp, uint64_t new_version)
2900 {
2901 	zfs_cmd_t zc = { 0 };
2902 	libzfs_handle_t *hdl = zhp->zpool_hdl;
2903 
2904 	(void) strcpy(zc.zc_name, zhp->zpool_name);
2905 	zc.zc_cookie = new_version;
2906 
2907 	if (zfs_ioctl(hdl, ZFS_IOC_POOL_UPGRADE, &zc) != 0)
2908 		return (zpool_standard_error_fmt(hdl, errno,
2909 		    dgettext(TEXT_DOMAIN, "cannot upgrade '%s'"),
2910 		    zhp->zpool_name));
2911 	return (0);
2912 }
2913 
2914 void
2915 zpool_set_history_str(const char *subcommand, int argc, char **argv,
2916     char *history_str)
2917 {
2918 	int i;
2919 
2920 	(void) strlcpy(history_str, subcommand, HIS_MAX_RECORD_LEN);
2921 	for (i = 1; i < argc; i++) {
2922 		if (strlen(history_str) + 1 + strlen(argv[i]) >
2923 		    HIS_MAX_RECORD_LEN)
2924 			break;
2925 		(void) strlcat(history_str, " ", HIS_MAX_RECORD_LEN);
2926 		(void) strlcat(history_str, argv[i], HIS_MAX_RECORD_LEN);
2927 	}
2928 }
2929 
2930 /*
2931  * Stage command history for logging.
2932  */
2933 int
2934 zpool_stage_history(libzfs_handle_t *hdl, const char *history_str)
2935 {
2936 	if (history_str == NULL)
2937 		return (EINVAL);
2938 
2939 	if (strlen(history_str) > HIS_MAX_RECORD_LEN)
2940 		return (EINVAL);
2941 
2942 	if (hdl->libzfs_log_str != NULL)
2943 		free(hdl->libzfs_log_str);
2944 
2945 	if ((hdl->libzfs_log_str = strdup(history_str)) == NULL)
2946 		return (no_memory(hdl));
2947 
2948 	return (0);
2949 }
2950 
2951 /*
2952  * Perform ioctl to get some command history of a pool.
2953  *
2954  * 'buf' is the buffer to fill up to 'len' bytes.  'off' is the
2955  * logical offset of the history buffer to start reading from.
2956  *
2957  * Upon return, 'off' is the next logical offset to read from and
2958  * 'len' is the actual amount of bytes read into 'buf'.
2959  */
2960 static int
2961 get_history(zpool_handle_t *zhp, char *buf, uint64_t *off, uint64_t *len)
2962 {
2963 	zfs_cmd_t zc = { 0 };
2964 	libzfs_handle_t *hdl = zhp->zpool_hdl;
2965 
2966 	(void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
2967 
2968 	zc.zc_history = (uint64_t)(uintptr_t)buf;
2969 	zc.zc_history_len = *len;
2970 	zc.zc_history_offset = *off;
2971 
2972 	if (ioctl(hdl->libzfs_fd, ZFS_IOC_POOL_GET_HISTORY, &zc) != 0) {
2973 		switch (errno) {
2974 		case EPERM:
2975 			return (zfs_error_fmt(hdl, EZFS_PERM,
2976 			    dgettext(TEXT_DOMAIN,
2977 			    "cannot show history for pool '%s'"),
2978 			    zhp->zpool_name));
2979 		case ENOENT:
2980 			return (zfs_error_fmt(hdl, EZFS_NOHISTORY,
2981 			    dgettext(TEXT_DOMAIN, "cannot get history for pool "
2982 			    "'%s'"), zhp->zpool_name));
2983 		case ENOTSUP:
2984 			return (zfs_error_fmt(hdl, EZFS_BADVERSION,
2985 			    dgettext(TEXT_DOMAIN, "cannot get history for pool "
2986 			    "'%s', pool must be upgraded"), zhp->zpool_name));
2987 		default:
2988 			return (zpool_standard_error_fmt(hdl, errno,
2989 			    dgettext(TEXT_DOMAIN,
2990 			    "cannot get history for '%s'"), zhp->zpool_name));
2991 		}
2992 	}
2993 
2994 	*len = zc.zc_history_len;
2995 	*off = zc.zc_history_offset;
2996 
2997 	return (0);
2998 }
2999 
3000 /*
3001  * Process the buffer of nvlists, unpacking and storing each nvlist record
3002  * into 'records'.  'leftover' is set to the number of bytes that weren't
3003  * processed as there wasn't a complete record.
3004  */
3005 int
3006 zpool_history_unpack(char *buf, uint64_t bytes_read, uint64_t *leftover,
3007     nvlist_t ***records, uint_t *numrecords)
3008 {
3009 	uint64_t reclen;
3010 	nvlist_t *nv;
3011 	int i;
3012 
3013 	while (bytes_read > sizeof (reclen)) {
3014 
3015 		/* get length of packed record (stored as little endian) */
3016 		for (i = 0, reclen = 0; i < sizeof (reclen); i++)
3017 			reclen += (uint64_t)(((uchar_t *)buf)[i]) << (8*i);
3018 
3019 		if (bytes_read < sizeof (reclen) + reclen)
3020 			break;
3021 
3022 		/* unpack record */
3023 		if (nvlist_unpack(buf + sizeof (reclen), reclen, &nv, 0) != 0)
3024 			return (ENOMEM);
3025 		bytes_read -= sizeof (reclen) + reclen;
3026 		buf += sizeof (reclen) + reclen;
3027 
3028 		/* add record to nvlist array */
3029 		(*numrecords)++;
3030 		if (ISP2(*numrecords + 1)) {
3031 			*records = realloc(*records,
3032 			    *numrecords * 2 * sizeof (nvlist_t *));
3033 		}
3034 		(*records)[*numrecords - 1] = nv;
3035 	}
3036 
3037 	*leftover = bytes_read;
3038 	return (0);
3039 }
3040 
3041 #define	HIS_BUF_LEN	(128*1024)
3042 
3043 /*
3044  * Retrieve the command history of a pool.
3045  */
3046 int
3047 zpool_get_history(zpool_handle_t *zhp, nvlist_t **nvhisp)
3048 {
3049 	char buf[HIS_BUF_LEN];
3050 	uint64_t off = 0;
3051 	nvlist_t **records = NULL;
3052 	uint_t numrecords = 0;
3053 	int err, i;
3054 
3055 	do {
3056 		uint64_t bytes_read = sizeof (buf);
3057 		uint64_t leftover;
3058 
3059 		if ((err = get_history(zhp, buf, &off, &bytes_read)) != 0)
3060 			break;
3061 
3062 		/* if nothing else was read in, we're at EOF, just return */
3063 		if (!bytes_read)
3064 			break;
3065 
3066 		if ((err = zpool_history_unpack(buf, bytes_read,
3067 		    &leftover, &records, &numrecords)) != 0)
3068 			break;
3069 		off -= leftover;
3070 
3071 		/* CONSTCOND */
3072 	} while (1);
3073 
3074 	if (!err) {
3075 		verify(nvlist_alloc(nvhisp, NV_UNIQUE_NAME, 0) == 0);
3076 		verify(nvlist_add_nvlist_array(*nvhisp, ZPOOL_HIST_RECORD,
3077 		    records, numrecords) == 0);
3078 	}
3079 	for (i = 0; i < numrecords; i++)
3080 		nvlist_free(records[i]);
3081 	free(records);
3082 
3083 	return (err);
3084 }
3085 
3086 void
3087 zpool_obj_to_path(zpool_handle_t *zhp, uint64_t dsobj, uint64_t obj,
3088     char *pathname, size_t len)
3089 {
3090 	zfs_cmd_t zc = { 0 };
3091 	boolean_t mounted = B_FALSE;
3092 	char *mntpnt = NULL;
3093 	char dsname[MAXNAMELEN];
3094 
3095 	if (dsobj == 0) {
3096 		/* special case for the MOS */
3097 		(void) snprintf(pathname, len, "<metadata>:<0x%llx>", obj);
3098 		return;
3099 	}
3100 
3101 	/* get the dataset's name */
3102 	(void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
3103 	zc.zc_obj = dsobj;
3104 	if (ioctl(zhp->zpool_hdl->libzfs_fd,
3105 	    ZFS_IOC_DSOBJ_TO_DSNAME, &zc) != 0) {
3106 		/* just write out a path of two object numbers */
3107 		(void) snprintf(pathname, len, "<0x%llx>:<0x%llx>",
3108 		    dsobj, obj);
3109 		return;
3110 	}
3111 	(void) strlcpy(dsname, zc.zc_value, sizeof (dsname));
3112 
3113 	/* find out if the dataset is mounted */
3114 	mounted = is_mounted(zhp->zpool_hdl, dsname, &mntpnt);
3115 
3116 	/* get the corrupted object's path */
3117 	(void) strlcpy(zc.zc_name, dsname, sizeof (zc.zc_name));
3118 	zc.zc_obj = obj;
3119 	if (ioctl(zhp->zpool_hdl->libzfs_fd, ZFS_IOC_OBJ_TO_PATH,
3120 	    &zc) == 0) {
3121 		if (mounted) {
3122 			(void) snprintf(pathname, len, "%s%s", mntpnt,
3123 			    zc.zc_value);
3124 		} else {
3125 			(void) snprintf(pathname, len, "%s:%s",
3126 			    dsname, zc.zc_value);
3127 		}
3128 	} else {
3129 		(void) snprintf(pathname, len, "%s:<0x%llx>", dsname, obj);
3130 	}
3131 	free(mntpnt);
3132 }
3133 
3134 /*
3135  * Read the EFI label from the config, if a label does not exist then
3136  * pass back the error to the caller. If the caller has passed a non-NULL
3137  * diskaddr argument then we set it to the starting address of the EFI
3138  * partition.
3139  */
3140 static int
3141 read_efi_label(nvlist_t *config, diskaddr_t *sb)
3142 {
3143 	char *path;
3144 	int fd;
3145 	char diskname[MAXPATHLEN];
3146 	int err = -1;
3147 
3148 	if (nvlist_lookup_string(config, ZPOOL_CONFIG_PATH, &path) != 0)
3149 		return (err);
3150 
3151 	(void) snprintf(diskname, sizeof (diskname), "%s%s", RDISK_ROOT,
3152 	    strrchr(path, '/'));
3153 	if ((fd = open(diskname, O_RDONLY|O_NDELAY)) >= 0) {
3154 		struct dk_gpt *vtoc;
3155 
3156 		if ((err = efi_alloc_and_read(fd, &vtoc)) >= 0) {
3157 			if (sb != NULL)
3158 				*sb = vtoc->efi_parts[0].p_start;
3159 			efi_free(vtoc);
3160 		}
3161 		(void) close(fd);
3162 	}
3163 	return (err);
3164 }
3165 
3166 /*
3167  * determine where a partition starts on a disk in the current
3168  * configuration
3169  */
3170 static diskaddr_t
3171 find_start_block(nvlist_t *config)
3172 {
3173 	nvlist_t **child;
3174 	uint_t c, children;
3175 	diskaddr_t sb = MAXOFFSET_T;
3176 	uint64_t wholedisk;
3177 
3178 	if (nvlist_lookup_nvlist_array(config,
3179 	    ZPOOL_CONFIG_CHILDREN, &child, &children) != 0) {
3180 		if (nvlist_lookup_uint64(config,
3181 		    ZPOOL_CONFIG_WHOLE_DISK,
3182 		    &wholedisk) != 0 || !wholedisk) {
3183 			return (MAXOFFSET_T);
3184 		}
3185 		if (read_efi_label(config, &sb) < 0)
3186 			sb = MAXOFFSET_T;
3187 		return (sb);
3188 	}
3189 
3190 	for (c = 0; c < children; c++) {
3191 		sb = find_start_block(child[c]);
3192 		if (sb != MAXOFFSET_T) {
3193 			return (sb);
3194 		}
3195 	}
3196 	return (MAXOFFSET_T);
3197 }
3198 
3199 /*
3200  * Label an individual disk.  The name provided is the short name,
3201  * stripped of any leading /dev path.
3202  */
3203 int
3204 zpool_label_disk(libzfs_handle_t *hdl, zpool_handle_t *zhp, char *name)
3205 {
3206 	char path[MAXPATHLEN];
3207 	struct dk_gpt *vtoc;
3208 	int fd;
3209 	size_t resv = EFI_MIN_RESV_SIZE;
3210 	uint64_t slice_size;
3211 	diskaddr_t start_block;
3212 	char errbuf[1024];
3213 
3214 	/* prepare an error message just in case */
3215 	(void) snprintf(errbuf, sizeof (errbuf),
3216 	    dgettext(TEXT_DOMAIN, "cannot label '%s'"), name);
3217 
3218 	if (zhp) {
3219 		nvlist_t *nvroot;
3220 
3221 		if (pool_is_bootable(zhp)) {
3222 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3223 			    "EFI labeled devices are not supported on root "
3224 			    "pools."));
3225 			return (zfs_error(hdl, EZFS_POOL_NOTSUP, errbuf));
3226 		}
3227 
3228 		verify(nvlist_lookup_nvlist(zhp->zpool_config,
3229 		    ZPOOL_CONFIG_VDEV_TREE, &nvroot) == 0);
3230 
3231 		if (zhp->zpool_start_block == 0)
3232 			start_block = find_start_block(nvroot);
3233 		else
3234 			start_block = zhp->zpool_start_block;
3235 		zhp->zpool_start_block = start_block;
3236 	} else {
3237 		/* new pool */
3238 		start_block = NEW_START_BLOCK;
3239 	}
3240 
3241 	(void) snprintf(path, sizeof (path), "%s/%s%s", RDISK_ROOT, name,
3242 	    BACKUP_SLICE);
3243 
3244 	if ((fd = open(path, O_RDWR | O_NDELAY)) < 0) {
3245 		/*
3246 		 * This shouldn't happen.  We've long since verified that this
3247 		 * is a valid device.
3248 		 */
3249 		zfs_error_aux(hdl,
3250 		    dgettext(TEXT_DOMAIN, "unable to open device"));
3251 		return (zfs_error(hdl, EZFS_OPENFAILED, errbuf));
3252 	}
3253 
3254 	if (efi_alloc_and_init(fd, EFI_NUMPAR, &vtoc) != 0) {
3255 		/*
3256 		 * The only way this can fail is if we run out of memory, or we
3257 		 * were unable to read the disk's capacity
3258 		 */
3259 		if (errno == ENOMEM)
3260 			(void) no_memory(hdl);
3261 
3262 		(void) close(fd);
3263 		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3264 		    "unable to read disk capacity"), name);
3265 
3266 		return (zfs_error(hdl, EZFS_NOCAP, errbuf));
3267 	}
3268 
3269 	slice_size = vtoc->efi_last_u_lba + 1;
3270 	slice_size -= EFI_MIN_RESV_SIZE;
3271 	if (start_block == MAXOFFSET_T)
3272 		start_block = NEW_START_BLOCK;
3273 	slice_size -= start_block;
3274 
3275 	vtoc->efi_parts[0].p_start = start_block;
3276 	vtoc->efi_parts[0].p_size = slice_size;
3277 
3278 	/*
3279 	 * Why we use V_USR: V_BACKUP confuses users, and is considered
3280 	 * disposable by some EFI utilities (since EFI doesn't have a backup
3281 	 * slice).  V_UNASSIGNED is supposed to be used only for zero size
3282 	 * partitions, and efi_write() will fail if we use it.  V_ROOT, V_BOOT,
3283 	 * etc. were all pretty specific.  V_USR is as close to reality as we
3284 	 * can get, in the absence of V_OTHER.
3285 	 */
3286 	vtoc->efi_parts[0].p_tag = V_USR;
3287 	(void) strcpy(vtoc->efi_parts[0].p_name, "zfs");
3288 
3289 	vtoc->efi_parts[8].p_start = slice_size + start_block;
3290 	vtoc->efi_parts[8].p_size = resv;
3291 	vtoc->efi_parts[8].p_tag = V_RESERVED;
3292 
3293 	if (efi_write(fd, vtoc) != 0) {
3294 		/*
3295 		 * Some block drivers (like pcata) may not support EFI
3296 		 * GPT labels.  Print out a helpful error message dir-
3297 		 * ecting the user to manually label the disk and give
3298 		 * a specific slice.
3299 		 */
3300 		(void) close(fd);
3301 		efi_free(vtoc);
3302 
3303 		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3304 		    "try using fdisk(1M) and then provide a specific slice"));
3305 		return (zfs_error(hdl, EZFS_LABELFAILED, errbuf));
3306 	}
3307 
3308 	(void) close(fd);
3309 	efi_free(vtoc);
3310 	return (0);
3311 }
3312 
3313 static boolean_t
3314 supported_dump_vdev_type(libzfs_handle_t *hdl, nvlist_t *config, char *errbuf)
3315 {
3316 	char *type;
3317 	nvlist_t **child;
3318 	uint_t children, c;
3319 
3320 	verify(nvlist_lookup_string(config, ZPOOL_CONFIG_TYPE, &type) == 0);
3321 	if (strcmp(type, VDEV_TYPE_RAIDZ) == 0 ||
3322 	    strcmp(type, VDEV_TYPE_FILE) == 0 ||
3323 	    strcmp(type, VDEV_TYPE_LOG) == 0 ||
3324 	    strcmp(type, VDEV_TYPE_HOLE) == 0 ||
3325 	    strcmp(type, VDEV_TYPE_MISSING) == 0) {
3326 		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3327 		    "vdev type '%s' is not supported"), type);
3328 		(void) zfs_error(hdl, EZFS_VDEVNOTSUP, errbuf);
3329 		return (B_FALSE);
3330 	}
3331 	if (nvlist_lookup_nvlist_array(config, ZPOOL_CONFIG_CHILDREN,
3332 	    &child, &children) == 0) {
3333 		for (c = 0; c < children; c++) {
3334 			if (!supported_dump_vdev_type(hdl, child[c], errbuf))
3335 				return (B_FALSE);
3336 		}
3337 	}
3338 	return (B_TRUE);
3339 }
3340 
3341 /*
3342  * check if this zvol is allowable for use as a dump device; zero if
3343  * it is, > 0 if it isn't, < 0 if it isn't a zvol
3344  */
3345 int
3346 zvol_check_dump_config(char *arg)
3347 {
3348 	zpool_handle_t *zhp = NULL;
3349 	nvlist_t *config, *nvroot;
3350 	char *p, *volname;
3351 	nvlist_t **top;
3352 	uint_t toplevels;
3353 	libzfs_handle_t *hdl;
3354 	char errbuf[1024];
3355 	char poolname[ZPOOL_MAXNAMELEN];
3356 	int pathlen = strlen(ZVOL_FULL_DEV_DIR);
3357 	int ret = 1;
3358 
3359 	if (strncmp(arg, ZVOL_FULL_DEV_DIR, pathlen)) {
3360 		return (-1);
3361 	}
3362 
3363 	(void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
3364 	    "dump is not supported on device '%s'"), arg);
3365 
3366 	if ((hdl = libzfs_init()) == NULL)
3367 		return (1);
3368 	libzfs_print_on_error(hdl, B_TRUE);
3369 
3370 	volname = arg + pathlen;
3371 
3372 	/* check the configuration of the pool */
3373 	if ((p = strchr(volname, '/')) == NULL) {
3374 		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3375 		    "malformed dataset name"));
3376 		(void) zfs_error(hdl, EZFS_INVALIDNAME, errbuf);
3377 		return (1);
3378 	} else if (p - volname >= ZFS_MAXNAMELEN) {
3379 		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3380 		    "dataset name is too long"));
3381 		(void) zfs_error(hdl, EZFS_NAMETOOLONG, errbuf);
3382 		return (1);
3383 	} else {
3384 		(void) strncpy(poolname, volname, p - volname);
3385 		poolname[p - volname] = '\0';
3386 	}
3387 
3388 	if ((zhp = zpool_open(hdl, poolname)) == NULL) {
3389 		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3390 		    "could not open pool '%s'"), poolname);
3391 		(void) zfs_error(hdl, EZFS_OPENFAILED, errbuf);
3392 		goto out;
3393 	}
3394 	config = zpool_get_config(zhp, NULL);
3395 	if (nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
3396 	    &nvroot) != 0) {
3397 		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3398 		    "could not obtain vdev configuration for  '%s'"), poolname);
3399 		(void) zfs_error(hdl, EZFS_INVALCONFIG, errbuf);
3400 		goto out;
3401 	}
3402 
3403 	verify(nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_CHILDREN,
3404 	    &top, &toplevels) == 0);
3405 	if (toplevels != 1) {
3406 		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3407 		    "'%s' has multiple top level vdevs"), poolname);
3408 		(void) zfs_error(hdl, EZFS_DEVOVERFLOW, errbuf);
3409 		goto out;
3410 	}
3411 
3412 	if (!supported_dump_vdev_type(hdl, top[0], errbuf)) {
3413 		goto out;
3414 	}
3415 	ret = 0;
3416 
3417 out:
3418 	if (zhp)
3419 		zpool_close(zhp);
3420 	libzfs_fini(hdl);
3421 	return (ret);
3422 }
3423