當(dāng)前位置:首頁(yè) > 嵌入式培訓(xùn) > 嵌入式學(xué)習(xí) > 講師博文 > 關(guān)于Inotify對(duì)linux文件系統(tǒng)的監(jiān)控
Linux提供了hotplup(熱插拔),udev和inotify機(jī)制幫助我們可以看到底層硬件設(shè)備發(fā)生了什么,從而能夠更好地管理設(shè)備,給用戶提供更好地服務(wù)。
Inotify通過(guò)如下三個(gè)系統(tǒng)調(diào)用和返回的文件描述符上的文件IO操作來(lái)使用。
Inotify的使用有如下幾個(gè)步驟:
1、創(chuàng)建'inotify實(shí)例(inotify_init())
2、添加一個(gè)watch(inotify_add_watch(fd,path,mask)) 刪除一個(gè)watch(inotify_rm_watch(fd,wd))
3、文件事件用一個(gè)inotify_event結(jié)構(gòu)表示
struct inotify_event {
__s32 wd; /* watch descriptor */
__u32 mask; /* watch mask */
__u32 cookie; /* cookie to synchronize two event*/
__u32 len; /* length (including nulls) of name */
char name[0]; /* stub for possible name */
};
4、Read調(diào)用可以一次獲得多個(gè)事件size_t len = read(fd,buf,BUF_LEN) 系統(tǒng)內(nèi)核的實(shí)現(xiàn)原理:
每個(gè)inotify實(shí)例對(duì)應(yīng)一個(gè)inotify_device結(jié)構(gòu):
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 */
};
使用實(shí)例:
#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 1024
int 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
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;
}
}
}