102 lines
3.6 KiB
Bash
Executable File
102 lines
3.6 KiB
Bash
Executable File
#!/bin/bash
|
|
# prerm - 卸载前卸载内核模块
|
|
set -e
|
|
|
|
# 当脚本由 dpkg 触发时,$DPKG_MAIN_TSN_PACKAGE 通常可用
|
|
PACKAGE_NAME="${DPKG_MAIN_TSN_PACKAGE}"
|
|
if [ -z "$PACKAGE_NAME" ]; then
|
|
SCRIPT_NAME=$(basename "$0")
|
|
PACKAGE_NAME=$(echo "$SCRIPT_NAME" | sed 's/\.postinst$//' | sed 's/\.prerm$//')
|
|
fi
|
|
|
|
# 从 dpkg 数据库获取版本
|
|
if [ -n "$PACKAGE_NAME" ]; then
|
|
PACKAGE_VERSION=$(dpkg-query -W -f='${Version}' "$PACKAGE_NAME" 2>/dev/null)
|
|
# 去掉 Debian 修订号(-1, -2, -ubuntu1 等)
|
|
PACKAGE_VERSION=$(echo "$PACKAGE_VERSION" | sed 's/-.*$//')
|
|
fi
|
|
|
|
DKMS_SRC_DIR="/usr/src/${PACKAGE_NAME}-${PACKAGE_VERSION}"
|
|
MAKEFILE_ABS_PATH="${DKMS_SRC_DIR}/Makefile"
|
|
MODULE_NAME=""
|
|
|
|
# 【核心修复】:使用绝对路径去解析真正的 Makefile 提取驱动名
|
|
if [ -f "${MAKEFILE_ABS_PATH}" ]; then
|
|
MODULE_NAME=$(sed -n -E 's/^DRIVER_NAME[[:space:]]*:?=[[:space:]]*([^[:space:]]+).*/\1/p' "${MAKEFILE_ABS_PATH}" | head -1 | sed 's/\.ko$//')
|
|
fi
|
|
|
|
# 如果从 Makefile 没解析出来,降级使用包名作为模块名
|
|
if [ -z "$MODULE_NAME" ]; then
|
|
MODULE_NAME="${PACKAGE_NAME}"
|
|
fi
|
|
|
|
case "$1" in
|
|
remove)
|
|
echo "正在卸载 ${PACKAGE_NAME}..."
|
|
|
|
# 1. 卸载内核模块
|
|
echo "检查内核模块状态: ${MODULE_NAME}"
|
|
if lsmod | grep -q "^${MODULE_NAME}"; then
|
|
echo "正在从当前内核中卸载模块 ${MODULE_NAME}..."
|
|
if rmmod "${MODULE_NAME}" 2>/dev/null; then
|
|
echo "模块 ${MODULE_NAME} 卸载成功"
|
|
else
|
|
echo "警告: 模块 ${MODULE_NAME} 卸载失败,可能有其他进程正在使用它" >&2
|
|
fi
|
|
else
|
|
echo "模块 ${MODULE_NAME} 当前未加载"
|
|
fi
|
|
|
|
# 2. 从 DKMS 移除模块 (修复:扩大 grep 范围以兼容 added/installed 各种状态)
|
|
if dkms status | grep -q "${PACKAGE_NAME}/${PACKAGE_VERSION}"; then
|
|
echo "从 DKMS 移除 ${PACKAGE_NAME} ${PACKAGE_VERSION}..."
|
|
dkms remove -m "${PACKAGE_NAME}" -v "${PACKAGE_VERSION}" --all 2>/dev/null || true
|
|
fi
|
|
|
|
echo "正在强行清理 /lib/modules/ 下的所有 ${MODULE_NAME} 残留文件..."
|
|
find /lib/modules/ -name "${MODULE_NAME}.ko*" -delete 2>/dev/null || true
|
|
|
|
# 3. 更新模块依赖
|
|
echo "更新模块依赖..."
|
|
depmod -a
|
|
|
|
# 4. 删除开机自动加载配置
|
|
if [ -f "/etc/modules-load.d/${PACKAGE_NAME}.conf" ]; then
|
|
echo "删除开机自动加载配置..."
|
|
rm -f "/etc/modules-load.d/${PACKAGE_NAME}.conf"
|
|
fi
|
|
|
|
echo "${PACKAGE_NAME} 卸载完成"
|
|
;;
|
|
|
|
upgrade)
|
|
echo "软件包升级中,清理旧版本..."
|
|
|
|
# 1. 升级时卸载旧版本的内核运行模块
|
|
if lsmod | grep -q "^${MODULE_NAME}"; then
|
|
echo "正在卸载旧版本内核运行模块..."
|
|
rmmod "${MODULE_NAME}" 2>/dev/null || true
|
|
fi
|
|
|
|
# 2. 从 DKMS 移除旧版本
|
|
if dkms status | grep -q "${PACKAGE_NAME}/${PACKAGE_VERSION}"; then
|
|
echo "从 DKMS 移除旧版本模块记录..."
|
|
dkms remove -m "${PACKAGE_NAME}" -v "${PACKAGE_VERSION}" --all || true
|
|
fi
|
|
|
|
# 3. 清理旧的内核模块文件 (原逻辑保留,提供兜底支持)
|
|
rm -f /lib/modules/*/kernel/drivers/misc/${MODULE_NAME}.ko 2>/dev/null || true
|
|
|
|
depmod -a
|
|
;;
|
|
|
|
failed-upgrade)
|
|
echo "升级失败,保留原有配置"
|
|
;;
|
|
|
|
*)
|
|
echo "prerm 被调用时参数: $1" >&2
|
|
;;
|
|
esac
|
|
|
|
exit 0 |