2008年10月25日 星期六 20:18
一:问题描述 环境: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>
Zeuux © 2024
京ICP备05028076号