DDI_LOG_SYSEVENT(9F) | Kernel Functions for Drivers | DDI_LOG_SYSEVENT(9F) |
ddi_log_sysevent - log system event for drivers
#include <sys/ddi.h> #include <sys/sunddi.h> int ddi_log_sysevent(dev_info_t *dip, char *vendor,
char *class, char *subclass, nvlist_t *attr_list,
sysevent_id_t *eidp, int sleep_flag);
illumos DDI specific (illumos DDI).
dip
vendor
class
subclass
attr_list
eidp
sleep_flag
The ddi_log_sysevent() function causes a system event, of the specified class and subclass, to be generated on behalf of the driver and queued for delivery to syseventd, the user-land sysevent daemon.
The publisher string for the event is constructed using the vendor name and driver name, with the format:
"<vendor>:kern:<driver-name>"
The two fields of eidp, eid_seq and eid_ts, are sufficient to uniquely identify an event.
The structure members of sysevent_id_t are:
uint64_t eid_seq; /* sysevent sequence number */
hrtime_t eid_ts; /* sysevent timestamp */
The ddi_log_sysevent() function returns:
DDI_SUCCESS
DDI_ENOMEM
DDI_EBUSY
DDI_ETRANSPORT
DDI_ECONTEXT
ddi_log_sysevent supports the following data types:
DATA_TYPE_BYTE
DATA_TYPE_INT16
DATA_TYPE_UINT16
DATA_TYPE_INT32
DATA_TYPE_UINT32
DATA_TYPE_INT64
DATA_TYPE_UINT64
DATA_TYPE_STRING
DATA_TYPE_BYTE_ARRAY
DATA_TYPE_INT16_ARRAY
DATA_TYPE_UINT16_ARRAY
DATA_TYPE_INT32_ARRAY
DATA_TYPE_UINT32_ARRAY
DATA_TYPE_INT64_ARRAY
DATA_TYPE_UINT64_ARRAY
The ddi_log_sysevent() function can be called from user, interrupt, or kernel context, except when sleep_flag is DDI_SLEEP, in which case it cannot be called from interrupt context.
Example 1 Logging System Event with No Attributes
if (ddi_log_sysevent(dip, DDI_VENDOR_SUNW, "class", "subclass",
NULL, NULL, DDI_SLEEP) != DDI_SUCCESS) {
cmn_err(CE_WARN, "error logging system event\n");
}
Example 2 Logging System Event with Two Name/Value Attributes, an Integer and a String
nvlist_t *attr_list; sysevent_id_t eid; if (nvlist_alloc(&attr_list, NV_UNIQUE_NAME_TYPE, KM_SLEEP) == 0) {
err = nvlist_add_uint32(attr_list, int_name, int_value);
if (err == 0)
err = nvlist_add_string(attr_list, str_name, str_value);
if (err == 0)
err = ddi_log_sysevent(dip, DDI_VENDOR_SUNW,
"class", "subclass", attr_list, &eid, DDI_SLEEP);
if (err != DDI_SUCCESS)
cmn_err(CE_WARN, "error logging system event\n");
nvlist_free(attr_list);
}
Example 3 Use Timeout to Handle nvlist and System Event Resource Allocation Failures
Since no blocking calls are made, this example would be useable from a driver needing to generate an event from interrupt context.
static int
xx_se_timeout_handler(xx_state_t *xx)
{
xx->xx_timeoutid = (xx_generate_event(xx) ?
timeout(xx_se_timeout_handler, xx, 4) : 0);
}
static int
xx_generate_event(xx_state_t *xx)
{
int err;
err = nvlist_alloc(&xx->xx_ev_attrlist, NV_UNIQUE_NAME_TYPE, 0);
if (err != 0)
return (1);
err = nvlist_add_uint32(&xx->xx_ev_attrlist,
xx->xx_ev_name, xx->xx_ev_value);
if (err != 0) {
nvlist_free(xx->xx_ev_attrlist);
return(1);
}
err = ddi_log_sysevent(xx->xx_dip, DDI_VENDOR_SUNW,
xx->xx_ev_class, xx->xx_ev_sbclass,
xx->xx_ev_attrlist, NULL, DDI_NOSLEEP);
nvlist_free(xx->xx_ev_attrlist);
if (err == DDI_SUCCESS || err == DDI_ETRANSPORT) {
if (err == DDI_ETRANSPORT)
cmn_err(CE_WARN, "cannot log system event\n");
return (0);
}
return (1);
}
attributes(7), syseventd(8), nvlist_add_boolean(9F), nvlist_alloc(9F)
Writing Device Drivers
January 16, 2006 | OmniOS |