proc 파일 시스템 프로그래밍
글쓴이: sangchu / 작성시간: 월, 2010/06/21 - 12:04오후
지금 proc 파일시스템에 대한 프로그래밍을 하고 있는데, 희한한 부분이 있어서 질문드립니다.
read_num을 생성한 파일시스템의 read_proc으로 등록시켰는데,
읽기를 수행하면 read_num 안의 printk("excute read_num")이 세번이 찍히네요.
세번을 호출한 일이 없는데 어찌 된일인지?
그리고 모듈 프로그래밍할 때 디버깅은 어떻게 하나요? gdb나 strace를 사용할 수 있는건가요?
#include <linux/module.h> #include <linux/init.h> #include <linux/proc_fs.h> #include <linux/kernel.h> #include <asm/uaccess.h> #include <linux/ip.h> #include <linux/in.h> #include <net/arp.h> #include <linux/types.h> #define MODULE_ON 1 #define MODULE_OFF 0 static int num = MODULE_OFF; static char buf[4*sizeof "123"]; char * inet_ntoa(struct in_addr ina) { unsigned char *ucp = (unsigned char *)&ina; sprintf(buf, "%d.%d.%d.%d", ucp[0] & 0xff, ucp[1] & 0xff, ucp[2] & 0xff, ucp[3] & 0xff); return buf; } static int my_protocol_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt, struct net_device *orig_dev) { unsigned char *p; int i; struct iphdr ipheader; struct in_addr in; if(skb->pkt_type == PACKET_OTHERHOST || skb->pkt_type == PACKET_LOOPBACK) { kfree_skb(skb); return 1; } printk("[Network]\n"); //printk("\n"); p = skb_network_header(skb); memcpy(&ipheader, p, sizeof(ipheader)); in.s_addr = ipheader.saddr; printk("src ip : %s\n", inet_ntoa(in)); in.s_addr = ipheader.daddr; printk("dst ip : %s\n", inet_ntoa(in)); p = skb_mac_header(skb); printk("[MAC]\n"); printk("dst mac : "); for(i=0; i<6; i++) printk("%x:", p[i]); printk("\n"); printk("src mac : "); for(; i<12; i++) printk("%x:", p[i]); printk("\n"); printk("\n"); kfree_skb(skb); return 1; } static struct packet_type my_packet_type = { .type = __constant_htons(ETH_P_ALL), .func = my_protocol_rcv, }; static int read_num(char * buffer, char ** start, off_t offset, int length) { int size = sprintf(buffer, "goodday %d\n", num); *start = buffer + offset; size -= offset; printk("excute read_num\n"); if(size>0) { if(size > length) return length; else return size; } else { if(size > length) return length; else return 0; } } static int write_num(struct file * file, const char * buffer, unsigned long count, void * data) { int val = 0; char buf[16]; char * endp; if(count > sizeof(buf)) return -EINVAL; if(copy_from_user(buf, buffer, count)) return -EFAULT; val = simple_strtoul(buf, &endp, 10); if(*endp != '\n') return -EINVAL; num = val; // here dev_add_pack if(val == MODULE_ON) dev_add_pack(&my_packet_type); else if(val == MODULE_OFF) dev_remove_pack(&my_packet_type); else printk("dev_add_pack : 0 , dev_remove_pack : 1\n"); return count; } static int num_init(void) { struct proc_dir_entry * proc_dir_juhee; struct proc_dir_entry * proc_wr_num; proc_dir_juhee = proc_mkdir("juhee", 0); if(!proc_dir_juhee) { printk(KERN_ERR "cannot create /proc/juhee\n"); return -ENOMEM; } proc_wr_num = create_proc_entry("num", 0, proc_dir_juhee); if(!proc_wr_num) { printk(KERN_ERR "cannot create /proc/juhee\n"); remove_proc_entry("juhee", 0); return -ENOMEM; } proc_wr_num->read_proc = read_num; proc_wr_num->write_proc = write_num; proc_wr_num->data = num; return 0; } static void num_exit(void) { remove_proc_entry("juhee/num", 0); remove_proc_entry("juhee", 0); } module_init(num_init); module_exit(num_exit); MODULE_LICENSE("GPL");
Forums:
코드를 코드블럭으로
코드를 코드블럭으로 감싸주시고 indentation도 넣어주세요. 이대로는 보기가 어려워서 대답할 마음도 가실겁니다;;
저는 커널 디버깅은 보통 printk;;; 로 합니다. 요새는 커널 유틸이 좋아져서 디버거 연결시키는 기능도 분명 있으리라 봅니다. 혹은 qemu나 bochs 등을 통해서 실행하고, gdb를 연결하는 것도 방법이겠지요.
언제나 삽질 - http://tisphie.net/typo/
프로그래밍 언어 개발 - http://langdev.net
언제나 삽질 - http://tisphie.net/typo/
프로그래밍 언어 개발 - http://langdev.net
제가 code lang='c'로
제가 code lang='c'로 감쌌습니다.
혹시 커널버전 몇을
혹시 커널버전 몇을 사용하시나요?
제가 찾아본 커널들은 proc_read_entry에 해당하는 프로토타입이
처럼 되어서, 전부 읽었다면 *eof = 1 을 설정하게 되어있더군요.
계속 읽었다면 아마 저부분이 문제가 아닐까 합니다.
언제나 삽질 - http://tisphie.net/typo/
프로그래밍 언어 개발 - http://langdev.net
언제나 삽질 - http://tisphie.net/typo/
프로그래밍 언어 개발 - http://langdev.net
댓글 달기