1、内核为 2.6.32。卸载模块 target时,不管是否为强制卸载,都输出:ERROR:Module target is in use.用 lsmod查看 target,发现 Used by计数为 1,而据我所知,没有其它模块依赖 target。编写模块检查 target的 module结构,发现:target-state = 0 / 模块存活module_refcount(target) = 1 / 模块引用计数为 1list_empty(target-modules_which_use_me) = 1 / 模块依赖列表为空这个就很奇怪,模块的引用计数为 1,却没有引用者。这可能是模块插入内
2、核时出错而引起的,这里先不研究,先关注怎么把它强制卸载掉,虽然insmod加载是临时的,所以通过重启电脑可以解决一些问题,但是不能总是依靠重启啊。解决方法:编写模块 mymod中把问题模块 target的引用计数置为 0,就可以顺利卸载掉 target了!代码java view plaincopy1. #include 2. #include 3. #include 4. #include 5. #include 6. 7. static int _init mymod_init(void) 8. 9. struct module *mod,*relate; 10. int cpu; 11.
3、12. / 打印本模块的模块名和模块状态 13. printk(KERN_ALERT“insmod mymod name:%s state:%dn“,THIS_MODULE-name,THIS_MODULE-state); 14. 15. / 遍历模块列表,查找 target模块 16. list_for_each_entry(mod,THIS_MODULE-list.prev,list) 17. 18. if(strcmp(mod-name,“target“)=0) 19. 20. / 打印 target的模块名、模块状态、引用计数 21. printk(KERN_ALERT“name:%s
4、 state:%d refcnt:%u “,mod-name,mod-state,module_refcount(mod); 22. 23. / 打印出所有依赖 target的模块名 24. if(!list_empty( 27. else 28. printk(KERN_ALERT“used by NULLn“); 29. 30. / 把 target的引用计数置为 0 31. for_each_possible_cpu(cpu) 32. local_set(_module_ref_addr(mod,cpu),0); 33. 34. / 再看看 target的名称、状态、引用计数35. pr
5、intk(KERN_ALERT“name:%s state:%d refcnt:%un“,mod-name,mod-state,module_refcount(mod); 36. 37. 38. return 0; 39. 40. 41.static void _exit mymod_exit(void) 42. 43. printk(KERN_ALERT“rmmod mymod name:%s state:%dn“,THIS_MODULE-name,THIS_MODULE-state); 44. 45. 46.module_init(mymod_init); 47.module_exit(m
6、ymod_exit); 48. 49.MODULE_AUTHOR(“Zhangsk“); 50.MODULE_LICENSE(“GPL“); 51.MODULE_DESCRIPTION(“Why module can not be removed“); 内核include/linux/module.h:java view plaincopy1. extern struct module _this_module; 2. #define THIS_MODULE ( 3. 4. enum module_state 5. MODULE_STATE_LIVE; / 模块存活,0 6. MODULE_S
7、TATE_COMING; / 正在加载模块,1 7. MODULE_STATE_GOING; / 正在卸载模块,2 8. ; 9. 10.struct module 11. enum module_state state; / 模块状态 12. 13. /* Member of list of modules */ 14. struct list_head list; / 内核模块链表 15. 16. /* Unique handle for this module */ 17. char nameMODULE_NAME_LEN; /模块名称 18. 19. . 20. 21.#ifdef C
8、ONFIG_MODULE_UNLOAD 22. /* What modules depend on me? */ 23. struct list_head modules_which_use_me; 24. 25. /* Who is waiting for us to be unloaded */ 26. struct task_struct *waiter; 27. 28. /* Destruction function. */ 29. void (*exit) (void); 30. 31.#ifdef CONFIG_SMP 32. char *refptr; 33.#else 34.
9、local_t ref; 35.#endif 36.#endif 37. 38. . 39. 40.; 41. 42.static inline local_t *_module_ref_addr(struct module *mod, int cpu) 43.#ifdef CONFIG_SMP 44. return (local_t *) (mod-refptr + per_cpu_offset(cpu); 45.#else 46. return 47.#endif 48. include/asm-generic/atomic.h:java view plaincopy1. typedef
10、atomic64_t atomic_long_t; include/linux/types.h:java view plaincopy1. typedef struct 2. volatile int counter; 3. atomic_t; 4. 5. #ifdef CONFIG_64BIT 6. typedef struct 7. volatile long counter; 8. atomic64_t; 9. #endif arch/x86/include/asm/local.h:java view plaincopy1. typedef struct 2. atomic_long_t a; 3. local_t; 4. 5. #define local_read(l) atomic_long_read( 10.#define per_cpu_offset(x) (_per_cpu_offsetx) 11.#endif