2010-12-15 3 views
0

제 목표는 커널에서 많은 활동을 기록하는 것입니다. 이를 위해서는 디스크 기반 파일 시스템에 기록해야합니다.리눅스에서 커널과 사용자 공간간에 의사 소통하고 동기화하는 가장 좋은 방법

그래서 문자 장치 드라이버와이 가상 장치에서 읽는 사용자 공간 프로세스를 구현했습니다. 드라이버는 데이터를 사용자 공간 버퍼에 복사하고 사용자 프로세스는이 파일을 파일에 씁니다.

내 문제는 데이터를 동기화하는 방법입니다. FIFO 용 커널 구현에서 kfifo를 사용하기 시작했습니다. 그래서 어디서나 로그를 만들고 싶습니다. 나는 FIFO에 데이터를 복사하기 위해 kfifo API를 사용합니다. 가상 장치 드라이버는 FIFO에서 읽고이를 사용자 공간에 복사합니다. 기록되는 데이터가 거대하기 때문에 제작자 소비자와 같은 동기화가 필요합니다. 내가 사용할 수있는 리눅스 커널에 그런 지원이 있는가?

netlink 소켓이 그런 문제를 해결합니까 ??

답변

0

릴레이 인터페이스를 사용할 수도 있습니다 (Documentation/filesystems/relay.txt 참조).

0

netlink 소켓이 char 디바이스보다 나은 용도로 사용될 것이라고 생각합니다. 커널은 쓰기를 원할 때마다 소켓에 쓸 것이고,이 소켓에서 기다리고있는 사용자 프로그램은 그것을 읽을 것이고 그것을 파일에 쓸 것이다.

또한 정보를 얻고 모듈을 작성하지 않거나 프로덕션 용도로 Linux 커널을 변경하지 않으려 고하면 커널에서 로그하는 중일 때 커널에서 파일을 열고 쓰는 것이 더 간단하고 빠릅니다 시각).

0

로그 할 데이터가 많고 로그 데이터를 놓치지 않으려면 간단한 이중 버퍼링 원리를 사용할 수도 있습니다.

kfifo에 대해 잘 모르겠지만 문자 장치 드라이버의 읽기 호출에서 장치에서 읽을 데이터가 없으면 사용자 공간 프로세스를 절전 모드로 설정할 수 있습니다. 커널이 문자 장치에 쓸 때마다 장치에서 대기중인 모든 프로세스를 깨울 수 있습니다. 예 :

In kernel 
struct logbufStruct { 
    char *kbuf; //by kmalloc or any means you wish. 
    int ptr; //ptr to next writeable byte in kbuf. 
    size_t kbuf_size; 
    unsigned int flags; 
    wait_queue_head_t data_wait; 
} 
read(inode, filep, buf, size) { 
    logbufStruct = filep->private_data 
    if (!test_bit(HAS_DATA, &logbufstruct.flags)) 
    wait_event_interruptible(&logbufstruct->data_wait, 
      test_bit(HAS_DATA, &logbufstruct.flags)|| 
      test_bit(ERROR, &logbufstruct.flags)); 
    /* 
    * When this call returns, you would either have woken up 
    * on data available or some signal interrupt which you should 
    * handle in your character device and set appropriate flags. 
    */ 
    if (test_bit(ERROR, &logbufstruct.flags) return -1; 
    numbytes = copy_data(logbufStruct, buf, size); 
    if(!has_more_data(logbufstruct)) clear_bit(HAS_DATA, &logbufstruct.flags); 
    return numbytes; 
} 

/* This is the function your modules would call to log data 
    * to be sent to userspace. 
    */ 
int mylogger_log(logbufstruct, char *msg, size_t n) 
{ 
    if (logbufstruct->ptr + n > logbufstruct->kbuf_size) 
     return -1; 
    copy the data. 
    wake_up_interruptible(&logbufstruct->data_wait); 
} 
//initialization 
    init_waitqueue_head(&logbufstruct->data_wait); 
    logbufstruct->kbuf = kmalloc or whatever way you have to allocate 
    space for holding log messages in memory. 
관련 문제