红联Linux门户
Linux帮助

iscsitarget-0.4.15在2.6.24内核下编译错误问题汇总及解决办法

发布时间:2008-03-23 00:39:02来源:红联作者:Entertr
平台说明:我使用的linux是FC8,内核版本是2.6.23。但是考虑到iscsitarget对内核有特殊要求,我重新编译了一个2.6.24的内核。

2.6.24内核在/home/lianxi1999/linux-2.6.24下编译的。iscsitarget-0.4.15需要对内核进行修改,所以在编译过程中需要root权限。源文件存放在/home/lianxi1999/iscsitarget-0.4.15/中。开始我是在2.6.24内核下编译的,在编译的过程可谓是困难重重!

第一个错误:
make[1]: Entering directory `/home/lianxi1999/linux-2.6.24'
CC [M] /home/lianxi1999/iscsitarget-0.4.15/kernel/tio.o
/home/lianxi1999/iscsitarget-0.4.15/kernel/tio.c: In function ‘tio_init’:
/home/lianxi1999/iscsitarget-0.4.15/kernel/tio.c:114: 错误:提供给函数'kmem_cache_create’ 的实参太多
make[2]: *** [/home/lianxi1999/iscsitarget-0.4.15/kernel/tio.o] 错误 1
make[1]: *** [_module_/home/lianxi1999/iscsitarget-0.4.15/kernel] 错误 2
make[1]: Leaving directory `/home/lianxi1999/linux-2.6.24' make: *** [kernel] 错误 2

通过错误提示可以看出,tio.c在调用函数kmem_cache_create时,给它传递的参数太多!找到tio.c中的调用语句:tio_cache = kmem_cache_create("tio", sizeof(struct tio),0, 0, NULL, NULL); 通过网络查找和查阅内核开发方面的书籍,发现内核函数 kmem_cache_create 用来创建一个新缓存。这通常是在内核初始化时执行的,或者在首次加载内核模块时执行。

其原型定义如下: struct kmem_cache * kmem_cache_create( const char *name, size_t size,
size_t align, unsigned long flags;
void (*ctor)(void*, struct kmem_cache *, unsigned long),
void (*dtor)(void*, struct kmem_cache *, unsigned long));

通过函数原型发现该函数确实是六个参数。到底怎么回事呢?看来只能通过查找内核源码来解决问题了!找到定义该函数的源文件:/home/lianxi1999/linux-2.6.24/include/linux/slab.h 发现函数原型为:

struct kmem_cache *kmem_cache_create(const char *, size_t, size_t, unsigned long,
void (*)(struct kmem_cache *, void *));

很明显,在新版本的内核里,该函数定义发生了变化!找到了问题的所在!(实际上,该函数的定义在2.6.23中就修改了)赶紧根据提示修改程序中调用该函数的地方吧!把所有调用该函数的最后一个参数都去掉,再次编译,成功通过!不过又出现了新的错误!

第二个错误: /root/iscsitarget-0.4.15/kernel/digest.c: In function ‘digest_header’:
/root/iscsitarget-0.4.15/kernel/digest.c:185: 错误:‘struct scatterlist’ 没有名 为 ‘page’ 的成员
/root/iscsitarget-0.4.15/kernel/digest.c:187: 错误:‘struct scatterlist’ 没有名 为 ‘page’ 的成员
/root/iscsitarget-0.4.15/kernel/digest.c: In function ‘digest_data’: /root/iscsitarget-0.4.15/kernel/digest.c:239: 错误:‘struct scatterlist’ 没有名 为 ‘page’ 的成员
make[2]: *** [/root/iscsitarget-0.4.15/kernel/digest.o] 错误 1
make[1]: *** [_module_/root/iscsitarget-0.4.15/kernel] 错误 2
make[1]: Leaving directory `/home/lianxi1999/linux-2.6.24' make: *** [kernel] 错误 2

这个错误比前一个更奇怪了!竟然使用了结构体没有的成员!还是跟第一次一样的顺序,通过上网和查书,发现struct scatterlist的定义如下:

struct scatterlist { struct page *page; unsigned int offset; dma_addr_t dma_address; unsigned int length; };

很明显,有page成员变量。那是怎么回事呢?看来还是老一套,查找内核源码!digest.c中包含的头文件是 打开内核中的这个文件,发现它的内容如下:

#ifdef CONFIG_X86_32
# include "scatterlist_32.h"
#else
# include "scatterlist_64.h"
#endif

我用的是32位的平台,只能去找scatterlist_32.h,还好这两个文件离的很近(很方便查找)。发现在2.6.24内核中该结构体的定义如下:

struct scatterlist { #ifdef CONFIG_DEBUG_SG unsigned long sg_magic; #endif unsigned long page_link; unsigned int offset; dma_addr_t dma_address; unsigned int length; };

果然没有page成员(!_!)这该怎么办啊!好像已经山穷水尽了,这是我想到了我的系统中还有一个2.6.23的内核。赶快找到它对这个struct的定义,哈哈,天无绝人之路!竟然是和老版本的定义一样!快点切过去吧。在2.6.23下果然没有了这个问题。但是新的问题又来了,真是郁闷阿。

干了上面这些事情,已经用了半天的时间,第三个问题待续吧

第三个问题:
/root/iscsitarget-0.4.15/kernel/event.c: In function ‘event_init’:
/root/iscsitarget-0.4.15/kernel/event.c:98: 警告:传递参数 4 (属于 ‘netlink_kernel_create’)时在不兼容的指针类型间转换
/root/iscsitarget-0.4.15/kernel/event.c:98: 错误:提供给函数 ‘netlink_kernel_create’ 的实参太少
make[2]: *** [/root/iscsitarget-0.4.15/kernel/event.o] 错误 1
make[1]: *** [_module_/root/iscsitarget-0.4.15/kernel] 错误 2
make[1]: Leaving directory `/usr/src/kernels/2.6.23.1-42.fc8-i686' make: *** [kernel] 错误 2

很明显这是netlink_kernel_create函数在新版本的内核中被重新定义了。

找到event.c中调用该函数的语句:nl = netlink_kernel_create(NETLINK_IET, 1, event_recv, THIS_MODULE);

这下我聪明了,一开始想就通过头文件找到该该函数的定义。可是我找了该文件包含的所有的头文件之后,还是没有找到这个函数的文件,有点失望了!还是找百度吧……还好,找到了,这个函数定义在linux/netlink.h中。终于找到了,哈哈。看看吧:

extern struct sock *netlink_kernel_create(int unit, unsigned int groups, void (*input)(struct sock *sk, int len), struct mutex *cb_mutex, struct module *module);

原型中定义了5个参数,而调用的时候只传递了4个。怎么办呢?通过观察,发现是第四个形参没有传递,网上的做法是把它置为NULL,我就照做了^_^。顺利过关!OYEAR! 修改以上三个错误以后,make->make install->start。OK,可以启动了!
文章评论

共有 0 条评论