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
,
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) {
295 (void) no_memory(hdl
);
302 stateval
= fnvlist_lookup_uint64(config
, ZPOOL_CONFIG_POOL_STATE
);
303 vdev_guid
= fnvlist_lookup_uint64(config
, ZPOOL_CONFIG_GUID
);
305 if (stateval
!= POOL_STATE_SPARE
&& stateval
!= POOL_STATE_L2CACHE
) {
306 name
= fnvlist_lookup_string(config
, ZPOOL_CONFIG_POOL_NAME
);
307 guid
= fnvlist_lookup_uint64(config
, ZPOOL_CONFIG_POOL_GUID
);
311 case POOL_STATE_EXPORTED
:
313 * A pool with an exported state may in fact be imported
314 * read-only, so check the in-core state to see if it's
315 * active and imported read-only. If it is, set
316 * its state to active.
318 if (pool_active(hdl
, name
, guid
, &isactive
) == 0 && isactive
&&
319 (zhp
= zpool_open_canfail(hdl
, name
)) != NULL
) {
320 if (zpool_get_prop_int(zhp
, ZPOOL_PROP_READONLY
, NULL
))
321 stateval
= POOL_STATE_ACTIVE
;
324 * All we needed the zpool handle for is the
325 * readonly prop check.
333 case POOL_STATE_ACTIVE
:
335 * For an active pool, we have to determine if it's really part
336 * of a currently active pool (in which case the pool will exist
337 * and the guid will be the same), or whether it's part of an
338 * active pool that was disconnected without being explicitly
341 if (pool_active(hdl
, name
, guid
, &isactive
) != 0) {
348 * Because the device may have been removed while
349 * offlined, we only report it as active if the vdev is
350 * still present in the config. Otherwise, pretend like
353 if ((zhp
= zpool_open_canfail(hdl
, name
)) != NULL
&&
354 (pool_config
= zpool_get_config(zhp
, NULL
))
356 nvlist_t
*nvroot
= fnvlist_lookup_nvlist(
357 pool_config
, ZPOOL_CONFIG_VDEV_TREE
);
358 ret
= find_guid(nvroot
, vdev_guid
);
364 * If this is an active spare within another pool, we
365 * treat it like an unused hot spare. This allows the
366 * user to create a pool with a hot spare that currently
367 * in use within another pool. Since we return B_TRUE,
368 * libdiskmgt will continue to prevent generic consumers
369 * from using the device.
371 if (ret
&& nvlist_lookup_uint64(config
,
372 ZPOOL_CONFIG_IS_SPARE
, &isspare
) == 0 && isspare
)
373 stateval
= POOL_STATE_SPARE
;
378 stateval
= POOL_STATE_POTENTIALLY_ACTIVE
;
383 case POOL_STATE_SPARE
:
385 * For a hot spare, it can be either definitively in use, or
386 * potentially active. To determine if it's in use, we iterate
387 * over all pools in the system and search for one with a spare
388 * with a matching guid.
390 * Due to the shared nature of spares, we don't actually report
391 * the potentially active case as in use. This means the user
392 * can freely create pools on the hot spares of exported pools,
393 * but to do otherwise makes the resulting code complicated, and
394 * we end up having to deal with this case anyway.
397 cb
.cb_guid
= vdev_guid
;
398 cb
.cb_type
= ZPOOL_CONFIG_SPARES
;
399 if (zpool_iter(hdl
, find_aux
, &cb
) == 1) {
400 name
= (char *)zpool_get_name(cb
.cb_zhp
);
407 case POOL_STATE_L2CACHE
:
410 * Check if any pool is currently using this l2cache device.
413 cb
.cb_guid
= vdev_guid
;
414 cb
.cb_type
= ZPOOL_CONFIG_L2CACHE
;
415 if (zpool_iter(hdl
, find_aux
, &cb
) == 1) {
416 name
= (char *)zpool_get_name(cb
.cb_zhp
);
429 *namestr
= zfs_strdup(hdl
, name
);
430 *state
= (pool_state_t
)stateval
;
434 zpool_close(cb
.cb_zhp
);