Linux 内核模块在卸载期间挂起
Linux kernel module hangs during unloading
我正在尝试根据书 'Operating System Concepts' 的第一章制作编程项目。任务是编写 Linux 内核模块,它使用内核列表数据结构迭代结构。我写了以下代码:
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/list.h>
#include <linux/slab.h>
struct birthday {
int day;
int month;
int year;
struct list_head list;
};
struct list_head birthday_list;
struct birthday *createBirthday(int day, int month, int year)
{
struct birthday *person = kmalloc(sizeof(struct birthday), GFP_KERNEL);
person->day = day;
person->month = month;
person->year = year;
return person;
}
void printInfo(char *str)
{
printk(KERN_INFO "OS Module: %s", str);
}
int simple_init(void)
{
struct birthday *person = createBirthday(13, 4, 1987);
struct birthday *ptr;
printInfo("Loading Module\n");
LIST_HEAD(birthday_list);
list_add_tail(&person->list, &birthday_list);
person = createBirthday(14, 4, 1987);
list_add_tail(&person->list, &birthday_list);
person = createBirthday(15, 4, 1987);
list_add_tail(&person->list, &birthday_list);
person = createBirthday(16, 4, 1987);
list_add_tail(&person->list, &birthday_list);
person = createBirthday(17, 4, 1987);
list_add_tail(&person->list, &birthday_list);
list_for_each_entry(ptr, &birthday_list, list) {
printk(KERN_INFO "OS Module: Day %d.%d.%d\n", ptr->day, ptr->month, ptr->year);
}
return 0;
}
void simple_exit(void)
{
struct birthday *tmp;
struct list_head *ptr, *next;
printInfo("Removing Module\n");
if (list_empty(&birthday_list)) {
printInfo("List is empty");
return;
}
list_for_each_safe(ptr, next, &birthday_list){
tmp = list_entry(ptr, struct birthday, list);
printk(KERN_INFO "OS Module: Removing %d.%d.%d\n", tmp->day, tmp->month, tmp->year);
list_del(ptr);
kfree(tmp);
}
//list_for_each_entry_safe(ptr, next, &birthday_list, list) {
// printk(KERN_INFO "OS Module: Removing %d.%d.%d\n", ptr->day, ptr->month, ptr->year);
// list_del(&ptr->list);
// kfree(ptr);
//}
printInfo("Module removed\n");
}
module_init( simple_init );
module_exit( simple_exit );
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Simple Module");
MODULE_AUTHOR("MP");
安装和删除模块后,我没有看到有关删除模块的消息。
~/kernelModule $ sudo insmod simple.ko
~/kernelModule $ sudo rmmod -f simple
~/kernelModule $ dmesg | grep 'OS Module'
[ 386.590198] OS Module: Loading Module
[ 386.590201] OS Module: Day 13.4.1987
[ 386.590202] OS Module: Day 14.1.1964
[ 386.590203] OS Module: Day 2.6.1964
[ 386.590204] OS Module: Day 13.8.1986
[ 386.590204] OS Module: Day 10.6.1990
[ 396.647828] OS Module: Removing Module
~/kernelModule $ sudo rmmod -f simple
rmmod: ERROR: ../libkmod/libkmod-module.c:769 kmod_module_remove_module() could not remove 'simple': Device or resource busy
rmmod: ERROR: could not remove module simple: Device or resource busy
据我了解,我的模块在删除过程中挂起。我不明白为什么。两个发布代码(也有注释)使模块挂起。
使用 [=e10=] 而不是 LIST_HEAD(birthday_list)
有助于解决问题。
我正在尝试根据书 'Operating System Concepts' 的第一章制作编程项目。任务是编写 Linux 内核模块,它使用内核列表数据结构迭代结构。我写了以下代码:
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/list.h>
#include <linux/slab.h>
struct birthday {
int day;
int month;
int year;
struct list_head list;
};
struct list_head birthday_list;
struct birthday *createBirthday(int day, int month, int year)
{
struct birthday *person = kmalloc(sizeof(struct birthday), GFP_KERNEL);
person->day = day;
person->month = month;
person->year = year;
return person;
}
void printInfo(char *str)
{
printk(KERN_INFO "OS Module: %s", str);
}
int simple_init(void)
{
struct birthday *person = createBirthday(13, 4, 1987);
struct birthday *ptr;
printInfo("Loading Module\n");
LIST_HEAD(birthday_list);
list_add_tail(&person->list, &birthday_list);
person = createBirthday(14, 4, 1987);
list_add_tail(&person->list, &birthday_list);
person = createBirthday(15, 4, 1987);
list_add_tail(&person->list, &birthday_list);
person = createBirthday(16, 4, 1987);
list_add_tail(&person->list, &birthday_list);
person = createBirthday(17, 4, 1987);
list_add_tail(&person->list, &birthday_list);
list_for_each_entry(ptr, &birthday_list, list) {
printk(KERN_INFO "OS Module: Day %d.%d.%d\n", ptr->day, ptr->month, ptr->year);
}
return 0;
}
void simple_exit(void)
{
struct birthday *tmp;
struct list_head *ptr, *next;
printInfo("Removing Module\n");
if (list_empty(&birthday_list)) {
printInfo("List is empty");
return;
}
list_for_each_safe(ptr, next, &birthday_list){
tmp = list_entry(ptr, struct birthday, list);
printk(KERN_INFO "OS Module: Removing %d.%d.%d\n", tmp->day, tmp->month, tmp->year);
list_del(ptr);
kfree(tmp);
}
//list_for_each_entry_safe(ptr, next, &birthday_list, list) {
// printk(KERN_INFO "OS Module: Removing %d.%d.%d\n", ptr->day, ptr->month, ptr->year);
// list_del(&ptr->list);
// kfree(ptr);
//}
printInfo("Module removed\n");
}
module_init( simple_init );
module_exit( simple_exit );
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Simple Module");
MODULE_AUTHOR("MP");
安装和删除模块后,我没有看到有关删除模块的消息。
~/kernelModule $ sudo insmod simple.ko
~/kernelModule $ sudo rmmod -f simple
~/kernelModule $ dmesg | grep 'OS Module'
[ 386.590198] OS Module: Loading Module
[ 386.590201] OS Module: Day 13.4.1987
[ 386.590202] OS Module: Day 14.1.1964
[ 386.590203] OS Module: Day 2.6.1964
[ 386.590204] OS Module: Day 13.8.1986
[ 386.590204] OS Module: Day 10.6.1990
[ 396.647828] OS Module: Removing Module
~/kernelModule $ sudo rmmod -f simple
rmmod: ERROR: ../libkmod/libkmod-module.c:769 kmod_module_remove_module() could not remove 'simple': Device or resource busy
rmmod: ERROR: could not remove module simple: Device or resource busy
据我了解,我的模块在删除过程中挂起。我不明白为什么。两个发布代码(也有注释)使模块挂起。
使用 [=e10=] 而不是 LIST_HEAD(birthday_list)
有助于解决问题。