How to monitor and notify filesystem changes in Linux (using inotify/inotify-tools/incrond)

inotify@man/inotify@wiki is a kernel feature to monitor file system changes, replaces Dnotify.

  • Installing
# you must have a Linux machine with kernel 2.6.13 or later
$ uname -a
Linux ubuntu-desktop 2.6.24-19-generic #1 SMP ... i686 GNU/Linux
  • Using c-apiI@ibm: create a file descriptor (inotify_init), attach one or more watches (a watch is a path and set of events) using inotify_add_watch, and use the read/blocking or select/non-blocking method to receive event information from the descriptor.
#include <sys/inotify.h>

#define EVENT_SIZE  ( sizeof (struct inotify_event) )
#define BUF_LEN     ( 1024 * ( EVENT_SIZE + 16 ) )

int main( int argc, char **argv ) 
{
  int fd, wd, len, i = 0;
  char buffer[BUF_LEN];

  fd = inotify_init();
  wd = inotify_add_watch( fd, "file", IN_MODIFY | IN_CREATE | IN_DELETE );
  len = read( fd, buffer, BUF_LEN );  

  while ( i < length ) {
    struct inotify_event *event = ( struct inotify_event * ) &buffer[ i ];
    if ( event->len ) {
      if ( event->mask & IN_CREATE ) {
        printf( "The %s %s was created.n", (event->mask & IN_ISDIR ? "directory" : "file"), event->name );
      }
      else if ( event->mask & IN_DELETE ) {
        printf( "The %s %s was deleted.n", (event->mask & IN_ISDIR ? "directory" : "file"), event->name );
      }
      else if ( event->mask & IN_MODIFY ) {
        printf( "The %s %s was modified.n", (event->mask & IN_ISDIR ? "directory" : "file"), event->name );
      }
    }
    i += EVENT_SIZE + event->len;
  }

  inotify_rm_watch(fd, wd);
  close(fd);
  exit(0);
}

Same but using select/non-blocking

int return_value;
fd_set descriptors;
struct timeval time_to_wait;

FD_ZERO ( &descriptors );
FD_SET( ..., &descriptors );
FD_SET ( fd, &descriptors );
...
time_to_wait.tv_sec = 3;
time.to_waittv_usec = 0;

return_value = select ( fd + 1, &descriptors, NULL, NULL, &time_to_wait);

if ( return_value < 0 ) {
    /* Error */
}

else if ( ! return_value ) {
    /* Timeout */
}

else if ( FD_ISSET ( fd, &descriptors ) ) {
    /* Process the inotify events */
}
$ sudo apt-get install inotify-tools | sudo yum install inotify-tools

# watching the '$HOME' directory for 60 seconds for access and modify and print stats
$ inotifywatch -v -e access -e modify -t 60 -r $HOME
Watches established.

# wait for log file changes
$ export F=/var/log/syslog; while inotifywait -e modify $F; do tail -n1 $F; done

# custom output recursive changes to $HOME
$ inotifywait -m -r --format '%:e %f' $HOME
$ sudo yum install incron | sudo apt-get install incron
$ service incrond start ; chkconfig incrond on

# edit '/etc/incron.conf' or '/etc/incron.d/'
$ incrontab -e

<directory> <file change mask> <command or action> options
/var/www/html IN_CREATE /root/scripts/backup.sh
/sales IN_DELETE /root/scripts/sync.sh
/var/named/chroot/var/master IN_CREATE,IN_ATTRIB,IN_MODIFY /sbin/rndc reload
/tmp IN_ALL_EVENTS logger "/tmp action for $# file"

# changes are logged
$ sudo tail -f /var/log/messages
Jul 17 18:39:25 vivek-desktop logger: "/tmp action for foo file"
Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s