You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Linux内核模块文件读写问题:内核线程执行时异常

内核线程中执行文件读写的路径问题分析与解决

首先得说,你遇到的这个问题核心在于内核线程和模块初始化函数(__init)的运行环境不一样,尤其是当前工作目录的差异。

问题根源

当你在__init函数里执行文件操作时,此时内核是在响应用户空间的insmod/modprobe命令,它会继承用户执行该命令时的当前工作目录——也就是你的.ko文件所在的目录,所以直接写test.txt会在这个目录下创建/更新文件。

但内核线程(kthread)是独立运行在内核态的执行流,它的默认当前工作目录是根目录(/),而不是你加载模块时的用户目录。这就导致你在kthread里写test.txt时,文件其实被创建到了根目录下,而不是你预期的.ko所在目录,看起来像是“没生效”。

解决方案

这里给你两个可行的处理方式:

1. 使用绝对路径(最稳妥)

直接在代码里指定文件的完整绝对路径,从根源上避免工作目录的影响:

struct file *file = filp_open("/home/your-user/path/to/test.txt", O_RDWR | O_CREAT, 0644);
if (IS_ERR(file)) {
    // 处理打开失败的情况
    return PTR_ERR(file);
}
// 后续执行kernel_read/kernel_write等操作
filp_close(file, NULL);

2. 保存模块加载时的工作目录,线程中复用

如果你必须用相对路径,可以在__init函数里先获取当前工作目录的路径并保存,内核线程里再用这个路径拼接文件名。示例代码如下:

static char *module_work_dir = NULL;

static int __init my_module_init(void) {
    struct path pwd;
    char *buf;

    // 获取模块加载时的当前工作目录
    get_fs_pwd(current->fs, &pwd);
    buf = (char *)__get_free_page(GFP_KERNEL);
    if (!buf) {
        return -ENOMEM;
    }
    // 将路径复制到缓冲区,保存供线程使用
    module_work_dir = d_path(&pwd, buf, PAGE_SIZE);
    // 注意:不同内核版本的路径获取接口可能有差异,需按需调整
    return 0;
}

static int my_kthread_func(void *data) {
    char file_path[256];
    struct file *file;

    // 拼接保存的工作目录和目标文件名
    snprintf(file_path, sizeof(file_path), "%s/test.txt", module_work_dir);
    file = filp_open(file_path, O_RDWR | O_CREAT, 0644);
    if (IS_ERR(file)) {
        return PTR_ERR(file);
    }
    // 执行读写操作...
    filp_close(file, NULL);
    return 0;
}

注意:要记得在模块退出时释放分配的内存,避免内存泄漏。

额外提醒

  • 内核态文件操作一定要严格检查返回值:比如filp_open可能返回错误指针,必须先判断IS_ERR(file)再继续。
  • 务必使用kernel_read/kernel_write进行读写,不要直接调用用户态的read/write函数。
  • 内核线程中执行文件IO要警惕死锁:不要在持有自旋锁等不可睡眠锁的情况下执行文件操作,因为文件系统操作可能会触发睡眠。

内容的提问来源于stack exchange,提问作者John

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 08:15:13