xref: /freebsd/sys/contrib/openzfs/lib/libzfs/libzfs_pool.c (revision fc6ed8627222a625a700e99cdfcda19654a0c651)
1 // SPDX-License-Identifier: CDDL-1.0
2 /*
3  * This file and its contents are supplied under the terms of the
4  * Common Development and Distribution License ("CDDL"), version 1.0.
5  * You may only use this file in accordance with the terms of version
6  * 1.0 of the CDDL.
7  *
8  * A full copy of the text of the CDDL should have accompanied this
9  * source.  A copy of the CDDL is also available via the Internet at
10  * https://opensource.org/license/CDDL-1.0.
11  */
12 
13 /*
14  * Copyright 2015 Nexenta Systems, Inc.  All rights reserved.
15  * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
16  * Copyright (c) 2011, 2024 by Delphix. All rights reserved.
17  * Copyright 2016 Igor Kozhukhov <ikozhukhov@gmail.com>
18  * Copyright (c) 2018 Datto Inc.
19  * Copyright (c) 2017 Open-E, Inc. All Rights Reserved.
20  * Copyright (c) 2017, Intel Corporation.
21  * Copyright (c) 2018, loli10K <ezomori.nozomu@gmail.com>
22  * Copyright (c) 2021, Colm Buckley <colm@tuatha.org>
23  * Copyright (c) 2021, 2023-2026, Klara, Inc.
24  * Copyright (c) 2025 Hewlett Packard Enterprise Development LP.
25  * Copyright (c) 2026, TrueNAS.
26  */
27 
28 #include <errno.h>
29 #include <libintl.h>
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include <strings.h>
33 #include <unistd.h>
34 #include <libgen.h>
35 #include <zone.h>
36 #include <sys/stat.h>
37 #include <sys/efi_partition.h>
38 #include <sys/range_tree.h>
39 #include <sys/systeminfo.h>
40 #include <sys/zfs_ioctl.h>
41 #include <sys/zfs_sysfs.h>
42 #include <sys/vdev_disk.h>
43 #include <sys/types.h>
44 #include <dlfcn.h>
45 #include <libzutil.h>
46 #include <fcntl.h>
47 
48 #include "zfs_namecheck.h"
49 #include "zfs_prop.h"
50 #include "libzfs_impl.h"
51 #include "zfs_comutil.h"
52 #include "zfeature_common.h"
53 
54 static boolean_t zpool_vdev_is_interior(const char *name);
55 static nvlist_t *zpool_get_extended_objset_stat(zpool_handle_t *zhp,
56     uint64_t dsobj, uint64_t obj);
57 
58 static nvlist_t *
59 zpool_get_extended_obj_stat(zpool_handle_t *zhp, uint64_t dsobj, uint64_t obj);
60 
61 typedef struct prop_flags {
62 	unsigned int create:1;	/* Validate property on creation */
63 	unsigned int import:1;	/* Validate property on import */
64 	unsigned int vdevprop:1; /* Validate property as a VDEV property */
65 } prop_flags_t;
66 
67 /*
68  * ====================================================================
69  *   zpool property functions
70  * ====================================================================
71  */
72 
73 static int
74 zpool_get_all_props(zpool_handle_t *zhp)
75 {
76 	zfs_cmd_t zc = {"\0"};
77 	libzfs_handle_t *hdl = zhp->zpool_hdl;
78 
79 	(void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
80 
81 	if (zhp->zpool_n_propnames > 0) {
82 		nvlist_t *innvl = fnvlist_alloc();
83 		fnvlist_add_string_array(innvl, ZPOOL_GET_PROPS_NAMES,
84 		    zhp->zpool_propnames, zhp->zpool_n_propnames);
85 		zcmd_write_src_nvlist(hdl, &zc, innvl);
86 		fnvlist_free(innvl);
87 	}
88 
89 	zcmd_alloc_dst_nvlist(hdl, &zc, 0);
90 
91 	while (zfs_ioctl(hdl, ZFS_IOC_POOL_GET_PROPS, &zc) != 0) {
92 		if (errno == ENOMEM)
93 			zcmd_expand_dst_nvlist(hdl, &zc);
94 		else {
95 			zcmd_free_nvlists(&zc);
96 			return (-1);
97 		}
98 	}
99 
100 	if (zcmd_read_dst_nvlist(hdl, &zc, &zhp->zpool_props) != 0) {
101 		zcmd_free_nvlists(&zc);
102 		return (-1);
103 	}
104 
105 	zcmd_free_nvlists(&zc);
106 
107 	return (0);
108 }
109 
110 int
111 zpool_props_refresh(zpool_handle_t *zhp)
112 {
113 	nvlist_t *old_props;
114 
115 	old_props = zhp->zpool_props;
116 
117 	if (zpool_get_all_props(zhp) != 0)
118 		return (-1);
119 
120 	nvlist_free(old_props);
121 	return (0);
122 }
123 
124 static const char *
125 zpool_get_prop_string(zpool_handle_t *zhp, zpool_prop_t prop,
126     zprop_source_t *src)
127 {
128 	nvlist_t *nv, *nvl;
129 	const char *value;
130 	zprop_source_t source;
131 
132 	nvl = zhp->zpool_props;
133 	if (nvlist_lookup_nvlist(nvl, zpool_prop_to_name(prop), &nv) == 0) {
134 		source = fnvlist_lookup_uint64(nv, ZPROP_SOURCE);
135 		value = fnvlist_lookup_string(nv, ZPROP_VALUE);
136 	} else {
137 		source = ZPROP_SRC_DEFAULT;
138 		if ((value = zpool_prop_default_string(prop)) == NULL)
139 			value = "-";
140 	}
141 
142 	if (src)
143 		*src = source;
144 
145 	return (value);
146 }
147 
148 uint64_t
149 zpool_get_prop_int(zpool_handle_t *zhp, zpool_prop_t prop, zprop_source_t *src)
150 {
151 	nvlist_t *nv, *nvl;
152 	uint64_t value;
153 	zprop_source_t source;
154 
155 	if (zhp->zpool_props == NULL && zpool_get_all_props(zhp)) {
156 		/*
157 		 * zpool_get_all_props() has most likely failed because
158 		 * the pool is faulted, but if all we need is the top level
159 		 * vdev's guid then get it from the zhp config nvlist.
160 		 */
161 		if ((prop == ZPOOL_PROP_GUID) &&
162 		    (nvlist_lookup_nvlist(zhp->zpool_config,
163 		    ZPOOL_CONFIG_VDEV_TREE, &nv) == 0) &&
164 		    (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_GUID, &value)
165 		    == 0)) {
166 			return (value);
167 		}
168 		return (zpool_prop_default_numeric(prop));
169 	}
170 
171 	nvl = zhp->zpool_props;
172 	if (nvlist_lookup_nvlist(nvl, zpool_prop_to_name(prop), &nv) == 0) {
173 		source = fnvlist_lookup_uint64(nv, ZPROP_SOURCE);
174 		value = fnvlist_lookup_uint64(nv, ZPROP_VALUE);
175 	} else {
176 		source = ZPROP_SRC_DEFAULT;
177 		value = zpool_prop_default_numeric(prop);
178 	}
179 
180 	if (src)
181 		*src = source;
182 
183 	return (value);
184 }
185 
186 /*
187  * Map VDEV STATE to printed strings.
188  */
189 const char *
190 zpool_state_to_name(vdev_state_t state, vdev_aux_t aux)
191 {
192 	switch (state) {
193 	case VDEV_STATE_CLOSED:
194 	case VDEV_STATE_OFFLINE:
195 		return (gettext("OFFLINE"));
196 	case VDEV_STATE_REMOVED:
197 		return (gettext("REMOVED"));
198 	case VDEV_STATE_CANT_OPEN:
199 		if (aux == VDEV_AUX_CORRUPT_DATA || aux == VDEV_AUX_BAD_LOG)
200 			return (gettext("FAULTED"));
201 		else if (aux == VDEV_AUX_SPLIT_POOL)
202 			return (gettext("SPLIT"));
203 		else
204 			return (gettext("UNAVAIL"));
205 	case VDEV_STATE_FAULTED:
206 		return (gettext("FAULTED"));
207 	case VDEV_STATE_DEGRADED:
208 		return (gettext("DEGRADED"));
209 	case VDEV_STATE_HEALTHY:
210 		return (gettext("ONLINE"));
211 
212 	default:
213 		break;
214 	}
215 
216 	return (gettext("UNKNOWN"));
217 }
218 
219 /*
220  * Map POOL STATE to printed strings.
221  */
222 const char *
223 zpool_pool_state_to_name(pool_state_t state)
224 {
225 	switch (state) {
226 	default:
227 		break;
228 	case POOL_STATE_ACTIVE:
229 		return (gettext("ACTIVE"));
230 	case POOL_STATE_EXPORTED:
231 		return (gettext("EXPORTED"));
232 	case POOL_STATE_DESTROYED:
233 		return (gettext("DESTROYED"));
234 	case POOL_STATE_SPARE:
235 		return (gettext("SPARE"));
236 	case POOL_STATE_L2CACHE:
237 		return (gettext("L2CACHE"));
238 	case POOL_STATE_UNINITIALIZED:
239 		return (gettext("UNINITIALIZED"));
240 	case POOL_STATE_UNAVAIL:
241 		return (gettext("UNAVAIL"));
242 	case POOL_STATE_POTENTIALLY_ACTIVE:
243 		return (gettext("POTENTIALLY_ACTIVE"));
244 	}
245 
246 	return (gettext("UNKNOWN"));
247 }
248 
249 /*
250  * Given a pool handle, return the pool health string ("ONLINE", "DEGRADED",
251  * "SUSPENDED", etc).
252  */
253 const char *
254 zpool_get_state_str(zpool_handle_t *zhp)
255 {
256 	zpool_errata_t errata;
257 	zpool_status_t status;
258 	const char *str;
259 
260 	status = zpool_get_status(zhp, NULL, &errata);
261 
262 	if (zpool_get_state(zhp) == POOL_STATE_UNAVAIL) {
263 		str = gettext("FAULTED");
264 	} else if (status == ZPOOL_STATUS_IO_FAILURE_WAIT ||
265 	    status == ZPOOL_STATUS_IO_FAILURE_CONTINUE ||
266 	    status == ZPOOL_STATUS_IO_FAILURE_MMP) {
267 		str = gettext("SUSPENDED");
268 	} else {
269 		nvlist_t *nvroot = fnvlist_lookup_nvlist(
270 		    zpool_get_config(zhp, NULL), ZPOOL_CONFIG_VDEV_TREE);
271 		uint_t vsc;
272 		vdev_stat_t *vs = (vdev_stat_t *)fnvlist_lookup_uint64_array(
273 		    nvroot, ZPOOL_CONFIG_VDEV_STATS, &vsc);
274 		str = zpool_state_to_name(vs->vs_state, vs->vs_aux);
275 	}
276 	return (str);
277 }
278 
279 /*
280  * Get a zpool property value for 'prop' and return the value in
281  * a pre-allocated buffer.
282  */
283 int
284 zpool_get_prop(zpool_handle_t *zhp, zpool_prop_t prop, char *buf,
285     size_t len, zprop_source_t *srctype, boolean_t literal)
286 {
287 	uint64_t intval;
288 	const char *strval;
289 	zprop_source_t src = ZPROP_SRC_NONE;
290 
291 	if (zpool_get_state(zhp) == POOL_STATE_UNAVAIL) {
292 		switch (prop) {
293 		case ZPOOL_PROP_NAME:
294 			(void) strlcpy(buf, zpool_get_name(zhp), len);
295 			break;
296 
297 		case ZPOOL_PROP_HEALTH:
298 			(void) strlcpy(buf, zpool_get_state_str(zhp), len);
299 			break;
300 
301 		case ZPOOL_PROP_GUID:
302 			intval = zpool_get_prop_int(zhp, prop, &src);
303 			(void) snprintf(buf, len, "%llu", (u_longlong_t)intval);
304 			break;
305 
306 		case ZPOOL_PROP_ALTROOT:
307 		case ZPOOL_PROP_CACHEFILE:
308 		case ZPOOL_PROP_COMMENT:
309 		case ZPOOL_PROP_COMPATIBILITY:
310 			if (zhp->zpool_props != NULL ||
311 			    zpool_get_all_props(zhp) == 0) {
312 				(void) strlcpy(buf,
313 				    zpool_get_prop_string(zhp, prop, &src),
314 				    len);
315 				break;
316 			}
317 			zfs_fallthrough;
318 		default:
319 			(void) strlcpy(buf, "-", len);
320 			break;
321 		}
322 
323 		if (srctype != NULL)
324 			*srctype = src;
325 		return (0);
326 	}
327 
328 	/*
329 	 * ZPOOL_PROP_DEDUPCACHED can be fetched by name only using
330 	 * the ZPOOL_GET_PROPS_NAMES mechanism
331 	 */
332 	if (prop == ZPOOL_PROP_DEDUPCACHED) {
333 		zpool_add_propname(zhp, ZPOOL_DEDUPCACHED_PROP_NAME);
334 		(void) zpool_props_refresh(zhp);
335 	}
336 
337 	if (zhp->zpool_props == NULL && zpool_get_all_props(zhp) &&
338 	    prop != ZPOOL_PROP_NAME)
339 		return (-1);
340 
341 	switch (zpool_prop_get_type(prop)) {
342 	case PROP_TYPE_STRING:
343 		(void) strlcpy(buf, zpool_get_prop_string(zhp, prop, &src),
344 		    len);
345 		break;
346 
347 	case PROP_TYPE_NUMBER:
348 		intval = zpool_get_prop_int(zhp, prop, &src);
349 
350 		switch (prop) {
351 		case ZPOOL_PROP_DEDUP_TABLE_QUOTA:
352 			/*
353 			 * If dedup quota is 0, we translate this into 'none'
354 			 * (unless literal is set). And if it is UINT64_MAX
355 			 * we translate that as 'automatic' (limit to size of
356 			 * the dedicated dedup VDEV.  Otherwise, fall throught
357 			 * into the regular number formating.
358 			 */
359 			if (intval == 0) {
360 				(void) strlcpy(buf, literal ? "0" : "none",
361 				    len);
362 				break;
363 			} else if (intval == UINT64_MAX) {
364 				(void) strlcpy(buf, "auto", len);
365 				break;
366 			}
367 			zfs_fallthrough;
368 
369 		case ZPOOL_PROP_SIZE:
370 		case ZPOOL_PROP_NORMAL_SIZE:
371 		case ZPOOL_PROP_SPECIAL_SIZE:
372 		case ZPOOL_PROP_DEDUP_SIZE:
373 		case ZPOOL_PROP_LOG_SIZE:
374 		case ZPOOL_PROP_ELOG_SIZE:
375 		case ZPOOL_PROP_SELOG_SIZE:
376 		case ZPOOL_PROP_ALLOCATED:
377 		case ZPOOL_PROP_NORMAL_ALLOCATED:
378 		case ZPOOL_PROP_SPECIAL_ALLOCATED:
379 		case ZPOOL_PROP_DEDUP_ALLOCATED:
380 		case ZPOOL_PROP_LOG_ALLOCATED:
381 		case ZPOOL_PROP_ELOG_ALLOCATED:
382 		case ZPOOL_PROP_SELOG_ALLOCATED:
383 		case ZPOOL_PROP_AVAILABLE:
384 		case ZPOOL_PROP_NORMAL_AVAILABLE:
385 		case ZPOOL_PROP_SPECIAL_AVAILABLE:
386 		case ZPOOL_PROP_DEDUP_AVAILABLE:
387 		case ZPOOL_PROP_LOG_AVAILABLE:
388 		case ZPOOL_PROP_ELOG_AVAILABLE:
389 		case ZPOOL_PROP_SELOG_AVAILABLE:
390 		case ZPOOL_PROP_FREE:
391 		case ZPOOL_PROP_NORMAL_FREE:
392 		case ZPOOL_PROP_SPECIAL_FREE:
393 		case ZPOOL_PROP_DEDUP_FREE:
394 		case ZPOOL_PROP_LOG_FREE:
395 		case ZPOOL_PROP_ELOG_FREE:
396 		case ZPOOL_PROP_SELOG_FREE:
397 		case ZPOOL_PROP_USABLE:
398 		case ZPOOL_PROP_NORMAL_USABLE:
399 		case ZPOOL_PROP_SPECIAL_USABLE:
400 		case ZPOOL_PROP_DEDUP_USABLE:
401 		case ZPOOL_PROP_LOG_USABLE:
402 		case ZPOOL_PROP_ELOG_USABLE:
403 		case ZPOOL_PROP_SELOG_USABLE:
404 		case ZPOOL_PROP_USED:
405 		case ZPOOL_PROP_NORMAL_USED:
406 		case ZPOOL_PROP_SPECIAL_USED:
407 		case ZPOOL_PROP_DEDUP_USED:
408 		case ZPOOL_PROP_LOG_USED:
409 		case ZPOOL_PROP_ELOG_USED:
410 		case ZPOOL_PROP_SELOG_USED:
411 		case ZPOOL_PROP_FREEING:
412 		case ZPOOL_PROP_LEAKED:
413 		case ZPOOL_PROP_ASHIFT:
414 		case ZPOOL_PROP_MAXBLOCKSIZE:
415 		case ZPOOL_PROP_MAXDNODESIZE:
416 		case ZPOOL_PROP_BCLONESAVED:
417 		case ZPOOL_PROP_BCLONEUSED:
418 		case ZPOOL_PROP_DEDUP_TABLE_SIZE:
419 		case ZPOOL_PROP_DEDUPUSED:
420 		case ZPOOL_PROP_DEDUPSAVED:
421 		case ZPOOL_PROP_DEDUPCACHED:
422 			if (literal)
423 				(void) snprintf(buf, len, "%llu",
424 				    (u_longlong_t)intval);
425 			else
426 				(void) zfs_nicenum(intval, buf, len);
427 			break;
428 
429 		case ZPOOL_PROP_EXPANDSZ:
430 		case ZPOOL_PROP_NORMAL_EXPANDSZ:
431 		case ZPOOL_PROP_SPECIAL_EXPANDSZ:
432 		case ZPOOL_PROP_DEDUP_EXPANDSZ:
433 		case ZPOOL_PROP_LOG_EXPANDSZ:
434 		case ZPOOL_PROP_ELOG_EXPANDSZ:
435 		case ZPOOL_PROP_SELOG_EXPANDSZ:
436 		case ZPOOL_PROP_CHECKPOINT:
437 			if (intval == 0) {
438 				(void) strlcpy(buf, "-", len);
439 			} else if (literal) {
440 				(void) snprintf(buf, len, "%llu",
441 				    (u_longlong_t)intval);
442 			} else {
443 				(void) zfs_nicebytes(intval, buf, len);
444 			}
445 			break;
446 
447 		case ZPOOL_PROP_CAPACITY:
448 		case ZPOOL_PROP_NORMAL_CAPACITY:
449 		case ZPOOL_PROP_SPECIAL_CAPACITY:
450 		case ZPOOL_PROP_DEDUP_CAPACITY:
451 		case ZPOOL_PROP_LOG_CAPACITY:
452 		case ZPOOL_PROP_ELOG_CAPACITY:
453 		case ZPOOL_PROP_SELOG_CAPACITY:
454 			if (literal) {
455 				(void) snprintf(buf, len, "%llu",
456 				    (u_longlong_t)intval);
457 			} else {
458 				(void) snprintf(buf, len, "%llu%%",
459 				    (u_longlong_t)intval);
460 			}
461 			break;
462 
463 		case ZPOOL_PROP_FRAGMENTATION:
464 		case ZPOOL_PROP_NORMAL_FRAGMENTATION:
465 		case ZPOOL_PROP_SPECIAL_FRAGMENTATION:
466 		case ZPOOL_PROP_DEDUP_FRAGMENTATION:
467 		case ZPOOL_PROP_LOG_FRAGMENTATION:
468 		case ZPOOL_PROP_ELOG_FRAGMENTATION:
469 		case ZPOOL_PROP_SELOG_FRAGMENTATION:
470 			if (intval == ZFS_FRAG_INVALID) {
471 				(void) strlcpy(buf, "-", len);
472 			} else if (literal) {
473 				(void) snprintf(buf, len, "%llu",
474 				    (u_longlong_t)intval);
475 			} else {
476 				(void) snprintf(buf, len, "%llu%%",
477 				    (u_longlong_t)intval);
478 			}
479 			break;
480 
481 		case ZPOOL_PROP_BCLONERATIO:
482 		case ZPOOL_PROP_DEDUPRATIO:
483 			if (literal)
484 				(void) snprintf(buf, len, "%llu.%02llu",
485 				    (u_longlong_t)(intval / 100),
486 				    (u_longlong_t)(intval % 100));
487 			else
488 				(void) snprintf(buf, len, "%llu.%02llux",
489 				    (u_longlong_t)(intval / 100),
490 				    (u_longlong_t)(intval % 100));
491 			break;
492 
493 		case ZPOOL_PROP_HEALTH:
494 			(void) strlcpy(buf, zpool_get_state_str(zhp), len);
495 			break;
496 		case ZPOOL_PROP_VERSION:
497 			if (intval >= SPA_VERSION_FEATURES) {
498 				(void) snprintf(buf, len, "-");
499 				break;
500 			}
501 			zfs_fallthrough;
502 		default:
503 			(void) snprintf(buf, len, "%llu", (u_longlong_t)intval);
504 		}
505 		break;
506 
507 	case PROP_TYPE_INDEX:
508 		intval = zpool_get_prop_int(zhp, prop, &src);
509 		if (zpool_prop_index_to_string(prop, intval, &strval)
510 		    != 0)
511 			return (-1);
512 		(void) strlcpy(buf, strval, len);
513 		break;
514 
515 	default:
516 		abort();
517 	}
518 
519 	if (srctype)
520 		*srctype = src;
521 
522 	return (0);
523 }
524 
525 /*
526  * Get a zpool property value for 'propname' and return the value in
527  * a pre-allocated buffer.
528  */
529 int
530 zpool_get_userprop(zpool_handle_t *zhp, const char *propname, char *buf,
531     size_t len, zprop_source_t *srctype)
532 {
533 	nvlist_t *nv;
534 	uint64_t ival;
535 	const char *value;
536 	zprop_source_t source = ZPROP_SRC_LOCAL;
537 
538 	if (zhp->zpool_props == NULL)
539 		zpool_get_all_props(zhp);
540 
541 	if (nvlist_lookup_nvlist(zhp->zpool_props, propname, &nv) == 0) {
542 		if (nvlist_lookup_uint64(nv, ZPROP_SOURCE, &ival) == 0)
543 			source = ival;
544 		verify(nvlist_lookup_string(nv, ZPROP_VALUE, &value) == 0);
545 	} else {
546 		source = ZPROP_SRC_DEFAULT;
547 		value = "-";
548 	}
549 
550 	if (srctype)
551 		*srctype = source;
552 
553 	(void) strlcpy(buf, value, len);
554 
555 	return (0);
556 }
557 
558 /*
559  * Check if the bootfs name has the same pool name as it is set to.
560  * Assuming bootfs is a valid dataset name.
561  */
562 static boolean_t
563 bootfs_name_valid(const char *pool, const char *bootfs)
564 {
565 	int len = strlen(pool);
566 	if (bootfs[0] == '\0')
567 		return (B_TRUE);
568 
569 	if (!zfs_name_valid(bootfs, ZFS_TYPE_FILESYSTEM|ZFS_TYPE_SNAPSHOT))
570 		return (B_FALSE);
571 
572 	if (strncmp(pool, bootfs, len) == 0 &&
573 	    (bootfs[len] == '/' || bootfs[len] == '\0'))
574 		return (B_TRUE);
575 
576 	return (B_FALSE);
577 }
578 
579 /*
580  * Given an nvlist of zpool properties to be set, validate that they are
581  * correct, and parse any numeric properties (index, boolean, etc) if they are
582  * specified as strings.
583  */
584 static nvlist_t *
585 zpool_valid_proplist(libzfs_handle_t *hdl, const char *poolname,
586     nvlist_t *props, uint64_t version, prop_flags_t flags, char *errbuf)
587 {
588 	nvpair_t *elem;
589 	nvlist_t *retprops;
590 	zpool_prop_t prop;
591 	const char *strval;
592 	uint64_t intval;
593 	const char *check;
594 	struct stat64 statbuf;
595 	zpool_handle_t *zhp;
596 	char *parent, *slash;
597 	char report[1024];
598 
599 	if (nvlist_alloc(&retprops, NV_UNIQUE_NAME, 0) != 0) {
600 		(void) no_memory(hdl);
601 		return (NULL);
602 	}
603 
604 	elem = NULL;
605 	while ((elem = nvlist_next_nvpair(props, elem)) != NULL) {
606 		const char *propname = nvpair_name(elem);
607 
608 		if (flags.vdevprop && zpool_prop_vdev(propname)) {
609 			vdev_prop_t vprop = vdev_name_to_prop(propname);
610 
611 			if (vdev_prop_readonly(vprop)) {
612 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "'%s' "
613 				    "is readonly"), propname);
614 				(void) zfs_error(hdl, EZFS_PROPREADONLY,
615 				    errbuf);
616 				goto error;
617 			}
618 
619 			if (zprop_parse_value(hdl, elem, vprop, ZFS_TYPE_VDEV,
620 			    retprops, &strval, &intval, errbuf) != 0)
621 				goto error;
622 
623 			continue;
624 		} else if (flags.vdevprop && vdev_prop_user(propname)) {
625 			if (nvlist_add_nvpair(retprops, elem) != 0) {
626 				(void) no_memory(hdl);
627 				goto error;
628 			}
629 			continue;
630 		} else if (flags.vdevprop) {
631 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
632 			    "invalid property: '%s'"), propname);
633 			(void) zfs_error(hdl, EZFS_BADPROP, errbuf);
634 			goto error;
635 		}
636 
637 		prop = zpool_name_to_prop(propname);
638 		if (prop == ZPOOL_PROP_INVAL && zpool_prop_feature(propname)) {
639 			int err;
640 			const char *fname = strchr(propname, '@') + 1;
641 
642 			err = zfeature_lookup_name(fname, NULL);
643 			if (err != 0) {
644 				ASSERT3U(err, ==, ENOENT);
645 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
646 				    "feature '%s' unsupported by kernel"),
647 				    fname);
648 				(void) zfs_error(hdl, EZFS_BADPROP, errbuf);
649 				goto error;
650 			}
651 
652 			if (nvpair_type(elem) != DATA_TYPE_STRING) {
653 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
654 				    "'%s' must be a string"), propname);
655 				(void) zfs_error(hdl, EZFS_BADPROP, errbuf);
656 				goto error;
657 			}
658 
659 			(void) nvpair_value_string(elem, &strval);
660 			if (strcmp(strval, ZFS_FEATURE_ENABLED) != 0 &&
661 			    strcmp(strval, ZFS_FEATURE_DISABLED) != 0) {
662 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
663 				    "property '%s' can only be set to "
664 				    "'enabled' or 'disabled'"), propname);
665 				(void) zfs_error(hdl, EZFS_BADPROP, errbuf);
666 				goto error;
667 			}
668 
669 			if (!flags.create &&
670 			    strcmp(strval, ZFS_FEATURE_DISABLED) == 0) {
671 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
672 				    "property '%s' can only be set to "
673 				    "'disabled' at creation time"), propname);
674 				(void) zfs_error(hdl, EZFS_BADPROP, errbuf);
675 				goto error;
676 			}
677 
678 			if (nvlist_add_uint64(retprops, propname, 0) != 0) {
679 				(void) no_memory(hdl);
680 				goto error;
681 			}
682 			continue;
683 		} else if (prop == ZPOOL_PROP_INVAL &&
684 		    zfs_prop_user(propname)) {
685 			/*
686 			 * This is a user property: make sure it's a
687 			 * string, and that it's less than ZAP_MAXNAMELEN.
688 			 */
689 			if (nvpair_type(elem) != DATA_TYPE_STRING) {
690 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
691 				    "'%s' must be a string"), propname);
692 				(void) zfs_error(hdl, EZFS_BADPROP, errbuf);
693 				goto error;
694 			}
695 
696 			if (strlen(nvpair_name(elem)) >= ZAP_MAXNAMELEN) {
697 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
698 				    "property name '%s' is too long"),
699 				    propname);
700 				(void) zfs_error(hdl, EZFS_BADPROP, errbuf);
701 				goto error;
702 			}
703 
704 			(void) nvpair_value_string(elem, &strval);
705 
706 			if (strlen(strval) >= ZFS_MAXPROPLEN) {
707 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
708 				    "property value '%s' is too long"),
709 				    strval);
710 				(void) zfs_error(hdl, EZFS_BADPROP, errbuf);
711 				goto error;
712 			}
713 
714 			if (nvlist_add_string(retprops, propname,
715 			    strval) != 0) {
716 				(void) no_memory(hdl);
717 				goto error;
718 			}
719 
720 			continue;
721 		}
722 
723 		/*
724 		 * Make sure this property is valid and applies to this type.
725 		 */
726 		if (prop == ZPOOL_PROP_INVAL) {
727 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
728 			    "invalid property '%s'"), propname);
729 			(void) zfs_error(hdl, EZFS_BADPROP, errbuf);
730 			goto error;
731 		}
732 
733 		if (zpool_prop_readonly(prop)) {
734 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "'%s' "
735 			    "is readonly"), propname);
736 			(void) zfs_error(hdl, EZFS_PROPREADONLY, errbuf);
737 			goto error;
738 		}
739 
740 		if (!flags.create && zpool_prop_setonce(prop)) {
741 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
742 			    "property '%s' can only be set at "
743 			    "creation time"), propname);
744 			(void) zfs_error(hdl, EZFS_BADPROP, errbuf);
745 			goto error;
746 		}
747 
748 		if (zprop_parse_value(hdl, elem, prop, ZFS_TYPE_POOL, retprops,
749 		    &strval, &intval, errbuf) != 0)
750 			goto error;
751 
752 		/*
753 		 * Perform additional checking for specific properties.
754 		 */
755 		switch (prop) {
756 		case ZPOOL_PROP_VERSION:
757 			if (intval < version ||
758 			    !SPA_VERSION_IS_SUPPORTED(intval)) {
759 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
760 				    "property '%s' number %llu is invalid."),
761 				    propname, (unsigned long long)intval);
762 				(void) zfs_error(hdl, EZFS_BADVERSION, errbuf);
763 				goto error;
764 			}
765 			break;
766 
767 		case ZPOOL_PROP_ASHIFT:
768 			if (intval != 0 &&
769 			    (intval < ASHIFT_MIN || intval > ASHIFT_MAX)) {
770 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
771 				    "property '%s' number %llu is invalid, "
772 				    "only values between %" PRId32 " and %"
773 				    PRId32 " are allowed."),
774 				    propname, (unsigned long long)intval,
775 				    ASHIFT_MIN, ASHIFT_MAX);
776 				(void) zfs_error(hdl, EZFS_BADPROP, errbuf);
777 				goto error;
778 			}
779 			break;
780 
781 		case ZPOOL_PROP_BOOTFS:
782 			if (flags.create || flags.import) {
783 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
784 				    "property '%s' cannot be set at creation "
785 				    "or import time"), propname);
786 				(void) zfs_error(hdl, EZFS_BADPROP, errbuf);
787 				goto error;
788 			}
789 
790 			if (version < SPA_VERSION_BOOTFS) {
791 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
792 				    "pool must be upgraded to support "
793 				    "'%s' property"), propname);
794 				(void) zfs_error(hdl, EZFS_BADVERSION, errbuf);
795 				goto error;
796 			}
797 
798 			/*
799 			 * bootfs property value has to be a dataset name and
800 			 * the dataset has to be in the same pool as it sets to.
801 			 */
802 			if (!bootfs_name_valid(poolname, strval)) {
803 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "'%s' "
804 				    "is an invalid name"), strval);
805 				(void) zfs_error(hdl, EZFS_INVALIDNAME, errbuf);
806 				goto error;
807 			}
808 
809 			if ((zhp = zpool_open_canfail(hdl, poolname)) == NULL) {
810 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
811 				    "could not open pool '%s'"), poolname);
812 				(void) zfs_error(hdl, EZFS_OPENFAILED, errbuf);
813 				goto error;
814 			}
815 			zpool_close(zhp);
816 			break;
817 
818 		case ZPOOL_PROP_ALTROOT:
819 			if (!flags.create && !flags.import) {
820 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
821 				    "property '%s' can only be set during pool "
822 				    "creation or import"), propname);
823 				(void) zfs_error(hdl, EZFS_BADPROP, errbuf);
824 				goto error;
825 			}
826 
827 			if (strval[0] != '/') {
828 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
829 				    "bad alternate root '%s'"), strval);
830 				(void) zfs_error(hdl, EZFS_BADPATH, errbuf);
831 				goto error;
832 			}
833 			break;
834 
835 		case ZPOOL_PROP_CACHEFILE:
836 			if (strval[0] == '\0')
837 				break;
838 
839 			if (strcmp(strval, "none") == 0)
840 				break;
841 
842 			if (strval[0] != '/') {
843 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
844 				    "property '%s' must be empty, an "
845 				    "absolute path, or 'none'"), propname);
846 				(void) zfs_error(hdl, EZFS_BADPATH, errbuf);
847 				goto error;
848 			}
849 
850 			parent = strdup(strval);
851 			if (parent == NULL) {
852 				(void) zfs_error(hdl, EZFS_NOMEM, errbuf);
853 				goto error;
854 			}
855 			slash = strrchr(parent, '/');
856 
857 			if (slash[1] == '\0' || strcmp(slash, "/.") == 0 ||
858 			    strcmp(slash, "/..") == 0) {
859 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
860 				    "'%s' is not a valid file"), parent);
861 				(void) zfs_error(hdl, EZFS_BADPATH, errbuf);
862 				free(parent);
863 				goto error;
864 			}
865 
866 			*slash = '\0';
867 
868 			if (parent[0] != '\0' &&
869 			    (stat64(parent, &statbuf) != 0 ||
870 			    !S_ISDIR(statbuf.st_mode))) {
871 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
872 				    "'%s' is not a valid directory"),
873 				    parent);
874 				(void) zfs_error(hdl, EZFS_BADPATH, errbuf);
875 				free(parent);
876 				goto error;
877 			}
878 			free(parent);
879 
880 			break;
881 
882 		case ZPOOL_PROP_COMPATIBILITY:
883 			switch (zpool_load_compat(strval, NULL, report, 1024)) {
884 			case ZPOOL_COMPATIBILITY_OK:
885 			case ZPOOL_COMPATIBILITY_WARNTOKEN:
886 				break;
887 			case ZPOOL_COMPATIBILITY_BADFILE:
888 			case ZPOOL_COMPATIBILITY_BADTOKEN:
889 			case ZPOOL_COMPATIBILITY_NOFILES:
890 				zfs_error_aux(hdl, "%s", report);
891 				(void) zfs_error(hdl, EZFS_BADPROP, errbuf);
892 				goto error;
893 			}
894 			break;
895 
896 		case ZPOOL_PROP_COMMENT:
897 			for (check = strval; *check != '\0'; check++) {
898 				if (!isprint(*check)) {
899 					zfs_error_aux(hdl,
900 					    dgettext(TEXT_DOMAIN,
901 					    "comment may only have printable "
902 					    "characters"));
903 					(void) zfs_error(hdl, EZFS_BADPROP,
904 					    errbuf);
905 					goto error;
906 				}
907 			}
908 			if (strlen(strval) > ZPROP_MAX_COMMENT) {
909 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
910 				    "comment must not exceed %d characters"),
911 				    ZPROP_MAX_COMMENT);
912 				(void) zfs_error(hdl, EZFS_BADPROP, errbuf);
913 				goto error;
914 			}
915 			break;
916 		case ZPOOL_PROP_READONLY:
917 			if (!flags.import) {
918 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
919 				    "property '%s' can only be set at "
920 				    "import time"), propname);
921 				(void) zfs_error(hdl, EZFS_BADPROP, errbuf);
922 				goto error;
923 			}
924 			break;
925 		case ZPOOL_PROP_MULTIHOST:
926 			if (get_system_hostid() == 0) {
927 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
928 				    "requires a non-zero system hostid"));
929 				(void) zfs_error(hdl, EZFS_BADPROP, errbuf);
930 				goto error;
931 			}
932 			break;
933 		case ZPOOL_PROP_DEDUPDITTO:
934 			printf("Note: property '%s' no longer has "
935 			    "any effect\n", propname);
936 			break;
937 
938 		default:
939 			break;
940 		}
941 	}
942 
943 	return (retprops);
944 error:
945 	nvlist_free(retprops);
946 	return (NULL);
947 }
948 
949 /*
950  * Set zpool property : propname=propval.
951  */
952 int
953 zpool_set_prop(zpool_handle_t *zhp, const char *propname, const char *propval)
954 {
955 	zfs_cmd_t zc = {"\0"};
956 	int ret;
957 	char errbuf[ERRBUFLEN];
958 	nvlist_t *nvl = NULL;
959 	nvlist_t *realprops;
960 	uint64_t version;
961 	prop_flags_t flags = { 0 };
962 
963 	(void) snprintf(errbuf, sizeof (errbuf),
964 	    dgettext(TEXT_DOMAIN, "cannot set property for '%s'"),
965 	    zhp->zpool_name);
966 
967 	if (nvlist_alloc(&nvl, NV_UNIQUE_NAME, 0) != 0)
968 		return (no_memory(zhp->zpool_hdl));
969 
970 	if (nvlist_add_string(nvl, propname, propval) != 0) {
971 		nvlist_free(nvl);
972 		return (no_memory(zhp->zpool_hdl));
973 	}
974 
975 	version = zpool_get_prop_int(zhp, ZPOOL_PROP_VERSION, NULL);
976 	if ((realprops = zpool_valid_proplist(zhp->zpool_hdl,
977 	    zhp->zpool_name, nvl, version, flags, errbuf)) == NULL) {
978 		nvlist_free(nvl);
979 		return (-1);
980 	}
981 
982 	nvlist_free(nvl);
983 	nvl = realprops;
984 
985 	/*
986 	 * Execute the corresponding ioctl() to set this property.
987 	 */
988 	(void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
989 
990 	zcmd_write_src_nvlist(zhp->zpool_hdl, &zc, nvl);
991 
992 	ret = zfs_ioctl(zhp->zpool_hdl, ZFS_IOC_POOL_SET_PROPS, &zc);
993 
994 	zcmd_free_nvlists(&zc);
995 	nvlist_free(nvl);
996 
997 	if (ret)
998 		(void) zpool_standard_error(zhp->zpool_hdl, errno, errbuf);
999 	else
1000 		(void) zpool_props_refresh(zhp);
1001 
1002 	return (ret);
1003 }
1004 
1005 int
1006 zpool_expand_proplist(zpool_handle_t *zhp, zprop_list_t **plp,
1007     zfs_type_t type, boolean_t literal)
1008 {
1009 	libzfs_handle_t *hdl = zhp->zpool_hdl;
1010 	zprop_list_t *entry;
1011 	char buf[ZFS_MAXPROPLEN];
1012 	nvlist_t *features = NULL;
1013 	nvpair_t *nvp;
1014 	zprop_list_t **last;
1015 	boolean_t firstexpand = (NULL == *plp);
1016 	int i;
1017 
1018 	if (zprop_expand_list(hdl, plp, type) != 0)
1019 		return (-1);
1020 
1021 	if (type == ZFS_TYPE_VDEV)
1022 		return (0);
1023 
1024 	last = plp;
1025 	while (*last != NULL)
1026 		last = &(*last)->pl_next;
1027 
1028 	if ((*plp)->pl_all)
1029 		features = zpool_get_features(zhp);
1030 
1031 	if ((*plp)->pl_all && firstexpand) {
1032 		/* Handle userprops in the all properties case */
1033 		if (zhp->zpool_props == NULL && zpool_props_refresh(zhp))
1034 			return (-1);
1035 
1036 		nvp = NULL;
1037 		while ((nvp = nvlist_next_nvpair(zhp->zpool_props, nvp)) !=
1038 		    NULL) {
1039 			const char *propname = nvpair_name(nvp);
1040 
1041 			if (!zfs_prop_user(propname))
1042 				continue;
1043 
1044 			entry = zfs_alloc(hdl, sizeof (zprop_list_t));
1045 			entry->pl_prop = ZPROP_USERPROP;
1046 			entry->pl_user_prop = zfs_strdup(hdl, propname);
1047 			entry->pl_width = strlen(entry->pl_user_prop);
1048 			entry->pl_all = B_TRUE;
1049 
1050 			*last = entry;
1051 			last = &entry->pl_next;
1052 		}
1053 
1054 		for (i = 0; i < SPA_FEATURES; i++) {
1055 			entry = zfs_alloc(hdl, sizeof (zprop_list_t));
1056 			entry->pl_prop = ZPROP_USERPROP;
1057 			entry->pl_user_prop = zfs_asprintf(hdl, "feature@%s",
1058 			    spa_feature_table[i].fi_uname);
1059 			entry->pl_width = strlen(entry->pl_user_prop);
1060 			entry->pl_all = B_TRUE;
1061 
1062 			*last = entry;
1063 			last = &entry->pl_next;
1064 		}
1065 	}
1066 
1067 	/* add any unsupported features */
1068 	for (nvp = nvlist_next_nvpair(features, NULL);
1069 	    nvp != NULL; nvp = nvlist_next_nvpair(features, nvp)) {
1070 		char *propname;
1071 		boolean_t found;
1072 
1073 		if (zfeature_is_supported(nvpair_name(nvp)))
1074 			continue;
1075 
1076 		propname = zfs_asprintf(hdl, "unsupported@%s",
1077 		    nvpair_name(nvp));
1078 
1079 		/*
1080 		 * Before adding the property to the list make sure that no
1081 		 * other pool already added the same property.
1082 		 */
1083 		found = B_FALSE;
1084 		entry = *plp;
1085 		while (entry != NULL) {
1086 			if (entry->pl_user_prop != NULL &&
1087 			    strcmp(propname, entry->pl_user_prop) == 0) {
1088 				found = B_TRUE;
1089 				break;
1090 			}
1091 			entry = entry->pl_next;
1092 		}
1093 		if (found) {
1094 			free(propname);
1095 			continue;
1096 		}
1097 
1098 		entry = zfs_alloc(hdl, sizeof (zprop_list_t));
1099 		entry->pl_prop = ZPROP_USERPROP;
1100 		entry->pl_user_prop = propname;
1101 		entry->pl_width = strlen(entry->pl_user_prop);
1102 		entry->pl_all = B_TRUE;
1103 
1104 		*last = entry;
1105 		last = &entry->pl_next;
1106 	}
1107 
1108 	for (entry = *plp; entry != NULL; entry = entry->pl_next) {
1109 		if (entry->pl_fixed && !literal)
1110 			continue;
1111 
1112 		if (entry->pl_prop != ZPROP_USERPROP &&
1113 		    zpool_get_prop(zhp, entry->pl_prop, buf, sizeof (buf),
1114 		    NULL, literal) == 0) {
1115 			if (strlen(buf) > entry->pl_width)
1116 				entry->pl_width = strlen(buf);
1117 		} else if (entry->pl_prop == ZPROP_INVAL &&
1118 		    zfs_prop_user(entry->pl_user_prop) &&
1119 		    zpool_get_userprop(zhp, entry->pl_user_prop, buf,
1120 		    sizeof (buf), NULL) == 0) {
1121 			if (strlen(buf) > entry->pl_width)
1122 				entry->pl_width = strlen(buf);
1123 		}
1124 	}
1125 
1126 	return (0);
1127 }
1128 
1129 int
1130 vdev_expand_proplist(zpool_handle_t *zhp, const char *vdevname,
1131     zprop_list_t **plp)
1132 {
1133 	zprop_list_t *entry;
1134 	char buf[ZFS_MAXPROPLEN];
1135 	const char *strval = NULL;
1136 	int err = 0;
1137 	nvpair_t *elem = NULL;
1138 	nvlist_t *vprops = NULL;
1139 	nvlist_t *propval = NULL;
1140 	const char *propname;
1141 	vdev_prop_t prop;
1142 	zprop_list_t **last;
1143 
1144 	for (entry = *plp; entry != NULL; entry = entry->pl_next) {
1145 		if (entry->pl_fixed)
1146 			continue;
1147 
1148 		if (zpool_get_vdev_prop(zhp, vdevname, entry->pl_prop,
1149 		    entry->pl_user_prop, buf, sizeof (buf), NULL,
1150 		    B_FALSE) == 0) {
1151 			if (strlen(buf) > entry->pl_width)
1152 				entry->pl_width = strlen(buf);
1153 		}
1154 		if (entry->pl_prop == VDEV_PROP_NAME &&
1155 		    strlen(vdevname) > entry->pl_width)
1156 			entry->pl_width = strlen(vdevname);
1157 	}
1158 
1159 	/* Handle the all properties case */
1160 	last = plp;
1161 	if (*last != NULL && (*last)->pl_all == B_TRUE) {
1162 		while (*last != NULL)
1163 			last = &(*last)->pl_next;
1164 
1165 		err = zpool_get_all_vdev_props(zhp, vdevname, &vprops);
1166 		if (err != 0)
1167 			return (err);
1168 
1169 		while ((elem = nvlist_next_nvpair(vprops, elem)) != NULL) {
1170 			propname = nvpair_name(elem);
1171 
1172 			/* Skip properties that are not user defined */
1173 			if ((prop = vdev_name_to_prop(propname)) !=
1174 			    VDEV_PROP_USERPROP)
1175 				continue;
1176 
1177 			if (nvpair_value_nvlist(elem, &propval) != 0)
1178 				continue;
1179 
1180 			strval = fnvlist_lookup_string(propval, ZPROP_VALUE);
1181 
1182 			entry = zfs_alloc(zhp->zpool_hdl,
1183 			    sizeof (zprop_list_t));
1184 			entry->pl_prop = prop;
1185 			entry->pl_user_prop = zfs_strdup(zhp->zpool_hdl,
1186 			    propname);
1187 			entry->pl_width = strlen(strval);
1188 			entry->pl_all = B_TRUE;
1189 			*last = entry;
1190 			last = &entry->pl_next;
1191 		}
1192 	}
1193 
1194 	return (0);
1195 }
1196 
1197 /*
1198  * Get the state for the given feature on the given ZFS pool.
1199  */
1200 int
1201 zpool_prop_get_feature(zpool_handle_t *zhp, const char *propname, char *buf,
1202     size_t len)
1203 {
1204 	uint64_t refcount;
1205 	boolean_t found = B_FALSE;
1206 	nvlist_t *features = zpool_get_features(zhp);
1207 	boolean_t supported;
1208 	const char *feature = strchr(propname, '@') + 1;
1209 
1210 	supported = zpool_prop_feature(propname);
1211 	ASSERT(supported || zpool_prop_unsupported(propname));
1212 
1213 	/*
1214 	 * Convert from feature name to feature guid. This conversion is
1215 	 * unnecessary for unsupported@... properties because they already
1216 	 * use guids.
1217 	 */
1218 	if (supported) {
1219 		int ret;
1220 		spa_feature_t fid;
1221 
1222 		ret = zfeature_lookup_name(feature, &fid);
1223 		if (ret != 0) {
1224 			(void) strlcpy(buf, "-", len);
1225 			return (ENOTSUP);
1226 		}
1227 		feature = spa_feature_table[fid].fi_guid;
1228 	}
1229 
1230 	if (nvlist_lookup_uint64(features, feature, &refcount) == 0)
1231 		found = B_TRUE;
1232 
1233 	if (supported) {
1234 		if (!found) {
1235 			(void) strlcpy(buf, ZFS_FEATURE_DISABLED, len);
1236 		} else  {
1237 			if (refcount == 0)
1238 				(void) strlcpy(buf, ZFS_FEATURE_ENABLED, len);
1239 			else
1240 				(void) strlcpy(buf, ZFS_FEATURE_ACTIVE, len);
1241 		}
1242 	} else {
1243 		if (found) {
1244 			if (refcount == 0) {
1245 				(void) strcpy(buf, ZFS_UNSUPPORTED_INACTIVE);
1246 			} else {
1247 				(void) strcpy(buf, ZFS_UNSUPPORTED_READONLY);
1248 			}
1249 		} else {
1250 			(void) strlcpy(buf, "-", len);
1251 			return (ENOTSUP);
1252 		}
1253 	}
1254 
1255 	return (0);
1256 }
1257 
1258 /*
1259  * Validate the given pool name, optionally putting an extended error message in
1260  * 'buf'.
1261  */
1262 boolean_t
1263 zpool_name_valid(libzfs_handle_t *hdl, boolean_t isopen, const char *pool)
1264 {
1265 	namecheck_err_t why;
1266 	char what;
1267 	int ret;
1268 
1269 	ret = pool_namecheck(pool, &why, &what);
1270 
1271 	/*
1272 	 * The rules for reserved pool names were extended at a later point.
1273 	 * But we need to support users with existing pools that may now be
1274 	 * invalid.  So we only check for this expanded set of names during a
1275 	 * create (or import), and only in userland.
1276 	 */
1277 	if (ret == 0 && !isopen &&
1278 	    (strncmp(pool, "mirror", 6) == 0 ||
1279 	    strncmp(pool, "raidz", 5) == 0 ||
1280 	    strncmp(pool, "draid", 5) == 0 ||
1281 	    strncmp(pool, "spare", 5) == 0 ||
1282 	    strcmp(pool, "log") == 0)) {
1283 		if (hdl != NULL)
1284 			zfs_error_aux(hdl,
1285 			    dgettext(TEXT_DOMAIN, "name is reserved"));
1286 		return (B_FALSE);
1287 	}
1288 
1289 
1290 	if (ret != 0) {
1291 		if (hdl != NULL) {
1292 			switch (why) {
1293 			case NAME_ERR_TOOLONG:
1294 				zfs_error_aux(hdl,
1295 				    dgettext(TEXT_DOMAIN, "name is too long"));
1296 				break;
1297 
1298 			case NAME_ERR_INVALCHAR:
1299 				zfs_error_aux(hdl,
1300 				    dgettext(TEXT_DOMAIN, "invalid character "
1301 				    "'%c' in pool name"), what);
1302 				break;
1303 
1304 			case NAME_ERR_NOLETTER:
1305 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1306 				    "name must begin with a letter"));
1307 				break;
1308 
1309 			case NAME_ERR_RESERVED:
1310 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1311 				    "name is reserved"));
1312 				break;
1313 
1314 			case NAME_ERR_DISKLIKE:
1315 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1316 				    "pool name is reserved"));
1317 				break;
1318 
1319 			case NAME_ERR_LEADING_SLASH:
1320 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1321 				    "leading slash in name"));
1322 				break;
1323 
1324 			case NAME_ERR_EMPTY_COMPONENT:
1325 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1326 				    "empty component in name"));
1327 				break;
1328 
1329 			case NAME_ERR_TRAILING_SLASH:
1330 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1331 				    "trailing slash in name"));
1332 				break;
1333 
1334 			case NAME_ERR_MULTIPLE_DELIMITERS:
1335 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1336 				    "multiple '@' and/or '#' delimiters in "
1337 				    "name"));
1338 				break;
1339 
1340 			case NAME_ERR_NO_AT:
1341 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1342 				    "permission set is missing '@'"));
1343 				break;
1344 
1345 			default:
1346 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1347 				    "(%d) not defined"), why);
1348 				break;
1349 			}
1350 		}
1351 		return (B_FALSE);
1352 	}
1353 
1354 	return (B_TRUE);
1355 }
1356 
1357 /*
1358  * Open a handle to the given pool, even if the pool is currently in the FAULTED
1359  * state.
1360  */
1361 zpool_handle_t *
1362 zpool_open_canfail(libzfs_handle_t *hdl, const char *pool)
1363 {
1364 	zpool_handle_t *zhp;
1365 	boolean_t missing;
1366 
1367 	/*
1368 	 * Make sure the pool name is valid.
1369 	 */
1370 	if (!zpool_name_valid(hdl, B_TRUE, pool)) {
1371 		(void) zfs_error_fmt(hdl, EZFS_INVALIDNAME,
1372 		    dgettext(TEXT_DOMAIN, "cannot open '%s'"),
1373 		    pool);
1374 		return (NULL);
1375 	}
1376 
1377 	zhp = zfs_alloc(hdl, sizeof (zpool_handle_t));
1378 
1379 	zhp->zpool_hdl = hdl;
1380 	(void) strlcpy(zhp->zpool_name, pool, sizeof (zhp->zpool_name));
1381 
1382 	if (zpool_refresh_stats(zhp, &missing) != 0) {
1383 		zpool_close(zhp);
1384 		return (NULL);
1385 	}
1386 
1387 	if (missing) {
1388 		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "no such pool"));
1389 		(void) zfs_error_fmt(hdl, EZFS_NOENT,
1390 		    dgettext(TEXT_DOMAIN, "cannot open '%s'"), pool);
1391 		zpool_close(zhp);
1392 		return (NULL);
1393 	}
1394 
1395 	return (zhp);
1396 }
1397 
1398 /*
1399  * Like the above, but silent on error.  Used when iterating over pools (because
1400  * the configuration cache may be out of date).
1401  */
1402 int
1403 zpool_open_silent(libzfs_handle_t *hdl, const char *pool, zpool_handle_t **ret)
1404 {
1405 	zpool_handle_t *zhp;
1406 	boolean_t missing;
1407 
1408 	zhp = zfs_alloc(hdl, sizeof (zpool_handle_t));
1409 
1410 	zhp->zpool_hdl = hdl;
1411 	(void) strlcpy(zhp->zpool_name, pool, sizeof (zhp->zpool_name));
1412 
1413 	if (zpool_refresh_stats(zhp, &missing) != 0) {
1414 		zpool_close(zhp);
1415 		return (-1);
1416 	}
1417 
1418 	if (missing) {
1419 		zpool_close(zhp);
1420 		*ret = NULL;
1421 		return (0);
1422 	}
1423 
1424 	*ret = zhp;
1425 	return (0);
1426 }
1427 
1428 /*
1429  * Similar to zpool_open_canfail(), but refuses to open pools in the faulted
1430  * state.
1431  */
1432 zpool_handle_t *
1433 zpool_open(libzfs_handle_t *hdl, const char *pool)
1434 {
1435 	zpool_handle_t *zhp;
1436 
1437 	if ((zhp = zpool_open_canfail(hdl, pool)) == NULL)
1438 		return (NULL);
1439 
1440 	if (zhp->zpool_state == POOL_STATE_UNAVAIL) {
1441 		(void) zfs_error_fmt(hdl, EZFS_POOLUNAVAIL,
1442 		    dgettext(TEXT_DOMAIN, "cannot open '%s'"), zhp->zpool_name);
1443 		zpool_close(zhp);
1444 		return (NULL);
1445 	}
1446 
1447 	return (zhp);
1448 }
1449 
1450 /*
1451  * Close the handle.  Simply frees the memory associated with the handle.
1452  */
1453 void
1454 zpool_close(zpool_handle_t *zhp)
1455 {
1456 	nvlist_free(zhp->zpool_config);
1457 	nvlist_free(zhp->zpool_old_config);
1458 	nvlist_free(zhp->zpool_props);
1459 	free(zhp);
1460 }
1461 
1462 /*
1463  * Return the name of the pool.
1464  */
1465 const char *
1466 zpool_get_name(zpool_handle_t *zhp)
1467 {
1468 	return (zhp->zpool_name);
1469 }
1470 
1471 
1472 /*
1473  * Return the state of the pool (ACTIVE or UNAVAILABLE)
1474  */
1475 int
1476 zpool_get_state(zpool_handle_t *zhp)
1477 {
1478 	return (zhp->zpool_state);
1479 }
1480 
1481 /*
1482  * Check if vdev list contains a dRAID vdev
1483  */
1484 static boolean_t
1485 zpool_has_draid_vdev(nvlist_t *nvroot)
1486 {
1487 	nvlist_t **child;
1488 	uint_t children;
1489 
1490 	if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_CHILDREN,
1491 	    &child, &children) == 0) {
1492 		for (uint_t c = 0; c < children; c++) {
1493 			const char *type;
1494 
1495 			if (nvlist_lookup_string(child[c],
1496 			    ZPOOL_CONFIG_TYPE, &type) == 0 &&
1497 			    strcmp(type, VDEV_TYPE_DRAID) == 0) {
1498 				return (B_TRUE);
1499 			}
1500 		}
1501 	}
1502 	return (B_FALSE);
1503 }
1504 
1505 /*
1506  * Output a dRAID top-level vdev name in to the provided buffer.
1507  */
1508 static char *
1509 zpool_draid_name(char *name, int len, uint64_t data, uint64_t parity,
1510     uint64_t spares, uint64_t children, uint64_t width)
1511 {
1512 	if (children < width)
1513 		snprintf(name, len, "%s%llu:%llud:%lluc:%lluw:%llus",
1514 		    VDEV_TYPE_DRAID, (u_longlong_t)parity, (u_longlong_t)data,
1515 		    (u_longlong_t)children, (u_longlong_t)width,
1516 		    (u_longlong_t)spares);
1517 	else
1518 		snprintf(name, len, "%s%llu:%llud:%lluc:%llus",
1519 		    VDEV_TYPE_DRAID, (u_longlong_t)parity, (u_longlong_t)data,
1520 		    (u_longlong_t)children, (u_longlong_t)spares);
1521 
1522 	return (name);
1523 }
1524 
1525 /*
1526  * Return B_TRUE if the provided name is a dRAID spare name.
1527  */
1528 boolean_t
1529 zpool_is_draid_spare(const char *name)
1530 {
1531 	uint64_t spare_id, parity, vdev_id;
1532 
1533 	if (sscanf(name, VDEV_TYPE_DRAID "%llu-%llu-%llu",
1534 	    (u_longlong_t *)&parity, (u_longlong_t *)&vdev_id,
1535 	    (u_longlong_t *)&spare_id) == 3) {
1536 		return (B_TRUE);
1537 	}
1538 
1539 	return (B_FALSE);
1540 }
1541 
1542 
1543 /*
1544  * Extract device-specific error information from a failed pool creation.
1545  * If the kernel returned ZPOOL_CONFIG_CREATE_INFO in the ioctl output,
1546  * set an appropriate error aux message identifying the problematic device.
1547  */
1548 static int
1549 zpool_create_info(libzfs_handle_t *hdl, zfs_cmd_t *zc)
1550 {
1551 	nvlist_t *outnv = NULL;
1552 	nvlist_t *info = NULL;
1553 	const char *vdev = NULL;
1554 	const char *pname = NULL;
1555 
1556 	if (zc->zc_nvlist_dst_size == 0)
1557 		return (ENOENT);
1558 
1559 	if (nvlist_unpack((void *)(uintptr_t)zc->zc_nvlist_dst,
1560 	    zc->zc_nvlist_dst_size, &outnv, 0) != 0 || outnv == NULL)
1561 		return (EINVAL);
1562 
1563 	if (nvlist_lookup_nvlist(outnv, ZPOOL_CONFIG_CREATE_INFO, &info) != 0) {
1564 		nvlist_free(outnv);
1565 		return (EINVAL);
1566 	}
1567 
1568 	if (nvlist_lookup_string(info, ZPOOL_CREATE_INFO_VDEV, &vdev) != 0) {
1569 		nvlist_free(outnv);
1570 		return (EINVAL);
1571 	}
1572 
1573 	if (nvlist_lookup_string(info, ZPOOL_CREATE_INFO_POOL, &pname) == 0) {
1574 		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1575 		    "device '%s' is part of active pool '%s'"),
1576 		    vdev, pname);
1577 	} else {
1578 		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1579 		    "device '%s' is in use"), vdev);
1580 	}
1581 
1582 	nvlist_free(outnv);
1583 	return (0);
1584 }
1585 
1586 /*
1587  * Create the named pool, using the provided vdev list.  It is assumed
1588  * that the consumer has already validated the contents of the nvlist, so we
1589  * don't have to worry about error semantics.
1590  */
1591 int
1592 zpool_create(libzfs_handle_t *hdl, const char *pool, nvlist_t *nvroot,
1593     nvlist_t *props, nvlist_t *fsprops)
1594 {
1595 	zfs_cmd_t zc = {"\0"};
1596 	nvlist_t *zc_fsprops = NULL;
1597 	nvlist_t *zc_props = NULL;
1598 	nvlist_t *hidden_args = NULL;
1599 	uint8_t *wkeydata = NULL;
1600 	uint_t wkeylen = 0;
1601 	char errbuf[ERRBUFLEN];
1602 	int ret = -1;
1603 
1604 	(void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
1605 	    "cannot create '%s'"), pool);
1606 
1607 	if (!zpool_name_valid(hdl, B_FALSE, pool))
1608 		return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf));
1609 
1610 	zcmd_write_conf_nvlist(hdl, &zc, nvroot);
1611 
1612 	if (props) {
1613 		prop_flags_t flags = { .create = B_TRUE, .import = B_FALSE };
1614 
1615 		if ((zc_props = zpool_valid_proplist(hdl, pool, props,
1616 		    SPA_VERSION_1, flags, errbuf)) == NULL) {
1617 			goto create_failed;
1618 		}
1619 	}
1620 
1621 	if (fsprops) {
1622 		uint64_t zoned;
1623 		const char *zonestr;
1624 
1625 		zoned = ((nvlist_lookup_string(fsprops,
1626 		    zfs_prop_to_name(ZFS_PROP_ZONED), &zonestr) == 0) &&
1627 		    strcmp(zonestr, "on") == 0);
1628 
1629 		if ((zc_fsprops = zfs_valid_proplist(hdl, ZFS_TYPE_FILESYSTEM,
1630 		    fsprops, zoned, NULL, NULL, B_TRUE, errbuf)) == NULL) {
1631 			goto create_failed;
1632 		}
1633 
1634 		if (!zc_props &&
1635 		    (nvlist_alloc(&zc_props, NV_UNIQUE_NAME, 0) != 0)) {
1636 			goto create_failed;
1637 		}
1638 		if (zfs_crypto_create(hdl, NULL, zc_fsprops, props, B_TRUE,
1639 		    &wkeydata, &wkeylen) != 0) {
1640 			zfs_error(hdl, EZFS_CRYPTOFAILED, errbuf);
1641 			goto create_failed;
1642 		}
1643 		if (nvlist_add_nvlist(zc_props,
1644 		    ZPOOL_ROOTFS_PROPS, zc_fsprops) != 0) {
1645 			goto create_failed;
1646 		}
1647 		if (wkeydata != NULL) {
1648 			if (nvlist_alloc(&hidden_args, NV_UNIQUE_NAME, 0) != 0)
1649 				goto create_failed;
1650 
1651 			if (nvlist_add_uint8_array(hidden_args, "wkeydata",
1652 			    wkeydata, wkeylen) != 0)
1653 				goto create_failed;
1654 
1655 			if (nvlist_add_nvlist(zc_props, ZPOOL_HIDDEN_ARGS,
1656 			    hidden_args) != 0)
1657 				goto create_failed;
1658 		}
1659 	}
1660 
1661 	if (zc_props)
1662 		zcmd_write_src_nvlist(hdl, &zc, zc_props);
1663 
1664 	(void) strlcpy(zc.zc_name, pool, sizeof (zc.zc_name));
1665 	zcmd_alloc_dst_nvlist(hdl, &zc, 4096);
1666 
1667 	if ((ret = zfs_ioctl(hdl, ZFS_IOC_POOL_CREATE, &zc)) != 0) {
1668 		switch (errno) {
1669 		case EBUSY:
1670 			/*
1671 			 * This can happen if the user has specified the same
1672 			 * device multiple times.  We can't reliably detect this
1673 			 * until we try to add it and see we already have a
1674 			 * label.  This can also happen under if the device is
1675 			 * part of an active md or lvm device.
1676 			 */
1677 			if (zpool_create_info(hdl, &zc) != 0) {
1678 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1679 				    "one or more vdevs refer to the same "
1680 				    "device, or one of\nthe devices is "
1681 				    "part of an active md or lvm device"));
1682 			}
1683 			ret = zfs_error(hdl, EZFS_BADDEV, errbuf);
1684 			break;
1685 
1686 		case ERANGE:
1687 			/*
1688 			 * This happens if the record size is smaller or larger
1689 			 * than the allowed size range, or not a power of 2.
1690 			 *
1691 			 * NOTE: although zfs_valid_proplist is called earlier,
1692 			 * this case may have slipped through since the
1693 			 * pool does not exist yet and it is therefore
1694 			 * impossible to read properties e.g. max blocksize
1695 			 * from the pool.
1696 			 */
1697 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1698 			    "record size invalid"));
1699 			ret = zfs_error(hdl, EZFS_BADPROP, errbuf);
1700 			break;
1701 
1702 		case EOVERFLOW:
1703 			/*
1704 			 * This occurs when one of the devices is below
1705 			 * SPA_MINDEVSIZE.  Unfortunately, we can't detect which
1706 			 * device was the problem device since there's no
1707 			 * reliable way to determine device size from userland.
1708 			 */
1709 			{
1710 				char buf[64];
1711 
1712 				zfs_nicebytes(SPA_MINDEVSIZE, buf,
1713 				    sizeof (buf));
1714 
1715 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1716 				    "one or more devices is less than the "
1717 				    "minimum size (%s)"), buf);
1718 			}
1719 			ret = zfs_error(hdl, EZFS_BADDEV, errbuf);
1720 			break;
1721 
1722 		case ENOSPC:
1723 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1724 			    "one or more devices is out of space"));
1725 			ret = zfs_error(hdl, EZFS_BADDEV, errbuf);
1726 			break;
1727 
1728 		case EINVAL:
1729 			if (zpool_has_draid_vdev(nvroot) &&
1730 			    zfeature_lookup_name("draid", NULL) != 0) {
1731 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1732 				    "dRAID vdevs are unsupported by the "
1733 				    "kernel"));
1734 				ret = zfs_error(hdl, EZFS_BADDEV, errbuf);
1735 			} else {
1736 				ret = zpool_standard_error(hdl, errno, errbuf);
1737 			}
1738 			break;
1739 
1740 		case ENXIO:
1741 			if (zpool_create_info(hdl, &zc) == 0) {
1742 				ret = zfs_error(hdl, EZFS_BADDEV, errbuf);
1743 			} else {
1744 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1745 				    "one or more devices could not be "
1746 				    "opened"));
1747 				ret = zfs_error(hdl, EZFS_BADDEV, errbuf);
1748 			}
1749 			break;
1750 
1751 		case EDOM:
1752 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1753 			    "block size out of range or does not match"));
1754 			ret = zfs_error(hdl, EZFS_BADDEV, errbuf);
1755 			break;
1756 
1757 		default:
1758 			ret = zpool_standard_error(hdl, errno, errbuf);
1759 			break;
1760 		}
1761 	}
1762 
1763 create_failed:
1764 	zcmd_free_nvlists(&zc);
1765 	nvlist_free(zc_props);
1766 	nvlist_free(zc_fsprops);
1767 	nvlist_free(hidden_args);
1768 	if (wkeydata != NULL)
1769 		free(wkeydata);
1770 	return (ret);
1771 }
1772 
1773 /*
1774  * Destroy the given pool.  It is up to the caller to ensure that there are no
1775  * datasets left in the pool.
1776  */
1777 int
1778 zpool_destroy(zpool_handle_t *zhp, const char *log_str)
1779 {
1780 	zfs_cmd_t zc = {"\0"};
1781 	zfs_handle_t *zfp = NULL;
1782 	libzfs_handle_t *hdl = zhp->zpool_hdl;
1783 	char errbuf[ERRBUFLEN];
1784 
1785 	if (zhp->zpool_state == POOL_STATE_ACTIVE &&
1786 	    (zfp = zfs_open(hdl, zhp->zpool_name, ZFS_TYPE_FILESYSTEM)) == NULL)
1787 		return (-1);
1788 
1789 	(void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
1790 	zc.zc_history = (uint64_t)(uintptr_t)log_str;
1791 
1792 	if (zfs_ioctl(hdl, ZFS_IOC_POOL_DESTROY, &zc) != 0) {
1793 		(void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
1794 		    "cannot destroy '%s'"), zhp->zpool_name);
1795 
1796 		if (errno == EROFS) {
1797 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1798 			    "one or more devices is read only"));
1799 			(void) zfs_error(hdl, EZFS_BADDEV, errbuf);
1800 		} else {
1801 			(void) zpool_standard_error(hdl, errno, errbuf);
1802 		}
1803 
1804 		if (zfp)
1805 			zfs_close(zfp);
1806 		return (-1);
1807 	}
1808 
1809 	if (zfp) {
1810 		remove_mountpoint(zfp);
1811 		zfs_close(zfp);
1812 	}
1813 
1814 	return (0);
1815 }
1816 
1817 /*
1818  * Create a checkpoint in the given pool.
1819  */
1820 int
1821 zpool_checkpoint(zpool_handle_t *zhp)
1822 {
1823 	libzfs_handle_t *hdl = zhp->zpool_hdl;
1824 	char errbuf[ERRBUFLEN];
1825 	int error;
1826 
1827 	error = lzc_pool_checkpoint(zhp->zpool_name);
1828 	if (error != 0) {
1829 		(void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
1830 		    "cannot checkpoint '%s'"), zhp->zpool_name);
1831 		(void) zpool_standard_error(hdl, error, errbuf);
1832 		return (-1);
1833 	}
1834 
1835 	return (0);
1836 }
1837 
1838 /*
1839  * Discard the checkpoint from the given pool.
1840  */
1841 int
1842 zpool_discard_checkpoint(zpool_handle_t *zhp)
1843 {
1844 	libzfs_handle_t *hdl = zhp->zpool_hdl;
1845 	char errbuf[ERRBUFLEN];
1846 	int error;
1847 
1848 	error = lzc_pool_checkpoint_discard(zhp->zpool_name);
1849 	if (error != 0) {
1850 		(void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
1851 		    "cannot discard checkpoint in '%s'"), zhp->zpool_name);
1852 		(void) zpool_standard_error(hdl, error, errbuf);
1853 		return (-1);
1854 	}
1855 
1856 	return (0);
1857 }
1858 
1859 /*
1860  * Load data type for the given pool.
1861  */
1862 int
1863 zpool_prefetch(zpool_handle_t *zhp, zpool_prefetch_type_t type)
1864 {
1865 	libzfs_handle_t *hdl = zhp->zpool_hdl;
1866 	char msg[1024];
1867 	int error;
1868 
1869 	error = lzc_pool_prefetch(zhp->zpool_name, type);
1870 	if (error != 0) {
1871 		const char *typename = "unknown";
1872 		if (type == ZPOOL_PREFETCH_DDT)
1873 			typename = "ddt";
1874 		else if (type == ZPOOL_PREFETCH_BRT)
1875 			typename = "brt";
1876 		(void) snprintf(msg, sizeof (msg), dgettext(TEXT_DOMAIN,
1877 		    "cannot prefetch %s in '%s'"), typename, zhp->zpool_name);
1878 		(void) zpool_standard_error(hdl, error, msg);
1879 		return (-1);
1880 	}
1881 
1882 	return (0);
1883 }
1884 
1885 /*
1886  * Add the given vdevs to the pool.  The caller must have already performed the
1887  * necessary verification to ensure that the vdev specification is well-formed.
1888  */
1889 int
1890 zpool_add(zpool_handle_t *zhp, nvlist_t *nvroot, boolean_t check_ashift)
1891 {
1892 	zfs_cmd_t zc = {"\0"};
1893 	int ret;
1894 	libzfs_handle_t *hdl = zhp->zpool_hdl;
1895 	char errbuf[ERRBUFLEN];
1896 	nvlist_t **spares, **l2cache;
1897 	uint_t nspares, nl2cache;
1898 
1899 	(void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
1900 	    "cannot add to '%s'"), zhp->zpool_name);
1901 
1902 	if (zpool_get_prop_int(zhp, ZPOOL_PROP_VERSION, NULL) <
1903 	    SPA_VERSION_SPARES &&
1904 	    nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_SPARES,
1905 	    &spares, &nspares) == 0) {
1906 		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "pool must be "
1907 		    "upgraded to add hot spares"));
1908 		return (zfs_error(hdl, EZFS_BADVERSION, errbuf));
1909 	}
1910 
1911 	if (zpool_get_prop_int(zhp, ZPOOL_PROP_VERSION, NULL) <
1912 	    SPA_VERSION_L2CACHE &&
1913 	    nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_L2CACHE,
1914 	    &l2cache, &nl2cache) == 0) {
1915 		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "pool must be "
1916 		    "upgraded to add cache devices"));
1917 		return (zfs_error(hdl, EZFS_BADVERSION, errbuf));
1918 	}
1919 
1920 	zcmd_write_conf_nvlist(hdl, &zc, nvroot);
1921 	(void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
1922 	zc.zc_flags = check_ashift;
1923 
1924 	if (zfs_ioctl(hdl, ZFS_IOC_VDEV_ADD, &zc) != 0) {
1925 		switch (errno) {
1926 		case EBUSY:
1927 			/*
1928 			 * This can happen if the user has specified the same
1929 			 * device multiple times.  We can't reliably detect this
1930 			 * until we try to add it and see we already have a
1931 			 * label.
1932 			 */
1933 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1934 			    "one or more vdevs refer to the same device"));
1935 			(void) zfs_error(hdl, EZFS_BADDEV, errbuf);
1936 			break;
1937 
1938 		case EINVAL:
1939 
1940 			if (zpool_has_draid_vdev(nvroot) &&
1941 			    zfeature_lookup_name("draid", NULL) != 0) {
1942 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1943 				    "dRAID vdevs are unsupported by the "
1944 				    "kernel"));
1945 			} else {
1946 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1947 				    "invalid config; a pool with removing/"
1948 				    "removed vdevs does not support adding "
1949 				    "raidz or dRAID vdevs"));
1950 			}
1951 
1952 			(void) zfs_error(hdl, EZFS_BADDEV, errbuf);
1953 			break;
1954 
1955 		case EOVERFLOW:
1956 			/*
1957 			 * This occurs when one of the devices is below
1958 			 * SPA_MINDEVSIZE.  Unfortunately, we can't detect which
1959 			 * device was the problem device since there's no
1960 			 * reliable way to determine device size from userland.
1961 			 */
1962 			{
1963 				char buf[64];
1964 
1965 				zfs_nicebytes(SPA_MINDEVSIZE, buf,
1966 				    sizeof (buf));
1967 
1968 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1969 				    "device is less than the minimum "
1970 				    "size (%s)"), buf);
1971 			}
1972 			(void) zfs_error(hdl, EZFS_BADDEV, errbuf);
1973 			break;
1974 
1975 		case ENOTSUP:
1976 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1977 			    "pool must be upgraded to add these vdevs"));
1978 			(void) zfs_error(hdl, EZFS_BADVERSION, errbuf);
1979 			break;
1980 
1981 		default:
1982 			(void) zpool_standard_error(hdl, errno, errbuf);
1983 		}
1984 
1985 		ret = -1;
1986 	} else {
1987 		ret = 0;
1988 	}
1989 
1990 	zcmd_free_nvlists(&zc);
1991 
1992 	return (ret);
1993 }
1994 
1995 /*
1996  * Exports the pool from the system.  The caller must ensure that there are no
1997  * mounted datasets in the pool.
1998  */
1999 static int
2000 zpool_export_common(zpool_handle_t *zhp, boolean_t force, boolean_t hardforce,
2001     const char *log_str)
2002 {
2003 	zfs_cmd_t zc = {"\0"};
2004 
2005 	(void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
2006 	zc.zc_cookie = force;
2007 	zc.zc_guid = hardforce;
2008 	zc.zc_history = (uint64_t)(uintptr_t)log_str;
2009 
2010 	if (zfs_ioctl(zhp->zpool_hdl, ZFS_IOC_POOL_EXPORT, &zc) != 0) {
2011 		switch (errno) {
2012 		case EXDEV:
2013 			zfs_error_aux(zhp->zpool_hdl, dgettext(TEXT_DOMAIN,
2014 			    "use '-f' to override the following errors:\n"
2015 			    "'%s' has an active shared spare which could be"
2016 			    " used by other pools once '%s' is exported."),
2017 			    zhp->zpool_name, zhp->zpool_name);
2018 			return (zfs_error_fmt(zhp->zpool_hdl, EZFS_ACTIVE_SPARE,
2019 			    dgettext(TEXT_DOMAIN, "cannot export '%s'"),
2020 			    zhp->zpool_name));
2021 		default:
2022 			return (zpool_standard_error_fmt(zhp->zpool_hdl, errno,
2023 			    dgettext(TEXT_DOMAIN, "cannot export '%s'"),
2024 			    zhp->zpool_name));
2025 		}
2026 	}
2027 
2028 	return (0);
2029 }
2030 
2031 /*
2032  * Export the pool from the system.  Setting force overrides the
2033  * active-shared-spare check.  The caller must unmount all datasets
2034  * in the pool first.
2035  */
2036 int
2037 zpool_export(zpool_handle_t *zhp, boolean_t force, const char *log_str)
2038 {
2039 	return (zpool_export_common(zhp, force, B_FALSE, log_str));
2040 }
2041 
2042 /*
2043  * Force-export the pool: bypasses the active-shared-spare check, and skips
2044  * writing the exported-state labels and updating the cachefile.
2045  */
2046 int
2047 zpool_export_force(zpool_handle_t *zhp, const char *log_str)
2048 {
2049 	return (zpool_export_common(zhp, B_TRUE, B_TRUE, log_str));
2050 }
2051 
2052 static void
2053 zpool_rewind_exclaim(libzfs_handle_t *hdl, const char *name, nvlist_t *config)
2054 {
2055 	nvlist_t *nv = NULL;
2056 	boolean_t dryrun;
2057 	uint64_t rewindto, rewindtxg;
2058 	int64_t loss = 0;
2059 	time_t when;
2060 	char timestr[26], whenstr[64];
2061 
2062 	if (!hdl->libzfs_printerr || config == NULL)
2063 		return;
2064 
2065 	if (nvlist_lookup_nvlist(config, ZPOOL_CONFIG_LOAD_INFO, &nv) != 0)
2066 		return;
2067 
2068 	/*
2069 	 * The kernel reports the load it did not commit nested, so the
2070 	 * nesting is what tells a hypothetical rewind from a real one.
2071 	 */
2072 	dryrun = nvlist_lookup_nvlist(nv, ZPOOL_CONFIG_REWIND_INFO, &nv) == 0;
2073 
2074 	if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_LOAD_TIME, &rewindto) != 0)
2075 		return;
2076 
2077 	/*
2078 	 * The loss is reported only if the load fell back to an older
2079 	 * uberblock, so an enacted load without it discarded nothing.
2080 	 */
2081 	if (nvlist_lookup_int64(nv, ZPOOL_CONFIG_REWIND_TIME, &loss) != 0 &&
2082 	    !dryrun)
2083 		return;
2084 
2085 	if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_LOAD_TXG, &rewindtxg) != 0)
2086 		rewindtxg = 0;
2087 
2088 	when = (time_t)rewindto;
2089 	if (ctime_r(&when, timestr) != NULL) {
2090 		timestr[24] = '\0';
2091 	} else {
2092 		(void) snprintf(timestr, sizeof (timestr), "%llu",
2093 		    (u_longlong_t)rewindto);
2094 	}
2095 
2096 	if (rewindtxg != 0) {
2097 		(void) snprintf(whenstr, sizeof (whenstr), "%s (txg %llu)",
2098 		    timestr, (u_longlong_t)rewindtxg);
2099 	} else {
2100 		(void) strlcpy(whenstr, timestr, sizeof (whenstr));
2101 	}
2102 
2103 	if (dryrun) {
2104 		(void) printf(dgettext(TEXT_DOMAIN,
2105 		    "Would be able to return %s to its state as of %s.\n"),
2106 		    name, whenstr);
2107 	} else {
2108 		(void) printf(dgettext(TEXT_DOMAIN,
2109 		    "Pool %s returned to its state as of %s.\n"),
2110 		    name, whenstr);
2111 	}
2112 	if (loss > 120) {
2113 		(void) printf(dgettext(TEXT_DOMAIN,
2114 		    "%s approximately %lld minutes of transactions.\n"),
2115 		    dryrun ? "Would discard" : "Discarded",
2116 		    ((longlong_t)loss + 30) / 60);
2117 	} else if (loss > 0) {
2118 		(void) printf(dgettext(TEXT_DOMAIN,
2119 		    "%s approximately %lld seconds of transactions.\n"),
2120 		    dryrun ? "Would discard" : "Discarded",
2121 		    (longlong_t)loss);
2122 	}
2123 }
2124 
2125 void
2126 zpool_explain_recover(libzfs_handle_t *hdl, const char *name, int reason,
2127     nvlist_t *config, char *buf, size_t size)
2128 {
2129 	nvlist_t *nv = NULL;
2130 	int64_t loss = -1;
2131 	uint64_t edata = UINT64_MAX;
2132 	uint64_t rewindto;
2133 	struct tm t;
2134 	char timestr[128], temp[1024];
2135 
2136 	if (!hdl->libzfs_printerr)
2137 		return;
2138 
2139 	/* All attempted rewinds failed if ZPOOL_CONFIG_LOAD_TIME missing */
2140 	if (nvlist_lookup_nvlist(config, ZPOOL_CONFIG_LOAD_INFO, &nv) != 0 ||
2141 	    nvlist_lookup_nvlist(nv, ZPOOL_CONFIG_REWIND_INFO, &nv) != 0 ||
2142 	    nvlist_lookup_uint64(nv, ZPOOL_CONFIG_LOAD_TIME, &rewindto) != 0)
2143 		goto no_info;
2144 
2145 	(void) nvlist_lookup_int64(nv, ZPOOL_CONFIG_REWIND_TIME, &loss);
2146 	(void) nvlist_lookup_uint64(nv, ZPOOL_CONFIG_LOAD_DATA_ERRORS,
2147 	    &edata);
2148 
2149 	(void) snprintf(buf, size, dgettext(TEXT_DOMAIN,
2150 	    "Recovery is possible, but will result in some data loss.\n"));
2151 
2152 	if (localtime_r((time_t *)&rewindto, &t) != NULL &&
2153 	    ctime_r((time_t *)&rewindto, timestr) != NULL) {
2154 		timestr[24] = 0;
2155 		(void) snprintf(temp, 1024, dgettext(TEXT_DOMAIN,
2156 		    "\tReturning the pool to its state as of %s\n"
2157 		    "\tshould correct the problem.  "), timestr);
2158 		(void) strlcat(buf, temp, size);
2159 	} else {
2160 		(void) strlcat(buf, dgettext(TEXT_DOMAIN,
2161 		    "\tReverting the pool to an earlier state "
2162 		    "should correct the problem.\n\t"), size);
2163 	}
2164 
2165 	if (loss > 120) {
2166 		(void) snprintf(temp, 1024, dgettext(TEXT_DOMAIN,
2167 		    "Approximately %lld minutes of data\n"
2168 		    "\tmust be discarded, irreversibly.  "),
2169 		    ((longlong_t)loss + 30) / 60);
2170 		(void) strlcat(buf, temp, size);
2171 	} else if (loss > 0) {
2172 		(void) snprintf(temp, 1024, dgettext(TEXT_DOMAIN,
2173 		    "Approximately %lld seconds of data\n"
2174 		    "\tmust be discarded, irreversibly.  "),
2175 		    (longlong_t)loss);
2176 		(void) strlcat(buf, temp, size);
2177 	}
2178 	if (edata != 0 && edata != UINT64_MAX) {
2179 		if (edata == 1) {
2180 			(void) strlcat(buf, dgettext(TEXT_DOMAIN,
2181 			    "After rewind, at least\n"
2182 			    "\tone persistent user-data error will remain.  "),
2183 			    size);
2184 		} else {
2185 			(void) strlcat(buf, dgettext(TEXT_DOMAIN,
2186 			    "After rewind, several\n"
2187 			    "\tpersistent user-data errors will remain.  "),
2188 			    size);
2189 		}
2190 	}
2191 	(void) snprintf(temp, 1024, dgettext(TEXT_DOMAIN,
2192 	    "Recovery can be attempted\n\tby executing 'zpool %s -F %s'.  "),
2193 	    reason >= 0 ? "clear" : "import", name);
2194 	(void) strlcat(buf, temp, size);
2195 
2196 	(void) strlcat(buf, dgettext(TEXT_DOMAIN,
2197 	    "A scrub of the pool\n"
2198 	    "\tis strongly recommended after recovery.\n"), size);
2199 	return;
2200 
2201 no_info:
2202 	(void) strlcat(buf, dgettext(TEXT_DOMAIN,
2203 	    "Ensure all pool devices are present and accessible, then "
2204 	    "retry the import.\n\tIf the problem persists, destroy and "
2205 	    "re-create the pool from a backup source.\n"), size);
2206 }
2207 
2208 /*
2209  * zpool_import() is a contracted interface. Should be kept the same
2210  * if possible.
2211  *
2212  * Applications should use zpool_import_props() to import a pool with
2213  * new properties value to be set.
2214  */
2215 int
2216 zpool_import(libzfs_handle_t *hdl, nvlist_t *config, const char *newname,
2217     char *altroot)
2218 {
2219 	nvlist_t *props = NULL;
2220 	int ret;
2221 
2222 	if (altroot != NULL) {
2223 		if (nvlist_alloc(&props, NV_UNIQUE_NAME, 0) != 0) {
2224 			return (zfs_error_fmt(hdl, EZFS_NOMEM,
2225 			    dgettext(TEXT_DOMAIN, "cannot import '%s'"),
2226 			    newname));
2227 		}
2228 
2229 		if (nvlist_add_string(props,
2230 		    zpool_prop_to_name(ZPOOL_PROP_ALTROOT), altroot) != 0 ||
2231 		    nvlist_add_string(props,
2232 		    zpool_prop_to_name(ZPOOL_PROP_CACHEFILE), "none") != 0) {
2233 			nvlist_free(props);
2234 			return (zfs_error_fmt(hdl, EZFS_NOMEM,
2235 			    dgettext(TEXT_DOMAIN, "cannot import '%s'"),
2236 			    newname));
2237 		}
2238 	}
2239 
2240 	ret = zpool_import_props(hdl, config, newname, props,
2241 	    ZFS_IMPORT_NORMAL);
2242 	nvlist_free(props);
2243 	return (ret);
2244 }
2245 
2246 static void
2247 print_vdev_tree(libzfs_handle_t *hdl, const char *name, nvlist_t *nv,
2248     int indent)
2249 {
2250 	nvlist_t **child;
2251 	uint_t c, children;
2252 	char *vname;
2253 	uint64_t is_log = 0;
2254 
2255 	(void) nvlist_lookup_uint64(nv, ZPOOL_CONFIG_IS_LOG,
2256 	    &is_log);
2257 
2258 	if (name != NULL)
2259 		(void) printf("\t%*s%s%s\n", indent, "", name,
2260 		    is_log ? " [log]" : "");
2261 
2262 	if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
2263 	    &child, &children) != 0)
2264 		return;
2265 
2266 	for (c = 0; c < children; c++) {
2267 		vname = zpool_vdev_name(hdl, NULL, child[c], VDEV_NAME_TYPE_ID);
2268 		print_vdev_tree(hdl, vname, child[c], indent + 2);
2269 		free(vname);
2270 	}
2271 }
2272 
2273 void
2274 zpool_collect_unsup_feat(nvlist_t *config, char *buf, size_t size)
2275 {
2276 	nvlist_t *nvinfo, *unsup_feat;
2277 	char temp[512];
2278 
2279 	nvinfo = fnvlist_lookup_nvlist(config, ZPOOL_CONFIG_LOAD_INFO);
2280 	unsup_feat = fnvlist_lookup_nvlist(nvinfo, ZPOOL_CONFIG_UNSUP_FEAT);
2281 
2282 	for (nvpair_t *nvp = nvlist_next_nvpair(unsup_feat, NULL);
2283 	    nvp != NULL; nvp = nvlist_next_nvpair(unsup_feat, nvp)) {
2284 		const char *desc = fnvpair_value_string(nvp);
2285 		if (strlen(desc) > 0) {
2286 			(void) snprintf(temp, 512, "\t%s (%s)\n",
2287 			    nvpair_name(nvp), desc);
2288 			(void) strlcat(buf, temp, size);
2289 		} else {
2290 			(void) snprintf(temp, 512, "\t%s\n", nvpair_name(nvp));
2291 			(void) strlcat(buf, temp, size);
2292 		}
2293 	}
2294 }
2295 
2296 /*
2297  * Import the given pool using the known configuration and a list of
2298  * properties to be set. The configuration should have come from
2299  * zpool_find_import(). The 'newname' parameters control whether the pool
2300  * is imported with a different name.
2301  */
2302 int
2303 zpool_import_props(libzfs_handle_t *hdl, nvlist_t *config, const char *newname,
2304     nvlist_t *props, int flags)
2305 {
2306 	zfs_cmd_t zc = {"\0"};
2307 	zpool_load_policy_t policy;
2308 	nvlist_t *nv = NULL;
2309 	nvlist_t *nvinfo = NULL;
2310 	nvlist_t *missing = NULL;
2311 	const char *thename;
2312 	const char *origname;
2313 	int ret;
2314 	int error = 0;
2315 	char buf[2048];
2316 	char errbuf[ERRBUFLEN];
2317 
2318 	origname = fnvlist_lookup_string(config, ZPOOL_CONFIG_POOL_NAME);
2319 
2320 	(void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
2321 	    "cannot import pool '%s'"), origname);
2322 
2323 	if (newname != NULL) {
2324 		if (!zpool_name_valid(hdl, B_FALSE, newname))
2325 			return (zfs_error_fmt(hdl, EZFS_INVALIDNAME,
2326 			    dgettext(TEXT_DOMAIN, "cannot import '%s'"),
2327 			    newname));
2328 		thename = newname;
2329 	} else {
2330 		thename = origname;
2331 	}
2332 
2333 	if (props != NULL) {
2334 		uint64_t version;
2335 		prop_flags_t flags = { .create = B_FALSE, .import = B_TRUE };
2336 
2337 		version = fnvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION);
2338 
2339 		if ((props = zpool_valid_proplist(hdl, origname,
2340 		    props, version, flags, errbuf)) == NULL)
2341 			return (-1);
2342 		zcmd_write_src_nvlist(hdl, &zc, props);
2343 		nvlist_free(props);
2344 	}
2345 
2346 	(void) strlcpy(zc.zc_name, thename, sizeof (zc.zc_name));
2347 
2348 	zc.zc_guid = fnvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_GUID);
2349 
2350 	zcmd_write_conf_nvlist(hdl, &zc, config);
2351 	zcmd_alloc_dst_nvlist(hdl, &zc, zc.zc_nvlist_conf_size * 2);
2352 
2353 	zc.zc_cookie = flags;
2354 	while ((ret = zfs_ioctl(hdl, ZFS_IOC_POOL_IMPORT, &zc)) != 0 &&
2355 	    errno == ENOMEM)
2356 		zcmd_expand_dst_nvlist(hdl, &zc);
2357 	if (ret != 0)
2358 		error = errno;
2359 
2360 	(void) zcmd_read_dst_nvlist(hdl, &zc, &nv);
2361 
2362 	zcmd_free_nvlists(&zc);
2363 
2364 	zpool_get_load_policy(config, &policy);
2365 
2366 	if (getenv("ZFS_LOAD_INFO_DEBUG") && nv != NULL &&
2367 	    nvlist_lookup_nvlist(nv, ZPOOL_CONFIG_LOAD_INFO, &nvinfo) == 0) {
2368 		dump_nvlist(nvinfo, 4);
2369 	}
2370 
2371 	if (error) {
2372 		char desc[1024];
2373 		char aux[256];
2374 
2375 		/*
2376 		 * Dry-run failed, but we print out what success
2377 		 * looks like if we found a best txg
2378 		 */
2379 		if (policy.zlp_rewind & ZPOOL_TRY_REWIND) {
2380 			zpool_rewind_exclaim(hdl, newname ? origname : thename,
2381 			    nv);
2382 			nvlist_free(nv);
2383 			return (-1);
2384 		}
2385 
2386 		if (newname == NULL)
2387 			(void) snprintf(desc, sizeof (desc),
2388 			    dgettext(TEXT_DOMAIN, "cannot import '%s'"),
2389 			    thename);
2390 		else
2391 			(void) snprintf(desc, sizeof (desc),
2392 			    dgettext(TEXT_DOMAIN, "cannot import '%s' as '%s'"),
2393 			    origname, thename);
2394 
2395 		switch (error) {
2396 		case ENOTSUP:
2397 			if (nv != NULL && nvlist_lookup_nvlist(nv,
2398 			    ZPOOL_CONFIG_LOAD_INFO, &nvinfo) == 0 &&
2399 			    nvlist_exists(nvinfo, ZPOOL_CONFIG_UNSUP_FEAT)) {
2400 				(void) printf(dgettext(TEXT_DOMAIN, "This "
2401 				    "pool uses the following feature(s) not "
2402 				    "supported by this system:\n"));
2403 				memset(buf, 0, 2048);
2404 				zpool_collect_unsup_feat(nv, buf, 2048);
2405 				(void) printf("%s", buf);
2406 				if (nvlist_exists(nvinfo,
2407 				    ZPOOL_CONFIG_CAN_RDONLY)) {
2408 					(void) printf(dgettext(TEXT_DOMAIN,
2409 					    "All unsupported features are only "
2410 					    "required for writing to the pool."
2411 					    "\nThe pool can be imported using "
2412 					    "'-o readonly=on'.\n"));
2413 				}
2414 			}
2415 			/*
2416 			 * Unsupported version.
2417 			 */
2418 			(void) zfs_error(hdl, EZFS_BADVERSION, desc);
2419 			break;
2420 
2421 		case EREMOTEIO:
2422 			if (nv != NULL && nvlist_lookup_nvlist(nv,
2423 			    ZPOOL_CONFIG_LOAD_INFO, &nvinfo) == 0) {
2424 				const char *hostname = "<unknown>";
2425 				uint64_t hostid = 0;
2426 				mmp_state_t mmp_state;
2427 				uint32_t mmp_result = 0;
2428 
2429 				mmp_state = fnvlist_lookup_uint64(nvinfo,
2430 				    ZPOOL_CONFIG_MMP_STATE);
2431 
2432 				/*
2433 				 * A kernel which does not report a cause
2434 				 * leaves this zero, which falls through to
2435 				 * the messages below.
2436 				 */
2437 				if (nvlist_exists(nvinfo,
2438 				    ZPOOL_CONFIG_MMP_RESULT))
2439 					mmp_result = fnvlist_lookup_uint32(
2440 					    nvinfo, ZPOOL_CONFIG_MMP_RESULT);
2441 
2442 				if (nvlist_exists(nvinfo,
2443 				    ZPOOL_CONFIG_MMP_HOSTNAME))
2444 					hostname = fnvlist_lookup_string(nvinfo,
2445 					    ZPOOL_CONFIG_MMP_HOSTNAME);
2446 
2447 				if (nvlist_exists(nvinfo,
2448 				    ZPOOL_CONFIG_MMP_HOSTID))
2449 					hostid = fnvlist_lookup_uint64(nvinfo,
2450 					    ZPOOL_CONFIG_MMP_HOSTID);
2451 
2452 				if (mmp_result == ENODEV) {
2453 					(void) snprintf(aux, sizeof (aux),
2454 					    dgettext(TEXT_DOMAIN, "the multi"
2455 					    "host claim could not be written "
2456 					    "to a device\nthe pool "
2457 					    "configuration expects to be "
2458 					    "present.\nIf the device is "
2459 					    "permanently gone, recover with "
2460 					    "'zhack mmp reclaim'."));
2461 				} else if (mmp_result == EIO) {
2462 					(void) snprintf(aux, sizeof (aux),
2463 					    dgettext(TEXT_DOMAIN, "I/O errors "
2464 					    "occurred while writing the multi"
2465 					    "host claim.\nClear the device "
2466 					    "errors, then run 'zpool "
2467 					    "import'."));
2468 				} else if (mmp_state == MMP_STATE_ACTIVE) {
2469 					(void) snprintf(aux, sizeof (aux),
2470 					    dgettext(TEXT_DOMAIN, "pool is imp"
2471 					    "orted on host '%s' (hostid=%lx).\n"
2472 					    "Export the pool on the other "
2473 					    "system, then run 'zpool import'."),
2474 					    hostname, (unsigned long) hostid);
2475 				} else if (mmp_state == MMP_STATE_NO_HOSTID) {
2476 					(void) snprintf(aux, sizeof (aux),
2477 					    dgettext(TEXT_DOMAIN, "pool has "
2478 					    "the multihost property on and "
2479 					    "the\nsystem's hostid is not set. "
2480 					    "Set a unique system hostid with "
2481 					    "the zgenhostid(8) command.\n"));
2482 				}
2483 
2484 				(void) zfs_error_aux(hdl, "%s", aux);
2485 			}
2486 			(void) zfs_error(hdl, EZFS_ACTIVE_POOL, desc);
2487 			break;
2488 
2489 		case EINVAL:
2490 			(void) zfs_error(hdl, EZFS_INVALCONFIG, desc);
2491 			break;
2492 
2493 		case EROFS:
2494 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
2495 			    "one or more devices is read only"));
2496 			(void) zfs_error(hdl, EZFS_BADDEV, desc);
2497 			break;
2498 
2499 		case ENXIO:
2500 			if (nv && nvlist_lookup_nvlist(nv,
2501 			    ZPOOL_CONFIG_LOAD_INFO, &nvinfo) == 0 &&
2502 			    nvlist_lookup_nvlist(nvinfo,
2503 			    ZPOOL_CONFIG_MISSING_DEVICES, &missing) == 0) {
2504 				(void) printf(dgettext(TEXT_DOMAIN,
2505 				    "The devices below are missing or "
2506 				    "corrupted, use '-m' to import the pool "
2507 				    "anyway:\n"));
2508 				print_vdev_tree(hdl, NULL, missing, 2);
2509 				(void) printf("\n");
2510 			}
2511 			(void) zpool_standard_error(hdl, error, desc);
2512 			break;
2513 
2514 		case EEXIST:
2515 			(void) zpool_standard_error(hdl, error, desc);
2516 			break;
2517 
2518 		case EBUSY:
2519 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
2520 			    "one or more devices are already in use\n"));
2521 			(void) zfs_error(hdl, EZFS_BADDEV, desc);
2522 			break;
2523 		case ENAMETOOLONG:
2524 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
2525 			    "new name of at least one dataset is longer than "
2526 			    "the maximum allowable length"));
2527 			(void) zfs_error(hdl, EZFS_NAMETOOLONG, desc);
2528 			break;
2529 		default:
2530 			(void) zpool_standard_error(hdl, error, desc);
2531 			memset(buf, 0, 2048);
2532 			zpool_explain_recover(hdl,
2533 			    newname ? origname : thename, -error, nv,
2534 			    buf, 2048);
2535 			(void) printf("\t%s", buf);
2536 			break;
2537 		}
2538 
2539 		nvlist_free(nv);
2540 		ret = -1;
2541 	} else {
2542 		zpool_handle_t *zhp;
2543 
2544 		/*
2545 		 * This should never fail, but play it safe anyway.
2546 		 */
2547 		if (zpool_open_silent(hdl, thename, &zhp) != 0)
2548 			ret = -1;
2549 		else if (zhp != NULL)
2550 			zpool_close(zhp);
2551 		if (policy.zlp_rewind &
2552 		    (ZPOOL_DO_REWIND | ZPOOL_TRY_REWIND)) {
2553 			zpool_rewind_exclaim(hdl, newname ? origname : thename,
2554 			    nv);
2555 		}
2556 		nvlist_free(nv);
2557 	}
2558 
2559 	return (ret);
2560 }
2561 
2562 /*
2563  * Translate vdev names to guids.  If a vdev_path is determined to be
2564  * unsuitable then a vd_errlist is allocated and the vdev path and errno
2565  * are added to it.
2566  */
2567 static int
2568 zpool_translate_vdev_guids(zpool_handle_t *zhp, nvlist_t *vds,
2569     nvlist_t *vdev_guids, nvlist_t *guids_to_paths, nvlist_t **vd_errlist)
2570 {
2571 	nvlist_t *errlist = NULL;
2572 	int error = 0;
2573 
2574 	for (nvpair_t *elem = nvlist_next_nvpair(vds, NULL); elem != NULL;
2575 	    elem = nvlist_next_nvpair(vds, elem)) {
2576 		boolean_t spare, cache;
2577 
2578 		const char *vd_path = nvpair_name(elem);
2579 		nvlist_t *tgt = zpool_find_vdev(zhp, vd_path, &spare, &cache,
2580 		    NULL);
2581 
2582 		if ((tgt == NULL) || cache || spare) {
2583 			if (errlist == NULL) {
2584 				errlist = fnvlist_alloc();
2585 				error = EINVAL;
2586 			}
2587 
2588 			uint64_t err = (tgt == NULL) ? EZFS_NODEVICE :
2589 			    (spare ? EZFS_ISSPARE : EZFS_ISL2CACHE);
2590 			fnvlist_add_int64(errlist, vd_path, err);
2591 			continue;
2592 		}
2593 
2594 		uint64_t guid = fnvlist_lookup_uint64(tgt, ZPOOL_CONFIG_GUID);
2595 		fnvlist_add_uint64(vdev_guids, vd_path, guid);
2596 
2597 		char msg[MAXNAMELEN];
2598 		(void) snprintf(msg, sizeof (msg), "%llu", (u_longlong_t)guid);
2599 		fnvlist_add_string(guids_to_paths, msg, vd_path);
2600 	}
2601 
2602 	if (error != 0) {
2603 		verify(errlist != NULL);
2604 		if (vd_errlist != NULL)
2605 			*vd_errlist = errlist;
2606 		else
2607 			fnvlist_free(errlist);
2608 	}
2609 
2610 	return (error);
2611 }
2612 
2613 static int
2614 xlate_init_err(int err)
2615 {
2616 	switch (err) {
2617 	case ENODEV:
2618 		return (EZFS_NODEVICE);
2619 	case EINVAL:
2620 	case EROFS:
2621 		return (EZFS_BADDEV);
2622 	case EBUSY:
2623 		return (EZFS_INITIALIZING);
2624 	case ESRCH:
2625 		return (EZFS_NO_INITIALIZE);
2626 	}
2627 	return (err);
2628 }
2629 
2630 /*
2631  * Start (or cancel/suspend/uninit) the initialize operation on every
2632  * leaf vdev of the pool.
2633  */
2634 int
2635 zpool_initialize_one(zpool_handle_t *zhp, void *data)
2636 {
2637 	int error;
2638 	libzfs_handle_t *hdl = zpool_get_handle(zhp);
2639 	const char *pool_name = zpool_get_name(zhp);
2640 	if (zpool_open_silent(hdl, pool_name, &zhp) != 0)
2641 		return (-1);
2642 	initialize_cbdata_t *cb = data;
2643 	nvlist_t *vdevs = fnvlist_alloc();
2644 
2645 	nvlist_t *config = zpool_get_config(zhp, NULL);
2646 	nvlist_t *nvroot = fnvlist_lookup_nvlist(config,
2647 	    ZPOOL_CONFIG_VDEV_TREE);
2648 	zpool_collect_leaves(zhp, nvroot, vdevs);
2649 	if (cb->wait)
2650 		error = zpool_initialize_wait(zhp, cb->cmd_type, vdevs,
2651 		    cb->value, cb->value_provided);
2652 	else
2653 		error = zpool_initialize(zhp, cb->cmd_type, vdevs,
2654 		    cb->value, cb->value_provided);
2655 	fnvlist_free(vdevs);
2656 
2657 	return (error);
2658 }
2659 
2660 /*
2661  * Begin, suspend, cancel, or uninit (clear) the initialization (initializing
2662  * of all free blocks) for the given vdevs in the given pool.
2663  */
2664 static int
2665 zpool_initialize_impl(zpool_handle_t *zhp, pool_initialize_func_t cmd_type,
2666     nvlist_t *vds, uint64_t value, boolean_t value_provided, boolean_t wait)
2667 {
2668 	int err;
2669 
2670 	nvlist_t *vdev_guids = fnvlist_alloc();
2671 	nvlist_t *guids_to_paths = fnvlist_alloc();
2672 	nvlist_t *vd_errlist = NULL;
2673 	nvlist_t *errlist;
2674 	nvpair_t *elem;
2675 
2676 	err = zpool_translate_vdev_guids(zhp, vds, vdev_guids,
2677 	    guids_to_paths, &vd_errlist);
2678 
2679 	if (err != 0) {
2680 		verify(vd_errlist != NULL);
2681 		goto list_errors;
2682 	}
2683 
2684 	err = lzc_initialize(zhp->zpool_name, cmd_type,
2685 	    value, value_provided, vdev_guids, &errlist);
2686 
2687 	if (err != 0) {
2688 		if (errlist != NULL && nvlist_lookup_nvlist(errlist,
2689 		    ZPOOL_INITIALIZE_VDEVS, &vd_errlist) == 0) {
2690 			goto list_errors;
2691 		}
2692 
2693 		if (err == EINVAL && cmd_type == POOL_INITIALIZE_UNINIT) {
2694 			zfs_error_aux(zhp->zpool_hdl, dgettext(TEXT_DOMAIN,
2695 			    "uninitialize is not supported by kernel"));
2696 		}
2697 
2698 		(void) zpool_standard_error(zhp->zpool_hdl, err,
2699 		    dgettext(TEXT_DOMAIN, "operation failed"));
2700 		goto out;
2701 	}
2702 
2703 	if (wait) {
2704 		for (elem = nvlist_next_nvpair(vdev_guids, NULL); elem != NULL;
2705 		    elem = nvlist_next_nvpair(vdev_guids, elem)) {
2706 
2707 			uint64_t guid = fnvpair_value_uint64(elem);
2708 
2709 			err = lzc_wait_tag(zhp->zpool_name,
2710 			    ZPOOL_WAIT_INITIALIZE, guid, NULL);
2711 			if (err != 0) {
2712 				(void) zpool_standard_error_fmt(zhp->zpool_hdl,
2713 				    err, dgettext(TEXT_DOMAIN, "error "
2714 				    "waiting for '%s' to initialize"),
2715 				    nvpair_name(elem));
2716 
2717 				goto out;
2718 			}
2719 		}
2720 	}
2721 	goto out;
2722 
2723 list_errors:
2724 	for (elem = nvlist_next_nvpair(vd_errlist, NULL); elem != NULL;
2725 	    elem = nvlist_next_nvpair(vd_errlist, elem)) {
2726 		int64_t vd_error = xlate_init_err(fnvpair_value_int64(elem));
2727 		const char *path;
2728 
2729 		if (nvlist_lookup_string(guids_to_paths, nvpair_name(elem),
2730 		    &path) != 0)
2731 			path = nvpair_name(elem);
2732 
2733 		(void) zfs_error_fmt(zhp->zpool_hdl, vd_error,
2734 		    "cannot initialize '%s'", path);
2735 	}
2736 
2737 out:
2738 	fnvlist_free(vdev_guids);
2739 	fnvlist_free(guids_to_paths);
2740 
2741 	if (vd_errlist != NULL)
2742 		fnvlist_free(vd_errlist);
2743 
2744 	return (err == 0 ? 0 : -1);
2745 }
2746 
2747 /*
2748  * Start (or cancel/suspend/uninit) the initialize operation on the listed
2749  * vdevs.  Returns once the new state is committed.
2750  */
2751 int
2752 zpool_initialize(zpool_handle_t *zhp, pool_initialize_func_t cmd_type,
2753     nvlist_t *vds, uint64_t value, boolean_t value_provided)
2754 {
2755 	return (zpool_initialize_impl(zhp, cmd_type, vds, value, value_provided,
2756 	    B_FALSE));
2757 }
2758 
2759 /*
2760  * Like zpool_initialize(), but waits for each listed vdev to finish.
2761  */
2762 int
2763 zpool_initialize_wait(zpool_handle_t *zhp, pool_initialize_func_t cmd_type,
2764     nvlist_t *vds, uint64_t value, boolean_t value_provided)
2765 {
2766 	return (zpool_initialize_impl(zhp, cmd_type, vds, value, value_provided,
2767 	    B_TRUE));
2768 }
2769 
2770 static int
2771 xlate_trim_err(int err)
2772 {
2773 	switch (err) {
2774 	case ENODEV:
2775 		return (EZFS_NODEVICE);
2776 	case EINVAL:
2777 	case EROFS:
2778 		return (EZFS_BADDEV);
2779 	case EBUSY:
2780 		return (EZFS_TRIMMING);
2781 	case ESRCH:
2782 		return (EZFS_NO_TRIM);
2783 	case EOPNOTSUPP:
2784 		return (EZFS_TRIM_NOTSUP);
2785 	}
2786 	return (err);
2787 }
2788 
2789 void
2790 zpool_collect_leaves(zpool_handle_t *zhp, nvlist_t *nvroot, nvlist_t *res)
2791 {
2792 	libzfs_handle_t *hdl = zhp->zpool_hdl;
2793 	uint_t children = 0;
2794 	nvlist_t **child;
2795 	uint_t i;
2796 
2797 	(void) nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_CHILDREN,
2798 	    &child, &children);
2799 
2800 	if (children == 0) {
2801 		char *path = zpool_vdev_name(hdl, zhp, nvroot,
2802 		    VDEV_NAME_PATH);
2803 
2804 		if (strcmp(path, VDEV_TYPE_INDIRECT) != 0 &&
2805 		    strcmp(path, VDEV_TYPE_HOLE) != 0)
2806 			fnvlist_add_boolean(res, path);
2807 
2808 		free(path);
2809 		return;
2810 	}
2811 
2812 	for (i = 0; i < children; i++) {
2813 		zpool_collect_leaves(zhp, child[i], res);
2814 	}
2815 }
2816 
2817 /*
2818  * Start (or cancel/suspend) the trim operation on every leaf vdev of
2819  * the pool.
2820  */
2821 int
2822 zpool_trim_one(zpool_handle_t *zhp, void *data)
2823 {
2824 	int error;
2825 	libzfs_handle_t *hdl = zpool_get_handle(zhp);
2826 	const char *pool_name = zpool_get_name(zhp);
2827 	if (zpool_open_silent(hdl, pool_name, &zhp) != 0)
2828 		return (-1);
2829 
2830 	trim_cbdata_t *cb = data;
2831 	nvlist_t *vdevs = fnvlist_alloc();
2832 
2833 	/* no individual leaf vdevs specified, so add them all */
2834 	nvlist_t *config = zpool_get_config(zhp, NULL);
2835 	nvlist_t *nvroot = fnvlist_lookup_nvlist(config,
2836 	    ZPOOL_CONFIG_VDEV_TREE);
2837 
2838 	zpool_collect_leaves(zhp, nvroot, vdevs);
2839 	error = zpool_trim(zhp, cb->cmd_type, vdevs, &cb->trim_flags);
2840 	fnvlist_free(vdevs);
2841 
2842 	return (error);
2843 }
2844 
2845 static int
2846 zpool_trim_wait(zpool_handle_t *zhp, nvlist_t *vdev_guids)
2847 {
2848 	int err;
2849 	nvpair_t *elem;
2850 
2851 	for (elem = nvlist_next_nvpair(vdev_guids, NULL); elem != NULL;
2852 	    elem = nvlist_next_nvpair(vdev_guids, elem)) {
2853 
2854 		uint64_t guid = fnvpair_value_uint64(elem);
2855 
2856 		err = lzc_wait_tag(zhp->zpool_name,
2857 		    ZPOOL_WAIT_TRIM, guid, NULL);
2858 		if (err != 0) {
2859 			(void) zpool_standard_error_fmt(zhp->zpool_hdl,
2860 			    err, dgettext(TEXT_DOMAIN, "error "
2861 			    "waiting to trim '%s'"), nvpair_name(elem));
2862 
2863 			return (err);
2864 		}
2865 	}
2866 	return (0);
2867 }
2868 
2869 /*
2870  * Check errlist and report any errors, omitting ones which should be
2871  * suppressed. Returns B_TRUE if any errors were reported.
2872  */
2873 static boolean_t
2874 check_trim_errs(zpool_handle_t *zhp, trimflags_t *trim_flags,
2875     nvlist_t *guids_to_paths, nvlist_t *vds, nvlist_t *errlist)
2876 {
2877 	nvpair_t *elem;
2878 	boolean_t reported_errs = B_FALSE;
2879 	int num_vds = 0;
2880 	int num_suppressed_errs = 0;
2881 
2882 	for (elem = nvlist_next_nvpair(vds, NULL);
2883 	    elem != NULL; elem = nvlist_next_nvpair(vds, elem)) {
2884 		num_vds++;
2885 	}
2886 
2887 	for (elem = nvlist_next_nvpair(errlist, NULL);
2888 	    elem != NULL; elem = nvlist_next_nvpair(errlist, elem)) {
2889 		int64_t vd_error = xlate_trim_err(fnvpair_value_int64(elem));
2890 		const char *path;
2891 
2892 		/*
2893 		 * If only the pool was specified, and it was not a secure
2894 		 * trim then suppress warnings for individual vdevs which
2895 		 * do not support trimming.
2896 		 */
2897 		if (vd_error == EZFS_TRIM_NOTSUP &&
2898 		    trim_flags->fullpool &&
2899 		    !trim_flags->secure) {
2900 			num_suppressed_errs++;
2901 			continue;
2902 		}
2903 
2904 		reported_errs = B_TRUE;
2905 		if (nvlist_lookup_string(guids_to_paths, nvpair_name(elem),
2906 		    &path) != 0)
2907 			path = nvpair_name(elem);
2908 
2909 		(void) zfs_error_fmt(zhp->zpool_hdl, vd_error,
2910 		    "cannot trim '%s'", path);
2911 	}
2912 
2913 	if (num_suppressed_errs == num_vds) {
2914 		(void) zfs_error_aux(zhp->zpool_hdl, dgettext(TEXT_DOMAIN,
2915 		    "no devices in pool support trim operations"));
2916 		(void) (zfs_error(zhp->zpool_hdl, EZFS_TRIM_NOTSUP,
2917 		    dgettext(TEXT_DOMAIN, "cannot trim")));
2918 		reported_errs = B_TRUE;
2919 	}
2920 
2921 	return (reported_errs);
2922 }
2923 
2924 /*
2925  * Begin, suspend, or cancel the TRIM (discarding of all free blocks) for
2926  * the given vdevs in the given pool.
2927  */
2928 int
2929 zpool_trim(zpool_handle_t *zhp, pool_trim_func_t cmd_type, nvlist_t *vds,
2930     trimflags_t *trim_flags)
2931 {
2932 	int err;
2933 	int retval = 0;
2934 
2935 	nvlist_t *vdev_guids = fnvlist_alloc();
2936 	nvlist_t *guids_to_paths = fnvlist_alloc();
2937 	nvlist_t *errlist = NULL;
2938 
2939 	err = zpool_translate_vdev_guids(zhp, vds, vdev_guids,
2940 	    guids_to_paths, &errlist);
2941 	if (err != 0) {
2942 		check_trim_errs(zhp, trim_flags, guids_to_paths, vds, errlist);
2943 		retval = -1;
2944 		goto out;
2945 	}
2946 
2947 	err = lzc_trim(zhp->zpool_name, cmd_type, trim_flags->rate,
2948 	    trim_flags->secure, vdev_guids, &errlist);
2949 	if (err != 0) {
2950 		nvlist_t *vd_errlist;
2951 		if (errlist != NULL && nvlist_lookup_nvlist(errlist,
2952 		    ZPOOL_TRIM_VDEVS, &vd_errlist) == 0) {
2953 			if (check_trim_errs(zhp, trim_flags, guids_to_paths,
2954 			    vds, vd_errlist)) {
2955 				retval = -1;
2956 				goto out;
2957 			}
2958 		} else {
2959 			char errbuf[ERRBUFLEN];
2960 
2961 			(void) snprintf(errbuf, sizeof (errbuf),
2962 			    dgettext(TEXT_DOMAIN, "operation failed"));
2963 			zpool_standard_error(zhp->zpool_hdl, err, errbuf);
2964 			retval = -1;
2965 			goto out;
2966 		}
2967 	}
2968 
2969 
2970 	if (trim_flags->wait)
2971 		retval = zpool_trim_wait(zhp, vdev_guids);
2972 
2973 out:
2974 	if (errlist != NULL)
2975 		fnvlist_free(errlist);
2976 	fnvlist_free(vdev_guids);
2977 	fnvlist_free(guids_to_paths);
2978 	return (retval);
2979 }
2980 
2981 /*
2982  * Scan the pool.
2983  */
2984 int
2985 zpool_scan(zpool_handle_t *zhp, pool_scan_func_t func, pool_scrub_cmd_t cmd) {
2986 	return (zpool_scan_range(zhp, func, cmd, 0, 0, 0));
2987 }
2988 
2989 int
2990 zpool_scan_range(zpool_handle_t *zhp, pool_scan_func_t func,
2991     pool_scrub_cmd_t cmd, pool_scrub_flags_t flags,
2992     time_t date_start, time_t date_end)
2993 {
2994 	char errbuf[ERRBUFLEN];
2995 	int err;
2996 	libzfs_handle_t *hdl = zhp->zpool_hdl;
2997 
2998 	nvlist_t *args = fnvlist_alloc();
2999 	fnvlist_add_uint64(args, "scan_type", (uint64_t)func);
3000 	fnvlist_add_uint64(args, "scan_command", (uint64_t)cmd);
3001 	if (flags != 0)
3002 		fnvlist_add_uint64(args, "scan_flags", (uint64_t)flags);
3003 	if (date_start != 0 || date_end != 0) {
3004 		fnvlist_add_uint64(args, "scan_date_start",
3005 		    (uint64_t)date_start);
3006 		fnvlist_add_uint64(args, "scan_date_end", (uint64_t)date_end);
3007 	}
3008 
3009 	err = lzc_scrub(ZFS_IOC_POOL_SCRUB, zhp->zpool_name, args, NULL);
3010 	fnvlist_free(args);
3011 
3012 	if (err == 0) {
3013 		return (0);
3014 	} else if (err == ZFS_ERR_IOC_CMD_UNAVAIL && flags == 0) {
3015 		zfs_cmd_t zc = {"\0"};
3016 		(void) strlcpy(zc.zc_name, zhp->zpool_name,
3017 		    sizeof (zc.zc_name));
3018 		zc.zc_cookie = func;
3019 		zc.zc_flags = cmd;
3020 
3021 		if (zfs_ioctl(hdl, ZFS_IOC_POOL_SCAN, &zc) == 0)
3022 			return (0);
3023 	}
3024 
3025 	/*
3026 	 * An ECANCELED on a scrub means one of the following:
3027 	 * 1. we resumed a paused scrub.
3028 	 * 2. we resumed a paused error scrub.
3029 	 * 3. Error scrub is not run because of no error log.
3030 	 *
3031 	 * Note that we no longer return ECANCELED in case 1 or 2. However, in
3032 	 * order to prevent problems where we have a newer userland than
3033 	 * kernel, we keep this check in place. That prevents erroneous
3034 	 * failures when an older kernel returns ECANCELED in those cases.
3035 	 */
3036 	if (err == ECANCELED && (func == POOL_SCAN_SCRUB ||
3037 	    func == POOL_SCAN_ERRORSCRUB) && cmd == POOL_SCRUB_NORMAL)
3038 		return (0);
3039 	/*
3040 	 * The following cases have been handled here:
3041 	 * 1. Paused a scrub/error scrub if there is none in progress.
3042 	 */
3043 	if (err == ENOENT && func != POOL_SCAN_NONE && cmd ==
3044 	    POOL_SCRUB_PAUSE) {
3045 		return (0);
3046 	}
3047 
3048 	ASSERT3U(func, >=, POOL_SCAN_NONE);
3049 	ASSERT3U(func, <, POOL_SCAN_FUNCS);
3050 
3051 	if (func == POOL_SCAN_SCRUB || func == POOL_SCAN_ERRORSCRUB) {
3052 		if (cmd == POOL_SCRUB_PAUSE) {
3053 			(void) snprintf(errbuf, sizeof (errbuf),
3054 			    dgettext(TEXT_DOMAIN, "cannot pause scrubbing %s"),
3055 			    zhp->zpool_name);
3056 		} else {
3057 			assert(cmd == POOL_SCRUB_NORMAL);
3058 			(void) snprintf(errbuf, sizeof (errbuf),
3059 			    dgettext(TEXT_DOMAIN, "cannot scrub %s"),
3060 			    zhp->zpool_name);
3061 		}
3062 	} else if (func == POOL_SCAN_RESILVER) {
3063 		assert(cmd == POOL_SCRUB_NORMAL);
3064 		(void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
3065 		    "cannot restart resilver on %s"), zhp->zpool_name);
3066 	} else if (func == POOL_SCAN_NONE) {
3067 		(void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
3068 		    "cannot cancel scrubbing %s"), zhp->zpool_name);
3069 	} else {
3070 		assert(!"unexpected result");
3071 	}
3072 
3073 	/*
3074 	 * With EBUSY, six cases are possible:
3075 	 *
3076 	 * Current state		Requested
3077 	 * 1. Normal Scrub Running	Normal Scrub or Error Scrub
3078 	 * 2. Normal Scrub Paused	Error Scrub
3079 	 * 3. Normal Scrub Paused 	Pause Normal Scrub
3080 	 * 4. Error Scrub Running	Normal Scrub or Error Scrub
3081 	 * 5. Error Scrub Paused	Pause Error Scrub
3082 	 * 6. Resilvering		Anything else
3083 	 */
3084 	if (err == EBUSY) {
3085 		nvlist_t *nvroot;
3086 		pool_scan_stat_t *ps = NULL;
3087 		uint_t psc;
3088 
3089 		nvroot = fnvlist_lookup_nvlist(zhp->zpool_config,
3090 		    ZPOOL_CONFIG_VDEV_TREE);
3091 		(void) nvlist_lookup_uint64_array(nvroot,
3092 		    ZPOOL_CONFIG_SCAN_STATS, (uint64_t **)&ps, &psc);
3093 		if (ps && ps->pss_func == POOL_SCAN_SCRUB &&
3094 		    ps->pss_state == DSS_SCANNING) {
3095 			if (ps->pss_pass_scrub_pause == 0) {
3096 				/* handles case 1 */
3097 				assert(cmd == POOL_SCRUB_NORMAL);
3098 				return (zfs_error(hdl, EZFS_SCRUBBING,
3099 				    errbuf));
3100 			} else {
3101 				if (func == POOL_SCAN_ERRORSCRUB) {
3102 					/* handles case 2 */
3103 					ASSERT3U(cmd, ==, POOL_SCRUB_NORMAL);
3104 					return (zfs_error(hdl,
3105 					    EZFS_SCRUB_PAUSED_TO_CANCEL,
3106 					    errbuf));
3107 				} else {
3108 					/* handles case 3 */
3109 					ASSERT3U(func, ==, POOL_SCAN_SCRUB);
3110 					ASSERT3U(cmd, ==, POOL_SCRUB_PAUSE);
3111 					return (zfs_error(hdl,
3112 					    EZFS_SCRUB_PAUSED, errbuf));
3113 				}
3114 			}
3115 		} else if (ps &&
3116 		    ps->pss_error_scrub_func == POOL_SCAN_ERRORSCRUB &&
3117 		    ps->pss_error_scrub_state == DSS_ERRORSCRUBBING) {
3118 			if (ps->pss_pass_error_scrub_pause == 0) {
3119 				/* handles case 4 */
3120 				ASSERT3U(cmd, ==, POOL_SCRUB_NORMAL);
3121 				return (zfs_error(hdl, EZFS_ERRORSCRUBBING,
3122 				    errbuf));
3123 			} else {
3124 				/* handles case 5 */
3125 				ASSERT3U(func, ==, POOL_SCAN_ERRORSCRUB);
3126 				ASSERT3U(cmd, ==, POOL_SCRUB_PAUSE);
3127 				return (zfs_error(hdl, EZFS_ERRORSCRUB_PAUSED,
3128 				    errbuf));
3129 			}
3130 		} else {
3131 			/* handles case 6 */
3132 			return (zfs_error(hdl, EZFS_RESILVERING, errbuf));
3133 		}
3134 	} else if (err == ENOENT) {
3135 		return (zfs_error(hdl, EZFS_NO_SCRUB, errbuf));
3136 	} else if (err == ENOTSUP && func == POOL_SCAN_RESILVER) {
3137 		return (zfs_error(hdl, EZFS_NO_RESILVER_DEFER, errbuf));
3138 	} else {
3139 		return (zpool_standard_error(hdl, err, errbuf));
3140 	}
3141 }
3142 
3143 /*
3144  * Find a vdev that matches the search criteria specified. We use the
3145  * the nvpair name to determine how we should look for the device.
3146  * 'avail_spare' is set to TRUE if the provided guid refers to an AVAIL
3147  * spare; but FALSE if its an INUSE spare.
3148  *
3149  * If 'return_parent' is set, then return the *parent* of the vdev you're
3150  * searching for rather than the vdev itself.
3151  */
3152 static nvlist_t *
3153 vdev_to_nvlist_iter(nvlist_t *nv, nvlist_t *search, boolean_t *avail_spare,
3154     boolean_t *l2cache, boolean_t *log, boolean_t return_parent)
3155 {
3156 	uint_t c, children;
3157 	nvlist_t **child;
3158 	nvlist_t *ret;
3159 	uint64_t is_log;
3160 	const char *srchkey;
3161 	nvpair_t *pair = nvlist_next_nvpair(search, NULL);
3162 	const char *tmp = NULL;
3163 	boolean_t is_root;
3164 
3165 	/* Nothing to look for */
3166 	if (search == NULL || pair == NULL)
3167 		return (NULL);
3168 
3169 	/* Obtain the key we will use to search */
3170 	srchkey = nvpair_name(pair);
3171 
3172 	nvlist_lookup_string(nv, ZPOOL_CONFIG_TYPE, &tmp);
3173 	if (strcmp(tmp, "root") == 0)
3174 		is_root = B_TRUE;
3175 	else
3176 		is_root = B_FALSE;
3177 
3178 	switch (nvpair_type(pair)) {
3179 	case DATA_TYPE_UINT64:
3180 		if (strcmp(srchkey, ZPOOL_CONFIG_GUID) == 0) {
3181 			uint64_t srchval = fnvpair_value_uint64(pair);
3182 			uint64_t theguid = fnvlist_lookup_uint64(nv,
3183 			    ZPOOL_CONFIG_GUID);
3184 			if (theguid == srchval)
3185 				return (nv);
3186 		}
3187 		break;
3188 
3189 	case DATA_TYPE_STRING: {
3190 		const char *srchval, *val;
3191 
3192 		srchval = fnvpair_value_string(pair);
3193 		if (nvlist_lookup_string(nv, srchkey, &val) != 0)
3194 			break;
3195 
3196 		/*
3197 		 * Search for the requested value. Special cases:
3198 		 *
3199 		 * - ZPOOL_CONFIG_PATH for whole disk entries.  These end in
3200 		 *   "-part1", or "p1".  The suffix is hidden from the user,
3201 		 *   but included in the string, so this matches around it.
3202 		 * - ZPOOL_CONFIG_PATH for short names zfs_strcmp_shortname()
3203 		 *   is used to check all possible expanded paths.
3204 		 * - looking for a top-level vdev name (i.e. ZPOOL_CONFIG_TYPE).
3205 		 *
3206 		 * Otherwise, all other searches are simple string compares.
3207 		 */
3208 		if (strcmp(srchkey, ZPOOL_CONFIG_PATH) == 0) {
3209 			uint64_t wholedisk = 0;
3210 
3211 			(void) nvlist_lookup_uint64(nv, ZPOOL_CONFIG_WHOLE_DISK,
3212 			    &wholedisk);
3213 			if (zfs_strcmp_pathname(srchval, val, wholedisk) == 0)
3214 				return (nv);
3215 
3216 		} else if (strcmp(srchkey, ZPOOL_CONFIG_TYPE) == 0) {
3217 			char *type, *idx, *end, *p;
3218 			uint64_t id, vdev_id;
3219 
3220 			/*
3221 			 * Determine our vdev type, keeping in mind
3222 			 * that the srchval is composed of a type and
3223 			 * vdev id pair (i.e. mirror-4).
3224 			 */
3225 			if ((type = strdup(srchval)) == NULL)
3226 				return (NULL);
3227 
3228 			if ((p = strrchr(type, '-')) == NULL) {
3229 				free(type);
3230 				break;
3231 			}
3232 			idx = p + 1;
3233 			*p = '\0';
3234 
3235 			/*
3236 			 * draid names are presented like: draid2:4d:6c:0s
3237 			 * We match them up to the first ':' so we can still
3238 			 * do the parity check below, but the other params
3239 			 * are ignored.
3240 			 */
3241 			if ((p = strchr(type, ':')) != NULL) {
3242 				if (strncmp(type, VDEV_TYPE_DRAID,
3243 				    strlen(VDEV_TYPE_DRAID)) == 0)
3244 					*p = '\0';
3245 			}
3246 
3247 			/*
3248 			 * If the types don't match then keep looking.
3249 			 */
3250 			if (strncmp(val, type, strlen(val)) != 0) {
3251 				free(type);
3252 				break;
3253 			}
3254 
3255 			verify(zpool_vdev_is_interior(type));
3256 
3257 			id = fnvlist_lookup_uint64(nv, ZPOOL_CONFIG_ID);
3258 			errno = 0;
3259 			vdev_id = strtoull(idx, &end, 10);
3260 
3261 			/*
3262 			 * If we are looking for a raidz and a parity is
3263 			 * specified, make sure it matches.
3264 			 */
3265 			int rzlen = strlen(VDEV_TYPE_RAIDZ);
3266 			assert(rzlen == strlen(VDEV_TYPE_DRAID));
3267 			int typlen = strlen(type);
3268 			if ((strncmp(type, VDEV_TYPE_RAIDZ, rzlen) == 0 ||
3269 			    strncmp(type, VDEV_TYPE_DRAID, rzlen) == 0) &&
3270 			    typlen != rzlen) {
3271 				uint64_t vdev_parity;
3272 				int parity = *(type + rzlen) - '0';
3273 
3274 				if (parity <= 0 || parity > 3 ||
3275 				    (typlen - rzlen) != 1) {
3276 					/*
3277 					 * Nonsense parity specified, can
3278 					 * never match
3279 					 */
3280 					free(type);
3281 					return (NULL);
3282 				}
3283 				vdev_parity = fnvlist_lookup_uint64(nv,
3284 				    ZPOOL_CONFIG_NPARITY);
3285 				if ((int)vdev_parity != parity) {
3286 					free(type);
3287 					break;
3288 				}
3289 			}
3290 
3291 			free(type);
3292 			if (errno != 0)
3293 				return (NULL);
3294 
3295 			/*
3296 			 * Now verify that we have the correct vdev id.
3297 			 */
3298 			if (vdev_id == id)
3299 				return (nv);
3300 		}
3301 
3302 		/*
3303 		 * Common case
3304 		 */
3305 		if (strcmp(srchval, val) == 0)
3306 			return (nv);
3307 		break;
3308 	}
3309 
3310 	default:
3311 		break;
3312 	}
3313 
3314 	if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
3315 	    &child, &children) != 0)
3316 		return (NULL);
3317 
3318 	for (c = 0; c < children; c++) {
3319 		if ((ret = vdev_to_nvlist_iter(child[c], search,
3320 		    avail_spare, l2cache, NULL, return_parent)) != NULL) {
3321 			/*
3322 			 * The 'is_log' value is only set for the toplevel
3323 			 * vdev, not the leaf vdevs.  So we always lookup the
3324 			 * log device from the root of the vdev tree (where
3325 			 * 'log' is non-NULL).
3326 			 */
3327 			if (log != NULL &&
3328 			    nvlist_lookup_uint64(child[c],
3329 			    ZPOOL_CONFIG_IS_LOG, &is_log) == 0 &&
3330 			    is_log) {
3331 				*log = B_TRUE;
3332 			}
3333 			return (ret && return_parent && !is_root ? nv : ret);
3334 		}
3335 	}
3336 
3337 	if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_SPARES,
3338 	    &child, &children) == 0) {
3339 		for (c = 0; c < children; c++) {
3340 			if ((ret = vdev_to_nvlist_iter(child[c], search,
3341 			    avail_spare, l2cache, NULL, return_parent))
3342 			    != NULL) {
3343 				*avail_spare = B_TRUE;
3344 				return (ret && return_parent &&
3345 				    !is_root ? nv : ret);
3346 			}
3347 		}
3348 	}
3349 
3350 	if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_L2CACHE,
3351 	    &child, &children) == 0) {
3352 		for (c = 0; c < children; c++) {
3353 			if ((ret = vdev_to_nvlist_iter(child[c], search,
3354 			    avail_spare, l2cache, NULL, return_parent))
3355 			    != NULL) {
3356 				*l2cache = B_TRUE;
3357 				return (ret && return_parent &&
3358 				    !is_root ? nv : ret);
3359 			}
3360 		}
3361 	}
3362 
3363 	return (NULL);
3364 }
3365 
3366 /*
3367  * Given a physical path or guid, find the associated vdev.
3368  */
3369 nvlist_t *
3370 zpool_find_vdev_by_physpath(zpool_handle_t *zhp, const char *ppath,
3371     boolean_t *avail_spare, boolean_t *l2cache, boolean_t *log)
3372 {
3373 	nvlist_t *search, *nvroot, *ret;
3374 	uint64_t guid;
3375 	char *end;
3376 
3377 	search = fnvlist_alloc();
3378 
3379 	guid = strtoull(ppath, &end, 0);
3380 	if (guid != 0 && *end == '\0') {
3381 		fnvlist_add_uint64(search, ZPOOL_CONFIG_GUID, guid);
3382 	} else {
3383 		fnvlist_add_string(search, ZPOOL_CONFIG_PHYS_PATH, ppath);
3384 	}
3385 
3386 	nvroot = fnvlist_lookup_nvlist(zhp->zpool_config,
3387 	    ZPOOL_CONFIG_VDEV_TREE);
3388 
3389 	*avail_spare = B_FALSE;
3390 	*l2cache = B_FALSE;
3391 	if (log != NULL)
3392 		*log = B_FALSE;
3393 	ret = vdev_to_nvlist_iter(nvroot, search, avail_spare, l2cache, log,
3394 	    B_FALSE);
3395 	fnvlist_free(search);
3396 
3397 	return (ret);
3398 }
3399 
3400 /*
3401  * Determine if we have an "interior" top-level vdev (i.e mirror/raidz).
3402  */
3403 static boolean_t
3404 zpool_vdev_is_interior(const char *name)
3405 {
3406 	if (strncmp(name, VDEV_TYPE_RAIDZ, strlen(VDEV_TYPE_RAIDZ)) == 0 ||
3407 	    strncmp(name, VDEV_TYPE_SPARE, strlen(VDEV_TYPE_SPARE)) == 0 ||
3408 	    strncmp(name,
3409 	    VDEV_TYPE_REPLACING, strlen(VDEV_TYPE_REPLACING)) == 0 ||
3410 	    strncmp(name, VDEV_TYPE_ROOT, strlen(VDEV_TYPE_ROOT)) == 0 ||
3411 	    strncmp(name, VDEV_TYPE_MIRROR, strlen(VDEV_TYPE_MIRROR)) == 0)
3412 		return (B_TRUE);
3413 
3414 	if (strncmp(name, VDEV_TYPE_DRAID, strlen(VDEV_TYPE_DRAID)) == 0 &&
3415 	    !zpool_is_draid_spare(name))
3416 		return (B_TRUE);
3417 
3418 	return (B_FALSE);
3419 }
3420 
3421 /*
3422  * Lookup the nvlist for a given vdev or vdev's parent (depending on
3423  * if 'return_parent' is set).
3424  */
3425 static nvlist_t *
3426 __zpool_find_vdev(zpool_handle_t *zhp, const char *path, boolean_t *avail_spare,
3427     boolean_t *l2cache, boolean_t *log, boolean_t return_parent)
3428 {
3429 	char *end;
3430 	nvlist_t *nvroot, *search, *ret;
3431 	uint64_t guid;
3432 	boolean_t __avail_spare, __l2cache, __log;
3433 
3434 	search = fnvlist_alloc();
3435 
3436 	guid = strtoull(path, &end, 0);
3437 	if (guid != 0 && *end == '\0') {
3438 		fnvlist_add_uint64(search, ZPOOL_CONFIG_GUID, guid);
3439 	} else if (zpool_vdev_is_interior(path)) {
3440 		fnvlist_add_string(search, ZPOOL_CONFIG_TYPE, path);
3441 	} else {
3442 		fnvlist_add_string(search, ZPOOL_CONFIG_PATH, path);
3443 	}
3444 
3445 	nvroot = fnvlist_lookup_nvlist(zhp->zpool_config,
3446 	    ZPOOL_CONFIG_VDEV_TREE);
3447 
3448 	/*
3449 	 * User can pass NULL for avail_spare, l2cache, and log, but
3450 	 * we still need to provide variables to vdev_to_nvlist_iter(), so
3451 	 * just point them to junk variables here.
3452 	 */
3453 	if (!avail_spare)
3454 		avail_spare = &__avail_spare;
3455 	if (!l2cache)
3456 		l2cache = &__l2cache;
3457 	if (!log)
3458 		log = &__log;
3459 
3460 	*avail_spare = B_FALSE;
3461 	*l2cache = B_FALSE;
3462 	if (log != NULL)
3463 		*log = B_FALSE;
3464 	ret = vdev_to_nvlist_iter(nvroot, search, avail_spare, l2cache, log,
3465 	    return_parent);
3466 	fnvlist_free(search);
3467 
3468 	return (ret);
3469 }
3470 
3471 /*
3472  * Look up a vdev in the pool by path, name, or guid.  Returns the
3473  * vdev's configuration nvlist, or NULL on no match.  Also, fills
3474  * in avail_spare, l2cache, and log if they are non-NULL.
3475  */
3476 nvlist_t *
3477 zpool_find_vdev(zpool_handle_t *zhp, const char *path, boolean_t *avail_spare,
3478     boolean_t *l2cache, boolean_t *log)
3479 {
3480 	return (__zpool_find_vdev(zhp, path, avail_spare, l2cache, log,
3481 	    B_FALSE));
3482 }
3483 
3484 /* Given a vdev path, return its parent's nvlist */
3485 nvlist_t *
3486 zpool_find_parent_vdev(zpool_handle_t *zhp, const char *path,
3487     boolean_t *avail_spare, boolean_t *l2cache, boolean_t *log)
3488 {
3489 	return (__zpool_find_vdev(zhp, path, avail_spare, l2cache, log,
3490 	    B_TRUE));
3491 }
3492 
3493 /*
3494  * Convert a vdev path to a GUID.  Returns GUID or 0 on error.
3495  *
3496  * If is_spare, is_l2cache, or is_log is non-NULL, then store within it
3497  * if the VDEV is a spare, l2cache, or log device.  If they're NULL then
3498  * ignore them.
3499  */
3500 static uint64_t
3501 zpool_vdev_path_to_guid_impl(zpool_handle_t *zhp, const char *path,
3502     boolean_t *is_spare, boolean_t *is_l2cache, boolean_t *is_log)
3503 {
3504 	boolean_t spare = B_FALSE, l2cache = B_FALSE, log = B_FALSE;
3505 	nvlist_t *tgt;
3506 
3507 	if ((tgt = zpool_find_vdev(zhp, path, &spare, &l2cache,
3508 	    &log)) == NULL)
3509 		return (0);
3510 
3511 	if (is_spare != NULL)
3512 		*is_spare = spare;
3513 	if (is_l2cache != NULL)
3514 		*is_l2cache = l2cache;
3515 	if (is_log != NULL)
3516 		*is_log = log;
3517 
3518 	return (fnvlist_lookup_uint64(tgt, ZPOOL_CONFIG_GUID));
3519 }
3520 
3521 /* Convert a vdev path to a GUID.  Returns GUID or 0 on error. */
3522 uint64_t
3523 zpool_vdev_path_to_guid(zpool_handle_t *zhp, const char *path)
3524 {
3525 	return (zpool_vdev_path_to_guid_impl(zhp, path, NULL, NULL, NULL));
3526 }
3527 
3528 /*
3529  * Bring the specified vdev online.   The 'flags' parameter is a set of the
3530  * ZFS_ONLINE_* flags.
3531  */
3532 int
3533 zpool_vdev_online(zpool_handle_t *zhp, const char *path, int flags,
3534     vdev_state_t *newstate)
3535 {
3536 	zfs_cmd_t zc = {"\0"};
3537 	char errbuf[ERRBUFLEN];
3538 	nvlist_t *tgt;
3539 	boolean_t avail_spare, l2cache, islog;
3540 	libzfs_handle_t *hdl = zhp->zpool_hdl;
3541 
3542 	if (flags & ZFS_ONLINE_EXPAND) {
3543 		(void) snprintf(errbuf, sizeof (errbuf),
3544 		    dgettext(TEXT_DOMAIN, "cannot expand %s"), path);
3545 	} else {
3546 		(void) snprintf(errbuf, sizeof (errbuf),
3547 		    dgettext(TEXT_DOMAIN, "cannot online %s"), path);
3548 	}
3549 
3550 	(void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
3551 	if ((tgt = zpool_find_vdev(zhp, path, &avail_spare, &l2cache,
3552 	    &islog)) == NULL)
3553 		return (zfs_error(hdl, EZFS_NODEVICE, errbuf));
3554 
3555 	zc.zc_guid = fnvlist_lookup_uint64(tgt, ZPOOL_CONFIG_GUID);
3556 
3557 	if (!(flags & ZFS_ONLINE_SPARE) && avail_spare)
3558 		return (zfs_error(hdl, EZFS_ISSPARE, errbuf));
3559 
3560 #ifndef __FreeBSD__
3561 	const char *pathname;
3562 	if ((flags & ZFS_ONLINE_EXPAND ||
3563 	    zpool_get_prop_int(zhp, ZPOOL_PROP_AUTOEXPAND, NULL)) &&
3564 	    nvlist_lookup_string(tgt, ZPOOL_CONFIG_PATH, &pathname) == 0) {
3565 		uint64_t wholedisk = 0;
3566 
3567 		(void) nvlist_lookup_uint64(tgt, ZPOOL_CONFIG_WHOLE_DISK,
3568 		    &wholedisk);
3569 
3570 		/*
3571 		 * XXX - L2ARC 1.0 devices can't support expansion.
3572 		 */
3573 		if (l2cache) {
3574 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3575 			    "cannot expand cache devices"));
3576 			return (zfs_error(hdl, EZFS_VDEVNOTSUP, errbuf));
3577 		}
3578 
3579 		if (wholedisk) {
3580 			const char *fullpath = path;
3581 			char buf[MAXPATHLEN];
3582 			int error;
3583 
3584 			if (path[0] != '/') {
3585 				error = zfs_resolve_shortname(path, buf,
3586 				    sizeof (buf));
3587 				if (error != 0)
3588 					return (zfs_error(hdl, EZFS_NODEVICE,
3589 					    errbuf));
3590 
3591 				fullpath = buf;
3592 			}
3593 
3594 			error = zpool_relabel_disk(hdl, fullpath, errbuf);
3595 			if (error != 0)
3596 				return (error);
3597 		}
3598 	}
3599 #endif
3600 
3601 	zc.zc_cookie = VDEV_STATE_ONLINE;
3602 	zc.zc_obj = flags;
3603 
3604 	if (zfs_ioctl(hdl, ZFS_IOC_VDEV_SET_STATE, &zc) != 0) {
3605 		if (errno == EINVAL) {
3606 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "was split "
3607 			    "from this pool into a new one.  Use '%s' "
3608 			    "instead"), "zpool detach");
3609 			return (zfs_error(hdl, EZFS_POSTSPLIT_ONLINE, errbuf));
3610 		}
3611 		return (zpool_standard_error(hdl, errno, errbuf));
3612 	}
3613 
3614 	*newstate = zc.zc_cookie;
3615 	return (0);
3616 }
3617 
3618 /*
3619  * Take the specified vdev offline
3620  */
3621 int
3622 zpool_vdev_offline(zpool_handle_t *zhp, const char *path, boolean_t istmp)
3623 {
3624 	zfs_cmd_t zc = {"\0"};
3625 	char errbuf[ERRBUFLEN];
3626 	nvlist_t *tgt;
3627 	boolean_t avail_spare, l2cache;
3628 	libzfs_handle_t *hdl = zhp->zpool_hdl;
3629 
3630 	(void) snprintf(errbuf, sizeof (errbuf),
3631 	    dgettext(TEXT_DOMAIN, "cannot offline %s"), path);
3632 
3633 	(void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
3634 	if ((tgt = zpool_find_vdev(zhp, path, &avail_spare, &l2cache,
3635 	    NULL)) == NULL)
3636 		return (zfs_error(hdl, EZFS_NODEVICE, errbuf));
3637 
3638 	zc.zc_guid = fnvlist_lookup_uint64(tgt, ZPOOL_CONFIG_GUID);
3639 
3640 	if (avail_spare)
3641 		return (zfs_error(hdl, EZFS_ISSPARE, errbuf));
3642 
3643 	zc.zc_cookie = VDEV_STATE_OFFLINE;
3644 	zc.zc_obj = istmp ? ZFS_OFFLINE_TEMPORARY : 0;
3645 
3646 	if (zfs_ioctl(hdl, ZFS_IOC_VDEV_SET_STATE, &zc) == 0)
3647 		return (0);
3648 
3649 	switch (errno) {
3650 	case EBUSY:
3651 
3652 		/*
3653 		 * There are no other replicas of this device.
3654 		 */
3655 		return (zfs_error(hdl, EZFS_NOREPLICAS, errbuf));
3656 
3657 	case EEXIST:
3658 		/*
3659 		 * The log device has unplayed logs
3660 		 */
3661 		return (zfs_error(hdl, EZFS_UNPLAYED_LOGS, errbuf));
3662 
3663 	default:
3664 		return (zpool_standard_error(hdl, errno, errbuf));
3665 	}
3666 }
3667 
3668 /*
3669  * Remove the specified vdev asynchronously from the configuration, so
3670  * that it may come ONLINE if reinserted. This is called from zed on
3671  * Udev remove event.
3672  * Note: We also have a similar function zpool_vdev_remove() that
3673  * removes the vdev from the pool.
3674  */
3675 int
3676 zpool_vdev_remove_wanted(zpool_handle_t *zhp, const char *path)
3677 {
3678 	zfs_cmd_t zc = {"\0"};
3679 	char errbuf[ERRBUFLEN];
3680 	nvlist_t *tgt;
3681 	boolean_t avail_spare, l2cache;
3682 	libzfs_handle_t *hdl = zhp->zpool_hdl;
3683 
3684 	(void) snprintf(errbuf, sizeof (errbuf),
3685 	    dgettext(TEXT_DOMAIN, "cannot remove %s"), path);
3686 
3687 	(void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
3688 	if ((tgt = zpool_find_vdev(zhp, path, &avail_spare, &l2cache,
3689 	    NULL)) == NULL)
3690 		return (zfs_error(hdl, EZFS_NODEVICE, errbuf));
3691 
3692 	zc.zc_guid = fnvlist_lookup_uint64(tgt, ZPOOL_CONFIG_GUID);
3693 
3694 	zc.zc_cookie = VDEV_STATE_REMOVED;
3695 
3696 	if (zfs_ioctl(hdl, ZFS_IOC_VDEV_SET_STATE, &zc) == 0)
3697 		return (0);
3698 
3699 	return (zpool_standard_error(hdl, errno, errbuf));
3700 }
3701 
3702 /*
3703  * Mark the given vdev faulted.
3704  */
3705 int
3706 zpool_vdev_fault(zpool_handle_t *zhp, uint64_t guid, vdev_aux_t aux)
3707 {
3708 	zfs_cmd_t zc = {"\0"};
3709 	char errbuf[ERRBUFLEN];
3710 	libzfs_handle_t *hdl = zhp->zpool_hdl;
3711 	nvlist_t *vdev_nv;
3712 	boolean_t avail_spare, l2cache;
3713 	char *vdev_name;
3714 	char guid_str[21]; /* 64-bit num + '\0' */
3715 	boolean_t is_draid_spare = B_FALSE;
3716 	const char *vdev_type;
3717 
3718 	(void) snprintf(errbuf, sizeof (errbuf),
3719 	    dgettext(TEXT_DOMAIN, "cannot fault %llu"), (u_longlong_t)guid);
3720 
3721 	snprintf(guid_str, sizeof (guid_str), "%llu", (u_longlong_t)guid);
3722 	if ((vdev_nv = zpool_find_vdev(zhp, guid_str, &avail_spare,
3723 	    &l2cache, NULL)) == NULL)
3724 		return (zfs_error(hdl, EZFS_NODEVICE, errbuf));
3725 
3726 	vdev_name = zpool_vdev_name(hdl, zhp, vdev_nv, 0);
3727 	if (vdev_name != NULL) {
3728 		/*
3729 		 * We have the actual vdev name, so use that instead of the GUID
3730 		 * in any error messages.
3731 		 */
3732 		(void) snprintf(errbuf, sizeof (errbuf),
3733 		    dgettext(TEXT_DOMAIN, "cannot fault %s"), vdev_name);
3734 		free(vdev_name);
3735 	}
3736 
3737 	/*
3738 	 * Spares (traditional or draid) cannot be faulted by libzfs, except:
3739 	 *
3740 	 * - Any spare type that exceeds it's errors can be faulted (aux =
3741 	 *   VDEV_AUX_ERR_EXCEEDED).  This is only used by zed.
3742 	 *
3743 	 * - Traditional spares that are active can be force faulted.
3744 	 */
3745 	if (nvlist_lookup_string(vdev_nv, ZPOOL_CONFIG_TYPE, &vdev_type) == 0)
3746 		if (strcmp(vdev_type, VDEV_TYPE_DRAID_SPARE) == 0)
3747 			is_draid_spare = B_TRUE;
3748 
3749 	/*
3750 	 * If vdev is a spare that is not being used, or is a dRAID spare (in
3751 	 * use or not), then don't allow it to be force-faulted.  However, an
3752 	 * in-use dRAID spare can be faulted by ZED if see too many errors
3753 	 * (aux = VDEV_AUX_ERR_EXCEEDED).
3754 	 */
3755 	if (avail_spare || (is_draid_spare && aux != VDEV_AUX_ERR_EXCEEDED))
3756 		return (zfs_error(hdl, EZFS_ISSPARE, errbuf));
3757 
3758 	(void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
3759 	zc.zc_guid = guid;
3760 	zc.zc_cookie = VDEV_STATE_FAULTED;
3761 	zc.zc_obj = aux;
3762 
3763 	if (zfs_ioctl(hdl, ZFS_IOC_VDEV_SET_STATE, &zc) == 0)
3764 		return (0);
3765 
3766 	switch (errno) {
3767 	case EBUSY:
3768 
3769 		/*
3770 		 * There are no other replicas of this device.
3771 		 */
3772 		return (zfs_error(hdl, EZFS_NOREPLICAS, errbuf));
3773 
3774 	default:
3775 		return (zpool_standard_error(hdl, errno, errbuf));
3776 	}
3777 
3778 }
3779 
3780 /*
3781  * Generic set vdev state function
3782  */
3783 static int
3784 zpool_vdev_set_state(zpool_handle_t *zhp, uint64_t guid, vdev_aux_t aux,
3785     vdev_state_t state)
3786 {
3787 	zfs_cmd_t zc = {"\0"};
3788 	char errbuf[ERRBUFLEN];
3789 	libzfs_handle_t *hdl = zhp->zpool_hdl;
3790 
3791 	(void) snprintf(errbuf, sizeof (errbuf),
3792 	    dgettext(TEXT_DOMAIN, "cannot set %s %llu"),
3793 	    zpool_state_to_name(state, aux), (u_longlong_t)guid);
3794 
3795 	(void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
3796 	zc.zc_guid = guid;
3797 	zc.zc_cookie = state;
3798 	zc.zc_obj = aux;
3799 
3800 	if (zfs_ioctl(hdl, ZFS_IOC_VDEV_SET_STATE, &zc) == 0)
3801 		return (0);
3802 
3803 	return (zpool_standard_error(hdl, errno, errbuf));
3804 }
3805 
3806 /*
3807  * Mark the given vdev degraded.
3808  */
3809 int
3810 zpool_vdev_degrade(zpool_handle_t *zhp, uint64_t guid, vdev_aux_t aux)
3811 {
3812 	return (zpool_vdev_set_state(zhp, guid, aux, VDEV_STATE_DEGRADED));
3813 }
3814 
3815 /*
3816  * Mark the given vdev as in a removed state (as if the device does not exist).
3817  *
3818  * This is different than zpool_vdev_remove() which does a removal of a device
3819  * from the pool (but the device does exist).
3820  */
3821 int
3822 zpool_vdev_set_removed_state(zpool_handle_t *zhp, uint64_t guid, vdev_aux_t aux)
3823 {
3824 	return (zpool_vdev_set_state(zhp, guid, aux, VDEV_STATE_REMOVED));
3825 }
3826 
3827 /*
3828  * Returns TRUE if the given nvlist is a vdev that was originally swapped in as
3829  * a hot spare.
3830  */
3831 static boolean_t
3832 is_replacing_spare(nvlist_t *search, nvlist_t *tgt, int which)
3833 {
3834 	nvlist_t **child;
3835 	uint_t c, children;
3836 
3837 	if (nvlist_lookup_nvlist_array(search, ZPOOL_CONFIG_CHILDREN, &child,
3838 	    &children) == 0) {
3839 		const char *type = fnvlist_lookup_string(search,
3840 		    ZPOOL_CONFIG_TYPE);
3841 		if ((strcmp(type, VDEV_TYPE_SPARE) == 0 ||
3842 		    strcmp(type, VDEV_TYPE_DRAID_SPARE) == 0) &&
3843 		    children == 2 && child[which] == tgt)
3844 			return (B_TRUE);
3845 
3846 		for (c = 0; c < children; c++)
3847 			if (is_replacing_spare(child[c], tgt, which))
3848 				return (B_TRUE);
3849 	}
3850 
3851 	return (B_FALSE);
3852 }
3853 
3854 /*
3855  * Attach new_disk (fully described by nvroot) to old_disk.
3856  * If 'replacing' is specified, the new disk will replace the old one.
3857  */
3858 int
3859 zpool_vdev_attach(zpool_handle_t *zhp, const char *old_disk,
3860     const char *new_disk, nvlist_t *nvroot, int replacing, boolean_t rebuild)
3861 {
3862 	zfs_cmd_t zc = {"\0"};
3863 	char errbuf[ERRBUFLEN];
3864 	int ret;
3865 	nvlist_t *tgt;
3866 	boolean_t avail_spare, l2cache, islog;
3867 	uint64_t val;
3868 	char *newname;
3869 	const char *type;
3870 	nvlist_t **child;
3871 	uint_t children;
3872 	nvlist_t *config_root;
3873 	libzfs_handle_t *hdl = zhp->zpool_hdl;
3874 
3875 	if (replacing)
3876 		(void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
3877 		    "cannot replace %s with %s"), old_disk, new_disk);
3878 	else
3879 		(void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
3880 		    "cannot attach %s to %s"), new_disk, old_disk);
3881 
3882 	(void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
3883 	if ((tgt = zpool_find_vdev(zhp, old_disk, &avail_spare, &l2cache,
3884 	    &islog)) == NULL)
3885 		return (zfs_error(hdl, EZFS_NODEVICE, errbuf));
3886 
3887 	if (avail_spare)
3888 		return (zfs_error(hdl, EZFS_ISSPARE, errbuf));
3889 
3890 	if (l2cache)
3891 		return (zfs_error(hdl, EZFS_ISL2CACHE, errbuf));
3892 
3893 	zc.zc_guid = fnvlist_lookup_uint64(tgt, ZPOOL_CONFIG_GUID);
3894 	zc.zc_cookie = replacing;
3895 	zc.zc_simple = rebuild;
3896 
3897 	if (rebuild &&
3898 	    zfeature_lookup_guid("org.openzfs:device_rebuild", NULL) != 0) {
3899 		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3900 		    "the loaded zfs module doesn't support device rebuilds"));
3901 		return (zfs_error(hdl, EZFS_POOL_NOTSUP, errbuf));
3902 	}
3903 
3904 	type = fnvlist_lookup_string(tgt, ZPOOL_CONFIG_TYPE);
3905 	if (strcmp(type, VDEV_TYPE_RAIDZ) == 0 &&
3906 	    zfeature_lookup_guid("org.openzfs:raidz_expansion", NULL) != 0) {
3907 		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3908 		    "the loaded zfs module doesn't support raidz expansion"));
3909 		return (zfs_error(hdl, EZFS_POOL_NOTSUP, errbuf));
3910 	}
3911 
3912 	if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_CHILDREN,
3913 	    &child, &children) != 0 || children != 1) {
3914 		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3915 		    "new device must be a single disk"));
3916 		return (zfs_error(hdl, EZFS_INVALCONFIG, errbuf));
3917 	}
3918 
3919 	config_root = fnvlist_lookup_nvlist(zpool_get_config(zhp, NULL),
3920 	    ZPOOL_CONFIG_VDEV_TREE);
3921 
3922 	if ((newname = zpool_vdev_name(NULL, NULL, child[0], 0)) == NULL)
3923 		return (-1);
3924 
3925 	/*
3926 	 * If the target is a hot spare that has been swapped in, we can only
3927 	 * replace it with another hot spare.
3928 	 */
3929 	if (replacing &&
3930 	    nvlist_lookup_uint64(tgt, ZPOOL_CONFIG_IS_SPARE, &val) == 0 &&
3931 	    (zpool_find_vdev(zhp, newname, &avail_spare, &l2cache,
3932 	    NULL) == NULL || !avail_spare) &&
3933 	    is_replacing_spare(config_root, tgt, 1)) {
3934 		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3935 		    "can only be replaced by another hot spare"));
3936 		free(newname);
3937 		return (zfs_error(hdl, EZFS_BADTARGET, errbuf));
3938 	}
3939 
3940 	free(newname);
3941 
3942 	zcmd_write_conf_nvlist(hdl, &zc, nvroot);
3943 
3944 	ret = zfs_ioctl(hdl, ZFS_IOC_VDEV_ATTACH, &zc);
3945 
3946 	zcmd_free_nvlists(&zc);
3947 
3948 	if (ret == 0)
3949 		return (0);
3950 
3951 	switch (errno) {
3952 	case ENOTSUP:
3953 		/*
3954 		 * Can't attach to or replace this type of vdev.
3955 		 */
3956 		if (replacing) {
3957 			uint64_t version = zpool_get_prop_int(zhp,
3958 			    ZPOOL_PROP_VERSION, NULL);
3959 
3960 			if (islog) {
3961 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3962 				    "cannot replace a log with a spare"));
3963 			} else if (rebuild) {
3964 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3965 				    "only mirror and dRAID vdevs support "
3966 				    "sequential reconstruction"));
3967 			} else if (zpool_is_draid_spare(new_disk)) {
3968 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3969 				    "dRAID spares can only replace child "
3970 				    "devices in their parent's dRAID vdev"));
3971 			} else if (version >= SPA_VERSION_MULTI_REPLACE) {
3972 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3973 				    "already in replacing/spare config; wait "
3974 				    "for completion or use 'zpool detach'"));
3975 			} else {
3976 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3977 				    "cannot replace a replacing device"));
3978 			}
3979 		} else if (strcmp(type, VDEV_TYPE_RAIDZ) == 0) {
3980 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3981 			    "raidz_expansion feature must be enabled "
3982 			    "in order to attach a device to raidz"));
3983 		} else {
3984 			char status[64] = {0};
3985 			zpool_prop_get_feature(zhp,
3986 			    "feature@device_rebuild", status, 63);
3987 			if (rebuild &&
3988 			    strncmp(status, ZFS_FEATURE_DISABLED, 64) == 0) {
3989 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3990 				    "device_rebuild feature must be enabled "
3991 				    "in order to use sequential "
3992 				    "reconstruction"));
3993 			} else {
3994 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3995 				    "can only attach to mirrors and top-level "
3996 				    "disks"));
3997 			}
3998 		}
3999 		(void) zfs_error(hdl, EZFS_BADTARGET, errbuf);
4000 		break;
4001 
4002 	case EINVAL:
4003 		/*
4004 		 * The new device must be a single disk.
4005 		 */
4006 		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
4007 		    "new device must be a single disk"));
4008 		(void) zfs_error(hdl, EZFS_INVALCONFIG, errbuf);
4009 		break;
4010 
4011 	case EBUSY:
4012 		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "%s is busy"),
4013 		    new_disk);
4014 		(void) zfs_error(hdl, EZFS_BADDEV, errbuf);
4015 		break;
4016 
4017 	case EOVERFLOW:
4018 		/*
4019 		 * The new device is too small.
4020 		 */
4021 		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
4022 		    "device is too small"));
4023 		(void) zfs_error(hdl, EZFS_BADDEV, errbuf);
4024 		break;
4025 
4026 	case EDOM:
4027 		/*
4028 		 * The new device has a different optimal sector size.
4029 		 */
4030 		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
4031 		    "new device has a different optimal sector size; use the "
4032 		    "option '-o ashift=N' to override the optimal size"));
4033 		(void) zfs_error(hdl, EZFS_BADDEV, errbuf);
4034 		break;
4035 
4036 	case ENAMETOOLONG:
4037 		/*
4038 		 * The resulting top-level vdev spec won't fit in the label.
4039 		 */
4040 		(void) zfs_error(hdl, EZFS_DEVOVERFLOW, errbuf);
4041 		break;
4042 
4043 	case ENXIO:
4044 		/*
4045 		 * The existing raidz vdev has offline children
4046 		 */
4047 		if (strcmp(type, VDEV_TYPE_RAIDZ) == 0) {
4048 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
4049 			    "raidz vdev has devices that are are offline or "
4050 			    "being replaced"));
4051 			(void) zfs_error(hdl, EZFS_BADDEV, errbuf);
4052 			break;
4053 		} else {
4054 			(void) zpool_standard_error(hdl, errno, errbuf);
4055 		}
4056 		break;
4057 
4058 	case EADDRINUSE:
4059 		/*
4060 		 * The boot reserved area is already being used (FreeBSD)
4061 		 */
4062 		if (strcmp(type, VDEV_TYPE_RAIDZ) == 0) {
4063 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
4064 			    "the reserved boot area needed for the expansion "
4065 			    "is already being used by a boot loader"));
4066 			(void) zfs_error(hdl, EZFS_BADDEV, errbuf);
4067 		} else {
4068 			(void) zpool_standard_error(hdl, errno, errbuf);
4069 		}
4070 		break;
4071 
4072 	case ZFS_ERR_ASHIFT_MISMATCH:
4073 		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
4074 		    "The new device cannot have a higher alignment requirement "
4075 		    "than the top-level vdev."));
4076 		(void) zfs_error(hdl, EZFS_BADTARGET, errbuf);
4077 		break;
4078 	default:
4079 		(void) zpool_standard_error(hdl, errno, errbuf);
4080 	}
4081 
4082 	return (-1);
4083 }
4084 
4085 /*
4086  * Detach the specified device.
4087  */
4088 int
4089 zpool_vdev_detach(zpool_handle_t *zhp, const char *path)
4090 {
4091 	zfs_cmd_t zc = {"\0"};
4092 	char errbuf[ERRBUFLEN];
4093 	nvlist_t *tgt;
4094 	boolean_t avail_spare, l2cache;
4095 	libzfs_handle_t *hdl = zhp->zpool_hdl;
4096 
4097 	(void) snprintf(errbuf, sizeof (errbuf),
4098 	    dgettext(TEXT_DOMAIN, "cannot detach %s"), path);
4099 
4100 	(void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
4101 	if ((tgt = zpool_find_vdev(zhp, path, &avail_spare, &l2cache,
4102 	    NULL)) == NULL)
4103 		return (zfs_error(hdl, EZFS_NODEVICE, errbuf));
4104 
4105 	if (avail_spare)
4106 		return (zfs_error(hdl, EZFS_ISSPARE, errbuf));
4107 
4108 	if (l2cache)
4109 		return (zfs_error(hdl, EZFS_ISL2CACHE, errbuf));
4110 
4111 	zc.zc_guid = fnvlist_lookup_uint64(tgt, ZPOOL_CONFIG_GUID);
4112 
4113 	if (zfs_ioctl(hdl, ZFS_IOC_VDEV_DETACH, &zc) == 0)
4114 		return (0);
4115 
4116 	switch (errno) {
4117 
4118 	case ENOTSUP:
4119 		/*
4120 		 * Can't detach from this type of vdev.
4121 		 */
4122 		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "only "
4123 		    "applicable to mirror and replacing vdevs"));
4124 		(void) zfs_error(hdl, EZFS_BADTARGET, errbuf);
4125 		break;
4126 
4127 	case EBUSY:
4128 		/*
4129 		 * There are no other replicas of this device.
4130 		 */
4131 		(void) zfs_error(hdl, EZFS_NOREPLICAS, errbuf);
4132 		break;
4133 
4134 	default:
4135 		(void) zpool_standard_error(hdl, errno, errbuf);
4136 	}
4137 
4138 	return (-1);
4139 }
4140 
4141 /*
4142  * Find a mirror vdev in the source nvlist.
4143  *
4144  * The mchild array contains a list of disks in one of the top-level mirrors
4145  * of the source pool.  The schild array contains a list of disks that the
4146  * user specified on the command line.  We loop over the mchild array to
4147  * see if any entry in the schild array matches.
4148  *
4149  * If a disk in the mchild array is found in the schild array, we return
4150  * the index of that entry.  Otherwise we return -1.
4151  */
4152 static int
4153 find_vdev_entry(zpool_handle_t *zhp, nvlist_t **mchild, uint_t mchildren,
4154     nvlist_t **schild, uint_t schildren)
4155 {
4156 	uint_t mc;
4157 
4158 	for (mc = 0; mc < mchildren; mc++) {
4159 		uint_t sc;
4160 		char *mpath = zpool_vdev_name(zhp->zpool_hdl, zhp,
4161 		    mchild[mc], 0);
4162 
4163 		for (sc = 0; sc < schildren; sc++) {
4164 			char *spath = zpool_vdev_name(zhp->zpool_hdl, zhp,
4165 			    schild[sc], 0);
4166 			boolean_t result = (strcmp(mpath, spath) == 0);
4167 
4168 			free(spath);
4169 			if (result) {
4170 				free(mpath);
4171 				return (mc);
4172 			}
4173 		}
4174 
4175 		free(mpath);
4176 	}
4177 
4178 	return (-1);
4179 }
4180 
4181 /*
4182  * Split a mirror pool.  If newroot points to null, then a new nvlist
4183  * is generated and it is the responsibility of the caller to free it.
4184  */
4185 int
4186 zpool_vdev_split(zpool_handle_t *zhp, char *newname, nvlist_t **newroot,
4187     nvlist_t *props, splitflags_t flags)
4188 {
4189 	zfs_cmd_t zc = {"\0"};
4190 	char errbuf[ERRBUFLEN];
4191 	const char *bias;
4192 	nvlist_t *tree, *config, **child, **newchild, *newconfig = NULL;
4193 	nvlist_t **varray = NULL, *zc_props = NULL;
4194 	uint_t c, children, newchildren, lastlog = 0, vcount, found = 0;
4195 	libzfs_handle_t *hdl = zhp->zpool_hdl;
4196 	uint64_t vers, readonly = B_FALSE;
4197 	boolean_t freelist = B_FALSE, memory_err = B_TRUE;
4198 	int retval = 0;
4199 
4200 	(void) snprintf(errbuf, sizeof (errbuf),
4201 	    dgettext(TEXT_DOMAIN, "Unable to split %s"), zhp->zpool_name);
4202 
4203 	if (!zpool_name_valid(hdl, B_FALSE, newname))
4204 		return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf));
4205 
4206 	if ((config = zpool_get_config(zhp, NULL)) == NULL) {
4207 		(void) fprintf(stderr, gettext("Internal error: unable to "
4208 		    "retrieve pool configuration\n"));
4209 		return (-1);
4210 	}
4211 
4212 	tree = fnvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE);
4213 	vers = fnvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION);
4214 
4215 	if (props) {
4216 		prop_flags_t flags = { .create = B_FALSE, .import = B_TRUE };
4217 		if ((zc_props = zpool_valid_proplist(hdl, zhp->zpool_name,
4218 		    props, vers, flags, errbuf)) == NULL)
4219 			return (-1);
4220 		(void) nvlist_lookup_uint64(zc_props,
4221 		    zpool_prop_to_name(ZPOOL_PROP_READONLY), &readonly);
4222 		if (readonly) {
4223 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
4224 			    "property %s can only be set at import time"),
4225 			    zpool_prop_to_name(ZPOOL_PROP_READONLY));
4226 			return (-1);
4227 		}
4228 	}
4229 
4230 	if (nvlist_lookup_nvlist_array(tree, ZPOOL_CONFIG_CHILDREN, &child,
4231 	    &children) != 0) {
4232 		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
4233 		    "Source pool is missing vdev tree"));
4234 		nvlist_free(zc_props);
4235 		return (-1);
4236 	}
4237 
4238 	varray = zfs_alloc(hdl, children * sizeof (nvlist_t *));
4239 	vcount = 0;
4240 
4241 	if (*newroot == NULL ||
4242 	    nvlist_lookup_nvlist_array(*newroot, ZPOOL_CONFIG_CHILDREN,
4243 	    &newchild, &newchildren) != 0)
4244 		newchildren = 0;
4245 
4246 	for (c = 0; c < children; c++) {
4247 		uint64_t is_log = B_FALSE, is_hole = B_FALSE;
4248 		boolean_t is_special = B_FALSE, is_dedup = B_FALSE;
4249 		const char *type;
4250 		nvlist_t **mchild, *vdev;
4251 		uint_t mchildren;
4252 		int entry;
4253 
4254 		/*
4255 		 * Unlike cache & spares, slogs are stored in the
4256 		 * ZPOOL_CONFIG_CHILDREN array.  We filter them out here.
4257 		 */
4258 		(void) nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_LOG,
4259 		    &is_log);
4260 		(void) nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_HOLE,
4261 		    &is_hole);
4262 		if (is_log || is_hole) {
4263 			/*
4264 			 * Create a hole vdev and put it in the config.
4265 			 */
4266 			if (nvlist_alloc(&vdev, NV_UNIQUE_NAME, 0) != 0)
4267 				goto out;
4268 			if (nvlist_add_string(vdev, ZPOOL_CONFIG_TYPE,
4269 			    VDEV_TYPE_HOLE) != 0)
4270 				goto out;
4271 			if (nvlist_add_uint64(vdev, ZPOOL_CONFIG_IS_HOLE,
4272 			    1) != 0)
4273 				goto out;
4274 			if (lastlog == 0)
4275 				lastlog = vcount;
4276 			varray[vcount++] = vdev;
4277 			continue;
4278 		}
4279 		lastlog = 0;
4280 		type = fnvlist_lookup_string(child[c], ZPOOL_CONFIG_TYPE);
4281 
4282 		if (strcmp(type, VDEV_TYPE_INDIRECT) == 0) {
4283 			vdev = child[c];
4284 			if (nvlist_dup(vdev, &varray[vcount++], 0) != 0)
4285 				goto out;
4286 			continue;
4287 		} else if (strcmp(type, VDEV_TYPE_MIRROR) != 0) {
4288 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
4289 			    "Source pool must be composed only of mirrors\n"));
4290 			retval = zfs_error(hdl, EZFS_INVALCONFIG, errbuf);
4291 			goto out;
4292 		}
4293 
4294 		if (nvlist_lookup_string(child[c],
4295 		    ZPOOL_CONFIG_ALLOCATION_BIAS, &bias) == 0) {
4296 			if (strcmp(bias, VDEV_ALLOC_BIAS_SPECIAL) == 0)
4297 				is_special = B_TRUE;
4298 			else if (strcmp(bias, VDEV_ALLOC_BIAS_DEDUP) == 0)
4299 				is_dedup = B_TRUE;
4300 		}
4301 		verify(nvlist_lookup_nvlist_array(child[c],
4302 		    ZPOOL_CONFIG_CHILDREN, &mchild, &mchildren) == 0);
4303 
4304 		/* find or add an entry for this top-level vdev */
4305 		if (newchildren > 0 &&
4306 		    (entry = find_vdev_entry(zhp, mchild, mchildren,
4307 		    newchild, newchildren)) >= 0) {
4308 			/* We found a disk that the user specified. */
4309 			vdev = mchild[entry];
4310 			++found;
4311 		} else {
4312 			/* User didn't specify a disk for this vdev. */
4313 			vdev = mchild[mchildren - 1];
4314 		}
4315 
4316 		if (nvlist_dup(vdev, &varray[vcount++], 0) != 0)
4317 			goto out;
4318 
4319 		if (flags.dryrun != 0) {
4320 			if (is_dedup == B_TRUE) {
4321 				if (nvlist_add_string(varray[vcount - 1],
4322 				    ZPOOL_CONFIG_ALLOCATION_BIAS,
4323 				    VDEV_ALLOC_BIAS_DEDUP) != 0)
4324 					goto out;
4325 			} else if (is_special == B_TRUE) {
4326 				if (nvlist_add_string(varray[vcount - 1],
4327 				    ZPOOL_CONFIG_ALLOCATION_BIAS,
4328 				    VDEV_ALLOC_BIAS_SPECIAL) != 0)
4329 					goto out;
4330 			}
4331 		}
4332 	}
4333 
4334 	/* did we find every disk the user specified? */
4335 	if (found != newchildren) {
4336 		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "Device list must "
4337 		    "include at most one disk from each mirror"));
4338 		retval = zfs_error(hdl, EZFS_INVALCONFIG, errbuf);
4339 		goto out;
4340 	}
4341 
4342 	/* Prepare the nvlist for populating. */
4343 	if (*newroot == NULL) {
4344 		if (nvlist_alloc(newroot, NV_UNIQUE_NAME, 0) != 0)
4345 			goto out;
4346 		freelist = B_TRUE;
4347 		if (nvlist_add_string(*newroot, ZPOOL_CONFIG_TYPE,
4348 		    VDEV_TYPE_ROOT) != 0)
4349 			goto out;
4350 	} else {
4351 		verify(nvlist_remove_all(*newroot, ZPOOL_CONFIG_CHILDREN) == 0);
4352 	}
4353 
4354 	/* Add all the children we found */
4355 	if (nvlist_add_nvlist_array(*newroot, ZPOOL_CONFIG_CHILDREN,
4356 	    (const nvlist_t **)varray, lastlog == 0 ? vcount : lastlog) != 0)
4357 		goto out;
4358 
4359 	/*
4360 	 * If we're just doing a dry run, exit now with success.
4361 	 */
4362 	if (flags.dryrun) {
4363 		memory_err = B_FALSE;
4364 		freelist = B_FALSE;
4365 		goto out;
4366 	}
4367 
4368 	/* now build up the config list & call the ioctl */
4369 	if (nvlist_alloc(&newconfig, NV_UNIQUE_NAME, 0) != 0)
4370 		goto out;
4371 
4372 	if (nvlist_add_nvlist(newconfig,
4373 	    ZPOOL_CONFIG_VDEV_TREE, *newroot) != 0 ||
4374 	    nvlist_add_string(newconfig,
4375 	    ZPOOL_CONFIG_POOL_NAME, newname) != 0 ||
4376 	    nvlist_add_uint64(newconfig, ZPOOL_CONFIG_VERSION, vers) != 0)
4377 		goto out;
4378 
4379 	/*
4380 	 * The new pool is automatically part of the namespace unless we
4381 	 * explicitly export it.
4382 	 */
4383 	if (!flags.import)
4384 		zc.zc_cookie = ZPOOL_EXPORT_AFTER_SPLIT;
4385 	(void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
4386 	(void) strlcpy(zc.zc_string, newname, sizeof (zc.zc_string));
4387 	zcmd_write_conf_nvlist(hdl, &zc, newconfig);
4388 	if (zc_props != NULL)
4389 		zcmd_write_src_nvlist(hdl, &zc, zc_props);
4390 
4391 	if (zfs_ioctl(hdl, ZFS_IOC_VDEV_SPLIT, &zc) != 0) {
4392 		retval = zpool_standard_error(hdl, errno, errbuf);
4393 		goto out;
4394 	}
4395 
4396 	freelist = B_FALSE;
4397 	memory_err = B_FALSE;
4398 
4399 out:
4400 	if (varray != NULL) {
4401 		int v;
4402 
4403 		for (v = 0; v < vcount; v++)
4404 			nvlist_free(varray[v]);
4405 		free(varray);
4406 	}
4407 	zcmd_free_nvlists(&zc);
4408 	nvlist_free(zc_props);
4409 	nvlist_free(newconfig);
4410 	if (freelist) {
4411 		nvlist_free(*newroot);
4412 		*newroot = NULL;
4413 	}
4414 
4415 	if (retval != 0)
4416 		return (retval);
4417 
4418 	if (memory_err)
4419 		return (no_memory(hdl));
4420 
4421 	return (0);
4422 }
4423 
4424 /*
4425  * Remove the given device.
4426  */
4427 int
4428 zpool_vdev_remove(zpool_handle_t *zhp, const char *path)
4429 {
4430 	zfs_cmd_t zc = {"\0"};
4431 	char errbuf[ERRBUFLEN];
4432 	nvlist_t *tgt;
4433 	boolean_t avail_spare, l2cache, islog;
4434 	libzfs_handle_t *hdl = zhp->zpool_hdl;
4435 	uint64_t version;
4436 
4437 	(void) snprintf(errbuf, sizeof (errbuf),
4438 	    dgettext(TEXT_DOMAIN, "cannot remove %s"), path);
4439 
4440 	if (zpool_is_draid_spare(path)) {
4441 		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
4442 		    "dRAID spares cannot be removed"));
4443 		return (zfs_error(hdl, EZFS_NODEVICE, errbuf));
4444 	}
4445 
4446 	(void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
4447 	if ((tgt = zpool_find_vdev(zhp, path, &avail_spare, &l2cache,
4448 	    &islog)) == NULL)
4449 		return (zfs_error(hdl, EZFS_NODEVICE, errbuf));
4450 
4451 	version = zpool_get_prop_int(zhp, ZPOOL_PROP_VERSION, NULL);
4452 	if (islog && version < SPA_VERSION_HOLES) {
4453 		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
4454 		    "pool must be upgraded to support log removal"));
4455 		return (zfs_error(hdl, EZFS_BADVERSION, errbuf));
4456 	}
4457 
4458 	zc.zc_guid = fnvlist_lookup_uint64(tgt, ZPOOL_CONFIG_GUID);
4459 
4460 	if (zfs_ioctl(hdl, ZFS_IOC_VDEV_REMOVE, &zc) == 0)
4461 		return (0);
4462 
4463 	switch (errno) {
4464 
4465 	case EALREADY:
4466 		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
4467 		    "removal for this vdev is already in progress."));
4468 		(void) zfs_error(hdl, EZFS_BUSY, errbuf);
4469 		break;
4470 
4471 	case EINVAL:
4472 		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
4473 		    "invalid config; all top-level vdevs must "
4474 		    "have the same sector size and not be raidz."));
4475 		(void) zfs_error(hdl, EZFS_INVALCONFIG, errbuf);
4476 		break;
4477 
4478 	case EBUSY:
4479 		if (islog) {
4480 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
4481 			    "Mount encrypted datasets to replay logs."));
4482 		} else {
4483 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
4484 			    "Pool busy; removal may already be in progress"));
4485 		}
4486 		(void) zfs_error(hdl, EZFS_BUSY, errbuf);
4487 		break;
4488 
4489 	case EACCES:
4490 		if (islog) {
4491 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
4492 			    "Mount encrypted datasets to replay logs."));
4493 			(void) zfs_error(hdl, EZFS_BUSY, errbuf);
4494 		} else {
4495 			(void) zpool_standard_error(hdl, errno, errbuf);
4496 		}
4497 		break;
4498 
4499 	default:
4500 		(void) zpool_standard_error(hdl, errno, errbuf);
4501 	}
4502 	return (-1);
4503 }
4504 
4505 int
4506 zpool_vdev_remove_cancel(zpool_handle_t *zhp)
4507 {
4508 	zfs_cmd_t zc = {{0}};
4509 	char errbuf[ERRBUFLEN];
4510 	libzfs_handle_t *hdl = zhp->zpool_hdl;
4511 
4512 	(void) snprintf(errbuf, sizeof (errbuf),
4513 	    dgettext(TEXT_DOMAIN, "cannot cancel removal"));
4514 
4515 	(void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
4516 	zc.zc_cookie = 1;
4517 
4518 	if (zfs_ioctl(hdl, ZFS_IOC_VDEV_REMOVE, &zc) == 0)
4519 		return (0);
4520 
4521 	return (zpool_standard_error(hdl, errno, errbuf));
4522 }
4523 
4524 int
4525 zpool_vdev_indirect_size(zpool_handle_t *zhp, const char *path,
4526     uint64_t *sizep)
4527 {
4528 	char errbuf[ERRBUFLEN];
4529 	nvlist_t *tgt;
4530 	boolean_t avail_spare, l2cache, islog;
4531 	libzfs_handle_t *hdl = zhp->zpool_hdl;
4532 
4533 	(void) snprintf(errbuf, sizeof (errbuf),
4534 	    dgettext(TEXT_DOMAIN, "cannot determine indirect size of %s"),
4535 	    path);
4536 
4537 	if ((tgt = zpool_find_vdev(zhp, path, &avail_spare, &l2cache,
4538 	    &islog)) == NULL)
4539 		return (zfs_error(hdl, EZFS_NODEVICE, errbuf));
4540 
4541 	if (avail_spare || l2cache || islog) {
4542 		*sizep = 0;
4543 		return (0);
4544 	}
4545 
4546 	if (nvlist_lookup_uint64(tgt, ZPOOL_CONFIG_INDIRECT_SIZE, sizep) != 0) {
4547 		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
4548 		    "indirect size not available"));
4549 		return (zfs_error(hdl, EINVAL, errbuf));
4550 	}
4551 	return (0);
4552 }
4553 
4554 /*
4555  * Clear the errors for the pool, or the particular device if specified.
4556  */
4557 int
4558 zpool_clear(zpool_handle_t *zhp, const char *path, nvlist_t *rewindnvl)
4559 {
4560 	zfs_cmd_t zc = {"\0"};
4561 	char errbuf[ERRBUFLEN];
4562 	nvlist_t *tgt;
4563 	zpool_load_policy_t policy;
4564 	boolean_t avail_spare, l2cache;
4565 	libzfs_handle_t *hdl = zhp->zpool_hdl;
4566 	nvlist_t *nvi = NULL;
4567 	int error;
4568 
4569 	if (path)
4570 		(void) snprintf(errbuf, sizeof (errbuf),
4571 		    dgettext(TEXT_DOMAIN, "cannot clear errors for %s"),
4572 		    path);
4573 	else
4574 		(void) snprintf(errbuf, sizeof (errbuf),
4575 		    dgettext(TEXT_DOMAIN, "cannot clear errors for %s"),
4576 		    zhp->zpool_name);
4577 
4578 	(void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
4579 	if (path) {
4580 		if ((tgt = zpool_find_vdev(zhp, path, &avail_spare,
4581 		    &l2cache, NULL)) == NULL)
4582 			return (zfs_error(hdl, EZFS_NODEVICE, errbuf));
4583 
4584 		/*
4585 		 * Don't allow error clearing for hot spares.  Do allow
4586 		 * error clearing for l2cache devices.
4587 		 */
4588 		if (avail_spare)
4589 			return (zfs_error(hdl, EZFS_ISSPARE, errbuf));
4590 
4591 		zc.zc_guid = fnvlist_lookup_uint64(tgt, ZPOOL_CONFIG_GUID);
4592 	}
4593 
4594 	zpool_get_load_policy(rewindnvl, &policy);
4595 	zc.zc_cookie = policy.zlp_rewind;
4596 
4597 	zcmd_alloc_dst_nvlist(hdl, &zc, zhp->zpool_config_size * 2);
4598 	if (rewindnvl != NULL)
4599 		zcmd_write_src_nvlist(hdl, &zc, rewindnvl);
4600 
4601 	while ((error = zfs_ioctl(hdl, ZFS_IOC_CLEAR, &zc)) != 0 &&
4602 	    errno == ENOMEM)
4603 		zcmd_expand_dst_nvlist(hdl, &zc);
4604 
4605 	if (!error || ((policy.zlp_rewind & ZPOOL_TRY_REWIND) &&
4606 	    errno != EPERM && errno != EACCES)) {
4607 		if (policy.zlp_rewind &
4608 		    (ZPOOL_DO_REWIND | ZPOOL_TRY_REWIND)) {
4609 			(void) zcmd_read_dst_nvlist(hdl, &zc, &nvi);
4610 			zpool_rewind_exclaim(hdl, zc.zc_name, nvi);
4611 			nvlist_free(nvi);
4612 		}
4613 		zcmd_free_nvlists(&zc);
4614 		return (0);
4615 	}
4616 
4617 	zcmd_free_nvlists(&zc);
4618 	return (zpool_standard_error(hdl, errno, errbuf));
4619 }
4620 
4621 /*
4622  * Similar to zpool_clear(), but takes a GUID (used by fmd).
4623  */
4624 int
4625 zpool_vdev_clear(zpool_handle_t *zhp, uint64_t guid)
4626 {
4627 	zfs_cmd_t zc = {"\0"};
4628 	char errbuf[ERRBUFLEN];
4629 	libzfs_handle_t *hdl = zhp->zpool_hdl;
4630 
4631 	(void) snprintf(errbuf, sizeof (errbuf),
4632 	    dgettext(TEXT_DOMAIN, "cannot clear errors for %llx"),
4633 	    (u_longlong_t)guid);
4634 
4635 	(void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
4636 	zc.zc_guid = guid;
4637 	zc.zc_cookie = ZPOOL_NO_REWIND;
4638 
4639 	if (zfs_ioctl(hdl, ZFS_IOC_CLEAR, &zc) == 0)
4640 		return (0);
4641 
4642 	return (zpool_standard_error(hdl, errno, errbuf));
4643 }
4644 
4645 /*
4646  * Change the GUID for a pool.
4647  *
4648  * Similar to zpool_reguid(), but may take a GUID.
4649  *
4650  * If the guid argument is NULL, then no GUID is passed in the nvlist to the
4651  * ioctl().
4652  */
4653 int
4654 zpool_set_guid(zpool_handle_t *zhp, const uint64_t *guid)
4655 {
4656 	char errbuf[ERRBUFLEN];
4657 	libzfs_handle_t *hdl = zhp->zpool_hdl;
4658 	nvlist_t *nvl = NULL;
4659 	zfs_cmd_t zc = {"\0"};
4660 	int error;
4661 
4662 	if (guid != NULL) {
4663 		if (nvlist_alloc(&nvl, NV_UNIQUE_NAME, 0) != 0)
4664 			return (no_memory(hdl));
4665 
4666 		if (nvlist_add_uint64(nvl, ZPOOL_REGUID_GUID, *guid) != 0) {
4667 			nvlist_free(nvl);
4668 			return (no_memory(hdl));
4669 		}
4670 
4671 		zcmd_write_src_nvlist(hdl, &zc, nvl);
4672 	}
4673 
4674 	(void) snprintf(errbuf, sizeof (errbuf),
4675 	    dgettext(TEXT_DOMAIN, "cannot reguid '%s'"), zhp->zpool_name);
4676 
4677 	(void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
4678 	error = zfs_ioctl(hdl, ZFS_IOC_POOL_REGUID, &zc);
4679 	if (error) {
4680 		return (zpool_standard_error(hdl, errno, errbuf));
4681 	}
4682 	if (guid != NULL) {
4683 		zcmd_free_nvlists(&zc);
4684 		nvlist_free(nvl);
4685 	}
4686 	return (0);
4687 }
4688 
4689 /*
4690  * Change the GUID for a pool.
4691  */
4692 int
4693 zpool_reguid(zpool_handle_t *zhp)
4694 {
4695 	return (zpool_set_guid(zhp, NULL));
4696 }
4697 
4698 /*
4699  * Reopen the pool.
4700  */
4701 int
4702 zpool_reopen_one(zpool_handle_t *zhp, void *data)
4703 {
4704 	libzfs_handle_t *hdl = zpool_get_handle(zhp);
4705 	const char *pool_name = zpool_get_name(zhp);
4706 	boolean_t *scrub_restart = data;
4707 	int error;
4708 
4709 	error = lzc_reopen(pool_name, *scrub_restart);
4710 	if (error) {
4711 		return (zpool_standard_error_fmt(hdl, error,
4712 		    dgettext(TEXT_DOMAIN, "cannot reopen '%s'"), pool_name));
4713 	}
4714 
4715 	return (0);
4716 }
4717 
4718 /*
4719  * Block until every buffered write for the pool has reached the
4720  * underlying disks.
4721  */
4722 int
4723 zpool_sync_one(zpool_handle_t *zhp, void *data)
4724 {
4725 	int ret;
4726 	libzfs_handle_t *hdl = zpool_get_handle(zhp);
4727 	const char *pool_name = zpool_get_name(zhp);
4728 	boolean_t *force = data;
4729 	nvlist_t *innvl = fnvlist_alloc();
4730 
4731 	fnvlist_add_boolean_value(innvl, "force", *force);
4732 	if ((ret = lzc_sync(pool_name, innvl, NULL)) != 0) {
4733 		nvlist_free(innvl);
4734 		return (zpool_standard_error_fmt(hdl, ret,
4735 		    dgettext(TEXT_DOMAIN, "sync '%s' failed"), pool_name));
4736 	}
4737 	nvlist_free(innvl);
4738 
4739 	return (0);
4740 }
4741 
4742 int
4743 zpool_condense(zpool_handle_t *zhp, const char *cmd, const char *type)
4744 {
4745 	int ret;
4746 
4747 	libzfs_handle_t *hdl = zpool_get_handle(zhp);
4748 	const char *pool_name = zpool_get_name(zhp);
4749 
4750 	if ((ret = lzc_condense(pool_name, cmd, type)) != 0) {
4751 		return (zpool_standard_error_fmt(hdl, ret,
4752 		    dgettext(TEXT_DOMAIN, "condense '%s' failed"), pool_name));
4753 	}
4754 
4755 	return (0);
4756 }
4757 
4758 #define	PATH_BUF_LEN	64
4759 
4760 /*
4761  * Given a vdev, return the name to display in iostat.  If the vdev has a path,
4762  * we use that, stripping off any leading "/dev/dsk/"; if not, we use the type.
4763  * We also check if this is a whole disk, in which case we strip off the
4764  * trailing 's0' slice name.
4765  *
4766  * This routine is also responsible for identifying when disks have been
4767  * reconfigured in a new location.  The kernel will have opened the device by
4768  * devid, but the path will still refer to the old location.  To catch this, we
4769  * first do a path -> devid translation (which is fast for the common case).  If
4770  * the devid matches, we're done.  If not, we do a reverse devid -> path
4771  * translation and issue the appropriate ioctl() to update the path of the vdev.
4772  * If 'zhp' is NULL, then this is an exported pool, and we don't need to do any
4773  * of these checks.
4774  */
4775 char *
4776 zpool_vdev_name(libzfs_handle_t *hdl, zpool_handle_t *zhp, nvlist_t *nv,
4777     int name_flags)
4778 {
4779 	const char *type, *tpath;
4780 	const char *path;
4781 	uint64_t value;
4782 	char buf[PATH_BUF_LEN];
4783 	char tmpbuf[PATH_BUF_LEN * 2];
4784 	char rpath[MAXPATHLEN];
4785 
4786 	/*
4787 	 * vdev_name will be "root"/"root-0" for the root vdev, but it is the
4788 	 * zpool name that will be displayed to the user.
4789 	 */
4790 	type = fnvlist_lookup_string(nv, ZPOOL_CONFIG_TYPE);
4791 	if (zhp != NULL && strcmp(type, "root") == 0)
4792 		return (zfs_strdup(hdl, zpool_get_name(zhp)));
4793 
4794 	if (libzfs_envvar_is_set("ZPOOL_VDEV_NAME_PATH"))
4795 		name_flags |= VDEV_NAME_PATH;
4796 	if (libzfs_envvar_is_set("ZPOOL_VDEV_NAME_GUID"))
4797 		name_flags |= VDEV_NAME_GUID;
4798 	if (libzfs_envvar_is_set("ZPOOL_VDEV_NAME_FOLLOW_LINKS"))
4799 		name_flags |= VDEV_NAME_FOLLOW_LINKS;
4800 
4801 	if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_NOT_PRESENT, &value) == 0 ||
4802 	    name_flags & VDEV_NAME_GUID) {
4803 		(void) nvlist_lookup_uint64(nv, ZPOOL_CONFIG_GUID, &value);
4804 		(void) snprintf(buf, sizeof (buf), "%llu", (u_longlong_t)value);
4805 		path = buf;
4806 	} else if (nvlist_lookup_string(nv, ZPOOL_CONFIG_PATH, &tpath) == 0) {
4807 		path = tpath;
4808 
4809 		if (name_flags & VDEV_NAME_FOLLOW_LINKS) {
4810 			if (realpath(path, rpath) != NULL)
4811 				path = rpath;
4812 		}
4813 
4814 		/*
4815 		 * For a block device only use the name.
4816 		 */
4817 		if ((strcmp(type, VDEV_TYPE_DISK) == 0) &&
4818 		    !(name_flags & VDEV_NAME_PATH)) {
4819 			path = zfs_strip_path(path);
4820 		}
4821 
4822 		/*
4823 		 * Remove the partition from the path if this is a whole disk.
4824 		 */
4825 		if (strcmp(type, VDEV_TYPE_DRAID_SPARE) != 0 &&
4826 		    nvlist_lookup_uint64(nv, ZPOOL_CONFIG_WHOLE_DISK, &value)
4827 		    == 0 && value && !(name_flags & VDEV_NAME_PATH)) {
4828 			return (zfs_strip_partition(path));
4829 		}
4830 	} else {
4831 		path = type;
4832 
4833 		/*
4834 		 * If it's a raidz device, we need to stick in the parity level.
4835 		 */
4836 		if (strcmp(path, VDEV_TYPE_RAIDZ) == 0) {
4837 			value = fnvlist_lookup_uint64(nv, ZPOOL_CONFIG_NPARITY);
4838 			(void) snprintf(buf, sizeof (buf), "%s%llu", path,
4839 			    (u_longlong_t)value);
4840 			path = buf;
4841 		}
4842 
4843 		/*
4844 		 * If it's a dRAID device, we add parity, groups, and spares.
4845 		 */
4846 		if (strcmp(path, VDEV_TYPE_DRAID) == 0) {
4847 			uint64_t ndata, nparity, nspares, children;
4848 			nvlist_t **child;
4849 			uint_t width;
4850 
4851 			verify(nvlist_lookup_nvlist_array(nv,
4852 			    ZPOOL_CONFIG_CHILDREN, &child, &width) == 0);
4853 			nparity = fnvlist_lookup_uint64(nv,
4854 			    ZPOOL_CONFIG_NPARITY);
4855 			ndata = fnvlist_lookup_uint64(nv,
4856 			    ZPOOL_CONFIG_DRAID_NDATA);
4857 			nspares = fnvlist_lookup_uint64(nv,
4858 			    ZPOOL_CONFIG_DRAID_NSPARES);
4859 
4860 			if (nvlist_lookup_uint64(nv,
4861 			    ZPOOL_CONFIG_DRAID_NCHILDREN, &children) != 0)
4862 				children = width;
4863 
4864 			path = zpool_draid_name(buf, sizeof (buf), ndata,
4865 			    nparity, nspares, children, width);
4866 		}
4867 
4868 		/*
4869 		 * We identify each top-level vdev by using a <type-id>
4870 		 * naming convention.
4871 		 */
4872 		if (name_flags & VDEV_NAME_TYPE_ID) {
4873 			uint64_t id = fnvlist_lookup_uint64(nv,
4874 			    ZPOOL_CONFIG_ID);
4875 			(void) snprintf(tmpbuf, sizeof (tmpbuf), "%s-%llu",
4876 			    path, (u_longlong_t)id);
4877 			path = tmpbuf;
4878 		}
4879 	}
4880 
4881 	return (zfs_strdup(hdl, path));
4882 }
4883 
4884 static int
4885 zbookmark_mem_compare(const void *a, const void *b)
4886 {
4887 	return (memcmp(a, b, sizeof (zbookmark_phys_t)));
4888 }
4889 
4890 void
4891 zpool_add_propname(zpool_handle_t *zhp, const char *propname)
4892 {
4893 	assert(zhp->zpool_n_propnames < ZHP_MAX_PROPNAMES);
4894 	zhp->zpool_propnames[zhp->zpool_n_propnames] = propname;
4895 	zhp->zpool_n_propnames++;
4896 }
4897 
4898 /*
4899  * Given a properties nvlist like:
4900  *
4901  * refreservation:
4902  *     source: 'tank/vol'
4903  *     value: 1092616192
4904  * recordsize:
4905  *     value: 4096
4906  *     source: 'tank'
4907  * refcompressratio:
4908  *     value: 100
4909  * logicalreferenced:
4910  *     value: 1076408320
4911  * compressratio:
4912  *    value: 100
4913  *    ...
4914  *
4915  * Lookup the 'value' field for a uint64_t and return it into *val.  For
4916  * example, if you pass "recordsize" for the name, it will store 4096 into *val.
4917  */
4918 static int
4919 zpool_get_from_prop_nvlist_uint64(nvlist_t *nv, const char *name, uint64_t *val)
4920 {
4921 	nvlist_t *tmp;
4922 	int rc;
4923 
4924 	rc = nvlist_lookup_nvlist(nv, name, &tmp);
4925 	if (rc != 0)
4926 		return (rc);
4927 
4928 	return (nvlist_lookup_uint64(tmp, "value", val));
4929 }
4930 
4931 /*
4932  * Given a dataset object and object number, return its data blocks size
4933  * and type string (type_str).  type_str must be freed when no longer needed.
4934  */
4935 static int
4936 zpool_get_extended_obj_stat_helper(zpool_handle_t *zhp, uint64_t dsobj,
4937     uint64_t obj, uint64_t *data_block_size, char **type_str)
4938 {
4939 	nvlist_t *nv;
4940 	boolean_t is_zvol = B_FALSE;
4941 	uint64_t val;
4942 	int rc;
4943 
4944 	nv = zpool_get_extended_obj_stat(zhp, dsobj, obj);
4945 	if (nv == NULL) {
4946 		nv = zpool_get_extended_objset_stat(zhp, dsobj, obj);
4947 		if (nv == NULL) {
4948 			return (-1);
4949 		}
4950 		is_zvol = B_TRUE;
4951 	}
4952 	if (is_zvol) {
4953 		rc = zpool_get_from_prop_nvlist_uint64(nv,
4954 		    zfs_prop_to_name(ZFS_PROP_VOLBLOCKSIZE), &val);
4955 	} else {
4956 		uint32_t val32 = 0;
4957 		rc = nvlist_lookup_uint32(nv, ZFS_OBJ_STAT_DATA_BLOCK_SIZE,
4958 		    &val32);
4959 		val = val32;
4960 	}
4961 
4962 	if (rc != 0) {
4963 		nvlist_free(nv);
4964 		return (rc);
4965 	}
4966 	*data_block_size = val;
4967 
4968 	const char *tmp;
4969 	if (is_zvol)
4970 		tmp = "zvol";
4971 	else
4972 		tmp = fnvlist_lookup_string(nv, ZFS_OBJ_STAT_TYPE_STR);
4973 	*type_str = strdup(tmp);
4974 
4975 	nvlist_free(nv);
4976 	return (0);
4977 }
4978 
4979 static void zpool_get_errlog_process_file_cb(void *arg, uint64_t start,
4980 	uint64_t size) {
4981 	nvlist_t ***tmp = arg;
4982 	nvlist_t **nva_next = *tmp;
4983 	nvlist_t *nv;
4984 
4985 	nv = fnvlist_alloc();
4986 	fnvlist_add_uint64(nv, ZPOOL_ERR_START_BYTE, start);
4987 	fnvlist_add_uint64(nv, ZPOOL_ERR_END_BYTE, start + size - 1);
4988 	*nva_next = nv;
4989 
4990 	/* Advance to next array entry */
4991 	*tmp = nva_next + 1;
4992 }
4993 
4994 static void
4995 zpool_get_errlog_process_file(zpool_handle_t *zhp,
4996     nvlist_t **nverrlistp, zbookmark_phys_t *zb_start, zbookmark_phys_t *zb_end)
4997 {
4998 	uint64_t data_block_size = 0;
4999 	char *type_str = NULL;
5000 	nvlist_t *nv, **nva, **nva_next;
5001 	uint64_t count = 0;
5002 
5003 	/* Make the linter happy */
5004 	VERIFY(zb_start != NULL);
5005 	VERIFY(zb_end != NULL);
5006 
5007 	nv = fnvlist_alloc();
5008 	fnvlist_add_uint64(nv, ZPOOL_ERR_DATASET, zb_start->zb_objset);
5009 	fnvlist_add_uint64(nv, ZPOOL_ERR_OBJECT, zb_start->zb_object);
5010 
5011 	if (zpool_get_extended_obj_stat_helper(zhp, zb_start->zb_objset,
5012 	    zb_start->zb_object, &data_block_size, &type_str) != 0) {
5013 		/*
5014 		 * If the kernel supports extended stats, then include them.
5015 		 * If not, it's still OK.
5016 		 */
5017 		goto end;
5018 	}
5019 
5020 	fnvlist_add_string(nv, ZPOOL_ERR_OBJECT_TYPE, type_str);
5021 	fnvlist_add_uint64(nv, ZPOOL_ERR_BLOCK_SIZE, data_block_size);
5022 	free(type_str);
5023 
5024 	zfs_range_tree_t *range_tree;
5025 	range_tree = zfs_range_tree_create(NULL, ZFS_RANGE_SEG64, NULL, 0,  0);
5026 	if (range_tree == NULL)
5027 		goto end;
5028 
5029 	do {
5030 		int data_block_size_shift;
5031 		uint64_t data_block_range;
5032 
5033 		/*
5034 		 * If an L1 (or higher block) is damaged, it will affect a much
5035 		 * larger byte range than a simple L0 block.  Calculate these
5036 		 * ranges correctly.
5037 		 */
5038 		if (highbit64(data_block_size) != lowbit64(data_block_size)) {
5039 			/*
5040 			 * Our data block size is not power-of-two.  This is
5041 			 * probably a single block file.
5042 			 */
5043 			data_block_size_shift = 0;
5044 			data_block_range = data_block_size;
5045 		} else {
5046 			data_block_size_shift = highbit64(data_block_size) - 1;
5047 			data_block_range = BP_BYTE_RANGE(data_block_size_shift,
5048 			    zb_start->zb_level);
5049 		}
5050 
5051 		/*
5052 		 * The range we are adding could overlap other entries.  Do
5053 		 * a clear first to punch a hole in any existing ranges,
5054 		 * then do the add.  We have to do this since our add can't
5055 		 * overlap an existing range.
5056 		 */
5057 		zfs_range_tree_clear(range_tree,
5058 		    zb_start->zb_blkid * data_block_range, data_block_range);
5059 		zfs_range_tree_add(range_tree,
5060 		    zb_start->zb_blkid * data_block_range, data_block_range);
5061 
5062 		if (zb_start == zb_end)
5063 			break;
5064 	} while (zb_start++);
5065 
5066 	/*
5067 	 * Our range tree has all our ranges.  Construct an array of start/end
5068 	 * entries.
5069 	 */
5070 	count = zfs_range_tree_numsegs(range_tree);
5071 
5072 	nva = zfs_alloc(zhp->zpool_hdl, sizeof (nvlist_t *) * count);
5073 	nva_next = &nva[0];
5074 
5075 	zfs_range_tree_walk(range_tree, zpool_get_errlog_process_file_cb,
5076 	    &nva_next);
5077 
5078 	zfs_range_tree_vacate(range_tree, NULL, NULL);
5079 	zfs_range_tree_destroy(range_tree);
5080 
5081 	fnvlist_add_nvlist_array(nv, ZPOOL_ERR_RANGES, (const nvlist_t **) nva,
5082 	    count);
5083 
5084 	for (uint64_t i = 0; i < count; i++)
5085 		nvlist_free(nva[i]);
5086 	free(nva);
5087 
5088 end:
5089 	fnvlist_add_nvlist(*nverrlistp, "ejk", nv);
5090 	nvlist_free(nv);
5091 }
5092 
5093 /*
5094  * Retrieve the persistent error log, uniquify the members, and return to the
5095  * caller.
5096  */
5097 int
5098 zpool_get_errlog(zpool_handle_t *zhp, nvlist_t **nverrlistp)
5099 {
5100 	zfs_cmd_t zc = {"\0"};
5101 	libzfs_handle_t *hdl = zhp->zpool_hdl;
5102 	zbookmark_phys_t *buf;
5103 	uint64_t buflen = 10000; /* approx. 1MB of RAM */
5104 	uint64_t i;
5105 
5106 	if (fnvlist_lookup_uint64(zhp->zpool_config,
5107 	    ZPOOL_CONFIG_ERRCOUNT) == 0)
5108 		return (0);
5109 
5110 	/*
5111 	 * Retrieve the raw error list from the kernel.  If it doesn't fit,
5112 	 * allocate a larger buffer and retry.
5113 	 */
5114 	(void) strcpy(zc.zc_name, zhp->zpool_name);
5115 	for (;;) {
5116 		buf = zfs_alloc(zhp->zpool_hdl,
5117 		    buflen * sizeof (zbookmark_phys_t));
5118 		zc.zc_nvlist_dst = (uintptr_t)buf;
5119 		zc.zc_nvlist_dst_size = buflen;
5120 		if (zfs_ioctl(zhp->zpool_hdl, ZFS_IOC_ERROR_LOG,
5121 		    &zc) != 0) {
5122 			free(buf);
5123 			if (errno == ENOMEM) {
5124 				buflen *= 2;
5125 			} else {
5126 				return (zpool_standard_error_fmt(hdl, errno,
5127 				    dgettext(TEXT_DOMAIN, "errors: List of "
5128 				    "errors unavailable")));
5129 			}
5130 		} else {
5131 			break;
5132 		}
5133 	}
5134 
5135 	/*
5136 	 * Sort the resulting bookmarks.  This is a little confusing due to the
5137 	 * implementation of ZFS_IOC_ERROR_LOG.  The bookmarks are copied last
5138 	 * to first, and 'zc_nvlist_dst_size' indicates the number of bookmarks
5139 	 * _not_ copied as part of the process.  So we point the start of our
5140 	 * array appropriate and decrement the total number of elements.
5141 	 */
5142 	zbookmark_phys_t *zb = buf + zc.zc_nvlist_dst_size;
5143 	uint64_t zblen = buflen - zc.zc_nvlist_dst_size;
5144 	if (zblen == 0) {
5145 		free(buf);
5146 		return (0); /* nothing to do */
5147 	}
5148 
5149 	qsort(zb, zblen, sizeof (zbookmark_phys_t), zbookmark_mem_compare);
5150 
5151 	verify(nvlist_alloc(nverrlistp, 0, KM_SLEEP) == 0);
5152 
5153 	/*
5154 	 * Fill in the nverrlistp with nvlist's of dataset and object numbers.
5155 	 */
5156 	zbookmark_phys_t *start = NULL;
5157 
5158 	for (i = 0; i < zblen; i++) {
5159 		if (start == NULL) {
5160 			start = &zb[i];
5161 			continue;
5162 		}
5163 
5164 		/* filter out duplicate files and levels */
5165 		if (zb[i-1].zb_objset == zb[i].zb_objset &&
5166 		    zb[i-1].zb_object == zb[i].zb_object) {
5167 			/* same file, new error block */
5168 			continue;
5169 		} else {
5170 			/*
5171 			 * Every time we see a new object, process the
5172 			 * previous one.
5173 			 */
5174 			zpool_get_errlog_process_file(zhp, nverrlistp,
5175 			    start, &zb[i-1]);
5176 			start = &zb[i];
5177 		}
5178 	}
5179 	/* Process the last entry */
5180 	zpool_get_errlog_process_file(zhp, nverrlistp, start, &zb[i-1]);
5181 
5182 	free(buf);
5183 
5184 	return (0);
5185 }
5186 
5187 /*
5188  * Upgrade a ZFS pool to the latest on-disk version.
5189  */
5190 int
5191 zpool_upgrade(zpool_handle_t *zhp, uint64_t new_version)
5192 {
5193 	zfs_cmd_t zc = {"\0"};
5194 	libzfs_handle_t *hdl = zhp->zpool_hdl;
5195 
5196 	(void) strcpy(zc.zc_name, zhp->zpool_name);
5197 	zc.zc_cookie = new_version;
5198 
5199 	if (zfs_ioctl(hdl, ZFS_IOC_POOL_UPGRADE, &zc) != 0)
5200 		return (zpool_standard_error_fmt(hdl, errno,
5201 		    dgettext(TEXT_DOMAIN, "cannot upgrade '%s'"),
5202 		    zhp->zpool_name));
5203 	return (0);
5204 }
5205 
5206 /*
5207  * Format the program name and its command-line arguments into a single
5208  * space-separated string.
5209  */
5210 void
5211 zfs_save_arguments(int argc, char **argv, char *string, int len)
5212 {
5213 	int i;
5214 
5215 	(void) strlcpy(string, zfs_basename(argv[0]), len);
5216 	for (i = 1; i < argc; i++) {
5217 		(void) strlcat(string, " ", len);
5218 		(void) strlcat(string, argv[i], len);
5219 	}
5220 }
5221 
5222 /*
5223  * Append a message to the pool's command-history log, retrievable via
5224  * "zpool history".
5225  */
5226 int
5227 zpool_log_history(libzfs_handle_t *hdl, const char *message)
5228 {
5229 	zfs_cmd_t zc = {"\0"};
5230 	nvlist_t *args;
5231 
5232 	args = fnvlist_alloc();
5233 	fnvlist_add_string(args, "message", message);
5234 	zcmd_write_src_nvlist(hdl, &zc, args);
5235 	int err = zfs_ioctl(hdl, ZFS_IOC_LOG_HISTORY, &zc);
5236 	nvlist_free(args);
5237 	zcmd_free_nvlists(&zc);
5238 	return (err);
5239 }
5240 
5241 /*
5242  * Perform ioctl to get some command history of a pool.
5243  *
5244  * 'buf' is the buffer to fill up to 'len' bytes.  'off' is the
5245  * logical offset of the history buffer to start reading from.
5246  *
5247  * Upon return, 'off' is the next logical offset to read from and
5248  * 'len' is the actual amount of bytes read into 'buf'.
5249  */
5250 static int
5251 get_history(zpool_handle_t *zhp, char *buf, uint64_t *off, uint64_t *len)
5252 {
5253 	zfs_cmd_t zc = {"\0"};
5254 	libzfs_handle_t *hdl = zhp->zpool_hdl;
5255 
5256 	(void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
5257 
5258 	zc.zc_history = (uint64_t)(uintptr_t)buf;
5259 	zc.zc_history_len = *len;
5260 	zc.zc_history_offset = *off;
5261 
5262 	if (zfs_ioctl(hdl, ZFS_IOC_POOL_GET_HISTORY, &zc) != 0) {
5263 		switch (errno) {
5264 		case EPERM:
5265 			return (zfs_error_fmt(hdl, EZFS_PERM,
5266 			    dgettext(TEXT_DOMAIN,
5267 			    "cannot show history for pool '%s'"),
5268 			    zhp->zpool_name));
5269 		case ENOENT:
5270 			return (zfs_error_fmt(hdl, EZFS_NOHISTORY,
5271 			    dgettext(TEXT_DOMAIN, "cannot get history for pool "
5272 			    "'%s'"), zhp->zpool_name));
5273 		case ENOTSUP:
5274 			return (zfs_error_fmt(hdl, EZFS_BADVERSION,
5275 			    dgettext(TEXT_DOMAIN, "cannot get history for pool "
5276 			    "'%s', pool must be upgraded"), zhp->zpool_name));
5277 		default:
5278 			return (zpool_standard_error_fmt(hdl, errno,
5279 			    dgettext(TEXT_DOMAIN,
5280 			    "cannot get history for '%s'"), zhp->zpool_name));
5281 		}
5282 	}
5283 
5284 	*len = zc.zc_history_len;
5285 	*off = zc.zc_history_offset;
5286 
5287 	return (0);
5288 }
5289 
5290 /*
5291  * Retrieve the command history of a pool.
5292  */
5293 int
5294 zpool_get_history(zpool_handle_t *zhp, nvlist_t **nvhisp, uint64_t *off,
5295     boolean_t *eof)
5296 {
5297 	libzfs_handle_t *hdl = zhp->zpool_hdl;
5298 	char *buf;
5299 	int buflen = 128 * 1024;
5300 	nvlist_t **records = NULL;
5301 	uint_t numrecords = 0;
5302 	int err = 0, i;
5303 	uint64_t start = *off;
5304 
5305 	buf = zfs_alloc(hdl, buflen);
5306 
5307 	/* process about 1MiB a time */
5308 	while (*off - start < 1024 * 1024) {
5309 		uint64_t bytes_read = buflen;
5310 		uint64_t leftover;
5311 
5312 		if ((err = get_history(zhp, buf, off, &bytes_read)) != 0)
5313 			break;
5314 
5315 		/* if nothing else was read in, we're at EOF, just return */
5316 		if (!bytes_read) {
5317 			*eof = B_TRUE;
5318 			break;
5319 		}
5320 
5321 		if ((err = zpool_history_unpack(buf, bytes_read,
5322 		    &leftover, &records, &numrecords)) != 0) {
5323 			zpool_standard_error_fmt(hdl, err,
5324 			    dgettext(TEXT_DOMAIN,
5325 			    "cannot get history for '%s'"), zhp->zpool_name);
5326 			break;
5327 		}
5328 		*off -= leftover;
5329 		if (leftover == bytes_read) {
5330 			/*
5331 			 * no progress made, because buffer is not big enough
5332 			 * to hold this record; resize and retry.
5333 			 */
5334 			buflen *= 2;
5335 			free(buf);
5336 			buf = zfs_alloc(hdl, buflen);
5337 		}
5338 	}
5339 
5340 	free(buf);
5341 
5342 	if (!err) {
5343 		*nvhisp = fnvlist_alloc();
5344 		fnvlist_add_nvlist_array(*nvhisp, ZPOOL_HIST_RECORD,
5345 		    (const nvlist_t **)records, numrecords);
5346 	}
5347 	for (i = 0; i < numrecords; i++)
5348 		nvlist_free(records[i]);
5349 	free(records);
5350 
5351 	return (err);
5352 }
5353 
5354 /*
5355  * Retrieve the next event given the passed 'zevent_fd' file descriptor.
5356  * If there is a new event available 'nvp' will contain a newly allocated
5357  * nvlist and 'dropped' will be set to the number of missed events since
5358  * the last call to this function.  When 'nvp' is set to NULL it indicates
5359  * no new events are available.  In either case the function returns 0 and
5360  * it is up to the caller to free 'nvp'.  In the case of a fatal error the
5361  * function will return a non-zero value.  When the function is called in
5362  * blocking mode (the default, unless the ZEVENT_NONBLOCK flag is passed),
5363  * it will not return until a new event is available.
5364  */
5365 int
5366 zpool_events_next(libzfs_handle_t *hdl, nvlist_t **nvp,
5367     int *dropped, unsigned flags, int zevent_fd)
5368 {
5369 	zfs_cmd_t zc = {"\0"};
5370 	int error = 0;
5371 
5372 	*nvp = NULL;
5373 	*dropped = 0;
5374 	zc.zc_cleanup_fd = zevent_fd;
5375 
5376 	if (flags & ZEVENT_NONBLOCK)
5377 		zc.zc_guid = ZEVENT_NONBLOCK;
5378 
5379 	zcmd_alloc_dst_nvlist(hdl, &zc, ZEVENT_SIZE);
5380 
5381 retry:
5382 	if (zfs_ioctl(hdl, ZFS_IOC_EVENTS_NEXT, &zc) != 0) {
5383 		switch (errno) {
5384 		case ESHUTDOWN:
5385 			error = zfs_error_fmt(hdl, EZFS_POOLUNAVAIL,
5386 			    dgettext(TEXT_DOMAIN, "zfs shutdown"));
5387 			goto out;
5388 		case ENOENT:
5389 			/* Blocking error case should not occur */
5390 			if (!(flags & ZEVENT_NONBLOCK))
5391 				error = zpool_standard_error_fmt(hdl, errno,
5392 				    dgettext(TEXT_DOMAIN, "cannot get event"));
5393 
5394 			goto out;
5395 		case ENOMEM:
5396 			zcmd_expand_dst_nvlist(hdl, &zc);
5397 			goto retry;
5398 		default:
5399 			error = zpool_standard_error_fmt(hdl, errno,
5400 			    dgettext(TEXT_DOMAIN, "cannot get event"));
5401 			goto out;
5402 		}
5403 	}
5404 
5405 	error = zcmd_read_dst_nvlist(hdl, &zc, nvp);
5406 	if (error != 0)
5407 		goto out;
5408 
5409 	*dropped = (int)zc.zc_cookie;
5410 out:
5411 	zcmd_free_nvlists(&zc);
5412 
5413 	return (error);
5414 }
5415 
5416 /*
5417  * Clear all events.
5418  */
5419 int
5420 zpool_events_clear(libzfs_handle_t *hdl, int *count)
5421 {
5422 	zfs_cmd_t zc = {"\0"};
5423 
5424 	if (zfs_ioctl(hdl, ZFS_IOC_EVENTS_CLEAR, &zc) != 0)
5425 		return (zpool_standard_error(hdl, errno,
5426 		    dgettext(TEXT_DOMAIN, "cannot clear events")));
5427 
5428 	if (count != NULL)
5429 		*count = (int)zc.zc_cookie; /* # of events cleared */
5430 
5431 	return (0);
5432 }
5433 
5434 /*
5435  * Seek to a specific EID, ZEVENT_SEEK_START, or ZEVENT_SEEK_END for
5436  * the passed zevent_fd file handle.  On success zero is returned,
5437  * otherwise -1 is returned and hdl->libzfs_error is set to the errno.
5438  */
5439 int
5440 zpool_events_seek(libzfs_handle_t *hdl, uint64_t eid, int zevent_fd)
5441 {
5442 	zfs_cmd_t zc = {"\0"};
5443 	int error = 0;
5444 
5445 	zc.zc_guid = eid;
5446 	zc.zc_cleanup_fd = zevent_fd;
5447 
5448 	if (zfs_ioctl(hdl, ZFS_IOC_EVENTS_SEEK, &zc) != 0) {
5449 		switch (errno) {
5450 		case ENOENT:
5451 			error = zfs_error_fmt(hdl, EZFS_NOENT,
5452 			    dgettext(TEXT_DOMAIN, "cannot get event"));
5453 			break;
5454 
5455 		case ENOMEM:
5456 			error = zfs_error_fmt(hdl, EZFS_NOMEM,
5457 			    dgettext(TEXT_DOMAIN, "cannot get event"));
5458 			break;
5459 
5460 		default:
5461 			error = zpool_standard_error_fmt(hdl, errno,
5462 			    dgettext(TEXT_DOMAIN, "cannot get event"));
5463 			break;
5464 		}
5465 	}
5466 
5467 	return (error);
5468 }
5469 
5470 /*
5471  * Return extended information about an object.  This calls the "extended"
5472  * variant of ZFS_IOC_OBJ_TO_STATS to return things things like block size,
5473  * dmu type, dnone size, etc (see dmu_object_info_t).
5474  *
5475  * Returned nvlist must be freed by the user when they are done with it.
5476  */
5477 static nvlist_t *
5478 zpool_get_extended_obj_stat_impl(zpool_handle_t *zhp, uint64_t dsobj,
5479     uint64_t obj, enum zfs_ioc stats_ioctl)
5480 {
5481 	zfs_cmd_t zc = {"\0"};
5482 	char dsname[ZFS_MAX_DATASET_NAME_LEN];
5483 	nvlist_t *nv = NULL;
5484 	int error;
5485 
5486 	/* get the dataset's name */
5487 	zc.zc_obj = dsobj;
5488 	(void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
5489 	error = zfs_ioctl(zhp->zpool_hdl, ZFS_IOC_DSOBJ_TO_DSNAME, &zc);
5490 	if (error)
5491 		return (NULL);
5492 
5493 	(void) strlcpy(dsname, zc.zc_value, sizeof (dsname));
5494 	(void) strlcpy(zc.zc_name, dsname, sizeof (zc.zc_name));
5495 
5496 	zcmd_alloc_dst_nvlist(zhp->zpool_hdl, &zc, 1024);
5497 	zc.zc_obj = obj;
5498 	while (zfs_ioctl(zhp->zpool_hdl, stats_ioctl, &zc) != 0) {
5499 		if (errno == ENOMEM) {
5500 			zcmd_expand_dst_nvlist(zhp->zpool_hdl, &zc);
5501 		} else {
5502 			zcmd_free_nvlists(&zc);
5503 			return (NULL);
5504 		}
5505 	}
5506 
5507 	zcmd_read_dst_nvlist(zhp->zpool_hdl, &zc, &nv);
5508 	zcmd_free_nvlists(&zc);
5509 
5510 	return (nv);
5511 }
5512 
5513 /*
5514  * Return extended information about an object.  This calls the "extended"
5515  * variant of ZFS_IOC_OBJ_TO_STATS to return things things like block size,
5516  * dmu type, dnone size, etc (see dmu_object_info_t).
5517  *
5518  * Returned nvlist must be freed by the user when they are done with it.
5519  */
5520 static nvlist_t *
5521 zpool_get_extended_obj_stat(zpool_handle_t *zhp, uint64_t dsobj, uint64_t obj)
5522 {
5523 	return (zpool_get_extended_obj_stat_impl(zhp, dsobj, obj,
5524 	    ZFS_IOC_OBJ_TO_STATS));
5525 }
5526 
5527 static nvlist_t *
5528 zpool_get_extended_objset_stat(zpool_handle_t *zhp, uint64_t dsobj,
5529     uint64_t obj)
5530 {
5531 	return (zpool_get_extended_obj_stat_impl(zhp, dsobj, obj,
5532 	    ZFS_IOC_OBJSET_STATS));
5533 }
5534 
5535 static void
5536 zpool_obj_to_path_impl(zpool_handle_t *zhp, uint64_t dsobj, uint64_t obj,
5537     char *pathname, size_t len, boolean_t always_unmounted)
5538 {
5539 	zfs_cmd_t zc = {"\0"};
5540 	boolean_t mounted = B_FALSE;
5541 	char *mntpnt = NULL;
5542 	char dsname[ZFS_MAX_DATASET_NAME_LEN];
5543 
5544 	if (dsobj == 0) {
5545 		/* special case for the MOS */
5546 		(void) snprintf(pathname, len, "<metadata>:<0x%llx>",
5547 		    (longlong_t)obj);
5548 		return;
5549 	}
5550 
5551 	/* get the dataset's name */
5552 	(void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
5553 	zc.zc_obj = dsobj;
5554 	if (zfs_ioctl(zhp->zpool_hdl,
5555 	    ZFS_IOC_DSOBJ_TO_DSNAME, &zc) != 0) {
5556 		/* just write out a path of two object numbers */
5557 		(void) snprintf(pathname, len, "<0x%llx>:<0x%llx>",
5558 		    (longlong_t)dsobj, (longlong_t)obj);
5559 		return;
5560 	}
5561 	(void) strlcpy(dsname, zc.zc_value, sizeof (dsname));
5562 
5563 	/* find out if the dataset is mounted */
5564 	mounted = !always_unmounted && is_mounted(zhp->zpool_hdl, dsname,
5565 	    &mntpnt);
5566 
5567 	/* get the corrupted object's path */
5568 	(void) strlcpy(zc.zc_name, dsname, sizeof (zc.zc_name));
5569 	zc.zc_obj = obj;
5570 	if (zfs_ioctl(zhp->zpool_hdl, ZFS_IOC_OBJ_TO_PATH,
5571 	    &zc) == 0) {
5572 		if (mounted) {
5573 			(void) snprintf(pathname, len, "%s%s", mntpnt,
5574 			    zc.zc_value);
5575 		} else {
5576 			(void) snprintf(pathname, len, "%s:%s",
5577 			    dsname, zc.zc_value);
5578 		}
5579 	} else {
5580 		(void) snprintf(pathname, len, "%s:<0x%llx>", dsname,
5581 		    (longlong_t)obj);
5582 	}
5583 	free(mntpnt);
5584 }
5585 
5586 /*
5587  * Translate a (dataset object id, file object id) pair into a readable
5588  * path.  If the dataset is mounted the result is an absolute filesystem
5589  * path; otherwise it is `dataset:path`.
5590  */
5591 void
5592 zpool_obj_to_path(zpool_handle_t *zhp, uint64_t dsobj, uint64_t obj,
5593     char *pathname, size_t len)
5594 {
5595 	zpool_obj_to_path_impl(zhp, dsobj, obj, pathname, len, B_FALSE);
5596 }
5597 
5598 /*
5599  * Translate a (dataset object id, file object id) pair into a
5600  * `dataset:path` string.
5601  */
5602 void
5603 zpool_obj_to_path_ds(zpool_handle_t *zhp, uint64_t dsobj, uint64_t obj,
5604     char *pathname, size_t len)
5605 {
5606 	zpool_obj_to_path_impl(zhp, dsobj, obj, pathname, len, B_TRUE);
5607 }
5608 /*
5609  * Wait while the specified activity is in progress in the pool.
5610  */
5611 int
5612 zpool_wait(zpool_handle_t *zhp, zpool_wait_activity_t activity)
5613 {
5614 	boolean_t missing;
5615 
5616 	int error = zpool_wait_status(zhp, activity, &missing, NULL);
5617 
5618 	if (missing) {
5619 		(void) zpool_standard_error_fmt(zhp->zpool_hdl, ENOENT,
5620 		    dgettext(TEXT_DOMAIN, "error waiting in pool '%s'"),
5621 		    zhp->zpool_name);
5622 		return (ENOENT);
5623 	} else {
5624 		return (error);
5625 	}
5626 }
5627 
5628 /*
5629  * Wait for the given activity and return the status of the wait (whether or not
5630  * any waiting was done) in the 'waited' parameter. Non-existent pools are
5631  * reported via the 'missing' parameter, rather than by printing an error
5632  * message. This is convenient when this function is called in a loop over a
5633  * long period of time (as it is, for example, by zpool's wait cmd). In that
5634  * scenario, a pool being exported or destroyed should be considered a normal
5635  * event, so we don't want to print an error when we find that the pool doesn't
5636  * exist.
5637  */
5638 int
5639 zpool_wait_status(zpool_handle_t *zhp, zpool_wait_activity_t activity,
5640     boolean_t *missing, boolean_t *waited)
5641 {
5642 	int error = lzc_wait(zhp->zpool_name, activity, waited);
5643 	*missing = (error == ENOENT);
5644 	if (*missing)
5645 		return (0);
5646 
5647 	if (error != 0) {
5648 		(void) zpool_standard_error_fmt(zhp->zpool_hdl, error,
5649 		    dgettext(TEXT_DOMAIN, "error waiting in pool '%s'"),
5650 		    zhp->zpool_name);
5651 	}
5652 
5653 	return (error);
5654 }
5655 
5656 /*
5657  * Store a boot configuration map in the bootenv area of each leaf
5658  * vdev's labels.
5659  */
5660 int
5661 zpool_set_bootenv(zpool_handle_t *zhp, const nvlist_t *envmap)
5662 {
5663 	int error = lzc_set_bootenv(zhp->zpool_name, envmap);
5664 	if (error != 0) {
5665 		(void) zpool_standard_error_fmt(zhp->zpool_hdl, error,
5666 		    dgettext(TEXT_DOMAIN,
5667 		    "error setting bootenv in pool '%s'"), zhp->zpool_name);
5668 	}
5669 
5670 	return (error);
5671 }
5672 
5673 /*
5674  * Read the boot configuration map from each leaf vdev's bootenv area.
5675  */
5676 int
5677 zpool_get_bootenv(zpool_handle_t *zhp, nvlist_t **nvlp)
5678 {
5679 	nvlist_t *nvl;
5680 	int error;
5681 
5682 	nvl = NULL;
5683 	error = lzc_get_bootenv(zhp->zpool_name, &nvl);
5684 	if (error != 0) {
5685 		(void) zpool_standard_error_fmt(zhp->zpool_hdl, error,
5686 		    dgettext(TEXT_DOMAIN,
5687 		    "error getting bootenv in pool '%s'"), zhp->zpool_name);
5688 	} else {
5689 		*nvlp = nvl;
5690 	}
5691 
5692 	return (error);
5693 }
5694 
5695 /*
5696  * Attempt to read and parse feature file(s) (from "compatibility" property).
5697  * Files contain zpool feature names, comma or whitespace-separated.
5698  * Comments (# character to next newline) are discarded.
5699  *
5700  * Arguments:
5701  *  compatibility : string containing feature filenames
5702  *  features : either NULL or pointer to array of boolean
5703  *  report : either NULL or pointer to string buffer
5704  *  rlen : length of "report" buffer
5705  *
5706  * compatibility is NULL (unset), "", "off", "legacy", or list of
5707  * comma-separated filenames. filenames should either be absolute,
5708  * or relative to:
5709  *   1) ZPOOL_SYSCONF_COMPAT_D (eg: /etc/zfs/compatibility.d) or
5710  *   2) ZPOOL_DATA_COMPAT_D (eg: /usr/share/zfs/compatibility.d).
5711  * (Unset), "" or "off" => enable all features
5712  * "legacy" => disable all features
5713  *
5714  * Any feature names read from files which match unames in spa_feature_table
5715  * will have the corresponding boolean set in the features array (if non-NULL).
5716  * If more than one feature set specified, only features present in *all* of
5717  * them will be set.
5718  *
5719  * "report" if not NULL will be populated with a suitable status message.
5720  *
5721  * Return values:
5722  *   ZPOOL_COMPATIBILITY_OK : files read and parsed ok
5723  *   ZPOOL_COMPATIBILITY_BADFILE : file too big or not a text file
5724  *   ZPOOL_COMPATIBILITY_BADTOKEN : SYSCONF file contains invalid feature name
5725  *   ZPOOL_COMPATIBILITY_WARNTOKEN : DATA file contains invalid feature name
5726  *   ZPOOL_COMPATIBILITY_NOFILES : no feature files found
5727  */
5728 zpool_compat_status_t
5729 zpool_load_compat(const char *compat, boolean_t *features, char *report,
5730     size_t rlen)
5731 {
5732 	int sdirfd, ddirfd, featfd;
5733 	struct stat fs;
5734 	char *fc;
5735 	char *ps, *ls, *ws;
5736 	char *file, *line, *word;
5737 
5738 	char l_compat[ZFS_MAXPROPLEN];
5739 
5740 	boolean_t ret_nofiles = B_TRUE;
5741 	boolean_t ret_badfile = B_FALSE;
5742 	boolean_t ret_badtoken = B_FALSE;
5743 	boolean_t ret_warntoken = B_FALSE;
5744 
5745 	/* special cases (unset), "" and "off" => enable all features */
5746 	if (compat == NULL || compat[0] == '\0' ||
5747 	    strcmp(compat, ZPOOL_COMPAT_OFF) == 0) {
5748 		if (features != NULL) {
5749 			for (uint_t i = 0; i < SPA_FEATURES; i++)
5750 				features[i] = B_TRUE;
5751 		}
5752 		if (report != NULL)
5753 			strlcpy(report, gettext("all features enabled"), rlen);
5754 		return (ZPOOL_COMPATIBILITY_OK);
5755 	}
5756 
5757 	/* Final special case "legacy" => disable all features */
5758 	if (strcmp(compat, ZPOOL_COMPAT_LEGACY) == 0) {
5759 		if (features != NULL)
5760 			for (uint_t i = 0; i < SPA_FEATURES; i++)
5761 				features[i] = B_FALSE;
5762 		if (report != NULL)
5763 			strlcpy(report, gettext("all features disabled"), rlen);
5764 		return (ZPOOL_COMPATIBILITY_OK);
5765 	}
5766 
5767 	/*
5768 	 * Start with all true; will be ANDed with results from each file
5769 	 */
5770 	if (features != NULL)
5771 		for (uint_t i = 0; i < SPA_FEATURES; i++)
5772 			features[i] = B_TRUE;
5773 
5774 	char err_badfile[ZFS_MAXPROPLEN] = "";
5775 	char err_badtoken[ZFS_MAXPROPLEN] = "";
5776 
5777 	/*
5778 	 * We ignore errors from the directory open()
5779 	 * as they're only needed if the filename is relative
5780 	 * which will be checked during the openat().
5781 	 */
5782 
5783 /* O_PATH safer than O_RDONLY if system allows it */
5784 #if defined(O_PATH)
5785 #define	ZC_DIR_FLAGS (O_DIRECTORY | O_CLOEXEC | O_PATH)
5786 #else
5787 #define	ZC_DIR_FLAGS (O_DIRECTORY | O_CLOEXEC | O_RDONLY)
5788 #endif
5789 
5790 	sdirfd = open(ZPOOL_SYSCONF_COMPAT_D, ZC_DIR_FLAGS);
5791 	ddirfd = open(ZPOOL_DATA_COMPAT_D, ZC_DIR_FLAGS);
5792 
5793 	(void) strlcpy(l_compat, compat, ZFS_MAXPROPLEN);
5794 
5795 	for (file = strtok_r(l_compat, ",", &ps);
5796 	    file != NULL;
5797 	    file = strtok_r(NULL, ",", &ps)) {
5798 
5799 		boolean_t l_features[SPA_FEATURES];
5800 
5801 		enum { Z_SYSCONF, Z_DATA } source;
5802 
5803 		/* try sysconfdir first, then datadir */
5804 		source = Z_SYSCONF;
5805 		if ((featfd = openat(sdirfd, file, O_RDONLY | O_CLOEXEC)) < 0) {
5806 			featfd = openat(ddirfd, file, O_RDONLY | O_CLOEXEC);
5807 			source = Z_DATA;
5808 		}
5809 
5810 		/* File readable and correct size? */
5811 		if (featfd < 0 ||
5812 		    fstat(featfd, &fs) < 0 ||
5813 		    fs.st_size < 1 ||
5814 		    fs.st_size > ZPOOL_COMPAT_MAXSIZE) {
5815 			(void) close(featfd);
5816 			strlcat(err_badfile, file, ZFS_MAXPROPLEN);
5817 			strlcat(err_badfile, " ", ZFS_MAXPROPLEN);
5818 			ret_badfile = B_TRUE;
5819 			continue;
5820 		}
5821 
5822 /* Prefault the file if system allows */
5823 #if defined(MAP_POPULATE)
5824 #define	ZC_MMAP_FLAGS (MAP_PRIVATE | MAP_POPULATE)
5825 #elif defined(MAP_PREFAULT_READ)
5826 #define	ZC_MMAP_FLAGS (MAP_PRIVATE | MAP_PREFAULT_READ)
5827 #else
5828 #define	ZC_MMAP_FLAGS (MAP_PRIVATE)
5829 #endif
5830 
5831 		/* private mmap() so we can strtok safely */
5832 		fc = (char *)mmap(NULL, fs.st_size, PROT_READ | PROT_WRITE,
5833 		    ZC_MMAP_FLAGS, featfd, 0);
5834 		(void) close(featfd);
5835 
5836 		/* need map ok, and last character == newline */
5837 		if (fc == MAP_FAILED || fc[fs.st_size - 1] != '\n') {
5838 			if (fc != MAP_FAILED)
5839 				(void) munmap((void *) fc, fs.st_size);
5840 			strlcat(err_badfile, file, ZFS_MAXPROPLEN);
5841 			strlcat(err_badfile, " ", ZFS_MAXPROPLEN);
5842 			ret_badfile = B_TRUE;
5843 			continue;
5844 		}
5845 
5846 		ret_nofiles = B_FALSE;
5847 
5848 		for (uint_t i = 0; i < SPA_FEATURES; i++)
5849 			l_features[i] = B_FALSE;
5850 
5851 		/* replace final newline with NULL to ensure string ends */
5852 		fc[fs.st_size - 1] = '\0';
5853 
5854 		for (line = strtok_r(fc, "\n", &ls);
5855 		    line != NULL;
5856 		    line = strtok_r(NULL, "\n", &ls)) {
5857 			/* discard comments */
5858 			char *r = strchr(line, '#');
5859 			if (r != NULL)
5860 				*r = '\0';
5861 
5862 			for (word = strtok_r(line, ", \t", &ws);
5863 			    word != NULL;
5864 			    word = strtok_r(NULL, ", \t", &ws)) {
5865 				/* Find matching feature name */
5866 				uint_t f;
5867 				for (f = 0; f < SPA_FEATURES; f++) {
5868 					zfeature_info_t *fi =
5869 					    &spa_feature_table[f];
5870 					if (strcmp(word, fi->fi_uname) == 0) {
5871 						l_features[f] = B_TRUE;
5872 						break;
5873 					}
5874 				}
5875 				if (f < SPA_FEATURES)
5876 					continue;
5877 
5878 				/* found an unrecognized word */
5879 				/* lightly sanitize it */
5880 				if (strlen(word) > 32)
5881 					word[32] = '\0';
5882 				for (char *c = word; *c != '\0'; c++)
5883 					if (!isprint(*c))
5884 						*c = '?';
5885 
5886 				strlcat(err_badtoken, word, ZFS_MAXPROPLEN);
5887 				strlcat(err_badtoken, " ", ZFS_MAXPROPLEN);
5888 				if (source == Z_SYSCONF)
5889 					ret_badtoken = B_TRUE;
5890 				else
5891 					ret_warntoken = B_TRUE;
5892 			}
5893 		}
5894 		(void) munmap((void *) fc, fs.st_size);
5895 
5896 		if (features != NULL)
5897 			for (uint_t i = 0; i < SPA_FEATURES; i++)
5898 				features[i] &= l_features[i];
5899 	}
5900 	(void) close(sdirfd);
5901 	(void) close(ddirfd);
5902 
5903 	/* Return the most serious error */
5904 	if (ret_badfile) {
5905 		if (report != NULL)
5906 			snprintf(report, rlen, gettext("could not read/"
5907 			    "parse feature file(s): %s"), err_badfile);
5908 		return (ZPOOL_COMPATIBILITY_BADFILE);
5909 	}
5910 	if (ret_nofiles) {
5911 		if (report != NULL)
5912 			strlcpy(report,
5913 			    gettext("no valid compatibility files specified"),
5914 			    rlen);
5915 		return (ZPOOL_COMPATIBILITY_NOFILES);
5916 	}
5917 	if (ret_badtoken) {
5918 		if (report != NULL)
5919 			snprintf(report, rlen, gettext("invalid feature "
5920 			    "name(s) in local compatibility files: %s"),
5921 			    err_badtoken);
5922 		return (ZPOOL_COMPATIBILITY_BADTOKEN);
5923 	}
5924 	if (ret_warntoken) {
5925 		if (report != NULL)
5926 			snprintf(report, rlen, gettext("unrecognized feature "
5927 			    "name(s) in distribution compatibility files: %s"),
5928 			    err_badtoken);
5929 		return (ZPOOL_COMPATIBILITY_WARNTOKEN);
5930 	}
5931 	if (report != NULL)
5932 		strlcpy(report, gettext("compatibility set ok"), rlen);
5933 	return (ZPOOL_COMPATIBILITY_OK);
5934 }
5935 
5936 static int
5937 zpool_vdev_guid(zpool_handle_t *zhp, const char *vdevname, uint64_t *vdev_guid)
5938 {
5939 	nvlist_t *tgt;
5940 	boolean_t avail_spare, l2cache;
5941 
5942 	verify(zhp != NULL);
5943 	if (zpool_get_state(zhp) == POOL_STATE_UNAVAIL) {
5944 		char errbuf[ERRBUFLEN];
5945 		(void) snprintf(errbuf, sizeof (errbuf),
5946 		    dgettext(TEXT_DOMAIN, "pool is in an unavailable state"));
5947 		return (zfs_error(zhp->zpool_hdl, EZFS_POOLUNAVAIL, errbuf));
5948 	}
5949 
5950 	if ((tgt = zpool_find_vdev(zhp, vdevname, &avail_spare, &l2cache,
5951 	    NULL)) == NULL) {
5952 		char errbuf[ERRBUFLEN];
5953 		(void) snprintf(errbuf, sizeof (errbuf),
5954 		    dgettext(TEXT_DOMAIN, "can not find %s in %s"),
5955 		    vdevname, zhp->zpool_name);
5956 		return (zfs_error(zhp->zpool_hdl, EZFS_NODEVICE, errbuf));
5957 	}
5958 
5959 	*vdev_guid = fnvlist_lookup_uint64(tgt, ZPOOL_CONFIG_GUID);
5960 	return (0);
5961 }
5962 
5963 /*
5964  * Get a vdev property value for 'prop' and return the value in
5965  * a pre-allocated buffer.
5966  */
5967 int
5968 zpool_get_vdev_prop_value(nvlist_t *nvprop, vdev_prop_t prop, char *prop_name,
5969     char *buf, size_t len, zprop_source_t *srctype, boolean_t literal)
5970 {
5971 	nvlist_t *nv;
5972 	const char *strval;
5973 	uint64_t intval;
5974 	zprop_source_t src = ZPROP_SRC_NONE;
5975 
5976 	if (prop == VDEV_PROP_USERPROP) {
5977 		/* user property, prop_name must contain the property name */
5978 		assert(prop_name != NULL);
5979 		if (nvlist_lookup_nvlist(nvprop, prop_name, &nv) == 0) {
5980 			src = fnvlist_lookup_uint64(nv, ZPROP_SOURCE);
5981 			strval = fnvlist_lookup_string(nv, ZPROP_VALUE);
5982 		} else {
5983 			/* user prop not found */
5984 			src = ZPROP_SRC_DEFAULT;
5985 			strval = "-";
5986 		}
5987 		(void) strlcpy(buf, strval, len);
5988 		if (srctype)
5989 			*srctype = src;
5990 		return (0);
5991 	}
5992 
5993 	if (prop_name == NULL)
5994 		prop_name = (char *)vdev_prop_to_name(prop);
5995 
5996 	switch (vdev_prop_get_type(prop)) {
5997 	case PROP_TYPE_STRING:
5998 		if (nvlist_lookup_nvlist(nvprop, prop_name, &nv) == 0) {
5999 			src = fnvlist_lookup_uint64(nv, ZPROP_SOURCE);
6000 			strval = fnvlist_lookup_string(nv, ZPROP_VALUE);
6001 		} else {
6002 			src = ZPROP_SRC_DEFAULT;
6003 			if ((strval = vdev_prop_default_string(prop)) == NULL)
6004 				strval = "-";
6005 		}
6006 		(void) strlcpy(buf, strval, len);
6007 		break;
6008 
6009 	case PROP_TYPE_NUMBER:
6010 		if (nvlist_lookup_nvlist(nvprop, prop_name, &nv) == 0) {
6011 			src = fnvlist_lookup_uint64(nv, ZPROP_SOURCE);
6012 			intval = fnvlist_lookup_uint64(nv, ZPROP_VALUE);
6013 		} else {
6014 			src = ZPROP_SRC_DEFAULT;
6015 			intval = vdev_prop_default_numeric(prop);
6016 		}
6017 
6018 		switch (prop) {
6019 		case VDEV_PROP_ASIZE:
6020 		case VDEV_PROP_PSIZE:
6021 		case VDEV_PROP_SIZE:
6022 		case VDEV_PROP_BOOTSIZE:
6023 		case VDEV_PROP_ALLOCATED:
6024 		case VDEV_PROP_FREE:
6025 		case VDEV_PROP_READ_ERRORS:
6026 		case VDEV_PROP_WRITE_ERRORS:
6027 		case VDEV_PROP_CHECKSUM_ERRORS:
6028 		case VDEV_PROP_INITIALIZE_ERRORS:
6029 		case VDEV_PROP_TRIM_ERRORS:
6030 		case VDEV_PROP_SLOW_IOS:
6031 		case VDEV_PROP_OPS_NULL:
6032 		case VDEV_PROP_OPS_READ:
6033 		case VDEV_PROP_OPS_WRITE:
6034 		case VDEV_PROP_OPS_FREE:
6035 		case VDEV_PROP_OPS_CLAIM:
6036 		case VDEV_PROP_OPS_TRIM:
6037 		case VDEV_PROP_BYTES_NULL:
6038 		case VDEV_PROP_BYTES_READ:
6039 		case VDEV_PROP_BYTES_WRITE:
6040 		case VDEV_PROP_BYTES_FREE:
6041 		case VDEV_PROP_BYTES_CLAIM:
6042 		case VDEV_PROP_BYTES_TRIM:
6043 			if (literal) {
6044 				(void) snprintf(buf, len, "%llu",
6045 				    (u_longlong_t)intval);
6046 			} else {
6047 				(void) zfs_nicenum(intval, buf, len);
6048 			}
6049 			break;
6050 		case VDEV_PROP_EXPANDSZ:
6051 			if (intval == 0) {
6052 				(void) strlcpy(buf, "-", len);
6053 			} else if (literal) {
6054 				(void) snprintf(buf, len, "%llu",
6055 				    (u_longlong_t)intval);
6056 			} else {
6057 				(void) zfs_nicenum(intval, buf, len);
6058 			}
6059 			break;
6060 		case VDEV_PROP_CAPACITY:
6061 			if (literal) {
6062 				(void) snprintf(buf, len, "%llu",
6063 				    (u_longlong_t)intval);
6064 			} else {
6065 				(void) snprintf(buf, len, "%llu%%",
6066 				    (u_longlong_t)intval);
6067 			}
6068 			break;
6069 		case VDEV_PROP_CHECKSUM_N:
6070 		case VDEV_PROP_CHECKSUM_T:
6071 		case VDEV_PROP_IO_N:
6072 		case VDEV_PROP_IO_T:
6073 		case VDEV_PROP_SLOW_IO_N:
6074 		case VDEV_PROP_SLOW_IO_T:
6075 		case VDEV_PROP_FDOMAIN:
6076 		case VDEV_PROP_FGROUP:
6077 			if (intval == UINT64_MAX) {
6078 				(void) strlcpy(buf, "-", len);
6079 			} else {
6080 				(void) snprintf(buf, len, "%llu",
6081 				    (u_longlong_t)intval);
6082 			}
6083 			break;
6084 		case VDEV_PROP_FRAGMENTATION:
6085 			if (intval == UINT64_MAX) {
6086 				(void) strlcpy(buf, "-", len);
6087 			} else {
6088 				(void) snprintf(buf, len, "%llu%%",
6089 				    (u_longlong_t)intval);
6090 			}
6091 			break;
6092 		case VDEV_PROP_STATE:
6093 			if (literal) {
6094 				(void) snprintf(buf, len, "%llu",
6095 				    (u_longlong_t)intval);
6096 			} else {
6097 				(void) strlcpy(buf, zpool_state_to_name(intval,
6098 				    VDEV_AUX_NONE), len);
6099 			}
6100 			break;
6101 		default:
6102 			(void) snprintf(buf, len, "%llu",
6103 			    (u_longlong_t)intval);
6104 		}
6105 		break;
6106 
6107 	case PROP_TYPE_INDEX:
6108 		if (nvlist_lookup_nvlist(nvprop, prop_name, &nv) == 0) {
6109 			src = fnvlist_lookup_uint64(nv, ZPROP_SOURCE);
6110 			intval = fnvlist_lookup_uint64(nv, ZPROP_VALUE);
6111 		} else {
6112 			/* 'trim_support' only valid for leaf vdevs */
6113 			if (prop == VDEV_PROP_TRIM_SUPPORT) {
6114 				(void) strlcpy(buf, "-", len);
6115 				break;
6116 			}
6117 			src = ZPROP_SRC_DEFAULT;
6118 			intval = vdev_prop_default_numeric(prop);
6119 			/* Only use if provided by the RAIDZ VDEV above */
6120 			if (prop == VDEV_PROP_RAIDZ_EXPANDING)
6121 				return (ENOENT);
6122 			if (prop == VDEV_PROP_SIT_OUT)
6123 				return (ENOENT);
6124 			/* Only valid for top-level vdevs */
6125 			if (prop == VDEV_PROP_ALLOC_BIAS)
6126 				return (ENOENT);
6127 		}
6128 		if (vdev_prop_index_to_string(prop, intval,
6129 		    (const char **)&strval) != 0)
6130 			return (-1);
6131 		(void) strlcpy(buf, strval, len);
6132 		break;
6133 
6134 	default:
6135 		abort();
6136 	}
6137 
6138 	if (srctype)
6139 		*srctype = src;
6140 
6141 	return (0);
6142 }
6143 
6144 /*
6145  * Get a vdev property value for 'prop_name' and return the value in
6146  * a pre-allocated buffer.
6147  */
6148 int
6149 zpool_get_vdev_prop(zpool_handle_t *zhp, const char *vdevname, vdev_prop_t prop,
6150     char *prop_name, char *buf, size_t len, zprop_source_t *srctype,
6151     boolean_t literal)
6152 {
6153 	nvlist_t *reqnvl, *reqprops;
6154 	nvlist_t *retprops = NULL;
6155 	uint64_t vdev_guid = 0;
6156 	int ret;
6157 
6158 	if ((ret = zpool_vdev_guid(zhp, vdevname, &vdev_guid)) != 0)
6159 		return (ret);
6160 
6161 	if (nvlist_alloc(&reqnvl, NV_UNIQUE_NAME, 0) != 0)
6162 		return (no_memory(zhp->zpool_hdl));
6163 	if (nvlist_alloc(&reqprops, NV_UNIQUE_NAME, 0) != 0)
6164 		return (no_memory(zhp->zpool_hdl));
6165 
6166 	fnvlist_add_uint64(reqnvl, ZPOOL_VDEV_PROPS_GET_VDEV, vdev_guid);
6167 
6168 	if (prop != VDEV_PROP_USERPROP) {
6169 		/* prop_name overrides prop value */
6170 		if (prop_name != NULL)
6171 			prop = vdev_name_to_prop(prop_name);
6172 		else
6173 			prop_name = (char *)vdev_prop_to_name(prop);
6174 		assert(prop < VDEV_NUM_PROPS);
6175 	}
6176 
6177 	assert(prop_name != NULL);
6178 	if (nvlist_add_uint64(reqprops, prop_name, prop) != 0) {
6179 		nvlist_free(reqnvl);
6180 		nvlist_free(reqprops);
6181 		return (no_memory(zhp->zpool_hdl));
6182 	}
6183 
6184 	fnvlist_add_nvlist(reqnvl, ZPOOL_VDEV_PROPS_GET_PROPS, reqprops);
6185 
6186 	ret = lzc_get_vdev_prop(zhp->zpool_name, reqnvl, &retprops);
6187 
6188 	if (ret == 0) {
6189 		ret = zpool_get_vdev_prop_value(retprops, prop, prop_name, buf,
6190 		    len, srctype, literal);
6191 	} else {
6192 		char errbuf[ERRBUFLEN];
6193 		(void) snprintf(errbuf, sizeof (errbuf),
6194 		    dgettext(TEXT_DOMAIN, "cannot get vdev property %s from"
6195 		    " %s in %s"), prop_name, vdevname, zhp->zpool_name);
6196 		(void) zpool_standard_error(zhp->zpool_hdl, ret, errbuf);
6197 	}
6198 
6199 	nvlist_free(reqnvl);
6200 	nvlist_free(reqprops);
6201 	nvlist_free(retprops);
6202 
6203 	return (ret);
6204 }
6205 
6206 /*
6207  * Get all vdev properties
6208  */
6209 int
6210 zpool_get_all_vdev_props(zpool_handle_t *zhp, const char *vdevname,
6211     nvlist_t **outnvl)
6212 {
6213 	nvlist_t *nvl = NULL;
6214 	uint64_t vdev_guid = 0;
6215 	int ret;
6216 
6217 	if ((ret = zpool_vdev_guid(zhp, vdevname, &vdev_guid)) != 0)
6218 		return (ret);
6219 
6220 	if (nvlist_alloc(&nvl, NV_UNIQUE_NAME, 0) != 0)
6221 		return (no_memory(zhp->zpool_hdl));
6222 
6223 	fnvlist_add_uint64(nvl, ZPOOL_VDEV_PROPS_GET_VDEV, vdev_guid);
6224 
6225 	ret = lzc_get_vdev_prop(zhp->zpool_name, nvl, outnvl);
6226 
6227 	nvlist_free(nvl);
6228 
6229 	if (ret) {
6230 		char errbuf[ERRBUFLEN];
6231 		(void) snprintf(errbuf, sizeof (errbuf),
6232 		    dgettext(TEXT_DOMAIN, "cannot get vdev properties for"
6233 		    " %s in %s"), vdevname, zhp->zpool_name);
6234 		(void) zpool_standard_error(zhp->zpool_hdl, errno, errbuf);
6235 	}
6236 
6237 	return (ret);
6238 }
6239 
6240 /*
6241  * Set vdev property
6242  */
6243 int
6244 zpool_set_vdev_prop(zpool_handle_t *zhp, const char *vdevname,
6245     const char *propname, const char *propval)
6246 {
6247 	int ret;
6248 	nvlist_t *nvl = NULL;
6249 	nvlist_t *outnvl = NULL;
6250 	nvlist_t *props;
6251 	nvlist_t *realprops;
6252 	prop_flags_t flags = { 0 };
6253 	uint64_t version;
6254 	uint64_t vdev_guid;
6255 
6256 	if ((ret = zpool_vdev_guid(zhp, vdevname, &vdev_guid)) != 0)
6257 		return (ret);
6258 
6259 	if (nvlist_alloc(&nvl, NV_UNIQUE_NAME, 0) != 0)
6260 		return (no_memory(zhp->zpool_hdl));
6261 	if (nvlist_alloc(&props, NV_UNIQUE_NAME, 0) != 0)
6262 		return (no_memory(zhp->zpool_hdl));
6263 
6264 	fnvlist_add_uint64(nvl, ZPOOL_VDEV_PROPS_SET_VDEV, vdev_guid);
6265 
6266 	if (nvlist_add_string(props, propname, propval) != 0) {
6267 		nvlist_free(props);
6268 		return (no_memory(zhp->zpool_hdl));
6269 	}
6270 
6271 	char errbuf[ERRBUFLEN];
6272 	(void) snprintf(errbuf, sizeof (errbuf),
6273 	    dgettext(TEXT_DOMAIN, "cannot set property %s for %s on %s"),
6274 	    propname, vdevname, zhp->zpool_name);
6275 
6276 	flags.vdevprop = 1;
6277 	version = zpool_get_prop_int(zhp, ZPOOL_PROP_VERSION, NULL);
6278 	if ((realprops = zpool_valid_proplist(zhp->zpool_hdl,
6279 	    zhp->zpool_name, props, version, flags, errbuf)) == NULL) {
6280 		nvlist_free(props);
6281 		nvlist_free(nvl);
6282 		return (-1);
6283 	}
6284 
6285 	nvlist_free(props);
6286 	props = realprops;
6287 
6288 	fnvlist_add_nvlist(nvl, ZPOOL_VDEV_PROPS_SET_PROPS, props);
6289 
6290 	ret = lzc_set_vdev_prop(zhp->zpool_name, nvl, &outnvl);
6291 
6292 	nvlist_free(props);
6293 	nvlist_free(nvl);
6294 	nvlist_free(outnvl);
6295 
6296 	if (ret) {
6297 		if (errno == ENOTSUP) {
6298 			zfs_error_aux(zhp->zpool_hdl, dgettext(TEXT_DOMAIN,
6299 			    "property not supported for this vdev"));
6300 			(void) zfs_error(zhp->zpool_hdl, EZFS_PROPTYPE, errbuf);
6301 		} else {
6302 			(void) zpool_standard_error(zhp->zpool_hdl, errno,
6303 			    errbuf);
6304 		}
6305 	}
6306 
6307 	return (ret);
6308 }
6309 
6310 /*
6311  * Prune older entries from the DDT to reclaim space under the quota
6312  */
6313 int
6314 zpool_ddt_prune(zpool_handle_t *zhp, zpool_ddt_prune_unit_t unit,
6315     uint64_t amount)
6316 {
6317 	int error = lzc_ddt_prune(zhp->zpool_name, unit, amount);
6318 	if (error != 0) {
6319 		libzfs_handle_t *hdl = zhp->zpool_hdl;
6320 		char errbuf[ERRBUFLEN];
6321 
6322 		(void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
6323 		    "cannot prune dedup table on '%s'"), zhp->zpool_name);
6324 
6325 		if (error == EALREADY) {
6326 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
6327 			    "a prune operation is already in progress"));
6328 			(void) zfs_error(hdl, EZFS_BUSY, errbuf);
6329 		} else {
6330 			(void) zpool_standard_error(hdl, errno, errbuf);
6331 		}
6332 		return (-1);
6333 	}
6334 
6335 	return (0);
6336 }
6337