【问题标题】:creating a shm file from kernel module从内核模块创建一个 shm 文件
【发布时间】:2017-11-07 23:50:35
【问题描述】:

我正在尝试打开一个 shm 文件以在内核和用户进程之间共享数据。 下面是我的内核模块代码。系统日志输出表明没有遇到错误。加载模块后,我看不到要在 /dev/shm 中创建的文件。我做错了什么?

#include <linux/module.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/shmem_fs.h>

static int __init moduleLoader(void) {
    struct file *shfile;

    printk(KERN_INFO "shkmod is loading...\n");

    shfile = shmem_file_setup("MyShmFile",sizeof(int),0);
    printk("shmem_file_setup returned %p\n",shfile);
    if (IS_ERR(shfile))
        printk("shmem_file_setup returned error.\n");
    printk("shfile is: %s\n", shfile->f_path.dentry->d_name.name);

    printk(KERN_INFO "shkmod is done loading.\n");
    return 0;
}

static void __exit moduleUnloader(void) {
    printk(KERN_INFO "shkmod was unloaded.\n");
    return;
}

module_init(moduleLoader);
module_exit(moduleUnloader);

MODULE_AUTHOR("Yaron Shragai");
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Lorem ipsum dolor sit amet");

这是系统日志中的输出:

Jun  6 15:25:59 yaron-VirtualBox kernel: [457160.335482] shkmod is loading...
Jun  6 15:25:59 yaron-VirtualBox kernel: [457160.335487] shmem_file_setup returned ffff8801fef53b00
Jun  6 15:25:59 yaron-VirtualBox kernel: [457160.335488] shfile is: MyShmFile
Jun  6 15:25:59 yaron-VirtualBox kernel: [457160.335488] shkmod is done loading.

$ unname -a
Linux yaron-VirtualBox 4.4.0-57-generic #78-Ubuntu SMP Fri Dec 9 23:50:32 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux

【问题讨论】:

  • 在您的问题中添加“C”标签,这将对您有所帮助。
  • 好的,添加了“c”标签! :-)

标签: c linux-kernel ipc shared-memory kernel-module


【解决方案1】:
/**
 * shmem_file_setup - get an unlinked file living in tmpfs

注释明确指出该文件不会出现在任何地方。

 * @name: name for dentry (to be seen in /proc/<pid>/maps

...名字就是要在地图上显示一些东西。

 * @size: size to be set for the file
 * @flags: VM_NORESERVE suppresses pre-accounting of the entire object size
 */
struct file *shmem_file_setup(const char *name, loff_t size, unsigned long flags)
{
        return __shmem_file_setup(name, size, flags, 0);
}

虽然有道理。您没有指定任何文件系统,只是使用了一个以相对路径开头的名称。为什么您希望该文件专门显示在 /dev 中?

像往常一样,真正的问题是您正在解决的实际问题是什么。

如果碰巧共享文件确实是要走的路,用户空间应该创建一个并告诉内核使用它。

【讨论】:

  • 由于 cmets 的字符限制,必须在多个帖子中回复您。
  • > 注释明确指出该文件不会出现在任何地方。这可能是一个愚蠢的问题,将我暴露为一个菜鸟,但是,它是如何说明这一点的?
  • 我并不总是信任内核函数上的 cmets,b/c 我看到了一些严重的剪切-粘贴错误。 shmem_file_setup() 调用 __shmem_file_setup(),其中包含:` .... this.name = name; .... sb = shm_mnt->mnt_sb; path.mnt = mntget(shm_mnt); path.dentry = d_alloc_pseudo(sb, &this); ....` shm_mnt 大概是指 /dev/shm,b/c 那是 shmfs(又名 tmpfs)。 /dev/shm 是调用用户空间 API shmem_open() 时创建文件的位置。
  • > 如果共享文件确实是要走的路,用户空间应该创建一个并告诉内核使用它。 --> 最初我实际上希望让用户进程通过 shmem_open() 分配共享内存,并让我的外部内核模块本质上映射它。在用户空间,这是小菜一碟: shmem_open() 按名称打开或查找共享内存对象(由 /dev/shm 中的文件备份),并通过 shmem_open() 返回的 fd 映射它.但是我找不到一个内核模块 API 来简单地完成这个。
  • 我需要一个内核模块来偶尔向用户进程发送状态数据。查看了 Generic Netlink - 但 GeNetlink 基本上是为(1)用户进程向内核发送请求,内核响应(需要我的用户进程发送连续请求);或(2)内核多播到用户进程订阅的组(出于安全考虑,我宁愿不多播)。我被 GeNetlink 卡住了,所以查看了共享内存 - 仍然需要用户进程来轮询,但我认为这会更容易......(最终做了 GeNL 多播。)
猜你喜欢
  • 2012-11-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多