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]
23 * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 #pragma ident "%Z%%M% %I% %E% SMI"
31 #include <libsysevent.h>
32 #include <libnvpair.h>
33 #include <sys/sysevent/svm.h>
34 #include <sys/sysevent/eventdefs.h>
38 obj2devname(uint32_t tag
, set_t setno
, md_dev64_t dev
)
42 char name
[MD_MAX_CTDLEN
];
44 md_error_t status
= mdnullerror
;
46 minor_t mnum
= meta_getminor(dev
);
50 if ((setno
!= MD_SET_BAD
) &&
51 ((sp
= metasetnosetname(setno
, &status
)) != NULL
)) {
52 setname
= sp
->setname
;
58 case SVM_TAG_METADEVICE
:
63 uname
= get_mdname(sp
, mnum
);
67 (void) strcpy(name
, uname
);
70 uname
= get_hspname(sp
, mnum
);
74 (void) strcpy(name
, uname
);
77 (void) sprintf(name
, "drive");
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");
97 if (setname
== NULL
) {
98 (void) sprintf(name
, "diskset");
100 rtn
= snprintf(name
, sizeof (name
), "%s", setname
);
104 if ((setname
= get_devname(setno
, dev
)) != NULL
) {
105 rtn
= snprintf(name
, sizeof (name
), "%s", setname
);
111 /* Check if we got any rubbish for any of the snprintf's */
112 if ((name
[0] == '\0') || (rtn
>= sizeof (name
))) {
116 return (strdup(name
));
119 /* Sysevent subclass and mdnotify event type pairs */
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
[] = {
190 ev_compare(const void *node1
, const void *node2
)
192 return (strcmp((const char *)node1
,
193 ((const struct node
*)node2
)->se_ev
));
200 do_mdnotify(char *se_subclass
, uint32_t tag
, set_t setno
, md_dev64_t devid
)
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
) {
213 ev_type
= node_ptr
->md_ev
;
216 if (tag
>= (sizeof (md_tags
) / sizeof (md_tags
[0]))) {
217 md_tag
= EVO_UNSPECIFIED
;
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
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
) {
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
) {
269 if ((_nvlist_free
== NULL
) &&
270 (_nvlist_free
= (void (*)(nvlist_t
*))dlsym(nv_handle
,
271 "nvlist_free")) == NULL
) {
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
) {
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
) {
286 if ((_nvlist_add_string
== NULL
) &&
287 (_nvlist_add_string
= (int (*)(nvlist_t
*, char *,
288 char *))dlsym(nv_handle
,
289 "nvlist_add_string")) == NULL
) {
297 if ((se_handle
!= NULL
) && (dlclose(se_handle
) == 0)) {
301 if ((nv_handle
!= NULL
) && (dlclose(nv_handle
) == 0)) {
305 _sysevent_post_event
= NULL
;
306 _nvlist_alloc
= NULL
;
308 _nvlist_add_uint32
= NULL
;
309 _nvlist_add_uint64
= NULL
;
310 _nvlist_add_string
= NULL
;
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()) {
340 err
= (*_nvlist_alloc
)(&attr_list
, NV_UNIQUE_NAME
, 0);
343 /* Add the version number */
344 err
= (*_nvlist_add_uint32
)(attr_list
, SVM_VERSION_NO
,
345 (uint32_t)SVM_VERSION
);
350 /* Add the tag attribute */
351 err
= (*_nvlist_add_uint32
)(attr_list
, SVM_TAG
, (uint32_t)tag
);
356 /* Add the set number attribute */
357 err
= (*_nvlist_add_uint32
)(attr_list
, SVM_SET_NO
,
363 /* Add the device id attribute */
364 err
= (*_nvlist_add_uint64
)(attr_list
, SVM_DEV_ID
,
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
,
377 err
= (*_nvlist_add_string
)(attr_list
, SVM_DEV_NAME
,
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
);
394 (*_nvlist_free
)(attr_list
);