Inotify, watch your filesystem

Wed 05 November 2008 by Thejaswi Puthraya

Inotify, watch your filesystem

Inotify, is a Linux kernel system call that helps you monitor the file system for various events.

Here is how I use it:

  • My blog basically consists of Restructured Text files in a particular directory. I use the Xapian indexer to provide the search facility on my site. Whenever a particular file is uploaded to the directory, the search index has to be rebuilt and the new blog post has to be updated. Also a ping request has to be sent to Google.

    Note

    • All these are possible within Django using signals and the sitemaps plugin, but my site doesn't use Django for uploading the files to the blog.

I could use cron to run periodically but it is going to have the following drawbacks:

  • Not going to update the index instantaneously.
  • If there's no change in the blogs, the index keeps getting updated unnecessarily.

Inotify keeps monitoring the blogs directory for a file-system event. When that occurs, it triggers the search index to be rebuilt and pings google that the blog has been updated.

Here's a sample script that uses Epoll (an IO notification facility).

 #include <sys/inotify.h>
 #include <sys/epoll.h>
 #include <unistd.h>
 #include <stdio.h>

 int main()
 {
   int fd, wd, efd, cfg, ret, shret;
   pid_t pid;
   struct epoll_event ev;

   fd = inotify_init();
   if (fd < 0)
     perror("Could not initialize inotify");

   wd = inotify_add_watch(fd, "/path/to/monitored/", IN_MODIFY);
   if (wd < 0)
     perror("Could not initialize the watch descriptor");

   efd = epoll_create(sizeof(fd));
   if (efd < 0)
     perror("Could not initialized epoll file descriptor");

   ev.events = EPOLLIN|EPOLLOUT|EPOLLET;
   cfg = epoll_ctl(efd, EPOLL_CTL_ADD, fd, &ev);
   if (cfg < 0)
     perror("Could not configure the epoll interface");

   while(1)
   {
     ret = epoll_wait(efd, &ev, 100, 86400000);
     if (ret > 0)
     {
       shret = execv("/path/to/the/indexer", NULL);
       if (shret < 0)
         perror("Feed Generator Script execution failed");
     }
     else if (ret < 0)
     {
       perror("Error in the polling");
       break;
     }
     else
     {
       perror("Timed Out");
       break;
     }
   }

   return 0;
}

This C program is run once a day (as against periodically every couple of hours) through cron and it keeps listening all the day for changes in the filesystem. If there was no change, the script times out else it triggers the indexer.

Note

  • I have come across the inotify-tools project only recently and is really awesome.