diff options
Diffstat (limited to 'src/VBox/Frontends/VBoxBalloonCtrl/VBoxModBallooning.cpp')
| -rw-r--r-- | src/VBox/Frontends/VBoxBalloonCtrl/VBoxModBallooning.cpp | 42 |
1 files changed, 35 insertions, 7 deletions
diff --git a/src/VBox/Frontends/VBoxBalloonCtrl/VBoxModBallooning.cpp b/src/VBox/Frontends/VBoxBalloonCtrl/VBoxModBallooning.cpp index 7bcddf63..225ca0ae 100644 --- a/src/VBox/Frontends/VBoxBalloonCtrl/VBoxModBallooning.cpp +++ b/src/VBox/Frontends/VBoxBalloonCtrl/VBoxModBallooning.cpp @@ -4,7 +4,7 @@ */ /* - * Copyright (C) 2011-2012 Oracle Corporation + * Copyright (C) 2011-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,6 +24,7 @@ #endif /* !VBOX_ONLY_DOCS */ #include "VBoxWatchdogInternal.h" +#include <iprt/system.h> using namespace com; @@ -34,10 +35,11 @@ using namespace com; */ enum GETOPTDEF_BALLOONCTRL { - GETOPTDEF_BALLOONCTRL_BALLOOINC = 2000, + GETOPTDEF_BALLOONCTRL_BALLOONINC = 2000, GETOPTDEF_BALLOONCTRL_BALLOONDEC, GETOPTDEF_BALLOONCTRL_BALLOONLOWERLIMIT, GETOPTDEF_BALLOONCTRL_BALLOONMAX, + GETOPTDEF_BALLOONCTRL_BALLOONSAFETY, GETOPTDEF_BALLOONCTRL_TIMEOUTMS, GETOPTDEF_BALLOONCTRL_GROUPS }; @@ -48,10 +50,11 @@ enum GETOPTDEF_BALLOONCTRL static const RTGETOPTDEF g_aBalloonOpts[] = { { "--balloon-dec", GETOPTDEF_BALLOONCTRL_BALLOONDEC, RTGETOPT_REQ_UINT32 }, { "--balloon-groups", GETOPTDEF_BALLOONCTRL_GROUPS, RTGETOPT_REQ_STRING }, - { "--balloon-inc", GETOPTDEF_BALLOONCTRL_BALLOOINC, RTGETOPT_REQ_UINT32 }, + { "--balloon-inc", GETOPTDEF_BALLOONCTRL_BALLOONINC, RTGETOPT_REQ_UINT32 }, { "--balloon-interval", GETOPTDEF_BALLOONCTRL_TIMEOUTMS, RTGETOPT_REQ_UINT32 }, { "--balloon-lower-limit", GETOPTDEF_BALLOONCTRL_BALLOONLOWERLIMIT, RTGETOPT_REQ_UINT32 }, - { "--balloon-max", GETOPTDEF_BALLOONCTRL_BALLOONMAX, RTGETOPT_REQ_UINT32 } + { "--balloon-max", GETOPTDEF_BALLOONCTRL_BALLOONMAX, RTGETOPT_REQ_UINT32 }, + { "--balloon-safety-margin", GETOPTDEF_BALLOONCTRL_BALLOONSAFETY, RTGETOPT_REQ_UINT32 } }; static unsigned long g_ulMemoryBalloonTimeoutMS = 0; @@ -61,6 +64,7 @@ static unsigned long g_ulMemoryBalloonDecrementMB = 0; * "VBoxInternal/Guest/BalloonSizeMax" value. */ static unsigned long g_ulMemoryBalloonMaxMB = 0; static unsigned long g_ulMemoryBalloonLowerLimitMB = 0; +static unsigned long g_ulMemoryBalloonSafetyMB = _1K; /** The ballooning module's payload. */ typedef struct VBOXWATCHDOG_BALLOONCTRL_PAYLOAD @@ -111,6 +115,25 @@ static long balloonGetDelta(unsigned long ulCurrentDesktopBalloonSize, } if (ulCurrentDesktopBalloonSize + lBalloonDelta > ulMaxBalloonSize) lBalloonDelta = (ulMaxBalloonSize - ulCurrentDesktopBalloonSize); + + /* Limit the ballooning to the available memory, leaving some free. + * If anything fails clamp the delta to 0. */ + if (lBalloonDelta < 0) + { + uint64_t cbSafety = (uint64_t)g_ulMemoryBalloonSafetyMB * _1M; + uint64_t cbHostRamAvail = 0; + int vrc = RTSystemQueryAvailableRam(&cbHostRamAvail); + if (RT_SUCCESS(vrc)) + { + if (cbHostRamAvail < cbSafety) + lBalloonDelta = 0; + else if ((uint64_t)(-lBalloonDelta) > (cbHostRamAvail - cbSafety) / _1M) + lBalloonDelta = -(long)((cbHostRamAvail - cbSafety) / _1M); + } + else + lBalloonDelta = 0; + } + return lBalloonDelta; } @@ -322,7 +345,7 @@ static int balloonMachineUpdate(const Bstr &strUuid, PVBOXWATCHDOG_MACHINE pMach if (SUCCEEDED(rc)) CHECK_ERROR_BREAK(guest, COMSETTER(MemoryBalloonSize)(lBalloonCur)); else - serviceLog("Error: Unable to set new balloon size %ld for machine \"%ls\", rc=%Rhrc", + serviceLog("Error: Unable to set new balloon size %ld for machine \"%ls\", rc=%Rhrc\n", lBalloonCur, strUuid.raw(), rc); if (FAILED(rc)) vrc = VERR_COM_IPRT_ERROR; @@ -334,7 +357,7 @@ static int balloonMachineUpdate(const Bstr &strUuid, PVBOXWATCHDOG_MACHINE pMach } } else - serviceLog("Error: Unable to retrieve metrics for machine \"%ls\", rc=%Rrc", + serviceLog("Error: Unable to retrieve metrics for machine \"%ls\", rc=%Rrc\n", strUuid.raw(), vrc); return vrc; } @@ -372,7 +395,7 @@ static DECLCALLBACK(int) VBoxModBallooningOption(int argc, char *argv[], int *pi g_ulMemoryBalloonDecrementMB = ValueUnion.u32; break; - case GETOPTDEF_BALLOONCTRL_BALLOOINC: + case GETOPTDEF_BALLOONCTRL_BALLOONINC: g_ulMemoryBalloonIncrementMB = ValueUnion.u32; break; @@ -388,6 +411,10 @@ static DECLCALLBACK(int) VBoxModBallooningOption(int argc, char *argv[], int *pi g_ulMemoryBalloonMaxMB = ValueUnion.u32; break; + case GETOPTDEF_BALLOONCTRL_BALLOONSAFETY: + g_ulMemoryBalloonSafetyMB = ValueUnion.u32; + break; + /** @todo This option is a common module option! Put * this into a utility function! */ case GETOPTDEF_BALLOONCTRL_TIMEOUTMS: @@ -547,6 +574,7 @@ VBOXMODULE g_ModBallooning = /* (Legacy) note. */ "Set \"VBoxInternal/Guest/BalloonSizeMax\" for a per-VM maximum ballooning size.\n" #endif + "--balloon-safety-margin Free memory when deflating a balloon in MB (1024 MB).\n" , /* methods. */ VBoxModBallooningPreInit, |
