4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
24 * Copyright (c) 2011, 2020 by Delphix. All rights reserved.
25 * Copyright 2019 Joyent, Inc.
26 * Copyright 2016 Nexenta Systems, Inc.
27 * Copyright 2016 Igor Kozhukhov <ikozhukhov@gmail.com>
28 * Copyright (c) 2017 Datto Inc.
29 * Copyright (c) 2017, Intel Corporation.
30 * Copyright 2022 OmniOS Community Edition (OmniOSce) Association.
31 * Copyright 2022 Oxide Computer Company
45 #include <sys/efi_partition.h>
47 #include <sys/zfs_ioctl.h>
48 #include <sys/modctl.h>
49 #include <sys/mkdev.h>
53 #include "zfs_namecheck.h"
55 #include "libzfs_impl.h"
56 #include "zfs_comutil.h"
57 #include "zfeature_common.h"
59 static int read_efi_label(nvlist_t
*, diskaddr_t
*, boolean_t
*);
60 static boolean_t
zpool_vdev_is_interior(const char *name
);
62 #define BACKUP_SLICE "s2"
64 typedef struct prop_flags
{
65 int create
:1; /* Validate property on creation */
66 int import
:1; /* Validate property on import */
70 * ====================================================================
71 * zpool property functions
72 * ====================================================================
76 zpool_get_all_props(zpool_handle_t
*zhp
)
79 libzfs_handle_t
*hdl
= zhp
->zpool_hdl
;
81 (void) strlcpy(zc
.zc_name
, zhp
->zpool_name
, sizeof (zc
.zc_name
));
83 if (zcmd_alloc_dst_nvlist(hdl
, &zc
, 0) != 0)
86 while (ioctl(hdl
->libzfs_fd
, ZFS_IOC_POOL_GET_PROPS
, &zc
) != 0) {
87 if (errno
== ENOMEM
) {
88 if (zcmd_expand_dst_nvlist(hdl
, &zc
) != 0) {
89 zcmd_free_nvlists(&zc
);
93 zcmd_free_nvlists(&zc
);
98 if (zcmd_read_dst_nvlist(hdl
, &zc
, &zhp
->zpool_props
) != 0) {
99 zcmd_free_nvlists(&zc
);
103 zcmd_free_nvlists(&zc
);
109 zpool_props_refresh(zpool_handle_t
*zhp
)
113 old_props
= zhp
->zpool_props
;
115 if (zpool_get_all_props(zhp
) != 0)
118 nvlist_free(old_props
);
123 zpool_get_prop_string(zpool_handle_t
*zhp
, zpool_prop_t prop
,
129 zprop_source_t source
;
131 nvl
= zhp
->zpool_props
;
132 if (nvlist_lookup_nvlist(nvl
, zpool_prop_to_name(prop
), &nv
) == 0) {
133 verify(nvlist_lookup_uint64(nv
, ZPROP_SOURCE
, &ival
) == 0);
135 verify(nvlist_lookup_string(nv
, ZPROP_VALUE
, &value
) == 0);
137 source
= ZPROP_SRC_DEFAULT
;
138 if ((value
= (char *)zpool_prop_default_string(prop
)) == NULL
)
149 zpool_get_prop_int(zpool_handle_t
*zhp
, zpool_prop_t prop
, zprop_source_t
*src
)
153 zprop_source_t source
;
155 if (zhp
->zpool_props
== NULL
&& zpool_get_all_props(zhp
)) {
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.
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
)
168 return (zpool_prop_default_numeric(prop
));
171 nvl
= zhp
->zpool_props
;
172 if (nvlist_lookup_nvlist(nvl
, zpool_prop_to_name(prop
), &nv
) == 0) {
173 verify(nvlist_lookup_uint64(nv
, ZPROP_SOURCE
, &value
) == 0);
175 verify(nvlist_lookup_uint64(nv
, ZPROP_VALUE
, &value
) == 0);
177 source
= ZPROP_SRC_DEFAULT
;
178 value
= zpool_prop_default_numeric(prop
);
188 * Map VDEV STATE to printed strings.
191 zpool_state_to_name(vdev_state_t state
, vdev_aux_t aux
)
194 case VDEV_STATE_CLOSED
:
195 case VDEV_STATE_OFFLINE
:
196 return (gettext("OFFLINE"));
197 case VDEV_STATE_REMOVED
:
198 return (gettext("REMOVED"));
199 case VDEV_STATE_CANT_OPEN
:
200 if (aux
== VDEV_AUX_CORRUPT_DATA
|| aux
== VDEV_AUX_BAD_LOG
)
201 return (gettext("FAULTED"));
202 else if (aux
== VDEV_AUX_SPLIT_POOL
)
203 return (gettext("SPLIT"));
205 return (gettext("UNAVAIL"));
206 case VDEV_STATE_FAULTED
:
207 return (gettext("FAULTED"));
208 case VDEV_STATE_DEGRADED
:
209 return (gettext("DEGRADED"));
210 case VDEV_STATE_HEALTHY
:
211 return (gettext("ONLINE"));
217 return (gettext("UNKNOWN"));
221 * Map POOL STATE to printed strings.
224 zpool_pool_state_to_name(pool_state_t state
)
227 case POOL_STATE_ACTIVE
:
228 return (gettext("ACTIVE"));
229 case POOL_STATE_EXPORTED
:
230 return (gettext("EXPORTED"));
231 case POOL_STATE_DESTROYED
:
232 return (gettext("DESTROYED"));
233 case POOL_STATE_SPARE
:
234 return (gettext("SPARE"));
235 case POOL_STATE_L2CACHE
:
236 return (gettext("L2CACHE"));
237 case POOL_STATE_UNINITIALIZED
:
238 return (gettext("UNINITIALIZED"));
239 case POOL_STATE_UNAVAIL
:
240 return (gettext("UNAVAIL"));
241 case POOL_STATE_POTENTIALLY_ACTIVE
:
242 return (gettext("POTENTIALLY_ACTIVE"));
245 return (gettext("UNKNOWN"));
249 * Get a zpool property value for 'prop' and return the value in
250 * a pre-allocated buffer.
253 zpool_get_prop(zpool_handle_t
*zhp
, zpool_prop_t prop
, char *buf
, size_t len
,
254 zprop_source_t
*srctype
, boolean_t literal
)
258 zprop_source_t src
= ZPROP_SRC_NONE
;
263 if (zpool_get_state(zhp
) == POOL_STATE_UNAVAIL
) {
265 case ZPOOL_PROP_NAME
:
266 (void) strlcpy(buf
, zpool_get_name(zhp
), len
);
269 case ZPOOL_PROP_HEALTH
:
270 (void) strlcpy(buf
, "FAULTED", len
);
273 case ZPOOL_PROP_GUID
:
274 intval
= zpool_get_prop_int(zhp
, prop
, &src
);
275 (void) snprintf(buf
, len
, "%llu", intval
);
278 case ZPOOL_PROP_ALTROOT
:
279 case ZPOOL_PROP_CACHEFILE
:
280 case ZPOOL_PROP_COMMENT
:
281 if (zhp
->zpool_props
!= NULL
||
282 zpool_get_all_props(zhp
) == 0) {
284 zpool_get_prop_string(zhp
, prop
, &src
),
290 (void) strlcpy(buf
, "-", len
);
299 if (zhp
->zpool_props
== NULL
&& zpool_get_all_props(zhp
) &&
300 prop
!= ZPOOL_PROP_NAME
)
303 switch (zpool_prop_get_type(prop
)) {
304 case PROP_TYPE_STRING
:
305 (void) strlcpy(buf
, zpool_get_prop_string(zhp
, prop
, &src
),
309 case PROP_TYPE_NUMBER
:
310 intval
= zpool_get_prop_int(zhp
, prop
, &src
);
313 case ZPOOL_PROP_SIZE
:
314 case ZPOOL_PROP_ALLOCATED
:
315 case ZPOOL_PROP_FREE
:
316 case ZPOOL_PROP_FREEING
:
317 case ZPOOL_PROP_LEAKED
:
318 case ZPOOL_PROP_ASHIFT
:
320 (void) snprintf(buf
, len
, "%llu",
321 (u_longlong_t
)intval
);
323 (void) zfs_nicenum(intval
, buf
, len
);
326 case ZPOOL_PROP_BOOTSIZE
:
327 case ZPOOL_PROP_EXPANDSZ
:
328 case ZPOOL_PROP_CHECKPOINT
:
330 (void) strlcpy(buf
, "-", len
);
331 } else if (literal
) {
332 (void) snprintf(buf
, len
, "%llu",
333 (u_longlong_t
)intval
);
335 (void) zfs_nicebytes(intval
, buf
, len
);
338 case ZPOOL_PROP_CAPACITY
:
340 (void) snprintf(buf
, len
, "%llu",
341 (u_longlong_t
)intval
);
343 (void) snprintf(buf
, len
, "%llu%%",
344 (u_longlong_t
)intval
);
347 case ZPOOL_PROP_FRAGMENTATION
:
348 if (intval
== UINT64_MAX
) {
349 (void) strlcpy(buf
, "-", len
);
350 } else if (literal
) {
351 (void) snprintf(buf
, len
, "%llu",
352 (u_longlong_t
)intval
);
354 (void) snprintf(buf
, len
, "%llu%%",
355 (u_longlong_t
)intval
);
358 case ZPOOL_PROP_DEDUPRATIO
:
360 (void) snprintf(buf
, len
, "%llu.%02llu",
361 (u_longlong_t
)(intval
/ 100),
362 (u_longlong_t
)(intval
% 100));
364 (void) snprintf(buf
, len
, "%llu.%02llux",
365 (u_longlong_t
)(intval
/ 100),
366 (u_longlong_t
)(intval
% 100));
368 case ZPOOL_PROP_HEALTH
:
369 verify(nvlist_lookup_nvlist(zpool_get_config(zhp
, NULL
),
370 ZPOOL_CONFIG_VDEV_TREE
, &nvroot
) == 0);
371 verify(nvlist_lookup_uint64_array(nvroot
,
372 ZPOOL_CONFIG_VDEV_STATS
, (uint64_t **)&vs
, &vsc
)
375 (void) strlcpy(buf
, zpool_state_to_name(intval
,
378 case ZPOOL_PROP_VERSION
:
379 if (intval
>= SPA_VERSION_FEATURES
) {
380 (void) snprintf(buf
, len
, "-");
385 (void) snprintf(buf
, len
, "%llu", intval
);
389 case PROP_TYPE_INDEX
:
390 intval
= zpool_get_prop_int(zhp
, prop
, &src
);
391 if (zpool_prop_index_to_string(prop
, intval
, &strval
)
394 (void) strlcpy(buf
, strval
, len
);
408 * Check if the bootfs name has the same pool name as it is set to.
409 * Assuming bootfs is a valid dataset name.
412 bootfs_name_valid(const char *pool
, const char *bootfs
)
414 int len
= strlen(pool
);
415 if (bootfs
[0] == '\0')
418 if (!zfs_name_valid(bootfs
, ZFS_TYPE_FILESYSTEM
|ZFS_TYPE_SNAPSHOT
))
421 if (strncmp(pool
, bootfs
, len
) == 0 &&
422 (bootfs
[len
] == '/' || bootfs
[len
] == '\0'))
429 zpool_is_bootable(zpool_handle_t
*zhp
)
431 char bootfs
[ZFS_MAX_DATASET_NAME_LEN
];
433 return (zpool_get_prop(zhp
, ZPOOL_PROP_BOOTFS
, bootfs
,
434 sizeof (bootfs
), NULL
, B_FALSE
) == 0 && strncmp(bootfs
, "-",
435 sizeof (bootfs
)) != 0);
440 * Given an nvlist of zpool properties to be set, validate that they are
441 * correct, and parse any numeric properties (index, boolean, etc) if they are
442 * specified as strings.
445 zpool_valid_proplist(libzfs_handle_t
*hdl
, const char *poolname
,
446 nvlist_t
*props
, uint64_t version
, prop_flags_t flags
, char *errbuf
)
454 struct stat64 statbuf
;
457 if (nvlist_alloc(&retprops
, NV_UNIQUE_NAME
, 0) != 0) {
458 (void) no_memory(hdl
);
463 while ((elem
= nvlist_next_nvpair(props
, elem
)) != NULL
) {
464 const char *propname
= nvpair_name(elem
);
466 prop
= zpool_name_to_prop(propname
);
467 if (prop
== ZPOOL_PROP_INVAL
&& zpool_prop_feature(propname
)) {
469 char *fname
= strchr(propname
, '@') + 1;
471 err
= zfeature_lookup_name(fname
, NULL
);
473 ASSERT3U(err
, ==, ENOENT
);
474 zfs_error_aux(hdl
, dgettext(TEXT_DOMAIN
,
475 "invalid feature '%s', '%s'"), fname
,
477 (void) zfs_error(hdl
, EZFS_BADPROP
, errbuf
);
481 if (nvpair_type(elem
) != DATA_TYPE_STRING
) {
482 zfs_error_aux(hdl
, dgettext(TEXT_DOMAIN
,
483 "'%s' must be a string"), propname
);
484 (void) zfs_error(hdl
, EZFS_BADPROP
, errbuf
);
488 (void) nvpair_value_string(elem
, &strval
);
489 if (strcmp(strval
, ZFS_FEATURE_ENABLED
) != 0 &&
490 strcmp(strval
, ZFS_FEATURE_DISABLED
) != 0) {
491 zfs_error_aux(hdl
, dgettext(TEXT_DOMAIN
,
492 "property '%s' can only be set to "
493 "'enabled' or 'disabled'"), propname
);
494 (void) zfs_error(hdl
, EZFS_BADPROP
, errbuf
);
498 if (nvlist_add_uint64(retprops
, propname
, 0) != 0) {
499 (void) no_memory(hdl
);
506 * Make sure this property is valid and applies to this type.
508 if (prop
== ZPOOL_PROP_INVAL
) {
509 zfs_error_aux(hdl
, dgettext(TEXT_DOMAIN
,
510 "invalid property '%s'"), propname
);
511 (void) zfs_error(hdl
, EZFS_BADPROP
, errbuf
);
515 if (zpool_prop_readonly(prop
)) {
516 zfs_error_aux(hdl
, dgettext(TEXT_DOMAIN
, "'%s' "
517 "is readonly"), propname
);
518 (void) zfs_error(hdl
, EZFS_PROPREADONLY
, errbuf
);
522 if (zprop_parse_value(hdl
, elem
, prop
, ZFS_TYPE_POOL
, retprops
,
523 &strval
, &intval
, errbuf
) != 0)
527 * Perform additional checking for specific properties.
530 case ZPOOL_PROP_VERSION
:
531 if (intval
< version
||
532 !SPA_VERSION_IS_SUPPORTED(intval
)) {
533 zfs_error_aux(hdl
, dgettext(TEXT_DOMAIN
,
534 "property '%s' number %d is invalid."),
536 (void) zfs_error(hdl
, EZFS_BADVERSION
, errbuf
);
541 case ZPOOL_PROP_BOOTSIZE
:
543 zfs_error_aux(hdl
, dgettext(TEXT_DOMAIN
,
544 "property '%s' can only be set during pool "
545 "creation"), propname
);
546 (void) zfs_error(hdl
, EZFS_BADPROP
, errbuf
);
551 case ZPOOL_PROP_ASHIFT
:
553 (intval
< ASHIFT_MIN
|| intval
> ASHIFT_MAX
)) {
554 zfs_error_aux(hdl
, dgettext(TEXT_DOMAIN
,
555 "invalid '%s=%d' property: only values "
556 "between %" PRId32
" and %" PRId32
" "
558 propname
, intval
, ASHIFT_MIN
, ASHIFT_MAX
);
559 (void) zfs_error(hdl
, EZFS_BADPROP
, errbuf
);
564 case ZPOOL_PROP_BOOTFS
:
565 if (flags
.create
|| flags
.import
) {
566 zfs_error_aux(hdl
, dgettext(TEXT_DOMAIN
,
567 "property '%s' cannot be set at creation "
568 "or import time"), propname
);
569 (void) zfs_error(hdl
, EZFS_BADPROP
, errbuf
);
573 if (version
< SPA_VERSION_BOOTFS
) {
574 zfs_error_aux(hdl
, dgettext(TEXT_DOMAIN
,
575 "pool must be upgraded to support "
576 "'%s' property"), propname
);
577 (void) zfs_error(hdl
, EZFS_BADVERSION
, errbuf
);
582 * bootfs property value has to be a dataset name and
583 * the dataset has to be in the same pool as it sets to.
585 if (!bootfs_name_valid(poolname
, strval
)) {
586 zfs_error_aux(hdl
, dgettext(TEXT_DOMAIN
, "'%s' "
587 "is an invalid name"), strval
);
588 (void) zfs_error(hdl
, EZFS_INVALIDNAME
, errbuf
);
592 if ((zhp
= zpool_open_canfail(hdl
, poolname
)) == NULL
) {
593 zfs_error_aux(hdl
, dgettext(TEXT_DOMAIN
,
594 "could not open pool '%s'"), poolname
);
595 (void) zfs_error(hdl
, EZFS_OPENFAILED
, errbuf
);
601 case ZPOOL_PROP_ALTROOT
:
602 if (!flags
.create
&& !flags
.import
) {
603 zfs_error_aux(hdl
, dgettext(TEXT_DOMAIN
,
604 "property '%s' can only be set during pool "
605 "creation or import"), propname
);
606 (void) zfs_error(hdl
, EZFS_BADPROP
, errbuf
);
610 if (strval
[0] != '/') {
611 zfs_error_aux(hdl
, dgettext(TEXT_DOMAIN
,
612 "bad alternate root '%s'"), strval
);
613 (void) zfs_error(hdl
, EZFS_BADPATH
, errbuf
);
618 case ZPOOL_PROP_CACHEFILE
:
619 if (strval
[0] == '\0')
622 if (strcmp(strval
, "none") == 0)
625 if (strval
[0] != '/') {
626 zfs_error_aux(hdl
, dgettext(TEXT_DOMAIN
,
627 "property '%s' must be empty, an "
628 "absolute path, or 'none'"), propname
);
629 (void) zfs_error(hdl
, EZFS_BADPATH
, errbuf
);
633 slash
= strrchr(strval
, '/');
635 if (slash
[1] == '\0' || strcmp(slash
, "/.") == 0 ||
636 strcmp(slash
, "/..") == 0) {
637 zfs_error_aux(hdl
, dgettext(TEXT_DOMAIN
,
638 "'%s' is not a valid file"), strval
);
639 (void) zfs_error(hdl
, EZFS_BADPATH
, errbuf
);
645 if (strval
[0] != '\0' &&
646 (stat64(strval
, &statbuf
) != 0 ||
647 !S_ISDIR(statbuf
.st_mode
))) {
648 zfs_error_aux(hdl
, dgettext(TEXT_DOMAIN
,
649 "'%s' is not a valid directory"),
651 (void) zfs_error(hdl
, EZFS_BADPATH
, errbuf
);
658 case ZPOOL_PROP_COMMENT
:
659 for (check
= strval
; *check
!= '\0'; check
++) {
660 if (!isprint(*check
)) {
662 dgettext(TEXT_DOMAIN
,
663 "comment may only have printable "
665 (void) zfs_error(hdl
, EZFS_BADPROP
,
670 if (strlen(strval
) > ZPROP_MAX_COMMENT
) {
671 zfs_error_aux(hdl
, dgettext(TEXT_DOMAIN
,
672 "comment must not exceed %d characters"),
674 (void) zfs_error(hdl
, EZFS_BADPROP
, errbuf
);
679 case ZPOOL_PROP_READONLY
:
681 zfs_error_aux(hdl
, dgettext(TEXT_DOMAIN
,
682 "property '%s' can only be set at "
683 "import time"), propname
);
684 (void) zfs_error(hdl
, EZFS_BADPROP
, errbuf
);
689 case ZPOOL_PROP_TNAME
:
691 zfs_error_aux(hdl
, dgettext(TEXT_DOMAIN
,
692 "property '%s' can only be set at "
693 "creation time"), propname
);
694 (void) zfs_error(hdl
, EZFS_BADPROP
, errbuf
);
699 case ZPOOL_PROP_MULTIHOST
:
700 if (get_system_hostid() == 0) {
701 zfs_error_aux(hdl
, dgettext(TEXT_DOMAIN
,
702 "requires a non-zero system hostid"));
703 (void) zfs_error(hdl
, EZFS_BADPROP
, errbuf
);
709 zfs_error_aux(hdl
, dgettext(TEXT_DOMAIN
,
710 "property '%s'(%d) not defined"), propname
, prop
);
717 nvlist_free(retprops
);
722 * Set zpool property : propname=propval.
725 zpool_set_prop(zpool_handle_t
*zhp
, const char *propname
, const char *propval
)
727 zfs_cmd_t zc
= { 0 };
730 nvlist_t
*nvl
= NULL
;
733 prop_flags_t flags
= { 0 };
735 (void) snprintf(errbuf
, sizeof (errbuf
),
736 dgettext(TEXT_DOMAIN
, "cannot set property for '%s'"),
739 if (nvlist_alloc(&nvl
, NV_UNIQUE_NAME
, 0) != 0)
740 return (no_memory(zhp
->zpool_hdl
));
742 if (nvlist_add_string(nvl
, propname
, propval
) != 0) {
744 return (no_memory(zhp
->zpool_hdl
));
747 version
= zpool_get_prop_int(zhp
, ZPOOL_PROP_VERSION
, NULL
);
748 if ((realprops
= zpool_valid_proplist(zhp
->zpool_hdl
,
749 zhp
->zpool_name
, nvl
, version
, flags
, errbuf
)) == NULL
) {
758 * Execute the corresponding ioctl() to set this property.
760 (void) strlcpy(zc
.zc_name
, zhp
->zpool_name
, sizeof (zc
.zc_name
));
762 if (zcmd_write_src_nvlist(zhp
->zpool_hdl
, &zc
, nvl
) != 0) {
767 ret
= zfs_ioctl(zhp
->zpool_hdl
, ZFS_IOC_POOL_SET_PROPS
, &zc
);
769 zcmd_free_nvlists(&zc
);
773 (void) zpool_standard_error(zhp
->zpool_hdl
, errno
, errbuf
);
775 (void) zpool_props_refresh(zhp
);
781 zpool_expand_proplist(zpool_handle_t
*zhp
, zprop_list_t
**plp
)
783 libzfs_handle_t
*hdl
= zhp
->zpool_hdl
;
785 char buf
[ZFS_MAXPROPLEN
];
786 nvlist_t
*features
= NULL
;
788 boolean_t firstexpand
= (NULL
== *plp
);
790 if (zprop_expand_list(hdl
, plp
, ZFS_TYPE_POOL
) != 0)
794 while (*last
!= NULL
)
795 last
= &(*last
)->pl_next
;
798 features
= zpool_get_features(zhp
);
800 if ((*plp
)->pl_all
&& firstexpand
) {
801 for (int i
= 0; i
< SPA_FEATURES
; i
++) {
802 zprop_list_t
*entry
= zfs_alloc(hdl
,
803 sizeof (zprop_list_t
));
804 entry
->pl_prop
= ZPROP_INVAL
;
805 entry
->pl_user_prop
= zfs_asprintf(hdl
, "feature@%s",
806 spa_feature_table
[i
].fi_uname
);
807 entry
->pl_width
= strlen(entry
->pl_user_prop
);
808 entry
->pl_all
= B_TRUE
;
811 last
= &entry
->pl_next
;
815 /* add any unsupported features */
816 for (nvpair_t
*nvp
= nvlist_next_nvpair(features
, NULL
);
817 nvp
!= NULL
; nvp
= nvlist_next_nvpair(features
, nvp
)) {
822 if (zfeature_is_supported(nvpair_name(nvp
)))
825 propname
= zfs_asprintf(hdl
, "unsupported@%s",
829 * Before adding the property to the list make sure that no
830 * other pool already added the same property.
834 while (entry
!= NULL
) {
835 if (entry
->pl_user_prop
!= NULL
&&
836 strcmp(propname
, entry
->pl_user_prop
) == 0) {
840 entry
= entry
->pl_next
;
847 entry
= zfs_alloc(hdl
, sizeof (zprop_list_t
));
848 entry
->pl_prop
= ZPROP_INVAL
;
849 entry
->pl_user_prop
= propname
;
850 entry
->pl_width
= strlen(entry
->pl_user_prop
);
851 entry
->pl_all
= B_TRUE
;
854 last
= &entry
->pl_next
;
857 for (entry
= *plp
; entry
!= NULL
; entry
= entry
->pl_next
) {
862 if (entry
->pl_prop
!= ZPROP_INVAL
&&
863 zpool_get_prop(zhp
, entry
->pl_prop
, buf
, sizeof (buf
),
864 NULL
, B_FALSE
) == 0) {
865 if (strlen(buf
) > entry
->pl_width
)
866 entry
->pl_width
= strlen(buf
);
874 * Get the state for the given feature on the given ZFS pool.
877 zpool_prop_get_feature(zpool_handle_t
*zhp
, const char *propname
, char *buf
,
881 boolean_t found
= B_FALSE
;
882 nvlist_t
*features
= zpool_get_features(zhp
);
884 const char *feature
= strchr(propname
, '@') + 1;
886 supported
= zpool_prop_feature(propname
);
887 ASSERT(supported
|| zpool_prop_unsupported(propname
));
890 * Convert from feature name to feature guid. This conversion is
891 * unecessary for unsupported@... properties because they already
898 ret
= zfeature_lookup_name(feature
, &fid
);
900 (void) strlcpy(buf
, "-", len
);
903 feature
= spa_feature_table
[fid
].fi_guid
;
906 if (nvlist_lookup_uint64(features
, feature
, &refcount
) == 0)
911 (void) strlcpy(buf
, ZFS_FEATURE_DISABLED
, len
);
914 (void) strlcpy(buf
, ZFS_FEATURE_ENABLED
, len
);
916 (void) strlcpy(buf
, ZFS_FEATURE_ACTIVE
, len
);
921 (void) strcpy(buf
, ZFS_UNSUPPORTED_INACTIVE
);
923 (void) strcpy(buf
, ZFS_UNSUPPORTED_READONLY
);
926 (void) strlcpy(buf
, "-", len
);
935 * Don't start the slice at the default block of 34; many storage
936 * devices will use a stripe width of 128k, so start there instead.
938 #define NEW_START_BLOCK 256
941 * Validate the given pool name, optionally putting an extended error message in
945 zpool_name_valid(libzfs_handle_t
*hdl
, boolean_t isopen
, const char *pool
)
951 ret
= pool_namecheck(pool
, &why
, &what
);
954 * The rules for reserved pool names were extended at a later point.
955 * But we need to support users with existing pools that may now be
956 * invalid. So we only check for this expanded set of names during a
957 * create (or import), and only in userland.
959 if (ret
== 0 && !isopen
&&
960 (strncmp(pool
, "mirror", 6) == 0 ||
961 strncmp(pool
, "raidz", 5) == 0 ||
962 strncmp(pool
, "spare", 5) == 0 ||
963 strcmp(pool
, "log") == 0)) {
966 dgettext(TEXT_DOMAIN
, "name is reserved"));
974 case NAME_ERR_TOOLONG
:
976 dgettext(TEXT_DOMAIN
, "name is too long"));
979 case NAME_ERR_INVALCHAR
:
981 dgettext(TEXT_DOMAIN
, "invalid character "
982 "'%c' in pool name"), what
);
985 case NAME_ERR_NOLETTER
:
986 zfs_error_aux(hdl
, dgettext(TEXT_DOMAIN
,
987 "name must begin with a letter"));
990 case NAME_ERR_RESERVED
:
991 zfs_error_aux(hdl
, dgettext(TEXT_DOMAIN
,
992 "name is reserved"));
995 case NAME_ERR_DISKLIKE
:
996 zfs_error_aux(hdl
, dgettext(TEXT_DOMAIN
,
997 "pool name is reserved"));
1000 case NAME_ERR_LEADING_SLASH
:
1001 zfs_error_aux(hdl
, dgettext(TEXT_DOMAIN
,
1002 "leading slash in name"));
1005 case NAME_ERR_EMPTY_COMPONENT
:
1006 zfs_error_aux(hdl
, dgettext(TEXT_DOMAIN
,
1007 "empty component in name"));
1010 case NAME_ERR_TRAILING_SLASH
:
1011 zfs_error_aux(hdl
, dgettext(TEXT_DOMAIN
,
1012 "trailing slash in name"));
1015 case NAME_ERR_MULTIPLE_DELIMITERS
:
1016 zfs_error_aux(hdl
, dgettext(TEXT_DOMAIN
,
1017 "multiple '@' and/or '#' delimiters in "
1022 zfs_error_aux(hdl
, dgettext(TEXT_DOMAIN
,
1023 "(%d) not defined"), why
);
1034 * Open a handle to the given pool, even if the pool is currently in the FAULTED
1038 zpool_open_canfail(libzfs_handle_t
*hdl
, const char *pool
)
1040 zpool_handle_t
*zhp
;
1044 * Make sure the pool name is valid.
1046 if (!zpool_name_valid(hdl
, B_TRUE
, pool
)) {
1047 (void) zfs_error_fmt(hdl
, EZFS_INVALIDNAME
,
1048 dgettext(TEXT_DOMAIN
, "cannot open '%s'"),
1053 if ((zhp
= zfs_alloc(hdl
, sizeof (zpool_handle_t
))) == NULL
)
1056 zhp
->zpool_hdl
= hdl
;
1057 (void) strlcpy(zhp
->zpool_name
, pool
, sizeof (zhp
->zpool_name
));
1059 if (zpool_refresh_stats(zhp
, &missing
) != 0) {
1065 zfs_error_aux(hdl
, dgettext(TEXT_DOMAIN
, "no such pool"));
1066 (void) zfs_error_fmt(hdl
, EZFS_NOENT
,
1067 dgettext(TEXT_DOMAIN
, "cannot open '%s'"), pool
);
1076 * Like the above, but silent on error. Used when iterating over pools (because
1077 * the configuration cache may be out of date).
1080 zpool_open_silent(libzfs_handle_t
*hdl
, const char *pool
, zpool_handle_t
**ret
)
1082 zpool_handle_t
*zhp
;
1085 if ((zhp
= zfs_alloc(hdl
, sizeof (zpool_handle_t
))) == NULL
)
1088 zhp
->zpool_hdl
= hdl
;
1089 (void) strlcpy(zhp
->zpool_name
, pool
, sizeof (zhp
->zpool_name
));
1091 if (zpool_refresh_stats(zhp
, &missing
) != 0) {
1107 * Similar to zpool_open_canfail(), but refuses to open pools in the faulted
1111 zpool_open(libzfs_handle_t
*hdl
, const char *pool
)
1113 zpool_handle_t
*zhp
;
1115 if ((zhp
= zpool_open_canfail(hdl
, pool
)) == NULL
)
1118 if (zhp
->zpool_state
== POOL_STATE_UNAVAIL
) {
1119 (void) zfs_error_fmt(hdl
, EZFS_POOLUNAVAIL
,
1120 dgettext(TEXT_DOMAIN
, "cannot open '%s'"), zhp
->zpool_name
);
1129 * Close the handle. Simply frees the memory associated with the handle.
1132 zpool_close(zpool_handle_t
*zhp
)
1134 nvlist_free(zhp
->zpool_config
);
1135 nvlist_free(zhp
->zpool_old_config
);
1136 nvlist_free(zhp
->zpool_props
);
1141 * Return the name of the pool.
1144 zpool_get_name(zpool_handle_t
*zhp
)
1146 return (zhp
->zpool_name
);
1151 * Return the state of the pool (ACTIVE or UNAVAILABLE)
1154 zpool_get_state(zpool_handle_t
*zhp
)
1156 return (zhp
->zpool_state
);
1160 * Check if vdev list contains a special vdev
1163 zpool_has_special_vdev(nvlist_t
*nvroot
)
1168 if (nvlist_lookup_nvlist_array(nvroot
, ZPOOL_CONFIG_CHILDREN
, &child
,
1170 for (uint_t c
= 0; c
< children
; c
++) {
1173 if (nvlist_lookup_string(child
[c
],
1174 ZPOOL_CONFIG_ALLOCATION_BIAS
, &bias
) == 0 &&
1175 strcmp(bias
, VDEV_ALLOC_BIAS_SPECIAL
) == 0) {
1184 * Create the named pool, using the provided vdev list. It is assumed
1185 * that the consumer has already validated the contents of the nvlist, so we
1186 * don't have to worry about error semantics.
1189 zpool_create(libzfs_handle_t
*hdl
, const char *pool
, nvlist_t
*nvroot
,
1190 nvlist_t
*props
, nvlist_t
*fsprops
)
1192 zfs_cmd_t zc
= { 0 };
1193 nvlist_t
*zc_fsprops
= NULL
;
1194 nvlist_t
*zc_props
= NULL
;
1195 nvlist_t
*hidden_args
= NULL
;
1196 uint8_t *wkeydata
= NULL
;
1201 (void) snprintf(msg
, sizeof (msg
), dgettext(TEXT_DOMAIN
,
1202 "cannot create '%s'"), pool
);
1204 if (!zpool_name_valid(hdl
, B_FALSE
, pool
))
1205 return (zfs_error(hdl
, EZFS_INVALIDNAME
, msg
));
1207 if (zcmd_write_conf_nvlist(hdl
, &zc
, nvroot
) != 0)
1211 prop_flags_t flags
= { .create
= B_TRUE
, .import
= B_FALSE
};
1213 if ((zc_props
= zpool_valid_proplist(hdl
, pool
, props
,
1214 SPA_VERSION_1
, flags
, msg
)) == NULL
) {
1223 zoned
= ((nvlist_lookup_string(fsprops
,
1224 zfs_prop_to_name(ZFS_PROP_ZONED
), &zonestr
) == 0) &&
1225 strcmp(zonestr
, "on") == 0);
1227 if ((zc_fsprops
= zfs_valid_proplist(hdl
, ZFS_TYPE_FILESYSTEM
,
1228 fsprops
, zoned
, NULL
, NULL
, B_TRUE
, msg
)) == NULL
) {
1232 if (nvlist_exists(zc_fsprops
,
1233 zfs_prop_to_name(ZFS_PROP_SPECIAL_SMALL_BLOCKS
)) &&
1234 !zpool_has_special_vdev(nvroot
)) {
1235 zfs_error_aux(hdl
, dgettext(TEXT_DOMAIN
,
1236 "%s property requires a special vdev"),
1237 zfs_prop_to_name(ZFS_PROP_SPECIAL_SMALL_BLOCKS
));
1238 (void) zfs_error(hdl
, EZFS_BADPROP
, msg
);
1243 (nvlist_alloc(&zc_props
, NV_UNIQUE_NAME
, 0) != 0)) {
1246 if (zfs_crypto_create(hdl
, NULL
, zc_fsprops
, props
, B_TRUE
,
1247 &wkeydata
, &wkeylen
) != 0) {
1248 (void) zfs_error(hdl
, EZFS_CRYPTOFAILED
, msg
);
1251 if (nvlist_add_nvlist(zc_props
,
1252 ZPOOL_ROOTFS_PROPS
, zc_fsprops
) != 0) {
1255 if (wkeydata
!= NULL
) {
1256 if (nvlist_alloc(&hidden_args
, NV_UNIQUE_NAME
, 0) != 0)
1259 if (nvlist_add_uint8_array(hidden_args
, "wkeydata",
1260 wkeydata
, wkeylen
) != 0)
1263 if (nvlist_add_nvlist(zc_props
, ZPOOL_HIDDEN_ARGS
,
1269 if (zc_props
&& zcmd_write_src_nvlist(hdl
, &zc
, zc_props
) != 0)
1272 (void) strlcpy(zc
.zc_name
, pool
, sizeof (zc
.zc_name
));
1274 if ((ret
= zfs_ioctl(hdl
, ZFS_IOC_POOL_CREATE
, &zc
)) != 0) {
1276 zcmd_free_nvlists(&zc
);
1277 nvlist_free(zc_props
);
1278 nvlist_free(zc_fsprops
);
1279 nvlist_free(hidden_args
);
1280 if (wkeydata
!= NULL
)
1286 * This can happen if the user has specified the same
1287 * device multiple times. We can't reliably detect this
1288 * until we try to add it and see we already have a
1291 zfs_error_aux(hdl
, dgettext(TEXT_DOMAIN
,
1292 "one or more vdevs refer to the same device"));
1293 return (zfs_error(hdl
, EZFS_BADDEV
, msg
));
1297 * This happens if the record size is smaller or larger
1298 * than the allowed size range, or not a power of 2.
1300 * NOTE: although zfs_valid_proplist is called earlier,
1301 * this case may have slipped through since the
1302 * pool does not exist yet and it is therefore
1303 * impossible to read properties e.g. max blocksize
1306 zfs_error_aux(hdl
, dgettext(TEXT_DOMAIN
,
1307 "record size invalid"));
1308 return (zfs_error(hdl
, EZFS_BADPROP
, msg
));
1312 * This occurs when one of the devices is below
1313 * SPA_MINDEVSIZE. Unfortunately, we can't detect which
1314 * device was the problem device since there's no
1315 * reliable way to determine device size from userland.
1320 zfs_nicebytes(SPA_MINDEVSIZE
, buf
,
1323 zfs_error_aux(hdl
, dgettext(TEXT_DOMAIN
,
1324 "one or more devices is less than the "
1325 "minimum size (%s)"), buf
);
1327 return (zfs_error(hdl
, EZFS_BADDEV
, msg
));
1330 zfs_error_aux(hdl
, dgettext(TEXT_DOMAIN
,
1331 "one or more devices is out of space"));
1332 return (zfs_error(hdl
, EZFS_BADDEV
, msg
));
1335 return (zpool_standard_error(hdl
, errno
, msg
));
1340 zcmd_free_nvlists(&zc
);
1341 nvlist_free(zc_props
);
1342 nvlist_free(zc_fsprops
);
1343 nvlist_free(hidden_args
);
1344 if (wkeydata
!= NULL
)
1350 * Destroy the given pool. It is up to the caller to ensure that there are no
1351 * datasets left in the pool.
1354 zpool_destroy(zpool_handle_t
*zhp
, const char *log_str
)
1356 zfs_cmd_t zc
= { 0 };
1357 zfs_handle_t
*zfp
= NULL
;
1358 libzfs_handle_t
*hdl
= zhp
->zpool_hdl
;
1361 if (zhp
->zpool_state
== POOL_STATE_ACTIVE
&&
1362 (zfp
= zfs_open(hdl
, zhp
->zpool_name
, ZFS_TYPE_FILESYSTEM
)) == NULL
)
1365 (void) strlcpy(zc
.zc_name
, zhp
->zpool_name
, sizeof (zc
.zc_name
));
1366 zc
.zc_history
= (uint64_t)(uintptr_t)log_str
;
1368 if (zfs_ioctl(hdl
, ZFS_IOC_POOL_DESTROY
, &zc
) != 0) {
1369 (void) snprintf(msg
, sizeof (msg
), dgettext(TEXT_DOMAIN
,
1370 "cannot destroy '%s'"), zhp
->zpool_name
);
1372 if (errno
== EROFS
) {
1373 zfs_error_aux(hdl
, dgettext(TEXT_DOMAIN
,
1374 "one or more devices is read only"));
1375 (void) zfs_error(hdl
, EZFS_BADDEV
, msg
);
1377 (void) zpool_standard_error(hdl
, errno
, msg
);
1386 remove_mountpoint(zfp
);
1394 * Create a checkpoint in the given pool.
1397 zpool_checkpoint(zpool_handle_t
*zhp
)
1399 libzfs_handle_t
*hdl
= zhp
->zpool_hdl
;
1403 error
= lzc_pool_checkpoint(zhp
->zpool_name
);
1405 (void) snprintf(msg
, sizeof (msg
), dgettext(TEXT_DOMAIN
,
1406 "cannot checkpoint '%s'"), zhp
->zpool_name
);
1407 (void) zpool_standard_error(hdl
, error
, msg
);
1415 * Discard the checkpoint from the given pool.
1418 zpool_discard_checkpoint(zpool_handle_t
*zhp
)
1420 libzfs_handle_t
*hdl
= zhp
->zpool_hdl
;
1424 error
= lzc_pool_checkpoint_discard(zhp
->zpool_name
);
1426 (void) snprintf(msg
, sizeof (msg
), dgettext(TEXT_DOMAIN
,
1427 "cannot discard checkpoint in '%s'"), zhp
->zpool_name
);
1428 (void) zpool_standard_error(hdl
, error
, msg
);
1436 * Add the given vdevs to the pool. The caller must have already performed the
1437 * necessary verification to ensure that the vdev specification is well-formed.
1440 zpool_add(zpool_handle_t
*zhp
, nvlist_t
*nvroot
)
1442 zfs_cmd_t zc
= { 0 };
1444 libzfs_handle_t
*hdl
= zhp
->zpool_hdl
;
1446 nvlist_t
**spares
, **l2cache
;
1447 uint_t nspares
, nl2cache
;
1449 (void) snprintf(msg
, sizeof (msg
), dgettext(TEXT_DOMAIN
,
1450 "cannot add to '%s'"), zhp
->zpool_name
);
1452 if (zpool_get_prop_int(zhp
, ZPOOL_PROP_VERSION
, NULL
) <
1453 SPA_VERSION_SPARES
&&
1454 nvlist_lookup_nvlist_array(nvroot
, ZPOOL_CONFIG_SPARES
,
1455 &spares
, &nspares
) == 0) {
1456 zfs_error_aux(hdl
, dgettext(TEXT_DOMAIN
, "pool must be "
1457 "upgraded to add hot spares"));
1458 return (zfs_error(hdl
, EZFS_BADVERSION
, msg
));
1461 if (zpool_get_prop_int(zhp
, ZPOOL_PROP_VERSION
, NULL
) <
1462 SPA_VERSION_L2CACHE
&&
1463 nvlist_lookup_nvlist_array(nvroot
, ZPOOL_CONFIG_L2CACHE
,
1464 &l2cache
, &nl2cache
) == 0) {
1465 zfs_error_aux(hdl
, dgettext(TEXT_DOMAIN
, "pool must be "
1466 "upgraded to add cache devices"));
1467 return (zfs_error(hdl
, EZFS_BADVERSION
, msg
));
1470 if (zcmd_write_conf_nvlist(hdl
, &zc
, nvroot
) != 0)
1472 (void) strlcpy(zc
.zc_name
, zhp
->zpool_name
, sizeof (zc
.zc_name
));
1474 if (zfs_ioctl(hdl
, ZFS_IOC_VDEV_ADD
, &zc
) != 0) {
1478 * This can happen if the user has specified the same
1479 * device multiple times. We can't reliably detect this
1480 * until we try to add it and see we already have a
1483 zfs_error_aux(hdl
, dgettext(TEXT_DOMAIN
,
1484 "one or more vdevs refer to the same device"));
1485 (void) zfs_error(hdl
, EZFS_BADDEV
, msg
);
1489 zfs_error_aux(hdl
, dgettext(TEXT_DOMAIN
,
1490 "invalid config; a pool with removing/removed "
1491 "vdevs does not support adding raidz vdevs"));
1492 (void) zfs_error(hdl
, EZFS_BADDEV
, msg
);
1497 * This occurrs when one of the devices is below
1498 * SPA_MINDEVSIZE. Unfortunately, we can't detect which
1499 * device was the problem device since there's no
1500 * reliable way to determine device size from userland.
1505 zfs_nicebytes(SPA_MINDEVSIZE
, buf
,
1508 zfs_error_aux(hdl
, dgettext(TEXT_DOMAIN
,
1509 "device is less than the minimum "
1512 (void) zfs_error(hdl
, EZFS_BADDEV
, msg
);
1516 zfs_error_aux(hdl
, dgettext(TEXT_DOMAIN
,
1517 "pool must be upgraded to add these vdevs"));
1518 (void) zfs_error(hdl
, EZFS_BADVERSION
, msg
);
1522 (void) zpool_standard_error(hdl
, errno
, msg
);
1530 zcmd_free_nvlists(&zc
);
1536 * Exports the pool from the system. The caller must ensure that there are no
1537 * mounted datasets in the pool.
1540 zpool_export_common(zpool_handle_t
*zhp
, boolean_t force
, boolean_t hardforce
,
1541 const char *log_str
)
1543 zfs_cmd_t zc
= { 0 };
1546 (void) snprintf(msg
, sizeof (msg
), dgettext(TEXT_DOMAIN
,
1547 "cannot export '%s'"), zhp
->zpool_name
);
1549 (void) strlcpy(zc
.zc_name
, zhp
->zpool_name
, sizeof (zc
.zc_name
));
1550 zc
.zc_cookie
= force
;
1551 zc
.zc_guid
= hardforce
;
1552 zc
.zc_history
= (uint64_t)(uintptr_t)log_str
;
1554 if (zfs_ioctl(zhp
->zpool_hdl
, ZFS_IOC_POOL_EXPORT
, &zc
) != 0) {
1557 zfs_error_aux(zhp
->zpool_hdl
, dgettext(TEXT_DOMAIN
,
1558 "use '-f' to override the following errors:\n"
1559 "'%s' has an active shared spare which could be"
1560 " used by other pools once '%s' is exported."),
1561 zhp
->zpool_name
, zhp
->zpool_name
);
1562 return (zfs_error(zhp
->zpool_hdl
, EZFS_ACTIVE_SPARE
,
1565 return (zpool_standard_error_fmt(zhp
->zpool_hdl
, errno
,
1574 zpool_export(zpool_handle_t
*zhp
, boolean_t force
, const char *log_str
)
1576 return (zpool_export_common(zhp
, force
, B_FALSE
, log_str
));
1580 zpool_export_force(zpool_handle_t
*zhp
, const char *log_str
)
1582 return (zpool_export_common(zhp
, B_TRUE
, B_TRUE
, log_str
));
1586 zpool_rewind_exclaim(libzfs_handle_t
*hdl
, const char *name
, boolean_t dryrun
,
1589 nvlist_t
*nv
= NULL
;
1595 if (!hdl
->libzfs_printerr
|| config
== NULL
)
1598 if (nvlist_lookup_nvlist(config
, ZPOOL_CONFIG_LOAD_INFO
, &nv
) != 0 ||
1599 nvlist_lookup_nvlist(nv
, ZPOOL_CONFIG_REWIND_INFO
, &nv
) != 0) {
1603 if (nvlist_lookup_uint64(nv
, ZPOOL_CONFIG_LOAD_TIME
, &rewindto
) != 0)
1605 (void) nvlist_lookup_int64(nv
, ZPOOL_CONFIG_REWIND_TIME
, &loss
);
1607 if (localtime_r((time_t *)&rewindto
, &t
) != NULL
&&
1608 strftime(timestr
, 128, 0, &t
) != 0) {
1610 (void) printf(dgettext(TEXT_DOMAIN
,
1611 "Would be able to return %s "
1612 "to its state as of %s.\n"),
1615 (void) printf(dgettext(TEXT_DOMAIN
,
1616 "Pool %s returned to its state as of %s.\n"),
1620 (void) printf(dgettext(TEXT_DOMAIN
,
1621 "%s approximately %lld "),
1622 dryrun
? "Would discard" : "Discarded",
1624 (void) printf(dgettext(TEXT_DOMAIN
,
1625 "minutes of transactions.\n"));
1626 } else if (loss
> 0) {
1627 (void) printf(dgettext(TEXT_DOMAIN
,
1628 "%s approximately %lld "),
1629 dryrun
? "Would discard" : "Discarded", loss
);
1630 (void) printf(dgettext(TEXT_DOMAIN
,
1631 "seconds of transactions.\n"));
1637 zpool_explain_recover(libzfs_handle_t
*hdl
, const char *name
, int reason
,
1640 nvlist_t
*nv
= NULL
;
1642 uint64_t edata
= UINT64_MAX
;
1647 if (!hdl
->libzfs_printerr
)
1651 (void) printf(dgettext(TEXT_DOMAIN
, "action: "));
1653 (void) printf(dgettext(TEXT_DOMAIN
, "\t"));
1655 /* All attempted rewinds failed if ZPOOL_CONFIG_LOAD_TIME missing */
1656 if (nvlist_lookup_nvlist(config
, ZPOOL_CONFIG_LOAD_INFO
, &nv
) != 0 ||
1657 nvlist_lookup_nvlist(nv
, ZPOOL_CONFIG_REWIND_INFO
, &nv
) != 0 ||
1658 nvlist_lookup_uint64(nv
, ZPOOL_CONFIG_LOAD_TIME
, &rewindto
) != 0)
1661 (void) nvlist_lookup_int64(nv
, ZPOOL_CONFIG_REWIND_TIME
, &loss
);
1662 (void) nvlist_lookup_uint64(nv
, ZPOOL_CONFIG_LOAD_DATA_ERRORS
,
1665 (void) printf(dgettext(TEXT_DOMAIN
,
1666 "Recovery is possible, but will result in some data loss.\n"));
1668 if (localtime_r((time_t *)&rewindto
, &t
) != NULL
&&
1669 strftime(timestr
, 128, 0, &t
) != 0) {
1670 (void) printf(dgettext(TEXT_DOMAIN
,
1671 "\tReturning the pool to its state as of %s\n"
1672 "\tshould correct the problem. "),
1675 (void) printf(dgettext(TEXT_DOMAIN
,
1676 "\tReverting the pool to an earlier state "
1677 "should correct the problem.\n\t"));
1681 (void) printf(dgettext(TEXT_DOMAIN
,
1682 "Approximately %lld minutes of data\n"
1683 "\tmust be discarded, irreversibly. "), (loss
+ 30) / 60);
1684 } else if (loss
> 0) {
1685 (void) printf(dgettext(TEXT_DOMAIN
,
1686 "Approximately %lld seconds of data\n"
1687 "\tmust be discarded, irreversibly. "), loss
);
1689 if (edata
!= 0 && edata
!= UINT64_MAX
) {
1691 (void) printf(dgettext(TEXT_DOMAIN
,
1692 "After rewind, at least\n"
1693 "\tone persistent user-data error will remain. "));
1695 (void) printf(dgettext(TEXT_DOMAIN
,
1696 "After rewind, several\n"
1697 "\tpersistent user-data errors will remain. "));
1700 (void) printf(dgettext(TEXT_DOMAIN
,
1701 "Recovery can be attempted\n\tby executing 'zpool %s -F %s'. "),
1702 reason
>= 0 ? "clear" : "import", name
);
1704 (void) printf(dgettext(TEXT_DOMAIN
,
1705 "A scrub of the pool\n"
1706 "\tis strongly recommended after recovery.\n"));
1710 (void) printf(dgettext(TEXT_DOMAIN
,
1711 "Destroy and re-create the pool from\n\ta backup source.\n"));
1715 * zpool_import() is a contracted interface. Should be kept the same
1718 * Applications should use zpool_import_props() to import a pool with
1719 * new properties value to be set.
1722 zpool_import(libzfs_handle_t
*hdl
, nvlist_t
*config
, const char *newname
,
1725 nvlist_t
*props
= NULL
;
1728 if (altroot
!= NULL
) {
1729 if (nvlist_alloc(&props
, NV_UNIQUE_NAME
, 0) != 0) {
1730 return (zfs_error_fmt(hdl
, EZFS_NOMEM
,
1731 dgettext(TEXT_DOMAIN
, "cannot import '%s'"),
1735 if (nvlist_add_string(props
,
1736 zpool_prop_to_name(ZPOOL_PROP_ALTROOT
), altroot
) != 0 ||
1737 nvlist_add_string(props
,
1738 zpool_prop_to_name(ZPOOL_PROP_CACHEFILE
), "none") != 0) {
1740 return (zfs_error_fmt(hdl
, EZFS_NOMEM
,
1741 dgettext(TEXT_DOMAIN
, "cannot import '%s'"),
1746 ret
= zpool_import_props(hdl
, config
, newname
, props
,
1753 print_vdev_tree(libzfs_handle_t
*hdl
, const char *name
, nvlist_t
*nv
,
1759 uint64_t is_log
= 0;
1761 (void) nvlist_lookup_uint64(nv
, ZPOOL_CONFIG_IS_LOG
,
1765 (void) printf("\t%*s%s%s\n", indent
, "", name
,
1766 is_log
? " [log]" : "");
1768 if (nvlist_lookup_nvlist_array(nv
, ZPOOL_CONFIG_CHILDREN
,
1769 &child
, &children
) != 0)
1772 for (c
= 0; c
< children
; c
++) {
1773 vname
= zpool_vdev_name(hdl
, NULL
, child
[c
], VDEV_NAME_TYPE_ID
);
1774 print_vdev_tree(hdl
, vname
, child
[c
], indent
+ 2);
1780 zpool_print_unsup_feat(nvlist_t
*config
)
1782 nvlist_t
*nvinfo
, *unsup_feat
;
1784 verify(nvlist_lookup_nvlist(config
, ZPOOL_CONFIG_LOAD_INFO
, &nvinfo
) ==
1786 verify(nvlist_lookup_nvlist(nvinfo
, ZPOOL_CONFIG_UNSUP_FEAT
,
1789 for (nvpair_t
*nvp
= nvlist_next_nvpair(unsup_feat
, NULL
); nvp
!= NULL
;
1790 nvp
= nvlist_next_nvpair(unsup_feat
, nvp
)) {
1793 verify(nvpair_type(nvp
) == DATA_TYPE_STRING
);
1794 verify(nvpair_value_string(nvp
, &desc
) == 0);
1796 if (strlen(desc
) > 0)
1797 (void) printf("\t%s (%s)\n", nvpair_name(nvp
), desc
);
1799 (void) printf("\t%s\n", nvpair_name(nvp
));
1804 * Import the given pool using the known configuration and a list of
1805 * properties to be set. The configuration should have come from
1806 * zpool_find_import(). The 'newname' parameters control whether the pool
1807 * is imported with a different name.
1810 zpool_import_props(libzfs_handle_t
*hdl
, nvlist_t
*config
, const char *newname
,
1811 nvlist_t
*props
, int flags
)
1813 zfs_cmd_t zc
= { 0 };
1814 zpool_load_policy_t policy
;
1815 nvlist_t
*nv
= NULL
;
1816 nvlist_t
*nvinfo
= NULL
;
1817 nvlist_t
*missing
= NULL
;
1824 verify(nvlist_lookup_string(config
, ZPOOL_CONFIG_POOL_NAME
,
1827 (void) snprintf(errbuf
, sizeof (errbuf
), dgettext(TEXT_DOMAIN
,
1828 "cannot import pool '%s'"), origname
);
1830 if (newname
!= NULL
) {
1831 if (!zpool_name_valid(hdl
, B_FALSE
, newname
))
1832 return (zfs_error_fmt(hdl
, EZFS_INVALIDNAME
,
1833 dgettext(TEXT_DOMAIN
, "cannot import '%s'"),
1835 thename
= (char *)newname
;
1840 if (props
!= NULL
) {
1842 prop_flags_t flags
= { .create
= B_FALSE
, .import
= B_TRUE
};
1844 verify(nvlist_lookup_uint64(config
, ZPOOL_CONFIG_VERSION
,
1847 if ((props
= zpool_valid_proplist(hdl
, origname
,
1848 props
, version
, flags
, errbuf
)) == NULL
)
1850 if (zcmd_write_src_nvlist(hdl
, &zc
, props
) != 0) {
1857 (void) strlcpy(zc
.zc_name
, thename
, sizeof (zc
.zc_name
));
1859 verify(nvlist_lookup_uint64(config
, ZPOOL_CONFIG_POOL_GUID
,
1862 if (zcmd_write_conf_nvlist(hdl
, &zc
, config
) != 0) {
1863 zcmd_free_nvlists(&zc
);
1866 if (zcmd_alloc_dst_nvlist(hdl
, &zc
, zc
.zc_nvlist_conf_size
* 2) != 0) {
1867 zcmd_free_nvlists(&zc
);
1871 zc
.zc_cookie
= flags
;
1872 while ((ret
= zfs_ioctl(hdl
, ZFS_IOC_POOL_IMPORT
, &zc
)) != 0 &&
1874 if (zcmd_expand_dst_nvlist(hdl
, &zc
) != 0) {
1875 zcmd_free_nvlists(&zc
);
1882 (void) zcmd_read_dst_nvlist(hdl
, &zc
, &nv
);
1884 zcmd_free_nvlists(&zc
);
1886 zpool_get_load_policy(config
, &policy
);
1893 * Dry-run failed, but we print out what success
1894 * looks like if we found a best txg
1896 if (policy
.zlp_rewind
& ZPOOL_TRY_REWIND
) {
1897 zpool_rewind_exclaim(hdl
, newname
? origname
: thename
,
1903 if (newname
== NULL
)
1904 (void) snprintf(desc
, sizeof (desc
),
1905 dgettext(TEXT_DOMAIN
, "cannot import '%s'"),
1908 (void) snprintf(desc
, sizeof (desc
),
1909 dgettext(TEXT_DOMAIN
, "cannot import '%s' as '%s'"),
1914 if (nv
!= NULL
&& nvlist_lookup_nvlist(nv
,
1915 ZPOOL_CONFIG_LOAD_INFO
, &nvinfo
) == 0 &&
1916 nvlist_exists(nvinfo
, ZPOOL_CONFIG_UNSUP_FEAT
)) {
1917 (void) printf(dgettext(TEXT_DOMAIN
, "This "
1918 "pool uses the following feature(s) not "
1919 "supported by this system:\n"));
1920 zpool_print_unsup_feat(nv
);
1921 if (nvlist_exists(nvinfo
,
1922 ZPOOL_CONFIG_CAN_RDONLY
)) {
1923 (void) printf(dgettext(TEXT_DOMAIN
,
1924 "All unsupported features are only "
1925 "required for writing to the pool."
1926 "\nThe pool can be imported using "
1927 "'-o readonly=on'.\n"));
1931 * Unsupported version.
1933 (void) zfs_error(hdl
, EZFS_BADVERSION
, desc
);
1937 if (nv
!= NULL
&& nvlist_lookup_nvlist(nv
,
1938 ZPOOL_CONFIG_LOAD_INFO
, &nvinfo
) == 0) {
1939 char *hostname
= "<unknown>";
1940 uint64_t hostid
= 0;
1941 mmp_state_t mmp_state
;
1943 mmp_state
= fnvlist_lookup_uint64(nvinfo
,
1944 ZPOOL_CONFIG_MMP_STATE
);
1946 if (nvlist_exists(nvinfo
,
1947 ZPOOL_CONFIG_MMP_HOSTNAME
))
1948 hostname
= fnvlist_lookup_string(nvinfo
,
1949 ZPOOL_CONFIG_MMP_HOSTNAME
);
1951 if (nvlist_exists(nvinfo
,
1952 ZPOOL_CONFIG_MMP_HOSTID
))
1953 hostid
= fnvlist_lookup_uint64(nvinfo
,
1954 ZPOOL_CONFIG_MMP_HOSTID
);
1956 if (mmp_state
== MMP_STATE_ACTIVE
) {
1957 (void) snprintf(aux
, sizeof (aux
),
1958 dgettext(TEXT_DOMAIN
, "pool is imp"
1959 "orted on host '%s' (hostid=%lx).\n"
1960 "Export the pool on the other "
1961 "system, then run 'zpool import'."),
1962 hostname
, (unsigned long) hostid
);
1963 } else if (mmp_state
== MMP_STATE_NO_HOSTID
) {
1964 (void) snprintf(aux
, sizeof (aux
),
1965 dgettext(TEXT_DOMAIN
, "pool has "
1966 "the multihost property on and "
1967 "the\nsystem's hostid is not "
1971 (void) zfs_error_aux(hdl
, aux
);
1973 (void) zfs_error(hdl
, EZFS_ACTIVE_POOL
, desc
);
1977 (void) zfs_error(hdl
, EZFS_INVALCONFIG
, desc
);
1981 zfs_error_aux(hdl
, dgettext(TEXT_DOMAIN
,
1982 "one or more devices is read only"));
1983 (void) zfs_error(hdl
, EZFS_BADDEV
, desc
);
1987 if (nv
&& nvlist_lookup_nvlist(nv
,
1988 ZPOOL_CONFIG_LOAD_INFO
, &nvinfo
) == 0 &&
1989 nvlist_lookup_nvlist(nvinfo
,
1990 ZPOOL_CONFIG_MISSING_DEVICES
, &missing
) == 0) {
1991 (void) printf(dgettext(TEXT_DOMAIN
,
1992 "The devices below are missing or "
1993 "corrupted, use '-m' to import the pool "
1995 print_vdev_tree(hdl
, NULL
, missing
, 2);
1996 (void) printf("\n");
1998 (void) zpool_standard_error(hdl
, error
, desc
);
2002 (void) zpool_standard_error(hdl
, error
, desc
);
2005 zfs_error_aux(hdl
, dgettext(TEXT_DOMAIN
,
2006 "new name of at least one dataset is longer than "
2007 "the maximum allowable length"));
2008 (void) zfs_error(hdl
, EZFS_NAMETOOLONG
, desc
);
2011 (void) zpool_standard_error(hdl
, error
, desc
);
2012 zpool_explain_recover(hdl
,
2013 newname
? origname
: thename
, -error
, nv
);
2020 zpool_handle_t
*zhp
;
2023 * This should never fail, but play it safe anyway.
2025 if (zpool_open_silent(hdl
, thename
, &zhp
) != 0)
2027 else if (zhp
!= NULL
)
2029 if (policy
.zlp_rewind
&
2030 (ZPOOL_DO_REWIND
| ZPOOL_TRY_REWIND
)) {
2031 zpool_rewind_exclaim(hdl
, newname
? origname
: thename
,
2032 ((policy
.zlp_rewind
& ZPOOL_TRY_REWIND
) != 0), nv
);
2042 * Translate vdev names to guids. If a vdev_path is determined to be
2043 * unsuitable then a vd_errlist is allocated and the vdev path and errno
2047 zpool_translate_vdev_guids(zpool_handle_t
*zhp
, nvlist_t
*vds
,
2048 nvlist_t
*vdev_guids
, nvlist_t
*guids_to_paths
, nvlist_t
**vd_errlist
)
2050 nvlist_t
*errlist
= NULL
;
2053 for (nvpair_t
*elem
= nvlist_next_nvpair(vds
, NULL
); elem
!= NULL
;
2054 elem
= nvlist_next_nvpair(vds
, elem
)) {
2055 boolean_t spare
, cache
;
2057 char *vd_path
= nvpair_name(elem
);
2058 nvlist_t
*tgt
= zpool_find_vdev(zhp
, vd_path
, &spare
, &cache
,
2061 if ((tgt
== NULL
) || cache
|| spare
) {
2062 if (errlist
== NULL
) {
2063 errlist
= fnvlist_alloc();
2067 uint64_t err
= (tgt
== NULL
) ? EZFS_NODEVICE
:
2068 (spare
? EZFS_ISSPARE
: EZFS_ISL2CACHE
);
2069 fnvlist_add_int64(errlist
, vd_path
, err
);
2073 uint64_t guid
= fnvlist_lookup_uint64(tgt
, ZPOOL_CONFIG_GUID
);
2074 fnvlist_add_uint64(vdev_guids
, vd_path
, guid
);
2076 char msg
[MAXNAMELEN
];
2077 (void) snprintf(msg
, sizeof (msg
), "%llu", (u_longlong_t
)guid
);
2078 fnvlist_add_string(guids_to_paths
, msg
, vd_path
);
2082 verify(errlist
!= NULL
);
2083 if (vd_errlist
!= NULL
)
2084 *vd_errlist
= errlist
;
2086 fnvlist_free(errlist
);
2096 zpool_scan(zpool_handle_t
*zhp
, pool_scan_func_t func
, pool_scrub_cmd_t cmd
)
2098 zfs_cmd_t zc
= { 0 };
2101 libzfs_handle_t
*hdl
= zhp
->zpool_hdl
;
2103 (void) strlcpy(zc
.zc_name
, zhp
->zpool_name
, sizeof (zc
.zc_name
));
2104 zc
.zc_cookie
= func
;
2107 if (zfs_ioctl(hdl
, ZFS_IOC_POOL_SCAN
, &zc
) == 0)
2112 /* ECANCELED on a scrub means we resumed a paused scrub */
2113 if (err
== ECANCELED
&& func
== POOL_SCAN_SCRUB
&&
2114 cmd
== POOL_SCRUB_NORMAL
)
2117 if (err
== ENOENT
&& func
!= POOL_SCAN_NONE
&& cmd
== POOL_SCRUB_NORMAL
)
2120 if (func
== POOL_SCAN_SCRUB
) {
2121 if (cmd
== POOL_SCRUB_PAUSE
) {
2122 (void) snprintf(msg
, sizeof (msg
), dgettext(TEXT_DOMAIN
,
2123 "cannot pause scrubbing %s"), zc
.zc_name
);
2125 assert(cmd
== POOL_SCRUB_NORMAL
);
2126 (void) snprintf(msg
, sizeof (msg
), dgettext(TEXT_DOMAIN
,
2127 "cannot scrub %s"), zc
.zc_name
);
2129 } else if (func
== POOL_SCAN_RESILVER
) {
2130 assert(cmd
== POOL_SCRUB_NORMAL
);
2131 (void) snprintf(msg
, sizeof (msg
), dgettext(TEXT_DOMAIN
,
2132 "cannot restart resilver on %s"), zc
.zc_name
);
2133 } else if (func
== POOL_SCAN_NONE
) {
2134 (void) snprintf(msg
, sizeof (msg
),
2135 dgettext(TEXT_DOMAIN
, "cannot cancel scrubbing %s"),
2138 assert(!"unexpected result");
2143 pool_scan_stat_t
*ps
= NULL
;
2146 verify(nvlist_lookup_nvlist(zhp
->zpool_config
,
2147 ZPOOL_CONFIG_VDEV_TREE
, &nvroot
) == 0);
2148 (void) nvlist_lookup_uint64_array(nvroot
,
2149 ZPOOL_CONFIG_SCAN_STATS
, (uint64_t **)&ps
, &psc
);
2150 if (ps
&& ps
->pss_func
== POOL_SCAN_SCRUB
) {
2151 if (cmd
== POOL_SCRUB_PAUSE
)
2152 return (zfs_error(hdl
, EZFS_SCRUB_PAUSED
, msg
));
2154 return (zfs_error(hdl
, EZFS_SCRUBBING
, msg
));
2156 return (zfs_error(hdl
, EZFS_RESILVERING
, msg
));
2158 } else if (err
== ENOENT
) {
2159 return (zfs_error(hdl
, EZFS_NO_SCRUB
, msg
));
2160 } else if (err
== ENOTSUP
&& func
== POOL_SCAN_RESILVER
) {
2161 return (zfs_error(hdl
, EZFS_NO_RESILVER_DEFER
, msg
));
2163 return (zpool_standard_error(hdl
, err
, msg
));
2168 xlate_init_err(int err
)
2172 return (EZFS_NODEVICE
);
2175 return (EZFS_BADDEV
);
2177 return (EZFS_INITIALIZING
);
2179 return (EZFS_NO_INITIALIZE
);
2185 * Begin, suspend, or cancel the initialization (initializing of all free
2186 * blocks) for the given vdevs in the given pool.
2189 zpool_initialize(zpool_handle_t
*zhp
, pool_initialize_func_t cmd_type
,
2195 nvlist_t
*vdev_guids
= fnvlist_alloc();
2196 nvlist_t
*guids_to_paths
= fnvlist_alloc();
2197 nvlist_t
*vd_errlist
= NULL
;
2201 err
= zpool_translate_vdev_guids(zhp
, vds
, vdev_guids
,
2202 guids_to_paths
, &vd_errlist
);
2205 err
= lzc_initialize(zhp
->zpool_name
, cmd_type
,
2206 vdev_guids
, &errlist
);
2208 fnvlist_free(vdev_guids
);
2209 fnvlist_free(guids_to_paths
);
2213 if (errlist
!= NULL
) {
2214 vd_errlist
= fnvlist_lookup_nvlist(errlist
,
2215 ZPOOL_INITIALIZE_VDEVS
);
2218 (void) snprintf(msg
, sizeof (msg
),
2219 dgettext(TEXT_DOMAIN
, "operation failed"));
2221 verify(vd_errlist
!= NULL
);
2224 for (elem
= nvlist_next_nvpair(vd_errlist
, NULL
); elem
!= NULL
;
2225 elem
= nvlist_next_nvpair(vd_errlist
, elem
)) {
2226 int64_t vd_error
= xlate_init_err(fnvpair_value_int64(elem
));
2229 if (nvlist_lookup_string(guids_to_paths
, nvpair_name(elem
),
2231 path
= nvpair_name(elem
);
2233 (void) zfs_error_fmt(zhp
->zpool_hdl
, vd_error
,
2234 "cannot initialize '%s'", path
);
2237 fnvlist_free(vdev_guids
);
2238 fnvlist_free(guids_to_paths
);
2240 if (vd_errlist
!= NULL
) {
2241 fnvlist_free(vd_errlist
);
2245 return (zpool_standard_error(zhp
->zpool_hdl
, err
, msg
));
2249 xlate_trim_err(int err
)
2253 return (EZFS_NODEVICE
);
2256 return (EZFS_BADDEV
);
2258 return (EZFS_TRIMMING
);
2260 return (EZFS_NO_TRIM
);
2262 return (EZFS_TRIM_NOTSUP
);
2268 * Begin, suspend, or cancel the TRIM (discarding of all free blocks) for
2269 * the given vdevs in the given pool.
2272 zpool_trim(zpool_handle_t
*zhp
, pool_trim_func_t cmd_type
, nvlist_t
*vds
,
2273 trimflags_t
*trim_flags
)
2278 nvlist_t
*vdev_guids
= fnvlist_alloc();
2279 nvlist_t
*guids_to_paths
= fnvlist_alloc();
2280 nvlist_t
*vd_errlist
= NULL
;
2284 err
= zpool_translate_vdev_guids(zhp
, vds
, vdev_guids
,
2285 guids_to_paths
, &vd_errlist
);
2287 err
= lzc_trim(zhp
->zpool_name
, cmd_type
, trim_flags
->rate
,
2288 trim_flags
->secure
, vdev_guids
, &errlist
);
2290 fnvlist_free(vdev_guids
);
2291 fnvlist_free(guids_to_paths
);
2295 if (errlist
!= NULL
) {
2296 vd_errlist
= fnvlist_lookup_nvlist(errlist
,
2300 (void) snprintf(msg
, sizeof (msg
),
2301 dgettext(TEXT_DOMAIN
, "operation failed"));
2303 verify(vd_errlist
!= NULL
);
2306 for (elem
= nvlist_next_nvpair(vd_errlist
, NULL
);
2307 elem
!= NULL
; elem
= nvlist_next_nvpair(vd_errlist
, elem
)) {
2308 int64_t vd_error
= xlate_trim_err(fnvpair_value_int64(elem
));
2311 * If only the pool was specified, and it was not a secure
2312 * trim then suppress warnings for individual vdevs which
2313 * do not support trimming.
2315 if (vd_error
== EZFS_TRIM_NOTSUP
&&
2316 trim_flags
->fullpool
&&
2317 !trim_flags
->secure
) {
2321 if (nvlist_lookup_string(guids_to_paths
, nvpair_name(elem
),
2323 path
= nvpair_name(elem
);
2325 (void) zfs_error_fmt(zhp
->zpool_hdl
, vd_error
,
2326 "cannot trim '%s'", path
);
2329 fnvlist_free(vdev_guids
);
2330 fnvlist_free(guids_to_paths
);
2332 if (vd_errlist
!= NULL
) {
2333 fnvlist_free(vd_errlist
);
2337 return (zpool_standard_error(zhp
->zpool_hdl
, err
, msg
));
2341 * This provides a very minimal check whether a given string is likely a
2342 * c#t#d# style string. Users of this are expected to do their own
2343 * verification of the s# part.
2345 #define CTD_CHECK(str) (str && str[0] == 'c' && isdigit(str[1]))
2348 * More elaborate version for ones which may start with "/dev/dsk/"
2352 ctd_check_path(char *str
)
2355 * If it starts with a slash, check the last component.
2357 if (str
&& str
[0] == '/') {
2358 char *tmp
= strrchr(str
, '/');
2361 * If it ends in "/old", check the second-to-last
2362 * component of the string instead.
2364 if (tmp
!= str
&& strcmp(tmp
, "/old") == 0) {
2365 for (tmp
--; *tmp
!= '/'; tmp
--)
2370 return (CTD_CHECK(str
));
2374 * Find a vdev that matches the search criteria specified. We use the
2375 * the nvpair name to determine how we should look for the device.
2376 * 'avail_spare' is set to TRUE if the provided guid refers to an AVAIL
2377 * spare; but FALSE if its an INUSE spare.
2380 vdev_to_nvlist_iter(nvlist_t
*nv
, nvlist_t
*search
, boolean_t
*avail_spare
,
2381 boolean_t
*l2cache
, boolean_t
*log
)
2388 nvpair_t
*pair
= nvlist_next_nvpair(search
, NULL
);
2390 /* Nothing to look for */
2391 if (search
== NULL
|| pair
== NULL
)
2394 /* Obtain the key we will use to search */
2395 srchkey
= nvpair_name(pair
);
2397 switch (nvpair_type(pair
)) {
2398 case DATA_TYPE_UINT64
:
2399 if (strcmp(srchkey
, ZPOOL_CONFIG_GUID
) == 0) {
2400 uint64_t srchval
, theguid
;
2402 verify(nvpair_value_uint64(pair
, &srchval
) == 0);
2403 verify(nvlist_lookup_uint64(nv
, ZPOOL_CONFIG_GUID
,
2405 if (theguid
== srchval
)
2410 case DATA_TYPE_STRING
: {
2411 char *srchval
, *val
;
2413 verify(nvpair_value_string(pair
, &srchval
) == 0);
2414 if (nvlist_lookup_string(nv
, srchkey
, &val
) != 0)
2418 * Search for the requested value. Special cases:
2420 * - ZPOOL_CONFIG_PATH for whole disk entries. To support
2421 * UEFI boot, these end in "s0" or "s0/old" or "s1" or
2422 * "s1/old". The "s0" or "s1" part is hidden from the user,
2423 * but included in the string, so this matches around it.
2424 * - looking for a top-level vdev name (i.e. ZPOOL_CONFIG_TYPE).
2426 * Otherwise, all other searches are simple string compares.
2428 if (strcmp(srchkey
, ZPOOL_CONFIG_PATH
) == 0 &&
2429 ctd_check_path(val
)) {
2430 uint64_t wholedisk
= 0;
2432 (void) nvlist_lookup_uint64(nv
, ZPOOL_CONFIG_WHOLE_DISK
,
2435 int slen
= strlen(srchval
);
2436 int vlen
= strlen(val
);
2438 if (slen
!= vlen
- 2)
2442 * make_leaf_vdev() should only set
2443 * wholedisk for ZPOOL_CONFIG_PATHs which
2444 * will include "/dev/dsk/", giving plenty of
2445 * room for the indices used next.
2450 * strings identical except trailing "s0"
2452 if ((strcmp(&val
[vlen
- 2], "s0") == 0 ||
2453 strcmp(&val
[vlen
- 2], "s1") == 0) &&
2454 strncmp(srchval
, val
, slen
) == 0)
2458 * strings identical except trailing "s0/old"
2460 if ((strcmp(&val
[vlen
- 6], "s0/old") == 0 ||
2461 strcmp(&val
[vlen
- 6], "s1/old") == 0) &&
2462 strcmp(&srchval
[slen
- 4], "/old") == 0 &&
2463 strncmp(srchval
, val
, slen
- 4) == 0)
2468 } else if (strcmp(srchkey
, ZPOOL_CONFIG_TYPE
) == 0 && val
) {
2469 char *type
, *idx
, *end
, *p
;
2470 uint64_t id
, vdev_id
;
2473 * Determine our vdev type, keeping in mind
2474 * that the srchval is composed of a type and
2475 * vdev id pair (i.e. mirror-4).
2477 if ((type
= strdup(srchval
)) == NULL
)
2480 if ((p
= strrchr(type
, '-')) == NULL
) {
2488 * If the types don't match then keep looking.
2490 if (strncmp(val
, type
, strlen(val
)) != 0) {
2495 verify(zpool_vdev_is_interior(type
));
2496 verify(nvlist_lookup_uint64(nv
, ZPOOL_CONFIG_ID
,
2500 vdev_id
= strtoull(idx
, &end
, 10);
2507 * Now verify that we have the correct vdev id.
2516 if (strcmp(srchval
, val
) == 0)
2525 if (nvlist_lookup_nvlist_array(nv
, ZPOOL_CONFIG_CHILDREN
,
2526 &child
, &children
) != 0)
2529 for (c
= 0; c
< children
; c
++) {
2530 if ((ret
= vdev_to_nvlist_iter(child
[c
], search
,
2531 avail_spare
, l2cache
, NULL
)) != NULL
) {
2533 * The 'is_log' value is only set for the toplevel
2534 * vdev, not the leaf vdevs. So we always lookup the
2535 * log device from the root of the vdev tree (where
2536 * 'log' is non-NULL).
2539 nvlist_lookup_uint64(child
[c
],
2540 ZPOOL_CONFIG_IS_LOG
, &is_log
) == 0 &&
2548 if (nvlist_lookup_nvlist_array(nv
, ZPOOL_CONFIG_SPARES
,
2549 &child
, &children
) == 0) {
2550 for (c
= 0; c
< children
; c
++) {
2551 if ((ret
= vdev_to_nvlist_iter(child
[c
], search
,
2552 avail_spare
, l2cache
, NULL
)) != NULL
) {
2553 *avail_spare
= B_TRUE
;
2559 if (nvlist_lookup_nvlist_array(nv
, ZPOOL_CONFIG_L2CACHE
,
2560 &child
, &children
) == 0) {
2561 for (c
= 0; c
< children
; c
++) {
2562 if ((ret
= vdev_to_nvlist_iter(child
[c
], search
,
2563 avail_spare
, l2cache
, NULL
)) != NULL
) {
2574 * Given a physical path (minus the "/devices" prefix), find the
2578 zpool_find_vdev_by_physpath(zpool_handle_t
*zhp
, const char *ppath
,
2579 boolean_t
*avail_spare
, boolean_t
*l2cache
, boolean_t
*log
)
2581 nvlist_t
*search
, *nvroot
, *ret
;
2583 verify(nvlist_alloc(&search
, NV_UNIQUE_NAME
, KM_SLEEP
) == 0);
2584 verify(nvlist_add_string(search
, ZPOOL_CONFIG_PHYS_PATH
, ppath
) == 0);
2586 verify(nvlist_lookup_nvlist(zhp
->zpool_config
, ZPOOL_CONFIG_VDEV_TREE
,
2589 *avail_spare
= B_FALSE
;
2593 ret
= vdev_to_nvlist_iter(nvroot
, search
, avail_spare
, l2cache
, log
);
2594 nvlist_free(search
);
2600 * Determine if we have an "interior" top-level vdev (i.e mirror/raidz).
2603 zpool_vdev_is_interior(const char *name
)
2605 if (strncmp(name
, VDEV_TYPE_RAIDZ
, strlen(VDEV_TYPE_RAIDZ
)) == 0 ||
2606 strncmp(name
, VDEV_TYPE_SPARE
, strlen(VDEV_TYPE_SPARE
)) == 0 ||
2608 VDEV_TYPE_REPLACING
, strlen(VDEV_TYPE_REPLACING
)) == 0 ||
2609 strncmp(name
, VDEV_TYPE_MIRROR
, strlen(VDEV_TYPE_MIRROR
)) == 0)
2615 zpool_find_vdev(zpool_handle_t
*zhp
, const char *path
, boolean_t
*avail_spare
,
2616 boolean_t
*l2cache
, boolean_t
*log
)
2618 char buf
[MAXPATHLEN
];
2620 nvlist_t
*nvroot
, *search
, *ret
;
2623 verify(nvlist_alloc(&search
, NV_UNIQUE_NAME
, KM_SLEEP
) == 0);
2625 guid
= strtoull(path
, &end
, 10);
2626 if (guid
!= 0 && *end
== '\0') {
2627 verify(nvlist_add_uint64(search
, ZPOOL_CONFIG_GUID
, guid
) == 0);
2628 } else if (zpool_vdev_is_interior(path
)) {
2629 verify(nvlist_add_string(search
, ZPOOL_CONFIG_TYPE
, path
) == 0);
2630 } else if (path
[0] != '/') {
2631 (void) snprintf(buf
, sizeof (buf
), "%s/%s", ZFS_DISK_ROOT
,
2633 verify(nvlist_add_string(search
, ZPOOL_CONFIG_PATH
, buf
) == 0);
2635 verify(nvlist_add_string(search
, ZPOOL_CONFIG_PATH
, path
) == 0);
2638 verify(nvlist_lookup_nvlist(zhp
->zpool_config
, ZPOOL_CONFIG_VDEV_TREE
,
2641 *avail_spare
= B_FALSE
;
2645 ret
= vdev_to_nvlist_iter(nvroot
, search
, avail_spare
, l2cache
, log
);
2646 nvlist_free(search
);
2652 vdev_is_online(nvlist_t
*nv
)
2656 if (nvlist_lookup_uint64(nv
, ZPOOL_CONFIG_OFFLINE
, &ival
) == 0 ||
2657 nvlist_lookup_uint64(nv
, ZPOOL_CONFIG_FAULTED
, &ival
) == 0 ||
2658 nvlist_lookup_uint64(nv
, ZPOOL_CONFIG_REMOVED
, &ival
) == 0)
2665 * Helper function for zpool_get_physpaths().
2668 vdev_get_one_physpath(nvlist_t
*config
, char *physpath
, size_t physpath_size
,
2669 size_t *bytes_written
)
2671 size_t bytes_left
, pos
, rsz
;
2675 if (nvlist_lookup_string(config
, ZPOOL_CONFIG_PHYS_PATH
,
2677 return (EZFS_NODEVICE
);
2679 pos
= *bytes_written
;
2680 bytes_left
= physpath_size
- pos
;
2681 format
= (pos
== 0) ? "%s" : " %s";
2683 rsz
= snprintf(physpath
+ pos
, bytes_left
, format
, tmppath
);
2684 *bytes_written
+= rsz
;
2686 if (rsz
>= bytes_left
) {
2687 /* if physpath was not copied properly, clear it */
2688 if (bytes_left
!= 0) {
2691 return (EZFS_NOSPC
);
2697 vdev_get_physpaths(nvlist_t
*nv
, char *physpath
, size_t phypath_size
,
2698 size_t *rsz
, boolean_t is_spare
)
2703 if (nvlist_lookup_string(nv
, ZPOOL_CONFIG_TYPE
, &type
) != 0)
2704 return (EZFS_INVALCONFIG
);
2706 if (strcmp(type
, VDEV_TYPE_DISK
) == 0) {
2708 * An active spare device has ZPOOL_CONFIG_IS_SPARE set.
2709 * For a spare vdev, we only want to boot from the active
2714 (void) nvlist_lookup_uint64(nv
, ZPOOL_CONFIG_IS_SPARE
,
2717 return (EZFS_INVALCONFIG
);
2720 if (vdev_is_online(nv
)) {
2721 if ((ret
= vdev_get_one_physpath(nv
, physpath
,
2722 phypath_size
, rsz
)) != 0)
2725 } else if (strcmp(type
, VDEV_TYPE_MIRROR
) == 0 ||
2726 strcmp(type
, VDEV_TYPE_RAIDZ
) == 0 ||
2727 strcmp(type
, VDEV_TYPE_REPLACING
) == 0 ||
2728 (is_spare
= (strcmp(type
, VDEV_TYPE_SPARE
) == 0))) {
2733 if (nvlist_lookup_nvlist_array(nv
,
2734 ZPOOL_CONFIG_CHILDREN
, &child
, &count
) != 0)
2735 return (EZFS_INVALCONFIG
);
2737 for (i
= 0; i
< count
; i
++) {
2738 ret
= vdev_get_physpaths(child
[i
], physpath
,
2739 phypath_size
, rsz
, is_spare
);
2740 if (ret
== EZFS_NOSPC
)
2745 return (EZFS_POOL_INVALARG
);
2749 * Get phys_path for a root pool config.
2750 * Return 0 on success; non-zero on failure.
2753 zpool_get_config_physpath(nvlist_t
*config
, char *physpath
, size_t phypath_size
)
2756 nvlist_t
*vdev_root
;
2763 if (nvlist_lookup_nvlist(config
, ZPOOL_CONFIG_VDEV_TREE
,
2765 return (EZFS_INVALCONFIG
);
2767 if (nvlist_lookup_string(vdev_root
, ZPOOL_CONFIG_TYPE
, &type
) != 0 ||
2768 nvlist_lookup_nvlist_array(vdev_root
, ZPOOL_CONFIG_CHILDREN
,
2769 &child
, &count
) != 0)
2770 return (EZFS_INVALCONFIG
);
2773 * root pool can only have a single top-level vdev.
2775 if (strcmp(type
, VDEV_TYPE_ROOT
) != 0 || count
!= 1)
2776 return (EZFS_POOL_INVALARG
);
2778 (void) vdev_get_physpaths(child
[0], physpath
, phypath_size
, &rsz
,
2781 /* No online devices */
2783 return (EZFS_NODEVICE
);
2789 * Get phys_path for a root pool
2790 * Return 0 on success; non-zero on failure.
2793 zpool_get_physpath(zpool_handle_t
*zhp
, char *physpath
, size_t phypath_size
)
2795 return (zpool_get_config_physpath(zhp
->zpool_config
, physpath
,
2800 * If the device has being dynamically expanded then we need to relabel
2801 * the disk to use the new unallocated space.
2804 zpool_relabel_disk(libzfs_handle_t
*hdl
, const char *name
, const char *msg
)
2806 char path
[MAXPATHLEN
];
2808 int (*_efi_use_whole_disk
)(int);
2809 char drv
[MODMAXNAMELEN
];
2813 if ((_efi_use_whole_disk
= (int (*)(int))dlsym(RTLD_DEFAULT
,
2814 "efi_use_whole_disk")) == NULL
)
2817 (void) snprintf(path
, sizeof (path
), "%s/%s", ZFS_RDISK_ROOT
, name
);
2819 if ((fd
= open(path
, O_RDWR
| O_NDELAY
)) < 0) {
2820 zfs_error_aux(hdl
, dgettext(TEXT_DOMAIN
, "cannot "
2821 "relabel '%s': unable to open device"), name
);
2822 return (zfs_error(hdl
, EZFS_OPENFAILED
, msg
));
2826 * It's possible that we might encounter an error if the device
2827 * does not have any unallocated space left. If so, we simply
2828 * ignore that error and continue on.
2830 error
= _efi_use_whole_disk(fd
);
2831 if (error
&& error
!= VT_ENOSPC
) {
2833 zfs_error_aux(hdl
, dgettext(TEXT_DOMAIN
, "cannot "
2834 "relabel '%s': unable to read disk capacity"), name
);
2835 return (zfs_error(hdl
, EZFS_NOCAP
, msg
));
2839 * Writing a new EFI partition table to the disk will have marked
2840 * the geometry as needing re-validation. Before returning, force
2841 * it to be checked by querying the device state, otherwise the
2842 * subsequent vdev_reopen() will very likely fail to read the device
2843 * size, faulting the pool.
2845 * The dkio(4I) ioctls are implemented by the disk driver rather than
2846 * some generic framework, so we limit its use here to drivers with
2847 * which it has been tested.
2849 if (fstat(fd
, &st
) == 0 &&
2850 (maj
= major(st
.st_rdev
)) != (major_t
)NODEV
&&
2851 modctl(MODGETNAME
, drv
, sizeof (drv
), &maj
) == 0 &&
2852 (strcmp(drv
, "blkdev") == 0 || strcmp(drv
, "sd") == 0)) {
2853 enum dkio_state dkst
= DKIO_NONE
;
2854 (void) ioctl(fd
, DKIOCSTATE
, &dkst
);
2863 * Bring the specified vdev online. The 'flags' parameter is a set of the
2864 * ZFS_ONLINE_* flags.
2867 zpool_vdev_online(zpool_handle_t
*zhp
, const char *path
, int flags
,
2868 vdev_state_t
*newstate
)
2870 zfs_cmd_t zc
= { 0 };
2874 boolean_t avail_spare
, l2cache
, islog
;
2875 libzfs_handle_t
*hdl
= zhp
->zpool_hdl
;
2878 if (flags
& ZFS_ONLINE_EXPAND
) {
2879 (void) snprintf(msg
, sizeof (msg
),
2880 dgettext(TEXT_DOMAIN
, "cannot expand %s"), path
);
2882 (void) snprintf(msg
, sizeof (msg
),
2883 dgettext(TEXT_DOMAIN
, "cannot online %s"), path
);
2886 (void) strlcpy(zc
.zc_name
, zhp
->zpool_name
, sizeof (zc
.zc_name
));
2887 if ((tgt
= zpool_find_vdev(zhp
, path
, &avail_spare
, &l2cache
,
2889 return (zfs_error(hdl
, EZFS_NODEVICE
, msg
));
2891 verify(nvlist_lookup_uint64(tgt
, ZPOOL_CONFIG_GUID
, &zc
.zc_guid
) == 0);
2894 return (zfs_error(hdl
, EZFS_ISSPARE
, msg
));
2896 if ((flags
& ZFS_ONLINE_EXPAND
||
2897 zpool_get_prop_int(zhp
, ZPOOL_PROP_AUTOEXPAND
, NULL
)) &&
2898 nvlist_lookup_string(tgt
, ZPOOL_CONFIG_PATH
, &pathname
) == 0) {
2899 uint64_t wholedisk
= 0;
2901 (void) nvlist_lookup_uint64(tgt
, ZPOOL_CONFIG_WHOLE_DISK
,
2905 * XXX - L2ARC 1.0 devices can't support expansion.
2908 zfs_error_aux(hdl
, dgettext(TEXT_DOMAIN
,
2909 "cannot expand cache devices"));
2910 return (zfs_error(hdl
, EZFS_VDEVNOTSUP
, msg
));
2914 pathname
+= strlen(ZFS_DISK_ROOT
) + 1;
2915 error
= zpool_relabel_disk(hdl
, pathname
, msg
);
2921 zc
.zc_cookie
= VDEV_STATE_ONLINE
;
2924 if (zfs_ioctl(hdl
, ZFS_IOC_VDEV_SET_STATE
, &zc
) != 0) {
2925 if (errno
== EINVAL
) {
2926 zfs_error_aux(hdl
, dgettext(TEXT_DOMAIN
, "was split "
2927 "from this pool into a new one. Use '%s' "
2928 "instead"), "zpool detach");
2929 return (zfs_error(hdl
, EZFS_POSTSPLIT_ONLINE
, msg
));
2931 return (zpool_standard_error(hdl
, errno
, msg
));
2934 *newstate
= zc
.zc_cookie
;
2939 * Take the specified vdev offline
2942 zpool_vdev_offline(zpool_handle_t
*zhp
, const char *path
, boolean_t istmp
)
2944 zfs_cmd_t zc
= { 0 };
2947 boolean_t avail_spare
, l2cache
;
2948 libzfs_handle_t
*hdl
= zhp
->zpool_hdl
;
2950 (void) snprintf(msg
, sizeof (msg
),
2951 dgettext(TEXT_DOMAIN
, "cannot offline %s"), path
);
2953 (void) strlcpy(zc
.zc_name
, zhp
->zpool_name
, sizeof (zc
.zc_name
));
2954 if ((tgt
= zpool_find_vdev(zhp
, path
, &avail_spare
, &l2cache
,
2956 return (zfs_error(hdl
, EZFS_NODEVICE
, msg
));
2958 verify(nvlist_lookup_uint64(tgt
, ZPOOL_CONFIG_GUID
, &zc
.zc_guid
) == 0);
2961 return (zfs_error(hdl
, EZFS_ISSPARE
, msg
));
2963 zc
.zc_cookie
= VDEV_STATE_OFFLINE
;
2964 zc
.zc_obj
= istmp
? ZFS_OFFLINE_TEMPORARY
: 0;
2966 if (zfs_ioctl(hdl
, ZFS_IOC_VDEV_SET_STATE
, &zc
) == 0)
2973 * There are no other replicas of this device.
2975 return (zfs_error(hdl
, EZFS_NOREPLICAS
, msg
));
2979 * The log device has unplayed logs
2981 return (zfs_error(hdl
, EZFS_UNPLAYED_LOGS
, msg
));
2984 return (zpool_standard_error(hdl
, errno
, msg
));
2989 * Mark the given vdev faulted.
2992 zpool_vdev_fault(zpool_handle_t
*zhp
, uint64_t guid
, vdev_aux_t aux
)
2994 zfs_cmd_t zc
= { 0 };
2996 libzfs_handle_t
*hdl
= zhp
->zpool_hdl
;
2998 (void) snprintf(msg
, sizeof (msg
),
2999 dgettext(TEXT_DOMAIN
, "cannot fault %llu"), guid
);
3001 (void) strlcpy(zc
.zc_name
, zhp
->zpool_name
, sizeof (zc
.zc_name
));
3003 zc
.zc_cookie
= VDEV_STATE_FAULTED
;
3006 if (ioctl(hdl
->libzfs_fd
, ZFS_IOC_VDEV_SET_STATE
, &zc
) == 0)
3013 * There are no other replicas of this device.
3015 return (zfs_error(hdl
, EZFS_NOREPLICAS
, msg
));
3018 return (zpool_standard_error(hdl
, errno
, msg
));
3024 * Mark the given vdev degraded.
3027 zpool_vdev_degrade(zpool_handle_t
*zhp
, uint64_t guid
, vdev_aux_t aux
)
3029 zfs_cmd_t zc
= { 0 };
3031 libzfs_handle_t
*hdl
= zhp
->zpool_hdl
;
3033 (void) snprintf(msg
, sizeof (msg
),
3034 dgettext(TEXT_DOMAIN
, "cannot degrade %llu"), guid
);
3036 (void) strlcpy(zc
.zc_name
, zhp
->zpool_name
, sizeof (zc
.zc_name
));
3038 zc
.zc_cookie
= VDEV_STATE_DEGRADED
;
3041 if (ioctl(hdl
->libzfs_fd
, ZFS_IOC_VDEV_SET_STATE
, &zc
) == 0)
3044 return (zpool_standard_error(hdl
, errno
, msg
));
3048 * Returns TRUE if the given nvlist is a vdev that was originally swapped in as
3052 is_replacing_spare(nvlist_t
*search
, nvlist_t
*tgt
, int which
)
3058 if (nvlist_lookup_nvlist_array(search
, ZPOOL_CONFIG_CHILDREN
, &child
,
3060 verify(nvlist_lookup_string(search
, ZPOOL_CONFIG_TYPE
,
3063 if (strcmp(type
, VDEV_TYPE_SPARE
) == 0 &&
3064 children
== 2 && child
[which
] == tgt
)
3067 for (c
= 0; c
< children
; c
++)
3068 if (is_replacing_spare(child
[c
], tgt
, which
))
3076 * Attach new_disk (fully described by nvroot) to old_disk.
3077 * If 'replacing' is specified, the new disk will replace the old one.
3080 zpool_vdev_attach(zpool_handle_t
*zhp
,
3081 const char *old_disk
, const char *new_disk
, nvlist_t
*nvroot
, int replacing
)
3083 zfs_cmd_t zc
= { 0 };
3086 nvlist_t
*tgt
, *newvd
;
3087 boolean_t avail_spare
, l2cache
, islog
;
3092 nvlist_t
*config_root
;
3093 libzfs_handle_t
*hdl
= zhp
->zpool_hdl
;
3094 boolean_t rootpool
= zpool_is_bootable(zhp
);
3097 (void) snprintf(msg
, sizeof (msg
), dgettext(TEXT_DOMAIN
,
3098 "cannot replace %s with %s"), old_disk
, new_disk
);
3100 (void) snprintf(msg
, sizeof (msg
), dgettext(TEXT_DOMAIN
,
3101 "cannot attach %s to %s"), new_disk
, old_disk
);
3103 (void) strlcpy(zc
.zc_name
, zhp
->zpool_name
, sizeof (zc
.zc_name
));
3104 if ((tgt
= zpool_find_vdev(zhp
, old_disk
, &avail_spare
, &l2cache
,
3106 return (zfs_error(hdl
, EZFS_NODEVICE
, msg
));
3109 return (zfs_error(hdl
, EZFS_ISSPARE
, msg
));
3112 return (zfs_error(hdl
, EZFS_ISL2CACHE
, msg
));
3114 verify(nvlist_lookup_uint64(tgt
, ZPOOL_CONFIG_GUID
, &zc
.zc_guid
) == 0);
3115 zc
.zc_cookie
= replacing
;
3117 if (nvlist_lookup_nvlist_array(nvroot
, ZPOOL_CONFIG_CHILDREN
,
3118 &child
, &children
) != 0 || children
!= 1) {
3119 zfs_error_aux(hdl
, dgettext(TEXT_DOMAIN
,
3120 "new device must be a single disk"));
3121 return (zfs_error(hdl
, EZFS_INVALCONFIG
, msg
));
3124 verify(nvlist_lookup_nvlist(zpool_get_config(zhp
, NULL
),
3125 ZPOOL_CONFIG_VDEV_TREE
, &config_root
) == 0);
3127 if ((newname
= zpool_vdev_name(NULL
, NULL
, child
[0], 0)) == NULL
)
3130 newvd
= zpool_find_vdev(zhp
, newname
, &avail_spare
, &l2cache
, NULL
);
3132 * If the target is a hot spare that has been swapped in, we can only
3133 * replace it with another hot spare.
3136 nvlist_lookup_uint64(tgt
, ZPOOL_CONFIG_IS_SPARE
, &val
) == 0 &&
3137 (newvd
== NULL
|| !avail_spare
) &&
3138 is_replacing_spare(config_root
, tgt
, 1)) {
3139 zfs_error_aux(hdl
, dgettext(TEXT_DOMAIN
,
3140 "can only be replaced by another hot spare"));
3142 return (zfs_error(hdl
, EZFS_BADTARGET
, msg
));
3147 if (replacing
&& avail_spare
&& !vdev_is_online(newvd
)) {
3148 (void) zpool_standard_error(hdl
, ENXIO
, msg
);
3152 if (zcmd_write_conf_nvlist(hdl
, &zc
, nvroot
) != 0)
3155 ret
= zfs_ioctl(hdl
, ZFS_IOC_VDEV_ATTACH
, &zc
);
3157 zcmd_free_nvlists(&zc
);
3162 * XXX need a better way to prevent user from
3163 * booting up a half-baked vdev.
3165 (void) fprintf(stderr
, dgettext(TEXT_DOMAIN
, "Make "
3166 "sure to wait until resilver is done "
3167 "before rebooting.\n"));
3175 * Can't attach to or replace this type of vdev.
3178 uint64_t version
= zpool_get_prop_int(zhp
,
3179 ZPOOL_PROP_VERSION
, NULL
);
3182 zfs_error_aux(hdl
, dgettext(TEXT_DOMAIN
,
3183 "cannot replace a log with a spare"));
3184 else if (version
>= SPA_VERSION_MULTI_REPLACE
)
3185 zfs_error_aux(hdl
, dgettext(TEXT_DOMAIN
,
3186 "already in replacing/spare config; wait "
3187 "for completion or use 'zpool detach'"));
3189 zfs_error_aux(hdl
, dgettext(TEXT_DOMAIN
,
3190 "cannot replace a replacing device"));
3192 zfs_error_aux(hdl
, dgettext(TEXT_DOMAIN
,
3193 "can only attach to mirrors and top-level "
3196 (void) zfs_error(hdl
, EZFS_BADTARGET
, msg
);
3201 * The new device must be a single disk.
3203 zfs_error_aux(hdl
, dgettext(TEXT_DOMAIN
,
3204 "new device must be a single disk"));
3205 (void) zfs_error(hdl
, EZFS_INVALCONFIG
, msg
);
3209 zfs_error_aux(hdl
, dgettext(TEXT_DOMAIN
, "%s is busy, "
3210 "or device removal is in progress"),
3212 (void) zfs_error(hdl
, EZFS_BADDEV
, msg
);
3217 * The new device is too small.
3219 zfs_error_aux(hdl
, dgettext(TEXT_DOMAIN
,
3220 "device is too small"));
3221 (void) zfs_error(hdl
, EZFS_BADDEV
, msg
);
3226 * The new device has a different optimal sector size.
3228 zfs_error_aux(hdl
, dgettext(TEXT_DOMAIN
,
3229 "new device has a different optimal sector size; use the "
3230 "option '-o ashift=N' to override the optimal size"));
3231 (void) zfs_error(hdl
, EZFS_BADDEV
, msg
);
3236 * The resulting top-level vdev spec won't fit in the label.
3238 (void) zfs_error(hdl
, EZFS_DEVOVERFLOW
, msg
);
3242 (void) zpool_standard_error(hdl
, errno
, msg
);
3249 * Detach the specified device.
3252 zpool_vdev_detach(zpool_handle_t
*zhp
, const char *path
)
3254 zfs_cmd_t zc
= { 0 };
3257 boolean_t avail_spare
, l2cache
;
3258 libzfs_handle_t
*hdl
= zhp
->zpool_hdl
;
3260 (void) snprintf(msg
, sizeof (msg
),
3261 dgettext(TEXT_DOMAIN
, "cannot detach %s"), path
);
3263 (void) strlcpy(zc
.zc_name
, zhp
->zpool_name
, sizeof (zc
.zc_name
));
3264 if ((tgt
= zpool_find_vdev(zhp
, path
, &avail_spare
, &l2cache
,
3266 return (zfs_error(hdl
, EZFS_NODEVICE
, msg
));
3269 return (zfs_error(hdl
, EZFS_ISSPARE
, msg
));
3272 return (zfs_error(hdl
, EZFS_ISL2CACHE
, msg
));
3274 verify(nvlist_lookup_uint64(tgt
, ZPOOL_CONFIG_GUID
, &zc
.zc_guid
) == 0);
3276 if (zfs_ioctl(hdl
, ZFS_IOC_VDEV_DETACH
, &zc
) == 0)
3283 * Can't detach from this type of vdev.
3285 zfs_error_aux(hdl
, dgettext(TEXT_DOMAIN
, "only "
3286 "applicable to mirror and replacing vdevs"));
3287 (void) zfs_error(hdl
, EZFS_BADTARGET
, msg
);
3292 * There are no other replicas of this device.
3294 (void) zfs_error(hdl
, EZFS_NOREPLICAS
, msg
);
3298 (void) zpool_standard_error(hdl
, errno
, msg
);
3305 * Find a mirror vdev in the source nvlist.
3307 * The mchild array contains a list of disks in one of the top-level mirrors
3308 * of the source pool. The schild array contains a list of disks that the
3309 * user specified on the command line. We loop over the mchild array to
3310 * see if any entry in the schild array matches.
3312 * If a disk in the mchild array is found in the schild array, we return
3313 * the index of that entry. Otherwise we return -1.
3316 find_vdev_entry(zpool_handle_t
*zhp
, nvlist_t
**mchild
, uint_t mchildren
,
3317 nvlist_t
**schild
, uint_t schildren
)
3321 for (mc
= 0; mc
< mchildren
; mc
++) {
3323 char *mpath
= zpool_vdev_name(zhp
->zpool_hdl
, zhp
,
3326 for (sc
= 0; sc
< schildren
; sc
++) {
3327 char *spath
= zpool_vdev_name(zhp
->zpool_hdl
, zhp
,
3329 boolean_t result
= (strcmp(mpath
, spath
) == 0);
3345 * Split a mirror pool. If newroot points to null, then a new nvlist
3346 * is generated and it is the responsibility of the caller to free it.
3349 zpool_vdev_split(zpool_handle_t
*zhp
, char *newname
, nvlist_t
**newroot
,
3350 nvlist_t
*props
, splitflags_t flags
)
3352 zfs_cmd_t zc
= { 0 };
3354 nvlist_t
*tree
, *config
, **child
, **newchild
, *newconfig
= NULL
;
3355 nvlist_t
**varray
= NULL
, *zc_props
= NULL
;
3356 uint_t c
, children
, newchildren
, lastlog
= 0, vcount
, found
= 0;
3357 libzfs_handle_t
*hdl
= zhp
->zpool_hdl
;
3359 boolean_t freelist
= B_FALSE
, memory_err
= B_TRUE
;
3362 (void) snprintf(msg
, sizeof (msg
),
3363 dgettext(TEXT_DOMAIN
, "Unable to split %s"), zhp
->zpool_name
);
3365 if (!zpool_name_valid(hdl
, B_FALSE
, newname
))
3366 return (zfs_error(hdl
, EZFS_INVALIDNAME
, msg
));
3368 if ((config
= zpool_get_config(zhp
, NULL
)) == NULL
) {
3369 (void) fprintf(stderr
, gettext("Internal error: unable to "
3370 "retrieve pool configuration\n"));
3374 verify(nvlist_lookup_nvlist(config
, ZPOOL_CONFIG_VDEV_TREE
, &tree
)
3376 verify(nvlist_lookup_uint64(config
, ZPOOL_CONFIG_VERSION
, &vers
) == 0);
3379 prop_flags_t flags
= { .create
= B_FALSE
, .import
= B_TRUE
};
3380 if ((zc_props
= zpool_valid_proplist(hdl
, zhp
->zpool_name
,
3381 props
, vers
, flags
, msg
)) == NULL
)
3385 if (nvlist_lookup_nvlist_array(tree
, ZPOOL_CONFIG_CHILDREN
, &child
,
3387 zfs_error_aux(hdl
, dgettext(TEXT_DOMAIN
,
3388 "Source pool is missing vdev tree"));
3389 nvlist_free(zc_props
);
3393 varray
= zfs_alloc(hdl
, children
* sizeof (nvlist_t
*));
3396 if (*newroot
== NULL
||
3397 nvlist_lookup_nvlist_array(*newroot
, ZPOOL_CONFIG_CHILDREN
,
3398 &newchild
, &newchildren
) != 0)
3401 for (c
= 0; c
< children
; c
++) {
3402 uint64_t is_log
= B_FALSE
, is_hole
= B_FALSE
;
3404 nvlist_t
**mchild
, *vdev
;
3409 * Unlike cache & spares, slogs are stored in the
3410 * ZPOOL_CONFIG_CHILDREN array. We filter them out here.
3412 (void) nvlist_lookup_uint64(child
[c
], ZPOOL_CONFIG_IS_LOG
,
3414 (void) nvlist_lookup_uint64(child
[c
], ZPOOL_CONFIG_IS_HOLE
,
3416 if (is_log
|| is_hole
) {
3418 * Create a hole vdev and put it in the config.
3420 if (nvlist_alloc(&vdev
, NV_UNIQUE_NAME
, 0) != 0)
3422 if (nvlist_add_string(vdev
, ZPOOL_CONFIG_TYPE
,
3423 VDEV_TYPE_HOLE
) != 0)
3425 if (nvlist_add_uint64(vdev
, ZPOOL_CONFIG_IS_HOLE
,
3430 varray
[vcount
++] = vdev
;
3434 verify(nvlist_lookup_string(child
[c
], ZPOOL_CONFIG_TYPE
, &type
)
3436 if (strcmp(type
, VDEV_TYPE_MIRROR
) != 0) {
3437 zfs_error_aux(hdl
, dgettext(TEXT_DOMAIN
,
3438 "Source pool must be composed only of mirrors\n"));
3439 retval
= zfs_error(hdl
, EZFS_INVALCONFIG
, msg
);
3443 verify(nvlist_lookup_nvlist_array(child
[c
],
3444 ZPOOL_CONFIG_CHILDREN
, &mchild
, &mchildren
) == 0);
3446 /* find or add an entry for this top-level vdev */
3447 if (newchildren
> 0 &&
3448 (entry
= find_vdev_entry(zhp
, mchild
, mchildren
,
3449 newchild
, newchildren
)) >= 0) {
3450 /* We found a disk that the user specified. */
3451 vdev
= mchild
[entry
];
3454 /* User didn't specify a disk for this vdev. */
3455 vdev
= mchild
[mchildren
- 1];
3458 if (nvlist_dup(vdev
, &varray
[vcount
++], 0) != 0)
3462 /* did we find every disk the user specified? */
3463 if (found
!= newchildren
) {
3464 zfs_error_aux(hdl
, dgettext(TEXT_DOMAIN
, "Device list must "
3465 "include at most one disk from each mirror"));
3466 retval
= zfs_error(hdl
, EZFS_INVALCONFIG
, msg
);
3470 /* Prepare the nvlist for populating. */
3471 if (*newroot
== NULL
) {
3472 if (nvlist_alloc(newroot
, NV_UNIQUE_NAME
, 0) != 0)
3475 if (nvlist_add_string(*newroot
, ZPOOL_CONFIG_TYPE
,
3476 VDEV_TYPE_ROOT
) != 0)
3479 verify(nvlist_remove_all(*newroot
, ZPOOL_CONFIG_CHILDREN
) == 0);
3482 /* Add all the children we found */
3483 if (nvlist_add_nvlist_array(*newroot
, ZPOOL_CONFIG_CHILDREN
, varray
,
3484 lastlog
== 0 ? vcount
: lastlog
) != 0)
3488 * If we're just doing a dry run, exit now with success.
3491 memory_err
= B_FALSE
;
3496 /* now build up the config list & call the ioctl */
3497 if (nvlist_alloc(&newconfig
, NV_UNIQUE_NAME
, 0) != 0)
3500 if (nvlist_add_nvlist(newconfig
,
3501 ZPOOL_CONFIG_VDEV_TREE
, *newroot
) != 0 ||
3502 nvlist_add_string(newconfig
,
3503 ZPOOL_CONFIG_POOL_NAME
, newname
) != 0 ||
3504 nvlist_add_uint64(newconfig
, ZPOOL_CONFIG_VERSION
, vers
) != 0)
3508 * The new pool is automatically part of the namespace unless we
3509 * explicitly export it.
3512 zc
.zc_cookie
= ZPOOL_EXPORT_AFTER_SPLIT
;
3513 (void) strlcpy(zc
.zc_name
, zhp
->zpool_name
, sizeof (zc
.zc_name
));
3514 (void) strlcpy(zc
.zc_string
, newname
, sizeof (zc
.zc_string
));
3515 if (zcmd_write_conf_nvlist(hdl
, &zc
, newconfig
) != 0)
3517 if (zc_props
!= NULL
&& zcmd_write_src_nvlist(hdl
, &zc
, zc_props
) != 0)
3520 if (zfs_ioctl(hdl
, ZFS_IOC_VDEV_SPLIT
, &zc
) != 0) {
3521 retval
= zpool_standard_error(hdl
, errno
, msg
);
3526 memory_err
= B_FALSE
;
3529 if (varray
!= NULL
) {
3532 for (v
= 0; v
< vcount
; v
++)
3533 nvlist_free(varray
[v
]);
3536 zcmd_free_nvlists(&zc
);
3537 nvlist_free(zc_props
);
3538 nvlist_free(newconfig
);
3540 nvlist_free(*newroot
);
3548 return (no_memory(hdl
));
3554 * Remove the given device.
3557 zpool_vdev_remove(zpool_handle_t
*zhp
, const char *path
)
3559 zfs_cmd_t zc
= { 0 };
3562 boolean_t avail_spare
, l2cache
, islog
;
3563 libzfs_handle_t
*hdl
= zhp
->zpool_hdl
;
3566 (void) snprintf(msg
, sizeof (msg
),
3567 dgettext(TEXT_DOMAIN
, "cannot remove %s"), path
);
3569 (void) strlcpy(zc
.zc_name
, zhp
->zpool_name
, sizeof (zc
.zc_name
));
3570 if ((tgt
= zpool_find_vdev(zhp
, path
, &avail_spare
, &l2cache
,
3572 return (zfs_error(hdl
, EZFS_NODEVICE
, msg
));
3574 version
= zpool_get_prop_int(zhp
, ZPOOL_PROP_VERSION
, NULL
);
3575 if (islog
&& version
< SPA_VERSION_HOLES
) {
3576 zfs_error_aux(hdl
, dgettext(TEXT_DOMAIN
,
3577 "pool must be upgraded to support log removal"));
3578 return (zfs_error(hdl
, EZFS_BADVERSION
, msg
));
3581 zc
.zc_guid
= fnvlist_lookup_uint64(tgt
, ZPOOL_CONFIG_GUID
);
3583 if (zfs_ioctl(hdl
, ZFS_IOC_VDEV_REMOVE
, &zc
) == 0)
3589 zfs_error_aux(hdl
, dgettext(TEXT_DOMAIN
,
3590 "invalid config; all top-level vdevs must "
3591 "have the same sector size and not be raidz."));
3592 (void) zfs_error(hdl
, EZFS_INVALCONFIG
, msg
);
3596 zfs_error_aux(hdl
, dgettext(TEXT_DOMAIN
,
3597 "Pool busy; removal may already be in progress"));
3598 (void) zfs_error(hdl
, EZFS_BUSY
, msg
);
3602 (void) zpool_standard_error(hdl
, errno
, msg
);
3608 zpool_vdev_remove_cancel(zpool_handle_t
*zhp
)
3610 zfs_cmd_t zc
= { 0 };
3612 libzfs_handle_t
*hdl
= zhp
->zpool_hdl
;
3614 (void) snprintf(msg
, sizeof (msg
),
3615 dgettext(TEXT_DOMAIN
, "cannot cancel removal"));
3617 (void) strlcpy(zc
.zc_name
, zhp
->zpool_name
, sizeof (zc
.zc_name
));
3620 if (zfs_ioctl(hdl
, ZFS_IOC_VDEV_REMOVE
, &zc
) == 0)
3623 return (zpool_standard_error(hdl
, errno
, msg
));
3627 zpool_vdev_indirect_size(zpool_handle_t
*zhp
, const char *path
,
3632 boolean_t avail_spare
, l2cache
, islog
;
3633 libzfs_handle_t
*hdl
= zhp
->zpool_hdl
;
3635 (void) snprintf(msg
, sizeof (msg
),
3636 dgettext(TEXT_DOMAIN
, "cannot determine indirect size of %s"),
3639 if ((tgt
= zpool_find_vdev(zhp
, path
, &avail_spare
, &l2cache
,
3641 return (zfs_error(hdl
, EZFS_NODEVICE
, msg
));
3643 if (avail_spare
|| l2cache
|| islog
) {
3648 if (nvlist_lookup_uint64(tgt
, ZPOOL_CONFIG_INDIRECT_SIZE
, sizep
) != 0) {
3649 zfs_error_aux(hdl
, dgettext(TEXT_DOMAIN
,
3650 "indirect size not available"));
3651 return (zfs_error(hdl
, EINVAL
, msg
));
3657 * Clear the errors for the pool, or the particular device if specified.
3660 zpool_clear(zpool_handle_t
*zhp
, const char *path
, nvlist_t
*rewindnvl
)
3662 zfs_cmd_t zc
= { 0 };
3665 zpool_load_policy_t policy
;
3666 boolean_t avail_spare
, l2cache
;
3667 libzfs_handle_t
*hdl
= zhp
->zpool_hdl
;
3668 nvlist_t
*nvi
= NULL
;
3672 (void) snprintf(msg
, sizeof (msg
),
3673 dgettext(TEXT_DOMAIN
, "cannot clear errors for %s"),
3676 (void) snprintf(msg
, sizeof (msg
),
3677 dgettext(TEXT_DOMAIN
, "cannot clear errors for %s"),
3680 (void) strlcpy(zc
.zc_name
, zhp
->zpool_name
, sizeof (zc
.zc_name
));
3682 if ((tgt
= zpool_find_vdev(zhp
, path
, &avail_spare
,
3683 &l2cache
, NULL
)) == NULL
)
3684 return (zfs_error(hdl
, EZFS_NODEVICE
, msg
));
3687 * Don't allow error clearing for hot spares. Do allow
3688 * error clearing for l2cache devices.
3691 return (zfs_error(hdl
, EZFS_ISSPARE
, msg
));
3693 verify(nvlist_lookup_uint64(tgt
, ZPOOL_CONFIG_GUID
,
3697 zpool_get_load_policy(rewindnvl
, &policy
);
3698 zc
.zc_cookie
= policy
.zlp_rewind
;
3700 if (zcmd_alloc_dst_nvlist(hdl
, &zc
, zhp
->zpool_config_size
* 2) != 0)
3703 if (zcmd_write_src_nvlist(hdl
, &zc
, rewindnvl
) != 0)
3706 while ((error
= zfs_ioctl(hdl
, ZFS_IOC_CLEAR
, &zc
)) != 0 &&
3708 if (zcmd_expand_dst_nvlist(hdl
, &zc
) != 0) {
3709 zcmd_free_nvlists(&zc
);
3714 if (!error
|| ((policy
.zlp_rewind
& ZPOOL_TRY_REWIND
) &&
3715 errno
!= EPERM
&& errno
!= EACCES
)) {
3716 if (policy
.zlp_rewind
&
3717 (ZPOOL_DO_REWIND
| ZPOOL_TRY_REWIND
)) {
3718 (void) zcmd_read_dst_nvlist(hdl
, &zc
, &nvi
);
3719 zpool_rewind_exclaim(hdl
, zc
.zc_name
,
3720 ((policy
.zlp_rewind
& ZPOOL_TRY_REWIND
) != 0),
3724 zcmd_free_nvlists(&zc
);
3728 zcmd_free_nvlists(&zc
);
3729 return (zpool_standard_error(hdl
, errno
, msg
));
3733 * Similar to zpool_clear(), but takes a GUID (used by fmd).
3736 zpool_vdev_clear(zpool_handle_t
*zhp
, uint64_t guid
)
3738 zfs_cmd_t zc
= { 0 };
3740 libzfs_handle_t
*hdl
= zhp
->zpool_hdl
;
3742 (void) snprintf(msg
, sizeof (msg
),
3743 dgettext(TEXT_DOMAIN
, "cannot clear errors for %llx"),
3746 (void) strlcpy(zc
.zc_name
, zhp
->zpool_name
, sizeof (zc
.zc_name
));
3748 zc
.zc_cookie
= ZPOOL_NO_REWIND
;
3750 if (ioctl(hdl
->libzfs_fd
, ZFS_IOC_CLEAR
, &zc
) == 0)
3753 return (zpool_standard_error(hdl
, errno
, msg
));
3757 * Change the GUID for a pool.
3760 zpool_reguid(zpool_handle_t
*zhp
)
3763 libzfs_handle_t
*hdl
= zhp
->zpool_hdl
;
3764 zfs_cmd_t zc
= { 0 };
3766 (void) snprintf(msg
, sizeof (msg
),
3767 dgettext(TEXT_DOMAIN
, "cannot reguid '%s'"), zhp
->zpool_name
);
3769 (void) strlcpy(zc
.zc_name
, zhp
->zpool_name
, sizeof (zc
.zc_name
));
3770 if (zfs_ioctl(hdl
, ZFS_IOC_POOL_REGUID
, &zc
) == 0)
3773 return (zpool_standard_error(hdl
, errno
, msg
));
3780 zpool_reopen(zpool_handle_t
*zhp
)
3782 zfs_cmd_t zc
= { 0 };
3784 libzfs_handle_t
*hdl
= zhp
->zpool_hdl
;
3786 (void) snprintf(msg
, sizeof (msg
),
3787 dgettext(TEXT_DOMAIN
, "cannot reopen '%s'"),
3790 (void) strlcpy(zc
.zc_name
, zhp
->zpool_name
, sizeof (zc
.zc_name
));
3791 if (zfs_ioctl(hdl
, ZFS_IOC_POOL_REOPEN
, &zc
) == 0)
3793 return (zpool_standard_error(hdl
, errno
, msg
));
3796 /* call into libzfs_core to execute the sync IOCTL per pool */
3798 zpool_sync_one(zpool_handle_t
*zhp
, void *data
)
3801 libzfs_handle_t
*hdl
= zpool_get_handle(zhp
);
3802 const char *pool_name
= zpool_get_name(zhp
);
3803 boolean_t
*force
= data
;
3804 nvlist_t
*innvl
= fnvlist_alloc();
3806 fnvlist_add_boolean_value(innvl
, "force", *force
);
3807 if ((ret
= lzc_sync(pool_name
, innvl
, NULL
)) != 0) {
3809 return (zpool_standard_error_fmt(hdl
, ret
,
3810 dgettext(TEXT_DOMAIN
, "sync '%s' failed"), pool_name
));
3818 * Convert from a devid string to a path.
3821 devid_to_path(char *devid_str
)
3826 devid_nmlist_t
*list
= NULL
;
3829 if (devid_str_decode(devid_str
, &devid
, &minor
) != 0)
3832 ret
= devid_deviceid_to_nmlist("/dev", devid
, minor
, &list
);
3834 devid_str_free(minor
);
3841 * In a case the strdup() fails, we will just return NULL below.
3843 path
= strdup(list
[0].devname
);
3845 devid_free_nmlist(list
);
3851 * Convert from a path to a devid string.
3854 path_to_devid(const char *path
)
3860 if ((fd
= open(path
, O_RDONLY
)) < 0)
3865 if (devid_get(fd
, &devid
) == 0) {
3866 if (devid_get_minor_name(fd
, &minor
) == 0)
3867 ret
= devid_str_encode(devid
, minor
);
3869 devid_str_free(minor
);
3877 struct path_from_physpath_walker_args
{
3882 * Walker for use with di_devlink_walk(). Stores the "/dev" path of the first
3883 * primary devlink (i.e., the first devlink which refers to our "/devices"
3884 * node) and stops walking.
3887 path_from_physpath_walker(di_devlink_t devlink
, void *arg
)
3889 struct path_from_physpath_walker_args
*pfpwa
= arg
;
3891 if (di_devlink_type(devlink
) != DI_PRIMARY_LINK
) {
3892 return (DI_WALK_CONTINUE
);
3895 verify(pfpwa
->pfpwa_path
== NULL
);
3896 if ((pfpwa
->pfpwa_path
= strdup(di_devlink_path(devlink
))) != NULL
) {
3897 return (DI_WALK_TERMINATE
);
3900 return (DI_WALK_CONTINUE
);
3904 * Search for a "/dev" path that refers to our physical path. Returns the new
3905 * path if one is found and it does not match the existing "path" value. If
3906 * the value is unchanged, or one could not be found, returns NULL.
3909 path_from_physpath(libzfs_handle_t
*hdl
, const char *path
,
3910 const char *physpath
)
3912 struct path_from_physpath_walker_args pfpwa
;
3914 if (physpath
== NULL
) {
3918 if (hdl
->libzfs_devlink
== NULL
) {
3919 if ((hdl
->libzfs_devlink
= di_devlink_init(NULL
, 0)) ==
3922 * We may not be able to open a handle if this process
3923 * is insufficiently privileged, or we are too early in
3924 * boot for devfsadm to be ready. Ignore this error
3925 * and defer the path check to a subsequent run.
3931 pfpwa
.pfpwa_path
= NULL
;
3932 (void) di_devlink_walk(hdl
->libzfs_devlink
, NULL
, physpath
,
3933 DI_PRIMARY_LINK
, &pfpwa
, path_from_physpath_walker
);
3935 if (path
!= NULL
&& pfpwa
.pfpwa_path
!= NULL
&&
3936 strcmp(path
, pfpwa
.pfpwa_path
) == 0) {
3938 * If the path is already correct, no change is required.
3940 free(pfpwa
.pfpwa_path
);
3944 return (pfpwa
.pfpwa_path
);
3948 * Issue the necessary ioctl() to update the stored path value for the vdev. We
3949 * ignore any failure here, since a common case is for an unprivileged user to
3950 * type 'zpool status', and we'll display the correct information anyway.
3953 set_path(zpool_handle_t
*zhp
, nvlist_t
*nv
, const char *path
)
3955 zfs_cmd_t zc
= { 0 };
3957 (void) strncpy(zc
.zc_name
, zhp
->zpool_name
, sizeof (zc
.zc_name
));
3958 (void) strncpy(zc
.zc_value
, path
, sizeof (zc
.zc_value
));
3959 verify(nvlist_lookup_uint64(nv
, ZPOOL_CONFIG_GUID
,
3962 (void) ioctl(zhp
->zpool_hdl
->libzfs_fd
, ZFS_IOC_VDEV_SETPATH
, &zc
);
3966 * This routine is responsible for identifying when disks have been
3967 * reconfigured in a new location. The kernel will have opened the device by
3968 * devid, but the path will still refer to the old location. To catch this, we
3969 * first do a path -> devid translation (which is fast for the common case).
3970 * If the devid matches, we're done. If not, we do a reverse devid -> path
3971 * translation and issue the appropriate ioctl() to update the path of the
3975 zpool_vdev_refresh_path(libzfs_handle_t
*hdl
, zpool_handle_t
*zhp
, nvlist_t
*nv
)
3978 char *newpath
= NULL
;
3979 char *physpath
= NULL
;
3982 if (nvlist_lookup_string(nv
, ZPOOL_CONFIG_PATH
, &path
) != 0) {
3986 if (nvlist_lookup_string(nv
, ZPOOL_CONFIG_DEVID
, &devid
) == 0) {
3988 * This vdev has a devid. We can use it to check the current
3991 char *newdevid
= path_to_devid(path
);
3993 if (newdevid
== NULL
|| strcmp(devid
, newdevid
) != 0) {
3994 newpath
= devid_to_path(devid
);
3997 if (newdevid
!= NULL
) {
3998 devid_str_free(newdevid
);
4001 } else if (nvlist_lookup_string(nv
, ZPOOL_CONFIG_PHYS_PATH
,
4004 * This vdev does not have a devid, but it does have a physical
4005 * path. Attempt to translate this to a /dev path.
4007 newpath
= path_from_physpath(hdl
, path
, physpath
);
4010 if (newpath
== NULL
) {
4012 * No path update is required.
4017 set_path(zhp
, nv
, newpath
);
4018 fnvlist_add_string(nv
, ZPOOL_CONFIG_PATH
, newpath
);
4024 * Given a vdev, return the name to display in iostat. If the vdev has a path,
4025 * we use that, stripping off any leading "/dev/dsk/"; if not, we use the type.
4026 * We will confirm that the path and name of the vdev are current, and update
4027 * them if not. We also check if this is a whole disk, in which case we strip
4028 * off the trailing 's0' slice name.
4030 * If 'zhp' is NULL, then this is an exported pool, and we don't need to do any
4034 zpool_vdev_name(libzfs_handle_t
*hdl
, zpool_handle_t
*zhp
, nvlist_t
*nv
,
4037 char *path
, *type
, *env
;
4041 * vdev_name will be "root"/"root-0" for the root vdev, but it is the
4042 * zpool name that will be displayed to the user.
4044 verify(nvlist_lookup_string(nv
, ZPOOL_CONFIG_TYPE
, &type
) == 0);
4045 if (zhp
!= NULL
&& strcmp(type
, "root") == 0)
4046 return (zfs_strdup(hdl
, zpool_get_name(zhp
)));
4048 env
= getenv("ZPOOL_VDEV_NAME_PATH");
4049 if (env
&& (strtoul(env
, NULL
, 0) > 0 ||
4050 !strncasecmp(env
, "YES", 3) || !strncasecmp(env
, "ON", 2)))
4051 name_flags
|= VDEV_NAME_PATH
;
4053 env
= getenv("ZPOOL_VDEV_NAME_GUID");
4054 if (env
&& (strtoul(env
, NULL
, 0) > 0 ||
4055 !strncasecmp(env
, "YES", 3) || !strncasecmp(env
, "ON", 2)))
4056 name_flags
|= VDEV_NAME_GUID
;
4058 env
= getenv("ZPOOL_VDEV_NAME_FOLLOW_LINKS");
4059 if (env
&& (strtoul(env
, NULL
, 0) > 0 ||
4060 !strncasecmp(env
, "YES", 3) || !strncasecmp(env
, "ON", 2)))
4061 name_flags
|= VDEV_NAME_FOLLOW_LINKS
;
4063 if (nvlist_lookup_uint64(nv
, ZPOOL_CONFIG_NOT_PRESENT
, &value
) == 0 ||
4064 name_flags
& VDEV_NAME_GUID
) {
4065 nvlist_lookup_uint64(nv
, ZPOOL_CONFIG_GUID
, &value
);
4066 path
= zfs_asprintf(hdl
, "%llu", (u_longlong_t
)value
);
4067 } else if (nvlist_lookup_string(nv
, ZPOOL_CONFIG_PATH
, &path
) == 0) {
4072 * If the device is dead (faulted, offline, etc) then don't
4073 * bother opening it. Otherwise we may be forcing the user to
4074 * open a misbehaving device, which can have undesirable
4077 if (nvlist_lookup_uint64_array(nv
, ZPOOL_CONFIG_VDEV_STATS
,
4078 (uint64_t **)&vs
, &vsc
) != 0 ||
4079 vs
->vs_state
< VDEV_STATE_DEGRADED
||
4081 path
= zfs_strdup(hdl
, path
);
4086 * Refresh the /dev path for this vdev if required, then ensure
4087 * we're using the latest path value:
4089 zpool_vdev_refresh_path(hdl
, zhp
, nv
);
4090 path
= fnvlist_lookup_string(nv
, ZPOOL_CONFIG_PATH
);
4092 if (name_flags
& VDEV_NAME_FOLLOW_LINKS
) {
4093 char *rp
= realpath(path
, NULL
);
4098 path
= zfs_strdup(hdl
, path
);
4102 if (strncmp(path
, ZFS_DISK_ROOTD
,
4103 sizeof (ZFS_DISK_ROOTD
) - 1) == 0) {
4104 const char *p2
= path
+ sizeof (ZFS_DISK_ROOTD
) - 1;
4106 memmove(path
, p2
, strlen(p2
) + 1);
4110 * Remove the partition from the path it this is a whole disk.
4112 if (nvlist_lookup_uint64(nv
, ZPOOL_CONFIG_WHOLE_DISK
, &value
)
4113 == 0 && value
&& !(name_flags
& VDEV_NAME_PATH
)) {
4114 int pathlen
= strlen(path
);
4117 * If it starts with c#, and ends with "s0" or "s1",
4118 * chop the slice off, or if it ends with "s0/old" or
4119 * "s1/old", remove the slice from the middle.
4121 if (CTD_CHECK(path
)) {
4122 if (strcmp(&path
[pathlen
- 2], "s0") == 0 ||
4123 strcmp(&path
[pathlen
- 2], "s1") == 0) {
4124 path
[pathlen
- 2] = '\0';
4125 } else if (pathlen
> 6 &&
4126 (strcmp(&path
[pathlen
- 6],
4128 strcmp(&path
[pathlen
- 6],
4130 (void) strcpy(&path
[pathlen
- 6],
4138 * If it's a raidz device, we need to stick in the parity level.
4140 if (strcmp(type
, VDEV_TYPE_RAIDZ
) == 0) {
4141 verify(nvlist_lookup_uint64(nv
, ZPOOL_CONFIG_NPARITY
,
4143 path
= zfs_asprintf(hdl
, "%s%llu", type
,
4144 (u_longlong_t
)value
);
4146 path
= zfs_strdup(hdl
, type
);
4150 * We identify each top-level vdev by using a <type-id>
4151 * naming convention.
4153 if (name_flags
& VDEV_NAME_TYPE_ID
) {
4157 verify(nvlist_lookup_uint64(nv
, ZPOOL_CONFIG_ID
,
4159 tmp
= zfs_asprintf(hdl
, "%s-%llu", path
,
4170 zbookmark_mem_compare(const void *a
, const void *b
)
4172 return (memcmp(a
, b
, sizeof (zbookmark_phys_t
)));
4176 * Retrieve the persistent error log, uniquify the members, and return to the
4180 zpool_get_errlog(zpool_handle_t
*zhp
, nvlist_t
**nverrlistp
)
4182 zfs_cmd_t zc
= { 0 };
4184 zbookmark_phys_t
*zb
= NULL
;
4188 * Retrieve the raw error list from the kernel. If the number of errors
4189 * has increased, allocate more space and continue until we get the
4192 verify(nvlist_lookup_uint64(zhp
->zpool_config
, ZPOOL_CONFIG_ERRCOUNT
,
4196 if ((zc
.zc_nvlist_dst
= (uintptr_t)zfs_alloc(zhp
->zpool_hdl
,
4197 count
* sizeof (zbookmark_phys_t
))) == (uintptr_t)NULL
)
4199 zc
.zc_nvlist_dst_size
= count
;
4200 (void) strcpy(zc
.zc_name
, zhp
->zpool_name
);
4202 if (ioctl(zhp
->zpool_hdl
->libzfs_fd
, ZFS_IOC_ERROR_LOG
,
4204 free((void *)(uintptr_t)zc
.zc_nvlist_dst
);
4205 if (errno
== ENOMEM
) {
4208 count
= zc
.zc_nvlist_dst_size
;
4209 dst
= zfs_alloc(zhp
->zpool_hdl
, count
*
4210 sizeof (zbookmark_phys_t
));
4213 zc
.zc_nvlist_dst
= (uintptr_t)dst
;
4223 * Sort the resulting bookmarks. This is a little confusing due to the
4224 * implementation of ZFS_IOC_ERROR_LOG. The bookmarks are copied last
4225 * to first, and 'zc_nvlist_dst_size' indicates the number of boomarks
4226 * _not_ copied as part of the process. So we point the start of our
4227 * array appropriate and decrement the total number of elements.
4229 zb
= ((zbookmark_phys_t
*)(uintptr_t)zc
.zc_nvlist_dst
) +
4230 zc
.zc_nvlist_dst_size
;
4231 count
-= zc
.zc_nvlist_dst_size
;
4233 qsort(zb
, count
, sizeof (zbookmark_phys_t
), zbookmark_mem_compare
);
4235 verify(nvlist_alloc(nverrlistp
, 0, KM_SLEEP
) == 0);
4238 * Fill in the nverrlistp with nvlist's of dataset and object numbers.
4240 for (i
= 0; i
< count
; i
++) {
4243 /* ignoring zb_blkid and zb_level for now */
4244 if (i
> 0 && zb
[i
-1].zb_objset
== zb
[i
].zb_objset
&&
4245 zb
[i
-1].zb_object
== zb
[i
].zb_object
)
4248 if (nvlist_alloc(&nv
, NV_UNIQUE_NAME
, KM_SLEEP
) != 0)
4250 if (nvlist_add_uint64(nv
, ZPOOL_ERR_DATASET
,
4251 zb
[i
].zb_objset
) != 0) {
4255 if (nvlist_add_uint64(nv
, ZPOOL_ERR_OBJECT
,
4256 zb
[i
].zb_object
) != 0) {
4260 if (nvlist_add_nvlist(*nverrlistp
, "ejk", nv
) != 0) {
4267 free((void *)(uintptr_t)zc
.zc_nvlist_dst
);
4271 free((void *)(uintptr_t)zc
.zc_nvlist_dst
);
4272 return (no_memory(zhp
->zpool_hdl
));
4276 * Upgrade a ZFS pool to the latest on-disk version.
4279 zpool_upgrade(zpool_handle_t
*zhp
, uint64_t new_version
)
4281 zfs_cmd_t zc
= { 0 };
4282 libzfs_handle_t
*hdl
= zhp
->zpool_hdl
;
4284 (void) strcpy(zc
.zc_name
, zhp
->zpool_name
);
4285 zc
.zc_cookie
= new_version
;
4287 if (zfs_ioctl(hdl
, ZFS_IOC_POOL_UPGRADE
, &zc
) != 0)
4288 return (zpool_standard_error_fmt(hdl
, errno
,
4289 dgettext(TEXT_DOMAIN
, "cannot upgrade '%s'"),
4295 zfs_save_arguments(int argc
, char **argv
, char *string
, int len
)
4297 (void) strlcpy(string
, basename(argv
[0]), len
);
4298 for (int i
= 1; i
< argc
; i
++) {
4299 (void) strlcat(string
, " ", len
);
4300 (void) strlcat(string
, argv
[i
], len
);
4305 zpool_log_history(libzfs_handle_t
*hdl
, const char *message
)
4307 zfs_cmd_t zc
= { 0 };
4311 args
= fnvlist_alloc();
4312 fnvlist_add_string(args
, "message", message
);
4313 err
= zcmd_write_src_nvlist(hdl
, &zc
, args
);
4315 err
= ioctl(hdl
->libzfs_fd
, ZFS_IOC_LOG_HISTORY
, &zc
);
4317 zcmd_free_nvlists(&zc
);
4322 * Perform ioctl to get some command history of a pool.
4324 * 'buf' is the buffer to fill up to 'len' bytes. 'off' is the
4325 * logical offset of the history buffer to start reading from.
4327 * Upon return, 'off' is the next logical offset to read from and
4328 * 'len' is the actual amount of bytes read into 'buf'.
4331 get_history(zpool_handle_t
*zhp
, char *buf
, uint64_t *off
, uint64_t *len
)
4333 zfs_cmd_t zc
= { 0 };
4334 libzfs_handle_t
*hdl
= zhp
->zpool_hdl
;
4336 (void) strlcpy(zc
.zc_name
, zhp
->zpool_name
, sizeof (zc
.zc_name
));
4338 zc
.zc_history
= (uint64_t)(uintptr_t)buf
;
4339 zc
.zc_history_len
= *len
;
4340 zc
.zc_history_offset
= *off
;
4342 if (ioctl(hdl
->libzfs_fd
, ZFS_IOC_POOL_GET_HISTORY
, &zc
) != 0) {
4345 return (zfs_error_fmt(hdl
, EZFS_PERM
,
4346 dgettext(TEXT_DOMAIN
,
4347 "cannot show history for pool '%s'"),
4350 return (zfs_error_fmt(hdl
, EZFS_NOHISTORY
,
4351 dgettext(TEXT_DOMAIN
, "cannot get history for pool "
4352 "'%s'"), zhp
->zpool_name
));
4354 return (zfs_error_fmt(hdl
, EZFS_BADVERSION
,
4355 dgettext(TEXT_DOMAIN
, "cannot get history for pool "
4356 "'%s', pool must be upgraded"), zhp
->zpool_name
));
4358 return (zpool_standard_error_fmt(hdl
, errno
,
4359 dgettext(TEXT_DOMAIN
,
4360 "cannot get history for '%s'"), zhp
->zpool_name
));
4364 *len
= zc
.zc_history_len
;
4365 *off
= zc
.zc_history_offset
;
4371 * Retrieve the command history of a pool.
4374 zpool_get_history(zpool_handle_t
*zhp
, nvlist_t
**nvhisp
, uint64_t *off
,
4378 int buflen
= 128 * 1024;
4379 nvlist_t
**records
= NULL
;
4380 uint_t numrecords
= 0;
4382 uint64_t start
= *off
;
4384 buf
= malloc(buflen
);
4387 /* process about 1MB a time */
4388 while (*off
- start
< 1024 * 1024) {
4389 uint64_t bytes_read
= buflen
;
4392 if ((err
= get_history(zhp
, buf
, off
, &bytes_read
)) != 0)
4395 /* if nothing else was read in, we're at EOF, just return */
4401 if ((err
= zpool_history_unpack(buf
, bytes_read
,
4402 &leftover
, &records
, &numrecords
)) != 0)
4405 if (leftover
== bytes_read
) {
4407 * no progress made, because buffer is not big enough
4408 * to hold this record; resize and retry.
4412 buf
= malloc(buflen
);
4421 verify(nvlist_alloc(nvhisp
, NV_UNIQUE_NAME
, 0) == 0);
4422 verify(nvlist_add_nvlist_array(*nvhisp
, ZPOOL_HIST_RECORD
,
4423 records
, numrecords
) == 0);
4425 for (i
= 0; i
< numrecords
; i
++)
4426 nvlist_free(records
[i
]);
4433 zpool_obj_to_path(zpool_handle_t
*zhp
, uint64_t dsobj
, uint64_t obj
,
4434 char *pathname
, size_t len
)
4436 zfs_cmd_t zc
= { 0 };
4437 boolean_t mounted
= B_FALSE
;
4438 char *mntpnt
= NULL
;
4439 char dsname
[ZFS_MAX_DATASET_NAME_LEN
];
4442 /* special case for the MOS */
4443 (void) snprintf(pathname
, len
, "<metadata>:<0x%llx>", obj
);
4447 /* get the dataset's name */
4448 (void) strlcpy(zc
.zc_name
, zhp
->zpool_name
, sizeof (zc
.zc_name
));
4450 if (ioctl(zhp
->zpool_hdl
->libzfs_fd
,
4451 ZFS_IOC_DSOBJ_TO_DSNAME
, &zc
) != 0) {
4452 /* just write out a path of two object numbers */
4453 (void) snprintf(pathname
, len
, "<0x%llx>:<0x%llx>",
4457 (void) strlcpy(dsname
, zc
.zc_value
, sizeof (dsname
));
4459 /* find out if the dataset is mounted */
4460 mounted
= is_mounted(zhp
->zpool_hdl
, dsname
, &mntpnt
);
4462 /* get the corrupted object's path */
4463 (void) strlcpy(zc
.zc_name
, dsname
, sizeof (zc
.zc_name
));
4465 if (ioctl(zhp
->zpool_hdl
->libzfs_fd
, ZFS_IOC_OBJ_TO_PATH
,
4468 (void) snprintf(pathname
, len
, "%s%s", mntpnt
,
4471 (void) snprintf(pathname
, len
, "%s:%s",
4472 dsname
, zc
.zc_value
);
4475 (void) snprintf(pathname
, len
, "%s:<0x%llx>", dsname
, obj
);
4481 zpool_set_bootenv(zpool_handle_t
*zhp
, const nvlist_t
*envmap
)
4483 int error
= lzc_set_bootenv(zhp
->zpool_name
, envmap
);
4485 (void) zpool_standard_error_fmt(zhp
->zpool_hdl
, error
,
4486 dgettext(TEXT_DOMAIN
,
4487 "error setting bootenv in pool '%s'"), zhp
->zpool_name
);
4494 zpool_get_bootenv(zpool_handle_t
*zhp
, nvlist_t
**nvlp
)
4500 error
= lzc_get_bootenv(zhp
->zpool_name
, &nvl
);
4502 (void) zpool_standard_error_fmt(zhp
->zpool_hdl
, error
,
4503 dgettext(TEXT_DOMAIN
,
4504 "error getting bootenv in pool '%s'"), zhp
->zpool_name
);
4513 * Read the EFI label from the config, if a label does not exist then
4514 * pass back the error to the caller. If the caller has passed a non-NULL
4515 * diskaddr argument then we set it to the starting address of the EFI
4516 * partition. If the caller has passed a non-NULL boolean argument, then
4517 * we set it to indicate if the disk does have efi system partition.
4520 read_efi_label(nvlist_t
*config
, diskaddr_t
*sb
, boolean_t
*system
)
4524 char diskname
[MAXPATHLEN
];
4525 boolean_t boot
= B_FALSE
;
4529 if (nvlist_lookup_string(config
, ZPOOL_CONFIG_PATH
, &path
) != 0)
4532 (void) snprintf(diskname
, sizeof (diskname
), "%s%s", ZFS_RDISK_ROOT
,
4533 strrchr(path
, '/'));
4534 if ((fd
= open(diskname
, O_RDONLY
|O_NDELAY
)) >= 0) {
4535 struct dk_gpt
*vtoc
;
4537 if ((err
= efi_alloc_and_read(fd
, &vtoc
)) >= 0) {
4538 for (slice
= 0; slice
< vtoc
->efi_nparts
; slice
++) {
4539 if (vtoc
->efi_parts
[slice
].p_tag
== V_SYSTEM
)
4541 if (vtoc
->efi_parts
[slice
].p_tag
== V_USR
)
4544 if (sb
!= NULL
&& vtoc
->efi_parts
[slice
].p_tag
== V_USR
)
4545 *sb
= vtoc
->efi_parts
[slice
].p_start
;
4556 * determine where a partition starts on a disk in the current
4560 find_start_block(nvlist_t
*config
)
4564 diskaddr_t sb
= MAXOFFSET_T
;
4567 if (nvlist_lookup_nvlist_array(config
,
4568 ZPOOL_CONFIG_CHILDREN
, &child
, &children
) != 0) {
4569 if (nvlist_lookup_uint64(config
,
4570 ZPOOL_CONFIG_WHOLE_DISK
,
4571 &wholedisk
) != 0 || !wholedisk
) {
4572 return (MAXOFFSET_T
);
4574 if (read_efi_label(config
, &sb
, NULL
) < 0)
4579 for (c
= 0; c
< children
; c
++) {
4580 sb
= find_start_block(child
[c
]);
4581 if (sb
!= MAXOFFSET_T
) {
4585 return (MAXOFFSET_T
);
4589 * Label an individual disk. The name provided is the short name,
4590 * stripped of any leading /dev path.
4593 zpool_label_disk(libzfs_handle_t
*hdl
, zpool_handle_t
*zhp
, const char *name
,
4594 zpool_boot_label_t boot_type
, uint64_t boot_size
, int *slice
)
4596 char path
[MAXPATHLEN
];
4597 struct dk_gpt
*vtoc
;
4600 uint64_t slice_size
;
4601 diskaddr_t start_block
;
4604 /* prepare an error message just in case */
4605 (void) snprintf(errbuf
, sizeof (errbuf
),
4606 dgettext(TEXT_DOMAIN
, "cannot label '%s'"), name
);
4611 verify(nvlist_lookup_nvlist(zhp
->zpool_config
,
4612 ZPOOL_CONFIG_VDEV_TREE
, &nvroot
) == 0);
4614 if (zhp
->zpool_start_block
== 0)
4615 start_block
= find_start_block(nvroot
);
4617 start_block
= zhp
->zpool_start_block
;
4618 zhp
->zpool_start_block
= start_block
;
4621 start_block
= NEW_START_BLOCK
;
4624 (void) snprintf(path
, sizeof (path
), "%s/%s%s", ZFS_RDISK_ROOT
, name
,
4627 if ((fd
= open(path
, O_RDWR
| O_NDELAY
)) < 0) {
4629 * This shouldn't happen. We've long since verified that this
4630 * is a valid device.
4633 dgettext(TEXT_DOMAIN
, "unable to open device"));
4634 return (zfs_error(hdl
, EZFS_OPENFAILED
, errbuf
));
4637 if (efi_alloc_and_init(fd
, EFI_NUMPAR
, &vtoc
) != 0) {
4639 * The only way this can fail is if we run out of memory, or we
4640 * were unable to read the disk's capacity
4642 if (errno
== ENOMEM
)
4643 (void) no_memory(hdl
);
4646 zfs_error_aux(hdl
, dgettext(TEXT_DOMAIN
,
4647 "unable to read disk capacity"), name
);
4649 return (zfs_error(hdl
, EZFS_NOCAP
, errbuf
));
4651 resv
= efi_reserved_sectors(vtoc
);
4654 * Why we use V_USR: V_BACKUP confuses users, and is considered
4655 * disposable by some EFI utilities (since EFI doesn't have a backup
4656 * slice). V_UNASSIGNED is supposed to be used only for zero size
4657 * partitions, and efi_write() will fail if we use it. V_ROOT, V_BOOT,
4658 * etc. were all pretty specific. V_USR is as close to reality as we
4659 * can get, in the absence of V_OTHER.
4661 /* first fix the partition start block */
4662 if (start_block
== MAXOFFSET_T
)
4663 start_block
= NEW_START_BLOCK
;
4666 * EFI System partition is using slice 0.
4667 * ZFS is on slice 1 and slice 8 is reserved.
4668 * We assume the GPT partition table without system
4669 * partition has zfs p_start == NEW_START_BLOCK.
4670 * If start_block != NEW_START_BLOCK, it means we have
4671 * system partition. Correct solution would be to query/cache vtoc
4672 * from existing vdev member.
4674 if (boot_type
== ZPOOL_CREATE_BOOT_LABEL
) {
4675 if (boot_size
% vtoc
->efi_lbasize
!= 0) {
4676 zfs_error_aux(hdl
, dgettext(TEXT_DOMAIN
,
4677 "boot partition size must be a multiple of %d"),
4681 return (zfs_error(hdl
, EZFS_LABELFAILED
, errbuf
));
4684 * System partition size checks.
4685 * Note the 1MB is quite arbitrary value, since we
4686 * are creating dedicated pool, it should be enough
4687 * to hold fat + efi bootloader. May need to be
4688 * adjusted if the bootloader size will grow.
4690 if (boot_size
< 1024 * 1024) {
4692 zfs_nicenum(boot_size
, buf
, sizeof (buf
));
4693 zfs_error_aux(hdl
, dgettext(TEXT_DOMAIN
,
4694 "Specified size %s for EFI System partition is too "
4695 "small, the minimum size is 1MB."), buf
);
4698 return (zfs_error(hdl
, EZFS_LABELFAILED
, errbuf
));
4700 /* 33MB is tested with mkfs -F pcfs */
4701 if (hdl
->libzfs_printerr
&&
4702 ((vtoc
->efi_lbasize
== 512 &&
4703 boot_size
< 33 * 1024 * 1024) ||
4704 (vtoc
->efi_lbasize
== 4096 &&
4705 boot_size
< 256 * 1024 * 1024))) {
4707 zfs_nicenum(boot_size
, buf
, sizeof (buf
));
4708 (void) fprintf(stderr
, dgettext(TEXT_DOMAIN
,
4709 "Warning: EFI System partition size %s is "
4710 "not allowing to create FAT32 file\nsystem, which "
4711 "may result in unbootable system.\n"), buf
);
4713 /* Adjust zfs partition start by size of system partition. */
4714 start_block
+= boot_size
/ vtoc
->efi_lbasize
;
4717 if (start_block
== NEW_START_BLOCK
) {
4719 * Use default layout.
4720 * ZFS is on slice 0 and slice 8 is reserved.
4722 slice_size
= vtoc
->efi_last_u_lba
+ 1;
4724 slice_size
-= start_block
;
4728 vtoc
->efi_parts
[0].p_start
= start_block
;
4729 vtoc
->efi_parts
[0].p_size
= slice_size
;
4731 vtoc
->efi_parts
[0].p_tag
= V_USR
;
4732 (void) strcpy(vtoc
->efi_parts
[0].p_name
, "zfs");
4734 vtoc
->efi_parts
[8].p_start
= slice_size
+ start_block
;
4735 vtoc
->efi_parts
[8].p_size
= resv
;
4736 vtoc
->efi_parts
[8].p_tag
= V_RESERVED
;
4738 slice_size
= start_block
- NEW_START_BLOCK
;
4739 vtoc
->efi_parts
[0].p_start
= NEW_START_BLOCK
;
4740 vtoc
->efi_parts
[0].p_size
= slice_size
;
4741 vtoc
->efi_parts
[0].p_tag
= V_SYSTEM
;
4742 (void) strcpy(vtoc
->efi_parts
[0].p_name
, "loader");
4745 /* prepare slice 1 */
4746 slice_size
= vtoc
->efi_last_u_lba
+ 1 - slice_size
;
4748 slice_size
-= NEW_START_BLOCK
;
4749 vtoc
->efi_parts
[1].p_start
= start_block
;
4750 vtoc
->efi_parts
[1].p_size
= slice_size
;
4751 vtoc
->efi_parts
[1].p_tag
= V_USR
;
4752 (void) strcpy(vtoc
->efi_parts
[1].p_name
, "zfs");
4754 vtoc
->efi_parts
[8].p_start
= slice_size
+ start_block
;
4755 vtoc
->efi_parts
[8].p_size
= resv
;
4756 vtoc
->efi_parts
[8].p_tag
= V_RESERVED
;
4759 if (efi_write(fd
, vtoc
) != 0) {
4761 * Some block drivers (like pcata) may not support EFI
4762 * GPT labels. Print out a helpful error message dir-
4763 * ecting the user to manually label the disk and give
4769 zfs_error_aux(hdl
, dgettext(TEXT_DOMAIN
,
4770 "try using fdisk(8) and then provide a specific slice"));
4771 return (zfs_error(hdl
, EZFS_LABELFAILED
, errbuf
));
4780 supported_dump_vdev_type(libzfs_handle_t
*hdl
, nvlist_t
*config
, char *errbuf
)
4786 verify(nvlist_lookup_string(config
, ZPOOL_CONFIG_TYPE
, &type
) == 0);
4787 if (strcmp(type
, VDEV_TYPE_FILE
) == 0 ||
4788 strcmp(type
, VDEV_TYPE_HOLE
) == 0 ||
4789 strcmp(type
, VDEV_TYPE_MISSING
) == 0) {
4790 zfs_error_aux(hdl
, dgettext(TEXT_DOMAIN
,
4791 "vdev type '%s' is not supported"), type
);
4792 (void) zfs_error(hdl
, EZFS_VDEVNOTSUP
, errbuf
);
4795 if (nvlist_lookup_nvlist_array(config
, ZPOOL_CONFIG_CHILDREN
,
4796 &child
, &children
) == 0) {
4797 for (c
= 0; c
< children
; c
++) {
4798 if (!supported_dump_vdev_type(hdl
, child
[c
], errbuf
))
4806 * Check if this zvol is allowable for use as a dump device; zero if
4807 * it is, > 0 if it isn't, < 0 if it isn't a zvol.
4809 * Allowable storage configurations include mirrors, all raidz variants, and
4810 * pools with log, cache, and spare devices. Pools which are backed by files or
4811 * have missing/hole vdevs are not suitable.
4814 zvol_check_dump_config(char *arg
)
4816 zpool_handle_t
*zhp
= NULL
;
4817 nvlist_t
*config
, *nvroot
;
4821 libzfs_handle_t
*hdl
;
4823 char poolname
[ZFS_MAX_DATASET_NAME_LEN
];
4824 int pathlen
= strlen(ZVOL_FULL_DEV_DIR
);
4827 if (strncmp(arg
, ZVOL_FULL_DEV_DIR
, pathlen
)) {
4831 (void) snprintf(errbuf
, sizeof (errbuf
), dgettext(TEXT_DOMAIN
,
4832 "dump is not supported on device '%s'"), arg
);
4834 if ((hdl
= libzfs_init()) == NULL
)
4836 libzfs_print_on_error(hdl
, B_TRUE
);
4838 volname
= arg
+ pathlen
;
4840 /* check the configuration of the pool */
4841 if ((p
= strchr(volname
, '/')) == NULL
) {
4842 zfs_error_aux(hdl
, dgettext(TEXT_DOMAIN
,
4843 "malformed dataset name"));
4844 (void) zfs_error(hdl
, EZFS_INVALIDNAME
, errbuf
);
4846 } else if (p
- volname
>= ZFS_MAX_DATASET_NAME_LEN
) {
4847 zfs_error_aux(hdl
, dgettext(TEXT_DOMAIN
,
4848 "dataset name is too long"));
4849 (void) zfs_error(hdl
, EZFS_NAMETOOLONG
, errbuf
);
4852 (void) strncpy(poolname
, volname
, p
- volname
);
4853 poolname
[p
- volname
] = '\0';
4856 if ((zhp
= zpool_open(hdl
, poolname
)) == NULL
) {
4857 zfs_error_aux(hdl
, dgettext(TEXT_DOMAIN
,
4858 "could not open pool '%s'"), poolname
);
4859 (void) zfs_error(hdl
, EZFS_OPENFAILED
, errbuf
);
4862 config
= zpool_get_config(zhp
, NULL
);
4863 if (nvlist_lookup_nvlist(config
, ZPOOL_CONFIG_VDEV_TREE
,
4865 zfs_error_aux(hdl
, dgettext(TEXT_DOMAIN
,
4866 "could not obtain vdev configuration for '%s'"), poolname
);
4867 (void) zfs_error(hdl
, EZFS_INVALCONFIG
, errbuf
);
4871 verify(nvlist_lookup_nvlist_array(nvroot
, ZPOOL_CONFIG_CHILDREN
,
4872 &top
, &toplevels
) == 0);
4874 if (!supported_dump_vdev_type(hdl
, top
[0], errbuf
)) {