歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux基礎 >> Linux教程 >> Linux proc 的文件系統的源碼分析

Linux proc 的文件系統的源碼分析

日期:2017/2/28 15:59:57   编辑:Linux教程

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,是為了構建父節點和子節點的關系

  1. struct proc_dir_entry *create_proc_entry(const char *name, mode_t mode,
  2. struct proc_dir_entry *parent)
  3. {
  4. struct proc_dir_entry *ent;
  5. nlink_t nlink;
  6. if (S_ISDIR(mode)) {
  7. if ((mode & S_IALLUGO) == 0)
  8. mode |= S_IRUGO | S_IXUGO;
  9. nlink = 2;
  10. } else {
  11. if ((mode & S_IFMT) == 0)
  12. mode |= S_IFREG;
  13. if ((mode & S_IALLUGO) == 0)
  14. mode |= S_IRUGO;
  15. nlink = 1;
  16. }
  17. ent = proc_create(&parent,name,mode,nlink);
  18. if (ent) {
  19. if (S_ISDIR(mode)) {
  20. ent->proc_fops = &proc_dir_operations;
  21. ent->proc_iops = &proc_dir_inode_operations;
  22. }
  23. if (proc_register(parent, ent) < 0) {
  24. kfree(ent);
  25. ent = NULL;
  26. }
  27. }
  28. return ent;
  29. }
在proc_register方法裡面會改變父子的proc_dir_entry鏈表指向構建父和子的樹狀結構,也就是struct proc_dir_entry *next, *parent, *subdir;

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文件中,然後進程讀出內容到自己的用戶空間,然後關閉這個文件。關閉這個動作就非常重要,如果不關閉,那麼裡面的內容將不會在跟新。

Copyright © Linux教程網 All Rights Reserved