Утечка файлового дескриптора приводит к потоку сообщения об ошибке из net-snmp.Звучит знакомо? - PullRequest
2 голосов
/ 15 марта 2012

Я столкнулся со странной проблемой, когда огромному количеству сообщений от snmplib's snmp_synch_response () удается заполнить жесткий диск объемом 60 ГБ в течение примерно трех часов.Все сообщения «Использовать snmp_sess_select_info2 () для обработки больших файловых дескрипторов», иногда повторяются более ста раз в строке.Я все еще работаю с заказчиком, чтобы выяснить, как воспроизвести это собственное дело, но я подумал, что могу спросить здесь, если это старая проблема или, по крайней мере, замечена кем-то еще.

Вот основная информация о системе: 8.1-RELEASE-p2 FreeBSD i386.Версия NET-SNMP - 5.5.

Ниже приведен упрощенный фрагмент ключевых частей моего кода.Сначала код создает список задач с инициализированными, но не открытыми сессиями.В других местах каждая задача, вплоть до небольшого предела (в нашем случае 64), разветвляется, и дочерние элементы открывают сокеты сеансов SNMP с помощью snmp_open () и так далее.Я просмотрел каждый из set (), get () и getnext () и уверен, что все они вызывают snmp_close () соответствующим образом - ранних возвратов или других переходов по этим вызовам нет - поэтому я неЯ думаю, что я явно пропускаю любые сокеты, но дескрипторы должны почему-то торчать.Это звонит кому-нибудь в колокола?

for(…){
    …
    snmp_sess_init(&task->sess_info);
    addtask(taskList, task);
    …
}

…

for(task = taskList; task && nkids < maxkids; task = task->next){
    if(fork() == 0){
        set(task);
        get(task);
        getnext(task);
        …
    }
    nkids++;
}

void set(Task *task){
    …
    sess = snmp_open(&task->sess_info);
    …
    pdu = snmp_pdu_create(SNMP_MSG_SET);
    …
    status = snmp_synch_response(sess, pdu, &resp);
    // check return, retr
    snmp_close(sess);
}

void get(Task *task){
    …
    sess = snmp_open(sess_info);
    …
    pdu = snmp_pdu_create(SNMP_MSG_GET);
    …
    status = snmp_synch_response(sess, pdu, &resp);
    // check return, read variables
    snmp_close(sess);
}

void getnext(Task *task){
    …
    sess = snmp_open(sess_info);
    for(obj = task->objs; obj; obj = obj->next){
        …
        pdu = snmp_pdu_create(SNMP_MSG_GET);
        …
        status = snmp_synch_response(sess, pdu, &resp);
        // check return, read variables
    }
    snmp_close(sess);
}

Ответы [ 2 ]

2 голосов
/ 16 мая 2012

В случае, если кому-то удастся столкнуться с чем-то подобным, это (неудивительно) в конечном итоге не имело ничего общего с net-snmp.Каждый дочерний процесс связывается с родителем через собственный сокет.По своей сути fork () список сокетов родительского объекта копировался для каждого дочернего элемента;решение было просто закрыть сокеты в этом списке в дочернем коде.

1 голос
/ 29 декабря 2017

Для тех, кто может здесь погуглить одно и то же сообщение об ошибке.Проблема в моем коде заключалась в том, что создание новых сессий, когда старые не были должным образом закрыты (snmp_close может завершиться ошибкой, я не проверял это) МОЖЕТ выдать эту ошибку на новых сессиях.

Я решил эту проблему с помощьюsnmp_close_sessions ().

...