Linux

tmpfs 已滿,儘管幾乎沒有使用。我該如何調試這個

  • November 7, 2012

我有一個帶有 / on tmpfs 的系統。大多數 / 子目錄都安裝了 aufs,覆蓋讀寫根文件系統和只讀基本文件系統(系統從只讀介質引導)。早些時候,我曾經使用 unionfs 而不是 aufs。它一直正常工作,直到最近 tmpfs 開始填滿。我不確定是什麼觸發了這種變化。可能是 unionfs 到 aufs 的更改、核心升級或系統中的某些更改以及它訪問文件系統的方式。

無論如何,似乎是 tmpfs 的行為有些錯誤。

儘管系統不應該向 tmpfs 寫入很多內容,但其中相當一部分已用完:

# df -m /
Filesystem     1M-blocks  Used Available Use% Mounted on
tmpfs                200    50       151  25% /

儘管:

# du -smx /
2       /

這是我的測試系統,基本上什麼都不做。當使用率迅速達到 90% 以上並且系統崩潰時,生產系統就會磨損。

我懷疑這些被刪除的文件仍然打開,但是:

# lsof | grep deleted

什麼都不顯示。

另一個想法是, / 上的一些文件被安裝在它上面的文件系統屏蔽,所以我嘗試了這個:

# mount --bind / /mnt
# du -sm /mnt
2       /mnt

儘管如此,沒有失去 48MB 的痕跡。

如何找出正在使用我的 tmpfs 文件系統的內容?

系統資訊:

# uname -rm
3.4.6 i686

更新:我已經嘗試過核心 3.4.17 和 3.6.6 - 沒有變化。

在 aufs 維護者 Junjiro Okajima 的幫助下,我自己解開了這個謎團。

調試問題的第一步是以可控的方式重現它。我花了一些時間(現在我想知道為什麼這麼多)才發現問題是在通過 aufs 寫入和刪除文件時發生的。

重現問題

創建掛載點:

# cd /tmp
# mkdir rw
# mkdir mnt

掛載 tmpfs:

# mount -t tmpfs none /tmp/rw

掛載aufs,用/tmp/rw覆蓋/usr:

# mount -t aufs  -n -o "br:/tmp/rw:/usr" none "/tmp/mnt"

現在我可以看到 /tmp/mnt 下的 /usr 內容:

# ls /tmp/mnt
bin  games  include  lib  lib64  local  sbin  share  src

我感興趣的是下面 tmpfs 上的已用/可用空間:

# du -sk /tmp/rw   
0   /tmp/rw
# df /tmp/rw  
Filesystem     1K-blocks  Used Available Use% Mounted on
none             1031128    24   1031104   1% /tmp/rw

/tmp/rw 中沒有文件,但分配了 24 個塊。仍然不是什麼大問題。

我可以將文件寫入 aufs,它將儲存在 /tmp/rw 的 tmpfs 中:

# dd if=/dev/zero of=/tmp/mnt/test bs=1024 count=100
100+0 records in
100+0 records out
102400 bytes (102 kB) copied, 0.000343903 s, 298 MB/s
# du -sk /tmp/rw
100 /tmp/rw
# df /tmp/rw
Filesystem     1K-blocks  Used Available Use% Mounted on
none             1031128   128   1031000   1% /tmp/rw

請注意使用情況統計數據的變化。du正如預期的那樣,顯示添加了 100kB,但df輸出中的“已使用”值增加了 104 個塊。

當我刪除文件時:

# du -sk /tmp/rw   
0   /tmp/rw
# df /tmp/rw
Filesystem     1K-blocks  Used Available Use% Mounted on
none             1031128    28   1031100   1% /tmp/rw

失去了四個塊。

當我重複ddandrm命令幾次時,我得到:

# df /tmp/rw                                         
Filesystem     1K-blocks  Used Available Use% Mounted on
none             1031128    36   1031092   1% /tmp/rw

越來越多的 tmpfs 塊消失了,我不知道在哪裡……

在我做同樣的事情的地方——dd直接rm在 /tmp/rw 上沒有任何東西失去。解除安裝aufs後,tmpfs上失去的空間被恢復了。所以,至少,我知道應該歸咎於 aufs,而不是 tmpfs。

發生了什麼

知道該怪什麼,我在 aufs-users 郵件列表中描述了我的問題。我很快收到了第一個答案。JR Okajima 的一位幫助我解釋了失去的 tmpfs 塊發生了什麼。

確實,這是一個已刪除的文件。它沒有被lsof任何/proc/<pid>/*使用者空間程序打開或映射,因此它沒有被任何使用者空間程序打開或映射。該文件,“xino 文件”,是 aufs 的外部 inode 編號轉換錶,由核心 aufs 模組在內部使用。

可以從 sysfs 讀取文件的路徑:

# cat /sys/fs/aufs/si_*/xi_path         
/tmp/rw/.aufs.xino

但是,由於文件被刪除,無法直接看到:

# ls -l /tmp/rw/.aufs.xino
ls: cannot access /tmp/rw/.aufs.xino: No such file or directory

不過,可以從 debugfs 中讀取有關其大小和其他特殊 aufs 文件大小的資訊:

# for f in /sys/kernel/debug/aufs/si_8c8d888a/* ; do echo -n "$f: " ; cat $f ; done 
/sys/kernel/debug/aufs/si_8c8d888a/xi0: 1, 32x4096 132416
/sys/kernel/debug/aufs/si_8c8d888a/xi1: 1, 24x4096 626868
/sys/kernel/debug/aufs/si_8c8d888a/xib: 8x4096 4096
/sys/kernel/debug/aufs/si_8c8d888a/xigen: 8x4096 88

詳細資訊在aufs 手冊頁中進行了描述。

解決方案

“xino 文件”可以通過以下方式手動截斷:

# mount -o remount,itrunc_xino=0 /tmp/mnt

在掛載 aufs 時,可以使用 trunc_xino 選項請求自動截斷 xino 文件:

# mount -t aufs -n -o "br:/tmp/rw:/usr,trunc_xino" none "/tmp/mnt"

我仍然不知道它如何影響文件系統性能,或者這是否真的能解決我在生產中的 tmpfs 空間不足問題……但我學到了很多東西。

引用自:https://serverfault.com/questions/445445