
Шустрый

Профиль
Группа: Участник
Сообщений: 73
Регистрация: 10.8.2006
Где: Киев
Репутация: нет Всего: нет
|
В приложении отдельный поток выполняет роль SNMP агента. В общем, обычная процедура загрузки агента: Header: | Код | namespace Snmp { class Agent : public Process { public: Agent(); ~Agent(); int main(); static const char *sessionName; private: char *objectid; snmp_session session, *snmpSession; };
// SNMP MIB initialization routine void InitMIB(void); unsigned char* ProceedRequest(variable *vp, oid *name, size_t *length, int exact, size_t *var_len, WriteMethod **write_method); }
|
Исходник: | Код |
Snmp::Agent::Agent() { objectid = strdup(".1.7.2.3.8.2.3773.1.1.1.1.4.0"); //Snmp object ID // Init session. Using SNMP v1 snmp_sess_init(&session); session.peername = "127.0.0.1"; session.version = SNMP_VERSION_1; session.community = (u_char*)strdup(Snmp::Agent::sessionName); session.community_len = strlen(Snmp::Agent::sessionName);
snmpSession = snmp_open(&session); if(!snmpSession) smartlog(Log::Fatal, Log::SNMP, "Can't start SNMP session"); init_mib(); }
AGate::Snmp::Agent::~Agent() { snmp_close(snmpSession); free(objectid); free(session.community); }
int Snmp::Agent::main() { smartlog(Log::Info, Log::SNMP, "Starting SNMP agent..."); // Init SNMP agent snmp_enable_stderrlog();
netsnmp_ds_set_boolean(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_ROLE, 1); netsnmp_ds_set_string(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_X_SOCKET, "127.0.0.1:705");
init_agent(Snmp::Agent::sessionName); Snmp::InitMIB(); init_snmp(Snmp::Agent::sessionName); while(Process::is_running()) { agent_check_and_process(0); // SNMP request process usleep(20000); } snmp_shutdown(Snmp::Agent::sessionName); smartlog(Log::Info, Log::SNMP, "SNMP agent terminated..."); return 0; }
struct variable2 snmpVariables[] = { /* magic number , variable type , ro/rw , callback fn , L, oidsuffix */ {enSystemTime, ASN_INTEGER, RONLY, Snmp::ProceedRequest, 1, {enSystemTime}}, {enShutdown, ASN_OCTET_STR, RWRITE, Snmp::ProceedRequest, 1, {enShutdown}}, {enReloadConfig, ASN_OCTET_STR, RWRITE, Snmp::ProceedRequest, 1, {enReloadConfig}}, {enClearCall, ASN_OCTET_STR, RWRITE, Snmp::ProceedRequest, 1, {enClearCall}}, {enMonitor, ASN_OCTET_STR, RONLY, Snmp::ProceedRequest, 1, {enMonitor}}, {enVersion, ASN_OCTET_STR, RONLY, Snmp::ProceedRequest, 1, {enVersion}} };
void Snmp::InitMIB(void) { DEBUGMSGTL((Snmp::Agent::sessionName,"initializing\n")); // Register ourselves with the agent to handle our mib tree REGISTER_MIB(Snmp::Agent::sessionName, snmpVariables, variable2, snmpVariablesObjectID);
// ... }
|
Snmp::Agent::main() можно считать центральной функцией потока в pthreads, вроде void *ReloadingThread(void *)  Так или иначе, мы открываем сессию SNMP, инициализируем все, регистрируем обработчики SNMP агента определенные в snmpVariables через REGISTER_MIB() С этого момента через каждые 20000 микросекунд в цикле потока запускается agent_check_and_process() и сам Net-SNMP framework запускает Snmp::ProceedRequest(), где мы собственно обрабатываем request'ы. Это все стандартно. Проблема в том, что framework какого-то запускает ProceedRequest() дважды для каждого обработчика, кроме первого - enSystemTime. Причем по параметрам нет надежного способа отличить - повторный вызов или нет. Для маленького вызова это нормально, но для тяжелого по временной сложности - уже нет. В общем, если кто-то сталкивался с подобной проблемой и решил ее... Это сообщение отредактировал(а) Dragon - 15.8.2006, 15:54
|