废弃

30. delete_module - 卸载内核模块 链接到标题

函数介绍 链接到标题

delete_module系统调用用于从内核中卸载已加载的模块。它会调用模块的清理函数并释放模块占用的内核资源。

函数原型 链接到标题

#include <linux/module.h>
#include <sys/syscall.h>

int delete_module(const char *name, int flags);

功能 链接到标题

从内核中卸载指定的模块。

参数 链接到标题

  • const char *name: 要卸载的模块名称
  • int flags: 卸载标志
    • 0: 正常卸载
    • O_NONBLOCK: 非阻塞模式
    • O_TRUNC: 强制卸载(危险)

返回值 链接到标题

  • 成功时返回0
  • 失败时返回-1,并设置errno

特殊限制 链接到标题

  • 需要root权限或CAP_SYS_MODULE能力
  • 模块正在使用时不能卸载(除非强制)
  • 某些关键模块不能卸载
  • 模块必须存在才能卸载

相似函数 链接到标题

  • init_module(): 加载内核模块
  • finit_module(): 通过文件描述符加载模块
  • 命令行工具rmmod

示例代码 链接到标题

#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/syscall.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
#include <sys/stat.h>
#include <linux/module.h>

// delete_module系统调用包装
static inline long delete_module_wrapper(const char *name, unsigned int flags) {
    return syscall(__NR_delete_module, name, flags);
}

int main() {
    printf("=== Delete_module函数示例 ===\n");
    
    // 示例1: 基本使用说明
    printf("示例1: 基本使用说明\n");
    printf("注意:需要root权限才能卸载内核模块\n");
    printf("普通用户应使用rmmod命令\n\n");
    
    // 示例2: 基本卸载操作
    printf("示例2: 基本卸载操作\n");
    
    // 正常卸载模块
    if (delete_module_wrapper("test_module", 0) == -1) {
        if (errno == ENOENT) {
            printf("模块不存在\n");
        } else if (errno == EPERM) {
            printf("权限不足\n");
        } else if (errno == EBUSY) {
            printf("模块正在使用中\n");
        } else {
            printf("卸载失败: %s\n", strerror(errno));
        }
    } else {
        printf("模块卸载成功\n");
    }
    
    // 示例3: 标志位使用
    printf("示例3: 标志位使用\n");
    
    // 非阻塞卸载
    if (delete_module_wrapper("busy_module", O_NONBLOCK) == -1) {
        if (errno == EBUSY) {
            printf("模块忙,非阻塞模式下立即返回\n");
        }
    }
    
    // 强制卸载(危险)
    printf("强制卸载标志(O_TRUNC):\n");
    printf("- 非常危险,可能导致系统崩溃\n");
    printf("- 通常不应该使用\n");
    printf("- 仅在极端情况下由专家使用\n\n");
    
    // 示例4: 常见错误类型
    printf("示例4: 常见错误类型\n");
    printf("delete_module可能的错误:\n");
    printf("- EPERM: 权限不足\n");
    printf("- ENOENT: 模块不存在\n");
    printf("- EBUSY: 模块正在使用\n");
    printf("- EFAULT: 模块名地址无效\n");
    printf("- EAGAIN: 非阻塞模式下模块忙\n\n");
    
    // 示例5: 安全卸载流程
    printf("示例5: 安全卸载流程\n");
    printf("推荐的卸载步骤:\n");
    printf("1. 检查模块是否在使用\n");
    printf("   cat /proc/modules | grep module_name\n");
    printf("2. 停止使用该模块的应用程序\n");
    printf("3. 尝试正常卸载\n");
    printf("4. 如果失败,检查错误原因\n");
    printf("5. 必要时寻求专业帮助\n\n");
    
    // 示例6: 实际使用场景
    printf("示例6: 实际使用场景\n");
    printf("系统管理员卸载驱动模块:\n");
    printf("// delete_module(\"usb_storage\", 0);\n");
    printf("// delete_module(\"bluetooth\", 0);\n");
    printf("// delete_module(\"nvidia\", 0);\n\n");
    
    // 示例7: 模块依赖处理
    printf("示例7: 模块依赖处理\n");
    printf("卸载有依赖关系的模块:\n");
    printf("1. 必须先卸载依赖它的模块\n");
    printf("2. 按依赖顺序逆向卸载\n");
    printf("3. 使用modprobe -r自动处理依赖\n\n");
    
    // 示例8: 错误恢复
    printf("示例8: 错误恢复\n");
    printf("遇到EBUSY错误时:\n");
    printf("1. 查找使用模块的进程:\n");
    printf("   lsof | grep module_name\n");
    printf("2. 停止相关进程\n");
    printf("3. 重新尝试卸载\n");
    printf("4. 重启系统(最后手段)\n\n");
    
    return 0;
}