某天 LibreNMS 告警,一台 Proxmox VE 節點的 SNMP 沒有回應。登入一看,snmpd 服務還在、網路也通,但 snmpwalk 怎麼打都逾時,重新啟動 snmpd 也卡住不動。
追到最後,原因出乎意料:一個早就刪掉的 CephFS,掛載點還留在節點上。這篇記錄追查過程,以及刪除 CephFS 時的正確步驟。
症狀
- LibreNMS 顯示該節點 SNMP 無回應,輪詢失敗
systemctl status snmpd顯示服務還在執行snmpwalk -v2c -c your-community 10.10.10.13逾時systemctl restart snmpd卡住很久,kill也殺不掉- 同一台節點上
df -h也會卡住
追查過程
看 snmpd 卡在哪裡
ps -o pid,stat,wchan:32,cmd -C snmpd
STAT 欄位是 D(不可中斷的睡眠),代表程式正在等某個核心操作完成,這種狀態下連 kill -9 都沒有用。
再看它的核心呼叫堆疊:
cat /proc/$(pidof snmpd)/stack
[<0>] wait_generic_request+0x1e/0x140 [libceph]
[<0>] ceph_monc_do_statfs+0xfc/0x130 [libceph]
[<0>] ceph_statfs+0x8c/0x1f0 [ceph]
[<0>] statfs_by_dentry+0x6a/0xb0
[<0>] user_statfs+0x6a/0xe0
[<0>] __do_sys_statfs+0x3d/0x80
[<0>] __x64_sys_statfs+0x16/0x20
[<0>] do_syscall_64+0x7e/0x170
[<0>] entry_SYSCALL_64_after_hwframe+0x76/0x7e
由下往上看:
| 呼叫 | 意義 |
|---|---|
__x64_sys_statfs、user_statfs | snmpd 呼叫了 statfs(),要查某個檔案系統的容量 |
ceph_statfs | 這個檔案系統是 CephFS |
ceph_monc_do_statfs | Ceph 核心用戶端向 MON 查詢容量 |
wait_generic_request | 一直在等 MON 回應 |
這就是鐵證:snmpd 沒有掛掉、也不是網路問題,而是被卡在核心的 statfs() 裡。
snmpd 為什麼會去查 CephFS
snmpd 回應 HOST-RESOURCES-MIB 的 hrStorageTable(LibreNMS 用來畫磁碟使用量的資料)時,會對每一個掛載點呼叫 statfs() 取得容量。只要其中一個卡住,而 snmpd 是單一執行緒處理請求,後面所有 SNMP 請求都會被堵住。
df 會卡住也是同樣的原因。
找出有問題的掛載點
findmnt -t ceph
TARGET SOURCE FSTYPE OPTIONS
/mnt/pve/cephfs1 10.10.10.11,10.10.10.12,10.10.10.13:/ ceph rw,relatime,name=admin,secret=<hidden>,acl,mds_namespace=cephfs1
/mnt/pve/cephfs2 10.10.10.11,10.10.10.12,10.10.10.13:/ ceph rw,relatime,name=admin,secret=<hidden>,acl,mds_namespace=cephfs2
cephfs2 是之前測試用、已經刪除的 CephFS,但掛載點還在。對它做 statfs(),Ceph 用戶端會一直等一個不存在的檔案系統回應,永遠等不到。
可以用 timeout 確認,不怕把自己的 Shell 也卡住:
timeout 5 stat -f /mnt/pve/cephfs1 && echo OK
timeout 5 stat -f /mnt/pve/cephfs2 || echo "卡住或失敗"
處理方式
移除儲存設定
先到「資料中心 → 儲存」確認 cephfs2 的儲存項目是否還在,還在的話先移除,否則 PVE 會再自動掛回來:
grep -A6 'cephfs: cephfs2' /etc/pve/storage.cfg
pvesm remove cephfs2
卸載殘留的掛載點
正常的 umount 也會卡住,用 lazy unmount:
umount -l /mnt/pve/cephfs2
-l 會先把掛載點從目錄樹上拆掉,等沒有人在使用時再真正釋放。叢集裡每個節點都要檢查,同樣的掛載點可能每台都有。
重新啟動 snmpd
killall -9 snmpd
systemctl start snmpd
# 確認恢復
snmpwalk -v2c -c your-community localhost hrStorageDescr
卸載之後,卡住的 statfs() 通常會結束,snmpd 就殺得掉了。如果還是一直停在 D 狀態,就只能安排時間重新開機。
正確的 CephFS 刪除步驟
這次的根本原因,是刪除 CephFS 時沒有把 PVE 的儲存設定與掛載點清乾淨。依 Proxmox VE 官方文件,完整的步驟是:
- 卸載所有非 PVE 的用戶端,例如 VM 裡掛載的 CephFS
- 停用 PVE 裡相關的 CephFS 儲存,避免被自動掛回去
- 移除 VM、CT 正在使用的資源,例如放在這個 CephFS 上的 ISO
- 在每個節點手動卸載:
umount /mnt/pve/<儲存名稱> - 停止或銷毀這個 CephFS 的 MDS,先停 standby 的,避免 standby 被升級為 active
- 刪除 CephFS,同時移除儲存設定與底層的儲存集區
第 5、6 步的指令:
# 停止或銷毀 MDS
pveceph stop --service mds.<名稱>
pveceph mds destroy <名稱>
# 刪除 CephFS、儲存設定與儲存集區
pveceph fs destroy <名稱> --remove-storages --remove-pools
pveceph fs destroy 在還有啟用中的儲存項目參照這個 CephFS 時會拒絕執行,這也是一道保護。這次的 cephfs2 應該是在舊版或手動用 ceph fs rm 刪除,才會留下沒清乾淨的掛載。
預防與監控
- 刪除 CephFS、外部 NFS、iSCSI 這類網路儲存後,到每個節點用
findmnt確認沒有殘留 - PVE 節點上的
pvestatd也會定期查詢所有儲存的容量,殘留的掛載點同樣可能讓它卡住,網頁介面上的儲存圖示會變成灰色問號 - LibreNMS 對節點的 SNMP 監控,其實也間接幫你監控了「有沒有卡住的掛載點」:SNMP 突然逾時、而網路正常時,可以優先往這個方向查
結論
這次的經驗是:程式卡住時,看 /proc/<pid>/stack 最快。它直接告訴你卡在核心的哪個呼叫,不用一直猜是網路、權限還是程式本身的問題。
另外,任何網路檔案系統的掛載點,只要後端不見了,都可能讓所有對它呼叫 statfs() 的程式一起卡住。刪除儲存時照官方步驟一步一步來,才不會留下這種不定時炸彈。
參考資料
- Proxmox VE 文件:Deploy Hyper-Converged Ceph Cluster(Destroy CephFS)
https://pve.proxmox.com/pve-docs/chapter-pveceph.html - Proxmox VE 文件:pveceph(1)
https://pve.proxmox.com/pve-docs/pveceph.1.html - Net-SNMP 文件:snmpd.conf
https://www.net-snmp.org/docs/man/snmpd.conf.html - Linux man page:statfs(2)
https://man7.org/linux/man-pages/man2/statfs.2.html



