in source/code/scxsystemlib/disk/diskdepend.cpp [503:694]
void DiskDependDefault::RefreshMNTTab(RefreshMNTTabParam *param)
{
static SCXCoreLib::LogSuppressor suppressor(SCXCoreLib::eWarning, SCXCoreLib::eTrace);
bool isTestEnv = FileExists(L"/etc/opt/omi/conf/SCX_TESTRUN_ACTIVE");
SCX_LOGTRACE(m_log, L"RefreshMNTTab: mnttab file being read");
if (0 < m_MntTab.size())
{
SCX_LOGTRACE(m_log, L"RefreshMNTTab: Clearing m_MntTab");
m_MntTab.clear();
}
#if defined(aix)
int needed = 0;
// Get the number of bytes needed for all mntctl data.
int r = mntctl(MCTL_QUERY, sizeof(needed), reinterpret_cast<char*>(&needed));
if (0 == r)
{
std::vector<char> buf(needed);
char* p = &buf[0];
// Returns number of structs in buffer; use that to limit data walk
r = mntctl(MCTL_QUERY, needed, &buf[0]);
if (r < 0)
{
SCX_LOGERROR(m_log, L"mntctl(MCTL_QUERY) failed with errno = " + SCXCoreLib::StrFrom(errno));
}
for (int i = 0; i < r; i++)
{
struct vmount* vmt = reinterpret_cast<struct vmount*>(p);
std::wstring fs = SCXCoreLib::StrFrom(vmt->vmt_gfstype);
if (vmt->vmt_data[VMT_OBJECT].vmt_size > 0 &&
vmt->vmt_data[VMT_STUB].vmt_size > 0 &&
m_fsMap.find(fs) != m_fsMap.end())
{
MntTabEntry entry;
std::string device(p + vmt->vmt_data[VMT_OBJECT].vmt_off);
std::string mountPoint(p + vmt->vmt_data[VMT_STUB].vmt_off);
if ( param != NULL && param->getValue() != L"" )
{
bool isContinue=false;
switch ( param->getType() ) {
case MOUNTPOINT:
if ( SCXCoreLib::StrFromUTF8(mountPoint) != param->getValue() ) isContinue=true;
break;
case DEVICE:
if ( SCXCoreLib::StrFromUTF8(device) != param->getValue() ) isContinue=true;
break;
case NOPARAM:
break;
}
if(isContinue) continue;
}
entry.device = SCXCoreLib::StrFromUTF8(device);
entry.mountPoint = SCXCoreLib::StrFromUTF8(mountPoint);
entry.fileSystem = m_fsMap.find(fs)->second;
m_MntTab.push_back(entry);
if ( param != NULL ) break;
}
p += vmt->vmt_length;
}
}
else
{
SCX_LOGERROR(m_log, L"mntctl(MCTL_QUERY) failed with errno = " + SCXCoreLib::StrFrom(errno));
}
#else
SCXCoreLib::SCXHandle<std::wfstream> fs(SCXCoreLib::SCXFile::OpenWFstream(
LocateMountTab(), std::ios::in));
fs.SetOwner();
while ( ! fs->eof() && fs->is_open() )
{
std::wstring line;
std::vector<std::wstring> parts;
getline( *fs, line );
#if defined (linux)
if (line.find(L"loop=") != std::wstring::npos || line.find(L"/dev/loop") != std::wstring::npos)
{
// for Linux, ignore files mounted as devices using the loopback driver
if (!isTestEnv) continue;
}
#endif
SCXCoreLib::StrTokenize(line, parts, L" \n\t");
if (parts.size() > 3)
{
if (std::wstring::npos != parts[0].find('#')) // Comment
{
continue;
}
#if defined(linux)
// WI 53975427:
//
// The fix here is meant to exclude pseudo file system in file system enumeration.
// It can also be fixed by adding these FS in IGFS. But the problem with this approacch is that every time new pseudo FS get introduced we need to make changes in IGFS
// and need to have subsequent release to fix the issue.
// The fix here is based on fundamental property of pseudo FS that it is not associated with any block device, hence not associated with any path.
if (parts[0].find(L"/") == std::wstring::npos)
{
continue;
}
// WI 574703:
//
// On Debian 7 systems, the system disk may come in with a device like:
// /dev/disk/by-uuid/e62e95e9-502b-463a-998d-23cf7130d7d2
// This differs from what's in /proc/diskstats (which is the real physical
// device). Since the path in /dev/disk/by-uuid is actually a soft link
// to the physical device, just resolve it if that's what we've got.
if (parts[0].find(L"/dev/disk/by-uuid/") == 0)
{
char buf[1024];
memset(buf, 0, sizeof(buf));
if (-1 == readlink(SCXCoreLib::StrToUTF8(parts[0]).c_str(), buf, sizeof(buf)))
{
std::wstringstream message;
message << L"readlink(file='" << parts[0] << "',...)";
SCXCoreLib::SCXErrnoException e(message.str(), errno, SCXSRCLOCATION);
SCXCoreLib::SCXLogSeverity severity(suppressor.GetSeverity(message.str()));
std::wstringstream out;
out << "RefreshMNTTab: Error : " << e.What() << " at " << e.Where();
SCX_LOG(m_log, severity, out.str());
}
else
{
// readlink returns something like "../../sda1"; trim to return "/dev/sda1"
std::wstring link = SCXCoreLib::StrFromUTF8(buf);
size_t pos;
if ( (pos = link.rfind(L"/")) != std::wstring::npos )
{
parts[0] = L"/dev/" + link.substr(pos+1);
}
else
{
std::wstringstream message;
message << L"RefreshMNTTab: Unable to find physical define in link: " << link
<< " (Original file: " << parts[0] << ")";
SCXCoreLib::SCXLogSeverity severity(suppressor.GetSeverity(message.str()));
SCX_LOG(m_log, severity, message.str());
}
}
}
#endif
if ( param != NULL && param->getValue() != L"" )
{
bool isContinue=false;
switch ( param->getType() ) {
case MOUNTPOINT:
if ( parts[1] != param->getValue() ) isContinue=true;
break;
case DEVICE:
if ( parts[0].find(param->getValue()) == std::wstring::npos ) isContinue=true;
break;
case NOPARAM:
break;
}
if(isContinue) continue;
}
MntTabEntry entry;
entry.device = parts[0];
entry.mountPoint = parts[1];
entry.fileSystem = parts[2];
if (parts[3].find(L"dev=") != std::wstring::npos)
{
entry.devAttribute = parts[3].substr(parts[3].find(L"dev="));
if (entry.devAttribute.length() > 0)
{
entry.devAttribute = entry.devAttribute.substr(4); // Removing "dev="
entry.devAttribute = entry.devAttribute.substr(0,entry.devAttribute.find_first_not_of(L"0123456789abcdef"));
}
}
SCX_LOGTRACE(m_log,
L"RefreshMNTTab: Storing device '" + entry.device
+ L"', mountpoint '" + entry.mountPoint
+ L"', filesysstem '" + entry.fileSystem + L"'" );
m_MntTab.push_back(entry);
if ( param != NULL ) break;
}
}
fs->close();
SCX_LOGTRACE(m_log, L"RefreshMNTTab: Done writing m_MntTab");
#endif
}