1

I'm trying to get notification of the state of a problematic sshfs mount

I have tried two bash scripts

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

and

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

To test, I'm running the following sequence, but neither of these scripts is responding.

 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
Stephen Boston
  • 2,178
  • 4
  • 32
  • 55
  • You could run inotify on a remote file, but inotify does not work with sshfs (currently). What is the problem you are trying to debug? There might be an alternative. – Eduardo Trápani Mar 03 '20 at 19:33
  • 1
    @EduardoTrápani I don't think that the OP want to be notified of changes to files located on a sshfs, but of changes to the state of a ssh mount. inotify not working with sshfs has nothing to do with it. –  Mar 03 '20 at 20:35
  • @mosvy I know. One way to see if the mount is not working is to follow a file in said mount. There is even an event for that in inotifywait: unmount. It could have been a workaround to indirectly know if the mount was no longer working, that's why I mentioned it. – Eduardo Trápani Mar 04 '20 at 12:39

1 Answers1

4

inotify doesn't work with the proc filesystem. Though they may look as regular files, the files in the proc filesystem don't contain any static data -- the kernel makes up the data on the fly when you read them. For instance, /proc/mounts => /proc/self/mounts has the size 0, but when you read it, it magically happens to contain something.

But /proc/self/mounts and /proc/self/mountinfo are pollable -- you can select(2) or poll(2) on it for an exceptional condition. According to the proc(5) manpage:

/proc/[pid]/mounts (since Linux 2.4.19)

This file lists all the filesystems currently mounted in the process's mount namespace (see mount_namespaces(7)). The format of this file is documented in fstab(5).

Since kernel version 2.6.15, this file is pollable: after opening the file for reading, a change in this file (i.e., a filesystem mount or unmount) causes select(2) to mark the file descriptor as having an exceptional condition, and poll(2) and epoll_wait(2) mark the file as having a priority event (POLLPRI).

[the same holds true for /proc/[pid]/mountinfo]

I don't think there's any way to do that from the shell. You can do it from perl, though:

#! /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";
}

A more useful example, which also shows what changed in /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;
}