comparison usr/src/cmd/fm/schemes/zfs/scheme.c @ 0:c9caec207d52 b86

Initial porting based on b86
author Koji Uno <koji.uno@sun.com>
date Tue, 02 Jun 2009 18:56:50 +0900
parents
children 1a15d5aaf794
comparison
equal deleted inserted replaced
-1:000000000000 0:c9caec207d52
1 /*
2 * CDDL HEADER START
3 *
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.
7 *
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.
12 *
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]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
24 */
25
26 #pragma ident "@(#)scheme.c 1.3 07/09/18 SMI"
27
28 #include <fm/fmd_fmri.h>
29 #include <strings.h>
30 #include <libzfs.h>
31
32 typedef struct cbdata {
33 uint64_t cb_guid;
34 zpool_handle_t *cb_pool;
35 } cbdata_t;
36
37 libzfs_handle_t *g_zfs;
38
39 static int
40 find_pool(zpool_handle_t *zhp, void *data)
41 {
42 cbdata_t *cbp = data;
43
44 if (zpool_get_prop_int(zhp, ZPOOL_PROP_GUID, NULL) == cbp->cb_guid) {
45 cbp->cb_pool = zhp;
46 return (1);
47 }
48
49 zpool_close(zhp);
50
51 return (0);
52 }
53
54 ssize_t
55 fmd_fmri_nvl2str(nvlist_t *nvl, char *buf, size_t buflen)
56 {
57 uint64_t pool_guid, vdev_guid;
58 cbdata_t cb;
59 ssize_t len;
60 const char *name;
61 char guidbuf[64];
62
63 (void) nvlist_lookup_uint64(nvl, FM_FMRI_ZFS_POOL, &pool_guid);
64
65 /*
66 * Attempt to convert the pool guid to a name.
67 */
68 cb.cb_guid = pool_guid;
69 cb.cb_pool = NULL;
70
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;
76 }
77
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);
84
85 if (cb.cb_pool)
86 zpool_close(cb.cb_pool);
87
88 return (len);
89 }
90
91 static nvlist_t *
92 find_vdev_iter(nvlist_t *nv, uint64_t search)
93 {
94 uint_t c, children;
95 nvlist_t **child;
96 uint64_t guid;
97 nvlist_t *ret;
98
99 (void) nvlist_lookup_uint64(nv, ZPOOL_CONFIG_GUID, &guid);
100
101 if (search == guid)
102 return (nv);
103
104 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
105 &child, &children) != 0)
106 return (0);
107
108 for (c = 0; c < children; c++)
109 if ((ret = find_vdev_iter(child[c], search)) != 0)
110 return (ret);
111
112 return (NULL);
113 }
114
115 static nvlist_t *
116 find_vdev(zpool_handle_t *zhp, uint64_t guid)
117 {
118 nvlist_t *config;
119 nvlist_t *nvroot;
120
121 config = zpool_get_config(zhp, NULL);
122
123 (void) nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE, &nvroot);
124
125 return (find_vdev_iter(nvroot, guid));
126 }
127
128 int
129 fmd_fmri_present(nvlist_t *nvl)
130 {
131 uint64_t pool_guid, vdev_guid;
132 cbdata_t cb;
133 int ret;
134
135 (void) nvlist_lookup_uint64(nvl, FM_FMRI_ZFS_POOL, &pool_guid);
136
137 cb.cb_guid = pool_guid;
138 cb.cb_pool = NULL;
139
140 if (zpool_iter(g_zfs, find_pool, &cb) != 1)
141 return (0);
142
143 if (nvlist_lookup_uint64(nvl, FM_FMRI_ZFS_VDEV, &vdev_guid) != 0) {
144 zpool_close(cb.cb_pool);
145 return (1);
146 }
147
148 ret = (find_vdev(cb.cb_pool, vdev_guid) != NULL);
149
150 zpool_close(cb.cb_pool);
151
152 return (ret);
153 }
154
155 int
156 fmd_fmri_unusable(nvlist_t *nvl)
157 {
158 uint64_t pool_guid, vdev_guid;
159 cbdata_t cb;
160 nvlist_t *vd;
161 int ret;
162
163 (void) nvlist_lookup_uint64(nvl, FM_FMRI_ZFS_POOL, &pool_guid);
164
165 cb.cb_guid = pool_guid;
166 cb.cb_pool = NULL;
167
168 if (zpool_iter(g_zfs, find_pool, &cb) != 1)
169 return (1);
170
171 if (nvlist_lookup_uint64(nvl, FM_FMRI_ZFS_VDEV, &vdev_guid) != 0) {
172 ret = (zpool_get_state(cb.cb_pool) == POOL_STATE_UNAVAIL);
173 zpool_close(cb.cb_pool);
174 return (ret);
175 }
176
177 vd = find_vdev(cb.cb_pool, vdev_guid);
178 if (vd == NULL) {
179 ret = 1;
180 } else {
181 vdev_stat_t *vs;
182 uint_t c;
183
184 (void) nvlist_lookup_uint64_array(vd, ZPOOL_CONFIG_STATS,
185 (uint64_t **)&vs, &c);
186
187 ret = (vs->vs_state < VDEV_STATE_DEGRADED);
188 }
189
190 zpool_close(cb.cb_pool);
191
192 return (ret);
193 }
194
195 int
196 fmd_fmri_init(void)
197 {
198 g_zfs = libzfs_init();
199
200 if (g_zfs == NULL)
201 return (-1);
202 else
203 return (0);
204 }
205
206 void
207 fmd_fmri_fini(void)
208 {
209 if (g_zfs)
210 libzfs_fini(g_zfs);
211 }