linux proc 源码,Linux proc 的文件系统的源码分析

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,是为了构建父节点和子节点的关系

structproc_dir_entry *create_proc_entry(constchar*name, mode_t mode,

structproc_dir_entry *parent)

{

structproc_dir_entry *ent;

nlink_t nlink;

if(S_ISDIR(mode)) {

if((mode & S_IALLUGO) == 0)

mode |= S_IRUGO | S_IXUGO;

nlink = 2;

}else{

if((mode & S_IFMT) == 0)

mode |= S_IFREG;

if((mode & S_IALLUGO) == 0)

mode |= S_IRUGO;

nlink = 1;

}

ent = proc_create(&parent,name,mode,nlink);

if(ent) {

if(S_ISDIR(mode)) {

ent->proc_fops = &proc_dir_operations;

ent->proc_iops = &proc_dir_inode_operations;

}

if(proc_register(parent, ent) 

kfree(ent);

ent = NULL;

}

}

returnent;

}在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文件中,然后进程读出内容到自己的用户空间,然后关闭这个文件。关闭这个动作就非常重要,如果不关闭,那么里面的内容将不会在跟新。0b1331709591d260c1c78e86d0c51c18.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值