8322 nl: misleading-indentation
[unleashed/tickless.git] / usr / src / cmd / fm / schemes / zfs / scheme.c
blobb52760c537485288fd8544d1a84264a6357efc94
1 /*
2 * CDDL HEADER START
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]
19 * CDDL HEADER END
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>
29 #include <strings.h>
30 #include <libzfs.h>
32 typedef struct cbdata {
33 uint64_t cb_guid;
34 zpool_handle_t *cb_pool;
35 } cbdata_t;
37 libzfs_handle_t *g_zfs;
39 static int
40 find_pool(zpool_handle_t *zhp, void *data)
42 cbdata_t *cbp = data;
44 if (zpool_get_prop_int(zhp, ZPOOL_PROP_GUID, NULL) == cbp->cb_guid) {
45 cbp->cb_pool = zhp;
46 return (1);
49 zpool_close(zhp);
51 return (0);
54 ssize_t
55 fmd_fmri_nvl2str(nvlist_t *nvl, char *buf, size_t buflen)
57 uint64_t pool_guid, vdev_guid;
58 cbdata_t cb;
59 ssize_t len;
60 const char *name;
61 char guidbuf[64];
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;
69 cb.cb_pool = NULL;
71 if (zpool_iter(g_zfs, find_pool, &cb) == 1) {
72 name = zpool_get_name(cb.cb_pool);
73 } else {
74 (void) snprintf(guidbuf, sizeof (guidbuf), "%llx", pool_guid);
75 name = guidbuf;
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);
81 else
82 len = snprintf(buf, buflen, "%s://pool=%s",
83 FM_FMRI_SCHEME_ZFS, name);
85 if (cb.cb_pool)
86 zpool_close(cb.cb_pool);
88 return (len);
91 static nvlist_t *
92 find_vdev_iter(nvlist_t *nv, uint64_t search)
94 uint_t c, children;
95 nvlist_t **child;
96 uint64_t guid;
97 nvlist_t *ret;
99 (void) nvlist_lookup_uint64(nv, ZPOOL_CONFIG_GUID, &guid);
101 if (search == guid)
102 return (nv);
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)
109 return (ret);
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)
117 return (ret);
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)
125 return (ret);
128 return (NULL);
131 static nvlist_t *
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;
147 cbdata_t cb;
148 int ret;
150 (void) nvlist_lookup_uint64(nvl, FM_FMRI_ZFS_POOL, &pool_guid);
152 cb.cb_guid = pool_guid;
153 cb.cb_pool = NULL;
155 if (zpool_iter(g_zfs, find_pool, &cb) != 1)
156 return (0);
158 if (nvlist_lookup_uint64(nvl, FM_FMRI_ZFS_VDEV, &vdev_guid) != 0) {
159 zpool_close(cb.cb_pool);
160 return (1);
163 ret = (find_vdev(cb.cb_pool, vdev_guid) != NULL);
165 zpool_close(cb.cb_pool);
167 return (ret);
171 fmd_fmri_replaced(nvlist_t *nvl)
173 uint64_t pool_guid, vdev_guid;
174 cbdata_t cb;
175 int ret;
177 (void) nvlist_lookup_uint64(nvl, FM_FMRI_ZFS_POOL, &pool_guid);
179 cb.cb_guid = pool_guid;
180 cb.cb_pool = NULL;
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);
195 return (ret);
199 fmd_fmri_unusable(nvlist_t *nvl)
201 uint64_t pool_guid, vdev_guid;
202 cbdata_t cb;
203 nvlist_t *vd;
204 int ret;
206 (void) nvlist_lookup_uint64(nvl, FM_FMRI_ZFS_POOL, &pool_guid);
208 cb.cb_guid = pool_guid;
209 cb.cb_pool = NULL;
211 if (zpool_iter(g_zfs, find_pool, &cb) != 1)
212 return (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);
217 return (ret);
220 vd = find_vdev(cb.cb_pool, vdev_guid);
221 if (vd == NULL) {
222 ret = 1;
223 } else {
224 vdev_stat_t *vs;
225 uint_t c;
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);
235 return (ret);
239 fmd_fmri_init(void)
241 g_zfs = libzfs_init();
243 if (g_zfs == NULL)
244 return (-1);
245 else
246 return (0);
249 void
250 fmd_fmri_fini(void)
252 if (g_zfs)
253 libzfs_fini(g_zfs);