sysfs中的内核模块参数 - 对更改的快速反应

Woj*_*ski 4 c kernel-module linux-kernel sysfs

当其中一个sys文件被更改时,是否可以通知模块?我的任务是做一个控制模块内缓冲区大小的文件,我想在文件中的值改变时调整缓冲区的大小.我的另一个想法(如果我不能通知模块)是每次使用模块时检查前一个值,然后调整缓冲区的大小.

eep*_*epp 9

这不是Sysfs的目的吗?

当您kobject在Sysfs(这是一个目录)中创建并提供表示时,您将为该对象创建属性,该属性将成为该目录中的文件.你提供一个store和一个show回调kobject,它基本上是resp的等价物.writeread.

store这就是你想要的.它看起来像这样:

ssize_t (*store)(struct kobject *kobj, struct attribute *attr, 
    const char *buffer, size_t size);
Run Code Online (Sandbox Code Playgroud)

只要在用户域中写入虚拟文件,就会在其中收到size字节buffer.

看看这个模块(从这里开始):

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/slab.h>

struct my_attr {
    struct attribute attr;
    int value;
};

static struct my_attr my_first = {
    .attr.name="first",
    .attr.mode = 0644,
    .value = 1,
};

static struct my_attr my_second = {
    .attr.name="second",
    .attr.mode = 0644,
    .value = 2,
};

static struct attribute * myattr[] = {
    &my_first.attr,
    &my_second.attr,
    NULL
};

static ssize_t default_show(struct kobject *kobj, struct attribute *attr,
        char *buf)
{
    struct my_attr *a = container_of(attr, struct my_attr, attr);
    return scnprintf(buf, PAGE_SIZE, "%d\n", a->value);
}

static ssize_t default_store(struct kobject *kobj, struct attribute *attr,
        const char *buf, size_t len)
{
    struct my_attr *a = container_of(attr, struct my_attr, attr);
    sscanf(buf, "%d", &a->value);
    return sizeof(int);
}

static struct sysfs_ops myops = {
    .show = default_show,
    .store = default_store,
};

static struct kobj_type mytype = {
    .sysfs_ops = &myops,
    .default_attrs = myattr,
};

struct kobject *mykobj;
static int __init sysfsexample_module_init(void)
{
    int err = -1;
    mykobj = kzalloc(sizeof(*mykobj), GFP_KERNEL);
    if (mykobj) {
        kobject_init(mykobj, &mytype);
        if (kobject_add(mykobj, NULL, "%s", "sysfs_sample")) {
             err = -1;
             printk("Sysfs creation failed\n");
             kobject_put(mykobj);
             mykobj = NULL;
        }
        err = 0;
    }
    return err;
}

static void __exit sysfsexample_module_exit(void)
{
    if (mykobj) {
        kobject_put(mykobj);
        kfree(mykobj);
    }
}

module_init(sysfsexample_module_init);
module_exit(sysfsexample_module_exit);
MODULE_LICENSE("GPL");
Run Code Online (Sandbox Code Playgroud)

另外:您可能希望在读取条目时将缓冲区大小输出给用户.这通常是这样做的方式.还要确保信息(读取和写入)采用人类可读的格式,以跟上Unix理念.

更新:请参阅最近关于Sysfs文件创建的有趣文章,该文章由顶级内核开发人员之一Greg Kroah-Hartman编写.