使用proc_create创建proc文件

本文介绍了如何在Linux内核3.10及以上版本中使用proc_create函数创建可读写的proc文件,对比了与之前create_proc_entry函数的区别,并提供了示例代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

下面这个例子是使用seq_file接口实现可读写proc文件的例子,适用于3.10以后的内核,这和之前创建proc文件的函数实现上有很大差别,3.10以前的内核调用create_proc_entry,3.10以后的内核调用proc_create。

proc.c

/*************************
 * 使用seq_file接口实现可读写的proc文件
 * 功能同proc_test02.c
 * Author: jx
 * Date: 2014-08-08
 *************************/
#include <linux/module.h>
#include <linux/sched.h>
#include <linux/fs.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/uaccess.h>

static char *str = NULL;

/*********************
 * seq_operations->show
 * 必须返回0,否则什么也显示不出来
 *********************/
static int 
my_proc_show(struct seq_file *m, void *v)
{
	seq_printf(m, "current kernel time is %ld\n", jiffies);
	seq_printf(m, "str is %s\n", str);

	return 0;
}

/***********************
 * file_operations->open
 ***********************/
static int 
my_proc_open(struct inode *inode, struct file *file)
{
	return single_op
<think>我们首先回答问题:在创建proc文件之前需要检查是否已存在,否则内核会报错。 然后,根据规则,在回答末尾提出3-5个相关问题,以“§§相关问题§§”开头,并且问题之间用换行分隔(但不要用换行分散,即每个问题一行,前面加序号)。 回答内容: 在内核中使用proc_create创建proc文件时,如果同名的proc文件已经存在,再次创建会导致内核报错(如"proc_dir_entry already exists")。为避免此问题,应在创建前检查文件是否存在。 解决方案: 1. 使用proc_mkdir创建父目录(如果需要)并记录proc_dir_entry指针。 2. 在创建proc文件前,使用proc_create_data或proc_create创建,但在此之前先检查同名文件是否已被注册。 但是,proc_create本身没有提供直接的检查函数,因此需要利用proc_parent和文件名手动检查。可以通过以下步骤实现: 步骤: a. 获取父目录的proc_dir_entry(如果未指定父目录,则使用proc_root作为根)。 b. 遍历父目录的子文件链表,检查是否存在同名文件。 示例代码: ```c #include <linux/proc_fs.h> // 检查proc文件是否已存在 static bool proc_file_exists(const char *name, struct proc_dir_entry *parent) { struct proc_dir_entry *p; bool exists = false; // 如果没有指定父目录,则使用proc根目录 if (!parent) parent = &proc_root; // 遍历父目录的所有子节点 spin_lock(&proc_subdir_lock); for (p = parent->subdir; p; p = p->next) { if (strcmp(p->name, name) == 0) { exists = true; break; } } spin_unlock(&proc_subdir_lock); return exists; } // 创建proc文件(带检查) static struct proc_dir_entry *safe_proc_create(const char *name, umode_t mode, struct proc_dir_entry *parent, const struct file_operations *proc_fops) { if (proc_file_exists(name, parent)) { printk(KERN_WARNING "proc file %s already exists\n", name); return NULL; } return proc_create(name, mode, parent, proc_fops); } ``` 注意:由于proc文件系统内部使用自旋锁(proc_subdir_lock)保护子节点链表,因此检查时必须加锁。 另一种简单做法:在模块卸载时删除proc文件,在加载时直接创建(确保模块卸载时删除对应的proc文件)。但如果模块多次加载(未卸载时再次加载)就会出问题,所以上述检查是必要的。 因此,在调用proc_create之前,建议使用类似上述的检查函数,以避免内核报错。 另外,在模块退出函数中,必须调用proc_remove或remove_proc_entry来删除创建proc文件。 §§相关问题§§ 1. 如何在内核中安全地递归删除整个proc目录? 2. 为什么在遍历proc_dir_entry的子节点时需要加锁(proc_subdir_lock)? 3. 除了手动检查,是否有内核API可以直接替换已存在的proc文件? 4. 当多个内核模块可能创建同名proc文件时,如何避免冲突? 5. proc文件系统与sysfs的主要区别是什么?</think>### 在 `proc_create` 前检查 proc 文件是否已存在的解决方案 在内核模块开发中,直接调用 `proc_create()` 创建 proc 文件时,如果同名文件已存在,会导致内核报错(如 `"proc_dir_entry already exists"`)。以下是完整的安全创建流程: #### 正确实现方法 ```c #include <linux/proc_fs.h> // 定义 proc 文件路径(示例) #define PROC_FILE_NAME "my_module_stats" static struct proc_dir_entry *my_proc_file; // 安全创建 proc 文件函数 int create_proc_entry(void) { // 1. 检查文件是否已存在 struct proc_dir_entry *existing = proc_lookup(PROC_FILE_NAME, NULL); if (existing) { pr_warn("Proc entry %s already exists!\n", PROC_FILE_NAME); return -EEXIST; // 文件已存在错误码 } // 2. 创建文件 my_proc_file = proc_create(PROC_FILE_NAME, 0644, NULL, &proc_fops); if (!my_proc_file) { pr_err("Failed to create proc entry\n"); return -ENOMEM; } return 0; } // 模块退出时删除 void remove_proc_entry(void) { if (my_proc_file) { proc_remove(my_proc_file); my_proc_file = NULL; // 防止重复删除 } } ``` #### 关键注意事项: 1. **检查机制** 使用 `proc_lookup()` 检查同名文件是否存在,避免直接创建冲突 - 第一个参数:文件名(不含路径) - 第二个参数:父目录(`NULL` 表示 `/proc` 根目录) 2. **错误处理** - 存在时返回 `-EEXIST`(文件已存在) - 创建失败返回 `-ENOMEM`(内存不足) 3. **权限设置** `0644` 表示: - 用户:读写(6 = rw-) - 组和其他:只读(4 = r--) 4. **资源清理** 在模块退出函数中**必须调用** `proc_remove()` 删除文件: ```c static void __exit my_module_exit(void) { remove_proc_entry(); // ...其他清理... } ``` #### 常见错误场景: ```c // 错误示例:未检查直接创建 proc_create("duplicate", 0, NULL, &fops); // 第一次成功 proc_create("duplicate", 0, NULL, &fops); // 第二次触发内核错误 ``` 此时内核会报错: `proc_dir_entry 'duplicate' already registered`
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值