/ / Netlink sockets und libnl - nl_recvmsgs_default geben -16 (EBUSY) - linux, linux-kernel, kernel, netlink zurück

Netlink-Sockets und libnl - nl_recvmsgs_default, die -16 (EBUSY) zurückgeben - Linux, Linux-Kernel, Kernel, Netlink

Ich versuche, einige grundlegende Kernel-Module zu codieren -Programmkommunikation zwischen Benutzern über Netlink-Sockets (libnl auf Benutzerseite). Das Userspace-Programm sendet eine Nachricht an den Kernel und erwartet eine Antwort. Leider schlägt der Empfang der Antwort mit dem Rückgabewert -16 (EBUSY) fehl.

Interessanterweise, wenn ich Daten direkt vom netlink-Socket mit einem Standardsystemaufruf erhalte recv auf nl_socket_get_fd(sock)alles funktioniert gut!

Hat jemand eine Idee, warum das passiert?

Hier ist der Userspace-Code (parse_cb ist ein Rückruf, der nicht aufgerufen wird):

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

Hier ist der kernelseitige Callback für Messsage, der vom Userspace-Programm gesendet wurde (dieses wird richtig aufgerufen):

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

Und hier ist die Funktion "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;
}

Antworten:

1 für die Antwort № 1

OK, ich fand was hier falsch war.

Das habe ich endlich herausgefunden libnl Funktionen haben eigene Fehlercodes, die sich von den Standard-POSIX-Rückkehrcodes und -16 unterscheiden NLE_SEQ_MISMATCH.

Das Problem wurde durch falsche Folgenummern verursacht, die ich meinen Nachrichten zugewiesen habe.