Registering Subsystems

Once more I use the generic hard disk code as an example for a subsystem that uses kobjects that are represented in sysfs. Observe that the directory /sys/block is used to represent this subsystem. For every block device available in the system, a subdirectory contains several attribute files:

[email protected]

# Is -

-l /sys/block

total

0

drwxr-

xr-

x

4

root

root

0

2008-

02-

■09

23:

: 26

loop0

drwxr-

xr-

x

4

root

root

0

2008-

02-

■09

23:

: 26

loop1

drwxr-

xr-

x

4

root

root

0

2008-

02-

■09

23:

: 26

loop2

drwxr-

xr-

x

4

root

root

0

2008-

02-

■09

23:

: 26

loop3

drwxr-

xr-

x

4

root

root

0

2008-

02-

09

23:

26

loop4

drwxr-

xr-

x

4

root

root

0

2008-

02-

09

23:

26

loop5

drwxr-

xr-

x

4

root

root

0

2008-

02-

09

23:

26

loop6

drwxr-

xr-

x

4

root

root

0

2008-

02-

09

23:

26

loop7

drwxr-

xr-

x

10

root

root

0

2008-

02-

09

23:

26

sda

drwxr-

xr-

x

5

root

root

0

2008-

02-

09

23:

26

sdb

drwxr-

xr-

x

5

root

root

0

2008-

02-

09

23:

26

sr0

[email protected]

# ls -

-l /sys/block/hda

total

0

-r--r--r-- 1 root root 4096 2008-02-09 23:26 capability

-r--r--r-- 1 root root 4096 2008-02-09 23:26 dev lrwxrwxrwx 1 root root 0 2008-02-09 23:26 device -> ../../devices/pci0000:00/

0000:00:1f.2/host0/target0:0:0/0:0:0:0

drwxr-xr-x 2 root root 0 2008-02-09 23:26 holders drwxr-xr-x 3 root root 0 2008-02-09 23:26 queue

-r--r--r-- 1 root root 4096 2008-02-09 23:26 range

-r--r--r-- 1 root root 4096 2008-02-09 23:26 removable drwxr-xr-x 3 root root 0 2008-02-09 23:26 sda1

drwxr-xr-x 3 root root 0 2008-02-09 23:26 sda2

drwxr-xr-x 3 root root 0 2008-02-09 23:26 sda5

drwxr-xr-x 3 root root 0 2008-02-09 23:26 sda6

drwxr-xr-x 3 root root 0 2008-02-09 23:26 sda7

-r--r--r-- 1 root root 4096 2008-02-09 23:26 size drwxr-xr-x 2 root root 0 2008-02-09 23:26 slaves

-r--r--r-- 1 root root 4096 2008-02-09 23:26 stat lrwxrwxrwx 1 root root 0 2008-02-09 23:26 subsystem -> ../../block

--w------- 1 root root 4096 2008-02-09 23:26 uevent

One of the central elements behind this output is the following data structure, which connects a sysfs-specific attribute structure with genhd-specific store and show methods. Note that these methods do not have the signature required for the show/store methods required by sysfs; these will be provided later:

struct disk_attribute {

struct attribute attr;

ssize_t (*store)(struct gendisk *, const char *, size_t);

Some attributes are attached to all objects represented by the genhd subsystem, so the kernel creates a collection of instances of disk_attribute as follows:

block/genhd.c static struct disk_attribute disk_attr_uevent = {

.attr = {.name = "uevent", .mode = S_IWUSR }, .store = disk_uevent_store

static struct disk_attribute disk_attr_dev = {

.attr = {.name = "dev", .mode = S_IRUGO }, .show = disk_dev_read

static struct disk_attribute disk_attr_stat = {

.attr = {.name = "stat", .mode = S_IRUGO }, .show = disk_stats_read

static struct attribute * default_attrs[] = { &disk_attr_uevent.attr, &disk_attr_dev.attr, &disk_attr_range.attr,

&disk_attr_stat.attr,

NULL,

The connection between the attribute-specific show/store methods and the show/store methods in sysfs_ops is made by the following structure:

block/genhd.c static struct sysfs_ops disk_sysfs_ops = { .show = &disk_attr_show, .store = &disk_attr_store,

Without getting into any details about their implementation, note that both methods are provided with an attribute instance when called by sysfs, transform this instance into a disk_attribute, and call the show/store method associated with the specific attributes that does the low-level, subsystem-specific work.

Finally, the only thing that needs to be considered is how the set of default attributes is connected with all kobjects belonging to the genhd subsystem. For this, a kobj_type is used:

block/genhd.c static struct kobj_type ktype_block = { .release = disk_release,

.sysfs_ops = &disk_sysfs_ops,

.default_attrs = default_attrs,

Two further steps are necessary to connect this data structure with sysfs:

1. Create a kset that corresponds to the kobj_type by using decl_subsys.

2. Register the kset with register_subsystem; this function ends up in calling kset_add which, in turn, calls kobject_add to create an appropriate directory with create_dir. Once more, this function calls populate_dir, which iterates over all default attributes and creates a sysfs file for each of them.

Because subelements of generic hard disks (i.e., partitions) are connected with the kset introduced above, they automatically inherit all default attributes by virtue of the kobject model.

Continue reading here: Summary

Was this article helpful?

0 0