Утечка дескриптора файла приводит к потоку сообщений об ошибках от net-snmp. Звучит знакомо?
Я столкнулся со странной проблемой, когда огромное количество сообщений от snmp_synch_response () snmplib умудряются заполнить жесткий диск объемом 60 ГБ примерно за три часа. часы. Сообщения все "Используйте snmp_sess_select_info2() для обработки большие файловые дескрипторы", иногда повторяемые более ста раз в секунду. линия. Я все еще работаю с клиентом, чтобы выяснить, как воспроизвести это в доме, но я подумал, что спрошу здесь на случай, если это старый вопрос или, по крайней мере, по крайней мере, видел кто-то другой. в каком-то смысле.
Вот основная информация о системе: 8.1-RELEASE-p2 FreeBSD i386. Сеть-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 ответа:
В случае, если кому-то удастся столкнуться с чем-то подобным, это (неудивительно) закончилось тем, что не имело ничего общего с net-snmp. Каждый дочерний процесс связывается с родительским через свой собственный сокет. По основной природе fork(), Родительский список сокетов копировался каждому дочернему; решение состояло в том, чтобы просто закрыть сокеты в этом списке в дочернем коде.
Для тех, кто может закончить здесь гуглить то же самое сообщение об ошибке. Проблема в моем коде заключалась в том, что создание новых сеансов, когда старые не закрыты должным образом (snmp_close может завершиться ошибкой, я не проверял это), может вызвать эту ошибку в новых сеансах.
Я решил эту проблему с помощью snmp_close_sessions().