
我想使用 cron 來安排 ZFS 池的定期清理,並且在相當短的時間內進行磨砂完成後,透過電子郵件向我自己發送狀態報告。這樣做的目的是捕獲任何問題,而無需手動查找它們(推而不是拉)。
第一部分很簡單:只需設定 cron 作業,以zpool scrub $POOL
在我的特定情況下合理的時間間隔以 root 身分執行。
第二部分,我不太確定該怎麼做。zpool scrub
立即返回,然後清理由系統在後台運行(如果清理由管理員從終端啟動,這當然是理想的行為)。zpool status
給我一個狀態報告並退出(清理運行時退出代碼為 0;它尚未完成,所以我不知道完成後退出狀態是否會改變,但我對此表示懷疑)。 zpool scraping 記錄的唯一參數是-s
「停止清理」。
主要問題是檢測狀態的變化擦洗到擦洗完畢。有鑑於此,其餘的事情應該就位了。
理想情況下,我想告訴zpool scrub
在擦洗完成之前不要返回,但我看不到任何方法可以讓它做到這一點。 (這會讓簡單的 cron 變得太容易了zpool scrub --wait-until-done $POOL; zpool status $POOL
。)
如果做不到這一點,我想詢問系統目前是否正在進行清理,最好是以一種不會因升級或配置更改而造成太大風險的方式,以便我可以根據之前運行的是否進行操作清理已完成(透過在清理狀態從清理變為未清理時執行zpool status)。
此特定設定適用於工作站系統,因此雖然 Nagios 等監控工具大概有可以解決問題的插件,但僅僅為了這項任務安裝這樣的工具感覺有點過分了。有人可以建議一個技術含量較低的解決方案嗎?
答案1
在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 在啟動時啟動。
答案2
雖然這個問題是針對linux的,但它是搜尋時第一個google結果“等到擦洗完成”,因此我想為運行 OpenSolaris 的人添加一些有用的信息(在 OmniOS 上測試過,但 SmartOS、illumos 等應該類似)而不是 Linux(普通 Solaris 也應該可以工作,但我沒有在那裡測試)。
您可以用來syseventadm
註冊內核事件。完整清單可以在/usr/include/sys/sysevent/eventdefs.h
(只需在此文件中搜尋“ZFS”)中找到。新增事件後,必須重新啟動服務,例如:
syseventadm add -c EC_zfs -s ESC_ZFS_scrub_finish /path/to/script.sh \$pool_name
syseventadm restart
這樣,當任何池的清理完成時,腳本就會啟動 - 您必須檢查腳本內部是否$1
等於您所需的池名稱。儘管如此,它的開銷比輪詢少得多。
答案3
我使用這個簡單的腳本透過電子郵件清理狀態報告。
如果您需要檢測從scrub running
到 的轉換,scrub finished
我會檢查 輸出state
欄位zpool status
。像這樣的事情:
# start scrubbing
zpool scrub ZPOOL
# wait till scrub is finished
while zpool status ZPOOL | grep 'scan: *scrub in progress' > /dev/null; do
echo -n '.'
sleep 10
done
# send a report
zpool status | mail -s "zpool status: ZPOOL" RECIPIENT
答案4
最近的 ZFS 版本準確地添加了 OP 要求的內容:用於-w
等待清理完成後再返回。例如:
zpool scrub tank -w ; zpool status tank | mail -s "report" [email protected]