如何監控Linux文件系統事件:inotify使用指南

如何監控Linux文件系統事件:inotify使用指南

§·inotify初識

Inotify 是一個 Linux特性,它監控文件系統操作,比如讀取、寫入和創建。Inotify 反應靈敏,用法非常簡單,并且比 cron 任務的繁忙輪詢高效得多。學習如何將 inotify 集成到您的應用程序中,并發現一組可用來進一步自動化系統治理的命令行工具。

§·inotify產生背景

系統治理就像日常生活一樣。就像刷牙和吃蔬菜一樣,日常的維護能保持機器的良好狀態。您必須定期清空廢物,比如臨時文件或無用的日志文件,以及花時間填寫表單、回復電話、更新和監控進程等。幸好自動化 shell 腳本、使用 Nagios 等工具進行監控、通過常見的 cron 進行任務調度可以減輕這個負擔。

但稀奇的是,這些工具沒有一個具有響應性。當然,您可以安排一個頻繁運行的 cron 任務來監控條件,但這樣繁忙的輪詢 — 消耗大量資源并且具有不確定性 — 并不是很理想。

例如,假如您必須監控輸入數據的幾個 Transfer ProtocolFTP)收存箱,您可能要通過 find 命令掃描每個目標目錄,列舉新的內容。然而,盡管這個操作看起來并沒有什么害處,但每個調用都產生一個新的 shell find 命令,這需要許多系統調用來打開目錄,然后掃描目錄,等等。這會造成過于頻繁的或大量的輪詢任務(更糟糕的是,繁忙的輪詢并不總是很好。想象一下一個文件系統瀏覽器,比如 Mac OS X Finder,輪詢更新時需要的大量資源及其復雜性)。那么,管理員應該怎么辦呢?令人興奮的是,您可以再次求助于可以信賴的計算機。

§·inotify詳細介紹

Inotify 是一個 Linux 內核特性,它監控文件系統,并且及時向專門的應用程序發出相關的事件警告,比如刪除、讀、寫和卸載操作等。您還可以跟蹤活動的源頭和目標等細節。

使用 inotify 很簡單:創建一個文件描述符,附加一個或多個監視器(一個監視器 是一個路徑和一組事件),然后使用 read 方法從描述符獲取事件。read 并不會用光整個周期,它在事件發生之前是被阻塞的。

更好的是,因為 inotify 通過傳統的文件描述符工作,您可以利用傳統的 select 系統調用來被動地監控監視器和許多其他輸入源。

兩種方法 — 阻塞文件描述符和使用 select— 都避免了繁忙輪詢。現在,深入了解 inotify,寫一些 C 代碼,然后看看一組命令行工具,可以構建并使用它們將命令和腳本附加到文件系統事件。Inotify 不會在中途失去控制,但它可以運行 cat wget,并且在必要時嚴格執行。

要使用 inotify,必須具備一臺帶有 2.6.13 或更新內核的 Linux 機器(以前的 Linux 內核版本使用更低級的文件監控器 dnotify)。如果不知道內核的版本,請轉到 shell,輸入 uname -a

% uname -a

Linux ubuntu-desktop 2.6.24-19-generic #1 SMP … i686 GNU/Linux

如果列出的內核版本不低于 2.6.13,系統就支持 inotify。還可以檢查機器的 /usr/include/sys/inotify.h 文件。

如果它存在,表明內核支持 inotify

注意:FreeBSD Mac OS X 提供一個類似于 inotify kqueue。在 FreeBSD 機器上輸入 man 2 kqueue 獲取更多信息。

本文基于 Ubuntu Desktop version 8.04.1(即 Hardy),它運行在 Mac OS X version 10.5 Leopard Parallels Desktop version 3.0

 

 

 

§·inotify其它介紹

當需要對Linux文件系統進行高效率、細粒度、異步地監控時,可以采用 inotify。

可利用它對用戶空間進行安全、性能、以及其他方面的監控。

inotify允許監控程序打開一個獨立文件描述符,并針對事件集監控一個或者多個文件,例如打開、關閉、移動/重命名、刪除、創建或者改變屬性。

從文件管理器到安全工具,文件系統監控對于的許多程序來說都是必不可少的。從 Linux 2.6.13 內核開始,Linux 就推出了 inotify,允許監控程序打開一個獨立文件描述符,并針對事件集監控一個或者多個文件,例如打開、關閉、移動/重命名、刪除、創建或者改變屬性。在后期的內核中有了很多增強,因此在依賴這些特性之前,請先檢查您的內核版本。

§·inotify功能簡單介紹

 

在本文中,您將會學習如何在簡單的監控應用程序中使用 inotify 功能。下載樣例代碼,在您的系統上編譯,進一步探索。

※·dnotify  inotify 對比

inotify 之前有 dnotify。不幸的是,dnotify 有局限性,用戶需要更好的產品。和 dnotify 相比 inotify 的優勢如下:

1  .  Inotify 使用一個獨立的文件描述符,而 dnotify 需要為每個受監控的目錄打開一個文件描述符。當您同時監控多個目錄時成本會非常高,而且還會遇到每進程文件描述符限制。

2  .  Inotify 所使用的文件描述符可以通過系統調用獲得,并且沒有相關設備或者文件。而使用 dnotify,文件描述符就固定了目錄,妨礙備用設備卸載,這是可移動媒體的一個典型問題。對于 inotify,卸載的文件系統上的監視文件或目錄會產生一個事件,而且監視也會自動移除。

3  .  Inotify 能夠監視文件或者目錄。Dnotify 則只監視目錄,因此程序員還必須保持 stat 結構或者一個等效的數據結構,來反映該被監視目錄中的文件,然后在一個事件發生時,將其與當前狀態進行對比,以此了解當前目錄中的條目發生了什么情況。

小結:如上所述,inotify 使用文件描述符,允許程序員使用標準 select 或者 poll 函數來監視事件。這允許高效的多路復用 I/O 或者與 Glib mainloop 的集成。相比之下,dnotify 使用信號,這使得程序員覺得比較困難或者不夠流暢。在 2.6.25 內核中 inotify 還添加了 Signal-drive I.O 通知功能。

※·用于 inotify API

Inotify 提供一個簡單的 API,使用最小的文件描述符,并且允許細粒度監控。與 inotify 的通信是通過系統調用實現。可用的函數如下所示:

 

◎·inotify_init

是用于創建一個 inotify 實例的系統調用,并返回一個指向該實例的文件描述符。

◎·inotify_init1

inotify_init 相似,并帶有附加標志。如果這些附加標志沒有指定,將采用與 inotify_init 相同的值。

◎·inotify_add_watch

增加對文件或者目錄的監控,并指定需要監控哪些事件。標志用于控制是否將事件添加到已有的監控中,是否只有路徑代表一個目錄才進行監控,是否要追蹤符號鏈接,是否進行一次性監控,當首次事件出現后就停止監控。

◎·inotify_rm_watch

從監控列表中移出監控項目。

◎·read

讀取包含一個或者多個事件信息的緩存。

◎·close

關閉文件描述符,并且移除所有在該描述符上的所有監控。當關于某實例的所有文件描述符都關閉時,資源和下層對象都將釋放,以供內核再次使用。

 

※·用于 inotify 監控程序

因此,典型的監控程序需要進行如下操作:

 

使用 inotify_init 打開一個文件描述符

添加一個或者多個監控

等待事件

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

當監控不再活動時,或者接到某個信號之后,關閉文件描述符,清空,然后退出。

在下一部分中,您將看到可以監控的事件,它們如何在簡單的程序中運行。最后,您將看到事件監控如何進行。

 

◎·通告

當您的應用程序讀取到一個通告時,事件的順序也被讀取到您提供的緩存中。事件在一個變長結構中被返回,如清單 1 所示。如果數據占滿了您的緩存,您可能需要對最后一個條目進行局部事件信息或者局部名處理。

 

清單 1. 用于 inotify 的事件結構體

 

struct inotify_event

{

  int wd;               /* Watch descriptor.  */

  uint32_t mask;        /* Watch mask.  */

  uint32_t cookie;      /* Cookie to synchronize two events.  */

  uint32_t len;         /* Length (including NULs) of name.  */

  char name __flexarr;  /* Name.  */

  };

請注意,只有當監控對象是一個目錄并且事件與目錄內部相關項目有關,而與目錄本身無關時,才提供 name 字段。如果 IN_MOVED_FROM 事件與相應的 IN_MOVED_TO 事件都與被監控的項目有關,cookie 就可用于將兩者關聯起來。事件類型在掩碼字段中返回,并伴隨著能夠被內核設置的標志。例如,如果事件與目錄有關,則標志 IN_ISDIR 將由內核設置。

 

◎·可監控的事件

有幾種事件能夠被監控。一些事件,比如 IN_DELETE_SELF 只適用于正在被監控的項目,而另一些,比如 IN_ATTRIB 或者 IN_OPEN 則只適用于監控過的項目,或者如果該項目是目錄,則可以應用到其所包含的目錄或文件。

 

IN_ACCESS

被監控項目或者被監控目錄中的條目被訪問過。例如,一個打開的文件被讀取。

IN_MODIFY

被監控項目或者被監控目錄中的條目被修改過。例如,一個打開的文件被修改。

IN_ATTRIB

被監控項目或者被監控目錄中條目的元數據被修改過。例如,時間戳或者許可被修改。

IN_CLOSE_WRITE

一個打開的,等待寫入的文件或目錄被關閉。

IN_CLOSE_NOWRITE

一個以只讀方式打開的文件或目錄被關閉。

IN_CLOSE

一個掩碼,可以很便捷地對前面提到的兩個關閉事件(IN_CLOSE_WRITE | IN_CLOSE_NOWRITE)進行邏輯操作。

IN_OPEN

文件或目錄被打開。

IN_MOVED_FROM

被監控項目或者被監控目錄中的條目被移出監控區域。該事件還包含一個 cookie 來實現 IN_MOVED_FROM IN_MOVED_TO 的關聯。

IN_MOVED_TO

文件或目錄被移入監控區域。該事件包含一個針對 IN_MOVED_FROM cookie。如果文件或目錄只是被重命名,將能看到這兩個事件,如果它只是被移入或移出非監控區域,將只能看到一個事件。如果移動或重命名一個被監控項目,監控將繼續進行。參見下面的 IN_MOVE-SELF。

IN_MOVE

可以很便捷地對前面提到的兩個移動事件(IN_MOVED_FROM | IN_MOVED_TO)進行邏輯操作的掩碼。

IN_CREATE

在被監控目錄中創建了子目錄或文件。

IN_DELETE

被監控目錄中有子目錄或文件被刪除。

IN_DELETE_SELF

被監控項目本身被刪除。監控終止,并且將收到一個 IN_IGNORED 事件。

IN_MOVE_SELF

監控項目本身被移動。

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

inotify 的可能使用

您可以將 inotify 用于多種目標。下面列舉一些可能的情況:

 

◎·性能監控

您可能想確定應用程序打開最頻繁的文件是哪個。如果發現一個小文件被頻繁打開與關閉,您可能會考慮采用內存版,或者改變應用程序來采取其他方式共享該數據。

元信息

您可能想記錄文件的附加信息,例如起始創建時間或者最后改變該文件的用戶 id

安全

您可能會因為安全原因,需要對特定文件或目錄的所有訪問進行監控。

我們的示例代碼監控所有事件并進行報告。實際上,您可能想依據您的需要,來查看這些事件的特定子集。您可能想監控不同被監控項目的不同事件。例如,您可能想監控文件的打開與關閉事件,但對于目錄只想監控創建與刪除事件。在任何可能的時候,您可以監控您所感興趣的最小事件集。

 

結束語

應用到性能監控、程序調試、以及自動化等領域時,inotify 是監控 Linux 文件系統的功能強大的、高粒度的機制。利用本文提供的樣例代碼,您可以開始編寫用來實時記錄文件系統事件并最小化性能開銷的應用程序。

原創文章,作者:linux_root,如若轉載,請注明出處:http://www.www58058.com/56011

(0)
linux_rootlinux_root
上一篇 2016-10-30 21:02
下一篇 2016-10-30 21:02

相關推薦

  • 正則表達式練習

       grep練習  : 1 、顯示/proc/meminfo 文件中以大小s 開頭的行:  2 、顯示/etc/passwd 文件中不以/bin/bash 結尾的行      3 、顯示用戶rpc 默認的shell        4 、找出/etc…

    Linux干貨 2016-08-10
  • 配置yum服務器——以centOS 6.9系統為例

    準備工作 關閉防火墻  關閉防火墻service iptables stop  設置防火墻開機不啟動chkconfig iptables off  查看一下防火墻狀態 iptables -vnL 如下圖,可以看到已經關閉 關閉SElinux 使用命令 vim /etc/selinux/config 將SELINUX=enable…

    Linux干貨 2017-08-05
  • 第四天作業

    1 、創建 用戶gentoo ,附加組為bin 和root ,默認shell為/bin/csh ,注釋信息為"Gentoo Distribution" 1 useradd -G bin,root -s /bin/csh -c "Gentoo Distribut…

    Linux干貨 2016-08-04
  • 網絡基礎筆記

    網絡管理筆記 1. 網絡概念:     一組網絡設備或計算機,通過無形的規則鏈接起來的體系!    2. 應用程序種類:     (1)批處理應用程序:            FTP、TFTP、庫存更新    &nbsp…

    Linux干貨 2017-03-16
  • shell腳本之數組

    認識數組:    變量是存儲單個元素的內存空間,而數組就是多個變量的合集,是一串連續的空間,但是,整個數組只能有一個名字。    數組內的數據都有指定的索引,以找到數組內指定的數據。索引的編號是從0開始,依次遞增(0,1,2,3…),屬于數值索引。索引也支持自定義的格式,而不僅是數值格式的索引,即為關聯索引…

    Linux干貨 2016-08-26
  • 馬哥教育網絡班21期第5周課程練習

    1、顯示/boot/grub/grub.conf中以至少一個空白字符開頭的行; # grep '^[[:space:]]\+' /boot/grub2/grub.cfg 2、顯示/etc/rc.d/rc.sysinit文件中以#開頭,后面跟至少一個空白字符,而后又有至少一個非空白字符的行; # grep…

    Linux干貨 2016-08-05
欧美性久久久久