Linux内核模块奇怪的行为

时间:2012-09-10 14:47:41

标签: c linux-kernel

我正在研究一个linux内核,所以我尝试编写一个简单的模块。

以下代码应控制调用read()的{​​{1}}次:

/proc/proc_test

我遇到的问题是,当我使用#include <linux/init.h> #include <linux/module.h> #include <linux/proc_fs.h> #include <linux/kernel.h> #include <asm/current.h> static int __init init(void); static void __exit stop(void); static int proc_read(char *buffer, char **start, off_t offset, int size, int *eof, void *data); static int counter = 0; static int proc_read(char *buffer, char **start, off_t offset, int size, int *eof, void *data) { if (size < 256) return -ENOMEM; return sprintf(buffer, "counter = %d\n", counter++); <-- supposed to be incremented once } static int __init init() { if (create_proc_read_entry("proc_test", 0, NULL, proc_read, NULL) == 0) { printk(KERN_ERR "Can not creat entry\n"); return -ENOMEM; } printk("Entry created!\n"); return 0; } static void __exit stop() { remove_proc_entry("proc_test", NULL); printk("Entry removed!\n"); return; } module_init(init); module_exit(stop); MODULE_LICENSE("GPL"); /proc/proc_test/cat读取时,计数器会增加3而不是1。

输出:

tail

我做错了什么?

3 个答案:

答案 0 :(得分:3)

试试这个:

static int proc_read(char *buffer, char **start, off_t offset, int size, int *eof, void *data) {
    if (size < 256) return -ENOMEM;
    int count= sprintf(buffer, "counter = %d\n", counter++);
    *eof = 1;
    return count;
}

设置* eof = 1,您的驱动程序通知内核(以及想要读取您的proc文件的应用程序)您的驱动程序已达到EOF。

答案 1 :(得分:3)

唯一不对的是你有一个不合理的期望。是什么让您认为cat /proc/proc_test只会拨打read一次?

$ strace cat /proc/self/stat | grep read
read(3, "17423 (cat) R 17420 17420 13224 "..., 32768) = 238
read(3, "", 32768)                      = 0
$

答案 2 :(得分:1)

即使this answer有一个很好的提示,我也遇到过这个问题。理论上设置*eof = 1应该已经解决了问题,但不知何故它没有。

我的解决方法是将此功能添加到功能的顶部:

if (offset > 0)    // even though I set *eof = 1, the kernel is still calling me, so return 0 for it to stop
    return 0;

上面的评论实际上就是我在自己的模块中所写的内容。

这样做是为了确保只对您的函数(offset为0)的第一次调用做任何事情。