I\'m using Linux Inotify to detect FS events on my program.
How could I be notified when a device is mounted on a monitored directory?
If you don't mind lots of false alarms, you might be able to watch for close_nowrite
on /etc/fstab
. . Watching /etc/mtab
, /proc/mounts
, etc. doesn't work for me.
I don't think you can do it with inotify
. Here is the method though:
"ACTION"
is not "mount"
."mount"
action.On modern Linux systems /etc/mtab often points to /proc/self/mounts:
$ ls -l /etc/mtab
lrwxrwxrwx 1 root root 12 Sep 5 2013 /etc/mtab -> /proc/mounts
$ ls -l /proc/mounts
lrwxrwxrwx 1 root root 11 Jul 10 14:56 /proc/mounts -> self/mounts
proc(5) manpage says that you don't really need to use inotify for this file, it is pollable:
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 readable, and poll(2) and epoll_wait(2) mark the file as having an error condition.
Was wondered why inotify not works on /etc/mtab and found this manpage.
inotify only tells you about unmounts, and uevents no longer tells you about mount/unmount.
The way to do is to poll on /proc/mounts, read in the contents, and keep track of the mounts you've seen, and then reparse when the poll wakes up. The poll will wake up on ERR/PRI when any filesystem is mounted or unmounted.
#include <fcntl.h>
#include <errno.h>
#include <poll.h>
#include <unistd.h>
#include <stdio.h>
int main()
{
int fd;
struct pollfd ev;
int ret;
ssize_t bytesread;
char buf[8192];
fd = open("/proc/mounts", O_RDONLY);
printf("########################################\n");
while ((bytesread = read(fd, buf, sizeof(buf))) > 0)
write(1, buf, bytesread);
do {
ev.events = POLLERR | POLLPRI;
ev.fd = fd;
ev.revents = 0;
ret = poll(&ev, 1, -1);
lseek(fd, 0, SEEK_SET);
if (ev.revents & POLLERR) {
printf("########################################\n");
while ((bytesread = read(fd, buf, sizeof(buf))) > 0)
write(1, buf, bytesread);
}
} while (ret >= 0);
close(fd);
return 0;
}
The above code just prints out the mount points on startup, and then on any mount/unmount. It's up to you to "diff" them to find out what got added/removed.
Note, all these techniques has been both unstable and/or broken in past Linux versions. It all got stable around the end of Linux 2.6.35 (or maybe a bit earlier).
EDIT: Update to be less than 5 years obsolete
If you're on anything but the most ancient of systems, libudev is what you want for the first step.
If you're on something from this decade, udisks will do all of this for you, too. You'd need to watch the org.Freedesktop.DBus.ObjectManager interface on /org/freedesktop/UDisks2 to see when new filesystems turn up.