Система зависает, если я перезагружаюсь или выключаю работающий демон, который управляет доступом к файлам с помощью fanotify

0

Я применил для своего демона 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 этим демонам при перезагрузке/завершении работы, это правильно? Если да, то демон не может разрешить доступ к любому файлу и блокирует систему?

Пожалуйста помоги.

Я использую Ubuntu 12.04 64-бит с ядром 3.11.0.

  • 0
    Я верю, что вижу, как Сигкилл отправляется на демонов. Возможно, я тоже не прав.
  • 0
    Да, я тоже так думаю, но демоны как-то приостановлены?
Показать ещё 2 комментария
Теги:
fanotify

1 ответ

0

Я узнал, почему он заблокирован.

По-видимому, при перезагрузке Linux интенсивно обращается к файлам, которые контролируются моим демоном. Каждый доступ должен быть разрешен в вызове _this.IsReplyReadyNow(), который в свою очередь использует несколько вызовов syslog() для регистрации событий файловой системы. При перезагрузке в syslog после того, как некоторые из моих записей пришли к этому сообщению:

"imuxsock начинает отбрасывать сообщения из-за ограничения скорости"

и после этого мой демон заблокирован и остановился, чтобы разрешить или запретить права доступа к файлу, и поэтому заблокировал систему.

Когда я прокомментировал вызовы syslog(), система, наконец, перезагрузилась.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню