【问题标题】:insmod: ERROR: could not insert module : No child processesinsmod:错误:无法插入模块:没有子进程
【发布时间】:2016-06-27 05:01:31
【问题描述】:

我正在尝试在 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;
}

有人能解释一下吗?

【问题讨论】:

    标签: linux sockets kernel netlink


    【解决方案1】:

    好的,我将 #define NETLINK_USER1 32 的值从 32 更改为 30,它工作正常。两个套接字都创建了。需要看fn原型

    netlink_kernel_create(&init_net, NETLINK_USER1, &cfg1);
    

    检查它期望作为中间参数的可能值。

    【讨论】:

    • netlink_kernel_create 呼叫__netlink_kernel_create。你可以在这个函数中看到early,最大套接字数是32。因此,只有 0 到 31 是有效标识符。另请注意,most of them 已被保留。
    【解决方案2】:

    注意:我(还)不是内核编码大师。

    如果我正确理解您的查询,只要注释掉第 3 行 netlink_kernel_create,此模块就会正确插入。如果是这种情况,很可能是因为一旦为特定单元 (NETLINK_USER) 创建了 Netlink 套接字,就需要使用 netlink_kernel_release 释放它,然后才能使用另一个 netlink_kernel_create 重新创建它。这也是模块加载失败后无法加载的原因;您永远不会释放分配的网络链接套接字。此外,netlink_kernel_create 的第三次调用对于 3.7 之后的内核不正确。

    我的建议是将您的代码重组为如下所示:

    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 调用

    【讨论】:

    • 是的,两个套接字的 netlink_kernel_release 调用都在 module_exit fn 中。当我加载我的模块时,它仅在第一次创建套接字时失败并打印“创建套接字 nl_sk 时出错”。当第二个套接字创建失败时,您提供的重构代码释放套接字,控制甚至没有到达那里。
    • 好的,我尝试了您的建议,使用重构的代码,现在 Ist skt 创建成功,但第二次失败。
    • NETLINK_USER 和 NETLINK_USER 使用什么值?
    • #define NETLINK_USER 31 #define NETLINK_USER1 32 我想,我可以使用任何整数值来识别用户空间中的程序。用户空间应用程序也使用相同的#defines 创建一个套接字。 int main() { sock_fd=socket(PF_NETLINK, SOCK_RAW, NETLINK_USER); if(sock_fd
    • 好的,我将#define NETLINK_USER1 32 的值从 32 更改为 30,效果很好。两个套接字都创建了。需要se fn原型 netlink_kernel_create(&init_net, NETLINK_USER1, &cfg1);检查它期望作为中间参数的可能值。
    猜你喜欢
    • 1970-01-01
    • 2015-01-15
    • 2022-12-30
    • 2016-03-26
    • 2013-03-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-06
    相关资源
    最近更新 更多