proc_create的使用方法

摘要:
proc_create的使用方法proc文件系统是个有用的东东。调用以下函数,即可实现proc文件夹的创建:structproc_dir_entry*proc_mkdir;name就是要创建的文件夹名称。parent与proc_mkdir中的parent类似。也是父文件夹的proc_dir_entry对象。staticconststructfile_operationsmytest_proc_fops={.open=mytest_proc_open,.read=seq_read,.write=mytest_proc_write,.llseek=seq_lseek,.release=single_release,};以seq_和single_为前缀的函数都是kernel中现成的。发现show函数的第一个参数为seq_file类型,在show函数中,可以将seq_file的private成员转换成对应的类型进行使用。例如,cat/proc/mytest/mytest时,mytest_proc_show函数将会被调用。"true":"false");return0;}接下来再看看mytest_proc_write函数的实现。顾名思义,mytest_proc_write函数会在写mytest文件时被调用。

proc_create的使用方法

proc文件系统是个有用的东东。
创建一个proc虚拟文件,应用层通过读写该文件,即可实现与内核的交互
proc虚拟文件是如何创建的呢?

先看看比较简单的,创建proc文件夹。
调用以下函数,即可实现proc文件夹的创建:
struct proc_dir_entry *proc_mkdir(const char *name, struct proc_dir_entry *parent);
name就是要创建的文件夹名称。
parent是要创建节点的父节点。也就是要在哪个文件夹之下创建新文件夹,需要将那个文件夹的proc_dir_entry传入。
如果是在/proc目录下创建文件夹,parent为NULL。
例如:

struct proc_dir_entry *mytest_dir = proc_mkdir("mytest", NULL);

然后来看看proc文件的创建。
创建方法是调用以下函数:

static inline struct proc_dir_entry *proc_create(const char *name, mode_t mode, struct proc_dir_entry *parent, const struct file_operations *proc_fops);

name就是要创建的文件名。
mode是文件的访问权限,以UGO的模式表示。
parent与proc_mkdir中的parent类似。也是父文件夹的proc_dir_entry对象
proc_fops就是该文件的操作函数了
例如:

struct proc_dir_entry *mytest_file = proc_create("mytest", 0x0644, mytest_dir, mytest_proc_fops);

还有一种方式:

struct proc_dir_entry *mytest_file = proc_create("mytest/mytest", 0x0644, NULL, mytest_proc_fops);

如果文件夹名称和文件名定义为常量:

#define MYTEST_PROC_DIR "mytest"
#define MYTEST_PROC_FILE "mytest"

第二种方式为:

struct proc_dir_entry *mytest_file = proc_create(MYTEST_PROC_DIR"/"MYTEST_PROC_FILE, 0x0644, NULL, mytest_proc_fops);

接下来看看mytest_proc_fops的定义。

static const struct file_operations mytest_proc_fops ={
 .open  =mytest_proc_open,
 .read  =seq_read,
 .write  =mytest_proc_write,
 .llseek  =seq_lseek,
 .release =single_release,
};

以seq_和single_为前缀的函数都是kernel中现成的。
可以参考文档:Documentationfilesystemsseq_file.txt
关于single_开头的函数,有以下说明:

The extra-simple version

For extremely simple virtual files, there is an even easier interface. A
module can define only the show() function, which should create all the
output that the virtual file will contain. The file's open() method then
calls:

 int single_open(struct file *file,
                 int (*show)(struct seq_file *m, void *p),
                 void *data);

When output time comes, the show() function will be called once. The data
value given to single_open() can be found in the private field of the
seq_file structure. When using single_open(), the programmer should use
single_release() instead of seq_release() in the file_operations structure
to avoid a memory leak.

根据以上这段说明,在mytest_proc_open函数中,只需要调用single_open函数,并传入一个show函数即可。
例如:

static int mytest_proc_open(struct inode *inode, struct file *file)
{
 return single_open(file, mytest_proc_show, inode->i_private);
}

其中第三个参数,也就是single_open的data参数,内核中有些地方传入的NULL,有些地方传入的inode->i_private,也有传入其他值的。
来看看data在single_open函数中如何被使用的:
if (!res)
((struct seq_file *)file->private_data)->private = data;
这与前面的英文说明一致,data是seq_file结构体的private成员。
那么data如何真正被使用的呢?
发现show函数的第一个参数为seq_file类型,在show函数中,可以将seq_file的private成员转换成对应的类型进行使用。

下面来看看mytest_proc_show函数如何实现。
传递给single_open的show函数指针,将在proc file输出时被调用。
例如,cat /proc/mytest/mytest时,mytest_proc_show函数将会被调用。
假设我们的mytest只是记录了一个标志,内核中会根据该标准执行不同的操作。
来看看mytest_proc_show的实现:

static int task_lifecycle_proc_show(struct seq_file *seq, void *v)
{
 seq_puts(seq, mytest_flag ? "true
" : "false
");
 return 0;        
}

接下来再看看mytest_proc_write函数的实现。
顾名思义,mytest_proc_write函数会在写mytest文件时被调用。
功能就是记录写入数据到mytest文件。
实现也不麻烦:

static ssize_t task_lifecycle_proc_write(struct file *file, const char __user *buffer,
        size_t count, loff_t *pos)
{
 charmode;
 if (count > 0) {
  if(get_user(mode, buffer))
   return -EFAULT;
   mytest_flag = (mode != '0');
 }
 returncount;
}

至此,proc文件创建完毕。
通过读写mytest文件,即可实现对mytest_flag的控制。
更深层次的原理,即proc文件系统是如何实现的,就先不讨论了。
不然又成懒婆娘的裹脚了

免责声明:文章转载自《proc_create的使用方法》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇安装Sql Server 2008R2报错0x84B10001sql查询数据库中所有表的记录条数,以及占用磁盘空间大小。下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

随便看看

ABB机器人功能程序(FUNC)

功能程序的应用范围非常广泛。熟练的人员可以根据不同的需求创建相应的功能程序。函数程序的固定格式是FUNC,返回结束。在ABB的学习中,许多学生对功能程序几乎一无所知,即使他们真的在使用它。在学习ABB的过程中,我遇到了几个用例,所以我总结了它们以加深我的理解。...

css实现切角效果

html<divclass=“corner”>#58a0);#58a0)右,#58a0)左;3.四个倒角css。角{width:4。圆弧倒角css。右上角(width:#58a0);背景重复:无重复;...

GeoServer基础教程(一):环境搭建篇

到目前为止,GeoServer环境已经建立,下面的博客文章将继续让您熟悉GeoServer的界面和基本功能。...

GitLab 数据库

要访问GitLab数据库步骤中使用的DockerGitlab,首先输入容器dockerexec-itgitlab/bin/bash ``查找数据库配置文件``bash/var/opt/GitLab/gitlabrails/etc/database yml内容如下,记录数据库配置信息production:adapter:postgresqlencoding:u...

Linux下如何确认磁盘是否为SSD

方法1:通过cat/sys/block/sda/queue/rotative查看/sys/block/sda/queet/rotative,返回值0为SSD;返回1表示HDD。方法2:通过lsscsi[root@ssd-testthatsit]#cat/sys/bl...

Docker(一)

Docker的优势:1.更高效的利用系统资源。docker-v:查看Docker版本。dockerhistory:查看镜像内的历史记录。dockerdiff:查看修改的内容。使用Dockerfile定制镜像:1.以之前定制nginx镜像为例,这次我们使用Dockerfile来定制。操作Docker容器:启动容器有两种方式:一种:是基于镜像新建一个容器并启动,...