00001
00003
00004 #include <stdio.h>
00005 #include <string>
00006 #include <sstream>
00007 #include <iomanip>
00008 #include <sys/types.h>
00009 #include <sys/stat.h>
00010 #include <fcntl.h>
00011 #include <dirent.h>
00012 #include <fnmatch.h>
00013 #include <pwd.h>
00014 #include <fstream>
00015 #include <algorithm>
00016
00017 #include <boost/bind.hpp>
00018 #include <boost/regex.hpp>
00019
00020 #include "EventFilter/StorageManager/interface/AlarmHandler.h"
00021 #include "EventFilter/StorageManager/interface/CurlInterface.h"
00022 #include "EventFilter/StorageManager/interface/Exception.h"
00023 #include "EventFilter/StorageManager/interface/ResourceMonitorCollection.h"
00024 #include "EventFilter/StorageManager/interface/Utils.h"
00025
00026
00027 namespace stor {
00028
00029 ResourceMonitorCollection::ResourceMonitorCollection
00030 (
00031 const utils::Duration_t& updateInterval,
00032 AlarmHandlerPtr ah
00033 ) :
00034 MonitorCollection(updateInterval),
00035 updateInterval_(updateInterval),
00036 alarmHandler_(ah),
00037 numberOfCopyWorkers_(-1),
00038 numberOfInjectWorkers_(-1),
00039 nLogicalDisks_(0),
00040 latchedSataBeastStatus_(-1)
00041 {}
00042
00043
00044 void ResourceMonitorCollection::configureDisks(DiskWritingParams const& dwParams)
00045 {
00046 boost::mutex::scoped_lock sl(diskUsageListMutex_);
00047
00048 dwParams_ = dwParams;
00049
00050 nLogicalDisks_ = std::max(dwParams.nLogicalDisk_, 1);
00051 diskUsageList_.clear();
00052 diskUsageList_.reserve(nLogicalDisks_+dwParams.otherDiskPaths_.size()+1);
00053
00054 for (unsigned int i=0; i<nLogicalDisks_; ++i) {
00055
00056 std::ostringstream pathName;
00057 pathName << dwParams.filePath_;
00058 if( dwParams.nLogicalDisk_ > 0 ) {
00059 pathName << "/" << std::setfill('0') << std::setw(2) << i;
00060 }
00061 addDisk(pathName.str());
00062 }
00063 addDisk(dwParams.dbFilePath_);
00064
00065 if ( alarmParams_.isProductionSystem_ )
00066 {
00067 addOtherDisks();
00068 }
00069 }
00070
00071
00072 void ResourceMonitorCollection::addDisk(const std::string& pathname)
00073 {
00074 if ( pathname.empty() ) return;
00075
00076 DiskUsagePtr diskUsage( new DiskUsage(pathname) );
00077 retrieveDiskSize(diskUsage);
00078 diskUsageList_.push_back(diskUsage);
00079 }
00080
00081
00082 void ResourceMonitorCollection::addOtherDisks()
00083 {
00084 for ( DiskWritingParams::OtherDiskPaths::const_iterator
00085 it = dwParams_.otherDiskPaths_.begin(),
00086 itEnd = dwParams_.otherDiskPaths_.end();
00087 it != itEnd;
00088 ++it)
00089 {
00090 addDisk(*it);
00091 }
00092 }
00093
00094
00095 void ResourceMonitorCollection::configureResources
00096 (
00097 ResourceMonitorParams const& rmParams
00098 )
00099 {
00100 rmParams_ = rmParams;
00101 }
00102
00103
00104 void ResourceMonitorCollection::configureAlarms
00105 (
00106 AlarmParams const& alarmParams
00107 )
00108 {
00109 alarmParams_ = alarmParams;
00110 }
00111
00112
00113 void ResourceMonitorCollection::getStats(Stats& stats) const
00114 {
00115 getDiskStats(stats);
00116
00117 stats.numberOfCopyWorkers = numberOfCopyWorkers_;
00118 stats.numberOfInjectWorkers = numberOfInjectWorkers_;
00119
00120 stats.sataBeastStatus = latchedSataBeastStatus_;
00121 }
00122
00123
00124 void ResourceMonitorCollection::getDiskStats(Stats& stats) const
00125 {
00126 boost::mutex::scoped_lock sl(diskUsageListMutex_);
00127
00128 stats.diskUsageStatsList.clear();
00129 stats.diskUsageStatsList.reserve(diskUsageList_.size());
00130 for ( DiskUsagePtrList::const_iterator it = diskUsageList_.begin(),
00131 itEnd = diskUsageList_.end();
00132 it != itEnd;
00133 ++it)
00134 {
00135 DiskUsageStatsPtr diskUsageStats(new DiskUsageStats);
00136 diskUsageStats->diskSize = (*it)->diskSize_;
00137 diskUsageStats->absDiskUsage = (*it)->absDiskUsage_;
00138 diskUsageStats->relDiskUsage = (*it)->relDiskUsage_;
00139 diskUsageStats->pathName = (*it)->pathName_;
00140 diskUsageStats->alarmState = (*it)->alarmState_;
00141 stats.diskUsageStatsList.push_back(diskUsageStats);
00142 }
00143 }
00144
00145
00146 void ResourceMonitorCollection::do_calculateStatistics()
00147 {
00148 calcDiskUsage();
00149 calcNumberOfCopyWorkers();
00150 calcNumberOfInjectWorkers();
00151 checkSataBeasts();
00152 }
00153
00154
00155 void ResourceMonitorCollection::do_reset()
00156 {
00157 numberOfCopyWorkers_ = -1;
00158 numberOfInjectWorkers_ = -1;
00159 latchedSataBeastStatus_ = -1;
00160
00161 boost::mutex::scoped_lock sl(diskUsageListMutex_);
00162 for ( DiskUsagePtrList::const_iterator it = diskUsageList_.begin(),
00163 itEnd = diskUsageList_.end();
00164 it != itEnd;
00165 ++it)
00166 {
00167 if ( ! (*it)->retrievingDiskSize_ )
00168 {
00169 (*it)->diskSize_ = -1;
00170 (*it)->absDiskUsage_ = -1;
00171 (*it)->relDiskUsage_ = -1;
00172 (*it)->retVal_ = 0;
00173 (*it)->alarmState_ = AlarmHandler::OKAY;
00174 }
00175 }
00176 }
00177
00178
00179 void ResourceMonitorCollection::do_appendInfoSpaceItems(InfoSpaceItems& infoSpaceItems)
00180 {
00181 infoSpaceItems.push_back(std::make_pair("copyWorkers", ©Workers_));
00182 infoSpaceItems.push_back(std::make_pair("injectWorkers", &injectWorkers_));
00183 infoSpaceItems.push_back(std::make_pair("sataBeastStatus", &sataBeastStatus_));
00184 infoSpaceItems.push_back(std::make_pair("numberOfDisks", &numberOfDisks_));
00185 infoSpaceItems.push_back(std::make_pair("diskPaths", &diskPaths_));
00186 infoSpaceItems.push_back(std::make_pair("totalDiskSpace", &totalDiskSpace_));
00187 infoSpaceItems.push_back(std::make_pair("usedDiskSpace", &usedDiskSpace_));
00188 }
00189
00190
00191 void ResourceMonitorCollection::do_updateInfoSpaceItems()
00192 {
00193 Stats stats;
00194 getStats(stats);
00195
00196 if (stats.numberOfCopyWorkers > 0)
00197 copyWorkers_ = static_cast<xdata::UnsignedInteger32>(stats.numberOfCopyWorkers);
00198 else
00199 copyWorkers_ = 0;
00200
00201 if (stats.numberOfInjectWorkers > 0)
00202 injectWorkers_ = static_cast<xdata::UnsignedInteger32>(stats.numberOfInjectWorkers);
00203 else
00204 injectWorkers_ = 0;
00205
00206 sataBeastStatus_ = stats.sataBeastStatus;
00207 numberOfDisks_ = nLogicalDisks_;
00208
00209 diskPaths_.clear();
00210 totalDiskSpace_.clear();
00211 usedDiskSpace_.clear();
00212
00213 diskPaths_.reserve(stats.diskUsageStatsList.size());
00214 totalDiskSpace_.reserve(stats.diskUsageStatsList.size());
00215 usedDiskSpace_.reserve(stats.diskUsageStatsList.size());
00216
00217 for (DiskUsageStatsPtrList::const_iterator
00218 it = stats.diskUsageStatsList.begin(),
00219 itEnd = stats.diskUsageStatsList.end();
00220 it != itEnd;
00221 ++it)
00222 {
00223 diskPaths_.push_back(
00224 static_cast<xdata::String>( (*it)->pathName )
00225 );
00226 totalDiskSpace_.push_back(
00227 static_cast<xdata::UnsignedInteger32>(
00228 static_cast<unsigned int>( (*it)->diskSize * 1024 )
00229 )
00230 );
00231 usedDiskSpace_.push_back(
00232 static_cast<xdata::UnsignedInteger32>(
00233 static_cast<unsigned int>( (*it)->absDiskUsage * 1024 )
00234 )
00235 );
00236 }
00237
00238 calcDiskUsage();
00239 }
00240
00241
00242 void ResourceMonitorCollection::calcDiskUsage()
00243 {
00244 boost::mutex::scoped_lock sl(diskUsageListMutex_);
00245
00246 for ( DiskUsagePtrList::iterator it = diskUsageList_.begin(),
00247 itEnd = diskUsageList_.end();
00248 it != itEnd;
00249 ++it)
00250 {
00251 retrieveDiskSize(*it);
00252 }
00253 }
00254
00255
00256 void ResourceMonitorCollection::retrieveDiskSize(DiskUsagePtr diskUsage)
00257 {
00258 if ( ! diskUsage->retrievingDiskSize_ )
00259
00260 {
00261 boost::thread thread(
00262 boost::bind( &ResourceMonitorCollection::doStatFs, this, diskUsage)
00263 );
00264 if (
00265 ( ! thread.timed_join( boost::posix_time::milliseconds(500) ) )
00266 || (diskUsage->retVal_ != 0)
00267 )
00268 {
00269 emitDiskAlarm(diskUsage);
00270 }
00271 else
00272 {
00273 const unsigned int blksize = diskUsage->statfs_.f_bsize;
00274 diskUsage->diskSize_ =
00275 static_cast<double>(diskUsage->statfs_.f_blocks * blksize) / 1024 / 1024 / 1024;
00276 diskUsage->absDiskUsage_ =
00277 diskUsage->diskSize_ -
00278 static_cast<double>(diskUsage->statfs_.f_bavail * blksize) / 1024 / 1024 / 1024;
00279 diskUsage->relDiskUsage_ = (100 * (diskUsage->absDiskUsage_ / diskUsage->diskSize_));
00280 if ( diskUsage->relDiskUsage_ > dwParams_.highWaterMark_ )
00281 {
00282 emitDiskSpaceAlarm(diskUsage);
00283 }
00284 else if ( diskUsage->relDiskUsage_ < dwParams_.highWaterMark_*0.95 )
00285
00286 {
00287 revokeDiskAlarm(diskUsage);
00288 }
00289 }
00290 }
00291 }
00292
00293
00294 void ResourceMonitorCollection::doStatFs(DiskUsagePtr diskUsage)
00295 {
00296 diskUsage->retrievingDiskSize_ = true;
00297
00298 #if __APPLE__
00299 diskUsage->retVal_ = statfs(diskUsage->pathName_.c_str(), &(diskUsage->statfs_));
00300 #else
00301 diskUsage->retVal_ = statfs64(diskUsage->pathName_.c_str(), &(diskUsage->statfs_));
00302 #endif
00303 if (diskUsage->pathName_ == "/aSlowDiskForUnitTests") ::sleep(5);
00304
00305 diskUsage->retrievingDiskSize_ = false;
00306 }
00307
00308
00309 void ResourceMonitorCollection::emitDiskAlarm(DiskUsagePtr diskUsage)
00310 {
00311 const std::string msg = "Cannot access " + diskUsage->pathName_ + ". Is it mounted?";
00312
00313 diskUsage->diskSize_ = -1;
00314 diskUsage->absDiskUsage_ = -1;
00315 diskUsage->relDiskUsage_ = -1;
00316
00317 if ( isImportantDisk(diskUsage->pathName_) )
00318 {
00319 diskUsage->alarmState_ = AlarmHandler::FATAL;
00320 XCEPT_DECLARE(stor::exception::DiskSpaceAlarm, ex, msg);
00321 alarmHandler_->moveToFailedState(ex);
00322 }
00323 else
00324 {
00325 diskUsage->alarmState_ = AlarmHandler::ERROR;
00326 XCEPT_DECLARE(stor::exception::DiskSpaceAlarm, ex, msg);
00327 alarmHandler_->raiseAlarm(diskUsage->pathName_, diskUsage->alarmState_, ex);
00328 }
00329 }
00330
00331
00332 void ResourceMonitorCollection::emitDiskSpaceAlarm(DiskUsagePtr diskUsage)
00333 {
00334 if (
00335 isImportantDisk(diskUsage->pathName_) &&
00336 (diskUsage->relDiskUsage_ > dwParams_.failHighWaterMark_)
00337 )
00338 {
00339 diskUsage->alarmState_ = AlarmHandler::FATAL;
00340 XCEPT_DECLARE(stor::exception::DiskSpaceAlarm, ex, diskUsage->toString());
00341 alarmHandler_->moveToFailedState(ex);
00342 }
00343 else
00344 {
00345 diskUsage->alarmState_ = AlarmHandler::WARNING;
00346 XCEPT_DECLARE(stor::exception::DiskSpaceAlarm, ex, diskUsage->toString());
00347 alarmHandler_->raiseAlarm(diskUsage->pathName_, diskUsage->alarmState_, ex);
00348 }
00349 }
00350
00351
00352 bool ResourceMonitorCollection::isImportantDisk(const std::string& pathName)
00353 {
00354 DiskWritingParams::OtherDiskPaths::const_iterator begin =
00355 dwParams_.otherDiskPaths_.begin();
00356 DiskWritingParams::OtherDiskPaths::const_iterator end =
00357 dwParams_.otherDiskPaths_.end();
00358 return ( std::find(begin, end, pathName) == end );
00359 }
00360
00361
00362 void ResourceMonitorCollection::revokeDiskAlarm(DiskUsagePtr diskUsage)
00363 {
00364 diskUsage->alarmState_ = AlarmHandler::OKAY;
00365
00366 alarmHandler_->revokeAlarm(diskUsage->pathName_);
00367 }
00368
00369
00370 void ResourceMonitorCollection::calcNumberOfCopyWorkers()
00371 {
00372 struct passwd* passwd = getpwnam(rmParams_.copyWorkers_.user_.c_str());
00373 if (passwd)
00374 {
00375 numberOfCopyWorkers_ =
00376 getProcessCount(rmParams_.copyWorkers_.command_, passwd->pw_uid);
00377 }
00378 else
00379 {
00380 numberOfCopyWorkers_ = 0;
00381 }
00382
00383 if ( alarmParams_.isProductionSystem_ && rmParams_.copyWorkers_.expectedCount_ >= 0 )
00384 {
00385 checkNumberOfCopyWorkers();
00386 }
00387 }
00388
00389
00390 void ResourceMonitorCollection::checkNumberOfCopyWorkers()
00391 {
00392 const std::string alarmName = "CopyWorkers";
00393
00394 if ( numberOfCopyWorkers_ < rmParams_.copyWorkers_.expectedCount_ )
00395 {
00396 std::ostringstream msg;
00397 msg << "Expected " << rmParams_.copyWorkers_.expectedCount_ <<
00398 " running CopyWorkers, but found " <<
00399 numberOfCopyWorkers_ << ".";
00400 XCEPT_DECLARE(stor::exception::CopyWorkers, ex, msg.str());
00401 alarmHandler_->raiseAlarm(alarmName, AlarmHandler::WARNING, ex);
00402 }
00403 else
00404 {
00405 alarmHandler_->revokeAlarm(alarmName);
00406 }
00407 }
00408
00409
00410 void ResourceMonitorCollection::calcNumberOfInjectWorkers()
00411 {
00412 struct passwd* passwd = getpwnam(rmParams_.injectWorkers_.user_.c_str());
00413 if (passwd)
00414 {
00415 numberOfInjectWorkers_ = getProcessCount(rmParams_.injectWorkers_.command_, passwd->pw_uid);
00416 }
00417 else
00418 {
00419 numberOfInjectWorkers_ = 0;
00420 }
00421
00422 if (
00423 alarmParams_.isProductionSystem_ &&
00424 rmParams_.injectWorkers_.expectedCount_ >= 0
00425 )
00426 {
00427 checkNumberOfInjectWorkers();
00428 }
00429 }
00430
00431
00432 void ResourceMonitorCollection::checkNumberOfInjectWorkers()
00433 {
00434 const std::string alarmName = "InjectWorkers";
00435
00436 if ( numberOfInjectWorkers_ != rmParams_.injectWorkers_.expectedCount_ )
00437 {
00438 std::ostringstream msg;
00439 msg << "Expected " << rmParams_.injectWorkers_.expectedCount_ <<
00440 " running InjectWorkers, but found " <<
00441 numberOfInjectWorkers_ << ".";
00442 XCEPT_DECLARE(stor::exception::InjectWorkers, ex, msg.str());
00443 alarmHandler_->raiseAlarm(alarmName, AlarmHandler::WARNING, ex);
00444 }
00445 else
00446 {
00447 alarmHandler_->revokeAlarm(alarmName);
00448 }
00449 }
00450
00451
00452 void ResourceMonitorCollection::checkSataBeasts()
00453 {
00454 SATABeasts sataBeasts;
00455 if ( getSataBeasts(sataBeasts) )
00456 {
00457 for (
00458 SATABeasts::const_iterator it = sataBeasts.begin(),
00459 itEnd= sataBeasts.end();
00460 it != itEnd;
00461 ++it
00462 )
00463 {
00464 checkSataBeast(*it);
00465 }
00466 }
00467 else
00468 {
00469 latchedSataBeastStatus_ = -1;
00470 }
00471 }
00472
00473
00474 bool ResourceMonitorCollection::getSataBeasts(SATABeasts& sataBeasts)
00475 {
00476 if (! alarmParams_.isProductionSystem_) return false;
00477
00478 std::ifstream in;
00479 in.open( "/proc/mounts" );
00480
00481 if ( ! in.is_open() ) return false;
00482
00483 std::string line;
00484 while( getline(in,line) )
00485 {
00486 size_t pos = line.find("sata");
00487 if ( pos != std::string::npos )
00488 {
00489 std::ostringstream host;
00490 host << "satab-c2c"
00491 << std::setw(2) << std::setfill('0')
00492 << line.substr(pos+4,1)
00493 << "-"
00494 << std::setw(2) << std::setfill('0')
00495 << line.substr(pos+5,1);
00496 sataBeasts.insert(host.str());
00497 }
00498 }
00499 return !sataBeasts.empty();
00500 }
00501
00502
00503 void ResourceMonitorCollection::checkSataBeast(const std::string& sataBeast)
00504 {
00505 if ( ! (checkSataDisks(sataBeast,"-00.cms") || checkSataDisks(sataBeast,"-10.cms")) )
00506 {
00507 XCEPT_DECLARE(stor::exception::SataBeast, ex,
00508 "Failed to connect to SATA beast " + sataBeast);
00509 alarmHandler_->raiseAlarm(sataBeast, AlarmHandler::ERROR, ex);
00510
00511 latchedSataBeastStatus_ = 99999;
00512 }
00513 }
00514
00515
00516 bool ResourceMonitorCollection::checkSataDisks
00517 (
00518 const std::string& sataBeast,
00519 const std::string& hostSuffix
00520 )
00521 {
00522 CurlInterfacePtr curlInterface = CurlInterface::getInterface();
00523 CurlInterface::Content content;
00524
00525
00526 if ( rmParams_.sataUser_.empty() ) return true;
00527
00528 const CURLcode returnCode =
00529 curlInterface->getContent(
00530 "https://" + sataBeast + hostSuffix + "/status.asp",rmParams_.sataUser_,
00531 content
00532 );
00533
00534 if (returnCode == CURLE_OK)
00535 {
00536 updateSataBeastStatus(sataBeast, std::string(&content[0]));
00537 return true;
00538 }
00539 else
00540 {
00541 std::ostringstream msg;
00542 msg << "Failed to connect to SATA controller "
00543 << sataBeast << hostSuffix
00544 << ": " << std::string(&content[0]);
00545 XCEPT_DECLARE(stor::exception::SataBeast, ex, msg.str());
00546 alarmHandler_->notifySentinel(AlarmHandler::WARNING, ex);
00547
00548 return false;
00549 }
00550 }
00551
00552
00553 void ResourceMonitorCollection::updateSataBeastStatus
00554 (
00555 const std::string& sataBeast,
00556 const std::string& content
00557 )
00558 {
00559 boost::regex failedEntry(">([^<]* has failed[^<]*)");
00560 boost::regex failedDisk("Hard disk([[:digit:]]+)");
00561 boost::regex failedController("RAID controller ([[:digit:]]+)");
00562 boost::match_results<std::string::const_iterator> matchedEntry, matchedCause;
00563 boost::match_flag_type flags = boost::match_default;
00564
00565 std::string::const_iterator start = content.begin();
00566 std::string::const_iterator end = content.end();
00567
00568 unsigned int newSataBeastStatus = 0;
00569
00570 while( regex_search(start, end, matchedEntry, failedEntry, flags) )
00571 {
00572 std::string errorMsg = matchedEntry[1];
00573 XCEPT_DECLARE(stor::exception::SataBeast, ex, sataBeast+": "+errorMsg);
00574 alarmHandler_->raiseAlarm(sataBeast, AlarmHandler::ERROR, ex);
00575
00576
00577 if ( regex_search(errorMsg, matchedCause, failedDisk) )
00578 {
00579
00580 ++newSataBeastStatus;
00581 }
00582 else if ( regex_search(errorMsg, matchedCause, failedController) )
00583 {
00584
00585 newSataBeastStatus += 100;
00586 }
00587 else
00588 {
00589
00590 newSataBeastStatus += 1000;
00591 }
00592
00593
00594 start = matchedEntry[0].second;
00595
00596 flags |= boost::match_prev_avail;
00597 flags |= boost::match_not_bob;
00598 }
00599
00600 latchedSataBeastStatus_ = newSataBeastStatus;
00601
00602 if (latchedSataBeastStatus_ == 0)
00603 alarmHandler_->revokeAlarm(sataBeast);
00604
00605 }
00606
00607
00608 namespace {
00609 int filter(const struct dirent *dir)
00610 {
00611 return !fnmatch("[1-9]*", dir->d_name, 0);
00612 }
00613
00614 bool matchUid(const std::string& filename, const uid_t& uid)
00615 {
00616 struct stat filestat;
00617 int result = stat(filename.c_str(), &filestat);
00618 return (result == 0 && filestat.st_uid == uid);
00619 }
00620
00621 bool isMaster(const char* pid)
00622 {
00623
00624 char buf[800];
00625 int fd;
00626 int ppid = 0;
00627 std::ostringstream statfile;
00628 statfile << "/proc/" << pid << "/stat";
00629 snprintf(buf, 32, statfile.str().c_str(), pid);
00630 if ( (fd = open(buf, O_RDONLY, 0) ) == -1 ) return false;
00631 int num = read(fd, buf, sizeof buf - 1);
00632 if(num<80) return false;
00633 buf[num] = '\0';
00634 char* tmp = strrchr(buf, ')');
00635 num = sscanf(tmp + 4,
00636 "%d", &ppid);
00637 close(fd);
00638 return ( num == 1 && ppid == 1 );
00639 }
00640
00641 bool grep(const std::string& cmdline, const std::string& name)
00642 {
00643
00644 std::ifstream in;
00645 in.open( cmdline.c_str() );
00646
00647 std::string line;
00648 if ( in.is_open() )
00649 {
00650 std::string tmp;
00651 while( getline(in,tmp,'\0') )
00652 {
00653 line.append(tmp);
00654 line.append(" ");
00655 }
00656 in.close();
00657 }
00658
00659 return ( line.find(name) != std::string::npos );
00660 }
00661 }
00662
00663
00664 int ResourceMonitorCollection::getProcessCount
00665 (
00666 const std::string& processName,
00667 const int& uid
00668 )
00669 {
00670 int count(0);
00671 struct dirent **namelist;
00672 int n;
00673
00674 #if __APPLE__
00675 return -1;
00676 #else
00677 n = scandir("/proc", &namelist, filter, 0);
00678 #endif
00679 if (n < 0) return -1;
00680
00681 while(n--)
00682 {
00683 std::ostringstream cmdline;
00684 cmdline << "/proc/" << namelist[n]->d_name << "/cmdline";
00685
00686 if ( grep(cmdline.str(), processName) &&
00687 (uid < 0 || matchUid(cmdline.str(), uid)) &&
00688 isMaster(namelist[n]->d_name) )
00689 {
00690 ++count;
00691 }
00692 free(namelist[n]);
00693 }
00694 free(namelist);
00695
00696 return count;
00697 }
00698
00699
00700 ResourceMonitorCollection::DiskUsage::DiskUsage(const std::string& path)
00701 : pathName_(path), absDiskUsage_(-1), relDiskUsage_(-1), diskSize_(-1),
00702 retrievingDiskSize_(false), alarmState_(AlarmHandler::OKAY), retVal_(0)
00703 {}
00704
00705
00706 std::string ResourceMonitorCollection::DiskUsage::toString()
00707 {
00708 std::ostringstream msg;
00709 msg << std::fixed << std::setprecision(1) <<
00710 "Disk space usage for " << pathName_ <<
00711 " is " << relDiskUsage_ << "% (" <<
00712 absDiskUsage_ << "GB of " <<
00713 diskSize_ << "GB).";
00714 return msg.str();
00715 }
00716
00717 }
00718