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 https://opensource.org/licenses/CDDL-1.0.
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]
22 * Copyright 2015 Nexenta Systems, Inc. All rights reserved.
23 * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
24 * Copyright (c) 2012, 2018 by Delphix. All rights reserved.
25 * Copyright 2015 RackTop Systems.
26 * Copyright (c) 2016, Intel Corporation.
27 * Copyright (c) 2021, Colm Buckley <colm@tuatha.org>
31 * Pool import support functions.
33 * Used by zpool, ztest, zdb, and zhack to locate importable configs. Since
34 * these commands are expected to run in the global zone, we can assume
35 * that the devices are all readable when called.
37 * To import a pool, we rely on reading the configuration information from the
38 * ZFS label of each device. If we successfully read the label, then we
39 * organize the configuration information in the following hierarchy:
41 * pool guid -> toplevel vdev guid -> label txg
43 * Duplicate entries matching this same tuple will be discarded. Once we have
44 * examined every device, we pick the best label txg config for each toplevel
45 * vdev. We then arrange these toplevel vdevs into a complete pool config, and
46 * update any paths that have changed. Finally, we attempt to import the pool
47 * using our derived config, and record the results.
64 #include <sys/dktp/fdisk.h>
65 #include <sys/vdev_impl.h>
66 #include <sys/fs/zfs.h>
68 #include <thread_pool.h>
70 #include <libnvpair.h>
72 #include "zutil_import.h"
75 libpc_error_description(libpc_handle_t
*hdl
)
77 if (hdl
->lpc_desc
[0] != '\0')
78 return (hdl
->lpc_desc
);
80 switch (hdl
->lpc_error
) {
82 return (dgettext(TEXT_DOMAIN
, "invalid or missing cache file"));
84 return (dgettext(TEXT_DOMAIN
, "must be an absolute path"));
86 return (dgettext(TEXT_DOMAIN
, "out of memory"));
88 return (dgettext(TEXT_DOMAIN
, "some devices require root "
91 return (dgettext(TEXT_DOMAIN
, "unknown error"));
93 assert(hdl
->lpc_error
== 0);
94 return (dgettext(TEXT_DOMAIN
, "no error"));
98 static __attribute__((format(printf
, 2, 3))) void
99 zutil_error_aux(libpc_handle_t
*hdl
, const char *fmt
, ...)
105 (void) vsnprintf(hdl
->lpc_desc
, sizeof (hdl
->lpc_desc
), fmt
, ap
);
106 hdl
->lpc_desc_active
= B_TRUE
;
112 zutil_verror(libpc_handle_t
*hdl
, lpc_error_t error
, const char *fmt
,
117 (void) vsnprintf(action
, sizeof (action
), fmt
, ap
);
118 hdl
->lpc_error
= error
;
120 if (hdl
->lpc_desc_active
)
121 hdl
->lpc_desc_active
= B_FALSE
;
123 hdl
->lpc_desc
[0] = '\0';
125 if (hdl
->lpc_printerr
)
126 (void) fprintf(stderr
, "%s: %s\n", action
,
127 libpc_error_description(hdl
));
130 static __attribute__((format(printf
, 3, 4))) int
131 zutil_error_fmt(libpc_handle_t
*hdl
, lpc_error_t error
,
132 const char *fmt
, ...)
138 zutil_verror(hdl
, error
, fmt
, ap
);
146 zutil_error(libpc_handle_t
*hdl
, lpc_error_t error
, const char *msg
)
148 return (zutil_error_fmt(hdl
, error
, "%s", msg
));
152 zutil_no_memory(libpc_handle_t
*hdl
)
154 zutil_error(hdl
, LPC_NOMEM
, "internal error");
159 zutil_alloc(libpc_handle_t
*hdl
, size_t size
)
163 if ((data
= calloc(1, size
)) == NULL
)
164 (void) zutil_no_memory(hdl
);
170 zutil_strdup(libpc_handle_t
*hdl
, const char *str
)
174 if ((ret
= strdup(str
)) == NULL
)
175 (void) zutil_no_memory(hdl
);
181 zutil_strndup(libpc_handle_t
*hdl
, const char *str
, size_t n
)
185 if ((ret
= strndup(str
, n
)) == NULL
)
186 (void) zutil_no_memory(hdl
);
192 * Intermediate structures used to gather configuration information.
194 typedef struct config_entry
{
197 struct config_entry
*ce_next
;
200 typedef struct vdev_entry
{
202 config_entry_t
*ve_configs
;
203 struct vdev_entry
*ve_next
;
206 typedef struct pool_entry
{
208 vdev_entry_t
*pe_vdevs
;
209 struct pool_entry
*pe_next
;
212 typedef struct name_entry
{
216 uint64_t ne_num_labels
;
217 struct name_entry
*ne_next
;
220 typedef struct pool_list
{
226 * Go through and fix up any path and/or devid information for the given vdev
230 fix_paths(libpc_handle_t
*hdl
, nvlist_t
*nv
, name_entry_t
*names
)
235 name_entry_t
*ne
, *best
;
238 if (nvlist_lookup_nvlist_array(nv
, ZPOOL_CONFIG_CHILDREN
,
239 &child
, &children
) == 0) {
240 for (c
= 0; c
< children
; c
++)
241 if (fix_paths(hdl
, child
[c
], names
) != 0)
247 * This is a leaf (file or disk) vdev. In either case, go through
248 * the name list and see if we find a matching guid. If so, replace
249 * the path and see if we can calculate a new devid.
251 * There may be multiple names associated with a particular guid, in
252 * which case we have overlapping partitions or multiple paths to the
253 * same disk. In this case we prefer to use the path name which
254 * matches the ZPOOL_CONFIG_PATH. If no matching entry is found we
255 * use the lowest order device which corresponds to the first match
256 * while traversing the ZPOOL_IMPORT_PATH search path.
258 verify(nvlist_lookup_uint64(nv
, ZPOOL_CONFIG_GUID
, &guid
) == 0);
259 if (nvlist_lookup_string(nv
, ZPOOL_CONFIG_PATH
, &path
) != 0)
263 for (ne
= names
; ne
!= NULL
; ne
= ne
->ne_next
) {
264 if (ne
->ne_guid
== guid
) {
270 if ((strlen(path
) == strlen(ne
->ne_name
)) &&
271 strncmp(path
, ne
->ne_name
, strlen(path
)) == 0) {
281 /* Prefer paths with move vdev labels. */
282 if (ne
->ne_num_labels
> best
->ne_num_labels
) {
287 /* Prefer paths earlier in the search order. */
288 if (ne
->ne_num_labels
== best
->ne_num_labels
&&
289 ne
->ne_order
< best
->ne_order
) {
299 if (nvlist_add_string(nv
, ZPOOL_CONFIG_PATH
, best
->ne_name
) != 0)
302 update_vdev_config_dev_strs(nv
);
308 * Add the given configuration to the list of known devices.
311 add_config(libpc_handle_t
*hdl
, pool_list_t
*pl
, const char *path
,
312 int order
, int num_labels
, nvlist_t
*config
)
314 uint64_t pool_guid
, vdev_guid
, top_guid
, txg
, state
;
321 * If this is a hot spare not currently in use or level 2 cache
322 * device, add it to the list of names to translate, but don't do
325 if (nvlist_lookup_uint64(config
, ZPOOL_CONFIG_POOL_STATE
,
327 (state
== POOL_STATE_SPARE
|| state
== POOL_STATE_L2CACHE
) &&
328 nvlist_lookup_uint64(config
, ZPOOL_CONFIG_GUID
, &vdev_guid
) == 0) {
329 if ((ne
= zutil_alloc(hdl
, sizeof (name_entry_t
))) == NULL
)
332 if ((ne
->ne_name
= zutil_strdup(hdl
, path
)) == NULL
) {
336 ne
->ne_guid
= vdev_guid
;
337 ne
->ne_order
= order
;
338 ne
->ne_num_labels
= num_labels
;
339 ne
->ne_next
= pl
->names
;
346 * If we have a valid config but cannot read any of these fields, then
347 * it means we have a half-initialized label. In vdev_label_init()
348 * we write a label with txg == 0 so that we can identify the device
349 * in case the user refers to the same disk later on. If we fail to
350 * create the pool, we'll be left with a label in this state
351 * which should not be considered part of a valid pool.
353 if (nvlist_lookup_uint64(config
, ZPOOL_CONFIG_POOL_GUID
,
355 nvlist_lookup_uint64(config
, ZPOOL_CONFIG_GUID
,
357 nvlist_lookup_uint64(config
, ZPOOL_CONFIG_TOP_GUID
,
359 nvlist_lookup_uint64(config
, ZPOOL_CONFIG_POOL_TXG
,
360 &txg
) != 0 || txg
== 0) {
365 * First, see if we know about this pool. If not, then add it to the
366 * list of known pools.
368 for (pe
= pl
->pools
; pe
!= NULL
; pe
= pe
->pe_next
) {
369 if (pe
->pe_guid
== pool_guid
)
374 if ((pe
= zutil_alloc(hdl
, sizeof (pool_entry_t
))) == NULL
) {
377 pe
->pe_guid
= pool_guid
;
378 pe
->pe_next
= pl
->pools
;
383 * Second, see if we know about this toplevel vdev. Add it if its
386 for (ve
= pe
->pe_vdevs
; ve
!= NULL
; ve
= ve
->ve_next
) {
387 if (ve
->ve_guid
== top_guid
)
392 if ((ve
= zutil_alloc(hdl
, sizeof (vdev_entry_t
))) == NULL
) {
395 ve
->ve_guid
= top_guid
;
396 ve
->ve_next
= pe
->pe_vdevs
;
401 * Third, see if we have a config with a matching transaction group. If
402 * so, then we do nothing. Otherwise, add it to the list of known
405 for (ce
= ve
->ve_configs
; ce
!= NULL
; ce
= ce
->ce_next
) {
406 if (ce
->ce_txg
== txg
)
411 if ((ce
= zutil_alloc(hdl
, sizeof (config_entry_t
))) == NULL
) {
415 ce
->ce_config
= fnvlist_dup(config
);
416 ce
->ce_next
= ve
->ve_configs
;
421 * At this point we've successfully added our config to the list of
422 * known configs. The last thing to do is add the vdev guid -> path
423 * mappings so that we can fix up the configuration as necessary before
426 if ((ne
= zutil_alloc(hdl
, sizeof (name_entry_t
))) == NULL
)
429 if ((ne
->ne_name
= zutil_strdup(hdl
, path
)) == NULL
) {
434 ne
->ne_guid
= vdev_guid
;
435 ne
->ne_order
= order
;
436 ne
->ne_num_labels
= num_labels
;
437 ne
->ne_next
= pl
->names
;
444 zutil_pool_active(libpc_handle_t
*hdl
, const char *name
, uint64_t guid
,
447 ASSERT(hdl
->lpc_ops
->pco_pool_active
!= NULL
);
449 int error
= hdl
->lpc_ops
->pco_pool_active(hdl
->lpc_lib_handle
, name
,
456 zutil_refresh_config(libpc_handle_t
*hdl
, nvlist_t
*tryconfig
)
458 ASSERT(hdl
->lpc_ops
->pco_refresh_config
!= NULL
);
460 return (hdl
->lpc_ops
->pco_refresh_config(hdl
->lpc_lib_handle
,
465 * Determine if the vdev id is a hole in the namespace.
468 vdev_is_hole(uint64_t *hole_array
, uint_t holes
, uint_t id
)
472 for (c
= 0; c
< holes
; c
++) {
474 /* Top-level is a hole */
475 if (hole_array
[c
] == id
)
482 * Convert our list of pools into the definitive set of configurations. We
483 * start by picking the best config for each toplevel vdev. Once that's done,
484 * we assemble the toplevel vdevs into a full config for the pool. We make a
485 * pass to fix up any incorrect paths, and then add it to the main list to
486 * return to the user.
489 get_configs(libpc_handle_t
*hdl
, pool_list_t
*pl
, boolean_t active_ok
,
495 nvlist_t
*ret
= NULL
, *config
= NULL
, *tmp
= NULL
, *nvtop
, *nvroot
;
496 nvlist_t
**spares
, **l2cache
;
497 uint_t i
, nspares
, nl2cache
;
498 boolean_t config_seen
;
500 const char *name
, *hostname
= NULL
;
503 nvlist_t
**child
= NULL
;
504 uint64_t *hole_array
, max_id
;
508 boolean_t valid_top_config
= B_FALSE
;
510 if (nvlist_alloc(&ret
, 0, 0) != 0)
513 for (pe
= pl
->pools
; pe
!= NULL
; pe
= pe
->pe_next
) {
514 uint64_t id
, max_txg
= 0, hostid
= 0;
517 if (nvlist_alloc(&config
, NV_UNIQUE_NAME
, 0) != 0)
519 config_seen
= B_FALSE
;
522 * Iterate over all toplevel vdevs. Grab the pool configuration
523 * from the first one we find, and then go through the rest and
524 * add them as necessary to the 'vdevs' member of the config.
526 for (ve
= pe
->pe_vdevs
; ve
!= NULL
; ve
= ve
->ve_next
) {
529 * Determine the best configuration for this vdev by
530 * selecting the config with the latest transaction
534 for (ce
= ve
->ve_configs
; ce
!= NULL
;
537 if (ce
->ce_txg
> best_txg
) {
539 best_txg
= ce
->ce_txg
;
544 * We rely on the fact that the max txg for the
545 * pool will contain the most up-to-date information
546 * about the valid top-levels in the vdev namespace.
548 if (best_txg
> max_txg
) {
549 (void) nvlist_remove(config
,
550 ZPOOL_CONFIG_VDEV_CHILDREN
,
552 (void) nvlist_remove(config
,
553 ZPOOL_CONFIG_HOLE_ARRAY
,
554 DATA_TYPE_UINT64_ARRAY
);
560 valid_top_config
= B_FALSE
;
562 if (nvlist_lookup_uint64(tmp
,
563 ZPOOL_CONFIG_VDEV_CHILDREN
, &max_id
) == 0) {
564 verify(nvlist_add_uint64(config
,
565 ZPOOL_CONFIG_VDEV_CHILDREN
,
567 valid_top_config
= B_TRUE
;
570 if (nvlist_lookup_uint64_array(tmp
,
571 ZPOOL_CONFIG_HOLE_ARRAY
, &hole_array
,
573 verify(nvlist_add_uint64_array(config
,
574 ZPOOL_CONFIG_HOLE_ARRAY
,
575 hole_array
, holes
) == 0);
581 * Copy the relevant pieces of data to the pool
587 * comment (if available)
588 * compatibility features (if available)
590 * hostid (if available)
591 * hostname (if available)
593 uint64_t state
, version
;
594 const char *comment
= NULL
;
595 const char *compatibility
= NULL
;
597 version
= fnvlist_lookup_uint64(tmp
,
598 ZPOOL_CONFIG_VERSION
);
599 fnvlist_add_uint64(config
,
600 ZPOOL_CONFIG_VERSION
, version
);
601 guid
= fnvlist_lookup_uint64(tmp
,
602 ZPOOL_CONFIG_POOL_GUID
);
603 fnvlist_add_uint64(config
,
604 ZPOOL_CONFIG_POOL_GUID
, guid
);
605 name
= fnvlist_lookup_string(tmp
,
606 ZPOOL_CONFIG_POOL_NAME
);
607 fnvlist_add_string(config
,
608 ZPOOL_CONFIG_POOL_NAME
, name
);
610 if (nvlist_lookup_string(tmp
,
611 ZPOOL_CONFIG_COMMENT
, &comment
) == 0)
612 fnvlist_add_string(config
,
613 ZPOOL_CONFIG_COMMENT
, comment
);
615 if (nvlist_lookup_string(tmp
,
616 ZPOOL_CONFIG_COMPATIBILITY
,
617 &compatibility
) == 0)
618 fnvlist_add_string(config
,
619 ZPOOL_CONFIG_COMPATIBILITY
,
622 state
= fnvlist_lookup_uint64(tmp
,
623 ZPOOL_CONFIG_POOL_STATE
);
624 fnvlist_add_uint64(config
,
625 ZPOOL_CONFIG_POOL_STATE
, state
);
628 if (nvlist_lookup_uint64(tmp
,
629 ZPOOL_CONFIG_HOSTID
, &hostid
) == 0) {
630 fnvlist_add_uint64(config
,
631 ZPOOL_CONFIG_HOSTID
, hostid
);
632 hostname
= fnvlist_lookup_string(tmp
,
633 ZPOOL_CONFIG_HOSTNAME
);
634 fnvlist_add_string(config
,
635 ZPOOL_CONFIG_HOSTNAME
, hostname
);
638 config_seen
= B_TRUE
;
642 * Add this top-level vdev to the child array.
644 verify(nvlist_lookup_nvlist(tmp
,
645 ZPOOL_CONFIG_VDEV_TREE
, &nvtop
) == 0);
646 verify(nvlist_lookup_uint64(nvtop
, ZPOOL_CONFIG_ID
,
649 if (id
>= children
) {
652 newchild
= zutil_alloc(hdl
, (id
+ 1) *
653 sizeof (nvlist_t
*));
654 if (newchild
== NULL
)
657 for (c
= 0; c
< children
; c
++)
658 newchild
[c
] = child
[c
];
664 if (nvlist_dup(nvtop
, &child
[id
], 0) != 0)
670 * If we have information about all the top-levels then
671 * clean up the nvlist which we've constructed. This
672 * means removing any extraneous devices that are
673 * beyond the valid range or adding devices to the end
674 * of our array which appear to be missing.
676 if (valid_top_config
) {
677 if (max_id
< children
) {
678 for (c
= max_id
; c
< children
; c
++)
679 nvlist_free(child
[c
]);
681 } else if (max_id
> children
) {
684 newchild
= zutil_alloc(hdl
, (max_id
) *
685 sizeof (nvlist_t
*));
686 if (newchild
== NULL
)
689 for (c
= 0; c
< children
; c
++)
690 newchild
[c
] = child
[c
];
698 verify(nvlist_lookup_uint64(config
, ZPOOL_CONFIG_POOL_GUID
,
702 * The vdev namespace may contain holes as a result of
703 * device removal. We must add them back into the vdev
704 * tree before we process any missing devices.
707 ASSERT(valid_top_config
);
709 for (c
= 0; c
< children
; c
++) {
712 if (child
[c
] != NULL
||
713 !vdev_is_hole(hole_array
, holes
, c
))
716 if (nvlist_alloc(&holey
, NV_UNIQUE_NAME
,
721 * Holes in the namespace are treated as
722 * "hole" top-level vdevs and have a
723 * special flag set on them.
725 if (nvlist_add_string(holey
,
727 VDEV_TYPE_HOLE
) != 0 ||
728 nvlist_add_uint64(holey
,
729 ZPOOL_CONFIG_ID
, c
) != 0 ||
730 nvlist_add_uint64(holey
,
731 ZPOOL_CONFIG_GUID
, 0ULL) != 0) {
740 * Look for any missing top-level vdevs. If this is the case,
741 * create a faked up 'missing' vdev as a placeholder. We cannot
742 * simply compress the child array, because the kernel performs
743 * certain checks to make sure the vdev IDs match their location
744 * in the configuration.
746 for (c
= 0; c
< children
; c
++) {
747 if (child
[c
] == NULL
) {
749 if (nvlist_alloc(&missing
, NV_UNIQUE_NAME
,
752 if (nvlist_add_string(missing
,
754 VDEV_TYPE_MISSING
) != 0 ||
755 nvlist_add_uint64(missing
,
756 ZPOOL_CONFIG_ID
, c
) != 0 ||
757 nvlist_add_uint64(missing
,
758 ZPOOL_CONFIG_GUID
, 0ULL) != 0) {
759 nvlist_free(missing
);
767 * Put all of this pool's top-level vdevs into a root vdev.
769 if (nvlist_alloc(&nvroot
, NV_UNIQUE_NAME
, 0) != 0)
771 if (nvlist_add_string(nvroot
, ZPOOL_CONFIG_TYPE
,
772 VDEV_TYPE_ROOT
) != 0 ||
773 nvlist_add_uint64(nvroot
, ZPOOL_CONFIG_ID
, 0ULL) != 0 ||
774 nvlist_add_uint64(nvroot
, ZPOOL_CONFIG_GUID
, guid
) != 0 ||
775 nvlist_add_nvlist_array(nvroot
, ZPOOL_CONFIG_CHILDREN
,
776 (const nvlist_t
**)child
, children
) != 0) {
781 for (c
= 0; c
< children
; c
++)
782 nvlist_free(child
[c
]);
788 * Go through and fix up any paths and/or devids based on our
789 * known list of vdev GUID -> path mappings.
791 if (fix_paths(hdl
, nvroot
, pl
->names
) != 0) {
797 * Add the root vdev to this pool's configuration.
799 if (nvlist_add_nvlist(config
, ZPOOL_CONFIG_VDEV_TREE
,
807 * zdb uses this path to report on active pools that were
808 * imported or created using -R.
814 * Determine if this pool is currently active, in which case we
815 * can't actually import it.
817 verify(nvlist_lookup_string(config
, ZPOOL_CONFIG_POOL_NAME
,
819 verify(nvlist_lookup_uint64(config
, ZPOOL_CONFIG_POOL_GUID
,
822 if (zutil_pool_active(hdl
, name
, guid
, &isactive
) != 0)
831 if (policy
!= NULL
) {
832 if (nvlist_add_nvlist(config
, ZPOOL_LOAD_POLICY
,
837 if ((nvl
= zutil_refresh_config(hdl
, config
)) == NULL
) {
847 * Go through and update the paths for spares, now that we have
850 verify(nvlist_lookup_nvlist(config
, ZPOOL_CONFIG_VDEV_TREE
,
852 if (nvlist_lookup_nvlist_array(nvroot
, ZPOOL_CONFIG_SPARES
,
853 &spares
, &nspares
) == 0) {
854 for (i
= 0; i
< nspares
; i
++) {
855 if (fix_paths(hdl
, spares
[i
], pl
->names
) != 0)
861 * Update the paths for l2cache devices.
863 if (nvlist_lookup_nvlist_array(nvroot
, ZPOOL_CONFIG_L2CACHE
,
864 &l2cache
, &nl2cache
) == 0) {
865 for (i
= 0; i
< nl2cache
; i
++) {
866 if (fix_paths(hdl
, l2cache
[i
], pl
->names
) != 0)
872 * Restore the original information read from the actual label.
874 (void) nvlist_remove(config
, ZPOOL_CONFIG_HOSTID
,
876 (void) nvlist_remove(config
, ZPOOL_CONFIG_HOSTNAME
,
879 verify(nvlist_add_uint64(config
, ZPOOL_CONFIG_HOSTID
,
881 verify(nvlist_add_string(config
, ZPOOL_CONFIG_HOSTNAME
,
887 * Add this pool to the list of configs.
889 verify(nvlist_lookup_string(config
, ZPOOL_CONFIG_POOL_NAME
,
892 if (nvlist_add_nvlist(ret
, name
, config
) != 0)
902 (void) zutil_no_memory(hdl
);
906 for (c
= 0; c
< children
; c
++)
907 nvlist_free(child
[c
]);
914 * Return the offset of the given label.
917 label_offset(uint64_t size
, int l
)
919 ASSERT(P2PHASE_TYPED(size
, sizeof (vdev_label_t
), uint64_t) == 0);
920 return (l
* sizeof (vdev_label_t
) + (l
< VDEV_LABELS
/ 2 ?
921 0 : size
- VDEV_LABELS
* sizeof (vdev_label_t
)));
925 * The same description applies as to zpool_read_label below,
926 * except here we do it without aio, presumably because an aio call
927 * errored out in a way we think not using it could circumvent.
930 zpool_read_label_slow(int fd
, nvlist_t
**config
, int *num_labels
)
932 struct stat64 statbuf
;
935 nvlist_t
*expected_config
= NULL
;
936 uint64_t expected_guid
= 0, size
;
940 if (fstat64_blk(fd
, &statbuf
) == -1)
942 size
= P2ALIGN_TYPED(statbuf
.st_size
, sizeof (vdev_label_t
), uint64_t);
944 label
= (vdev_phys_t
*)umem_alloc_aligned(sizeof (*label
), PAGESIZE
,
949 for (l
= 0; l
< VDEV_LABELS
; l
++) {
950 uint64_t state
, guid
, txg
;
951 off_t offset
= label_offset(size
, l
) + VDEV_SKIP_SIZE
;
953 if (pread64(fd
, label
, sizeof (vdev_phys_t
),
954 offset
) != sizeof (vdev_phys_t
))
957 if (nvlist_unpack(label
->vp_nvlist
,
958 sizeof (label
->vp_nvlist
), config
, 0) != 0)
961 if (nvlist_lookup_uint64(*config
, ZPOOL_CONFIG_GUID
,
962 &guid
) != 0 || guid
== 0) {
963 nvlist_free(*config
);
967 if (nvlist_lookup_uint64(*config
, ZPOOL_CONFIG_POOL_STATE
,
968 &state
) != 0 || state
> POOL_STATE_L2CACHE
) {
969 nvlist_free(*config
);
973 if (state
!= POOL_STATE_SPARE
&& state
!= POOL_STATE_L2CACHE
&&
974 (nvlist_lookup_uint64(*config
, ZPOOL_CONFIG_POOL_TXG
,
975 &txg
) != 0 || txg
== 0)) {
976 nvlist_free(*config
);
981 if (expected_guid
== guid
)
984 nvlist_free(*config
);
986 expected_config
= *config
;
987 expected_guid
= guid
;
992 if (num_labels
!= NULL
)
995 umem_free_aligned(label
, sizeof (*label
));
996 *config
= expected_config
;
1002 * Given a file descriptor, read the label information and return an nvlist
1003 * describing the configuration, if there is one. The number of valid
1004 * labels found will be returned in num_labels when non-NULL.
1007 zpool_read_label(int fd
, nvlist_t
**config
, int *num_labels
)
1010 return (zpool_read_label_slow(fd
, config
, num_labels
));
1012 struct stat64 statbuf
;
1013 struct aiocb aiocbs
[VDEV_LABELS
];
1014 struct aiocb
*aiocbps
[VDEV_LABELS
];
1015 vdev_phys_t
*labels
;
1016 nvlist_t
*expected_config
= NULL
;
1017 uint64_t expected_guid
= 0, size
;
1018 int error
, l
, count
= 0;
1022 if (fstat64_blk(fd
, &statbuf
) == -1)
1024 size
= P2ALIGN_TYPED(statbuf
.st_size
, sizeof (vdev_label_t
), uint64_t);
1026 labels
= (vdev_phys_t
*)umem_alloc_aligned(
1027 VDEV_LABELS
* sizeof (*labels
), PAGESIZE
, UMEM_DEFAULT
);
1031 memset(aiocbs
, 0, sizeof (aiocbs
));
1032 for (l
= 0; l
< VDEV_LABELS
; l
++) {
1033 off_t offset
= label_offset(size
, l
) + VDEV_SKIP_SIZE
;
1035 aiocbs
[l
].aio_fildes
= fd
;
1036 aiocbs
[l
].aio_offset
= offset
;
1037 aiocbs
[l
].aio_buf
= &labels
[l
];
1038 aiocbs
[l
].aio_nbytes
= sizeof (vdev_phys_t
);
1039 aiocbs
[l
].aio_lio_opcode
= LIO_READ
;
1040 aiocbps
[l
] = &aiocbs
[l
];
1043 if (lio_listio(LIO_WAIT
, aiocbps
, VDEV_LABELS
, NULL
) != 0) {
1044 int saved_errno
= errno
;
1045 boolean_t do_slow
= B_FALSE
;
1048 if (errno
== EAGAIN
|| errno
== EINTR
|| errno
== EIO
) {
1050 * A portion of the requests may have been submitted.
1053 for (l
= 0; l
< VDEV_LABELS
; l
++) {
1055 switch (aio_error(&aiocbs
[l
])) {
1059 // This shouldn't be possible to
1060 // encounter, die if we do.
1069 (void) aio_return(&aiocbs
[l
]);
1075 * At least some IO involved access unsafe-for-AIO
1076 * files. Let's try again, without AIO this time.
1078 error
= zpool_read_label_slow(fd
, config
, num_labels
);
1079 saved_errno
= errno
;
1081 umem_free_aligned(labels
, VDEV_LABELS
* sizeof (*labels
));
1082 errno
= saved_errno
;
1086 for (l
= 0; l
< VDEV_LABELS
; l
++) {
1087 uint64_t state
, guid
, txg
;
1089 if (aio_return(&aiocbs
[l
]) != sizeof (vdev_phys_t
))
1092 if (nvlist_unpack(labels
[l
].vp_nvlist
,
1093 sizeof (labels
[l
].vp_nvlist
), config
, 0) != 0)
1096 if (nvlist_lookup_uint64(*config
, ZPOOL_CONFIG_GUID
,
1097 &guid
) != 0 || guid
== 0) {
1098 nvlist_free(*config
);
1102 if (nvlist_lookup_uint64(*config
, ZPOOL_CONFIG_POOL_STATE
,
1103 &state
) != 0 || state
> POOL_STATE_L2CACHE
) {
1104 nvlist_free(*config
);
1108 if (state
!= POOL_STATE_SPARE
&& state
!= POOL_STATE_L2CACHE
&&
1109 (nvlist_lookup_uint64(*config
, ZPOOL_CONFIG_POOL_TXG
,
1110 &txg
) != 0 || txg
== 0)) {
1111 nvlist_free(*config
);
1115 if (expected_guid
) {
1116 if (expected_guid
== guid
)
1119 nvlist_free(*config
);
1121 expected_config
= *config
;
1122 expected_guid
= guid
;
1127 if (num_labels
!= NULL
)
1128 *num_labels
= count
;
1130 umem_free_aligned(labels
, VDEV_LABELS
* sizeof (*labels
));
1131 *config
= expected_config
;
1138 * Sorted by full path and then vdev guid to allow for multiple entries with
1139 * the same full path name. This is required because it's possible to
1140 * have multiple block devices with labels that refer to the same
1141 * ZPOOL_CONFIG_PATH yet have different vdev guids. In this case both
1142 * entries need to be added to the cache. Scenarios where this can occur
1143 * include overwritten pool labels, devices which are visible from multiple
1144 * hosts and multipath devices.
1147 slice_cache_compare(const void *arg1
, const void *arg2
)
1149 const char *nm1
= ((rdsk_node_t
*)arg1
)->rn_name
;
1150 const char *nm2
= ((rdsk_node_t
*)arg2
)->rn_name
;
1151 uint64_t guid1
= ((rdsk_node_t
*)arg1
)->rn_vdev_guid
;
1152 uint64_t guid2
= ((rdsk_node_t
*)arg2
)->rn_vdev_guid
;
1155 rv
= TREE_ISIGN(strcmp(nm1
, nm2
));
1159 return (TREE_CMP(guid1
, guid2
));
1163 label_paths_impl(libpc_handle_t
*hdl
, nvlist_t
*nvroot
, uint64_t pool_guid
,
1164 uint64_t vdev_guid
, const char **path
, const char **devid
)
1172 if (nvlist_lookup_nvlist_array(nvroot
, ZPOOL_CONFIG_CHILDREN
,
1173 &child
, &children
) == 0) {
1174 for (c
= 0; c
< children
; c
++) {
1175 error
= label_paths_impl(hdl
, child
[c
],
1176 pool_guid
, vdev_guid
, path
, devid
);
1186 error
= nvlist_lookup_uint64(nvroot
, ZPOOL_CONFIG_GUID
, &guid
);
1187 if ((error
!= 0) || (guid
!= vdev_guid
))
1190 error
= nvlist_lookup_string(nvroot
, ZPOOL_CONFIG_PATH
, &val
);
1194 error
= nvlist_lookup_string(nvroot
, ZPOOL_CONFIG_DEVID
, &val
);
1202 * Given a disk label fetch the ZPOOL_CONFIG_PATH and ZPOOL_CONFIG_DEVID
1203 * and store these strings as config_path and devid_path respectively.
1204 * The returned pointers are only valid as long as label remains valid.
1207 label_paths(libpc_handle_t
*hdl
, nvlist_t
*label
, const char **path
,
1217 if (nvlist_lookup_nvlist(label
, ZPOOL_CONFIG_VDEV_TREE
, &nvroot
) ||
1218 nvlist_lookup_uint64(label
, ZPOOL_CONFIG_POOL_GUID
, &pool_guid
) ||
1219 nvlist_lookup_uint64(label
, ZPOOL_CONFIG_GUID
, &vdev_guid
))
1222 return (label_paths_impl(hdl
, nvroot
, pool_guid
, vdev_guid
, path
,
1227 zpool_find_import_scan_add_slice(libpc_handle_t
*hdl
, pthread_mutex_t
*lock
,
1228 avl_tree_t
*cache
, const char *path
, const char *name
, int order
)
1233 slice
= zutil_alloc(hdl
, sizeof (rdsk_node_t
));
1234 if (asprintf(&slice
->rn_name
, "%s/%s", path
, name
) == -1) {
1238 slice
->rn_vdev_guid
= 0;
1239 slice
->rn_lock
= lock
;
1240 slice
->rn_avl
= cache
;
1241 slice
->rn_hdl
= hdl
;
1242 slice
->rn_order
= order
+ IMPORT_ORDER_SCAN_OFFSET
;
1243 slice
->rn_labelpaths
= B_FALSE
;
1245 pthread_mutex_lock(lock
);
1246 if (avl_find(cache
, slice
, &where
)) {
1247 free(slice
->rn_name
);
1250 avl_insert(cache
, slice
, where
);
1252 pthread_mutex_unlock(lock
);
1256 zpool_find_import_scan_dir(libpc_handle_t
*hdl
, pthread_mutex_t
*lock
,
1257 avl_tree_t
*cache
, const char *dir
, int order
)
1260 char path
[MAXPATHLEN
];
1261 struct dirent64
*dp
;
1264 if (realpath(dir
, path
) == NULL
) {
1266 if (error
== ENOENT
)
1269 zutil_error_aux(hdl
, "%s", strerror(error
));
1270 (void) zutil_error_fmt(hdl
, LPC_BADPATH
, dgettext(TEXT_DOMAIN
,
1271 "cannot resolve path '%s'"), dir
);
1275 dirp
= opendir(path
);
1278 zutil_error_aux(hdl
, "%s", strerror(error
));
1279 (void) zutil_error_fmt(hdl
, LPC_BADPATH
, dgettext(TEXT_DOMAIN
,
1280 "cannot open '%s'"), path
);
1284 while ((dp
= readdir64(dirp
)) != NULL
) {
1285 const char *name
= dp
->d_name
;
1286 if (strcmp(name
, ".") == 0 || strcmp(name
, "..") == 0)
1289 switch (dp
->d_type
) {
1302 zpool_find_import_scan_add_slice(hdl
, lock
, cache
, path
, name
,
1306 (void) closedir(dirp
);
1311 zpool_find_import_scan_path(libpc_handle_t
*hdl
, pthread_mutex_t
*lock
,
1312 avl_tree_t
*cache
, const char *dir
, int order
)
1315 char path
[MAXPATHLEN
];
1318 const char *dpath
, *name
;
1321 * Separate the directory and the basename.
1322 * We do this so that we can get the realpath of
1323 * the directory. We don't get the realpath on the
1324 * whole path because if it's a symlink, we want the
1325 * path of the symlink not where it points to.
1327 name
= zfs_basename(dir
);
1328 if ((dl
= zfs_dirnamelen(dir
)) == -1)
1331 dpath
= d
= zutil_strndup(hdl
, dir
, dl
);
1333 if (realpath(dpath
, path
) == NULL
) {
1335 if (error
== ENOENT
) {
1340 zutil_error_aux(hdl
, "%s", strerror(error
));
1341 (void) zutil_error_fmt(hdl
, LPC_BADPATH
, dgettext(TEXT_DOMAIN
,
1342 "cannot resolve path '%s'"), dir
);
1346 zpool_find_import_scan_add_slice(hdl
, lock
, cache
, path
, name
, order
);
1354 * Scan a list of directories for zfs devices.
1357 zpool_find_import_scan(libpc_handle_t
*hdl
, pthread_mutex_t
*lock
,
1358 avl_tree_t
**slice_cache
, const char * const *dir
, size_t dirs
)
1365 *slice_cache
= NULL
;
1366 cache
= zutil_alloc(hdl
, sizeof (avl_tree_t
));
1367 avl_create(cache
, slice_cache_compare
, sizeof (rdsk_node_t
),
1368 offsetof(rdsk_node_t
, rn_node
));
1370 for (i
= 0; i
< dirs
; i
++) {
1373 if (stat(dir
[i
], &sbuf
) != 0) {
1375 if (error
== ENOENT
)
1378 zutil_error_aux(hdl
, "%s", strerror(error
));
1379 (void) zutil_error_fmt(hdl
, LPC_BADPATH
, dgettext(
1380 TEXT_DOMAIN
, "cannot resolve path '%s'"), dir
[i
]);
1385 * If dir[i] is a directory, we walk through it and add all
1386 * the entries to the cache. If it's not a directory, we just
1387 * add it to the cache.
1389 if (S_ISDIR(sbuf
.st_mode
)) {
1390 if ((error
= zpool_find_import_scan_dir(hdl
, lock
,
1391 cache
, dir
[i
], i
)) != 0)
1394 if ((error
= zpool_find_import_scan_path(hdl
, lock
,
1395 cache
, dir
[i
], i
)) != 0)
1400 *slice_cache
= cache
;
1405 while ((slice
= avl_destroy_nodes(cache
, &cookie
)) != NULL
) {
1406 free(slice
->rn_name
);
1415 * Given a list of directories to search, find all pools stored on disk. This
1416 * includes partial pools which are not available to import. If no args are
1417 * given (argc is 0), then the default directory (/dev/dsk) is searched.
1418 * poolname or guid (but not both) are provided by the caller when trying
1419 * to import a specific pool.
1422 zpool_find_import_impl(libpc_handle_t
*hdl
, importargs_t
*iarg
,
1423 pthread_mutex_t
*lock
, avl_tree_t
*cache
)
1426 nvlist_t
*ret
= NULL
;
1427 pool_list_t pools
= { 0 };
1428 pool_entry_t
*pe
, *penext
;
1429 vdev_entry_t
*ve
, *venext
;
1430 config_entry_t
*ce
, *cenext
;
1431 name_entry_t
*ne
, *nenext
;
1436 verify(iarg
->poolname
== NULL
|| iarg
->guid
== 0);
1439 * Create a thread pool to parallelize the process of reading and
1440 * validating labels, a large number of threads can be used due to
1441 * minimal contention.
1443 t
= tpool_create(1, 2 * sysconf(_SC_NPROCESSORS_ONLN
), 0, NULL
);
1444 for (slice
= avl_first(cache
); slice
;
1445 (slice
= avl_walk(cache
, slice
, AVL_AFTER
)))
1446 (void) tpool_dispatch(t
, zpool_open_func
, slice
);
1452 * Process the cache, filtering out any entries which are not
1453 * for the specified pool then adding matching label configs.
1456 while ((slice
= avl_destroy_nodes(cache
, &cookie
)) != NULL
) {
1457 if (slice
->rn_config
!= NULL
) {
1458 nvlist_t
*config
= slice
->rn_config
;
1459 boolean_t matched
= B_TRUE
;
1460 boolean_t aux
= B_FALSE
;
1464 * Check if it's a spare or l2cache device. If it is,
1465 * we need to skip the name and guid check since they
1466 * don't exist on aux device label.
1468 if (iarg
->poolname
!= NULL
|| iarg
->guid
!= 0) {
1470 aux
= nvlist_lookup_uint64(config
,
1471 ZPOOL_CONFIG_POOL_STATE
, &state
) == 0 &&
1472 (state
== POOL_STATE_SPARE
||
1473 state
== POOL_STATE_L2CACHE
);
1476 if (iarg
->poolname
!= NULL
&& !aux
) {
1479 matched
= nvlist_lookup_string(config
,
1480 ZPOOL_CONFIG_POOL_NAME
, &pname
) == 0 &&
1481 strcmp(iarg
->poolname
, pname
) == 0;
1482 } else if (iarg
->guid
!= 0 && !aux
) {
1485 matched
= nvlist_lookup_uint64(config
,
1486 ZPOOL_CONFIG_POOL_GUID
, &this_guid
) == 0 &&
1487 iarg
->guid
== this_guid
;
1491 * Verify all remaining entries can be opened
1492 * exclusively. This will prune all underlying
1493 * multipath devices which otherwise could
1494 * result in the vdev appearing as UNAVAIL.
1496 * Under zdb, this step isn't required and
1497 * would prevent a zdb -e of active pools with
1500 fd
= open(slice
->rn_name
,
1501 O_RDONLY
| O_EXCL
| O_CLOEXEC
);
1502 if (fd
>= 0 || iarg
->can_be_active
) {
1505 add_config(hdl
, &pools
,
1506 slice
->rn_name
, slice
->rn_order
,
1507 slice
->rn_num_labels
, config
);
1510 nvlist_free(config
);
1512 free(slice
->rn_name
);
1518 ret
= get_configs(hdl
, &pools
, iarg
->can_be_active
, iarg
->policy
);
1520 for (pe
= pools
.pools
; pe
!= NULL
; pe
= penext
) {
1521 penext
= pe
->pe_next
;
1522 for (ve
= pe
->pe_vdevs
; ve
!= NULL
; ve
= venext
) {
1523 venext
= ve
->ve_next
;
1524 for (ce
= ve
->ve_configs
; ce
!= NULL
; ce
= cenext
) {
1525 cenext
= ce
->ce_next
;
1526 nvlist_free(ce
->ce_config
);
1534 for (ne
= pools
.names
; ne
!= NULL
; ne
= nenext
) {
1535 nenext
= ne
->ne_next
;
1544 * Given a config, discover the paths for the devices which
1545 * exist in the config.
1548 discover_cached_paths(libpc_handle_t
*hdl
, nvlist_t
*nv
,
1549 avl_tree_t
*cache
, pthread_mutex_t
*lock
)
1551 const char *path
= NULL
;
1556 if (nvlist_lookup_nvlist_array(nv
, ZPOOL_CONFIG_CHILDREN
,
1557 &child
, &children
) == 0) {
1558 for (int c
= 0; c
< children
; c
++) {
1559 discover_cached_paths(hdl
, child
[c
], cache
, lock
);
1564 * Once we have the path, we need to add the directory to
1565 * our directory cache.
1567 if (nvlist_lookup_string(nv
, ZPOOL_CONFIG_PATH
, &path
) == 0) {
1570 if ((dl
= zfs_dirnamelen(path
)) == -1) {
1574 ((char *)path
)[dl
] = '\0';
1577 ret
= zpool_find_import_scan_dir(hdl
, lock
, cache
,
1580 ((char *)path
)[dl
] = c
;
1588 * Given a cache file, return the contents as a list of importable pools.
1589 * poolname or guid (but not both) are provided by the caller when trying
1590 * to import a specific pool.
1593 zpool_find_import_cached(libpc_handle_t
*hdl
, importargs_t
*iarg
)
1597 struct stat64 statbuf
;
1598 nvlist_t
*raw
, *src
, *dst
;
1605 verify(iarg
->poolname
== NULL
|| iarg
->guid
== 0);
1607 if ((fd
= open(iarg
->cachefile
, O_RDONLY
| O_CLOEXEC
)) < 0) {
1608 zutil_error_aux(hdl
, "%s", strerror(errno
));
1609 (void) zutil_error(hdl
, LPC_BADCACHE
, dgettext(TEXT_DOMAIN
,
1610 "failed to open cache file"));
1614 if (fstat64(fd
, &statbuf
) != 0) {
1615 zutil_error_aux(hdl
, "%s", strerror(errno
));
1617 (void) zutil_error(hdl
, LPC_BADCACHE
, dgettext(TEXT_DOMAIN
,
1618 "failed to get size of cache file"));
1622 if ((buf
= zutil_alloc(hdl
, statbuf
.st_size
)) == NULL
) {
1627 if (read(fd
, buf
, statbuf
.st_size
) != statbuf
.st_size
) {
1630 (void) zutil_error(hdl
, LPC_BADCACHE
, dgettext(TEXT_DOMAIN
,
1631 "failed to read cache file contents"));
1637 if (nvlist_unpack(buf
, statbuf
.st_size
, &raw
, 0) != 0) {
1639 (void) zutil_error(hdl
, LPC_BADCACHE
, dgettext(TEXT_DOMAIN
,
1640 "invalid or corrupt cache file contents"));
1647 * Go through and get the current state of the pools and refresh their
1650 if (nvlist_alloc(&pools
, 0, 0) != 0) {
1651 (void) zutil_no_memory(hdl
);
1657 while ((elem
= nvlist_next_nvpair(raw
, elem
)) != NULL
) {
1658 src
= fnvpair_value_nvlist(elem
);
1660 name
= fnvlist_lookup_string(src
, ZPOOL_CONFIG_POOL_NAME
);
1661 if (iarg
->poolname
!= NULL
&& strcmp(iarg
->poolname
, name
) != 0)
1664 this_guid
= fnvlist_lookup_uint64(src
, ZPOOL_CONFIG_POOL_GUID
);
1665 if (iarg
->guid
!= 0 && iarg
->guid
!= this_guid
)
1668 if (zutil_pool_active(hdl
, name
, this_guid
, &active
) != 0) {
1678 uint64_t saved_guid
= iarg
->guid
;
1679 const char *saved_poolname
= iarg
->poolname
;
1680 pthread_mutex_t lock
;
1683 * Create the device cache that will hold the
1684 * devices we will scan based on the cachefile.
1685 * This will get destroyed and freed by
1686 * zpool_find_import_impl.
1688 avl_tree_t
*cache
= zutil_alloc(hdl
,
1689 sizeof (avl_tree_t
));
1690 avl_create(cache
, slice_cache_compare
,
1691 sizeof (rdsk_node_t
),
1692 offsetof(rdsk_node_t
, rn_node
));
1693 nvlist_t
*nvroot
= fnvlist_lookup_nvlist(src
,
1694 ZPOOL_CONFIG_VDEV_TREE
);
1697 * We only want to find the pool with this_guid.
1698 * We will reset these values back later.
1700 iarg
->guid
= this_guid
;
1701 iarg
->poolname
= NULL
;
1704 * We need to build up a cache of devices that exists
1705 * in the paths pointed to by the cachefile. This allows
1706 * us to preserve the device namespace that was
1707 * originally specified by the user but also lets us
1708 * scan devices in those directories in case they had
1711 pthread_mutex_init(&lock
, NULL
);
1712 discover_cached_paths(hdl
, nvroot
, cache
, &lock
);
1713 nvlist_t
*nv
= zpool_find_import_impl(hdl
, iarg
,
1715 pthread_mutex_destroy(&lock
);
1718 * zpool_find_import_impl will return back
1719 * a list of pools that it found based on the
1720 * device cache. There should only be one pool
1721 * since we're looking for a specific guid.
1722 * We will use that pool to build up the final
1723 * pool nvlist which is returned back to the
1726 nvpair_t
*pair
= nvlist_next_nvpair(nv
, NULL
);
1729 fnvlist_add_nvlist(pools
, nvpair_name(pair
),
1730 fnvpair_value_nvlist(pair
));
1732 VERIFY3P(nvlist_next_nvpair(nv
, pair
), ==, NULL
);
1734 iarg
->guid
= saved_guid
;
1735 iarg
->poolname
= saved_poolname
;
1739 if (nvlist_add_string(src
, ZPOOL_CONFIG_CACHEFILE
,
1740 iarg
->cachefile
) != 0) {
1741 (void) zutil_no_memory(hdl
);
1747 update_vdevs_config_dev_sysfs_path(src
);
1749 if ((dst
= zutil_refresh_config(hdl
, src
)) == NULL
) {
1755 if (nvlist_add_nvlist(pools
, nvpair_name(elem
), dst
) != 0) {
1756 (void) zutil_no_memory(hdl
);
1769 zpool_find_import(libpc_handle_t
*hdl
, importargs_t
*iarg
)
1771 pthread_mutex_t lock
;
1773 nvlist_t
*pools
= NULL
;
1775 verify(iarg
->poolname
== NULL
|| iarg
->guid
== 0);
1776 pthread_mutex_init(&lock
, NULL
);
1779 * Locate pool member vdevs by blkid or by directory scanning.
1780 * On success a newly allocated AVL tree which is populated with an
1781 * entry for each discovered vdev will be returned in the cache.
1782 * It's the caller's responsibility to consume and destroy this tree.
1784 if (iarg
->scan
|| iarg
->paths
!= 0) {
1785 size_t dirs
= iarg
->paths
;
1786 const char * const *dir
= (const char * const *)iarg
->path
;
1789 dir
= zpool_default_search_paths(&dirs
);
1791 if (zpool_find_import_scan(hdl
, &lock
, &cache
,
1793 pthread_mutex_destroy(&lock
);
1797 if (zpool_find_import_blkid(hdl
, &lock
, &cache
) != 0) {
1798 pthread_mutex_destroy(&lock
);
1803 pools
= zpool_find_import_impl(hdl
, iarg
, &lock
, cache
);
1804 pthread_mutex_destroy(&lock
);
1810 zpool_search_import(libpc_handle_t
*hdl
, importargs_t
*import
)
1812 nvlist_t
*pools
= NULL
;
1814 verify(import
->poolname
== NULL
|| import
->guid
== 0);
1816 if (import
->cachefile
!= NULL
)
1817 pools
= zpool_find_import_cached(hdl
, import
);
1819 pools
= zpool_find_import(hdl
, import
);
1821 if ((pools
== NULL
|| nvlist_empty(pools
)) &&
1822 hdl
->lpc_open_access_error
&& geteuid() != 0) {
1823 (void) zutil_error(hdl
, LPC_EACCESS
, dgettext(TEXT_DOMAIN
,
1831 pool_match(nvlist_t
*cfg
, const char *tgt
)
1833 uint64_t v
, guid
= strtoull(tgt
, NULL
, 0);
1837 if (nvlist_lookup_uint64(cfg
, ZPOOL_CONFIG_POOL_GUID
, &v
) == 0)
1840 if (nvlist_lookup_string(cfg
, ZPOOL_CONFIG_POOL_NAME
, &s
) == 0)
1841 return (strcmp(s
, tgt
) == 0);
1847 zpool_find_config(libpc_handle_t
*hdl
, const char *target
, nvlist_t
**configp
,
1851 nvlist_t
*match
= NULL
;
1852 nvlist_t
*config
= NULL
;
1855 char *targetdup
= strdup(target
);
1857 if (targetdup
== NULL
)
1862 if ((sepp
= strpbrk(targetdup
, "/@")) != NULL
)
1865 pools
= zpool_search_import(hdl
, args
);
1867 if (pools
!= NULL
) {
1868 nvpair_t
*elem
= NULL
;
1869 while ((elem
= nvlist_next_nvpair(pools
, elem
)) != NULL
) {
1870 VERIFY0(nvpair_value_nvlist(elem
, &config
));
1871 if (pool_match(config
, targetdup
)) {
1873 if (match
!= NULL
) {
1874 /* multiple matches found */
1877 match
= fnvlist_dup(config
);
1881 fnvlist_free(pools
);
1891 fnvlist_free(match
);
1902 * Internal function for iterating over the vdevs.
1904 * For each vdev, func() will be called and will be passed 'zhp' (which is
1905 * typically the zpool_handle_t cast as a void pointer), the vdev's nvlist, and
1906 * a user-defined data pointer).
1908 * The return values from all the func() calls will be OR'd together and
1912 for_each_vdev_cb(void *zhp
, nvlist_t
*nv
, pool_vdev_iter_f func
,
1921 const char *list
[] = {
1922 ZPOOL_CONFIG_SPARES
,
1923 ZPOOL_CONFIG_L2CACHE
,
1924 ZPOOL_CONFIG_CHILDREN
1927 if (nvlist_lookup_string(nv
, ZPOOL_CONFIG_TYPE
, &type
) != 0)
1930 /* Don't run our function on indirect vdevs */
1931 if (strcmp(type
, VDEV_TYPE_INDIRECT
) != 0) {
1932 ret
|= func(zhp
, nv
, data
);
1935 for (i
= 0; i
< ARRAY_SIZE(list
); i
++) {
1936 if (nvlist_lookup_nvlist_array(nv
, list
[i
], &child
,
1938 for (c
= 0; c
< children
; c
++) {
1939 uint64_t ishole
= 0;
1941 (void) nvlist_lookup_uint64(child
[c
],
1942 ZPOOL_CONFIG_IS_HOLE
, &ishole
);
1947 ret
|= for_each_vdev_cb(zhp
, child
[c
],
1957 * Given an ZPOOL_CONFIG_VDEV_TREE nvpair, iterate over all the vdevs, calling
1958 * func() for each one. func() is passed the vdev's nvlist and an optional
1959 * user-defined 'data' pointer.
1962 for_each_vdev_in_nvlist(nvlist_t
*nvroot
, pool_vdev_iter_f func
, void *data
)
1964 return (for_each_vdev_cb(NULL
, nvroot
, func
, data
));