netlink 套接字问题:内核冻结

Posted

技术标签:

【中文标题】netlink 套接字问题:内核冻结【英文标题】:Problem with netlink socket: kernel freeze 【发布时间】:2011-05-04 14:09:18 【问题描述】:

我正在尝试使用 netlink 套接字在用户空间和内核空间之间交换消息...我将消息从用户空间发送到内核空间并且一切正常但是当我尝试从内核空间回复时,系统死机。特别是我使用工作队列安排了一个函数,该函数创建消息并使用 netlink_unicast 函数发送到用户空间......这里有一些内核代码:

void wq_func(struct work_queue *wq)

  struct sk_buff *resp = alloc_skb(NLMSG_LENGTH(100), GFP_KERNEL);
  if (!resp)
  
     printk(KERN_INFO "alloc_skb failed");
     return;
  

  struct nlmsghdr *nlh = (struct nlmsghdr *)skb_put(resp, NLMSG_LENGTH(100));
  memset(nlh, 0, NLMSG_LENGTH(100));
  nlh->nlmsg_len = NLMSG_LENGTH(100);
  nlh->nlmsg_pid = 0;
  nlh->nlmsg_flags = 0;
  strcpy(NLMSG_DATA(nlh), "From kernel: Yes i'm here!");
  NETLINK_CB(resp).pid = 0;
  NETLINK_CB(resp).dst_group = 0;

  printk(KERN_INFO "Trying to send a netlink message to pid %d", pid);
  int err = netlink_unicast(s, resp, pid, MSG_DONTWAIT);
  if (err < 0)
    printk(KERN_ALERT "Error sending message to user-space");
  kfree_skb(resp);

DECLARE_WORK(wq, wq_func);

static void input_nl(struct sk_buff *buff)

  printk(KERN_INFO "Received message socket NETLINK_TEST");
  if (buff == NULL)
  
    printk(KERN_ALERT "NULL sk_buff!");
    return;
  
  struct nlmsghdr *nlh = (struct nlmsghdr *)buff->data;
  printk(KERN_INFO "Received netlink message from pid %d: %s", nlh->nlmsg_pid,       NLMSG_DATA(nlh));

  pid = nlh->nlmsg_pid;

  schedule_work(&wq);


int __init knl_init()

  printk(KERN_INFO "knl module loaded");

  s = netlink_kernel_create(&init_net, NETLINK_TEST, 0, input_nl, NULL, THIS_MODULE);

  if (s == NULL)
    return -1;
  return 0;

如果我尝试评论对 netlink_unicast 的调用,内核不会冻结。从用户空间我可以正确发送消息。我记得过去相同的代码运行良好,现在我对这个奇怪的错误感到非常惊讶。

有什么想法吗?

谢谢大家!


我试图在 netlink_unicast 调用之后删除 kfree_skb 调用并且一切正常......那么,为什么系统会因该调用而挂起?我应该在哪里释放分配的 sk_buff?

【问题讨论】:

netlink 在某些时候变得内部同步,尝试不调用 schedule_work() 【参考方案1】:

netlink_unicast() 获得skb 的所有权并自行释放。

【讨论】:

啊,好吧……这是一个缺失的概念!谢谢咖啡馆!【参考方案2】:

拨打netlink_unicast后,您无法释放struct sk_buff

【讨论】:

以上是关于netlink 套接字问题:内核冻结的主要内容,如果未能解决你的问题,请参考以下文章

在 Linux 内核中使用 netlink 套接字在用户空间应用程序和字符设备之间进行通信时出错

linux下netlink的使用简介

打开 netlink 套接字将使用相同的 pid 然后绑定和创建失败

Windows IPC 模拟 Linux Unix 域和 Netlink 套接字

linux netlink套接字学习资料

uevent 从内核发送到用户空间 (udev)