admin 管理员组文章数量: 887021
/proc文件系统的使用
/proc文件系统是Linux内核的一个虚拟文件系统,说它虚拟,是因为和磁盘分区上的文件系统不同,它只有在内核启动以后,工作起来的时候才会被动态创建。
/proc下面的内容会随着内核的配置和工作的状态在变化,比如/proc/meminfo这个文件,里面的内容是内存信息,不同的机器自然不同;还有就是/proc目录下面用数字命名的子目录,每个子目录的名字也就是数字,对应当前系统正在运行的进程,而子目录里面的内容就是对应进程的信息。
/proc里面还有其他许多信息,这里就不一一描述了,有兴趣可以谷歌一下。
Linux内核经过多年发展,/proc目录下的林林总总,已经是非常多了,虽然已经开发出了新的/sys文件系统替代/proc,但是,许多传统的程序仍然使用/proc文件系统作为内核与用户程序的接口。
如何让内核更高效,那是内核开发人员的事情。作为一个使用内核的开发人员,掌握/proc文件系统的使用方法也是很有用的,和/sys文件系统组织严密的结构相比,用/proc有时候还是很方便的。
不多说废话了,先入个门,介绍/proc的最基本操作。
这一集我们就介绍操作/proc文件系统的三个最基本函数:
代码片段1 定义在内核代码的<linux/proc_fs.h>
- struct proc_dir_entry *create_proc_entry(const char *name, mode_t mode,
- struct proc_dir_entry *parent);
- struct proc_dir_entry *proc_mkdir(const char *name,
- struct proc_dir_entry *parent);
- void remove_proc_entry(const char *name, struct proc_dir_entry *parent);
先插一句,本例所有代码使用内核版本2.6.38.2,系统是ubuntu 11.04 amd64,要注意哦。
这三个函数,从函数名称就可以理解出来意思,第一个create_proc_entry()函数用做创建一个节点,也就是创建一个文件;
第二个proc_mkdir()函数建立一个目录;
第三个remove_proc_entry()函数是删除一个节点,实际上,不仅能删除节点,也可以删除proc_mkdir()函数创建的目录。
需要注意的是,proc相关的函数,操作的目标都是在/proc目录下。好,继续看函数参数:
create_proc_entry()函数:
name 是节点的名称,一个字符串;
mode 访问权限,可以使用八进制表示,chmod命令使用的权限一样;
parent 父目录,注意是一个struct proc_dir_entry结构,如果写NULL表示/proc目录。
proc_mkdir()函数:
name 子目录名称,一个字符串;
parent 父目录,和上面解释一样。
remove_proc_entry()函数:
参数同上面一样。
函数介绍完毕。有这三个函数就可以开工了。废话少说,贴代码:
代码片段2 自己写的小模块,演示如何建立删除/proc节点
- #include <linux/module.h>
- #include <linux/init.h>
- #include <linux/version.h>
- #include <linux/proc_fs.h>
- MODULE_LICENSE("Dual BSD/GPL");
- MODULE_AUTHOR("<freshpassport@gmail>");
- #define USER_ROOT_DIR "pt"
- #define USER_ENTRY1 "pt_entry1"
- static struct proc_dir_entry *pt_root;
- static struct proc_dir_entry *pt_entry1;
- static int proc_test_init(void)
- {
- pt_root = proc_mkdir(USER_ROOT_DIR, NULL);
- if (NULL==pt_root)
- {
- printk(KERN_ALERT "Create dir /proc/%s error!\n",
- USER_ROOT_DIR);
- return -1;
- }
- printk(KERN_INFO "Create dir /proc/%s\n", USER_ROOT_DIR);
- pt_entry1 = create_proc_entry(USER_ENTRY1,
- 0666, pt_root);
- if (NULL == pt_entry1)
- {
- printk(KERN_ALERT "Create entry %s under /proc/%s error!\n",
- USER_ENTRY1, USER_ROOT_DIR);
- goto err_out;
- }
- printk(KERN_INFO "Create /proc/%s/%s\n",
- USER_ROOT_DIR, USER_ENTRY1);
- pt_entry1->read_proc = NULL;
- pt_entry1->write_proc = NULL;
- return 0;
- err_out:
- remove_proc_entry(USER_ROOT_DIR, pt_root);
- return -1;
- }
- static void proc_test_exit(void)
- {
- remove_proc_entry(USER_ENTRY1, pt_root);
- remove_proc_entry(USER_ROOT_DIR, NULL);
- printk(KERN_INFO "All Proc Entry Removed!\n");
- }
- module_init(proc_test_init);
- module_exit(proc_test_exit);
一个标准的2.6内核模块写法。proc_test_init()函数是入口,proc_test_exit()函数是出口。
最开始引入了4个头文件,其中3个是内核模块标配的头文件,第4个是主角,proc_fs.h,前面说了,操作/proc的函数就定义在里面。
第9行,USER_ROOT_DIR定义了我们要在/proc目录下建立的子目录名称,也是用户的根目录;第10行,USER_ENTRY1定义了欲在USER_ROOT_DIR下面建立的节点名称。
第13、14行分别定义了USER_ROOT_DIR和USER_ENTRY1对应的目录结构pt_root和pt_entry1。
操作的数据介绍好了,说下流程吧。
proc_test_init()函数:
此函数是加载模块的时候执行的入口函数,会被内核自动调用。第19行,函数一开始就调用proc_mkdir()函数,在/proc目录下建立一个子目录,注意proc_mkdir()函数的第二个参数,NULL表示以/proc作为根目录。
子目录USER_ROOT_DIR建立成功后,紧接着调用create_proc_entry()函数建立一个文件节点,注意函数的第三个参数parent,不是NULL,而是pt_root,表示以USER_ROOT_DIR作为根目录。
文件建立成功后,需要设置pt_entry1的读写回调函数为NULL,这样做的目的是该文件节点读写操作都不处理。
proc_test_exit()函数:
用户调用rmmod卸载内核模块的时候被内核调用。此函数删除已经建立的节点,要注意的是remove_proc_entry()函数的parent实参,这里容易出错,导致内核报错。
最后贴一下Makefile:
- obj-m += proc_test1.o
- all:
- make -C /usr/src/linux-headers-2.6.38-8-generic M=`pwd` modules
- clean:
- make -C /usr/src/linux-headers-2.6.38-8-generic M=`pwd` clean
看看执行的效果:
下面是加载模块后列出文件节点
- root@iscsia:~/proc_test# ll /proc/pt/
- total 0
- -rw-rw-rw- 1 root root 0 2011-07-01 15:04 pt_entry1
下面是读文件节点/proc/pt/pt_entry1
- root@iscsia:~/proc_test# cat /proc/pt/pt_entry1
- root@iscsia:~/proc_test#
什么结果都没有,正常,因为回调函数都给设置为NULL了。
下面是写文件节点/proc/pt/pt_entry1
- root@iscsia:~/proc_test# echo "hello,entry" > /proc/pt/pt_entry1
- -bash: echo: write error: Input/output error
看来写操作不是很理想,报错了,pt_entry1不是很合作啊,也是,前面都给人家设置成NULL了,也不能全怪人家了。哈哈。下次继续介绍如何进行自己的读写操作。
版权声明:本文标题:proc文件系统的使用 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.freenas.com.cn/jishu/1725892092h888370.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论