summaryrefslogtreecommitdiff
path: root/src/VBox/Main/src-server/Performance.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/VBox/Main/src-server/Performance.cpp')
-rw-r--r--src/VBox/Main/src-server/Performance.cpp257
1 files changed, 203 insertions, 54 deletions
diff --git a/src/VBox/Main/src-server/Performance.cpp b/src/VBox/Main/src-server/Performance.cpp
index 465bfa1c..41ace847 100644
--- a/src/VBox/Main/src-server/Performance.cpp
+++ b/src/VBox/Main/src-server/Performance.cpp
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2008 Oracle Corporation
+ * Copyright (C) 2008-2013 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -24,8 +24,12 @@
#ifndef VBOX_COLLECTOR_TEST_CASE
#include "VirtualBoxImpl.h"
#include "MachineImpl.h"
+#include "MediumImpl.h"
+#include "AutoCaller.h"
#endif
#include "Performance.h"
+#include "HostNetworkInterfaceImpl.h"
+#include "netif.h"
#include <VBox/com/array.h>
#include <VBox/com/ptr.h>
@@ -45,47 +49,57 @@ using namespace pm;
int CollectorHAL::getHostCpuLoad(ULONG * /* user */, ULONG * /* kernel */, ULONG * /* idle */)
{
- return E_NOTIMPL;
+ return VERR_NOT_IMPLEMENTED;
}
int CollectorHAL::getProcessCpuLoad(RTPROCESS /* process */, ULONG * /* user */, ULONG * /* kernel */)
{
- return E_NOTIMPL;
+ return VERR_NOT_IMPLEMENTED;
}
int CollectorHAL::getRawHostCpuLoad(uint64_t * /* user */, uint64_t * /* kernel */, uint64_t * /* idle */)
{
- return E_NOTIMPL;
+ return VERR_NOT_IMPLEMENTED;
}
int CollectorHAL::getRawHostNetworkLoad(const char * /* name */, uint64_t * /* rx */, uint64_t * /* tx */)
{
- return E_NOTIMPL;
+ return VERR_NOT_IMPLEMENTED;
}
int CollectorHAL::getRawHostDiskLoad(const char * /* name */, uint64_t * /* disk_ms */, uint64_t * /* total_ms */)
{
- return E_NOTIMPL;
+ return VERR_NOT_IMPLEMENTED;
}
int CollectorHAL::getRawProcessCpuLoad(RTPROCESS /* process */, uint64_t * /* user */, uint64_t * /* kernel */, uint64_t * /* total */)
{
- return E_NOTIMPL;
+ return VERR_NOT_IMPLEMENTED;
}
int CollectorHAL::getHostMemoryUsage(ULONG * /* total */, ULONG * /* used */, ULONG * /* available */)
{
- return E_NOTIMPL;
+ return VERR_NOT_IMPLEMENTED;
}
int CollectorHAL::getHostFilesystemUsage(const char * /* name */, ULONG * /* total */, ULONG * /* used */, ULONG * /* available */)
{
- return E_NOTIMPL;
+ return VERR_NOT_IMPLEMENTED;
+}
+
+int CollectorHAL::getHostDiskSize(const char * /* name */, uint64_t * /* size */)
+{
+ return VERR_NOT_IMPLEMENTED;
}
int CollectorHAL::getProcessMemoryUsage(RTPROCESS /* process */, ULONG * /* used */)
{
- return E_NOTIMPL;
+ return VERR_NOT_IMPLEMENTED;
+}
+
+int CollectorHAL::getDiskListByFs(const char * /* name */, DiskList& /* listUsage */, DiskList& /* listLoad */)
+{
+ return VERR_NOT_IMPLEMENTED;
}
/* Generic implementations */
@@ -169,7 +183,7 @@ CollectorGuestRequest* CollectorGuestQueue::pop()
return NULL;
}
-int CGRQEnable::execute()
+HRESULT CGRQEnable::execute()
{
Assert(mCGuest);
return mCGuest->enableInternal(mMask);
@@ -184,7 +198,7 @@ void CGRQEnable::debugPrint(void *aObject, const char *aFunction, const char *aT
aObject, aFunction, mMask, aText));
}
-int CGRQDisable::execute()
+HRESULT CGRQDisable::execute()
{
Assert(mCGuest);
return mCGuest->disableInternal(mMask);
@@ -199,7 +213,7 @@ void CGRQDisable::debugPrint(void *aObject, const char *aFunction, const char *a
aObject, aFunction, mMask, aText));
}
-int CGRQAbort::execute()
+HRESULT CGRQAbort::execute()
{
return E_ABORT;
}
@@ -217,7 +231,7 @@ CollectorGuest::CollectorGuest(Machine *machine, RTPROCESS process) :
mUnregistered(false), mEnabled(false), mValid(false), mMachine(machine), mProcess(process),
mCpuUser(0), mCpuKernel(0), mCpuIdle(0),
mMemTotal(0), mMemFree(0), mMemBalloon(0), mMemShared(0), mMemCache(0), mPageTotal(0),
- mAllocVMM(0), mFreeVMM(0), mBalloonedVMM(0), mSharedVMM(0)
+ mAllocVMM(0), mFreeVMM(0), mBalloonedVMM(0), mSharedVMM(0), mVmNetRx(0), mVmNetTx(0)
{
Assert(mMachine);
/* cannot use ComObjPtr<Machine> in Performance.h, do it manually */
@@ -267,7 +281,7 @@ int CollectorGuest::disable(ULONG mask)
return enqueueRequest(new CGRQDisable(mask));
}
-int CollectorGuest::enableInternal(ULONG mask)
+HRESULT CollectorGuest::enableInternal(ULONG mask)
{
HRESULT ret = S_OK;
@@ -306,7 +320,7 @@ int CollectorGuest::enableInternal(ULONG mask)
this, __PRETTY_FUNCTION__, SUCCEEDED(ret)?"success":"failed"));
}
}
- if ((mask & GUESTSTATS_VMMRAM) == GUESTSTATS_VMMRAM)
+ if ((mask & VMSTATS_VMM_RAM) == VMSTATS_VMM_RAM)
enableVMMStats(true);
mEnabled |= mask;
@@ -318,7 +332,7 @@ int CollectorGuest::disableInternal(ULONG mask)
if (!(mEnabled & mask))
return E_UNEXPECTED;
- if ((mask & GUESTSTATS_VMMRAM) == GUESTSTATS_VMMRAM)
+ if ((mask & VMSTATS_VMM_RAM) == VMSTATS_VMM_RAM)
enableVMMStats(false);
mEnabled &= ~mask;
if (!mEnabled)
@@ -328,7 +342,7 @@ int CollectorGuest::disableInternal(ULONG mask)
NOREF(ret);
LogAleksey(("{%p} " LOG_FN_FMT ": Set guest statistics update interval to 0 sec (%s)\n",
this, __PRETTY_FUNCTION__, SUCCEEDED(ret)?"success":"failed"));
- invalidate(GUESTSTATS_ALL);
+ invalidate(VMSTATS_ALL);
}
return S_OK;
@@ -353,15 +367,16 @@ void CollectorGuest::updateStats(ULONG aValidStats, ULONG aCpuUser,
ULONG aMemBalloon, ULONG aMemShared,
ULONG aMemCache, ULONG aPageTotal,
ULONG aAllocVMM, ULONG aFreeVMM,
- ULONG aBalloonedVMM, ULONG aSharedVMM)
+ ULONG aBalloonedVMM, ULONG aSharedVMM,
+ ULONG aVmNetRx, ULONG aVmNetTx)
{
- if ((aValidStats & GUESTSTATS_CPULOAD) == GUESTSTATS_CPULOAD)
+ if ((aValidStats & VMSTATS_GUEST_CPULOAD) == VMSTATS_GUEST_CPULOAD)
{
mCpuUser = aCpuUser;
mCpuKernel = aCpuKernel,
mCpuIdle = aCpuIdle;
}
- if ((aValidStats & GUESTSTATS_RAMUSAGE) == GUESTSTATS_RAMUSAGE)
+ if ((aValidStats & VMSTATS_GUEST_RAMUSAGE) == VMSTATS_GUEST_RAMUSAGE)
{
mMemTotal = aMemTotal;
mMemFree = aMemFree;
@@ -370,13 +385,18 @@ void CollectorGuest::updateStats(ULONG aValidStats, ULONG aCpuUser,
mMemCache = aMemCache;
mPageTotal = aPageTotal;
}
- if ((aValidStats & GUESTSTATS_VMMRAM) == GUESTSTATS_VMMRAM)
+ if ((aValidStats & VMSTATS_VMM_RAM) == VMSTATS_VMM_RAM)
{
mAllocVMM = aAllocVMM;
mFreeVMM = aFreeVMM;
mBalloonedVMM = aBalloonedVMM;
mSharedVMM = aSharedVMM;
}
+ if ((aValidStats & VMSTATS_NET_RATE) == VMSTATS_NET_RATE)
+ {
+ mVmNetRx = aVmNetRx;
+ mVmNetTx = aVmNetTx;
+ }
mValid = aValidStats;
}
@@ -446,7 +466,7 @@ void CollectorGuestManager::unregisterGuest(CollectorGuest* pGuest)
{
/* Found the guest already collecting stats, elect it */
mVMMStatsProvider = *it;
- rc = mVMMStatsProvider->enqueueRequest(new CGRQEnable(GUESTSTATS_VMMRAM));
+ rc = mVMMStatsProvider->enqueueRequest(new CGRQEnable(VMSTATS_VMM_RAM));
if (FAILED(rc))
{
/* This is not a good candidate -- try to find another */
@@ -466,8 +486,8 @@ void CollectorGuestManager::unregisterGuest(CollectorGuest* pGuest)
continue;
mVMMStatsProvider = *it;
- //mVMMStatsProvider->enable(GUESTSTATS_VMMRAM);
- rc = mVMMStatsProvider->enqueueRequest(new CGRQEnable(GUESTSTATS_VMMRAM));
+ //mVMMStatsProvider->enable(VMSTATS_VMM_RAM);
+ rc = mVMMStatsProvider->enqueueRequest(new CGRQEnable(VMSTATS_VMM_RAM));
if (SUCCEEDED(rc))
break;
/* This was not a good candidate -- try to find another */
@@ -508,7 +528,7 @@ int CollectorGuestManager::enqueueRequest(CollectorGuestRequest *aRequest)
*/
if (aRequest->getGuest() && aRequest->getGuest() == mGuestBeingCalled)
{
- /*
+ /*
* Before we can declare a guest blocked we need to wait for a while
* and then check again as it may never had a chance to process
* the previous request. Half a second is an eternity for processes
@@ -619,6 +639,12 @@ void HostCpuLoad::collect()
}
}
+void HostCpuLoadRaw::init(ULONG period, ULONG length)
+{
+ HostCpuLoad::init(period, length);
+ mHAL->getRawHostCpuLoad(&mUserPrev, &mKernelPrev, &mIdlePrev);
+}
+
void HostCpuLoadRaw::preCollect(CollectorHints& hints, uint64_t /* iTick */)
{
hints.collectHostCpuLoad();
@@ -659,13 +685,50 @@ void HostCpuLoadRaw::collect()
}
}
+#ifndef VBOX_COLLECTOR_TEST_CASE
+static bool getLinkSpeed(const char *szShortName, uint32_t *pSpeed)
+{
+ NETIFSTATUS enmState = NETIF_S_UNKNOWN;
+ int rc = NetIfGetState(szShortName, &enmState);
+ if (RT_FAILURE(rc))
+ return false;
+ if (enmState != NETIF_S_UP)
+ *pSpeed = 0;
+ else
+ {
+ rc = NetIfGetLinkSpeed(szShortName, pSpeed);
+ if (RT_FAILURE(rc))
+ return false;
+ }
+ return true;
+}
+
+void HostNetworkSpeed::init(ULONG period, ULONG length)
+{
+ mPeriod = period;
+ mLength = length;
+ mLinkSpeed->init(length);
+ /*
+ * Retrieve the link speed now as it may be wrong if the metric was
+ * registered at boot (see @bugref{6613}).
+ */
+ getLinkSpeed(mShortName.c_str(), &mSpeed);
+}
+
void HostNetworkLoadRaw::init(ULONG period, ULONG length)
{
mPeriod = period;
mLength = length;
mRx->init(mLength);
mTx->init(mLength);
- int rc = mHAL->getRawHostNetworkLoad(mShortName.c_str(), &mRxPrev, &mTxPrev);
+ /*
+ * Retrieve the link speed now as it may be wrong if the metric was
+ * registered at boot (see @bugref{6613}).
+ */
+ uint32_t uSpeedMbit = 65535;
+ if (getLinkSpeed(mShortName.c_str(), &uSpeedMbit))
+ mSpeed = (uint64_t)uSpeedMbit * (1000000/8); /* Convert to bytes/sec */
+ /*int rc =*/ mHAL->getRawHostNetworkLoad(mShortName.c_str(), &mRxPrev, &mTxPrev);
//AssertRC(rc);
}
@@ -686,25 +749,23 @@ void HostNetworkLoadRaw::preCollect(CollectorHints& /* hints */, uint64_t /* iTi
void HostNetworkLoadRaw::collect()
{
- uint64_t rx, tx;
+ uint64_t rx = mRxPrev;
+ uint64_t tx = mTxPrev;
+ if (RT_UNLIKELY(mSpeed * getPeriod() == 0))
+ {
+ LogFlowThisFunc(("Check cable for %s! speed=%llu period=%d.\n", mShortName.c_str(), mSpeed, getPeriod()));
+ /* We do not collect host network metrics for unplugged interfaces! */
+ return;
+ }
mRc = mHAL->getRawHostNetworkLoad(mShortName.c_str(), &rx, &tx);
if (RT_SUCCESS(mRc))
{
uint64_t rxDiff = rx - mRxPrev;
uint64_t txDiff = tx - mTxPrev;
- if (RT_UNLIKELY(mSpeed * getPeriod() == 0))
- {
- LogFlowThisFunc(("Check cable for %s! speed=%llu period=%d.\n", mShortName.c_str(), mSpeed, getPeriod()));
- mRx->put(0);
- mTx->put(0);
- }
- else
- {
- mRx->put((ULONG)(PM_NETWORK_LOAD_MULTIPLIER * rxDiff / (mSpeed * getPeriod())));
- mTx->put((ULONG)(PM_NETWORK_LOAD_MULTIPLIER * txDiff / (mSpeed * getPeriod())));
- }
+ mRx->put((ULONG)(PM_NETWORK_LOAD_MULTIPLIER * rxDiff / (mSpeed * getPeriod())));
+ mTx->put((ULONG)(PM_NETWORK_LOAD_MULTIPLIER * txDiff / (mSpeed * getPeriod())));
mRxPrev = rx;
mTxPrev = tx;
@@ -713,6 +774,7 @@ void HostNetworkLoadRaw::collect()
LogFlowThisFunc(("Failed to collect data: %Rrc (%d)."
" Will update the list of interfaces...\n", mRc,mRc));
}
+#endif /* !VBOX_COLLECTOR_TEST_CASE */
void HostDiskLoadRaw::init(ULONG period, ULONG length)
{
@@ -815,7 +877,6 @@ void HostRamUsage::collect()
mTotal->put(total);
mUsed->put(used);
mAvailable->put(available);
-
}
}
@@ -841,10 +902,28 @@ void HostFilesystemUsage::collect()
mTotal->put(total);
mUsed->put(used);
mAvailable->put(available);
-
}
}
+void HostDiskUsage::init(ULONG period, ULONG length)
+{
+ mPeriod = period;
+ mLength = length;
+ mTotal->init(mLength);
+}
+
+void HostDiskUsage::preCollect(CollectorHints& /* hints */, uint64_t /* iTick */)
+{
+}
+
+void HostDiskUsage::collect()
+{
+ uint64_t total;
+ int rc = mHAL->getHostDiskSize(mDiskName.c_str(), &total);
+ if (RT_SUCCESS(rc))
+ mTotal->put((ULONG)(total / _1M));
+}
+
#ifndef VBOX_COLLECTOR_TEST_CASE
void HostRamVmm::init(ULONG period, ULONG length)
{
@@ -861,7 +940,7 @@ int HostRamVmm::enable()
int rc = S_OK;
CollectorGuest *provider = mCollectorGuestManager->getVMMStatsProvider();
if (provider)
- rc = provider->enable(GUESTSTATS_VMMRAM);
+ rc = provider->enable(VMSTATS_VMM_RAM);
BaseMetric::enable();
return rc;
}
@@ -872,7 +951,7 @@ int HostRamVmm::disable()
BaseMetric::disable();
CollectorGuest *provider = mCollectorGuestManager->getVMMStatsProvider();
if (provider)
- rc = provider->disable(GUESTSTATS_VMMRAM);
+ rc = provider->disable(VMSTATS_VMM_RAM);
return rc;
}
@@ -888,15 +967,15 @@ void HostRamVmm::collect()
{
LogAleksey(("{%p} " LOG_FN_FMT ": provider=%p enabled=%s valid=%s...\n",
this, __PRETTY_FUNCTION__, provider, provider->isEnabled()?"y":"n",
- provider->isValid(GUESTSTATS_VMMRAM)?"y":"n"));
- if (provider->isValid(GUESTSTATS_VMMRAM))
+ provider->isValid(VMSTATS_VMM_RAM)?"y":"n"));
+ if (provider->isValid(VMSTATS_VMM_RAM))
{
/* Provider is ready, get updated stats */
mAllocCurrent = provider->getAllocVMM();
mFreeCurrent = provider->getFreeVMM();
mBalloonedCurrent = provider->getBalloonedVMM();
mSharedCurrent = provider->getSharedVMM();
- provider->invalidate(GUESTSTATS_VMMRAM);
+ provider->invalidate(VMSTATS_VMM_RAM);
}
/*
* Note that if there are no new values from the provider we will use
@@ -994,6 +1073,76 @@ void MachineRamUsage::collect()
#ifndef VBOX_COLLECTOR_TEST_CASE
+void MachineDiskUsage::init(ULONG period, ULONG length)
+{
+ mPeriod = period;
+ mLength = length;
+ mUsed->init(mLength);
+}
+
+void MachineDiskUsage::preCollect(CollectorHints& /* hints */, uint64_t /* iTick */)
+{
+}
+
+void MachineDiskUsage::collect()
+{
+ ULONG used = 0;
+
+ for (MediaList::iterator it = mDisks.begin(); it != mDisks.end(); ++it)
+ {
+ ComObjPtr<Medium> pMedium = *it;
+
+ /* just in case */
+ AssertStmt(!pMedium.isNull(), continue);
+
+ AutoCaller localAutoCaller(pMedium);
+ if (FAILED(localAutoCaller.rc())) continue;
+
+ AutoReadLock local_alock(pMedium COMMA_LOCKVAL_SRC_POS);
+
+ used += (ULONG)(pMedium->getSize() / _1M);
+ }
+
+ mUsed->put(used);
+}
+
+void MachineNetRate::init(ULONG period, ULONG length)
+{
+ mPeriod = period;
+ mLength = length;
+
+ mRx->init(mLength);
+ mTx->init(mLength);
+}
+
+void MachineNetRate::collect()
+{
+ if (mCGuest->isValid(VMSTATS_NET_RATE))
+ {
+ mRx->put(mCGuest->getVmNetRx());
+ mTx->put(mCGuest->getVmNetTx());
+ mCGuest->invalidate(VMSTATS_NET_RATE);
+ }
+}
+
+int MachineNetRate::enable()
+{
+ int rc = mCGuest->enable(VMSTATS_NET_RATE);
+ BaseMetric::enable();
+ return rc;
+}
+
+int MachineNetRate::disable()
+{
+ BaseMetric::disable();
+ return mCGuest->disable(VMSTATS_NET_RATE);
+}
+
+void MachineNetRate::preCollect(CollectorHints& hints, uint64_t /* iTick */)
+{
+ hints.collectGuestStats(mCGuest->getProcess());
+}
+
void GuestCpuLoad::init(ULONG period, ULONG length)
{
mPeriod = period;
@@ -1011,18 +1160,18 @@ void GuestCpuLoad::preCollect(CollectorHints& hints, uint64_t /* iTick */)
void GuestCpuLoad::collect()
{
- if (mCGuest->isValid(GUESTSTATS_CPULOAD))
+ if (mCGuest->isValid(VMSTATS_GUEST_CPULOAD))
{
mUser->put((ULONG)(PM_CPU_LOAD_MULTIPLIER * mCGuest->getCpuUser()) / 100);
mKernel->put((ULONG)(PM_CPU_LOAD_MULTIPLIER * mCGuest->getCpuKernel()) / 100);
mIdle->put((ULONG)(PM_CPU_LOAD_MULTIPLIER * mCGuest->getCpuIdle()) / 100);
- mCGuest->invalidate(GUESTSTATS_CPULOAD);
+ mCGuest->invalidate(VMSTATS_GUEST_CPULOAD);
}
}
int GuestCpuLoad::enable()
{
- int rc = mCGuest->enable(GUESTSTATS_CPULOAD);
+ int rc = mCGuest->enable(VMSTATS_GUEST_CPULOAD);
BaseMetric::enable();
return rc;
}
@@ -1030,7 +1179,7 @@ int GuestCpuLoad::enable()
int GuestCpuLoad::disable()
{
BaseMetric::disable();
- return mCGuest->disable(GUESTSTATS_CPULOAD);
+ return mCGuest->disable(VMSTATS_GUEST_CPULOAD);
}
void GuestRamUsage::init(ULONG period, ULONG length)
@@ -1048,7 +1197,7 @@ void GuestRamUsage::init(ULONG period, ULONG length)
void GuestRamUsage::collect()
{
- if (mCGuest->isValid(GUESTSTATS_RAMUSAGE))
+ if (mCGuest->isValid(VMSTATS_GUEST_RAMUSAGE))
{
mTotal->put(mCGuest->getMemTotal());
mFree->put(mCGuest->getMemFree());
@@ -1056,13 +1205,13 @@ void GuestRamUsage::collect()
mShared->put(mCGuest->getMemShared());
mCache->put(mCGuest->getMemCache());
mPagedTotal->put(mCGuest->getPageTotal());
- mCGuest->invalidate(GUESTSTATS_RAMUSAGE);
+ mCGuest->invalidate(VMSTATS_GUEST_RAMUSAGE);
}
}
int GuestRamUsage::enable()
{
- int rc = mCGuest->enable(GUESTSTATS_RAMUSAGE);
+ int rc = mCGuest->enable(VMSTATS_GUEST_RAMUSAGE);
BaseMetric::enable();
return rc;
}
@@ -1070,7 +1219,7 @@ int GuestRamUsage::enable()
int GuestRamUsage::disable()
{
BaseMetric::disable();
- return mCGuest->disable(GUESTSTATS_RAMUSAGE);
+ return mCGuest->disable(VMSTATS_GUEST_RAMUSAGE);
}
void GuestRamUsage::preCollect(CollectorHints& hints, uint64_t /* iTick */)