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.
37 #include <sys/vdev_impl.h>
39 #include "libzfs_impl.h"
41 #include <sys/arc_impl.h>
44 * Returns true if the named pool matches the given GUID.
47 pool_active(libzfs_handle_t
*hdl
, const char *name
, uint64_t guid
,
52 if (zpool_open_silent(hdl
, name
, &zhp
) != 0)
60 uint64_t theguid
= fnvlist_lookup_uint64(zhp
->zpool_config
,
61 ZPOOL_CONFIG_POOL_GUID
);
65 *isactive
= (theguid
== guid
);
70 refresh_config(libzfs_handle_t
*hdl
, nvlist_t
*config
)
73 zfs_cmd_t zc
= {"\0"};
76 zcmd_write_conf_nvlist(hdl
, &zc
, config
);
78 dstbuf_size
= MAX(CONFIG_BUF_MINSIZE
, zc
.zc_nvlist_conf_size
* 32);
80 zcmd_alloc_dst_nvlist(hdl
, &zc
, dstbuf_size
);
82 while ((err
= zfs_ioctl(hdl
, ZFS_IOC_POOL_TRYIMPORT
,
83 &zc
)) != 0 && errno
== ENOMEM
)
84 zcmd_expand_dst_nvlist(hdl
, &zc
);
87 zcmd_free_nvlists(&zc
);
91 if (zcmd_read_dst_nvlist(hdl
, &zc
, &nvl
) != 0) {
92 zcmd_free_nvlists(&zc
);
96 zcmd_free_nvlists(&zc
);
101 refresh_config_libzfs(void *handle
, nvlist_t
*tryconfig
)
103 return (refresh_config((libzfs_handle_t
*)handle
, tryconfig
));
107 pool_active_libzfs(void *handle
, const char *name
, uint64_t guid
,
110 return (pool_active((libzfs_handle_t
*)handle
, name
, guid
, isactive
));
113 const pool_config_ops_t libzfs_config_ops
= {
114 .pco_refresh_config
= refresh_config_libzfs
,
115 .pco_pool_active
= pool_active_libzfs
,
119 * Return the offset of the given label.
122 label_offset(uint64_t size
, int l
)
124 ASSERT(P2PHASE_TYPED(size
, sizeof (vdev_label_t
), uint64_t) == 0);
125 return (l
* sizeof (vdev_label_t
) + (l
< VDEV_LABELS
/ 2 ?
126 0 : size
- VDEV_LABELS
* sizeof (vdev_label_t
)));
130 * Given a file descriptor, clear (zero) the label information. This function
131 * is used in the appliance stack as part of the ZFS sysevent module and
132 * to implement the "zpool labelclear" command.
135 zpool_clear_label(int fd
)
137 struct stat64 statbuf
;
141 boolean_t labels_cleared
= B_FALSE
, clear_l2arc_header
= B_FALSE
,
142 header_cleared
= B_FALSE
;
144 if (fstat64_blk(fd
, &statbuf
) == -1)
147 size
= P2ALIGN_TYPED(statbuf
.st_size
, sizeof (vdev_label_t
), uint64_t);
149 if ((label
= calloc(1, sizeof (vdev_label_t
))) == NULL
)
152 for (l
= 0; l
< VDEV_LABELS
; l
++) {
153 uint64_t state
, guid
, l2cache
;
156 if (pread64(fd
, label
, sizeof (vdev_label_t
),
157 label_offset(size
, l
)) != sizeof (vdev_label_t
)) {
161 if (nvlist_unpack(label
->vl_vdev_phys
.vp_nvlist
,
162 sizeof (label
->vl_vdev_phys
.vp_nvlist
), &config
, 0) != 0) {
166 /* Skip labels which do not have a valid guid. */
167 if (nvlist_lookup_uint64(config
, ZPOOL_CONFIG_GUID
,
168 &guid
) != 0 || guid
== 0) {
173 /* Skip labels which are not in a known valid state. */
174 if (nvlist_lookup_uint64(config
, ZPOOL_CONFIG_POOL_STATE
,
175 &state
) != 0 || state
> POOL_STATE_L2CACHE
) {
180 /* If the device is a cache device clear the header. */
181 if (!clear_l2arc_header
) {
182 if (nvlist_lookup_uint64(config
,
183 ZPOOL_CONFIG_POOL_STATE
, &l2cache
) == 0 &&
184 l2cache
== POOL_STATE_L2CACHE
) {
185 clear_l2arc_header
= B_TRUE
;
192 * A valid label was found, overwrite this label's nvlist
193 * and uberblocks with zeros on disk. This is done to prevent
194 * system utilities, like blkid, from incorrectly detecting a
195 * partial label. The leading pad space is left untouched.
197 memset(label
, 0, sizeof (vdev_label_t
));
198 size_t label_size
= sizeof (vdev_label_t
) - (2 * VDEV_PAD_SIZE
);
200 if (pwrite64(fd
, label
, label_size
, label_offset(size
, l
) +
201 (2 * VDEV_PAD_SIZE
)) == label_size
)
202 labels_cleared
= B_TRUE
;
205 if (clear_l2arc_header
) {
206 _Static_assert(sizeof (*label
) >= sizeof (l2arc_dev_hdr_phys_t
),
207 "label < l2arc_dev_hdr_phys_t");
208 memset(label
, 0, sizeof (l2arc_dev_hdr_phys_t
));
209 if (pwrite64(fd
, label
, sizeof (l2arc_dev_hdr_phys_t
),
210 VDEV_LABEL_START_SIZE
) == sizeof (l2arc_dev_hdr_phys_t
))
211 header_cleared
= B_TRUE
;
216 if (!labels_cleared
|| (clear_l2arc_header
&& !header_cleared
))
223 find_guid(nvlist_t
*nv
, uint64_t guid
)
228 if (fnvlist_lookup_uint64(nv
, ZPOOL_CONFIG_GUID
) == guid
)
231 if (nvlist_lookup_nvlist_array(nv
, ZPOOL_CONFIG_CHILDREN
,
232 &child
, &children
) == 0) {
233 for (c
= 0; c
< children
; c
++)
234 if (find_guid(child
[c
], guid
))
241 typedef struct aux_cbdata
{
244 zpool_handle_t
*cb_zhp
;
248 find_aux(zpool_handle_t
*zhp
, void *data
)
250 aux_cbdata_t
*cbp
= data
;
254 nvlist_t
*nvroot
= fnvlist_lookup_nvlist(zhp
->zpool_config
,
255 ZPOOL_CONFIG_VDEV_TREE
);
257 if (nvlist_lookup_nvlist_array(nvroot
, cbp
->cb_type
,
258 &list
, &count
) == 0) {
259 for (uint_t i
= 0; i
< count
; i
++) {
260 uint64_t guid
= fnvlist_lookup_uint64(list
[i
],
262 if (guid
== cbp
->cb_guid
) {
274 * Determines if the pool is in use. If so, it returns true and the state of
275 * the pool as well as the name of the pool. Name string is allocated and
276 * must be freed by the caller.
279 zpool_in_use(libzfs_handle_t
*hdl
, int fd
, pool_state_t
*state
, char **namestr
,
283 const char *name
= NULL
;
285 uint64_t guid
= 0, vdev_guid
;
287 nvlist_t
*pool_config
;
288 uint64_t stateval
, isspare
;
289 aux_cbdata_t cb
= { 0 };
294 if (zpool_read_label(fd
, &config
, NULL
) != 0)
300 stateval
= fnvlist_lookup_uint64(config
, ZPOOL_CONFIG_POOL_STATE
);
301 vdev_guid
= fnvlist_lookup_uint64(config
, ZPOOL_CONFIG_GUID
);
303 if (stateval
!= POOL_STATE_SPARE
&& stateval
!= POOL_STATE_L2CACHE
) {
304 name
= fnvlist_lookup_string(config
, ZPOOL_CONFIG_POOL_NAME
);
305 guid
= fnvlist_lookup_uint64(config
, ZPOOL_CONFIG_POOL_GUID
);
309 case POOL_STATE_EXPORTED
:
311 * A pool with an exported state may in fact be imported
312 * read-only, so check the in-core state to see if it's
313 * active and imported read-only. If it is, set
314 * its state to active.
316 if (pool_active(hdl
, name
, guid
, &isactive
) == 0 && isactive
&&
317 (zhp
= zpool_open_canfail(hdl
, name
)) != NULL
) {
318 if (zpool_get_prop_int(zhp
, ZPOOL_PROP_READONLY
, NULL
))
319 stateval
= POOL_STATE_ACTIVE
;
322 * All we needed the zpool handle for is the
323 * readonly prop check.
331 case POOL_STATE_ACTIVE
:
333 * For an active pool, we have to determine if it's really part
334 * of a currently active pool (in which case the pool will exist
335 * and the guid will be the same), or whether it's part of an
336 * active pool that was disconnected without being explicitly
339 if (pool_active(hdl
, name
, guid
, &isactive
) != 0) {
346 * Because the device may have been removed while
347 * offlined, we only report it as active if the vdev is
348 * still present in the config. Otherwise, pretend like
351 if ((zhp
= zpool_open_canfail(hdl
, name
)) != NULL
&&
352 (pool_config
= zpool_get_config(zhp
, NULL
))
354 nvlist_t
*nvroot
= fnvlist_lookup_nvlist(
355 pool_config
, ZPOOL_CONFIG_VDEV_TREE
);
356 ret
= find_guid(nvroot
, vdev_guid
);
362 * If this is an active spare within another pool, we
363 * treat it like an unused hot spare. This allows the
364 * user to create a pool with a hot spare that currently
365 * in use within another pool. Since we return B_TRUE,
366 * libdiskmgt will continue to prevent generic consumers
367 * from using the device.
369 if (ret
&& nvlist_lookup_uint64(config
,
370 ZPOOL_CONFIG_IS_SPARE
, &isspare
) == 0 && isspare
)
371 stateval
= POOL_STATE_SPARE
;
376 stateval
= POOL_STATE_POTENTIALLY_ACTIVE
;
381 case POOL_STATE_SPARE
:
383 * For a hot spare, it can be either definitively in use, or
384 * potentially active. To determine if it's in use, we iterate
385 * over all pools in the system and search for one with a spare
386 * with a matching guid.
388 * Due to the shared nature of spares, we don't actually report
389 * the potentially active case as in use. This means the user
390 * can freely create pools on the hot spares of exported pools,
391 * but to do otherwise makes the resulting code complicated, and
392 * we end up having to deal with this case anyway.
395 cb
.cb_guid
= vdev_guid
;
396 cb
.cb_type
= ZPOOL_CONFIG_SPARES
;
397 if (zpool_iter(hdl
, find_aux
, &cb
) == 1) {
398 name
= (char *)zpool_get_name(cb
.cb_zhp
);
405 case POOL_STATE_L2CACHE
:
408 * Check if any pool is currently using this l2cache device.
411 cb
.cb_guid
= vdev_guid
;
412 cb
.cb_type
= ZPOOL_CONFIG_L2CACHE
;
413 if (zpool_iter(hdl
, find_aux
, &cb
) == 1) {
414 name
= (char *)zpool_get_name(cb
.cb_zhp
);
427 *namestr
= zfs_strdup(hdl
, name
);
428 *state
= (pool_state_t
)stateval
;
432 zpool_close(cb
.cb_zhp
);