in source/code/scxsystemlib/disk/staticdiskpartitioninstance.cpp [158:346]
void StaticDiskPartitionInstance::Update_Solaris()
{
SCX_LOGTRACE(m_log, L"DiskPartition::Update_Solaris():: Entering, DeviceID is:" + m_deviceID);
// Execute 'df -g' and retrieve result to determine filesystem that is mounted on
// and block size. Then, go through output of prtvtoc for this filesystem to
// retrieve the remaining partition information.
#if PF_MAJOR == 5 && (PF_MINOR == 9 || PF_MINOR == 10)
wstring cmdStringDf = L"/usr/sbin/df -g";
#elif PF_MAJOR == 5 && PF_MINOR == 11
wstring cmdStringDf = L"/sbin/df -g";
#else
#error "Platform not supported"
#endif
int status;
std::istringstream processInputDf;
std::ostringstream processOutputDf;
std::ostringstream processErrDf;
wstring curLine;
curLine.clear();
wstring mountedStr;
wstring blockSizeStr;
std::string dfResult;
vector<wstring> allLines; // all lines read from output
allLines.clear();
SCXStream::NLFs nlfs;
bool foundIt = false;
vector<wstring> matchingVector;
SCXRegexPtr solDfPatternPtr(NULL);
SCXRegexPtr solPrtvtocBpSPatternPtr(NULL);
SCXRegexPtr solPrtvtocDetailPatternPtr(NULL);
// Let's build our RegEx:
try
{
solDfPatternPtr = new SCXCoreLib::SCXRegex(c_SolDfPattern);
solPrtvtocBpSPatternPtr = new SCXCoreLib::SCXRegex(c_SolPrtvtocBpSPattern);
solPrtvtocDetailPatternPtr = new SCXCoreLib::SCXRegex(c_SolprtvtocDetailPattern);
}
catch(SCXCoreLib::SCXInvalidRegexException &e)
{
SCX_LOGERROR(m_log, L"Exception caught in compiling regex: " + e.What());
return;
}
try
{
status = SCXCoreLib::SCXProcess::Run(cmdStringDf, processInputDf, processOutputDf, processErrDf, 15000);
if (status != 0)
{
SCX_LOGERROR(m_log, StrAppend(L"Error on command " + cmdStringDf + L" - status ", status));
SCX_LOGERROR(m_log, StrFromUTF8("Output - " + processOutputDf.str()));
SCX_LOGERROR(m_log, StrFromUTF8("Error - " + processErrDf.str()));
return;
}
dfResult = processOutputDf.str();
}
catch(SCXCoreLib::SCXException &e)
{
SCX_LOGERROR(m_log, L"Unable to retrieve partition information from OS using 'df -g'..." + e.What());
}
std::istringstream stringStrmDf_g(dfResult);
allLines.clear();
size_t dfLineCt = 100;
allLines.reserve(dfLineCt);
foundIt = false;
SCXCoreLib::SCXStream::ReadAllLinesAsUTF8(stringStrmDf_g, allLines, nlfs);
for (vector<wstring>::iterator it = allLines.begin(); it != allLines.end() && !foundIt; it++)
{
curLine.assign(*it);
matchingVector.clear();
if ((solDfPatternPtr->ReturnMatch(curLine, matchingVector, 0)) && (matchingVector.size() >= 4) &&
(m_deviceID == matchingVector[2]))
{
mountedStr = matchingVector[1];
blockSizeStr = matchingVector[3];
foundIt = true;
}
else if (matchingVector.size() > 0)
{
//Have an error message
SCX_LOGINFO(m_log, L"No match found! Error: " + matchingVector[0]);
}
}
//Check the results
if (!foundIt || mountedStr .size() == 0)
{
SCX_LOGERROR(m_log, L"Failed to find this partition info with df -g: " + m_deviceID );
return;
}
//The next (and last) step is to do a prtvtoc [dir] command to retrieve the rest of the partition info:
#if PF_MAJOR == 5 && (PF_MINOR == 9 || PF_MINOR == 10)
wstring cmdStringPrtvToc = L"/usr/sbin/prtvtoc " + m_deviceID;
#elif PF_MAJOR == 5 && PF_MINOR == 11
wstring cmdStringPrtvToc = L"/sbin/prtvtoc " + m_deviceID;
#else
#error "Platform not supported"
#endif
std::istringstream processInputPrtvtoc;
std::ostringstream processOutputPrtvtoc;
std::ostringstream processErrPrtvtoc;
curLine.clear();
wstring firstSectorStr;
wstring sectorCountStr;
wstring bytesPerSectorStr;
std::string prtResult("");
try
{
SCXCoreLib::SCXProcess::Run(cmdStringPrtvToc, processInputPrtvtoc, processOutputPrtvtoc, processErrPrtvtoc, 15000);
prtResult = processOutputPrtvtoc.str();
size_t lengthCaptured = prtResult.length();
// Truncate trailing newline if there in captured output
if (lengthCaptured > 0)
{
if (prtResult[lengthCaptured - 1] == '\n')
{
prtResult[lengthCaptured - 1] = '\0';
}
}
}
catch(SCXCoreLib::SCXException &e)
{
SCX_LOGERROR(m_log, L"Unable to retrieve partition information from OS using 'df -g'..." + e.What());
}
std::istringstream stringStrmPrtvtoc(prtResult);
allLines.clear();
foundIt = false;
SCXCoreLib::SCXStream::ReadAllLinesAsUTF8(stringStrmPrtvtoc, allLines, nlfs);;
for(vector<wstring>::iterator it = allLines.begin(); it != allLines.end() && !foundIt; it++)
{
curLine.assign(*it);
matchingVector.clear();
// First, we match on a comment line that tells us the Sector Size
if (solPrtvtocBpSPatternPtr->ReturnMatch(curLine, matchingVector, 0))
{
bytesPerSectorStr = matchingVector[1];
} // Next, we look for a detail line that matches our index:
else if ((solPrtvtocDetailPatternPtr->ReturnMatch(curLine, matchingVector, 0)) &&
(matchingVector.size() >= 5) &&
(m_index == SCXCoreLib::StrToUInt(matchingVector[1])))
{
// This is our row in the Partion info output
firstSectorStr = matchingVector[2];
sectorCountStr = matchingVector[3];
foundIt = true;
}
}
//Check the results
if (!foundIt || bytesPerSectorStr.size() == 0)
{
SCX_LOGERROR(m_log, L"Failed to find this partition info with prtvtoc: " + m_deviceID +
L" And Regex Error Msg: " + matchingVector[0]);
return;
}
// If we reached here we have everything we need
// just need to do a little arithmetic and fill in our Properties struct:
m_blockSize = SCXCoreLib::StrToULong(blockSizeStr);
char dummyChar;
unsigned int sectorSz = StrToUInt(bytesPerSectorStr);
unsigned long long totalSectors = StrToUInt(sectorCountStr);
unsigned long long startingSector = StrToUInt(firstSectorStr);
m_partitionSize = totalSectors * sectorSz;
m_startingOffset = startingSector * sectorSz;
m_numberOfBlocks = RoundToUnsignedInt(static_cast<double>(m_partitionSize) /
static_cast<double>(m_blockSize));
return;
}