文档章节

proc_fs 使用说明

吃草小蚁
 吃草小蚁
发布于 2013/12/04 08:59
字数 1175
阅读 205
收藏 1

创建一个 proc 文件
根据对 proc 文件的不同使用,内核提供了多种包装函数来创建一个 proc 文件。

方法一:
struct proc_dir_entry *create_proc_entry(const char *name, mode_t mode, struct proc_dir_entry *parent)
这是最直接,包装最少的创建方法。
参数 name 是要创建的 proc 文件名。mode 是该文件权限值,例如 S_IRUGO,可传入0表示采用系统默认值。parent 指定该文件的上层 proc 目录项,如果为 NULL,表示创建在 /proc 根目录下。
create_proc_entry() 完成的任务主要包括:检测 mode 值,分配 proc_dir_entry 结构,注册 proc_dir_entry。

方法二:
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)
{
    struct proc_dir_entry *res=create_proc_entry(name,mode,base);
    if (res) {
        res->read_proc=read_proc;
        res->data=data;
    }
    return res;
}
如果要创建一个只读的 proc 文件,可以采用 create_proc_read_entry() 这个接口。这个接口其实就是给 proc_dir_entry 多赋了两个值,其中 read_proc 是一个函数指针, data 是 read_proc 调用时传给它一个参数。关于 read_proc 函数,接下来会另行分析。

方法三:
struct proc_dir_entry *proc_create(const char *name, mode_t mode, struct proc_dir_entry *parent, const struct file_operations *proc_fops)
如果要创建一个 proc 文件,并且不用 proc_fs 默认提供的 file_operations 的话,可以使用 proc_create() 这个函数,通过最后一个参数来指定要创建的 proc 文件的 file_operations。
每个 proc 文件也都会用到 file_operations,在调用 create_proc_entry() 创建 proc 文件时,其中一步是调用 proc_register(),proc_register() 会为 proc_dir_entry 提供一个默认的 file_operations,而 proc_create() 与 create_proc_entry() 唯一差别就是在调用 proc_register() 前先设置好 proc_dir_entry 的 file_operations,这样在 proc_register() 时就不会设置使用 proc_fs 默认的 file_operations 了。
proc_fs 默认的 file_operations 定义如下:
static const struct file_operations proc_file_operations = {
    .llseek        = proc_file_lseek,
    .read        = proc_file_read,
    .write        = proc_file_write,
};
关于这个 proc_file_operations,后面会继续讲到。
proc_create() 一般在创建使用 seq_file 接口的 proc 文件时会使用。

创建一个 proc 目录
创建一个 proc 目录就调用 struct proc_dir_entry *proc_mkdir(const char *name, struct proc_dir_entry *parent) 这个函数。参数name 是目录名,parent 是该目录的上层 proc 目录项,如果为 NULL,表示创建在 /proc 根目录下。

删除一个 proc 项
要删除一个 proc 文件或目录就调用 void remove_proc_entry(const char *name, struct proc_dir_entry *parent)

注意事项

proc 项创建时要避免已经存在同名的 proc 项,否则注册时内核会报错(但还是会成功返回那个 proc 项),在删除时有时会删不掉(尤其是 proc 目录)。
删除一个 proc 目录会把这个目录所有的 proc 文件都删除。

读 proc 文件

proc 文件的读需要自己提供一个 read_proc_t 类型的函数放在 proc_dir_entry 结构中供 proc_file_read() 函数调用。下面是 read_proc_t 类型函数的定义:
typedef int (read_proc_t)(char *page, char **start, off_t off, int count, int *eof, void *data);
这个函数的定义很复杂,不过当 proc 文件返回的数据量总是小于一个 PAGE_SIZE 时可以简化使用。关于这个函数以及它的那一大串参数我觉得再怎么解释都解释不全,所以还是留给自己去看 proc_file_read() 的代码就明白了。

写 proc 文件
proc 文件的写很简单。如果是使用 proc_fs 默认提供的 file_operations 的话,要自己实现一个 write_proc_t 类型的函数放在 proc_dir_entry 结构中供 proc_file_write() 函数调用。write_proc_t 类型函数的定义如下:
typedef int (write_proc_t)(struct file *file, const char __user *buffer, unsigned long count, void *data);
下面是 proc_file_write() 的实现:
static ssize_t proc_file_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos)
{
    struct inode *inode = file->f_path.dentry->d_inode;
    struct proc_dir_entry * dp;
  
    dp = PDE(inode);

    f (!dp->write_proc)
        return -EIO;

    /* FIXME: does this routine need ppos? probably... */
    return dp->write_proc(file, buffer, count, dp->data);
}
可见 proc 文件的写忽略了使用偏移量。

如果是使用自己提供的 file_operations 的话,那还是要自己实现一个 write 函数赋给 file_operations 的 .write 指针。

一个例子
#include <linux/module.h>
#include <linux/proc_fs.h>
#include <asm/uaccess.h>

static struct proc_dir_entry *mydir;
static struct proc_dir_entry *pfile;

static char msg[255];

static int myproc_read(char *page, char **start, off_t off, int count, int *eof, void *data)
{
        int len = strlen(msg);

        if (off >= len)
                return 0;

        if (count > len - off)
                count = len - off;

        memcpy(page + off, msg + off, count);
        return off + count;
}

static int myproc_write(struct file *file, const char __user *buffer, unsigned long count, void *data)
{
        unsigned long count2 = count;

        if (count2 >= sizeof(msg))
                count2 = sizeof(msg) - 1;

        if (copy_from_user(msg, buffer, count2))
                return -EFAULT;

        msg[count2] = '/0';
        return count;
}

static int __init myproc_init(void)
{
        mydir = proc_mkdir("mydir", NULL);
        if (!mydir) {
                printk(KERN_ERR "Can't create /proc/mydir/n");
                return -1;
        }

        pfile = create_proc_entry("pool", 0666, mydir);
        if (!pfile) {
                printk(KERN_ERR "Can't create /proc/mydir/pool/n");
                remove_proc_entry("mydir", NULL);
                return -1;
        }

        pfile->read_proc = myproc_read;
        pfile->write_proc = myproc_write;

        return 0;
}

static void __exit myproc_exit(void)
{
        remove_proc_entry("pool", mydir);
        remove_proc_entry("mydir", NULL);
}

module_init(myproc_init);
module_exit(myproc_exit);

这个例子创建一个 /proc/mydir/pool,它相当于一个池子,你向它写什么,你读它的时候它就返回什么,当然它的容量是有限的 :)

© 著作权归作者所有

共有 人打赏支持
吃草小蚁
粉丝 15
博文 63
码字总数 110019
作品 0
深圳
高级程序员
[linux c]proc 文件系统查看及修改

本文参考 华清远见资料 使用 proc 文件系统查看进程信息 1)认识 proc 文件系统的文件和目录 [root@vm root]#cd /proc [root@vm root]#ls 2)通过 proc 文件系统查看系统当前进行状态 [root@vm...

lilin9105
2014/05/28
0
0
Linux最大打开文件描述符数

1. 系统最大打开文件描述符数:/proc/sys/fs/file-max a. 查看 $ cat /proc/sys/fs/file-max 186405 2. 设置 a. 临时性 # echo 1000000 > /proc/sys/fs/file-max 2. 永久性:在/etc/sysctl.c......

liujing07
06/26
0
0
Linux的mount命令,关于rootfs的一个疑问

首先,使用Linux系统的朋友可以先敲下命令‘mount’吗? 在大家的输出中有出现类似'rootfs on / type rootfs'这样的结果吗? 我的结果大致如下: /dev/sda1 on / type ext3 (rw) proc on /p...

ChenQi
2012/08/31
3.6K
8
linux 高并发系统限制 设置

本文打算探讨两种设置方法,一种是在程序中动态设置,一种是在程序启动前的静态设置。 先说静态设置(具体设置见:参考csdn的一篇文章): 1,在/etc/security/limits.conf中修改或者添加进程...

hakuyo
06/26
0
0
centos7修改内核参数

临时修改: a.开启内核路由转发功能:echo "1" >> /proc/sys/net/ipv4/ip_forwardb.禁止所有的icmp回包(禁止其它机器ping本机):echo "1" >> /proc/sys/net/ipv4/icmpechoignore_allc.调整......

Lee_吉
2017/12/28
0
0

没有更多内容

加载失败,请刷新页面

加载更多

可爱的python测试开发库(python测试开发工具库汇总)

欢迎转载,转载请注明来源: github地址 谢谢点赞 本文地址 相关书籍下载 测试开发 Web UI测试自动化 splinter - web UI测试工具,基于selnium封装。 链接 selenium - web UI自动化测试。 链...

python测试开发人工智能安全
55分钟前
2
0
Shiro | 实现权限验证完整版

写在前面的话 提及权限,就会想到安全,是一个十分棘手的话题。这里只是作为学校Shiro的一个记录,而不是,权限就应该这样设计之类的。 Shiro框架 1、Shiro是基于Apache开源的强大灵活的开源...

冯文议
今天
1
0
linux 系统的运行级别

运行级别 运行级别 | 含义 0 关机 1 单用户模式,可以想象为windows 的安全模式,主要用于修复系统 2 不完全的命令模式,不含NFS服务 3 完全的命令行模式,就是标准的字符界面 4 系统保留 5 ...

Linux学习笔记
今天
2
0
学习设计模式——命令模式

任何模式的出现,都是为了解决一些特定的场景的耦合问题,以达到对修改封闭,对扩展开放的效果。命令模式也不例外: 命令模式是为了解决命令的请求者和命令的实现者之间的耦合关系。 解决了这...

江左煤郎
今天
3
0
字典树收集(非线程安全,后续做线程安全改进)

将500W个单词放进一个数据结构进行存储,然后进行快速比对,判断一个单词是不是这个500W单词之中的;来了一个单词前缀,给出500w个单词中有多少个单词是该前缀. 1、这个需求首先需要设计好数据结...

算法之名
昨天
15
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部