Netlink套接字和libnl-nl_recvmsgs_default返回-16(EBUSY) [英] Netlink sockets and libnl - nl_recvmsgs_default returning -16 (EBUSY)

查看:747
本文介绍了Netlink套接字和libnl-nl_recvmsgs_default返回-16(EBUSY)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试编写一些基本的内核模块-使用netlink套接字(用户侧为libnl)的用户空间程序通信.用户空间程序向内核发送一条消息,并期望得到答复.不幸的是,接收到回复失败,返回值为-16(EBUSY).

I'm trying to code some basic kernel module - userspace program communication using netlink sockets (libnl on user side). Userspace program sends a message to kernel and expects a reply. Unfortunately, receiving reply fails with return value -16 (EBUSY).

有趣的是,当我直接从netlink套接字接收数据时,使用nl_socket_get_fd(sock)上的标准系统调用recv,一切正常!

Interestingly enough, when I receive data from netlink socket directly, using standard system call recv on nl_socket_get_fd(sock), everything works fine!

有人知道为什么会这样吗?

Does anyone have an idea why this is happening?

这是用户空间代码(parse_cb是不会被调用的回调):

Here is the userspace code (parse_cb is a callback that doesn't get invoked):

struct nl_sock *sock;
struct nl_msg *msg;
int family, res;

// Allocate a new netlink socket
sock = nl_socket_alloc();

// Connect to generic netlink socket on kernel side
genl_connect(sock);

// Ask kernel to resolve family name to family id
family = genl_ctrl_resolve(sock, PSVFS_FAMILY_NAME);

// Construct a generic netlink by allocating a new message, fill in
// the header and append a simple integer attribute.
msg = nlmsg_alloc();
genlmsg_put(msg, NL_AUTO_PID, NL_AUTO_SEQ, family, 0, NLM_F_ECHO,
        PSVFS_C_INIT, PSVFS_VERSION);
nla_put_string(msg, PSVFS_A_MSG, "stuff");

// Send message over netlink socket
nl_send_auto_complete(sock, msg);

// Free message
nlmsg_free(msg);

nl_socket_modify_cb(sock, NL_CB_VALID, NL_CB_CUSTOM, parse_cb, NULL);

res = nl_recvmsgs_default(sock);
printf("After receive %i.\n", res);

这是用户空间程序发送的消息的内核端回调(此调用已正确调用):

Here is the kernel-side callback for messsage sent by userspace program (this one gets invoked properly):

int psvfs_vfs_init(struct sk_buff *skb2, struct genl_info *info) {
    send_to_daemon("VFS initialized.", PSVFS_C_INIT, info->snd_seq+1, info->snd_pid);

    return 0;
}

这是'send_to_daemon'函数:

And here is the 'send_to_daemon' function:

int send_to_daemon(char* msg, int command, int seq, u32 pid) {
    int res = 0;
    struct sk_buff* skb;
    void* msg_head;

    skb = genlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
    if (skb == NULL) {
        res = -ENOMEM;
        goto out;
    }

    msg_head = genlmsg_put(skb, 0, seq, &psvfs_gnl_family, 0, command);
    if (msg_head == NULL) {
        res = -ENOMEM;
        goto out;
    }

    res = nla_put_string(skb, PSVFS_A_MSG, msg);
    if (res != 0)
        goto out;

    genlmsg_end(skb, msg_head);

    res = genlmsg_unicast(&init_net, skb, pid);
    if (res != 0)
        goto out;

  out:
    return res;
}

推荐答案

好的,我发现这里出了问题.

OK, I found what was wrong here.

我终于发现libnl函数有其自己的错误代码,与标准POSIX返回代码不同,并且NLE_SEQ_MISMATCH代表-16.

I finally found out that libnl functions have their own error codes, different from standard POSIX return codes and -16 stands for NLE_SEQ_MISMATCH.

问题是由我分配给邮件的错误序列号引起的.

The problem was caused by bad sequence numbers that I assigned to my messages.

这篇关于Netlink套接字和libnl-nl_recvmsgs_default返回-16(EBUSY)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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