VirtualBox

Changeset 40010 in vbox


Ignore:
Timestamp:
Feb 6, 2012 10:23:09 PM (13 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
76127
Message:

VBoxBalloonCtrl: Update.

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

Legend:

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

    r39988 r40010  
    2222*******************************************************************************/
    2323#ifndef VBOX_ONLY_DOCS
    24 # include <VBox/com/com.h>
    25 # include <VBox/com/string.h>
    26 # include <VBox/com/Guid.h>
    27 # include <VBox/com/array.h>
    28 # include <VBox/com/ErrorInfo.h>
    2924# include <VBox/com/errorprint.h>
    30 
    31 # include <VBox/com/EventQueue.h>
    32 # include <VBox/com/listeners.h>
    33 # include <VBox/com/VirtualBox.h>
    3425#endif /* !VBOX_ONLY_DOCS */
    35 
    36 #include <VBox/err.h>
    37 #include <VBox/log.h>
    38 #include <VBox/version.h>
    39 
    40 #include <package-generated.h>
    41 
    42 #include <iprt/asm.h>
    43 #include <iprt/buildconfig.h>
    44 #include <iprt/critsect.h>
    45 #include <iprt/getopt.h>
    46 #include <iprt/initterm.h>
    47 #include <iprt/path.h>
    48 #include <iprt/process.h>
    49 #include <iprt/semaphore.h>
    50 #include <iprt/stream.h>
    51 #include <iprt/string.h>
    52 #include <iprt/system.h>
    53 
    54 #include <map>
    55 #include <string>
    56 #include <signal.h>
    5726
    5827#include "VBoxWatchdogInternal.h"
     
    6534 * The module's RTGetOpt-IDs for the command line.
    6635 */
    67 enum GETOPTDEF_APIMON
    68 {
    69     GETOPTDEF_APIMON_ISLN_RESPONSE = 1000,
     36static enum GETOPTDEF_APIMON
     37{
     38    GETOPTDEF_APIMON_ISLN_RESPONSE = 3000,
    7039    GETOPTDEF_APIMON_ISLN_TIMEOUT,
    7140    GETOPTDEF_APIMON_GROUPS
     
    8150};
    8251
    83 static unsigned long g_ulAPIMonIslnTimeoutMS = 0;
    84 static Bstr g_strAPIMonGroups;
    85 static Bstr g_strAPIMonIslnCmdResp;
     52static enum APIMON_RESPONSE
     53{
     54    /** Unknown / unhandled response. */
     55    APIMON_RESPONSE_UNKNOWN    = 0,
     56    /** Tries to shut down all running VMs in
     57     *  a gentle manner. */
     58    APIMON_RESPONSE_SHUTDOWN   = 200
     59};
     60
     61static Bstr                         g_strAPIMonGroups;
     62
     63static APIMON_RESPONSE              g_enmAPIMonIslnResp     = APIMON_RESPONSE_UNKNOWN;
     64static unsigned long                g_ulAPIMonIslnTimeoutMS = 0;
     65static Bstr                         g_strAPIMonIslnLastBeat;
     66static uint64_t                     g_uAPIMonIslnLastBeatMS = 0;
     67
     68int apimonResponseToEnum(const char *pszResponse, APIMON_RESPONSE *pResp)
     69{
     70    AssertPtrReturn(pszResponse, VERR_INVALID_POINTER);
     71    AssertPtrReturn(pResp, VERR_INVALID_POINTER);
     72
     73    int rc = VINF_SUCCESS;
     74    if (   !RTStrICmp(pszResponse, "shutdown")
     75        || !RTStrICmp(pszResponse, "poweroff"))
     76    {
     77        *pResp = APIMON_RESPONSE_SHUTDOWN;
     78    }
     79    else
     80        *pResp = APIMON_RESPONSE_UNKNOWN;
     81
     82    return (*pResp > APIMON_RESPONSE_UNKNOWN ? VINF_SUCCESS : VERR_INVALID_PARAMETER);
     83}
     84
     85int apimonMachineControl(const Bstr &strUuid, PVBOXWATCHDOG_MACHINE pMachine,
     86                         APIMON_RESPONSE enmResp)
     87{
     88    /** @todo Add other commands (with enmResp) here. */
     89    AssertPtrReturn(pMachine, VERR_INVALID_PARAMETER);
     90
     91    serviceLog("Shutting down machine \"%ls\"\n", strUuid.raw());
     92
     93    /* Open a session for the VM. */
     94    HRESULT rc;
     95    CHECK_ERROR_RET(pMachine->machine, LockMachine(g_pSession, LockType_Shared), VERR_ACCESS_DENIED);
     96    do
     97    {
     98        /* get the associated console */
     99        ComPtr<IConsole> console;
     100        CHECK_ERROR_BREAK(g_pSession, COMGETTER(Console)(console.asOutParam()));
     101
     102        if (!g_fDryrun)
     103        {
     104            ComPtr<IProgress> progress;
     105            CHECK_ERROR_BREAK(console, PowerDown(progress.asOutParam()));
     106            if (g_fVerbose)
     107            {
     108                serviceLogVerbose(("Waiting for shutting down machine \"%ls\" ...\n",
     109                                   strUuid.raw()));
     110                progress->WaitForCompletion(-1);
     111            }
     112        }
     113    } while (0);
     114
     115    /* Unlock the machine again. */
     116    g_pSession->UnlockMachine();
     117
     118    return SUCCEEDED(rc) ? VINF_SUCCESS : VERR_COM_IPRT_ERROR;
     119}
     120
     121int apimonTrigger(APIMON_RESPONSE enmResp)
     122{
     123    int rc = VINF_SUCCESS;
     124
     125    /** @todo Add proper grouping support! */
     126    bool fAllGroups = g_strAPIMonGroups.isEmpty();
     127    mapVMIter it = g_mapVM.begin();
     128    while (it != g_mapVM.end())
     129    {
     130        if (   !it->second.group.compare(g_strAPIMonGroups, Bstr::CaseInsensitive)
     131            || fAllGroups)
     132        {
     133            rc = apimonMachineControl(it->first /* Uuid */,
     134                                       &it->second, enmResp);
     135        }
     136        it++;
     137    }
     138
     139    return rc;
     140}
    86141
    87142/* Callbacks. */
     
    114169        {
    115170            case GETOPTDEF_APIMON_ISLN_RESPONSE:
     171                rc = apimonResponseToEnum(ValueUnion.psz, &g_enmAPIMonIslnResp);
     172                if (RT_FAILURE(rc))
     173                    rc = -1; /* Option unknown. */
    116174                break;
    117175
     
    123181
    124182            case GETOPTDEF_APIMON_GROUPS:
     183                g_strAPIMonGroups = ValueUnion.psz;
    125184                break;
    126185
     
    140199    do
    141200    {
    142         Bstr bstrValue;
     201        Bstr strValue;
    143202
    144203        /* Host isolation timeout (in ms). */
    145204        if (!g_ulAPIMonIslnTimeoutMS) /* Not set by command line? */
    146205        {
    147             CHECK_ERROR_BREAK(g_pVirtualBox, GetExtraData(Bstr("VBoxInternal2/Watchdog/APIMonitor/IsolationTimeout").raw(),
    148                                                           bstrValue.asOutParam()));
    149             g_ulAPIMonIslnTimeoutMS = Utf8Str(bstrValue).toUInt32();
    150         }
    151         if (!g_ulAPIMonIslnTimeoutMS)
    152         {
    153              /* Default is 30 seconds timeout. */
     206            CHECK_ERROR_BREAK(g_pVirtualBox, GetExtraData(Bstr("Watchdog/APIMonitor/IsolationTimeout").raw(),
     207                                                          strValue.asOutParam()));
     208            if (!strValue.isEmpty())
     209                g_ulAPIMonIslnTimeoutMS = Utf8Str(strValue).toUInt32();
     210        }
     211        if (!g_ulAPIMonIslnTimeoutMS) /* Still not set? Use a default. */
     212        {
     213            serviceLogVerbose(("API monitor isolation timeout not given, defaulting to 30s\n"));
     214
     215            /* Default is 30 seconds timeout. */
    154216            g_ulAPIMonIslnTimeoutMS = 30 * 1000;
    155217        }
     
    158220        if (g_strAPIMonGroups.isEmpty()) /* Not set by command line? */
    159221        {
    160             CHECK_ERROR_BREAK(g_pVirtualBox, GetExtraData(Bstr("VBoxInternal2/Watchdog/APIMonitor/Groups").raw(),
     222            CHECK_ERROR_BREAK(g_pVirtualBox, GetExtraData(Bstr("Watchdog/APIMonitor/Groups").raw(),
    161223                                                          g_strAPIMonGroups.asOutParam()));
    162224        }
    163225
    164226        /* Host isolation command response. */
    165         if (g_strAPIMonIslnCmdResp.isEmpty()) /* Not set by command line? */
    166         {
    167             CHECK_ERROR_BREAK(g_pVirtualBox, GetExtraData(Bstr("VBoxInternal2/Watchdog/APIMonitor/IsolationResponse").raw(),
    168                                                           g_strAPIMonIslnCmdResp.asOutParam()));
     227        if (g_enmAPIMonIslnResp == APIMON_RESPONSE_UNKNOWN) /* Not set by command line? */
     228        {
     229            CHECK_ERROR_BREAK(g_pVirtualBox, GetExtraData(Bstr("Watchdog/APIMonitor/IsolationResponse").raw(),
     230                                                          strValue.asOutParam()));
     231            if (!strValue.isEmpty())
     232            {
     233                int rc2 = apimonResponseToEnum(Utf8Str(strValue).c_str(), &g_enmAPIMonIslnResp);
     234                if (RT_FAILURE(rc2))
     235                {
     236                    serviceLog("Warning: API monitor response string invalid (%ls), default to shutdown\n",
     237                               strValue.raw());
     238                    g_enmAPIMonIslnResp = APIMON_RESPONSE_SHUTDOWN;
     239                }
     240            }
     241            else
     242                g_enmAPIMonIslnResp = APIMON_RESPONSE_SHUTDOWN;
    169243        }
    170244    } while (0);
    171245
     246    if (SUCCEEDED(rc))
     247    {
     248        g_uAPIMonIslnLastBeatMS = 0;
     249    }
     250
    172251    return SUCCEEDED(rc) ? VINF_SUCCESS : VERR_COM_IPRT_ERROR; /* @todo Find a better rc! */
    173252}
     
    175254static DECLCALLBACK(int) VBoxModAPIMonitorMain(void)
    176255{
    177     return VINF_SUCCESS; /* Nothing to do here right now. */
     256    static uint64_t uLastRun = 0;
     257    uint64_t uNow = RTTimeProgramMilliTS();
     258    uint64_t uDelta = uNow - uLastRun;
     259    if (uDelta < 1000)
     260        return VINF_SUCCESS;
     261    uLastRun = uNow;
     262
     263    int vrc = VINF_SUCCESS;
     264    HRESULT rc;
     265
     266    serviceLogVerbose(("Checking for API heartbeat (%RU64ms) ...\n",
     267                       g_ulAPIMonIslnTimeoutMS));
     268
     269    do
     270    {
     271        Bstr strHeartbeat;
     272        CHECK_ERROR_BREAK(g_pVirtualBox, GetExtraData(Bstr("Watchdog/APIMonitor/Heartbeat").raw(),
     273                                                      strHeartbeat.asOutParam()));
     274        if (   SUCCEEDED(rc)
     275            && !strHeartbeat.isEmpty()
     276            && g_strAPIMonIslnLastBeat.compare(strHeartbeat, Bstr::CaseSensitive))
     277        {
     278            serviceLogVerbose(("API heartbeat received, resetting timeout\n"));
     279
     280            g_uAPIMonIslnLastBeatMS = 0;
     281            g_strAPIMonIslnLastBeat = strHeartbeat;
     282        }
     283        else
     284        {
     285            g_uAPIMonIslnLastBeatMS += uDelta;
     286            if (g_uAPIMonIslnLastBeatMS > g_ulAPIMonIslnTimeoutMS)
     287            {
     288                serviceLogVerbose(("No API heartbeat within time received (%RU64ms)\n",
     289                                   g_ulAPIMonIslnTimeoutMS));
     290
     291                vrc = apimonTrigger(g_enmAPIMonIslnResp);
     292                g_uAPIMonIslnLastBeatMS = 0;
     293            }
     294        }
     295    } while (0);
     296
     297    if (FAILED(rc))
     298        vrc = VERR_COM_IPRT_ERROR;
     299
     300    return vrc;
    178301}
    179302
     
    205328static DECLCALLBACK(int) VBoxModAPIMonitorOnServiceStateChanged(bool fAvailable)
    206329{
     330    if (!fAvailable)
     331        apimonTrigger(g_enmAPIMonIslnResp);
    207332    return VINF_SUCCESS;
    208333}
     
    225350    " [--apimon-groups=<string>]\n",
    226351    /* pszOptions. */
    227     "--apimon-isln-response   Sets the isolation response (shutdown VM).\n"
    228     "--apimon-isln-timeout    Sets the isolation timeout in ms (none).\n"
    229     "--apimon-groups          Sets the VM groups for monitoring (none).\n",
     352    "--apimon-isln-response Sets the isolation response (shutdown VM).\n"
     353    "--apimon-isln-timeout  Sets the isolation timeout in ms (30s).\n"
     354    "--apimon-groups        Sets the VM groups for monitoring (none).\n",
    230355    /* methods. */
    231356    VBoxModAPIMonitorPreInit,
  • trunk/src/VBox/Frontends/VBoxBalloonCtrl/VBoxModBallooning.cpp

    r39988 r40010  
    2121*******************************************************************************/
    2222#ifndef VBOX_ONLY_DOCS
    23 # include <VBox/com/com.h>
    24 # include <VBox/com/string.h>
    25 # include <VBox/com/Guid.h>
    26 # include <VBox/com/array.h>
    27 # include <VBox/com/ErrorInfo.h>
    2823# include <VBox/com/errorprint.h>
    29 
    30 # include <VBox/com/EventQueue.h>
    31 # include <VBox/com/listeners.h>
    32 # include <VBox/com/VirtualBox.h>
    3324#endif /* !VBOX_ONLY_DOCS */
    3425
    35 #include <VBox/err.h>
    36 #include <VBox/log.h>
    37 #include <VBox/version.h>
    38 
    39 #include <package-generated.h>
    40 
    41 #include <iprt/asm.h>
    42 #include <iprt/buildconfig.h>
    43 #include <iprt/critsect.h>
    44 #include <iprt/getopt.h>
    45 #include <iprt/initterm.h>
    46 #include <iprt/path.h>
    47 #include <iprt/process.h>
    48 #include <iprt/semaphore.h>
    49 #include <iprt/stream.h>
    50 #include <iprt/string.h>
    51 #include <iprt/system.h>
    52 
    53 #include <map>
    54 #include <string>
    55 #include <signal.h>
    56 
    5726#include "VBoxWatchdogInternal.h"
    5827
     
    6433 * The module's RTGetOpt-IDs for the command line.
    6534 */
    66 enum GETOPTDEF_BALLOONCTRL
    67 {
    68     GETOPTDEF_BALLOONCTRL_BALLOOINC = 1000,
     35static enum GETOPTDEF_BALLOONCTRL
     36{
     37    GETOPTDEF_BALLOONCTRL_BALLOOINC = 2000,
    6938    GETOPTDEF_BALLOONCTRL_BALLOONDEC,
    7039    GETOPTDEF_BALLOONCTRL_BALLOONLOWERLIMIT,
     
    349318            HRESULT rc;
    350319
    351             /* Open a session for the VM. */
    352             CHECK_ERROR(pMachine->machine, LockMachine(g_pSession, LockType_Shared));
    353 
    354             do
     320            if (!g_fDryrun)
    355321            {
    356                 /* Get the associated console. */
    357                 ComPtr<IConsole> console;
    358                 CHECK_ERROR_BREAK(g_pSession, COMGETTER(Console)(console.asOutParam()));
    359 
    360                 ComPtr <IGuest> guest;
    361                 rc = console->COMGETTER(Guest)(guest.asOutParam());
    362                 if (SUCCEEDED(rc))
    363                     CHECK_ERROR_BREAK(guest, COMSETTER(MemoryBalloonSize)(lBalloonCur));
    364                 else
    365                     serviceLog("Error: Unable to set new balloon size %ld for machine \"%ls\", rc=%Rhrc",
    366                                lBalloonCur, strUuid.raw(), rc);
    367             } while (0);
    368 
    369             /* Unlock the machine again. */
    370             g_pSession->UnlockMachine();
     322                /* Open a session for the VM. */
     323                CHECK_ERROR(pMachine->machine, LockMachine(g_pSession, LockType_Shared));
     324
     325                do
     326                {
     327                    /* Get the associated console. */
     328                    ComPtr<IConsole> console;
     329                    CHECK_ERROR_BREAK(g_pSession, COMGETTER(Console)(console.asOutParam()));
     330
     331                    ComPtr <IGuest> guest;
     332                    rc = console->COMGETTER(Guest)(guest.asOutParam());
     333                    if (SUCCEEDED(rc))
     334                        CHECK_ERROR_BREAK(guest, COMSETTER(MemoryBalloonSize)(lBalloonCur));
     335                    else
     336                        serviceLog("Error: Unable to set new balloon size %ld for machine \"%ls\", rc=%Rhrc",
     337                                   lBalloonCur, strUuid.raw(), rc);
     338                } while (0);
     339
     340                /* Unlock the machine again. */
     341                g_pSession->UnlockMachine();
     342            }
    371343        }
    372344    }
  • trunk/src/VBox/Frontends/VBoxBalloonCtrl/VBoxWatchdog.cpp

    r39988 r40010  
    5454
    5555
     56#include <algorithm>
    5657#include <string>
    5758#include <signal.h>
     
    6162using namespace com;
    6263
    63 /* When defined, use a global performance collector instead
    64  * of a per-machine based one. */
    65 #define VBOX_WATCHDOG_GLOBAL_PERFCOL
    66 
    6764/** External globals. */
     65bool                                g_fDryrun     = false;
    6866bool                                g_fVerbose    = false;
    6967ComPtr<IVirtualBox>                 g_pVirtualBox = NULL;
    7068ComPtr<ISession>                    g_pSession    = NULL;
    7169mapVM                               g_mapVM;
     70mapGroup                            g_mapGroup;
    7271# ifdef VBOX_WATCHDOG_GLOBAL_PERFCOL
    7372ComPtr<IPerformanceCollector>       g_pPerfCollector = NULL;
     
    107106};
    108107
     108static enum GETOPTDEF_WATCHDOG
     109{
     110    GETOPTDEF_WATCHDOG_DRYRUN = 1000
     111};
     112
    109113/**
    110114 * Command line arguments.
     
    115119#endif
    116120    /** For displayHelp(). */
     121    { "--dryrun",               GETOPTDEF_WATCHDOG_DRYRUN,                 RTGETOPT_REQ_NOTHING },
    117122    { "--help",                 'h',                                       RTGETOPT_REQ_NOTHING },
    118123    { "--verbose",              'v',                                       RTGETOPT_REQ_NOTHING },
     
    124129};
    125130
    126 static unsigned long g_ulTimeoutMS = 500; /* Default is 500ms timeout. */
    127 static unsigned long g_ulMemoryBalloonIncrementMB = 256;
    128 static unsigned long g_ulMemoryBalloonDecrementMB = 128;
    129 /** Global balloon limit is 0, so disabled. Can be overridden by a per-VM
    130  *  "VBoxInternal/Guest/BalloonSizeMax" value. */
    131 static unsigned long g_ulMemoryBalloonMaxMB = 0;
    132 static unsigned long g_ulLowerMemoryLimitMB = 64;
    133 
    134131/** Global static objects. */
    135132static ComPtr<IVirtualBoxClient> g_pVirtualBoxClient = NULL;
    136 static ComPtr<IEventSource> g_pEventSource = NULL;
    137 static ComPtr<IEventSource> g_pEventSourceClient = NULL;
    138 static ComPtr<IEventListener> g_pVBoxEventListener = NULL;
    139 static EventQueue *g_pEventQ = NULL;
     133static ComPtr<IEventSource>      g_pEventSource = NULL;
     134static ComPtr<IEventSource>      g_pEventSourceClient = NULL;
     135static ComPtr<IEventListener>    g_pVBoxEventListener = NULL;
     136static EventQueue               *g_pEventQ = NULL;
    140137
    141138/* Prototypes. */
    142139static int machineAdd(const Bstr &strUuid);
    143140static int machineRemove(const Bstr &strUuid);
    144 //static int machineUpdate(const Bstr &strUuid, MachineState_T enmState);
    145141static HRESULT watchdogSetup();
    146142static void watchdogShutdown();
     
    345341    HRESULT rc;
    346342
     343    /** @todo Add exception handling! */
     344
    347345    do
    348346    {
    349347        ComPtr <IMachine> machine;
    350348        CHECK_ERROR_BREAK(g_pVirtualBox, FindMachine(strUuid.raw(), machine.asOutParam()));
    351 
    352         MachineState_T machineState;
    353         CHECK_ERROR_BREAK(machine, COMGETTER(State)(&machineState));
    354 
    355         VBOXWATCHDOG_MACHINE m;
    356         m.machine = machine;
     349        Assert(!machine.isNull());
     350
     351        Bstr strGroup;
     352        CHECK_ERROR_BREAK(machine, GetExtraData(Bstr("VBoxInternal2/VMGroup").raw(),
     353                                                strGroup.asOutParam()));
    357354
    358355        /*
    359356         * Add machine to map.
    360357         */
     358        VBOXWATCHDOG_MACHINE m;
     359        m.machine = machine;
     360        m.group = strGroup;
     361
    361362        mapVMIter it = g_mapVM.find(strUuid);
    362363        Assert(it == g_mapVM.end());
    363364        g_mapVM.insert(std::make_pair(strUuid, m));
    364 
    365365        serviceLogVerbose(("Added machine \"%ls\"\n", strUuid.raw()));
    366366
    367         /* Let all modules know. */
     367        /*
     368         * Get the machine's VM group(s).
     369         */
     370        if (!strGroup.isEmpty())
     371        {
     372            serviceLogVerbose(("Machine \"%ls\" is in VM group \"%ls\"\n",
     373                               strUuid.raw(), strGroup.raw()));
     374
     375            /** @todo Support more than one group! */
     376            /* Add machine to group(s). */
     377            mapGroupIter itGroup = g_mapGroup.find(strGroup);
     378            if (itGroup == g_mapGroup.end())
     379            {
     380                vecGroupMembers vecMembers;
     381                vecMembers.push_back(strUuid);
     382                g_mapGroup.insert(std::make_pair(strGroup, vecMembers));
     383
     384                itGroup = g_mapGroup.find(strGroup);
     385                Assert(itGroup != g_mapGroup.end());
     386            }
     387            else
     388                itGroup->second.push_back(strUuid);
     389            serviceLogVerbose(("Group \"%ls\" now has %ld machine(s)\n",
     390                               strGroup.raw(), itGroup->second.size()));
     391        }
     392        else
     393            serviceLogVerbose(("Machine \"%ls\" has no VM group assigned\n",
     394                               strUuid.raw()));
     395
     396        /*
     397         * Let all modules know. Typically all modules would register
     398         * their per-machine payload here.
     399         */
    368400        for (unsigned j = 0; j < RT_ELEMENTS(g_aModules); j++)
    369401            if (g_aModules[j].fEnabled)
     
    399431        }
    400432
    401     mapVMIter it = g_mapVM.find(strUuid);
    402     Assert(it != g_mapVM.end());
    403 
    404 #ifndef VBOX_WATCHDOG_GLOBAL_PERFCOL
    405     it->second.collector.setNull();
    406 #endif
    407     it->second.machine.setNull();
    408 
    409433    /* Must log before erasing the iterator because of the UUID ref! */
    410434    serviceLogVerbose(("Removing machine \"%ls\"\n", strUuid.raw()));
     435
     436    mapVMIter itVM = g_mapVM.find(strUuid);
     437    Assert(itVM != g_mapVM.end());
     438
     439    /* Remove machine from group(s). */
     440    /** @todo Add support for multiple groups! */
     441    Bstr strGroup = itVM->second.group;
     442    if (!strGroup.isEmpty())
     443    {
     444        mapGroupIter itGroup = g_mapGroup.find(strGroup);
     445        Assert(itGroup != g_mapGroup.end());
     446
     447        vecGroupMembers vecMembers = itGroup->second;
     448        vecGroupMembersIter itMember = std::find(vecMembers.begin(),
     449                                                 vecMembers.end(),
     450                                                 strUuid);
     451        Assert(itMember != vecMembers.end());
     452        vecMembers.erase(itMember);
     453
     454        serviceLogVerbose(("Group \"%ls\" has %ld machines left\n",
     455                           itGroup->first, vecMembers.size()));
     456        if (!vecMembers.size())
     457            g_mapGroup.erase(itGroup);
     458    }
     459
     460#ifndef VBOX_WATCHDOG_GLOBAL_PERFCOL
     461    itVM->second.collector.setNull();
     462#endif
     463    itVM->second.machine.setNull();
    411464
    412465    /*
    413466     * Remove machine from map.
    414467     */
    415     g_mapVM.erase(it);
     468    g_mapVM.erase(itVM);
    416469
    417470    return rc;
     
    440493                rc = rc2;
    441494        }
    442 
    443495    }
    444496    else
     
    671723                        if (RT_FAILURE(rc2))
    672724                            serviceLog("Module '%s' reported an error: %Rrc\n",
    673                                        g_aModules[j].pDesc->pszName, rc);
     725                                       g_aModules[j].pDesc->pszName, rc2);
    674726                        /* Keep going. */
    675727                    }
     
    685737             * processes NULL events signalling event loop termination.
    686738             */
    687             g_pEventQ->processEventQueue(g_ulTimeoutMS / 10);
     739            g_pEventQ->processEventQueue(500 / 10);
    688740
    689741            if (g_fCanceled)
     
    848900        switch (g_aOptions[i].iShort)
    849901        {
     902            case GETOPTDEF_WATCHDOG_DRYRUN:
     903                pcszDescr = "Dryrun mode -- do not perform any actions.";
     904                break;
     905
    850906            case 'h':
    851907                pcszDescr = "Print this help message and exit.";
     
    9841040        switch (c)
    9851041        {
     1042            case GETOPTDEF_WATCHDOG_DRYRUN:
     1043                g_fDryrun = true;
     1044                break;
     1045
    9861046            case 'h':
    9871047                displayHelp(argv[0]);
     
    10301090                {
    10311091                    rc = watchdogLazyPreInit();
    1032                     if (RT_SUCCESS(rc))
     1092                    if (RT_FAILURE(rc))
    10331093                        return RTEXITCODE_FAILURE;
    10341094
     
    11431203    }
    11441204
     1205    if (g_fDryrun)
     1206        serviceLog("Running in dryrun mode\n");
     1207
    11451208    hrc = watchdogSetup();
    11461209    if (FAILED(hrc))
  • trunk/src/VBox/Frontends/VBoxBalloonCtrl/VBoxWatchdogInternal.h

    r39986 r40010  
    2020
    2121#ifndef VBOX_ONLY_DOCS
    22 #include <VBox/com/com.h>
    23 #include <VBox/com/assert.h>
    24 #include <VBox/com/string.h>
    25 #include <VBox/com/VirtualBox.h>
    26 
    27 #include <iprt/getopt.h>
    28 #include <iprt/time.h>
     22# include <iprt/getopt.h>
     23# include <iprt/time.h>
     24
     25# include <VBox/err.h>
     26# include <VBox/com/com.h>
     27# include <VBox/com/string.h>
     28# include <VBox/com/Guid.h>
     29# include <VBox/com/array.h>
     30# include <VBox/com/ErrorInfo.h>
     31# include <VBox/com/VirtualBox.h>
    2932#endif /* !VBOX_ONLY_DOCS */
    3033
     
    8184    ComPtr<IPerformanceCollector> collector;
    8285#endif
     86    /** The machine's VM group(s). */
     87    Bstr group;
    8388    /** Map containing the individual
    8489     *  module payloads. */
     
    8994typedef std::map<Bstr, VBOXWATCHDOG_MACHINE>::const_iterator mapVMIterConst;
    9095
    91 /** A VM group entry. Note that a machine can belong
    92  *  to more than one group. */
    93 typedef struct VBOXWATCHDOG_VM_GROUP
    94 {
    95     /** UUIDs of machines belonging to this group. */
    96     std::vector<Bstr> machine;
    97 } VBOXWATCHDOG_VM_GROUP;
    98 typedef std::map<Bstr, VBOXWATCHDOG_VM_GROUP> mapGroup;
    99 typedef std::map<Bstr, VBOXWATCHDOG_VM_GROUP>::iterator mapGroupIter;
    100 typedef std::map<Bstr, VBOXWATCHDOG_VM_GROUP>::const_iterator mapGroupIterConst;
     96/** Members of a VM group; currently only represented by the machine's UUID. */
     97typedef std::vector<Bstr> vecGroupMembers;
     98typedef std::vector<Bstr>::iterator vecGroupMembersIter;
     99typedef std::vector<Bstr>::const_iterator vecGroupMembersIterConst;
     100
     101/** A VM group. Can contain none, one or more group members. */
     102typedef std::map<Bstr, vecGroupMembers> mapGroup;
     103typedef std::map<Bstr, vecGroupMembers>::iterator mapGroupIter;
     104typedef std::map<Bstr, vecGroupMembers>::const_iterator mapGroupIterConst;
    101105
    102106/**
     
    195199RT_C_DECLS_BEGIN
    196200
    197 extern bool g_fVerbose;
     201extern bool                             g_fDryrun;
     202extern bool                             g_fVerbose;
    198203extern ComPtr<IVirtualBox>              g_pVirtualBox;
    199204extern ComPtr<ISession>                 g_pSession;
    200205extern mapVM                            g_mapVM;
     206extern mapGroup                         g_mapGroup;
    201207# ifdef VBOX_WATCHDOG_GLOBAL_PERFCOL
    202208extern ComPtr<IPerformanceCollector>    g_pPerfCollector;
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