/proc 虚拟文件系统(实例)
Linux下有一个神奇的目录/proc,经常会运行 cat /proc/cpuinfo 命令查看cpu信息,/proc下的确有cpuinfo文件,但是这个文件不是物理存在的,是软件虚拟出来的,与普通文件不同,该文件是动态的。通过/proc可以实现用户态与内核态之间的通信。在内核模式下,可以很方便的创建/proc子目录,并进行读写操作,只不过此时你需要实现文件读写接口,因为内核不知道如何处理该文件。
下面创建/proc/test目录,并新建log文件,进行读写操作。
一.系统API
extern struct proc_dir_entry proc_mkdir(const char *dir_name,struct proc_dir_entry *parent);
新建/proc子目录,如parent为NULL,则在/proc根下建立目录
extern struct proc_dir_entry proc_create_entry(const char *name,mode_t mode,struct proc_dir_entry *parent);
在/proc下新建虚拟文件
extern void *remove_proc_entry(const char *name,struct proc_dir_entry *parent);
删除新建的文件或目录
二.编码
- #ifndef __KERNEL__
- #define __KERNEL__
- #endif /* __KERNEL__ */
- #include <linux/module.h>
- #include <linux/kernel.h>
- #include <linux/init.h>
- #include <linux/types.h>
- #include <linux/netdevice.h>
- #include <linux/proc_fs.h>
- #include <linux/inet.h>
- #include <linux/vmalloc.h>
- #define MAX_COOKIE_LENGTH PAGE_SIZE
- static struct proc_dir_entry *test_proc_dir;
- static struct proc_dir_entry *log_proc_dir;
- static char *cookie_pot; // 内核缓冲区,用于写数据
- static int tValue = 12; // 显示值
- // 读取日志文件函数
- int ProcLogRead( char *buffer,
- char **start,
- off_t offset,
- int length,
- int *eof,
- void *data )
- {
- int len;
- if( offset > 0 )
- {
- *eof = 1;
- return 0;
- }
- len = sprintf(buffer, "number:%x\n",tValue);
- return len;
- }
- // 写日志文件函数
- int ProcLogWrite( struct file *filp,
- const char __user *buff,
- unsigned long len,
- void *data)
- {
- if( copy_from_user( cookie_pot,buff,len ) ) // 拷贝用户空间值至内核缓冲区
- {
- return -EFAULT;
- }
- sscanf(cookie_pot,"%d",&tValue); // 保存至全局变量tValue
- printk(KERN_ALERT "%s len:%lu vl:%d\n",cookie_pot,len,tValue);
- return len;
- }
- static int __init testproc_init(void)
- {
- int ret = 0;
- printk(KERN_ALERT "proc test init\n");
- cookie_pot = (char*)vmalloc( MAX_COOKIE_LENGTH ); // 为内核缓冲区分配空间
- if(!cookie_pot)
- {
- ret = -ENOMEM;
- }
- else
- {
- memset(cookie_pot,0,MAX_COOKIE_LENGTH);
- test_proc_dir = proc_mkdir("test",init_net.proc_net); // 新建/proc/net/test目录,注:2.6.32以上内核,用init_net.proc_net取代先前的pro_net
- log_proc_dir = create_proc_entry("log",0644,test_proc_dir); // 新建文件 /proc/net/test/log
- if(test_proc_dir == NULL
- || log_proc_dir == NULL)
- {
- ret = -ENOMEM;
- vfree(cookie_pot);
- }
- else
- {
- // 注册读写函数
- log_proc_dir->read_proc = ProcLogRead;
- log_proc_dir->write_proc = ProcLogWrite;
- }
- }
- return 0;
- }
- static void __exit testproc_exit(void)
- {
- printk(KERN_ALERT "clean test proc\n");
- remove_proc_entry("log",test_proc_dir); // 删除log文件
- remove_proc_entry("test",init_net.proc_net); // 删除test目录
- vfree(cookie_pot);
- }
- module_init(testproc_init);
- module_exit(testproc_exit);
- MODULE_LICENSE("Dual BSD/GPL");
- MODULE_AUTHOR("kettas");
- MODULE_DESCRIPTION("proc test");
- MODULE_VERSION("1.0.0");
- MODULE_ALIAS("Proc 01");
三.编译运行
- [scada@linux proc_test]$ sudo insmod proc_test.ko
- [scada@linux proc_test]$ ll /proc/net/test/
- 总用量 0
- -rw-r--r--. 1 root root 0 1月 11 22:14 log
- [scada@linux proc_test]$ cat /proc/net/test/log
- number:c
四.接口操作
上面用cat命令直接查看log文件,既然内核提供了通用的read(),write()文件访问接口,那试试。
- #include <unistd.h>
- #include <stdio.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <fcntl.h>
- #include <assert.h>
- #include <string.h>
- int main(int argc,char **argv)
- {
- int fd = open("/proc/net/test/log",O_RDWR,0);
- assert(fd != -1);
- char *vl = "10"; // 此处为字符串
- // write
- int ret = write(fd,vl,strlen(vl));
- printf("ret:%d\n",ret);
- // read
- char buff[100] = {};
- ret = read(fd,buff,100);
- assert(ret != -1);
- printf("read:%s\n",buff);
- close(fd);
- return 0;
- }
运行:
- [scada@linux proc_test]$ sudo ./write_test
- ret:2
- read:number:a
向/proc/net/test/log写入10后,显示了16进制结果a,测试OK
/proc 虚拟文件系统(实例)相关推荐
- oracle 截取字符串中指定位置_手撕虚拟内存(1)——字符串在虚拟内存中的段位置与/proc虚拟文件系统...
原文:Hack The Virtual Memory: C strings & /proc - Holberton 翻译:RobotCode俱乐部 介绍 这是一系列关于虚拟内存的小文章/教程中 ...
- linux 创建 虚拟文件系统设备 文件节点 使用 proc_create 实例 简介
proc虚拟文件系统也可以创建虚拟文件节点,实现用户空间与内核空间的交互.在驱动中创建节点,可以实现对硬件的控制.proc_create函数原型(在kernel-3.10/include/linux/ ...
- 虚拟文件系统(无持久存储的文件系统),以proc和sysfs为例
对于现代操作系统,虚拟文件系统是一个几乎无处不见的功能,因此,要探究现代操作系统的运行机制,对其进行讨论是必然的. 本文使用的是Linux 2.6.x.x,这是一个变革性的版本,无论是内存管理,进程管 ...
- Linux虚拟文件系统vfs及proc详解
/proc文件系统下的多种文件提供的系统信息不是针对某个特定进程的,而是能够在整个系统范围的上下文中使用.可以使用的文件随系统配置的变化而变化.命令procinfo能够显示基于其中某些文件的多种系统信 ...
- ABP虚拟文件系统(VirtualFileSystem)实例------定制菜单栏显示用户姓名
ABP默认的MVC启动模板在登录后, 右上角显示的是用户名: 如果想让它显示用户的姓名该如何做呢?这就需要用到ABP一个非常强大的功能------虚拟文件系统. 前期准备 使用ABP CLI创建一个名 ...
- linux VFS 虚拟文件系统 简介 super_block inode dentry file
1.简介 1.Linux 中允许众多不同的文件系统共存,如 ext2, ext3, vfat 等.通过使用同一套文件 I/O 系统 调用即可对 Linux 中的任意文件进行操作而无需考虑其所在的具体文 ...
- linux 文件系统_Linux 虚拟文件系统
虚拟文件系统 为了支持各种本机文件系统,且同时允许访问其他操作系统的文件,Linux 内核在用户进程与实际文件系统实现之间引入了一个抽象层,该层称为虚拟文件系统.它的任务并不简单,一方面它要提供一套管 ...
- 《Linux内核设计与实现》读书笔记(十三)- 虚拟文件系统
虚拟文件系统(VFS)是linux内核和具体I/O设备之间的封装的一层共通访问接口,通过这层接口,linux内核可以以同一的方式访问各种I/O设备. 虚拟文件系统本身是linux内核的一部分,是纯软件 ...
- Linux虚拟文件系统
从文件 I/O 看 Linux 的虚拟文件系统 1 引言 Linux 中允许众多不同的文件系统共存,如 ext2, ext3, vfat 等.通过使用同一套文件 I/O 系统 调用即可对 Linux ...
最新文章
- 服务器中加速BIOS启动的方法
- java int byte数组_Java 中int与byte数组转换详解
- 1.25亿用户以后,Netflix总结的系统高可用经验
- 【阿里巴巴研发效能峰会】低代码与数智化分论坛在线预约中……
- Web Service简洁版调用公开手机api
- 前端、数据库、Django简单的练习
- javascript异步_JavaScript异步并在循环中等待
- ElasticSearch 索引基本操作_04
- 如何安装Linux操作系统
- 升级AndroidStudio3.4问题汇总
- SQLServer:执行计划
- sqlplus 乱码的资料
- [swift] LeetCode 215. Kth Largest Element in an Array
- 为什么不使用ipv6计算机网络,ipv6无网络访问权限解决教程
- win7卡在正在启动windows界面_Windows系统电脑卡在开机界面进不去系统解决方法
- 《前端框架开发技术》HTML+CSS+JavaScript 制作个人简历模板
- R语言绘制差异火山图示例
- 解决谷歌浏览器添加插件时显示程序包无效:CRX_HEADER_INVALID
- win10家庭版添加“本地安全策略”
- 笔记 android 知乎,字节跳动团队发布Android Framework笔记,知乎上已获万赞
热门文章
- 360浏览器兼容问题
- recovery编译问题汇总
- Spring MVC+Ant+Tomcat+Eclipse最简单的demo
- MySQL Show命令的使用
- mysql主从安装配置_如何安装和配置mysql主从同步
- python在线问卷调查系统源代码_基于Python 练习1情况的在线问卷
- 伸缩轨道_深度解析——伸缩喷漆房为什么这么受欢迎!
- oracle块空间的使用,Oracle管理存储架构(二)--Oracle管理数据块空间
- php ci 框架 扩展缓存类,CodeIgniter扩展核心类实例详解
- 软件测试bug文档模板,软件bug测试记录模板