Linux字符驱动中如何为不同读取进程返回不同数据?
Linux字符驱动:为不同进程返回对应键值的实现方案
问题背景
开发一款Linux字符驱动,目标是实现键值存储功能:不同进程向/dev/key写入查询键后,读取/dev/value时能返回对应的值。核心需求是驱动需跟踪每个进程的查询键,但不清楚如何获取当前执行读写操作的进程信息,误以为struct file结构体中包含相关字段,实际未找到。
驱动接口使用示例:
# 终端1执行 echo "test" > /dev/key # 告知驱动要查询的键 cat /dev/value # 读取与"test"关联的值
# 终端2执行 echo "other_key" > /dev/key cat /dev/value
实现方法
1. 通过current宏获取当前进程标识
Linux内核提供current宏,直接指向当前正在执行的进程描述符struct task_struct,可在驱动的read/write回调中直接调用,获取PID、线程ID等唯一标识来区分不同进程:
#include <linux/sched.h> ssize_t key_write(struct file *filp, const char __user *buf, size_t count, loff_t *f_pos) { // 获取用户空间可见的进程ID(线程组ID) pid_t proc_id = current->tgid; // 获取内核级线程ID pid_t thread_id = current->pid; // 用proc_id作为键,将用户写入的key存储到内核哈希表或其他结构中 // ... return count; }
2. 利用struct file的private_data存储进程上下文
struct file本身没有进程标识字段,但可以在进程打开设备文件时(open回调),为每个进程分配独立的上下文结构体,挂载到filp->private_data上,后续读写操作直接从该字段获取进程对应的查询键:
// 自定义上下文结构体,保存进程ID和对应的查询键 struct proc_key_ctx { pid_t proc_id; char query_key[64]; }; // 设备open回调:为进程分配上下文 int key_open(struct inode *inode, struct file *filp) { struct proc_key_ctx *ctx = kmalloc(sizeof(struct proc_key_ctx), GFP_KERNEL); if (!ctx) return -ENOMEM; ctx->proc_id = current->tgid; memset(ctx->query_key, 0, sizeof(ctx->query_key)); filp->private_data = ctx; return 0; } // 设备write回调:保存用户写入的查询键到上下文 ssize_t key_write(struct file *filp, const char __user *buf, size_t count, loff_t *f_pos) { struct proc_key_ctx *ctx = filp->private_data; size_t copy_len = min(count, sizeof(ctx->query_key) - 1); if (copy_from_user(ctx->query_key, buf, copy_len)) { return -EFAULT; } return count; } // 设备release回调:释放上下文内存,避免泄漏 int key_release(struct inode *inode, struct file *filp) { kfree(filp->private_data); return 0; }
在/dev/value的read回调中,同样通过current->tgid匹配对应的上下文,取出查询键后返回关联的值即可。
3. 关键注意事项
- 内存管理:必须在
release回调中释放private_data分配的内存,防止进程退出后内存泄漏。 - 线程区分:如果需要区分同一进程内的不同线程,使用
current->pid(内核线程ID)而非current->tgid(用户空间进程ID)。 - 键值存储:内核中可使用哈希表(如
struct hlist_head)或idr结构,以进程ID为键,存储查询键与对应值的映射关系。
内容的提问来源于stack exchange,提问作者Jacob Garby
相关产品推荐
相关产品推荐

