精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

inotify監(jiān)控Linux文件系統(tǒng)的必備利器

運(yùn)維 系統(tǒng)運(yùn)維
文件系統(tǒng)事件監(jiān)控對(duì)于從文件管理器到安全工具等多種程序來(lái)說(shuō)都是必要的。對(duì)于如何整理和控制Linux文件系統(tǒng)中的事件在實(shí)際的使用中有很多方式,inotify是比較常用的一種方法。在本文中你會(huì)學(xué)習(xí)到如何使用inotify以及他的一些相關(guān)知識(shí)。

本文主要向大家介紹了如何使用inotify控制Linux文件系統(tǒng)中的事件。在具體的學(xué)習(xí)之前我們先來(lái)看看什么是inotify以及他的歷史簡(jiǎn)介。我們還會(huì)向大家介紹inotify的具體應(yīng)用情況以及使中遇到問(wèn)題的解決方案。

inotify 介紹

文件系統(tǒng)事件監(jiān)控對(duì)于從文件管理器到安全工具等多種程序來(lái)說(shuō)都是必要的。自 2.6.13 版本內(nèi)核開(kāi)始,Linux 就提供 inotify 功能,這允許監(jiān)控程序打開(kāi)一個(gè)獨(dú)立文件描述符,并針對(duì)一系列特定的事件來(lái)監(jiān)控一個(gè)或多個(gè)文件或者目錄,例如打開(kāi)、關(guān)閉、移動(dòng)/重命名、 刪除、創(chuàng)建或者改變屬性。在以后的版本中還提供更多增強(qiáng)功能,因此在依賴這些特性之前請(qǐng)先檢查系統(tǒng)的內(nèi)核版本。

在本文中,您將學(xué)會(huì)如何在簡(jiǎn)單的監(jiān)控程序當(dāng)中使用 inotify 函數(shù)。下載樣例代碼 并在系統(tǒng)當(dāng)中進(jìn)行編譯,來(lái)為后面的研究做準(zhǔn)備。

歷史簡(jiǎn)介

在 inotify 之前有 dnotify 。不幸的是,dnotify 有局限性,無(wú)法滿足用戶的需求, inotify 的優(yōu)勢(shì)如下:

Inotify 采用簡(jiǎn)單的文件描述符,而 dnotify 需要為每個(gè)受監(jiān)控的目錄打開(kāi)一個(gè)文件描述符。 這使得同時(shí)監(jiān)控多個(gè)目錄成本很高,而且還會(huì)遇到每進(jìn)程文件描述符限制問(wèn)題。

inotify 所采用的文件描述符通過(guò)系統(tǒng)調(diào)用獲得,并且沒(méi)有相關(guān)的設(shè)備或文件。對(duì)于 dnotify ,文件描述符與目錄關(guān)系固定,避免了相關(guān)設(shè)備未被加載的問(wèn)題,這是可移動(dòng)媒體的典型問(wèn)題。對(duì)于 inotify ,如果受監(jiān)控文件或目錄所在的文件系統(tǒng)未被加載, 則會(huì)產(chǎn)生一個(gè)事件,然后該監(jiān)控會(huì)被自動(dòng)移除。

Inotify 能夠監(jiān)控文件或目錄。Dnotify 監(jiān)控目錄, 因此程序員必須保持 stat 結(jié)構(gòu)或者等效的數(shù)據(jù)結(jié)構(gòu),來(lái)反映目錄當(dāng)中被監(jiān)控的文件, 然后在一個(gè)事件發(fā)生時(shí),將其與當(dāng)前狀態(tài)進(jìn)行對(duì)比,來(lái)知曉目錄當(dāng)中的條目發(fā)生了什么情況。

如前面所述,inotify 采用文件描述符,允許程序員采用標(biāo)準(zhǔn) select 或者 poll 函數(shù)來(lái)對(duì)事件進(jìn)行監(jiān)控。 這允許高效的多重 I/O 或者與 Glib 的 mainloop 集成。相比之下,dnotify 采用信號(hào), 這使得程序員感到難度更大或者不夠流暢。 在 2.6.25 版本內(nèi)核中,inotify 也增加了 Signal-drive I.O 通告功能。

用于 inotify 的 API

Inotify 提供簡(jiǎn)單的 API ,采用最小的文件描述符并允許細(xì)粒度監(jiān)控。與 inotify 的通信通過(guò)系統(tǒng)調(diào)用實(shí)現(xiàn)。

inotify_init

是用于創(chuàng)建 inotify 實(shí)例的系統(tǒng)調(diào)用,并返回一個(gè)指向該實(shí)例的文件描述符。

inotify_init1

與 inotify_init 相似,并帶有附加標(biāo)志。如果這些標(biāo)志沒(méi)有指定,將采用與 inotify_init 相同的值。

inotify_add_watch

增加對(duì)文件或目錄的監(jiān)控并指定需要監(jiān)控哪些事件。 標(biāo)志用于控制是否將事件加入到已有的監(jiān)控當(dāng)中,是否只有路徑代表一個(gè)目錄才進(jìn)行監(jiān)控, 是否需要追蹤符號(hào)鏈接,是否進(jìn)行一次性監(jiān)控,當(dāng)首次出現(xiàn)事件后就停止監(jiān)控。

inotify_rm_watch

從監(jiān)控列表中移除監(jiān)控項(xiàng)目。

read

讀取包含一個(gè)或多個(gè)事件信息的緩存。

close

關(guān)閉文件描述符,并移除所有在該描述符上的監(jiān)控。 當(dāng)關(guān)于某一實(shí)例的文件描述符都關(guān)閉以后, 資源和下層的對(duì)象都將釋放,來(lái)供內(nèi)核再次使用。

因此,典型的監(jiān)控程序要進(jìn)行如下操作:

利用 inotify_init 打開(kāi)文件描述符;

增加一個(gè)或多個(gè)監(jiān)控;

等待事件;

處理事件,然后返回并等待更多事件;

當(dāng)沒(méi)有活躍的監(jiān)控時(shí)或者基于某些信號(hào)的指示,關(guān)閉文件描述符,清空,然后退出。

在下一部分中,您將看到可以監(jiān)控的事件,以及它們?nèi)绾卧诤?jiǎn)單程序當(dāng)中運(yùn)行。最后您將看到如何進(jìn)行事件監(jiān)控。

通告

當(dāng)應(yīng)用程序讀取一個(gè)通告時(shí),事件的順序也被讀取到緩存中。事件在一個(gè)變長(zhǎng)結(jié)構(gòu)體中被返回,見(jiàn)清單 1 。如果數(shù)據(jù)占滿了緩存,可能需要對(duì)最后一個(gè)條目進(jìn)行局部事件信息或者局部名處理。

清單 1. 用于 inotify 的事件結(jié)構(gòu)體

  1. struct inotify_event  
  2. {  
  3. int wd; /* Watch descriptor. */  
  4. uint32_t mask; /* Watch mask. */  
  5. uint32_t cookie; /* Cookie to synchronize two events. */  
  6. uint32_t len; /* Length (including NULs) of name. */  
  7. char name __flexarr; /* Name. */  
  8. }; 

注意,只有當(dāng)監(jiān)控對(duì)象是一個(gè)目錄并且事件與目錄內(nèi)部相關(guān)項(xiàng)目有關(guān),而與目錄本身無(wú)關(guān)時(shí),才提供 name 字段。 如果 IN_MOVED_FROM 事件與相應(yīng)的 IN_MOVED_TO 事件都與被監(jiān)控的項(xiàng)目有關(guān),cookie 就可用于將兩者關(guān)聯(lián)起來(lái)。 事件類型在掩碼字段中返回,并伴隨著能夠被內(nèi)核設(shè)置的標(biāo)志。 例如,如果事件與目錄有關(guān),則標(biāo)志 IN_ISDIR 將由內(nèi)核設(shè)置。

能夠監(jiān)控的事件

有幾種事件能夠被監(jiān)控。有一些,比如 IN_DELETE_SELF 只應(yīng)用到正在被監(jiān)控的項(xiàng)目,然而另一些比如 IN_ATTRIB 或者 IN_OPEN 可以應(yīng)用到監(jiān)控過(guò)的項(xiàng)目, 或者如果該項(xiàng)目是目錄,則可以應(yīng)用到其所包含的目錄或文件。

IN_ACCESS

被監(jiān)控項(xiàng)目或者被監(jiān)控目錄當(dāng)中的條目被訪問(wèn)過(guò)。例如,一個(gè)打開(kāi)的文件被讀取。

IN_MODIFY

被監(jiān)控項(xiàng)目或者被監(jiān)控目錄當(dāng)中的條目被修改過(guò)。例如,一個(gè)打開(kāi)的文件被修改。

IN_ATTRIB

被監(jiān)控項(xiàng)目或者被監(jiān)控目錄當(dāng)中條目的元數(shù)據(jù)被修改過(guò)。例如,時(shí)間戳或者許可被修改。

IN_CLOSE_WRITE

一個(gè)打開(kāi)的,等待寫入的文件或目錄被關(guān)閉。

IN_CLOSE_NOWRITE

一個(gè)以只讀方式打開(kāi)的文件或目錄被關(guān)閉。

IN_CLOSE

是可以很便捷地對(duì)前面提到的兩個(gè)關(guān)閉事件(IN_CLOSE_WRITE | IN_CLOSE_NOWRITE)進(jìn)行邏輯或操作的掩碼。

IN_OPEN

文件或目錄被打開(kāi)。

IN_MOVED_FROM

被監(jiān)控項(xiàng)目或者被監(jiān)控目錄當(dāng)中的條目被移出監(jiān)控區(qū)域。該事件還包含一個(gè) cookie 來(lái)實(shí)現(xiàn) IN_MOVED_FROM 與 IN_MOVED_TO 的關(guān)聯(lián)。

IN_MOVED_TO

文件或目錄被移入監(jiān)控區(qū)域。該事件包含一個(gè)針對(duì) IN_MOVED_FROM 的 cookie 。如果文件或目錄只是被重命名,將能看到這兩個(gè)事件,如果它只是被移入或移出非監(jiān)控區(qū)域,將只能看到一個(gè)事件。 如果移動(dòng)或重命名一個(gè)被監(jiān)控項(xiàng)目,監(jiān)控將繼續(xù)進(jìn)行。參見(jiàn)下面的 IN_MOVE-SELF 。

IN_MOVE

是可以很便捷地對(duì)前面提到的兩個(gè)移動(dòng)事件(IN_MOVED_FROM | IN_MOVED_TO)進(jìn)行邏輯或操作的掩碼。

IN_CREATE

在被監(jiān)控目錄當(dāng)中創(chuàng)建了子目錄或文件。

IN_DELETE

被監(jiān)控目錄當(dāng)中有子目錄或文件被刪除。

IN_DELETE_SELF

被監(jiān)控項(xiàng)目本身被刪除。監(jiān)控被終止并收到一個(gè) IN_IGNORED 事件。

IN_MOVE_SELF

監(jiān)控項(xiàng)目本身被移動(dòng)。

除了事件標(biāo)志以外,還可以在 inotify 頭文件(/usr/include/sys/inotify.h)中找到其他幾個(gè)標(biāo)志。 例如,如果只想監(jiān)控第一個(gè)事件,可以在增加監(jiān)控時(shí)設(shè)置 IN_ONESHOT 標(biāo)志。#p#

inotify 簡(jiǎn)單應(yīng)用

這里的簡(jiǎn)單應(yīng)用遵循以上的通用邏輯。 我們使用一個(gè)信號(hào)處理程序來(lái)監(jiān)控 ctrl-c(SIGINT)并且 重置一個(gè)標(biāo)志(keep_running)使應(yīng)用了解終止操作。 真實(shí)的 inotify 調(diào)用在 utility 例程當(dāng)中完成。注意, 我們還創(chuàng)建了一個(gè)隊(duì)列,這樣能夠?qū)⑹录?inotify 底層對(duì)象中清除,留著稍后處理。在真實(shí)的應(yīng)用當(dāng)中,您可能希望用其他(具有更高優(yōu)先級(jí))的線程來(lái)完成這一操作。 這里的列舉的應(yīng)用程序,只是為了對(duì)一般原理進(jìn)行舉例說(shuō)明。我們采用了一個(gè)簡(jiǎn)單的事件鏈表, 隊(duì)列中的每一條目都包含原始事件加上用于存儲(chǔ)指向隊(duì)列中下一事件指針的空間。

主程序

清單 2 中展示了信號(hào)處理程序和主程序。在本例當(dāng)中,對(duì)所有在命令行中出現(xiàn)過(guò)的文件或目錄進(jìn)行監(jiān)控, 并利用事件掩碼 IN_ALL_EVENTS 來(lái)監(jiān)控每一對(duì)象的所有事件。 在真實(shí)的應(yīng)用程序中,您可能只希望追蹤文件與目錄的創(chuàng)建或刪除事件,因此您可以掩去打開(kāi)、關(guān)閉以及屬性改變事件。 如果您對(duì)文件或目錄的重命名和移動(dòng)不感興趣,您也可以掩去各種移動(dòng)事件。關(guān)于更多細(xì)節(jié),參見(jiàn) inotify 幫助信息。

清單 2. inotify-test.c 的簡(jiǎn)單主程序

  1. /* Signal handler that simply resets a flag to cause termination */  
  2. void signal_handler (int signum)  
  3. {  
  4. keep_running = 0;  
  5. }  
  6. int main (int argc, char **argv)  
  7. {  
  8. /* This is the file descriptor for the inotify watch */  
  9. int inotify_fd;  
  10. keep_running = 1;  
  11. /* Set a ctrl-c signal handler */  
  12. if (signal (SIGINT, signal_handler) == SIG_IGN)  
  13. {  
  14. /* Reset to SIG_IGN (ignore) if that was the prior state */  
  15. signal (SIGINT, SIG_IGN);  
  16. }  
  17. /* First we open the inotify dev entry */  
  18. inotify_fd = open_inotify_fd ();  
  19. if (inotify_fd > 0)  
  20. {  
  21. /* We will need a place to enqueue inotify events,  
  22. this is needed because if you do not read events  
  23. fast enough, you will miss them. This queue is   
  24. probably too small if you are monitoring something  
  25. like a directory with a lot of files and the directory   
  26. is deleted.  
  27. */  
  28. queue_t q;  
  29. q = queue_create (128);  
  30. /* This is the watch descriptor returned for each item we are   
  31. watching. A real application might keep these for some use   
  32. in the application. This sample only makes sure that none of  
  33. the watch descriptors is less than 0.  
  34. */  
  35. int wd;  
  36. /* Watch all events (IN_ALL_EVENTS) for the directories and   
  37. files passed in as arguments.  
  38. Read the article for why you might want to alter this for   
  39. more efficient inotify use in your app.   
  40. */  
  41. int index;  
  42. wd = 0;  
  43. printf("\n");  
  44. for (index = 1; (index < argc) && (wd >= 0); index++)   
  45. {  
  46. wd = watch_dir (inotify_fd, argv[index], IN_ALL_EVENTS);  
  47. }  
  48. if (wd > 0)   
  49. {  
  50. /* Wait for events and process them until a   
  51. termination condition is detected  
  52. */  
  53. process_inotify_events (q, inotify_fd);  
  54. }  
  55. printf ("\nTerminating\n");  
  56. /* Finish up by closing the fd, destroying the queue,  
  57. and returning a proper code  
  58. */  
  59. close_inotify_fd (inotify_fd);  
  60. queue_destroy (q);  
  61. }  
  62. return 0;  

利用 inotify_init 打開(kāi)文件描述符

清單 3 展示了用于創(chuàng)建 inotify 實(shí)例的簡(jiǎn)單應(yīng)用函數(shù),并為其獲得一個(gè)文件描述符。文件描述符返回給了調(diào)用者。 如果出現(xiàn)錯(cuò)誤,返回值將為負(fù)。

清單 3. 使用 inotify_init

  1. /* Create an inotify instance and open a file descriptor  
  2. to access it */  
  3. int open_inotify_fd ()  
  4. {  
  5. int fd;  
  6. watched_items = 0;  
  7. fd = inotify_init ();  
  8. if (fd < 0)  
  9. {  
  10. perror ("inotify_init () = ");  
  11. }  
  12. return fd;  

利用 inotify_add_watch 來(lái)增加監(jiān)控

有了用于 inotify 實(shí)例的文件描述符之后,就需要增加一個(gè)或多個(gè)監(jiān)控。 可以使用掩碼來(lái)設(shè)置想要監(jiān)控的事件。在本例當(dāng)中,采用掩碼 IN_ALL_EVENTS,來(lái)監(jiān)控全部的有效事件。

清單 4. 使用 inotify_add_watch

  1. int watch_dir (int fd, const char *dirname, unsigned long mask)  
  2. {  
  3. int wd;  
  4. wd = inotify_add_watch (fd, dirname, mask);  
  5. if (wd < 0)  
  6. {  
  7. printf ("Cannot add watch for \"%s\" with event mask %lX", dirname,  
  8. mask);  
  9. fflush (stdout);  
  10. perror (" ");  
  11. }  
  12. else  
  13. {  
  14. watched_items++;  
  15. printf ("Watching %s WD=%d\n", dirname, wd);  
  16. printf ("Watching = %d items\n", watched_items);   
  17. }  
  18. return wd;  

#p#事件處理循環(huán)

現(xiàn)在我們已經(jīng)設(shè)置了一些監(jiān)控,接下來(lái)就要等待事件。如果還存在監(jiān)控,并且 keep_running 標(biāo)志沒(méi)有被信號(hào)處理程序重置,則循環(huán)會(huì)一直進(jìn)行。循環(huán)進(jìn)程等待事件的發(fā)生,對(duì)有效事件進(jìn)行排隊(duì),并在返回等待狀態(tài)之前并處理隊(duì)列。 在真實(shí)應(yīng)用程序當(dāng)中,可能會(huì)采用一個(gè)線程將事件放入隊(duì)列,而采用另一個(gè)線程處理它們,清單 5 展示了該循環(huán)。

清單 5. 事件處理循環(huán)

  1. int process_inotify_events (queue_t q, int fd)  
  2. {  
  3. while (keep_running && (watched_items > 0))  
  4. {  
  5. if (event_check (fd) > 0)  
  6. {  
  7. int r;  
  8. r = read_events (q, fd);  
  9. if (r < 0)  
  10. {  
  11. break;  
  12. }  
  13. else  
  14. {  
  15. handle_events (q);  
  16. }  
  17. }  
  18. }  
  19. return 0;  

等待事件

在本程序中,循環(huán)會(huì)不停地進(jìn)行下去,直至發(fā)生被監(jiān)控事件或者收到了中斷信號(hào)。清單 6 展示了相關(guān)代碼。

清單 6. 等待事件或中斷

  1. int event_check (int fd)  
  2. {  
  3. fd_set rfds;  
  4. FD_ZERO (&rfds);  
  5. FD_SET (fd, &rfds);  
  6. /* Wait until an event happens or we get interrupted   
  7. by a signal that we catch */  
  8. return select (FD_SETSIZE, &rfds, NULL, NULL, NULL);  

讀取事件

當(dāng)事件發(fā)生時(shí),程序會(huì)依照緩存區(qū)的大小來(lái)讀取盡量多的事件,然后把這些事件放入隊(duì)列等待事件處理程序來(lái)處理。 樣例代碼對(duì)于事件量大于 16.384-byte 之類的問(wèn)題不作處理。 想處理這類問(wèn)題,需要在緩存末端處理局部事件。當(dāng)前對(duì)名字長(zhǎng)度所做的限制沒(méi)有問(wèn)題,但是優(yōu)秀的防御式編程會(huì)檢查名字,來(lái)確保不會(huì)出現(xiàn)緩存區(qū)溢出。

清單 7. 讀取事件并排隊(duì)

  1. int read_events (queue_t q, int fd)  
  2. {  
  3. char buffer[16384];  
  4. size_t buffer_i;  
  5. struct inotify_event *pevent;  
  6. queue_entry_t event;  
  7. ssize_t r;  
  8. size_t event_size, q_event_size;-  
  9. int count = 0;  
  10. r = read (fd, buffer, 16384);  
  11. if (r <= 0)  
  12. return r;  
  13. buffer_i = 0;  
  14. while (buffer_i < r)  
  15. {  
  16. /* Parse events and queue them. */  
  17. pevent = (struct inotify_event *) &buffer[buffer_i];  
  18. event_size = offsetof (struct inotify_event, name) + pevent->
    len;  
  19. q_event_size = offsetof (struct queue_entry, inot_ev.name) +   
  20. pevent->len;  
  21. event = malloc (q_event_size);  
  22. memmove (&(event->inot_ev), pevent, event_size);  
  23. queue_enqueue (event, q);  
  24. buffer_i += event_size;  
  25. count++;  
  26. }  
  27. printf ("\n%d events queued\n", count);  
  28. return count;  

處理事件

最終,需要對(duì)事件做處理。本例中的應(yīng)用程序不處理事件,只報(bào)告發(fā)生了哪些事件。如果事件結(jié)構(gòu)體中有一個(gè)名字出現(xiàn), 程序?qū)?bào)告其是目錄還是文件。在發(fā)生移動(dòng)操作時(shí),還會(huì)報(bào)告與移動(dòng)或重命名事件相關(guān)的 cookie 信息。 清單 8 展示了部分代碼,包括對(duì)一些事件的處理。參見(jiàn) 下載 部分可獲得全部代碼。

清單 8. 處理事件

  1. void handle_event (queue_entry_t event)  
  2. {  
  3. /* If the event was associated with a filename, we will 
    store it here */  
  4. char *cur_event_filename = NULL;  
  5. char *cur_event_file_or_dir = NULL;  
  6. /* This is the watch descriptor the event occurred on */  
  7. int cur_event_wd = event->inot_ev.wd;  
  8. int cur_event_cookie = event->inot_ev.cookie;  
  9. unsigned long flags;  
  10. if (event->inot_ev.len)  
  11. {  
  12. cur_event_filename = event->inot_ev.name;  
  13. }  
  14. if ( event->inot_ev.mask & IN_ISDIR )  
  15. {  
  16. cur_event_file_or_dir = "Dir";  
  17. }  
  18. else   
  19. {  
  20. cur_event_file_or_dir = "File";  
  21. }  
  22. flags = event->inot_ev.mask &   
  23. ~(IN_ALL_EVENTS | IN_UNMOUNT | IN_Q_OVERFLOW | IN_IGNORED );  
  24. /* Perform event dependent handler routines */  
  25. /* The mask is the magic that tells us what file operation 
    occurred */  
  26. switch (event->inot_ev.mask &   
  27. (IN_ALL_EVENTS | IN_UNMOUNT | IN_Q_OVERFLOW | IN_IGNORED))  
  28. {  
  29. /* File was accessed */  
  30. case IN_ACCESS:  
  31. printf ("ACCESS: %s \"%s\" on WD #%i\n",  
  32. cur_event_file_or_dir, cur_event_filename, cur_event_wd);  
  33. break;  
  34. /* File was modified */  
  35. case IN_MODIFY:  
  36. printf ("MODIFY: %s \"%s\" on WD #%i\n",  
  37. cur_event_file_or_dir, cur_event_filename, cur_event_wd);  
  38. break;  
  39. /* File changed attributes */  
  40. case IN_ATTRIB:  
  41. printf ("ATTRIB: %s \"%s\" on WD #%i\n",  
  42. cur_event_file_or_dir, cur_event_filename, cur_event_wd);  
  43. break;  
  44. /* File open for writing was closed */  
  45. case IN_CLOSE_WRITE:  
  46. printf ("CLOSE_WRITE: %s \"%s\" on WD #%i\n",  
  47. cur_event_file_or_dir, cur_event_filename, cur_event_wd);  
  48. break;  
  49. /* File open read-only was closed */  
  50. case IN_CLOSE_NOWRITE:  
  51. printf ("CLOSE_NOWRITE: %s \"%s\" on WD #%i\n",  
  52. cur_event_file_or_dir, cur_event_filename, cur_event_wd);  
  53. break;  
  54. /* File was opened */  
  55. case IN_OPEN:  
  56. printf ("OPEN: %s \"%s\" on WD #%i\n",  
  57. cur_event_file_or_dir, cur_event_filename, cur_event_wd);  
  58. break;  
  59. /* File was moved from X */  
  60. case IN_MOVED_FROM:  
  61. printf ("MOVED_FROM: %s \"%s\" on WD #%i. Cookie=%d\n",  
  62. cur_event_file_or_dir, cur_event_filename, cur_event_wd,   
  63. cur_event_cookie);  
  64. break;  
  65. .  
  66. . (other cases)  
  67. .  
  68. /* Watch was removed explicitly by inotify_rm_watch or 
    automatically  
  69. because file was deleted, or file system was unmounted. */  
  70. case IN_IGNORED:  
  71. watched_items--;  
  72. printf ("IGNORED: WD #%d\n", cur_event_wd);  
  73. printf("Watching = %d items\n",watched_items);   
  74. break;  
  75. /* Some unknown message received */  
  76. default:  
  77. printf ("UNKNOWN EVENT \"%X\" OCCURRED for file \"%s\" on WD #%i\n",  
  78. event->inot_ev.mask, cur_event_filename, cur_event_wd);  
  79. break;  
  80. }  
  81. /* If any flags were set other than IN_ISDIR, report the flags */  
  82. if (flags & (~IN_ISDIR))  
  83. {  
  84. flags = event->inot_ev.mask;  
  85. printf ("Flags=%lX\n", flags);  
  86. }  

該例子用來(lái)舉例說(shuō)明 inotify 如何工作以及能夠監(jiān)控哪些事件。 您的實(shí)際需求將決定對(duì)哪些事件進(jìn)行監(jiān)控以及如何處理這些事件。#p#

用法舉例

在這部分當(dāng)中,我們創(chuàng)建一個(gè)簡(jiǎn)單的兩級(jí)目錄結(jié)構(gòu),目錄中有一個(gè)文件, 然后運(yùn)行簡(jiǎn)單程序來(lái)舉例說(shuō)明 inotify 所能監(jiān)控的一些事件。 我們將在一個(gè)終端會(huì)話中啟動(dòng) inotify 樣例程序, 但是因?yàn)樗窃诤笈_(tái)運(yùn)行的(利用 &)因此程序的輸出與我們輸入的命令會(huì)交替出現(xiàn)。 應(yīng)該在一個(gè)終端窗口運(yùn)行該程序,而在其他窗口輸入命令。清單 9 展示了簡(jiǎn)單文件結(jié)構(gòu)和空文件的創(chuàng)建,以及最初啟動(dòng)該簡(jiǎn)單程序時(shí)的輸出。

清單 9. 創(chuàng)建樣例環(huán)境

  1. ian@attic4:~/inotify-sample$ mkdir -p dir1/dir2  
  2. ian@attic4:~/inotify-sample$ touch dir1/dir2/file1  
  3. ian@attic4:~/inotify-sample$ ./inotify_test dir1/ 
    dir1/dir2/ dir1/dir2/file1&  
  4. [2] 8733  
  5. ian@attic4:~/inotify-sample$   
  6. Watching dir1/ WD=1 
  7. Watching = 1 items  
  8. Watching dir1/dir2/ WD=2 
  9. Watching = 2 items  
  10. Watching dir1/dir2/file1 WD=3 
  11. Watching = 3 items  
  12. ian@attic4:~/inotify-sample$  

在清單 10 當(dāng)中,展示了列舉 dir2 內(nèi)容時(shí)的輸出。 第一個(gè)事件報(bào)告與 dir1 有關(guān),顯示出有些東西,名字叫做 dir2 ,在與監(jiān)控描述符 1 相關(guān)的被監(jiān)控目錄當(dāng)中被打開(kāi)了。 第二個(gè)條目與監(jiān)控描述符 2 有關(guān),顯示出被監(jiān)控項(xiàng)目(在本例中為 dir2 )被打開(kāi)了。如果正在監(jiān)控目錄樹(shù)中的多個(gè)項(xiàng)目, 可能會(huì)經(jīng)常遇到這種雙重輸出。

清單 10. 列出 dir2 的內(nèi)容

  1. ian@attic4:~/inotify-sample$ ls dir1/dir2  
  2. file1  
  3. 4 events queued  
  4. OPEN: Dir "dir2" on WD #1  
  5. OPEN: Dir "(null)" on WD #2  
  6. CLOSE_NOWRITE: Dir "dir2" on WD #1  
  7. CLOSE_NOWRITE: Dir "(null)" on WD #2 

在清單 11 當(dāng)中,在 file1 中加入一些文字。需要再次強(qiáng)調(diào)對(duì)于文件以及該文件所在目錄的雙重打開(kāi),關(guān)閉,和修改事件。還要注意不是全部事件都會(huì)被立刻讀取。排隊(duì)例程被調(diào)用了3次,每次有兩個(gè)事件。如果再次運(yùn)行該程序,并且每次操作相同,您未必會(huì)再次遇到這一特別情況。

清單 11. 在 file1 中加入一些文字

  1. ian@attic4:~/inotify-sample$ echo "Some text" >> dir1/dir2/file1  
  2. 2 events queued  
  3. OPEN: File "file1" on WD #2  
  4. OPEN: File "(null)" on WD #3  
  5. 2 events queued  
  6. MODIFY: File "file1" on WD #2  
  7. MODIFY: File "(null)" on WD #3  
  8. 2 events queued  
  9. CLOSE_WRITE: File "file1" on WD #2  
  10. CLOSE_WRITE: File "(null)" on WD #3 

在清單 12 當(dāng)中,改變 file1 的屬性。我們?cè)俅蔚玫接嘘P(guān)被監(jiān)控項(xiàng)目以及其所在目錄的雙重輸出。

清單 12. 改變文件屬性

  1. ian@attic4:~/inotify-sample$ chmod a+w dir1/dir2/file1  
  2. 2 events queued  
  3. ATTRIB: File "file1" on WD #2  
  4. ATTRIB: File "(null)" on WD #3 

現(xiàn)在將文件 file1 移動(dòng)到上一級(jí)目錄 dir1 當(dāng)中。在清單 13 中顯示了輸出結(jié)果。 這次沒(méi)有雙重條目。我們實(shí)際上得到了 3 個(gè)條目,每個(gè)目錄一個(gè),文件本身一個(gè)。 注意 cookie (569) 允許將 MOVED-FROM 事件與 MOVED_TO 事件關(guān)聯(lián)起來(lái)。

清單 13. 將文件 file1 移入 dir1

  1. ian@attic4:~/inotify-sample$ mv dir1/dir2/file1 dir1  
  2. 3 events queued  
  3. MOVED_FROM: File "file1" on WD #2. Cookie=569 
  4. MOVED_TO: File "file1" on WD #1. Cookie=569 
  5. MOVE_SELF: File "(null)" on WD #3 

現(xiàn)在創(chuàng)建一個(gè) file1 到 file2 的硬鏈接。由于到 inode 的鏈接數(shù)量變了,我們得到針對(duì) file1 的 ATTRIB 事件,還得到一個(gè)針對(duì) file2 的 CREATE 事件。

清單 14. 創(chuàng)建硬鏈接

  1. ian@attic4:~/inotify-sample$ ln dir1/file1 dir1/file2  
  2. 2 events queued  
  3. ATTRIB: File "(null)" on WD #3  
  4. CREATE: File "file2" on WD #1 

現(xiàn)在將文件 file1 移入當(dāng)前目錄,將其重命名為 file3 。當(dāng)前目錄沒(méi)有被監(jiān)控,因此不存在與 MOVED_FROM 事件相關(guān)聯(lián)的 MOVED_TO 事件。

清單 15. 將 file1 移入不受監(jiān)控的目錄當(dāng)中

  1. ian@attic4:~/inotify-sample$ mv dir1/file1 ./file3  
  2. 2 events queued  
  3. MOVED_FROM: File "file1" on WD #1. Cookie=572 
  4. MOVE_SELF: File "(null)" on WD #3 

此時(shí),dir2 是空的,因此可以移動(dòng)它。注意我們得到一個(gè)關(guān)于監(jiān)控描述符 2 的 IGNORED 事件,可見(jiàn)我們只在監(jiān)控兩個(gè)項(xiàng)目。

清單 16. 移動(dòng) dir2

  1. ian@attic4:~/inotify-sample$ rmdir dir1/dir2  
  2. 3 events queued  
  3. DELETE: Dir "dir2" on WD #1  
  4. DELETE_SELF: File "(null)" on WD #2  
  5. IGNORED: WD #2  
  6. Watching = 2 items 

移動(dòng)文件 file3。注意這次我們沒(méi)有得到 IGNORED 事件。為什么呢?為什么得到了關(guān)于 file 3 的 ATTRIB 事件(就是原來(lái)的 dir1/dir2/file1)?

清單 17. 刪除 file3

  1. ian@attic4:~/inotify-sample$ rm file3  
  2. 1 events queued  
  3. ATTRIB: File "(null)" on WD #3 

記住我們創(chuàng)建了 file1 到 file2 的硬鏈接。清單 17 顯示我們還在通過(guò)監(jiān)控描述符 3 來(lái)監(jiān)控 file2,盡管最開(kāi)始不存在文件 2!

清單 18. 仍對(duì) file2 進(jìn)行監(jiān)控!

  1. ian@attic4:~/inotify-sample$ touch dir1/file2  
  2. 6 events queued  
  3. OPEN: File "file2" on WD #1  
  4. OPEN: File "(null)" on WD #3  
  5. ATTRIB: File "file2" on WD #1  
  6. ATTRIB: File "(null)" on WD #3  
  7. CLOSE_WRITE: File "file2" on WD #1  
  8. CLOSE_WRITE: File "(null)" on WD #3 

現(xiàn)在刪除 dir1 來(lái)監(jiān)控事件級(jí)聯(lián),因?yàn)槌绦蛩槐O(jiān)控任何事,它結(jié)束了自己。

清單 19. 刪除 dir1

  1. ian@attic4:~/inotify-sample$ rm -rf dir1  
  2. 8 events queued  
  3. OPEN: Dir "(null)" on WD #1  
  4. ATTRIB: File "(null)" on WD #3  
  5. DELETE_SELF: File "(null)" on WD #3  
  6. IGNORED: WD #3  
  7. Watching = 1 items  
  8. DELETE: File "file2" on WD #1  
  9. CLOSE_NOWRITE: Dir "(null)" on WD #1  
  10. DELETE_SELF: File "(null)" on WD #1  
  11. IGNORED: WD #1  
  12. Watching = 0 items  
  13. Terminating 

inotify 的使用情況

可將 inotify 用于多種目標(biāo)。下面列舉一些可能的情況:

性能監(jiān)控

您可能想確定應(yīng)用程序打開(kāi)最頻繁的文件是哪個(gè)。如果發(fā)現(xiàn)一個(gè)小文件被頻繁打開(kāi)與關(guān)閉, 您可能會(huì)考慮采用內(nèi)存版,或者改變應(yīng)用程序來(lái)采取其他方式共享該數(shù)據(jù)。

元信息

您可能想記錄文件的附加信息,例如起始創(chuàng)建時(shí)間,或者最后改變?cè)撐募挠脩?id 。

安全

您可能會(huì)因?yàn)榘踩颍枰獙?duì)特定文件或目錄的所有訪問(wèn)進(jìn)行監(jiān)控。

我們的樣例代碼監(jiān)控所有事件并進(jìn)行報(bào)告。實(shí)際上,您可能想依據(jù)您的需要,來(lái)查看這些事件的特定子集。您可能想監(jiān)控不同被監(jiān)控項(xiàng)目的不同事件。例如,您可能想監(jiān)控文件的打開(kāi)與關(guān)閉事件,但對(duì)于目錄只想監(jiān)控創(chuàng)建與刪除事件。在任何可能的時(shí)候,您可以監(jiān)控您所感興趣的最小事件集。

結(jié)束語(yǔ)

在應(yīng)用到性能監(jiān)控,程序調(diào)試,以及自動(dòng)化等領(lǐng)域時(shí),inotify 是功能強(qiáng)大,高級(jí)粒度機(jī)制的 Linux 文件系統(tǒng)監(jiān)控工具。利用本文提供的樣例代碼,您可以開(kāi)始編寫用來(lái)實(shí)時(shí)記錄文件系統(tǒng)事件并最小化性能開(kāi)銷的應(yīng)用程序。

【編輯推薦】

  1. Linux inotify使用安裝創(chuàng)建設(shè)備
  2. 四大Linux文件系統(tǒng)在2.6.34內(nèi)核下的基準(zhǔn)測(cè)試
  3. 下一代Linux文件系統(tǒng)將如何發(fā)展?
  4. Linux文件系統(tǒng)組織結(jié)構(gòu)簡(jiǎn)說(shuō)分析結(jié)構(gòu)
責(zé)任編輯:張浩 來(lái)源: IBMDW
相關(guān)推薦

2010-05-07 15:40:18

ibmdwLinux

2010-11-04 10:16:11

inotify監(jiān)控Linux文件系統(tǒng)

2009-10-28 12:05:32

linux監(jiān)控技術(shù)

2011-01-13 14:10:30

Linux文件系統(tǒng)

2020-07-22 14:53:06

Linux系統(tǒng)虛擬文件

2017-04-20 14:55:36

LinuxPyinotifyPython

2021-04-12 05:44:44

Linux文件系統(tǒng)

2021-06-06 16:55:22

Linux文件系統(tǒng)

2020-09-25 07:48:12

Linux系統(tǒng)文件

2012-05-10 13:49:44

Linux文件系統(tǒng)

2011-01-11 10:29:35

Linux文件

2009-12-14 13:14:57

2011-01-13 13:18:38

Linux網(wǎng)絡(luò)文件

2021-11-01 13:38:55

Linux文件系統(tǒng)

2009-12-25 09:58:46

linux劃分文件系統(tǒng)

2009-12-22 15:12:33

Linux擴(kuò)展文件系統(tǒng)

2018-08-24 10:10:25

Linux文件系統(tǒng)技術(shù)

2019-09-20 10:04:45

Linux系統(tǒng)虛擬文件

2020-01-15 09:10:13

LinuxWindowsmacOS

2021-05-31 07:50:59

Linux文件系統(tǒng)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

91色国产在线| 欧洲亚洲一区| 日本三级免费看| 国产成人av| 欧美性淫爽ww久久久久无| 中文字幕精品—区二区日日骚| 精品国产亚洲av麻豆| 亚洲日韩成人| 日韩在线观看免费高清| 91视频在线免费| 日韩精品一页| 欧美性猛xxx| 国产av不卡一区二区| 天堂在线视频免费观看| 老司机精品视频导航| 久久久久久久成人| 国产一区二区三区四区在线| 中文字幕一区二区三区日韩精品| 色婷婷久久久久swag精品| 日韩视频一二三| 国产中文在线视频| 国产不卡在线一区| 国产精品亚洲视频在线观看| 日本高清www免费视频| 羞羞答答成人影院www| 亚洲欧洲中文天堂| 国产一级免费片| 91视频成人| 欧美日韩一区二区在线视频| 欧美 激情 在线| av资源在线看片| 亚洲精品乱码久久久久久久久 | 成熟老妇女视频| 蜜臀av在线| 亚洲欧美日韩中文字幕一区二区三区| 日本一区二区精品| 少妇性bbb搡bbb爽爽爽欧美| 国产a久久麻豆| 91精品国自产在线观看 | 日韩欧美国产系列| 邪恶网站在线观看| 欧美xxxx做受欧美护士| 欧美日韩中文在线观看| www..com日韩| 日韩三级免费| 亚洲最新视频在线播放| 日韩精品一区二区三区电影| 欧美黑人激情| 中文字幕色av一区二区三区| 亚欧精品在线| 国产日韩精品在线看| 久久综合狠狠综合久久激情| 国内精品久久国产| 天天射天天操天天干| 国产99久久精品| 91观看网站| 成人高潮片免费视频| 国产精品一区二区黑丝| 99精品国产一区二区| 性一交一乱一精一晶| 粉嫩13p一区二区三区| 国产日韩一区欧美| 五月婷婷激情在线| a在线欧美一区| 精品午夜一区二区三区| 天堂成人在线| 久久久久久久久久久久久夜| 亚洲高清资源综合久久精品| 亚洲精品传媒| 亚洲免费观看高清完整版在线观看 | 国产乱淫av片免费| 国产激情一区二区三区| 国产精品免费一区二区三区观看| 欧美一级在线免费观看| 91色乱码一区二区三区| 日韩电影大全在线观看| 日本电影在线观看网站| 亚洲精品一二三| 成人黄色av片| 精品日韩视频| 制服丝袜成人动漫| 亚洲高清无码久久| 国内精品伊人久久久| 日韩一区二区在线视频| 麻豆国产尤物av尤物在线观看| 亚洲国产mv| 国产精品wwwwww| www.97av| 国产欧美久久久精品影院| 一级黄色片播放| 黄毛片在线观看| 欧美老人xxxx18| 国产69视频在线观看| 狠狠色丁香婷婷综合影院| 色偷偷噜噜噜亚洲男人的天堂| 欧美精品入口蜜桃| 日韩二区在线观看| 成人欧美一区二区三区黑人免费| 毛片在线播放网址| 亚洲欧美日韩电影| 久久精品一区二| 免费观看性欧美大片无片| 亚洲精品久久久一区二区三区| 天堂在线中文视频| 国产一区亚洲| 国产伦精品一区二区三区精品视频 | 多野结衣av一区| 欧美猛男超大videosgay| 亚洲麻豆一区二区三区| 97视频热人人精品免费| 91大神在线播放精品| 国产免费不卡av| 国产日韩欧美一区二区三区综合| 日产精品久久久久久久蜜臀| 国产a亚洲精品| 亚洲第一福利网站| 欧美性x x x| 日韩精品一二三| 久久九九视频| www.8ⅹ8ⅹ羞羞漫画在线看| 9191国产精品| 天天操天天干天天操天天干| 一区二区三区成人精品| 97操在线视频| 看黄网站在线| 欧美日韩中文国产| 91精品人妻一区二区三区| 极品尤物久久久av免费看| 91视频88av| 免费在线观看av| 欧美性欧美巨大黑白大战| 青青草视频播放| 91久久亚洲| 成人免费91在线看| 日本动漫理论片在线观看网站 | 亚洲黄色小视频在线观看| 色婷婷av一区二区三区丝袜美腿| 欧美激情亚洲国产| 丰满熟女一区二区三区| 亚洲精品自拍动漫在线| 999久久久精品视频| 日本久久黄色| 国产精品人成电影在线观看| 可以在线观看的av网站| 一本色道久久综合精品竹菊| 国产三级视频网站| 午夜影院日韩| 久热国产精品视频一区二区三区| 老牛影视精品| 亚洲欧洲在线观看| 欧美精品韩国精品| 久久亚洲欧美国产精品乐播| 久久久噜噜噜www成人网| 欧美色图婷婷| 日本精品免费观看| 国产福利片在线| 欧美色国产精品| 最新一区二区三区| 国产经典欧美精品| 丁香六月激情婷婷| 日韩av影院| 国产成人一区二区| 91美女视频在线| 91精品中文字幕一区二区三区| 三级全黄做爰视频| 国产福利一区在线| av在线播放天堂| 啪啪激情综合网| 国产精品91在线观看| av网站无病毒在线| 4438x亚洲最大成人网| 国产免费无码一区二区视频| 成人少妇影院yyyy| 欧美成人免费高清视频| 久久理论电影| 成人h在线播放| 亚洲国产欧美日本视频| 中文字幕日韩综合av| 国内精品久久久久久久久久| 精品久久久久久中文字幕大豆网| 亚洲一区二区三区蜜桃| 经典一区二区三区| 无码粉嫩虎白一线天在线观看 | 成人一区二区三区中文字幕| 日韩中文字幕三区| 99精品一区| 国产三级精品在线不卡| 成人国产激情在线| 欧美精品久久久久久久久久| 久青青在线观看视频国产| 91精品国产乱| 亚洲成人第一网站| 亚洲精品综合在线| 精品欧美一区二区久久久| 国产美女主播视频一区| 国产淫片免费看| 亚洲xxx拳头交| 久久99影院| 伊人久久综合网另类网站| 91超碰caoporn97人人| 天堂а√在线资源在线| 亚洲第一区在线| 91tv国产成人福利| 欧美日韩亚洲网| 亚洲国产精品久| 国产精品你懂的在线| 欧产日产国产精品98| 激情五月婷婷综合网| 欧美国产激情视频| 欧美婷婷在线| 中文字幕一区综合| 伊人久久大香线蕉无限次| 亚洲自拍偷拍一区| 国产精品蜜月aⅴ在线| 91国在线精品国内播放| 91精品久久久久久粉嫩| 在线成人激情视频| 神马久久高清| 精品国产乱码久久久久久浪潮| 中文字幕在线观看国产| 色综合久久66| 国产成人精品a视频一区| 亚洲柠檬福利资源导航| 激情五月深爱五月| 久久精品人人做人人爽人人| 又黄又色的网站| 国产酒店精品激情| 天天干天天色天天干| 青椒成人免费视频| avav在线看| 国产精品主播| 精品国产一二三四区| 影音先锋日韩资源| 国产精品视频网站在线观看| 重囗味另类老妇506070| 色中文字幕在线观看| 久久视频国产| 在线观看日韩羞羞视频| 成人情趣视频网站| 天堂一区二区三区| 国内成人精品| 水蜜桃亚洲精品| 日韩一区二区中文| 一区二区不卡在线观看| 三级电影一区| 正在播放国产精品| 亚洲xxx拳头交| 青青在线视频免费观看| 色爱综合网欧美| 亚洲一区二区三区精品视频| 色88久久久久高潮综合影院| 伊人久久大香线蕉成人综合网 | www.九色.com| 亚洲精品影院在线观看| 日韩av片在线看| 日韩有码一区二区三区| 蜜桃免费在线视频| 狠狠色丁香久久婷婷综合_中| 亚洲制服在线观看| 国产精品综合在线视频| 天天躁日日躁狠狠躁av| av资源网一区| 亚洲精品国产91| 国产精品久久久久久久久免费桃花| 国产精品suv一区二区88| 亚洲欧洲精品一区二区三区不卡| 色婷婷在线视频观看| 亚洲午夜久久久久久久久久久 | 884aa四虎影成人精品一区| 国产农村老头老太视频| 精品国产乱码久久久久久久| 日本一二三区在线视频| 中文字幕亚洲欧美| 手机av在线播放| 日本三级韩国三级久久| 亚洲人体在线| 国内精品久久国产| 日韩精品一区二区三区免费观看| 黄色一级片网址| 日韩一级不卡| 天天操,天天操| 成人永久看片免费视频天堂| 中文字幕免费视频| 亚洲乱码国产乱码精品精可以看 | 国产ts在线播放| 最近中文字幕一区二区三区| 日韩欧美国产亚洲| 欧美体内she精视频| www黄色网址| 亚洲色图50p| 欧美人动性xxxxz0oz| 日本中文字幕成人| 久久伊人影院| 欧美主播一区二区三区美女 久久精品人| 999国产精品视频| 日韩在线一级片| 国产一区二区三区在线观看免费视频| 亚洲成av人片在线观看无| 国产精品另类一区| 久久久久久久久久免费视频| 666欧美在线视频| 美女做暖暖视频免费在线观看全部网址91 | 色乱码一区二区三在线看| 欧美日韩第一区| 日本黄色福利视频| www国产精品av| 青青草手机在线视频| 欧美综合视频在线观看| 欧美77777| 欧美www在线| 国产成人午夜性a一级毛片| 久久国产主播精品| 欧美日韩国产一区精品一区| 伊人色在线观看| 久久九九国产精品| 中文字幕一区二区三区精品 | 99国产精品免费视频| 国产女人水真多18毛片18精品视频 | 国产精品伦子伦免费视频| 日韩高清成人在线| 人妻av无码专区| 国产一区二区调教| 免费黄色国产视频| 91福利视频久久久久| 污污视频在线免费看| 欧美大片在线看| а天堂中文最新一区二区三区| 日韩妆和欧美的一区二区| 日韩图片一区| 日本一卡二卡在线| 亚洲国产精品欧美一二99| 国产黄色片av| 欧美成人精品不卡视频在线观看| 久久亚洲人体| 亚洲精品高清国产一线久久| 首页亚洲欧美制服丝腿| 熟女俱乐部一区二区视频在线| 亚洲成av人片一区二区| 亚洲黄色在线观看视频| 欧美大片在线看免费观看| 伊人精品综合| 青青草国产免费| 成人高清视频在线观看| 国产无码精品视频| 亚洲激情在线观看| 在线中文字幕播放| 久久这里精品国产99丫e6| 99国产精品久久久久久久| 亚洲精品第二页| 黑人巨大精品欧美一区二区一视频| 日本免费不卡视频| 欧美亚洲成人精品| 久久99国产精一区二区三区| 日本成人中文字幕在线| 国产免费成人在线视频| 97成人在线观看| 欧美精品在线极品| 99re6热只有精品免费观看| 人体内射精一区二区三区| 91香蕉视频在线| 中文字幕日韩免费| 中文字幕日韩欧美在线| 国产一区二区三区黄网站| 福利视频免费在线观看| 97久久久精品综合88久久| 日日夜夜狠狠操| 日韩视频在线观看免费| 日韩精品一区二区三区中文| 欧美aⅴ一区二区三区视频| 午夜福利三级理论电影| 欧美日韩性视频在线| 国产精品一级伦理| 91精品中文在线| 欧美精品日韩| 黄色工厂在线观看| 精品污污网站免费看| 91麻豆免费在线视频| 久久婷婷人人澡人人喊人人爽| 日日噜噜夜夜狠狠视频欧美人| 美国一级片在线观看| 欧美精品一区二| 欧美成人精品三级网站| 狠狠精品干练久久久无码中文字幕 | 午夜精品久久一牛影视| 免费理论片在线观看播放老| 国产日韩在线亚洲字幕中文| 黄色精品免费| 欧美三级视频网站| 日韩一区二区电影| 午夜影院一区| 路边理发店露脸熟妇泻火| 99精品视频在线播放观看| 中文字幕第2页| 欧美国产日韩一区二区在线观看 | 黄色a级在线观看| 97久久超碰精品国产| 国产精品日韩无码| 日韩av电影中文字幕| 欧美一区二区三区免费看| 成人午夜剧场视频网站|