Question

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?

Was it helpful?

Solution

I don't think you can do it with inotify. Here is the method though:

  1. Read uevents from kernel via a Netlink socket and filter out those where "ACTION" is not "mount".
  2. Read and parse "/proc/mounts" when you get an event with a "mount" action.
  3. Find a record for a mount point with device that was just mounted and filter it out if it's not the directory you are watching.

OTHER TIPS

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.

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.

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.

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).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top