Linux 系统中使用 inotify 监视文件或目录的改变 - yanbin's Blog

Linux 系统中使用 inotify 监视文件或目录的改变

yanbin posted @ 2015年3月31日 23:32 in Programming with tags linux programming inotify , 7159 阅读

0.注意事项

int inotify_init();
int inotify_add_watch(int fd, const char *name);
int inotify_rm_watch(int fd, int wd);
int inotify_init1(int mask);
 
这些是一系列的 linux 系统调用;
前三个是 linux 2.6.13 引入的, 最后一个是 2.6.27 引入的。

但是一些 C libray(C 语言实现库), 并没有定义这些系统调用的封装。
可以用 syscall(__NR_inotify_init); 这样的形式调用。
__NR_inotify_init 是系统调用号,可以在 unistd.h 中看到。

有些 SDK 中的内核配置没有默认的选定对 inotify 的支持。
可以在 linux 配置中的 kernel setup:
fs-->
   [] support inotify for user space
选上对些系统调用的支持。

如果内核没有对这些系统调用的支持,
int fd = syscall(inotify_init) 总是返回 89,
read(fd, buff, sizeof(buff)) 会返回 -1, errno 被设置为 "Bad file descriptor"。

inotify 会监视目录下所有文件。
inotify 并不自动的递归监视目录下的子目录,需要程序员自己完成这样的工作。

 

1.简介

使用这些 API 可以监视文件系统的 events.
当文件或者目录有改变时,内核产生 inotify events, 用户使用这些 API 获取关注的 events.
不同于陈旧的 dnotify API, inotify API 既可以监视 files 也可以监视 directories.
监视一个目录,不仅可以获取目录自身改变的 event(e.g. 从目录移除文件),也可以监视目录内文件内容改变产生的 event.
另外:称这些函数为 API 是因为它封装了 system call。每一个函数对应一个 system call. 


2.每个 API 的作用与使用方式。

inotify_init(2) 用来获取一个文件描述符,这个文件描述符是一个 inotify instance 的引用。
用户通过这个实例建立了一条从内核获取文件系统 events 的渠道或者说连接。
每个 inotify 实例中维护着一个 watch list, 其中的每个 item 对应一个文件/目录。

获取 event 的方式是 read() inotify_init(2) 返回的文件描述符。
若这个文件描述符没有设置为 NONBLOCK, read() 会阻塞,read() 返回时,就是文件系统 events 到来了。

既然类似于「连接」当然就可以应用 select() or poll() 于 inotify 文件描述符了。
这也正是 inotify 系统的优点之一。

当与 inotify 实例关联的文件描述符关闭时,内核释放与该实例相关的资源,并且释放该实例。
FIXE: 为什么 man 手册中讲:所有引用这个 inotify 实例的文件描述(s)? 一个 inotify 实例为什么会有多个
文件描述符引用?
(a)
这个文件描述符号可能会被 dup() 多次。
(b)文件描述符没有设置为 CLOEXEC, 子进程继承了父进程的文件描述符。

inotify_init(2) 返回的文件描述符可以使用 fcntl(2) 设置为 nonblock 以及 close-on-exec.
inotify_init1(2) 则提供了便利,在返回文件描述符之前,将它上设置为 nonblock 和/或 close-on-exec;
inotify_init1(2) 接受一个 flags 参数指定为 IN_NONBLOCK, IN_CLOEXEC, 或者 IN_NONBLOCK | IN_CLOEXEC;
flags 参数为 0 时它与 inotify_init(2) 别无二致。

inotify_add_watch(2) 用于向一个 inotify 实例的 watch list 追加 item,或用于改变某个 item.
指定期望监视的文件或目录——使用绝对或相对路径——, 指定期望关注的文件系统 events。若指定的文件或目录不在 inotify 实例的
watch list 之中,内核会创建一个 watch item 追加至 watch list 之中。
若指定的文件或者目录已经存在于 wach list 中,inotify_add_watch(2) 直接返会与文件或目录对应的文件描述符。
若指定的 events 不同与之前的,则重新设置对文件或目录的监视,改变或追加期望获得的 events.
NOTE: 这一改变不会清除已经产生却没有读取的 events.

inotify_watch() 返回的 watch fd 的用处之一: 指定给 inotify_rm_watch() 从 inotify 实例的 watch list
移除某个 item, 从而移除对某个文件或目录的监视。
也就是说,可以删除或更新某个 watch item,从而移除或更新对某个文件或目录的引用。


3.使用 bit mask 标识 inotify event, 列表如下:

  IN_ACCESS                      文件被访问,有读——read(2)——操作。例如: cat filename.txt
  IN_ATTRIB                        文件元数据发生改变,例如:
                                               permissions, timestamps, extended attributes,link count(since Linux2.6.25), UID, GID, 等等。
  IN_CLOSE_WRITE            文件关闭,并且发生写操作。例如: echo "add data" >> filename.txt
  IN_CLOSE_NOWRITE       文件关闭,但是没有发生写操作。例如:open(filename, O_WRONLY); close(fd);
  IN_CREATE                      目录中有新的文件或目录创建。例如: touch dirname/filename
  IN_DELETE                      目录中有文件被删除。例如:rm dirname/filename
  IN_DELETE_SELF            监视的文件或目录本身被删除。
  IN_MODIFY                      文件发生改变。FIXME: 什么改变会引发这个 event? 写操作会吗?
  IN_MOVE_SELF               监视的文件或目录本身被移动。
  IN_MOVED_FROM           从目录中移出一个文件或目录。
  IN_MOVED_TO                移动一个文件或目录到目录中。
  IN_OPEN                        文件打开操作发生。
   
指定给 inotify_add_watch(2) 的第二个参数,就是上面的一个或多个 bit mask(s);
从而可以得到 intofiy events.

4.inotify event 数据结构:

  struct inotify_event {
      int wd; /* watch 文件描述符 */
      uint32_t mask; /* Mask of events */
      uint32_t cookie;
      uint32_t len /* size of name filed */
      char name[]; /* optional null-terminated name */
  };


5.解析 events.
使用 read() 读取 events 数据到 buff 中,从 buffer 中解析出 events.
NOTE:
1)event->len 是 size of name, 不是 size of event;
2)read() 不保证完整的读取了最后一个 event, 甚至不保证完整的读取了一个 event;
需要比较 size of buff 中剩余有效数据 与 sizeof(inotify_event);
然后再比较 size of buff 中剩余有效数据 与 sizeof(inotify_event) + event->len;
3)读取 events 到 buff 中再解析,为了尽可能一次性读取更多的 event;

#define BUFF_SIZE         ((sizeof(struct inotify_event) + NAME_MAX + 1)*5)
#define MIN_EVENT_SIZE    (sizeof(struct inotify_event)
char buff[BUFF_SIZE];
char pos = buff;
ssize_t readn;
ssize_t data_size;
int index;
const struct inotify_event *event = NULL;

for (; ;) {
    int nready;
    int maxfd = watchfd + 1;
    fd_set readset;

    FD_ZERO(readset);
    FD_SET(watchfd, &maxfd);

    nready = select(maxfd, &readset, NULL, NULL, NULL);
    if (nready < 0) {
        perror("select");
    } else if (FD_ISSET(watchfd, &readset)) {
__read_data__:
        readn = read(watchfd, pos, sizeof(buff)-(pos-buff));
        if (readn == -1) {
            if (errno == EGAIN) {
                goto __read_data__;
            } else {
                goto __error__;
            }
        } else {
            data_size = readn + (pos - buff);
            pos = buff;
            index = 0;
            while (index < data_size) {
                event = (const struct inotify_event *)&pos[index];
                ssize_t size = sizeof(*event) + event->len;
                ssize_t remain = data_size - index;
                if (remain < size) goto __incomplete__;

                struct inotify_event *eventobj = malloc(size);
                if (eventobj != NULL) {
                    memset(*event_obj, 0, sizeof(*event_obj));
                    memcpy(eventobj, pos[index], size);
                    /* Process inotify event */
                    process(eventobj);
                    free(eventobj);
                }

                index += size;
                remain = data_size - index;
                if (remain <= MIN_EVENT_SIZE) goto __incomplete__;

__incomplete__:
                memmove(buff, pos[index], remain);
                pos = &buff[remain];
                goto __read_data__;
            }
            goto __read_data__;
        }
    }
}

4月5号更新:之前理解错误,谬误太多。
感谢 依云 指点「一个 inotify 实例为什么会有多个文件描述符引用?」问题。
5月3号更新:增加解析 events 伪代码。

参考:
Linux Programmer's Manual INOTIFY(7)

http://en.wikipedia.org/wiki/Inotify

http://zh.wikipedia.org/wiki/Inotify

Avatar_small
spotify web player 说:
2018年7月24日 11:24

This is really interesting information for me. Thanks for sharing!

Avatar_small
run 3 说:
2019年10月17日 12:14

Your blog provided us with valuable information to work with. Each & every tip of your post is awesome. Thanks a lot for sharing. Keep blogging,

Avatar_small
paper io 2 说:
2020年2月11日 16:55

I'm glad I found this web site, I couldn't find any knowledge on this matter prior to. Also, operate a site and if you are ever interested in doing some visitor writing for me if possible feel free to let me know, I'm always looking for people to check out my web site.

Avatar_small
Haryana Board Model 说:
2022年9月03日 18:26

Haryana Board Model Paper 2023 Class 7 Pdf Download with Answers for English Medium, Hindi Medium, Urdu Medium & Students for Small Answers, Long Answer, Very Long Answer Questions, and Essay Type Questions to Term1 & Term2 Exams at official website. Haryana Board Model Paper Class 7 New Exam Scheme or Question Pattern for Sammittive Assignment Exams (SA1 & SA2): Very Long Answer (VLA), Long Answer (LA), Small Answer (SA), Very Small Answer (VSA), Single Answer, Multiple Choice and etc.

Avatar_small
collgirlsagency 说:
2022年9月08日 20:57

Best Womens Escort Girls Provider in Delhi find high standard quality staff. Arranged for fulfill your intent, get vision proper with Call Girls in Delhi.

Visit:
https://www.callgirlsagency.com/
https://www.callgirlsagency.com/delhi.php

Local Places
https://www.callgirlsagency.com/escorts-in-dwarka.php
https://www.callgirlsagency.com/escorts-in-aerocity.php
https://www.callgirlsagency.com/escorts-in-janak-puri.php
https://www.callgirlsagency.com/escorts-in-karol-bagh.php
https://www.callgirlsagency.com/escorts-in-lajpat-nagar.php
https://www.callgirlsagency.com/escorts-in-mahipalpur.php
https://www.callgirlsagency.com/escorts-in-malviya-nagar.php
https://www.callgirlsagency.com/escorts-in-paharganj.php
https://www.callgirlsagency.com/escorts-in-pitam-pura.php
https://www.callgirlsagency.com/escorts-in-saket.php

Outer Places
https://www.callgirlsagency.com/agra.php
https://www.callgirlsagency.com/ahmedabad.php
https://www.callgirlsagency.com/amritsar.php
https://www.callgirlsagency.com/bangalore.php
https://www.callgirlsagency.com/chandigarh.php
https://www.callgirlsagency.com/chennai.php
https://www.callgirlsagency.com/dehradun.php
https://www.callgirlsagency.com/goa.php
https://www.callgirlsagency.com/gujarat.php
https://www.callgirlsagency.com/gurgaon.php
https://www.callgirlsagency.com/hyderabad.php
https://www.callgirlsagency.com/jaipur.php
https://www.callgirlsagency.com/jalandhar.php
https://www.callgirlsagency.com/jodhpur.php
https://www.callgirlsagency.com/manali.php
https://www.callgirlsagency.com/mohali.php
https://www.callgirlsagency.com/massoorie.php
https://www.callgirlsagency.com/noida.php
https://www.callgirlsagency.com/pune.php
https://www.callgirlsagency.com/surat.php

Avatar_small
AP 2nd Inter Economi 说:
2022年9月08日 22:22

The AP Intermediate students can download the Economics question bank with solved study material with practice questions in chapter wise to every TM, EM, UM student, and the economics subject paper-1 AP 2nd Inter Economics Question Paper and paper-2 important questions with suggestions are available through AP Jr and Sr inter Economics Model Paper 2023 Pdf with guess paper. The AP Intermediate students can download the Economics question bank with solved study material with practice questions in chapter wise to every TM, EM, UM student

Avatar_small
charlly 说:
2023年1月16日 13:44

Inotify is a Linux kernel subsystem that provides file system event notification. It is useful for monitoring file or directory Pasadena Nursing Center changes in Linux systems. Inotify can be used to monitor file creations, deletions, and modifications.

Avatar_small
Tamil Nadu 10th Que 说:
2023年9月04日 16:02

TN DGE Recently upload TN 10th Last Year Question Paper 2024 at Official Website for Students Final Exam Practice Purpose, Students our Suggestion TN SCERT Model Question Paper 2024 Download and Prepare , Practice Good Pass Marks in Exam The Final Exam. Exam Paper Available Tamil Nadu State Council of Educational Research and Training (TN SCERT) Official Website. Tamil Nadu Tamil Nadu 10th Question Paper 2024 Question Paper 2024 is Available for All the Subjects such as English, Tamil, Mathematics, Computer Science, History, Economics, Home Science, Zoology, Physics, Chemistry etc, Students can Improve their Reading Comprehension and can also Develop their Vocabulary.


登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter
Host by is-Programmer.com | Power by Chito 1.3.3 beta | © 2007 LinuxGem | Design by Matthew "Agent Spork" McGee