博客
背景:
FNos 目前对硬盘休眠的控制和逻辑不够完善。对于备份盘这种低频使用的硬件,系统后台进程(App/Web 服务等)即便在闲置状态下,也有极率触发意外唤醒,导致磁头频繁起旋。
我起初尝试通过定时卸载挂载点(Unmount)来规避,但测试结果显示,这种方式在 FNos 环境下会被系统机制强制唤醒,无法达到真正的“静默”效果。经过与 AI 的多轮技术探讨与测试,最终锁定了一套利用内核状态控制(Device Offline)来实现物理级屏蔽的方案。此方案目前已稳定运行,完美实现了备份盘的按需唤醒。
1. 前置准备:精准识别设备信息
在执行脚本前,必须获取备份盘的三个关键参数:物理盘符、分区 UUID、挂载目录。
1.1查询 UUID 与挂载目录
在终端执行以下命令,这是最直观查看系统层级关系的方法:
Bash
lsblk -f
如何看懂输出?
- NAME: 设备名称。在 FNos 中,你的路径通常是 sdb -> sdb1 -> md1 -> LVM卷 。
- UUID: 这一长串字符是分区的唯一标识,重启后即使 sdb 变成 sdc,UUID 也不会变 。
- MOUNTPOINT: 记录当前的挂载点(例如 /vol3) 。
2. 核心原理:为什么普通休眠会失败?
在 FNos 系统中,即便执行了 umount,系统后台的 S.M.A.R.T 监控进程仍会绕过挂载点,直接访问 /dev/sdb 节点来读取温度和健康数据。
- 现象:手动执行 hdparm -y 后,查询状态为 standby,但几秒钟后再次查询即变为 active/idle 。
- 对策:将磁盘状态修改为 offline。这会在内核层面封死该设备的 I/O 接口,让所有后台扫描指令直接返回错误,从而保住休眠状态 。
3. 自动化脚本实现
脚本一:备份前“唤醒并挂载”
此脚本负责将“隐身”的磁盘拉回系统并上线。
Bash
#!/bin/bash
# --- 基础配置 ---
TARGET_UUID="9183f4f3-9d3a-474b-8783-6d2db2c36430" # 从 lsblk -f 获取 [cite: 1]
DISK_NAME="sdb" # 物理母盘名
MOUNT_POINT="/vol3" # 挂载目录 [cite: 1]
# 1. 恢复内核运行状态
echo "running" > /sys/block/"$DISK_NAME"/device/state
# 强制触发内核重扫,识别分区表
echo "1" > /sys/class/block/"$DISK_NAME"/device/rescan
sleep 10 # 预留硬件起旋时间
# 2. 执行挂载
PART_DEV=$(blkid -U "$TARGET_UUID")
if [ -n "$PART_DEV" ]; then
mkdir -p "$MOUNT_POINT"
mount "$PART_DEV" "$MOUNT_POINT"
echo "磁盘已激活并挂载到 $MOUNT_POINT"
else
echo "错误:无法找到 UUID 对应的设备"
exit 1 # 触发任务失败状态
fi
脚本二:备份后“卸载并下线”
此脚本在官方备份任务结束后运行,实现永久静默。
Bash
#!/bin/bash
# --- 基础配置 ---
TARGET_UUID="9183f4f3-9d3a-474b-8783-6d2db2c36430"
MOUNT_POINT="/vol3"
# 1. 溯源物理母盘
PART_DEV=$(blkid -U "$TARGET_UUID")
REAL_DISK=$(lsblk -pns "$PART_DEV" | grep -o '/dev/sd[a-z]' | head -n1)
# 2. 卸载与同步
sync
umount -l "$MOUNT_POINT"
sleep 5
# 3. 验证并执行内核级屏蔽
if ! mountpoint -q "$MOUNT_POINT"; then
# 强制物理停转
hdparm -y "$REAL_DISK"
# 内核隔离:标记为 offline
echo "offline" > /sys/block/"${REAL_DISK#/dev/}"/device/state
echo "任务成功:磁盘已下线休眠"
else
echo "任务失败:挂载点仍被占用"
exit 1
fi
以上命令的实现是通过”任务计划“实现,当然单纯使用corn定时脚本一样使用,注意执行权限需要是root,普通用户权限不足。