10Sstevel@tonic-gate /*
20Sstevel@tonic-gate * CDDL HEADER START
30Sstevel@tonic-gate *
40Sstevel@tonic-gate * The contents of this file are subject to the terms of the
5*1623Stw21770 * Common Development and Distribution License (the "License").
6*1623Stw21770 * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate *
80Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate * See the License for the specific language governing permissions
110Sstevel@tonic-gate * and limitations under the License.
120Sstevel@tonic-gate *
130Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate *
190Sstevel@tonic-gate * CDDL HEADER END
200Sstevel@tonic-gate */
210Sstevel@tonic-gate
220Sstevel@tonic-gate /*
23*1623Stw21770 * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
240Sstevel@tonic-gate * Use is subject to license terms.
250Sstevel@tonic-gate */
260Sstevel@tonic-gate
270Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI"
280Sstevel@tonic-gate
290Sstevel@tonic-gate #include <stdlib.h>
300Sstevel@tonic-gate #include <meta.h>
310Sstevel@tonic-gate #include <libsysevent.h>
320Sstevel@tonic-gate #include <libnvpair.h>
330Sstevel@tonic-gate #include <sys/sysevent/svm.h>
340Sstevel@tonic-gate #include <sys/sysevent/eventdefs.h>
350Sstevel@tonic-gate #include <dlfcn.h>
360Sstevel@tonic-gate
370Sstevel@tonic-gate char *
obj2devname(uint32_t tag,set_t setno,md_dev64_t dev)380Sstevel@tonic-gate obj2devname(uint32_t tag, set_t setno, md_dev64_t dev)
390Sstevel@tonic-gate {
400Sstevel@tonic-gate char *setname;
41*1623Stw21770 char *uname;
420Sstevel@tonic-gate char name[MD_MAX_CTDLEN];
430Sstevel@tonic-gate mdsetname_t *sp;
440Sstevel@tonic-gate md_error_t status = mdnullerror;
450Sstevel@tonic-gate md_set_record *md_sr;
460Sstevel@tonic-gate minor_t mnum = meta_getminor(dev);
470Sstevel@tonic-gate int rtn = 0;
480Sstevel@tonic-gate
490Sstevel@tonic-gate setname = NULL;
500Sstevel@tonic-gate if ((setno != MD_SET_BAD) &&
510Sstevel@tonic-gate ((sp = metasetnosetname(setno, &status)) != NULL)) {
520Sstevel@tonic-gate setname = sp->setname;
530Sstevel@tonic-gate }
540Sstevel@tonic-gate
550Sstevel@tonic-gate name[0] = '\0';
560Sstevel@tonic-gate switch (tag) {
570Sstevel@tonic-gate case SVM_TAG_HS:
580Sstevel@tonic-gate case SVM_TAG_METADEVICE:
590Sstevel@tonic-gate case SVM_TAG_MIRROR:
600Sstevel@tonic-gate case SVM_TAG_RAID5:
610Sstevel@tonic-gate case SVM_TAG_STRIPE:
620Sstevel@tonic-gate case SVM_TAG_TRANS:
63*1623Stw21770 uname = get_mdname(sp, mnum);
64*1623Stw21770 if (uname == NULL)
65*1623Stw21770 return (NULL);
66*1623Stw21770
67*1623Stw21770 (void) strcpy(name, uname);
680Sstevel@tonic-gate break;
690Sstevel@tonic-gate case SVM_TAG_HSP:
70*1623Stw21770 uname = get_hspname(sp, mnum);
71*1623Stw21770 if (uname == NULL)
72*1623Stw21770 return (NULL);
73*1623Stw21770
74*1623Stw21770 (void) strcpy(name, uname);
750Sstevel@tonic-gate break;
760Sstevel@tonic-gate case SVM_TAG_DRIVE:
770Sstevel@tonic-gate (void) sprintf(name, "drive");
780Sstevel@tonic-gate break;
790Sstevel@tonic-gate case SVM_TAG_HOST:
800Sstevel@tonic-gate md_sr = NULL;
810Sstevel@tonic-gate if (setname != NULL) {
820Sstevel@tonic-gate md_sr = getsetbyname(setname, &status);
830Sstevel@tonic-gate }
840Sstevel@tonic-gate if ((md_sr != NULL) && (md_sr->sr_nodes[mnum] != NULL)) {
850Sstevel@tonic-gate /*
860Sstevel@tonic-gate * Get the host data from the node array.
870Sstevel@tonic-gate */
880Sstevel@tonic-gate rtn = snprintf(name, sizeof (name), "%s",
890Sstevel@tonic-gate md_sr->sr_nodes[mnum]);
900Sstevel@tonic-gate }
910Sstevel@tonic-gate if ((name[0] == '\0') || (rtn >= sizeof (name))) {
920Sstevel@tonic-gate (void) sprintf(name, "host");
930Sstevel@tonic-gate rtn = 0;
940Sstevel@tonic-gate }
950Sstevel@tonic-gate break;
960Sstevel@tonic-gate case SVM_TAG_SET:
970Sstevel@tonic-gate if (setname == NULL) {
980Sstevel@tonic-gate (void) sprintf(name, "diskset");
990Sstevel@tonic-gate } else {
1000Sstevel@tonic-gate rtn = snprintf(name, sizeof (name), "%s", setname);
1010Sstevel@tonic-gate }
1020Sstevel@tonic-gate break;
1030Sstevel@tonic-gate default:
1040Sstevel@tonic-gate if ((setname = get_devname(setno, dev)) != NULL) {
1050Sstevel@tonic-gate rtn = snprintf(name, sizeof (name), "%s", setname);
1060Sstevel@tonic-gate }
1070Sstevel@tonic-gate break;
1080Sstevel@tonic-gate }
1090Sstevel@tonic-gate mdclrerror(&status);
1100Sstevel@tonic-gate
1110Sstevel@tonic-gate /* Check if we got any rubbish for any of the snprintf's */
1120Sstevel@tonic-gate if ((name[0] == '\0') || (rtn >= sizeof (name))) {
1130Sstevel@tonic-gate return (NULL);
1140Sstevel@tonic-gate }
1150Sstevel@tonic-gate
1160Sstevel@tonic-gate return (strdup(name));
1170Sstevel@tonic-gate }
1180Sstevel@tonic-gate
1190Sstevel@tonic-gate /* Sysevent subclass and mdnotify event type pairs */
1200Sstevel@tonic-gate struct node {
1210Sstevel@tonic-gate char *se_ev;
1220Sstevel@tonic-gate evid_t md_ev;
1230Sstevel@tonic-gate };
1240Sstevel@tonic-gate
1250Sstevel@tonic-gate /* Table must be sorted in ascending order */
1260Sstevel@tonic-gate static struct node ev_table[] = {
1270Sstevel@tonic-gate { ESC_SVM_ADD, EV_ADD },
1280Sstevel@tonic-gate { ESC_SVM_ATTACH, EV_ATTACH },
1290Sstevel@tonic-gate { ESC_SVM_ATTACHING, EV_ATTACHING },
1300Sstevel@tonic-gate { ESC_SVM_CHANGE, EV_CHANGE },
1310Sstevel@tonic-gate { ESC_SVM_CREATE, EV_CREATE },
1320Sstevel@tonic-gate { ESC_SVM_DELETE, EV_DELETE },
1330Sstevel@tonic-gate { ESC_SVM_DETACH, EV_DETACH },
1340Sstevel@tonic-gate { ESC_SVM_DETACHING, EV_DETACHING },
1350Sstevel@tonic-gate { ESC_SVM_DRIVE_ADD, EV_DRIVE_ADD },
1360Sstevel@tonic-gate { ESC_SVM_DRIVE_DELETE, EV_DRIVE_DELETE },
1370Sstevel@tonic-gate { ESC_SVM_ENABLE, EV_ENABLE },
1380Sstevel@tonic-gate { ESC_SVM_ERRED, EV_ERRED },
1390Sstevel@tonic-gate { ESC_SVM_EXCHANGE, EV_EXCHANGE },
1400Sstevel@tonic-gate { ESC_SVM_GROW, EV_GROW },
1410Sstevel@tonic-gate { ESC_SVM_HS_CHANGED, EV_HS_CHANGED },
1420Sstevel@tonic-gate { ESC_SVM_HS_FREED, EV_HS_FREED },
1430Sstevel@tonic-gate { ESC_SVM_HOST_ADD, EV_HOST_ADD },
1440Sstevel@tonic-gate { ESC_SVM_HOST_DELETE, EV_HOST_DELETE },
1450Sstevel@tonic-gate { ESC_SVM_HOTSPARED, EV_HOTSPARED },
1460Sstevel@tonic-gate { ESC_SVM_INIT_FAILED, EV_INIT_FAILED },
1470Sstevel@tonic-gate { ESC_SVM_INIT_FATAL, EV_INIT_FATAL },
1480Sstevel@tonic-gate { ESC_SVM_INIT_START, EV_INIT_START },
1490Sstevel@tonic-gate { ESC_SVM_INIT_SUCCESS, EV_INIT_SUCCESS },
1500Sstevel@tonic-gate { ESC_SVM_IOERR, EV_IOERR },
1510Sstevel@tonic-gate { ESC_SVM_LASTERRED, EV_LASTERRED },
1520Sstevel@tonic-gate { ESC_SVM_MEDIATOR_ADD, EV_MEDIATOR_ADD },
1530Sstevel@tonic-gate { ESC_SVM_MEDIATOR_DELETE, EV_MEDIATOR_DELETE },
1540Sstevel@tonic-gate { ESC_SVM_OFFLINE, EV_OFFLINE },
1550Sstevel@tonic-gate { ESC_SVM_OK, EV_OK },
1560Sstevel@tonic-gate { ESC_SVM_ONLINE, EV_ONLINE },
1570Sstevel@tonic-gate { ESC_SVM_OPEN_FAIL, EV_OPEN_FAIL },
1580Sstevel@tonic-gate { ESC_SVM_REGEN_DONE, EV_REGEN_DONE },
1590Sstevel@tonic-gate { ESC_SVM_REGEN_FAILED, EV_REGEN_FAILED },
1600Sstevel@tonic-gate { ESC_SVM_REGEN_START, EV_REGEN_START },
1610Sstevel@tonic-gate { ESC_SVM_RELEASE, EV_RELEASE },
1620Sstevel@tonic-gate { ESC_SVM_REMOVE, EV_REMOVE },
1630Sstevel@tonic-gate { ESC_SVM_RENAME_DST, EV_RENAME_DST },
1640Sstevel@tonic-gate { ESC_SVM_RENAME_SRC, EV_RENAME_SRC },
1650Sstevel@tonic-gate { ESC_SVM_REPLACE, EV_REPLACE },
1660Sstevel@tonic-gate { ESC_SVM_RESYNC_DONE, EV_RESYNC_DONE },
1670Sstevel@tonic-gate { ESC_SVM_RESYNC_FAILED, EV_RESYNC_FAILED },
1680Sstevel@tonic-gate { ESC_SVM_RESYNC_START, EV_RESYNC_START },
1690Sstevel@tonic-gate { ESC_SVM_RESYNC_SUCCESS, EV_RESYNC_SUCCESS },
1700Sstevel@tonic-gate { ESC_SVM_TAKEOVER, EV_TAKEOVER }
1710Sstevel@tonic-gate };
1720Sstevel@tonic-gate
1730Sstevel@tonic-gate static ev_obj_t md_tags[] = {
1740Sstevel@tonic-gate EVO_UNSPECIFIED,
1750Sstevel@tonic-gate EVO_METADEV,
1760Sstevel@tonic-gate EVO_MIRROR,
1770Sstevel@tonic-gate EVO_STRIPE,
1780Sstevel@tonic-gate EVO_RAID5,
1790Sstevel@tonic-gate EVO_TRANS,
1800Sstevel@tonic-gate EVO_REPLICA,
1810Sstevel@tonic-gate EVO_HSP,
1820Sstevel@tonic-gate EVO_HS,
1830Sstevel@tonic-gate EVO_SET,
1840Sstevel@tonic-gate EVO_DRIVE,
1850Sstevel@tonic-gate EVO_HOST,
1860Sstevel@tonic-gate EVO_MEDIATOR
1870Sstevel@tonic-gate };
1880Sstevel@tonic-gate
1890Sstevel@tonic-gate static int
ev_compare(const void * node1,const void * node2)1900Sstevel@tonic-gate ev_compare(const void *node1, const void *node2)
1910Sstevel@tonic-gate {
1920Sstevel@tonic-gate return (strcmp((const char *)node1,
1930Sstevel@tonic-gate ((const struct node *)node2)->se_ev));
1940Sstevel@tonic-gate }
1950Sstevel@tonic-gate
1960Sstevel@tonic-gate /*
1970Sstevel@tonic-gate * Log mdnotify event
1980Sstevel@tonic-gate */
1990Sstevel@tonic-gate void
do_mdnotify(char * se_subclass,uint32_t tag,set_t setno,md_dev64_t devid)2000Sstevel@tonic-gate do_mdnotify(char *se_subclass, uint32_t tag, set_t setno, md_dev64_t devid)
2010Sstevel@tonic-gate {
2020Sstevel@tonic-gate evid_t ev_type;
2030Sstevel@tonic-gate ev_obj_t md_tag;
2040Sstevel@tonic-gate struct node *node_ptr;
2050Sstevel@tonic-gate
2060Sstevel@tonic-gate /* Translate sysevent into mdnotify event */
2070Sstevel@tonic-gate node_ptr = bsearch(se_subclass, ev_table, (sizeof (ev_table) /
2080Sstevel@tonic-gate sizeof (ev_table[0])), sizeof (ev_table[0]), ev_compare);
2090Sstevel@tonic-gate
2100Sstevel@tonic-gate if (node_ptr == NULL) {
2110Sstevel@tonic-gate ev_type = EV_EMPTY;
2120Sstevel@tonic-gate } else {
2130Sstevel@tonic-gate ev_type = node_ptr->md_ev;
2140Sstevel@tonic-gate }
2150Sstevel@tonic-gate
2160Sstevel@tonic-gate if (tag >= (sizeof (md_tags) / sizeof (md_tags[0]))) {
2170Sstevel@tonic-gate md_tag = EVO_UNSPECIFIED;
2180Sstevel@tonic-gate } else {
2190Sstevel@tonic-gate md_tag = md_tags[tag];
2200Sstevel@tonic-gate }
2210Sstevel@tonic-gate
2220Sstevel@tonic-gate NOTIFY_MD(md_tag, setno, devid, ev_type);
2230Sstevel@tonic-gate }
2240Sstevel@tonic-gate
2250Sstevel@tonic-gate /*
2260Sstevel@tonic-gate * External symbols from libsysevent and libnvpair which are not
2270Sstevel@tonic-gate * available in static forms
2280Sstevel@tonic-gate */
2290Sstevel@tonic-gate static void *se_handle = NULL, *nv_handle = NULL;
2300Sstevel@tonic-gate static int (*_sysevent_post_event)(char *, char *, char *, char *,
2310Sstevel@tonic-gate nvlist_t *, sysevent_id_t *) = NULL;
2320Sstevel@tonic-gate static int (*_nvlist_alloc)(nvlist_t **, uint_t, int) = NULL;
2330Sstevel@tonic-gate static void (*_nvlist_free)(nvlist_t *) = NULL;
2340Sstevel@tonic-gate static int (*_nvlist_add_uint32)(nvlist_t *, char *, uint32_t) = NULL;
2350Sstevel@tonic-gate static int (*_nvlist_add_uint64)(nvlist_t *, char *, uint64_t) = NULL;
2360Sstevel@tonic-gate static int (*_nvlist_add_string)(nvlist_t *, char *, char *) = NULL;
2370Sstevel@tonic-gate
2380Sstevel@tonic-gate /*
2390Sstevel@tonic-gate * Load nvpair and sysevent symbols
2400Sstevel@tonic-gate */
2410Sstevel@tonic-gate static int
load_sev_lib()2420Sstevel@tonic-gate load_sev_lib()
2430Sstevel@tonic-gate {
2440Sstevel@tonic-gate /* Try to load the sysevent symbol */
2450Sstevel@tonic-gate if (se_handle == NULL) {
2460Sstevel@tonic-gate se_handle = dlopen("/usr/lib/libsysevent.so.1", RTLD_LAZY);
2470Sstevel@tonic-gate }
2480Sstevel@tonic-gate if (se_handle != NULL) {
2490Sstevel@tonic-gate if ((_sysevent_post_event == NULL) &&
2500Sstevel@tonic-gate (_sysevent_post_event = (int (*)(char *, char *, char *,
2510Sstevel@tonic-gate char *, nvlist_t *, sysevent_id_t *))
2520Sstevel@tonic-gate dlsym(se_handle, "sysevent_post_event")) == NULL) {
2530Sstevel@tonic-gate goto out;
2540Sstevel@tonic-gate }
2550Sstevel@tonic-gate } else {
2560Sstevel@tonic-gate return (1);
2570Sstevel@tonic-gate }
2580Sstevel@tonic-gate
2590Sstevel@tonic-gate /* Try to load the nvpair symbols */
2600Sstevel@tonic-gate if (nv_handle == NULL) {
2610Sstevel@tonic-gate nv_handle = dlopen("/usr/lib/libnvpair.so.1", RTLD_LAZY);
2620Sstevel@tonic-gate }
2630Sstevel@tonic-gate if (nv_handle != NULL) {
2640Sstevel@tonic-gate if ((_nvlist_alloc == NULL) &&
2650Sstevel@tonic-gate (_nvlist_alloc = (int (*)(nvlist_t **, uint_t, int))
2660Sstevel@tonic-gate dlsym(nv_handle, "nvlist_alloc")) == NULL) {
2670Sstevel@tonic-gate goto out;
2680Sstevel@tonic-gate }
2690Sstevel@tonic-gate if ((_nvlist_free == NULL) &&
2700Sstevel@tonic-gate (_nvlist_free = (void (*)(nvlist_t *))dlsym(nv_handle,
2710Sstevel@tonic-gate "nvlist_free")) == NULL) {
2720Sstevel@tonic-gate goto out;
2730Sstevel@tonic-gate }
2740Sstevel@tonic-gate if ((_nvlist_add_uint32 == NULL) &&
2750Sstevel@tonic-gate (_nvlist_add_uint32 = (int (*)(nvlist_t *, char *,
2760Sstevel@tonic-gate uint32_t))dlsym(nv_handle,
2770Sstevel@tonic-gate "nvlist_add_uint32")) == NULL) {
2780Sstevel@tonic-gate goto out;
2790Sstevel@tonic-gate }
2800Sstevel@tonic-gate if ((_nvlist_add_uint64 == NULL) &&
2810Sstevel@tonic-gate (_nvlist_add_uint64 = (int (*)(nvlist_t *, char *,
2820Sstevel@tonic-gate uint64_t))dlsym(nv_handle,
2830Sstevel@tonic-gate "nvlist_add_uint64")) == NULL) {
2840Sstevel@tonic-gate goto out;
2850Sstevel@tonic-gate }
2860Sstevel@tonic-gate if ((_nvlist_add_string == NULL) &&
2870Sstevel@tonic-gate (_nvlist_add_string = (int (*)(nvlist_t *, char *,
2880Sstevel@tonic-gate char *))dlsym(nv_handle,
2890Sstevel@tonic-gate "nvlist_add_string")) == NULL) {
2900Sstevel@tonic-gate goto out;
2910Sstevel@tonic-gate }
2920Sstevel@tonic-gate
2930Sstevel@tonic-gate return (0);
2940Sstevel@tonic-gate }
2950Sstevel@tonic-gate
2960Sstevel@tonic-gate out:
2970Sstevel@tonic-gate if ((se_handle != NULL) && (dlclose(se_handle) == 0)) {
2980Sstevel@tonic-gate se_handle = NULL;
2990Sstevel@tonic-gate }
3000Sstevel@tonic-gate
3010Sstevel@tonic-gate if ((nv_handle != NULL) && (dlclose(nv_handle) == 0)) {
3020Sstevel@tonic-gate nv_handle = NULL;
3030Sstevel@tonic-gate }
3040Sstevel@tonic-gate
3050Sstevel@tonic-gate _sysevent_post_event = NULL;
3060Sstevel@tonic-gate _nvlist_alloc = NULL;
3070Sstevel@tonic-gate _nvlist_free = NULL;
3080Sstevel@tonic-gate _nvlist_add_uint32 = NULL;
3090Sstevel@tonic-gate _nvlist_add_uint64 = NULL;
3100Sstevel@tonic-gate _nvlist_add_string = NULL;
3110Sstevel@tonic-gate
3120Sstevel@tonic-gate return (1);
3130Sstevel@tonic-gate }
3140Sstevel@tonic-gate
3150Sstevel@tonic-gate /*
3160Sstevel@tonic-gate * Log SVM sys events
3170Sstevel@tonic-gate */
3180Sstevel@tonic-gate void
meta_svm_sysevent(char * se_class,char * se_subclass,uint32_t tag,set_t setno,md_dev64_t devid)3190Sstevel@tonic-gate meta_svm_sysevent(
3200Sstevel@tonic-gate char *se_class,
3210Sstevel@tonic-gate char *se_subclass,
3220Sstevel@tonic-gate uint32_t tag,
3230Sstevel@tonic-gate set_t setno,
3240Sstevel@tonic-gate md_dev64_t devid
3250Sstevel@tonic-gate )
3260Sstevel@tonic-gate {
3270Sstevel@tonic-gate sysevent_id_t eid;
3280Sstevel@tonic-gate nvlist_t *attr_list;
3290Sstevel@tonic-gate int err = 0;
3300Sstevel@tonic-gate char *devname;
3310Sstevel@tonic-gate
3320Sstevel@tonic-gate /* Raise the mdnotify event before anything else */
3330Sstevel@tonic-gate do_mdnotify(se_subclass, tag, setno, devid);
3340Sstevel@tonic-gate
3350Sstevel@tonic-gate /* Just get out if the sysevent symbol can't be loaded */
3360Sstevel@tonic-gate if (load_sev_lib()) {
3370Sstevel@tonic-gate return;
3380Sstevel@tonic-gate }
3390Sstevel@tonic-gate
3400Sstevel@tonic-gate err = (*_nvlist_alloc)(&attr_list, NV_UNIQUE_NAME, 0);
3410Sstevel@tonic-gate
3420Sstevel@tonic-gate if (err == 0) {
3430Sstevel@tonic-gate /* Add the version number */
3440Sstevel@tonic-gate err = (*_nvlist_add_uint32)(attr_list, SVM_VERSION_NO,
3450Sstevel@tonic-gate (uint32_t)SVM_VERSION);
3460Sstevel@tonic-gate if (err != 0) {
3470Sstevel@tonic-gate goto fail;
3480Sstevel@tonic-gate }
3490Sstevel@tonic-gate
3500Sstevel@tonic-gate /* Add the tag attribute */
3510Sstevel@tonic-gate err = (*_nvlist_add_uint32)(attr_list, SVM_TAG, (uint32_t)tag);
3520Sstevel@tonic-gate if (err != 0) {
3530Sstevel@tonic-gate goto fail;
3540Sstevel@tonic-gate }
3550Sstevel@tonic-gate
3560Sstevel@tonic-gate /* Add the set number attribute */
3570Sstevel@tonic-gate err = (*_nvlist_add_uint32)(attr_list, SVM_SET_NO,
3580Sstevel@tonic-gate (uint32_t)setno);
3590Sstevel@tonic-gate if (err != 0) {
3600Sstevel@tonic-gate goto fail;
3610Sstevel@tonic-gate }
3620Sstevel@tonic-gate
3630Sstevel@tonic-gate /* Add the device id attribute */
3640Sstevel@tonic-gate err = (*_nvlist_add_uint64)(attr_list, SVM_DEV_ID,
3650Sstevel@tonic-gate (uint64_t)devid);
3660Sstevel@tonic-gate if (err != 0) {
3670Sstevel@tonic-gate goto fail;
3680Sstevel@tonic-gate }
3690Sstevel@tonic-gate
3700Sstevel@tonic-gate /* Add the device name attribute */
3710Sstevel@tonic-gate devname = obj2devname(tag, setno, devid);
3720Sstevel@tonic-gate if (devname != NULL) {
3730Sstevel@tonic-gate err = (*_nvlist_add_string)(attr_list, SVM_DEV_NAME,
3740Sstevel@tonic-gate devname);
3750Sstevel@tonic-gate free(devname);
3760Sstevel@tonic-gate } else {
3770Sstevel@tonic-gate err = (*_nvlist_add_string)(attr_list, SVM_DEV_NAME,
3780Sstevel@tonic-gate "unspecified");
3790Sstevel@tonic-gate }
3800Sstevel@tonic-gate if (err != 0) {
3810Sstevel@tonic-gate goto fail;
3820Sstevel@tonic-gate }
3830Sstevel@tonic-gate
3840Sstevel@tonic-gate /* Attempt to post event */
3850Sstevel@tonic-gate (void) (*_sysevent_post_event)(se_class, se_subclass,
3860Sstevel@tonic-gate SUNW_VENDOR, EP_SVM, attr_list, &eid);
3870Sstevel@tonic-gate
3880Sstevel@tonic-gate (*_nvlist_free)(attr_list);
3890Sstevel@tonic-gate }
3900Sstevel@tonic-gate
3910Sstevel@tonic-gate return;
3920Sstevel@tonic-gate
3930Sstevel@tonic-gate fail:
3940Sstevel@tonic-gate (*_nvlist_free)(attr_list);
3950Sstevel@tonic-gate }
396