ネットリンクソケットを使用してユーザースペースとカーネルスペースの間でメッセージを交換しようとしています...ユーザースペースからカーネルスペースにメッセージを送信するとすべて正常に機能しますが、カーネルスペースから返信しようとするとシステムがフリーズします。特に、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をどこで解放する必要がありますか?