//#include "StdAfx.h" #include "host.hpp" #define MAX_PARALLEL_THREAD_HOST 5 // Static members boost::mutex host::host_move_mutex; // Constructor host :: host(presetHandler pHandle, CLIHandler *cHandle, outputHandler *oHandle, int nHostType) :m_pOutputHandle(NULL),m_pSeqController(NULL), m_pParallelHost(NULL),m_pConnectionHandle(NULL), m_pTempFilePtr(NULL),m_pStrHostSpecificPaths(NULL) { m_pCommonOutputHandle = oHandle; m_pCLIHandle = cHandle; m_bIsSSHSupported = true; m_bConfigJustOnce = false; m_HostType = nHostType; m_nBeginID = 0; m_nEndID = 0; m_bOraclePresent = false; m_bStart = false; m_pPresetHandle = pHandle; m_pOutputHandle = new outputHandler(); m_pSeqController = new controller(); m_nHistoInterval = m_pCLIHandle->getSampleInterval(); m_nHistoCount = m_pCLIHandle->getSamples(); m_nHistoTotalSecs = (m_pCLIHandle->getSampleTime())*60; m_nIterationNumber = 0; m_strOracleLogin = STR_ORACLE_DEFAULT_LOGIN; m_strRunAsUser = ""; m_bSysDBAFlag = false; m_strSqlPlus = STR_SQL_PLUS; if(m_pCLIHandle->getAppFlag()) { setAppParams(); } m_pStrHostSpecificPaths = new string[NUM_HOST_SPECIFIC_PATHS]; bRHEL5 = false; bquickPoststatsFlag = false; startTime = 0; } host :: ~host() { SAFE_DELETE(m_pOutputHandle); SAFE_DELETE(m_pSeqController); SAFE_ARRAY_DELETE(m_pStrHostSpecificPaths); } void host :: ProcessCommands(int iterNum, boost::barrier *serThreadBar) { try { bool bWindows = false; #ifdef WIN32 bWindows = true; #endif m_nIterationNumber = iterNum; int nMaxNumOfIterations = m_pCLIHandle->getNumberOfIter(); m_pCommonOutputHandle->writeDataToLogFile(STR_INFO, m_strHostName, "Connecting to Host."); if(!m_bStart) { m_strHostType = GetHostOSType(); // Added to get the OS Version for Linux getOSVersion(); m_bStart = true; if(m_strHostType.empty()) { m_pCommonOutputHandle->writeDataToLogFile(STR_ERROR, m_strHostName, "Exiting as Host type not identified properly"); m_pCommonOutputHandle->writeDataToLogFile(STR_INFO, m_strHostName, "Please check RSH connectivity"); } GenerateHeader(serThreadBar); } if(!bWindows || (m_HostType == HOST_REMOTE)) { GetHostSpecificPaths(); } time_t cmdStartTime; time(&cmdStartTime); time(&startTime); string dateStr = ProcessDateCommand(serThreadBar); string temp = STR_ITERATION + boost::lexical_cast(m_nIterationNumber) + "/" + boost::lexical_cast(nMaxNumOfIterations) + ":\n"; m_pCommonOutputHandle->writeDataToLogFile(STR_STATUS, m_strHostName, temp); temp = STR_BEGIN_ITER_NUM; temp.append(boost::lexical_cast(m_nIterationNumber)); m_pCommonOutputHandle->writeDataToLogFile(STR_INFO, m_strHostName, temp); m_pOutputHandle->writeIterToHostFile(m_nIterationNumber, STR_BEGIN_ITER, dateStr); longerRuntimeCmd.clear(); if(m_HostType == HOST_REMOTE && m_pConnectionHandle != NULL) { m_pConnectionHandle->setIterationChanged(true); } bool status = ProcessPrestatCommands(serThreadBar); if(!status) { m_pCommonOutputHandle->writeDataToLogFile(STR_ERROR, m_strHostName, "Failed to execute processPrestatsCommands. "); } (*serThreadBar).wait(); /* StartParallelThread(serThreadBar); //StartParallelThread(serThreadBar, iterationNum); status = ProcessPoststatCommands(serThreadBar); if(!status) { m_pCommonOutputHandle->writeDataToLogFile(STR_ERROR, m_strHostName, "Failed to execute processPoststatsCommands. "); } dateStr = ProcessDateCommand(serThreadBar); time_t cmdEndTime; time(&cmdEndTime); string data="--- EXE-TIME of : Iteration number: "; data.append(boost::lexical_cast(iterNum) + " : "); data.append(boost::lexical_cast(cmdEndTime - cmdStartTime) + " seconds"); m_pCommonOutputHandle->writeDataToLogFile(STR_INFO, m_strHostName, data); m_pOutputHandle->writeIterToHostFile(m_nIterationNumber, STR_END_ITER, dateStr); temp = STR_END_ITER_NUM + boost::lexical_cast(m_nIterationNumber); m_pCommonOutputHandle->writeDataToLogFile(STR_INFO, m_strHostName, temp); //check for long runtime commands if(longerRuntimeCmd.size() != 0) { for(int k = 0; k < (int)longerRuntimeCmd.size(); k++) { string tmp = "Execution time for command \'" + longerRuntimeCmd[k]; tmp.append("\' was more than 2 mins"); m_pCommonOutputHandle->writeDataToLogFile(STR_WARNING, m_strHostName, tmp); } } if( m_nIterationNumber == nMaxNumOfIterations ) { m_pOutputHandle->closeHostFile(); if(m_HostType == HOST_REMOTE && m_pConnectionHandle != NULL) { m_pConnectionHandle->disconnectToFiler(); } } */ } catch(std::exception& e) { string tmp = ""; if(m_HostType == HOST_REMOTE) { tmp = "Exception : Remote Host : processCommands :"; } else { tmp = "Exception : Local Host : processCommands :"; } tmp.append(e.what()); m_pCommonOutputHandle->writeDataToLogFile(STR_ERROR, m_strHostName, tmp); } } void host :: GenerateHeader(boost::barrier *serThreadBar) { try { string headerNote = ("*------------- "); headerNote.append(m_pCLIHandle->getVersion()); headerNote.append(" -------------*"); string header; header.append(" \n"); //print user inputs: map > dataMap = m_pCLIHandle->getCLIDataMap(); map >::iterator iter; for (iter=dataMap.begin(); iter!= dataMap.end(); iter++) { vector data = ((*iter).second); if(((*iter).first.find("passwd")!=string::npos) && data[0].compare("set") ==0) { header.append(printHeader((*iter).first, data[0], "*******")); } else { header.append(printHeader((*iter).first, data[0], data[1])); } } header.append("\n"); m_pOutputHandle->writeDataToHostFile(headerNote, header); if(serThreadBar) { (*serThreadBar).wait(); } } catch(std::exception& e) { string tmp = "Exception : Host : GenerateHeader :"; tmp.append(e.what()); m_pCommonOutputHandle->writeDataToLogFile("ERROR", m_strHostName, tmp); } } void host :: GetHostSpecificPaths() { string strPaths[NUM_HOST_SPECIFIC_PATHS] = {"/opt/sanlun/bin/ /opt/NetApp/santools/sanlun/ /opt/NTAPsanlun/bin/ /opt/NetApp/santools/bin/ /opt/netapp/santools/ /opt/ontap/santools", "/usr/sbin/", "/usr/sbin/ /usr/local/sbin/", "/usr/bin/ /usr/local/bin/", "/usr/bin/"}; string strSearchFor[NUM_HOST_SPECIFIC_PATHS] = {"sanlun", "nfsstat", "iscsi-ls", "sar", "iostat"}; for(int nIndex = 0; nIndex < NUM_HOST_SPECIFIC_PATHS; ++nIndex) { string strPath = SetPaths(strPaths[nIndex], strSearchFor[nIndex]); if(!strPath.empty()) { m_pStrHostSpecificPaths[nIndex] = strPath; } //m_pStrHostSpecificPaths.push_back(strPath); } } string host :: SetPaths(string strPath, string strCmdToFind) { string strCorrectPath = ""; vector vec_strPaths = tokenizeString(strPath, " "); for(size_t nIndex = 0; nIndex < vec_strPaths.size(); ++nIndex) { string strTestPath = vec_strPaths.at(nIndex); string strCmd = "ls " + strTestPath; strCmd = strCmd + strCmdToFind; strCmd = strCmd + " 2>/dev/null | wc -l "; vector vec_strRes; bool bFlag = ProcessCommand(strCmd, false, NULL, &vec_strRes); string strOutput = ""; if(vec_strRes.size() >= 1 && bFlag) { strOutput = vec_strRes.at(0); } //execCommandOnHost( strCmd, false, NULL, vec_strRes); boost::algorithm::trim(strOutput); if(!strOutput.empty() && (strOutput.compare("1") == 0)) { strCorrectPath = strTestPath; break; } } return strCorrectPath; } vector host :: tokenizeString(string dataStr, string sep) { vector output; char * token = NULL; char *dataArr = NULL; dataArr = new char[dataStr.length() + 1]; strcpy(dataArr, dataStr.c_str()); token = strtok (dataArr, sep.c_str()); while (token != NULL) { output.push_back(token); token = strtok (NULL, sep.c_str()); } delete [] dataArr; dataArr = NULL; return output; } void host :: ProcessPresetCommand(presetMetaData presetInfo) { try { string command = presetInfo.getCommand(); GetCommand(command, presetInfo); string temp = STR_PROCESSING_CMD; temp.append(presetInfo.toString()); m_pCommonOutputHandle->writeDataToLogFile(STR_INFO, m_strHostName, temp); if(command != "") { m_pTempFilePtr = m_pOutputHandle->createTempFile("temp_host"); time_t cmdStartTime; time(&cmdStartTime); string data = "=-=-=-=-=-= " + presetInfo.getType() + " " + m_strHostName + " "; data.append(presetInfo.getSection() + " =-=-=-=-=-= "); if(presetInfo.getShortname().compare("") != 0) { data.append(presetInfo.getShortname()); } else { data.append(presetInfo.getCommand()); } //m_pOutputHandle->writeDataToTempFile(m_pTempFilePtr, data); string totalOutput = ""; totalOutput.append(STR_PERF_EPOCH); totalOutput.append(boost::lexical_cast(cmdStartTime)); totalOutput.append("\n"); //m_pOutputHandle->writeDataToTempFile(m_pTempFilePtr, totalOutput); m_pOutputHandle->writeDataToHostFile(data, totalOutput); ProcessCommand(command, true, m_pTempFilePtr); time_t cmdEndTime; time(&cmdEndTime); data="\n--- EXE-TIME of : " + presetInfo.getCommand() + " : "; data.append(boost::lexical_cast(cmdEndTime - cmdStartTime) + " seconds"); m_pOutputHandle->writeDataToTempFile(m_pTempFilePtr, data); if((int)(cmdEndTime - cmdStartTime) > cmdRunTime) { longerRuntimeCmd.push_back(presetInfo.toString()); } m_pOutputHandle->closeTempFile(m_pTempFilePtr); m_pOutputHandle->MoveFromTempToHostFile("temp_host", true); m_pOutputHandle->removeTempFile("temp_host"); } } catch(std::exception& e) { string tmp = ""; if(m_HostType == HOST_REMOTE) { tmp = "Exception : Remote Host : processCommands :"; } else { tmp = "Exception : Local Host : processCommands :"; } tmp.append(e.what()); m_pCommonOutputHandle->writeDataToLogFile("ERROR", m_strHostName, tmp); } } string host :: ProcessDateCommand(boost::barrier *serThreadBar) { vector vec_strData; bool bFlag = ProcessCommand("date", false, NULL, &vec_strData); string output = ""; if(vec_strData.size() >= 1 && bFlag) { output = vec_strData.at(0); } boost::algorithm::trim(output); if(serThreadBar) { (*serThreadBar).wait(); } return output; } void host :: ProcessDateCommand(string token, boost::barrier *serThreadBar) { vector data; data.push_back(token); data.push_back("PERF"); data.push_back(""); data.push_back("*"); data.push_back("*"); data.push_back("*"); data.push_back(""); data.push_back(""); data.push_back("date"); data.push_back("true"); presetMetaData dateCmd = presetMetaData(data); ProcessPresetCommand(dateCmd); if(serThreadBar) { (*serThreadBar).wait(); } } bool host :: ProcessPrestatCommands(boost::barrier *serThreadBar) { try { m_pCommonOutputHandle->writeDataToLogFile(STR_INFO, m_strHostName, STR_START_PRESTAT); ProcessDateCommand(STR_PRESTATS, serThreadBar); m_pOutputHandle->writeSTATSToHostFile(STR_BEGIN_PRESTATS, m_strHostName); bool bSignalStatus = checkSignal(); if(bSignalStatus) { //m_pSeqController->startPreStatsCommands(); return false; } string strHardware = (m_HostType == HOST_LOCAL) ? "HOST" : "REMOTEHOST"; if(!m_bConfigJustOnce) { vector prestatsConfigHostVector = m_pPresetHandle.getPrestatsCommands("TYPE", "CONFIG", strHardware); bSignalStatus = ProcessHostCommands(prestatsConfigHostVector); if(!m_pCLIHandle->getConfigAllFlag()) { m_bConfigJustOnce = true; } } // All CONFIG Commands join at the same time if(serThreadBar) { (*serThreadBar).wait(); } m_pCommonOutputHandle->writeDataToLogFile("INFO",m_strHostName, "Finished processing of PRESTATS CONFIG commands"); //m_pSeqController->startPreStatsCommands(); vector prestatsPerfHostVector = m_pPresetHandle.getPrestatsCommands("TYPE", "PERF",strHardware); bSignalStatus = ProcessHostCommands(prestatsPerfHostVector); if(m_pCLIHandle->getAppFlag()) { string strSqlTest = "which sqlplus 2>/dev/null"; vector vec_SqlTest; if(!m_pCLIHandle->getAppName().compare("oracle")) { if(ProcessCommand(strSqlTest, false, NULL, &vec_SqlTest)) { string strTest = (vec_SqlTest.size() > 0) ? vec_SqlTest.at(0) : ""; if(strTest.find("no sqlplus") != string::npos || strTest.empty() || strTest.find("sqlplus: Command not found") != string::npos ) { m_bOraclePresent = false; } else { m_bOraclePresent = true; } } if(m_bOraclePresent) { ProcessOraclePrestats(); } } } m_pOutputHandle->writeSTATSToHostFile(STR_END_PRESTATS, m_strHostName); // All PERF Commands join at the same time if(serThreadBar) { (*serThreadBar).wait(); } m_pCommonOutputHandle->writeDataToLogFile("INFO",m_strHostName, "Finished processing of PRESTATS PERF commands"); if(bSignalStatus) { bquickPoststatsFlag = true; return false; } else { if(serThreadBar) { (*serThreadBar).wait(); } m_pCommonOutputHandle->writeDataToLogFile(STR_INFO, m_strHostName, STR_FINISH_PRESTAT); //m_pSeqController->startPreStatsCmd = false; } } catch(std::exception& e) { string tmp = "Exception : Host : ProcessPrestatCommands :"; tmp.append(e.what()); m_pCommonOutputHandle->writeDataToLogFile(STR_ERROR, m_strHostName, tmp); } return true; } bool host :: ProcessPoststatCommands(boost::barrier *serThreadBar) { try { bool bSignalStatus = checkSignal(); m_pCommonOutputHandle->writeDataToLogFile(STR_INFO, m_strHostName, STR_START_POSTSTAT); m_pOutputHandle->writeSTATSToHostFile(STR_BEGIN_POSTSTATS, m_strHostName); if(bSignalStatus) { return false; } string strHardware = (m_HostType == HOST_LOCAL) ? "HOST" : "REMOTEHOST"; vector poststatsVec = m_pPresetHandle.getAllPoststatsCommands(strHardware); bSignalStatus = ProcessHostCommands(poststatsVec, bquickPoststatsFlag); if(m_pCLIHandle->getAppFlag()) { if(!m_pCLIHandle->getAppName().compare("oracle") && m_bOraclePresent) { ProcessOraclePoststats(); } } (*serThreadBar).wait(); // Added for BURT_562755 m_pOutputHandle->writeSTATSToHostFile(STR_END_POSTSTATS, m_strHostName); if(bSignalStatus) { return false; } else { ProcessDateCommand(STR_POSTSTATS, serThreadBar); m_pCommonOutputHandle->writeDataToLogFile(STR_INFO, m_strHostName, STR_FINISH_POSTSTAT); if(serThreadBar) { (*serThreadBar).wait(); } } } catch(std::exception& e) { string tmp = "Exception : Host : processPoststatsCommands :"; tmp.append(e.what()); m_pCommonOutputHandle->writeDataToLogFile(STR_ERROR, m_strHostName, tmp); } return true; } // The extra parameter bool bquickFlag can be removed.. and the check can be done with bquickPoststatsFlag bool host :: ProcessHostCommands(const vector& prestatCommands, bool bquickFlag) { bool bStatus = false; for(size_t nIndex = 0; nIndex < prestatCommands.size(); ++nIndex) { presetMetaData presetInfo= prestatCommands.at(nIndex); string strOS = presetInfo.getOS(); std::transform(strOS.begin(), strOS.end(), strOS.begin(), (int(*)(int))std::toupper); if(strOS.compare(m_strHostType) == 0) { ProcessPresetCommand(presetInfo); if(bquickFlag == false) { bStatus = checkSignal(); if(bStatus) { break; } } } } return bStatus; } void host :: GetCommand(string& strCmd, presetMetaData pMetaData) { boost::mutex::scoped_lock lock(host_move_mutex); { string temp = "