14.3. Hotplug Event Generation
A hotplug event is a notification to user space from the kernel that something has changed in the system's configuration. They are generated whenever a kobject is created or destroyed. Such events are generated, for example, when a digital camera is plugged in with a USB cable, when a user switches console modes, or when a disk is repartitioned. Hotplug events turn into an invocation of /sbin/hotplug, which can respond to each event by loading drivers, creating device nodes, mounting partitions, or taking any other action that is appropriate.
The last major kobject function we look at is the generation of these events. The actual event generation takes place when a kobject is passed to kobject_add or kobject_del. Before the event is handed to user space, code associated with the kobject (or, more specifically, the kset to which it belongs) has the opportunity to add information for user space or to disable event generation entirely.
14.3.1. Hotplug Operations
Actual control of hotplug events is exercised by way of a set of methods stored in the kset_hotplug_ops structure:
struct kset_hotplug_ops {
int (*filter)(struct kset *kset, struct kobject *kobj);
char *(*name)(struct kset *kset, struct kobject *kobj);
int (*hotplug)(struct kset *kset, struct kobject *kobj,
char **envp, int num_envp, char *buffer,
int buffer_size);
};
A pointer to this structure is found in the hotplug_ops field of the kset structure. If a given kobject is not contained within a kset, the kernel searchs up through the hierarchy (via the parent pointer) until it finds a kobject that does have a kset; that kset's hotplug operations are then used.
The filter hotplug operation is called whenever the kernel is considering generating an event for a given kobject. If filter returns 0, the event is not created. This method, therefore, gives the kset code an opportunity to decide which events should be passed on to user space and which should not.
As an example of how this method might be used, consider the block subsystem. There are at least three types of kobjects used there, representing disks, partitions, and request queues. User space may want to react to the addition of a disk or a partition, but it does not normally care about request queues. So the filter method allows event generation only for kobjects representing disks and partitions. It looks like this:
static int block_hotplug_filter(struct kset *kset, struct kobject *kobj)
{
struct kobj_type *ktype = get_ktype(kobj);
return ((ktype = = &ktype_block) || (ktype = = &ktype_part));
}
Here, a quick test on the type of kobject is sufficient to decide whether the event should be generated or not.
When the user-space hotplug program is invoked, it is passed to the name of the relevant subsystem as its one and only parameter. The name hotplug method is charged with providing that name. It should return a simple string suitable for passing to user space.
Everything else that the hotplug script might want to know is passed in the environment. The final hotplug method (hotplug) gives an opportunity to add useful environment variables prior to the invocation of that script. Again, this method's prototype is:
int (*hotplug)(struct kset *kset, struct kobject *kobj,
char **envp, int num_envp, char *buffer,
int buffer_size);
As usual, kset and kobject describe the object for which the event is being generated. The envp array is a place to store additional environment variable definitions (in the usual NAME=value format); it has num_envp entries available. The variables themselves should be encoded into buffer, which is buffer_size bytes long. If you add any variables to envp, be sure to add a NULL entry after your last addition so that the kernel knows where the end is. The return value should normally be 0; any nonzero return aborts the generation of the hotplug event.
The generation of hotplug events (like much of the work in the device model) is usually handled by logic at the bus driver level.
A hotplug event is a notification to user space from the kernel that something has changed in the system's configuration. They are generated whenever a kobject is created or destroyed. Such events are generated, for example, when a digital camera is plugged in with a USB cable, when a user switches console modes, or when a disk is repartitioned. Hotplug events turn into an invocation of /sbin/hotplug, which can respond to each event by loading drivers, creating device nodes, mounting partitions, or taking any other action that is appropriate.
The last major kobject function we look at is the generation of these events. The actual event generation takes place when a kobject is passed to kobject_add or kobject_del. Before the event is handed to user space, code associated with the kobject (or, more specifically, the kset to which it belongs) has the opportunity to add information for user space or to disable event generation entirely.
14.3.1. Hotplug Operations
Actual control of hotplug events is exercised by way of a set of methods stored in the kset_hotplug_ops structure:
struct kset_hotplug_ops {
int (*filter)(struct kset *kset, struct kobject *kobj);
char *(*name)(struct kset *kset, struct kobject *kobj);
int (*hotplug)(struct kset *kset, struct kobject *kobj,
char **envp, int num_envp, char *buffer,
int buffer_size);
};
A pointer to this structure is found in the hotplug_ops field of the kset structure. If a given kobject is not contained within a kset, the kernel searchs up through the hierarchy (via the parent pointer) until it finds a kobject that does have a kset; that kset's hotplug operations are then used.
The filter hotplug operation is called whenever the kernel is considering generating an event for a given kobject. If filter returns 0, the event is not created. This method, therefore, gives the kset code an opportunity to decide which events should be passed on to user space and which should not.
As an example of how this method might be used, consider the block subsystem. There are at least three types of kobjects used there, representing disks, partitions, and request queues. User space may want to react to the addition of a disk or a partition, but it does not normally care about request queues. So the filter method allows event generation only for kobjects representing disks and partitions. It looks like this:
static int block_hotplug_filter(struct kset *kset, struct kobject *kobj)
{
struct kobj_type *ktype = get_ktype(kobj);
return ((ktype = = &ktype_block) || (ktype = = &ktype_part));
}
Here, a quick test on the type of kobject is sufficient to decide whether the event should be generated or not.
When the user-space hotplug program is invoked, it is passed to the name of the relevant subsystem as its one and only parameter. The name hotplug method is charged with providing that name. It should return a simple string suitable for passing to user space.
Everything else that the hotplug script might want to know is passed in the environment. The final hotplug method (hotplug) gives an opportunity to add useful environment variables prior to the invocation of that script. Again, this method's prototype is:
int (*hotplug)(struct kset *kset, struct kobject *kobj,
char **envp, int num_envp, char *buffer,
int buffer_size);
As usual, kset and kobject describe the object for which the event is being generated. The envp array is a place to store additional environment variable definitions (in the usual NAME=value format); it has num_envp entries available. The variables themselves should be encoded into buffer, which is buffer_size bytes long. If you add any variables to envp, be sure to add a NULL entry after your last addition so that the kernel knows where the end is. The return value should normally be 0; any nonzero return aborts the generation of the hotplug event.
The generation of hotplug events (like much of the work in the device model) is usually handled by logic at the bus driver level.
Комментариев нет:
Отправить комментарий
Примечание. Отправлять комментарии могут только участники этого блога.