日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

Linux inotify功能及实现原理【转】

發布時間:2025/3/21 linux 53 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Linux inotify功能及实现原理【转】 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

轉自:http://blog.csdn.net/myarrow/article/details/7096460

1. inotify主要功能

它是一個內核用于通知用戶空間程序文件系統變化的機制。

眾所周知,Linux 桌面系統與 MAC 或?Windows?相比有許多不如人意的地方,為了改善這種狀況,開源社區提出用戶態需要內核提供一些機制,以便用戶態能夠及時地得知內核或底層硬件設備發生了什么,從而能夠更好地管理設備,給用戶提供更好的服務,如 hotplug、udev 和 inotify 就是這種需求催生的。Hotplug 是一種內核向用戶態應用通報關于熱插拔設備一些事件發生的機制,桌面系統能夠利用它對設備進行有效的管理,udev 動態地維護 /dev 下的設備文件,inotify 是一種文件系統的變化通知機制,如文件增加、刪除等事件可以立刻讓用戶態得知,該機制是著名的桌面搜索引擎項目 beagle 引入的,并在 Gamin 等項目中被應用。

2. 用戶接口

在用戶態,inotify 通過三個系統調用和在返回的文件描述符上的文件 I/ 操作來使用,使用 inotify 的第一步是創建 inotify 實例:

??

?

int fd = inotify_init ();

?

??? 每一個 inotify 實例對應一個獨立的排序的隊列。

??? 文件系統的變化事件被稱做 watches 的一個對象管理,每一個 watch 是一個二元組(目標,事件掩碼),目標可以是文件或目錄,事件掩碼表示應用希望關注的 inotify 事件,每一個位對應一個 inotify 事件。Watch 對象通過 watch描述符引用,watches 通過文件或目錄的路徑名來添加。目錄 watches 將返回在該目錄下的所有文件上面發生的事件。

??? 下面函數用于添加一個 watch:

?

int wd = inotify_add_watch (fd, path, mask);

?

??? fd 是 inotify_init() 返回的文件描述符,path 是被監視的目標的路徑名(即文件名或目錄名),mask 是事件掩碼, 在頭文件?linux/inotify.h 中定義了每一位代表的事件。可以使用同樣的方式來修改事件掩碼,即改變希望被通知的inotify 事件。Wd 是 watch 描述符。

??? 下面的函數用于刪除一個 watch:

?

int ret = inotify_rm_watch (fd, wd);


??? fd 是 inotify_init() 返回的文件描述符,wd 是 inotify_add_watch() 返回的 watch 描述符。Ret 是函數的返回值。

?

??? 文件事件用一個 inotify_event 結構表示,它通過由 inotify_init() 返回的文件描述符使用通常文件讀取函數 read 來獲得

:?

struct inotify_event {__s32 wd; /* watch descriptor */__u32 mask; /* watch mask */__u32 cookie; /* cookie to synchronize two events */__u32 len; /* length (including nulls) of name */char name[0]; /* stub for possible name */ };


??? 結構中的 wd 為被監視目標的 watch 描述符,mask 為事件掩碼,len 為 name字符串的長度,name 為被監視目標的路徑名,該結構的 name 字段為一個樁,它只是為了用戶方面引用文件名,文件名是變長的,它實際緊跟在該結構的后面,文件名將被 0 填充以使下一個事件結構能夠 4 字節對齊。注意,len 也把填充字節數統計在內。

?

??? 通過 read 調用可以一次獲得多個事件,只要提供的 buf 足夠大。

?

size_t len = read (fd, buf, BUF_LEN);

?

?

??? buf 是一個 inotify_event 結構的數組指針,BUF_LEN 指定要讀取的總長度,buf 大小至少要不小于 BUF_LEN,該調用返回的事件數取決于 BUF_LEN 以及事件中文件名的長度。Len 為實際讀去的字節數,即獲得的事件的總長度。

??? 可以在函數 inotify_init() 返回的文件描述符 fd 上使用 select() 或poll(), 也可以在 fd 上使用 ioctl 命令 FIONREAD 來得到當前隊列的長度。close(fd)將刪除所有添加到 fd 中的 watch 并做必要的清理。

?

int inotify_init (void);int inotify_add_watch (int fd, const char *path, __u32 mask);int inotify_rm_watch (int fd, __u32 mask);

?

3. 內核實現原理

?在內核中,每一個 inotify 實例對應一個 inotify_device 結構:

?

?

struct inotify_device {wait_queue_head_t wq; /* wait queue for i/o */struct idr idr; /* idr mapping wd -> watch */struct semaphore sem; /* protects this bad boy */struct list_head events; /* list of queued events */struct list_head watches; /* list of watches */atomic_t count; /* reference count */struct user_struct *user; /* user who opened this dev */unsigned int queue_size; /* size of the queue (bytes) */unsigned int event_count; /* number of pending events */unsigned int max_events; /* maximum number of events */u32 last_wd; /* the last wd allocated */ };

?

?

??? d_list 指向所有 inotify_device 組成的列表的,i_list 指向所有被監視 inode 組成的列表,count 是引用計數,dev 指向該 watch 所在的 inotify 實例對應的 inotify_device 結構,inode 指向該 watch 要監視的 inode,wd 是分配給該 watch 的描述符,mask 是該 watch 的事件掩碼,表示它對哪些文件系統事件感興趣。

??? 結構 inotify_device 在用戶態調用 inotify_init() 時創建,當關閉 inotify_init()返回的文件描述符時將被釋放。結構 inotify_watch 在用戶態調用 inotify_add_watch()時創建,在用戶態調用 inotify_rm_watch() 或 close(fd) 時被釋放。

??? 無論是目錄還是文件,在內核中都對應一個 inode 結構,inotify 系統在 inode 結構中增加了兩個字段:

?

?

struct inotify_watch {struct list_head d_list; /* entry in inotify_device's list */struct list_head i_list; /* entry in inode's list */atomic_t count; /* reference count */struct inotify_device *dev; /* associated device */struct inode *inode; /* associated inode */s32 wd; /* watch descriptor */u32 mask; /* event mask for this watch */ };

?

?

??? d_list 指向所有 inotify_device 組成的列表的,i_list 指向所有被監視 inode 組成的列表,count 是引用計數,dev 指向該 watch 所在的 inotify 實例對應的 inotify_device 結構,inode 指向該 watch 要監視的 inode,wd 是分配給該 watch 的描述符,mask 是該 watch 的事件掩碼,表示它對哪些文件系統事件感興趣。

??? 結構 inotify_device 在用戶態調用 inotify_init() 時創建,當關閉 inotify_init()返回的文件描述符時將被釋放。結構 inotify_watch 在用戶態調用 inotify_add_watch()時創建,在用戶態調用 inotify_rm_watch() 或 close(fd) 時被釋放。

??? 無論是目錄還是文件,在內核中都對應一個 inode 結構,inotify 系統在 inode 結構中增加了兩個字段:

?

?

#ifdef CONFIG_INOTIFYstruct list_head inotify_watches; /* watches on this inode */struct semaphore inotify_sem; /* protects the watches list */ #endif

?

?

??? inotify_watches 是在被監視目標上的 watch 列表,每當用戶調用 inotify_add_watch()時,內核就為添加的 watch 創建一個 inotify_watch 結構,并把它插入到被監視目標對應的 inode 的 inotify_watches 列表。inotify_sem 用于同步對 inotify_watches 列表的訪問。當文件系統發生第一部分提到的事件之一時,相應的文件系統代碼將顯示調用fsnotify_* 來把相應的事件報告給 inotify 系統,其中*號就是相應的事件名,目前實現包括:

??? fsnotify_move,文件從一個目錄移動到另一個目錄fsnotify_nameremove,文件從目錄中刪除fsnotify_inoderemove,自刪除fsnotify_create,創建新文件fsnotify_mkdir,創建新目錄fsnotify_access,文件被讀fsnotify_modify,文件被寫fsnotify_open,文件被打開fsnotify_close,文件被關閉fsnotify_xattr,文件的擴展屬性被修改fsnotify_change,文件被修改或原數據被修改有一個例外情況,就是 inotify_unmount_inodes,它會在文件系統被 umount 時調用來通知 umount 事件給 inotify 系統。

??? 以上提到的通知函數最后都調用 inotify_inode_queue_event(inotify_unmount_inodes直接調用 inotify_dev_queue_event ),該函數首先判斷對應的inode是否被監視,這通過查看 inotify_watches 列表是否為空來實現,如果發現 inode 沒有被監視,什么也不做,立刻返回,反之,遍歷 inotify_watches 列表,看是否當前的文件操作事件被某個 watch 監視,如果是,調用 inotify_dev_queue_event,否則,返回。函數inotify_dev_queue_event 首先判斷該事件是否是上一個事件的重復,如果是就丟棄該事件并返回,否則,它判斷是否 inotify 實例即 inotify_device 的事件隊列是否溢出,如果溢出,產生一個溢出事件,否則產生一個當前的文件操作事件,這些事件通過kernel_event 構建,kernel_event 將創建一個 inotify_kernel_event 結構,然后把該結構插入到對應的 inotify_device 的 events 事件列表,然后喚醒等待在inotify_device 結構中的 wq 指向的等待隊列。想監視文件系統事件的用戶態進程在inotify 實例(即 inotify_init() 返回的文件描述符)上調用 read 時但沒有事件時就掛在等待隊列 wq 上。

4. 使用示例

下面是一個使用 inotify 來監視文件系統事件的例子:

?

?

#include #include #include _syscall0(int, inotify_init) _syscall3(int, inotify_add_watch, int, fd, const char *, path, __u32, mask) _syscall2(int, inotify_rm_watch, int, fd, __u32, mask)char * monitored_files[] = {"./tmp_file","./tmp_dir","/mnt/sda3/windows_file" };struct wd_name {int wd;char * name; };#define WD_NUM 3 struct wd_name wd_array[WD_NUM];char * event_array[] = {"File was accessed","File was modified","File attributes were changed","writtable file closed","Unwrittable file closed","File was opened","File was moved from X","File was moved to Y","Subfile was created","Subfile was deleted","Self was deleted","Self was moved","","Backing fs was unmounted","Event queued overflowed","File was ignored" }; #define EVENT_NUM 16 #define MAX_BUF_SIZE 1024int main(void) {int fd;int wd;char buffer[1024];char * offset = NULL;struct inotify_event * event;int len, tmp_len;char strbuf[16];int i = 0;fd = inotify_init();if (fd < 0) {printf("Fail to initialize inotify.\n");exit(-1);}for (i=0; i<WD_NUM; wd="inotify_add_watch(fd," add (event- if { len) < buffer) - *)event (((char while *)buffer; inotify_event event len); len='%d.\n",' happens, printf(?Some offset="buffer;" MAX_BUF_SIZE)) buffer, while(len="read(fd," } wd_array[i].wd="wd;" exit(-1); wd_array[i].name); %s.\n?, for watch printf(?Can?t 0) (wd IN_ALL_EVENTS); wd_array[i].name, wd_array[i].name="monitored_files[i];" i++)>mask & IN_ISDIR) {memcpy(strbuf, "Direcotory", 11);}else {memcpy(strbuf, "File", 5);}printf("Object type: %s\n", strbuf);for (i=0; iwd != wd_array[i].wd) continue;printf("Object name: %s\n", wd_array[i].name);break;}printf("Event mask: %08X\n", event->mask);for (i=0; imask & (1<len;event = (struct inotify_event *)(offset + tmp_len); offset += tmp_len;}} }


轉自:http://linux.chinaitlab.com/kernel/391147_4.html












本文轉自張昺華-sky博客園博客,原文鏈接:http://www.cnblogs.com/sky-heaven/p/4837284.html,如需轉載請自行聯系原作者


總結

以上是生活随笔為你收集整理的Linux inotify功能及实现原理【转】的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 国产黄色免费视频 | 91亚洲精品久久久蜜桃网站 | 日日夜夜添 | 精品国产二区三区 | 精产国品一区二区三区 | 国产又爽又黄无码无遮挡在线观看 | 无码h肉动漫在线观看 | 91麻豆精品久久久久蜜臀 | 在线播放你懂的 | 久久香焦| 成人午夜福利视频 | 色一情 | 婷婷玖玖 | 成人毛片在线播放 | 午夜精品久久久久久久四虎美女版 | 超碰超碰超碰超碰 | 在线看成人 | 欧美成人黄色片 | 蜜臀久久99精品久久久久久宅男 | 青青视频一区二区 | 激情小说一区 | 国产麻豆一精品一av一免费 | 涩涩视频网站 | 不卡视频一区二区 | 色xxxx | 在线观看你懂的网站 | 久久久久国产精品区片区无码 | 午夜视频成人 | 久久久久久国 | 欧美乱人伦 | 好吊操这里有精品 | 毛片亚洲av无码精品国产午夜 | 亚洲欧美另类视频 | 日韩在线一二三区 | 欧美视频免费在线观看 | 97狠狠干| 99福利影院 | 中文字幕一区三区 | 亲嘴扒胸摸屁股激烈网站 | 小柔好湿好紧太爽了国产网址 | 在线黄色网 | 在线 日本 制服 中文 欧美 | 日本高清xxx | 亚洲17p | 噜噜噜久久 | 久久婷婷伊人 | 男人的天堂日韩 | 蜜臀99久久精品久久久久久软件 | 成人免费在线小视频 | 成人午夜免费福利视频 | 2024国产精品视频 | 国产精品视频导航 | 国产一级片在线播放 | 日本a在线天堂 | 师生出轨h灌满了1v1 | 国产日韩视频在线观看 | 日本久草视频 | 福利免费视频 | 国产精品99久久久久久一二区 | 手机av网 | 久久久无码18禁高潮喷水 | 天天综合天天做 | 中文字幕人妻一区二区三区在线视频 | 理论片亚洲 | 亚洲精品乱码久久 | 国产一区二区三区在线观看免费 | 久久精品人人爽 | 麻豆网站在线播放 | 黄色中文视频 | 后进极品美女白嫩翘臀 | 日皮视频网站 | 国产999在线 | 国产乱人乱偷精品视频 | 波多野结衣办公室33分钟 | 激情综合网五月 | 一本色道久久hezyo无码 | 自拍偷拍亚洲区 | 国产在线免费视频 | 亚欧综合在线 | 初高中福利视频网站 | www.av日韩 | 国产综合视频在线观看 | 欧美成人高潮一二区在线看 | 2019天天干天天操 | 欧美亚洲国产一区二区三区 | 国产超碰人人爽人人做人人爱 | 久久久久人妻精品色欧美 | 一级片视频免费观看 | 一区二区三区精品在线观看 | 欧美性插动态图 | 中文字幕亚洲一区二区三区 | 欧美性猛交乱大交 | 亚洲天堂五码 | 91拔萝卜视频 | 国产精品永久 | 国产激情第一页 | 激情拍拍 | 一区二区免费在线播放 | 男生舔女生的屁股 |