Writing Device Drivers

How Drivers Track Events: ddi_log_sysevent()

Device drivers use the ddi_log_sysevent(9F) interface to generate and log an event with the system; an event tells the system what has just occurred to the device. The system, in turn, queues events and passes them to the syseventd() daemon outside of kernel process space. syseventd() then passes the events on to an appropriate event-handling process, as shown in Figure 4–1.

Figure 4–1 Event Plumbing

Diagram shows how events are generated and logged.

ddi_log_sysevent() takes the following arguments:

dip

A pointer to the dev_info node for this driver.

vendor

A pointer to a string defining the driver's vendor. Third-party drivers should use their company's stock symbol or a similarly enduring identifier. Sun-supplied drivers use DDI_VENDOR_SUNW.

class

A pointer to a string defining the event's class. This is a driver–specific value. An example of a class might be a string representing a set of environmental conditions affecting a device. This value must be intelligible to the event consumer.

subclass

Also a driver-specific string, this parameter represents a subset of the class argument. For example, within a class representing environmental conditions, an event subclass might refer to the device's temperature. This value must be intelligible to the event consumer.

attr_list

A pointer to an nvlist_t structure, listing name-value attributes associated with the event. Name-value attributes, like class and subclass, are driver-defined; they refer to some specific attribute or condition of the device. For example, a device that reads both CD-ROMs and DVDs may create a string name-value pair in which the name is disc_type and the value is either cd_rom or dvd. As with class and subclass, the driver handle (outside of kernel process space) must be able to interpret name–value pairs and respond to them in an appropriate manner.

For more on name-value pairs and the nvlist_t structure, see Event Name-Value Pairs, as well as nvlist_alloc(9F)

If there are no such attributes for an event, then this argument should be set to NULL.

eidp

The address of a sysevent_id_t structure. The sysevent_id_t structure is used to provide a unique identification for the event. ddi_log_sysevent(9F) returns this structure with a system-provided event sequence number and timestamp. See the ddi_log_sysevent(9F) page for more information on the sysevent_id_t structure.

sleep_flag

This flag indicates how a caller will handle the possibility of resources not being available. If sleep_flag is DDI_NOSLEEP, then it does not matter if allocation fails or the queue is full; the caller will handle such a failure appropriately. If sleep_flag is set to DDI_SLEEP, the caller will have allocation and queuing routines wait for resources to become available.

The following example demonstrates how ddi_log_sysevent() is used.


char *vendor_name = "DDI_VENDOR_JGJG"
char *my_class = "EC_ENVIRONMENT";
char *my_subclass = "ESC_TEMPERATURE";
nvlist_t *nvl;
...
nvl = create_nvlist();
...
     /* an event occurs... */ ...
        if (ddi_log_sysevent(dip, vendor_name, my_class, 
            my_subclass, nvl, NULL, DDI_SLEEP)!= DDI_SUCCESS)
                 cmn_err(CE_WARN, "error logging system event");