Linux内核开发  - 讨论区

标题:[zeuux-linux] Linux下守护进程使用Netlink与内核模块通信问题

2008年10月25日 星期六 20:18

Docoocoo docoocoo在gmail.com
星期六 十月 25 20:18:41 CST 2008

一:问题描述
环境:Red Hat Enterprise Linux AS release3
内核版本:2.4.21-4.EL

本程序分两个模块,一个应用层程序(A),一个可卸载的内核模块(B),两者之间通过Netlink机制通信,原先A作为普通程序实现时没有问题,但现在需要把A改为守护进程模式,两者之间的通信出现问题了,求高手解答。谢谢!

两者之间的通信过程是:首先由A向B传入初始参数,然后A一直处于接收B传来的数据;


改为守护进程后的问题是:A向B传入初始参数能够正常接收,
A接收B的第一次数据正常,B输出到控制台的调试信息如下:
Message from syslogd在Dispaly at Thu Oct 23 10:54:22 2008 ...
Dispaly kernel: Send message ok-- Alarm! [/usr/bin/nautilus] is trying to
rename /11/11/FtpServer.ppt, denied! :92 !!

第二次开始就报如下错误,B输出到控制台的调试信息如下:
Message from syslogd在Dispaly at Thu Oct 23 10:54:43 2008 ...
Dispaly kernel: Send message ok-- Alarm! [/usr/bin/nautilus] is trying to
rename /11/11/1111.h, denied! :-111 !!

错误代码的系统定义
#define        ECONNREFUSED        111        /* Connection refused */

二:代码片段
//////////////////////////////////////////////////////////////////////////////////////
//以下代码是实现守护进程功能的代码
void init_daemon(void)
{
        int pid;
        int i;
        if(pid=fork())
        exit(0);
        else if(pid< 0)
        exit(1);

        setsid();

        if(pid=fork())
        exit(0);
        else if(pid<0)
        exit(1);

        for(i=0;i<NOFILE;++i)
        close(i);
        chdir("/");
        umask(0);
        return;
}

void signal_handle(int signal)
{
        exit(0);
}
//////////////////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////////////////
//以下代码是内核模块(B)向A发送数据的代码,同时向控制台输出调试信息
static int send_to_user(char *info)
{
  int ret,err;
  int size;
  struct sk_buff *skb;
  struct nlmsghdr *nlh;

  if(user_proc.pid <0)
  {
                return 0 ;
  }

  if((ret=strlen(info)) > PACKETSIZE)
  {
          return 0 ;
  }

  size = NLMSG_SPACE(PACKETSIZE);
  skb = alloc_skb(size, GFP_ATOMIC);
  memset(skb->data,0,size);

  nlh = (struct nlmsghdr*)skb->data ;

  skb_put(skb,sizeof(struct nlmsghdr)) ;
  nlh->nlmsg_len = NLMSG_SPACE(PACKETSIZE) ;
  nlh->nlmsg_pid = 0;
  nlh->nlmsg_flags = 0;

  skb_put(skb,strlen(info)) ;
  strcpy(NLMSG_DATA(nlh),info);
  nlh->nlmsg_len = skb->len ;
  NETLINK_CB(skb).groups = 0;
  NETLINK_CB(skb).pid = 0;
  NETLINK_CB(skb).dst_pid =     user_proc.pid ;
  NETLINK_CB(skb).dst_groups = 0;
  err=netlink_unicast(nl_sk, skb, user_proc.pid , MSG_DONTWAIT);
  if(DEBUG_MODE)
          printk(KERN_EMERG"Send message ok-- %s :%d !!\n",info,err) ;
  return err ;
}
//////////////////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////////////////
//以下代码是守护进程的代码;
//testlog(void * path)---向内核模块(B)传入初始参数,并接收内核模块发送过来的数据;
//main()---将进程改为守护进程模式,并调用testlog(void * path);

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

void testlog(void * path)
{
        char * pathname=(char *)path;

        int i,count ;
        char info[256] ;
        sock_fd = socket(PF_NETLINK, SOCK_RAW, NETLINK_TEST);
        memset(&dst_addr, 0, sizeof(dst_addr));
        dst_addr.nl_family = AF_NETLINK;

        dst_addr.nl_groups = 0;

        nlh = (struct nlhmsghdr *)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;

        FILE *fp;
        if((fp=fopen("/home/show/deamo/all/test.log","a"))>=0)
        {
                fprintf(fp,"the pid is %d\n",nlh->nlmsg_pid);
                fclose(fp);
        }

        strcpy(NLMSG_DATA(nlh), protectpathname);
        iov.iov_base = (void *)nlh;
        iov.iov_len = nlh->nlmsg_len;
        msg.msg_name = (void *)&dst_addr;
        msg.msg_namelen = sizeof(dst_addr);
        msg.msg_iov = &iov;
        msg.msg_iovlen = 1;
        count = sendmsg(sock_fd, &msg, 0);

        if((fp=fopen("/home/show/deamo/all/test.log","a"))>=0)
        {
                fprintf(fp,"the path send counts is %d\n",count);
                fclose(fp);
        }

        int ret;
        char sendmessage [MAX_PAYLOAD];                        //define this
buffer ,just for Redhat linux AS4
        memset(sendmessage, 0,MAX_PAYLOAD);

        int ntime=0;
        while(1)
        {
                memset(nlh, 0, NLMSG_SPACE(MAX_PAYLOAD));
                count = recvmsg(sock_fd, &msg, 0);
                strcpy(sendmessage,NLMSG_DATA(nlh));

                if(strlen(NLMSG_DATA(nlh))==0)
                {
                        continue;
                }

                if((fp=fopen("/home/show/deamo/all/test.log","a"))>=0)
                {
                        fprintf(fp,"Test log!----%s\n", NLMSG_DATA(nlh));
                        fclose(fp);
                }
        }

        close(sock_fd);
        return;
}

/*------------------------------------主函数------------------------------*/
int main(int argc,char * *argv)
{
        init_daemon();

        signal(SIGUSR2, signal_handle);

        int pathfd,size;
        char path [256];
        memset(path,00,256);
        pathfd=open("/home/show/deamo/all/path",O_RDONLY);
        size=read(pathfd,path,256);
        close(pathfd);

        FILE *fp;
        if((fp=fopen("/home/show/deamo/all/test.log","a"))>=0)
        {
                fprintf(fp,"the proctet path is %s\n",path);
                fclose(fp);
        }

        testlog(path);

  return 0;
}
-------------- 下一部分 --------------
一个HTML附件被移除...
URL: <http://www.zeuux.org/pipermail/zeuux-linux/attachments/20081025/5d5b4466/attachment.html>

[导入自Mailman归档:http://www.zeuux.org/pipermail/zeuux-linux]

如下红色区域有误,请重新填写。

    你的回复:

    请 登录 后回复。还没有在Zeuux哲思注册吗?现在 注册 !

    Zeuux © 2024

    京ICP备05028076号