Changeset 43629 in vbox for trunk/src/VBox/Main/src-server
- Timestamp:
- Oct 12, 2012 9:26:07 AM (12 years ago)
- svn:sync-xref-src-repo-rev:
- 81354
- Location:
- trunk/src/VBox/Main/src-server
- Files:
-
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Main/src-server/HostImpl.cpp
r43525 r43629 2884 2884 #ifdef VBOX_WITH_RESOURCE_USAGE_API 2885 2885 2886 void Host::registerDiskMetrics(PerformanceCollector *aCollector) 2887 { 2888 pm::CollectorHAL *hal = aCollector->getHAL(); 2889 /* Create sub metrics */ 2890 Utf8StrFmt fsNameBase("FS/{%s}/Usage", "/"); 2891 //Utf8StrFmt fsNameBase("Filesystem/[root]/Usage"); 2892 pm::SubMetric *fsRootUsageTotal = new pm::SubMetric(fsNameBase + "/Total", 2893 "Root file system size."); 2894 pm::SubMetric *fsRootUsageUsed = new pm::SubMetric(fsNameBase + "/Used", 2895 "Root file system space currently occupied."); 2896 pm::SubMetric *fsRootUsageFree = new pm::SubMetric(fsNameBase + "/Free", 2897 "Root file system space currently empty."); 2898 2899 pm::BaseMetric *fsRootUsage = new pm::HostFilesystemUsage(hal, this, 2900 fsNameBase, "/", 2901 fsRootUsageTotal, 2902 fsRootUsageUsed, 2903 fsRootUsageFree); 2904 aCollector->registerBaseMetric (fsRootUsage); 2905 2906 aCollector->registerMetric(new pm::Metric(fsRootUsage, fsRootUsageTotal, 0)); 2907 aCollector->registerMetric(new pm::Metric(fsRootUsage, fsRootUsageTotal, 2908 new pm::AggregateAvg())); 2909 aCollector->registerMetric(new pm::Metric(fsRootUsage, fsRootUsageTotal, 2910 new pm::AggregateMin())); 2911 aCollector->registerMetric(new pm::Metric(fsRootUsage, fsRootUsageTotal, 2912 new pm::AggregateMax())); 2913 2914 aCollector->registerMetric(new pm::Metric(fsRootUsage, fsRootUsageUsed, 0)); 2915 aCollector->registerMetric(new pm::Metric(fsRootUsage, fsRootUsageUsed, 2916 new pm::AggregateAvg())); 2917 aCollector->registerMetric(new pm::Metric(fsRootUsage, fsRootUsageUsed, 2918 new pm::AggregateMin())); 2919 aCollector->registerMetric(new pm::Metric(fsRootUsage, fsRootUsageUsed, 2920 new pm::AggregateMax())); 2921 2922 aCollector->registerMetric(new pm::Metric(fsRootUsage, fsRootUsageFree, 0)); 2923 aCollector->registerMetric(new pm::Metric(fsRootUsage, fsRootUsageFree, 2924 new pm::AggregateAvg())); 2925 aCollector->registerMetric(new pm::Metric(fsRootUsage, fsRootUsageFree, 2926 new pm::AggregateMin())); 2927 aCollector->registerMetric(new pm::Metric(fsRootUsage, fsRootUsageFree, 2928 new pm::AggregateMax())); 2929 2930 /* For now we are concerned with the root file system only. */ 2931 pm::DiskList disks; 2932 int rc = pm::getDiskListByFs("/", disks); 2933 if (RT_FAILURE(rc) || disks.empty()) 2934 return; 2935 pm::DiskList::iterator it; 2936 for (it = disks.begin(); it != disks.end(); ++it) 2937 { 2938 Utf8StrFmt strName("Disk/%s/Load", it->c_str()); 2939 pm::SubMetric *fsLoadUtil = new pm::SubMetric(strName + "/Util", 2940 "Percentage of time disk was busy serving I/O requests."); 2941 pm::BaseMetric *fsLoad = new pm::HostDiskLoadRaw(hal, this, strName, 2942 *it, fsLoadUtil); 2943 aCollector->registerBaseMetric (fsLoad); 2944 2945 aCollector->registerMetric(new pm::Metric(fsLoad, fsLoadUtil, 0)); 2946 aCollector->registerMetric(new pm::Metric(fsLoad, fsLoadUtil, 2947 new pm::AggregateAvg())); 2948 aCollector->registerMetric(new pm::Metric(fsLoad, fsLoadUtil, 2949 new pm::AggregateMin())); 2950 aCollector->registerMetric(new pm::Metric(fsLoad, fsLoadUtil, 2951 new pm::AggregateMax())); 2952 } 2953 } 2954 2886 2955 void Host::registerMetrics(PerformanceCollector *aCollector) 2887 2956 { … … 3017 3086 aCollector->registerMetric(new pm::Metric(ramVmm, ramVMMShared, 3018 3087 new pm::AggregateMax())); 3088 registerDiskMetrics(aCollector); 3019 3089 } 3020 3090 -
trunk/src/VBox/Main/src-server/HostNetworkInterfaceImpl.cpp
r43618 r43629 95 95 Utf8StrFmt strName("Net/%ls/Load", mShortName.raw()); 96 96 pm::SubMetric *networkLoadRx = new pm::SubMetric(strName + "/Rx", 97 "Percentage of network interface bandwidth used.");97 "Percentage of network interface receive bandwidth used."); 98 98 pm::SubMetric *networkLoadTx = new pm::SubMetric(strName + "/Tx", 99 "Percentage of network interface bandwidth used.");99 "Percentage of network interface transmit bandwidth used."); 100 100 101 101 /* Create and register base metrics */ -
trunk/src/VBox/Main/src-server/Performance.cpp
r43618 r43629 64 64 } 65 65 66 int CollectorHAL::getRawHostDiskLoad(const char * /* name */, uint64_t * /* disk_ms */, uint64_t * /* total_ms */) 67 { 68 return E_NOTIMPL; 69 } 70 66 71 int CollectorHAL::getRawProcessCpuLoad(RTPROCESS /* process */, uint64_t * /* user */, uint64_t * /* kernel */, uint64_t * /* total */) 67 72 { … … 70 75 71 76 int CollectorHAL::getHostMemoryUsage(ULONG * /* total */, ULONG * /* used */, ULONG * /* available */) 77 { 78 return E_NOTIMPL; 79 } 80 81 int CollectorHAL::getHostFilesystemUsage(const char * /* name */, ULONG * /* total */, ULONG * /* used */, ULONG * /* available */) 72 82 { 73 83 return E_NOTIMPL; … … 705 715 } 706 716 717 void HostDiskLoadRaw::init(ULONG period, ULONG length) 718 { 719 mPeriod = period; 720 mLength = length; 721 mUtil->init(mLength); 722 int rc = mHAL->getRawHostDiskLoad(mDiskName.c_str(), &mDiskPrev, &mTotalPrev); 723 AssertRC(rc); 724 } 725 726 void HostDiskLoadRaw::preCollect(CollectorHints& hints, uint64_t /* iTick */) 727 { 728 hints.collectHostCpuLoad(); 729 } 730 731 void HostDiskLoadRaw::collect() 732 { 733 uint64_t disk, total; 734 735 int rc = mHAL->getRawHostDiskLoad(mDiskName.c_str(), &disk, &total); 736 if (RT_SUCCESS(rc)) 737 { 738 uint64_t diskDiff = disk - mDiskPrev; 739 uint64_t totalDiff = total - mTotalPrev; 740 741 if (RT_UNLIKELY(totalDiff == 0)) 742 { 743 Assert(totalDiff); 744 LogFlowThisFunc(("Improbable! Less than millisecond passed! Disk=%s\n", mDiskName.c_str())); 745 mUtil->put(0); 746 } 747 else if (diskDiff > totalDiff) 748 { 749 /* 750 * It is possible that the disk spent more time than CPU because 751 * CPU measurements are taken during the pre-collect phase. We try 752 * to compensate for than by adding the extra to the next round of 753 * measurements. 754 */ 755 mUtil->put(PM_NETWORK_LOAD_MULTIPLIER); 756 Assert((diskDiff - totalDiff) < mPeriod * 1000); 757 if ((diskDiff - totalDiff) > mPeriod * 1000) 758 { 759 LogRel(("Disk utilization time exceeds CPU time by more" 760 " than the collection period (%llu ms)\n", diskDiff - totalDiff)); 761 } 762 else 763 { 764 disk = mDiskPrev + totalDiff; 765 LogFlowThisFunc(("Moved %u milliseconds to the next period.\n", (unsigned)(diskDiff - totalDiff))); 766 } 767 } 768 else 769 { 770 mUtil->put((ULONG)(PM_NETWORK_LOAD_MULTIPLIER * diskDiff / totalDiff)); 771 } 772 773 mDiskPrev = disk; 774 mTotalPrev = total; 775 } 776 else 777 LogFlowThisFunc(("Failed to collect data: %Rrc (%d).\n", rc)); 778 } 779 707 780 void HostCpuMhz::init(ULONG period, ULONG length) 708 781 { … … 738 811 ULONG total, used, available; 739 812 int rc = mHAL->getHostMemoryUsage(&total, &used, &available); 813 if (RT_SUCCESS(rc)) 814 { 815 mTotal->put(total); 816 mUsed->put(used); 817 mAvailable->put(available); 818 819 } 820 } 821 822 void HostFilesystemUsage::init(ULONG period, ULONG length) 823 { 824 mPeriod = period; 825 mLength = length; 826 mTotal->init(mLength); 827 mUsed->init(mLength); 828 mAvailable->init(mLength); 829 } 830 831 void HostFilesystemUsage::preCollect(CollectorHints& /* hints */, uint64_t /* iTick */) 832 { 833 } 834 835 void HostFilesystemUsage::collect() 836 { 837 ULONG total, used, available; 838 int rc = mHAL->getHostFilesystemUsage(mFsName.c_str(), &total, &used, &available); 740 839 if (RT_SUCCESS(rc)) 741 840 { -
trunk/src/VBox/Main/src-server/darwin/PerformanceDarwin.cpp
r43556 r43629 162 162 } 163 163 164 int getDiskListByFs(const char *name, DiskList& list) 165 { 166 return VERR_NOT_IMPLEMENTED; 164 167 } 165 168 169 } 170 -
trunk/src/VBox/Main/src-server/linux/PerformanceLinux.cpp
r43512 r43629 19 19 20 20 #include <stdio.h> 21 #include <unistd.h> 22 #include <sys/statvfs.h> 23 #include <errno.h> 24 #include <mntent.h> 21 25 #include <iprt/alloc.h> 26 #include <iprt/cdefs.h> 27 #include <iprt/ctype.h> 22 28 #include <iprt/err.h> 23 29 #include <iprt/param.h> 24 30 #include <iprt/string.h> 31 #include <iprt/mp.h> 25 32 26 33 #include <map> … … 35 42 { 36 43 public: 44 CollectorLinux(); 37 45 virtual int preCollect(const CollectorHints& hints, uint64_t /* iTick */); 38 46 virtual int getHostMemoryUsage(ULONG *total, ULONG *used, ULONG *available); 47 virtual int getHostFilesystemUsage(const char *name, ULONG *total, ULONG *used, ULONG *available); 39 48 virtual int getProcessMemoryUsage(RTPROCESS process, ULONG *used); 40 49 41 50 virtual int getRawHostCpuLoad(uint64_t *user, uint64_t *kernel, uint64_t *idle); 42 51 virtual int getRawHostNetworkLoad(const char *name, uint64_t *rx, uint64_t *tx); 52 virtual int getRawHostDiskLoad(const char *name, uint64_t *disk_ms, uint64_t *total_ms); 43 53 virtual int getRawProcessCpuLoad(RTPROCESS process, uint64_t *user, uint64_t *kernel, uint64_t *total); 44 54 private: 45 virtual int _getRawHostCpuLoad( uint64_t *user, uint64_t *kernel, uint64_t *idle);55 virtual int _getRawHostCpuLoad(); 46 56 int getRawProcessStats(RTPROCESS process, uint64_t *cpuUser, uint64_t *cpuKernel, ULONG *memPagesUsed); 47 57 … … 57 67 VMProcessMap mProcessStats; 58 68 uint64_t mUser, mKernel, mIdle; 69 uint64_t mSingleUser, mSingleKernel, mSingleIdle; 70 uint32_t mHZ; 59 71 }; 60 72 … … 65 77 66 78 // Collector HAL for Linux 79 80 CollectorLinux::CollectorLinux() 81 { 82 long hz = sysconf(_SC_CLK_TCK); 83 if (hz == -1) 84 { 85 LogRel(("CollectorLinux failed to obtain HZ from kernel, assuming 100.\n")); 86 mHZ = 100; 87 } 88 else 89 mHZ = hz; 90 LogFlowThisFunc(("mHZ=%u\n", mHZ)); 91 } 67 92 68 93 int CollectorLinux::preCollect(const CollectorHints& hints, uint64_t /* iTick */) … … 84 109 if (hints.isHostCpuLoadCollected() || mProcessStats.size()) 85 110 { 86 _getRawHostCpuLoad( &mUser, &mKernel, &mIdle);87 } 88 return VINF_SUCCESS; 89 } 90 91 int CollectorLinux::_getRawHostCpuLoad( uint64_t *user, uint64_t *kernel, uint64_t *idle)92 { 93 int rc = VINF_SUCCESS; 94 ULONG u32user, u32nice, u32kernel, u32idle;111 _getRawHostCpuLoad(); 112 } 113 return VINF_SUCCESS; 114 } 115 116 int CollectorLinux::_getRawHostCpuLoad() 117 { 118 int rc = VINF_SUCCESS; 119 long long unsigned uUser, uNice, uKernel, uIdle, uIowait, uIrq, uSoftirq; 95 120 FILE *f = fopen("/proc/stat", "r"); 96 121 97 122 if (f) 98 123 { 99 if (fscanf(f, "cpu %u %u %u %u", &u32user, &u32nice, &u32kernel, &u32idle) == 4) 100 { 101 *user = (uint64_t)u32user + u32nice; 102 *kernel = u32kernel; 103 *idle = u32idle; 124 char szBuf[128]; 125 if (fgets(szBuf, sizeof(szBuf), f)) 126 { 127 if (sscanf(szBuf, "cpu %llu %llu %llu %llu %llu %llu %llu", 128 &uUser, &uNice, &uKernel, &uIdle, &uIowait, 129 &uIrq, &uSoftirq) == 7) 130 { 131 mUser = uUser + uNice; 132 mKernel = uKernel + uIrq + uSoftirq; 133 mIdle = uIdle + uIowait; 134 } 135 /* Try to get single CPU stats. */ 136 if (fgets(szBuf, sizeof(szBuf), f)) 137 { 138 if (sscanf(szBuf, "cpu0 %llu %llu %llu %llu %llu %llu %llu", 139 &uUser, &uNice, &uKernel, &uIdle, &uIowait, 140 &uIrq, &uSoftirq) == 7) 141 { 142 mSingleUser = uUser + uNice; 143 mSingleKernel = uKernel + uIrq + uSoftirq; 144 mSingleIdle = uIdle + uIowait; 145 } 146 else 147 { 148 /* Assume that this is not an SMP system. */ 149 Assert(RTMpGetCount() == 1); 150 mSingleUser = mUser; 151 mSingleKernel = mKernel; 152 mSingleIdle = mIdle; 153 } 154 } 155 else 156 rc = VERR_FILE_IO_ERROR; 104 157 } 105 158 else … … 161 214 162 215 return rc; 216 } 217 218 int CollectorLinux::getHostFilesystemUsage(const char *path, ULONG *total, ULONG *used, ULONG *available) 219 { 220 struct statvfs stats; 221 const unsigned _MB = 1024 * 1024; 222 223 if (statvfs(path, &stats) == -1) 224 { 225 LogRel(("Failed to collect %s filesystem usage: errno=%d.\n", path, errno)); 226 return VERR_ACCESS_DENIED; 227 } 228 uint64_t cbBlock = stats.f_frsize ? stats.f_frsize : stats.f_bsize; 229 *total = (ULONG)(cbBlock * stats.f_blocks / _MB); 230 *used = (ULONG)(cbBlock * (stats.f_blocks - stats.f_bfree) / _MB); 231 *available = (ULONG)(cbBlock * stats.f_bavail / _MB); 232 233 return VINF_SUCCESS; 163 234 } 164 235 … … 252 323 } 253 324 254 } 255 325 int CollectorLinux::getRawHostDiskLoad(const char *name, uint64_t *disk_ms, uint64_t *total_ms) 326 { 327 int rc = VINF_SUCCESS; 328 char szIfName[/*IFNAMSIZ*/ 16 + 36]; 329 long long unsigned int u64Busy, tmp; 330 331 RTStrPrintf(szIfName, sizeof(szIfName), "/sys/class/block/%s/stat", name); 332 FILE *f = fopen(szIfName, "r"); 333 if (f) 334 { 335 if (fscanf(f, "%llu %llu %llu %llu %llu %llu %llu %llu %llu %llu %llu", 336 &tmp, &tmp, &tmp, &tmp, &tmp, &tmp, &tmp, &tmp, &tmp, &u64Busy, &tmp) == 11) 337 { 338 *disk_ms = u64Busy; 339 *total_ms = (uint64_t)(mSingleUser + mSingleKernel + mSingleIdle) * 1000 / mHZ; 340 } 341 else 342 rc = VERR_FILE_IO_ERROR; 343 fclose(f); 344 } 345 else 346 rc = VERR_ACCESS_DENIED; 347 348 return rc; 349 } 350 351 static char *getDiskName(char *pszDiskName, size_t cbDiskName, const char *pszDevName) 352 { 353 unsigned cbName = 0; 354 unsigned cbDevName = strlen(pszDevName); 355 const char *pszEnd = pszDevName + cbDevName - 1; 356 while (pszEnd > pszDevName && RT_C_IS_DIGIT(*pszEnd)) 357 pszEnd--; 358 while (pszEnd > pszDevName && *pszEnd != '/') 359 { 360 cbName++; 361 pszEnd--; 362 } 363 RTStrCopy(pszDiskName, RT_MIN(cbName + 1, cbDiskName), pszEnd + 1); 364 return pszDiskName; 365 } 366 367 368 int getDiskListByFs(const char *pszPath, DiskList& listDisks) 369 { 370 FILE *mtab = setmntent("/etc/mtab", "r"); 371 if (mtab) 372 { 373 struct mntent *mntent; 374 while ((mntent = getmntent(mtab))) 375 { 376 if (strcmp(pszPath, mntent->mnt_dir) == 0) 377 { 378 char szDevName[32]; 379 listDisks.push_back(RTCString(getDiskName(szDevName, sizeof(szDevName), mntent->mnt_fsname))); 380 break; 381 } 382 } 383 endmntent(mtab); 384 } 385 return VINF_SUCCESS; 386 } 387 388 } 389 -
trunk/src/VBox/Main/src-server/os2/PerformanceOs2.cpp
r28800 r43629 63 63 } 64 64 65 int getDiskListByFs(const char *name, DiskList& list) 66 { 67 return VERR_NOT_IMPLEMENTED; 65 68 } 69 70 } -
trunk/src/VBox/Main/src-server/solaris/PerformanceSolaris.cpp
r43618 r43629 329 329 } 330 330 331 } 331 int getDiskListByFs(const char *name, DiskList& list) 332 { 333 return VERR_NOT_IMPLEMENTED; 334 } 335 336 } -
trunk/src/VBox/Main/src-server/win/PerformanceWin.cpp
r43550 r43629 350 350 } 351 351 352 } 352 int getDiskListByFs(const char *name, DiskList& list) 353 { 354 return VERR_NOT_IMPLEMENTED; 355 } 356 357 }
Note:
See TracChangeset
for help on using the changeset viewer.