Netlink:从内核发送到用户-EAGAIN和ENOBUFS [英] Netlink: sending from kernel to user - EAGAIN and ENOBUFS

查看:280
本文介绍了Netlink:从内核发送到用户-EAGAIN和ENOBUFS的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

从内核模块向用户空间守护程序发送netlink消息时遇到很多麻烦.他们随机失败.在内核方面,genlmsg_unicast失败,并出现EAGAIN;而在用户方面,nl_recvmsgs_default(来自libnl的函数)失败,出现NLE_NOMEM,这是由于recvmsg系统调用失败并导致ENOBUFS引起的.

I'm having a lot of trouble sending netlink messages from kernel module to userspace-daemon. They randomly fail. On the kernel side, the genlmsg_unicast fails with EAGAIN while on the user-side, nl_recvmsgs_default (function from libnl) fails with NLE_NOMEM which is caused by recvmsg syscall failing with ENOBUFS.

Netlink消息很小,最大有效负载大小约为300B.

Netlink messages are small, maximum payload size is ~300B.

这是从内核发送消息的代码:

Here is the code for sending message from kernel:

int send_to_daemon(void* msg, int len, int command, int seq, u32 pid) {
    struct sk_buff* skb;
    void* msg_head;
    int res, payload;

    payload = GENL_HDRLEN+nla_total_size(len)+36;
    skb = genlmsg_new(payload, GFP_KERNEL);
    msg_head = genlmsg_put(skb, pid, seq, &psvfs_gnl_family, 0, command);
    nla_put(skb, PSVFS_A_MSG, len, msg);
    genlmsg_end(skb, msg_head);
    genlmsg_unicast(&init_net, skb, pid);

    return 0;
}

我绝对不知道为什么会这样,而我的项目也因此而无法正常工作!我真的希望有人可以帮助我.

I absolutely have no idea why this is happening and my project just won't work because of that! I really hope someone could help me with that.

推荐答案

我在通过netvm套接字通过recvmsg接收ENOBUFS时遇到类似的问题.我发现我的问题是内核套接字缓冲区在用户空间耗尽之前就已填充.

I was having a similar problem receiving ENOBUFS via recvmsg from a netlink socket. I found that my problem was the kernel socket buffer filling before userspace could drain it.

netlink(7)手册页中:

   However, reliable transmissions from kernel to user are impossible in
   any case.  The kernel can't send a  netlink  message  if  the  socket
   buffer  is  full:  the message will be dropped and the kernel and the
   user-space process will no longer have the same view of kernel state.
   It  is  up  to  the  application to detect when this happens (via the
   ENOBUFS error returned by recvmsg(2)) and resynchronize.

我通过增加套接字接收缓冲区(setsockopt(fd,SOL_SOCKET,SO_RCVBUF,...)的大小来解决此问题. 或 nl_socket_set_buffer_size()如果您使用的是libnl ).

I addressed this problem by increasing the size of the socket receive buffer (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, ...) , or nl_socket_set_buffer_size() if you are using libnl).

这篇关于Netlink:从内核发送到用户-EAGAIN和ENOBUFS的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆