VirtualBox

Changeset 59907 in vbox


Ignore:
Timestamp:
Mar 3, 2016 12:57:45 PM (9 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
105824
Message:

FE/VBoxBalloonCtrl: Bugfixes for ballooning module + extended logging.

To not break backwards-compatibility, global "VBoxInternal/Guest/BalloonSizeMax" or the command line ("--balloon-max") will be used for specifying a maximum ballooning size. Writing 0 (default) or deleting the value will disable having a maximum.

The per-VM's "VBoxInternal2/Watchdog/BalloonCtrl/BalloonSizeMax" or "VBoxInternal/Guest/BalloonSizeMax" (legacy) will be used for setting the VM's balloon (limiting to the maximum ballooning size mentioned above, if set).

Location:
trunk/src/VBox/Frontends/VBoxBalloonCtrl
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Frontends/VBoxBalloonCtrl/VBoxModBallooning.cpp

    r59893 r59907  
    3131#define VBOX_MOD_BALLOONING_NAME "balloon"
    3232
     33/*********************************************************************************************************************************
     34*   Local Structures                                                                                                             *
     35*********************************************************************************************************************************/
     36
    3337/**
    3438 * The module's RTGetOpt-IDs for the command line.
     
    5862};
    5963
    60 static unsigned long g_ulMemoryBalloonTimeoutMS = 0;
    61 static unsigned long g_ulMemoryBalloonIncrementMB = 0;
    62 static unsigned long g_ulMemoryBalloonDecrementMB = 0;
    63 /** Global balloon limit is 0, so disabled. Can be overridden by a per-VM
    64  *  "VBoxInternal/Guest/BalloonSizeMax" value. */
    65 static unsigned long g_ulMemoryBalloonMaxMB = 0;
    66 static unsigned long g_ulMemoryBalloonLowerLimitMB = 0;
    67 static unsigned long g_ulMemoryBalloonSafetyMB = _1K;
    68 
    6964/** The ballooning module's payload. */
    7065typedef struct VBOXWATCHDOG_BALLOONCTRL_PAYLOAD
    7166{
    72     /** The maximum ballooning size for the VM.
     67    /** The maximum ballooning size for the VM set last.
    7368     *  Specify 0 for ballooning disabled. */
    74     unsigned long ulBalloonSizeMax;
     69    unsigned long ulBalloonMaxLast;
    7570} VBOXWATCHDOG_BALLOONCTRL_PAYLOAD, *PVBOXWATCHDOG_BALLOONCTRL_PAYLOAD;
    7671
     72/*********************************************************************************************************************************
     73*   Globals                                                                                                                      *
     74*********************************************************************************************************************************/
     75
     76static unsigned long g_ulMemoryBalloonTimeoutMS    = 30 * 1000;
     77static unsigned long g_ulMemoryBalloonIncrementMB  = 256;
     78static unsigned long g_ulMemoryBalloonDecrementMB  = 128;
     79/** Command line: Global balloon limit (in MB) for all VMs. Default is 0, which means
     80 *  no global limit is set. See balloonGetMaxSize() for more information. */
     81static unsigned long g_ulMemoryBalloonMaxMB        = 0;
     82static unsigned long g_ulMemoryBalloonLowerLimitMB = 128;
     83static unsigned long g_ulMemoryBalloonSafetyMB     = 1024;
     84
     85/*********************************************************************************************************************************
     86*   Local Function Prototypes                                                                                                    *
     87*********************************************************************************************************************************/
     88static int balloonSetSize(PVBOXWATCHDOG_MACHINE pMachine, unsigned long ulBalloonCur);
    7789
    7890/**
    7991 * Retrieves the current delta value
    8092 *
    81  * @return  long                                Delta (MB) of the balloon to be deflated (<0) or inflated (>0).
    82  * @param   ulCurrentDesktopBalloonSize         The balloon's current size.
    83  * @param   ulDesktopFreeMemory                 The VM's current free memory.
    84  * @param   ulMaxBalloonSize                    The maximum balloon size (MB) it can inflate to.
    85  */
    86 static long balloonGetDelta(unsigned long ulCurrentDesktopBalloonSize,
    87                             unsigned long ulDesktopFreeMemory, unsigned long ulMaxBalloonSize)
    88 {
    89     if (ulCurrentDesktopBalloonSize > ulMaxBalloonSize)
    90         return (ulMaxBalloonSize - ulCurrentDesktopBalloonSize);
     93 * @return  long                Delta (MB) of the balloon to be deflated (<0) or inflated (>0).
     94 * @param   pMachine            Pointer to the machine's internal structure.
     95 * @param   ulGuestMemFree      The guest's current free memory (MB).
     96 * @param   ulBalloonOld        The balloon's current (old) size (MB).
     97 * @param   ulBalloonNew        The balloon's new size (MB).
     98 * @param   ulBalloonMax        The maximum ballooning size (MB) it can inflate to.
     99 */
     100static long balloonGetDelta(PVBOXWATCHDOG_MACHINE pMachine,
     101                            unsigned long ulGuestMemFree,
     102                            unsigned long ulBalloonOld, unsigned long ulBalloonNew, unsigned long ulBalloonMax)
     103{
     104    serviceLogVerbose(("[%ls] ulGuestMemFree=%RU32, ulBalloonOld=%RU32, ulBalloonNew=%RU32, ulBalloonMax=%RU32\n",
     105                       pMachine->strName.raw(), ulGuestMemFree, ulBalloonOld, ulBalloonNew, ulBalloonMax));
     106
     107    /* Make sure that the requested new ballooning size does not
     108     * exceed the maximum ballooning size (if set). */
     109    if (   ulBalloonMax
     110        && (ulBalloonNew > ulBalloonMax))
     111    {
     112        ulBalloonNew = ulBalloonMax;
     113    }
     114
     115RT_BREAKPOINT();
    91116
    92117    long lBalloonDelta = 0;
    93     if (ulDesktopFreeMemory < g_ulMemoryBalloonLowerLimitMB)
     118    if (ulGuestMemFree < g_ulMemoryBalloonLowerLimitMB)
    94119    {
    95120        /* Guest is running low on memory, we need to
     
    99124        /* Ensure that the delta will not return a negative
    100125         * balloon size. */
    101         if ((long)ulCurrentDesktopBalloonSize + lBalloonDelta < 0)
     126        if ((long)ulBalloonOld + lBalloonDelta < 0)
    102127            lBalloonDelta = 0;
    103128    }
    104     else if (ulMaxBalloonSize > ulCurrentDesktopBalloonSize)
     129    else if (ulBalloonNew > ulBalloonOld) /* Inflate. */
    105130    {
    106131        /* We want to inflate the balloon if we have room. */
    107         long lIncrement = g_ulMemoryBalloonIncrementMB;
    108         while (lIncrement >= 16 && (ulDesktopFreeMemory - lIncrement) < g_ulMemoryBalloonLowerLimitMB)
    109         {
    110             lIncrement = (lIncrement / 2);
    111         }
    112 
    113         if ((ulDesktopFreeMemory - lIncrement) > g_ulMemoryBalloonLowerLimitMB)
    114             lBalloonDelta = lIncrement;
    115     }
    116     if (ulCurrentDesktopBalloonSize + lBalloonDelta > ulMaxBalloonSize)
    117         lBalloonDelta = (ulMaxBalloonSize - ulCurrentDesktopBalloonSize);
    118 
    119     /* Limit the ballooning to the available memory, leaving some free.
     132        unsigned long ulIncrement = g_ulMemoryBalloonIncrementMB;
     133        while (ulIncrement >= 16 && (ulGuestMemFree - ulIncrement) < g_ulMemoryBalloonLowerLimitMB)
     134            ulIncrement = (ulIncrement / 2);
     135
     136        if ((ulGuestMemFree - ulIncrement) > g_ulMemoryBalloonLowerLimitMB)
     137            lBalloonDelta = (long)ulIncrement;
     138
     139        /* Make sure we're still within bounds. */
     140        Assert(lBalloonDelta >= 0);
     141        if (ulBalloonOld + lBalloonDelta > ulBalloonNew)
     142            lBalloonDelta = RT_MIN(g_ulMemoryBalloonIncrementMB, ulBalloonNew - ulBalloonOld);
     143    }
     144    else if (ulBalloonNew < ulBalloonOld) /* Deflate. */
     145    {
     146        lBalloonDelta = RT_CLAMP(g_ulMemoryBalloonDecrementMB, 0, ulBalloonOld - ulBalloonNew) * -1;
     147    }
     148
     149    /* Limit the ballooning to the available host memory, leaving some free.
    120150     * If anything fails clamp the delta to 0. */
    121151    if (lBalloonDelta < 0)
     
    141171 * Determines the maximum balloon size to set for the specified machine.
    142172 *
    143  * @return  unsigned long           Balloon size (in MB) to set, 0 if no ballooning required.
    144  * @param   rptrMachine             Pointer to interface of specified machine.
    145  */
    146 static unsigned long balloonGetMaxSize(const ComPtr<IMachine> &rptrMachine)
    147 {
     173 * @return  unsigned long           Maximum ballooning size (in MB), 0 if no maximum set.
     174 * @param   pMachine                Machine to determine maximum ballooning size for.
     175 */
     176static unsigned long balloonGetMaxSize(PVBOXWATCHDOG_MACHINE pMachine)
     177{
     178    const ComPtr<IMachine> &rptrMachine = pMachine->machine;
     179
    148180    /*
    149      * Try to retrieve the balloon maximum size via the following order:
    150      *  - command line parameter ("--balloon-max")
    151      *  Legacy (VBoxBalloonCtrl):
    152      *  - per-VM parameter ("VBoxInternal/Guest/BalloonSizeMax")
    153      *  Global:
    154      *  - global parameter ("VBoxInternal/Guest/BalloonSizeMax")
    155      *  New:
    156      *  - per-VM parameter ("VBoxInternal2/Watchdog/BalloonCtrl/BalloonSizeMax")
     181     * Is a maximum ballooning size set? Make sure we're within bounds.
    157182     *
    158      *  By default (e.g. if none of above is set), ballooning is disabled.
     183     * The maximum balloning size can be set
     184     * - via global extra-data ("VBoxInternal/Guest/BalloonSizeMax")
     185     * - via command line ("--balloon-max")
     186     *
     187     * Precedence from top to bottom.
    159188     */
    160     unsigned long ulBalloonMax = g_ulMemoryBalloonMaxMB;
    161     if (!ulBalloonMax)
    162     {
    163         int vrc = cfgGetValueULong(g_pVirtualBox, rptrMachine,
    164                                   "VBoxInternal/Guest/BalloonSizeMax", "VBoxInternal/Guest/BalloonSizeMax", &ulBalloonMax, 0 /* Ballooning disabled */);
    165         if (RT_FAILURE(vrc))
     189    unsigned long ulBalloonMax = 0;
     190    char szSource[64];
     191
     192    Bstr strValue;
     193    HRESULT hr = g_pVirtualBox->GetExtraData(Bstr("VBoxInternal/Guest/BalloonSizeMax").raw(),
     194                                             strValue.asOutParam());
     195    if (   SUCCEEDED(hr)
     196        && strValue.isNotEmpty())
     197    {
     198        ulBalloonMax = Utf8Str(strValue).toUInt32();
     199        if (g_fVerbose)
     200            RTStrPrintf(szSource, sizeof(szSource), "global extra-data");
     201    }
     202
     203    if (strValue.isEmpty())
     204    {
     205        Assert(ulBalloonMax == 0);
     206
     207        ulBalloonMax = g_ulMemoryBalloonMaxMB;
     208        if (g_fVerbose)
     209            RTStrPrintf(szSource, sizeof(szSource), "command line");
     210    }
     211
     212    serviceLogVerbose(("[%ls] Maximum balloning size is (%s): %RU32MB\n", pMachine->strName.raw(), szSource, ulBalloonMax));
     213    return ulBalloonMax;
     214}
     215
     216/**
     217 * Determines the current (set) balloon size of the specified machine.
     218 *
     219 * @return  IPRT status code.
     220 * @param   pMachine                Machine to determine maximum ballooning size for.
     221 * @param   pulBalloonCur           Where to store the current (set) balloon size (in MB) on success.
     222 */
     223static int balloonGetCurrentSize(PVBOXWATCHDOG_MACHINE pMachine, unsigned long *pulBalloonCur)
     224{
     225    LONG lBalloonCur;
     226    int vrc = getMetric(pMachine, L"Guest/RAM/Usage/Balloon", &lBalloonCur);
     227    if (RT_SUCCESS(vrc))
     228    {
     229        lBalloonCur /= 1024; /* Convert to MB. */
     230        if (pulBalloonCur)
     231            *pulBalloonCur = (unsigned long)lBalloonCur;
     232    }
     233
     234    return vrc;
     235}
     236
     237/**
     238 * Determines the requested balloon size to set for the specified machine.
     239 *
     240 * @return  unsigned long           Requested ballooning size (in MB), 0 if ballooning should be disabled.
     241 * @param   pMachine                Machine to determine maximum ballooning size for.
     242 */
     243static unsigned long balloonGetRequestedSize(PVBOXWATCHDOG_MACHINE pMachine)
     244{
     245    const ComPtr<IMachine> &rptrMachine = pMachine->machine;
     246
     247    /*
     248     * The maximum balloning size can be set
     249     * - via per-VM extra-data ("VBoxInternal2/Watchdog/BalloonCtrl/BalloonSizeMax")
     250     * - via per-VM extra-data (legacy) ("VBoxInternal/Guest/BalloonSizeMax")
     251     *
     252     * Precedence from top to bottom.
     253     */
     254    unsigned long ulBalloonReq;
     255    char szSource[64];
     256
     257    Bstr strValue;
     258    HRESULT hr = rptrMachine->GetExtraData(Bstr("VBoxInternal2/Watchdog/BalloonCtrl/BalloonSizeMax").raw(),
     259                                           strValue.asOutParam());
     260    if (   SUCCEEDED(hr)
     261        && strValue.isNotEmpty())
     262    {
     263        ulBalloonReq = Utf8Str(strValue).toUInt32();
     264        if (g_fVerbose)
     265            RTStrPrintf(szSource, sizeof(szSource), "per-VM extra-data");
     266    }
     267    else
     268    {
     269        hr = rptrMachine->GetExtraData(Bstr("VBoxInternal/Guest/BalloonSizeMax").raw(),
     270                                       strValue.asOutParam());
     271        if (   SUCCEEDED(hr)
     272            && strValue.isNotEmpty())
    166273        {
    167             /* Try (new) VBoxWatch per-VM approach. */
    168             Bstr strValue;
    169             HRESULT rc = rptrMachine->GetExtraData(Bstr("VBoxInternal2/Watchdog/BalloonCtrl/BalloonSizeMax").raw(),
    170                                                    strValue.asOutParam());
    171             if (   SUCCEEDED(rc)
    172                 && !strValue.isEmpty())
    173             {
    174                 ulBalloonMax = Utf8Str(strValue).toUInt32();
    175             }
     274            ulBalloonReq = Utf8Str(strValue).toUInt32();
     275            if (g_fVerbose)
     276                RTStrPrintf(szSource, sizeof(szSource), "per-VM extra-data (legacy)");
    176277        }
    177278    }
    178279
    179     return ulBalloonMax;
     280    if (   FAILED(hr)
     281        || strValue.isEmpty())
     282    {
     283        ulBalloonReq = 0;
     284        if (g_fVerbose)
     285            RTStrPrintf(szSource, sizeof(szSource), "none (disabled)");
     286    }
     287
     288    serviceLogVerbose(("[%ls] Requested balloning size is (%s): %RU32MB\n", pMachine->strName.raw(), szSource, ulBalloonReq));
     289    return ulBalloonReq;
    180290}
    181291
     
    206316}
    207317
    208 /**
    209  * Determines whether ballooning is required to the specified machine.
    210  *
    211  * @return  bool                    True if ballooning is required, false if not.
    212  * @param   pMachine                Machine to determine ballooning for.
    213  */
    214 static bool balloonIsRequired(PVBOXWATCHDOG_MACHINE pMachine)
    215 {
    216     AssertPtrReturn(pMachine, false);
    217 
    218     /* Only do ballooning if we have a maximum balloon size set. */
    219     PVBOXWATCHDOG_BALLOONCTRL_PAYLOAD pData = (PVBOXWATCHDOG_BALLOONCTRL_PAYLOAD)
    220                                               payloadFrom(pMachine, VBOX_MOD_BALLOONING_NAME);
    221     AssertPtr(pData);
    222     pData->ulBalloonSizeMax = pMachine->machine.isNull()
    223                               ? 0 : balloonGetMaxSize(pMachine->machine);
    224 
    225     /** @todo Add grouping as a criteria! */
    226 
    227     return pData->ulBalloonSizeMax ? true : false;
    228 }
    229 
    230318int balloonMachineSetup(const Bstr& strUuid)
    231319{
     
    280368 *
    281369 * @return  IPRT status code.
    282  * @param   strUuid                 UUID of the specified machine.
    283370 * @param   pMachine                Pointer to the machine's internal structure.
    284371 */
    285 static int balloonMachineUpdate(const Bstr &strUuid, PVBOXWATCHDOG_MACHINE pMachine)
     372static int balloonMachineUpdate(PVBOXWATCHDOG_MACHINE pMachine)
    286373{
    287374    AssertPtrReturn(pMachine, VERR_INVALID_POINTER);
     
    290377     * Get metrics collected at this point.
    291378     */
    292     LONG lMemFree, lBalloonCur;
    293     int vrc = getMetric(pMachine, L"Guest/RAM/Usage/Free", &lMemFree);
     379    LONG lGuestMemFree;
     380    unsigned long ulBalloonCur;
     381
     382    int vrc = getMetric(pMachine, L"Guest/RAM/Usage/Free", &lGuestMemFree);
    294383    if (RT_SUCCESS(vrc))
    295         vrc = getMetric(pMachine, L"Guest/RAM/Usage/Balloon", &lBalloonCur);
     384        vrc = balloonGetCurrentSize(pMachine, &ulBalloonCur);
    296385
    297386    if (RT_SUCCESS(vrc))
    298387    {
    299         /* If guest statistics are not up and running yet, skip this iteration
    300          * and try next time. */
    301         if (lMemFree <= 0)
     388        /* If guest statistics are not up and running yet, skip this iteration and try next time. */
     389        if (lGuestMemFree <= 0)
    302390        {
    303391#ifdef DEBUG
    304             serviceLogVerbose(("%ls: No metrics available yet!\n", strUuid.raw()));
     392            serviceLogVerbose(("[%ls] No metrics available yet!\n", pMachine->strName.raw()));
    305393#endif
    306394            return VINF_SUCCESS;
    307395        }
    308396
    309         lMemFree /= 1024;
    310         lBalloonCur /= 1024;
     397        lGuestMemFree /= 1024;
    311398
    312399        PVBOXWATCHDOG_BALLOONCTRL_PAYLOAD pData = (PVBOXWATCHDOG_BALLOONCTRL_PAYLOAD)
     
    314401        AssertPtr(pData);
    315402
    316         serviceLogVerbose(("%ls: Balloon: %ld, Free mem: %ld, Max ballon: %ld\n",
    317                            strUuid.raw(),
    318                            lBalloonCur, lMemFree, pData->ulBalloonSizeMax));
     403        /* Determine the current set maximum balloon size. */
     404        unsigned long ulBalloonMax = balloonGetMaxSize(pMachine);
     405
     406        /* Determine the requested balloon size. */
     407        unsigned long ulBalloonReq = balloonGetRequestedSize(pMachine);
     408
     409        serviceLogVerbose(("[%ls] Free RAM (MB): %RI32, Ballooning: Current=%RU32MB, Requested=%RU32MB, Maximum=%RU32MB\n",
     410                           pMachine->strName.raw(), lGuestMemFree, ulBalloonCur, ulBalloonReq, ulBalloonMax));
     411
     412        if (   ulBalloonMax
     413            && (ulBalloonReq > ulBalloonMax))
     414        {
     415            serviceLog("[%ls] Warning: Requested ballooning size (%RU32MB) exceeds set maximum ballooning size (%RU32MB), limiting ...\n",
     416                       pMachine->strName.raw(), ulBalloonReq, ulBalloonMax);
     417        }
    319418
    320419        /* Calculate current balloon delta. */
    321         long lDelta = balloonGetDelta(lBalloonCur, lMemFree, pData->ulBalloonSizeMax);
    322         if (lDelta) /* Only do ballooning if there's really smth. to change ... */
     420        long lBalloonDelta = balloonGetDelta(pMachine,
     421                                             (unsigned long)lGuestMemFree, ulBalloonCur, ulBalloonReq, ulBalloonMax);
     422#ifdef DEBUG
     423        serviceLogVerbose(("[%ls] lBalloonDelta=%RI32\n", pMachine->strName.raw(), lBalloonDelta));
     424#endif
     425        if (lBalloonDelta) /* Only do ballooning if there's really smth. to change ... */
    323426        {
    324             lBalloonCur = lBalloonCur + lDelta;
    325             Assert(lBalloonCur > 0);
    326 
    327             serviceLog("%ls: %s balloon by %ld to %ld ...\n",
    328                        strUuid.raw(),
    329                        lDelta > 0 ? "Inflating" : "Deflating", lDelta, lBalloonCur);
    330 
    331             if (!g_fDryrun)
    332             {
    333                 /* Open a session for the VM. */
    334                 HRESULT rc;
    335                 CHECK_ERROR(pMachine->machine, LockMachine(g_pSession, LockType_Shared));
    336 
    337                 do
    338                 {
    339                     /* Get the associated console. */
    340                     ComPtr<IConsole> console;
    341                     CHECK_ERROR_BREAK(g_pSession, COMGETTER(Console)(console.asOutParam()));
    342 
    343                     ComPtr <IGuest> guest;
    344                     rc = console->COMGETTER(Guest)(guest.asOutParam());
    345                     if (SUCCEEDED(rc))
    346                         CHECK_ERROR_BREAK(guest, COMSETTER(MemoryBalloonSize)(lBalloonCur));
    347                     else
    348                         serviceLog("Error: Unable to set new balloon size %ld for machine \"%ls\", rc=%Rhrc\n",
    349                                    lBalloonCur, strUuid.raw(), rc);
    350                     if (FAILED(rc))
    351                         vrc = VERR_COM_IPRT_ERROR;
    352                 } while (0);
    353 
    354                 /* Unlock the machine again. */
    355                 g_pSession->UnlockMachine();
    356             }
     427            ulBalloonCur = ulBalloonCur + lBalloonDelta;
     428
     429            serviceLog("[%ls] %s balloon by %RU32MB to %RU32MB ...\n",
     430                       pMachine->strName.raw(), lBalloonDelta > 0 ? "Inflating" : "Deflating", RT_ABS(lBalloonDelta), ulBalloonCur);
     431
     432            vrc = balloonSetSize(pMachine, ulBalloonCur);
     433            if (RT_SUCCESS(vrc))
     434                pData->ulBalloonMaxLast = ulBalloonMax;
    357435        }
    358436    }
    359437    else
    360         serviceLog("Error: Unable to retrieve metrics for machine \"%ls\", rc=%Rrc\n",
    361                    strUuid.raw(), vrc);
     438        serviceLog("Error: Unable to retrieve metrics for machine '%ls', rc=%Rrc\n",
     439                   pMachine->strName.raw(), vrc);
     440    return vrc;
     441}
     442
     443static int balloonSetSize(PVBOXWATCHDOG_MACHINE pMachine, unsigned long ulBalloonCur)
     444{
     445    int vrc = VINF_SUCCESS;
     446
     447    serviceLogVerbose(("[%ls] Setting balloon size to %RU32MB ...\n", pMachine->strName.raw(), ulBalloonCur));
     448
     449    if (g_fDryrun)
     450        return VINF_SUCCESS;
     451
     452    /* Open a session for the VM. */
     453    HRESULT rc;
     454    CHECK_ERROR_RET(pMachine->machine, LockMachine(g_pSession, LockType_Shared), VERR_ACCESS_DENIED);
     455
     456    do
     457    {
     458        /* Get the associated console. */
     459        ComPtr<IConsole> console;
     460        CHECK_ERROR_BREAK(g_pSession, COMGETTER(Console)(console.asOutParam()));
     461
     462        ComPtr <IGuest> guest;
     463        rc = console->COMGETTER(Guest)(guest.asOutParam());
     464        if (SUCCEEDED(rc))
     465            CHECK_ERROR_BREAK(guest, COMSETTER(MemoryBalloonSize)((LONG)ulBalloonCur));
     466        else
     467            serviceLog("Error: Unable to set new balloon size %RU32 for machine '%ls', rc=%Rhrc\n",
     468                       ulBalloonCur, pMachine->strName.raw(), rc);
     469        if (FAILED(rc))
     470            vrc = VERR_COM_IPRT_ERROR;
     471
     472    } while (0);
     473
     474
     475    /* Unlock the machine again. */
     476    CHECK_ERROR_RET(g_pSession,  UnlockMachine(), VERR_ACCESS_DENIED);
     477
    362478    return vrc;
    363479}
     
    465581static DECLCALLBACK(int) VBoxModBallooningMain(void)
    466582{
    467     static uint64_t uLast = UINT64_MAX;
    468     uint64_t uNow = RTTimeProgramMilliTS() / g_ulMemoryBalloonTimeoutMS;
    469     if (uLast == uNow)
     583    static uint64_t s_msLast = RTTimeMilliTS();
     584    uint64_t msDelta = RTTimeMilliTS() - s_msLast;
     585    if (msDelta <= g_ulMemoryBalloonTimeoutMS)
    470586        return VINF_SUCCESS;
    471     uLast = uNow;
    472587
    473588    int rc = VINF_SUCCESS;
     
    480595
    481596        /* Our actual ballooning criteria. */
    482         if (   balloonIsPossible(state)
    483             && balloonIsRequired(&it->second))
     597        if (balloonIsPossible(state))
    484598        {
    485             rc = balloonMachineUpdate(it->first /* UUID */,
    486                                       &it->second /* Machine */);
     599            rc = balloonMachineUpdate(&it->second);
    487600            AssertRC(rc);
    488601        }
     
    493606    }
    494607
     608    s_msLast = RTTimeMilliTS();
    495609    return rc;
    496610}
     
    514628                          sizeof(VBOXWATCHDOG_BALLOONCTRL_PAYLOAD), (void**)&pData);
    515629    if (RT_SUCCESS(rc))
    516         rc = balloonMachineUpdate(strUuid, pMachine);
     630        rc = balloonMachineUpdate(pMachine);
    517631
    518632    return rc;
     
    538652        return VINF_SUCCESS;
    539653
    540     return balloonMachineUpdate(strUuid, pMachine);
     654    return balloonMachineUpdate(pMachine);
    541655}
    542656
  • trunk/src/VBox/Frontends/VBoxBalloonCtrl/VBoxWatchdog.cpp

    r59893 r59907  
    369369        VBOXWATCHDOG_MACHINE m;
    370370        m.machine = machine;
     371        CHECK_ERROR_BREAK(machine, COMGETTER(Name)(m.strName.asOutParam()));
     372
    371373        int rc2 = groupAdd(m.groups, strGroups.c_str(), 0 /* Flags */);
    372374        AssertRC(rc2);
  • trunk/src/VBox/Frontends/VBoxBalloonCtrl/VBoxWatchdogInternal.h

    r43738 r59907  
    55
    66/*
    7  * Copyright (C) 2011-2012 Oracle Corporation
     7 * Copyright (C) 2011-2016 Oracle Corporation
    88 *
    99 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    8888{
    8989    ComPtr<IMachine> machine;
     90    /** The machine's name. For logging. */
     91    Bstr strName;
    9092#ifndef VBOX_WATCHDOG_GLOBAL_PERFCOL
    9193    ComPtr<IPerformanceCollector> collector;
  • trunk/src/VBox/Frontends/VBoxBalloonCtrl/VBoxWatchdogUtils.cpp

    r57358 r59907  
    158158    AssertReturn(cbSize, VERR_INVALID_PARAMETER);
    159159
    160     void *pvData = RTMemAlloc(cbSize);
     160    void *pvData = RTMemAllocZ(cbSize);
    161161    AssertPtrReturn(pvData, VERR_NO_MEMORY);
    162162
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