VirtualBox

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)

File:
1 edited

Legend:

Unmodified
Added
Removed
  • 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;
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