VirtualBox

Ignore:
Timestamp:
Oct 4, 2012 12:24:20 PM (13 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
81139
Message:

Main/Metrics: Host network interface metrics for Solaris (#6345)

Location:
trunk/src/VBox/Main/src-server/solaris
Files:
2 edited

Legend:

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

    r40078 r43538  
    2525#include <iprt/err.h>
    2626#include <iprt/ctype.h>
     27#include <iprt/path.h>
    2728#include <list>
    2829
     
    4950
    5051#include "DynLoadLibSolaris.h"
     52
     53static uint64 kstatGet(const char *pszMask)
     54{
     55    char szBuf[RTPATH_MAX];
     56    RTStrPrintf(szBuf, sizeof(szBuf),
     57                "/usr/bin/kstat -c net -p %s", pszMask);
     58    uint64_t uSpeed = 0;
     59    FILE *fp = popen(szBuf, "r");
     60    LogFlowFunc(("popen(%s) returned %p\n", szBuf, fp));
     61    if (fp)
     62    {
     63        if (fgets(szBuf, sizeof(szBuf), fp))
     64        {
     65            LogFlowFunc(("fgets returned %s\n", szBuf));
     66            char *pszDigit = szBuf;
     67            /* Skip the id string */
     68            int i = 0;
     69            while (i++ < sizeof(szBuf) && *pszDigit && !RT_C_IS_SPACE(*pszDigit))
     70                pszDigit++;
     71            while (i++ < sizeof(szBuf) && *pszDigit && !RT_C_IS_DIGIT(*pszDigit))
     72                pszDigit++;
     73            LogFlowFunc(("located number %s\n", pszDigit));
     74            uSpeed = RTStrToUInt64(pszDigit);
     75        }
     76        else
     77            LogFlowFunc(("fgets returned nothing\n"));
     78        fclose(fp);
     79    }
     80    return uSpeed;
     81}
     82
     83static uint32_t getInstance(const char *pszIfaceName, char *pszDevName)
     84{
     85    /*
     86     * Get the instance number from the interface name, then clip it off.
     87     */
     88    int cbInstance = 0;
     89    int cbIface = strlen(pszIfaceName);
     90    const char *pszEnd = pszIfaceName + cbIface - 1;
     91    for (int i = 0; i < cbIface - 1; i++)
     92    {
     93        if (!RT_C_IS_DIGIT(*pszEnd))
     94            break;
     95        cbInstance++;
     96        pszEnd--;
     97    }
     98
     99    uint32_t uInstance = RTStrToUInt32(pszEnd + 1);
     100    strncpy(pszDevName, pszIfaceName, cbIface - cbInstance);
     101    pszDevName[cbIface - cbInstance] = '\0';
     102    return uInstance;
     103}
     104
     105static void queryIfaceSpeed(PNETIFINFO pInfo)
     106{
     107    char szMask[RTPATH_MAX];
     108    RTStrPrintf(szMask, sizeof(szMask), "*:*:%s:ifspeed", pInfo->szShortName);
     109    pInfo->uSpeedMbits = kstatGet(szMask);
     110    if (pInfo->uSpeedMbits == 0)
     111    {
     112        Log(("queryIfaceSpeed: failed to get speed for %s via kstat(%s)\n", pInfo->szShortName, szMask));
     113        /* Lets try module:instance approach */
     114        char szDevName[sizeof(pInfo->szShortName)];
     115        uint32_t uInstance = getInstance(pInfo->szShortName, szDevName);
     116        RTStrPrintf(szMask, sizeof(szMask), "%s:%u:*:ifspeed",
     117                    szDevName, uInstance);
     118        pInfo->uSpeedMbits = kstatGet(szMask);
     119        if (pInfo->uSpeedMbits == 0)
     120            LogRel(("queryIfaceSpeed: failed to get speed for %s(instance=%u) via kstat\n", szDevName, uInstance));
     121    }
     122    pInfo->uSpeedMbits /= 1000000; /* bits -> Mbits */
     123}
    51124
    52125static void vboxSolarisAddHostIface(char *pszIface, int Instance, void *pvHostNetworkInterfaceList)
     
    209282    else
    210283        enmType = HostNetworkInterfaceType_HostOnly;
     284    queryIfaceSpeed(&Info);
    211285    ComObjPtr<HostNetworkInterface> IfObj;
    212286    IfObj.createObject();
  • trunk/src/VBox/Main/src-server/solaris/PerformanceSolaris.cpp

    r40504 r43538  
    2828#include <sys/time.h>
    2929
     30#include <iprt/ctype.h>
    3031#include <iprt/err.h>
    3132#include <iprt/string.h>
     
    4647
    4748    virtual int getRawHostCpuLoad(uint64_t *user, uint64_t *kernel, uint64_t *idle);
     49    virtual int getRawHostNetworkLoad(const char *name, uint64_t *rx, uint64_t *tx);
    4850    virtual int getRawProcessCpuLoad(RTPROCESS process, uint64_t *user, uint64_t *kernel, uint64_t *total);
    4951private:
     52    static uint32_t getInstance(const char *pszIfaceName, char *pszDevName);
    5053    kstat_ctl_t *mKC;
    5154    kstat_t     *mSysPages;
     
    261264}
    262265
    263 }
     266uint32_t CollectorSolaris::getInstance(const char *pszIfaceName, char *pszDevName)
     267{
     268    /*
     269     * Get the instance number from the interface name, then clip it off.
     270     */
     271    int cbInstance = 0;
     272    int cbIface = strlen(pszIfaceName);
     273    const char *pszEnd = pszIfaceName + cbIface - 1;
     274    for (int i = 0; i < cbIface - 1; i++)
     275    {
     276        if (!RT_C_IS_DIGIT(*pszEnd))
     277            break;
     278        cbInstance++;
     279        pszEnd--;
     280    }
     281
     282    uint32_t uInstance = RTStrToUInt32(pszEnd + 1);
     283    strncpy(pszDevName, pszIfaceName, cbIface - cbInstance);
     284    pszDevName[cbIface - cbInstance] = '\0';
     285    return uInstance;
     286}
     287
     288int CollectorSolaris::getRawHostNetworkLoad(const char *name, uint64_t *rx, uint64_t *tx)
     289{
     290    AssertReturn(strlen(name) < KSTAT_STRLEN, VERR_INVALID_PARAMETER);
     291    kstat_t *ksAdapter = kstat_lookup(mKC, NULL, -1, (char *)name);
     292    if (ksAdapter == 0)
     293    {
     294        char szModule[KSTAT_STRLEN];
     295        uint32_t uInstance = getInstance(name, szModule);
     296        ksAdapter = kstat_lookup(mKC, szModule, uInstance, NULL);
     297        if (ksAdapter == 0)
     298        {
     299            LogRel(("Failed to get network statistics for %s\n", name));
     300            return VERR_INTERNAL_ERROR;
     301        }
     302    }
     303    if (kstat_read(mKC, ksAdapter, 0) == -1)
     304    {
     305        LogRel(("kstat_read(adapter) -> %d\n", errno));
     306        return VERR_INTERNAL_ERROR;
     307    }
     308    kstat_named_t *kn;
     309    if ((kn = (kstat_named_t *)kstat_data_lookup(ksAdapter, (char *)"rbytes")) == 0)
     310    {
     311        LogRel(("kstat_data_lookup(rbytes) -> %d\n", errno));
     312        return VERR_INTERNAL_ERROR;
     313    }
     314    *rx = kn->value.ul;
     315    if ((kn = (kstat_named_t *)kstat_data_lookup(ksAdapter, (char *)"obytes")) == 0)
     316    {
     317        LogRel(("kstat_data_lookup(obytes) -> %d\n", errno));
     318        return VERR_INTERNAL_ERROR;
     319    }
     320    *tx = kn->value.ul;
     321    return VINF_SUCCESS;
     322}
     323
     324}
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette