dnotify를 대체할 2.6 커널의 파일 시스템 이벤트 모니터링 메커니즘
난이도 : 초급
Eli M. Dow
소프트웨어 엔지니어, IBM Linux Test and Integration Center
2005년 4 월 12 일
Inotify는 차기 리눅스 커널에 포함될 파일 시스템 모니터링 메커니즘으로서, 구 커널에서 지원되던 파일 모니터링 메커니즘이였던 dnotify의 강력한 대체재이다. Inotify는 강력하고 세련된 비동기식 메커니즘으로서 보안과 퍼포먼스 등 다양한 파일 모니터링의 필요를 이상적으로 채운다. Inotify를 설치하는 방법과 파일 시스템 이벤트에 응답하는 사용자 공간의 애플리케이션 샘플을 구현하는 방법을 설명한다.
파일 시스템 이벤트 모니터링은 파일 매니저에서 보안 툴에 이르기까지 다양한 유형의 프로그램들에 필수적인 것이지만, 이전 커널의 표준인 dnotify는 아쉽게도 제한이 많았다. 이제, 보다 현대적인 파일 시스템 이벤트-모니터링 대안인 Inotify를 만나보자.
왜 Inotify인가?
dnotify 대신 Inotify를 사용하는데는 많은 이유가 있다. 우선, dnotify는 변경사항을 보고자 할 때 각 디렉토리에 대한 한 개의 파일 디스크립터를 열어야 한다. 따라서, 여러 디렉토리들을 한번에 모니터링 할 때는 작업량이 많을 수 밖에 없다. 프로세스 당 파일 디스크립터 제한에 걸리기 때문이다.
게다가 파일 디스크립터는 디렉토리를 고정하기 때문에 지원 장치의 언마운트가 허용되지 않는다. 따라서 제거 가능한 미디어가 개입된 시나리오에서 문제가 발생한다. Inotify를 사용할 때, 언마운트 된 파일시스템 상의 파일을 보고자 한다면, 보기(watch)는 자동으로 제거되고 언마운트 이벤트를 받는다.
dnotify 보다 Inotify가 더 나은 두 번째 이유는 약간 복잡하다. dnotify 인프라를 사용하는 단순한 파일시스템-모니터링 세분성은 디렉토리 레벨에서만 존재한다. dnotify를 이용하여 보다 정밀한 모니터링을 하려면 애플리케이션 프로그래머들은 관찰되고 있는 각 디렉토리와 관련된 stat 구조의 캐시를 유지해야한다. stat 구조의 사용자 공간 캐시는 공지 신호를 받았을 때 디렉토리에 정확히 어떤 변화가 발생했는지를 결정하는데 필요하다. 공지를 받으면 stat 구조의 리스트가 생성되고 마지막 상태와 비교된다. 확실히 이는 최상의 방법은 아니다.
Inotify의 또 다른 장점은 기본 인터페이스로서 파일 디스크립터를 사용하여 애플리케이션 개발자들이 select와 poll 을 사용하여 장치 볼 수 있다는 점이다. 이로서 효율적인 다중화 I/O와 Glib의 mainloop와의 통합이 가능하다. 이와 반대로, dnotify는 프로그래머들이 어려워하는 신호를 사용하고 있다.
Inotify는 최소한의 파일 디스크립터를 사용하고 보다 세분화된 모니터링을 보장하는 등의 고급 기능을 제공하여 이러한 문제들을 해결한다. Inotify와의 통신은 디바이스 노트를 통해 이루어진다. 따라서, Linux 2.6에서 파일 모니터링을 할 때 선택을 분명히 해야 한다.
Inotify 설치하기
Inotify를 설치하는 첫 번째 단계는 현재 사용하고 있는 리눅스 커널이 이를 지원하는지의 여부를 결정하는 것이다. 배포판을 확인하는 가장 간단한 방법은 /dev/inotify 장치의 존재 유무를 확인하는 것이다. 이 장치가 있으면 애플리케이션에서 Inotify 사용하기섹션으로 이동하기 바란다.
이 글이 쓰여질 당시, Inotify는 Andrew Morton의 리눅스 Linux 2.6-mm 트리에 포함되었고 여러 리눅스 배포판들이 Inotify를 실행하는 커널(Gentoo와 Ubuntu)을 제공하고 있거나 또는 이를 지원하는 보조 커널 패키지를 갖고 있었다. (Fedora와 SuSE). Andrew가 트리에서 Inotify 지원을 제거할 수도 있고 Inotify를 제거하는 일은 개발 단계에서는 종종 있는 일이였기 때문에 처음부터 다시 붙이는 것을 권장한다.
이 장치가 없다면 커널을 패치하고 장치를 만들어야 한다.
Inotify용 커널 패치
Linux Kernel Archives (참고자료)에서 Inotify 패치를 얻을 수 있다.
자신의 커널에 해당하는 버전 숫자 중 가장 높은 숫자를 가진 패치를 적용해야 한다. 배포판마다 커널 설치를 약간 다르게 핸들하긴 하지만 여기에서는 일반적인 가이드라인을 설명하겠다: Note: 배포판의 2.6 리눅스 커널 소스나, Linux Kernel Archives에서 안정적인 최신 릴리스를 사용해야 한다.
우선 커널 소스 디렉토리로 간다:
bash:~$ cd /usr/src
앞서 커널 소스를 설치했기 때문에 이를 패킹을 푼다(unpack):
bash:~$ sudo tar jxvf linux-source-2.6.8.1.tar.bz2
symlink를 새로운 소스 트리로 만든다:
bash:~$ sudo ln -sf linux-source-2.6.8.1 linux
현재 디렉토리를 방금 만든 커널 소스 디렉토리로 변경한다:
bash:~$ cd linux
Inotify 패치를 복사한다:
bash:~$ sudo cp ~/inotify* /usr/src
커널을 붙인다(patch):
bash:~$ sudo patch -p1 < ../inotify*.patch
커널을 구현한다:
bash:~$ sudo make menuconfig
inotify 기능을 확인하면서 일반적인 방식으로 커널을 설정한다. 필요하다면 이 새로운 커널을 bootloader에 추가한다. 단 구 커널 이미지와 bootloader 옵션을 기억해야 한다. 이 단계는 bootloader 마다 다양하다. (bootloader 관련 추가정보는 참고자료 참조). 머신을 재부팅하고 inotify 기능이 추가된 커널을 선택한다. 새로운 커널을 테스트하여 올바르게 작동하는지 확인한다.
inotify 장치 만들기
다음에는, /dev/inotify 장치가 만들어졌는지를 확인해야 한다. 다음은 그 단계이다. Important note: 마이너 넘버(minor number)가 변경될 수 있기 때문에 최신 것인지를 부지런히 검토해야 한다. 자신의 리눅스가 udev 기능을 지원한다면 자동으로 업데이트 된다.
새로운 커널로 재부팅 한 후에, 마이너 넘버를 획득해야 한다:
bash:~$ dmesg | grep ^inotify
다음은 리턴된 예제이다:
inotify device minor=63
inotify는 misc 장치이기 때문에 메이저는 10이다. 다음 명령행을 실행하여 장치 노드를 root 사용자로 만든다:
bash:~$ mknod /dev/inotify c 10 63
Note: 필요할 경우 "63"을 적당한 마이너 넘버로 대체한다.
선택적으로 허가(permission)를 설정해야 한다. 허가 설정 샘플은 다음과 같다:
bash:~$ chown root:root /dev/inotify
bash:~$ chmod 666 /dev/inotify
이제 파일 시스템 모니터링을 위한 inotify 장치를 사용할 준비를 갖추게 되었다.
애플리케이션에서 Inotify 사용하기
파일 시스템 이벤트에 임의의 디렉토리를 감시하는 샘플 프로그램일 만드는 방법을 설명하겠다. inotify가 파일 시스템 모니터링을 얼마나 쉽게 만드는지를 보여줄 예정이다.
주 메소드
이 간단한 예제를 통해 임의의 디렉토리에 대한 watch를 설정하는 것이 얼마나 쉬운지를 보게 될 것이다. 주요 헬퍼 루틴은 나중에 설명하도록 하겠다. 여기에 사용되는 샘플 코드는 Download 섹션을 참조하기 바란다.
Listing 1. 디렉토리에 대한 watch 설정하기
중요한 헬퍼 메소드
다음은 모든 inotify 기반 애플리케이션에 공통적으로 적용되는 가장 중요한 헬퍼 루틴들이다:
읽기를 위한 inotify 장치 열기
이 장치에서 읽혀지는 이벤트 큐잉(queuing)
애플리케이션들이 이벤트 공지를 사용하여 유용하게 일을 수행하도록 하는 이벤트 핸들러
여러 전략들이 사용될 수 있기 때문에 이벤트 큐잉에 대한 자세한 설명은 하지 않겠다. 멀티 쓰레디드 방식이 진화될수록 어디에서나 구현될 수 있다. 그와 같은 구현은 읽기 쓰레드가 inotify 장치에 대해 select()를 수행하고 그런 다음 이벤트를 몇몇 쓰레드가 공유된 스토리지(또는 Glib의 비동기식 메시지 큐)에 복사한다. 이곳은 핸들러 쓰레드가 실행되는 장소이다.
Listing 2. inotify 장치 열기
이것은 리눅스 시스템 상에서 파일들을 이용한 프로그래밍을 했다면 매우 익숙할 것이다.
Listing 3. 실제 이벤트-핸들링 루틴
각 case 문장 내에서 필요에 맞춰 구현한 어떤 메소드라도 실행할 수 있다.
퍼포먼스 모니터링과 관련하여 어떤 파일들이 가장 자주 읽히는지, 그리고 파일이 열려있던 기간을 파악할 수 있다. 이러한 종류의 모니터링은 쉽다. 어떤 상황에서, 짧은 기간 동안 애플리케이션에 의해 파일이 반복적으로 읽힌다면, 디스크로 돌아가기 보다는 메모리의 파일을 캐시하여 퍼포먼스를 향상시키기 때문이다.
특정 액션을 수행하는 이벤트 스팩의 핸들러들에 대한 다른 예제들도 이해하기 쉽다. 예를 들어, 기반 파일 시스템에 대해 메타데이터 스토리지 인덱스를 구현한다면 파일 생성 이벤트를 찾아 그 파일에 대한 데이터 마이닝 작동을 실행할 수 있다. 보안을 위해서는, 어떤 누구도 작성해서는 안되는 디렉토리에 파일이 쓰여졌다면 시스템 경고를 실행할 수 있다.
inotify가 많은 정밀한 이벤트들 CLOSE versus CLOSE_WRITE을 지원한다는 것도 기억하라.
이 글에서 사용된 코드의 많은 이벤트들이 코드가 실행될 때마다 보고자 하는 것이 아닐 수도 있다. 사실, 가능하다면 본인의 애플리케이션에 필요한 이벤트의 하위세트만 요청할 수 있으면 좋겠다. 이 글에서 제시한 코드에서는 전체 마스크를 사용하여 많은 이벤트들을 보여주고자 하였다. (샘플 코드에 있는 51줄의 main 메소드 (참고자료) 또는 Listing 1의 29줄) 애플리케이션 프로그래머들은 일반적으로 많은 선택권이 주워지길 바란다. 또한 여러분도 필요에 맞는 특정 마스크가 필요하다. 이는 앞서 보여준 handle_event() 메소드에서 catch 문장에서 관심 없는 아이템들을 제거할 수 있다.
결론
inotify가 퍼포먼스 모니터링, 디버깅, 자동화 같은 분야에 적용된다면 강력하고 정밀한 리눅스 파일 시스템의 모니터링 메커니즘이 된다. 이 글에 제시된 코드를 사용하여 최소한의 퍼포먼스 오버헤드로 실시간 파일 시스템 이벤트에 응답하고 이를 기록할 수 있는 애플리케이션을 작성할 수 있다.
http://www-128.ibm.com/developerworks/k ··· ify.html
난이도 : 초급
Eli M. Dow
소프트웨어 엔지니어, IBM Linux Test and Integration Center
2005년 4 월 12 일
Inotify는 차기 리눅스 커널에 포함될 파일 시스템 모니터링 메커니즘으로서, 구 커널에서 지원되던 파일 모니터링 메커니즘이였던 dnotify의 강력한 대체재이다. Inotify는 강력하고 세련된 비동기식 메커니즘으로서 보안과 퍼포먼스 등 다양한 파일 모니터링의 필요를 이상적으로 채운다. Inotify를 설치하는 방법과 파일 시스템 이벤트에 응답하는 사용자 공간의 애플리케이션 샘플을 구현하는 방법을 설명한다.
파일 시스템 이벤트 모니터링은 파일 매니저에서 보안 툴에 이르기까지 다양한 유형의 프로그램들에 필수적인 것이지만, 이전 커널의 표준인 dnotify는 아쉽게도 제한이 많았다. 이제, 보다 현대적인 파일 시스템 이벤트-모니터링 대안인 Inotify를 만나보자.
왜 Inotify인가?
dnotify 대신 Inotify를 사용하는데는 많은 이유가 있다. 우선, dnotify는 변경사항을 보고자 할 때 각 디렉토리에 대한 한 개의 파일 디스크립터를 열어야 한다. 따라서, 여러 디렉토리들을 한번에 모니터링 할 때는 작업량이 많을 수 밖에 없다. 프로세스 당 파일 디스크립터 제한에 걸리기 때문이다.
게다가 파일 디스크립터는 디렉토리를 고정하기 때문에 지원 장치의 언마운트가 허용되지 않는다. 따라서 제거 가능한 미디어가 개입된 시나리오에서 문제가 발생한다. Inotify를 사용할 때, 언마운트 된 파일시스템 상의 파일을 보고자 한다면, 보기(watch)는 자동으로 제거되고 언마운트 이벤트를 받는다.
dnotify 보다 Inotify가 더 나은 두 번째 이유는 약간 복잡하다. dnotify 인프라를 사용하는 단순한 파일시스템-모니터링 세분성은 디렉토리 레벨에서만 존재한다. dnotify를 이용하여 보다 정밀한 모니터링을 하려면 애플리케이션 프로그래머들은 관찰되고 있는 각 디렉토리와 관련된 stat 구조의 캐시를 유지해야한다. stat 구조의 사용자 공간 캐시는 공지 신호를 받았을 때 디렉토리에 정확히 어떤 변화가 발생했는지를 결정하는데 필요하다. 공지를 받으면 stat 구조의 리스트가 생성되고 마지막 상태와 비교된다. 확실히 이는 최상의 방법은 아니다.
Inotify의 또 다른 장점은 기본 인터페이스로서 파일 디스크립터를 사용하여 애플리케이션 개발자들이 select와 poll 을 사용하여 장치 볼 수 있다는 점이다. 이로서 효율적인 다중화 I/O와 Glib의 mainloop와의 통합이 가능하다. 이와 반대로, dnotify는 프로그래머들이 어려워하는 신호를 사용하고 있다.
Inotify는 최소한의 파일 디스크립터를 사용하고 보다 세분화된 모니터링을 보장하는 등의 고급 기능을 제공하여 이러한 문제들을 해결한다. Inotify와의 통신은 디바이스 노트를 통해 이루어진다. 따라서, Linux 2.6에서 파일 모니터링을 할 때 선택을 분명히 해야 한다.
Inotify 설치하기
Inotify를 설치하는 첫 번째 단계는 현재 사용하고 있는 리눅스 커널이 이를 지원하는지의 여부를 결정하는 것이다. 배포판을 확인하는 가장 간단한 방법은 /dev/inotify 장치의 존재 유무를 확인하는 것이다. 이 장치가 있으면 애플리케이션에서 Inotify 사용하기섹션으로 이동하기 바란다.
이 글이 쓰여질 당시, Inotify는 Andrew Morton의 리눅스 Linux 2.6-mm 트리에 포함되었고 여러 리눅스 배포판들이 Inotify를 실행하는 커널(Gentoo와 Ubuntu)을 제공하고 있거나 또는 이를 지원하는 보조 커널 패키지를 갖고 있었다. (Fedora와 SuSE). Andrew가 트리에서 Inotify 지원을 제거할 수도 있고 Inotify를 제거하는 일은 개발 단계에서는 종종 있는 일이였기 때문에 처음부터 다시 붙이는 것을 권장한다.
이 장치가 없다면 커널을 패치하고 장치를 만들어야 한다.
Inotify용 커널 패치
Linux Kernel Archives (참고자료)에서 Inotify 패치를 얻을 수 있다.
자신의 커널에 해당하는 버전 숫자 중 가장 높은 숫자를 가진 패치를 적용해야 한다. 배포판마다 커널 설치를 약간 다르게 핸들하긴 하지만 여기에서는 일반적인 가이드라인을 설명하겠다: Note: 배포판의 2.6 리눅스 커널 소스나, Linux Kernel Archives에서 안정적인 최신 릴리스를 사용해야 한다.
우선 커널 소스 디렉토리로 간다:
bash:~$ cd /usr/src
앞서 커널 소스를 설치했기 때문에 이를 패킹을 푼다(unpack):
bash:~$ sudo tar jxvf linux-source-2.6.8.1.tar.bz2
symlink를 새로운 소스 트리로 만든다:
bash:~$ sudo ln -sf linux-source-2.6.8.1 linux
현재 디렉토리를 방금 만든 커널 소스 디렉토리로 변경한다:
bash:~$ cd linux
Inotify 패치를 복사한다:
bash:~$ sudo cp ~/inotify* /usr/src
커널을 붙인다(patch):
bash:~$ sudo patch -p1 < ../inotify*.patch
커널을 구현한다:
bash:~$ sudo make menuconfig
inotify 기능을 확인하면서 일반적인 방식으로 커널을 설정한다. 필요하다면 이 새로운 커널을 bootloader에 추가한다. 단 구 커널 이미지와 bootloader 옵션을 기억해야 한다. 이 단계는 bootloader 마다 다양하다. (bootloader 관련 추가정보는 참고자료 참조). 머신을 재부팅하고 inotify 기능이 추가된 커널을 선택한다. 새로운 커널을 테스트하여 올바르게 작동하는지 확인한다.
inotify 장치 만들기
다음에는, /dev/inotify 장치가 만들어졌는지를 확인해야 한다. 다음은 그 단계이다. Important note: 마이너 넘버(minor number)가 변경될 수 있기 때문에 최신 것인지를 부지런히 검토해야 한다. 자신의 리눅스가 udev 기능을 지원한다면 자동으로 업데이트 된다.
새로운 커널로 재부팅 한 후에, 마이너 넘버를 획득해야 한다:
bash:~$ dmesg | grep ^inotify
다음은 리턴된 예제이다:
inotify device minor=63
inotify는 misc 장치이기 때문에 메이저는 10이다. 다음 명령행을 실행하여 장치 노드를 root 사용자로 만든다:
bash:~$ mknod /dev/inotify c 10 63
Note: 필요할 경우 "63"을 적당한 마이너 넘버로 대체한다.
선택적으로 허가(permission)를 설정해야 한다. 허가 설정 샘플은 다음과 같다:
bash:~$ chown root:root /dev/inotify
bash:~$ chmod 666 /dev/inotify
이제 파일 시스템 모니터링을 위한 inotify 장치를 사용할 준비를 갖추게 되었다.
애플리케이션에서 Inotify 사용하기
파일 시스템 이벤트에 임의의 디렉토리를 감시하는 샘플 프로그램일 만드는 방법을 설명하겠다. inotify가 파일 시스템 모니터링을 얼마나 쉽게 만드는지를 보여줄 예정이다.
주 메소드
이 간단한 예제를 통해 임의의 디렉토리에 대한 watch를 설정하는 것이 얼마나 쉬운지를 보게 될 것이다. 주요 헬퍼 루틴은 나중에 설명하도록 하겠다. 여기에 사용되는 샘플 코드는 Download 섹션을 참조하기 바란다.
Listing 1. 디렉토리에 대한 watch 설정하기
중요한 헬퍼 메소드
다음은 모든 inotify 기반 애플리케이션에 공통적으로 적용되는 가장 중요한 헬퍼 루틴들이다:
읽기를 위한 inotify 장치 열기
이 장치에서 읽혀지는 이벤트 큐잉(queuing)
애플리케이션들이 이벤트 공지를 사용하여 유용하게 일을 수행하도록 하는 이벤트 핸들러
여러 전략들이 사용될 수 있기 때문에 이벤트 큐잉에 대한 자세한 설명은 하지 않겠다. 멀티 쓰레디드 방식이 진화될수록 어디에서나 구현될 수 있다. 그와 같은 구현은 읽기 쓰레드가 inotify 장치에 대해 select()를 수행하고 그런 다음 이벤트를 몇몇 쓰레드가 공유된 스토리지(또는 Glib의 비동기식 메시지 큐)에 복사한다. 이곳은 핸들러 쓰레드가 실행되는 장소이다.
Listing 2. inotify 장치 열기
이것은 리눅스 시스템 상에서 파일들을 이용한 프로그래밍을 했다면 매우 익숙할 것이다.
Listing 3. 실제 이벤트-핸들링 루틴
각 case 문장 내에서 필요에 맞춰 구현한 어떤 메소드라도 실행할 수 있다.
퍼포먼스 모니터링과 관련하여 어떤 파일들이 가장 자주 읽히는지, 그리고 파일이 열려있던 기간을 파악할 수 있다. 이러한 종류의 모니터링은 쉽다. 어떤 상황에서, 짧은 기간 동안 애플리케이션에 의해 파일이 반복적으로 읽힌다면, 디스크로 돌아가기 보다는 메모리의 파일을 캐시하여 퍼포먼스를 향상시키기 때문이다.
특정 액션을 수행하는 이벤트 스팩의 핸들러들에 대한 다른 예제들도 이해하기 쉽다. 예를 들어, 기반 파일 시스템에 대해 메타데이터 스토리지 인덱스를 구현한다면 파일 생성 이벤트를 찾아 그 파일에 대한 데이터 마이닝 작동을 실행할 수 있다. 보안을 위해서는, 어떤 누구도 작성해서는 안되는 디렉토리에 파일이 쓰여졌다면 시스템 경고를 실행할 수 있다.
inotify가 많은 정밀한 이벤트들 CLOSE versus CLOSE_WRITE을 지원한다는 것도 기억하라.
이 글에서 사용된 코드의 많은 이벤트들이 코드가 실행될 때마다 보고자 하는 것이 아닐 수도 있다. 사실, 가능하다면 본인의 애플리케이션에 필요한 이벤트의 하위세트만 요청할 수 있으면 좋겠다. 이 글에서 제시한 코드에서는 전체 마스크를 사용하여 많은 이벤트들을 보여주고자 하였다. (샘플 코드에 있는 51줄의 main 메소드 (참고자료) 또는 Listing 1의 29줄) 애플리케이션 프로그래머들은 일반적으로 많은 선택권이 주워지길 바란다. 또한 여러분도 필요에 맞는 특정 마스크가 필요하다. 이는 앞서 보여준 handle_event() 메소드에서 catch 문장에서 관심 없는 아이템들을 제거할 수 있다.
결론
inotify가 퍼포먼스 모니터링, 디버깅, 자동화 같은 분야에 적용된다면 강력하고 정밀한 리눅스 파일 시스템의 모니터링 메커니즘이 된다. 이 글에 제시된 코드를 사용하여 최소한의 퍼포먼스 오버헤드로 실시간 파일 시스템 이벤트에 응답하고 이를 기록할 수 있는 애플리케이션을 작성할 수 있다.
http://www-128.ibm.com/developerworks/k ··· ify.html
"System" 카테고리의 다른 글
- 여러 가지 설정으로 공격으로부터 시스템을 안전하... (0)2007/05/10
- 데이터 문제에 대한 차세대 NFS 계열 파일 시스템... (0)2007/05/10
- inotify를 이용한 리눅스 파일 시스템 감시 (0)2007/05/10
- Secure programmer: 컴포넌트를 안전하게 호출하기 (0)2007/05/04
- 리눅스에서의 메모리관리 (0)2007/05/04

수안이의 컴퓨터 연구실



Leave your greetings.