in source/code/scxsystemlib/disk/diskdepend.cpp [936:1110]
std::map<std::wstring, std::wstring> DiskDependDefault::GetPhysicalDevices(const std::wstring& device)
{
std::map<std::wstring, std::wstring> devices;
SCXCoreLib::SCXFilePath path(device);
std::wstring name = path.GetFilename();
#if defined(aix)
// Since we do not have the associaction between logical and physical disks - return them all
perfstat_id_t id;
perfstat_disk_t data;
strcpy(id.name, FIRST_DISKPATH);
do {
int r = perfstat_disk(&id, &data, sizeof(data), 1);
if (1 == r && 0 != strncmp(data.name, "cd", 2)) // TODO: better way to exclude CD/DVD!
{
name = SCXCoreLib::StrFromUTF8(data.name);
devices[name] = L"/dev/" + name;
}
// TODO: Error handling?
} while (0 != strcmp(id.name, FIRST_DISKPATH));
#elif defined(hpux)
size_t vg_idx;
for (vg_idx = 0; vg_idx < GetLVMTab().GetVGCount(); ++vg_idx)
{
// Stored name is without trailing slash.
if (SCXCoreLib::StrAppend(GetLVMTab().GetVG(vg_idx),L"/") == path.GetDirectory())
{
for (size_t pidx = 0; pidx < GetLVMTab().GetPartCount(vg_idx); ++pidx)
{
path.Set(GetLVMTab().GetPart(vg_idx, pidx));
name = path.GetFilename();
if (0 == SCXCoreLib::StrCompare(name.substr(0,4),L"disk",true))
{ // New style: disk1_p2 (or just disk3)
name = name.substr(0, name.find_last_of(L"_"));
}
else
{ // "sun" style: c1t2d3s4
if (name.substr(name.find_last_not_of(L"0123456789"),1) == L"s")
{ // Remove partition identifier
name = name.substr(0,name.find_last_not_of(L"0123456789"));
}
}
path.SetFilename(name);
// Bug 6755 & 6883: partial discoveries of disks.
// Using algorithm from static PAL for exclusion.
std::wstring rawDevice = path.Get();
if (std::wstring::npos != rawDevice.find(L"/dsk/"))
{
rawDevice = SCXCoreLib::StrAppend(L"/dev/rdsk/", path.GetFilename());
}
else
{
rawDevice = SCXCoreLib::StrAppend(L"/dev/rdisk/", path.GetFilename());
}
if (this->open(SCXCoreLib::StrToUTF8(rawDevice).c_str(), O_RDONLY))
{
devices[name] = path.Get();
this->close();
}
}
break;
}
}
#elif defined(linux)
// Given a device path to a partition (for example /dev/hda5 or /dev/cciss/c0d0p1), convert
// it to a path to the base device (for example /dev/hda or /dev/cciss/c0d0).
try
{
static SCXLVMUtils lvmUtils;
// Try to convert the potential LVM device path into its matching
// device mapper (dm) device path.
std::wstring dmDevice = lvmUtils.GetDMDevice(device);
if (dmDevice.empty())
{
// device is a normal partition device path
path = GuessPhysicalFromLogicalDevice(device);
name = path.GetFilename();
devices[name] = path.Get();
}
else
{
// device was an LVM device path and dmDevice is the path to
// the same device using the device mapper name. The dm device
// is located on one or more normal devices, known as slaves.
std::vector< std::wstring > slaves = lvmUtils.GetDMSlaves(dmDevice);
if (slaves.size() == 0)
{
// this condition can only be reached on RHEL4/SLES9 systems
std::wstringstream out;
static SCXCoreLib::LogSuppressor suppressor(SCXCoreLib::eInfo, SCXCoreLib::eHysterical);
out << L"Because of limited support for LVM on "
# if defined(PF_DISTRO_SUSE)
<< L"SuSE Linux Enterprise Server 9"
# else
<< L"Red Hat Enterprise Linux 4"
# endif
<< L", the logical device " << device << L": cannot be mapped to the physical device(s) that contain it.";
SCX_LOG(m_log, suppressor.GetSeverity(device), out.str());
}
else
{
for (std::vector< std::wstring >::const_iterator iter = slaves.begin();
iter != slaves.end(); iter++)
{
if ((*iter).empty() || !isdigit((int)(*iter)[(*iter).size() - 1]))
{
path = *iter;
}
else
{
path = GuessPhysicalFromLogicalDevice(*iter);
}
name = path.GetFilename();
devices[name] = path.Get();
}
}
}
}
catch (SCXCoreLib::SCXException& e)
{
static SCXCoreLib::LogSuppressor suppressor(SCXCoreLib::eError, SCXCoreLib::eTrace);
std::wstringstream out;
out << L"An exception occurred resolving the physical devices that contain the LVM device " << device << L": " << e.What();
SCX_LOG(m_log, suppressor.GetSeverity(out.str()), out.str());
}
#elif defined(sun)
std::vector<std::wstring> devs;
if (device.find(L"/md/") != std::wstring::npos)
{
// meta devices can be built from multiple normal devices
if (0 == m_pRaid)
{
SCXCoreLib::SCXHandle<SCXSystemLib::SCXRaidCfgParser> raidCfgParser( new SCXSystemLib::SCXRaidCfgParserDefault() );
m_pRaid = new SCXRaid(raidCfgParser);
}
m_pRaid->GetDevices(name, devs);
// rewrite the path for mapping physical devices kstat module, instance and name
path.SetDirectory(L"/dev/dsk/");
}
else
{
// normal device
devs.push_back(name);
}
for (std::vector<std::wstring>::const_iterator it = devs.begin(); it != devs.end(); ++it)
{
name = it->substr(0,it->find_last_not_of(L"0123456789"));
std::wstring dev = SCXCoreLib::StrAppend(L"/dev/dsk/", *it);
try
{
if (IsDiskInKstat(path.GetDirectory() + L"/" + name))
{
devices[name] = dev.substr(0,dev.find_last_not_of(L"0123456789"));
}
}
catch (SCXCoreLib::SCXException& )
{
}
}
#endif
return devices;
}