데몬이 파일에 대한 액세스를 제어하기 위해 fanotify API를 사용하게했습니다. 다음은 작업 스레드입니다.fanotify를 사용하여 파일에 대한 액세스를 제어하는 실행중인 데몬으로 시스템을 재부팅하거나 종료하면 시스템이 멈 춥니 다
void * threadProc(void * data)
{
if(data == NULL) return 0;
RealTimeDrvrImp & _this = *((RealTimeDrvrImp *)data);
const unsigned int fi_flags = FAN_CLOEXEC | FAN_CLASS_CONTENT | FAN_NONBLOCK;
const unsigned int fi_event_f_flags = O_RDONLY | O_LARGEFILE;
_this.m_fa_fd = fanotify_init(fi_flags, fi_event_f_flags);
if (-1 == _this.m_fa_fd)
return NULL;
const unsigned int fm_flags = FAN_MARK_ADD | FAN_MARK_MOUNT;
const uint64_t fm_event_f_flags = FAN_OPEN_PERM /*| FAN_ACCESS_PERM*/ /*| FAN_CLOSE_WRITE*/;
if (-1 == fanotify_mark(_this.m_fa_fd, fm_flags, fm_event_f_flags, 0, "/"))
{
close(_this.m_fa_fd);
return NULL;
}
char buf[4096];
int len = 0;
struct timespec tmsp = { 0, 1000000 };//500 miliseconds
pid_t self_pid = getpid();
while(_this.m_DoAvRealtimeScanThread)
{
if(-1 == (len = read(_this.m_fa_fd, (void *) &buf, sizeof (buf))))
{
if(EAGAIN == errno)
{
nanosleep(& tmsp, NULL);
continue;
}
else
break;
}
const struct fanotify_event_metadata *metadata
= (struct fanotify_event_metadata *) buf;
while (FAN_EVENT_OK(metadata, len)) {
if (metadata->fd != FAN_NOFD) {
if (metadata->fd >= 0)
{
bool bCloseFdNow = true;
if( metadata->mask & FAN_OPEN_PERM ||
metadata->mask & FAN_ACCESS_PERM)
{
bool bWriteNow = true;
struct fanotify_response response = {0,0};
response.fd = metadata->fd;
response.response = FAN_ALLOW;
if(metadata->pid == self_pid)
{//this process event, always allow
}
else if(_this.IsReplyReadyNow(response))
{//response.response is set in IsReplyReadyNow();
}
else //else event is added to a queue,
//will be handled and closed later in another thread
{
bCloseFdNow = false;
bWriteNow = false;
}
if(bWriteNow)
{
pthread_mutex_lock(& _this.m_faWriteMtx);
write(_this.m_fa_fd, &response, sizeof (struct fanotify_response));
pthread_mutex_unlock(& _this.m_faWriteMtx);
}
}
if(bCloseFdNow)
close(metadata->fd);
}
}
metadata = FAN_EVENT_NEXT(metadata, len);
}
}
close(_this.m_fa_fd);
_this.m_fa_fd = -1;
return NULL;
}
올바르게 작동합니다. 재부팅하기 전에 데몬을 중지 시키거나 모든 것을 종료해도 괜찮습니다. 하지만 시스템을 재부팅하거나 데몬이 실행중인 경우 시스템이 정지합니다.
아마도 시스템이 SIGSTOP을 재부팅/시스템 종료시 데몬으로 보내는 것일까 요? 맞습니까? 그렇다면 데몬은 모든 파일에 대한 액세스를 허용 할 수 없으며 시스템을 잠급니다.
도와주세요.
저는 커널 3.11.0에서 64 비트 우분투 12.04를 사용하고 있습니다.
나는 SIGKILL이 데몬으로 보내지는 것을 본다. 나도 틀렸어. – DumbCoder
그래, 나도 그렇게 생각한다. 그러나 그 사이에 데몬이 어떻게 든 잠겨 있니? – kopalvich
재부팅 중에 다른 사용자 프로세스가 어떻게 중지됩니까? 어쩌면 당신은 그것을 따를 수 있습니다. Probabaly 브라우저를 열고 재부팅을 시작하십시오. – DumbCoder