2016年11月9日 星期三

iNotify 筆記

iNotify 可用來監控目錄或是檔案變化,包含 read/write/add/delete 等等,Linux 2.6.13 之後導入此機制。可以用來判斷是否有人將惡意軟體下載到某個目錄(例如:mirai),或是與rsync結合,當作 Linux 系統的檔案同步機制。

此篇記錄此函數的使用方法。

iNotify 共提供三個 API
  • int inotify_init(void)
  • int inotify_add_watch(int fd, const char* pathname, int mask)
  • int inotify_rm_watch(int fd, int wd)
inotify_init() 初始化完成後,可得到一個file descriptor。
該descriptor 可經由 read()、select()、epoll來操作,與多數的file descriptor無異,同時支援blocking、non-blocking IO。
當有任何事件觸發時,系統會將事件寫入在 inotify_event 結構中,供使用者存取
struct inotify_event {
int      wd;       /* Watch descriptor */
uint32_t mask;     /* Mask of events */
uint32_t cookie;   /* Unique cookie associating related events */
uint32_t len;      /* Size of name field */
char     name[];   /* Optional null-terminated name */
};

程式範例
#define EVENT_SIZE  ( sizeof (struct inotify_event) )
#define BUF_LEN     ( 1024 * ( EVENT_SIZE + 16 ) )

int fd, wd, length, i = 0;
char buffer[BUF_LEN];

fd = inotify_init();
wd = inotify_add_watch( fd, "/home/strike", 
      IN_MODIFY | IN_CREATE | IN_DELETE );
length = read( fd, buffer, BUF_LEN );  // blocked before event occurs
while ( i < length ) {
 struct inotify_event *event = ( struct inotify_event * ) &buffer[ i ];
 if ( event->len ) {
  if ( event->mask & IN_CREATE ) { // created
  }
  else if ( event->mask & IN_DELETE ) { // deleted
  }
  else if ( event->mask & IN_MODIFY ) { // modified
  }
 }
 i += EVENT_SIZE + event->len;
}

inotify_rm_watch( fd, wd );
close( fd );


參考資料:
  1. http://www.ibm.com/developerworks/cn/linux/l-ubuntu-inotify/
  2. http://man7.org/linux/man-pages/man7/inotify.7.html