smartctl 退出码 32:专门跳过你最该看的硬盘的那个"错误"

· 2 min read · notes smartsmartctlunraidmonitoringbashdiskshomelab

我的硬盘健康采集脚本连续几周都是”全绿”。每块盘都有温度、通电小时数和 SMART 结论,指标看起来完整——直到我数了一下只有 4 块 SSD 里的 2 块。

不是故障,是消失了。脚本认定这两块盘不存在。

问题出在把退出码当布尔值

采集脚本遍历块设备、对每块盘跑 smartctl、再写 Prometheus textfile 指标。错误处理看起来挺防御:

for dev in /dev/sd?; do
  if ! smartctl -A -H "$dev" > /tmp/smart.out 2>&1; then
    continue          # "盘不支持 SMART / 读不到"
  fi
  # 解析并输出指标
done

if ! cmd 是布尔判断,但 smartctl 的退出状态不是布尔值,是一个位域。把位域当真假用,就是这次翻车的原因。

退出码 32 的真实含义

man smartctl 里这些位是独立累加的:

位值含义
01命令行解析失败
12设备打开失败 / 无 IDENTIFY DEVICE 结构
24SMART 或 ATA 命令失败、校验和错误
38SMART 状态为 DISK FAILING
416有预失效属性 <= 阈值
532SMART 状态 OK,但某些属性曾经低于阈值
664设备错误日志中有记录
7128自检日志中有失败记录

所以 32 的意思和”读不到盘”正好相反:现在没问题,但它曾经踩过阈值。 这正是应该持续盯着的那类盘——而我的脚本把它们丢掉了。

消失的两块盘,恰好是原始属性长期处在边缘值的那两块;退出码为 0 的”健康盘”被正常采集。这个过滤器实际上筛选出了”没有任何历史可报告”的盘。

修法:把”信息位”掩掉

对监控来说,位 32 和 64 是信息;位 8 和 16 才是该告警的。掩掉信息位,只对剩下的做判断:

smartctl -A -H -d sat "$dev" > /tmp/smart.out 2>&1
rc=$?

# fatal bits: 1 (parse), 2 (open), 4 (command/checksum), 8 (FAILING)
# informational bits: 32 (was below threshold in the past), 64 (error log has records)
fatal=$(( rc & ~(32 | 64) ))
if [ "$fatal" -ne 0 ]; then
  echo "device $dev unreadable or failing (rc=$rc)" >&2
  continue
fi

# emit the verdict AND the exit code, so the code itself is a metric
echo "disk_smart_exit_code{device=\"$dev\"} $rc"
echo "disk_smart_health{device=\"$dev\"} $(( rc & 8 ? 0 : 1 ))"

三点改变:

  1. 退出码变成数据,而不是控制流。 它作为指标被导出,磁盘从 0 → 32 → 64 的漂移会变成趋势,而不是一次静默跳过。
  2. 信息位不再致命。 有历史的盘被采集,这才是监控它们的目的。
  3. NAS 上 -d sat 很关键。 在 Synology DSM(以及某些 USB 桥接)上,设备类型不对时 smartctl 拿不到有用输出——症状同样是”盘消失”,原因却不同。

我下次会怎么做

结果

采集器从 2 块可用盘变成 4 块,每块都报温度、通电小时数、SMART 状态和原始退出码——共 122 个 textfile 指标,包括我真正想要的 btrfs 错误计数。重新出现的那两块,正是长期处在边缘属性值的盘。

一个会跳过自己最坏信号的监控流水线,比没有监控更糟——因为它一直告诉你一切正常。

需要为你的业务做这个吗?

如果你在跑 NAS 或服务器机架,想让硬盘健康真正”会通知你”——SMART 属性、温度、btrfs/RAID 错误计数,并推到 Telegram 或邮件——这类自托管监控流水线我可以帮你搭。

WhatsApp:+60 12-797 2969 · 邮箱:[email protected] · hoelee.com

网站设计与开发是我的主业;服务器加固与自托管基础设施是它的另一半。

Lee Teong Hoe

Full-stack developer & DevOps engineer. I build web apps, self-host infrastructure, and automate things — this blog is my living portfolio.