Linux – Cannot remove or reinsert kernel module after error while inserting it without rebooting

kernel-moduleslinux

I am learning how to create kernel modules and it was all working fine: I compiled, inserted the .ko with sudo insmod cheat.ko, and the printk messages inside the init function (set by module_init) appeared correctly in /etc/log/syslog. Then I made changes to the module, removed it with sudo rmmod cheat.ko, reinserted, and printk messages were good again.

Then, when I tried a new feature the screen became like a tty, error messages all over, I did ctrl-alt-f2 ctrl-alt-f7 (I'm on ubuntu), and I got back to the X server.

I undid the most recent modifications to the source file, recompiled, but the problem now is that I am unable to reinsert the module to test things out again, unless I reboot, which is too annoying for testing.

How can I reinsert the modified module without rebooting?

What I tried and info I got:

  • cat /etc/log/syslog: The only relevant information to me was:

    BUG: unable to handle kernel NULL pointer dereference at 00000003
    

    so it seems that was the cause of the problem, and then I got an oops:

    Oops: 0002 [#1] SMP
    

    Horrid debug information follows that, but nothing that seems to help me on how to reinsert the module.

  • sudo insmod cheat.ko: command just hangs, outputs nothing, and the only way I can get on using that terminal emulator is killing it with c-c

  • sudo rmmod cheat:

    Error: Module cheat is not currently loaded
    
  • sudo modprobe -r cheat.ko

    FATAL: Module cheat.ko not found.
    
  • lsmod | grep cheat:

    cheat                  19009  -2
    

    which has a very suspicious -2 usage count…

  • cat /proc/modules | grep cheat

    cheat 19009 1 - Loading 0x00000000 (OF+)
    

    interesting, so the module is still loading…

Edit

As others have said, use a VM. And I strongly recommend you to use Vagrant to manage it.

Edit 2

Nah, Vagrant is for newbs, use QEMU + Buildroot instead: https://github.com/cirosantilli/linux-kernel-module-cheat

Best Answer

The Linux kernel is only willing to unload modules if their module_exit function returns successfully. If some function from the module crashes, the kernel may be able to recover, but the module is locked in memory. It may be possible to rummage through the kernel data structures and forcibly mark the module as unloadable (try patching the module_exit function to do nothing), but that's risky. Your best bet is to reboot.

The normal way to test a kernel module is in a virtual machine. Don't test the module on your development machine. A VM has the advantage over a physical machine that you can save the VM state in a ready-for-testing configuration and restore it as many times as you like, which saves the startup time between tests.

Related Question