[ENBD] enbd_ioctl 2.6.9 kernel fails to modprobe enbd - seg fault

Peter T. Breuer ptb at inv.it.uc3m.es
Thu Mar 2 23:50:04 MST 2006


"Also sprach scunacc:"
> I did them all in one go.
> 
> Now it compiles thru to here cleanly:

OK.

> 
> # make module 2>&1
> mkdir -p /tmp/enbd/linux-2.6.x/.tmp_versions
> make -f /usr/src/linux-2.6.9-cm46/scripts/Makefile.build
> obj=arch/i386/kernel arch/i386/kernel/asm-offsets.s
> make[2]: `arch/i386/kernel/asm-offsets.s' is up to date.
>   CHK     include/asm-i386/asm_offsets.h
> make -f /usr/src/linux-2.6.9-cm46/scripts/Makefile.build
> obj=/tmp/enbd/linux-2.6.x/drivers/block/enbd
>   gcc -I/home/sysadmin/net_disk/nbd-2.4.33/kernel/linux-2.6.x/include
> -Wp,-MD,/tmp/enbd/linux-2.6.x/drivers/block/enbd/.enbd_base.o.d
> -nostdinc -iwithprefix include -D__KERNEL__ -Iinclude  -D__KERNEL__
> -Iinclude  -Wall -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing
> -fno-common -pipe -msoft-float     -Iinclude/asm-i386/mach-default -O2
> -fomit-frame-pointer -Wdeclaration-after-statement -D__SMP__
> -DCONFIG_X86_LOCAL_APIC  -DMODULE
> -I"/home/sysadmin/net_disk/nbd-2.4.33/kernel/linux-2.6.x/include"
> -DKBUILD_BASENAME=enbd_base -DKBUILD_MODNAME=enbd -c
> -o /tmp/enbd/linux-2.6.x/drivers/block/enbd/.tmp_enbd_base.o /tmp/enbd/linux-2.6.x/drivers/block/enbd/enbd_base.c

Probably OK.

> /tmp/enbd/linux-2.6.x/drivers/block/enbd/enbd_base.c:2859: warning:
> conflicting types for built-in function ___log2___

There's a problem. I have defined a function that conflicts with their
internal

  static inline unsigned
  log2 (unsigned arg)

Please change the name to "mylog2"  throughout.

It's a compiler bug ... my definition should win, but it hasn't.

> /tmp/enbd/linux-2.6.x/drivers/block/enbd/enbd_base.c: In function
> ___enbd_ioctl___:
> /tmp/enbd/linux-2.6.x/drivers/block/enbd/enbd_base.c:4423: warning:
> pointer targets in passing argument 1 of
> ___remote_ioctl->convert_inplace___ differ in signedness

Unimportant.

> /tmp/enbd/linux-2.6.x/drivers/block/enbd/enbd_base.c: At top level:
> /tmp/enbd/linux-2.6.x/drivers/block/enbd/enbd_base.c:4531: warning:
> ___enbd_read_block_0___ defined but not used

OK.

Rest is OK too.

>   ld -m elf_i386  -r
> -o /tmp/enbd/linux-2.6.x/drivers/block/enbd/enbd.o /tmp/enbd/linux-2.6.x/drivers/block/enbd/enbd_base.o /tmp/enbd/linux-2.6.x/drivers/block/enbd/enbd_ioctl_stub.o /tmp/enbd/linux-2.6.x/drivers/block/enbd/enbd_seqno.o /tmp/enbd/linux-2.6.x/drivers/block/enbd/enbd_md.o /tmp/enbd/linux-2.6.x/drivers/block/enbd/enbd_speed.o /tmp/enbd/linux-2.6.x/drivers/block/enbd/enbd_proc.o
>   gcc -I/home/sysadmin/net_disk/nbd-2.4.33/kernel/linux-2.6.x/include
> -Wp,-MD,/tmp/enbd/linux-2.6.x/drivers/block/enbd/.enbd_ioctl.o.d
> -nostdinc -iwithprefix include -D__KERNEL__ -Iinclude  -D__KERNEL__
> -Iinclude  -Wall -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing
> -fno-common -pipe -msoft-float     -Iinclude/asm-i386/mach-default -O2
> -fomit-frame-pointer -Wdeclaration-after-statement -D__SMP__
> -DCONFIG_X86_LOCAL_APIC  -DMODULE
> -I"/home/sysadmin/net_disk/nbd-2.4.33/kernel/linux-2.6.x/include"
> -DKBUILD_BASENAME=enbd_ioctl -DKBUILD_MODNAME=enbd_ioctl -c
> -o /tmp/enbd/linux-2.6.x/drivers/block/enbd/.tmp_enbd_ioctl.o /tmp/enbd/linux-2.6.x/drivers/block/enbd/enbd_ioctl.c
> In file included
> from /tmp/enbd/linux-2.6.x/drivers/block/enbd/enbd_ioctl.c:26:
> /home/sysadmin/net_disk/nbd-2.4.33/kernel/linux-2.6.x/include/linux/enbd_ioctl_table.h: In function ___new_IO_copy_from_user___:

Interesting ...

> /home/sysadmin/net_disk/nbd-2.4.33/kernel/linux-2.6.x/include/linux/enbd_ioctl_table.h:761: warning: ignoring return value of ___copy_from_user___, declared with attribute warn_unused_result

They're right. I'll do something about that.


> /home/sysadmin/net_disk/nbd-2.4.33/kernel/linux-2.6.x/include/linux/enbd_ioctl_table.h: In function ___new_IO_copy_to_user___:
> /home/sysadmin/net_disk/nbd-2.4.33/kernel/linux-2.6.x/include/linux/enbd_ioctl_table.h:776: warning: ignoring return value of ___copy_to_user___, declared with attribute warn_unused_result

Ditto.

>   Building modules, stage 2.
> make -rR -f /usr/src/linux-2.6.9-cm46/scripts/Makefile.modpost
> VPATH=/usr/src/linux-2.6.9-cm46
>   scripts/mod/modpost -m -o /usr/src/linux-2.6.9-cm46/Module.symvers
> vmlinux /tmp/enbd/linux-2.6.x/drivers/block/enbd/enbd.o /tmp/enbd/linux-2.6.x/drivers/block/enbd/enbd_ioctl.o
>   gcc -I/home/sysadmin/net_disk/nbd-2.4.33/kernel/linux-2.6.x/include
> -Wp,-MD,/tmp/enbd/linux-2.6.x/drivers/block/enbd/.enbd.mod.o.d -nostdinc
> -iwithprefix include -D__KERNEL__ -Iinclude  -D__KERNEL__ -Iinclude
> -Wall -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing
> -fno-common -pipe -msoft-float     -Iinclude/asm-i386/mach-default -O2
> -fomit-frame-pointer -Wdeclaration-after-statement -D__SMP__
> -DCONFIG_X86_LOCAL_APIC   -DKBUILD_BASENAME=enbd -DKBUILD_MODNAME=enbd
> -DMODULE
> -I"/home/sysadmin/net_disk/nbd-2.4.33/kernel/linux-2.6.x/include" -c
> -o /tmp/enbd/linux-2.6.x/drivers/block/enbd/enbd.mod.o /tmp/enbd/linux-2.6.x/drivers/block/enbd/enbd.mod.c
>   ld -m elf_i386 -r
> -o /tmp/enbd/linux-2.6.x/drivers/block/enbd/enbd.ko /tmp/enbd/linux-2.6.x/drivers/block/enbd/enbd.o /tmp/enbd/linux-2.6.x/drivers/block/enbd/enbd.mod.o

Looks happy.

> I.e. it ran thru' to completion
> 
> (Just like before I started the thread... :-)
> 
> So, I did make install as well, and got:


Just insmod /tmp/enbd/linux-2.6.x/drivers/block/enbd/enbd.ko please.


> modprobe enbd 
> 
> still doesn't work...

No guarantee right one chosen.

Do insmod (NOT modprobe). We'll have to instrument the init_module. I
think the trace says death occurs in blk_queue_max_sectors
(ll_rw_blk.c) at the line

   q->max_sectors = q->max_hw_sectors = max_sectors;


> EFLAGS: 00010212   (2.6.9-cm46customVM) 
> EIP is at blk_queue_max_sectors+0x34/0x47

Which presumably means q = 0. The call is from enbd_init_queue, first
line

     blk_queue_max_sectors (queue, buf_sectors); 

and "queue" is passed in as the secnd arg of enbd_init_queue:

     static void
     enbd_init_queue (struct enbd_device *lo, struct request_queue *queue)

and the call is from enbd_init:

     enbd_init_queue(lo, disk->queue);

but that call is guarded:

                disk->queue = blk_init_queue(do_enbd_request, &lo->lock);
                if (!disk->queue) {
                        put_disk(disk);
                        lo->disk = NULL;
                        ENBD_ERROR(
                            "Not enough memory to make a queue struct\n");
                        goto out_nomem;
                }
                enbd_init_queue(lo, disk->queue);
 
So on the face of it, the report is impossible. Please use insmod.




> This is where I was on the kernel module before we started... :-(
> 
> However, we have cleaned up the compile a little.

Indeed.

Peter


More information about the ENBD mailing list