inotifywaitが/proc/mountsの変更に応答しません。

inotifywaitが/proc/mountsの変更に応答しません。

問題のあるsshfsのインストール状況に関する通知を受け取ろうとしています。

2つのbashスクリプトを試しました

while inotifywait -e modify /proc/mounts; do
  echo "modified" 
done

そして

inotifywait -m /proc/mounts |
while read event; do
  echo $event
done

テストのために次のシーケンスを実行していますが、どのスクリプトも応答しません。

 stephen@asus:~/log$ sudo umount /mnt/lexar
 stephen@asus:~/log$ sshfs michigan:/home/stephen/ /mnt/lexar
 stephen@asus:~/log$ sudo umount /mnt/lexar
 stephen@asus:~/log$ sshfs michigan:/home/stephen/ /mnt/lexar
 stephen@asus:~/log$ grep lexar /proc/mounts
 michigan:/home/stephen/ /mnt/lexar fuse.sshfs rw,nosuid,nodev,relatime,user_id=1000,group_id=1000 0 0
 stephen@asus:~/log$ sudo umount /mnt/lexar
 stephen@asus:~/log$ grep lexar /proc/mounts

ベストアンサー1

inotifyprocファイルシステムには適用できません。通常のファイルのように見えますが、procファイルシステムのファイルには静的データは含まれていません。カーネルはファイルを読み込むと動的にデータを生成します。たとえば、/proc/mounts=>/proc/self/mountsのサイズは0ですが、それを読むと魔法的に何かが含まれている場合があります。

しかし、/proc/self/mountsそして/proc/self/mountinfoポーリング可能- 特別な状況で使用select(2)できます。poll(2)~によるとproc(5)マンページ:

/proc/[pid]/mounts(Linux 2.4.19以降)

このファイルには、現在のプロセスのマウント名前空間にマウントされているすべてのファイルシステムが一覧表示されます(参考資料を参照mount_namespaces(7))。このファイルの形式はで説明されていますfstab(5)

カーネルバージョン2.6.15以降、このファイルはポーリング可能です。ファイルを読み取るために開いた後にこのファイルが変更されると(ファイルシステムのマウントまたはアンマウントなど)、select(2)ファイル記述子は例外を持つとマークされます。ファイルを優先順位イベント()と見なします。poll(2)epoll_wait(2)POLLPRI

[これは次にも適用されます/proc/[pid]/mountinfo]

シェルでこれを行う方法はないと思います。ただし、以下でこれを行うことができますperl

#! /usr/bin/perl
use strict;
my $mf = "/proc/self/mountinfo";
open my $mh, "<$mf" or die "open <$mf: $!";
vec(my $ebits, $mh->fileno, 1) = 1;
while(1){
        select(undef, undef, my $e = $ebits, undef) == -1 and die "select: $!";
        print "some mount or umount happened\n";
}

より有用な例は次のとおりです。以下から変更されました/proc/self/mountinfo:

#! /usr/bin/perl
use strict;
my $mf = "/proc/self/mountinfo";
open my $mh, "<$mf" or die "open <$mf: $!";
vec(my $ebits, $mh->fileno, 1) = 1;
sub read_mounts {
        seek $mh, 0, 0 or die "seek: $!";
        my ($h, $i); $$h{$_} = ++$i while <$mh>; return $h;
}
for(my ($old, $new) = read_mounts;; $old = $new) {
        select undef, undef, my $e = $ebits, undef or die "select: $!";
        $new = read_mounts;
        for(keys %$new){
                if(exists $$old{$_}){ delete $$old{$_} }
                else{ print '+ ', $_ }
        }
        print '- ', $_ for keys %$old;
}

おすすめ記事