Table of Contents

Kernel Objects and Sysfs

The /proc filesystem emerged as a superb tool during the development of the 2.4 kernel series.

It provided “instant” access to and control of kernel parameters in a user friendly manner such that by simply using “cat” and “echo” kernel features could be examined and manipulated.

Lack of documentation and a non unified structure caused a some what haphazard application of this excellent feature.

An attempt was made in the 2.4 kernel to provide a more uniform approach to the concept using the SYSCTL interface.

The 2.6 kernel permitted a major change to the whole infrastructure and produced what is called sysfs.

Tightly coupled with the sysfs are things called kernel objects (more about those soon)

A brief Overview of Sysfs

Sysfs is a ram based file system like procfs. It allows kernel structures to be exported and their attributes and relationships to be visible from userspace.

In fact it has all of the good features of the proc interface but with formal structure and documentation.

The only possible drawback to the system is the large amount of memory it takes to hold the in memory filesystem. This problem is being addressed in recent kernel patches.

Here is an overview of sysfs features

Mounting Sysfs

The following command will mount the sysfs on a 2.6 system

mount -t sysfs sysfs /sys

Normally this is done in the /etc/rc file.

Some sysfs examples

A tree view of a hard disk in sysfs.

|-- block
|   |-- hda
|   |   |-- dev
|   |   |-- device -> ../../devices/pci0000:00/0000:00:07.1/ide0/0.0
|   |   |-- hda1
|   |   |   |-- dev
|   |   |   |-- size
|   |   |   |-- start
|   |   |   `-- stat
|   |   |-- queue
|   |   |   |-- iosched
|   |   |   |   |-- antic_expire
|   |   |   |   |-- est_time
|   |   |   |   |-- read_batch_expire
|   |   |   |   |-- read_expire
|   |   |   |   |-- write_batch_expire
|   |   |   |   `-- write_expire
|   |   |   |-- nr_requests
|   |   |   `-- read_ahead_kb
|   |   |-- range

Looking at some of the elements

>cat /sys/block/hda/hda2/start

>cat /sys/block/hda/hda2/dev

>cat /sys/block/hda/queue/nr_requests

>cat /sys/block/hda/queue/iosched/est_time
18 % exit probability
1 ms new thinktime
1056767 sectors new seek distance

Sysfs Documentation

Unlike the older proc file system the sysfs and associated kernel objects do have some documentation and a reference design to look at.


* ./Documentation/kobject.txt

Reference Example:

Kernel Objects Introduction

The Kernel Object subsystem is complex. This is an attempt to understand the basics.

The key feature of a kernel object is the concept of a reference count.

The creator of an object can delete that object at any time but any users of that object will cause the object to remain in the system until its reference count falls to zero. At that time the object will be deleted.

The Kernel Object Players

The Kernel object basic structure is shown

file: include/linux/kobject.h

scm failed with exit code 1:
file does not exist in git

The Kernel Object Elements

In general a Kernel Object needs the following elements

Major Components

The Major Components used in understanding the Kernel Object System are:

Use Overview

In general, when using an object the flow is…

  1. Define a type that tells the system the object attributes and the release function to delete the object.
  2. Create a set of objects of the same type belonging to the same subsystem.
    • The set object will be the object's parent. Each set has a object type that defines the subsystem and a type that defines the type of objects contained in the set.
  3. Create a subsystem to act as the root directory ( or use an existing one )
  4. Create the object and fill in the name, parent, set and type fields
  5. Register the object (which adds it to the sysfs).

Kset Overview

A Kset belongs to a subsystem, it has a type, a list of members and also contains a kobject of its own.

Ksets also participate in helping with hotplug operations by specifying a hotplug name and adding items to the hotplug helper's environment.

file: include/linux/kobject.h

scm failed with exit code 1:
file does not exist in git

Ktype Overview

A Ktype defines the show and store operations that can be performed on the objectit also sets up the default attributes for the object.

file: include/linux/kobject.h

scm failed with exit code 1:
file does not exist in git

Subsystem Overview

This is a base level system it has a kset whose kobject allows the subsystem to be placed in the system hierarchy properly.

file: include/linux/kobject.h

scm failed with exit code 1:
file does not exist in git

Confused ??

An example will show the basic mechanics of setting up a small subsystem.

Kernel Object / Sysfs Example

The example discussed will show the basics of setting up a subsystem of a single type of object with attributes.

The Computer Object

The important kernel entity here is the kobject, the attributes are defined by the use of the object.

// Step 1 define an object
struct computer {
     struct kobject kobj;  /* contains the name is also the directory entry */
                           /* user defined attributes follow                */
     char make[16];
     char ip[16];
     int speed;
     int capacity;
     int used;

Define the attributes

The attributes of the object will appear as regular files permissions and names need to be set at this stage. The only other element in the attribute structure is the module owner.

Note that no show / store access functions are defined in basic attributes.

 * Step 2 define its attributes
#define COM_MODE ( S_IRUGO | S_IWUGO )
static struct attribute computer_attr_make ={.name="make",.mode=COM_MODE };
static struct attribute computer_attr_ip   ={.name="ip",  .mode=COM_MODE };
static struct attribute computer_attr_speed={.name="speed",.mode=COM_MODE };
static struct attribute computer_attr_capacity={.name="capacity",.mode=COM_MODE};
static struct attribute computer_attr_used = {.name="used",.mode=COM__MODE };
 * Now build an attribute structure as a null terminated list
static struct attribute* computer_default_attrs[] = {

Define the object type

The sysfs_ops table will contain the show and store routines

The release routine will tell the system how to remove the object.

The type also defines the default attributes for the object.

 * Now we can define the type
static struct kobj_type computer_ktype = {
    .release = computer_release,
    .sysfs_ops = &computer_sysfs_ops,
    .default_attrs = computer_default_attrs

Define the subsystem type

The subsystem type simply contains the notifier and clean up routine used when the system is deleted.

Again the sysfs_ops table will contain the show and store routines

The release routine will tell the system how to remove the object.

The type also defines the default attributes for th object.

static struct kobj_type sysfs_computer_ktype = {
    .release = sysfs_computer_release,
    .sysfs_ops = NULL,
    .default_attrs = NULL

Define the Set

In this example a static definition is used for a set.

All the generated objects will be added to this set which will also be used by the subsystem to find its components.

   static struct kset computer_set;

Declare the Subsystem

The decl_subsystem helper function can be used here

/* The following macro completes the definition of the subsystem */
decl_subsys(sysfs_computer, &sysfs_computer_ktype, 0 );

or by hand ..

struct subsystem sysfs_computer_subsys = {
        .kset = {
                .kobj = { .name = __stringify(sysfs_computer) },
                .ktype = &sysfs_computer_ktype,
                .hotplug_ops =0

Define the KSET

The KOBJECT SET is the key to the whole system

    char * name = "computers";
    kobject_set_name(&computer_set->kobj, "%s", name);
    // associate the set with a subsystem
    computer_set->subsys = &sysfs_computer_subsys;
    // define the type of the set
    computer_set->kobj.ktype = &sysfs_computer_ktype;
    // define the type of objects contained in the set
    computer_set->ktype = &computer_ktype;
    // No hotplug for this object
    computer_set->hotplug_ops = NULL;
   // register the set to make it appear

Register the Subsystem

This will make sysfs aware of the subsystem.


Initialize each object's system components

This sets up the object in the sysfs hierarchy

    // create a new computer
    struct computer * computer = (struct computer*)kmalloc(
        sizeof(struct computer),GFP_KERNEL);
    if ( NULL == computer ) return NULL;
    memset(computer, 0x00, sizeof(struct computer));
    kobject_set_name(&computer->kobj, "%s" , name);
    computer->kobj.parent = &computer_set.kobj;
    computer->kobj.kset = &computer_set;
    computer->kobj.ktype = computer_set.ktype;

Initialize each object's attributes

Having established the object's place in the hierarchy now set its attributes.

    computer->speed = speed;
    computer->capacity = capacity;
    computer->used = used;

Register the object

This step will expose the object to the sysfs system.


<h3> Clean up </h3>

<p> This step will remove object from the sysfs system.

        struct kobject * kobj = NULL;
        while(!list_empty(&computer_set.list)) {
            kobj = (struct kobject *) list_entry(,
                                                 struct kobject, entry);

The system in action

Here is an example of this system in action


/sys/sysfs_computer/ `-- computers

  |-- comp_node_0
  |   |-- capacity
  |   |-- ip
  |   |-- make
  |   |-- speed
  |   `-- used


  `-- comp_node_4
      |-- capacity
      |-- ip
      |-- make
      |-- speed
      `-- used