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
zpool_get_all_props(zpool_handle_t * zhp)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
zpool_props_refresh(zpool_handle_t * zhp)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 *
zpool_get_prop_string(zpool_handle_t * zhp,zpool_prop_t prop,zprop_source_t * src)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
zpool_get_prop_int(zpool_handle_t * zhp,zpool_prop_t prop,zprop_source_t * src)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 *
zpool_state_to_name(vdev_state_t state,vdev_aux_t aux)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 *
zpool_pool_state_to_name(pool_state_t state)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 *
zpool_get_state_str(zpool_handle_t * zhp)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
zpool_get_prop(zpool_handle_t * zhp,zpool_prop_t prop,char * buf,size_t len,zprop_source_t * srctype,boolean_t literal)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
zpool_get_userprop(zpool_handle_t * zhp,const char * propname,char * buf,size_t len,zprop_source_t * srctype)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
bootfs_name_valid(const char * pool,const char * bootfs)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 *
zpool_valid_proplist(libzfs_handle_t * hdl,const char * poolname,nvlist_t * props,uint64_t version,prop_flags_t flags,char * errbuf)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
zpool_set_prop(zpool_handle_t * zhp,const char * propname,const char * propval)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
zpool_expand_proplist(zpool_handle_t * zhp,zprop_list_t ** plp,zfs_type_t type,boolean_t literal)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
vdev_expand_proplist(zpool_handle_t * zhp,const char * vdevname,zprop_list_t ** plp)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
zpool_prop_get_feature(zpool_handle_t * zhp,const char * propname,char * buf,size_t len)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
zpool_name_valid(libzfs_handle_t * hdl,boolean_t isopen,const char * pool)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 *
zpool_open_canfail(libzfs_handle_t * hdl,const char * pool)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
zpool_open_silent(libzfs_handle_t * hdl,const char * pool,zpool_handle_t ** ret)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 *
zpool_open(libzfs_handle_t * hdl,const char * pool)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
zpool_close(zpool_handle_t * zhp)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 *
zpool_get_name(zpool_handle_t * zhp)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
zpool_get_state(zpool_handle_t * zhp)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
zpool_has_draid_vdev(nvlist_t * nvroot)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 *
zpool_draid_name(char * name,int len,uint64_t data,uint64_t parity,uint64_t spares,uint64_t children,uint64_t width)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
zpool_is_draid_spare(const char * name)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
zpool_create_info(libzfs_handle_t * hdl,zfs_cmd_t * zc)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
zpool_create(libzfs_handle_t * hdl,const char * pool,nvlist_t * nvroot,nvlist_t * props,nvlist_t * fsprops)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
zpool_destroy(zpool_handle_t * zhp,const char * log_str)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
zpool_checkpoint(zpool_handle_t * zhp)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
zpool_discard_checkpoint(zpool_handle_t * zhp)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
zpool_prefetch(zpool_handle_t * zhp,zpool_prefetch_type_t type)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
zpool_add(zpool_handle_t * zhp,nvlist_t * nvroot,boolean_t check_ashift)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
zpool_export_common(zpool_handle_t * zhp,boolean_t force,boolean_t hardforce,const char * log_str)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
zpool_export(zpool_handle_t * zhp,boolean_t force,const char * log_str)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
zpool_export_force(zpool_handle_t * zhp,const char * log_str)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
zpool_rewind_exclaim(libzfs_handle_t * hdl,const char * name,nvlist_t * config)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
zpool_explain_recover(libzfs_handle_t * hdl,const char * name,int reason,nvlist_t * config,char * buf,size_t size)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
zpool_import(libzfs_handle_t * hdl,nvlist_t * config,const char * newname,char * altroot)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
print_vdev_tree(libzfs_handle_t * hdl,const char * name,nvlist_t * nv,int indent)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
zpool_collect_unsup_feat(nvlist_t * config,char * buf,size_t size)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
zpool_import_props(libzfs_handle_t * hdl,nvlist_t * config,const char * newname,nvlist_t * props,int flags)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
zpool_translate_vdev_guids(zpool_handle_t * zhp,nvlist_t * vds,nvlist_t * vdev_guids,nvlist_t * guids_to_paths,nvlist_t ** vd_errlist)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
xlate_init_err(int err)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
zpool_initialize_one(zpool_handle_t * zhp,void * data)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
zpool_initialize_impl(zpool_handle_t * zhp,pool_initialize_func_t cmd_type,nvlist_t * vds,uint64_t value,boolean_t value_provided,boolean_t wait)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
zpool_initialize(zpool_handle_t * zhp,pool_initialize_func_t cmd_type,nvlist_t * vds,uint64_t value,boolean_t value_provided)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
zpool_initialize_wait(zpool_handle_t * zhp,pool_initialize_func_t cmd_type,nvlist_t * vds,uint64_t value,boolean_t value_provided)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
xlate_trim_err(int err)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
zpool_collect_leaves(zpool_handle_t * zhp,nvlist_t * nvroot,nvlist_t * res)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
zpool_trim_one(zpool_handle_t * zhp,void * data)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
zpool_trim_wait(zpool_handle_t * zhp,nvlist_t * vdev_guids)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
check_trim_errs(zpool_handle_t * zhp,trimflags_t * trim_flags,nvlist_t * guids_to_paths,nvlist_t * vds,nvlist_t * errlist)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
zpool_trim(zpool_handle_t * zhp,pool_trim_func_t cmd_type,nvlist_t * vds,trimflags_t * trim_flags)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
zpool_scan(zpool_handle_t * zhp,pool_scan_func_t func,pool_scrub_cmd_t cmd)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
zpool_scan_range(zpool_handle_t * zhp,pool_scan_func_t func,pool_scrub_cmd_t cmd,pool_scrub_flags_t flags,time_t date_start,time_t date_end)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 *
vdev_to_nvlist_iter(nvlist_t * nv,nvlist_t * search,boolean_t * avail_spare,boolean_t * l2cache,boolean_t * log,boolean_t return_parent)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 *
zpool_find_vdev_by_physpath(zpool_handle_t * zhp,const char * ppath,boolean_t * avail_spare,boolean_t * l2cache,boolean_t * log)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
zpool_vdev_is_interior(const char * name)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 *
__zpool_find_vdev(zpool_handle_t * zhp,const char * path,boolean_t * avail_spare,boolean_t * l2cache,boolean_t * log,boolean_t return_parent)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 *
zpool_find_vdev(zpool_handle_t * zhp,const char * path,boolean_t * avail_spare,boolean_t * l2cache,boolean_t * log)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 *
zpool_find_parent_vdev(zpool_handle_t * zhp,const char * path,boolean_t * avail_spare,boolean_t * l2cache,boolean_t * log)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
zpool_vdev_path_to_guid_impl(zpool_handle_t * zhp,const char * path,boolean_t * is_spare,boolean_t * is_l2cache,boolean_t * is_log)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
zpool_vdev_path_to_guid(zpool_handle_t * zhp,const char * path)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
zpool_vdev_online(zpool_handle_t * zhp,const char * path,int flags,vdev_state_t * newstate)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
zpool_vdev_offline(zpool_handle_t * zhp,const char * path,boolean_t istmp)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
zpool_vdev_remove_wanted(zpool_handle_t * zhp,const char * path)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
zpool_vdev_fault(zpool_handle_t * zhp,uint64_t guid,vdev_aux_t aux)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
zpool_vdev_set_state(zpool_handle_t * zhp,uint64_t guid,vdev_aux_t aux,vdev_state_t state)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
zpool_vdev_degrade(zpool_handle_t * zhp,uint64_t guid,vdev_aux_t aux)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
zpool_vdev_set_removed_state(zpool_handle_t * zhp,uint64_t guid,vdev_aux_t aux)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
is_replacing_spare(nvlist_t * search,nvlist_t * tgt,int which)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
zpool_vdev_attach(zpool_handle_t * zhp,const char * old_disk,const char * new_disk,nvlist_t * nvroot,int replacing,boolean_t rebuild)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
zpool_vdev_detach(zpool_handle_t * zhp,const char * path)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
find_vdev_entry(zpool_handle_t * zhp,nvlist_t ** mchild,uint_t mchildren,nvlist_t ** schild,uint_t schildren)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
zpool_vdev_split(zpool_handle_t * zhp,char * newname,nvlist_t ** newroot,nvlist_t * props,splitflags_t flags)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
zpool_vdev_remove(zpool_handle_t * zhp,const char * path)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
zpool_vdev_remove_cancel(zpool_handle_t * zhp)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
zpool_vdev_indirect_size(zpool_handle_t * zhp,const char * path,uint64_t * sizep)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
zpool_clear(zpool_handle_t * zhp,const char * path,nvlist_t * rewindnvl)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
zpool_vdev_clear(zpool_handle_t * zhp,uint64_t guid)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
zpool_set_guid(zpool_handle_t * zhp,const uint64_t * guid)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
zpool_reguid(zpool_handle_t * zhp)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
zpool_reopen_one(zpool_handle_t * zhp,void * data)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
zpool_sync_one(zpool_handle_t * zhp,void * data)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
zpool_condense(zpool_handle_t * zhp,const char * cmd,const char * type)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 *
zpool_vdev_name(libzfs_handle_t * hdl,zpool_handle_t * zhp,nvlist_t * nv,int name_flags)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
zbookmark_mem_compare(const void * a,const void * b)4885 zbookmark_mem_compare(const void *a, const void *b)
4886 {
4887 return (memcmp(a, b, sizeof (zbookmark_phys_t)));
4888 }
4889
4890 void
zpool_add_propname(zpool_handle_t * zhp,const char * propname)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
zpool_get_from_prop_nvlist_uint64(nvlist_t * nv,const char * name,uint64_t * val)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
zpool_get_extended_obj_stat_helper(zpool_handle_t * zhp,uint64_t dsobj,uint64_t obj,uint64_t * data_block_size,char ** type_str)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
zpool_get_errlog_process_file_cb(void * arg,uint64_t start,uint64_t size)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
zpool_get_errlog_process_file(zpool_handle_t * zhp,nvlist_t ** nverrlistp,zbookmark_phys_t * zb_start,zbookmark_phys_t * zb_end)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
zpool_get_errlog(zpool_handle_t * zhp,nvlist_t ** nverrlistp)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
zpool_upgrade(zpool_handle_t * zhp,uint64_t new_version)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
zfs_save_arguments(int argc,char ** argv,char * string,int len)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
zpool_log_history(libzfs_handle_t * hdl,const char * message)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
get_history(zpool_handle_t * zhp,char * buf,uint64_t * off,uint64_t * len)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
zpool_get_history(zpool_handle_t * zhp,nvlist_t ** nvhisp,uint64_t * off,boolean_t * eof)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
zpool_events_next(libzfs_handle_t * hdl,nvlist_t ** nvp,int * dropped,unsigned flags,int zevent_fd)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
zpool_events_clear(libzfs_handle_t * hdl,int * count)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
zpool_events_seek(libzfs_handle_t * hdl,uint64_t eid,int zevent_fd)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 *
zpool_get_extended_obj_stat_impl(zpool_handle_t * zhp,uint64_t dsobj,uint64_t obj,enum zfs_ioc stats_ioctl)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 *
zpool_get_extended_obj_stat(zpool_handle_t * zhp,uint64_t dsobj,uint64_t obj)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 *
zpool_get_extended_objset_stat(zpool_handle_t * zhp,uint64_t dsobj,uint64_t obj)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
zpool_obj_to_path_impl(zpool_handle_t * zhp,uint64_t dsobj,uint64_t obj,char * pathname,size_t len,boolean_t always_unmounted)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
zpool_obj_to_path(zpool_handle_t * zhp,uint64_t dsobj,uint64_t obj,char * pathname,size_t len)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
zpool_obj_to_path_ds(zpool_handle_t * zhp,uint64_t dsobj,uint64_t obj,char * pathname,size_t len)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
zpool_wait(zpool_handle_t * zhp,zpool_wait_activity_t activity)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
zpool_wait_status(zpool_handle_t * zhp,zpool_wait_activity_t activity,boolean_t * missing,boolean_t * waited)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
zpool_set_bootenv(zpool_handle_t * zhp,const nvlist_t * envmap)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
zpool_get_bootenv(zpool_handle_t * zhp,nvlist_t ** nvlp)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
zpool_load_compat(const char * compat,boolean_t * features,char * report,size_t rlen)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
zpool_vdev_guid(zpool_handle_t * zhp,const char * vdevname,uint64_t * vdev_guid)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
zpool_get_vdev_prop_value(nvlist_t * nvprop,vdev_prop_t prop,char * prop_name,char * buf,size_t len,zprop_source_t * srctype,boolean_t literal)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
zpool_get_vdev_prop(zpool_handle_t * zhp,const char * vdevname,vdev_prop_t prop,char * prop_name,char * buf,size_t len,zprop_source_t * srctype,boolean_t literal)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
zpool_get_all_vdev_props(zpool_handle_t * zhp,const char * vdevname,nvlist_t ** outnvl)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
zpool_set_vdev_prop(zpool_handle_t * zhp,const char * vdevname,const char * propname,const char * propval)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
zpool_ddt_prune(zpool_handle_t * zhp,zpool_ddt_prune_unit_t unit,uint64_t amount)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