Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is this kernel module marked at permanent on 2.6.39

When I load this module:

#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>

MODULE_LICENSE("Dual BSD/GPL");

static int hello_init(void) {
  printk("<1> Hello world!\n");
  return 0;
}

static void hello_exit(void) {
  printk("<1> Bye, cruel world\n");
}


module_init(hello_init);
module_exit(hello_exit);

(From http://www.freesoftwaremagazine.com/articles/drivers_linux?page=0,2 )

The module get marked as [permanent] in lsmod and can't be unloaded, on 2.6.39-02063904-generic (from the Ubuntu PPA). But it works fine on the default 2.6.38 kernel. (Both on Ubuntu 11.04 x86).

What has changed in 2.6.39? and what do I need to change in my code?

I was trying to isolate a more complicated problem when I ran into this issue.

EDIT:

Following a suggestion from an answer I edited the code to add __init and __exit (hello3.c):

#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>

MODULE_LICENSE("Dual BSD/GPL");

static int __init hello_init(void) {
  printk("<1> Hello world!\n");
  return 0;
}

static void __exit hello_exit(void) {
  printk("<1> Bye, cruel world\n");
}

module_init(hello_init);
module_exit(hello_exit);

The build output:

make -C /lib/modules/2.6.39-02063904-generic/build M=/home/douglas/kernelmod modules
make[1]: Entering directory `/usr/src/linux-headers-2.6.39-02063904-generic'
Building with KERNELRELEASE = 2.6.39-02063904-generic
  CC [M]  /home/douglas/kernelmod/hello3.o
  Building modules, stage 2.
Building with KERNELRELEASE = 2.6.39-02063904-generic
  MODPOST 8 modules
  CC      /home/douglas/kernelmod/hello3.mod.o
  LD [M]  /home/douglas/kernelmod/hello3.ko
make[1]: Leaving directory `/usr/src/linux-headers-2.6.39-02063904-generic'

EDIT2:

hello3.mod.c:

#include <linux/module.h>
#include <linux/vermagic.h>
#include <linux/compiler.h>

MODULE_INFO(vermagic, VERMAGIC_STRING);

struct module __this_module
__attribute__((section(".gnu.linkonce.this_module"))) = {
 .name = KBUILD_MODNAME,
 .init = init_module,
#ifdef CONFIG_MODULE_UNLOAD
 .exit = cleanup_module,
#endif
 .arch = MODULE_ARCH_INIT,
};

static const struct modversion_info ____versions[]
__used
__attribute__((section("__versions"))) = {
    { 0xbe4b3e92, "module_layout" },
    { 0xb4390f9a, "mcount" },
    { 0x5e3b3ab4, "printk" },
};

static const char __module_depends[]
__used
__attribute__((section(".modinfo"))) =
"depends=";


MODULE_INFO(srcversion, "D2A869459874C22AB265981");

Also

# grep CONFIG_MODULE_UNLOAD /boot/config-2.6.39-02063904-generic 
CONFIG_MODULE_UNLOAD=y

EDIT3:

More interestingly it doesn't happen with a vanilla kernel I've compiled myself - that loads and unloads modules fine.

EDIT4:

I installed the Oneiric beta 2 build on a VM, and that 3.0.0-11 kernel doesn't have any problem either. So it appears to be limited to the Ubuntu Vanilla PPA kernels. That won't be much fun to resolve.

like image 950
Douglas Leeder Avatar asked Sep 20 '11 08:09

Douglas Leeder


People also ask

How do I force remove a kernel module?

NAME rmmod - Simple program to remove a module from the Linux Kernel SYNOPSIS rmmod [-f] [-s] [-v] [modulename] DESCRIPTION rmmod is a trivial program to remove a module (when module unloading support is provided) from the kernel. Most users will want to use modprobe(8) with the -r option instead.

How do I blacklist a kernel module to prevent it from loading automatically?

Use the --builtin=module_name flag to mkinitrd to have it skip the module in question. [ step6 ] Append module_name. blacklist to the kernel cmdline . We give it an invalid parameter of blacklist and set it to 1 as a way to preclude the kernel from loading it.

What does the kernel module do?

Kernel modules are pieces of code that can be loaded and unloaded into the kernel upon demand. They extend the functionality of the kernel without the need to reboot the system. A module can be configured as built-in or loadable.

How do I see what is using my kernel module?

You can try lsmod | grep <module name> to see all loaded kernel modules that are using a module. You can also try dmesg | grep <module name> to see if the kernel logs have any clues as to which processes may be using a module.


1 Answers

So, after consultation with Canonical, I know what the problem is:

Ubuntu mainline builds are built with the Hardy tool chain, and the 11.04 and 11.10 tool chains are incompatible for building out-of-tree kernel modules.

like image 56
Douglas Leeder Avatar answered Nov 15 '22 00:11

Douglas Leeder