我正在尝试创建一个Linux内核模块,允许用户空间中的其他程序使用键值存储功能。我不知道如何与两者互动。
我的想法是使用哈希表并暂时做一些基本的事情,如下所示:
struct hashtable{
char name[100];
int data;
struct hlist_node my_hash_list;
}
static int hash_table_init(void){
//TODO
return 0;
}
module_init(hash_table_init);
更具体地说;使用这样的基本模块,我将如何执行诸如从用户空间添加到哈希表之类的操作?我知道文件操作是与模块进行通信的一种方式,但我不确定在这种情况下如何工作(如果适用)。
最佳答案
我认为最常见的范例是在 sysfs
或 devfs
上基于 VFS 的操作。使用 struct file_operations ,您可以定义一个 vtable 来处理虚拟文件上的用户空间操作。 much greater detail here对此进行了解释。 .
在您的具体情况下,miscdevice
将是定义 IOCTL 的最佳方法,用于从哈希表中添加、获取或删除条目。基本 miscdevice
驱动程序的一个很好的示例 can be found here 。您的 IOCTL 可以使用 copy_from_user
获取用户空间地址来获取 IOCTL 调用中的数据所指向的必要缓冲区(例如 key 或哈希的名称),并且类似于 IOCTL 通过使用 copy_to_user
将特定 key 的内容复制到用户空间。 (类似于 BSD 的 copyin
/copyout
)。
Netlink套接字是用户<->内核通信的另一种方式,你可以找到example here 。它们使用起来稍微复杂一些,如果您刚刚开始内核开发,我不会建议它们。
如果您想弄乱 arch/
代码,您还可以添加自己的系统调用来调用您的驱动程序,这要求驱动程序的特定部分始终存在于内核中,至少检查驱动程序是否已加载并转发调用。如果您采用这种方式,则无法将整个驱动程序编译为模块,并且通常不应尝试执行我刚才描述的拆分方法并确保它只能作为内核的一部分进行编译。
现在到了可怕的部分,你真的在这里玩火,在内核中你必须在边界检查、锁定、抢占意识(即不要在自旋锁下屈服)、资源管理方面保持高度警惕并解决检查问题,因为如果出现问题,您将使系统崩溃,甚至更糟糕的是引入安全漏洞。
我不建议尝试这个,除非这只是为了学习如何进行内核开发。即使像示例中的基本驱动程序也可以轻松引入关键的驱动程序内核的安全错误或不稳定。
如果这不仅仅是为了学习那么我可以建议 memcached或Redis两者都是用户空间,并且经过了实战测试,并且被许多公司用作进程外共享哈希表,无论是否具有网络透明性(即 Redis 可以在 UNIX 域套接字上工作)。
关于c - 从用户空间与内核模块哈希表交互,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49972490/