我正在尝试在linux内核中运行linux内核模块。但是发生了什么,有时它成功并运行,有时模块插入失败并出现错误:
insmod: ERROR: could not insert module netlinkKernel.ko: No child processes内核日志显示它在打印时失败
Error creating socket nl_sk我认为这是一个常见的错误,我不认为它与模块有任何关系。
我只是在模块中创建了两个netlink套接字。当我注释第二个套接字创建行时,使用一个netlink套接字,模块工作正常,但是粘贴在下面代码中的两个套接字时,它显示此错误,然后再次尝试使用一个netlink套接字的模块时,它也失败,我必须重新启动系统。
static int __init hello_init(void) {
printk("Entering: %s\n",__FUNCTION__);
// This is for 3.6 kernels and above.
struct netlink_kernel_cfg cfg = {
.input = hello_nl_recv_msg,
};
struct netlink_kernel_cfg cfg1 = {
.input = hello_nl_recv_msg1,
};
nl_sk = netlink_kernel_create(&init_net, NETLINK_USER, &cfg);
nl_sk1 = netlink_kernel_create(&init_net, NETLINK_USER1, &cfg1);
//nl_sk = netlink_kernel_create(&init_net, NETLINK_USER, 0, hello_nl_recv_msg,NULL,THIS_MODULE);
if(!nl_sk)
{
printk(KERN_ALERT "Error creating socket nl_sk.\n");
return -10;
}
if(!nl_sk1)
{
printk(KERN_ALERT "Error creating socket nl_sk1.\n");
return -10;
}
return 0;
}有没有人能解释一下这个?
发布于 2016-03-12 13:59:21
注:我还不是一个内核编码大师。
如果我正确理解了您的查询,只要第三个netlink_kernel_create行被注释掉,这个模块就可以正确插入。如果是这种情况,很可能是因为一旦为特定单元(NETLINK_USER)创建了Netlink套接字,就需要使用netlink_kernel_release释放它,然后才能使用另一个netlink_kernel_create重新创建它。这也是在模块加载失败后无法加载模块的原因;您永远不会释放分配的netlink套接字。此外,对于3.7之后的内核,第三次调用netlink_kernel_create是不正确的。
我的建议是将您的代码重构为如下所示:
nl_sk = netlink_kernel_create(&init_net, NETLINK_USER, &cfg);
if(!nl_sk)
{
printk(KERN_ALERT "Error creating socket nl_sk.\n");
return -10;
}
nl_sk1 = netlink_kernel_create(&init_net, NETLINK_USER1, &cfg1);
if(!nl_sk1)
{
printk(KERN_ALERT "Error creating socket nl_sk1.\n");
netlink_kernel_release(nl_sk);
return -10;
}此外,还应在module_exit函数中包含匹配的netlink_kernel_release调用
发布于 2016-03-12 15:13:13
好的,我将#define NETLINK_USER1 32的值从32改为30,它工作得很好。两个套接字都已创建。需要查看fn原型
netlink_kernel_create(&init_net, NETLINK_USER1, &cfg1);来检查它期望作为中间参数的可能值。
https://stackoverflow.com/questions/35948879
复制相似问题