일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
Tags
- tomcat
- inotify
- postfix
- connection tunning
- 펄 코딩스타일
- 오라클
- 리눅스
- pvfs
- ext3
- 가상파일시스템
- clustering
- 파일시스템
- CVSROOT 세팅
- 포기해버린꿈
- Nexenta
- OCFS2
- pgpool-ii
- Replication
- ZFS
- mailfiler
- 펄
- PERL
- Openfiler
- 시그널
- pgbench
- ext4
- LVS
- php-oracle 연동
- perltidy
- pgsql
Archives
- Today
- Total
avicom의 신변잡기
inotify 본문
개요
- Inotify는 inode를 기반으로 파일시스템의 활동을 감시하는 커널의 이벤트 모니터 서브시스템이다. 최초의 파일시스템 이벤트 모니터인 Dnotify를 대체하고 있으며 커널 2.6.13부터 기본 제공하는 기능이다. (그 이전의 커널에서도 패치를 통해 사용할 수 있다.)
- 커널 내에 inotify를 위한 시스템 콜이 존재하며 이 시스템 콜을 활용하여 사용할 수 있다.
- 서브디렉토리에 대한 감시가 자동으로 이루어지지 않기 때문에 감시하고자 하는 디렉토리를 모두 watch 인스턴스에 일일이 포함시켜주어야한다. 이러한 문제점을 해결한 fanotify라는 서브 시스템이 개발진행중이며 향후 커널 mainline에 추가될 예정임.
- watch 인스턴스의 최대 갯수는 8192개이며 커널 파라메터중 fs.inotify.max_user_watches 를 수정하여 늘릴 수 있다.
동작
대략적인 동작 방식은 다음과 같다
1. 인스턴스 생성하고 fd 반환
int inotify_init ()
2. 감시대상 추가하고 감시 시작. pathname에 대한 mask를 감시한다. 여러개의 pathname들이 동일한 inode/감시기술자(watch descriptor)를 가리킬 수 있다.
int inotify_add_watch (int fd, const char* pathname, int mask)
모니터되는 mask는 다음과 같다.
IN_ACCESS - 파일의 마지막 접근
IN_MODIFY - 파일의 마지막 수정
IN_ATTRIB - 파일 변경의 속성
IN_OPEN 및 IN_CLOSE - 파일의 열기 혹은 닫기
IN_MOVED_FROM 및 IN_MOVED_TO - 파일이 이동(move)되거나 이름이 바뀜(rename)
IN_DELETE - 파일/디렉터리의 삭제
IN_CREATE - 파일/디렉터리의 생성
IN_DELETE_SELF - 모니터되는 파일 자체의 삭제
3. 감시기술자 감시중단.
int inotify_rm_watch (int fd, int wd)
c와 perl, python, java에 대한 API를 제공한다.
예제 코드
C
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/inotify.h>
#define EVENT_SIZE ( sizeof (struct inotify_event) )
#define BUF_LEN ( 1024 * ( EVENT_SIZE + 16 ) )
int main( int argc, char **argv )
{
int length, i = 0;
int fd;
int wd;
char buffer[BUF_LEN];
fd = inotify_init();
if ( fd < 0 ) {
perror( "inotify_init" );
}
wd = inotify_add_watch( fd, "/home",
IN_MODIFY | IN_CREATE | IN_DELETE );
length = read( fd, buffer, BUF_LEN );
if ( length < 0 ) {
perror( "read" );
}
while ( i < length ) {
struct inotify_event *event = ( struct inotify_event * ) &buffer[ i ];
if ( event->len ) {
if ( event->mask & IN_CREATE ) {
if ( event->mask & IN_ISDIR ) {
printf( "The directory %s was created.\n", event->name );
}
else {
printf( "The file %s was created.\n", event->name );
}
}
else if ( event->mask & IN_DELETE ) {
if ( event->mask & IN_ISDIR ) {
printf( "The directory %s was deleted.\n", event->name );
}
else {
printf( "The file %s was deleted.\n", event->name );
}
}
else if ( event->mask & IN_MODIFY ) {
if ( event->mask & IN_ISDIR ) {
printf( "The directory %s was modified.\n", event->name );
}
else {
printf( "The file %s was modified.\n", event->name );
}
}
}
i += EVENT_SIZE + event->len;
}
( void ) inotify_rm_watch( fd, wd );
( void ) close( fd );
exit( 0 );
}
perl
#!/usr/bin/perl
use strict qw(vars);
use warnings;
use Linux::Inotify2;
use File::Find;
use Event;
my %hash;
my $e;
my $watch;
my $inotify = new Linux::Inotify2 or die "unable to create new inotify object: $!";
open (FH,'<','./inotify.conf');
while (<FH>) {
next if ($_ =~ /^#/ || $_ =~ /^$/);
my $dir = $_;
chomp($dir);
find(\&watch, $dir);
}
close(FH);
sub watch {
$watch = $inotify->watch ($File::Find::dir, IN_MODIFY | IN_CREATE | IN_DELETE | IN_ACCESS, \&call_back);
}
sub call_back {
$e = shift;
$hash{name} = $e->fullname;
$hash{name}->{flag} = "modified" if ($e->IN_MODIFY);
$hash{name}->{flag} = "accessed" if ($e->IN_ACCESS);
$hash{name}->{flag} = "created" if ($e->IN_CREATE );
$hash{name}->{flag} = "deleted" if ($e->IN_DELETE );
if (!defined($hash{name}->{p_flag}) || $hash{name}->{p_flag} ne $hash{name}->{flag} || $hash{name} ne $e->fullname) {
if ($e->name =~ /^\w+(.+\w+)?$/ && $e->name !~ /^\d+\d+$/) {
print $hash{name} . " : " . $hash{name}->{flag} ."\n";
$hash{name}->{p_flag} = $hash{name}->{flag};
}
}
else { %hash = (); }
}
Event->io (fd =>$inotify->fileno, poll => 'r', cb => sub { $inotify->poll });
while(1) {
if (!defined($hash{name}) || !defined($hash{name}->{p_flag}) || $hash{name}->{flag} eq $hash{name}->{p_flag}) {
print "polling.... \n";
$inotify->poll;
}
else {
next;
}
}
참고
http://www.linuxjournal.com/article/8478
http://www.ibm.com/developerworks/kr/library/l-inotify.html
http://search.cpan.org/~mlehmann/Linux-Inotify2-1.21/Inotify2.pm
https://fedoraproject.org/wiki/Features/fanotify
http://kernelnewbies.org/Linux_2_6_31#head-082d9a34a245a3a3211244078f276bf3348bf0d6
http://lwn.net/Articles/339253/