in source/code/scxsystemlib/disk/staticdiskpartitioninstance.cpp [364:570]
bool StaticDiskPartitionInstance::GetBootDrivePath(wstring& bootpathStr)
{
SCX_LOGTRACE(m_log, L"DiskPartition::GetBootDrivePath():: Entering . . .");
bootpathStr.clear();
// buffer to store lines read from process output
wstring curLine;
wstring bootInterfacePath;
// Determine Solaris boot disk using 'prtconf' and 'ls /dev/dsk'
// cmdString stores the current process we are running via SCXProcess::Run()
#if defined(sparc)
#if PF_MAJOR == 5 && (PF_MINOR == 9 || PF_MINOR == 10)
wstring cmdPrtString = L"/usr/sbin/prtconf -pv";
#elif PF_MAJOR == 5 && PF_MINOR == 11
wstring cmdPrtString = L"/sbin/prtconf -pv";
#else
#error "Platform not supported"
#endif
#else// sparc
wstring cmdPrtString = L"/usr/bin/grep bootpath /boot/solaris/bootenv.rc";
#endif
std::string prtconfResult;
std::string finalResult;
std::istringstream processInputPrt;
std::ostringstream processOutputPrt;
std::ostringstream processErrPrt;
try
{
int retCode = m_deps->Run(cmdPrtString, processInputPrt, processOutputPrt, processErrPrt, 15000);
if (retCode)
{
SCX_LOGERROR(m_log, L"Error returned from prtconf, unable to determine boot partition. Error code=" + StrFrom(retCode));
return false;
}
prtconfResult = processOutputPrt.str();
SCX_LOGTRACE(m_log, L" Got this output from " + cmdPrtString + L" : " + StrFromUTF8(prtconfResult) );
size_t lengthCaptured = prtconfResult.length();
// Truncate trailing newline if there in captured output
if (lengthCaptured > 0)
{
if (prtconfResult[lengthCaptured - 1] == '\n')
{
prtconfResult[lengthCaptured - 1] = '\0';
}
}
}
catch(SCXCoreLib::SCXException &e)
{
SCX_LOGERROR(m_log, L"Unable to determine boot partition using prtconf ..." + e.What());
return false;
}
SCXRegexPtr solPrtconfPatternPtr(NULL);
std::vector<wstring> matchingVector;
// Let's build our RegEx:
try
{
SCX_LOGTRACE(m_log, L" Using this regex on PrtConf output: " + c_SolPrtconfPattern );
solPrtconfPatternPtr = new SCXCoreLib::SCXRegex(c_SolPrtconfPattern);
}
catch(SCXCoreLib::SCXInvalidRegexException &e)
{
SCX_LOGERROR(m_log, L"Exception caught in compiling regex: " + e.What());
return false;
}
std::istringstream stringStrmPrtconf(prtconfResult);
vector<wstring> allLines; // all lines read from prtconf output
allLines.clear();
SCXStream::NLFs nlfs;
SCXCoreLib::SCXStream::ReadAllLinesAsUTF8(stringStrmPrtconf, allLines, nlfs);
for(vector<wstring>::iterator it = allLines.begin(); it != allLines.end(); it++)
{
curLine.assign(*it);
matchingVector.clear();
// Let's get the Boot partition interface and drive letter from prtconf
if (solPrtconfPatternPtr->ReturnMatch(curLine, matchingVector, 0))
{
bootInterfacePath = matchingVector[1];
SCX_LOGTRACE(m_log, L"Found match of PrtConfPattern : " + bootInterfacePath);
break;
}
}
if (bootInterfacePath.size() == 0)
{
std::wstringstream warningMsg;
if (matchingVector.size() > 0)
{
warningMsg << L"Couldn't find Boot Partition, regular expression error message was: " << matchingVector[0];
}
else
{
warningMsg << L"Couldn't find Boot Partition.";
}
SCX_LOG(m_log, suppressor.GetSeverity(warningMsg.str()), warningMsg.str());
return false;
}
// Replace "disk" by "disk" or "sd" to normalize the boot interface path
wstring from(L"disk");
size_t start_pos = bootInterfacePath.find(from);
if(start_pos != std::string::npos)
{
bootInterfacePath.replace(start_pos, from.length(), L"(disk|sd)");
}
wstring solLsPattern(c_SolLsPatternBeg);
solLsPattern += bootInterfacePath;
// Now we need to build up our pattern to find the bootdisk, using our results from above:
SCXRegexPtr solLsPatternPtr(NULL);
//Let's build our RegEx:
try
{
SCX_LOGTRACE(m_log, L" Using this regex on ls -l /dev/dsk output: " + solLsPattern );
solLsPatternPtr = new SCXCoreLib::SCXRegex(solLsPattern);
}
catch(SCXCoreLib::SCXInvalidRegexException &e)
{
SCX_LOGERROR(m_log, L"Exception caught in compiling LS Pattern regex: " + e.What());
return false;
}
// Retrieve the bootdrive using the bootInterface and driveLetter
wstring cmdStringLs = L"/usr/bin/ls -l /dev/dsk";
std::string devDskResult;
std::istringstream processInputLs;
std::ostringstream processOutputLs;
std::ostringstream processErrLs;
curLine.clear();
try
{
SCXCoreLib::SCXProcess::Run(cmdStringLs, processInputLs, processOutputLs, processErrLs, 15000);
devDskResult = processOutputLs.str();
SCX_LOGTRACE(m_log, L" Got this output from " + cmdStringLs + L" : " + StrFromUTF8(devDskResult) );
size_t lengthCaptured = devDskResult.length();
// Truncate trailing newline if there in captured output
if (lengthCaptured > 0)
{
if (devDskResult[lengthCaptured - 1] == '\n')
{
devDskResult[lengthCaptured - 1] = '\0';
}
}
}
catch(SCXCoreLib::SCXException &e)
{
SCX_LOGERROR(m_log, L"Unable to determine boot partition..." + e.What());
return false;
}
std::istringstream stringStrmDevDsk(devDskResult);
allLines.clear();
SCXCoreLib::SCXStream::ReadAllLinesAsUTF8(stringStrmDevDsk, allLines, nlfs);
wstring bootDisk(L"");
for(vector<wstring>::iterator it = allLines.begin(); it != allLines.end(); it++)
{
curLine.assign(*it);
curLine.push_back('\n');
matchingVector.clear();
// Let's get the boot drive
if (solLsPatternPtr->ReturnMatch(curLine, matchingVector, 0))
{
bootDisk = matchingVector[1]; //e.g. "c1t0d0s0"
break;
}
}
//Check the results
if (bootDisk.size() == 0)
{
std::wstringstream warningMsg;
if (matchingVector.size() > 0)
{
warningMsg << L"Couldn't find Boot Drive, regular expression error message was: " << matchingVector[0];
}
else
{
warningMsg << L"Couldn't find Boot Drive.";
}
SCX_LOG(m_log, suppressor.GetSeverity(warningMsg.str()), warningMsg.str());
return false;
}
bootpathStr = L"/dev/dsk/" + bootDisk; //e.g. "/dev/dsk/c1t0d0s0"
return true;
}