gpt4 book ai didi

c++ - 如果我使用 fanotify 控制对文件的访问的正在运行的守护进程重新启动或关闭,系统会卡住

转载 作者:太空宇宙 更新时间:2023-11-04 04:05:18 29 4
gpt4 key购买 nike

我让我的守护进程使用 fanotify API 来控制对文件的访问。这是工作线程:

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,这是正确的吗?如果是这样,守护进程将无法允许对任何文件进行任何访问,从而锁定系统?

请帮忙。

我使用的是 Ubuntu 12.04 64 位,内核为 3.11.0。

最佳答案

我找到了它被阻止的原因。

显然,在重新启动时,Linux 会密集地访问由我的守护进程控制的文件。 _this.IsReplyReadyNow() 调用中必须允许每次访问,该调用又使用多个 syslog() 调用来记录文件系统事件。在我的一些条目之后重新启动系统日志时,出现以下消息:

'imuxsock begins to drop messages from due to rate-limiting'

之后我的守护进程被阻止,并停止以允许或拒绝文件访问权限,从而阻止了系统。

当我注释掉 syslog() 调用时,系统终于重新启动了。

关于c++ - 如果我使用 fanotify 控制对文件的访问的正在运行的守护进程重新启动或关闭,系统会卡住,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21413206/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com