inotify 心得


inotify 心得

一、inotify簡介

inotify是Linux內核2.6.13 (June 18, 2005)版本新增的一個子系統(API),它提供了一種監控文件系統(基於inode的)事件的機制,可以監控文件系統的變化如文件修改、新增、刪除等,並可以將相應的事件通知給應用程序。該機制由著名的桌面搜索引擎項目beagle引入用於替代此前具有類似功能但存在諸多缺陷的dnotify。

inotify既可以監控文件,也可以監控目錄。當監控目錄時,它可以同時監控目錄及目錄中的各子目錄及文件的。此外,inotify 使用文件描述符作為接口,因而可以使用通常的文件I/O操作select、poll和epoll來監視文件系統的變化。

inotify 可以監視的文件系統常見事件包括:
IN_ACCESS:文件被訪問
IN_MODIFY:文件被修改
IN_ATTRIB,文件屬性被修改
IN_CLOSE_WRITE,以可寫方式打開的文件被關閉
IN_CLOSE_NOWRITE,以不可寫方式打開的文件被關閉
IN_OPEN,文件被打開
IN_MOVED_FROM,文件被移出監控的目錄
IN_MOVED_TO,文件被移入監控着的目錄
IN_CREATE,在監控的目錄中新建文件或子目錄
IN_DELETE,文件或目錄被刪除
IN_DELETE_SELF,自刪除,即一個可執行文件在執行時刪除自己
IN_MOVE_SELF,自移動,即一個可執行文件在執行時移動自己

通過/proc接口中的如下參數設定inotify能夠使用的內存大小:
1、/proc/sys/fs/inotify/max_queue_events
應用程序調用inotify時需要初始化inotify實例,並時會為其設定一個事件隊列,此文件中的值則是用於設定此隊列長度的上限;超出此上限的事件將會被丟棄;
2、/proc/sys/fs/inotify/max_user_instances
此文件中的數值用於設定每個用戶ID(以ID標識的用戶)可以創建的inotify實例數目的上限;
3、/proc/sys/fs/inotify/max_user_watches
此文件中的數值用於設定每個用戶ID可以監控的文件或目錄數目上限;


二、inotify-tools

inotify是一個API,需要通過開發應用程序進行調用,對於大多數用戶來講這有着許多不便,inotify-tools的出現彌補了這一不足。inotify-tools是一套組件,它包括一個C庫和幾個命令行工具,這些命令行工具可用於通過命令行或腳本對某文件系統的事件進行監控。它由Rohan McGovern開發,其項目網址為http://inotify-tools.sourceforge.net。

inotify-tools提供的兩個命令行工具:
inotifywait:通過inotify API等待被監控文件上的相應事件並返回監控結果,默認情況下,正常的結果返回至標准輸出,診斷類的信息則返回至標准錯誤輸出。它可以在監控到對應監控對象上指定的事件后退出,也可以進行持續性的監控。
inotifywatch:通過inotify API收集被監控文件或目錄的相關事件並輸出統計信息。


inotifywait命令使用簡介:
inotifywait尤其適用於在腳本中等待某事件的發生,並可基於特定的事件執行相應操作。如將其用於腳本中監控某指定目錄中的文件上的修改、新建、刪除、屬性信息的改變,而后使用rsync命令將某事件對應的文件同步至其它主機上。其常用選項如下:
-m, --monitor:inotifywait的默認動作是在監控至指定文件的特定事件發生一次后就退出了,而使用此選項則可實現持續性的監控;
-r, --recursive:遞歸監控指定目錄下的所有文件,包括新建的文件或子目錄;如果要監控的目錄中文件數量巨大,則通常需要修改/proc/sys/fs/inotify/max_users_watchs內核參數,因為其默認值為8192。
-e , --event :指定要監控的特定事件,默認是監控所有的事件;此處包括access, modify, attrib, close_write, close_nowirte, close, open, moved_to, moved_from, move, create, delete, delete_selt等;
--timefmt :當在--format選項中使用%T時,--timefrt選項則可以用來指定自定義的符合strftime規范的時間格式,此時間格式可用的格式符可以通過strftime的手冊頁獲取;--timefrt后常用的參數是'%d/%m/%y %H:%M';
--format :自定義inotifywait的輸出格式,如--format '%T %w %f';常用的格式符如下:
%w:顯示被監控文件的文件名;
%f:如果發生某事件的對象是目錄,則顯示被監控目錄的名字;默認顯示為空串;
%T:使用--timefmt選項中自定義的時間格式;

例如,要監控/tmp/test目錄及其內部所有文件上發生的create,delete,modify,close_write事件,則使用如下命令:
# inotify -r --timefmt '%d/%m/%y %H:%M' --format '%T %w %f' -e create,delete,modify,close_write /tmp/test

此命令在監控到某文件上第一次事件后就會退出,如果想一直監控,則需要為命令添加-m選項。

在很多場景中都會用到將某主機上的某目錄下的所有文件改變實時同步至另一主機上的指定位置,這也可以通過在腳本中使用inotifywait結合rsync命令來實現,比如如下腳本:

#!/bin/bash

DESTHOST=172.16.100.6
DESTHOSTDIR=/www/htdocs/
SRCDIR=/www/htdocs/

inotifywait -mr --timefmt '%d/%m/%y %H:%M' --format '%T %w %f' \
-e create,delete,modify,attrib $SRCDIR | while read DATE TIME DIR FILE; do
$FILECHANGE=${DIR}${FILE}

rsync -avze 'ssh' $SRCDIR root@${DESTHOST}:${DESTHOSTDIR} &>/dev/null && \
echo "At ${TIME} on ${DATE}, file $FILECHANGE was backed up via rsync" >> /var/log/filesync.log

done

需要注意的是,此腳本中的rsync是通過ssh加密后進行文件傳輸的,因此需要事先配置好相應的ssh能夠基於密鑰對用戶進行認證,以免每一次文件同步都需要用戶手動輸入密碼。

當然,如果數據傳輸不需要加密,此處也可以通過在目錄主機的啟動rsyncd守護進程來實現。

三、配置rsyncd+inotify實現文件實時同步:

本案例實現監控原主機上指定目錄中的所有文件變化,並將變化實時同步至目標主機的指定目錄中;所用主機及相關目錄如下:
源主機:RHEL5.4(x86),172.16.100.1, 文件所在的目錄為/www/htdocs;
目標主機:RHEL5.4(x86),172.16.100.6, 文件所在的目錄為/www/htdocs;

1、設定目標主機(本例為172.16.100.6)

本案例中采用基於rsync守護進程的方式進行數據同步,其數據傳輸過程是明文方式,因此只適用於在特定的場景中應用。

1)安裝相關軟件:
目標主機是接收別的主機發送來的文件的服務器,因此,其rsync需要以守護進程的方式工作。rsync服務通常基於超級守護進程xinetd管理的方式來實現,因此需要事先安裝rysnc和xinetd:
# yum -y install rsync xinetd

2)為rsync提供配置文件/etc/rsyncd.conf,內容類似如下內容:
# Section 1: Global settings
uid = nobody
gid = nobody
use chroot = no
max connections = 3
strict modes = yes
pid file = /var/run/rsyncd.pid
log file = /var/log/rsyncd.log
# Section 2:Directory to be synced
[htdocs]
path = /www/htdocs
ignore errors = yes
read only = no
write only = no
hosts allow = 172.16.0.0/16
hosts deny = *
list = false
uid = root
gid = root
auth users = wwwuser
secrets file = /etc/rsync.passwd

其中的相關指令及其說明可以通過rsyncd.conf的手冊而獲取。而其訪問控制功能也可基於xinetd進行,具體方法請參照xinetd.conf的手冊頁。

3)提供secrets file所指定的口令文件/etc/rsync.passwd,其內容類似如下:
htdocsuser:passwOrdForhtdOcs

其中冒號前的是用戶名,冒號后的是對應用戶的密碼。此文件不能為其他任意用戶可訪問,因此可用如下命令修改:
# chmod 600 /etc/rsync.passwd

4)配置服務可以開機啟動:
# chkconfig rsync on
# chkconfig xinetd on
# service xinetd start

默認情況下,rsyncd監聽的端口為873/TCP,這可以通過如下命令查看:
# netstat -tnlp | grep ":873"
tcp 0 0 0.0.0.0:873 0.0.0.0:* LISTEN 3653/xinetd

2、設定源主機

1)安裝相關軟件
源主機需要實時監控指定目錄中的所有文件上與文件改變相關的事件,並在事件發生時將改變的數據同步至目錄主機,因此,源主機上需要確保內核支持inotify,並安裝inotify-tools和rsync。

rsync的安裝參照目標主機的中的方式進行即可。

inotify-tools的安裝可以基於源碼編譯的方式進行,也可以通過安裝其rpm進行。
源碼下載地址:http://github.com/downloads/rvoicilas/inotify-tools/inotify-tools-3.14.tar.gz
rpm包下載頁面:http://rpm.pbone.net/index.php3/stat/4/idpl/15265939/dir/redhat_el_5/com/inotify-tools-3.14-1.el5.i386.rpm.html

這里以編譯源代碼的方式演示安裝過程:
# tar xf inotify-tools-3.14.tar.gz
# cd inotify-tools-3.14
# ./configure
# make
# make install
# echo "/usr/local/lib" > /etc/ld.so.conf.d/usr_local_lib.conf
# ldconfig

2)為源主機的rsync提供通過htdocsuser用戶同步文件至目標主機的口令文件
# echo 'passwOrdForhtdOcs' > /etc/rsync.passwd
# chmod 600 /etc/rsync.passwd

注意,對於RHEL5.4自帶的2.6.8版本的rsync來說,其客戶端(即此處的源主機上的rsync)的口令文件中只能保存用戶的口令,而不能類似目標主機上可同時指定用戶名。

3)建立腳本/root/bin/htdocsync.sh,通過inotifywait監控目標文件上的相應事件,並在事件觸發時啟動同步過程:
#!/bin/bash
#
DESTHOST=172.16.100.6
DESTHOSTDIR=/www/htdocs/
SRCDIR=/www/htdocs/

inotifywait -mr --timefmt '%d/%m/%y %H:%M' --format '%T %w %f' -e close_write,modify,delete,create,attrib $SRCDIR | while read DATE TIME DIR FILE; do

FILECHANGE=${DIR}${FILE}

rsync -avz --password-file=/etc/rsync.passwd $SRCDIR htdocsuser@${DESTHOST}::htdocs &>/dev/null && \
echo "At ${TIME} on ${DATE}, file $FILECHANGE was backed up via rsync" >> /var/log/websync.log
done

而后給此腳本執行權限,並執行即可:
# chmod u+x /root/bin/htdocsync.sh
# /root/bin/htdocsync.sh &

如果想讓此功能可以在開機時自動啟動,則可以通過如下方式進行:
# echo '/root/bin/htdocsync.sh &' >> /etc/rc.d/rc.local


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM