VirtualBox

Changeset 43445 in vbox for trunk/src/VBox/Main/src-server


Ignore:
Timestamp:
Sep 27, 2012 8:28:59 AM (12 years ago)
Author:
vboxsync
Message:

Main/Metrics: Host network metrics, linux only (#6345)

Location:
trunk/src/VBox/Main/src-server
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Main/src-server/HostImpl.cpp

    r43387 r43445  
    179179    VirtualBox              *pParent;
    180180
     181    HostNetworkInterfaceList llNetIfs;                  // list of network interfaces
     182
    181183#ifdef VBOX_WITH_USB
    182184    USBDeviceFilterList     llChildren;                 // all USB device filters
     
    272274    registerMetrics(aParent->performanceCollector());
    273275#endif /* VBOX_WITH_RESOURCE_USAGE_API */
     276    /* Create the list of network interfaces so their metrics get registered. */
     277    updateNetIfList();
    274278
    275279#if defined (RT_OS_WINDOWS)
     
    437441
    438442#ifdef VBOX_WITH_RESOURCE_USAGE_API
    439     unregisterMetrics (m->pParent->performanceCollector());
     443    PerformanceCollector *aCollector = m->pParent->performanceCollector();
     444    unregisterMetrics (aCollector);
     445    HostNetworkInterfaceList::iterator it;
     446    for (it = m->llNetIfs.begin(); it != m->llNetIfs.end(); ++it)
     447        (*it)->unregisterMetrics(aCollector, this);
    440448#endif /* VBOX_WITH_RESOURCE_USAGE_API */
     449    m->llNetIfs.clear();
    441450
    442451#ifdef VBOX_WITH_USB
     
    584593    if (FAILED(autoCaller.rc())) return autoCaller.rc();
    585594
     595    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
     596# ifdef VBOX_WITH_HOSTNETIF_API
     597    int rc = updateNetIfList();
     598    if (rc)
     599    {
     600        Log(("Failed to get host network interface list with rc=%Rrc\n", rc));
     601    }
     602
     603    SafeIfaceArray<IHostNetworkInterface> networkInterfaces (m->llNetIfs);
     604    networkInterfaces.detachTo(ComSafeArrayOutArg(aNetworkInterfaces));
     605
     606    return S_OK;
     607
     608# else
    586609    std::list<ComObjPtr<HostNetworkInterface> > list;
    587 
    588 # ifdef VBOX_WITH_HOSTNETIF_API
    589     int rc = NetIfList(list);
    590     if (rc)
    591     {
    592         Log(("Failed to get host network interface list with rc=%Rrc\n", rc));
    593     }
    594 # else
    595610
    596611#  if defined(RT_OS_DARWIN)
     
    739754    }
    740755#  endif /* RT_OS_LINUX */
    741 # endif
    742 
    743     std::list <ComObjPtr<HostNetworkInterface> >::iterator it;
    744     for (it = list.begin(); it != list.end(); ++it)
    745     {
    746         (*it)->setVirtualBox(m->pParent);
    747     }
    748756
    749757    SafeIfaceArray<IHostNetworkInterface> networkInterfaces (list);
     
    752760    return S_OK;
    753761
     762# endif
    754763#else
    755764    /* Not implemented / supported on this platform. */
     
    13911400        return E_POINTER;
    13921401
     1402    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
     1403
    13931404    *networkInterface = NULL;
    13941405    ComObjPtr<HostNetworkInterface> found;
    1395     std::list <ComObjPtr<HostNetworkInterface> > list;
    1396     int rc = NetIfList(list);
     1406    int rc = updateNetIfList();
    13971407    if (RT_FAILURE(rc))
    13981408    {
     
    14001410        return E_FAIL;
    14011411    }
    1402     std::list <ComObjPtr<HostNetworkInterface> >::iterator it;
    1403     for (it = list.begin(); it != list.end(); ++it)
     1412    HostNetworkInterfaceList::iterator it;
     1413    for (it = m->llNetIfs.begin(); it != m->llNetIfs.end(); ++it)
    14041414    {
    14051415        Bstr n;
     
    14121422        return setError(E_INVALIDARG,
    14131423                        HostNetworkInterface::tr("The host network interface with the given name could not be found"));
    1414 
    1415     found->setVirtualBox(m->pParent);
    14161424
    14171425    return found.queryInterfaceTo(networkInterface);
     
    14291437        return E_POINTER;
    14301438
     1439    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
     1440
    14311441    *networkInterface = NULL;
    14321442    ComObjPtr<HostNetworkInterface> found;
    1433     std::list <ComObjPtr<HostNetworkInterface> > list;
    1434     int rc = NetIfList(list);
     1443    int rc = updateNetIfList();
    14351444    if (RT_FAILURE(rc))
    14361445    {
     
    14381447        return E_FAIL;
    14391448    }
    1440     std::list <ComObjPtr<HostNetworkInterface> >::iterator it;
    1441     for (it = list.begin(); it != list.end(); ++it)
     1449    HostNetworkInterfaceList::iterator it;
     1450    for (it = m->llNetIfs.begin(); it != m->llNetIfs.end(); ++it)
    14421451    {
    14431452        Bstr g;
     
    14511460                        HostNetworkInterface::tr("The host network interface with the given GUID could not be found"));
    14521461
    1453     found->setVirtualBox(m->pParent);
    1454 
    14551462    return found.queryInterfaceTo(networkInterface);
    14561463#endif
     
    14611468{
    14621469#ifdef VBOX_WITH_HOSTNETIF_API
    1463     std::list <ComObjPtr<HostNetworkInterface> > allList;
    1464     int rc = NetIfList(allList);
     1470    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
     1471
     1472    int rc = updateNetIfList();
    14651473    if (RT_FAILURE(rc))
    14661474        return E_FAIL;
    14671475
    1468     std::list <ComObjPtr<HostNetworkInterface> > resultList;
    1469 
    1470     std::list <ComObjPtr<HostNetworkInterface> >::iterator it;
    1471     for (it = allList.begin(); it != allList.end(); ++it)
     1476    HostNetworkInterfaceList resultList;
     1477
     1478    HostNetworkInterfaceList::iterator it;
     1479    for (it = m->llNetIfs.begin(); it != m->llNetIfs.end(); ++it)
    14721480    {
    14731481        HostNetworkInterfaceType_T t;
     
    14771485
    14781486        if (t == type)
    1479         {
    1480             (*it)->setVirtualBox(m->pParent);
    14811487            resultList.push_back (*it);
    1482         }
    14831488    }
    14841489
     
    28112816#endif /* VBOX_WITH_USB */
    28122817
     2818HRESULT Host::updateNetIfList()
     2819{
     2820#ifdef VBOX_WITH_HOSTNETIF_API
     2821    AssertReturn(AutoCaller(this).state() == InInit ||
     2822                 isWriteLockOnCurrentThread(), E_FAIL);
     2823
     2824    HostNetworkInterfaceList list, listCopy;
     2825    int rc = NetIfList(list);
     2826    if (rc)
     2827    {
     2828        Log(("Failed to get host network interface list with rc=%Rrc\n", rc));
     2829        return E_FAIL;
     2830    }
     2831    AssertReturn(m->pParent, E_FAIL);
     2832    /* Make a copy as the original may be partially destroyed later. */
     2833    listCopy = list;
     2834    HostNetworkInterfaceList::iterator itOld, itNew;
     2835    PerformanceCollector *aCollector = m->pParent->performanceCollector();
     2836    for (itOld = m->llNetIfs.begin(); itOld != m->llNetIfs.end(); ++itOld)
     2837    {
     2838        bool fGone = true;
     2839        Bstr nameOld;
     2840        (*itOld)->COMGETTER(Name) (nameOld.asOutParam());
     2841        for (itNew = listCopy.begin(); itNew != listCopy.end(); ++itNew)
     2842        {
     2843            Bstr nameNew;
     2844            (*itNew)->COMGETTER(Name) (nameNew.asOutParam());
     2845            if (nameNew == nameOld)
     2846            {
     2847                fGone = false;
     2848                listCopy.erase(itNew);
     2849                break;
     2850            }
     2851        }
     2852        if (fGone)
     2853            (*itOld)->unregisterMetrics(aCollector, this);
     2854    }
     2855    /* At this point listCopy will contain newly discovered interfaces only. */
     2856    for (itNew = listCopy.begin(); itNew != listCopy.end(); ++itNew)
     2857    {
     2858        (*itNew)->setVirtualBox(m->pParent);
     2859        (*itNew)->registerMetrics(aCollector, this);
     2860    }
     2861    m->llNetIfs = list;
     2862    return S_OK;
     2863#else
     2864    return E_NOTIMPL;
     2865#endif
     2866}
     2867
    28132868#ifdef VBOX_WITH_RESOURCE_USAGE_API
    28142869
     
    28422897
    28432898    /* Create and register base metrics */
    2844     IUnknown *objptr;
    2845     ComObjPtr<Host> tmp = this;
    2846     tmp.queryInterfaceTo(&objptr);
    2847     pm::BaseMetric *cpuLoad = new pm::HostCpuLoadRaw(hal, objptr, cpuLoadUser, cpuLoadKernel,
     2899    pm::BaseMetric *cpuLoad = new pm::HostCpuLoadRaw(hal, this, cpuLoadUser, cpuLoadKernel,
    28482900                                          cpuLoadIdle);
    28492901    aCollector->registerBaseMetric (cpuLoad);
    2850     pm::BaseMetric *cpuMhz = new pm::HostCpuMhz(hal, objptr, cpuMhzSM);
     2902    pm::BaseMetric *cpuMhz = new pm::HostCpuMhz(hal, this, cpuMhzSM);
    28512903    aCollector->registerBaseMetric (cpuMhz);
    2852     pm::BaseMetric *ramUsage = new pm::HostRamUsage(hal, objptr,
     2904    pm::BaseMetric *ramUsage = new pm::HostRamUsage(hal, this,
    28532905                                                    ramUsageTotal,
    28542906                                                    ramUsageUsed,
    28552907                                                    ramUsageFree);
    28562908    aCollector->registerBaseMetric (ramUsage);
    2857     pm::BaseMetric *ramVmm = new pm::HostRamVmm(aCollector->getGuestManager(), objptr,
     2909    pm::BaseMetric *ramVmm = new pm::HostRamVmm(aCollector->getGuestManager(), this,
    28582910                                                ramVMMUsed,
    28592911                                                ramVMMFree,
  • trunk/src/VBox/Main/src-server/HostNetworkInterfaceImpl.cpp

    r42551 r43445  
    2222#include "Logging.h"
    2323#include "netif.h"
     24#include "Performance.h"
     25#include "PerformanceImpl.h"
    2426
    2527#include <iprt/cpp/utils.h>
     
    8385
    8486    return S_OK;
     87}
     88
     89void HostNetworkInterface::registerMetrics(PerformanceCollector *aCollector, ComPtr<IUnknown> objptr)
     90{
     91    LogFlowThisFunc(("mInterfaceName={%ls}, mGuid={%s}\n",
     92                      mInterfaceName.raw(), mGuid.toString().c_str()));
     93    pm::CollectorHAL *hal = aCollector->getHAL();
     94    /* Create sub metrics */
     95    Utf8StrFmt strName("Net/%ls/Load", mInterfaceName.raw());
     96    pm::SubMetric *networkLoadRx   = new pm::SubMetric(strName + "/Rx",
     97        "Percentage of network interface bandwidth used.");
     98    pm::SubMetric *networkLoadTx   = new pm::SubMetric(strName + "/Tx",
     99        "Percentage of network interface bandwidth used.");
     100
     101    /* Create and register base metrics */
     102    pm::BaseMetric *networkLoad = new pm::HostNetworkLoadRaw(hal, objptr, strName, Utf8Str(mInterfaceName), networkLoadRx, networkLoadTx);
     103    aCollector->registerBaseMetric(networkLoad);
     104
     105    aCollector->registerMetric(new pm::Metric(networkLoad, networkLoadRx, 0));
     106    aCollector->registerMetric(new pm::Metric(networkLoad, networkLoadRx,
     107                                              new pm::AggregateAvg()));
     108    aCollector->registerMetric(new pm::Metric(networkLoad, networkLoadRx,
     109                                              new pm::AggregateMin()));
     110    aCollector->registerMetric(new pm::Metric(networkLoad, networkLoadRx,
     111                                              new pm::AggregateMax()));
     112
     113    aCollector->registerMetric(new pm::Metric(networkLoad, networkLoadTx, 0));
     114    aCollector->registerMetric(new pm::Metric(networkLoad, networkLoadTx,
     115                                              new pm::AggregateAvg()));
     116    aCollector->registerMetric(new pm::Metric(networkLoad, networkLoadTx,
     117                                              new pm::AggregateMin()));
     118    aCollector->registerMetric(new pm::Metric(networkLoad, networkLoadTx,
     119                                              new pm::AggregateMax()));
     120}
     121
     122void HostNetworkInterface::unregisterMetrics(PerformanceCollector *aCollector, ComPtr<IUnknown> objptr)
     123{
     124    LogFlowThisFunc(("mInterfaceName={%ls}, mGuid={%s}\n",
     125                      mInterfaceName.raw(), mGuid.toString().c_str()));
     126    aCollector->unregisterMetricsFor(objptr);
     127    aCollector->unregisterBaseMetricsFor(objptr);
    85128}
    86129
     
    553596    AutoCaller autoCaller(this);
    554597    if (FAILED(autoCaller.rc())) return autoCaller.rc();
     598    AssertReturn(mVBox != pVBox, S_OK);
     599
    555600    unconst(mVBox) = pVBox;
    556601
  • trunk/src/VBox/Main/src-server/Performance.cpp

    r40568 r43445  
    5555
    5656int CollectorHAL::getRawHostCpuLoad(uint64_t * /* user */, uint64_t * /* kernel */, uint64_t * /* idle */)
     57{
     58    return E_NOTIMPL;
     59}
     60
     61int CollectorHAL::getRawHostNetworkLoad(const char * /* name */, uint64_t * /* rx */, uint64_t * /* tx */, uint64_t */* speed */)
    5762{
    5863    return E_NOTIMPL;
     
    554559    if (isEnabled())
    555560    {
    556         if (nowAt - mLastSampleTaken >= mPeriod * 1000)
     561        if (mLastSampleTaken == 0)
    557562        {
    558563            mLastSampleTaken = nowAt;
     
    561566            return true;
    562567        }
     568        /*
     569         * We use low resolution timers which may fire just a little bit early.
     570         * We compensate for that by jumping into the future by several
     571         * milliseconds (see @bugref{6345}).
     572         */
     573        if (nowAt - mLastSampleTaken + PM_SAMPLER_PRECISION_MS >= mPeriod * 1000)
     574        {
     575            /*
     576             * We don't want the beat to drift. This is why the timestamp of
     577             * the last taken sample is not the actual time but the time we
     578             * should have taken the measurement at.
     579             */
     580            mLastSampleTaken += mPeriod * 1000;
     581            Log4(("{%p} " LOG_FN_FMT ": Collecting %s for obj(%p)...\n",
     582                        this, __PRETTY_FUNCTION__, getName(), (void *)mObject));
     583            return true;
     584        }
     585        Log4(("{%p} " LOG_FN_FMT ": Enabled but too early to collect %s for obj(%p)\n",
     586              this, __PRETTY_FUNCTION__, getName(), (void *)mObject));
    563587    }
    564588    return false;
     
    623647        mKernelPrev = kernel;
    624648        mIdlePrev   = idle;
     649    }
     650}
     651
     652void HostNetworkLoadRaw::init(ULONG period, ULONG length)
     653{
     654    mPeriod = period;
     655    mLength = length;
     656    mRx->init(mLength);
     657    mTx->init(mLength);
     658    uint64_t speed;
     659    int rc = mHAL->getRawHostNetworkLoad(mInterfaceName.c_str(), &mRxPrev, &mTxPrev, &speed);
     660    AssertRC(rc);
     661}
     662
     663void HostNetworkLoadRaw::preCollect(CollectorHints& /* hints */, uint64_t /* iTick */)
     664{
     665}
     666
     667void HostNetworkLoadRaw::collect()
     668{
     669    uint64_t rx, tx, speed;
     670
     671    int rc = mHAL->getRawHostNetworkLoad(mInterfaceName.c_str(), &rx, &tx, &speed);
     672    if (RT_SUCCESS(rc))
     673    {
     674        uint64_t rxDiff = rx - mRxPrev;
     675        uint64_t txDiff = tx - mTxPrev;
     676
     677        if (RT_UNLIKELY(speed * getPeriod() == 0))
     678        {
     679            Assert(speed * getPeriod());
     680            LogFlowThisFunc(("Impossible! speed=%llu period=%d.\n", speed, getPeriod()));
     681            mRx->put(0);
     682            mTx->put(0);
     683        }
     684        else
     685        {
     686            mRx->put((ULONG)(PM_NETWORK_LOAD_MULTIPLIER * rxDiff / (speed * getPeriod())));
     687            mTx->put((ULONG)(PM_NETWORK_LOAD_MULTIPLIER * txDiff / (speed * getPeriod())));
     688        }
     689
     690        mRxPrev = rx;
     691        mTxPrev = tx;
    625692    }
    626693}
  • trunk/src/VBox/Main/src-server/PerformanceImpl.cpp

    r40358 r43445  
    6666    "CPU/MHz:min",
    6767    "CPU/MHz:max",
     68    "Net/*/Load/Rx",
     69    "Net/*/Load/Rx:avg",
     70    "Net/*/Load/Rx:min",
     71    "Net/*/Load/Rx:max",
     72    "Net/*/Load/Tx",
     73    "Net/*/Load/Tx:avg",
     74    "Net/*/Load/Tx:min",
     75    "Net/*/Load/Tx:max",
    6876    "RAM/Usage/Total",
    6977    "RAM/Usage/Total:avg",
  • trunk/src/VBox/Main/src-server/linux/PerformanceLinux.cpp

    r37713 r43445  
    4040
    4141    virtual int getRawHostCpuLoad(uint64_t *user, uint64_t *kernel, uint64_t *idle);
     42    virtual int getRawHostNetworkLoad(const char *name, uint64_t *rx, uint64_t *tx, uint64_t *speed);
    4243    virtual int getRawProcessCpuLoad(RTPROCESS process, uint64_t *user, uint64_t *kernel, uint64_t *total);
    4344private:
     
    217218}
    218219
    219 }
    220 
     220int CollectorLinux::getRawHostNetworkLoad(const char *name, uint64_t *rx, uint64_t *tx, uint64_t *speed)
     221{
     222    int rc = VINF_SUCCESS;
     223    char szIfName[/*IFNAMSIZ*/ 16 + 36];
     224    long long unsigned int u64Rx, u64Tx, u64Speed;
     225
     226    RTStrPrintf(szIfName, sizeof(szIfName), "/sys/class/net/%s/statistics/rx_bytes", name);
     227    FILE *f = fopen(szIfName, "r");
     228    if (f)
     229    {
     230        if (fscanf(f, "%llu", &u64Rx) == 1)
     231            *rx = u64Rx;
     232        else
     233            rc = VERR_FILE_IO_ERROR;
     234        fclose(f);
     235        RTStrPrintf(szIfName, sizeof(szIfName), "/sys/class/net/%s/statistics/tx_bytes", name);
     236        f = fopen(szIfName, "r");
     237        if (f)
     238        {
     239            if (fscanf(f, "%llu", &u64Tx) == 1)
     240                *tx = u64Tx;
     241            else
     242                rc = VERR_FILE_IO_ERROR;
     243            fclose(f);
     244            RTStrPrintf(szIfName, sizeof(szIfName), "/sys/class/net/%s/speed", name);
     245            f = fopen(szIfName, "r");
     246            if (f)
     247            {
     248                if (fscanf(f, "%llu", &u64Speed) == 1)
     249                    *speed = u64Speed * (1000000/8); /* Convert to bytes/sec */
     250                else
     251                    rc = VERR_FILE_IO_ERROR;
     252                fclose(f);
     253            }
     254            else
     255                rc = VERR_ACCESS_DENIED;
     256        }
     257        else
     258            rc = VERR_ACCESS_DENIED;
     259    }
     260    else
     261        rc = VERR_ACCESS_DENIED;
     262
     263    return rc;
     264}
     265
     266}
     267
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