我正在尝试创建一个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);
更具体地说;使用这样的基本模块,我如何执行操作,例如从用户空间添加哈希表?我理解文件操作是与模块进行通信的一种方式,但我不确定在这种情况下如何适用。(/ p>
答案 0 :(得分:1)
我认为最常用的范例是sysfs
或devfs
上基于VFS的操作。使用struct file_operations
,您可以定义一个vtable来处理在虚拟文件上运行的用户空间。这在much greater detail here中解释。
在您的特定情况下,miscdevice
是最佳方法,IOCTL定义为从哈希表中添加,获取或删除条目。基本miscdevice
驱动程序can be found here的一个很好的示例。您的IOCTL可以使用用户空间地址copy_from_user
来获取IOCTL调用中的数据所指向的必要缓冲区(如密钥或哈希的名称),类似于使用{{1}获取内容的IOCTL将特定密钥的内容复制到用户空间。 (类似于BSD的copy_to_user
/ copyin
)。
Netlink套接字是用户< - >内核通信的另一种方式,您可以找到example here。它们使用起来稍微复杂一点,如果你刚刚开始使用内核开发,我不建议使用它们。
如果你想弄乱copyout
代码,你也可以添加自己的系统调用来调用你的驱动程序,这需要驱动程序的某个部分始终存在于内核中,至少要检查一下如果驱动程序已加载并转发呼叫。如果你这样做你就不能将整个驱动程序编译为模块,你通常不应该尝试我刚才描述的拆分方法,并确保它只能作为内核的一部分进行编译。
现在到了可怕的部分,你真的在这里玩火,在内核中你必须在边界检查,锁定,抢占意识(即不要在自旋锁下产生),资源管理方面保持警惕和地址检查,因为你会崩溃系统,或者更糟糕的是在出现问题时引入安全漏洞。
我不建议尝试这样做,除非这只是为了学习如何进行内核开发。即使像示例中那样的基本驱动程序也可以轻松引入关键安全漏洞或内核不稳定。
如果这不仅仅是为了学习,那么我可以建议memcached或Redis两者都是用户空间,并经过实战测试并被许多公司使用作为进程外共享哈希表,有或没有网络透明性(即Redis可以在UNIX域套接字上工作)。