我遇到了一个奇怪的问题,来自 snmplib 的 snmp_synch_response() 的大量消息在大约三个小时内设法填满了 60GB 硬盘。这些消息都是“使用 snmp_sess_select_info2() 处理大型文件描述符”,有时每行重复一百多次。我仍在与客户合作,以找出如何在内部重现此问题,但我想我会在这里问一下,以防这是一个老问题,或者至少以某种方式被其他人看到。
这是基本的系统信息:8.1-RELEASE-p2 FreeBSD i386。NET-SNMP 版本是 5.5。
下面是我的代码关键部分的简化片段。代码首先创建一个包含已初始化但未打开的会话的任务列表。在其他地方,每个任务,最多一个小的限制(在这种情况下为 64 个),都被分叉,并且子进程使用 snmp_open() 打开 SNMP 会话套接字,依此类推。我已经搜索了 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);
}