7712 mandoc -Tlint does always exit with error code 0
[unleashed.git] / usr / src / lib / lvm / libmeta / common / meta_se_notify.c
blob61e4db69945e5e14ff353b59862074b49af6a2c0
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
23 * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 #pragma ident "%Z%%M% %I% %E% SMI"
29 #include <stdlib.h>
30 #include <meta.h>
31 #include <libsysevent.h>
32 #include <libnvpair.h>
33 #include <sys/sysevent/svm.h>
34 #include <sys/sysevent/eventdefs.h>
35 #include <dlfcn.h>
37 char *
38 obj2devname(uint32_t tag, set_t setno, md_dev64_t dev)
40 char *setname;
41 char *uname;
42 char name[MD_MAX_CTDLEN];
43 mdsetname_t *sp;
44 md_error_t status = mdnullerror;
45 md_set_record *md_sr;
46 minor_t mnum = meta_getminor(dev);
47 int rtn = 0;
49 setname = NULL;
50 if ((setno != MD_SET_BAD) &&
51 ((sp = metasetnosetname(setno, &status)) != NULL)) {
52 setname = sp->setname;
55 name[0] = '\0';
56 switch (tag) {
57 case SVM_TAG_HS:
58 case SVM_TAG_METADEVICE:
59 case SVM_TAG_MIRROR:
60 case SVM_TAG_RAID5:
61 case SVM_TAG_STRIPE:
62 case SVM_TAG_TRANS:
63 uname = get_mdname(sp, mnum);
64 if (uname == NULL)
65 return (NULL);
67 (void) strcpy(name, uname);
68 break;
69 case SVM_TAG_HSP:
70 uname = get_hspname(sp, mnum);
71 if (uname == NULL)
72 return (NULL);
74 (void) strcpy(name, uname);
75 break;
76 case SVM_TAG_DRIVE:
77 (void) sprintf(name, "drive");
78 break;
79 case SVM_TAG_HOST:
80 md_sr = NULL;
81 if (setname != NULL) {
82 md_sr = getsetbyname(setname, &status);
84 if ((md_sr != NULL) && (md_sr->sr_nodes[mnum] != NULL)) {
86 * Get the host data from the node array.
88 rtn = snprintf(name, sizeof (name), "%s",
89 md_sr->sr_nodes[mnum]);
91 if ((name[0] == '\0') || (rtn >= sizeof (name))) {
92 (void) sprintf(name, "host");
93 rtn = 0;
95 break;
96 case SVM_TAG_SET:
97 if (setname == NULL) {
98 (void) sprintf(name, "diskset");
99 } else {
100 rtn = snprintf(name, sizeof (name), "%s", setname);
102 break;
103 default:
104 if ((setname = get_devname(setno, dev)) != NULL) {
105 rtn = snprintf(name, sizeof (name), "%s", setname);
107 break;
109 mdclrerror(&status);
111 /* Check if we got any rubbish for any of the snprintf's */
112 if ((name[0] == '\0') || (rtn >= sizeof (name))) {
113 return (NULL);
116 return (strdup(name));
119 /* Sysevent subclass and mdnotify event type pairs */
120 struct node {
121 char *se_ev;
122 evid_t md_ev;
125 /* Table must be sorted in ascending order */
126 static struct node ev_table[] = {
127 { ESC_SVM_ADD, EV_ADD },
128 { ESC_SVM_ATTACH, EV_ATTACH },
129 { ESC_SVM_ATTACHING, EV_ATTACHING },
130 { ESC_SVM_CHANGE, EV_CHANGE },
131 { ESC_SVM_CREATE, EV_CREATE },
132 { ESC_SVM_DELETE, EV_DELETE },
133 { ESC_SVM_DETACH, EV_DETACH },
134 { ESC_SVM_DETACHING, EV_DETACHING },
135 { ESC_SVM_DRIVE_ADD, EV_DRIVE_ADD },
136 { ESC_SVM_DRIVE_DELETE, EV_DRIVE_DELETE },
137 { ESC_SVM_ENABLE, EV_ENABLE },
138 { ESC_SVM_ERRED, EV_ERRED },
139 { ESC_SVM_EXCHANGE, EV_EXCHANGE },
140 { ESC_SVM_GROW, EV_GROW },
141 { ESC_SVM_HS_CHANGED, EV_HS_CHANGED },
142 { ESC_SVM_HS_FREED, EV_HS_FREED },
143 { ESC_SVM_HOST_ADD, EV_HOST_ADD },
144 { ESC_SVM_HOST_DELETE, EV_HOST_DELETE },
145 { ESC_SVM_HOTSPARED, EV_HOTSPARED },
146 { ESC_SVM_INIT_FAILED, EV_INIT_FAILED },
147 { ESC_SVM_INIT_FATAL, EV_INIT_FATAL },
148 { ESC_SVM_INIT_START, EV_INIT_START },
149 { ESC_SVM_INIT_SUCCESS, EV_INIT_SUCCESS },
150 { ESC_SVM_IOERR, EV_IOERR },
151 { ESC_SVM_LASTERRED, EV_LASTERRED },
152 { ESC_SVM_MEDIATOR_ADD, EV_MEDIATOR_ADD },
153 { ESC_SVM_MEDIATOR_DELETE, EV_MEDIATOR_DELETE },
154 { ESC_SVM_OFFLINE, EV_OFFLINE },
155 { ESC_SVM_OK, EV_OK },
156 { ESC_SVM_ONLINE, EV_ONLINE },
157 { ESC_SVM_OPEN_FAIL, EV_OPEN_FAIL },
158 { ESC_SVM_REGEN_DONE, EV_REGEN_DONE },
159 { ESC_SVM_REGEN_FAILED, EV_REGEN_FAILED },
160 { ESC_SVM_REGEN_START, EV_REGEN_START },
161 { ESC_SVM_RELEASE, EV_RELEASE },
162 { ESC_SVM_REMOVE, EV_REMOVE },
163 { ESC_SVM_RENAME_DST, EV_RENAME_DST },
164 { ESC_SVM_RENAME_SRC, EV_RENAME_SRC },
165 { ESC_SVM_REPLACE, EV_REPLACE },
166 { ESC_SVM_RESYNC_DONE, EV_RESYNC_DONE },
167 { ESC_SVM_RESYNC_FAILED, EV_RESYNC_FAILED },
168 { ESC_SVM_RESYNC_START, EV_RESYNC_START },
169 { ESC_SVM_RESYNC_SUCCESS, EV_RESYNC_SUCCESS },
170 { ESC_SVM_TAKEOVER, EV_TAKEOVER }
173 static ev_obj_t md_tags[] = {
174 EVO_UNSPECIFIED,
175 EVO_METADEV,
176 EVO_MIRROR,
177 EVO_STRIPE,
178 EVO_RAID5,
179 EVO_TRANS,
180 EVO_REPLICA,
181 EVO_HSP,
182 EVO_HS,
183 EVO_SET,
184 EVO_DRIVE,
185 EVO_HOST,
186 EVO_MEDIATOR
189 static int
190 ev_compare(const void *node1, const void *node2)
192 return (strcmp((const char *)node1,
193 ((const struct node *)node2)->se_ev));
197 * Log mdnotify event
199 void
200 do_mdnotify(char *se_subclass, uint32_t tag, set_t setno, md_dev64_t devid)
202 evid_t ev_type;
203 ev_obj_t md_tag;
204 struct node *node_ptr;
206 /* Translate sysevent into mdnotify event */
207 node_ptr = bsearch(se_subclass, ev_table, (sizeof (ev_table) /
208 sizeof (ev_table[0])), sizeof (ev_table[0]), ev_compare);
210 if (node_ptr == NULL) {
211 ev_type = EV_EMPTY;
212 } else {
213 ev_type = node_ptr->md_ev;
216 if (tag >= (sizeof (md_tags) / sizeof (md_tags[0]))) {
217 md_tag = EVO_UNSPECIFIED;
218 } else {
219 md_tag = md_tags[tag];
222 NOTIFY_MD(md_tag, setno, devid, ev_type);
226 * External symbols from libsysevent and libnvpair which are not
227 * available in static forms
229 static void *se_handle = NULL, *nv_handle = NULL;
230 static int (*_sysevent_post_event)(char *, char *, char *, char *,
231 nvlist_t *, sysevent_id_t *) = NULL;
232 static int (*_nvlist_alloc)(nvlist_t **, uint_t, int) = NULL;
233 static void (*_nvlist_free)(nvlist_t *) = NULL;
234 static int (*_nvlist_add_uint32)(nvlist_t *, char *, uint32_t) = NULL;
235 static int (*_nvlist_add_uint64)(nvlist_t *, char *, uint64_t) = NULL;
236 static int (*_nvlist_add_string)(nvlist_t *, char *, char *) = NULL;
239 * Load nvpair and sysevent symbols
241 static int
242 load_sev_lib()
244 /* Try to load the sysevent symbol */
245 if (se_handle == NULL) {
246 se_handle = dlopen("/usr/lib/libsysevent.so.1", RTLD_LAZY);
248 if (se_handle != NULL) {
249 if ((_sysevent_post_event == NULL) &&
250 (_sysevent_post_event = (int (*)(char *, char *, char *,
251 char *, nvlist_t *, sysevent_id_t *))
252 dlsym(se_handle, "sysevent_post_event")) == NULL) {
253 goto out;
255 } else {
256 return (1);
259 /* Try to load the nvpair symbols */
260 if (nv_handle == NULL) {
261 nv_handle = dlopen("/usr/lib/libnvpair.so.1", RTLD_LAZY);
263 if (nv_handle != NULL) {
264 if ((_nvlist_alloc == NULL) &&
265 (_nvlist_alloc = (int (*)(nvlist_t **, uint_t, int))
266 dlsym(nv_handle, "nvlist_alloc")) == NULL) {
267 goto out;
269 if ((_nvlist_free == NULL) &&
270 (_nvlist_free = (void (*)(nvlist_t *))dlsym(nv_handle,
271 "nvlist_free")) == NULL) {
272 goto out;
274 if ((_nvlist_add_uint32 == NULL) &&
275 (_nvlist_add_uint32 = (int (*)(nvlist_t *, char *,
276 uint32_t))dlsym(nv_handle,
277 "nvlist_add_uint32")) == NULL) {
278 goto out;
280 if ((_nvlist_add_uint64 == NULL) &&
281 (_nvlist_add_uint64 = (int (*)(nvlist_t *, char *,
282 uint64_t))dlsym(nv_handle,
283 "nvlist_add_uint64")) == NULL) {
284 goto out;
286 if ((_nvlist_add_string == NULL) &&
287 (_nvlist_add_string = (int (*)(nvlist_t *, char *,
288 char *))dlsym(nv_handle,
289 "nvlist_add_string")) == NULL) {
290 goto out;
293 return (0);
296 out:
297 if ((se_handle != NULL) && (dlclose(se_handle) == 0)) {
298 se_handle = NULL;
301 if ((nv_handle != NULL) && (dlclose(nv_handle) == 0)) {
302 nv_handle = NULL;
305 _sysevent_post_event = NULL;
306 _nvlist_alloc = NULL;
307 _nvlist_free = NULL;
308 _nvlist_add_uint32 = NULL;
309 _nvlist_add_uint64 = NULL;
310 _nvlist_add_string = NULL;
312 return (1);
316 * Log SVM sys events
318 void
319 meta_svm_sysevent(
320 char *se_class,
321 char *se_subclass,
322 uint32_t tag,
323 set_t setno,
324 md_dev64_t devid
327 sysevent_id_t eid;
328 nvlist_t *attr_list;
329 int err = 0;
330 char *devname;
332 /* Raise the mdnotify event before anything else */
333 do_mdnotify(se_subclass, tag, setno, devid);
335 /* Just get out if the sysevent symbol can't be loaded */
336 if (load_sev_lib()) {
337 return;
340 err = (*_nvlist_alloc)(&attr_list, NV_UNIQUE_NAME, 0);
342 if (err == 0) {
343 /* Add the version number */
344 err = (*_nvlist_add_uint32)(attr_list, SVM_VERSION_NO,
345 (uint32_t)SVM_VERSION);
346 if (err != 0) {
347 goto fail;
350 /* Add the tag attribute */
351 err = (*_nvlist_add_uint32)(attr_list, SVM_TAG, (uint32_t)tag);
352 if (err != 0) {
353 goto fail;
356 /* Add the set number attribute */
357 err = (*_nvlist_add_uint32)(attr_list, SVM_SET_NO,
358 (uint32_t)setno);
359 if (err != 0) {
360 goto fail;
363 /* Add the device id attribute */
364 err = (*_nvlist_add_uint64)(attr_list, SVM_DEV_ID,
365 (uint64_t)devid);
366 if (err != 0) {
367 goto fail;
370 /* Add the device name attribute */
371 devname = obj2devname(tag, setno, devid);
372 if (devname != NULL) {
373 err = (*_nvlist_add_string)(attr_list, SVM_DEV_NAME,
374 devname);
375 free(devname);
376 } else {
377 err = (*_nvlist_add_string)(attr_list, SVM_DEV_NAME,
378 "unspecified");
380 if (err != 0) {
381 goto fail;
384 /* Attempt to post event */
385 (void) (*_sysevent_post_event)(se_class, se_subclass,
386 SUNW_VENDOR, EP_SVM, attr_list, &eid);
388 (*_nvlist_free)(attr_list);
391 return;
393 fail:
394 (*_nvlist_free)(attr_list);