确保模块使用期间不被卸载

来源:互联网 发布:手机百度网盘网络出错 编辑:程序博客网 时间:2024/05/04 10:04
用两行代码就可以完成这个功能。
 
模块open时,在注册的open函数里调用try_module_get(&THIS_MODULE),增加模块的引用计数。
模块close的时候,在注册的release函数里调用module_put(&THIS_MODULE),减少模块的引用计数。
 
只有当模块的引用计数为0时,rmmod才能成功。
 
当应用程序open这个设备时,就调用了try_module_get(&THIS_MODULE),用lsmod 可以看到设备的引用计数增加了1.
 
try_module_get()/module_put() include/linux/module.h

These manipulate the module usage count, to protect against removal (a module also can't be removed if another module uses one of its exported symbols: see below). Before calling into module code, you should call try_module_get() on that module: if it fails, then the module is being removed and you should act as if it wasn't there. Otherwise, you can safely enter the module, and call module_put() when you're finished.

Most registerable structures have an owner field, such as in the file_operations structure. Set this field to the macro THIS_MODULE.

 
顺便说一下THIS_MODULE这个宏,这个宏相当于进程的CURRENT,指向当前的模块。

内核源码目录下include/linux/module.h

#ifdef MODULE

    #define MODULE_GENERIC_TABLE(gtype,name) \

    extern const struct gtype##_id __mod_##gtype##_table \

       __attribute__ ((unused, alias(__stringify(name))))

 

extern struct module __this_module;

    #define THIS_MODULE (&__this_module)

    #else

    #define MODULE_GENERIC_TABLE(gtype,name)

    #define THIS_MODULE ((struct module *)0)

    #endif

 

__this_module这个符号是在加载到内核后才产生的。insmod命令执行后,会调用kernel/module.c里的一个系统调用 sys_init_module,它会调用load_module函数,将用户空间传入的整个内核模块文件创建成一个内核模块,并返回一个struct module结构体,从此,内核中便以这个结构体代表这个内核模块。