PROC虚拟文件系统
首先介绍一下proc虚拟文件系统,这些虚拟文件里面的内容都是动态创建,通过它可以使用一种
新的方法在Linux内核空间和用户空间进行通信,也就是说可以通过虚拟文件的读写操作与内核。
/proc 文件系统主要可以让您查看运行中的内核,这一点对于监控性能、查找系统信息、了解系统是如何配置的以及更改该配置很有用。该文件系统被称为 虚拟文件系统,因为它实际上根本不是一个文件系统。它只是内核提供的一个映射,被附加在通常的文件系统结构之上,从而使您能够访问它。中的实体进行通信的方式,
其实一开始/proc虚拟文件系统仅是为了了将系统中进程运行时的信息给大家访问,后来发现这个
这个思想还不错,然后有些大侠使用它来一个信息处理,在学习proc文件系统的时候,进入到
/proc目录下,发现每一个进程都对应这一个目录,
执行 ps aux 对照/proc 目录下的各个数字文件
执行 ls /proc
每一个进程ID都有一个对应的ID文件,里面包含进程各个信息。我们还可以到一下这些进程文件
里面的信息具体有什么
执行 cat /proc/iomem
或者 cat /proc/cpuinfo
??? <微笑> 为什么打上这个水印给我的图片啊 什么鬼
下面是介绍关于proc文件的一些操作,里面包括了对于proc目录的创建,proc文件的创建,
怎么将回调函数给实现, 卸载(注销)proc
创建proc目录
你可以创建一个这样的目录放到/proc文件下
因为系统的公共目录也有,但是你想自己区分开的也可以指定文件夹。proc区创建目录那就在下面这个函数的第二个参数传进去一个NULL
如果说想在/
struct proc_dir_entry *proc_mkdir(const char *name,
struct proc_dir_entry *parent);
参数:
name : 文件名
parent:创建或加入文件的节点结构,如果加入/proc下面的传NULL
返回值:要进行必要的说明一下struct proc_dir_entry 结构,
目录文件也是一个文件,文件就得有属性,信息,id,权限等等东西都
保存在里面。
创建一个proc文件,
但是主要讲解创建函数的第四个参数,它是一个结构体,struct file_operations *proc_fops,
要是注意到学过的字符设备或者其他设备的发现这个结构体 struct file_operations 文件操作的一个结构体,
里面成员包含了文件的各种操作。在这个结构里面设置你的读和写的回调。
当时会发现他们的写法和我们普通文件的写法不太一致。
static inline struct proc_dir_entry *proc_create(const char *name, umode_t mode,
struct proc_dir_entry *parent, const struct file_operations *proc_fops)
参数:
name 文件名
mode 文件的访问权限(UGO的模式表示--八进制)
parent 父文件夹的proc_dir_entry对象。
proc_fops 文件的操作函数包含了(open ,read,write)。
网络上一般有两种实现:
1、struct proc_dir_entry *myProc_File = proc_create(\
"file/mytest", \0777, NULL, &myProc_Fops);
2、
#define DRIVER_NAME "myProc_Path"
#define PROCFS_NAME "myProc_File"
struct proc_dir_entry *myProc_File = proc_create(\
DRIVER_NAME'/'PROCFS_NAME, 0777, NULL, &myProc_Fops);
认真观察所谓的两种实现方法都是一种,只是换个裤子放屁。没啥大意义不大细讲。指明路径就可以把创建的虚拟文件生成到对应文件夹。
分析struct file_operations *proc_fops 这个参数
,在此之前要讲解一个序列文件(seq_file)接口的内核实现
怎么使用它将Linux内核里面常用数据结构通过proc文件导出到用户空间,由于虚拟文件系统proc在处理、
大数据的结构(超过page)会有局限性。有些Linux黑客就将它们的一些共性提取出来,做出序列文件接口对内核访问信息更加友好。具体的文件在
Documentation\filesystems\seq_file.txt(序列文件)
填充这个结构体一般来说都是这个模型。要注意的是以seq和single开头的函数,都是序列文件接口提供的
会发现只有open这个函数经过了修饰。往下看
static const struct file_operations myProc_fops = {
.owner = THIS_MODULE,
.open = myProc_open,
.read = seq_read,
.write = myProc_write,
.llseek = seq_lseek,
.release = single_release,
};
关于open这个函数的写法,在Documentation\filesystems\seq_file.txt也做出一些规范对于一个简单的虚拟文件,有一个简单的接口,一个模块只能定义show()函数,他应该 创建所有的虚拟文件将文件输出,对应的open方法如下面这样。
也就是说在open这个回调函数
还有一个函数需要我们自定义实现叫show(),
int single_open(struct file *file,
int (*show)(struct seq_file *m, void *p),
void *data);
show()函数将被调用一次 这数据的私有字段中可以找到给定给single_open()的值seq_file结构。当使用single_open()时,程序员应该使用在file_operations结构中使用single_release()。而不是seq_release()以避免内存泄漏,指定说明释放的方式避免内存泄漏。
所以说在这个里面的我们还要对一个函数进行实现。
在内核里面那就是上
int (*show)(struct seq_file *m, void *p)
具体可以参考下面的例子
#include "linux/module.h"
#define PROC__NAME_DIR "/proc_dir"
#define PROC_NAME_FILE "proc"
static int chrdrv_proc_show(struct seq_file *m, void *v) {
......
return 0;
}
static int chrdrv_proc_open(struct inode *inode, struct file *file) {
return single_open(file, chrdrv_proc_show, NULL);
}
static const struct file_operations proc_fops = {
.owner = THIS_MODULE,
.open = proc_open, // single_open
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
};
void __init proc_init(viod) {
return proc_create(PROC__NAME_DIR '/'PROC_NAME_FILE,\
0777,NULL,&proc_fpos);
}
void __exit proc_exit(void) {
return remove_proc_entry(PROC_NAME,null);
}
module_init(proc_init);
module_exit(proc_exit);
用户层怎么来玩转这个proc虚拟文件系统呢。/proc文件系统主要可以让我们查看在运行的内核,监控性能,信息。
它只是内核提供的一个映射,如果你要做任何修改都必须名字你自己在干嘛,这么做的后果是什么
虚拟文件;事实上这个文件是不存在的,但是你可以访问到里面的数据。那么如果保存这些数据,更改这些数据?
我们不应该使用编辑器来修改这些虚拟文件,要想/proc文件系统修改任何内容的时候,应该使用使用echo命令
然后从命令行输出重定向到/proc 下所选中的文件
如:
echo "hello world" > /proc/my/file
如果想查看/proc 中的信息,应该使用专门的命令或者是 cat 命令
警告:
在/proc下面有着大量关于系统,内核,进程,内存等各种文件。如非熟知里面的结构或者内容,不建议随意改动有关于系统的。 可以在一台对于你或者公司来说不重要的机器上面进行试验操作。
查看这些文件权限的时候,要求用户等级非常之高。并且关系到系统的文件都是要求超级用户进行操作。有些文件对系统用户是不可见的,只对root用户可见。