文件描述符泄漏导致net-snmp出现错误消息。听起来有点熟?

问题描述 投票:2回答:2

我遇到了一个奇怪的问题,来自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);
}
c freebsd net-snmp
2个回答
2
投票

如果有人设法遇到类似的东西,这(不出所料)最终与net-snmp没有任何关系。每个子进程通过自己的套接字与父进程通信。根据fork()的基本特性,父节点的套接字列表被复制到每个子节点;解决方案只是关闭子代码中此列表中的套接字。


1
投票

对于那些可能最终在谷歌搜索相同的错误消息。我的代码中的问题是,当旧的会话未正确关闭时创建新会话(snmp_close可能会失败,我没有检查这个)可能会在新会话上抛出此错误。

我通过使用snmp_close_sessions()解决了这个问题。

© www.soinside.com 2019 - 2024. All rights reserved.