원래 하려고 했던게, 특정 데몬에서 하드웨어 검출하는 작업을 polling이 아니라 interrupt 방법으로 구현하는 것이었다.  여기저기 찾아본 결과 여러가지 방법이 있었지만 그중에서 udev event에서 제어하기로 하였다.

Kernel의 소스트리에 lib/kobject_uevent.c를 보면 다음과 같은 부분을 찾을 수 있다.

if (uevent_helper[0]) {
  char *argv[3];

  argv [0] = uevent_helper;
  argv [1] = (char *)subsystem;
  argv [2] = NULL;
  call_usermodehelper (argv[0], argv, envp, 0);
}

여기서 말하는 uevent_helper라는 것은, 단순히 문자열인데 여기서는 "/sbin/hotplug"를 의미한다.  결국 uevent가 작동하면, /sbin/hotplug를 작동시키는데, argv와 envp를 저렇게 만들어주겠다는 의미이다.

실제로 /sbin/hotplug도 이러한 인자와 환경변수들을 바탕으로 작업을 수행하도록 되어있다.

어찌되었던, 여기에다 몇줄을 추가했다.

if (0 == strcmp ("mount", action_string) || 0 == strcmp ("umount", action_string)) {
  argv [0] = "/root/detect_test";
  call_usermodehelper (argv[0], argv, envp, 0);
}


이렇게 하면, /root/detect_test가 장치가 mount/umount 되었을 때에 /sbin/hotplug가 실행될때와 동일한 인자와 환경변수들을 가지고 실행되게 된다.  detect_test에서 간단히 결과를 찍어보면 (그냥 printf로는 확인 안됨)

/root/detect_test
block

HOME=/
PATH=/sbin:/bin:/usr/sbin:/usr/bin
ACTION=mount
DEVPATH=/block/sda/sda1
SUBSYSTEM=block
SEQNUM=706
MINOR=1
MAJOR=8
PHYSDEVPATH=/devices/platform/s3c2410-ohci/usb1/1-1/1-1:1.0/host0/target0:0:0/0:0:0:0
PHYSDEVBUS=scsi
PHYSDEVDRIVER=sd


ACTION에서 알 수 있다시피, 이것은 mount되었을 때의 argv와 envp이다.

/root/detect_test
block

HOME=/
PATH=/sbin:/bin:/usr/sbin:/usr/bin
ACTION=umount
DEVPATH=/block/sda/sda1
SUBSYSTEM=block
SEQNUM=707
MINOR=1
MAJOR=8
PHYSDEVPATH=/devices/platform/s3c2410-ohci/usb1/1-1/1-1:1.0/host0/target0:0:0/0:0:0:0
PHYSDEVBUS=scsi
PHYSDEVDRIVER=sd


당연히 이것은 umount 하였을 때이다.

이 프로그램에서 이 ACTION 값을 바탕으로 signal을 받기 원하는 daemon에게 (아마 select ()로 기다리고 있을) 전달해주면 되겠다.
Posted by 강군님

댓글을 달아 주세요