简体   繁体   English

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

[英]Kernel module's parameters in sysfs - quick reaction for changes

Is it possible to notify the module when one of it's sys files was changed? 当其中一个sys文件被更改时,是否可以通知模块? My task is to do a file which controls size of buffer inside the module, I want to resize the buffer when the value in the file is changed. 我的任务是做一个控制模块内缓冲区大小的文件,我想在文件中的值改变时调整缓冲区的大小。 My other idea (if I can't notify the module) was to check the previous value each time the module is used and then resize the buffer. 我的另一个想法(如果我不能通知模块)是每次使用模块时检查前一个值,然后调整缓冲区的大小。

Isn't this the purpose of Sysfs? 这不是Sysfs的目的吗?

When you create a kobject and give it a representation in Sysfs (which is a directory), you then create attributes for that object which will become files in that directory. 当您创建kobject并在Sysfs(这是一个目录)中为其提供表示时,您将为该对象创建属性,该属性将成为该目录中的文件。 You provide a store and a show callback to the kobject , which are basically equivalents of resp. 你为kobject提供了一个store和一个show callback,它基本上等同于resp。 write and read . writeread

store is what you want here. store就是你想要的。 It looks like this: 它看起来像这样:

ssize_t (*store)(struct kobject *kobj, struct attribute *attr, 
    const char *buffer, size_t size);

You receive size bytes within buffer as soon as the virtual file is written in user land. 只要在用户域中写入虚拟文件,就会在buffer内收到size字节。

Have a look at this module which does it (taken from here ): 看看这个模块(从这里开始 ):

#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");

Also : you might want to output the buffer size to the user when the entry is read. 另外 :您可能希望在读取条目时将缓冲区大小输出给用户。 This is usually the way of doing it. 这通常是这样做的方式。 Also make sure the information (read and written) is in a human-readable format to keep up with the Unix philosophy. 还要确保信息(读取和写入)采用人类可读的格式,以跟上Unix理念。

Update : see this recent interesting article about Sysfs file creation written by Greg Kroah-Hartman, one of the top kernel developers. 更新 :请参阅最近关于Sysfs文件创建的有趣文章,该文章由顶级内核开发人员之一Greg Kroah-Hartman编写。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM