VirtualBox

Changeset 45051 in vbox


Ignore:
Timestamp:
Mar 15, 2013 3:34:54 PM (12 years ago)
Author:
vboxsync
Message:

Main/Metrics: handle less common cases for FS to disk resolution (#6345)

Location:
trunk/src/VBox/Main
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Main/include/Performance.h

    r44551 r45051  
    389389        virtual int getRawProcessCpuLoad(RTPROCESS process, uint64_t *user, uint64_t *kernel, uint64_t *total);
    390390
    391         /** Returns the list of disks used by the specified file system. */
    392         virtual int getDiskListByFs(const char *name, DiskList& list);
     391        /** Returns the lists of disks (aggregate and physical) used by the specified file system. */
     392        virtual int getDiskListByFs(const char *name, DiskList& listUsage, DiskList& listLoad);
    393393    };
    394394
  • trunk/src/VBox/Main/src-server/HostImpl.cpp

    r44179 r45051  
    29782978
    29792979    /* For now we are concerned with the root file system only. */
    2980     pm::DiskList disks;
    2981     int rc = hal->getDiskListByFs("/", disks);
    2982     if (RT_FAILURE(rc) || disks.empty())
     2980    pm::DiskList disksUsage, disksLoad;
     2981    int rc = hal->getDiskListByFs("/", disksUsage, disksLoad);
     2982    if (RT_FAILURE(rc))
    29832983        return;
    29842984    pm::DiskList::iterator it;
    2985     for (it = disks.begin(); it != disks.end(); ++it)
     2985    for (it = disksLoad.begin(); it != disksLoad.end(); ++it)
    29862986    {
    29872987        Utf8StrFmt strName("Disk/%s", it->c_str());
    29882988        pm::SubMetric *fsLoadUtil   = new pm::SubMetric(strName + "/Load/Util",
    29892989            "Percentage of time disk was busy serving I/O requests.");
    2990         pm::SubMetric *fsUsageTotal = new pm::SubMetric(strName + "/Usage/Total",
    2991             "Disk size.");
    29922990        pm::BaseMetric *fsLoad  = new pm::HostDiskLoadRaw(hal, this, strName + "/Load",
    29932991                                                         *it, fsLoadUtil);
    29942992        aCollector->registerBaseMetric (fsLoad);
    2995         pm::BaseMetric *fsUsage = new pm::HostDiskUsage(hal, this, strName + "/Usage",
    2996                                                         *it, fsUsageTotal);
    2997         aCollector->registerBaseMetric (fsUsage);
    29982993
    29992994        aCollector->registerMetric(new pm::Metric(fsLoad, fsLoadUtil, 0));
     
    30042999        aCollector->registerMetric(new pm::Metric(fsLoad, fsLoadUtil,
    30053000                                                  new pm::AggregateMax()));
     3001    }
     3002    for (it = disksUsage.begin(); it != disksUsage.end(); ++it)
     3003    {
     3004        Utf8StrFmt strName("Disk/%s", it->c_str());
     3005        pm::SubMetric *fsUsageTotal = new pm::SubMetric(strName + "/Usage/Total",
     3006            "Disk size.");
     3007        pm::BaseMetric *fsUsage = new pm::HostDiskUsage(hal, this, strName + "/Usage",
     3008                                                        *it, fsUsageTotal);
     3009        aCollector->registerBaseMetric (fsUsage);
    30063010
    30073011        aCollector->registerMetric(new pm::Metric(fsUsage, fsUsageTotal, 0));
  • trunk/src/VBox/Main/src-server/Performance.cpp

    r44742 r45051  
    9898}
    9999
    100 int CollectorHAL::getDiskListByFs(const char * /* name */, DiskList& /* list */)
     100int CollectorHAL::getDiskListByFs(const char * /* name */, DiskList& /* listUsage */, DiskList& /* listLoad */)
    101101{
    102102    return E_NOTIMPL;
  • trunk/src/VBox/Main/src-server/freebsd/PerformanceFreeBSD.cpp

    r44528 r45051  
    110110}
    111111
    112 int getDiskListByFs(const char *name, DiskList& list)
    113 {
    114     return VERR_NOT_IMPLEMENTED;
    115 }
    116 
    117112} /* namespace pm */
    118113
  • trunk/src/VBox/Main/src-server/linux/PerformanceLinux.cpp

    r44528 r45051  
    5757    virtual int getRawProcessCpuLoad(RTPROCESS process, uint64_t *user, uint64_t *kernel, uint64_t *total);
    5858
    59     virtual int getDiskListByFs(const char *name, DiskList& list);
     59    virtual int getDiskListByFs(const char *name, DiskList& listUsage, DiskList& listLoad);
    6060private:
    6161    virtual int _getRawHostCpuLoad();
     
    6363    char *getDiskName(char *pszDiskName, size_t cbDiskName, const char *pszDevName, bool fTrimDigits);
    6464    void addVolumeDependencies(const char *pcszVolume, DiskList& listDisks);
     65    void addRaidDisks(const char *pcszDevice, DiskList& listDisks);
    6566    char *trimTrailingDigits(char *pszName);
     67    char *trimNewline(char *pszName);
    6668
    6769    struct VMProcessStats
     
    425427}
    426428
     429char *CollectorLinux::trimNewline(char *pszName)
     430{
     431    unsigned cbName = strlen(pszName);
     432    if (cbName == 0)
     433        return pszName;
     434
     435    char *pszEnd = pszName + cbName - 1;
     436    while (pszEnd > pszName && *pszEnd == '\n')
     437        pszEnd--;
     438    pszEnd[1] = '\0';
     439
     440    return pszName;
     441}
     442
    427443char *CollectorLinux::trimTrailingDigits(char *pszName)
    428444{
     
    456472}
    457473
     474void CollectorLinux::addRaidDisks(const char *pcszDevice, DiskList& listDisks)
     475{
     476    FILE *f = fopen("/proc/mdstat", "r");
     477    if (f)
     478    {
     479        char szBuf[128];
     480        while (fgets(szBuf, sizeof(szBuf), f))
     481        {
     482            char *pszBufName = szBuf;
     483
     484            char *pszBufData = strchr(pszBufName, ' ');
     485            if (!pszBufData)
     486            {
     487                LogRel(("CollectorLinux::addRaidDisks() failed to parse disk stats: %s\n", szBuf));
     488                continue;
     489            }
     490            *pszBufData++ = '\0';
     491            if (!strcmp(pcszDevice, pszBufName))
     492            {
     493                while (*pszBufData == ':')         ++pszBufData; /* Skip delimiter */
     494                while (*pszBufData == ' ')         ++pszBufData; /* Skip spaces */
     495                while (RT_C_IS_ALNUM(*pszBufData)) ++pszBufData; /* Skip status */
     496                while (*pszBufData == ' ')         ++pszBufData; /* Skip spaces */
     497                while (RT_C_IS_ALNUM(*pszBufData)) ++pszBufData; /* Skip type */
     498
     499                while (*pszBufData != '\0')
     500                {
     501                    while (*pszBufData == ' ') ++pszBufData; /* Skip spaces */
     502                    char *pszDisk = pszBufData;
     503                    while (RT_C_IS_ALPHA(*pszBufData))
     504                        ++pszBufData;
     505                    if (*pszBufData)
     506                    {
     507                        *pszBufData++ = '\0';
     508                        listDisks.push_back(RTCString(pszDisk));
     509                        while (*pszBufData != '\0' && *pszBufData != ' ')
     510                            ++pszBufData;
     511                    }
     512                    else
     513                        listDisks.push_back(RTCString(pszDisk));
     514                }
     515                break;
     516            }
     517        }
     518        fclose(f);
     519    }
     520}
     521
    458522void CollectorLinux::addVolumeDependencies(const char *pcszVolume, DiskList& listDisks)
    459523{
     
    474538
    475539        while (fgets(szBuf, sizeof(szBuf), fp))
    476             listDisks.push_back(RTCString(trimTrailingDigits(szBuf)));
     540            if (strncmp(szBuf, "dm-", 3))
     541                listDisks.push_back(RTCString(trimTrailingDigits(szBuf)));
     542            else
     543                listDisks.push_back(RTCString(trimNewline(szBuf)));
    477544
    478545        pclose(fp);
     
    482549}
    483550
    484 int CollectorLinux::getDiskListByFs(const char *pszPath, DiskList& listDisks)
     551int CollectorLinux::getDiskListByFs(const char *pszPath, DiskList& listUsage, DiskList& listLoad)
    485552{
    486553    FILE *mtab = setmntent("/etc/mtab", "r");
     
    490557        while ((mntent = getmntent(mtab)))
    491558        {
     559            /* Skip rootfs entry, there must be another root mount. */
     560            if (strcmp(mntent->mnt_fsname, "rootfs") == 0)
     561                continue;
    492562            if (strcmp(pszPath, mntent->mnt_dir) == 0)
    493563            {
    494564                char szDevName[128];
    495                 if (strncmp(mntent->mnt_fsname, "/dev/mapper", 11))
    496                 {
     565                char szFsName[1024];
     566                /* Try to resolve symbolic link if necessary */
     567                ssize_t cbFsName = readlink(mntent->mnt_fsname, szFsName, sizeof(szFsName) - 1);
     568                if (cbFsName != -1)
     569                    szFsName[cbFsName] = '\0';
     570                else
     571                    strcpy(szFsName, mntent->mnt_fsname);
     572                if (!strncmp(szFsName, "/dev/mapper", 11))
     573                {
     574                    /* LVM */
     575                    getDiskName(szDevName, sizeof(szDevName), szFsName, false);
     576                    addVolumeDependencies(szDevName, listUsage);
     577                    listLoad = listUsage;
     578                }
     579                else if (!strncmp(szFsName, "/dev/md", 7))
     580                {
     581                    /* Software RAID */
     582                    getDiskName(szDevName, sizeof(szDevName), szFsName, false);
     583                    listUsage.push_back(RTCString(szDevName));
     584                    addRaidDisks(szDevName, listLoad);
     585                }
     586                else
     587                {
     588                    /* Plain disk partition */
    497589                    getDiskName(szDevName, sizeof(szDevName), mntent->mnt_fsname, true);
    498                     listDisks.push_back(RTCString(szDevName));
    499                 }
    500                 else
    501                 {
    502                     getDiskName(szDevName, sizeof(szDevName), mntent->mnt_fsname, false);
    503                     addVolumeDependencies(szDevName, listDisks);
     590                    listUsage.push_back(RTCString(szDevName));
     591                    listLoad.push_back(RTCString(szDevName));
     592                }
     593                if (listUsage.empty() || listLoad.empty())
     594                {
     595                    LogRel(("Failed to retrive disk info: getDiskName(%s) --> %s\n", mntent->mnt_fsname, szDevName));
    504596                }
    505597                break;
  • trunk/src/VBox/Main/src-server/solaris/PerformanceSolaris.cpp

    r44529 r45051  
    7474    virtual int getRawProcessCpuLoad(RTPROCESS process, uint64_t *user, uint64_t *kernel, uint64_t *total);
    7575
    76     virtual int getDiskListByFs(const char *name, DiskList& list);
     76    virtual int getDiskListByFs(const char *name, DiskList& listUsage, DiskList& listLoad);
    7777private:
    7878    static uint32_t getInstance(const char *pszIfaceName, char *pszDevName);
     
    665665}
    666666
    667 int CollectorSolaris::getDiskListByFs(const char *name, DiskList& list)
     667int CollectorSolaris::getDiskListByFs(const char *name, DiskList& listUsage, DiskList& listLoad)
    668668{
    669669    FsMap::iterator it = mFsMap.find(name);
     
    708708                                pszStart += 8; // Skip "/devices"
    709709                                *pszEnd = '\0'; // Trim partition
    710                                 list.push_back(physToInstName(pszStart));
     710                                listUsage.push_back(physToInstName(pszStart));
    711711                            }
    712712                        }
     
    719719    }
    720720    else
    721         list.push_back(pathToInstName(it->second.c_str()));
     721        listUsage.push_back(pathToInstName(it->second.c_str()));
     722    listLoad = listUsage;
    722723    return VINF_SUCCESS;
    723724}
  • trunk/src/VBox/Main/testcase/tstCollector.cpp

    r45012 r45051  
    224224    uint64_t diskMsStop, totalMsStop;
    225225
    226     pm::DiskList disks;
    227     int rc = collector->getDiskListByFs(FSNAME, disks);
     226    pm::DiskList disksUsage, disksLoad;
     227    int rc = collector->getDiskListByFs(FSNAME, disksUsage, disksLoad);
    228228    if (RT_FAILURE(rc))
    229229    {
     
    231231        return 1;
    232232    }
    233     if (disks.empty())
    234     {
    235         RTPrintf("tstCollector: getDiskListByFs(%s) returned empty list\n", FSNAME);
     233    if (disksUsage.empty())
     234    {
     235        RTPrintf("tstCollector: getDiskListByFs(%s) returned empty usage list\n", FSNAME);
     236        return 1;
     237    }
     238    if (disksLoad.empty())
     239    {
     240        RTPrintf("tstCollector: getDiskListByFs(%s) returned empty usage list\n", FSNAME);
    236241        return 1;
    237242    }
    238243
    239244    pm::DiskList::iterator it;
    240     for (it = disks.begin(); it != disks.end(); ++it)
     245    for (it = disksUsage.begin(); it != disksUsage.end(); ++it)
    241246    {
    242247        uint64_t diskSize = 0;
    243         rc = collector->getHostDiskSize(disks.front().c_str(), &diskSize);
    244         RTPrintf("tstCollector: TESTING - Disk size (%s) = %llu\n", disks.front().c_str(), diskSize);
     248        rc = collector->getHostDiskSize(it->c_str(), &diskSize);
     249        RTPrintf("tstCollector: TESTING - Disk size (%s) = %llu\n", it->c_str(), diskSize);
    245250        if (RT_FAILURE(rc))
    246251        {
     
    248253            return 1;
    249254        }
    250 
    251         RTPrintf("tstCollector: TESTING - Disk utilization (%s), sleeping for 5 sec...\n", disks.front().c_str());
     255    }
     256
     257    for (it = disksLoad.begin(); it != disksLoad.end(); ++it)
     258    {
     259        RTPrintf("tstCollector: TESTING - Disk utilization (%s), sleeping for 5 sec...\n", it->c_str());
    252260
    253261        hints.collectHostCpuLoad();
     
    258266            return 1;
    259267        }
    260         rc = collector->getRawHostDiskLoad(disks.front().c_str(), &diskMsStart, &totalMsStart);
     268        rc = collector->getRawHostDiskLoad(it->c_str(), &diskMsStart, &totalMsStart);
    261269        if (RT_FAILURE(rc))
    262270        {
     
    273281            return 1;
    274282        }
    275         rc = collector->getRawHostDiskLoad(disks.front().c_str(), &diskMsStop, &totalMsStop);
     283        rc = collector->getRawHostDiskLoad(it->c_str(), &diskMsStop, &totalMsStop);
    276284        if (RT_FAILURE(rc))
    277285        {
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette