/** The disk sampler thread body. \param param - thread parameters. */ void StatisticalLogicalDiskEnumeration::DiskSampler(SCXCoreLib::SCXThreadParamHandle& param) { StatisticalLogicalDiskSamplerParam* p = static_cast<StatisticalLogicalDiskSamplerParam*>(param.GetData()); SCXASSERT(0 != p); SCXASSERT(0 != p->m_diskEnum); bool bUpdate = true; p->m_cond.SetSleep(DISK_SECONDS_PER_SAMPLE * 1000); { SCXCoreLib::SCXConditionHandle h(p->m_cond); while( ! p->GetTerminateFlag()) { if (bUpdate) { try { p->m_diskEnum->SampleDisks(); } catch (const SCXCoreLib::SCXException& e) { SCX_LOGERROR(p->m_diskEnum->m_log, std::wstring(L"StatisticalLogicalDiskEnumeration::DiskSampler() - Unexpected exception caught: ").append(e.What()).append(L" - ").append(e.Where())); } bUpdate = false; } enum SCXCoreLib::SCXCondition::eConditionResult r = h.Wait(); if (SCXCoreLib::SCXCondition::eCondTimeout == r) { bUpdate = true; } } } }
/** Discover physical disks. Logical disks are identified by the /etc/mnttab file (by design). Physical disks discovered will be those "hosting" the logical disks found. If ever seen in that file, the disk will be discovered. If the disk is removed it will be marked as offline. How to identify physical disks from logical disks: Linux -- Logical disks are named things like /dev/hda0, /dev/hda1 and so on. The numeric value in the end of the name is the partition/logical ID of the physical disk. In the example above both logical disks are on physical disk /dev/hda. For LVM partitions on Linux have two entries for the same device. An LVM device entry is stored in the /dev/mapper directory with a name in the form <logical-volume-group>-<logical-volume>. There is also a device mapper (dm) device entry stored in the /dev directory in the form dm-<id>. This is a 1-to-1 relationship and the <id> is equal to the device minor ID that both device entries have in common. Discovery of the physical device(s) that contain the LVM partition is done by mapping the LVM device to the dm device, then looking at the dm devices slave entries in Sysfs, and then finally performing the same conversion from a logical Linux partition name to a physical drive name that is done for all other partitions. Solaris -- Logical disks are named things like /dev/dsk/c1t0d0s0, /dev/dsk/c1t0d0s1 and so on. The last letter/numeric pair is the partition/logical ID of the physical disk. In the example above both logical disks are on physical disk /dev/dsk/c1t0d0. HPUX -- Logical disks are logical volumes with names like /dev/vg00/lvol3. /dev/vg00 in the example name is the volume group name. Using the /etc/lvmtab file the volume group can be translated to a partition named /dev/disk/disk3_p2 (or /dev/dsk/c2t0d0s2 using a naming standard deprecated as of HPUX 11.3). The old naming standard works like the one for solaris while the new one identifies the physical disk as /dev/disk/disk3 in the example above. AIX -- TODO: Document how disks are enumerated on AIX. */ void StatisticalPhysicalDiskEnumeration::FindPhysicalDisks() { for (EntityIterator iter=Begin(); iter!=End(); iter++) { SCXCoreLib::SCXHandle<StatisticalPhysicalDiskInstance> disk = *iter; disk->m_online = false; } m_deps->RefreshMNTTab(); for (std::vector<MntTabEntry>::const_iterator it = m_deps->GetMNTTab().begin(); it != m_deps->GetMNTTab().end(); it++) { if ( ! m_deps->FileSystemIgnored(it->fileSystem) && ! m_deps->DeviceIgnored(it->device) && m_deps->LinkToPhysicalExists(it->fileSystem, it->device, it->mountPoint) ) { std::map<std::wstring, std::wstring> devices = m_deps->GetPhysicalDevices(it->device); if (devices.size() == 0) { static SCXCoreLib::LogSuppressor suppressor(SCXCoreLib::eError, SCXCoreLib::eTrace); std::wstringstream out; out << L"Unable to locate physical devices for: " << it->device; SCX_LOG(m_log, suppressor.GetSeverity(out.str()), out.str()); continue; } for (std::map<std::wstring, std::wstring>::const_iterator dev_it = devices.begin(); dev_it != devices.end(); dev_it++) { SCXCoreLib::SCXHandle<StatisticalPhysicalDiskInstance> disk = AddDiskInstance(dev_it->first, dev_it->second); #if defined(hpux) if (0 != disk) { if (m_pathToRdev.end() == m_pathToRdev.find(disk->m_device)) { SCXCoreLib::SCXFilePath fp(disk->m_device); fp.SetFilename(L""); UpdatePathToRdev(fp.Get()); } SCXASSERT(m_pathToRdev.end() != m_pathToRdev.find(disk->m_device)); scxlong diskInfoIndex = disk->FindDiskInfoByID(m_pathToRdev.find(disk->m_device)->second); m_deps->AddDeviceInstance(disk->m_device, L"", diskInfoIndex, m_pathToRdev.find(disk->m_device)->second); } #endif } } } #if defined(sun) this->UpdateSolarisHelper(); #endif }
/** Thread body that scans for updated configuration file and updates the configuration if it has changed. \param[in] param Thread parameters. */ void SCXLogFileConfigurator::ConfigUpdateThreadBody(SCXCoreLib::SCXThreadParamHandle& param) { LogFileConfiguratorParam* p = static_cast<LogFileConfiguratorParam*>(param.GetData()); SCXASSERT(0 != p); SCXLogFileConfigurator* configurator = p->m_configurator; SCXASSERT(0 != configurator); p->m_cond.SetSleep(configurator->m_ConfigRefreshRate); { SCXConditionHandle h(p->m_cond); while ( ! param->GetTerminateFlag() ) { enum SCXCondition::eConditionResult r = h.Wait(); if (!param->GetTerminateFlag() && SCXCondition::eCondTimeout == r && configurator->IsConfigurationChanged()) { configurator->RestoreConfiguration(); } } } }
/** Virtual destructor. Kills the thread. */ SCXLogFileConfigurator::~SCXLogFileConfigurator() { if (m_ConfigUpdateThread != 0) { // If the thread is still alive (it should be), ask it to go away if ( m_ConfigUpdateThread->IsAlive() ) { m_ConfigUpdateThread->RequestTerminate(); m_ConfigUpdateThread->Wait(); } SCXASSERT( ! m_ConfigUpdateThread->IsAlive() ); m_ConfigUpdateThread = 0; } }
void ApplicationServerProvider::Unload() { SCX_LOGTRACE(m_log, L"ApplicationServerProvider::Unload()"); SCXASSERT( ms_loadCount >= 1 ); if ( 0 == --ms_loadCount ) { if (NULL != m_appservers) { m_appservers->CleanUp(); m_appservers = NULL; } m_deps = NULL; } }
void ApplicationServerProvider::Load() { SCXASSERT( ms_loadCount >= 0 ); if ( 1 == ++ms_loadCount ) { m_log = SCXLogHandleFactory::GetLogHandle(L"scx.core.providers.appserverprovider"); LogStartup(); SCX_LOGTRACE(m_log, L"ApplicationServerProvider::Load()"); if ( NULL == m_deps ) { m_deps = new AppServerProviderPALDependencies(); } m_appservers = m_deps->CreateEnum(); m_appservers->Init(); } }
/** Opens a file stream assuming the file is encoded according to the system locale \param[in] file The file to open \param[in] mode How to open it, explicitly. \throws SCXFilePathNotFoundException \throws SCXUnauthorizedFileSystemAccessException \throws SCXNotSupportedException \throws InvalidArgumentException Arguments Unlike STL there is no implicit (default) mode, the requested mode has to explicitly stated. The content of the file is assumed to be encoded according to system default. */ SCXHandle<std::wfstream> SCXFile::OpenWFstream(const SCXFilePath& file, std::ios_base::openmode mode) { if (!(mode & std::ios::in) && !(mode & std::ios::out)) { throw SCXInvalidArgumentException(L"mode", L"Specify ios::in or ios::out, or both", SCXSRCLOCATION); } if (mode & std::ios::binary) { throw SCXNotSupportedException(L"wide streams must not be binary", SCXSRCLOCATION); } #if defined(WIN32) SCXHandle<std::wfstream> streamPtr(new std::wfstream(file.Get().c_str(), mode)); #elif defined(SCX_UNIX) SCXHandle<std::wfstream> streamPtr(new std::wfstream(SCXFileSystem::EncodePath(file).c_str(), mode)); #else #error #endif if (streamPtr->good()) { SCXFileSystem::Attributes attribs(SCXFileSystem::GetAttributes(file)); if (attribs.count(SCXFileSystem::eDirectory) > 0) { throw SCXUnauthorizedFileSystemAccessException(file, attribs, SCXSRCLOCATION); } } else { SCXFileInfo info(file); if (mode & std::ios::in) { if (!info.PathExists()) { throw SCXFilePathNotFoundException(file, SCXSRCLOCATION); } else { throw SCXUnauthorizedFileSystemAccessException(file, SCXFileSystem::GetAttributes(file), SCXSRCLOCATION); } } else if (mode & std::ios::out) { throw SCXUnauthorizedFileSystemAccessException(file, SCXFileSystem::GetAttributes(file), SCXSRCLOCATION); } else { SCXASSERT(!"Invalid mode"); } } return streamPtr; }
/** Discover logical disks. Logical disks are identified by the /etc/mnttab file (by design). If ever seen in that file, the disk will be discovered. If the disk is removed it will be marked as offline. */ void StatisticalLogicalDiskEnumeration::FindLogicalDisks() { for (EntityIterator iter=Begin(); iter!=End(); iter++) { SCXCoreLib::SCXHandle<StatisticalLogicalDiskInstance> disk = *iter; disk->m_online = false; } m_deps->RefreshMNTTab(); for (std::vector<MntTabEntry>::const_iterator it = m_deps->GetMNTTab().begin(); it != m_deps->GetMNTTab().end(); it++) { if ( ! m_deps->FileSystemIgnored(it->fileSystem) && ! m_deps->DeviceIgnored(it->device)) { SCXCoreLib::SCXHandle<StatisticalLogicalDiskInstance> disk = FindDiskByDevice(it->device); if (0 == disk) { disk = new StatisticalLogicalDiskInstance(m_deps); disk->m_device = it->device; disk->m_mountPoint = it->mountPoint; disk->m_fsType = it->fileSystem; disk->SetId(disk->m_mountPoint); #if defined(linux) static SCXLVMUtils lvmUtils; if (lvmUtils.IsDMDevice(it->device)) { try { // Try to convert the potential LVM device path into its matching // device mapper (dm) device path. std::wstring dmDevice = lvmUtils.GetDMDevice(it->device); SCXASSERT(!dmDevice.empty()); disk->m_samplerDevices.push_back(dmDevice); } catch (SCXCoreLib::SCXException& e) { static SCXCoreLib::LogSuppressor suppressor(SCXCoreLib::eWarning, SCXCoreLib::eTrace); std::wstringstream out; out << L"An exception occurred resolving the dm device that represents the LVM partition " << it->device << L" : " << e.What(); SCX_LOG(m_log, suppressor.GetSeverity(out.str()), out.str()); } } // no else required; device was not an LVM device #endif AddInstance(disk); #if defined(hpux) if (m_pathToRdev.end() == m_pathToRdev.find(disk->m_device)) { SCXCoreLib::SCXFilePath fp(disk->m_device); fp.SetFilename(L""); UpdatePathToRdev(fp.Get()); } SCXASSERT(m_pathToRdev.end() != m_pathToRdev.find(disk->m_device)); m_deps->AddDeviceInstance(disk->m_device, L"", disk->FindLVInfoByID(m_pathToRdev.find(disk->m_device)->second), m_pathToRdev.find(disk->m_device)->second); #endif } disk->m_online = true; } } }