/* **************************************************************************** * PROGRAM MODULE * * $Workfile: agent.cpp $ * $Author: poullain $ * $Date: 2005/07/18 13:26:53 $ * * Copyright (C) 2004 by SPiDCOM Technologies All rights reserved. * **************************************************************************** */ #ifndef _eventManager_cpp #define _eventManager_cpp #include "macro.h" #include "processManager.h" //#include "eventListener.h" //#include "requestManager.h" #include "agent_pp/system_group.h" #include #ifndef WIN32 #include #endif #include "mib-common.h" #include "systemmanager.h" #include "AlarmListManager.h" #include "eventListener.h" #include "agent_pp/agent++.h" #include "agent_pp/system_group.h" // quick fix for SNMP bug when master crashes with many slaves pthread_mutex_t condition_mutex = PTHREAD_MUTEX_INITIALIZER; pthread_cond_t condition_cond = PTHREAD_COND_INITIALIZER; //using namespace threads_namespace; using namespace agentsnmp; //Singleton instance processManager* processManager::m_instance_p = 0; //Table of threads pthread_t processManager::m_threadsTable[NB_THREADS]; /** * Handler for Interruption signal in main process => kill all threads and release memory */ void killAllThreads(int sigNb) { int status = 0; switch (sigNb) { case SIGINT: case SIGTERM: { cout<<"user abort"<killThreads(sigNb); processManager::instance()->freeMemory(); SystemManager::instance()->freeMemory(); AlarmListManager::instance()->freeMemory(); //exit(0); break; } case SIGSEGV: { pthread_t interruptedThread = pthread_self(); cout<<"Segmentation fault in Thread id: "<< interruptedThread<killThreads(interruptedThread, sigNb); //pthread_kill(interruptedThread, SIGUSR1); processManager::instance()->freeMemory(); SystemManager::instance()->freeMemory(); AlarmListManager::instance()->freeMemory(); // exit(1); status = 1; break; } default: { cout<<"Unhandled signal"<freeMemory(); // SystemManager::instance()->freeMemory(); // AlarmListManager::instance()->freeMemory(); cout<<"Aborting Program"<killThreads(interruptedThread, sigNb); } /** * Manager the incommong SNMP requests */ void* requestManagerRun(void* varg) { //u_short* port = (u_short*) varg; u_short* port = static_cast (varg); DEBUG_IF((port==0), "port is null ponteur<startRequestManager(*port); else //port chosen by default: 161 processManager::instance()->startRequestManager(161); return 0; } #ifdef TRAP_SUPPORT /** * Manager the incommong events from kernel */ void* eventListenerRun(void* varg) { processManager::instance()->startEventListener(); return 0; } #endif /** * Manager the polling of the alarm OIDs */ void* alarmManagerRun(void* varg) { processManager::instance()->startAlarmManager(); return 0; } void processManager::killThreads(pthread_t interruptedThread, int sigNb) { DEBUG("kill threads in process manager"<run(); } #endif void processManager::startAlarmManager() { int i = 0; char temp[32]; while (true) { sleep(15); SystemManager::instance()->checkAllAlarms(); } return; } void processManager::startRequestManager(u_short port) { #ifndef WIN32 struct sigaction action; action.sa_flags = 0; action.sa_handler = killAllThreads; sigemptyset(&(action.sa_mask)); if ( sigaction(SIGSEGV, &action, NULL) < 0 ) { DEBUG("Cannot set SIGSEGV signal!" << endl); } #endif int status; m_port = port; Snmp::socket_startup(); // Initialize socket subsystem Snmpx snmp(status, m_port ); if (status != SNMP_CLASS_SUCCESS) { cerr << "main: SNMP port [" << port << "] init failed." << endl; cerr << "Please check that it is not already used by another application." << endl; exit(1); } m_mib = new Mib(); m_reqList = new RequestList(); #ifndef _NO_LOGGING // set the DefaultLog used for log feature #ifndef REMOTE_LOG char* user = getenv("USER"); char location[100] = "/tmp"; if ( NULL != user ) { strcat(location,"/"); strcat(location,user); mkdir(location,0777); } strcat(location,"/sm-agent.log"); AgentLog* agentLog = new AgentLogImpl(location); #else //printf("remote logger: before creation\n"); AgentLog* agentLog = new AgentRemoteLog("192.168.6.9",5501); //printf("remote logger: after creation\n"); #endif // REMOTE_LOG DefaultLog::init(agentLog); //printf("DefaultLog initialized\n"); #endif // _NO_LOGGING // register requestList for outgoing requests m_mib->set_request_list(m_reqList); #ifdef __LINUX__ init_socket(); #endif //__LINUX__ // get agent config from file init_agent_config(); //---- FD01: SNMP community // mib initialisation SystemManager::instance()->Init( *m_mib ); SystemManager::instance()->setMib(m_mib); m_mib->init(); // request list initialisation m_reqList->set_snmp(&snmp); char snmp_GET_community_name[ASN_MAX_NAME_LEN]; char snmp_SET_community_name[ASN_MAX_NAME_LEN]; SystemManager::instance()->getSNMPCommunity( snmp_GET_community_name, snmp_SET_community_name ); m_reqList->set_read_community( OctetStr(snmp_GET_community_name)); m_reqList->set_write_community( OctetStr(snmp_SET_community_name)); Request* req = 0; LOG_BEGIN(DEBUG_LOG); LOG("agent has been started"); LOG_END; SnmpTarget::set_default_timeout(1000); //generate a segmentation fault in thread int segfault = 0; // bool mibCleaned = false; // signal the condition variable to allow eventListener thread to continue pthread_mutex_lock(&condition_mutex); pthread_cond_signal(&condition_cond); pthread_mutex_unlock(&condition_mutex); while (true) { req = m_reqList->receive(120); /* if (segfault>5) { cout<<"Manual segmentation fault generated for test"<process_request(req); // mibCleaned = false; // ++segfault; } else { //if (!mibCleaned) //{ m_mib->cleanup(); // mibCleaned = true; //} } } delete m_reqList; delete m_mib; #ifdef __LINUX__ close_socket(); #endif //__LINUX__ } /** * To get the only Singleton instance */ processManager* processManager::instance() { if ( m_instance_p == 0 ) { m_instance_p = new processManager(); } return m_instance_p; } /** * To avoid singleton memory leaks */ void processManager::freeMemory() { if (0 != m_reqList) delete m_reqList; if (0 != m_mib) delete m_mib; m_threadsTable[0]=0; m_threadsTable[1]=0; if ( m_instance_p != 0 ) { delete m_instance_p; m_instance_p = 0; } } processManager::~processManager() { } /* commonThread* processManager::getNthThread(int i) { if (i>NB_THREADS) return 0; else return m_threadsTable[i]; } */ RequestList* processManager::getReqList() { return m_reqList; } Mib* processManager::getMib() { return m_mib; } void processManager::initThreads(u_short* port) { // Alarm Initialisation //cout<<"instanciation of AlamrListManager in main"<startRequestManager(*port); retcode = pthread_create(&m_threadsTable[1], 0, requestManagerRun, port); if (retcode != 0) { cerr << "create_thread: " << m_threadsTable[1] << " failed!" << endl; } DEBUG("SNMP Request Manager Thread"<