一、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>, --event <event>:指定要監控的特定事件,預設是監控所有的事件;此處<event>包括access, modify, attrib, close_write, close_nowirte, close, open, moved_to, moved_from, move, create, delete, delete_selt等;
--timefmt <fmt>:當在--format選項中使用%T時,--timefrt選項則可以用來指定自定義的符合strftime規範的時間格式,此 時間格式可用的格式符可以通過strftime的手冊頁擷取;--timefrt後常用的參數是'%d/%m/%y %H:%M';
--format <fmt>:自定義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監控目标檔案上的相應事件,并在事件觸發時啟動同步過程:
#
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
而後給此腳本執行權限,并執行即可:
# chmod u+x /root/bin/htdocsync.sh
# /root/bin/htdocsync.sh &
如果想讓此功能可以在開機時自動啟動,則可以通過如下方式進行:
# echo '/root/bin/htdocsync.sh &' >> /etc/rc.d/rc.local
補充說明:如果您期望将源主機上的資料同步至多台目标主機,對每個目标主機均類似上面的目标主機的設定方法進行設定即可。
本文轉自 dengaosky 51CTO部落格,原文連結:http://blog.51cto.com/dengaosky/1853560,如需轉載請自行聯系原作者