Linux内核与设备管理:USB存储驱动usb_storage/uas的安全卸载与复原

Linux内核与设备管理:USB存储驱动usb_storage/uas的安全卸载与复原

Linux内核模块安全卸载与复原的十步法

摘要

在Linux系统中,想要安全地卸载并重新加载USB存储驱动,必须先解除文件系统与进程占用,再按依赖关系逆序卸载模块,最后按需恢复加载 。本文给出可直接执行的一步一命令实操清单,采用"箭头注释"逐字符解释每条命令,覆盖usb_storage与其依赖uas的处理策略,并以真实场景举例说明判读与排错方法,附流程图与术语表以便系统性理解。

一、前置知识与名词解释

内核模块是可按需装载的功能单元,USB存储链路常由uasusb_storage协作完成。为避免含糊,先统一术语。

名称 全称与缩写(首次出现按规范) 简要说明
通用串行总线(Universal Serial Bus, USB) USB 外设总线标准,常见于U盘、移动硬盘等
小型计算机系统接口(Small Computer System Interface, SCSI) SCSI 通用存储访问协议栈概念
USB附加SCSI(USB Attached SCSI, UAS) UAS 走SCSI命令集的USB高效传输协议,Linux内核以uas模块实现
USB存储类驱动 usb_storage 传统USB大容量存储驱动,部分设备在无UAS时退回使用
动态可加载内核模块(Loadable Kernel Module, LKM) LKM 通过modprobe/lsmod管理的内核功能单元
挂载点(Mountpoint) --- 文件系统在目录树中的挂载位置
设备断电/解绑 --- 通过udisksctl power-offeject/sys写接口让内核不再使用设备

结论先行:处理顺序应为"解除占用→卸载依赖者uas→卸载被依赖者usb_storage→按需恢复加载

二、环境假设与操作目标

你当前的机器状态(来自实际输出)说明如下:

bash 复制代码
lsmod | grep usb_storage
# 输出:usb_storage            66636  1 uas
lsblk -o NAME,TRAN,MOUNTPOINT
# 输出未见 TRAN=usb 且挂载点非空的分区

结论先行:usb_storage已被uas占用且没有USB分区挂载 。目标是安全卸载uasusb_storage,并在需要时恢复。

三、流程总览与关键路径

flowchart LR A[确认模块与占用\nlsmod|grep] --> B[确认挂载点\nlsblk -o ...] B --> C{有挂载?} C -- 是 --> D[umount 分区\nsync] C -- 否 --> E[检查进程占用\nfuser -vm] D --> F[设备断电/解绑\nudisksctl / eject / sysfs delete] E --> F F --> G[先卸载 uas\nmodprobe -r uas] G --> H[再卸载 usb_storage\nmodprobe -r usb_storage] H --> I{需要恢复?} I -- 是 --> J[modprobe usb_storage] I -- 否 --> K[保持卸载状态]

结论先行:无论是否挂载,卸载顺序始终是"先uasusb_storage,否则会提示 in use

四、一步一命令的标准清单(逐字符箭头注释)

说明在前:下面是通用"十步法"的完整清单,每条命令都可单独复制执行 。若你的现场"没有挂载且usb_storageuas占用",请优先看第五章"最短路径实操"。

一、1.1 查看模块加载情况与占用关系

在任何操作前,先确定模块与占用链路,避免盲目卸载。

bash 复制代码
lsmod | grep usb_storage
# └─┬─┘   └──┬──┘ └──────────┘
#  lsmod     |        usb_storage:要查找的模块名
#            └─ 管道,把 lsmod 的输出交给 grep
# 作用:查看 usb_storage 是否加载、Used by 是否被 uas 占用

一、1.2 列出块设备、传输方式与挂载点

用以判定是否需要先卸载文件系统。

bash 复制代码
lsblk -o NAME,TRAN,MOUNTPOINT
# └──┬──┘ └─┬─┘ └──────────┘
#  命令    -o    指定输出列
#  NAME/TRAN/MOUNTPOINT:设备名/传输方式/挂载点
# 作用:定位 TRAN=usb 且 MOUNTPOINT 非空的分区

二、2.1 卸载文件系统分区(示例:/dev/sdb1)

若上一步发现已挂载,这一步必须先做。

bash 复制代码
sudo umount /dev/sdb1
# └──┬┘ └──┬──┘ └─────┘
#  sudo  umount  设备文件
# 以 root 权限卸载,使内核停止使用该分区

二、2.2 同步缓存,降低风险

在移除硬件或卸载模块前,确保缓冲写入磁盘。

bash 复制代码
sync
# 单词 sync:把内存中未写入磁盘的数据写回磁盘

二、2.3 检查并清理占用进程(可选但常用)

避免因进程占用导致umount失败或模块 in use。

bash 复制代码
sudo fuser -vm /dev/sdb1
# └──┬┘ └──┬┘ └┬┘ └──────┘
#  sudo fuser -v  -m   目标(分区或挂载点)
# -v:verbose 详细输出
# -m:把参数当作挂载点处理
# 作用:查看有哪些进程仍在占用

若需要强制清理:

bash 复制代码
sudo fuser -km /dev/sdb1
# └──┬┘ └──┬┘ └┬┘ └──────┘
#  sudo fuser -k  -m   目标
# -k:kill 杀掉占用进程
# -m:挂载点语义

三、3.1 让设备断电或从内核解绑(三选一)

只需任选其一,目的都是让内核彻底不再使用该设备。

bash 复制代码
sudo udisksctl power-off -b /dev/sdb
# └──┬┘ └──────────────┬─────────┘ └──┬──┘
#  sudo     udisksctl  power-off     -b   /dev/sdb
# 提权      工具名       断电动作    block设备  目标整盘

或:

bash 复制代码
sudo eject /dev/sdb
# └──┬┘ └──┬┘ └─────┘
#  sudo eject  设备
# 作用:弹出/解绑该块设备

或(最底层方式):

bash 复制代码
echo 1 | sudo tee /sys/block/sdb/device/delete
# └─┬─┘   └──┬┘ └──┬──┘ └──────────────┘
#  echo 1   管道  sudo  tee   目标文件
# 把"1"写入 delete,通知内核删除 sdb 这个设备

四、4.1 再次确认占用关系(可选)

确认Used by是否归零。

bash 复制代码
lsmod | grep usb_storage
# 作用:检查 usb_storage 是否仍被其它模块占用

四、4.2 卸载依赖者模块uas

必须先卸载占用者uas,否则usb_storage会 in use

bash 复制代码
sudo modprobe -r uas
# └──┬──┘ └──────┬──────┘ └─┘
#  sudo  modprobe    -r    uas
#  提权  模块管理   remove 卸载模块  模块名:USB Attached SCSI

四、4.3 卸载usb_storage

此时不应再报 in use。

bash 复制代码
sudo modprobe -r usb_storage
# └──┬──┘ └──────┬──────┘ └──────────┘
#  sudo  modprobe    -r      usb_storage
#  提权  模块管理   卸载      模块名(USB存储驱动)

五、5.1 按需恢复加载usb_storage

如果你需要恢复USB存储功能,重新加载即可。

bash 复制代码
sudo modprobe usb_storage
# └──┬──┘ └──────┬──────┘ └──────────┘
#  sudo  modprobe          usb_storage
#  提权  加载模块          模块名

五、5.2 验证加载成功

确认模块已回到内核。

bash 复制代码
lsmod | grep usb_storage
# 看到 usb_storage 再次出现在列表中即为成功

解释在后 :上面的清单把"解除文件系统占用→解绑/断电→卸载依赖者uas→卸载usb_storage→按需恢复"拆成独立、互不合并的命令,任何一步失败都可针对性排查,不会把问题混在一起。

四、1.3 常用命令与作用速查表

命令 关键参数 作用 典型失败原因
lsmod ` grep 模块名` 查看模块是否加载、被谁占用
lsblk -o NAME,TRAN,MOUNTPOINT 查设备传输方式与挂载点
umount 设备或挂载点 卸载文件系统 仍被进程占用
fuser -vm/-km 查看或杀占用进程 执行环境无psmisc
udisksctl power-off -b /dev/sdX 逻辑断电 桌面环境缺失时不可用
eject 设备名 解绑/弹出设备 设备忙
tee /sys/block/.../delete 内核层删除设备 路径写错
modprobe -r 模块名 卸载模块 被依赖 in use
modprobe 模块名 加载模块 设备不匹配

五、案例演示:当前状态下的"最短路径实操"

场景复述:usb_storage ... 1 uas 且没有USB分区挂载。结论先行:直接卸载uas再卸载usb_storage即可

二、1.1 卸载占用者模块uas

bash 复制代码
sudo modprobe -r uas
# └──┬──┘ └──────┬──────┘ └─┘
#  sudo  modprobe    -r    uas
#  提权  模块管理    卸载   模块名

二、1.2 确认uas已卸载

bash 复制代码
lsmod | grep uas
# 无输出则说明 uas 不在了

二、1.3 卸载usb_storage

bash 复制代码
sudo modprobe -r usb_storage
# └──┬──┘ └──────┬──────┘ └──────────┘
#  sudo  modprobe    -r      usb_storage

二、1.4 需要恢复时只加载usb_storage

bash 复制代码
sudo modprobe usb_storage
# └──┬──┘ └──────┬──────┘ └──────────┘
#  提权  加载模块          模块名

解释在后 :该"最短路径"省略了卸载分区与断电步骤,因为你现场没有挂载点;若未来插入U盘自动挂载,务必先umount后再做模块操作。

六、扩展与排错:自动加载、强制卸载与三种解绑方式差异

结论先行:不要用强制卸载rmmod -f,更不要在生产环境里图快

三、1.1 三种解绑方式对比

方法 层级 优点 注意点
udisksctl power-off -b /dev/sdX 桌面服务层 逻辑断电,温和安全 依赖udisks2
eject /dev/sdX 工具层 简单直观 有时仅逻辑弹出,未必断电
echo 1 > /sys/block/sdX/device/delete 内核/sysfs 最底层,效果直接 必须确认路径准确,误删风险高

三、1.2 防止UAS自动加载(可选)

部分老U盘在UAS下表现不稳定,可临时禁用UAS回退到usb_storage

bash 复制代码
echo "blacklist uas" | sudo tee /etc/modprobe.d/disable-uas.conf
# └──┬──┘ └──────────┬──────────┘ └──────────────┘
#  echo 文本   管道       sudo  tee      目标配置文件
# 写入一行:blacklist uas,用于阻止内核自动加载 uas

更新initramfs(部分发行版需要):

bash 复制代码
sudo update-initramfs -u
# └──┬──┘ └──────────┬──┘
#  sudo   update-initramfs  -u
# 以 root 权限更新 initramfs,使黑名单在早期启动生效

恢复UAS自动加载:

bash 复制代码
sudo rm /etc/modprobe.d/disable-uas.conf
# └──┬┘ └──────────┬──────────┘
#  sudo      rm      配置文件
# 删除黑名单文件,允许 uas 再次自动加载

三、1.3 常见报错与对策

  • modprobe: FATAL: Module usb_storage is in use
    先卸载uas或其它依赖者,再卸载usb_storage。若仍失败,检查是否有挂载或进程占用。
  • umount: target is busy
    fuser -vm找出进程并fuser -km清理,或确认是否在该目录中工作导致"自占用"。

七、结论或总结

安全地卸载并恢复USB存储驱动的关键在于"先解除占用,再按依赖逆序卸载,最后按需恢复加载" 。在实务中,占用者通常是uas,被占用者是usb_storage,顺序错误将直接导致 in use 。结合流程图、一步一命令与箭头注释,配合fuserlsblk的判读,你可以在任何发行版上稳定复现该流程并快速定位问题根因。

相关推荐
风为你而吹2 小时前
【玩泰山派】4、制作ubuntu镜像-(5)总结制作镜像流程
linux·ubuntu
andyguo2 小时前
AI模型测评平台工程化实战十二讲(第五讲:大模型测评分享功能:安全、高效的结果展示与协作)
人工智能·安全·c#
tt5555555555552 小时前
Linux虚拟机固定IP超详细教程
linux·运维·tcp/ip
Gss7773 小时前
Docker 镜像知识总结
运维·docker·容器
梁正雄3 小时前
1、docker入门简介
运维·docker·容器
東雪蓮☆3 小时前
Docker 数据卷与存储机制(持久化与共享实战)
运维·docker·容器
牛马的人生3 小时前
GitLab入门教程:打开DevOps全流程的大门
运维·其他·gitlab·devops
阑梦清川3 小时前
动静态库和编译链接简述
linux
拾光Ծ3 小时前
【Linux】入门指南:基础指令详解Part One
linux·运维·服务器·centos