proc 的文件系統是linux 裡面常用的基於內存的文件系統。linux的內核版本 2.6.18
重要的struct:
struct proc_dir_entry {
unsigned int low_ino;
unsigned short namelen;
const char *name;
mode_t mode;
nlink_t nlink;
uid_t uid;
gid_t gid;
loff_t size;
struct inode_operations * proc_iops;
const struct file_operations * proc_fops;
get_info_t *get_info;
struct module *owner;
struct proc_dir_entry *next, *parent, *subdir;
void *data;
read_proc_t *read_proc;
write_proc_t *write_proc;
atomic_t count;/* use count */
int deleted; /* delete flag */
void *set;
};
其中3個核心的函數指針
const struct file_operations * proc_fops; 當文件系統操作proc文件系統的時候,read,write,open所調用的函數
proc 文件系統同時定義了默認的proc file operations的時候
static struct file_operations proc_file_operations = {
.llseek = proc_file_lseek,
.read = proc_file_read,
.write = proc_file_write,
};
在使用默認的proc file operations 的時候,需要定義自己的read_proc/write_proc的函數
read_proc_t *read_proc; 寫自己的read的函數
write_proc_t *write_proc; 寫自己的write的函數
1.初始化
在Main.c裡面調用了 root.c 裡的函數 proc_root_init(); 初始化了一些基本的proc目錄下的文件,例如 cpuinfo, stat....
2.創建proc文件
a . struct proc_dir_entry *create_proc_entry(const char *name, mode_t mode, struct proc_dir_entry *parent)
參數 name 是要創建的 proc 文件名。
mode 是該entry性質,例如 DIR(目錄)/LNK(鏈接)/REG(文件)
parent 指定該文件的上層 proc 目錄項,如果為 NULL,表示創建在 /proc 根目錄下。
在create_proc_entry函數裡會設置文件的名字,文件的權限,傳入上層的 proc_dir_entry,是為了構建父節點和子節點的關系
dp->next = dir->subdir;
dp->parent = dir;
dir->subdir = dp;
同時也指定了默認的const struct file_operations * proc_fops,為proc_file_operations
b. static inline struct proc_dir_entry *create_proc_read_entry(const char *name,
mode_t mode, struct proc_dir_entry *base,
read_proc_t *read_proc, void * data)
創建函數體傳進的指定的read proc文件的方法 read_proc_t *read_proc;
實際上這個函數存在的意義不是很大,直接可以使用create_proc_entry來替代,在多做一件事情,就是指定proc_dir_entr->read_proc=read_proc;
如果不想默認的proc file 的操作函數,你也可以自己指定自己的操作函數,只要用create_proc_entry返回的proc_dir_entry結構體裡直接指定proc_fops指針指向自己的定義的結構體,就可以了
比如:
static struct file_operations proc_my_operations = {
.open = my_open,
.read = my_read,
.write = my_write
.llseek = my_lseek,
.release = my_release,
};
/proc/stat /proc/interrupts ... 顯示系統運行狀態的設計技巧
象stat,interrupts 的這樣反應系統狀態的文件,
首先系統的狀態實際上都是已經在系統的內存中,
其次如果沒有別的進程對該文件監視,是不需要往這個文件裡寫內容的
哪怕在時間中斷中去寫這個文件(內存的一次復制),也是沒有必要的,第一有系統的開銷,第二沒有人關注它,第三不可控性
所以對於系統狀態的監聽,應該是由外部(想監聽的系統)來觸發的,不需要內核時時刻刻去寫系統狀態文件,那麼這樣的設計就很簡單了,內核只要在open的函數裡去寫當時的狀態就足夠了。
也就是對外部系統按照自己的頻率去打開這個文件,內核復制狀態到proc文件中,然後進程讀出內容到自己的用戶空間,然後關閉這個文件。關閉這個動作就非常重要,如果不關閉,那麼裡面的內容將不會在跟新。