列出 inotify
實例正在監視的文件
我有一個小腳本,列出了每個程序的 inotify 監視數量。這通常會讓我得到我想要的,但現在我想知道正在觀看哪些文件。我認為這是可能的,並且inotify 監視對應於 inotify 實例正在監視的文件?
我還假設我可以建立在我目前在該腳本中擁有的內容之上。例如,
sudo find /proc/*/fd -lname anon_inode:inotify | cut -d "/" -f 3
給我一個帶有
inotify
文件描述符的程序列表。如果我查看其中一個文件描述符的資訊,我會得到我假設的文件句柄/監視列表:$ sudo cat /proc/50679/fdinfo/19 pos: 0 flags: 00 mnt_id: 15 inotify wd:8 ino:640001 sdev:800001 mask:3cc ignored_mask:0 fhandle-bytes:8 fhandle-type:1 f_handle:01006400feaad211 inotify wd:7 ino:a08da sdev:800001 mask:3cc ignored_mask:0 fhandle-bytes:8 fhandle-type:1 f_handle:da080a0094019e8f inotify wd:6 ino:840003 sdev:800001 mask:3cc ignored_mask:0 fhandle-bytes:8 fhandle-type:1 f_handle:030084005ae9e3df inotify wd:5 ino:840002 sdev:800001 mask:3cc ignored_mask:0 fhandle-bytes:8 fhandle-type:1 f_handle:020084000d506c1f inotify wd:4 ino:840001 sdev:800001 mask:3cc ignored_mask:0 fhandle-bytes:8 fhandle-type:1 f_handle:01008400e47bab26 inotify wd:3 ino:32004e sdev:800001 mask:3cc ignored_mask:0 fhandle-bytes:8 fhandle-type:1 f_handle:4e003200488122df inotify wd:2 ino:320001 sdev:800001 mask:3cc ignored_mask:0 fhandle-bytes:8 fhandle-type:1 f_handle:01003200545a9f32 inotify wd:1 ino:2 sdev:800001 mask:3cc ignored_mask:0 fhandle-bytes:8 fhandle-type:1 f_handle:0200000000000000
我希望我能找出
f_handle:01003200545a9f32
對應的文件,基本上將f_handle
/proc/../fdinfo/ 中的 a 轉換為文件名。
我不知道處理該
f_handle
領域的標準工具。使用系統呼叫會很方便open_by_handle_at(2)
,但無論如何該欄位可能並不總是有效的。例如,核心nfsd
不提供它。但是,Linux 中任何文件的完整座標仍然是舊設備號和 inode 號,它們在
sdev
和ino
欄位中報告。這只是解碼它們的問題。這兩個值(目前)以十六進製表示法表示。您可以按
ino
原樣使用,只需將其轉換為十進製表示法即可。
sdev
另一方面,該值需要一些解碼,因為您需要將其拆分為傳統的“主要和次要”設備編號。請注意,即使駐留在不受實際塊設備支持的文件系統中的文件仍然帶有唯一的偽設備編號,該編號會在該sdev
欄位中報告。假設該
sdev
欄位是根據 Linux 所謂的“巨大編碼”進行編碼的,該編碼使用 20 位(而不是 8 位)作為次要數字,按位說法,主要數字是.sdev >> 20
而次要數字是sdev & 0xfffff
. 或者使用外行文本處理方法,次要數字是最右邊(最多)5 個十六進制數字,而主要數字是最後 5 個十六進制數字之前的所有內容。如果少於 5 個十六進制數字,則主要數字只是0
.一旦獲得了主要和次要,您就可以在目標程序的
mountinfo
文件中查找它們。在你的例子中,那將是/proc/50679/mountinfo
. 具體來說,您要尋找一條帶有這樣的major:minor
對的行作為第三個欄位。找到的行的第五個find
欄位是您尋找所需文件/目錄的最終路徑。注意:
inotify
in 一行得到的major 和minor/proc/*/fdinfo/*
用十六進製表示,inmountinfo
用十進製表示,所以在in 中搜尋前需要先轉換一下mountinfo
。**注意:**如果自身或 <space>、<newline>、<tab> 字元是路徑的一部分,則其中的第五個欄位
mountinfo
可能包含\
- 轉義的八進制序列。\
這意味著空格被編碼為\040
, a\
as\134
,依此類推。您可以通過例如將該路徑提供給printf(1)
自己的%b
說明符來取消轉義。**注意:**為了考慮命名空間(即容器),您需要在目標程序
find
所在的掛載命名空間中執行最終命令,因此例如(例如):nsenter -mt 50679 find "$unescaped_path" -inum "$decimal_ino" -print -quit