Tôi gặp phải vấn đề này và không có câu trả lời nào trong số này cho bạn câu trả lời là " mỗi quy trình hiện đang sử dụng bao nhiêu đồng hồ ?" Tất cả các lớp lót đều cung cấp cho bạn bao nhiêu trường hợp được mở, đó chỉ là một phần của câu chuyện và các công cụ theo dõi chỉ hữu ích khi thấy đồng hồ mới được mở.
TL; DR: Điều này sẽ giúp bạn có một tệp với danh sách các inotify
trường hợp mở và số lượng đồng hồ họ có, cùng với các pids và nhị phân sinh ra chúng, được sắp xếp theo thứ tự giảm dần theo số lượng xem:
sudo lsof | awk '/anon_inode/ { gsub(/[urw]$/,"",$4); print "/proc/"$2"/fdinfo/"$4; }' | while read fdi; do count=$(sudo grep -c inotify $fdi); exe=$(sudo readlink $(dirname $(dirname $fdi))/exe); echo -e $count"\t"$fdi"\t"$exe; done | sort -nr > watches
Đó là một quả bóng lớn lộn xộn, vì vậy đây là cách tôi đến đó. Để bắt đầu, tôi đã chạy một tail
tệp thử nghiệm và xem fd của nó đã mở:
joel@gladstone:~$ tail -f test > /dev/null &
[3] 22734
joel@opx1:~$ ls -ahltr /proc/22734/fd
total 0
dr-xr-xr-x 9 joel joel 0 Feb 22 22:34 ..
dr-x------ 2 joel joel 0 Feb 22 22:34 .
lr-x------ 1 joel joel 64 Feb 22 22:35 4 -> anon_inode:inotify
lr-x------ 1 joel joel 64 Feb 22 22:35 3 -> /home/joel/test
lrwx------ 1 joel joel 64 Feb 22 22:35 2 -> /dev/pts/2
l-wx------ 1 joel joel 64 Feb 22 22:35 1 -> /dev/null
lrwx------ 1 joel joel 64 Feb 22 22:35 0 -> /dev/pts/2
Vì vậy, 4 là fd chúng tôi muốn điều tra. Chúng ta hãy xem những gì trong fdinfo
đó:
joel@opx1:~$ cat /proc/22734/fdinfo/4
pos: 0
flags: 00
mnt_id: 11
inotify wd:1 ino:15f51d sdev:ca00003 mask:c06 ignored_mask:0 fhandle-bytes:8 fhandle-type:1 f_handle:1df51500a75e538c
Trông giống như một mục cho đồng hồ ở phía dưới!
Hãy thử một cái gì đó với nhiều đồng hồ hơn, lần này với inotifywait
tiện ích, chỉ cần xem bất cứ thứ gì có trong /tmp
:
joel@gladstone:~$ inotifywait /tmp/* &
[4] 27862
joel@gladstone:~$ Setting up watches.
Watches established.
joel@gladstone:~$ ls -ahtlr /proc/27862/fd | grep inotify
lr-x------ 1 joel joel 64 Feb 22 22:41 3 -> anon_inode:inotify
joel@gladstone:~$ cat /proc/27862/fdinfo/3
pos: 0
flags: 00
mnt_id: 11
inotify wd:6 ino:7fdc sdev:ca00003 mask:fff ignored_mask:0 fhandle-bytes:8 fhandle-type:1 f_handle:dc7f0000551e9d88
inotify wd:5 ino:7fcb sdev:ca00003 mask:fff ignored_mask:0 fhandle-bytes:8 fhandle-type:1 f_handle:cb7f00005b1f9d88
inotify wd:4 ino:7fcc sdev:ca00003 mask:fff ignored_mask:0 fhandle-bytes:8 fhandle-type:1 f_handle:cc7f00006a1d9d88
inotify wd:3 ino:7fc6 sdev:ca00003 mask:fff ignored_mask:0 fhandle-bytes:8 fhandle-type:1 f_handle:c67f00005d1d9d88
inotify wd:2 ino:7fc7 sdev:ca00003 mask:fff ignored_mask:0 fhandle-bytes:8 fhandle-type:1 f_handle:c77f0000461d9d88
inotify wd:1 ino:7fd7 sdev:ca00003 mask:fff ignored_mask:0 fhandle-bytes:8 fhandle-type:1 f_handle:d77f00000053c98b
Aha! Thêm mục! Vì vậy, chúng ta nên có sáu điều /tmp
sau đó:
joel@opx1:~$ ls /tmp/ | wc -l
6
Xuất sắc. Cái mới của tôi inotifywait
có một mục trong fd
danh sách của nó (đó là những gì mà một lớp lót khác ở đây đang đếm), nhưng sáu mục trong fdinfo
tệp của nó . Vì vậy, chúng ta có thể tìm ra có bao nhiêu đồng hồ một fd nhất định cho một quy trình nhất định đang sử dụng bằng cách tham khảo fdinfo
tệp của nó . Bây giờ để kết hợp nó với một số ở trên để lấy danh sách các quy trình đã thông báo cho đồng hồ mở và sử dụng nó để đếm các mục trong mỗi mục fdinfo
. Điều này tương tự như ở trên, vì vậy tôi sẽ chỉ đổ một lớp lót ở đây:
sudo lsof | awk '/anon_inode/ { gsub(/[urw]$/,"",$4); print "/proc/"$2"/fdinfo/"$4; }' | while read fdi; do count=$(sudo grep -c inotify $fdi); echo -e $count"\t"$fdi; done
Có một số thứ dày ở đây, nhưng điều cơ bản là tôi sử dụng awk
để xây dựng một fdinfo
đường dẫn từ lsof
đầu ra, lấy số pid và fd, tước cờ u / r / w từ cái sau. Sau đó, với mỗi fdinfo
đường dẫn được xây dựng , tôi đếm số lượng inotify
dòng và xuất số đếm và pid.
Sẽ thật tuyệt nếu tôi có những quy trình mà các pids này thể hiện ở cùng một nơi, phải không? Tôi đã nghĩ như vậy. Vì vậy, trong một chút đặc biệt lộn xộn, tôi quyết định gọi dirname
hai lần trên fdinfo
đường dẫn để nhận gói /proc/<pid>
, thêm /exe
vào nó, và sau đó chạy readlink
trên đó để lấy tên exe của quy trình. Cũng ném nó vào đó, sắp xếp nó theo số lượng đồng hồ và chuyển hướng nó đến một tệp để giữ an toàn và chúng tôi nhận được:
sudo lsof | awk '/anon_inode/ { gsub(/[urw]$/,"",$4); print "/proc/"$2"/fdinfo/"$4; }' | while read fdi; do count=$(sudo grep -c inotify $fdi); exe=$(sudo readlink $(dirname $(dirname $fdi))/exe); echo -e $count"\t"$fdi"\t"$exe; done | sort -n > watches
Chạy mà không cần sudo để chỉ hiển thị các quy trình tôi đã khởi chạy ở trên, tôi nhận được:
joel@gladstone:~$ cat watches
6 /proc/4906/fdinfo/3 /usr/bin/inotifywait
1 /proc/22734/fdinfo/4 /usr/bin/tail
Hoàn hảo! Danh sách các quy trình, fd và số lượng đồng hồ mỗi chiếc đang sử dụng, đó chính xác là những gì tôi cần.
find /proc/*/fd/* -type l -lname 'anon_inode:inotify' -print