fanotify

FANOTIFY(7)                Linux Programmer's Manual               FANOTIFY(7)



åå
       fanotify - ãã¡ã¤ã«ã·ã¹ãã ã¤ãã³ããç£è¦ãã

説æ
       fanotify API ã¯ãã¡ã¤ã«ã·ã¹ãã ã¤ãã³ãã®éç¥ã¨æ¨ªåãæ©è½ (interception)
       ãæä¾ããã ã¦ã¼ã¹ã±ã¼ã¹ã¨ãã¦ã¯ãã¦ã¤ã«ã¹ã¹ã‐
       ã£ã³ãé層åã¹ãã¬ã¼ã¸ã®ç®¡çãªã©ãããã
       ç¾å¨ã®ã¨ãããéå®çãªã¤ãã³ãã®ã¿ããµãã¼ãããã¦ããã ç¹ã«ãä½æ (create)ãåé¤
       (delete)ã移å (move) ã¤ãã³ãããµãã¼ãããã¦ããªã (ãããã®ã¤ãã³ããéç¥ãã API
       ã®è©³ç´°ã«ã¤ãã¦ã¯ inotify(7) ãåç§)ã

       inotify(7) API ã¨æ¯è¼ãã¦è¿½å ããã¦ããæ©è½ã¨ãã¦ã¯ã
       ãã¦ã³ãããããã¡ã¤ã«ã·ã¹ãã ã®å¨ãªãã¸ã§ã¯ããç£è¦ããæ©è½ã
       ã¢ã¯ã»ã¹è¨±å¯ã®å¤å®ãè¡ãæ©è½ã
       ä»ã®ã¢ããªã±ã¼ã·ã§ã³ã«ããã¢ã¯ã»ã¹ã®åã«ãã¡ã¤ã«ãèªã¿åºãããå¤æ´ãããããæ©è½ãããã

       ãã® API ã§ã¯ä»¥ä¸ã®ã·ã¹ãã ã³ã¼ã«ã使ç¨ãã: fanotify_init(2),
       fanotify_mark(2), read(2), write(2), close(2)ã

   fanotify_init(), fanotify_mark() ã¨éç¥ã°ã«ã¼ã
       fanotify_init(2) ã·ã¹ãã ã³ã¼ã«ã¯ fanotify éç¥ã°ã«ã¼ããä½æãåæåãã
       ãã®éç¥ã°ã«ã¼ããåç§ãããã¡ã¤ã«ãã£ã¹ã¯ãªãã¿ã¼ãè¿ãã

       fanotify éç¥ã°ã«ã¼ãã¯ã«ã¼ãã«åé¨ã®ãªãã¸ã§ã¯ãã§ã ã¤ãã³ããä½æããããã¡ã¤ã«ã
       ãã£ã¬ã¯ããªã ãã¦ã³ããã¤ã³ãã®ãªã¹ããä¿æããã

       fanotify éç¥ã°ã«ã¼ãã®åã¨ã³ããªã¼ã«ã¯ 2 ã¤ã®ããããã¹ã¯ãããã mark ãã¹ã¯ã¨
       ignore ãã¹ã¯ã§ããã mark
       ãã¹ã¯ã¯ã©ã®ãã¡ã¤ã«æä½ã«ã¤ãã¦ã¤ãã³ããä½æããããå®ç¾©ããã ignore
       ãã¹ã¯ã¯ã©ã®æä½ã«ã¤ãã¦ã¤ãã³ããä½æããªãããå®ç¾©ããã ãããã® 2
       種é¡ã®ãã¹ã¯ããããã¨ã§ã ãã¦ã³ããã¤ã³ãããã£ã¬ã¯ããªã«å¯¾ãã¦ã¤ãã³ãã®åä¿¡ã mark
       ãã¦ããã¤ã¤ã
       åæã«ãã®ãã¦ã³ããã¤ã³ãããã£ã¬ã¯ããªéä¸ã®ç¹å®ã®ãªãã¸ã§ã¯ãã«å¯¾ããã¤ãã³ããç¡è¦ããã
       ã¨ãã£ããã¨ãã§ããã

       fanotify_mark(2)
       ã·ã¹ãã ã³ã¼ã«ã¯ããã¡ã¤ã«ããã£ã¬ã¯ããªããã¦ã³ããéç¥ã°ã«ã¼ãã«è¿½å ãã
       ã©ã®ã¤ãã³ããå ±å (ãããã¯ç¡è¦) ããããæå®ããã
       ã¾ãããã®ãããªã¨ã³ããªã¼ã®åé¤ãå¤æ´ãè¡ãã

       ignore ãã¹ã¯ã®èãããã使ç¨æ¹æ³ã¯ãã¡ã¤ã«ãã£ãã·ã¥ã«å¯¾ãã¦ã§ããã ãã¡ã¤ã«ã‐
       ã£ãã·ã¥ã«é¢ãã¦èå³ã®ããã¤ãã³ãã¯ããã¡ã¤ã«ã®å¤æ´ã¨ãã¡ã¤ã«ã®ã¯ãã¼ãºã§ããã
       ããããã ãã£ãã·ã¥ããããã£ã¬ã¯ããªããã¦ã³ããã¤ã³ãã¯ã
       ãããã®ã¤ãã³ããåä¿¡ããããã«ãã¼ã¯ãããã
       ãã¡ã¤ã«ãå¤æ´ãããã¨ããæåã®ã¤ãã³ããåä¿¡ããå¾ã¯ã 対å¿ããã‐
       ã£ãã·ã¥ã¨ã³ããªã¼ã¯ç¡å¹åãããã ãã®ãã¡ã¤ã«ãã¯ãã¼ãºãããã¾ã§ã¯ã
       ãã®ãã¡ã¤ã«ã«å¯¾ããå¤æ´ã¤ãã³ãã¯èå³ã®ãªãæå ±ã¨ãªãã ãããã£ã¦ã å¤æ´ã¤ãã³ãã
       ignore ãã¹ã¯ã«è¿½å ãããã¨ãã§ããã ã¯ãã¼ãºã¤ãã³ããåä¿¡ããã¨ã å¤æ´ã¤ãã³ãã
       ignore ã¤ãã³ãããåé¤ãã ãã¡ã¤ã«ãã£ãã·ã¥ã¨ã³ããªã¼ãæ´æ°ãããã¨ãã§ããã

       fanotify éç¥ã°ã«ã¼ãã®ã¨ã³ããªã¼ã¯ã ãã¡ã¤ã«ããã£ã¬ã¯ããªã§ã¯ inode
       çªå·çµç±ã§åç§ããã ãã¦ã³ãã§ã¯ãã¦ã³ã ID çµç±ã§åç§ãããã
       ãã¡ã¤ã«ããã£ã¬ã¯ããªã®ååãå¤æ´ããããã移åããããããå ´åãã
       é¢é£ããã¨ã³ããªã¼ã¯ãã®ã¾ã¾æ®ãã
       ãã¡ã¤ã«ããã£ã¬ã¯ããªãåé¤ããããããã¦ã³ããã¢ã³ãã¦ã³ãããããããå ´åã«ã¯ã
       対å¿ããã¨ã³ããªã¼ã¯åé¤ãããã

   ã¤ãã³ããã¥ã¼
       éç¥ã°ã«ã¼ãã«ããç£è¦ããã¦ãããã¡ã¤ã«ã·ã¹ãã ãªãã¸ã§ã¯ãã§ã¤ãã³ããçºçããã¨ã
       fanotify ã·ã¹ãã ã¯ã¤ãã³ããçæãã ãã®ã¤ãã³ãã¯ãã¥ã¼ã«ã¾ã¨ããããã
       ãããã®ã¤ãã³ãã¯ã fanotify_init(2) ãè¿ãã fanotify ãã¡ã¤ã«ãã£ã¹ã¯ãªãã¿ã¼ãã
       (read(2) ãªã©ã使ã£ã¦) èªã¿åºããã¨ãã§ããã

       2 種é¡ã®ã¤ãã³ããçæãããã notification (éç¥) ã¤ãã³ã㨠permission
       (ã¢ã¯ã»ã¹è¨±å¯) ã¤ãã³ãã§ããã éç¥ã¤ãã³ãã¯åãªãæå ±éç¥ã§ããã
       ã¤ãã³ãã§æ¸¡ããããã¡ã¤ã«ãã£ã¹ã¯ãªãã¿ã¼ãã¯ãã¼ãºããå ´å (ä¸è¨åç§) ãé¤ãã
       åä¿¡ããã¢ããªã±ã¼ã·ã§ã³ã§ã¢ã¯ã·ã§ã³ãåãå¿è¦ã¯ãªãã ã¢ã¯ã»ã¹è¨±å¯ã¤ãã³ãã¯ã
       åä¿¡ããã¢ããªã±ã¼ã·ã§ã³ããã¡ã¤ã«ã¢ã¯ã»ã¹ã®è¨±å¯ãæ¿èªããããå¤å®ããå¿è¦ãããã
       ãã®å ´åã åä¿¡èã¯ã¢ã¯ã»ã¹ã許å¯ããããå¦ãã決å®ããå¿çãæ¸ãè¾¼ã¾ãªããã°ãªããªãã

       ã¤ãã³ãã¯ã èªã¿åºãããã¨ã fanotify ã°ã«ã¼ãã®ã¤ãã³ããã¥ã¼ããåé¤ãããã èª‐
       ã¿åºãããã¢ã¯ã»ã¹è¨±å¯ã¤ãã³ãã¯ã fanotify
       ãã¡ã¤ã«ãã£ã¹ã¯ãªãã¿ã¼ã«ã¢ã¯ã»ã¹è¨±å¯ã®å¤å®ãæ¸ãè¾¼ã¾ãããã fanotify
       ãã¡ã¤ã«ãã£ã¹ã¯ãªãã¿ã¼ãã¯ãã¼ãºãããã¾ã§ã fanotify
       ã°ã«ã¼ãã®åé¨ã®ãªã¹ãã«ä¿æãããã

   fanotify ã¤ãã³ãã®èªã¿åºã
       fanotify_init(2) ãè¿ãããã¡ã¤ã«ãã£ã¹ã¯ãªãã¿ã¼ã«å¯¾ãã read(2) ãå¼ã³åºãã¯ã
       (fanotify_init(2) ã®å¼ã³åºãã§ãã©ã° FAN_NONBLOCK ãæå®ããªãã£ãå ´å)
       ãã¡ã¤ã«ã¤ãã³ããèµ·ããããå¼ã³åºããã·ã°ãã«ã«ãã£ã¦å²ãè¾¼ã¾ãã (signal(7) åç§)
       ã¾ã§åæ¢ããã

       read(2) ãæåããã¨ãèªã¿åºããããã¡ã¼ã«ã¯ä»¥ä¸ã®æ§é ä½ã 1 ã¤ä»¥ä¸æ ¼ç´ãããã

           struct fanotify_event_metadata {
               __u32 event_len;
               __u8 vers;
               __u8 reserved;
               __u16 metadata_len;
               __aligned_u64 mask;
               __s32 fd;
               __s32 pid;
           };

       æ§è½ä¸ã®çç±ãããè¤æ°ã®ã¤ãã³ããä¸åº¦ã® read(2)
       ã§åå¾ã§ããããã«å¤§ããã®ãããã¡ã¼ãµã¤ãº (ä¾ãã° 4096 ãã¤ã)
       ã使ç¨ãããã¨ãæ¨å¥¨ããã

       read(2) ã®è¿ãå¤ã¯ãããã¡ã¼ã«æ ¼ç´ããããã¤ãæ°ã§ããã ã¨ã©ã¼ã®å ´å㯠-1 ãè¿ããã
       (ãã ãããã°ãåç§)ã

       fanotify_event_metadata æ§é ä½ã®ãã£ã¼ã«ãã¯ä»¥ä¸ã®ã¨ããã§ããã

       event_len
              ããã¯ã
              ãã®ã¤ãã³ãã®ãã¼ã¿é·ã§ããããããã¡ã¼åã®æ¬¡ã®ã¤ãã³ãã¸ã®ãªãã»ããã§ããã
              ç¾å¨ã®å®è£ã§ã¯ã event_len ã®å¤ã¯å¸¸ã« FAN_EVENT_METADATA_LEN
              ã§ããã ããããªããã API ã¯å°æ¥å¯å¤é·ã®æ§é ä½ãè¿ããã¨ãã§ããããã«è¨‐
              è¨ããã¦ããã

       vers   ãã®ãã£ã¼ã«ãã«ã¯æ§é ä½ã®ãã¼ã¸ã§ã³çªå·ãå¥ãã
              å®è¡æã«è¿ãããæ§é ä½ãã³ã³ãã¤ã«æã®æ§é ä½ã¨ä¸è´ãã¦ããããæ¤æ»ããã«ã¯ã
              ãã®å¤ã FANOTIFY_METADATA_VERSION ãæ¯è¼ãããã¨ã ä¸è´ããªãå ´åã
              ã¢ããªã±ã¼ã·ã§ã³ã¯ãã® fanotify
              ãã¡ã¤ã«ãã£ã¹ã¯ãªãã¿ã¼ã使ç¨ããã®ã諦ããã¹ãã§ããã

       reserved
              ãã®ãã£ã¼ã«ãã¯ä½¿ç¨ãããªãã

       metadata_len
              ãã®æ§é ä½ã®é·ãã§ããã ãã®ãã£ã¼ã«ãã¯ã
              ã¤ãã³ã種å¥åä½ã®ãªãã·ã§ã³ãããã¼ã®å®è£ãæ±ãããã«å°å¥ãããã
              ç¾å¨ã®å®è£ã§ã¯ãã®ãããªãªãã·ã§ã³ãããã¼ã¯åå¨ããªãã

       mask   ã¤ãã³ãã示ãããããã¹ã¯ã§ãã (ä¸è¨åç§)

       fd     ããã¯ã¢ã¯ã»ã¹ããããªãã¸ã§ã¯ãã«å¯¾ãããªã¼ãã³ããããã¡ã¤ã«ãã£ã¹ã¯ãªãã¿ã¼ã§ããã
              ã¾ãã¯ããã¥ã¼ã®ãªã¼ãã¼ããã¼ãçºçããå ´åã«ã¯ FAN_NOFD ãå¥ãã
              ãã¡ã¤ã«ãã£ã¹ã¯ãªãã¿ã¼ã¯ç£è¦å¯¾è±¡ã®ãã¡ã¤ã«ããã£ã¬ã¯ããªã®å容ã«ã¢ã¯ã»ã¹ããã®ã«ä½¿ç¨ã§ããã
              èª‐
              ã¿åºããã¢ããªã±ã¼ã·ã§ã³ã¯è²¬ä»»ãæã£ã¦ãã®ãã¡ã¤ã«ãã£ã¹ã¯ãªãã¿ã¼ãã¯ã‐
              ã¼ãºããªããã°ãªããªãã

              fanotify_init(2) ãå¼ã³åºãéã
              å¼ã³åºãåã¯ãã®ãã¡ã¤ã«ãã£ã¹ã¯ãªãã¿ã¼ã«å¯¾å¿ãããªã¼ãã³ãã¡ã¤ã«è¨è¿°ã«ã»ãããããæ§ããªãã¡ã¤ã«ç¶æãã©ã°ã
              (event_f_flags å¼ãæ°ã使ã£ã¦) æå®ãããã¨ãã§ããã ããã«ã
              (ã«ã¼ãã«åé¨ã®) FMODE_NONOTIFY
              ãã¡ã¤ã«ç¶æãã©ã°ããªã¼ãã³ãã¡ã¤ã«è¨è¿°ã«ã»ãããããã ãã®ãã©ã°ã¯
              fanotify ã¤ãã³ãã®çæãæå¶ããã ãããã£ã¦ã fanotify
              ã¤ãã³ãã®åä¿¡èããã®ãã¡ã¤ã«ãã£ã¹ã¯ãªãã¿ã¼ã使ã£ã¦éç¥ããããã¡ã¤ã«ããã£ã¬ã¯ããªã«ã¢ã¯ã»ã¹ããéã«ã
              ãã以ä¸ã¤ãã³ããä½æãããªããªãã

       pid    ããã¯ã¤ãã³ããçºçããåå ã¨ãªã£ãããã»ã¹ ID ã§ããã fanotify
              ã¤ãã³ããç£è¦ãã¦ããããã°ã©ã ã¯ã ãã® PID ã getpid(2) ãè¿ã PID
              ã¨æ¯è¼ãããã¨ã§ã ã¤ãã³ããç£è¦ãã¦ããããã°ã©ã èªèº«ããçºçãããã©ããã
              å¥ã®ããã»ã¹ã«ãããã¡ã¤ã«ã¢ã¯ã»ã¹ã«ããçºçãããããå¤å®ã§ããã

       mask ã®ããããã¹ã¯ã¯ã1
       ã¤ã®ãã¡ã¤ã«ã·ã¹ãã ãªãã¸ã§ã¯ãã«å¯¾ãã¦ã©ã®ã¤ãã³ããçºçãããã示ãã
       ç£è¦å¯¾è±¡ã®ãã¡ã¤ã«ã·ã¹ãã ãªãã¸ã§ã¯ãã«è¤æ°ã®ã¤ãã³ããçºçããå ´åã¯ã
       ãã®ãã¹ã¯ã«è¤æ°ã®ããããã»ããããããã¨ãããã ç¹ã«ã
       åããã¡ã¤ã«ã·ã¹ãã ãªãã¸ã§ã¯ãã«å¯¾ããé£ç¶ããã¤ãã³ããåãããã»ã¹ããçæãããå ´åã«ã¯ã
       ä¸ã¤ã®ã¤ãã³ãã«ã¾ã¨ãããããã¨ãããã ä¾å¤ã¨ãã¦ã 2
       ã¤ã®ã¢ã¯ã»ã¹è¨±å¯ã¤ãã³ããä¸ã¤ã®ãã¥ã¼ã¨ã³ããªã¼ã«ã¾ã¨ãããããã¨ã¯æ±ºãã¦ãªãã

       mask ã§ã»ããããã¦ããå¯è½æ§ã®ãããããã¯ä»¥ä¸ã®ã¨ããã§ããã

       FAN_ACCESS
              ãã¡ã¤ã«ããã£ã¬ã¯ããªãã¢ã¯ã»ã¹ããã (èªã¿åºããè¡ããã)
              (ãã ããããã°ãã®ç¯ãåç§)ã

       FAN_OPEN
              ãã¡ã¤ã«ããã£ã¬ã¯ããªããªã¼ãã³ãããã

       FAN_MODIFY
              ãã¡ã¤ã«ããã£ã¬ã¯ããªãå¤æ´ãããã

       FAN_CLOSE_WRITE
              æ¸ãè¾¼ã¿ç¨ (O_WRONLY ã O_RDWR) ã«ãªã¼ãã³ããããã¡ã¤ã«ãã¯ãã¼ãºãããã

       FAN_CLOSE_NOWRITE
              èªã¿åºãç¨ (O_RDONLY) ã«ãªã¼ãã³ããããã¡ã¤ã«ãã¯ãã¼ãºãããã

       FAN_Q_OVERFLOW
              ã¤ãã³ããã¥ã¼ã 16384 ã¨ã³ããªã¼ã®ä¸éãè¶éããã ãã®ä¸éã¯
              fanotify_init(2) å¼ã³åºãæã« FAN_UNLIMITED_QUEUE
              ãã©ã°ãæå®ãããã¨ã§ä¸æ¸ãã§ããã

       FAN_ACCESS_PERM
              ã¢ããªã±ã¼ã·ã§ã³ãä¾ãã° read(2) ã readdir(2)
              ãªã©ã使ã£ã¦ãã¡ã¤ã«ããã£ã¬ã¯ããªãèªã¿åºããã¨ããã ãã®ã¤ãã³ããèª‐
              ã¿åºããããã°ã©ã ã¯ã
              ãã®ãã¡ã¤ã«ã·ã¹ãã ãªãã¸ã§ã¯ãã¸ã®ã¢ã¯ã»ã¹è¨±å¯ãæ¿èªããããå¤å®ã
              (ä¸è¨ã§èª¬æããã¨ãã) å¿çãæ¸ãè¾¼ã¾ãªããã°ãªããªãã

       FAN_OPEN_PERM
              ã¢ããªã±ã¼ã·ã§ã³ããã¡ã¤ã«ããã£ã¬ã¯ããªããªã¼ãã³ãããã¨ããã ãã®ã¤ãã³ããèª‐
              ã¿åºããããã°ã©ã ã¯ã
              ãã®ãã¡ã¤ã«ã·ã¹ãã ãªãã¸ã§ã¯ãã®ãªã¼ãã³ãæ¿èªããããå¤å®ã
              (ä¸è¨ã§èª¬æããã¨ãã) å¿çãæ¸ãè¾¼ã¾ãªããã°ãªããªãã

       ã¯ãã¼ãºã¤ãã³ãã確èªããããã«ä»¥ä¸ã®ããããã¹ã¯ã使ããã¨ãã§ããã

       FAN_CLOSE
              ãã¡ã¤ã«ãã¯ãã¼ãºãããã 以ä¸ã®å義èªã§ããã

                  FAN_CLOSE_WRITE | FAN_CLOSE_NOWRITE

       fanotify ãã¡ã¤ã«ãã£ã¹ã¯ãªãã¿ã¼ããã® read(2) ãè¿ãã fanotify
       ã¤ãã³ãã¡ã¿ãã¼ã¿ãå«ããããã¡ã¼ã«å¯¾ãã¦ç¹°ãè¿ããè¡ãããã 以ä¸ã®ãã¯ããæä¾ããã¦ããã

       FAN_EVENT_OK(meta, len)
              ãã®ãã¯ãã¯ã ãããã¡ã¼ meta ã®æ®ãã®é·ã len ãã
              ã¡ã¿ãã¼ã¿æ§é ä½ã®é·ãã¨ãããã¡ã¼ã®æåã®ã¡ã¿ãã¼ã¿æ§é ä½ã® event_len
              ãã£ã¼ã«ãã¨æ¯è¼ãã¦æ¤æ»ããã

       FAN_EVENT_NEXT(meta, len)
              ãã®ãã¯ãã¯ã meta ãæãã¡ã¿ãã¼ã¿æ§é ä½ã® event_len
              ãã£ã¼ã«ãã§ç¤ºãããé·ãã使ã£ã¦ã meta
              ã®æ¬¡ã®ã¡ã¿ãã¼ã¿æ§é ä½ã®ã¢ãã¬ã¹ãè¨ç®ããã len
              ã¯ãããã¡ã¼ã«ç¾å¨æ®ã£ã¦ããã¡ã¿ãã¼ã¿ã®ãã¤ãæ°ã§ããã ãã®ãã¯ã㯠meta
              ã®æ¬¡ã®ã¡ã¿ãã¼ã¿æ§é ä½ã¸ã®ãã¤ã³ã¿ã¼ãè¿ãã ã¹ã‐
              ãããããã¡ã¿ãã¼ã¿æ§é ä½ã®ãã¤ãæ°ã ã len ãæ¸ç®ãã (ã¤ã¾ãã len ãã
              meta->event_len ãå¼ãç®ãã)ã

       ã¾ãã 以ä¸ã®ãã¯ããç¨æããã¦ããã

       FAN_EVENT_METADATA_LEN
              ãã®ãã¯ã㯠fanotify_event_metadata æ§é ä½ã® (ãã¤ãåä½ã®)
              ãµã¤ãºãè¿ãã è¿ãããå¤ã¯ã¤ãã³ãã¡ã¿ãã¼ã¿ã®æå°å¤ã§ãã
              (ç¾å¨ã®ã¨ããããããå¯ä¸ã®ãµã¤ãºã§ãã)ã

   fanotify ãã¡ã¤ã«ãã£ã¹ã¯ãªãã¿ã¼ã®ã¤ãã³ããç£è¦ãã
       fanotify ã¤ãã³ããçºçããã¨ã epoll(7), poll(2), select(2) ã« fanotify
       ãã¡ã¤ã«ãã£ã¹ã¯ãªãã¿ã¼ã渡ãããå ´åã«ã¯ããã®ãã¡ã¤ã«ãã£ã¹ã¯ãªãã¿ã¼ãèª‐
       ã¿åºãå¯è½ã§ããã¨éç¥ãããã

   ã¢ã¯ã»ã¹è¨±å¯ã¤ãã³ãã®åãæ±ã
       ã¢ã¯ã»ã¹è¨±å¯ã¤ãã³ãã§ã¯ã ã¢ããªã±ã¼ã·ã§ã³ã¯ä»¥ä¸ã®å½¢å¼ã®æ§é ä½ã
       fanotify ãã¡ã¤ã«ãã£ã¹ã¯ãªãã¿ã¼ã« write(2) ããªããã°ãªããªãã

           struct fanotify_response {
               __s32 fd;
               __u32 response;
           };

       ãã®æ§é ä½ã®ãã£ã¼ã«ãã¯ä»¥ä¸ã®ã¨ããã§ããã

       fd     ãã®ãã£ã¼ã«ã㯠fanotify_event_metadata
              æ§é ä½ã§è¿ããããã¡ã¤ã«ãã£ã¹ã¯ãªãã¿ã¼ã§ããã

       response
              ãã®ãã£ã¼ã«ãã¯ã¢ã¯ã»ã¹è¨±å¯ãæ¿èªãããã©ããã示ãã
              å¤ã¯ããã®ãã¡ã¤ã«æä½ã許å¯ãã FAN_ALLOW ãã ãã®ãã¡ã¤ã«æä½ãæå¦ãã
              FAN_DENY ã®ããããã§ãªããã°ãªããªãã

       ã¢ã¯ã»ã¹ãæå¦ããå ´åã ã¢ã¯ã»ã¹ãè¦æ±ããã¢ããªã±ã¼ã·ã§ã³ã¯ EPERM
       ã¨ã©ã¼ãåãåããã¨ã«ãªãã

   fanotify ãã¡ã¤ã«ãã£ã¹ã¯ãªãã¿ã¼ã®ã¯ãã¼ãº
       fanotify éç¥ã°ã«ã¼ããåç§ãããã¹ã¦ã®ãã¡ã¤ã«ãã£ã¹ã¯ãªãã¿ã¼ãã¯ãã¼ãºãããã¨ã
       fanotify ã°ã«ã¼ãã¯è§£æ¾ããã ã«ã¼ãã«ãåå©ç¨ã§ããããã«ãã®ãªã½ã¼ã¹ã¯è§£æ¾ãããã
       close(2) ã®éã«ã å¦çä¸ã§ãã£ãã¢ã¯ã»ã¹è¨±å¯ã¤ãã³ãã«ã¯è¨±å¯ãè¨å®ãããã

   /proc/[pid]/fdinfo
       ãã¡ã¤ã« /proc/[pid]/fdinfo/[fd] ã«ã¯ã ããã»ã¹ pid
       ã®ãã¡ã¤ã«ãã£ã¹ã¯ãªãã¿ã¼ fd ã® fanotify ãã¼ã¯ã«é¢ããæå ±ãæ ¼ç´ãããã
       詳細ã¯ã«ã¼ãã«ã®ã½ã¼ã¹ãã¡ã¤ã« Documentation/filesystems/proc.txt ãåç§ã

ã¨ã©ã¼
       é常㮠read(2) ã®ã¨ã©ã¼ã«å ãã fanotify ãã¡ã¤ã«ãã£ã¹ã¯ãªãã¿ã¼ããèª‐
       ã¿åºããè¡ã£ãéã«ä»¥ä¸ã®ã¨ã©ã¼ãçºçãããã¨ãããã

       EINVAL ãããã¡ã¼ãã¤ãã³ããä¿æããã«ã¯å°ããããã

       EMFILE ãªã¼ãã³ãããã¡ã¤ã«æ°ã®ããã»ã¹æ¯ã®ä¸éã«éããã getrlimit(2) ã®
              RLIMIT_NOFILE ã®èª¬æãåç§ã

       ENFILE ãªã¼ãã³ããããã¡ã¤ã«æ°ã®ã·ã¹ãã å¨ä½ã®ä¸éã«éããã proc(5) ã®
              /proc/sys/fs/file-max ãåç§ã

       ETXTBSY
              fanotify_init(2) ã®å¼ã³åºãæã« O_RDWR ã O_WRONLY ã event_f_flags
              å¼ãæ°ã«æå®ããã¦ããã ç¾å¨å®è¡ä¸‐
              ã®ç£è¦å¯¾è±¡ã®ãã¡ã¤ã«ã«å¯¾ãã¦ã¤ãã³ããçºçããéã«ã ãã®ã¨ã©ã¼ã read(2)
              ããè¿ãããã

       é常㮠write(2) ã®ã¨ã©ã¼ã«å ãã fanotify
       ãã¡ã¤ã«ãã£ã¹ã¯ãªãã¿ã¼ã«æ¸ãè¾¼ã¿ãè¡ã£ãéã«ä»¥ä¸ã®ã¨ã©ã¼ãçºçãããã¨ãããã

       EINVAL fanotify ã¢ã¯ã»ã¹è¨±å¯ãã«ã¼ãã«ã®è¨å®ã§æå¹ã«ãªã£ã¦ããªãã å¿ç‐
              æ§é ä½ã® response å¤ãç¡å¹ã§ããã

       ENOENT å¿çæ§é ä½ã®ãã¡ã¤ã«ãã£ã¹ã¯ãªãã¿ã¼ fd ãç¡å¹ã§ããã
              ãã®ã¨ã©ã¼ã¯ã¢ã¯ã»ã¹è¨±å¯ã¤ãã³ãã«å¯¾ããå¿ç‐
              ããã§ã«æ¸ãè¾¼ã¾ãã¦ããéã«çºçããã

ãã¼ã¸ã§ã³
       fanotify API 㯠Linux ã«ã¼ãã«ã®ãã¼ã¸ã§ã³ 2.6.36 ã§å°å¥ããã ãã¼ã¸ã§ã³
       2.6.37 ã§æå¹ã«ãããã fdinfo ã®ãµãã¼ãã¯ãã¼ã¸ã§ã³ 3.8 ã§è¿½å ãããã

æºæ
       fanotify API 㯠Linux ç¬èªã®ãã®ã§ããã

注æ
       fanotify API ãå©ç¨ã§ããã®ã¯ã ã«ã¼ãã«ã CONFIG_FANOTIFY è¨‐
       å®ãªãã·ã§ã³ãæå¹ã«ãã¦ä½æããã¦ããå ´åã ãã§ããã ã¾ãã fanotify
       ã¢ã¯ã»ã¹è¨±å¯ã®å¦çãå©ç¨ã§ããã®ã¯ CONFIG_FANOTIFY_ACCESS_PERMISSIONS è¨‐
       å®ãªãã·ã§ã³ãæå¹ã«ãªã£ã¦ããå ´åã ãã§ããã

   å¶éã¨è¦å
       fanotify ãå ±åããã®ã¯ã¦ã¼ã¶ã¼ç©ºéããã°ã©ã ããã¡ã¤ã«ã·ã¹ãã  API
       çµç±ã§è¡ã£ãã¤ãã³ãã ãã§ããã ãã®çµæã fanotify
       ã§ã¯ãããã¯ã¼ã¯ãã¡ã¤ã«ã·ã¹ãã ä¸ã§çºçãããªã¢ã¼ãã¤ãã³ãã¯ææã§ããªãã

       inotify API 㯠mmap(2), msync(2), munmap(2)
       ã«ããèµ·ãã£ããã¡ã¤ã«ã®ã¢ã¯ã»ã¹ã¨å¤æ´ãå ±åããªãã

       ãã£ã¬ã¯ããªã®ã¤ãã³ãã¯ããã£ã¬ã¯ããªèªèº«ããªã¼ãã³ãèªã¿åºããã¯ã‐
       ã¼ãºãããå ´åã«ããä½æãããªãã ãã¼ã¯ããããã£ã¬ã¯ããªã§ã®å‐
       è¦ç´ ã®è¿½å ãåé¤ãå¤æ´ã§ã¯ãç£è¦å¯¾è±¡ã®ãã£ã¬ã¯ããªèªèº«ã¸ã®ã¤ãã³ãã¯ä½æãããªãã

       fanotify ã®ãã£ã¬ã¯ããªã®ç£è¦ã¯å帰çã§ã¯ãªãã
       ãã£ã¬ã¯ããªåã®ãµããã£ã¬ã¯ããªãç£è¦ããã«ã¯ã
       追å ã§ç£è¦ç¨ã®ãã¼ã¯ãä½æããªããã°ãªããªãã (ãã ãã fanotify API
       ã§ã¯ããµããã£ã¬ã¯ããªãç£è¦å¯¾è±¡ã¨ãã¦ãã¼ã¯ããã¦ãããã£ã¬ã¯ããªã«ä½æãããéã«æ¤åºããæ段ã¯æä¾ããã¦ããªãç¹ã«æ³¨æãããã¨ã)
       ãã¦ã³ãã®ç£è¦ã使ããã¨ã§ã ãã£ã¬ã¯ããªããªã¼å¨ä½ãç£è¦ãããã¨ãã§ããã

       ãã³ããã¥ã¼ã¯ãªã¼ãã¼ããã¼ãããã¨ãããã ãã®å ´åã ã¤ãã³ãã¯å¤±ãããã

ãã°
       Linux 3.17 æç¹ã§ã¯ã 以ä¸ã®ãã°ãåå¨ããã

       *  Linux ã§ã¯ããã¡ã¤ã«ã·ã¹ãã ãªãã¸ã§ã¯ãã¯è¤æ°ã®ãã¹ã§ã¢ã¯ã»ã¹å¯è½ã§ããã
          ä¾ãã°ã ãã¡ã¤ã«ã·ã¹ãã ã®ä¸é¨ã¯ mount(8) ã® --bind
          ãªãã·ã§ã³ã使ã£ã¦åãã¦ã³ãããããã¨ãããã ãã¼ã¯ããããã¦ã³ãã®ç£è¦èã¯ã
          åããã¦ã³ãã使ã£ããã¡ã¤ã«ãªãã¸ã§ã¯ãã«ã¤ãã¦ã®ã¿ã¤ãã³ãéç¥ãåããã
          ãã以å¤ã®ã¤ãã³ãã¯éç¥ãããªãã

       *  fallocate(2) ã®å¼ã³åºãã§ã¯ fanotify ã¤ãã³ããä½æãããªãã

       *  ã¤ãã³ããçæãããéã«ã ãã®ãã¡ã¤ã«ã®ãã¡ã¤ã«ãã£ã¹ã¯ãªãã¿ã¼ã渡ãåã«ã
          ã¤ãã³ããåä¿¡ããããã»ã¹ã®ã¦ã¼ã¶ã¼ ID ããã®ãã¡ã¤ã«ã«å¯¾ããèª‐
          ã¿åºãï¼æ¸ãè¾¼ã¿è¨±å¯ããããã®ç¢ºèªã¯è¡ãããªãã
          éç¹æ¨©ã¦ã¼ã¶ã¼ã«ãã£ã¦å®è¡ãããããã°ã©ã ã« CAP_SYS_ADMIN
          ã±ã¼ãããªãã£ã¼ãã»ããããã¦ããå ´åã«ã¯ã ãã®ãã¨ã¯ã»ãã¥ãªãã£ã¼ãªã¹ã¯ã¨ãªãã

       *  read(2) ã®å¼ã³åºãã fanotify ãã¥ã¼ããè¤æ°ã®ã¤ãã³ããå¦çãã¦ããéã«ã
          ã¨ã©ã¼ãçºçããå ´åã è¿ãå¤ã¯ã¨ã©ã¼ãçºçããåã¾ã§ã«ã¦ã¼ã¶ã¼ç©ºéãããã¡ã¼ã«æ‐
          £å¸¸ã«ã³ãã¼ãããã¤ãã³ãã®åè¨é·ã¨ãªãã è¿ãå¤ã¯ -1 ã«ãªããã errno
          ãã»ãããããªãã ãããã£ã¦ã èª‐
          ã¿åºããè¡ãã¢ããªã±ã¼ã·ã§ã³ã§ã¯ã¨ã©ã¼ãæ¤åºããæ¹æ³ã¯ãªãã

ä¾
       以ä¸ã®ããã°ã©ã 㯠fanotify API ã®ä½¿ç¨æ³ã示ããã®ã§ããã
       ã³ãã³ãã©ã¤ã³å¼ãæ°ã§æ¸¡ããããã¦ã³ããã¤ã³ããç£è¦ãã 種å¥ã FAN_PERM_OPEN ã¨
       FAN_CLOSE_WRITE ã®ã¤ãã³ããå¾ã¤ã ã¢ã¯ã»ã¹è¨±å¯ã¤ãã³ããçºçã«ã¯ã FAN_ALLOW
       å¿çãè¿ãã

       以ä¸ã®åºåä¾ã¯ãã¡ã¤ã« /home/user/temp/notes ãç·¨éããéã«è¨é²ããããã®ã§ããã
       ãã¡ã¤ã«ããªã¼ãã³ããåã« FAN_OPEN_PERM ã¤ãã³ããçºçãã¦ããã ãã¡ã¤ã«ãã¯ã‐
       ã¼ãºããå¾ã« FAN_CLOSE_WRITE ã¤ãã³ããçºçãã¦ããã ã¨ã³ã¿ã¼ãã¼ãã¦ã¼ã¶ã¼ãæ¼ãã¨ã
       ãã®ããã°ã©ã ã®å®è¡ã¯çµäºããã

   åºåä¾
           # ./fanotify_example /home
           Press enter key to terminate.
           Listening for events.
           FAN_OPEN_PERM: File /home/user/temp/notes
           FAN_CLOSE_WRITE: File /home/user/temp/notes

           Listening for events stopped.

   ããã°ã©ã ã½ã¼ã¹
       #define _GNU_SOURCE     /* O_LARGEFILE ã®å®ç¾©ãå¾ãããã«å¿è¦ */
       #include <errno.h>
       #include <fcntl.h>
       #include <limits.h>
       #include <poll.h>
       #include <stdio.h>
       #include <stdlib.h>
       #include <sys/fanotify.h>
       #include <unistd.h>

       /* ãã¡ã¤ã«ãã£ã¹ã¯ãªãã¿ã¼ 'fd' ããèªã¿åºãã§ããå¨ fanotify ã¤ãã³ããèªã¿åºã */

       static void
       handle_events(int fd)
       {
           const struct fanotify_event_metadata *metadata;
           struct fanotify_event_metadata buf[200];
           ssize_t len;
           char path[PATH_MAX];
           ssize_t path_len;
           char procfd_path[PATH_MAX];
           struct fanotify_response response;

           /* fanotify ãã¡ã¤ã«ãã£ã¹ã¯ãªãã¿ã¼ããã¤ãã³ããèªã¿åºããéã¯ã«ã¼ããã */

           for(;;) {

               /* ã¤ãã³ããèªã¿åºã */

               len = read(fd, (void *) &buf, sizeof(buf));
               if (len == -1 && errno != EAGAIN) {
                   perror("read");
                   exit(EXIT_FAILURE);
               }

               /* èªã¿åºãããã¼ã¿ã®æå¾ã«éãã¦ããããã§ãã¯ãã */

               if (len <= 0)
                   break;

               /* ãããã¡ã¼ã®æåã®ã¤ãã³ããåç§ãã */

               metadata = buf;

               /* ãããã¡ã¼åã®å¨ã¤ãã³ããå¦çãã */

               while (FAN_EVENT_OK(metadata, len)) {

                   /* å®è¡æã¨ã³ã³ãã¤ã«æã®æ§é ä½ãä¸è´ããã確èªãã */

                   if (metadata->vers != FANOTIFY_METADATA_VERSION) {
                       fprintf(stderr,
                               "Mismatch of fanotify metadata version.\n");
                       exit(EXIT_FAILURE);
                   }

                   /* metadata->fd ã«ã¯ããã¥ã¼ã®ãªã¼ãã¼ããã¼ã示ã FAN_NOFD ãã
                      ãã¡ã¤ã«ãã£ã¹ã¯ãªãã¿ã¼ (è² ã§ãªãæ´æ°) ã®ãããããå¥ã£ã¦ããã
                      ããã§ã¯ãã¥ã¼ã®ãªã¼ãã¼ããã¼ã¯ç¡è¦ãã¦ããã */

                   if (metadata->fd >= 0) {

                       /* ãªã¼ãã³è¨±å¯ã¤ãã³ããå¦çãã */

                       if (metadata->mask & FAN_OPEN_PERM) {
                           printf("FAN_OPEN_PERM: ");

                           /* ãã¡ã¤ã«ã®ãªã¼ãã³ã許å¯ãã */

                           response.fd = metadata->fd;
                           response.response = FAN_ALLOW;
                           write(fd, &response,
                                 sizeof(struct fanotify_response));
                       }

                       /* æ¸ãè¾¼ã¿å¯è½ãã¡ã¤ã«ã®ã¯ãã¼ãºã¤ãã³ããå¦çãã */

                       if (metadata->mask & FAN_CLOSE_WRITE)
                           printf("FAN_CLOSE_WRITE: ");

                       /* ã¢ã¯ã»ã¹ããããã¡ã¤ã«ã®ãã¹åãåå¾ã表示ãã */

                       snprintf(procfd_path, sizeof(procfd_path),
                                "/proc/self/fd/%d", metadata->fd);
                       path_len = readlink(procfd_path, path,
                                           sizeof(path) - 1);
                       if (path_len == -1) {
                           perror("readlink");
                           exit(EXIT_FAILURE);
                       }

                       path[path_len] = '\0';
                       printf("File %s\n", path);

                       /* ã¤ãã³ãã®ãã¡ã¤ã«ãã£ã¹ã¯ãªãã¿ã¼ãã¯ãã¼ãºãã */

                       close(metadata->fd);
                   }

                   /* 次ã®ã¤ãã³ãã«é²ã */

                   metadata = FAN_EVENT_NEXT(metadata, len);
               }
           }
       }

       int
       main(int argc, char *argv[])
       {
           char buf;
           int fd, poll_num;
           nfds_t nfds;
           struct pollfd fds[2];

           /* ãã¦ã³ããã¤ã³ããæå®ãããã確èªãã */

           if (argc != 2) {
               fprintf(stderr, "Usage: %s MOUNT\n", argv[0]);
               exit(EXIT_FAILURE);
           }

           printf("Press enter key to terminate.\n");

           /* fanotify API ã«ã¢ã¯ã»ã¹ããããã®ãã¡ã¤ã«ãã£ã¹ã¯ãªãã¿ã¼ãä½æãã */

           fd = fanotify_init(FAN_CLOEXEC | FAN_CLASS_CONTENT | FAN_NONBLOCK,
                              O_RDONLY | O_LARGEFILE);
           if (fd == -1) {
               perror("fanotify_init");
               exit(EXIT_FAILURE);
           }

           /* æå®ããããã¦ã³ãã«å¯¾ãã¦ä»¥ä¸ãç£è¦ããããã«ãã¼ã¯ãä»ãã:
              - ãã¡ã¤ã«ã®ãªã¼ãã³åã®ã¢ã¯ã»ã¹è¨±å¯ã¤ãã³ã
              - æ¸ãè¾¼ã¿å¯è½ãªãã¡ã¤ã«ãã£ã¹ã¯ãªãã¿ã¼ã®ã¯ãã¼ãºå¾ã®
                éç¥ã¤ãã³ã */

           if (fanotify_mark(fd, FAN_MARK_ADD | FAN_MARK_MOUNT,
                             FAN_OPEN_PERM | FAN_CLOSE_WRITE, AT_FDCWD,
                             argv[1]) == -1) {
               perror("fanotify_mark");
               exit(EXIT_FAILURE);
           }

           /* ãã¼ãªã³ã°ã®æºå */

           nfds = 2;

           /* ã³ã³ã½ã¼ã«ã®å¥å */

           fds[0].fd = STDIN_FILENO;
           fds[0].events = POLLIN;

           /* fanotify ã®å¥å */

           fds[1].fd = fd;
           fds[1].events = POLLIN;

           /* ã¤ãã³ãã®çºçãå¾ã¤ã«ã¼ã */

           printf("Listening for events.\n");

           while (1) {
               poll_num = poll(fds, nfds, -1);
               if (poll_num == -1) {
                   if (errno == EINTR)     /* ã·ã°ãã«ã«å²ãè¾¼ã¾ããå ´å */
                       continue;           /* poll() ãåéãã */

                   perror("poll");         /* äºæããªãã¨ã©ã¼ */
                   exit(EXIT_FAILURE);
               }

               if (poll_num > 0) {
                   if (fds[0].revents & POLLIN) {

                       /* ã³ã³ã½ã¼ã«ããã®å¥åãããå ´å: 空ã®æ¨æºå¥åã§ããã°çµäº */

                       while (read(STDIN_FILENO, &buf, 1) > 0 && buf != '\n')
                           continue;
                       break;
                   }

                   if (fds[1].revents & POLLIN) {

                       /* fanotify ã¤ãã³ããããå ´å */

                       handle_events(fd);
                   }
               }
           }

           printf("Listening for events stopped.\n");
           exit(EXIT_SUCCESS);
       }

é¢é£é ç®
       fanotify_init(2), fanotify_mark(2), inotify(7)

ãã®ææ¸ã«ã¤ãã¦
       ãã® man ãã¼ã¸ã¯ Linux man-pages ããã¸ã§ã¯ãã®ãªãªã¼ã¹ 3.79 ã®ä¸é¨
       ã§ãããããã¸ã§ã¯ãã®èª¬æã¨ãã°å ±åã«é¢ããæå ±ã¯
       http://www.kernel.org/doc/man-pages/ ã«æ¸ããã¦ããã



Linux                             2014-12-31                       FANOTIFY(7)