【问题标题】:How to create a file with content using debugfs in kernel module?如何在内核模块中使用 debugfs 创建包含内容的文件?
【发布时间】:2023-01-14 18:46:40
【问题描述】:

使用此 debugfs API,我可以在 /sys/kernel/debug/parent/name 中创建一个文件,但它是空的,无论我在void *data 参数中输入了哪些数据

struct dentry *debugfs_create_file(const char *name, mode_t mode, struct dentry *parent, void *data, struct file_operations *fops);

根据documentation,我们需要自己实现 file_operations 来处理文件的打开和写入。 我的一段代码:

static ssize_t myreader(struct file *fp, char __user *user_buffer, 
                                size_t count, loff_t *position) 
{ 
     return simple_read_from_buffer(user_buffer, count, position, ker_buf, len);
} 
 
static ssize_t mywriter(struct file *fp, const char __user *user_buffer, 
                                size_t count, loff_t *position) 
{ 
        if(count > len ) 
                return -EINVAL; 
  
        return simple_write_to_buffer(ker_buf, len, position, user_buffer, count); 
} 
 
static const struct file_operations fops_debug = { 
        .read = myreader, 
        .write = mywriter, 
}; 
 
static int __init init_debug(void) 
{ 
    dirret = debugfs_create_dir("dell", NULL); 
      
    fileret = debugfs_create_file("text", 0644, dirret, "HELLO WORLD", &fops_debug);
    debugfs_create_u64("number", 0644, dirret, &intvalue); 
 
    return (0); 
}

将此模块安装到内核后,将在文件夹“dell”中创建两个文件“text”和“number”。文件“number”包含我按预期作为“intvalue”传入的数字,但另一个文件“text”为空。 文档里写的是数据将存储在生成的 inode 结构的 i_private 字段中我的期望:字符串“HELLO WORLD”将在模块加载后写入文件。

我认为问题应该出在读写操作函数上。是否可以使用 debugfs_create_file 方法创建具有特定内容的文件?

【问题讨论】:

    标签: linux linux-kernel operating-system filesystems


    【解决方案1】:

    要回答您的问题,您对代码的期望是正确的,但不会产生预期的结果。我相信还有其他更有效和正确的方法可以做到这一点,但要解释当前的行为:

    • 您正在将数据初始化为文件 text 的内容,但您正在从 user_buffer 中的缓冲区 ker_buf 读取数据,而不是使用 simple_read_from_buffer(user_buffer, count, position, ker_buf, len); 的文件指针
    • 同样,您正在使用simple_write_to_buffer(ker_buf, len, position, user_buffer, count);user_buffer写信给kern_buf

    使用现有代码,如果您想实现您想要做的事情,那么您必须将字符串"HELLO WORLD"复制到kern_buf中的init_debug()

    就像是:

    strscpy(kern_buf, "HELLO WORLD", strlen("HELLO WORLD") + 1);
    

    或以完整功能的形式:

    static int __init init_debug(void) 
    { 
        dirret = debugfs_create_dir("dell", NULL); 
          
        fileret = debugfs_create_file("text", 0644, dirret, NULL, &fops_debug);
        debugfs_create_u64("number", 0644, dirret, &intvalue);
        
        strscpy(kern_buf, "HELLO WORLD", strlen("HELLO WORLD") + 1);
        return (0); 
    }
    

    编辑:

    参考了一些网上资料,发现在初始化时提供给debugfs_create_file()void *data存储在i_private字段中,稍后可以从结果inode structurei_private字段中检索。

    可以从 struct file *fp 获取相应文件的索引节点,这是 read()write() 操作的第一个参数。

    struct inodestruct file 的成员,i_privatestruct inode 的成员

    要通过 read() 中的 debugfs_create_file() 获取文件创建期间提供的 void *data,您可以执行类似于如下所示的操作:

    static ssize_t myreader(struct file *fp, char __user *user_buffer, 
                                    size_t count, loff_t *position) 
    {
        struct inode *l_inode = fp->f_inode;
        strscpy(user_buffer, (char *)l_inode->i_private, PAGE_SIZE);
        ...
        
    }
    

    【讨论】:

      猜你喜欢
      • 2013-01-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-01-27
      • 1970-01-01
      • 2020-09-17
      • 1970-01-01
      相关资源
      最近更新 更多