/* Copyright (C) 2014 InfiniDB, Inc. Copyright (C) 2016 MariaDB Corporaton This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /****************************************************************************************** ******************************************************************************************/ /** * @file */ #include #include #include #include #include #include #if defined(__linux__) #include #include #include #include #elif defined (_MSC_VER) #elif defined (__FreeBSD__) #include #include #include #include #include #include #include #endif #include #include #include #include "ddlpkg.h" #include "../../dbcon/dmlpackage/dmlpkg.h" #define LIBOAM_DLLEXPORT #include "liboamcpp.h" #undef LIBOAM_DLLEXPORT #ifdef _MSC_VER #include "idbregistry.h" #endif #include "installdir.h" #include "dbrm.h" #include "sessionmanager.h" #include "IDBPolicy.h" #include "IDBDataFile.h" #if defined(__GNUC__) #include static const std::string optim("Build is " #if !defined(__OPTIMIZE__) "NOT " #endif "optimized"); #endif namespace fs = boost::filesystem; using namespace alarmmanager; using namespace config; using namespace std; using namespace messageqcpp; using namespace oam; using namespace logging; using namespace BRM; namespace oam { // flag to tell us ctrl-c was hit uint32_t ctrlc = 0; // flag for using HDFS // -1: non-hdfs // 0: unknown // 1: hdfs int Oam::UseHdfs = 0; //------------------------------------------------------------------------------ // Signal handler to catch Control-C signal to terminate the process // while waiting for a shutdown or suspend action //------------------------------------------------------------------------------ void handleControlC(int i) { std::cout << "Received Control-C to terminate the command..." << std::endl; ctrlc = 1; } Oam::Oam() { // Assigned pointers to Config files string calpontfiledir; const char* cf=0; InstallDir = startup::StartUp::installDir(); calpontfiledir = InstallDir + "/etc"; //FIXME: we should not use this anymore. Everything should be based off the install dir //If CALPONT_HOME is set, use it for etc directory #ifdef _MSC_VER cf = 0; string cfStr = IDBreadRegistry("CalpontHome"); if (!cfStr.empty()) cf = cfStr.c_str(); #else cf = getenv("CALPONT_HOME"); #endif if (cf != 0 && *cf != 0) calpontfiledir = cf; CalpontConfigFile = calpontfiledir + "/Columnstore.xml"; AlarmConfigFile = calpontfiledir + "/AlarmConfig.xml"; ProcessConfigFile = calpontfiledir + "/ProcessConfig.xml"; if (UseHdfs == 0) { try { Config* sysConfig = Config::makeConfig(CalpontConfigFile.c_str()); string tmp = sysConfig->getConfig("Installation", "DBRootStorageType"); if (boost::iequals(tmp, "hdfs")) UseHdfs = 1; else UseHdfs = -1; } catch(...) {} // defaulted to false } } Oam::~Oam() {} /******************************************************************** * * get System Software information * ********************************************************************/ void Oam::getSystemSoftware(SystemSoftware& systemsoftware) { // parse releasenum file string rn = InstallDir + "/releasenum"; ifstream File(rn.c_str()); if (!File) // Open File error return; char line[400]; string buf; while (File.getline(line, 400)) { buf = line; for ( unsigned int i = 0;; i++) { if ( SoftwareData[i] == "") //end of list break; string data = ""; string::size_type pos = buf.find(SoftwareData[i],0); if (pos != string::npos) { string::size_type pos1 = buf.find("=",pos); if (pos1 != string::npos) { data = buf.substr(pos1+1, 80); } else // parse error exceptionControl("getSystemSoftware", API_FAILURE); //strip off any leading or trailing spaces for(;;) { string::size_type pos = data.find(' ',0); if (pos == string::npos) // no more found break; // strip leading if (pos == 0) { data = data.substr(pos+1,10000); } else { // strip trailing data = data.substr(0, pos); } } switch(i) { case(0): // line up with SoftwareData[] systemsoftware.Version = data; break; case(1): systemsoftware.Release = data; break; } } } //end of for loop } //end of while File.close(); } /******************************************************************** * * get System Configuration Information * ********************************************************************/ void Oam::getSystemConfig(SystemConfig& systemconfig) { Config* sysConfig = Config::makeConfig(CalpontConfigFile.c_str()); string Section = "SystemConfig"; // get numberic variables systemconfig.DBRootCount = strtol(sysConfig->getConfig(Section, "DBRootCount").c_str(), 0, 0); systemconfig.ModuleHeartbeatPeriod = strtol(sysConfig->getConfig(Section, "ModuleHeartbeatPeriod").c_str(), 0, 0); systemconfig.ModuleHeartbeatCount = strtol(sysConfig->getConfig(Section, "ModuleHeartbeatCount").c_str(), 0, 0); // systemconfig.ProcessHeartbeatPeriod = strtol(sysConfig->getConfig(Section, "ProcessHeartbeatPeriod").c_str(), 0, 0); systemconfig.ExternalCriticalThreshold = strtol(sysConfig->getConfig(Section, "ExternalCriticalThreshold").c_str(), 0, 0); systemconfig.ExternalMajorThreshold = strtol(sysConfig->getConfig(Section, "ExternalMajorThreshold").c_str(), 0, 0); systemconfig.ExternalMinorThreshold = strtol(sysConfig->getConfig(Section, "ExternalMinorThreshold").c_str(), 0, 0); systemconfig.TransactionArchivePeriod = strtol(sysConfig->getConfig(Section, "TransactionArchivePeriod").c_str(), 0, 0); // get string variables for ( unsigned int dbrootID = 1 ; dbrootID < systemconfig.DBRootCount + 1 ; dbrootID++) { systemconfig.DBRoot.push_back(sysConfig->getConfig(Section, "DBRoot" + itoa(dbrootID))); } systemconfig.SystemName = sysConfig->getConfig(Section, "SystemName"); systemconfig.DBRMRoot = sysConfig->getConfig(Section, "DBRMRoot"); systemconfig.ParentOAMModule = sysConfig->getConfig(Section, "ParentOAMModuleName"); systemconfig.StandbyOAMModule = sysConfig->getConfig(Section, "StandbyOAMModuleName"); Section = "SessionManager"; systemconfig.MaxConcurrentTransactions = strtol(sysConfig->getConfig(Section, "MaxConcurrentTransactions").c_str(), 0, 0); systemconfig.SharedMemoryTmpFile = sysConfig->getConfig(Section, "SharedMemoryTmpFile"); Section = "VersionBuffer"; systemconfig.NumVersionBufferFiles = strtol(sysConfig->getConfig(Section, "NumVersionBufferFiles").c_str(), 0, 0); systemconfig.VersionBufferFileSize = strtol(sysConfig->getConfig(Section, "VersionBufferFileSize").c_str(), 0, 0); Section = "OIDManager"; systemconfig.OIDBitmapFile = sysConfig->getConfig(Section, "OIDBitmapFile"); systemconfig.FirstOID = strtol(sysConfig->getConfig(Section, "FirstOID").c_str(), 0, 0); } /******************************************************************** * * get System Module Type Configuration Information * ********************************************************************/ void Oam::getSystemConfig(SystemModuleTypeConfig& systemmoduletypeconfig) { const string Section = "SystemModuleConfig"; const string MODULE_TYPE = "ModuleType"; systemmoduletypeconfig.moduletypeconfig.clear(); Config* sysConfig = Config::makeConfig(CalpontConfigFile.c_str()); for (int moduleTypeID = 1; moduleTypeID < MAX_MODULE_TYPE+1; moduleTypeID++) { ModuleTypeConfig moduletypeconfig; // get Module info string moduleType = MODULE_TYPE + itoa(moduleTypeID); Oam::getSystemConfig(sysConfig->getConfig(Section, moduleType), moduletypeconfig ); if (moduletypeconfig.ModuleType.empty()) continue; systemmoduletypeconfig.moduletypeconfig.push_back(moduletypeconfig); } } /******************************************************************** * * get System Module Configuration Information by Module Type * ********************************************************************/ void Oam::getSystemConfig(const std::string&moduletype, ModuleTypeConfig& moduletypeconfig) { Config* sysConfig = Config::makeConfig(CalpontConfigFile.c_str()); const string Section = "SystemModuleConfig"; const string MODULE_TYPE = "ModuleType"; const string MODULE_DESC = "ModuleDesc"; const string MODULE_RUN_TYPE = "RunType"; const string MODULE_COUNT = "ModuleCount"; const string MODULE_DISABLE_STATE = "ModuleDisableState"; const string MODULE_CPU_CRITICAL = "ModuleCPUCriticalThreshold"; const string MODULE_CPU_MAJOR = "ModuleCPUMajorThreshold"; const string MODULE_CPU_MINOR = "ModuleCPUMinorThreshold"; const string MODULE_CPU_MINOR_CLEAR = "ModuleCPUMinorClearThreshold"; const string MODULE_DISK_CRITICAL = "ModuleDiskCriticalThreshold"; const string MODULE_DISK_MAJOR = "ModuleDiskMajorThreshold"; const string MODULE_DISK_MINOR = "ModuleDiskMinorThreshold"; const string MODULE_MEM_CRITICAL = "ModuleMemCriticalThreshold"; const string MODULE_MEM_MAJOR = "ModuleMemMajorThreshold"; const string MODULE_MEM_MINOR = "ModuleMemMinorThreshold"; const string MODULE_SWAP_CRITICAL = "ModuleSwapCriticalThreshold"; const string MODULE_SWAP_MAJOR = "ModuleSwapMajorThreshold"; const string MODULE_SWAP_MINOR = "ModuleSwapMinorThreshold"; const string MODULE_IP_ADDR = "ModuleIPAddr"; const string MODULE_SERVER_NAME = "ModuleHostName"; const string MODULE_DISK_MONITOR_FS = "ModuleDiskMonitorFileSystem"; const string MODULE_DBROOT_COUNT = "ModuleDBRootCount"; const string MODULE_DBROOT_ID = "ModuleDBRootID"; for (int moduleTypeID = 1; moduleTypeID < MAX_MODULE_TYPE+1; moduleTypeID++) { string moduleType = MODULE_TYPE + itoa(moduleTypeID); if( sysConfig->getConfig(Section, moduleType) == moduletype) { string ModuleCount = MODULE_COUNT + itoa(moduleTypeID); string ModuleType = MODULE_TYPE + itoa(moduleTypeID); string ModuleDesc = MODULE_DESC + itoa(moduleTypeID); string ModuleRunType = MODULE_RUN_TYPE + itoa(moduleTypeID); string ModuleCPUCriticalThreshold = MODULE_CPU_CRITICAL + itoa(moduleTypeID); string ModuleCPUMajorThreshold = MODULE_CPU_MAJOR + itoa(moduleTypeID); string ModuleCPUMinorThreshold = MODULE_CPU_MINOR + itoa(moduleTypeID); string ModuleCPUMinorClearThreshold = MODULE_CPU_MINOR_CLEAR + itoa(moduleTypeID); string ModuleDiskCriticalThreshold = MODULE_DISK_CRITICAL + itoa(moduleTypeID); string ModuleDiskMajorThreshold = MODULE_DISK_MAJOR + itoa(moduleTypeID); string ModuleDiskMinorThreshold = MODULE_DISK_MINOR + itoa(moduleTypeID); string ModuleMemCriticalThreshold = MODULE_MEM_CRITICAL + itoa(moduleTypeID); string ModuleMemMajorThreshold = MODULE_MEM_MAJOR + itoa(moduleTypeID); string ModuleMemMinorThreshold = MODULE_MEM_MINOR + itoa(moduleTypeID); string ModuleSwapCriticalThreshold = MODULE_SWAP_CRITICAL + itoa(moduleTypeID); string ModuleSwapMajorThreshold = MODULE_SWAP_MAJOR + itoa(moduleTypeID); string ModuleSwapMinorThreshold = MODULE_SWAP_MINOR + itoa(moduleTypeID); moduletypeconfig.ModuleCount = strtol(sysConfig->getConfig(Section, ModuleCount).c_str(), 0, 0); moduletypeconfig.ModuleType = sysConfig->getConfig(Section, ModuleType); moduletypeconfig.ModuleDesc = sysConfig->getConfig(Section, ModuleDesc); moduletypeconfig.RunType = sysConfig->getConfig(Section, ModuleRunType); moduletypeconfig.ModuleCPUCriticalThreshold = strtol(sysConfig->getConfig(Section, ModuleCPUCriticalThreshold).c_str(), 0, 0); moduletypeconfig.ModuleCPUMajorThreshold = strtol(sysConfig->getConfig(Section, ModuleCPUMajorThreshold).c_str(), 0, 0); moduletypeconfig.ModuleCPUMinorThreshold = strtol(sysConfig->getConfig(Section, ModuleCPUMinorThreshold).c_str(), 0, 0); moduletypeconfig.ModuleCPUMinorClearThreshold = strtol(sysConfig->getConfig(Section, ModuleCPUMinorClearThreshold).c_str(), 0, 0); moduletypeconfig.ModuleDiskCriticalThreshold = strtol(sysConfig->getConfig(Section, ModuleDiskCriticalThreshold).c_str(), 0, 0); moduletypeconfig.ModuleDiskMajorThreshold = strtol(sysConfig->getConfig(Section, ModuleDiskMajorThreshold).c_str(), 0, 0); moduletypeconfig.ModuleDiskMinorThreshold = strtol(sysConfig->getConfig(Section, ModuleDiskMinorThreshold).c_str(), 0, 0); moduletypeconfig.ModuleMemCriticalThreshold = strtol(sysConfig->getConfig(Section, ModuleMemCriticalThreshold).c_str(), 0, 0); moduletypeconfig.ModuleMemMajorThreshold = strtol(sysConfig->getConfig(Section, ModuleMemMajorThreshold).c_str(), 0, 0); moduletypeconfig.ModuleMemMinorThreshold = strtol(sysConfig->getConfig(Section, ModuleMemMinorThreshold).c_str(), 0, 0); moduletypeconfig.ModuleSwapCriticalThreshold = strtol(sysConfig->getConfig(Section, ModuleSwapCriticalThreshold).c_str(), 0, 0); moduletypeconfig.ModuleSwapMajorThreshold = strtol(sysConfig->getConfig(Section, ModuleSwapMajorThreshold).c_str(), 0, 0); moduletypeconfig.ModuleSwapMinorThreshold = strtol(sysConfig->getConfig(Section, ModuleSwapMinorThreshold).c_str(), 0, 0); int moduleFound = 0; //get NIC IP address/hostnames for (int moduleID = 1; moduleID <= moduletypeconfig.ModuleCount ; moduleID++) { DeviceNetworkConfig devicenetworkconfig; HostConfig hostconfig; for (int nicID= 1; nicID < MAX_NIC+1 ; nicID++) { string ModuleIpAddr = MODULE_IP_ADDR + itoa(moduleID) + "-" + itoa(nicID) + "-" + itoa(moduleTypeID); string ipAddr = sysConfig->getConfig(Section, ModuleIpAddr); if (ipAddr.empty()) break; else if (ipAddr == UnassignedIpAddr ) continue; string ModuleHostName = MODULE_SERVER_NAME + itoa(moduleID) + "-" + itoa(nicID) + "-" + itoa(moduleTypeID); string serverName = sysConfig->getConfig(Section, ModuleHostName); hostconfig.IPAddr = ipAddr; hostconfig.HostName = serverName; hostconfig.NicID = nicID; devicenetworkconfig.hostConfigList.push_back(hostconfig); } if ( !devicenetworkconfig.hostConfigList.empty() ) { string ModuleDisableState = MODULE_DISABLE_STATE + itoa(moduleID) + "-" + itoa(moduleTypeID); devicenetworkconfig.DisableState = sysConfig->getConfig(Section, ModuleDisableState); devicenetworkconfig.DeviceName = moduletypeconfig.ModuleType + itoa(moduleID); moduletypeconfig.ModuleNetworkList.push_back(devicenetworkconfig); devicenetworkconfig.hostConfigList.clear(); moduleFound++; if ( moduleFound >= moduletypeconfig.ModuleCount ) break; } } // get filesystems DiskMonitorFileSystems fs; for (int fsID = 1;; fsID++) { string ModuleDiskMonitorFS = MODULE_DISK_MONITOR_FS + itoa(fsID) + "-" + itoa(moduleTypeID); string fsName = sysConfig->getConfig(Section, ModuleDiskMonitorFS); if (fsName.empty()) break; fs.push_back(fsName); } moduletypeconfig.FileSystems = fs; // get dbroot IDs moduleFound = 0; for (int moduleID = 1; moduleID <= moduletypeconfig.ModuleCount ; moduleID++) { string ModuleDBRootCount = MODULE_DBROOT_COUNT + itoa(moduleID) + "-" + itoa(moduleTypeID); string temp = sysConfig->getConfig(Section, ModuleDBRootCount).c_str(); if ( temp.empty() || temp == oam::UnassignedName) continue; int moduledbrootcount = strtol(temp.c_str(), 0, 0); DeviceDBRootConfig devicedbrootconfig; DBRootConfigList dbrootconfiglist; if ( moduledbrootcount < 1 ) { dbrootconfiglist.clear(); } else { int foundIDs = 0; for (int dbrootID = 1; dbrootID < moduledbrootcount+1 ; dbrootID++) { string DBRootID = MODULE_DBROOT_ID + itoa(moduleID) + "-" + itoa(dbrootID) + "-" + itoa(moduleTypeID); string dbrootid = sysConfig->getConfig(Section, DBRootID); if (dbrootid.empty() || dbrootid == oam::UnassignedName || dbrootid == "0") continue; dbrootconfiglist.push_back(atoi(dbrootid.c_str())); foundIDs++; if ( moduledbrootcount == foundIDs) break; } } sort ( dbrootconfiglist.begin(), dbrootconfiglist.end() ); devicedbrootconfig.DeviceID = moduleID; devicedbrootconfig.dbrootConfigList = dbrootconfiglist; moduletypeconfig.ModuleDBRootList.push_back(devicedbrootconfig); devicedbrootconfig.dbrootConfigList.clear(); moduleFound++; if ( moduleFound >= moduletypeconfig.ModuleCount ) break; } return; } } // Module Not found exceptionControl("getSystemConfig", API_INVALID_PARAMETER); } /******************************************************************** * * get System Module Configuration Information by Module Name * ********************************************************************/ void Oam::getSystemConfig(const std::string&module, ModuleConfig& moduleconfig) { Config* sysConfig = Config::makeConfig(CalpontConfigFile.c_str()); const string Section = "SystemModuleConfig"; const string MODULE_TYPE = "ModuleType"; const string MODULE_DESC = "ModuleDesc"; const string MODULE_COUNT = "ModuleCount"; const string MODULE_IP_ADDR = "ModuleIPAddr"; const string MODULE_SERVER_NAME = "ModuleHostName"; const string MODULE_DISABLE_STATE = "ModuleDisableState"; const string MODULE_DBROOT_COUNT = "ModuleDBRootCount"; const string MODULE_DBROOT_ID = "ModuleDBRootID"; string moduletype = module.substr(0,MAX_MODULE_TYPE_SIZE); int moduleID = atoi(module.substr(MAX_MODULE_TYPE_SIZE,MAX_MODULE_ID_SIZE).c_str()); if ( moduleID < 1 ) //invalid ID exceptionControl("getSystemConfig", API_INVALID_PARAMETER); for (int moduleTypeID = 1; moduleTypeID < MAX_MODULE_TYPE+1; moduleTypeID++) { string moduleType = MODULE_TYPE + itoa(moduleTypeID); string ModuleCount = MODULE_COUNT + itoa(moduleTypeID); if( sysConfig->getConfig(Section, moduleType) == moduletype ) { string ModuleType = MODULE_TYPE + itoa(moduleTypeID); string ModuleDesc = MODULE_DESC + itoa(moduleTypeID); string ModuleDisableState = MODULE_DISABLE_STATE + itoa(moduleID) + "-" + itoa(moduleTypeID); moduleconfig.ModuleName = module; moduleconfig.ModuleType = sysConfig->getConfig(Section, ModuleType); moduleconfig.ModuleDesc = sysConfig->getConfig(Section, ModuleDesc) + " #" + itoa(moduleID); moduleconfig.DisableState = sysConfig->getConfig(Section, ModuleDisableState); string ModuleDBRootCount = MODULE_DBROOT_COUNT + itoa(moduleID) + "-" + itoa(moduleTypeID); string temp = sysConfig->getConfig(Section, ModuleDBRootCount).c_str(); int moduledbrootcount = 0; if ( temp.empty() || temp != oam::UnassignedName) moduledbrootcount = strtol(temp.c_str(), 0, 0); HostConfig hostconfig; //get NIC IP address/hostnames moduleconfig.hostConfigList.clear(); for (int nicID = 1; nicID < MAX_NIC+1 ; nicID++) { string ModuleIpAddr = MODULE_IP_ADDR + itoa(moduleID) + "-" + itoa(nicID) + "-" + itoa(moduleTypeID); string ipAddr = sysConfig->getConfig(Section, ModuleIpAddr); if (ipAddr.empty() || ipAddr == UnassignedIpAddr ) continue; string ModuleHostName = MODULE_SERVER_NAME + itoa(moduleID) + "-" + itoa(nicID) + "-" + itoa(moduleTypeID); string serverName = sysConfig->getConfig(Section, ModuleHostName); hostconfig.IPAddr = ipAddr; hostconfig.HostName = serverName; hostconfig.NicID = nicID; moduleconfig.hostConfigList.push_back(hostconfig); } //get DBroot IDs moduleconfig.dbrootConfigList.clear(); for (int dbrootID = 1; dbrootID < moduledbrootcount+1 ; dbrootID++) { string ModuleDBRootID = MODULE_DBROOT_ID + itoa(moduleID) + "-" + itoa(dbrootID) + "-" + itoa(moduleTypeID); string moduleDBRootID = sysConfig->getConfig(Section, ModuleDBRootID); if (moduleDBRootID.empty() || moduleDBRootID == oam::UnassignedName || moduleDBRootID == "0") continue; moduleconfig.dbrootConfigList.push_back(atoi(moduleDBRootID.c_str())); } sort ( moduleconfig.dbrootConfigList.begin(), moduleconfig.dbrootConfigList.end() ); return; } } // Module Not found exceptionControl("getSystemConfig", API_INVALID_PARAMETER); } /******************************************************************** * * get Local Module Configuration Information * ********************************************************************/ void Oam::getSystemConfig(ModuleConfig& moduleconfig) { // get Local Module Name oamModuleInfo_t t = Oam::getModuleInfo(); string module = boost::get<0>(t); // get Module info Oam::getSystemConfig(module, moduleconfig); } /******************************************************************** * * get Local Module Type Configuration Information * ********************************************************************/ void Oam::getSystemConfig(ModuleTypeConfig& moduletypeconfig) { // get Local Module Name oamModuleInfo_t t = Oam::getModuleInfo(); string module = boost::get<0>(t); string moduleType = module.substr(0,MAX_MODULE_TYPE_SIZE); // get Module info Oam::getSystemConfig(moduleType, moduletypeconfig); } /******************************************************************** * * get System External Device Configuration information * ********************************************************************/ void Oam::getSystemConfig(SystemExtDeviceConfig& systemextdeviceconfig) { Config* sysConfig = Config::makeConfig(CalpontConfigFile.c_str()); const string Section = "SystemExtDeviceConfig"; const string NAME = "Name"; const string IPADDR = "IPAddr"; const string DISABLE_STATE = "DisableState"; systemextdeviceconfig.Count = strtol(sysConfig->getConfig(Section, "Count").c_str(), 0, 0); int configCount = 0; for (int extDeviceID = 1; extDeviceID < MAX_EXT_DEVICE+1; extDeviceID++) { ExtDeviceConfig Extdeviceconfig; string name = NAME + itoa(extDeviceID); try { Extdeviceconfig.Name = sysConfig->getConfig(Section, name); } catch(...) { continue; } if (Extdeviceconfig.Name == oam::UnassignedName || Extdeviceconfig.Name.empty()) continue; string ipaddr = IPADDR + itoa(extDeviceID); string disablestate = DISABLE_STATE + itoa(extDeviceID); Extdeviceconfig.IPAddr = sysConfig->getConfig(Section, ipaddr); Extdeviceconfig.DisableState = sysConfig->getConfig(Section, disablestate); systemextdeviceconfig.extdeviceconfig.push_back(Extdeviceconfig); configCount++; } //correct count if not matching if ( systemextdeviceconfig.Count != configCount ) { systemextdeviceconfig.Count = configCount; sysConfig->setConfig(Section, "Count", itoa(configCount)); try { sysConfig->write(); } catch(...) { exceptionControl("getSystemConfig", API_FAILURE); } } } /******************************************************************** * * get System External Device Configuration information * ********************************************************************/ void Oam::getSystemConfig(const std::string&extDevicename, ExtDeviceConfig& extdeviceconfig) { Config* sysConfig = Config::makeConfig(CalpontConfigFile.c_str()); const string Section = "SystemExtDeviceConfig"; const string NAME = "Name"; const string IPADDR = "IPAddr"; const string DISABLE_STATE = "DisableState"; for (int extDeviceID = 1; extDeviceID < MAX_EXT_DEVICE+1; extDeviceID++) { string name = NAME + itoa(extDeviceID); extdeviceconfig.Name = sysConfig->getConfig(Section, name); if (extdeviceconfig.Name != extDevicename) continue; string ipaddr = IPADDR + itoa(extDeviceID); string disablestate = DISABLE_STATE + itoa(extDeviceID); extdeviceconfig.IPAddr = sysConfig->getConfig(Section, ipaddr); extdeviceconfig.DisableState = sysConfig->getConfig(Section, disablestate); return; } // Ext Device Not found exceptionControl("getSystemConfig", API_INVALID_PARAMETER); } /******************************************************************** * * set Ext Device Configuration information * ********************************************************************/ void Oam::setSystemConfig(const std::string deviceName, ExtDeviceConfig extdeviceconfig) { if ( deviceName == oam::UnassignedName ) return; Config* sysConfig = Config::makeConfig(CalpontConfigFile.c_str()); const string Section = "SystemExtDeviceConfig"; const string NAME = "Name"; const string IPADDR = "IPAddr"; const string DISABLE_STATE = "DisableState"; int count = strtol(sysConfig->getConfig(Section, "Count").c_str(), 0, 0); int entry = 0; int extDeviceID = 1; for (; extDeviceID < MAX_EXT_DEVICE+1; extDeviceID++) { string name = NAME + itoa(extDeviceID); if (sysConfig->getConfig(Section, name) == oam::UnassignedName) entry = extDeviceID; if ((sysConfig->getConfig(Section, name)).empty() && entry == 0) entry = extDeviceID; if (sysConfig->getConfig(Section, name) != deviceName) continue; string ipaddr = IPADDR + itoa(extDeviceID); string disablestate = DISABLE_STATE + itoa(extDeviceID); sysConfig->setConfig(Section, name, extdeviceconfig.Name); sysConfig->setConfig(Section, ipaddr, extdeviceconfig.IPAddr); sysConfig->setConfig(Section, disablestate, extdeviceconfig.DisableState); if ( extdeviceconfig.Name == oam::UnassignedName ) { // entry deleted decrement count count--; if ( count < 0 ) count = 0 ; sysConfig->setConfig(Section, "Count", itoa(count)); // //send message to Process Monitor to remove external device to shared memory // try { ByteStream obs; obs << (ByteStream::byte) REMOVE_EXT_DEVICE; obs << deviceName; sendStatusUpdate(obs, REMOVE_EXT_DEVICE); } catch(...) { exceptionControl("setSystemConfig", API_INVALID_PARAMETER); } } try { sysConfig->write(); } catch(...) { exceptionControl("setSystemConfig", API_FAILURE); } return; } if ( entry == 0 ) entry = extDeviceID; // Ext Device Not found, add it sysConfig->setConfig(Section, "Count", itoa(count+1)); string name = NAME + itoa(entry); string ipaddr = IPADDR + itoa(entry); string disablestate = DISABLE_STATE + itoa(entry); sysConfig->setConfig(Section, name, extdeviceconfig.Name); sysConfig->setConfig(Section, ipaddr, extdeviceconfig.IPAddr); if (extdeviceconfig.DisableState.empty() ) extdeviceconfig.DisableState = oam::ENABLEDSTATE; sysConfig->setConfig(Section, disablestate, extdeviceconfig.DisableState); try { sysConfig->write(); } catch(...) { exceptionControl("setSystemConfig", API_FAILURE); } // //send message to Process Monitor to add new external device to shared memory // try { ByteStream obs; obs << (ByteStream::byte) ADD_EXT_DEVICE; obs << extdeviceconfig.Name; sendStatusUpdate(obs, ADD_EXT_DEVICE); } catch(...) { exceptionControl("setSystemConfig", API_INVALID_PARAMETER); } return; } /******************************************************************** * * get System Configuration String Parameter value * ********************************************************************/ void Oam::getSystemConfig(const std::string&name, std::string& value) { Config* sysConfig = Config::makeConfig(CalpontConfigFile.c_str()); // get string variables for( int i = 0;;i++) { if ( configSections[i] == "" ) // end of section list break; value = sysConfig->getConfig(configSections[i], name); if (!(value.empty())) { // match found return; } } // no match found exceptionControl("getSystemConfig", API_INVALID_PARAMETER); } /******************************************************************** * * get System Configuration Integer Parameter value * ********************************************************************/ void Oam::getSystemConfig(const std::string&name, int& value) { string returnValue; // get string variables Oam::getSystemConfig(name, returnValue); // covert returned Parameter value to Interger value = atoi(returnValue.c_str()); } /******************************************************************** * * get Module Name for IP Address * ********************************************************************/ void Oam::getModuleNameByIPAddr(const std::string IpAddress, std::string& moduleName) { SystemModuleTypeConfig systemmoduletypeconfig; ModuleTypeConfig moduletypeconfig; ModuleConfig moduleconfig; systemmoduletypeconfig.moduletypeconfig.clear(); string returnValue; string Argument; try { Oam::getSystemConfig(systemmoduletypeconfig); for( unsigned int i = 0 ; i < systemmoduletypeconfig.moduletypeconfig.size(); i++) { if( systemmoduletypeconfig.moduletypeconfig[i].ModuleType.empty() ) // end of list break; int moduleCount = systemmoduletypeconfig.moduletypeconfig[i].ModuleCount; if ( moduleCount == 0 ) // skip if no modules continue; string moduletype = systemmoduletypeconfig.moduletypeconfig[i].ModuleType; DeviceNetworkList::iterator pt = systemmoduletypeconfig.moduletypeconfig[i].ModuleNetworkList.begin(); for( ; pt != systemmoduletypeconfig.moduletypeconfig[i].ModuleNetworkList.end() ; pt++) { string modulename = (*pt).DeviceName; string moduleID = modulename.substr(MAX_MODULE_TYPE_SIZE,MAX_MODULE_ID_SIZE); HostConfigList::iterator pt1 = (*pt).hostConfigList.begin(); for( ; pt1 != (*pt).hostConfigList.end() ; pt1++) { if ( IpAddress == (*pt1).IPAddr ) { moduleName = modulename; return; } } } } moduleName = oam::UnassignedName; return; } catch (exception&) { exceptionControl("getModuleNameByIPAddr", API_FAILURE); } } /******************************************************************** * * set System Configuration String Parameter value * ********************************************************************/ void Oam::setSystemConfig(const std::string name, const std::string value) { string mem = "Mem"; string disk = "Disk"; string swap = "Swap"; string threshold = "Threshold"; string critical = "Critical"; string major = "Major"; string minor = "Minor"; Config* sysConfig = Config::makeConfig(CalpontConfigFile.c_str()); string returnValue; // find and write new value to disk for( int i = 0;;i++) { if ( configSections[i] == "" ) // end of section list, no match found exceptionControl("setSystemConfig", API_INVALID_PARAMETER); returnValue = sysConfig->getConfig(configSections[i], name); if (!(returnValue.empty())) { // match found sysConfig->setConfig(configSections[i], name, value); try { sysConfig->write(); } catch(...) { exceptionControl("setSystemConfig", API_FAILURE); } break; } } return; } /******************************************************************** * * set System Configuration Interger Parameter value * ********************************************************************/ void Oam::setSystemConfig(const std::string name, const int value) { string valueString; // convert Incoming Interger Parameter value to String valueString = itoa(value); // write parameter to disk Oam::setSystemConfig(name, valueString); } /******************************************************************** * * set System Module Configuration Information by Module Type * ********************************************************************/ void Oam::setSystemConfig(const std::string moduletype, ModuleTypeConfig moduletypeconfig) { Config* sysConfig = Config::makeConfig(CalpontConfigFile.c_str()); const string Section = "SystemModuleConfig"; const string MODULE_TYPE = "ModuleType"; const string MODULE_DESC = "ModuleDesc"; const string MODULE_RUN_TYPE = "RunType"; const string MODULE_COUNT = "ModuleCount"; const string MODULE_CPU_CRITICAL = "ModuleCPUCriticalThreshold"; const string MODULE_CPU_MAJOR = "ModuleCPUMajorThreshold"; const string MODULE_CPU_MINOR = "ModuleCPUMinorThreshold"; const string MODULE_CPU_MINOR_CLEAR = "ModuleCPUMinorClearThreshold"; const string MODULE_DISK_CRITICAL = "ModuleDiskCriticalThreshold"; const string MODULE_DISK_MAJOR = "ModuleDiskMajorThreshold"; const string MODULE_DISK_MINOR = "ModuleDiskMinorThreshold"; const string MODULE_MEM_CRITICAL = "ModuleMemCriticalThreshold"; const string MODULE_MEM_MAJOR = "ModuleMemMajorThreshold"; const string MODULE_MEM_MINOR = "ModuleMemMinorThreshold"; const string MODULE_SWAP_CRITICAL = "ModuleSwapCriticalThreshold"; const string MODULE_SWAP_MAJOR = "ModuleSwapMajorThreshold"; const string MODULE_SWAP_MINOR = "ModuleSwapMinorThreshold"; const string MODULE_IP_ADDR = "ModuleIPAddr"; const string MODULE_SERVER_NAME = "ModuleHostName"; const string MODULE_DISK_MONITOR_FS = "ModuleDiskMonitorFileSystem"; const string MODULE_DISABLE_STATE = "ModuleDisableState"; for (int moduleTypeID = 1; moduleTypeID < MAX_MODULE_TYPE+1; moduleTypeID++) { string moduleType = MODULE_TYPE + itoa(moduleTypeID); if( sysConfig->getConfig(Section, moduleType) == moduletype) { string ModuleType = MODULE_TYPE + itoa(moduleTypeID); string ModuleDesc = MODULE_DESC + itoa(moduleTypeID); string ModuleRunType = MODULE_RUN_TYPE + itoa(moduleTypeID); string ModuleCount = MODULE_COUNT + itoa(moduleTypeID); string ModuleCPUCriticalThreshold = MODULE_CPU_CRITICAL + itoa(moduleTypeID); string ModuleCPUMajorThreshold = MODULE_CPU_MAJOR + itoa(moduleTypeID); string ModuleCPUMinorThreshold = MODULE_CPU_MINOR + itoa(moduleTypeID); string ModuleCPUMinorClearThreshold = MODULE_CPU_MINOR_CLEAR + itoa(moduleTypeID); string ModuleDiskCriticalThreshold = MODULE_DISK_CRITICAL + itoa(moduleTypeID); string ModuleDiskMajorThreshold = MODULE_DISK_MAJOR + itoa(moduleTypeID); string ModuleDiskMinorThreshold = MODULE_DISK_MINOR + itoa(moduleTypeID); string ModuleMemCriticalThreshold = MODULE_MEM_CRITICAL + itoa(moduleTypeID); string ModuleMemMajorThreshold = MODULE_MEM_MAJOR + itoa(moduleTypeID); string ModuleMemMinorThreshold = MODULE_MEM_MINOR + itoa(moduleTypeID); string ModuleSwapCriticalThreshold = MODULE_SWAP_CRITICAL + itoa(moduleTypeID); string ModuleSwapMajorThreshold = MODULE_SWAP_MAJOR + itoa(moduleTypeID); string ModuleSwapMinorThreshold = MODULE_SWAP_MINOR + itoa(moduleTypeID); int oldModuleCount = atoi(sysConfig->getConfig(Section, ModuleCount).c_str()); sysConfig->setConfig(Section, ModuleType, moduletypeconfig.ModuleType); sysConfig->setConfig(Section, ModuleDesc, moduletypeconfig.ModuleDesc); sysConfig->setConfig(Section, ModuleRunType, moduletypeconfig.RunType); sysConfig->setConfig(Section, ModuleCount, itoa(moduletypeconfig.ModuleCount)); sysConfig->setConfig(Section, ModuleCPUCriticalThreshold, itoa(moduletypeconfig.ModuleCPUCriticalThreshold)); sysConfig->setConfig(Section, ModuleCPUMajorThreshold, itoa(moduletypeconfig.ModuleCPUMajorThreshold)); sysConfig->setConfig(Section, ModuleCPUMinorThreshold, itoa(moduletypeconfig.ModuleCPUMinorThreshold)); sysConfig->setConfig(Section, ModuleCPUMinorClearThreshold, itoa(moduletypeconfig.ModuleCPUMinorClearThreshold)); sysConfig->setConfig(Section, ModuleDiskCriticalThreshold, itoa(moduletypeconfig.ModuleDiskCriticalThreshold)); sysConfig->setConfig(Section, ModuleDiskMajorThreshold, itoa(moduletypeconfig.ModuleDiskMajorThreshold)); sysConfig->setConfig(Section, ModuleDiskMinorThreshold, itoa(moduletypeconfig.ModuleDiskMinorThreshold)); sysConfig->setConfig(Section, ModuleMemCriticalThreshold, itoa(moduletypeconfig.ModuleMemCriticalThreshold)); sysConfig->setConfig(Section, ModuleMemMajorThreshold, itoa(moduletypeconfig.ModuleMemMajorThreshold)); sysConfig->setConfig(Section, ModuleMemMinorThreshold, itoa(moduletypeconfig.ModuleMemMinorThreshold)); sysConfig->setConfig(Section, ModuleSwapCriticalThreshold, itoa(moduletypeconfig.ModuleSwapCriticalThreshold)); sysConfig->setConfig(Section, ModuleSwapMajorThreshold, itoa(moduletypeconfig.ModuleSwapMajorThreshold)); sysConfig->setConfig(Section, ModuleSwapMinorThreshold, itoa(moduletypeconfig.ModuleSwapMinorThreshold)); // clear out hostConfig info before adding in new contents if ( oldModuleCount > 0) { for (int moduleID = 1; moduleID < MAX_MODULE ; moduleID++) { //get NIC IP address/hostnames for (int nicID = 1; nicID < MAX_NIC+1 ; nicID++) { string ModuleIpAddr = MODULE_IP_ADDR + itoa(moduleID) + "-" + itoa(nicID) + "-" + itoa(moduleTypeID); string ipAddr = sysConfig->getConfig(Section, ModuleIpAddr); if (ipAddr.empty()) continue; string ModuleHostName = MODULE_SERVER_NAME + itoa(moduleID) + "-" + itoa(nicID) + "-" + itoa(moduleTypeID); string ModuleDisableState = MODULE_DISABLE_STATE + itoa(moduleID) + "-" + itoa(moduleTypeID); sysConfig->setConfig(Section, ModuleIpAddr, UnassignedIpAddr); sysConfig->setConfig(Section, ModuleHostName, UnassignedName); sysConfig->setConfig(Section, ModuleDisableState, oam::ENABLEDSTATE); } } } if ( moduletypeconfig.ModuleCount > 0 ) { DeviceNetworkList::iterator pt = moduletypeconfig.ModuleNetworkList.begin(); for( ; pt != moduletypeconfig.ModuleNetworkList.end() ; pt++) { int ModuleID = atoi((*pt).DeviceName.substr(MAX_MODULE_TYPE_SIZE,MAX_MODULE_ID_SIZE).c_str()); string ModuleDisableState = MODULE_DISABLE_STATE + itoa(ModuleID) + "-" + itoa(moduleTypeID); sysConfig->setConfig(Section, ModuleDisableState, (*pt).DisableState); HostConfigList::iterator pt1 = (*pt).hostConfigList.begin(); for( ; pt1 != (*pt).hostConfigList.end() ; pt1++) { int nidID = (*pt1).NicID; string ModuleIpAddr = MODULE_IP_ADDR + itoa(ModuleID) + "-" + itoa(nidID) + "-" + itoa(moduleTypeID); sysConfig->setConfig(Section, ModuleIpAddr, (*pt1).IPAddr); string ModuleHostName = MODULE_SERVER_NAME + itoa(ModuleID) + "-" + itoa(nidID) + "-" + itoa(moduleTypeID); sysConfig->setConfig(Section, ModuleHostName, (*pt1).HostName); } } } DiskMonitorFileSystems::iterator pt = moduletypeconfig.FileSystems.begin(); int id=1; for( ; pt != moduletypeconfig.FileSystems.end() ; pt++) { string ModuleDiskMonitorFS = MODULE_DISK_MONITOR_FS + itoa(id) + "-" + itoa(moduleTypeID); sysConfig->setConfig(Section, ModuleDiskMonitorFS, *pt); ++id; } try { sysConfig->write(); } catch(...) { exceptionControl("getSystemConfig", API_FAILURE); } return; } } // Module Not found exceptionControl("getSystemConfig", API_INVALID_PARAMETER); } /******************************************************************** * * set System Module Configuration Information by Module Name * ********************************************************************/ void Oam::setSystemConfig(const std::string module, ModuleConfig moduleconfig) { Config* sysConfig100 = Config::makeConfig(CalpontConfigFile.c_str()); const string MODULE_TYPE = "ModuleType"; const string Section = "SystemModuleConfig"; const string MODULE_COUNT = "ModuleCount"; const string MODULE_IP_ADDR = "ModuleIPAddr"; const string MODULE_SERVER_NAME = "ModuleHostName"; const string MODULE_DISABLE_STATE = "ModuleDisableState"; const string MODULE_DBROOTID = "ModuleDBRootID"; const string MODULE_DBROOT_COUNT = "ModuleDBRootCount"; string moduletype = module.substr(0,MAX_MODULE_TYPE_SIZE); int moduleID = atoi(module.substr(MAX_MODULE_TYPE_SIZE,MAX_MODULE_ID_SIZE).c_str()); if ( moduleID < 1 ) //invalid ID exceptionControl("setSystemConfig", API_INVALID_PARAMETER); for (int moduleTypeID = 1; moduleTypeID < MAX_MODULE_TYPE+1; moduleTypeID++) { string moduleType = MODULE_TYPE + itoa(moduleTypeID); string ModuleCount = MODULE_COUNT + itoa(moduleTypeID); if( sysConfig100->getConfig(Section, moduleType) == moduletype ) { string ModuleDisableState = MODULE_DISABLE_STATE + itoa(moduleID) + "-" + itoa(moduleTypeID); sysConfig100->setConfig(Section, ModuleDisableState, moduleconfig.DisableState); HostConfigList::iterator pt1 = moduleconfig.hostConfigList.begin(); for( ; pt1 != moduleconfig.hostConfigList.end() ; pt1++) { string ModuleIpAddr = MODULE_IP_ADDR + itoa(moduleID) + "-" + itoa((*pt1).NicID) + "-" + itoa(moduleTypeID); sysConfig100->setConfig(Section, ModuleIpAddr, (*pt1).IPAddr); string ModuleHostName = MODULE_SERVER_NAME + itoa(moduleID) + "-" + itoa((*pt1).NicID) + "-" + itoa(moduleTypeID); sysConfig100->setConfig(Section, ModuleHostName, (*pt1).HostName); } int id = 1; if ( moduleconfig.dbrootConfigList.size() == 0 ) { string ModuleDBrootID = MODULE_DBROOTID + itoa(moduleID) + "-" + itoa((id)) + "-" + itoa(moduleTypeID); sysConfig100->setConfig(Section, ModuleDBrootID, oam::UnassignedName); } else { DBRootConfigList::iterator pt2 = moduleconfig.dbrootConfigList.begin(); for( ; pt2 != moduleconfig.dbrootConfigList.end() ; pt2++, id++) { string ModuleDBrootID = MODULE_DBROOTID + itoa(moduleID) + "-" + itoa((id)) + "-" + itoa(moduleTypeID); sysConfig100->setConfig(Section, ModuleDBrootID, itoa((*pt2))); } } //set entries no longer configured to unsassigned for ( int extraid = id ; id < MAX_DBROOT ; extraid++ ) { string ModuleDBrootID = MODULE_DBROOTID + itoa(moduleID) + "-" + itoa((extraid)) + "-" + itoa(moduleTypeID); if ( sysConfig100->getConfig(Section, ModuleDBrootID).empty() || sysConfig100->getConfig(Section, ModuleDBrootID) == oam::UnassignedName ) break; sysConfig100->setConfig(Section, ModuleDBrootID, oam::UnassignedName); } string ModuleDBRootCount = MODULE_DBROOT_COUNT + itoa(moduleID) + "-" + itoa(moduleTypeID); sysConfig100->setConfig(Section, ModuleDBRootCount, itoa(moduleconfig.dbrootConfigList.size())); try { sysConfig100->write(); } catch(...) { exceptionControl("setSystemConfig", API_FAILURE); } return; } } // Module Not found exceptionControl("setSystemConfig", API_INVALID_PARAMETER); } /******************************************************************** * * add Module * ********************************************************************/ void Oam::addModule(DeviceNetworkList devicenetworklist, const std::string password, const std::string mysqlpw) { // build and send msg int returnStatus = sendMsgToProcMgr2(ADDMODULE, devicenetworklist, FORCEFUL, ACK_YES, password, mysqlpw); if (returnStatus != API_SUCCESS) exceptionControl("addModule", returnStatus); } /******************************************************************** * * remove Module * ********************************************************************/ void Oam::removeModule(DeviceNetworkList devicenetworklist) { DeviceNetworkList::iterator pt = devicenetworklist.begin(); for( ; pt != devicenetworklist.end() ; pt++) { // validate Module name int returnStatus = validateModule((*pt).DeviceName); if (returnStatus != API_SUCCESS) exceptionControl("removeModule", returnStatus); } // build and send msg int returnStatus = sendMsgToProcMgr2(REMOVEMODULE, devicenetworklist, FORCEFUL, ACK_YES); if (returnStatus != API_SUCCESS) exceptionControl("removeModule", returnStatus); } /******************************************************************** * * reconfigure Module * ********************************************************************/ void Oam::reconfigureModule(DeviceNetworkList devicenetworklist) { DeviceNetworkList::iterator pt = devicenetworklist.begin(); // validate Module name int returnStatus = validateModule((*pt).DeviceName); if (returnStatus != API_SUCCESS) exceptionControl("reconfigureModule", returnStatus); // build and send msg returnStatus = sendMsgToProcMgr2(RECONFIGUREMODULE, devicenetworklist, FORCEFUL, ACK_YES); if (returnStatus != API_SUCCESS) exceptionControl("reconfigureModule", returnStatus); } /******************************************************************** * * get System Status Information * ********************************************************************/ void Oam::getSystemStatus(SystemStatus& systemstatus, bool systemStatusOnly) { if (!checkSystemRunning()) return; #ifdef _MSC_VER // TODO: Remove when we create OAM for Windows return; #endif ModuleStatus modulestatus; systemstatus.systemmodulestatus.modulestatus.clear(); ExtDeviceStatus extdevicestatus; systemstatus.systemextdevicestatus.extdevicestatus.clear(); NICStatus nicstatus; systemstatus.systemnicstatus.nicstatus.clear(); DbrootStatus dbrootstatus; systemstatus.systemdbrootstatus.dbrootstatus.clear(); for ( int i = 0 ; i < 2 ; i ++) { try { MessageQueueClient processor("ProcStatusControl"); // processor.syncProto(false); ByteStream::byte ModuleNumber; ByteStream::byte ExtDeviceNumber; ByteStream::byte dbrootNumber; ByteStream::byte NICNumber; ByteStream::byte state; std::string name; std::string date; ByteStream obs, ibs; obs << (ByteStream::byte) GET_SYSTEM_STATUS; if ( systemStatusOnly ) obs << (ByteStream::byte) 1; else obs << (ByteStream::byte) 2; try { struct timespec ts = { 3, 0 }; processor.write(obs, &ts); } catch (exception& e) { processor.shutdown(); string error = e.what(); //writeLog("getSystemStatus: write exception: " + error, LOG_TYPE_ERROR); exceptionControl("getSystemStatus write", API_FAILURE); } catch(...) { processor.shutdown(); //writeLog("getSystemStatus: write exception: unknown", LOG_TYPE_ERROR); exceptionControl("getSystemStatus write", API_FAILURE); } // wait 30 seconds for ACK from Process Monitor try { struct timespec ts = { 30, 0 }; ibs = processor.read(&ts); } catch (exception& e) { processor.shutdown(); string error = e.what(); //writeLog("getSystemStatus: read exception: " + error, LOG_TYPE_ERROR); exceptionControl("getSystemStatus read", API_FAILURE); } catch(...) { processor.shutdown(); //writeLog("getSystemStatus: read exception: unknown", LOG_TYPE_ERROR); exceptionControl("getSystemStatus read", API_FAILURE); } if (ibs.length() > 0) { if ( systemStatusOnly ) { ibs >> name; ibs >> state; ibs >> date; if ( name.find("system") != string::npos ) { systemstatus.SystemOpState = state; systemstatus.StateChangeDate = date; } } else { ibs >> ModuleNumber; for( int i=0 ; i < ModuleNumber ; ++i) { ibs >> name; ibs >> state; ibs >> date; if ( name.find("system") != string::npos ) { systemstatus.SystemOpState = state; systemstatus.StateChangeDate = date; } else { modulestatus.Module = name; modulestatus.ModuleOpState = state; modulestatus.StateChangeDate = date; systemstatus.systemmodulestatus.modulestatus.push_back(modulestatus); } } ibs >> ExtDeviceNumber; for( int i=0 ; i < ExtDeviceNumber ; ++i) { ibs >> name; ibs >> state; ibs >> date; extdevicestatus.Name = name; extdevicestatus.OpState = state; extdevicestatus.StateChangeDate = date; systemstatus.systemextdevicestatus.extdevicestatus.push_back(extdevicestatus); } ibs >> NICNumber; for( int i=0 ; i < NICNumber ; ++i) { ibs >> name; ibs >> state; ibs >> date; nicstatus.HostName = name; nicstatus.NICOpState = state; nicstatus.StateChangeDate = date; systemstatus.systemnicstatus.nicstatus.push_back(nicstatus); } ibs >> dbrootNumber; for( int i=0 ; i < dbrootNumber ; ++i) { ibs >> name; ibs >> state; ibs >> date; dbrootstatus.Name = name; dbrootstatus.OpState = state; dbrootstatus.StateChangeDate = date; systemstatus.systemdbrootstatus.dbrootstatus.push_back(dbrootstatus); } } processor.shutdown(); return; } else { //writeLog("getSystemStatus: ProcStatusControl returns 0 length", LOG_TYPE_ERROR); } // timeout ocurred, shutdown connection processor.shutdown(); //writeLog("getSystemStatus: read 0 length", LOG_TYPE_ERROR); exceptionControl("getSystemStatus read 0", API_FAILURE); } catch (exception& e) { string error = e.what(); //writeLog("getSystemStatus: final exception: " + error, LOG_TYPE_ERROR); } catch(...) { //writeLog("getSystemStatus: final exception: unknown", LOG_TYPE_ERROR); } } exceptionControl("getSystemStatus:MessageQueueClient-Error", API_FAILURE); } /******************************************************************** * * set System Status information * ********************************************************************/ void Oam::setSystemStatus(const int state) { //send and wait for ack and resend if not received //retry 3 time max for ( int i=0; i < 3 ; i++) { try { ByteStream obs; obs << (ByteStream::byte) SET_SYSTEM_STATUS; obs << (ByteStream::byte) state; sendStatusUpdate(obs, SET_SYSTEM_STATUS); return; } catch(...) {} } exceptionControl("setSystemStatus", API_FAILURE); } /******************************************************************** * * get Module Status information * ********************************************************************/ void Oam::getModuleStatus(const std::string name, int& state, bool& degraded) { SystemStatus systemstatus; ModuleConfig moduleconfig; std::vector NICstates; degraded = false; state = oam::UNEQUIP; try { getSystemStatus(systemstatus, false); for( unsigned int i = 0 ; i < systemstatus.systemmodulestatus.modulestatus.size(); i++) { if( systemstatus.systemmodulestatus.modulestatus[i].Module == name ) { state = systemstatus.systemmodulestatus.modulestatus[i].ModuleOpState; // get NIC status for degraded state info try { getSystemConfig(name, moduleconfig); HostConfigList::iterator pt1 = moduleconfig.hostConfigList.begin(); for( ; pt1 != moduleconfig.hostConfigList.end() ; pt1++) { try { int state; getNICStatus((*pt1).HostName, state); NICstates.push_back(state); } catch (exception& e) { Oam oam; ostringstream os; os << "Oam::getModuleStatus exception while getNICStatus " << (*pt1).HostName << " " << e.what(); //oam.writeLog(os.str(), logging::LOG_TYPE_ERROR); } catch (...) { Oam oam; ostringstream os; os << "Oam::getModuleStatus exception while getNICStatus " << (*pt1).HostName; //oam.writeLog(os.str(), logging::LOG_TYPE_ERROR); } } vector::iterator pt = NICstates.begin(); for( ; pt != NICstates.end() ; pt++) { if ( (*pt) == oam::DOWN ) { degraded = true; break; } } return; } catch (exception& e) { Oam oam; ostringstream os; os << "Oam::getModuleStatus exception while getSystemConfig " << name << " " << e.what(); //oam.writeLog(os.str(), logging::LOG_TYPE_ERROR); } catch (...) { Oam oam; ostringstream os; os << "Oam::getModuleStatus exception while getSystemConfig " << name; //oam.writeLog(os.str(), logging::LOG_TYPE_ERROR); } } } } catch (exception& e) { Oam oam; ostringstream os; os << "Oam::getModuleStatus exception while getSystemStatus " << e.what(); //oam.writeLog(os.str(), logging::LOG_TYPE_ERROR); } catch (...) { Oam oam; ostringstream os; os << "Oam::getModuleStatus exception while getSystemStatus"; //oam.writeLog(os.str(), logging::LOG_TYPE_ERROR); } // no match found exceptionControl("getModuleStatus", API_INVALID_PARAMETER); } /******************************************************************** * * set Module Status information * ********************************************************************/ void Oam::setModuleStatus(const std::string name, const int state) { //send and wait for ack and resend if not received //retry 3 time max for ( int i=0; i < 3 ; i++) { try { ByteStream obs; obs << (ByteStream::byte) SET_MODULE_STATUS; obs << name; obs << (ByteStream::byte) state; sendStatusUpdate(obs, SET_MODULE_STATUS); return; } catch(...) {} } exceptionControl("setModuleStatus", API_FAILURE); } /******************************************************************** * * get External Device Status information * ********************************************************************/ void Oam::getExtDeviceStatus(const std::string name, int& state) { SystemStatus systemstatus; try { getSystemStatus(systemstatus, false); for( unsigned int i = 0 ; i < systemstatus.systemextdevicestatus.extdevicestatus.size(); i++) { if( systemstatus.systemextdevicestatus.extdevicestatus[i].Name == name ) { state = systemstatus.systemextdevicestatus.extdevicestatus[i].OpState; return; } } } catch (exception&) { exceptionControl("getExtDeviceStatus", API_FAILURE); } // no match found exceptionControl("getExtDeviceStatus", API_INVALID_PARAMETER); } /******************************************************************** * * set External Device Status information * ********************************************************************/ void Oam::setExtDeviceStatus(const std::string name, const int state) { //send and wait for ack and resend if not received //retry 3 time max for ( int i=0; i < 3 ; i++) { try { ByteStream obs; obs << (ByteStream::byte) SET_EXT_DEVICE_STATUS; obs << name; obs << (ByteStream::byte) state; sendStatusUpdate(obs, SET_EXT_DEVICE_STATUS); return; } catch(...) {} } exceptionControl("setExtDeviceStatus", API_FAILURE); } /******************************************************************** * * get DBroot Status information * ********************************************************************/ void Oam::getDbrootStatus(const std::string name, int& state) { SystemStatus systemstatus; try { getSystemStatus(systemstatus, false); for( unsigned int i = 0 ; i < systemstatus.systemdbrootstatus.dbrootstatus.size(); i++) { if( systemstatus.systemdbrootstatus.dbrootstatus[i].Name == name ) { state = systemstatus.systemdbrootstatus.dbrootstatus[i].OpState; return; } } } catch (exception&) { exceptionControl("getDbrootStatus", API_FAILURE); } // no match found exceptionControl("getDbrootStatus", API_INVALID_PARAMETER); } /******************************************************************** * * set DBroot Status information * ********************************************************************/ void Oam::setDbrootStatus(const std::string name, const int state) { //send and wait for ack and resend if not received //retry 3 time max for ( int i=0; i < 3 ; i++) { try { ByteStream obs; obs << (ByteStream::byte) SET_DBROOT_STATUS; obs << name; obs << (ByteStream::byte) state; sendStatusUpdate(obs, SET_DBROOT_STATUS); return; } catch(...) {} } exceptionControl("setDbrootStatus", API_FAILURE); } /******************************************************************** * * get NIC Status information * ********************************************************************/ void Oam::getNICStatus(const std::string name, int& state) { SystemStatus systemstatus; try { getSystemStatus(systemstatus, false); for( unsigned int i = 0 ; i < systemstatus.systemnicstatus.nicstatus.size(); i++) { if( systemstatus.systemnicstatus.nicstatus[i].HostName == name ) { state = systemstatus.systemnicstatus.nicstatus[i].NICOpState; return; } } } catch (exception& e) { Oam oam; ostringstream os; os << "Oam::getNICStatus exception while getSystemStatus for " << name << " " << e.what(); //oam.writeLog(os.str(), logging::LOG_TYPE_ERROR); exceptionControl("getNICStatus", API_FAILURE); } // no match found exceptionControl("getNICStatus", API_INVALID_PARAMETER); } /******************************************************************** * * set NIC Status information * ********************************************************************/ void Oam::setNICStatus(const std::string name, const int state) { //send and wait for ack and resend if not received //retry 3 time max for ( int i=0; i < 3 ; i++) { try { ByteStream obs; obs << (ByteStream::byte) SET_NIC_STATUS; obs << name; obs << (ByteStream::byte) state; sendStatusUpdate(obs, SET_NIC_STATUS); return; } catch(...) {} } exceptionControl("setNICStatus", API_FAILURE); } /******************************************************************** * * get Process Configuration Information * ********************************************************************/ void Oam::getProcessConfig(const std::string process, const std::string module, ProcessConfig& processconfig) { Config* proConfig = Config::makeConfig(ProcessConfigFile.c_str()); const string SECTION_NAME = "PROCESSCONFIG"; const string ARG_NAME = "ProcessArg"; string argName; const string DEP_NAME = "DepProcessName"; const string DEP_MDLNAME = "DepModuleName"; string depName; string depMdlName; string moduleType = module.substr(0,MAX_MODULE_TYPE_SIZE); for (int processID = 1; processID < MAX_PROCESS+1; processID++) { string sectionName = SECTION_NAME + itoa(processID); if( proConfig->getConfig(sectionName, "ProcessName") == process ) { string ModuleType = proConfig->getConfig(sectionName, "ModuleType"); if ( ModuleType == "ParentOAMModule" || ModuleType == "ChildExtOAMModule" || ( ModuleType == "ChildOAMModule" && moduleType != "xm" ) || ModuleType == moduleType) { // get string variables processconfig.ProcessName = process; processconfig.ModuleType = ModuleType; processconfig.ProcessLocation = proConfig->getConfig(sectionName, "ProcessLocation"); processconfig.LogFile = proConfig->getConfig(sectionName, "LogFile");; // get Integer variables processconfig.BootLaunch = strtol(proConfig->getConfig(sectionName, "BootLaunch").c_str(), 0, 0); processconfig.LaunchID = strtol(proConfig->getConfig(sectionName, "LaunchID").c_str(), 0, 0);; // get Auguments for (int argID = 0; argID < MAX_ARGUMENTS; argID++) { argName = ARG_NAME + itoa(argID+1); processconfig.ProcessArgs[argID] = proConfig->getConfig(sectionName, argName); } // get process dependencies for (int depID = 0; depID < MAX_DEPENDANCY; depID++) { depName = DEP_NAME + itoa(depID+1); processconfig.DepProcessName[depID] = proConfig->getConfig(sectionName, depName); } // get dependent process Module name for (int moduleID = 0; moduleID < MAX_DEPENDANCY; moduleID++) { depMdlName = DEP_MDLNAME + itoa(moduleID+1); processconfig.DepModuleName[moduleID] = proConfig->getConfig(sectionName, depMdlName); } // get optional group id and type try { processconfig.RunType = proConfig->getConfig(sectionName, "RunType"); } catch(...) { processconfig.RunType = "LOADSHARE"; } return; } } } // Process Not found exceptionControl("getProcessConfig", API_INVALID_PARAMETER); } /******************************************************************** * * get System Process Configuration Information * ********************************************************************/ void Oam::getProcessConfig(SystemProcessConfig& systemprocessconfig) { const string SECTION_NAME = "PROCESSCONFIG"; systemprocessconfig.processconfig.clear(); Config* proConfig = Config::makeConfig(ProcessConfigFile.c_str()); for (int processID = 1; processID < MAX_PROCESS+1; processID++) { ProcessConfig processconfig; // get process info string sectionName = SECTION_NAME + itoa(processID); Oam::getProcessConfig(proConfig->getConfig(sectionName, "ProcessName"), proConfig->getConfig(sectionName, "ModuleType"), processconfig ); if (processconfig.ProcessName.empty()) continue; systemprocessconfig.processconfig.push_back(processconfig); } } /******************************************************************** * * get Process Configuration String Parameter value * ********************************************************************/ void Oam::getProcessConfig(const std::string process, const std::string module, const std::string name, std::string& value) { Config* proConfig = Config::makeConfig(ProcessConfigFile.c_str()); const string SECTION_NAME = "PROCESSCONFIG"; string moduleType = module.substr(0,MAX_MODULE_TYPE_SIZE); for (int processID = 1; processID < MAX_PROCESS+1; processID++) { string sectionName = SECTION_NAME + itoa(processID); if( proConfig->getConfig(sectionName, "ProcessName") == process ) { string ModuleType = proConfig->getConfig(sectionName, "ModuleType"); if ( ModuleType == "ParentOAMModule" || ModuleType == "ChildExtOAMModule" || ( ModuleType == "ChildOAMModule" && moduleType != "xm" ) || ModuleType == moduleType) { // get string variables value = proConfig->getConfig(sectionName, name); if (value.empty()) { exceptionControl("getProcessConfig", API_INVALID_PARAMETER); } return; } } } // Process Not found exceptionControl("getProcessConfig", API_INVALID_PARAMETER); } /******************************************************************** * * get Process Configuration Integer Parameter value * ********************************************************************/ void Oam::getProcessConfig(const std::string process, const std::string module, const std::string name, int& value) { string returnValue; Oam::getProcessConfig(process, module, name, returnValue); value = atoi(returnValue.c_str()); } /******************************************************************** * * set Process Configuration String Parameter value * ********************************************************************/ void Oam::setProcessConfig(const std::string process, const std::string module, const std::string name, const std::string value) { Config* proConfig = Config::makeConfig(ProcessConfigFile.c_str()); const string SECTION_NAME = "PROCESSCONFIG"; string returnValue; string moduleType = module.substr(0,MAX_MODULE_TYPE_SIZE); for (int processID = 1; processID < MAX_PROCESS+1; processID++) { string sectionName = SECTION_NAME + itoa(processID); if( proConfig->getConfig(sectionName, "ProcessName") == process ) { string ModuleType = proConfig->getConfig(sectionName, "ModuleType"); if ( ModuleType == "ParentOAMModule" || ModuleType == "ChildExtOAMModule" || ( ModuleType == "ChildOAMModule" && moduleType != "xm" ) || ModuleType == moduleType) { // check if parameter exist Oam::getProcessConfig(process, module, name, returnValue); // Set string variables proConfig->setConfig(sectionName, name, value); try { proConfig->write(); } catch(...) { exceptionControl("setProcessConfig", API_FAILURE); } // build and send msg to inform Proc-Mgt that Configuration is updated // don't care if fails, sincet his can be called with Proc-Mgr enable sendMsgToProcMgr(UPDATECONFIG, "", FORCEFUL, ACK_NO); return; } } } // Process Not found exceptionControl("setProcessConfig", API_INVALID_PARAMETER); } /******************************************************************** * * set Process Configuration Interger Parameter value * ********************************************************************/ void Oam::setProcessConfig(const std::string process, const std::string module, const std::string name, const int value) { string valueString; // convert Incoming Interger Parameter value to String valueString = itoa(value); // write parameter to disk Oam::setProcessConfig(process, module, name, valueString); } /******************************************************************** * * System Process Status information from the Process status file. * ********************************************************************/ void Oam::getProcessStatus(SystemProcessStatus& systemprocessstatus, string port) { if (!checkSystemRunning()) exceptionControl("getProcessStatus", API_FAILURE); ProcessStatus processstatus; systemprocessstatus.processstatus.clear(); try { MessageQueueClient processor(port); // processor.syncProto(false); ByteStream::quadbyte processNumber; ByteStream::byte state; ByteStream::quadbyte PID; std::string changeDate; std::string processName; std::string moduleName; ByteStream obs, ibs; obs << (ByteStream::byte) GET_ALL_PROC_STATUS; try { struct timespec ts = { 5, 0 }; processor.write(obs, &ts); } catch (std::exception& ex) { exceptionControl("getProcessStatus:write", API_FAILURE); } catch(...) { exceptionControl("getProcessStatus:write", API_TIMEOUT); } // wait 10 seconds for ACK from Process Monitor struct timespec ts = { 30, 0 }; try { ibs = processor.read(&ts); } catch (std::exception& ex) { exceptionControl("getProcessStatus:read", API_FAILURE); } catch(...) { exceptionControl("getProcessStatus:read", API_TIMEOUT); } if (ibs.length() > 0) { ibs >> processNumber; for( unsigned i=0 ; i < processNumber ; ++i) { ibs >> processName; ibs >> moduleName; ibs >> state; ibs >> PID; ibs >> changeDate; processstatus.ProcessName = processName; processstatus.Module = moduleName; processstatus.ProcessOpState = state; processstatus.ProcessID = PID; processstatus.StateChangeDate = changeDate; systemprocessstatus.processstatus.push_back(processstatus); } processor.shutdown(); return; } // timeout occurred, shutdown connection processor.shutdown(); } catch (std::exception& ex) { exceptionControl("getProcessStatus:MessageQueueClient", API_FAILURE, ex.what()); } catch(...) { exceptionControl("getProcessStatus:MessageQueueClient", API_FAILURE); } exceptionControl("getProcessStatus", API_TIMEOUT); } /******************************************************************** * * get Process information from the Process Status file. * ********************************************************************/ void Oam::getProcessStatus(const std::string process, const std::string module, ProcessStatus& processstatus) { #ifdef _MSC_VER // TODO: Remove when we create OAM for Windows return; #endif if (!checkSystemRunning()) exceptionControl("getProcessStatus", API_FAILURE); for ( int i = 0 ; i < 5 ; i ++) { try { MessageQueueClient processor("ProcStatusControl"); // processor.syncProto(false); ByteStream::byte status, state; ByteStream::quadbyte PID; std::string changeDate; ByteStream obs, ibs; obs << (ByteStream::byte) GET_PROC_STATUS; obs << module; obs << process; try { struct timespec ts = { 5, 0 }; processor.write(obs, &ts); } catch (std::exception& ex) { processor.shutdown(); exceptionControl("getProcessStatus:write", API_FAILURE, ex.what()); } catch(...) { processor.shutdown(); exceptionControl("getProcessStatus:write", API_TIMEOUT); } // wait 10 seconds for ACK from Process Monitor struct timespec ts = { 15, 0 }; try { ibs = processor.read(&ts); } catch (std::exception& ex) { processor.shutdown(); exceptionControl("getProcessStatus:read", API_FAILURE, ex.what()); } catch(...) { processor.shutdown(); exceptionControl("getProcessStatus:read", API_TIMEOUT); } if (ibs.length() > 0) { ibs >> status; if ( status == oam::API_SUCCESS ) { ibs >> state; ibs >> PID; ibs >> changeDate; } else { // shutdown connection processor.shutdown(); exceptionControl("getProcessStatus:status", API_FAILURE); } processstatus.ProcessName = process; processstatus.Module = module; processstatus.ProcessOpState = state; processstatus.ProcessID = PID; processstatus.StateChangeDate = changeDate; processor.shutdown(); return; } // timeout occurred, shutdown connection processor.shutdown(); exceptionControl("getProcessStatus:status", API_TIMEOUT); } catch(...) {} } exceptionControl("getProcessStatus:MessageQueueClient-Error", API_FAILURE); } /******************************************************************** * * set Process Status String Parameter from the Process Status file. * ********************************************************************/ void Oam::setProcessStatus(const std::string process, const std::string module, const int state, pid_t PID) { if (!checkSystemRunning()) exceptionControl("setProcessStatus", API_FAILURE); //send and wait for ack and resend if not received //retry 5 time max for ( int i=0; i < 5 ; i++) { try { ByteStream obs; obs << (ByteStream::byte) SET_PROC_STATUS; obs << module; obs << process; obs << (ByteStream::byte) state; obs << (ByteStream::quadbyte) PID; sendStatusUpdate(obs, SET_PROC_STATUS); return; } catch(...) {} #ifdef _MSC_VER Sleep(1 * 1000); #else sleep(1); #endif } exceptionControl("setProcessStatus", API_TIMEOUT); } /******************************************************************** * * Process Initization Successful Completed, Mark Process ACTIVE * ********************************************************************/ void Oam::processInitComplete(std::string processName, int state) { //This method takes too long on Windows and doesn't do anything there anyway... #if !defined(_MSC_VER) && !defined(SKIP_OAM_INIT) // get current Module name string moduleName; oamModuleInfo_t st; try { st = getModuleInfo(); moduleName = boost::get<0>(st); } catch (...) { //system("touch /var/log/mariadb/columnstore/test2"); } for ( int i = 0 ; i < 5 ; i++) { //set process try { setProcessStatus(processName, moduleName, state, getpid()); //verify it's set try{ ProcessStatus procstat; getProcessStatus(processName, moduleName, procstat); if ( procstat.ProcessOpState == state) return; } catch (...) {} } catch(...) { //system("touch /var/log/mariadb/columnstore/test3"); } sleep(1); } writeLog("processInitComplete: Status update failed", LOG_TYPE_ERROR ); exceptionControl("processInitComplete", API_FAILURE); #endif } /******************************************************************** * * Process Initization Failed, Mark Process FAILED * ********************************************************************/ void Oam::processInitFailure() { // get current process name string processName; myProcessStatus_t t; try { t = getMyProcessStatus(); processName = boost::get<1>(t); } catch (...) { exceptionControl("processInitFailure", API_FAILURE); } // get current Module name string moduleName; oamModuleInfo_t st; try { st = getModuleInfo(); moduleName = boost::get<0>(st); } catch (...) { exceptionControl("processInitFailure", API_FAILURE); } //set process to FAILED try { setProcessStatus(processName, moduleName, FAILED, 0); } catch(...) { exceptionControl("processInitFailure", API_FAILURE); } //set MODULE to FAILED try { setModuleStatus(moduleName, FAILED); } catch(...) { exceptionControl("processInitFailure", API_FAILURE); } } /******************************************************************** * * get Alarm Configuration Information by Alarm ID * ********************************************************************/ void Oam::getAlarmConfig(const int alarmid, AlarmConfig& alarmconfig) { Config* alaConfig = Config::makeConfig(AlarmConfigFile.c_str()); string temp; string Section = "AlarmConfig"; // validate Alarm ID if( alarmid > MAX_ALARM_ID ) exceptionControl("getAlarmConfig", API_INVALID_PARAMETER); // convert Alarm ID to ASCII Section.append(itoa(alarmid)); // get string variables temp = alaConfig->getConfig(Section, "AlarmID"); if( temp.empty()) { exceptionControl("getAlarmConfig", API_INVALID_PARAMETER); } alarmconfig.BriefDesc = alaConfig->getConfig(Section, "BriefDesc"); alarmconfig.DetailedDesc = alaConfig->getConfig(Section, "DetailedDesc"); // get numberic variables alarmconfig.AlarmID = strtol(alaConfig->getConfig(Section, "alarmid").c_str(), 0, 0); alarmconfig.Severity = strtol(alaConfig->getConfig(Section, "Severity").c_str(), 0, 0); alarmconfig.Threshold = strtol(alaConfig->getConfig(Section, "Threshold").c_str(), 0, 0); alarmconfig.Occurrences = strtol(alaConfig->getConfig(Section, "Occurrences").c_str(), 0, 0); alarmconfig.LastIssueTime = strtol(alaConfig->getConfig(Section, "LastIssueTime").c_str(), 0, 0); } /******************************************************************** * * get Alarm Configuration String Parameter value * ********************************************************************/ void Oam::getAlarmConfig(const int alarmid, const std::string name, std::string& value) { Config* alaConfig = Config::makeConfig(AlarmConfigFile.c_str()); string Section = "AlarmConfig"; // validate Alarm ID if( alarmid > MAX_ALARM_ID ) exceptionControl("getSystemConfig", API_INVALID_PARAMETER); // convert Alarm ID to ASCII Section.append(itoa(alarmid)); // get string variables value = alaConfig->getConfig(Section, name); if (value.empty()) { exceptionControl("getSystemConfig", API_INVALID_PARAMETER); } } /******************************************************************** * * get Alarm Configuration Integer Parameter value * ********************************************************************/ void Oam::getAlarmConfig(const int alarmid, const std::string name, int& value) { string returnValue; // get string variables Oam::getAlarmConfig(alarmid, name, returnValue); value = atoi(returnValue.c_str()); } /******************************************************************** * * set Alarm Configuration String Parameter value by Alarm ID * ********************************************************************/ void Oam::setAlarmConfig(const int alarmid, const std::string name, const std::string value) { string Section = "AlarmConfig"; int returnValue; struct flock fl; int fd; // validate Alarm ID if( alarmid > MAX_ALARM_ID ) exceptionControl("setAlarmConfig", API_INVALID_PARAMETER); // convert Alarm ID to ASCII Section.append(itoa(alarmid)); // check if parameter exist Oam::getAlarmConfig(alarmid, name, returnValue); // only allow user to change these levels if ( name != "Threshold" && name != "Occurrences" && name != "LastIssueTime" ) exceptionControl("setAlarmConfig", API_READONLY_PARAMETER); string fileName = AlarmConfigFile; memset(&fl, 0, sizeof(fl)); fl.l_type = F_RDLCK; // read lock fl.l_whence = SEEK_SET; fl.l_start = 0; fl.l_len = 0; //lock whole file // open config file if ((fd = open(fileName.c_str(), O_RDWR)) >= 0) { // lock file if (fcntl(fd, F_SETLKW, &fl) != 0) { ostringstream oss; oss << "Oam::setAlarmConfig: error locking file " << fileName << ": " << strerror(errno) << ", proceding anyway."; cerr << oss.str() << endl; } // write parameter to disk Config* alaConfig = Config::makeConfig(AlarmConfigFile.c_str()); alaConfig->setConfig(Section, name, value); try { alaConfig->write(); } catch(...) {} fl.l_type = F_UNLCK; //unlock fcntl(fd, F_SETLK, &fl); close(fd); } else { ostringstream oss; oss << "Oam::setAlarmConfig: error opening file " << fileName << ": " << strerror(errno); throw runtime_error(oss.str()); } return; } /******************************************************************** * * set Alarm Configuration Interger Parameter value by Alarm ID * ********************************************************************/ void Oam::setAlarmConfig(const int alarmid, const std::string name, const int value) { string Section = "AlarmConfig"; string valueString; // convert Incoming Interger Parameter value to String valueString = itoa(value); // write parameter to disk Oam::setAlarmConfig(alarmid, name, valueString); } /******************************************************************** * * get Active Alarm List * ********************************************************************/ void Oam::getActiveAlarms(AlarmList& activeAlarm) { // check if on Active OAM Parent bool OAMParentModuleFlag; oamModuleInfo_t st; try { st = getModuleInfo(); OAMParentModuleFlag = boost::get<4>(st); if (OAMParentModuleFlag) { //call getAlarm API directly ALARMManager sm; sm.getActiveAlarm(activeAlarm); return; } } catch (...) { exceptionControl("getActiveAlarms", API_FAILURE); } int returnStatus = API_SUCCESS; if (UseHdfs > 0) { // read from HDFS files returnStatus = readHdfsActiveAlarms(activeAlarm); } else { // build and send msg returnStatus = sendMsgToProcMgr3(GETACTIVEALARMDATA, activeAlarm, ""); } if (returnStatus != API_SUCCESS) exceptionControl("getActiveAlarms", returnStatus); } /******************************************************************** * * get Historical Alarm List * ********************************************************************/ void Oam::getAlarms(std::string date, AlarmList& alarmlist) { // check if on Active OAM Parent bool OAMParentModuleFlag; oamModuleInfo_t st; try { st = getModuleInfo(); OAMParentModuleFlag = boost::get<4>(st); if (OAMParentModuleFlag) { //call getAlarm API directly ALARMManager sm; sm.getAlarm(date, alarmlist); return; } } catch (...) { exceptionControl("getAlarms", API_FAILURE); } // build and send msg int returnStatus = sendMsgToProcMgr3(GETALARMDATA, alarmlist, date); if (returnStatus != API_SUCCESS) exceptionControl("getAlarms", returnStatus); } /******************************************************************** * * check Active Alarm * ********************************************************************/ bool Oam::checkActiveAlarm(const int alarmid, const std::string moduleName, const std::string deviceName) { AlarmList activeAlarm; // check if on Active OAM Parent bool OAMParentModuleFlag; oamModuleInfo_t st; try { st = getModuleInfo(); OAMParentModuleFlag = boost::get<4>(st); if (OAMParentModuleFlag) { //call getAlarm API directly ALARMManager sm; sm.getActiveAlarm(activeAlarm); } else if (UseHdfs > 0) { // read from HDFS files if (readHdfsActiveAlarms(activeAlarm) != API_SUCCESS) return false; } else { // build and send msg int returnStatus = sendMsgToProcMgr3(GETACTIVEALARMDATA, activeAlarm, ""); if (returnStatus != API_SUCCESS) return false; } } catch (...) { return false; } for (AlarmList::iterator i = activeAlarm.begin(); i != activeAlarm.end(); ++i) { // check if matching ID if (alarmid != (i->second).getAlarmID() ) continue; //check for moduleName of wildcard "*", if so return if alarm set on any module if (deviceName.compare((i->second).getComponentID()) == 0 && moduleName == "*") return true; // check if the same fault component on same Module if (deviceName.compare((i->second).getComponentID()) == 0 && moduleName.compare((i->second).getSname()) == 0) return true; } return false; } /******************************************************************** * * get Local Module Information from Local Module Configuration file * * Returns: Local Module Name, Local Module Type, Local Module ID, * OAM Parent Module Name, and OAM Parent Flag * ********************************************************************/ oamModuleInfo_t Oam::getModuleInfo() { string localModule; string localModuleType; int localModuleID; // Get Module Name from module-file string fileName = InstallDir + "/local/module"; ifstream oldFile (fileName.c_str()); char line[400]; while (oldFile.getline(line, 400)) { localModule = line; break; } oldFile.close(); if (localModule.empty() ) { // not found //system("touch /var/log/mariadb/columnstore/test8"); exceptionControl("getModuleInfo", API_FAILURE); } localModuleType = localModule.substr(0,MAX_MODULE_TYPE_SIZE); localModuleID = atoi(localModule.substr(MAX_MODULE_TYPE_SIZE,MAX_MODULE_ID_SIZE).c_str()); // Get Parent OAM Module name string ParentOAMModule = oam::UnassignedName; string StandbyOAMModule = oam::UnassignedName; bool parentOAMModuleFlag = false; bool standbyOAMModuleFlag = false; int serverTypeInstall = 1; try { Config* sysConfig = Config::makeConfig(CalpontConfigFile.c_str()); string Section = "SystemConfig"; ParentOAMModule = sysConfig->getConfig(Section, "ParentOAMModuleName"); StandbyOAMModule = sysConfig->getConfig(Section, "StandbyOAMModuleName"); if ( localModule == ParentOAMModule ) parentOAMModuleFlag = true; if ( localModule == StandbyOAMModule ) standbyOAMModuleFlag = true; // Get Server Type Install ID serverTypeInstall = atoi(sysConfig->getConfig("Installation", "ServerTypeInstall").c_str()); sysConfig; } catch (...) {} return boost::make_tuple(localModule, localModuleType, localModuleID, ParentOAMModule, parentOAMModuleFlag, serverTypeInstall, StandbyOAMModule, standbyOAMModuleFlag); } /******************************************************************** * * get My Process Status from Process Status file * ********************************************************************/ myProcessStatus_t Oam::getMyProcessStatus(pid_t processID) { string returnValue; ByteStream::quadbyte pid; if ( processID == 0 ) // get current process PID pid = getpid(); else pid = processID; // get process current Module string moduleName; oamModuleInfo_t st; try { st = getModuleInfo(); moduleName = boost::get<0>(st); } catch (...) { //system("touch /var/log/mariadb/columnstore/test4"); exceptionControl("getMyProcessStatus", API_FAILURE); } if (!checkSystemRunning()) exceptionControl("getMyProcessStatus", API_FAILURE); for ( int i = 0 ; i < 5 ; i ++) { try { MessageQueueClient processor("ProcStatusControl"); // processor.syncProto(false); ByteStream::byte status, state; std::string processName; ByteStream obs, ibs; obs << (ByteStream::byte) GET_PROC_STATUS_BY_PID; obs << moduleName; obs << pid; try { struct timespec ts = { 5, 0 }; processor.write(obs, &ts); try { // wait 10 seconds for ACK from Process Monitor struct timespec ts = { 10, 0 }; ibs = processor.read(&ts); if (ibs.length() > 0) { ibs >> status; if ( status == oam::API_SUCCESS ) { ibs >> state; ibs >> processName; } else { // shutdown connection processor.shutdown(); //system("touch /var/log/mariadb/columnstore/test5"); exceptionControl("getMyProcessStatus", API_FAILURE); } // shutdown connection processor.shutdown(); return boost::make_tuple((pid_t) pid, processName, state); } } catch(...) { //system("touch /var/log/mariadb/columnstore/test6"); processor.shutdown(); exceptionControl("getMyProcessStatus", API_INVALID_PARAMETER); } } catch(...) { //system("touch /var/log/mariadb/columnstore/test7"); processor.shutdown(); exceptionControl("getMyProcessStatus", API_INVALID_PARAMETER); } // timeout occurred, shutdown connection processor.shutdown(); exceptionControl("getMyProcessStatus", API_TIMEOUT); } catch(...) {} } //system("touch /var/log/mariadb/columnstore/test9"); exceptionControl("getMyProcessStatus", API_FAILURE); return boost::make_tuple(-1, "", -1); } /******************************************************************** * * Stop Module * ********************************************************************/ void Oam::stopModule(DeviceNetworkList devicenetworklist, GRACEFUL_FLAG gracefulflag, ACK_FLAG ackflag) { DeviceNetworkList::iterator pt = devicenetworklist.begin(); for( ; pt != devicenetworklist.end() ; pt++) { // validate Module name int returnStatus = validateModule((*pt).DeviceName); if (returnStatus != API_SUCCESS) exceptionControl("stopModule", returnStatus); } // build and send msg int returnStatus = sendMsgToProcMgr2(STOPMODULE, devicenetworklist, gracefulflag, ackflag); if (returnStatus != API_SUCCESS) exceptionControl("stopModule", returnStatus); } /******************************************************************** * * Shutdown Module - build and send message to Process Manager * ********************************************************************/ void Oam::shutdownModule(DeviceNetworkList devicenetworklist, GRACEFUL_FLAG gracefulflag, ACK_FLAG ackflag) { DeviceNetworkList::iterator pt = devicenetworklist.begin(); for( ; pt != devicenetworklist.end() ; pt++) { // validate Module name int returnStatus = validateModule((*pt).DeviceName); if (returnStatus != API_SUCCESS) exceptionControl("shutdownModule", returnStatus); } // build and send msg int returnStatus = sendMsgToProcMgr2(SHUTDOWNMODULE, devicenetworklist, gracefulflag, ackflag); if (returnStatus != API_SUCCESS) exceptionControl("shutdownModule", returnStatus); } /******************************************************************** * * Start Module - build and send message to Process Manager * ********************************************************************/ void Oam::startModule(DeviceNetworkList devicenetworklist, ACK_FLAG ackflag) { DeviceNetworkList::iterator pt = devicenetworklist.begin(); for( ; pt != devicenetworklist.end() ; pt++) { // validate Module name int returnStatus = validateModule((*pt).DeviceName); if (returnStatus != API_SUCCESS) exceptionControl("startModule", returnStatus); } // build and send msg int returnStatus = sendMsgToProcMgr2(STARTMODULE, devicenetworklist, FORCEFUL, ackflag); if (returnStatus != API_SUCCESS) exceptionControl("startModule", returnStatus); } /******************************************************************** * * Restart Module - build and send message to Process Manager * ********************************************************************/ void Oam::restartModule(DeviceNetworkList devicenetworklist, GRACEFUL_FLAG gracefulflag, ACK_FLAG ackflag) { DeviceNetworkList::iterator pt = devicenetworklist.begin(); for( ; pt != devicenetworklist.end() ; pt++) { // validate Module name int returnStatus = validateModule((*pt).DeviceName); if (returnStatus != API_SUCCESS) exceptionControl("restartModule", returnStatus); } // build and send msg int returnStatus = sendMsgToProcMgr2(RESTARTMODULE, devicenetworklist, gracefulflag, ackflag); if (returnStatus != API_SUCCESS) exceptionControl("restartModule", returnStatus); } /******************************************************************** * * Disable Module - build and send message to Process Manager * ********************************************************************/ void Oam::disableModule(DeviceNetworkList devicenetworklist) { DeviceNetworkList::iterator pt = devicenetworklist.begin(); for( ; pt != devicenetworklist.end() ; pt++) { // validate Module name int returnStatus = validateModule((*pt).DeviceName); if (returnStatus != API_SUCCESS) exceptionControl("disableModule", returnStatus); } // build and send msg int returnStatus = sendMsgToProcMgr2(DISABLEMODULE, devicenetworklist, FORCEFUL, ACK_YES); if (returnStatus != API_SUCCESS) exceptionControl("disableModule", returnStatus); } /******************************************************************** * * Enable Module - build and send message to Process Manager * ********************************************************************/ void Oam::enableModule(DeviceNetworkList devicenetworklist) { DeviceNetworkList::iterator pt = devicenetworklist.begin(); for( ; pt != devicenetworklist.end() ; pt++) { // validate Module name int returnStatus = validateModule((*pt).DeviceName); if (returnStatus != API_SUCCESS) exceptionControl("enableModule", returnStatus); } // build and send msg int returnStatus = sendMsgToProcMgr2(ENABLEMODULE, devicenetworklist, FORCEFUL, ACK_YES); if (returnStatus != API_SUCCESS) exceptionControl("enableModule", returnStatus); } /******************************************************************** * * Stop System - build and send message to Process Manager * ********************************************************************/ void Oam::stopSystem(GRACEFUL_FLAG gracefulflag, ACK_FLAG ackflag) { // build and send msg int returnStatus = sendMsgToProcMgrWithStatus(STOPSYSTEM, "stopped", gracefulflag, ackflag); if (returnStatus != API_SUCCESS) exceptionControl("stopSystem", returnStatus); } /******************************************************************** * * Shutdown System - build and send message to Process Manager * ********************************************************************/ void Oam::shutdownSystem(GRACEFUL_FLAG gracefulflag, ACK_FLAG ackflag) { int returnStatus = sendMsgToProcMgrWithStatus(SHUTDOWNSYSTEM, "shutdown", gracefulflag, ackflag); //Wait for everything to settle down sleep(10); switch (returnStatus) { case API_SUCCESS: cout << endl << " Successful shutdown of System " << endl << endl; break; case API_CANCELLED: cout << endl << " Shutdown of System canceled" << endl << endl; break; default: exceptionControl("shutdownSystem", returnStatus); break; } } /******************************************************************** * * Suspend Database Writes - build and send message to Process Manager * ********************************************************************/ void Oam::SuspendWrites(GRACEFUL_FLAG gracefulflag, ACK_FLAG ackflag) { SystemProcessStatus systemprocessstatus; // Send the message to suspend and wait for it to finish int returnStatus = sendMsgToProcMgrWithStatus(SUSPENDWRITES, "write suspended", gracefulflag, ackflag); // An error throws here. switch (returnStatus) { case API_SUCCESS: cout << endl << "Suspend Calpont Database Writes Request successfully completed" << endl; break; case API_FAILURE_DB_ERROR: cout << endl << "**** stopDatabaseWrites Failed: save_brm Failed" << endl; break; case API_CANCELLED: cout << endl << " Suspension of database writes canceled" << endl << endl; break; default: exceptionControl("suspendWrites", returnStatus); break; } } /******************************************************************** * * Start System - build and send message to Process Manager * ********************************************************************/ void Oam::startSystem(ACK_FLAG ackflag) { // build and send msg int returnStatus = sendMsgToProcMgr(STARTSYSTEM, "", FORCEFUL, ackflag); if (returnStatus != API_SUCCESS) exceptionControl("startSystem", returnStatus); } /******************************************************************** * * Restart System - build and send message to Process Manager * ********************************************************************/ int Oam::restartSystem(GRACEFUL_FLAG gracefulflag, ACK_FLAG ackflag) { // Send the restart message (waits for completion) int returnStatus = sendMsgToProcMgrWithStatus(RESTARTSYSTEM, "restarted", gracefulflag, ackflag); if (returnStatus != API_SUCCESS && returnStatus != API_CANCELLED) { exceptionControl("restartSystem", returnStatus); } return returnStatus; } /******************************************************************** * * Stop Process - build and send message to Process Manager * ********************************************************************/ void Oam::stopProcess(const std::string moduleName, const std::string processName, GRACEFUL_FLAG gracefulflag, ACK_FLAG ackflag) { // validate Process name int returnStatus = validateProcess(moduleName, processName); if (returnStatus != API_SUCCESS) exceptionControl("stopProcess", returnStatus); // validate Process Name, don't allow Process-Monitor / Process-Manager if ( processName == "ProcessMonitor" || processName == "ProcessManager" ) exceptionControl("stopProcess", API_INVALID_PARAMETER); // validate Process Name, don't allow COLD-STANDBY process ProcessStatus procstat; getProcessStatus(processName, moduleName, procstat); if ( procstat.ProcessOpState == oam::COLD_STANDBY ) exceptionControl("stopProcess", API_INVALID_STATE); // build and send msg returnStatus = sendMsgToProcMgr(STOPPROCESS, processName, gracefulflag, ackflag, moduleName); if (returnStatus != API_SUCCESS) exceptionControl("stopProcess", returnStatus); } /******************************************************************** * * Start Process - build and send message to Process Manager * ********************************************************************/ void Oam::startProcess(const std::string moduleName, const std::string processName, GRACEFUL_FLAG gracefulflag, ACK_FLAG ackflag) { // validate Process name int returnStatus = validateProcess(moduleName, processName); if (returnStatus != API_SUCCESS) exceptionControl("startProcess", returnStatus); // validate Process Name, don't allow COLD-STANDBY process // ProcessStatus procstat; // getProcessStatus(processName, moduleName, procstat); // if ( procstat.ProcessOpState == oam::COLD_STANDBY ) // exceptionControl("startProcess", API_INVALID_STATE); // build and send msg returnStatus = sendMsgToProcMgr(STARTPROCESS, processName, gracefulflag, ackflag, moduleName); if (returnStatus != API_SUCCESS) exceptionControl("startProcess", returnStatus); } /******************************************************************** * * Restart Process - build and send message to Process Manager * ********************************************************************/ void Oam::restartProcess(const std::string moduleName, const std::string processName, GRACEFUL_FLAG gracefulflag, ACK_FLAG ackflag) { // validate Process name int returnStatus = validateProcess(moduleName, processName); if (returnStatus != API_SUCCESS) exceptionControl("restartProcess", returnStatus); // build and send msg returnStatus = sendMsgToProcMgr(RESTARTPROCESS, processName, gracefulflag, ackflag, moduleName); if (returnStatus != API_SUCCESS) exceptionControl("restartProcess", returnStatus); } /******************************************************************** * * Stop Process - build and send message to Process Manager * ********************************************************************/ void Oam::stopProcessType(std::string type) { // build and send msg int returnStatus = sendMsgToProcMgr(STOPPROCESSTYPE, type); if (returnStatus != API_SUCCESS) exceptionControl("stopProcessType", returnStatus); } /******************************************************************** * * Start Processes - build and send message to Process Manager * ********************************************************************/ void Oam::startProcessType(std::string type) { // build and send msg int returnStatus = sendMsgToProcMgr(STARTPROCESSTYPE, type); if (returnStatus != API_SUCCESS) exceptionControl("startProcessType", returnStatus); } /******************************************************************** * * Restart Process Type- build and send message to Process Manager * ********************************************************************/ void Oam::restartProcessType(std::string type) { // build and send msg int returnStatus = sendMsgToProcMgr(RESTARTPROCESSTYPE, type); if (returnStatus != API_SUCCESS) exceptionControl("restartProcessType", returnStatus); } /******************************************************************** * * Reinit Process Type- build and send message to Process Manager * ********************************************************************/ void Oam::reinitProcessType(std::string type) { // build and send msg int returnStatus = sendMsgToProcMgr(REINITPROCESSTYPE, type, FORCEFUL); if (returnStatus != API_SUCCESS) exceptionControl("reinitProcessType", returnStatus); } /******************************************************************** * * Update Logging - Enable/Disable Logging with the system or on a specific * Module at a specific level * ********************************************************************/ void Oam::updateLog(const std::string action, const std::string deviceid, const std::string loglevel) { // validate the loglevel for( int i = 0;;i++) { if ( LogLevel[i] == "" ) { // end of section list exceptionControl("updateLog", API_INVALID_PARAMETER); } if ( loglevel == LogLevel[i] ) { // build and send msg int returnStatus = sendMsgToProcMgr(UPDATELOG, deviceid, FORCEFUL, ACK_YES, action, loglevel); if (returnStatus != API_SUCCESS) exceptionControl("updateLog", returnStatus); return; } } } /******************************************************************** * * Get Log File - Get Log file location for specific Module at a specific level * ********************************************************************/ void Oam::getLogFile(const std::string moduleName, const std::string loglevel, std::string& filelocation) { // validate Module name int returnStatus = validateModule(moduleName); if (returnStatus != API_SUCCESS) exceptionControl("getLogFile", returnStatus); string path; // Get Parent OAM Module name Config* sysConfig = Config::makeConfig(CalpontConfigFile.c_str()); string Section = "SystemConfig"; string ParentOAMModule = sysConfig->getConfig(Section, "ParentOAMModuleName"); if (moduleName == ParentOAMModule) path = "//"; else path = "/mnt/" + moduleName; // get log file name for level string logFile; for( int i = 0;;i++) { if ( LogLevel[i] == "" ) { // end of list exceptionControl("getLogFile", API_INVALID_PARAMETER); break; } if ( loglevel == LogLevel[i] ) { // match found, get and strip off to '/' logFile = LogFile[i]; string::size_type pos = logFile.find('/',0); if (pos != string::npos) { logFile = logFile.substr(pos,200); break; } } } filelocation = path + logFile; } /******************************************************************** * * Get Log File - Get Log file location for specific Module at a specific level * ********************************************************************/ void Oam::getLogFile(const std::string moduleName, const std::string loglevel, const std::string date, std::string& filelocation) { // validate Module name int returnStatus = validateModule(moduleName); if (returnStatus != API_SUCCESS) exceptionControl("getLogFile", returnStatus); string path; // Get Parent OAM Module name Config* sysConfig = Config::makeConfig(CalpontConfigFile.c_str()); string Section = "SystemConfig"; string ParentOAMModule = sysConfig->getConfig(Section, "ParentOAMModuleName"); if (moduleName == ParentOAMModule) path = "/"; else path = "/mnt/" + moduleName; // get log file name for level string logFile; string logFileName; for( int i = 0;;i++) { if ( LogLevel[i] == "" ) { // end of list exceptionControl("getLogFile", API_INVALID_PARAMETER); break; } if ( loglevel == LogLevel[i] ) { // match found, get and strip off to '/' logFile = LogFile[i]; string::size_type pos = logFile.find('/',0); if (pos != string::npos) { logFile = logFile.substr(pos,200); pos = logFile.rfind('/',200); logFileName = logFile.substr(pos+1,200); break; } } } logFile = path + logFile; string tempLogFile = "/tmp/logs"; //make 1 log file made up of archive and current *.log (void)system("touch /tmp/logs"); string logdir("/var/log/mariadb/columnstore"); if (access(logdir.c_str(), W_OK) != 0) logdir = "/tmp"; string cmd = "ls " + path + logdir + "/archive | grep '" + logFileName + "' > /tmp/logfiles"; (void)system(cmd.c_str()); string fileName = "/tmp/logfiles"; ifstream oldFile (fileName.c_str()); if (oldFile) { char line[400]; string buf; while (oldFile.getline(line, 400)) { buf = line; cmd = "cat " + path + logdir + "/archive/" + buf + " >> /tmp/logs"; (void)system(cmd.c_str()); } oldFile.close(); unlink (fileName.c_str()); } cmd = "cat " + logFile + " >> /tmp/logs"; (void)system(cmd.c_str()); //validate and get mm / dd from incoming date if ( date.substr(2,1) != "/" ) exceptionControl("getLogFile", oam::API_INVALID_PARAMETER); string dd = date.substr(3,2); if (dd.substr(0,1) == "0" ) dd = " " + dd.substr(1,1); int mmName = atoi(date.substr(0,2).c_str()); string mm; switch ( mmName ) { case (1): { mm = "Jan"; break; } case (2): { mm = "Feb"; break; } case (3): { mm = "Mar"; break; } case (4): { mm = "Apr"; break; } case (5): { mm = "May"; break; } case (6): { mm = "Jun"; break; } case (7): { mm = "Jul"; break; } case (8): { mm = "Aug"; break; } case (9): { mm = "Sep"; break; } case (10): { mm = "Oct"; break; } case (11): { mm = "Nov"; break; } case (12): { mm = "Dec"; break; } default: { filelocation = ""; return; } } string findDate = mm + " " + dd; ifstream file (tempLogFile.c_str()); vector lines; if (file) { char line[400]; string buf; while (file.getline(line, 400)) { buf = line; string::size_type pos = buf.find(findDate,0); if (pos != string::npos) lines.push_back(buf); } unlink (tempLogFile.c_str()); } fileName = "/tmp/logsByDate"; ofstream newFile (fileName.c_str()); //create new file int fd = open(fileName.c_str(),O_RDWR|O_CREAT, 0664); copy(lines.begin(), lines.end(), ostream_iterator(newFile, "\n")); newFile.close(); close(fd); filelocation = fileName; } /******************************************************************** * * Get Log Config - Get Log Config data, which is the File IDs in the * Module syslog.conf file * ********************************************************************/ void Oam::getLogConfig(SystemLogConfigData& configdata ) { SystemModuleTypeConfig systemmoduletypeconfig; LogConfigData logconfigdata; try { Oam::getSystemConfig(systemmoduletypeconfig); } catch(...) { exceptionControl("getLogConfig", API_FAILURE); } for( unsigned int i = 0 ; i < systemmoduletypeconfig.moduletypeconfig.size(); i++) { if( systemmoduletypeconfig.moduletypeconfig[i].ModuleType.empty() ) //end of file break; if ( systemmoduletypeconfig.moduletypeconfig[i].ModuleCount == 0 ) continue; DeviceNetworkList::iterator pt = systemmoduletypeconfig.moduletypeconfig[i].ModuleNetworkList.begin(); for( ; pt != systemmoduletypeconfig.moduletypeconfig[i].ModuleNetworkList.end() ; pt++) { string moduleName = (*pt).DeviceName; int returnStatus = sendMsgToProcMgr(GETCONFIGLOG, moduleName, FORCEFUL, ACK_YES); logconfigdata.moduleName = moduleName; logconfigdata.configData = returnStatus; configdata.push_back(logconfigdata); } } } /****************************************************************************************** * @brief DisplayLockedTables * * purpose: Show the details of all the locks in tableLocks * Used when attempting to suspend or stop the * database, but there are table locks. * ******************************************************************************************/ void Oam::DisplayLockedTables(std::vector& tableLocks, BRM::DBRM* pDBRM) { cout << "The following tables are locked:" << endl; // Initial widths of columns to display. We pass thru the table // and see if we need to grow any of these. unsigned int lockIDColumnWidth = 6; // "LockID" unsigned int tableNameColumnWidth = 12; // "Name" unsigned int ownerColumnWidth = 7; // "Process" unsigned int pidColumnWidth = 3; // "PID" unsigned int sessionIDColumnWidth = 7; // "Session" unsigned int createTimeColumnWidth= 12; // "CreationTime" unsigned int dbrootColumnWidth = 7; // "DBRoots" unsigned int stateColumnWidth = 9; // "State" // Initialize System Catalog object used to get table name boost::shared_ptr systemCatalogPtr = execplan::CalpontSystemCatalog::makeCalpontSystemCatalog(0); std::string fullTblName; const char* tableState; // Make preliminary pass through the table locks in order to determine our // output column widths based on the data. Min column widths are based on // the width of the column heading (except for the 'state' column). uint64_t maxLockID = 0; uint32_t maxPID = 0; int32_t maxSessionID = 0; int32_t minSessionID = 0; std::vector createTimes; std::vector pms; char cTimeBuffer[64]; execplan::CalpontSystemCatalog::TableName tblName; for (unsigned idx=0; idx maxLockID) { maxLockID = tableLocks[idx].id; } try { tblName = systemCatalogPtr->tableName(tableLocks[idx].tableOID); } catch (...) { tblName.schema.clear(); tblName.table.clear(); } fullTblName = tblName.toString(); if (fullTblName.size() > tableNameColumnWidth) { tableNameColumnWidth = fullTblName.size(); } if (tableLocks[idx].ownerName.length() > ownerColumnWidth) { ownerColumnWidth = tableLocks[idx].ownerName.length(); } if (tableLocks[idx].ownerPID > maxPID) { maxPID = tableLocks[idx].ownerPID; } if (tableLocks[idx].ownerSessionID > maxSessionID) { maxSessionID = tableLocks[idx].ownerSessionID; } if (tableLocks[idx].ownerSessionID < minSessionID) { minSessionID = tableLocks[idx].ownerSessionID; } // Creation Time. // While we're at it, we save the time string off into a vector // so we can display it later without recalcing it. struct tm timeTM; localtime_r(&tableLocks[idx].creationTime,&timeTM); ctime_r(&tableLocks[idx].creationTime, cTimeBuffer); strftime(cTimeBuffer, 64, "%F %r:", &timeTM); cTimeBuffer[strlen(cTimeBuffer)-1] = '\0'; // strip trailing '\n' std::string cTimeStr( cTimeBuffer ); if (cTimeStr.length() > createTimeColumnWidth) { createTimeColumnWidth = cTimeStr.length(); } createTimes.push_back(cTimeStr); } tableNameColumnWidth += 1; ownerColumnWidth += 1; createTimeColumnWidth += 1; std::ostringstream idString; idString << maxLockID; if (idString.str().length() > lockIDColumnWidth) lockIDColumnWidth = idString.str().length(); lockIDColumnWidth += 1; std::ostringstream pidString; pidString << maxPID; if (pidString.str().length() > pidColumnWidth) pidColumnWidth = pidString.str().length(); pidColumnWidth += 1; const std::string sessionNoneStr("BulkLoad"); std::ostringstream sessionString; sessionString << maxSessionID; if (sessionString.str().length() > sessionIDColumnWidth) sessionIDColumnWidth = sessionString.str().length(); if ((minSessionID < 0) && (sessionNoneStr.length() > sessionIDColumnWidth)) sessionIDColumnWidth = sessionNoneStr.length(); sessionIDColumnWidth += 1; // write the column headers before the first entry cout.setf(ios::left, ios::adjustfield); cout << setw(lockIDColumnWidth) << "LockID" << setw(tableNameColumnWidth) << "Name" << setw(ownerColumnWidth) << "Process" << setw(pidColumnWidth) << "PID" << setw(sessionIDColumnWidth) << "Session" << setw(createTimeColumnWidth) << "CreationTime" << setw(stateColumnWidth) << "State" << setw(dbrootColumnWidth) << "DBRoots" << endl; for (unsigned idx=0; idxtableName(tableLocks[idx].tableOID); } catch(...) { tblName.schema.clear(); tblName.table.clear(); } fullTblName = tblName.toString(); cout << setw(lockIDColumnWidth) << tableLocks[idx].id << setw(tableNameColumnWidth) << fullTblName << setw(ownerColumnWidth) << tableLocks[idx].ownerName << setw(pidColumnWidth) << tableLocks[idx].ownerPID; // Log session ID, or "BulkLoad" if session is -1 if (tableLocks[idx].ownerSessionID < 0) cout << setw(sessionIDColumnWidth) << sessionNoneStr; else cout << setw(sessionIDColumnWidth) << tableLocks[idx].ownerSessionID; // Creation Time cout << setw(createTimeColumnWidth) << createTimes[idx]; // Processor State if (pDBRM && !pDBRM->checkOwner(tableLocks[idx].id)) { tableState = "Abandoned"; } else { tableState = ((tableLocks[idx].state==BRM::LOADING) ? "LOADING" : "CLEANUP"); } cout << setw(stateColumnWidth) << tableState; // PM List cout << setw(dbrootColumnWidth); for (unsigned k=0; k 0) cout << ','; cout << tableLocks[idx].dbrootList[k]; } cout << endl; } // end of loop through table locks } /****************************************************************************************** * @brief getCurrentTime * * purpose: get time/date in string format * ******************************************************************************************/ string Oam::getCurrentTime() { time_t cal; time (&cal); string stime; char ctime[26]; ctime_r (&cal, ctime); stime = ctime; // string stime = ctime_r (&cal); // strip off cr/lf stime = stime.substr (0,24); return stime; } /****************************************************************************************** * @brief Get Local DBRM ID * * purpose: Get Local DBRM ID for Module * ******************************************************************************************/ int Oam::getLocalDBRMID(const std::string moduleName) { string cmd = "touch " + CalpontConfigFile; (void)system(cmd.c_str()); string SECTION = "DBRM_Worker"; Config* sysConfig = Config::makeConfig(CalpontConfigFile.c_str()); int numWorker = atoi(sysConfig->getConfig("DBRM_Controller", "NumWorkers").c_str()); for (int workerID = 1; workerID < numWorker+1; workerID++) { string section = SECTION + itoa(workerID); if( sysConfig->getConfig(section, "Module") == moduleName ) return workerID; } // not found exceptionControl("getLocalDBRMID", API_INVALID_PARAMETER); return -1; } /****************************************************************************************** * @brief build empty set of System Tables * * purpose: build empty set of System Tables * ******************************************************************************************/ void Oam::buildSystemTables() { //determine active PM (DDLProc is ACTIVE) to send request to SystemProcessStatus systemprocessstatus; string PMmodule; int returnStatus = API_FAILURE; try { getProcessStatus(systemprocessstatus); for( unsigned int i = 0 ; i < systemprocessstatus.processstatus.size(); i++) { if ( systemprocessstatus.processstatus[i].ProcessName == "DDLProc" && systemprocessstatus.processstatus[i].ProcessOpState == oam::ACTIVE) { PMmodule = systemprocessstatus.processstatus[i].Module; // build and send msg returnStatus = sendMsgToProcMgr(BUILDSYSTEMTABLES, PMmodule, FORCEFUL, ACK_YES); } } } catch(...) { exceptionControl("buildSystemTables", API_FAILURE); } if (returnStatus != API_SUCCESS) exceptionControl("buildSystemTables", returnStatus); else return; } /****************************************************************************************** * @brief Get Network IP Address for Host Name * * purpose: Get Network IP Address for Host Name * ******************************************************************************************/ string Oam::getIPAddress(string hostName) { static uint32_t my_bind_addr; struct hostent *ent; string IPAddr = ""; ent=gethostbyname(hostName.c_str()); if (ent != 0) { my_bind_addr = (uint32_t) ((in_addr*)ent->h_addr_list[0])->s_addr; uint8_t split[4]; uint32_t ip = my_bind_addr; split[0] = (ip & 0xff000000) >> 24; split[1] = (ip & 0x00ff0000) >> 16; split[2] = (ip & 0x0000ff00) >> 8; split[3] = (ip & 0x000000ff); IPAddr = itoa(split[3]) + "." + itoa(split[2]) + "." +itoa(split[1]) + "." + itoa(split[0]); } return IPAddr; } /****************************************************************************************** * @brief Get System TOP Process CPU Users * * purpose: Get System TOP Process CPU Users * ******************************************************************************************/ void Oam::getTopProcessCpuUsers(int topNumber, SystemTopProcessCpuUsers& systemtopprocesscpuusers) { SystemModuleTypeConfig systemmoduletypeconfig; TopProcessCpuUsers Topprocesscpuusers; try { Oam::getSystemConfig(systemmoduletypeconfig); } catch(...) { exceptionControl("getTopProcessCpuUsers", API_FAILURE); } for( unsigned int i = 0 ; i < systemmoduletypeconfig.moduletypeconfig.size(); i++) { if( systemmoduletypeconfig.moduletypeconfig[i].ModuleType.empty() ) //end of file break; if ( systemmoduletypeconfig.moduletypeconfig[i].ModuleCount == 0 ) continue; DeviceNetworkList::iterator pt = systemmoduletypeconfig.moduletypeconfig[i].ModuleNetworkList.begin(); for( ; pt != systemmoduletypeconfig.moduletypeconfig[i].ModuleNetworkList.end() ; pt++) { string moduleName = (*pt).DeviceName; try { getTopProcessCpuUsers(moduleName, topNumber, Topprocesscpuusers); systemtopprocesscpuusers.topprocesscpuusers.push_back(Topprocesscpuusers); } catch (exception&) { } } } } /****************************************************************************************** * @brief Get Module TOP Process CPU Users * * purpose: Get SModule TOP Process CPU Users * ******************************************************************************************/ void Oam::getTopProcessCpuUsers(const std::string module, int topNumber, TopProcessCpuUsers& topprocesscpuusers) { ByteStream msg; ByteStream receivedMSG; ByteStream::byte count; string processName; ByteStream::quadbyte cpuUsage; ProcessCpuUser Processcpuuser; topprocesscpuusers.processcpuuser.clear(); // validate Module name if ( module.find("xm") != string::npos ) exceptionControl("getTopProcessCpuUsers", API_INVALID_PARAMETER); int returnStatus = validateModule(module); if (returnStatus != API_SUCCESS) exceptionControl("getTopProcessCpuUsers", returnStatus); // setup message msg << (ByteStream::byte) GET_PROC_CPU_USAGE; msg << (ByteStream::byte) topNumber; topprocesscpuusers.ModuleName = module; topprocesscpuusers.numberTopUsers = topNumber; try { //send the msg to Server Monitor MessageQueueClient servermonitor(module + "_ServerMonitor"); servermonitor.write(msg); // wait 10 seconds for ACK from Server Monitor struct timespec ts = { 30, 0 }; receivedMSG = servermonitor.read(&ts); if (receivedMSG.length() > 0) { receivedMSG >> count; for ( int i=0 ; i < count ; i++) { receivedMSG >> processName; receivedMSG >> cpuUsage; Processcpuuser.ProcessName = processName; Processcpuuser.CpuUsage = cpuUsage; topprocesscpuusers.processcpuuser.push_back(Processcpuuser); } } else// timeout exceptionControl("getTopProcessCpuUsers", API_TIMEOUT); // shutdown connection servermonitor.shutdown(); } catch(...) { exceptionControl("getTopProcessCpuUsers", API_FAILURE); } } /****************************************************************************************** * @brief get System CPU Usage * * purpose: get System CPU Usage * ******************************************************************************************/ void Oam::getSystemCpuUsage(SystemCpu& systemcpu) { SystemModuleTypeConfig systemmoduletypeconfig; ModuleCpu Modulecpu; try { Oam::getSystemConfig(systemmoduletypeconfig); } catch(...) { exceptionControl("getSystemCpuUsage", API_FAILURE); } for( unsigned int i = 0 ; i < systemmoduletypeconfig.moduletypeconfig.size(); i++) { if( systemmoduletypeconfig.moduletypeconfig[i].ModuleType.empty() ) //end of file break; if ( systemmoduletypeconfig.moduletypeconfig[i].ModuleCount == 0 ) continue; DeviceNetworkList::iterator pt = systemmoduletypeconfig.moduletypeconfig[i].ModuleNetworkList.begin(); for( ; pt != systemmoduletypeconfig.moduletypeconfig[i].ModuleNetworkList.end() ; pt++) { string moduleName = (*pt).DeviceName; try{ getModuleCpuUsage(moduleName, Modulecpu); systemcpu.modulecpu.push_back(Modulecpu); } catch (exception&) { } } } } /****************************************************************************************** * @brief get Module CPU Usage * * purpose: get Module CPU Usage * ******************************************************************************************/ void Oam::getModuleCpuUsage(const std::string module, ModuleCpu& modulecpu) { ByteStream msg; ByteStream receivedMSG; string processName; ByteStream::byte cpuUsage; // validate Module name if ( module.find("xm") != string::npos ) exceptionControl("getModuleCpuUsage", API_INVALID_PARAMETER); int returnStatus = validateModule(module); if (returnStatus != API_SUCCESS) exceptionControl("getModuleCpuUsage", returnStatus); // setup message msg << (ByteStream::byte) GET_MODULE_CPU_USAGE; modulecpu.ModuleName = module; try { //send the msg to Server Monitor MessageQueueClient servermonitor(module + "_ServerMonitor"); servermonitor.write(msg); // wait 30 seconds for ACK from Server Monitor struct timespec ts = { 30, 0 }; receivedMSG = servermonitor.read(&ts); if (receivedMSG.length() > 0) { receivedMSG >> cpuUsage; modulecpu.CpuUsage = cpuUsage; } else // timeout exceptionControl("getModuleCpuUsage", API_TIMEOUT); // shutdown connection servermonitor.shutdown(); } catch(...) { exceptionControl("getModuleCpuUsage", API_FAILURE); } } /****************************************************************************************** * @brief get System TOP Process Memory Users * * purpose: get System TOP Process Memory Users * ******************************************************************************************/ void Oam::getTopProcessMemoryUsers(int topNumber, SystemTopProcessMemoryUsers& systemtopprocessmemoryusers) { SystemModuleTypeConfig systemmoduletypeconfig; TopProcessMemoryUsers Topprocessmemoryusers; try { Oam::getSystemConfig(systemmoduletypeconfig); } catch(...) { exceptionControl("getTopProcessMemoryUsers", API_FAILURE); } for( unsigned int i = 0 ; i < systemmoduletypeconfig.moduletypeconfig.size(); i++) { if( systemmoduletypeconfig.moduletypeconfig[i].ModuleType.empty() ) //end of file break; if ( systemmoduletypeconfig.moduletypeconfig[i].ModuleCount == 0 ) continue; DeviceNetworkList::iterator pt = systemmoduletypeconfig.moduletypeconfig[i].ModuleNetworkList.begin(); for( ; pt != systemmoduletypeconfig.moduletypeconfig[i].ModuleNetworkList.end() ; pt++) { string moduleName = (*pt).DeviceName; try { getTopProcessMemoryUsers(moduleName, topNumber, Topprocessmemoryusers); systemtopprocessmemoryusers.topprocessmemoryusers.push_back(Topprocessmemoryusers); } catch (exception&) { } } } } /****************************************************************************************** * @brief get Module TOP Process Memory Users * * purpose: get Module TOP Process Memory Users * ******************************************************************************************/ void Oam::getTopProcessMemoryUsers(const std::string module, int topNumber, TopProcessMemoryUsers& topprocessmemoryusers) { ByteStream msg; ByteStream receivedMSG; ByteStream::byte count; string processName; ByteStream::quadbyte memoryUsed; ByteStream::byte memoryUsage; ProcessMemoryUser Processmemoryuser; topprocessmemoryusers.processmemoryuser.clear(); // validate Module name if ( module.find("xm") != string::npos ) exceptionControl("getTopProcessMemoryUsers", API_INVALID_PARAMETER); int returnStatus = validateModule(module); if (returnStatus != API_SUCCESS) exceptionControl("getTopProcessMemoryUsers", returnStatus); // setup message msg << (ByteStream::byte) GET_PROC_MEMORY_USAGE; msg << (ByteStream::byte) topNumber; topprocessmemoryusers.ModuleName = module; topprocessmemoryusers.numberTopUsers = topNumber; try { //send the msg to Server Monitor MessageQueueClient servermonitor(module + "_ServerMonitor"); servermonitor.write(msg); // wait 30 seconds for ACK from Server Monitor struct timespec ts = { 30, 0 }; receivedMSG = servermonitor.read(&ts); if (receivedMSG.length() > 0) { receivedMSG >> count; for ( int i=0 ; i < count ; i++) { receivedMSG >> processName; receivedMSG >> memoryUsed; receivedMSG >> memoryUsage; Processmemoryuser.ProcessName = processName; Processmemoryuser.MemoryUsed = memoryUsed; Processmemoryuser.MemoryUsage = memoryUsage; topprocessmemoryusers.processmemoryuser.push_back(Processmemoryuser); } } else // timeout exceptionControl("getTopProcessMemoryUsers", API_TIMEOUT); // shutdown connection servermonitor.shutdown(); } catch(...) { exceptionControl("getTopProcessMemoryUsers", API_FAILURE); } } /****************************************************************************************** * @brief get System Memory Usage * * purpose: get System Memory Usage * ******************************************************************************************/ void Oam::getSystemMemoryUsage(SystemMemory& systemmemory) { SystemModuleTypeConfig systemmoduletypeconfig; ModuleMemory Modulememory; try { Oam::getSystemConfig(systemmoduletypeconfig); } catch(...) { exceptionControl("getSystemMemoryUsage", API_FAILURE); } for( unsigned int i = 0 ; i < systemmoduletypeconfig.moduletypeconfig.size(); i++) { if( systemmoduletypeconfig.moduletypeconfig[i].ModuleType.empty() ) //end of file break; if ( systemmoduletypeconfig.moduletypeconfig[i].ModuleCount == 0 ) continue; DeviceNetworkList::iterator pt = systemmoduletypeconfig.moduletypeconfig[i].ModuleNetworkList.begin(); for( ; pt != systemmoduletypeconfig.moduletypeconfig[i].ModuleNetworkList.end() ; pt++) { string moduleName = (*pt).DeviceName; try { getModuleMemoryUsage(moduleName, Modulememory); systemmemory.modulememory.push_back(Modulememory); } catch (exception&) { } } } } /****************************************************************************************** * @brief get Module Memory Usage * * purpose: get Module Memory Usage * ******************************************************************************************/ void Oam::getModuleMemoryUsage(const std::string module, ModuleMemory& modulememory) { ByteStream msg; ByteStream receivedMSG; string processName; ByteStream::quadbyte mem_total; ByteStream::quadbyte mem_used; ByteStream::quadbyte cache; ByteStream::byte memoryUsagePercent; ByteStream::quadbyte swap_total; ByteStream::quadbyte swap_used; ByteStream::byte swapUsagePercent; // validate Module name if ( module.find("xm") != string::npos ) exceptionControl("getModuleMemoryUsage", API_INVALID_PARAMETER); // validate Module name int returnStatus = validateModule(module); if (returnStatus != API_SUCCESS) exceptionControl("getModuleMemoryUsage", returnStatus); // setup message msg << (ByteStream::byte) GET_MODULE_MEMORY_USAGE; modulememory.ModuleName = module; try { //send the msg to Server Monitor MessageQueueClient servermonitor(module + "_ServerMonitor"); servermonitor.write(msg); // wait 30 seconds for ACK from Server Monitor struct timespec ts = { 30, 0 }; receivedMSG = servermonitor.read(&ts); if (receivedMSG.length() > 0) { receivedMSG >> mem_total; receivedMSG >> mem_used; receivedMSG >> cache; receivedMSG >> memoryUsagePercent; receivedMSG >> swap_total; receivedMSG >> swap_used; receivedMSG >> swapUsagePercent; modulememory.MemoryTotal = mem_total; modulememory.MemoryUsed = mem_used; modulememory.cache = cache; modulememory.MemoryUsage = memoryUsagePercent; modulememory.SwapTotal = swap_total; modulememory.SwapUsed = swap_used; modulememory.SwapUsage = swapUsagePercent; } else // timeout exceptionControl("getModuleMemoryUsage", API_TIMEOUT); // shutdown connection servermonitor.shutdown(); } catch(...) { exceptionControl("getModuleMemoryUsage", API_FAILURE); } } /****************************************************************************************** * @brief get System Disk Usage * * purpose: get System Disk Usage * ******************************************************************************************/ void Oam::getSystemDiskUsage(SystemDisk& systemdisk) { SystemModuleTypeConfig systemmoduletypeconfig; ModuleDisk Moduledisk; try { Oam::getSystemConfig(systemmoduletypeconfig); } catch(...) { exceptionControl("getSystemMemoryUsage", API_FAILURE); } for( unsigned int i = 0 ; i < systemmoduletypeconfig.moduletypeconfig.size(); i++) { if( systemmoduletypeconfig.moduletypeconfig[i].ModuleType.empty() ) //end of file break; if ( systemmoduletypeconfig.moduletypeconfig[i].ModuleCount == 0 ) continue; DeviceNetworkList::iterator pt = systemmoduletypeconfig.moduletypeconfig[i].ModuleNetworkList.begin(); for( ; pt != systemmoduletypeconfig.moduletypeconfig[i].ModuleNetworkList.end() ; pt++) { string moduleName = (*pt).DeviceName; try { getModuleDiskUsage(moduleName, Moduledisk); systemdisk.moduledisk.push_back(Moduledisk); } catch (exception&) { } } } } /****************************************************************************************** * @brief get Module Disk Usage * * purpose: get Module Disk Usage * ******************************************************************************************/ void Oam::getModuleDiskUsage(const std::string module, ModuleDisk& moduledisk) { ByteStream msg; ByteStream receivedMSG; string processName; DiskUsage Diskusage; moduledisk.diskusage.clear(); // validate Module name if ( module.find("xm") != string::npos ) exceptionControl("getModuleDiskUsage", API_INVALID_PARAMETER); // validate Module name int returnStatus = validateModule(module); if (returnStatus != API_SUCCESS) exceptionControl("getModuleDiskUsage", returnStatus); ByteStream::byte entries; string deviceName; uint64_t totalBlocks; uint64_t usedBlocks; uint8_t diskUsage; // setup message msg << (ByteStream::byte) GET_MODULE_DISK_USAGE; moduledisk.ModuleName = module; try { //send the msg to Server Monitor MessageQueueClient servermonitor(module + "_ServerMonitor"); servermonitor.write(msg); // wait 30 seconds for ACK from Server Monitor struct timespec ts = { 30, 0 }; receivedMSG = servermonitor.read(&ts); if (receivedMSG.length() > 0) { receivedMSG >> entries; for ( int i=0 ; i < entries ; i++) { receivedMSG >> deviceName; receivedMSG >> totalBlocks; receivedMSG >> usedBlocks; receivedMSG >> diskUsage; Diskusage.DeviceName = deviceName; Diskusage.TotalBlocks = totalBlocks; Diskusage.UsedBlocks = usedBlocks; Diskusage.DiskUsage = diskUsage; moduledisk.diskusage.push_back(Diskusage); } } else // timeout exceptionControl("getModuleDiskUsage", API_TIMEOUT); // shutdown connection servermonitor.shutdown(); } catch(...) { exceptionControl("getModuleDiskUsage", API_FAILURE); } } /****************************************************************************************** * @brief get Active SQL Statements * * purpose: get Active SQL Statements * ******************************************************************************************/ void Oam::getActiveSQLStatements(ActiveSqlStatements& activesqlstatements) { SystemModuleTypeConfig systemmoduletypeconfig; ByteStream msg; ByteStream receivedMSG; ByteStream::byte entries; ByteStream::byte retStatus; try { Oam::getSystemConfig(systemmoduletypeconfig); // get Server Type Install ID int serverTypeInstall = oam::INSTALL_NORMAL; oamModuleInfo_t st; st = getModuleInfo(); serverTypeInstall = boost::get<5>(st); string sendModule; switch (serverTypeInstall) { case oam::INSTALL_NORMAL: case oam::INSTALL_COMBINE_DM_UM: sendModule = "um"; break; case oam::INSTALL_COMBINE_PM_UM: case oam::INSTALL_COMBINE_DM_UM_PM: sendModule = "pm"; break; } //send request to modules for ( unsigned int i = 0 ; i < systemmoduletypeconfig.moduletypeconfig.size(); i++) { if ( systemmoduletypeconfig.moduletypeconfig[i].ModuleType.empty() ) //end of file break; if ( systemmoduletypeconfig.moduletypeconfig[i].ModuleType == sendModule ) { if ( systemmoduletypeconfig.moduletypeconfig[i].ModuleCount == 0 ) break; DeviceNetworkList::iterator pt = systemmoduletypeconfig.moduletypeconfig[i].ModuleNetworkList.begin(); for ( ; pt != systemmoduletypeconfig.moduletypeconfig[i].ModuleNetworkList.end() ; pt++) { string module = (*pt).DeviceName; // setup message msg << (ByteStream::byte) GET_ACTIVE_SQL_QUERY; //send the msg to Server Monitor MessageQueueClient servermonitor(module + "_ServerMonitor"); servermonitor.write(msg); // wait 30 seconds for ACK from Server Monitor struct timespec ts = { 30, 0 }; receivedMSG = servermonitor.read(&ts); if (receivedMSG.length() > 0) { receivedMSG >> retStatus; if ( retStatus != oam::API_SUCCESS ) { // shutdown connection servermonitor.shutdown(); exceptionControl("getActiveSQLStatements", (int) retStatus); } receivedMSG >> entries; ActiveSqlStatement activeSqlStatement; for (int i = 0; i < entries; i++) { receivedMSG >> activeSqlStatement.sqlstatement; receivedMSG >> activeSqlStatement.starttime; receivedMSG >> activeSqlStatement.sessionid; activesqlstatements.push_back(activeSqlStatement); } } else { // timeout exceptionControl("getActiveSQLStatements", API_TIMEOUT); } // shutdown connection servermonitor.shutdown(); } break; } } } catch (std::exception& ex) { exceptionControl("getActiveSQLStatements", API_FAILURE, ex.what()); } catch (...) { exceptionControl("getActiveSQLStatements", API_FAILURE); } } /******************************************************************** * * IsValidIP - Validate IP Address format * ********************************************************************/ bool Oam::isValidIP(const std::string ipAddress) { int currentPos = 0; for ( int i = 0 ; i < 4 ; i++) { string::size_type pos = ipAddress.find(".",currentPos); if (pos != string::npos) { if ( (pos - currentPos) > 3 || (pos - currentPos) <= 0) return false; currentPos = pos+1; } else { if ( i < 3 ) return false; if ( (ipAddress.size() - currentPos) > 3 || (ipAddress.size() - currentPos) <= 0) return false; else return true; } } return false; } /******************************************************************** * * incrementIPAddress - Increment IP Address * ********************************************************************/ std::string Oam::incrementIPAddress(const std::string ipAddress) { string newipAddress = ipAddress; string::size_type pos = ipAddress.rfind(".",80); if (pos != string::npos) { string last = ipAddress.substr(pos+1,80); int Ilast = atoi(last.c_str()); Ilast++; if ( Ilast > 255 ) { writeLog("incrementIPAddress: new address invalid, larger than 255", LOG_TYPE_ERROR ); exceptionControl("incrementIPAddress", API_FAILURE); } last = itoa(Ilast); newipAddress = ipAddress.substr(0,pos+1); newipAddress = newipAddress + last; } else { writeLog("incrementIPAddress: passed address invalid: " + ipAddress, LOG_TYPE_ERROR ); exceptionControl("incrementIPAddress", API_FAILURE); } return newipAddress; } /******************************************************************** * * checkLogStatus - Check for a phrase in a log file and return status * ********************************************************************/ bool Oam::checkLogStatus(std::string fileName, std::string phrase ) { ifstream file (fileName.c_str()); if (!file.is_open()) { return false; } string buf; while (getline(file, buf)) { string::size_type pos = buf.find(phrase,0); if (pos != string::npos) //found phrase return true; } if (file.bad()) { return false; } file.close(); return false; } /******************************************************************** * * fixRSAkey - Fix RSA key * ********************************************************************/ void Oam::fixRSAkey(std::string logFile) { ifstream file (logFile.c_str()); char line[400]; string buf; while (file.getline(line, 400)) { buf = line; string::size_type pos = buf.find("Offending",0); if (pos != string::npos) { // line ID pos = buf.find(":",0); string lineID = buf.substr(pos+1,80); //remove non alphanumber characters for (size_t i = 0; i < lineID.length();) { if (!isdigit(lineID[i])) lineID.erase(i, 1); else i++; } //get user string USER = "root"; char* p= getenv("USER"); if (p && *p) USER = p; string userDir = USER; if ( USER != "root") userDir = "home/" + USER; string cmd = "sed '" + lineID + "d' /" + userDir + "/.ssh/known_hosts > /" + userDir + "/.ssh/known_hosts"; cout << cmd << endl; system(cmd.c_str()); return; } } file.close(); return; } /******************************************************************** * * getWritablePM - Get PM with read-write mount * ********************************************************************/ string Oam::getWritablePM() { string moduleName; oamModuleInfo_t st; try { st = getModuleInfo(); moduleName = boost::get<3>(st); if ( moduleName == oam::UnassignedName ) return ""; return moduleName; } catch (...) { exceptionControl("getWritablePM", API_FAILURE); } return ""; } /******************************************************************** * * getHotStandbyPM * ********************************************************************/ string Oam::getHotStandbyPM() { string fileName = InstallDir + "/local/hotStandbyPM"; string module; ifstream oldFile (fileName.c_str()); if (!oldFile) return module; char line[400]; while (oldFile.getline(line, 400)) { module = line; break; } oldFile.close(); return module; } /******************************************************************** * * setHotStandbyPM * ********************************************************************/ void Oam::setHotStandbyPM(std::string moduleName) { string fileName = InstallDir + "/local/hotStandbyPM"; unlink (fileName.c_str()); if ( moduleName.empty() || moduleName == " " ) return; ofstream newFile (fileName.c_str()); string cmd = "echo " + moduleName + " > " + fileName; (void)system(cmd.c_str()); newFile.close(); return; } /******************************************************************** * * Distribute Calpont Configure File * ********************************************************************/ void Oam::distributeConfigFile(std::string name, std::string file) { ACK_FLAG ackflag = oam::ACK_YES; if ( name == "system" ) ackflag = oam::ACK_NO; // build and send msg int returnStatus = sendMsgToProcMgr(DISTRIBUTECONFIG, name, oam::FORCEFUL, ackflag, file, "", 30); if (returnStatus != API_SUCCESS) exceptionControl("distributeConfigFile", returnStatus); return; } /******************************************************************** * * Switch Parent OAM Module * ********************************************************************/ bool Oam::switchParentOAMModule(std::string moduleName, GRACEFUL_FLAG gracefulflag) { if (!checkSystemRunning()) exceptionControl("switchParentOAMModule", API_FAILURE); int returnStatus; // We assume that moduleName is a valid pm // check if current Active Parent Process-Manager is down and running on Standby Module // if so, send signal to Standby Process-Manager to start failover Config* sysConfig = Config::makeConfig(); string IPAddr = sysConfig->getConfig("ProcStatusControl", "IPAddr"); string cmdLine = "ping "; string cmdOption = " -w 1 >> /dev/null"; string cmd = cmdLine + IPAddr + cmdOption; if ( system(cmd.c_str()) != 0 ) { //ping failure try{ string standbyOAMModule; getSystemConfig("StandbyOAMModuleName", standbyOAMModule); oamModuleInfo_t t = Oam::getModuleInfo(); string localModule = boost::get<0>(t); if (standbyOAMModule == localModule ) // send SIGUSR1 system("pkill -SIGUSR1 ProcMgr"); } catch(...) { exceptionControl("switchParentOAMModule", API_FAILURE); } return false; } // only make call if system is ACTIVE and module switching to is ACTIVE SystemStatus systemstatus; try { getSystemStatus(systemstatus); } catch (exception& ) {} if (systemstatus.SystemOpState == oam::MAN_INIT || systemstatus.SystemOpState == oam::AUTO_INIT || systemstatus.SystemOpState == oam::UP || systemstatus.SystemOpState == oam::BUSY_INIT || systemstatus.SystemOpState == oam::UP ) exceptionControl("switchParentOAMModule", API_INVALID_STATE); if (systemstatus.SystemOpState == oam::ACTIVE || systemstatus.SystemOpState == oam::FAILED ) { // build and send msg to stop system returnStatus = sendMsgToProcMgrWithStatus(STOPSYSTEM, "OAM Module switched", gracefulflag, ACK_YES); if ( returnStatus != API_SUCCESS ) exceptionControl("stopSystem", returnStatus); } // build and send msg to switch configuration cout << endl << " Switch Active Parent OAM to Module '" << moduleName << "', please wait..."; returnStatus = sendMsgToProcMgr(SWITCHOAMPARENT, moduleName, FORCEFUL, ACK_YES); if (returnStatus != API_SUCCESS) exceptionControl("switchParentOAMModule", returnStatus); if (systemstatus.SystemOpState == oam::ACTIVE || systemstatus.SystemOpState == oam::FAILED ) { //give time for ProcMon/ProcMgr to get fully active on new pm sleep(10); // build and send msg to restart system returnStatus = sendMsgToProcMgr(RESTARTSYSTEM, "", FORCEFUL, ACK_YES); if (returnStatus != API_SUCCESS) exceptionControl("startSystem", returnStatus); return true; // Caller should wait for system to come up. } return false; // Caller should not wait for system to come up. } /******************************************************************** * * Get Storage Config Data * ********************************************************************/ systemStorageInfo_t Oam::getStorageConfig() { DeviceDBRootList deviceDBRootList; std::string storageType = ""; std::string UMstorageType = ""; int SystemDBRootCount = 0; try { getSystemConfig("DBRootStorageType", storageType); } catch(...) { exceptionControl("getStorageConfig", oam::API_FAILURE); } try { getSystemConfig("UMStorageType", UMstorageType); } catch(...) { exceptionControl("getStorageConfig", oam::API_FAILURE); } try { getSystemConfig("DBRootCount", SystemDBRootCount); } catch(...) { exceptionControl("getStorageConfig", oam::API_FAILURE); } try { SystemModuleTypeConfig systemmoduletypeconfig; getSystemConfig(systemmoduletypeconfig); for( unsigned int i = 0 ; i < systemmoduletypeconfig.moduletypeconfig.size(); i++) { if( systemmoduletypeconfig.moduletypeconfig[i].ModuleType.empty() ) // end of list break; int moduleCount = systemmoduletypeconfig.moduletypeconfig[i].ModuleCount; string moduletype = systemmoduletypeconfig.moduletypeconfig[i].ModuleType; if ( moduleCount > 0 && moduletype == "pm") { deviceDBRootList = systemmoduletypeconfig.moduletypeconfig[i].ModuleDBRootList; return boost::make_tuple(storageType, SystemDBRootCount, deviceDBRootList, UMstorageType); } } } catch(...) { exceptionControl("getStorageConfig", oam::API_FAILURE); } return boost::make_tuple(storageType, SystemDBRootCount, deviceDBRootList, UMstorageType); } /******************************************************************** * * Get PM - DBRoot Config data * ********************************************************************/ void Oam::getPmDbrootConfig(const int pmid, DBRootConfigList& dbrootconfiglist) { string module = "pm" + itoa(pmid); // validate Module name int returnStatus = validateModule(module); if (returnStatus != API_SUCCESS) exceptionControl("getPmDbrootConfig", returnStatus); try { ModuleConfig moduleconfig; getSystemConfig(module, moduleconfig); DBRootConfigList::iterator pt1 = moduleconfig.dbrootConfigList.begin(); for( ; pt1 != moduleconfig.dbrootConfigList.end() ; pt1++) { dbrootconfiglist.push_back((*pt1)); } } catch (...) { // dbrootid not found, return with error exceptionControl("getPmDbrootConfig", API_INVALID_PARAMETER); } } /******************************************************************** * * Get DBRoot - PM Config data * ********************************************************************/ void Oam::getDbrootPmConfig(const int dbrootid, int& pmid) { SystemModuleTypeConfig systemmoduletypeconfig; ModuleTypeConfig moduletypeconfig; ModuleConfig moduleconfig; try { getSystemConfig(systemmoduletypeconfig); for( unsigned int i = 0 ; i < systemmoduletypeconfig.moduletypeconfig.size(); i++) { if( systemmoduletypeconfig.moduletypeconfig[i].ModuleType.empty() ) // end of list break; int moduleCount = systemmoduletypeconfig.moduletypeconfig[i].ModuleCount; string moduletype = systemmoduletypeconfig.moduletypeconfig[i].ModuleType; if ( moduleCount > 0 && moduletype == "pm") { DeviceDBRootList::iterator pt = systemmoduletypeconfig.moduletypeconfig[i].ModuleDBRootList.begin(); for( ; pt != systemmoduletypeconfig.moduletypeconfig[i].ModuleDBRootList.end() ; pt++) { DBRootConfigList::iterator pt1 = (*pt).dbrootConfigList.begin(); for( ; pt1 != (*pt).dbrootConfigList.end() ; pt1++) { if (*pt1 == dbrootid) { pmid = (*pt).DeviceID; return; } } } } } // dbrootid not found, return with error exceptionControl("getDbrootPmConfig", API_INVALID_PARAMETER); } catch (exception& ) {} // dbrootid not found, return with error exceptionControl("getDbrootPmConfig", API_INVALID_PARAMETER); } /******************************************************************** * * Get DBRoot - PM Config data * ********************************************************************/ void Oam::getDbrootPmConfig(const int dbrootid, std::string& pmid) { try { int PMid; getDbrootPmConfig(dbrootid, PMid); pmid = itoa(PMid); return; } catch (exception& ) {} // dbrootid not found, return with error exceptionControl("getDbrootPmConfig", API_INVALID_PARAMETER); } /******************************************************************** * * Get System DBRoot Config data * ********************************************************************/ void Oam::getSystemDbrootConfig(DBRootConfigList& dbrootconfiglist) { SystemModuleTypeConfig systemmoduletypeconfig; ModuleTypeConfig moduletypeconfig; ModuleConfig moduleconfig; try { getSystemConfig(systemmoduletypeconfig); for( unsigned int i = 0 ; i < systemmoduletypeconfig.moduletypeconfig.size(); i++) { if( systemmoduletypeconfig.moduletypeconfig[i].ModuleType.empty() ) // end of list break; int moduleCount = systemmoduletypeconfig.moduletypeconfig[i].ModuleCount; string moduletype = systemmoduletypeconfig.moduletypeconfig[i].ModuleType; if ( moduleCount > 0 && moduletype == "pm") { DeviceDBRootList::iterator pt = systemmoduletypeconfig.moduletypeconfig[i].ModuleDBRootList.begin(); for( ; pt != systemmoduletypeconfig.moduletypeconfig[i].ModuleDBRootList.end() ; pt++) { DBRootConfigList::iterator pt1 = (*pt).dbrootConfigList.begin(); for( ; pt1 != (*pt).dbrootConfigList.end() ; pt1++) { dbrootconfiglist.push_back(*pt1); } } } } sort ( dbrootconfiglist.begin(), dbrootconfiglist.end() ); } catch (...) { // dbrootid not found, return with error exceptionControl("getSystemDbrootConfig", API_INVALID_PARAMETER); } return; } /******************************************************************** * * Set PM - DBRoot Config data * ********************************************************************/ void Oam::setPmDbrootConfig(const int pmid, DBRootConfigList& dbrootconfiglist) { ModuleConfig moduleconfig; string module = "pm" + itoa(pmid); try { getSystemConfig(module, moduleconfig); moduleconfig.dbrootConfigList = dbrootconfiglist; try { setSystemConfig(module, moduleconfig); return; } catch(...) { // writeLog("ERROR: setSystemConfig api failure for " + module , LOG_TYPE_ERROR ); // cout << endl << "ERROR: setSystemConfig api failure for " + module << endl; exceptionControl("getSystemDbrootConfig", API_INVALID_PARAMETER); } } catch(...) { // writeLog("ERROR: getSystemConfig api failure for " + module , LOG_TYPE_ERROR ); // cout << endl << "ERROR: getSystemConfig api failure for " + module << endl; exceptionControl("getSystemDbrootConfig", API_INVALID_PARAMETER); } //set System DBRoot Count try { setSystemDBrootCount(); } catch (exception& ) { cout << endl << "**** setSystemDBrootCount Failed" << endl; exceptionControl("assignPmDbrootConfig", API_FAILURE); } } /******************************************************************** * * Manual Move PM - DBRoot data * ********************************************************************/ void Oam::manualMovePmDbroot(std::string residePM, std::string dbrootIDs, std::string toPM) { typedef std::vector dbrootList; dbrootList dbrootlist; dbrootList tempdbrootlist; writeLog("manualMovePmDbroot: " + dbrootIDs + " from " + residePM + " to " + toPM, LOG_TYPE_DEBUG ); string DataRedundancyConfig = "n"; try { getSystemConfig( "DataRedundancyConfig", DataRedundancyConfig); } catch(...) { DataRedundancyConfig = "n"; } boost::char_separator sep(", "); boost::tokenizer< boost::char_separator > tokens(dbrootIDs, sep); for ( boost::tokenizer< boost::char_separator >::iterator it = tokens.begin(); it != tokens.end(); ++it) { //if gluster, check if there are copies on the to-pm if ( DataRedundancyConfig == "y") { string pmList = ""; try { string errmsg; int ret = glusterctl(oam::GLUSTER_WHOHAS, *it, pmList, errmsg); if ( ret != 0 ) { writeLog("ERROR: glusterctl failure getting pm list for dbroot " + *it + " , error: " + errmsg, LOG_TYPE_ERROR ); exceptionControl("autoMovePmDbroot", API_INVALID_PARAMETER); } } catch (exception& ) { writeLog("ERROR: glusterctl failure getting pm list for dbroot " + *it, LOG_TYPE_ERROR ); exceptionControl("autoMovePmDbroot", API_INVALID_PARAMETER); } catch (...) { writeLog("ERROR: glusterctl failure getting pm list for dbroot " + *it, LOG_TYPE_ERROR ); exceptionControl("autoMovePmDbroot", API_INVALID_PARAMETER); } boost::char_separator sep(" "); boost::tokenizer< boost::char_separator > tokens(pmList, sep); for ( boost::tokenizer< boost::char_separator >::iterator it1 = tokens.begin(); it1 != tokens.end(); ++it1) { string pmModule = "pm" + *it1; if ( pmModule == toPM ) { dbrootlist.push_back(*it); tempdbrootlist.push_back(*it); } } if ( dbrootlist.size() == 0 ) { writeLog("ERROR: No DBROOTs to move to-pm, no gluster copies", LOG_TYPE_ERROR ); exceptionControl("autoMovePmDbroot", API_INVALID_PARAMETER); } } else { dbrootlist.push_back(*it); tempdbrootlist.push_back(*it); } } string residePMID = residePM.substr(MAX_MODULE_TYPE_SIZE,MAX_MODULE_ID_SIZE);; string toPMID = toPM.substr(MAX_MODULE_TYPE_SIZE,MAX_MODULE_ID_SIZE);; //get dbroots ids for reside PM DBRootConfigList residedbrootConfigList; try { getPmDbrootConfig(atoi(residePMID.c_str()), residedbrootConfigList); DBRootConfigList::iterator pt = residedbrootConfigList.begin(); for( ; pt != residedbrootConfigList.end() ; pt++) { //check if entered dbroot id is in residing pm dbrootList::iterator pt1 = tempdbrootlist.begin(); for( ; pt1 != tempdbrootlist.end() ; pt1++) { if ( itoa(*pt) == *pt1 ) { tempdbrootlist.erase(pt1); break; } } } if ( !tempdbrootlist.empty() ) { // there is a entered dbroot id not in the residing pm writeLog("ERROR: dbroot IDs not assigned to " + residePM , LOG_TYPE_ERROR ); cout << endl << "ERROR: these dbroot IDs not assigned to '" << residePM << "' : "; dbrootList::iterator pt1 = tempdbrootlist.begin(); for( ; pt1 != tempdbrootlist.end() ;) { cout << *pt1; pt1++; if (pt1 != tempdbrootlist.end()) cout << ", "; } cout << endl << endl; exceptionControl("manualMovePmDbroot", API_FAILURE); } } catch (exception& ) { writeLog("ERROR: getPmDbrootConfig api failure for pm" + residePMID , LOG_TYPE_ERROR ); cout << endl << "ERROR: getPmDbrootConfig api failure for pm" + residePMID << endl; exceptionControl("manualMovePmDbroot", API_FAILURE); } //get dbroots ids for reside PM DBRootConfigList todbrootConfigList; try { getPmDbrootConfig(atoi(toPMID.c_str()), todbrootConfigList); } catch (exception& ) { writeLog("ERROR: getPmDbrootConfig api failure for pm" + toPMID , LOG_TYPE_ERROR ); cout << endl << "ERROR: getPmDbrootConfig api failure for pm" + toPMID << endl; exceptionControl("manualMovePmDbroot", API_FAILURE); } //remove entered dbroot IDs from reside PM list dbrootList::iterator pt1 = dbrootlist.begin(); for( ; pt1 != dbrootlist.end() ; pt1++) { DBRootConfigList::iterator pt2 = residedbrootConfigList.begin(); for( ; pt2 != residedbrootConfigList.end() ; pt2++) { if ( itoa(*pt2) == *pt1 ) { dbrootList dbroot1; dbroot1.push_back(*pt1); //send msg to unmount dbroot if module is not offline int opState; bool degraded; try { getModuleStatus(residePM, opState, degraded); } catch(...) {} if (opState != oam::AUTO_OFFLINE || opState != oam::AUTO_DISABLED) { // bool unmountPass = true; try { mountDBRoot(dbroot1, false); } catch (exception& ) { writeLog("ERROR: dbroot failed to unmount", LOG_TYPE_ERROR ); cout << endl << "ERROR: umountDBRoot api failure" << endl; exceptionControl("manualMovePmDbroot", API_FAILURE); // unmountPass = false; } // if ( !unmountPass) { // dbrootlist.erase(pt1); // break; // } } //check for amazon moving required try { amazonReattach(toPM, dbroot1); } catch (exception& ) { writeLog("ERROR: amazonReattach api failure", LOG_TYPE_ERROR ); cout << endl << "ERROR: amazonReattach api failure" << endl; exceptionControl("manualMovePmDbroot", API_FAILURE); } //if Gluster, do the assign command if ( DataRedundancyConfig == "y") { try { string errmsg; int ret = glusterctl(oam::GLUSTER_ASSIGN, *pt1, toPM, errmsg); if ( ret != 0 ) { cerr << "FAILURE: Error assigning gluster dbroot# " + *pt1 + " to pm" + toPMID + ", error: " + errmsg << endl; exceptionControl("manualMovePmDbroot", API_FAILURE); } } catch (exception& e) { cout << endl << "**** glusterctl API exception: " << e.what() << endl; cerr << "FAILURE: Error assigning gluster dbroot# " + *pt1 + " to pm" + toPMID << endl; exceptionControl("manualMovePmDbroot", API_FAILURE); } catch (...) { cout << endl << "**** glusterctl API exception: UNKNOWN" << endl; cerr << "FAILURE: Error assigning gluster dbroot# " + *pt1 + " to pm" + toPMID << endl; exceptionControl("manualMovePmDbroot", API_FAILURE); } } todbrootConfigList.push_back(*pt2); residedbrootConfigList.erase(pt2); break; } } } //set the 2 pms dbroot config try { setPmDbrootConfig(atoi(residePMID.c_str()), residedbrootConfigList); } catch (exception& ) { writeLog("ERROR: setPmDbrootConfig api failure for pm" + residePMID , LOG_TYPE_ERROR ); cout << endl << "ERROR: setPmDbrootConfig api failure for pm" + residePMID << endl; exceptionControl("manualMovePmDbroot", API_FAILURE); } try { setPmDbrootConfig(atoi(toPMID.c_str()), todbrootConfigList); } catch (exception& ) { writeLog("ERROR: setPmDbrootConfig api failure for pm" + toPMID , LOG_TYPE_ERROR ); cout << endl << "ERROR: setPmDbrootConfig api failure for pm" + toPMID << endl; exceptionControl("manualMovePmDbroot", API_FAILURE); } //send msg to mount dbroot try { mountDBRoot(dbrootlist); } catch (exception& ) { writeLog("ERROR: mountDBRoot api failure", LOG_TYPE_DEBUG ); cout << endl << "ERROR: mountDBRoot api failure" << endl; } //get updated Columnstore.xml distributed distributeConfigFile("system"); return; } bool comparex(const PmDBRootCount_s& x, const PmDBRootCount_s& y) { return x.count < y.count; } /******************************************************************** * * Auto Move PM - DBRoot data * ********************************************************************/ bool Oam::autoMovePmDbroot(std::string residePM) { writeLog("autoMovePmDbroot: " + residePM, LOG_TYPE_DEBUG ); string DBRootStorageType; try { getSystemConfig("DBRootStorageType", DBRootStorageType); } catch(...) {} string DataRedundancyConfig = "n"; try { getSystemConfig( "DataRedundancyConfig", DataRedundancyConfig); } catch(...) { DataRedundancyConfig = "n"; } if (DBRootStorageType == "internal" && DataRedundancyConfig == "n") return 1; // get current Module name string localModuleName; oamModuleInfo_t st; try { st = getModuleInfo(); localModuleName = boost::get<0>(st); } catch (...) {} int localPMID = atoi(localModuleName.substr(MAX_MODULE_TYPE_SIZE,MAX_MODULE_ID_SIZE).c_str()); string localPM = localModuleName; int residePMID = atoi(residePM.substr(MAX_MODULE_TYPE_SIZE,MAX_MODULE_ID_SIZE).c_str()); //get dbroot ids for reside PM DBRootConfigList residedbrootConfigList; try { getPmDbrootConfig(residePMID, residedbrootConfigList); if ( residedbrootConfigList.empty() ) { writeLog("ERROR: residedbrootConfigList empty", LOG_TYPE_ERROR ); exceptionControl("autoMovePmDbroot", API_INVALID_PARAMETER); } } catch (...) { writeLog("ERROR: getPmDbrootConfig failure", LOG_TYPE_ERROR ); exceptionControl("autoMovePmDbroot", API_INVALID_PARAMETER); } //get dbroot id for other PMs systemStorageInfo_t t; DeviceDBRootList moduledbrootlist; try { t = getStorageConfig(); moduledbrootlist = boost::get<2>(t); } catch (exception& ) { writeLog("ERROR: getStorageConfig failure", LOG_TYPE_ERROR ); exceptionControl("autoMovePmDbroot", API_FAILURE); } // get list of dbroot count for each pm typedef std::vector PMdbrootList; PMdbrootList pmdbrootList; PmDBRootCount_s pmdbroot; DeviceDBRootList::iterator pt = moduledbrootlist.begin(); for( ; pt != moduledbrootlist.end() ; pt++) { // only put pms with dbroots assigned, if 0 then that pm is disabled if ( (*pt).dbrootConfigList.size() > 0 ) { pmdbroot.pmID = (*pt).DeviceID; pmdbroot.count = (*pt).dbrootConfigList.size(); pmdbrootList.push_back(pmdbroot); } } sort ( pmdbrootList.begin(), pmdbrootList.end(), comparex ); //clear reside IDs DBRootConfigList clearresidedbrootConfigList; try { setPmDbrootConfig(residePMID, clearresidedbrootConfigList); } catch (...) { writeLog("ERROR: setPmDbrootConfig failure - clear reside ID", LOG_TYPE_ERROR ); exceptionControl("autoMovePmDbroot", API_FAILURE); } //distribute dbroot IDs to other PMs starting with lowest count bool exceptionFailure = false; bool dbroot1 = false; DBRootConfigList::iterator pt2 = residedbrootConfigList.begin(); for( ; pt2 != residedbrootConfigList.end() ; ) { int dbrootID = *pt2; //dbroot #1 always get moved to local module if ( dbrootID == 1 ) { dbroot1 = true; //get dbroot ids for PM DBRootConfigList todbrootConfigList; try { getPmDbrootConfig(localPMID, todbrootConfigList); } catch (...) { writeLog("ERROR: getPmDbrootConfig failure", LOG_TYPE_ERROR ); exceptionControl("autoMovePmDbroot", API_INVALID_PARAMETER); } //get the first dbroot assigned to this pm, so it can be auto unmoved later instead of dbroot1 DBRootConfigList::iterator pt = todbrootConfigList.begin(); int subDBRootID = *pt; todbrootConfigList.push_back(dbrootID); try { setPmDbrootConfig(localPMID, todbrootConfigList); writeLog("autoMovePmDbroot/setPmDbrootConfig : " + localModuleName + ":" + itoa(dbrootID), LOG_TYPE_DEBUG); sleep(5); //send msg to toPM to mount dbroot try { typedef std::vector dbrootList; dbrootList dbrootlist; dbrootlist.push_back(itoa(dbrootID)); mountDBRoot(dbrootlist); } catch (exception& ) { writeLog("ERROR: mountDBRoot api failure", LOG_TYPE_DEBUG ); cout << endl << "ERROR: mountDBRoot api failure" << endl; } } catch (...) { writeLog("ERROR: setPmDbrootConfig failure", LOG_TYPE_ERROR ); exceptionControl("autoMovePmDbroot", API_FAILURE); } if ( DataRedundancyConfig == "y") { try { string errmsg; int ret = glusterctl(oam::GLUSTER_ASSIGN, itoa(dbrootID), localPM, errmsg); if ( ret != 0 ) { writeLog("FAILURE: Error assigning gluster dbroot# " + itoa(dbrootID), LOG_TYPE_ERROR ); } } catch (...) { writeLog("FAILURE: Error assigning gluster dbroot# " + itoa(dbrootID), LOG_TYPE_ERROR ); } // check if a copy is available when residePM returns string pmList = ""; try { string errmsg; int ret = glusterctl(oam::GLUSTER_WHOHAS, itoa(subDBRootID), pmList, errmsg); if ( ret != 0 ) { writeLog("ERROR: glusterctl failure getting pm list for dbroot " + itoa(subDBRootID) + " , error: " + errmsg, LOG_TYPE_ERROR ); exceptionControl("autoMovePmDbroot", API_INVALID_PARAMETER); } } catch (exception& ) { writeLog("ERROR: glusterctl failure getting pm list for dbroot " + itoa(subDBRootID), LOG_TYPE_ERROR ); exceptionControl("autoMovePmDbroot", API_INVALID_PARAMETER); } catch (...) { writeLog("ERROR: glusterctl failure getting pm list for dbroot " + itoa(subDBRootID), LOG_TYPE_ERROR ); exceptionControl("autoMovePmDbroot", API_INVALID_PARAMETER); } bool found = false; boost::char_separator sep(" "); boost::tokenizer< boost::char_separator > tokens(pmList, sep); for ( boost::tokenizer< boost::char_separator >::iterator it = tokens.begin(); it != tokens.end(); ++it) { if ( atoi((*it).c_str()) == residePMID ) { // found it and can assign the subDBRoot back to residedPM no switch back is needed found = true; } } // We will go back to this PM if (!found) { subDBRootID = dbrootID; } } //store in move dbroot transaction file string fileName = InstallDir + "/local/moveDbrootTransactionLog"; string cmd = "echo '" + residePM + "|" + localModuleName + "|" + itoa(subDBRootID) + "' >> " + fileName; system(cmd.c_str()); writeLog("WRITE1: " + cmd, LOG_TYPE_DEBUG ); //check for amazon moving required try { typedef std::vector dbrootList; dbrootList dbrootlist; dbrootlist.push_back(itoa(dbrootID)); amazonReattach(localModuleName, dbrootlist, true); } catch (exception& ) { writeLog("ERROR: amazonReattach failure", LOG_TYPE_ERROR ); exceptionControl("autoMovePmDbroot", API_FAILURE); } pt2++; if ( pt2 == residedbrootConfigList.end() ) break; } else { //if Gluster, get it's list for DBroot and move to one of those string toPmID; if ( DataRedundancyConfig == "y") { string pmList = ""; try { string errmsg; int ret = glusterctl(oam::GLUSTER_WHOHAS, itoa(dbrootID), pmList, errmsg); if ( ret != 0 ) { writeLog("ERROR: glusterctl failure getting pm list for dbroot " + itoa(dbrootID) + " , error: " + errmsg, LOG_TYPE_ERROR ); exceptionControl("autoMovePmDbroot", API_INVALID_PARAMETER); } } catch (exception& ) { writeLog("ERROR: glusterctl failure getting pm list for dbroot " + itoa(dbrootID), LOG_TYPE_ERROR ); exceptionControl("autoMovePmDbroot", API_INVALID_PARAMETER); } catch (...) { writeLog("ERROR: glusterctl failure getting pm list for dbroot " + itoa(dbrootID), LOG_TYPE_ERROR ); exceptionControl("autoMovePmDbroot", API_INVALID_PARAMETER); } bool found = false; boost::char_separator sep(" "); boost::tokenizer< boost::char_separator > tokens(pmList, sep); for ( boost::tokenizer< boost::char_separator >::iterator it = tokens.begin(); it != tokens.end(); ++it) { if ( atoi((*it).c_str()) != residePMID ) { found = true; toPmID = *it; string toPM = "pm" + toPmID; try { string errmsg; int ret = glusterctl(oam::GLUSTER_ASSIGN, itoa(dbrootID), toPM, errmsg); if ( ret != 0 ) { writeLog("FAILURE: Error assigning gluster dbroot# " + itoa(dbrootID), LOG_TYPE_ERROR ); } } catch (...) { writeLog("FAILURE: Error assigning gluster dbroot# " + itoa(dbrootID), LOG_TYPE_ERROR ); } DBRootConfigList todbrootConfigList; try { getPmDbrootConfig(atoi(toPmID.c_str()), todbrootConfigList); } catch (...) { writeLog("ERROR: getPmDbrootConfig failure", LOG_TYPE_ERROR ); exceptionControl("autoMovePmDbroot", API_INVALID_PARAMETER); } todbrootConfigList.push_back(dbrootID); try { setPmDbrootConfig(atoi(toPmID.c_str()), todbrootConfigList); writeLog("autoMovePmDbroot/setPmDbrootConfig : " + toPM + ":" + itoa(dbrootID), LOG_TYPE_DEBUG); sleep(5); //send msg to toPM to mount dbroot try { typedef std::vector dbrootList; dbrootList dbrootlist; dbrootlist.push_back(itoa(dbrootID)); mountDBRoot(dbrootlist); } catch (exception& ) { writeLog("ERROR: mountDBRoot api failure", LOG_TYPE_DEBUG ); cout << endl << "ERROR: mountDBRoot api failure" << endl; } } catch (...) { writeLog("ERROR: setPmDbrootConfig failure", LOG_TYPE_ERROR ); exceptionFailure = true; } //store in move dbroot transaction file string fileName = InstallDir + "/local/moveDbrootTransactionLog"; string cmd = "echo '" + residePM + "|" + toPM + "|" + itoa(dbrootID) + "' >> " + fileName; system(cmd.c_str()); writeLog("WRITE2: " + cmd, LOG_TYPE_DEBUG ); pt2++; if ( pt2 == residedbrootConfigList.end() ) break; dbrootID = *pt2; } } if (!found) { writeLog("ERROR: no available pm found for DBRoot " + itoa(dbrootID), LOG_TYPE_ERROR ); exceptionControl("autoMovePmDbroot", API_INVALID_PARAMETER); } } else { // not gluster, pmdbrootList = available pms for assigning PMdbrootList::iterator pt1 = pmdbrootList.begin(); for( ; pt1 != pmdbrootList.end() ; pt1++) { //if dbroot1 was moved, skip local module the first time through if ( dbroot1 ) { if ( (*pt1).pmID == localPMID ) { dbroot1 = false; continue; } } if ( (*pt1).pmID != residePMID ) { string toPM = "pm" + itoa((*pt1).pmID); //get dbroot ids for PM DBRootConfigList todbrootConfigList; try { getPmDbrootConfig((*pt1).pmID, todbrootConfigList); } catch (...) { writeLog("ERROR: getPmDbrootConfig failure", LOG_TYPE_ERROR ); exceptionControl("autoMovePmDbroot", API_INVALID_PARAMETER); } todbrootConfigList.push_back(dbrootID); //check for amazon moving required try { typedef std::vector dbrootList; dbrootList dbrootlist; dbrootlist.push_back(itoa(dbrootID)); amazonReattach(toPM, dbrootlist, true); } catch (exception& ) { writeLog("ERROR: amazonReattach failure", LOG_TYPE_ERROR ); exceptionFailure = true; } try { setPmDbrootConfig((*pt1).pmID, todbrootConfigList); writeLog("autoMovePmDbroot/setPmDbrootConfig : " + toPM + ":" + itoa(dbrootID), LOG_TYPE_DEBUG); sleep(5); //send msg to toPM to mount dbroot try { typedef std::vector dbrootList; dbrootList dbrootlist; dbrootlist.push_back(itoa(dbrootID)); mountDBRoot(dbrootlist); } catch (exception& ) { writeLog("ERROR: mountDBRoot api failure", LOG_TYPE_DEBUG ); cout << endl << "ERROR: mountDBRoot api failure" << endl; } } catch (...) { writeLog("ERROR: setPmDbrootConfig failure", LOG_TYPE_ERROR ); exceptionFailure = true; } //store in move dbroot transaction file string fileName = InstallDir + "/local/moveDbrootTransactionLog"; string cmd = "echo '" + residePM + "|" + toPM + "|" + itoa(dbrootID) + "' >> " + fileName; system(cmd.c_str()); writeLog("WRITE3: " + cmd, LOG_TYPE_DEBUG ); pt2++; if ( pt2 == residedbrootConfigList.end() ) break; dbrootID = *pt2; } } } } } if (exceptionFailure) exceptionControl("autoMovePmDbroot", API_FAILURE); return 0; } /******************************************************************** * * Auto Move PM - DBRoot data * ********************************************************************/ bool Oam::autoUnMovePmDbroot(std::string toPM) { writeLog("autoUnMovePmDbroot: " + toPM, LOG_TYPE_DEBUG ); string residePM; string fromPM; string dbrootIDs; string DBRootStorageType; try { getSystemConfig("DBRootStorageType", DBRootStorageType); } catch(...) {} string DataRedundancyConfig = "n"; try { getSystemConfig( "DataRedundancyConfig", DataRedundancyConfig); } catch(...) { DataRedundancyConfig = "n"; } if (DBRootStorageType == "internal" && DataRedundancyConfig == "n") return 1; //store in move dbroot transaction file string fileName = InstallDir + "/local/moveDbrootTransactionLog"; ifstream oldFile (fileName.c_str()); if (!oldFile) { ofstream newFile (fileName.c_str()); int fd = open(fileName.c_str(), O_RDWR|O_CREAT, 0664); newFile.close(); close(fd); } vector lines; char line[200]; string buf; string newLine; bool found = false; while (oldFile.getline(line, 200)) { buf = line; writeLog("READ: " + buf, LOG_TYPE_DEBUG ); string::size_type pos = buf.find("|",0); if (pos != string::npos) { residePM = buf.substr(0,pos); if ( residePM == toPM ) { string::size_type pos1 = buf.find("|",pos+1); if (pos1 != string::npos) { fromPM = buf.substr(pos+1,pos1-pos-1); dbrootIDs = buf.substr(pos1+1,80); found = true; try { manualMovePmDbroot(fromPM, dbrootIDs, toPM); writeLog("autoUnMovePmDbroot/manualMovePmDbroot : " + fromPM + ":" + dbrootIDs + ":" + toPM, LOG_TYPE_DEBUG); } catch (...) { writeLog("ERROR: manualMovePmDbroot failure: " + fromPM + ":" + dbrootIDs + ":" + toPM, LOG_TYPE_ERROR ); cout << "ERROR: manualMovePmDbroot failure" << endl; exceptionControl("autoUnMovePmDbroot", API_FAILURE); } } } else lines.push_back(buf); } } if (!found) { writeLog("ERROR: no dbroots found in ../Calpont/local/moveDbrootTransactionLog", LOG_TYPE_ERROR ); cout << "ERROR: no dbroots found in " << fileName << endl; exceptionControl("autoUnMovePmDbroot", API_FAILURE); } oldFile.close(); unlink (fileName.c_str()); ofstream newFile (fileName.c_str()); //create new file int fd = open(fileName.c_str(), O_RDWR|O_CREAT, 0664); copy(lines.begin(), lines.end(), ostream_iterator(newFile, "\n")); newFile.close(); close(fd); return 0; } /*************************************************************************** * * Function: addUMdisk * * Purpose: add UM disk * ****************************************************************************/ void Oam::addUMdisk(const int moduleID, std::string& volumeName, std::string& device, string EBSsize) { string UMVolumeSize = "10"; try{ getSystemConfig("UMVolumeSize", UMVolumeSize); } catch(...) {} writeLog("addUMdisk - Create new Volume for um" + itoa(moduleID), LOG_TYPE_DEBUG); cout << " Create AWS Volume for UM #" << itoa(moduleID) << endl; int retry = 0; for ( ; retry < 5 ; retry++ ) { volumeName = createEC2Volume(UMVolumeSize, "um"); if ( volumeName == "failed" || volumeName.empty() ) retry = retry; else break; } if ( retry >= 5 ) { cout << " *** ERROR: Failed to create a Volume for um1 " << moduleID << endl; exceptionControl("addUMdisk", API_FAILURE); } //attach and format volumes device = "/dev/xvdf"; string localInstance = getEC2LocalInstance(); //attach volumes to local instance writeLog("addUMdisk - Attach new Volume to local instance: " + volumeName, LOG_TYPE_DEBUG); retry = 0; for ( ; retry < 5 ; retry++ ) { if (!attachEC2Volume(volumeName, device, localInstance)) detachEC2Volume(volumeName); else break; } if ( retry >= 5 ) { cout << " *** ERROR: Volume " << volumeName << " failed to attach to local instance" << endl; exceptionControl("addUMdisk", API_FAILURE); } //format attached volume writeLog("addUMdisk - Format new Volume for: " + volumeName, LOG_TYPE_DEBUG); cout << " Formatting disk for UM #" << itoa(moduleID) << ", please wait..." << endl; string cmd; int user; user = getuid(); if (user == 0) cmd = "mkfs.ext2 -F " + device + " > /dev/null 2>&1"; else cmd = "sudo mkfs.ext2 -F " + device + " > /dev/null 2>&1"; system(cmd.c_str()); //detach volume writeLog("addUMdisk - detach new Volume from local instance: " + volumeName, LOG_TYPE_DEBUG); if (!detachEC2Volume(volumeName)) { exceptionControl("addUMdisk", API_FAILURE); } // add instance tag string AmazonAutoTagging; string systemName; try { getSystemConfig("AmazonAutoTagging", AmazonAutoTagging); getSystemConfig("SystemName", systemName); } catch(...) {} if ( AmazonAutoTagging == "y" ) { string tagValue = systemName + "-um" + itoa(moduleID); createEC2tag( volumeName, "Name", tagValue ); } } /*************************************************************************** * * Function: addDbroot * * Purpose: add DBRoot * ****************************************************************************/ void Oam::addDbroot(const int dbrootNumber, DBRootConfigList& dbrootlist, string EBSsize) { int SystemDBRootCount = 0; string cloud; string DBRootStorageType; string volumeSize; Config* sysConfig = Config::makeConfig(CalpontConfigFile.c_str()); string Section = "SystemConfig"; try { getSystemConfig("DBRootCount", SystemDBRootCount); getSystemConfig("Cloud", cloud); getSystemConfig("DBRootStorageType", DBRootStorageType); getSystemConfig("PMVolumeSize", volumeSize); } catch(...) {} int newSystemDBRootCount = SystemDBRootCount + dbrootNumber; if ( newSystemDBRootCount > MAX_DBROOT ) { cout << "ERROR: Failed add, total Number of DBRoots would be over maximum of " << MAX_DBROOT << endl; exceptionControl("addDbroot", API_INVALID_PARAMETER); } if ( (cloud == "amazon-ec2" || cloud == "amazon-vpc") && DBRootStorageType == "external" ) { if ( volumeSize == oam::UnassignedName ) { if ( EBSsize != oam::UnassignedName ) { volumeSize = EBSsize; setSystemConfig("PMVolumeSize", volumeSize); } } else { if ( EBSsize != oam::UnassignedName ) { volumeSize = EBSsize; } } if ( newSystemDBRootCount > MAX_DBROOT_AMAZON ) { cout << "ERROR: Failed add, total Number of DBRoots would be over maximum of " << MAX_DBROOT_AMAZON << endl; exceptionControl("addDbroot", API_INVALID_PARAMETER); } } //get assigned DBRoots IDs DBRootConfigList dbrootConfigList; try { getSystemDbrootConfig(dbrootConfigList); } catch(...) {} //get unassigned DBRoots IDs DBRootConfigList undbrootlist; try { getUnassignedDbroot(undbrootlist); } catch(...) {} //combined list DBRootConfigList::iterator pt1 = undbrootlist.begin(); for( ; pt1 != undbrootlist.end() ; pt1++) { dbrootConfigList.push_back(*pt1); } if ( dbrootlist.empty() ) { int newID = 1; for ( int count = 0 ; count < dbrootNumber ; count++ ) { //check for match while (true) { bool found = false; DBRootConfigList::iterator pt = dbrootConfigList.begin(); for( ; pt != dbrootConfigList.end() ; pt++) { if ( newID == *pt ) { newID++; found = true; break; } } if (!found) { dbrootlist.push_back(newID); newID++; break; } } } } if ( dbrootlist.empty() ) { cout << "ERROR: Failed add, No DBRoot IDs available" << endl; exceptionControl("addDbroot", API_INVALID_PARAMETER); } //if amazon cloud with external volumes, create AWS volumes if ( (cloud == "amazon-ec2" || cloud == "amazon-vpc") && DBRootStorageType == "external" ) { //get local instance name (pm1) string localInstance = getEC2LocalInstance(); if ( localInstance == "failed" || localInstance.empty() || localInstance == "") { cout << endl << "ERROR: Failed to get Instance ID" << endl; exceptionControl("addDbroot", API_INVALID_PARAMETER); } string Section = "Installation"; DBRootConfigList::iterator pt1 = dbrootlist.begin(); for( ; pt1 != dbrootlist.end() ; pt1++) { cout << " Create AWS Volume for DBRoot #" << itoa(*pt1) << endl; //create volume string volumeName; int retry = 0; for ( ; retry < 5 ; retry++ ) { volumeName = createEC2Volume(volumeSize, "pm"); if ( volumeName == "failed" || volumeName.empty() ) retry = retry; else break; } if ( retry >= 5 ) { cout << " *** ERROR: Failed to create a Volume for dbroot " << *pt1 << endl; exceptionControl("addDbroot", API_FAILURE); } string autoTagging; string systemName; try { getSystemConfig("AmazonAutoTagging", autoTagging); getSystemConfig("SystemName", systemName); } catch(...) {} if ( autoTagging == "y" ) { string tagValue = systemName + "-dbroot" + itoa(*pt1); createEC2tag( volumeName, "Name", tagValue ); } //get device name based on dbroot ID storageID_t st; try { st = getAWSdeviceName( *pt1 ); } catch(...) {} string deviceName = boost::get<0>(st); string amazonDeviceName = boost::get<1>(st); //attach volumes to local instance retry = 0; for ( ; retry < 5 ; retry++ ) { if (!attachEC2Volume(volumeName, deviceName, localInstance)) { detachEC2Volume(volumeName); } else break; } if ( retry >= 5 ) { cout << " *** ERROR: Volume " << volumeName << " failed to attach to local instance" << endl; exceptionControl("addDbroot", API_FAILURE); } //format attached volume cout << " Formatting DBRoot #" << itoa(*pt1) << ", please wait..." << endl; string cmd; int user; user = getuid(); if (user == 0) cmd = "mkfs.ext2 -F " + amazonDeviceName + " > /tmp/format.log 2>&1"; else cmd = "sudo mkfs.ext2 -F " + amazonDeviceName + " > /tmp/format.log 2>&1"; writeLog("addDbroot format cmd: " + cmd, LOG_TYPE_DEBUG ); system(cmd.c_str()); //detach detachEC2Volume(volumeName); string volumeNameID = "PMVolumeName" + itoa(*pt1); string deviceNameID = "PMVolumeDeviceName" + itoa(*pt1); string amazonDeviceNameID = "PMVolumeAmazonDeviceName" + itoa(*pt1); //write volume and device name try { sysConfig->setConfig(Section, volumeNameID, volumeName); sysConfig->setConfig(Section, deviceNameID, deviceName); sysConfig->setConfig(Section, amazonDeviceNameID, amazonDeviceName); } catch(...) {} // fstabs string entry = updateFstab( amazonDeviceName, itoa(*pt1)); //send update pms if (entry != "" ) distributeFstabUpdates(entry); } } //update Columnstore.xml entries DBRootConfigList::iterator pt2 = dbrootlist.begin(); for( ; pt2 != dbrootlist.end() ; pt2++) { string DBrootID = "DBRoot" + itoa(*pt2); string pathID = InstallDir + "/data" + itoa(*pt2); try { sysConfig->setConfig(Section, DBrootID, pathID); } catch(...) { cout << "ERROR: Problem setting DBRoot in the MariaDB Columnstore System Configuration file" << endl; exceptionControl("setConfig", API_FAILURE); } } try { sysConfig->write(); } catch(...) { exceptionControl("sysConfig->write", API_FAILURE); } if (!checkSystemRunning()) return; //get updated Columnstore.xml distributed distributeConfigFile("system"); // //send message to Process Monitor to add new dbroot to shared memory // pt2 = dbrootlist.begin(); for( ; pt2 != dbrootlist.end() ; pt2++) { try { ByteStream obs; obs << (ByteStream::byte) ADD_DBROOT; obs << itoa(*pt2); sendStatusUpdate(obs, ADD_DBROOT); } catch(...) { exceptionControl("setSystemConfig", API_INVALID_PARAMETER); } } return; } /*************************************************************************** * * Function: distributeFstabUpdates * * Purpose: distribute Fstab Updates * ****************************************************************************/ void Oam::distributeFstabUpdates(std::string entry, std::string toPM) { if (!checkSystemRunning()) return; ACK_FLAG ackflag = oam::ACK_YES; // build and send msg int returnStatus = sendMsgToProcMgr(FSTABUPDATE, toPM, FORCEFUL, ackflag, entry); if (returnStatus != API_SUCCESS) exceptionControl("distributeFstabUpdates", returnStatus); } /*************************************************************************** * * Function: assignDbroot * * Purpose: assign DBRoot * ****************************************************************************/ void Oam::assignDbroot(std::string toPM, DBRootConfigList& dbrootlist) { //make sure this new DBroot IDs aren't being used already try { systemStorageInfo_t t; t = getStorageConfig(); DeviceDBRootList moduledbrootlist = boost::get<2>(t); DBRootConfigList::iterator pt3 = dbrootlist.begin(); for( ; pt3 != dbrootlist.end() ; pt3++) { DeviceDBRootList::iterator pt = moduledbrootlist.begin(); for( ; pt != moduledbrootlist.end() ; pt++) { string moduleID = itoa((*pt).DeviceID); DBRootConfigList::iterator pt1 = (*pt).dbrootConfigList.begin(); for( ; pt1 != (*pt).dbrootConfigList.end() ; pt1++) { if ( *pt3 == *pt1) { cout << endl << "**** assignPmDbrootConfig Failed : DBRoot ID " + itoa(*pt3) + " already assigned to 'pm" + moduleID << "'" << endl; exceptionControl("assignPmDbrootConfig", API_INVALID_PARAMETER); } } } } } catch (exception& e) { cout << endl << "**** getStorageConfig Failed : " << e.what() << endl; } //make sure it's exist and unassigned DBRootConfigList undbrootlist; try { getUnassignedDbroot(undbrootlist); } catch(...) {} if ( undbrootlist.empty() ) { cout << endl << "**** assignPmDbrootConfig Failed : no available dbroots are unassigned" << endl; exceptionControl("assignPmDbrootConfig", API_INVALID_PARAMETER); } DBRootConfigList::iterator pt1 = dbrootlist.begin(); for( ; pt1 != dbrootlist.end() ; pt1++) { bool found = false; DBRootConfigList::iterator pt2 = undbrootlist.begin(); for( ; pt2 != undbrootlist.end() ; pt2++) { if ( *pt1 == * pt2 ) { found = true; break; } } if (!found) { cout << endl << "**** assignPmDbrootConfig Failed : dbroot " << *pt1 << " doesn't exist" << endl; exceptionControl("assignPmDbrootConfig", API_INVALID_PARAMETER); } } string toPMID = toPM.substr(MAX_MODULE_TYPE_SIZE,MAX_MODULE_ID_SIZE);; //get dbroots ids for to PM DBRootConfigList todbrootConfigList; try { getPmDbrootConfig(atoi(toPMID.c_str()), todbrootConfigList); cout << "DBRoot IDs assigned to '" + toPM + "' = "; DBRootConfigList::iterator pt = todbrootConfigList.begin(); for( ; pt != todbrootConfigList.end() ;) { cout << itoa(*pt); pt++; if (pt != todbrootConfigList.end()) cout << ", "; } cout << endl; } catch (exception& e) { cout << endl << "**** getPmDbrootConfig Failed for '" << toPM << "' : " << e.what() << endl; exceptionControl("assignPmDbrootConfig", API_FAILURE); } cout << endl << "Changes being applied" << endl << endl; //added entered dbroot IDs to to-PM list and do Gluster assign if needed string DataRedundancyConfig = "n"; try { getSystemConfig( "DataRedundancyConfig", DataRedundancyConfig); } catch(...) { DataRedundancyConfig = "n"; } DBRootConfigList::iterator pt3 = dbrootlist.begin(); for( ; pt3 != dbrootlist.end() ; pt3++) { todbrootConfigList.push_back(*pt3); /* if ( DataRedundancyConfig == "y") { try { string errmsg; int ret = glusterctl(oam::GLUSTER_ASSIGN, itoa(*pt3), toPM, errmsg); if ( ret != 0 ) { cerr << "FAILURE: Error assigning gluster dbroot# " + itoa(*pt3) + " to pm" + toPMID + ", error: " + errmsg << endl; exceptionControl("assignPmDbrootConfig", API_FAILURE); } } catch (exception& e) { cout << endl << "**** glusterctl API exception: " << e.what() << endl; cerr << "FAILURE: Error assigning gluster dbroot# " + itoa(*pt3) + " to pm" + toPMID << endl; exceptionControl("assignPmDbrootConfig", API_FAILURE); } catch (...) { cout << endl << "**** glusterctl API exception: UNKNOWN" << endl; cerr << "FAILURE: Error assigning gluster dbroot# " + itoa(*pt3) + " to pm" + toPMID << endl; exceptionControl("assignPmDbrootConfig", API_FAILURE); } } */ } try { setPmDbrootConfig(atoi(toPMID.c_str()), todbrootConfigList); } catch (exception& e) { cout << endl << "**** setPmDbrootConfig Failed for '" << toPM << "' : " << e.what() << endl; exceptionControl("assignPmDbrootConfig", API_FAILURE); } //get dbroots ids for to-PM try { todbrootConfigList.clear(); getPmDbrootConfig(atoi(toPMID.c_str()), todbrootConfigList); cout << "DBRoot IDs assigned to '" + toPM + "' = "; DBRootConfigList::iterator pt = todbrootConfigList.begin(); for( ; pt != todbrootConfigList.end() ;) { cout << itoa(*pt); pt++; if (pt != todbrootConfigList.end()) cout << ", "; } cout << endl; } catch (exception& e) { cout << endl << "**** getPmDbrootConfig Failed for '" << toPM << "' : " << e.what() << endl; exceptionControl("assignPmDbrootConfig", API_FAILURE); } //get old System DBRoot Count int oldSystemDbRootCount = 0; try { getSystemConfig("DBRootCount", oldSystemDbRootCount); if (oldSystemDbRootCount < 1) throw runtime_error("SystemDbRootCount not > 0"); } catch (exception& e) { cout << endl << "**** getSystemConfig for DBRootCount failed; " << e.what() << endl; exceptionControl("assignPmDbrootConfig", API_FAILURE); } //set new System DBRoot Count try { setSystemDBrootCount(); } catch (exception& ) { cout << endl << "**** setSystemDBrootCount Failed" << endl; exceptionControl("assignPmDbrootConfig", API_FAILURE); } //set FilesPerColumnPartition try { setFilesPerColumnPartition( oldSystemDbRootCount ); } catch (exception& ) { cout << endl << "**** setFilesPerColumnPartition Failed" << endl; exceptionControl("assignPmDbrootConfig", API_FAILURE); } //get updated Columnstore.xml distributed distributeConfigFile("system"); return; } /*************************************************************************** * * Function: unassignDbroot * * Purpose: unassign DBRoot * ****************************************************************************/ void Oam::unassignDbroot(std::string residePM, DBRootConfigList& dbrootlist) { string residePMID = residePM.substr(MAX_MODULE_TYPE_SIZE,MAX_MODULE_ID_SIZE);; //get dbroots ids for reside PM DBRootConfigList residedbrootConfigList; try { getPmDbrootConfig(atoi(residePMID.c_str()), residedbrootConfigList); cout << endl << "DBRoot IDs assigned to '" + residePM + "' = "; DBRootConfigList::iterator pt = residedbrootConfigList.begin(); for( ; pt != residedbrootConfigList.end() ;) { cout << itoa(*pt); pt++; if (pt != residedbrootConfigList.end()) cout << ", "; } cout << endl; } catch (exception& e) { cout << endl << "**** getPmDbrootConfig Failed for '" << residePM << "' : " << e.what() << endl; exceptionControl("unassignPmDbrootConfig", API_FAILURE); } cout << "Changes being applied..." << endl; //remove entered dbroot IDs from reside PM list DBRootConfigList::iterator pt1 = dbrootlist.begin(); for( ; pt1 != dbrootlist.end() ; pt1++) { DBRootConfigList::iterator pt2 = residedbrootConfigList.begin(); for( ; pt2 != residedbrootConfigList.end() ; pt2++) { if ( *pt2 == *pt1 ) { dbrootList dbroot1; dbroot1.push_back(itoa(*pt1)); //send msg to unmount dbroot if module is not offline int opState; bool degraded; try { getModuleStatus(residePM, opState, degraded); } catch(...) {} if (opState != oam::AUTO_OFFLINE || opState != oam::AUTO_DISABLED) { try { mountDBRoot(dbroot1, false); } catch (exception& ) { writeLog("ERROR: dbroot failed to unmount", LOG_TYPE_ERROR ); cout << endl << "ERROR: umountDBRoot api failure" << endl; exceptionControl("unassignPmDbrootConfig", API_FAILURE); } } //get volume name and detach it string volumeNameID = "PMVolumeName" + itoa(*pt1); string volumeName = oam::UnassignedName; try { getSystemConfig( volumeNameID, volumeName); } catch(...) {} if ( volumeName != oam::UnassignedName ) detachEC2Volume(volumeName); residedbrootConfigList.erase(pt2); cout << "DBRoot IDs unassigned from '" + residePM + "' = " + itoa(*pt1) << endl; break; } } } try { setPmDbrootConfig(atoi(residePMID.c_str()), residedbrootConfigList); } catch (exception& e) { cout << endl << "**** setPmDbrootConfig Failed for '" << residePM << "' : " << e.what() << endl; exceptionControl("unassignPmDbrootConfig", API_FAILURE); } //get dbroots ids for reside-PM try { residedbrootConfigList.clear(); getPmDbrootConfig(atoi(residePMID.c_str()), residedbrootConfigList); cout << "DBRoot IDs assigned to '" + residePM + "' = "; DBRootConfigList::iterator pt = residedbrootConfigList.begin(); for( ; pt != residedbrootConfigList.end() ;) { cout << itoa(*pt); pt++; if (pt != residedbrootConfigList.end()) cout << ", "; } cout << endl << endl; } catch (exception& e) { cout << endl << "**** getPmDbrootConfig Failed for '" << residePM << "' : " << e.what() << endl; exceptionControl("unassignPmDbrootConfig", API_FAILURE); } //get old System DBRoot Count int oldSystemDbRootCount = 0; try { getSystemConfig("DBRootCount", oldSystemDbRootCount); if (oldSystemDbRootCount < 1) throw runtime_error("SystemDbRootCount not > 0"); } catch (exception& e) { cout << endl << "**** getSystemConfig for DBRootCount failed; " << e.what() << endl; exceptionControl("unassignPmDbrootConfig", API_FAILURE); } //set new System DBRoot Count try { setSystemDBrootCount(); } catch (exception& ) { cout << endl << "**** setSystemDBrootCount Failed" << endl; exceptionControl("unassignPmDbrootConfig", API_FAILURE); } //set FilesPerColumnPartition try { setFilesPerColumnPartition( oldSystemDbRootCount ); } catch (exception& ) { cout << endl << "**** setFilesPerColumnPartition Failed" << endl; exceptionControl("unassignPmDbrootConfig", API_FAILURE); } return; } /*************************************************************************** * * Function: getUnassignedDbroot * * Purpose: get unassigned DBRoot list * ****************************************************************************/ void Oam::getUnassignedDbroot(DBRootConfigList& dbrootlist) { //get assigned dbroots IDs DBRootConfigList dbrootConfigList; try { getSystemDbrootConfig(dbrootConfigList); } catch(...) {} // get string variables Config* sysConfig = Config::makeConfig(CalpontConfigFile.c_str()); string Section = "SystemConfig"; for ( int dbrootID = 1 ; dbrootID < MAX_DBROOT ; dbrootID++) { string dbrootPath; try { dbrootPath = sysConfig->getConfig(Section, "DBRoot" + itoa(dbrootID)); } catch(...) {} if (dbrootPath.empty() || dbrootPath == oam::UnassignedName) continue; bool found = false; DBRootConfigList::iterator pt = dbrootConfigList.begin(); for( ; pt != dbrootConfigList.end() ; pt++) { if ( dbrootID == *pt ) { found = true; break; } } if (!found) dbrootlist.push_back(dbrootID); } return; } /*************************************************************************** * * Function: removeDbroot * * Purpose: remove DBRoot * ****************************************************************************/ void Oam::removeDbroot(DBRootConfigList& dbrootlist) { int SystemDBRootCount = 0; string cloud; string DBRootStorageType; string DataRedundancyConfig = "n"; try { getSystemConfig("DBRootCount", SystemDBRootCount); getSystemConfig("Cloud", cloud); getSystemConfig("DBRootStorageType", DBRootStorageType); getSystemConfig("DataRedundancyConfig", DataRedundancyConfig); } catch(...) {} int dbrootNumber = dbrootlist.size(); if ( dbrootNumber < 1 ) { cout << "ERROR: Failed remove, total Number of DBRoots to remove is less than 1 " << endl; exceptionControl("removeDbroot", API_INVALID_PARAMETER); } Config* sysConfig = Config::makeConfig(CalpontConfigFile.c_str()); string Section = "SystemConfig"; //check if dbroot requested to be removed is empty and dboot #1 is requested to be removed DBRootConfigList::iterator pt = dbrootlist.begin(); for( ; pt != dbrootlist.end() ; pt++) { int dbrootID = *pt; //see if dbroot exist string DBrootpath = "DBRoot" + itoa(dbrootID); string dbrootdir; try { dbrootdir = sysConfig->getConfig(Section, DBrootpath); } catch(...) {} if ( dbrootdir.empty() || dbrootdir == oam::UnassignedName ) { cout << "ERROR: DBRoot doesn't exist: " << itoa(dbrootID) << endl; exceptionControl("removeDbroot", API_FAILURE); } if ( dbrootID == 1 ) { cout << "ERROR: Failed remove, can't remove dbroot #1" << endl; exceptionControl("removeDbroot", API_INVALID_PARAMETER); } //check if dbroot is empty bool isEmpty = false; string errMsg; try { BRM::DBRM dbrm; if ( dbrm.isDBRootEmpty(dbrootID, isEmpty, errMsg) != 0) { cout << "ERROR: isDBRootEmpty API error, dbroot #" << itoa(dbrootID) << " :" << errMsg << endl; exceptionControl("removeDbroot", API_FAILURE); } } catch (exception& ) {} if (!isEmpty) { cout << "ERROR: Failed remove, dbroot #" << itoa(dbrootID) << " is not empty" << endl; exceptionControl("removeDbroot", API_FAILURE); } //check if dbroot is assigned to a pm and if so, unassign it int pmid = 0; try { getDbrootPmConfig(dbrootID, pmid); } catch (exception& ) {} if ( pmid > 0 ) { //unassign dbroot from pm DBRootConfigList pmdbrootlist; pmdbrootlist.push_back(dbrootID); try { unassignDbroot("pm" + itoa(pmid), pmdbrootlist); } catch (exception& ) { cout << endl << "**** unassignDbroot Failed" << endl; exceptionControl("removeDbroot", API_FAILURE); } } // if gluster, request volume delete if ( DataRedundancyConfig == "y") { try { string errmsg1; string errmsg2; int ret = glusterctl(oam::GLUSTER_DELETE, itoa(dbrootID), errmsg1, errmsg2); if ( ret != 0 ) { cerr << "FAILURE: Error deleting gluster dbroot# " + itoa(dbrootID) + ", error: " + errmsg1 << endl; exceptionControl("removeDbroot", API_FAILURE); } } catch (exception& e) { cout << endl << "**** glusterctl API exception: " << e.what() << endl; cerr << "FAILURE: Error assigning gluster dbroot# " + itoa(dbrootID) << endl; exceptionControl("removeDbroot", API_FAILURE); } catch (...) { cout << endl << "**** glusterctl API exception: UNKNOWN" << endl; cerr << "FAILURE: Error assigning gluster dbroot# " + itoa(dbrootID) << endl; exceptionControl("removeDbroot", API_FAILURE); } } try { sysConfig->delConfig(Section, DBrootpath); } catch(...) { cout << "ERROR: Problem deleting DBRoot in the MariaDB Columnstore System Configuration file" << endl; exceptionControl("deleteConfig", API_FAILURE); } } try { sysConfig->write(); } catch(...) { exceptionControl("sysConfig->write", API_FAILURE); } //get updated Columnstore.xml distributed distributeConfigFile("system"); // //send message to Process Monitor to remove dbroot to shared memory // pt = dbrootlist.begin(); for( ; pt != dbrootlist.end() ; pt++) { try { ByteStream obs; obs << (ByteStream::byte) REMOVE_DBROOT; obs << itoa(*pt); sendStatusUpdate(obs, REMOVE_DBROOT); } catch(...) { exceptionControl("setSystemConfig", API_INVALID_PARAMETER); } } return; } //current amazon max dbroot id support = 190; string PMdeviceName = "/dev/sd"; string deviceLetter[] = {"g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z","end"}; /*************************************************************************** * * Function: getAWSdeviceName * * Purpose: get AWS Device Name for DBRoot ID * ****************************************************************************/ storageID_t Oam::getAWSdeviceName( const int dbrootid) { string amazondeviceName = "/dev/xvd"; try { getSystemConfig( "AmazonDeviceName", amazondeviceName ); } catch(...) {} if ( amazondeviceName.empty() || amazondeviceName == "" ) amazondeviceName = "/dev/xvd"; //calulate id numbers from DBRoot ID // int lid = (dbrootid-1) / 10; // int did = dbrootid - (dbrootid * lid); // return boost::make_tuple(PMdeviceName + deviceLetter[lid] + itoa(did), amazondeviceName + deviceLetter[lid] + itoa(did)); return boost::make_tuple(PMdeviceName + deviceLetter[dbrootid-1], amazondeviceName + deviceLetter[dbrootid-1]); } /*************************************************************************** * * Function: setSystemDBrootCount * * Purpose: set System DBRoot Count * ****************************************************************************/ void Oam::setSystemDBrootCount() { sleep(1); //let other updates get applied to the config file //set the system dbroot number try { DBRootConfigList dbrootConfigList; getSystemDbrootConfig(dbrootConfigList); try { setSystemConfig("DBRootCount", dbrootConfigList.size()); } catch(...) { writeLog("ERROR: setSystemConfig DBRootCount " + dbrootConfigList.size() , LOG_TYPE_ERROR ); cout << endl << "ERROR: setSystemConfig DBRootCount " + dbrootConfigList.size() << endl; exceptionControl("setSystemConfig", API_FAILURE); } } catch(...) { writeLog("ERROR: getSystemDbrootConfig ", LOG_TYPE_ERROR ); cout << endl << "ERROR: getSystemDbrootConfig " << endl; exceptionControl("getSystemDbrootConfig", API_INVALID_PARAMETER); } return; } /*************************************************************************** * * Function: setFilesPerColumnPartition * * Purpose: set FilesPerColumnPartition * This function takes the old DBRootCount as an input arg * and expects that the new DBRootCount has been set in the * Columnstore.xml file. Function assumes oldSystemDBRootCount * has already been validated to be > 0 (else we could get a * divide by 0 error). * ****************************************************************************/ void Oam::setFilesPerColumnPartition( int oldSystemDBRootCount ) { int newSystemDBRootCount = 0; int oldFilesPerColumnPartition = 4; try { getSystemConfig("DBRootCount", newSystemDBRootCount); } catch(...) { writeLog("ERROR: getSystemConfig DBRootCount ", LOG_TYPE_ERROR ); cout << endl << "ERROR: getSystemConfig DBRootCount" << endl; exceptionControl("setFilesPerColumnPartition", API_INVALID_PARAMETER); } try { getSystemConfig("FilesPerColumnPartition", oldFilesPerColumnPartition); } catch(...) { writeLog("ERROR: getSystemConfig FilesPerColumnPartition ", LOG_TYPE_ERROR ); cout << endl << "ERROR: getSystemConfig FilesPerColumnPartition" << endl; exceptionControl("setFilesPerColumnPartition", API_INVALID_PARAMETER); } if ( oldFilesPerColumnPartition != oldSystemDBRootCount * (oldFilesPerColumnPartition/oldSystemDBRootCount) ) { writeLog("ERROR: old FilesPerColumnPartition not a multiple of DBRootCount", LOG_TYPE_ERROR ); cout << endl << "ERROR: old FilesPerColumnPartition not a multiple of DBRootCount " << endl; exceptionControl("setFilesPerColumnPartition", API_INVALID_PARAMETER); } int newFilesPerColumnPartition = (oldFilesPerColumnPartition/oldSystemDBRootCount) * newSystemDBRootCount; try { setSystemConfig("FilesPerColumnPartition", newFilesPerColumnPartition); } catch(...) { writeLog("ERROR: setSystemConfig FilesPerColumnPartition " + newFilesPerColumnPartition , LOG_TYPE_ERROR ); cout << endl << "ERROR: setSystemConfig FilesPerColumnPartition " + newFilesPerColumnPartition << endl; exceptionControl("setFilesPerColumnPartition", API_FAILURE); } } #pragma pack(push,1) struct NotifyMsgStruct { uint32_t magic; uint32_t msgno; char node[8]; uint32_t paylen; }; #pragma pack(pop) /*************************************************************************** * * Function: sendDeviceNotification * * Purpose: send Device Notification Msg * ****************************************************************************/ int Oam::sendDeviceNotification(std::string deviceName, NOTIFICATION_TYPE type, std::string payload) { //first check if there are any CMP entries configured try { Config* sysConfig = Config::makeConfig(CalpontConfigFile.c_str()); string CMPsection = "CMP"; for ( int id = 1 ;; id++) { string CMP = CMPsection + itoa(id); try { string ipaddr = sysConfig->getConfig(CMP, "IPAddr"); if (ipaddr.empty()) return API_SUCCESS; string port = sysConfig->getConfig(CMP, "Port"); NotifyMsgStruct msg; memset(&msg, 0, sizeof(msg)); msg.magic = NOTIFICATIONKEY; msg.msgno = type; strncpy(msg.node, deviceName.c_str(), 7); if (!payload.empty()) msg.paylen = payload.length() + 1; // send notification msg to this exchange try { int ds = -1; ds = ::socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); struct sockaddr_in serv_addr; struct in_addr la; ::inet_aton(ipaddr.c_str(), &la); memset(&serv_addr, 0, sizeof(serv_addr)); serv_addr.sin_family = AF_INET; serv_addr.sin_addr.s_addr = la.s_addr; serv_addr.sin_port = htons(atoi(port.c_str())); int rc = -1; rc = ::connect(ds, (struct sockaddr*)&serv_addr, sizeof(serv_addr)); if (rc < 0) throw runtime_error("socket connect error"); rc = ::write(ds, &msg, sizeof(msg)); if (rc < 0) throw runtime_error("socket write error"); if (msg.paylen > 0) { rc = ::write(ds, payload.c_str(), msg.paylen); if (rc < 0) throw runtime_error("socket write error"); } ::shutdown(ds, SHUT_RDWR); ::close(ds); } catch (std::runtime_error&) { //There's other reasons, but this is the most likely... return API_CONN_REFUSED; } catch (std::exception&) { return API_FAILURE; } catch (...) { return API_FAILURE; } } catch (...) { return API_SUCCESS; } } } catch (...) {} return API_SUCCESS; } /*************************************************************************** * * Function: actionMysqlCalpont * * Purpose: mysql-Columnstore service command * ****************************************************************************/ void Oam::actionMysqlCalpont(MYSQLCALPONT_ACTION action) { // check system type to see if mysqld should be accessed on this module int serverTypeInstall = oam::INSTALL_NORMAL; string moduleType; string moduleName; oamModuleInfo_t st; try { st = getModuleInfo(); moduleType = boost::get<1>(st); serverTypeInstall = boost::get<5>(st); moduleName = boost::get<0>(st); } catch (...) {} //PMwithUM config string PMwithUM = "n"; try { getSystemConfig( "PMwithUM", PMwithUM); } catch(...) { PMwithUM = "n"; } if ( ( serverTypeInstall == oam::INSTALL_NORMAL && moduleType == "um" ) || ( serverTypeInstall == oam::INSTALL_NORMAL && moduleType == "pm" && PMwithUM == "y") || ( serverTypeInstall == oam::INSTALL_COMBINE_DM_UM_PM ) ) PMwithUM = PMwithUM; else return; // check if mysql-Capont is installed string mysqlscript = InstallDir + "/mysql/mysql-Columnstore"; if (access(mysqlscript.c_str(), X_OK) != 0) return; string command; switch(action) { case MYSQL_START: { command = "start > /tmp/actionMysqlCalpont.log 2>&1"; break; } case MYSQL_STOP: { command = "stop > /tmp/actionMysqlCalpont.log 2>&1"; //set process status try { setProcessStatus("mysqld", moduleName, MAN_OFFLINE, 0); } catch(...) {} break; } case MYSQL_RESTART: { command = "restart > /tmp/actionMysqlCalpont.log 2>&1"; break; } case MYSQL_RELOAD: { command = "reload > /tmp/actionMysqlCalpont.log 2>&1"; break; } case MYSQL_FORCE_RELOAD: { command = "force-reload > /tmp/actionMysqlCalpont.log 2>&1"; break; } case MYSQL_STATUS: { command = "status > /tmp/mysql.status"; break; } default: { writeLog("***DEFAULT OPTION", LOG_TYPE_ERROR); exceptionControl("actionMysqlCalpont", API_INVALID_PARAMETER); } } //RUN COMMAND string cmd = mysqlscript + " " + command; system(cmd.c_str()); if (action == MYSQL_START || action == MYSQL_RESTART) { //get pid cmd = "cat " + InstallDir + "/mysql/db/*.pid > /tmp/mysql.pid"; system(cmd.c_str()); ifstream oldFile ("/tmp/mysql.pid"); //fail if file size 0 oldFile.seekg(0, std::ios::end); int size = oldFile.tellg(); if ( size == 0 ) { // mysql not started writeLog("***mysql.pid FILE SIZE EQUALS ZERO", LOG_TYPE_ERROR); exceptionControl("actionMysqlCalpont", API_FAILURE); } char line[400]; string pid; while (oldFile.getline(line, 400)) { pid = line; string::size_type pos = pid.find("cat",0); if (pos != string::npos) { // mysql not started writeLog("***mysql.pid FILE HAS CAT", LOG_TYPE_ERROR); exceptionControl("actionMysqlCalpont", API_FAILURE); } break; } oldFile.close(); int PID = atoi(pid.c_str()); //set process status try { setProcessStatus("mysqld", moduleName, ACTIVE, PID); } catch(...) {} } if (action == MYSQL_STATUS ) { ProcessStatus procstat; getProcessStatus("mysqld", moduleName, procstat); int state = procstat.ProcessOpState; pid_t pidStatus = procstat.ProcessID; if (checkLogStatus("/tmp/mysql.status", "MySQL running")) { if ( state != ACTIVE ) { //get pid cmd = "cat " + InstallDir + "/mysql/db/*.pid > /tmp/mysql.pid"; system(cmd.c_str()); ifstream oldFile ("/tmp/mysql.pid"); char line[400]; string pid; while (oldFile.getline(line, 400)) { pid = line; break; } oldFile.close(); //set process status try { setProcessStatus("mysqld", moduleName, ACTIVE, atoi(pid.c_str())); } catch(...) {} return; } else { //check if pid has changed cmd = "cat " + InstallDir + "/mysql/db/*.pid > /tmp/mysql.pid"; system(cmd.c_str()); ifstream oldFile ("/tmp/mysql.pid"); char line[400]; string pid; while (oldFile.getline(line, 400)) { pid = line; break; } oldFile.close(); if ( pidStatus != atoi(pid.c_str()) ) { //set process status try { setProcessStatus("mysqld", moduleName, ACTIVE, atoi(pid.c_str())); } catch(...) {} } } //check module status, if DEGRADED set to ACTIVE int opState; bool degraded; try { getModuleStatus(moduleName, opState, degraded); } catch(...) {} if (opState == oam::DEGRADED) { try { setModuleStatus(moduleName, ACTIVE); } catch(...) {} } } else { if ( state == ACTIVE ) { //set process status try { setProcessStatus("mysqld", moduleName, MAN_OFFLINE, 0); } catch(...) {} } //check module status, if ACTIVE set to DEGRADED int opState; bool degraded; try { getModuleStatus(moduleName, opState, degraded); } catch(...) {} if (opState == oam::ACTIVE) { try { setModuleStatus(moduleName, DEGRADED); } catch(...) {} } return; } } return; } /****************************************************************************************** * @brief run DBHealth Check * * purpose: test the health of the DB * ******************************************************************************************/ void Oam::checkDBFunctional(bool action) { ByteStream msg; ByteStream receivedMSG; // only make call if system is active SystemStatus systemstatus; try { getSystemStatus(systemstatus); } catch (exception& ) {} if (systemstatus.SystemOpState != oam::ACTIVE ) exceptionControl("checkDBHealth", API_INVALID_STATE); SystemModuleTypeConfig systemmoduletypeconfig; try { Oam::getSystemConfig(systemmoduletypeconfig); } catch(...) { exceptionControl("checkDBHealth", API_FAILURE); } // get Server Type Install ID int serverTypeInstall = oam::INSTALL_NORMAL; string OAMParentModuleName; oamModuleInfo_t st; try { st = getModuleInfo(); OAMParentModuleName = boost::get<3>(st); serverTypeInstall = boost::get<5>(st); } catch (...) { exceptionControl("getMyProcessStatus", API_FAILURE); } string module; switch ( serverTypeInstall ) { case (oam::INSTALL_NORMAL): case (oam::INSTALL_COMBINE_DM_UM): { module = "um1"; break; } case (oam::INSTALL_COMBINE_PM_UM): case (oam::INSTALL_COMBINE_DM_UM_PM): { module = OAMParentModuleName; break; } } // setup message msg << (ByteStream::byte) RUN_DBHEALTH_CHECK; msg << (ByteStream::byte) action; try { //send the msg to Server Monitor MessageQueueClient servermonitor(module + "_ServerMonitor"); servermonitor.write(msg); // wait 30 seconds for ACK from Server Monitor struct timespec ts = { 30, 0 }; receivedMSG = servermonitor.read(&ts); if (receivedMSG.length() > 0) { ByteStream::byte returnType; receivedMSG >> returnType; if ( returnType == RUN_DBHEALTH_CHECK ) { ByteStream::byte returnStatus; receivedMSG >> returnStatus; if ( returnStatus == oam::API_SUCCESS ) { // succesfull servermonitor.shutdown(); return; } } // shutdown connection servermonitor.shutdown(); exceptionControl("checkDBHealth", API_FAILURE); } else { // timeout // shutdown connection servermonitor.shutdown(); exceptionControl("checkDBHealth", API_TIMEOUT); } } catch(...) { exceptionControl("checkDBHealth", API_FAILURE); return; } return; } /*************************************************************************** * * Function: validateModule * * Purpose: Validate Module Name * ****************************************************************************/ int Oam::validateModule(const std::string name) { if ( name.size() < 3 ) // invalid ID return API_INVALID_PARAMETER; string moduletype = name.substr(0,MAX_MODULE_TYPE_SIZE); int moduleID = atoi(name.substr(MAX_MODULE_TYPE_SIZE,MAX_MODULE_ID_SIZE).c_str()); if ( moduleID < 1 ) // invalid ID return API_INVALID_PARAMETER; SystemModuleTypeConfig systemmoduletypeconfig; try { getSystemConfig(systemmoduletypeconfig); } catch(...) { return API_INVALID_PARAMETER; } for( unsigned int i = 0 ; i < systemmoduletypeconfig.moduletypeconfig.size(); i++) { if (systemmoduletypeconfig.moduletypeconfig[i].ModuleType == moduletype ) { if (systemmoduletypeconfig.moduletypeconfig[i].ModuleCount == 0 ) return API_INVALID_PARAMETER; DeviceNetworkList::iterator pt = systemmoduletypeconfig.moduletypeconfig[i].ModuleNetworkList.begin(); for( ; pt != systemmoduletypeconfig.moduletypeconfig[i].ModuleNetworkList.end() ; pt++) { if ( name == (*pt).DeviceName ) return API_SUCCESS; } } } return API_INVALID_PARAMETER; } /*************************************************************************** * * Function: getEC2InstanceIpAddress * * Purpose: Check Amazon EC2 is running and returns Private IP address * ****************************************************************************/ std::string Oam::getEC2InstanceIpAddress(std::string instanceName) { // run script to get Instance status and IP Address string cmd = InstallDir + "/bin/MCSInstanceCmds.sh getPrivateIP " + instanceName + " > /tmp/getCloudIP_" + instanceName; system(cmd.c_str()); if (checkLogStatus("/tmp/getCloudIP_" + instanceName, "stopped") ) return "stopped"; if (checkLogStatus("/tmp/getCloudIP_" + instanceName, "terminated") ) return "terminated"; // get IP Address string IPAddr; string file = "/tmp/getCloudIP_" + instanceName; ifstream oldFile (file.c_str()); char line[400]; while (oldFile.getline(line, 400)) { IPAddr = line; } oldFile.close(); if (isValidIP(IPAddr)) return IPAddr; return "terminated"; } /*************************************************************************** * * Function: getEC2LocalInstance * * Purpose: Get Amazon EC2 local Instance Name * ****************************************************************************/ std::string Oam::getEC2LocalInstance(std::string name) { // run script to get Instance status and IP Address string cmd = InstallDir + "/bin/MCSInstanceCmds.sh getInstance > /tmp/getInstanceInfo_" + name; int status = system(cmd.c_str()); if (WEXITSTATUS(status) != 0 ) return "failed"; // get Instance Name string instanceName; string file = "/tmp/getInstanceInfo_" + name; ifstream oldFile (file.c_str()); char line[400]; while (oldFile.getline(line, 400)) { instanceName = line; } oldFile.close(); return instanceName; } /*************************************************************************** * * Function: getEC2LocalInstanceType * * Purpose: Get Amazon EC2 local Instance Type * ****************************************************************************/ std::string Oam::getEC2LocalInstanceType(std::string name) { // run script to get Instance status and IP Address string cmd = InstallDir + "/bin/MCSInstanceCmds.sh getType > /tmp/getInstanceType_" + name; int status = system(cmd.c_str()); if (WEXITSTATUS(status) != 0 ) return "failed"; // get Instance Name string instanceType; string file = "/tmp/getInstanceType_" + name; ifstream oldFile (file.c_str()); char line[400]; while (oldFile.getline(line, 400)) { instanceType = line; } oldFile.close(); return instanceType; } /*************************************************************************** * * Function: getEC2LocalInstanceSubnet * * Purpose: Get Amazon EC2 local Instance Subnet * ****************************************************************************/ std::string Oam::getEC2LocalInstanceSubnet(std::string name) { // run script to get Instance Subnet string cmd = InstallDir + "/bin/MCSInstanceCmds.sh getSubnet > /tmp/getInstanceSubnet_" + name; int status = system(cmd.c_str()); if (WEXITSTATUS(status) != 0 ) return "failed"; // get Instance Name string instanceSubnet; string file = "/tmp/getInstanceSubnet_" + name; ifstream oldFile (file.c_str()); char line[400]; while (oldFile.getline(line, 400)) { instanceSubnet = line; } oldFile.close(); return instanceSubnet; } /*************************************************************************** * * Function: launchEC2Instance * * Purpose: Launch Amazon EC2 Instance * ****************************************************************************/ std::string Oam::launchEC2Instance( const std::string name, const std::string IPAddress, const std::string type, const std::string group) { // run script to get Instance status and IP Address string cmd = InstallDir + "/bin/MCSInstanceCmds.sh launchInstance " + IPAddress + " " + type + " " + group + " > /tmp/getInstance_" + name; int status = system(cmd.c_str()); if (WEXITSTATUS(status) != 0 ) return "failed"; if (checkLogStatus("/tmp/getInstance", "Required") ) return "failed"; // get Instance ID string instance; string file = "/tmp/getInstance_" + name; ifstream oldFile (file.c_str()); char line[400]; while (oldFile.getline(line, 400)) { instance = line; } oldFile.close(); if (instance.empty()) return "failed"; if (instance == "unknown") return "failed"; if (instance.find("i-") == string::npos) return "failed"; return instance; } /*************************************************************************** * * Function: terminateEC2Instance * * Purpose: Terminate Amazon EC2 Instance * ****************************************************************************/ void Oam::terminateEC2Instance(std::string instanceName) { // run script to get Instance status and IP Address string cmd = InstallDir + "/bin/MCSInstanceCmds.sh terminateInstance " + instanceName + " > /tmp/terminateEC2Instance_" + instanceName; system(cmd.c_str()); return; } /*************************************************************************** * * Function: stopEC2Instance * * Purpose: Terminate Amazon EC2 Instance * ****************************************************************************/ void Oam::stopEC2Instance(std::string instanceName) { // run script to get Instance status and IP Address string cmd = InstallDir + "/bin/MCSInstanceCmds.sh stopInstance " + instanceName + " > /tmp/stopEC2Instance_" + instanceName; system(cmd.c_str()); return; } /*************************************************************************** * * Function: startEC2Instance * * Purpose: Start Amazon EC2 Instance * ****************************************************************************/ bool Oam::startEC2Instance(std::string instanceName) { // run script to get Instance status and IP Address string cmd = InstallDir + "/bin/MCSInstanceCmds.sh startInstance " + instanceName + " > /tmp/startEC2Instance_" + instanceName; int ret = system(cmd.c_str()); if (WEXITSTATUS(ret) != 0 ) return false; return true; } /*************************************************************************** * * Function: assignElasticIP * * Purpose: assign Elastic IP Address on Amazon * ****************************************************************************/ bool Oam::assignElasticIP(std::string instanceName, std::string IpAddress) { // run script to get Instance status and IP Address string cmd = InstallDir + "/bin/MCSInstanceCmds.sh assignElasticIP " + instanceName + " " + IpAddress + " > /tmp/assignElasticIP_" + instanceName; int ret = system(cmd.c_str()); if (WEXITSTATUS(ret) != 0 ) exceptionControl("assignElasticIP", oam::API_FAILURE); return true; } /*************************************************************************** * * Function: deassignElasticIP * * Purpose: deassign Elastic IP Address on Amazon * ****************************************************************************/ bool Oam::deassignElasticIP(std::string IpAddress) { // run script to get Instance status and IP Address string cmd = InstallDir + "/bin/MCSInstanceCmds.sh deassignElasticIP " + IpAddress + " > /tmp/deassignElasticIP_" + IpAddress; int ret = system(cmd.c_str()); if (WEXITSTATUS(ret) != 0 ) exceptionControl("deassignElasticIP", oam::API_FAILURE); return true; } /*************************************************************************** * * Function: getEC2VolumeStatus * * Purpose: get Volume Status * ****************************************************************************/ std::string Oam::getEC2VolumeStatus(std::string volumeName) { // run script to get Volume Status string cmd = InstallDir + "/bin/MCSVolumeCmds.sh describe " + volumeName + " > /tmp/getVolumeStatus_" + volumeName; int ret = system(cmd.c_str()); if (WEXITSTATUS(ret) != 0 ) return "failed"; // get status string status; string file = "/tmp/getVolumeStatus_" + volumeName; ifstream oldFile (file.c_str()); char line[400]; while (oldFile.getline(line, 400)) { status = line; break; } oldFile.close(); return status; } /*************************************************************************** * * Function: createEC2Volume * * Purpose: create a EC2 Volume * ****************************************************************************/ std::string Oam::createEC2Volume(std::string size, std::string name) { // run script to get Volume Status string cmd = InstallDir + "/bin/MCSVolumeCmds.sh create " + size + " " + name + " > /tmp/createVolumeStatus_" + name; int ret = system(cmd.c_str()); if (WEXITSTATUS(ret) != 0 ) return "failed"; // get status string volumeName; string file = "/tmp/createVolumeStatus_" + name; ifstream oldFile (file.c_str()); char line[400]; while (oldFile.getline(line, 400)) { volumeName = line; } oldFile.close(); if ( volumeName == "unknown" ) return "failed"; if ( volumeName == "unknown" ) return "failed"; if (volumeName.find("vol-") == string::npos) return "failed"; return volumeName; } /*************************************************************************** * * Function: attachEC2Volume * * Purpose: attach EC2 Volume * ****************************************************************************/ bool Oam::attachEC2Volume(std::string volumeName, std::string deviceName, std::string instanceName) { // add 1 retry if it fails by dettaching then attaching int ret = 0; string status; for ( int retry = 0 ; retry < 2 ; retry++ ) { // run script to attach Volume string cmd = InstallDir + "/bin/MCSVolumeCmds.sh attach " + volumeName + " " + instanceName + " " + deviceName + " > /tmp/attachVolumeStatus_" + volumeName; ret = system(cmd.c_str()); if (WEXITSTATUS(ret) == 0 ) return true; //failing to attach, dettach and retry detachEC2Volume(volumeName); } if (ret == 0 ) return true; else return false; } /*************************************************************************** * * Function: detachEC2Volume * * Purpose: detach EC2 Volume * ****************************************************************************/ bool Oam::detachEC2Volume(std::string volumeName) { // run script to attach Volume string cmd = InstallDir + "/bin/MCSVolumeCmds.sh detach " + volumeName + " > /tmp/detachVolumeStatus_" + volumeName; int ret = system(cmd.c_str()); if (WEXITSTATUS(ret) != 0 ) return false; return true; } /*************************************************************************** * * Function: deleteEC2Volume * * Purpose: detach EC2 Volume * ****************************************************************************/ bool Oam::deleteEC2Volume(std::string volumeName) { // run script to delete Volume string cmd = InstallDir + "/bin/MCSVolumeCmds.sh delete " + volumeName + " > /tmp/deleteVolumeStatus_" + volumeName; int ret = system(cmd.c_str()); if (WEXITSTATUS(ret) != 0 ) return false; return true; } /*************************************************************************** * * Function: createEC2tag * * Purpose: create EC2 tag * ****************************************************************************/ bool Oam::createEC2tag(std::string resourceName, std::string tagName, std::string tagValue) { // run script to create a tag string cmd = InstallDir + "/bin/MCSVolumeCmds.sh createTag " + resourceName + " " + tagName + " " + tagValue + " > /tmp/createTagStatus_" + resourceName; int ret = system(cmd.c_str()); if (WEXITSTATUS(ret) != 0 ) return false; return true; } /****************************************************************************************** * @brief syslogAction * * purpose: Take Action on Syslog Process * ******************************************************************************************/ void Oam::syslogAction( std::string action) { #ifndef _MSC_VER writeLog("syslogAction: " + action, LOG_TYPE_DEBUG ); string systemlog = "syslog"; string fileName; getSystemConfig("SystemLogConfigFile", fileName); if (fileName == oam::UnassignedName ) { return; } string::size_type pos = fileName.find("syslog-ng",0); if (pos != string::npos) systemlog = "syslog-ng"; else { pos = fileName.find("rsyslog",0); if (pos != string::npos) systemlog = "rsyslog"; } string cmd; if ( action == "sighup" ) { if ( systemlog == "syslog" || systemlog == "rsyslog") systemlog = systemlog + "d"; cmd = "pkill -hup " + systemlog + " > /dev/null 2>&1"; } else { int user; user = getuid(); if (user == 0) cmd = "systemctl " + action + " " + systemlog + ".service > /dev/null 2>&1"; else cmd = "sudo systemctl " + action + " " + systemlog + ".service > /dev/null 2>&1"; system(cmd.c_str()); if (user == 0) cmd = "/service " + systemlog + " " + action + " > /dev/null 2>&1"; else cmd = "sudo service" + systemlog + " " + action + " > /dev/null 2>&1"; } // take action on syslog service writeLog("syslogAction cmd: " + cmd, LOG_TYPE_DEBUG ); system(cmd.c_str()); // delay to give time for syslog to get up and going sleep(2); #endif } /****************************************************************************************** * @brief dbrmctl * * purpose: call dbrm control * ******************************************************************************************/ void Oam::dbrmctl(std::string command) { //reload DBRM with new configuration string cmd = InstallDir + "/bin/dbrmctl " + command + " > /dev/null 2>&1"; system(cmd.c_str()); return; } /****************************************************************************************** * @brief glusterctl * * purpose: gluster control and glusteradd * * commands: status - Used to check status of gluster and disk good/bad * returns * NOTINSTALLED * OK * FAILED! erorrmsg * setddc - Set Number of gluster disk copies * argument = # * returns * NOTINSTALLED * OK * FAILED! erorrmsg * assign - Used to assign a dbroot to a primary pm * argument1 = dbroot# * argument2 = pm# * returns * NOTINSTALLED * OK * FAILED! erorrmsg * unassign - Used to assign a dbroot to a primary pm * argument1 = dbroot# * argument2 = pm# * returns * NOTINSTALLED * OK * FAILED! erorrmsg * whohas - Used to get secondary pm for a dbroot for moving * argument1 = dbroot# * return argument #2 - pm# * returns * NOTINSTALLED * OK * FAILED! erorrmsg * add - Used to add new gluster pm and dbroot * argument1 = firstnewpm# * argument2 = firstnewdbroot# * returns * NOTINSTALLED * OK * FAILED! erorrmsg * delete - Used to delete dbroot volumes * argument1 = dbroot# * returns * NOTINSTALLED * OK * FAILED! erorrmsg * ******************************************************************************************/ int Oam::glusterctl(GLUSTER_COMMANDS command, std::string argument1, std::string& argument2, std::string& errmsg) { #ifndef _MSC_VER int user,group; user = getuid(); group = getgid(); string glustercmd = "gluster "; if (user!=0) { glustercmd = "sudo " + glustercmd; } errmsg = ""; switch ( command ) { case (oam::GLUSTER_STATUS): { string command = glustercmd + "volume status"; char buffer[128]; string result = ""; FILE* pipe = popen(command.c_str(), "r"); if (!pipe) exceptionControl("GLUSTER_STATUS", API_FAILURE,"popen() failed"); try { while (!feof(pipe)) { if (fgets(buffer, 128, pipe) != NULL) result += buffer; } } catch (...) { exceptionControl("GLUSTER_STATUS", API_FAILURE); throw; } pclose(pipe); argument2 = result; return 0; } case (oam::GLUSTER_SETDDC): { // The way this was implemented it doesn't seem possible to actually change the value.. return 0; } case (oam::GLUSTER_ASSIGN): { string dbrootID = argument1; string pm = argument2; // build and send msg int returnStatus = sendMsgToProcMgr(GLUSTERASSIGN, pm, FORCEFUL, ACK_YES, dbrootID); if (returnStatus != API_SUCCESS) exceptionControl("GLUSTER_ASSIGN", returnStatus); break; } case (oam::GLUSTER_UNASSIGN): { string dbrootID = argument1; string pm = argument2; // build and send msg int returnStatus = sendMsgToProcMgr(GLUSTERUNASSIGN, pm, FORCEFUL, ACK_YES, dbrootID); if (returnStatus != API_SUCCESS) exceptionControl("GLUSTER_UNASSIGN", returnStatus); break; } case (oam::GLUSTER_WHOHAS): { // Script returned a string of space separated PMIDs everywhere this is called it expects that return form. // When configuring or adding Modules we need to update DataRedundancyConfig section of configuration file. Config* sysConfig = Config::makeConfig(CalpontConfigFile.c_str()); string dbrootID = argument1; string moduleDBRootIDPMs = "DBRoot" + dbrootID + "PMs"; string msg = sysConfig->getConfig("DataRedundancyConfig",moduleDBRootIDPMs); if (msg.empty()) { exceptionControl("glusterctl", API_FAILURE); } argument2 = msg; return 0; break; } case (oam::GLUSTER_ADD): { int pmID = atoi(argument1.c_str()); int dbrootID = atoi(argument2.c_str()); string password = errmsg; string command = ""; int status; writeLog("glusterctl: GLUSTER_ADD: dbroot = " + argument2 + " pm = " + argument1, LOG_TYPE_DEBUG ); Config* sysConfig = Config::makeConfig(); ModuleTypeConfig moduletypeconfig; getSystemConfig("pm", moduletypeconfig); int dataRedundancyCopies; int dbrootCount; getSystemConfig("DataRedundancyCopies",dataRedundancyCopies); getSystemConfig("DBRootCount",dbrootCount); int numberPMs = moduletypeconfig.ModuleCount; int numberNewPMs = numberPMs - pmID + 1; int numberNewDBRoots = (dbrootCount - dbrootID) + 1; int numberDBRootsPerPM = numberNewDBRoots/numberNewPMs; std::vector dbrootPms[dbrootCount]; DataRedundancySetup DataRedundancyConfigs[numberPMs]; int startDBRootID = dbrootID; for (int pm=(pmID-1); pm < numberPMs; pm++,startDBRootID++) { DataRedundancyConfigs[pm].pmID = (pm+1); string moduleHostName = "ModuleHostName" + itoa(pm+1) + "-1-3"; string moduleIpAddr = "ModuleIPAddr" + itoa(pm+1) + "-1-3"; DataRedundancyConfigs[pm].pmHostname = sysConfig->getConfig("DataRedundancyConfig",moduleHostName); DataRedundancyConfigs[pm].pmIpAddr = sysConfig->getConfig("DataRedundancyConfig",moduleIpAddr); if (DataRedundancyConfigs[pm].pmHostname.empty()) { DataRedundancyConfigs[pm].pmHostname = sysConfig->getConfig("SystemModuleConfig",moduleHostName); } if (DataRedundancyConfigs[pm].pmIpAddr.empty()) { DataRedundancyConfigs[pm].pmIpAddr = sysConfig->getConfig("SystemModuleConfig",moduleIpAddr); } int nextPM = (pm+1); int dbrootCopy = startDBRootID; if (nextPM >= numberPMs) { nextPM=(pmID-1); } for ( int i=0; i= numberPMs) { nextPM=(pmID-1); } if (nextPM == pm) { nextPM++; } if (nextPM >= numberPMs) { nextPM=(pmID-1); } } dbrootCopy += numberNewPMs; } } for (int db=(dbrootID-1); db < dbrootCount; db++) { int newDBrootID = db + 1; string dbrootIDPMs = ""; string moduleDBRootIDPMs = "DBRoot" + itoa(newDBrootID) + "PMs"; for (int pm=(pmID-1); pm < numberPMs; pm++) { if(find(DataRedundancyConfigs[pm].dbrootCopies.begin(),DataRedundancyConfigs[pm].dbrootCopies.end(),newDBrootID) != DataRedundancyConfigs[pm].dbrootCopies.end()) { dbrootPms[db].push_back(DataRedundancyConfigs[pm].pmID); dbrootIDPMs += itoa(DataRedundancyConfigs[pm].pmID); dbrootIDPMs += " "; } } // Store to config and distribute so that GLUSTER_WHOHAS will work sysConfig->setConfig("DataRedundancyConfig", moduleDBRootIDPMs, dbrootIDPMs); } for (int pm=(pmID-1); pm < numberPMs; pm++) { cout << "gluster peer probe " + DataRedundancyConfigs[pm].pmIpAddr << endl; status = system(command.c_str()); if (WEXITSTATUS(status) != 0 ) { cout << "ERROR: peer probe command failed." << endl; command = InstallDir + "/bin/remote_command.sh " + DataRedundancyConfigs[pm].pmIpAddr + " " + password + " 'stat /var/run/glusterd.pid > /dev/null 2>&1'"; status = system(command.c_str()); if (WEXITSTATUS(status) != 0 ) { cout << "ERROR: No glusterd process detected at " << DataRedundancyConfigs[pm].pmIpAddr << "." << endl; cout << " Start and enable glusterd at " << DataRedundancyConfigs[pm].pmIpAddr << "." << endl; } exceptionControl("GLUSTER_ADD", API_FAILURE); } } sleep(5); command = glustercmd + "peer status " + " >> /tmp/glusterCommands.txt 2>&1"; status = system(command.c_str()); if (WEXITSTATUS(status) != 0 ) { cout << "ERROR: command failed: " << command << endl; exit(1); } //Need to wait since peer probe success does not always mean it is ready for volume create command sleep(10); int pmnextbrick[numberPMs]; for (int pm=(pmID-1); pm < numberPMs; pm++) { pmnextbrick[pm]=1; } for (int db=(dbrootID-1); db < dbrootCount; db++) { int newDbrootID = db + 1; command = glustercmd + "volume create dbroot" + itoa(newDbrootID) + " transport tcp replica " + itoa(dataRedundancyCopies) + " "; vector::iterator dbrootPmIter = dbrootPms[db].begin(); for (; dbrootPmIter < dbrootPms[db].end(); dbrootPmIter++ ) { int pm = (*dbrootPmIter) - 1; command += DataRedundancyConfigs[pm].pmIpAddr + ":" + InstallDir +"/gluster/brick" + itoa(pmnextbrick[pm]) + " "; pmnextbrick[pm]++; } command += "force >> /tmp/glusterCommands.txt 2>&1"; cout << "Gluster create and start volume dbroot" << itoa(newDbrootID) << "..."; status = system(command.c_str()); if (WEXITSTATUS(status) != 0 ) { writeLog("ERROR: command failed: " + command,LOG_TYPE_DEBUG); exceptionControl("GLUSTER_ADD", API_FAILURE); } if (user != 0) { command = "sudo gluster volume set dbroot" + itoa(newDbrootID) + " storage.owner-uid " + itoa(user) + " >> /tmp/glusterCommands.txt 2>&1";; status = system(command.c_str()); if (WEXITSTATUS(status) != 0 ) { writeLog("ERROR: command failed: ",LOG_TYPE_DEBUG); exceptionControl("GLUSTER_ADD", API_FAILURE); } command = "sudo gluster volume set dbroot" + itoa(newDbrootID) + " storage.owner-gid " + itoa(group) + " >> /tmp/glusterCommands.txt 2>&1";; status = system(command.c_str()); if (WEXITSTATUS(status) != 0 ) { writeLog("ERROR: command failed: ",LOG_TYPE_DEBUG); exceptionControl("GLUSTER_ADD", API_FAILURE); } } command = glustercmd + "volume start dbroot" + itoa(newDbrootID) + " >> /tmp/glusterCommands.txt 2>&1"; status = system(command.c_str()); if (WEXITSTATUS(status) != 0 ) { writeLog("ERROR: command failed: ",LOG_TYPE_DEBUG); exceptionControl("GLUSTER_ADD", API_FAILURE); } cout << "DONE" << endl; } try { sysConfig->write(); } catch(...) { exceptionControl("sysConfig->write", API_FAILURE); } distributeConfigFile("system"); for (int pm=(pmID-1); pm < numberPMs; pm++) { for (int i=0; igetConfig("SystemModuleConfig",ModuleDBRootID); string command = "" + DataRedundancyConfigs[pm].pmIpAddr + ":/dbroot" + dbr + " " + InstallDir + "/data" + dbr + " glusterfs defaults,direct-io-mode=enable 00"; string toPM = "pm" + itoa(pm+1); distributeFstabUpdates(command,toPM); } } break; } case (oam::GLUSTER_DELETE): { string dbrootID = argument1; string command = ""; int status; writeLog("glusterctl: GLUSTER_DELETE: dbroot = " + dbrootID, LOG_TYPE_DEBUG ); command = glustercmd + "--mode=script volume stop dbroot" + dbrootID + " >> /tmp/glusterCommands.txt 2>&1"; status = system(command.c_str()); if (WEXITSTATUS(status) != 0 ) { writeLog("ERROR: command failed: ",LOG_TYPE_DEBUG); exceptionControl("GLUSTER_DELETE", API_FAILURE); } // give time for transaction to finish after stopping sleep(10); command = glustercmd + " --mode=script volume delete dbroot" + dbrootID + " >> /tmp/glusterCommands.txt 2>&1"; status = system(command.c_str()); if (WEXITSTATUS(status) != 0 ) { writeLog("ERROR: command failed: ",LOG_TYPE_DEBUG); exceptionControl("GLUSTER_DELETE", API_FAILURE); } break; } case (oam::GLUSTER_PEERPROBE): { string ipAddress = argument1; string password = argument2; string command = ""; int status; command = glustercmd + "peer probe " + ipAddress + " >> /tmp/glusterCommands.txt 2>&1"; cout << "gluster peer probe " + ipAddress << endl; status = system(command.c_str()); if (WEXITSTATUS(status) != 0 ) { cout << "ERROR: peer probe command failed." << endl; command = InstallDir + "/bin/remote_command.sh " + ipAddress + " " + password + " 'stat /var/run/glusterd.pid > /dev/null 2>&1'"; status = system(command.c_str()); if (WEXITSTATUS(status) != 0 ) { cout << "ERROR: No glusterd process detected at " << ipAddress << "." << endl; cout << " Start and enable glusterd at " << ipAddress << "." << endl; } return 1; } break; } default: break; } #endif return 0; } /****************************************************************************************** * @brief changeMyCnf * * purpose: change my.cnf and add if value is not present to mysqld section * ******************************************************************************************/ bool Oam::changeMyCnf( std::string paramater, std::string value ) { string mycnfFile = startup::StartUp::installDir() + "/mysql/my.cnf"; ifstream file (mycnfFile.c_str()); if (!file) { cout << "File not found: " << mycnfFile << endl; return false; } vector lines; char line[200]; string buf; bool foundIt = false; while (file.getline(line, 200)) { buf = line; string::size_type pos = buf.find(paramater,0); if ( pos == 0 ) { string::size_type pos = buf.find("=",0); if ( pos != string::npos ) { buf = paramater + " = " + value; foundIt = true; } } //output to temp file lines.push_back(buf); } if (!foundIt) { // Its not in the file go back to beginning of file file.clear(); file.seekg(0, ios::beg); lines.clear(); while (file.getline(line, 200)) { buf = line; string::size_type pos = buf.find("[mysqld]",0); if ( pos != string::npos ) { lines.push_back(buf); buf = "loose-" + paramater + " = " + value; } //output to temp file lines.push_back(buf); } } file.close(); unlink (mycnfFile.c_str()); ofstream newFile (mycnfFile.c_str()); //create new file int fd = open(mycnfFile.c_str(), O_RDWR|O_CREAT, 0664); copy(lines.begin(), lines.end(), ostream_iterator(newFile, "\n")); newFile.close(); close(fd); return true; } /****************************************************************************************** * @brief enableMySQLRep * * purpose: enable MySQL Replication on the system * ******************************************************************************************/ bool Oam::enableMySQLRep( std::string password ) { // build and send msg int returnStatus = sendMsgToProcMgr(ENABLEMYSQLREP, password, FORCEFUL, ACK_YES); if (returnStatus != API_SUCCESS) exceptionControl("enableMySQLRep", returnStatus); return true; } /****************************************************************************************** * @brief disableMySQLRep * * purpose: enable MySQL Replication on the system * ******************************************************************************************/ bool Oam::disableMySQLRep() { // build and send msg int returnStatus = sendMsgToProcMgr(DISABLEMYSQLREP, oam::UnassignedName, FORCEFUL, ACK_YES); if (returnStatus != API_SUCCESS) exceptionControl("disableMySQLRep", returnStatus); return true; } /*************************************************************************** * * Function: checkGlusterLog * * Purpose: check Gluster Log after a Gluster control call * ****************************************************************************/ int Oam::checkGlusterLog(std::string logFile, std::string& msg) { if (checkLogStatus(logFile, "OK")) { if ( logFile == "/tmp/gluster_howhas.log" ) { ifstream File(logFile.c_str()); char line[100]; string buf; while (File.getline(line, 100)) { buf = line; string::size_type pos = buf.find("OK",0); if (pos != string::npos) { msg = buf.substr(3,100); return 0; } } msg = ""; return 1; } msg = ""; return 0; } if (checkLogStatus(logFile, "NOTINSTALLED")) { writeLog("checkGlusterLog: NOTINSTALLED", LOG_TYPE_DEBUG ); exceptionControl("glusterctl", API_DISABLED); } if (checkLogStatus(logFile, "FAILED")) { ifstream File(logFile.c_str()); char line[100]; string buf; while (File.getline(line, 100)) { buf = line; string::size_type pos = buf.find("FAILED",0); if (pos != string::npos) { msg = buf.substr(7,100); writeLog("checkGlusterLog: " + buf, LOG_TYPE_ERROR); return 1; } } writeLog("checkGlusterLog: FAILURE", LOG_TYPE_ERROR); if ( logFile == "/tmp/gluster_howhas.log" ) return 2; else exceptionControl("glusterctl", API_FAILURE); } writeLog("checkGlusterLog: FAILURE - no log file match: " + logFile, LOG_TYPE_ERROR); exceptionControl("glusterctl", API_FAILURE); return 1; } /****************************************************************************************** * @brief getMySQLPassword * * purpose: check and get mysql user password * ******************************************************************************************/ std::string Oam::getMySQLPassword() { return oam::UnassignedName; string mysqlUser = "root"; string USER = "root"; char* p= getenv("USER"); if (p && *p) USER = p; string HOME = "/root"; p= getenv("HOME"); if (p && *p) HOME = p; string fileName = HOME + "/.my.cnf"; writeLog("getMySQLPassword: checking: " + fileName, LOG_TYPE_DEBUG); ifstream file (fileName.c_str()); if (!file) { writeLog("getMySQLPassword: doesn't exist: " + fileName, LOG_TYPE_DEBUG); exceptionControl("getMySQLPassword", API_FILE_OPEN_ERROR); } char line[400]; string buf; while (file.getline(line, 400)) { buf = line; string::size_type pos = buf.find(mysqlUser,0); if (pos != string::npos) { file.getline(line, 400); buf = line; pos = buf.find("password",0); if (pos != string::npos) { string::size_type pos1 = buf.find("=",pos); if (pos1 != string::npos) { //password found string password = buf.substr(pos1+1, 80); password.erase(remove_if(password.begin(), password.end(), ::isspace), password.end()); writeLog("getMySQLPassword: password found", LOG_TYPE_DEBUG); return password; } } break; } } file.close(); writeLog("getMySQLPassword: no password found", LOG_TYPE_DEBUG); exceptionControl("getMySQLPassword", API_FAILURE); return oam::UnassignedName; } /****************************************************************************************** * @brief updateFstab * * purpose: check and get mysql user password * ******************************************************************************************/ std::string Oam::updateFstab(std::string device, std::string dbrootID) { writeLog("updateFstab called: " + device + ":" + dbrootID, LOG_TYPE_DEBUG ); //check if entry already exist int user; user = getuid(); string entry; if (user == 0) entry = device + " " + InstallDir + "/data" + dbrootID + " ext2 noatime,nodiratime,noauto 0 0"; else entry = device + " " + InstallDir + "/data" + dbrootID + " ext2 noatime,nodiratime,noauto,user 0 0"; string cmd; if (user == 0) cmd = "grep /data" + dbrootID + " /etc/fstab > /dev/null 2>&1"; else cmd = "sudo grep /data" + dbrootID + " /etc/fstab > /dev/null 2>&1"; int status = system(cmd.c_str()); if (WEXITSTATUS(status) != 0 ) { //update /etc/fstab with mount //update local fstab if (user == 0) cmd = "echo " + entry + " >> /etc/fstab"; else cmd = "sudo echo " + entry + " >> /etc/fstab"; system(cmd.c_str()); } if (user == 0) cmd = "grep /data" + dbrootID + " " + InstallDir + "/local/etc/pm1/fstab > /dev/null 2>&1"; else cmd = "sudo grep /data" + dbrootID + " " + InstallDir + "/local/etc/pm1/fstab > /dev/null 2>&1"; status = system(cmd.c_str()); if (WEXITSTATUS(status) != 0 ) { //use from addmodule later cmd = "touch " + InstallDir + "/local/etc/pm1/fstab;echo " + entry + " >> " + InstallDir + "/local/etc/pm1/fstab"; system(cmd.c_str()); } return entry; } /*************************************************************************** * PRIVATE FUNCTIONS ***************************************************************************/ /*************************************************************************** * * Function: exceptionControl * * Purpose: exception control function * ****************************************************************************/ void Oam::exceptionControl(std::string function, int returnStatus, const char* extraMsg) { std::string msg; switch(returnStatus) { case API_INVALID_PARAMETER: { msg = "Invalid Parameter passed in "; msg.append(function); msg.append(" API"); } break; case API_FILE_OPEN_ERROR: { msg = "File Open error from "; msg.append(function); msg.append(" API"); } break; case API_TIMEOUT: { msg = "Timeout error from "; msg.append(function); msg.append(" API"); } break; case API_DISABLED: { msg = "API Disabled: "; msg.append(function); } break; case API_FILE_ALREADY_EXIST: { msg = "File Already Exist"; } break; case API_ALREADY_IN_PROGRESS: { msg = "Already In Process"; } break; case API_FAILURE_DB_ERROR: { msg = "Database Test Error"; } break; case API_INVALID_STATE: { msg = "Target in an invalid state"; } break; case API_READONLY_PARAMETER: { msg = "Parameter is Read-Only, can't update"; } break; case API_TRANSACTIONS_COMPLETE: { msg = "Finished waiting for transactions"; } break; case API_CONN_REFUSED: { msg = "Connection refused"; } break; case API_CANCELLED: { msg = "Operation Cancelled"; } break; default: { msg = "API Failure return in "; msg.append(function); msg.append(" API"); } break; } // end of switch if (extraMsg) { msg.append(":\n "); msg.append(extraMsg); } throw runtime_error(msg); } /*************************************************************************** * * Function: getFreeSpace * * Purpose: get free disk space in bytes * ****************************************************************************/ double Oam::getFreeSpace(std::string path) { double free_space = 0.0; #ifdef _MSC_VER ULARGE_INTEGER freeBytesAvail; if (GetDiskFreeSpaceEx(path.c_str(), &freeBytesAvail, 0, 0) != 0) free_space = (double)freeBytesAvail.QuadPart; #else struct statfs statBuf; if ( statfs(path.c_str(), &statBuf) == 0) { free_space = ((double)statBuf.f_bavail) * ((double)statBuf.f_bsize); return free_space; } else { exceptionControl("statvfs failed", API_FAILURE ); } #endif return free_space; } /*************************************************************************** * * Function: itoa * * Purpose: Integer to ASCII convertor * ****************************************************************************/ std::string Oam::itoa(const int i) { stringstream ss; ss << i; return ss.str(); } /*************************************************************************** * * Function: sendMsgToProcMgr * * Purpose: Build and send request message to Process Manager * ****************************************************************************/ int Oam::sendMsgToProcMgr(messageqcpp::ByteStream::byte requestType, const std::string name, GRACEFUL_FLAG gracefulflag, ACK_FLAG ackflag, const std::string argument1, const std::string argument2, int timeout) { if (!checkSystemRunning()) return API_CONN_REFUSED; int returnStatus = API_SUCCESS; //default ByteStream msg; ByteStream receivedMSG; ByteStream::byte msgType; ByteStream::byte actionType; string target; ByteStream::byte status; // get current requesting process, an error will occur if process is a UI tool (not kept in Status Table) // this will be used to determine if this is a manually or auto request down within Process-Monitor bool requestManual; myProcessStatus_t t; try { t = getMyProcessStatus(); requestManual = false; // set to auto } catch (...) { requestManual = true; // set to manual } // setup message msg << (ByteStream::byte) REQUEST; msg << requestType; msg << name; msg << (ByteStream::byte) gracefulflag; msg << (ByteStream::byte) ackflag; msg << (ByteStream::byte) requestManual; if (!argument1.empty()) msg << argument1; if (!argument2.empty()) msg << argument2; try { //send the msg to Process Manager MessageQueueClient procmgr("ProcMgr"); procmgr.write(msg); // check for Ack msg if needed if ( ackflag == ACK_YES ) { // wait for ACK from Process Manager struct timespec ts = { timeout, 0 }; receivedMSG = procmgr.read(&ts); if (receivedMSG.length() > 0) { receivedMSG >> msgType; receivedMSG >> actionType; receivedMSG >> target; receivedMSG >> status; if ( msgType == oam::ACK && actionType == requestType && target == name) { // ACK for this request returnStatus = status; } } else // timeout returnStatus = API_TIMEOUT; } else // No ACK, assume write success returnStatus = API_SUCCESS; // shutdown connection procmgr.shutdown(); } catch (std::runtime_error&) { //There's other reasons, but this is the most likely... returnStatus = API_CONN_REFUSED; } catch (std::exception&) { returnStatus = API_FAILURE; } catch (...) { returnStatus = API_FAILURE; } return returnStatus; } /*************************************************************************** * * Function: sendMsgToProcMgr2 * * Purpose: Build and send request message to Process Manager * ****************************************************************************/ int Oam::sendMsgToProcMgr2(messageqcpp::ByteStream::byte requestType, DeviceNetworkList devicenetworklist, GRACEFUL_FLAG gracefulflag, ACK_FLAG ackflag, const std::string password, const std::string mysqlpw) { if (!checkSystemRunning()) return API_CONN_REFUSED; int returnStatus = API_TIMEOUT; //default ByteStream msg; ByteStream receivedMSG; ByteStream::byte msgType; ByteStream::byte actionType; ByteStream::byte status; // get current requesting process, an error will occur if process is a UI tool (not kept in Status Table) // this will be used to determine if this is a manually or auto request down within Process-Monitor bool requestManual; myProcessStatus_t t; try { t = getMyProcessStatus(); requestManual = false; // set to auto } catch (...) { requestManual = true; // set to manual } // setup message msg << (ByteStream::byte) REQUEST; msg << requestType; msg << (std::string) " "; msg << (ByteStream::byte) gracefulflag; msg << (ByteStream::byte) ackflag; msg << (ByteStream::byte) requestManual; msg << (uint16_t) devicenetworklist.size(); DeviceNetworkList::iterator pt = devicenetworklist.begin(); for( ; pt != devicenetworklist.end() ; pt++) { msg << (*pt).DeviceName; if ( (*pt).UserTempDeviceName.empty() ) msg << " "; else msg << (*pt).UserTempDeviceName; if ( (*pt).DisableState.empty() ) msg << " "; else msg << (*pt).DisableState; msg << (uint16_t) (*pt).hostConfigList.size(); HostConfigList::iterator pt1 = (*pt).hostConfigList.begin(); for( ; pt1 != (*pt).hostConfigList.end() ; pt1++) { msg << (*pt1).IPAddr; msg << (*pt1).HostName; msg << (*pt1).NicID; } } msg << password; msg < 0) { receivedMSG >> msgType; receivedMSG >> actionType; receivedMSG >> status; if ( msgType == oam::ACK && actionType == requestType) { // ACK for this request returnStatus = status; } } else // timeout returnStatus = API_TIMEOUT; } else // No ACK, assume write success returnStatus = API_SUCCESS; // shutdown connection procmgr.shutdown(); } catch(...) { returnStatus = API_FAILURE; } return returnStatus; } /*************************************************************************** * * Function: sendMsgToProcMgr3 * * Purpose: Build and send Alarm request message to Process Manager * ****************************************************************************/ int Oam::sendMsgToProcMgr3(messageqcpp::ByteStream::byte requestType, AlarmList& alarmlist, const std::string date) { if (!checkSystemRunning()) return API_CONN_REFUSED; int returnStatus = API_SUCCESS; //default ByteStream msg; ByteStream receivedMSG; ByteStream::byte msgType; ByteStream::byte actionType; ByteStream::byte status; // setup message msg << requestType; msg << date; try { //send the msg to Process Manager MessageQueueClient procmgr("ProcMgr"); procmgr.write(msg); // wait 30 seconds for ACK from Process Manager struct timespec ts = { 30, 0 }; receivedMSG = procmgr.read(&ts); if (receivedMSG.length() > 0) { receivedMSG >> msgType; receivedMSG >> actionType; receivedMSG >> status; if ( msgType == oam::ACK && actionType == requestType && status == API_SUCCESS ) { ByteStream::byte numAlarms; while(true) { //number of alarms receivedMSG >> numAlarms; //check for end-of-list if ( numAlarms == 0) break; for ( int i = 0 ; i < numAlarms ; i++ ) { Alarm alarm; ByteStream::doublebyte value; string svalue; receivedMSG >> value; alarm.setAlarmID(value); receivedMSG >> svalue; alarm.setDesc(svalue); receivedMSG >> value; alarm.setSeverity(value); receivedMSG >> svalue; alarm.setTimestamp(svalue); receivedMSG >> svalue; alarm.setSname(svalue); receivedMSG >> svalue; alarm.setPname(svalue); receivedMSG >> svalue; alarm.setComponentID(svalue); alarmlist.insert (AlarmList::value_type(alarm.getTimestampSeconds(), alarm)); } break; } } else returnStatus = API_FAILURE; } else // timeout returnStatus = API_TIMEOUT; // shutdown connection procmgr.shutdown(); } catch(...) { returnStatus = API_FAILURE; } return returnStatus; } /*************************************************************************** * * Function: sendMsgToProcMgrWithStatus * * Purpose: Build and send a request message to Process Manager * Check for status messages and display on stdout. * * This is used only in manual mode. * ****************************************************************************/ int Oam::sendMsgToProcMgrWithStatus(messageqcpp::ByteStream::byte requestType, const std::string name, GRACEFUL_FLAG gracefulflag, ACK_FLAG ackflag, const std::string argument1, const std::string argument2, int timeout) { if (!checkSystemRunning()) return API_CONN_REFUSED; int returnStatus = API_STILL_WORKING; ByteStream msg; ByteStream receivedMSG; ByteStream::byte msgType; ByteStream::byte actionType; string target; ByteStream::byte status; struct timespec ts = {timeout, 0}; bool requestManual = true; std::stringstream buffer; BRM::DBRM dbrm; #ifndef _MSC_VER struct sigaction ctrlcHandler; struct sigaction oldCtrlcHandler; memset(&ctrlcHandler, 0, sizeof(ctrlcHandler)); #endif // setup message msg << (ByteStream::byte) REQUEST; msg << requestType; msg << name; msg << (ByteStream::byte) gracefulflag; msg << (ByteStream::byte) ackflag; msg << (ByteStream::byte) requestManual; if (!argument1.empty()) msg << argument1; if (!argument2.empty()) msg << argument2; if (gracefulflag == GRACEFUL_WAIT) { // Control-C signal to terminate the shutdown command ctrlc = 0; #ifdef _MSC_VER //FIXME: #else ctrlcHandler.sa_handler = handleControlC; sigaction(SIGINT, &ctrlcHandler, &oldCtrlcHandler); #endif } try { //send the msg to Process Manager MessageQueueClient procmgr("ProcMgr"); procmgr.write(msg); // check for Ack msg if needed if (ackflag == ACK_YES) { while (returnStatus == API_STILL_WORKING) { // wait for ACK from Process Manager receivedMSG = procmgr.read(&ts); // If user hit ctrl-c, we've been cancelled if (ctrlc == 1) { writeLog("Clearing System Shutdown pending", LOG_TYPE_INFO ); dbrm.setSystemShutdownPending(false); dbrm.setSystemSuspendPending(false); returnStatus = API_CANCELLED; break; } if (receivedMSG.length() > 0) { receivedMSG >> msgType; receivedMSG >> actionType; receivedMSG >> target; receivedMSG >> status; if ( msgType == oam::ACK && actionType == requestType && target == name) { if (status == API_TRANSACTIONS_COMPLETE) { cout << endl << " System being " << name << ", please wait..." << flush; // More work to wait on.... // At this point, the requirement is to have ctrl-c drop us out of calpont console // so we'll restore the handler to default. if (gracefulflag == GRACEFUL_WAIT) { #ifdef _MSC_VER //FIXME: #else sigaction(SIGINT, &oldCtrlcHandler, NULL); #endif } } else { returnStatus = status; } } if (returnStatus == API_STILL_WORKING) { cout << "." << flush; } } else // timeout { returnStatus = API_TIMEOUT; } } } else { // No ACK, assume write success returnStatus = API_SUCCESS; } // shutdown connection procmgr.shutdown(); } catch (std::runtime_error&) { //There's other reasons, but this is the most likely... returnStatus = API_CONN_REFUSED; } catch (std::exception&) { returnStatus = API_FAILURE; } catch (...) { returnStatus = API_FAILURE; } if (gracefulflag == GRACEFUL_WAIT) { // Just in case we errored out and bypassed the normal restore, // restore ctrl-c to previous handler. #ifdef _MSC_VER //FIXME: #else sigaction(SIGINT, &oldCtrlcHandler, NULL); #endif } return returnStatus; } /*************************************************************************** * * Function: validateProcess * * Purpose: Validate Process Name * ****************************************************************************/ int Oam::validateProcess(const std::string moduleName, std::string processName) { SystemProcessStatus systemprocessstatus; ProcessStatus processstatus; try { getProcessStatus(systemprocessstatus); for( unsigned int i = 0 ; i < systemprocessstatus.processstatus.size(); i++) { if ( systemprocessstatus.processstatus[i].Module == moduleName && systemprocessstatus.processstatus[i].ProcessName == processName) // found it return API_SUCCESS; } } catch(...) { return API_INVALID_PARAMETER; } return API_INVALID_PARAMETER; } /*************************************************************************** * * Function: sendStatusUpdate * * Purpose: Send Status Update to Process Monitor * ****************************************************************************/ void Oam::sendStatusUpdate(ByteStream obs, ByteStream::byte returnRequestType) { if (!checkSystemRunning()) return; for ( int i = 0 ; i < 5 ; i ++) { try { MessageQueueClient processor("ProcStatusControl"); // processor.syncProto(false); ByteStream ibs; try { struct timespec ts = { 3, 0 }; processor.write(obs, &ts); } catch(...) { processor.shutdown(); throw std::runtime_error("write error"); } try { struct timespec ts1 = { 15, 0 }; ibs = processor.read(&ts1); } catch(...) { processor.shutdown(); throw std::runtime_error("read error"); } ByteStream::byte returnRequestType; if (ibs.length() > 0) { ibs >> returnRequestType; if ( returnRequestType == returnRequestType ) { processor.shutdown(); return; } } else { // timeout occurred, shutdown connection and retry processor.shutdown(); throw std::runtime_error("timeout"); return; } } catch(...) {} } return; } /*************************************************************************** * * Function: amazonReattach * * Purpose: Amazon EC2 volume reattach needed * ****************************************************************************/ void Oam::amazonReattach(std::string toPM, dbrootList dbrootConfigList, bool attach) { //if amazon cloud with external volumes, do the detach/attach moves string cloud; string DBRootStorageType; try { getSystemConfig("Cloud", cloud); getSystemConfig("DBRootStorageType", DBRootStorageType); } catch(...) {} if ( (cloud == "amazon-ec2" || cloud == "amazon-vpc") && DBRootStorageType == "external" ) { writeLog("amazonReattach function started ", LOG_TYPE_DEBUG ); //get Instance Name for to-pm string toInstanceName = oam::UnassignedName; try { ModuleConfig moduleconfig; getSystemConfig(toPM, moduleconfig); HostConfigList::iterator pt1 = moduleconfig.hostConfigList.begin(); toInstanceName = (*pt1).HostName; } catch(...) {} if ( toInstanceName == oam::UnassignedName || toInstanceName.empty() ) { cout << " ERROR: amazonReattach, invalid Instance Name for " << toPM << endl; writeLog("ERROR: amazonReattach, invalid Instance Name " + toPM, LOG_TYPE_ERROR ); exceptionControl("amazonReattach", API_INVALID_PARAMETER); } dbrootList::iterator pt3 = dbrootConfigList.begin(); for( ; pt3 != dbrootConfigList.end() ; pt3++) { string dbrootid = *pt3; string volumeNameID = "PMVolumeName" + dbrootid; string volumeName = oam::UnassignedName; string deviceNameID = "PMVolumeDeviceName" + dbrootid; string deviceName = oam::UnassignedName; try { getSystemConfig( volumeNameID, volumeName); getSystemConfig( deviceNameID, deviceName); } catch(...) {} if ( volumeName == oam::UnassignedName || deviceName == oam::UnassignedName ) { cout << " ERROR: amazonReattach, invalid configure " + volumeName + ":" + deviceName << endl; writeLog("ERROR: amazonReattach, invalid configure " + volumeName + ":" + deviceName, LOG_TYPE_ERROR ); exceptionControl("amazonReattach", API_INVALID_PARAMETER); } if (!attach) { //send msg to to-pm to umount volume int returnStatus = sendMsgToProcMgr(UNMOUNT, dbrootid, FORCEFUL, ACK_YES); if (returnStatus != API_SUCCESS) { writeLog("ERROR: amazonReattach, umount failed on " + dbrootid, LOG_TYPE_ERROR ); } } if (!detachEC2Volume(volumeName)) { cout << " ERROR: amazonReattach, detachEC2Volume failed on " + volumeName << endl; writeLog("ERROR: amazonReattach, detachEC2Volume failed on " + volumeName , LOG_TYPE_ERROR ); exceptionControl("amazonReattach", API_FAILURE); } writeLog("amazonReattach, detachEC2Volume passed on " + volumeName , LOG_TYPE_DEBUG ); if (!attachEC2Volume(volumeName, deviceName, toInstanceName)) { cout << " ERROR: amazonReattach, attachEC2Volume failed on " + volumeName + ":" + deviceName + ":" + toInstanceName << endl; writeLog("ERROR: amazonReattach, attachEC2Volume failed on " + volumeName + ":" + deviceName + ":" + toInstanceName, LOG_TYPE_ERROR ); exceptionControl("amazonReattach", API_FAILURE); } writeLog("amazonReattach, attachEC2Volume passed on " + volumeName + ":" + toPM, LOG_TYPE_DEBUG ); } } } /*************************************************************************** * * Function: mountDBRoot * * Purpose: Send msg to ProcMon to mount/unmount a external DBRoot * ****************************************************************************/ void Oam::mountDBRoot(dbrootList dbrootConfigList, bool mount) { //if external volumes, mount to device string DBRootStorageType; try { getSystemConfig("DBRootStorageType", DBRootStorageType); } catch(...) {} string DataRedundancyConfig = "n"; try { getSystemConfig( "DataRedundancyConfig", DataRedundancyConfig); } catch(...) { DataRedundancyConfig = "n"; } if ( (DBRootStorageType == "external" && DataRedundancyConfig == "n") || (DataRedundancyConfig == "y" && !mount) ) { dbrootList::iterator pt3 = dbrootConfigList.begin(); for( ; pt3 != dbrootConfigList.end() ; pt3++) { string dbrootid = *pt3; int mountCmd = oam::MOUNT; if (!mount) { mountCmd = oam::UNMOUNT; writeLog("mountDBRoot api, umount dbroot" + dbrootid, LOG_TYPE_DEBUG); } else writeLog("mountDBRoot api, mount dbroot" + dbrootid, LOG_TYPE_DEBUG); //send msg to to-pm to umount volume int returnStatus = sendMsgToProcMgr(mountCmd, dbrootid, FORCEFUL, ACK_YES); if (returnStatus != API_SUCCESS) { if ( mountCmd == oam::MOUNT ) { writeLog("ERROR: mount failed on dbroot" + dbrootid, LOG_TYPE_ERROR ); cout << " ERROR: mount failed on dbroot" + dbrootid << endl; } else { writeLog("ERROR: unmount failed on dbroot" + dbrootid, LOG_TYPE_ERROR ); cout << " ERROR: unmount failed on dbroot" + dbrootid << endl; exceptionControl("mountDBRoot", API_FAILURE); } } } } return; } /****************************************************************************************** * @brief writeLog * * purpose: Write the message to the log * ******************************************************************************************/ void Oam::writeLog(const string logContent, const LOG_TYPE logType) { LoggingID lid(8); MessageLog ml(lid); Message msg; Message::Args args; args.add(logContent); msg.format(args); switch(logType) { case LOG_TYPE_DEBUG: ml.logDebugMessage(msg); break; case LOG_TYPE_INFO: ml.logInfoMessage(msg); break; case LOG_TYPE_WARNING: ml.logWarningMessage(msg); break; case LOG_TYPE_ERROR: ml.logErrorMessage(msg); break; case LOG_TYPE_CRITICAL: ml.logCriticalMessage(msg); break; } return; } /*************************************************************************** * * Function: waitForSystem * * Purpose: When a Shutdown, stop, restart or suspend * operation is requested but there are active * transactions of some sort, We wait for all * transactions to close before performing the * action. ****************************************************************************/ bool Oam::waitForSystem(PROC_MGT_MSG_REQUEST request, messageqcpp::IOSocket& ios, messageqcpp::ByteStream& stillWorkingMsg) { // Use ios to send back periodic still working messages BRM::DBRM dbrm; execplan::SessionManager sessionManager; bool bIsDbrmUp; BRM::SIDTIDEntry blockingsid; std::vector tableLocks; bool bActiveTransactions = true; bool bRollback; bool bForce; bool ret = false; size_t idx; try { while (bActiveTransactions) { sleep(3); ios.write(stillWorkingMsg); bActiveTransactions = false; // Any table locks still set? tableLocks = dbrm.getAllTableLocks(); for (idx = 0; idx < tableLocks.size(); ++idx) { if (dbrm.checkOwner(tableLocks[idx].id)) { bActiveTransactions = true; break; } } // Any active transactions? if (sessionManager.checkActiveTransaction(0, bIsDbrmUp, blockingsid)) { bActiveTransactions = true; } // check to see if the user canceled the request. if (request == SUSPENDWRITES) { if (dbrm.getSystemSuspendPending(bRollback) == 0) // Means we no longer are going to suspend { writeLog("System Suspend Canceled in wait", LOG_TYPE_INFO ); break; } } else { if (dbrm.getSystemShutdownPending(bRollback, bForce) == 0) // Means we no longer are going to shutdown { writeLog("System Shutdown Canceled in wait", LOG_TYPE_INFO ); break; } } if (!bActiveTransactions) { ret = true; } } } catch (...) { writeLog("Communication with calpont console failed while waiting for transactions", LOG_TYPE_ERROR); } // writeLog("Returning from wait with value " + itoa(ret), LOG_TYPE_INFO ); return ret; } int Oam::readHdfsActiveAlarms(AlarmList& alarmList) { int returnStatus = API_FAILURE; Alarm alarm; // the alarm file will be pushed to all nodes every 10 seconds, retry 1 second for (int i = 0; i < 10 && returnStatus != API_SUCCESS; i++) { try { ifstream activeAlarm(ACTIVE_ALARM_FILE.c_str(), ios::in); if (!activeAlarm.is_open()) { // file may be temporary not available due to dpcp. usleep(10000); activeAlarm.open(ACTIVE_ALARM_FILE.c_str(), ios::in); if (!activeAlarm.is_open()) { // still cannot open, treat as no activeAlarms file. returnStatus = API_SUCCESS; continue; } } // read from opened file. while (!activeAlarm.eof() && activeAlarm.good()) { activeAlarm >> alarm; if (alarm.getAlarmID() != INVALID_ALARM_ID) alarmList.insert (AlarmList::value_type(INVALID_ALARM_ID, alarm)); } activeAlarm.close(); returnStatus = API_SUCCESS; } catch (...) { } // wait a second and try again if (returnStatus != API_SUCCESS) usleep (100000); } return returnStatus; } bool Oam::checkSystemRunning() { // string cmd = startup::StartUp::installDir() + "/bin/columnstore status > /tmp/status.log"; // system(cmd.c_str()); struct stat st; if (stat("/var/lock/subsys/columnstore", &st) == 0) { return true; } if (geteuid() != 0) { // not root user // The stat above may fail for non-root because of permissions // This is a non-optimal solution string cmd = "pgrep ProcMon > /dev/null 2>&1"; if (system(cmd.c_str()) == 0) { return true; } } return false; } } //namespace oam namespace procheartbeat { /* ProcHeartbeat::ProcHeartbeat() {} ProcHeartbeat::~ProcHeartbeat() {} */ /******************************************************************** * * Register for Proc Heartbeat * ********************************************************************/ /* void ProcHeartbeat::registerHeartbeat(int ID) { Oam oam; // get current Module name string Module; oamModuleInfo_t st; try { st = getModuleInfo(); Module = boost::get<0>(st); } catch (...) { exceptionControl("registerHeartbeat", API_FAILURE); } // get current process Name string processName; myProcessStatus_t t; try { t = getMyProcessStatus(); processName = boost::get<1>(t); } catch (...) { exceptionControl("registerHeartbeat", API_FAILURE); } ByteStream msg; // setup message msg << (ByteStream::byte) HEARTBEAT_REGISTER; msg << Module; msg << processName; msg << (ByteStream::byte) ID; try { //send the msg to Process Manager MessageQueueClient procmgr("ProcHeartbeatControl"); procmgr.write(msg); procmgr.shutdown(); } catch(...) { exceptionControl("registerHeartbeat", API_FAILURE); } } */ /******************************************************************** * * De-Register for Proc Heartbeat * ********************************************************************/ /* void ProcHeartbeat::deregisterHeartbeat(int ID) { Oam oam; // get current Module name string Module; oamModuleInfo_t st; try { st = getModuleInfo(); Module = boost::get<0>(st); } catch (...) { exceptionControl("deregisterHeartbeat", API_FAILURE); } // get current process Name string processName; myProcessStatus_t t; try { t = getMyProcessStatus(); processName = boost::get<1>(t); } catch (...) { exceptionControl("deregisterHeartbeat", API_FAILURE); } ByteStream msg; // setup message msg << (ByteStream::byte) HEARTBEAT_DEREGISTER; msg << Module; msg << processName; msg << (ByteStream::byte) ID; try { //send the msg to Process Manager MessageQueueClient procmgr("ProcHeartbeatControl"); procmgr.write(msg); procmgr.shutdown(); } catch(...) { exceptionControl("deregisterHeartbeat", API_FAILURE); } } */ /******************************************************************** * * Send Proc Heartbeat * ********************************************************************/ /* void ProcHeartbeat::sendHeartbeat(int ID, oam::ACK_FLAG ackFlag) { Oam oam; // get process heartbeat period int processHeartbeatPeriod = 60; //default try { getSystemConfig("ProcessHeartbeatPeriod", processHeartbeatPeriod); } catch(...) { } //skip sending if Heartbeat is disable if( processHeartbeatPeriod == -1 ) exceptionControl("sendHeartbeat", API_DISABLED); // get current Module name string Module; oamModuleInfo_t st; try { st = getModuleInfo(); Module = boost::get<0>(st); } catch (...) { exceptionControl("sendHeartbeat", API_FAILURE); } // get current process Name string processName; myProcessStatus_t t; try { t = getMyProcessStatus(); processName = boost::get<1>(t); } catch (...) { exceptionControl("sendHeartbeat", API_FAILURE); } ByteStream msg; // setup message msg << (ByteStream::byte) HEARTBEAT_SEND; msg << Module; msg << processName; msg << getCurrentTime(); msg << (ByteStream::byte) ID; msg << (ByteStream::byte) ackFlag; try { //send the msg to Process Manager MessageQueueClient procmgr("ProcHeartbeatControl"); procmgr.write(msg); //check for ACK if ( ackFlag == oam::ACK_YES ) { ByteStream ackMsg; ByteStream::byte type; // wait for ACK from Process Manager struct timespec ts = { processHeartbeatPeriod, 0 }; ackMsg = procmgr.read(&ts); if (ackMsg.length() > 0) { ackMsg >> type; if ( type != HEARTBEAT_SEND ) { //Ack not received procmgr.shutdown(); exceptionControl("sendHeartbeat", API_TIMEOUT); } } else { procmgr.shutdown(); exceptionControl("sendHeartbeat", API_TIMEOUT); } } procmgr.shutdown(); } catch(...) { exceptionControl("sendHeartbeat", API_FAILURE); } } */ } // end of namespace // vim:ts=4 sw=4: