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]
22 * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
25 * Copyright 2010 Nexenta Systems, Inc. All rights reserved.
28 #include <fm/fmd_fmri.h>
32 typedef struct cbdata
{
34 zpool_handle_t
*cb_pool
;
37 libzfs_handle_t
*g_zfs
;
40 find_pool(zpool_handle_t
*zhp
, void *data
)
44 if (zpool_get_prop_int(zhp
, ZPOOL_PROP_GUID
, NULL
) == cbp
->cb_guid
) {
55 fmd_fmri_nvl2str(nvlist_t
*nvl
, char *buf
, size_t buflen
)
57 uint64_t pool_guid
, vdev_guid
;
63 (void) nvlist_lookup_uint64(nvl
, FM_FMRI_ZFS_POOL
, &pool_guid
);
66 * Attempt to convert the pool guid to a name.
68 cb
.cb_guid
= pool_guid
;
71 if (zpool_iter(g_zfs
, find_pool
, &cb
) == 1) {
72 name
= zpool_get_name(cb
.cb_pool
);
74 (void) snprintf(guidbuf
, sizeof (guidbuf
), "%llx", pool_guid
);
78 if (nvlist_lookup_uint64(nvl
, FM_FMRI_ZFS_VDEV
, &vdev_guid
) == 0)
79 len
= snprintf(buf
, buflen
, "%s://pool=%s/vdev=%llx",
80 FM_FMRI_SCHEME_ZFS
, name
, vdev_guid
);
82 len
= snprintf(buf
, buflen
, "%s://pool=%s",
83 FM_FMRI_SCHEME_ZFS
, name
);
86 zpool_close(cb
.cb_pool
);
92 find_vdev_iter(nvlist_t
*nv
, uint64_t search
)
99 (void) nvlist_lookup_uint64(nv
, ZPOOL_CONFIG_GUID
, &guid
);
104 if (nvlist_lookup_nvlist_array(nv
, ZPOOL_CONFIG_CHILDREN
,
105 &child
, &children
) == 0) {
107 for (c
= 0; c
< children
; c
++)
108 if ((ret
= find_vdev_iter(child
[c
], search
)) != 0)
112 if (nvlist_lookup_nvlist_array(nv
, ZPOOL_CONFIG_L2CACHE
,
113 &child
, &children
) == 0) {
115 for (c
= 0; c
< children
; c
++)
116 if ((ret
= find_vdev_iter(child
[c
], search
)) != 0)
120 if (nvlist_lookup_nvlist_array(nv
, ZPOOL_CONFIG_SPARES
,
121 &child
, &children
) == 0) {
123 for (c
= 0; c
< children
; c
++)
124 if ((ret
= find_vdev_iter(child
[c
], search
)) != 0)
132 find_vdev(zpool_handle_t
*zhp
, uint64_t guid
)
134 nvlist_t
*config
, *nvroot
;
136 config
= zpool_get_config(zhp
, NULL
);
138 (void) nvlist_lookup_nvlist(config
, ZPOOL_CONFIG_VDEV_TREE
, &nvroot
);
140 return (find_vdev_iter(nvroot
, guid
));
144 fmd_fmri_present(nvlist_t
*nvl
)
146 uint64_t pool_guid
, vdev_guid
;
150 (void) nvlist_lookup_uint64(nvl
, FM_FMRI_ZFS_POOL
, &pool_guid
);
152 cb
.cb_guid
= pool_guid
;
155 if (zpool_iter(g_zfs
, find_pool
, &cb
) != 1)
158 if (nvlist_lookup_uint64(nvl
, FM_FMRI_ZFS_VDEV
, &vdev_guid
) != 0) {
159 zpool_close(cb
.cb_pool
);
163 ret
= (find_vdev(cb
.cb_pool
, vdev_guid
) != NULL
);
165 zpool_close(cb
.cb_pool
);
171 fmd_fmri_replaced(nvlist_t
*nvl
)
173 uint64_t pool_guid
, vdev_guid
;
177 (void) nvlist_lookup_uint64(nvl
, FM_FMRI_ZFS_POOL
, &pool_guid
);
179 cb
.cb_guid
= pool_guid
;
182 if (zpool_iter(g_zfs
, find_pool
, &cb
) != 1)
183 return (FMD_OBJ_STATE_NOT_PRESENT
);
185 if (nvlist_lookup_uint64(nvl
, FM_FMRI_ZFS_VDEV
, &vdev_guid
) != 0) {
186 zpool_close(cb
.cb_pool
);
187 return (FMD_OBJ_STATE_STILL_PRESENT
);
190 ret
= (find_vdev(cb
.cb_pool
, vdev_guid
) != NULL
) ?
191 FMD_OBJ_STATE_STILL_PRESENT
: FMD_OBJ_STATE_NOT_PRESENT
;
193 zpool_close(cb
.cb_pool
);
199 fmd_fmri_unusable(nvlist_t
*nvl
)
201 uint64_t pool_guid
, vdev_guid
;
206 (void) nvlist_lookup_uint64(nvl
, FM_FMRI_ZFS_POOL
, &pool_guid
);
208 cb
.cb_guid
= pool_guid
;
211 if (zpool_iter(g_zfs
, find_pool
, &cb
) != 1)
214 if (nvlist_lookup_uint64(nvl
, FM_FMRI_ZFS_VDEV
, &vdev_guid
) != 0) {
215 ret
= (zpool_get_state(cb
.cb_pool
) == POOL_STATE_UNAVAIL
);
216 zpool_close(cb
.cb_pool
);
220 vd
= find_vdev(cb
.cb_pool
, vdev_guid
);
227 (void) nvlist_lookup_uint64_array(vd
, ZPOOL_CONFIG_VDEV_STATS
,
228 (uint64_t **)&vs
, &c
);
230 ret
= (vs
->vs_state
< VDEV_STATE_DEGRADED
);
233 zpool_close(cb
.cb_pool
);
241 g_zfs
= libzfs_init();