You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何防止故障USB驱动器导致Ubuntu服务器冻结无响应?

如何防止故障USB驱动器导致Ubuntu服务器冻结无响应?

遇到过一模一样的糟心情况!USB磁盘挂掉后把整个系统拖得完全没法操作,连SSH都连不上,只能硬重启,折腾死人。结合我踩过的坑,给你几个实际可行的解决方案,从简单到进阶:

1. 先优化fstab挂载参数(最快速见效)

你现有的fstab参数已经有nofail和x-systemd.device-timeout,但还可以调整几个关键选项来避免系统无限等待IO:

修改后的fstab条目参考:

UUID=UUID_HERE       /data/path/disk1       ext4    user,defaults,nofail,noatime,commit=60,x-systemd.device-timeout=30,x-systemd.mount-timeout=30,errors=remount-ro     0       2 # Modified to prevent freeze on failure

逐个解释调整的点:

  • errors=remount-ro:把你原来的errors=continue换成这个,当文件系统检测到错误时,自动把磁盘挂载为只读模式,避免系统持续重试IO操作导致IO Wait飙升卡死。
  • x-systemd.mount-timeout=30:新增这个参数,让systemd在挂载操作超时30秒后直接放弃,不会一直等设备响应。
  • 缩小x-systemd.device-timeout到30:原来的120秒太长,缩短后系统能更快识别设备故障,不会长时间卡在IO等待上。

修改后记得执行sudo mount -a测试挂载是否正常,没问题的话重启让参数生效。

2. 用udev规则自动处理故障磁盘(进阶自动修复)

如果单纯调整挂载参数还不够,可以用udev规则监控磁盘状态,一旦检测到故障就自动卸载甚至断电USB端口,彻底切断故障设备的影响:

步骤1:安装USB端口控制工具

先装uhubctl,这个工具能控制USB端口的电源:

sudo apt update && sudo apt install uhubctl

步骤2:写故障处理脚本

创建脚本/usr/local/bin/usb-fault-handler.sh,内容如下:

#!/bin/bash
MOUNT_POINT="/data/path/disk1"
DISK_SERIAL="你的磁盘序列号" # 替换成实际的磁盘序列号

# 先尝试正常卸载
umount "$MOUNT_POINT"
if [ $? -ne 0 ]; then
    # 正常卸载失败就用懒卸载(安全强制卸载)
    umount -l "$MOUNT_POINT"
fi

# 找到对应USB端口并断电
# 先查看你的USB总线编号,执行uhubctl会输出类似1-1、2-1的总线标识
uhubctl -l 1-1 -a status | grep "$DISK_SERIAL" | awk '{print $4}' | while read PORT; do
    uhubctl -l 1-1 -p "$PORT" -a off
done

给脚本加执行权限:

sudo chmod +x /usr/local/bin/usb-fault-handler.sh

步骤3:写udev规则

创建/etc/udev/rules.d/99-usb-fault.rules规则文件:

KERNEL=="sd*", SUBSYSTEM=="block", ENV{DEVTYPE}=="disk", ACTION=="change", ENV{ID_SERIAL_SHORT}=="你的磁盘序列号", RUN+="/usr/local/bin/usb-fault-handler.sh"

替换里面的“你的磁盘序列号”,可以用这个命令获取:

lsblk -no SERIAL /dev/sdX # 把sdX换成你的USB磁盘设备名,比如sdb

最后重载udev规则生效:

sudo udevadm control --reload-rules

3. 定时监控脚本(兜底方案)

如果udev规则没触发,还可以加个定时脚本,每分钟检查一次磁盘状态,发现故障就强制卸载:

创建脚本/usr/local/bin/check-disk-health.sh:

#!/bin/bash
MOUNT_POINT="/data/path/disk1"
DISK_DEVICE="/dev/sdX" # 替换成你的磁盘设备名

# 尝试读取磁盘的第一个扇区,测试是否响应
if ! dd if="$DISK_DEVICE" of=/dev/null bs=512 count=1 2>/dev/null; then
    echo "磁盘$DISK_DEVICE无响应,尝试卸载..."
    umount -l "$MOUNT_POINT"
fi

加执行权限:

sudo chmod +x /usr/local/bin/check-disk-health.sh

然后用crontab添加定时任务,每分钟执行一次:

crontab -e

添加一行:

* * * * * /usr/local/bin/check-disk-health.sh >> /var/log/disk-monitor.log 2>&1

这样脚本会把日志写到/var/log/disk-monitor.log,方便后续排查。

额外小贴士

  • 尽量用umount -l(懒卸载)代替umount -f(强制卸载),前者不会强制终止正在运行的进程,更安全,系统会在合适的时候清理挂载点。
  • 可以开启smartmontools监控磁盘健康,提前预警故障:sudo apt install smartmontools,然后配置/etc/smartd.conf让它定期检测磁盘状态。

备注:内容来源于stack exchange,提问作者Hackeron

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.23 15:12:44