我正在更新我們的內核驅動程序以在Ubuntu 16.0.4上使用Linux內核4.4.0。最後的驅動程序使用linux內核3.9.2。 在其中一個模塊中,我們創建了一個procfs條目來讀取/寫入板載風扇監視值。風扇監控用於讀取/寫入CPU或GPU溫度/調製等。值。如何替換返回EOF和字節數讀取的procfs條目的讀取函數?
使用以下API創建的procfs項的模塊:
struct proc_dir_entry *create_proc_entry(const char *name, umode_t
mode,struct proc_dir_entry *parent);
是這樣的:現在
struct proc_dir_entry * proc_entry =
create_proc_entry("fmon_gpu_temp",0644,proc_dir);
proc_entry->read_proc = read_proc;
proc_entry->write_proc = write_proc;
,該read_proc實現東西是這樣的:
static int read_value(char *buf, char **start, off_t offset, int count, int *eof, void *data) {
int len = 0;
int idx = (int)data;
if(idx == TEMP_FANCTL)
len = sprintf (buf, "%d.%02d\n", fmon_readings[idx]/TEMP_SAMPLES,
fmon_readings[idx] % TEMP_SAMPLES * 100/TEMP_SAMPLES);
else if(idx == TEMP_CPU) {
int i;
len = sprintf (buf, "%d", fmon_readings[idx]);
for(i=0; i < FCTL_MAX_CPUS && fmon_cpu_temps[i]; i++) {
len += sprintf (buf+len, " CPU%d=%d",i,fmon_cpu_temps[i]);
}
len += sprintf (buf+len, "\n");
}
else if(idx >= 0 && idx < READINGS_MAX)
len = sprintf (buf, "%d\n", fmon_readings[idx]);
*eof = 1;
return len;
}
這個讀取函數肯定假設用戶提供了足夠的緩衝空間來存儲t他的溫度值。這在用戶空間程序中正確處理。而且,對於每次調用此函數,讀取值都是全部的,因此對於相同的溫度值,不需要支持/需要後續讀取。 另外,如果我在shell的這個procfs入口上使用「cat」程序,'cat'程序正確顯示了這個值。我認爲通過將EOF設置爲true並返回讀取字節數來支持這一點。
新的Linux內核不再支持這個API。
我的問題是:
我怎麼能這個API更改爲新的procfs的API結構保持功能一樣:每次讀取應返回的值,程序「貓」也應該很好地工作,而不是進入無限循環?
我已經在問題中添加了讀取函數的實現。我知道我可以從用戶空間多次調用讀取函數,並且每次獲得更新的溫度值。對 ? 此外,這裏沒有文件偏移,因此每次調用這裏讀取就像讀取一個變量。程序'貓'沒有進入無限循環就可以正常工作。 – Monku
對我來說,問題是如何實現與新內核API類似的東西。也就是說,我應該可以打開單個文件多次調用讀取。如果我將seq_file與single_open一起使用,那麼在第二次調用讀取之前,我將不得不關閉文件,對吧? – Monku
'如果我使用seq_file與single_open,我將不得不在第二次打電話之前關閉文件,對吧?' - 是的,當文件被讀取到EOF時,您需要在重新讀取之前重置讀取位置。它可以通過文件重新打開('close()'+'open()')或者使用'lseek()'到0來完成。但'single_open()'並不意味着你可能只打印單個值來輸出:在'.show'函數內部,你可以執行類似於'read_proc'中的循環。但更好的方法是用'seq_open()'而不是'single_open()'使用完整的'seq_file'功能。 – Tsyvarev