Index: trunk/src/VBox/Main/include/Performance.h
===================================================================
--- trunk/src/VBox/Main/include/Performance.h	(revision 45034)
+++ trunk/src/VBox/Main/include/Performance.h	(revision 45051)
@@ -389,6 +389,6 @@
         virtual int getRawProcessCpuLoad(RTPROCESS process, uint64_t *user, uint64_t *kernel, uint64_t *total);
 
-        /** Returns the list of disks used by the specified file system. */
-        virtual int getDiskListByFs(const char *name, DiskList& list);
+        /** Returns the lists of disks (aggregate and physical) used by the specified file system. */
+        virtual int getDiskListByFs(const char *name, DiskList& listUsage, DiskList& listLoad);
     };
 
Index: trunk/src/VBox/Main/src-server/HostImpl.cpp
===================================================================
--- trunk/src/VBox/Main/src-server/HostImpl.cpp	(revision 45034)
+++ trunk/src/VBox/Main/src-server/HostImpl.cpp	(revision 45051)
@@ -2978,22 +2978,17 @@
 
     /* For now we are concerned with the root file system only. */
-    pm::DiskList disks;
-    int rc = hal->getDiskListByFs("/", disks);
-    if (RT_FAILURE(rc) || disks.empty())
+    pm::DiskList disksUsage, disksLoad;
+    int rc = hal->getDiskListByFs("/", disksUsage, disksLoad);
+    if (RT_FAILURE(rc))
         return;
     pm::DiskList::iterator it;
-    for (it = disks.begin(); it != disks.end(); ++it)
+    for (it = disksLoad.begin(); it != disksLoad.end(); ++it)
     {
         Utf8StrFmt strName("Disk/%s", it->c_str());
         pm::SubMetric *fsLoadUtil   = new pm::SubMetric(strName + "/Load/Util",
             "Percentage of time disk was busy serving I/O requests.");
-        pm::SubMetric *fsUsageTotal = new pm::SubMetric(strName + "/Usage/Total",
-            "Disk size.");
         pm::BaseMetric *fsLoad  = new pm::HostDiskLoadRaw(hal, this, strName + "/Load",
                                                          *it, fsLoadUtil);
         aCollector->registerBaseMetric (fsLoad);
-        pm::BaseMetric *fsUsage = new pm::HostDiskUsage(hal, this, strName + "/Usage",
-                                                        *it, fsUsageTotal);
-        aCollector->registerBaseMetric (fsUsage);
 
         aCollector->registerMetric(new pm::Metric(fsLoad, fsLoadUtil, 0));
@@ -3004,4 +2999,13 @@
         aCollector->registerMetric(new pm::Metric(fsLoad, fsLoadUtil,
                                                   new pm::AggregateMax()));
+    }
+    for (it = disksUsage.begin(); it != disksUsage.end(); ++it)
+    {
+        Utf8StrFmt strName("Disk/%s", it->c_str());
+        pm::SubMetric *fsUsageTotal = new pm::SubMetric(strName + "/Usage/Total",
+            "Disk size.");
+        pm::BaseMetric *fsUsage = new pm::HostDiskUsage(hal, this, strName + "/Usage",
+                                                        *it, fsUsageTotal);
+        aCollector->registerBaseMetric (fsUsage);
 
         aCollector->registerMetric(new pm::Metric(fsUsage, fsUsageTotal, 0));
Index: trunk/src/VBox/Main/src-server/Performance.cpp
===================================================================
--- trunk/src/VBox/Main/src-server/Performance.cpp	(revision 45034)
+++ trunk/src/VBox/Main/src-server/Performance.cpp	(revision 45051)
@@ -98,5 +98,5 @@
 }
 
-int CollectorHAL::getDiskListByFs(const char * /* name */, DiskList& /* list */)
+int CollectorHAL::getDiskListByFs(const char * /* name */, DiskList& /* listUsage */, DiskList& /* listLoad */)
 {
     return E_NOTIMPL;
Index: trunk/src/VBox/Main/src-server/freebsd/PerformanceFreeBSD.cpp
===================================================================
--- trunk/src/VBox/Main/src-server/freebsd/PerformanceFreeBSD.cpp	(revision 45034)
+++ trunk/src/VBox/Main/src-server/freebsd/PerformanceFreeBSD.cpp	(revision 45051)
@@ -110,9 +110,4 @@
 }
 
-int getDiskListByFs(const char *name, DiskList& list)
-{
-    return VERR_NOT_IMPLEMENTED;
-}
-
 } /* namespace pm */
 
Index: trunk/src/VBox/Main/src-server/linux/PerformanceLinux.cpp
===================================================================
--- trunk/src/VBox/Main/src-server/linux/PerformanceLinux.cpp	(revision 45034)
+++ trunk/src/VBox/Main/src-server/linux/PerformanceLinux.cpp	(revision 45051)
@@ -57,5 +57,5 @@
     virtual int getRawProcessCpuLoad(RTPROCESS process, uint64_t *user, uint64_t *kernel, uint64_t *total);
 
-    virtual int getDiskListByFs(const char *name, DiskList& list);
+    virtual int getDiskListByFs(const char *name, DiskList& listUsage, DiskList& listLoad);
 private:
     virtual int _getRawHostCpuLoad();
@@ -63,5 +63,7 @@
     char *getDiskName(char *pszDiskName, size_t cbDiskName, const char *pszDevName, bool fTrimDigits);
     void addVolumeDependencies(const char *pcszVolume, DiskList& listDisks);
+    void addRaidDisks(const char *pcszDevice, DiskList& listDisks);
     char *trimTrailingDigits(char *pszName);
+    char *trimNewline(char *pszName);
 
     struct VMProcessStats
@@ -425,4 +427,18 @@
 }
 
+char *CollectorLinux::trimNewline(char *pszName)
+{
+    unsigned cbName = strlen(pszName);
+    if (cbName == 0)
+        return pszName;
+
+    char *pszEnd = pszName + cbName - 1;
+    while (pszEnd > pszName && *pszEnd == '\n')
+        pszEnd--;
+    pszEnd[1] = '\0';
+
+    return pszName;
+}
+
 char *CollectorLinux::trimTrailingDigits(char *pszName)
 {
@@ -456,4 +472,52 @@
 }
 
+void CollectorLinux::addRaidDisks(const char *pcszDevice, DiskList& listDisks)
+{
+    FILE *f = fopen("/proc/mdstat", "r");
+    if (f)
+    {
+        char szBuf[128];
+        while (fgets(szBuf, sizeof(szBuf), f))
+        {
+            char *pszBufName = szBuf;
+
+            char *pszBufData = strchr(pszBufName, ' ');
+            if (!pszBufData)
+            {
+                LogRel(("CollectorLinux::addRaidDisks() failed to parse disk stats: %s\n", szBuf));
+                continue;
+            }
+            *pszBufData++ = '\0';
+            if (!strcmp(pcszDevice, pszBufName))
+            {
+                while (*pszBufData == ':')         ++pszBufData; /* Skip delimiter */
+                while (*pszBufData == ' ')         ++pszBufData; /* Skip spaces */
+                while (RT_C_IS_ALNUM(*pszBufData)) ++pszBufData; /* Skip status */
+                while (*pszBufData == ' ')         ++pszBufData; /* Skip spaces */
+                while (RT_C_IS_ALNUM(*pszBufData)) ++pszBufData; /* Skip type */
+
+                while (*pszBufData != '\0')
+                {
+                    while (*pszBufData == ' ') ++pszBufData; /* Skip spaces */
+                    char *pszDisk = pszBufData;
+                    while (RT_C_IS_ALPHA(*pszBufData))
+                        ++pszBufData;
+                    if (*pszBufData)
+                    {
+                        *pszBufData++ = '\0';
+                        listDisks.push_back(RTCString(pszDisk));
+                        while (*pszBufData != '\0' && *pszBufData != ' ')
+                            ++pszBufData;
+                    }
+                    else
+                        listDisks.push_back(RTCString(pszDisk));
+                }
+                break;
+            }
+        }
+        fclose(f);
+    }
+}
+
 void CollectorLinux::addVolumeDependencies(const char *pcszVolume, DiskList& listDisks)
 {
@@ -474,5 +538,8 @@
 
         while (fgets(szBuf, sizeof(szBuf), fp))
-            listDisks.push_back(RTCString(trimTrailingDigits(szBuf)));
+            if (strncmp(szBuf, "dm-", 3))
+                listDisks.push_back(RTCString(trimTrailingDigits(szBuf)));
+            else
+                listDisks.push_back(RTCString(trimNewline(szBuf)));
 
         pclose(fp);
@@ -482,5 +549,5 @@
 }
 
-int CollectorLinux::getDiskListByFs(const char *pszPath, DiskList& listDisks)
+int CollectorLinux::getDiskListByFs(const char *pszPath, DiskList& listUsage, DiskList& listLoad)
 {
     FILE *mtab = setmntent("/etc/mtab", "r");
@@ -490,16 +557,41 @@
         while ((mntent = getmntent(mtab)))
         {
+            /* Skip rootfs entry, there must be another root mount. */
+            if (strcmp(mntent->mnt_fsname, "rootfs") == 0)
+                continue;
             if (strcmp(pszPath, mntent->mnt_dir) == 0)
             {
                 char szDevName[128];
-                if (strncmp(mntent->mnt_fsname, "/dev/mapper", 11))
-                {
+                char szFsName[1024];
+                /* Try to resolve symbolic link if necessary */
+                ssize_t cbFsName = readlink(mntent->mnt_fsname, szFsName, sizeof(szFsName) - 1);
+                if (cbFsName != -1)
+                    szFsName[cbFsName] = '\0';
+                else
+                    strcpy(szFsName, mntent->mnt_fsname);
+                if (!strncmp(szFsName, "/dev/mapper", 11))
+                {
+                    /* LVM */
+                    getDiskName(szDevName, sizeof(szDevName), szFsName, false);
+                    addVolumeDependencies(szDevName, listUsage);
+                    listLoad = listUsage;
+                }
+                else if (!strncmp(szFsName, "/dev/md", 7))
+                {
+                    /* Software RAID */
+                    getDiskName(szDevName, sizeof(szDevName), szFsName, false);
+                    listUsage.push_back(RTCString(szDevName));
+                    addRaidDisks(szDevName, listLoad);
+                }
+                else
+                {
+                    /* Plain disk partition */
                     getDiskName(szDevName, sizeof(szDevName), mntent->mnt_fsname, true);
-                    listDisks.push_back(RTCString(szDevName));
-                }
-                else
-                {
-                    getDiskName(szDevName, sizeof(szDevName), mntent->mnt_fsname, false);
-                    addVolumeDependencies(szDevName, listDisks);
+                    listUsage.push_back(RTCString(szDevName));
+                    listLoad.push_back(RTCString(szDevName));
+                }
+                if (listUsage.empty() || listLoad.empty())
+                {
+                    LogRel(("Failed to retrive disk info: getDiskName(%s) --> %s\n", mntent->mnt_fsname, szDevName));
                 }
                 break;
Index: trunk/src/VBox/Main/src-server/solaris/PerformanceSolaris.cpp
===================================================================
--- trunk/src/VBox/Main/src-server/solaris/PerformanceSolaris.cpp	(revision 45034)
+++ trunk/src/VBox/Main/src-server/solaris/PerformanceSolaris.cpp	(revision 45051)
@@ -74,5 +74,5 @@
     virtual int getRawProcessCpuLoad(RTPROCESS process, uint64_t *user, uint64_t *kernel, uint64_t *total);
 
-    virtual int getDiskListByFs(const char *name, DiskList& list);
+    virtual int getDiskListByFs(const char *name, DiskList& listUsage, DiskList& listLoad);
 private:
     static uint32_t getInstance(const char *pszIfaceName, char *pszDevName);
@@ -665,5 +665,5 @@
 }
 
-int CollectorSolaris::getDiskListByFs(const char *name, DiskList& list)
+int CollectorSolaris::getDiskListByFs(const char *name, DiskList& listUsage, DiskList& listLoad)
 {
     FsMap::iterator it = mFsMap.find(name);
@@ -708,5 +708,5 @@
                                 pszStart += 8; // Skip "/devices"
                                 *pszEnd = '\0'; // Trim partition
-                                list.push_back(physToInstName(pszStart));
+                                listUsage.push_back(physToInstName(pszStart));
                             }
                         }
@@ -719,5 +719,6 @@
     }
     else
-        list.push_back(pathToInstName(it->second.c_str()));
+        listUsage.push_back(pathToInstName(it->second.c_str()));
+    listLoad = listUsage;
     return VINF_SUCCESS;
 }
Index: trunk/src/VBox/Main/testcase/tstCollector.cpp
===================================================================
--- trunk/src/VBox/Main/testcase/tstCollector.cpp	(revision 45034)
+++ trunk/src/VBox/Main/testcase/tstCollector.cpp	(revision 45051)
@@ -224,6 +224,6 @@
     uint64_t diskMsStop, totalMsStop;
 
-    pm::DiskList disks;
-    int rc = collector->getDiskListByFs(FSNAME, disks);
+    pm::DiskList disksUsage, disksLoad;
+    int rc = collector->getDiskListByFs(FSNAME, disksUsage, disksLoad);
     if (RT_FAILURE(rc))
     {
@@ -231,16 +231,21 @@
         return 1;
     }
-    if (disks.empty())
-    {
-        RTPrintf("tstCollector: getDiskListByFs(%s) returned empty list\n", FSNAME);
+    if (disksUsage.empty())
+    {
+        RTPrintf("tstCollector: getDiskListByFs(%s) returned empty usage list\n", FSNAME);
+        return 1;
+    }
+    if (disksLoad.empty())
+    {
+        RTPrintf("tstCollector: getDiskListByFs(%s) returned empty usage list\n", FSNAME);
         return 1;
     }
 
     pm::DiskList::iterator it;
-    for (it = disks.begin(); it != disks.end(); ++it)
+    for (it = disksUsage.begin(); it != disksUsage.end(); ++it)
     {
         uint64_t diskSize = 0;
-        rc = collector->getHostDiskSize(disks.front().c_str(), &diskSize);
-        RTPrintf("tstCollector: TESTING - Disk size (%s) = %llu\n", disks.front().c_str(), diskSize);
+        rc = collector->getHostDiskSize(it->c_str(), &diskSize);
+        RTPrintf("tstCollector: TESTING - Disk size (%s) = %llu\n", it->c_str(), diskSize);
         if (RT_FAILURE(rc))
         {
@@ -248,6 +253,9 @@
             return 1;
         }
-
-        RTPrintf("tstCollector: TESTING - Disk utilization (%s), sleeping for 5 sec...\n", disks.front().c_str());
+    }
+
+    for (it = disksLoad.begin(); it != disksLoad.end(); ++it)
+    {
+        RTPrintf("tstCollector: TESTING - Disk utilization (%s), sleeping for 5 sec...\n", it->c_str());
 
         hints.collectHostCpuLoad();
@@ -258,5 +266,5 @@
             return 1;
         }
-        rc = collector->getRawHostDiskLoad(disks.front().c_str(), &diskMsStart, &totalMsStart);
+        rc = collector->getRawHostDiskLoad(it->c_str(), &diskMsStart, &totalMsStart);
         if (RT_FAILURE(rc))
         {
@@ -273,5 +281,5 @@
             return 1;
         }
-        rc = collector->getRawHostDiskLoad(disks.front().c_str(), &diskMsStop, &totalMsStop);
+        rc = collector->getRawHostDiskLoad(it->c_str(), &diskMsStop, &totalMsStop);
         if (RT_FAILURE(rc))
         {
