我想使用 cron 安排定期清理我的 ZFS 池,并在清理完成后相当短的时间内通过电子邮件将状态报告发送给我自己。这样做的目的是捕获任何问题,而无需手动查找它们(推而不是拉)。
第一部分很简单:只需设置一个 cron 作业,zpool scrub $POOL
在我的特定情况下以任何合理的间隔以 root 身份运行。
第二部分,我不太确定该怎么做。zpool scrub
立即返回,然后系统在后台运行清理(如果清理是由管理员从终端启动的,这当然是可取的行为)。zpool status
给我一个状态报告并退出(在清理运行时退出代码为 0;它还没有完成,所以我不知道退出状态在完成后是否会改变,但我对此表示怀疑)。zpool scrub 记录的唯一参数是-s
“停止清理”。
主要问题是检测状态从擦洗到完成擦洗的变化。鉴于此,其余的应该就位。
理想情况下,我想告诉zpool scrub
在擦洗完成之前不要返回,但我看不出有任何方法可以做到这一点。(这会使简单的 cron 变得几乎太容易了zpool scrub --wait-until-done $POOL; zpool status $POOL
。)
如果做不到这一点,我想询问系统当前是否正在进行清理,最好以一种不会因升级或配置更改而中断的方式,以便我可以对先前是否运行清理已完成(通过在清理状态从清理变为不清理时执行 zpool 状态)。
这个特定的设置是针对工作站系统的,所以虽然像 Nagios 这样的监控工具可能有可以解决问题的插件,但只为这一项任务安装这样的工具感觉有点矫枉过正。有人可以提出一个技术含量较低的解决方案吗?
在Linux 上的 ZFS 上,从0.6.3 版开始,可以使用ZFS 事件守护程序 (zed) 非常优雅地处理此问题。事件守护进程通过直接监视内核事件,几乎可以立即对发生的任何事件做出反应,并且不依赖于对其他命令输出的连续轮询和解析。
/etc/zfs/zed.d/scrub.finish
使用以(例如, )开头的任何文件名创建一个 shell 脚本scrub.finish-custom.sh
。该脚本可以采取任何适当的操作,例如发送电子邮件、在某处写入日志条目或让系统唱歌跳舞(好吧,也许不是那样)。提供的示例可以提供一个起点。如果您只想在清理完成后收到一封电子邮件,那么提供的
scrub.finish-email.sh
脚本会很好地完成。只需编辑 /etc/zfs/zed.d/zed.rc 以指示电子邮件应该发送到哪里以及如果池没有遇到任何问题,是否也应该发送电子邮件,确保scrub.finish
在 /etc 中命名的内容后跟任何内容/zfs/zed.d 导致它,并确保 zed 在引导时启动。虽然这个问题是特定于 linux 的,但它是搜索“等待清理完成”时的第一个谷歌结果,因此我想为运行 OpenSolaris 的人添加一些有用的信息(在 OmniOS 上测试过,但 SmartOS、illumos 等. 应该类似)而不是 Linux(普通的 Solaris 也应该可以工作,但我没有在那里测试)。
您可以使用
syseventadm
来注册内核事件。完整列表可在/usr/include/sys/sysevent/eventdefs.h
(只需在此文件中搜索“ZFS”)中找到。添加事件后,必须重新启动服务,例如:这样,脚本将在任何池的任何清理完成时启动 - 如果
$1
等于所需的池名称,您必须检查脚本内部。不过,它的开销比轮询要少得多。我使用这个简单的脚本通过电子邮件清理状态报告。
如果您需要检测从
scrub running
到scrub finished
的转换,我会检查 输出state
字段zpool status
。像这样的东西:我在zfswatcher上取得了很大的成功