2012-09-10 59 views
2

我學習Linux內核,所以我嘗試寫一個簡單的模塊。Linux內核模塊奇怪的行爲

下面的代碼應該控制多少次read()/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"); 

我面對的是,當我使用cattail/proc/proc_test/讀取時,計數器加問題3,而不是由1

輸出:

cat /proc/proc_test 
counter = 0 

cat /proc/proc_test 
counter = 3 

cat /proc/proc_test 
counter = 6 

我做錯了什麼?

回答

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)做任何事情。

+0

這似乎是一個解決方案。無論如何,我應該更加小心'read()'調用。 – Alex

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。

+0

現在,它是由2 – Alex

+0

如果u想用dd讀取數據時會發生什麼遞增(同時獲得100個字節):$ DD如果=的/ proc/= test.out BS = 100計數= 1個 –

+0

DD的proc_test :讀取'/ proc/proc_test':無法分配內存 0 + 0記錄在 0 + 0記錄輸出 0字節(0 B)複製,0.000511612 s,0.0 kB/s – Alex

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 
$ 
+0

似乎是合理的。我沒有試過這個工具。 – Alex

+0

它計算在該模塊創建僞文件執行'read'系統調用,並非所有的讀取由工藝進行。雖然是正確的,但是你的示例顯示從具有相同描述符ID的不同文件中讀取(可能是關閉的,然後在第一次和第二次讀取調用之間重新打開),而不僅僅是/ proc/self/stat,並且可能是有點誤導。 –

+0

@HristoIliev:已更正。謝謝。我的觀點只是期望在這一點上閱讀這篇文章是不合理的。 –