网络链路捐赠内核崩溃 [英] Netlink giving kernel panic

查看:229
本文介绍了网络链路捐赠内核崩溃的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试过这个计划。这个程序发送你好,再次一次性内核和内核的答复你好到用户空间。

I tried this program. This program send "hello" to kernel and kernel replies "hello" to user space again for one time.

我的要求:用户发送你好,并有收到消息每2秒

My requirement: user has to send "hello" and have to receive message for every 2 seconds.

我都试过了。

用户应用:添加loopfor发送和接收

User app: added loopfor sending and receiving

#define NETLINK_USER 31    
#define MAX_PAYLOAD 1024 /* maximum payload size*/

struct sockaddr_nl src_addr, dest_addr;
struct nlmsghdr *nlh = NULL;
struct iovec iov;
int sock_fd;
struct msghdr msg;

int main()
{
    sock_fd=socket(PF_NETLINK, SOCK_RAW, NETLINK_USER);
    if(sock_fd<0)
        return -1;

    memset(&src_addr, 0, sizeof(src_addr));
    src_addr.nl_family = AF_NETLINK;
    src_addr.nl_pid = getpid(); /* self pid */

    bind(sock_fd, (struct sockaddr*)&src_addr, sizeof(src_addr));

    memset(&dest_addr, 0, sizeof(dest_addr));
    memset(&dest_addr, 0, sizeof(dest_addr));
    dest_addr.nl_family = AF_NETLINK;
    dest_addr.nl_pid = 0; /* For Linux Kernel */
    dest_addr.nl_groups = 0; /* unicast */

    nlh = (struct nlmsghdr *)malloc(NLMSG_SPACE(MAX_PAYLOAD));
    memset(nlh, 0, NLMSG_SPACE(MAX_PAYLOAD));
    nlh->nlmsg_len = NLMSG_SPACE(MAX_PAYLOAD);
    nlh->nlmsg_pid = getpid();
    nlh->nlmsg_flags = 0;

    strcpy(NLMSG_DATA(nlh), "Hello");

    iov.iov_base = (void *)nlh;
    iov.iov_len = nlh->nlmsg_len;
    msg.msg_name = (void *)&dest_addr;
    msg.msg_namelen = sizeof(dest_addr);
    msg.msg_iov = &iov;
    msg.msg_iovlen = 1;
    while(1) {           // <--- loop here. only works once.
        sleep(2);
        printf("Sending message to kernel\n");
        sendmsg(sock_fd,&msg,0);

        recvmsg(sock_fd, &msg, 0);
        printf("Received message payload: %s\n", (char *)NLMSG_DATA(nlh));
    }

    close(sock_fd);
}

内核模块:没有改变任何东西。

#define NETLINK_USER 31
struct sock *nl_sk = NULL;

static void hello_nl_recv_msg(struct sk_buff *skb) 
{
    struct nlmsghdr *nlh;
    int pid;
    struct sk_buff *skb_out;
    int msg_size;
    char *msg="Hello from kernel";
    int res;

    printk(KERN_INFO "Entering: %s\n", __FUNCTION__);

    msg_size=strlen(msg);

    nlh=(struct nlmsghdr*)skb->data;
    printk(KERN_INFO "Netlink received msg payload:%s\n",(char*)nlmsg_data(nlh));
    pid = nlh->nlmsg_pid; /*pid of sending process */

    skb_out = nlmsg_new(msg_size,0);

    if(!skb_out)
    {
        printk(KERN_ERR "Failed to allocate new skb\n");
        return;
    } 
    nlh=nlmsg_put(skb_out,0,0,NLMSG_DONE,msg_size,0);  
    NETLINK_CB(skb_out).dst_group = 0; /* not in mcast group */
    strncpy(nlmsg_data(nlh),msg,msg_size);

    res=nlmsg_unicast(nl_sk,skb_out,pid);

    if(res<0)
        printk(KERN_INFO "Error while sending bak to user\n"); 
}

static int __init hello_init(void)
{
    struct netlink_kernel_cfg cfg = {
        .input = hello_nl_recv_msg
    };

    nl_sk = netlink_kernel_create(&init_net, NETLINK_USER, &cfg);

    printk("Entering: %s\n",__FUNCTION__);

    if(!nl_sk)
    {    
        printk(KERN_ALERT "Error creating socket.\n");
        return -10;
    }
    return 0;
}

static void __exit hello_exit(void) 
{
    printk(KERN_INFO "exiting hello module\n");
    netlink_kernel_release(nl_sk);
}

module_init(hello_init);
module_exit(hello_exit);

这code适用于仅第一个循环。下一次的内核崩溃,并在黑色的屏幕给人的内核恐慌的错误。每次我在做重启。为什么它给内核恐慌?我哪里需要修改?我认为问题是内核模块中。
结果内核: 3.13.0-24泛型

This code works for first loop only. next time kernel is crashing and giving kernel panic error in black screen. Every time I'm doing reboot. Why it is giving kernel panic? Where I have to modify? I think problem is in kernel module.
Kernel: 3.13.0-24-generic

推荐答案

好了,我想这个问题是在内核模块。但问题是用户模块。我曾3天找出这个问题。问题是在

Well, I thought the problem is in Kernel module. But the problem is in user module. I worked 3 days to identify this problem. The problem is at

while(1) {           
    sleep(2);
    printf("Sending message to kernel\n");
    sendmsg(sock_fd,&msg,0);     // In 2nd iteration msg value chaged

    recvmsg(sock_fd, &msg, 0);  // <--- msg will update
    printf("Received message payload: %s\n", (char *)NLMSG_DATA(nlh));
}

这个循环的作品只有一次。那是真实的。使用 recvmsg 信息变量更新,我用该变量再次发送收到消息后。这是因为,在智能,两者(源和目标)是指同一指针的code。

This loops works only once. That is true. After receiving the message using recvmsg, msg variable is updated and I used that variable to send again. This is because of the code is over smart, both(source and destination) are referring to same pointer.

通过对 SENDMSG recvmsg 将删除的问题。

By writing different variables for sendmsg and recvmsg will remove the problem.

int main()
{
    int seq_no = 1;
    sock_fd=socket(PF_NETLINK, SOCK_RAW, NETLINK_USER);
    if(sock_fd<0)
            return -1;

    memset(&src_addr, 0, sizeof(src_addr));
    src_addr.nl_family = AF_NETLINK;
    src_addr.nl_pid = getpid(); /* self pid */

    bind(sock_fd, (struct sockaddr*)&src_addr, sizeof(src_addr));

    memset(&dest_addr, 0, sizeof(dest_addr));
    dest_addr.nl_family = AF_NETLINK;
    dest_addr.nl_pid = 0; /* For Linux Kernel */
    dest_addr.nl_groups = 0; /* unicast */

    nlh = (struct nlmsghdr *)malloc(NLMSG_SPACE(MAX_PAYLOAD));
    memset(nlh, 0, NLMSG_SPACE(MAX_PAYLOAD));
    nlh->nlmsg_len = NLMSG_SPACE(MAX_PAYLOAD);
    nlh->nlmsg_pid = getpid();
    nlh->nlmsg_flags = 0;

    strcpy(NLMSG_DATA(nlh), "Hello");

    iov.iov_base = (void *)nlh;
    iov.iov_len = nlh->nlmsg_len;
    msg.msg_name = (void *)&dest_addr;
    msg.msg_namelen = sizeof(dest_addr);
    msg.msg_iov = &iov;
    msg.msg_iovlen = 1;
                                            /* receiver parameters */
    nlh_in = (struct nlmsghdr *)malloc(NLMSG_SPACE(MAX_PAYLOAD));
    iov_in.iov_base = (void *)nlh_in;
    iov_in.iov_len = nlh->nlmsg_len;
    msg_in.msg_iov = &iov_in;
    msg_in.msg_iovlen = 1;                  /* end */

    while(1) {
        printf("sending message to kernel\n");
        sendmsg(sock_fd,&msg,0);

        recvmsg(sock_fd, &msg_in, 0);
        printf("Received message payload: %s\n", (char *)NLMSG_DATA(nlh_in));
        sleep(1);
    }
    free(nlh);
    close(sock_fd);
}

这篇关于网络链路捐赠内核崩溃的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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