强制删除异常驱动设备

目录

背景

解决方案

具体实现

编译

卸载异常驱动


背景

        在进行驱动编程的时候, 如果驱动出现了异常, insmod、 rmmod、 或者使用过程中出现了异常, 那么导致系统的驱动加载了, 但是却无法被卸载, 或者卸载时出错,如下错误:rmmod: ERROR: Module kerneloops is in use.

解决方案

通过force_rmmod外部驱动模块强制卸载异常驱动.

具体实现

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 


/*
 *  加载模块的时候, 传递字符串到模块的一个全局字符数组里面
 *
 *  module_param_string(name, string, len, perm)
 *
 *  @name   在加载模块时,参数的名字
 *  @string 模块内部的字符数组的名字
 *  @len    模块内部的字符数组的大小
 *  #perm   访问权限
 *
 * */
static char *modname = NULL;
module_param(modname, charp, 0644);
MODULE_PARM_DESC(modname, "The name of module you want do clean or delete...\n");

static int force_cleanup_module(char *del_mod_name)
{
    struct module   *mod = NULL, *relate = NULL;
    int              cpu;

    //  方法一, 遍历内核模块树list_mod查询
    struct module *list_mod = NULL;
    /*  遍历模块列表, 查找 del_mod_name 模块  */
    list_for_each_entry(list_mod, THIS_MODULE->list.prev, list)
    {
        if (strcmp(list_mod->name, del_mod_name) == 0)
        {
            mod = list_mod;
        }
    }
    /*  如果未找到 del_mod_name 则直接退出  */
    if(mod == NULL){
        printk("[%s] module %s not found\n", THIS_MODULE->name, modname);
        return -1;
    }

    //  如果有其他驱动依赖于当前驱动, 则不能强制卸载, 立刻退出
    /*  如果有其他模块依赖于 del_mod  */
    if (!list_empty(&mod->source_list)){
        /*  打印出所有依赖target的模块名  */
        list_for_each_entry(relate, &mod->source_list, source_list){
            printk("[relate]:%s\n", relate->name);
        }
    } else {
        printk("No modules depond on %s...\n", del_mod_name);
    }


    //  清除驱动的状态和引用计数
    //  修正驱动的状态为LIVE
    mod->state = MODULE_STATE_LIVE;
    //  清除驱动的引用计数
    for_each_possible_cpu(cpu) {
        local_set((local_t*)per_cpu_ptr(&(mod->refcnt), cpu), 0);
    }
    atomic_set(&mod->refcnt, 1);
    printk("[after] name:%s, state:%d, refcnt:%u\n", mod->name, mod->state, module_refcount(mod));

    return 0;
}


static int __init force_rmmod_init(void)
{
    return force_cleanup_module(modname);
}


static void __exit force_rmmod_exit(void)
{
    printk("name : %s, state : %d EXIT \n", THIS_MODULE->name, THIS_MODULE->state);
}

module_init(force_rmmod_init);
module_exit(force_rmmod_exit);

MODULE_LICENSE("GPL");

编译

#KERNELDIR := /home/scs/project/linux-6.1.18
KERNELDIR := /lib/modules/$(shell uname -r)/build
CURRENT_PATH := $(shell pwd)
obj-m := force_rmmod.o

build: kernel_modules

kernel_modules:
   $(MAKE) -C $(KERNELDIR) M=$(CURRENT_PATH) modules
clean:
   $(MAKE) -C $(KERNELDIR) M=$(CURRENT_PATH) clean

卸载异常驱动

sudo insmod force_rmmod.ko modname=异常驱动名

你可能感兴趣的:(linux,C/C++,linux)