[英]System freezes if I reboot or shutdown with a running daemon that controls access to files using fanotify
I made my daemon use fanotify API to control access to files. 我使守护程序使用fanotify API来控制对文件的访问。 Here is the working thread: 这是工作线程:
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;
}
It works correctly. 它可以正常工作。 If I stop the daemon before rebooting or shutting down everything is okay. 如果我在重新引导或关闭之前停止了守护进程,一切都还可以。 But if I'm trying to reboot the system or shutdown whith the daemon running, the system freezes. 但是,如果我尝试重新引导系统或关闭运行守护程序的系统,系统将冻结。
I thougth that maybe the system sends SIGSTOP to it's daemons on reboot/shutdown, is that correct? 我认为系统可能会在重新启动/关闭时将SIGSTOP发送到它的守护程序,对吗? If so the daemon cannot allow any access to any file and that locks the system? 如果是这样,该守护程序无法允许任何文件访问并且锁定了系统?
Please help. 请帮忙。
I'm using Ubuntu 12.04 64-bit with kernel 3.11.0. 我正在使用带有内核3.11.0的64位Ubuntu 12.04。
I found out why it blocked. 我发现了为什么阻止。
Apparently on reboot linux intensively accesses files, which are controlled by my daemon. 显然,重新启动后,Linux会密集访问文件,这些文件由我的守护程序控制。 Each access must be allowed in _this.IsReplyReadyNow() call, which in it's turn uses several syslog() calls to log filesystem events. 必须在_this.IsReplyReadyNow()调用中允许每次访问,而该调用又使用多个syslog()调用来记录文件系统事件。 On reboot in syslog after some of my entries came this message: 在我的某些条目输入后,在syslog中重新启动时出现以下消息:
'imuxsock begins to drop messages from due to rate-limiting' “由于速率限制,imuxsock开始丢弃邮件”
and after that my daemon blocked, and stopped to allow or deny file access permissions, and so blocked the system. 之后,我的守护程序被阻止,并停止以允许或拒绝文件访问权限,从而阻止了系统。
When I commented out syslog() calls, the system finally rebooted. 当我注释掉syslog()调用时,系统终于重新启动。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.