[zeuux-linux] Linux下守护进程使用Netlink与内核模块通信问题
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>
关于邮件列表 zeuux-linux 的更多信息