Netlink sockets and libnl - nl_recvmsgs_default returning -1



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

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

有人知道为什么会发生这种情况吗?

下面是用户空间代码(parse_cb是一个回调,不会被调用):

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);

下面是由用户空间程序发送的消息的内核端回调(这个被正确调用):

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函数:

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;
}

好了,我找到问题所在了。

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

问题是由于我分配给我的消息的错误序列号引起的。

最新更新