[英]Linux kernel module strange behaviour
我正在研究linux內核,因此我嘗試編寫一個簡單的模塊。
以下代碼應該控制/proc/proc_test
read()
調用次數:
#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");
我遇到的問題是,當我使用cat
或tail
從/proc/proc_test/
讀取時,計數器將增加3而不是增加1。
輸出:
cat /proc/proc_test
counter = 0
cat /proc/proc_test
counter = 3
cat /proc/proc_test
counter = 6
我究竟做錯了什么?
嘗試這個:
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。
唯一的錯誤是您的期望不合理。 是什么讓您認為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
$
即使這個答案有一個很好的提示,我也一直遇到這個問題。 理論上設置*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)會執行任何操作。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.