VirtualBox

Changeset 39986 in vbox for trunk/src/VBox


Ignore:
Timestamp:
Feb 3, 2012 2:21:28 PM (13 years ago)
Author:
vboxsync
Message:

VBoxBalloonCtrl: Update.

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

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Frontends/VBoxBalloonCtrl/Makefile.kmk

    r39929 r39986  
    2222 VBoxBalloonCtrl_TEMPLATE   = VBOXMAINCLIENTEXE
    2323 VBoxBalloonCtrl_DEFS      += \
    24         VBOX_BUILD_TARGET=\"$(KBUILD_TARGET).$(KBUILD_TARGET_ARCH)\"
     24        VBOX_WATCHDOG_GLOBAL_PERFCOL VBOX_BUILD_TARGET=\"$(KBUILD_TARGET).$(KBUILD_TARGET_ARCH)\"
    2525 VBoxBalloonCtrl_DEFS.win   = _WIN32_WINNT=0x0500
    2626 VBoxBalloonCtrl_SOURCES    = \
  • trunk/src/VBox/Frontends/VBoxBalloonCtrl/VBoxModAPIMonitor.cpp

    r39936 r39986  
     1
     2/* $Id$ */
     3/** @file
     4 * VBoxModAPIMonitor - API monitor module for detecting host isolation.
     5 */
     6
     7/*
     8 * Copyright (C) 2012 Oracle Corporation
     9 *
     10 * This file is part of VirtualBox Open Source Edition (OSE), as
     11 * available from http://www.virtualbox.org. This file is free software;
     12 * you can redistribute it and/or modify it under the terms of the GNU
     13 * General Public License (GPL) as published by the Free Software
     14 * Foundation, in version 2 as it comes in the "COPYING" file of the
     15 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
     16 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
     17 */
     18
     19
     20/*******************************************************************************
     21*   Header Files                                                               *
     22*******************************************************************************/
     23#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>
     29# include <VBox/com/errorprint.h>
     30
     31# include <VBox/com/EventQueue.h>
     32# include <VBox/com/listeners.h>
     33# include <VBox/com/VirtualBox.h>
     34#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>
     57
     58#include "VBoxWatchdogInternal.h"
     59
     60using namespace com;
     61
     62#define VBOX_MOD_APIMONITOR_NAME "apimonitor"
     63
     64/**
     65 * The module's RTGetOpt-IDs for the command line.
     66 */
     67enum GETOPTDEF_APIMONITOR
     68{
     69    GETOPTDEF_APIMONITOR_GROUPS = 1000,
     70};
     71
     72/**
     73 * The module's command line arguments.
     74 */
     75static const RTGETOPTDEF g_aAPIMonitorOpts[] = {
     76    { "--apimonitor-groups",         GETOPTDEF_APIMONITOR_GROUPS,         RTGETOPT_REQ_STRING }
     77};
     78
     79/* Callbacks. */
     80static DECLCALLBACK(int) VBoxModAPIMonitorPreInit(void)
     81{
     82    return VINF_SUCCESS;
     83}
     84
     85static DECLCALLBACK(int) VBoxModAPIMonitorOption(int argc, char **argv)
     86{
     87    if (!argc) /* Take a shortcut. */
     88        return -1;
     89
     90    AssertPtrReturn(argv, VERR_INVALID_PARAMETER);
     91
     92    RTGETOPTSTATE GetState;
     93    int rc = RTGetOptInit(&GetState, argc, argv,
     94                          g_aAPIMonitorOpts, RT_ELEMENTS(g_aAPIMonitorOpts),
     95                          0 /* First */, 0 /*fFlags*/);
     96    if (RT_FAILURE(rc))
     97        return rc;
     98
     99    rc = 0; /* Set default parsing result to valid. */
     100
     101    int c;
     102    RTGETOPTUNION ValueUnion;
     103    while ((c = RTGetOpt(&GetState, &ValueUnion)))
     104    {
     105        switch (c)
     106        {
     107            case GETOPTDEF_APIMONITOR_GROUPS:
     108                break;
     109
     110            default:
     111                rc = -1; /* We don't handle this option, skip. */
     112                break;
     113        }
     114    }
     115
     116    return rc;
     117}
     118
     119static DECLCALLBACK(int) VBoxModAPIMonitorInit(void)
     120{
     121    return VINF_SUCCESS; /* Nothing to do here right now. */
     122}
     123
     124static DECLCALLBACK(int) VBoxModAPIMonitorMain(void)
     125{
     126    return VINF_SUCCESS; /* Nothing to do here right now. */
     127}
     128
     129static DECLCALLBACK(int) VBoxModAPIMonitorStop(void)
     130{
     131    return VINF_SUCCESS;
     132}
     133
     134static DECLCALLBACK(void) VBoxModAPIMonitorTerm(void)
     135{
     136}
     137
     138static DECLCALLBACK(int) VBoxModAPIMonitorOnMachineRegistered(const Bstr &strUuid)
     139{
     140    return VINF_SUCCESS;
     141}
     142
     143static DECLCALLBACK(int) VBoxModAPIMonitorOnMachineUnregistered(const Bstr &strUuid)
     144{
     145    return VINF_SUCCESS;
     146}
     147
     148static DECLCALLBACK(int) VBoxModAPIMonitorOnMachineStateChanged(const Bstr &strUuid,
     149                                                                MachineState_T enmState)
     150{
     151    return VINF_SUCCESS;
     152}
     153
     154static DECLCALLBACK(int) VBoxModAPIMonitorOnServiceStateChanged(bool fAvailable)
     155{
     156    return VINF_SUCCESS;
     157}
     158
     159/**
     160 * The 'apimonitor' module description.
     161 */
     162VBOXMODULE g_ModAPIMonitor =
     163{
     164    /* pszName. */
     165    VBOX_MOD_APIMONITOR_NAME,
     166    /* pszDescription. */
     167    "API monitor for host isolation detection",
     168    /* pszDepends. */
     169    NULL,
     170    /* uPriority. */
     171    0 /* Not used */,
     172    /* pszUsage. */
     173    " [--apimonitor-groups <string>]\n"
     174    ,
     175    /* pszOptions. */
     176    "--apimonitor-groups    Sets the VM groups for monitoring (none).\n",
     177    /* methods. */
     178    VBoxModAPIMonitorPreInit,
     179    VBoxModAPIMonitorOption,
     180    VBoxModAPIMonitorInit,
     181    VBoxModAPIMonitorMain,
     182    VBoxModAPIMonitorStop,
     183    VBoxModAPIMonitorTerm,
     184    /* callbacks. */
     185    VBoxModAPIMonitorOnMachineRegistered,
     186    VBoxModAPIMonitorOnMachineUnregistered,
     187    VBoxModAPIMonitorOnMachineStateChanged,
     188    VBoxModAPIMonitorOnServiceStateChanged
     189};
     190
  • trunk/src/VBox/Frontends/VBoxBalloonCtrl/VBoxModBallooning.cpp

    r39943 r39986  
    199199
    200200/**
     201 * Indicates whether ballooning on the specified machine state is
     202 * possible -- this only is true if the machine is up and running.
     203 *
     204 * @return  bool            Flag indicating whether the VM is running or not.
     205 * @param   enmState        The VM's machine state to judge whether it's running or not.
     206 */
     207static bool balloonIsPossible(MachineState_T enmState)
     208{
     209    switch (enmState)
     210    {
     211        case MachineState_Running:
     212#if 0
     213        /* Not required for ballooning. */
     214        case MachineState_Teleporting:
     215        case MachineState_LiveSnapshotting:
     216        case MachineState_Paused:
     217        case MachineState_TeleportingPausedVM:
     218#endif
     219            return true;
     220        default:
     221            break;
     222    }
     223    return false;
     224}
     225
     226/**
    201227 * Determines whether ballooning is required to the specified machine.
    202228 *
     
    207233{
    208234    AssertPtrReturn(pMachine, false);
    209 
    210     /** @todo Add grouping! */
    211235
    212236    /* Only do ballooning if we have a maximum balloon size set. */
     
    217241                              ? 0 : balloonGetMaxSize(pMachine->machine);
    218242
     243    /** @todo Add grouping as a criteria! */
     244
    219245    return pData->ulBalloonSizeMax ? true : false;
     246}
     247
     248int balloonMachineSetup(const Bstr& strUuid)
     249{
     250    int vrc = VINF_SUCCESS;
     251
     252    do
     253    {
     254        PVBOXWATCHDOG_MACHINE pMachine = getMachine(strUuid);
     255        AssertPtrBreakStmt(pMachine, vrc=VERR_INVALID_PARAMETER);
     256
     257        ComPtr<IMachine> m = pMachine->machine;
     258
     259        /*
     260         * Setup metrics required for ballooning.
     261         */
     262        com::SafeArray<BSTR> metricNames(1);
     263        com::SafeIfaceArray<IUnknown> metricObjects(1);
     264        com::SafeIfaceArray<IPerformanceMetric> metricAffected;
     265
     266        Bstr strMetricNames(L"Guest/RAM/Usage");
     267        strMetricNames.cloneTo(&metricNames[0]);
     268
     269        HRESULT rc = m.queryInterfaceTo(&metricObjects[0]);
     270
     271#ifdef VBOX_WATCHDOG_GLOBAL_PERFCOL
     272        CHECK_ERROR_BREAK(g_pPerfCollector, SetupMetrics(ComSafeArrayAsInParam(metricNames),
     273                                                         ComSafeArrayAsInParam(metricObjects),
     274                                                         5 /* 5 seconds */,
     275                                                         1 /* One sample is enough */,
     276                                                         ComSafeArrayAsOutParam(metricAffected)));
     277#else
     278        ComPtr<IPerformanceCollector> coll = pMachine->collector;
     279
     280        CHECK_ERROR_BREAK(g_pVirtualBox, COMGETTER(PerformanceCollector)(coll.asOutParam()));
     281        CHECK_ERROR_BREAK(coll, SetupMetrics(ComSafeArrayAsInParam(metricNames),
     282                                             ComSafeArrayAsInParam(metricObjects),
     283                                             5 /* 5 seconds */,
     284                                             1 /* One sample is enough */,
     285                                             ComSafeArrayAsOutParam(metricAffected)));
     286#endif
     287        if (FAILED(rc))
     288            vrc = VERR_COM_IPRT_ERROR; /* @todo Find better rc! */
     289
     290    } while (0);
     291
     292    return vrc;
    220293}
    221294
     
    228301 * @param   pMachine                Pointer to the machine's internal structure.
    229302 */
    230 static int balloonUpdate(const Bstr &strUuid, PVBOXWATCHDOG_MACHINE pMachine)
     303static int balloonMachineUpdate(const Bstr &strUuid, PVBOXWATCHDOG_MACHINE pMachine)
    231304{
    232305    AssertPtrReturn(pMachine, VERR_INVALID_POINTER);
     
    304377}
    305378
     379/* Callbacks. */
    306380static DECLCALLBACK(int) VBoxModBallooningPreInit(void)
    307381{
    308     int rc = -1;
    309     /* Not yet implemented. */
    310     return rc;
     382    return VINF_SUCCESS;
    311383}
    312384
     
    373445static DECLCALLBACK(int) VBoxModBallooningInit(void)
    374446{
    375     int rc = -1;
    376     /* Not yet implemented. */
    377     return rc;
     447    return VINF_SUCCESS; /* Nothing to do here right now. */
    378448}
    379449
     
    385455        return VINF_SUCCESS;
    386456    uLast = uNow;
    387 #if 0
    388     int rc = RTCritSectEnter(&g_MapCritSect);
     457
     458    int rc = VINF_SUCCESS;
     459
     460    /** @todo Provide API for enumerating/working w/ machines inside a module! */
     461    mapVMIter it = g_mapVM.begin();
     462    while (it != g_mapVM.end())
     463    {
     464        MachineState_T state = getMachineState(&it->second);
     465
     466        /* Our actual ballooning criteria. */
     467        if (   balloonIsPossible(state)
     468            && balloonIsRequired(&it->second))
     469        {
     470            rc = balloonMachineUpdate(it->first /* UUID */,
     471                                      &it->second /* Machine */);
     472            AssertRC(rc);
     473        }
     474        if (RT_FAILURE(rc))
     475            break;
     476
     477        it++;
     478    }
     479
     480    return rc;
     481}
     482
     483static DECLCALLBACK(int) VBoxModBallooningStop(void)
     484{
     485    return VINF_SUCCESS;
     486}
     487
     488static DECLCALLBACK(void) VBoxModBallooningTerm(void)
     489{
     490}
     491
     492static DECLCALLBACK(int) VBoxModBallooningOnMachineRegistered(const Bstr &strUuid)
     493{
     494    PVBOXWATCHDOG_MACHINE pMachine = getMachine(strUuid);
     495    AssertPtrReturn(pMachine, VERR_INVALID_PARAMETER);
     496
     497    PVBOXWATCHDOG_BALLOONCTRL_PAYLOAD pData;
     498    int rc = payloadAlloc(pMachine, VBOX_MOD_BALLOONING_NAME,
     499                          sizeof(VBOXWATCHDOG_BALLOONCTRL_PAYLOAD), (void**)&pData);
    389500    if (RT_SUCCESS(rc))
    390     {
    391         mapVMIter it = g_mapVM.begin();
    392         while (it != g_mapVM.end())
    393         {
    394             MachineState_T machineState;
    395             HRESULT hrc = it->second.machine->COMGETTER(State)(&machineState);
    396             if (SUCCEEDED(hrc))
    397             {
    398                 rc = machineUpdate(it->first /* UUID */, machineState);
    399                 if (RT_FAILURE(rc))
    400                     break;
    401             }
    402             it++;
    403         }
    404 
    405         int rc2 = RTCritSectLeave(&g_MapCritSect);
    406         if (RT_SUCCESS(rc))
    407             rc = rc2;
    408     }
     501        rc = balloonMachineUpdate(strUuid, pMachine);
    409502
    410503    return rc;
    411 #endif
    412     return 0;
    413 }
    414 
    415 static DECLCALLBACK(int) VBoxModBallooningStop(void)
    416 {
    417     return 0;
    418 }
    419 
    420 static DECLCALLBACK(void) VBoxModBallooningTerm(void)
    421 {
    422 }
    423 
    424 static DECLCALLBACK(int) VBoxModBallooningOnMachineRegistered(const Bstr &strUuid)
    425 {
    426     return 0;
    427504}
    428505
    429506static DECLCALLBACK(int) VBoxModBallooningOnMachineUnregistered(const Bstr &strUuid)
    430507{
    431     return 0;
     508    PVBOXWATCHDOG_MACHINE pMachine = getMachine(strUuid);
     509    AssertPtrReturn(pMachine, VERR_INVALID_PARAMETER);
     510
     511    payloadFree(pMachine, VBOX_MOD_BALLOONING_NAME);
     512
     513    return VINF_SUCCESS;
    432514}
    433515
     
    435517                                                                MachineState_T enmState)
    436518{
    437     return 0;
     519    PVBOXWATCHDOG_MACHINE pMachine = getMachine(strUuid);
     520    AssertPtrReturn(pMachine, VERR_INVALID_PARAMETER);
     521
     522    return balloonMachineUpdate(strUuid, pMachine);
    438523}
    439524
    440525static DECLCALLBACK(int) VBoxModBallooningOnServiceStateChanged(bool fAvailable)
    441526{
    442     return 0;
     527    return VINF_SUCCESS;
    443528}
    444529
     
    457542    0 /* Not used */,
    458543    /* pszUsage. */
    459     "              [--balloon-dec <MB>] [--balloon-inc <MB>]\n"
    460     "              [--balloon-interval <ms>] [--balloon-lower-limit <MB>]\n"
    461     "              [--balloon-max <MB>]",
     544    " [--balloon-dec <MB>] [--balloon-groups <string>] [--balloon-inc <MB>]\n"
     545    " [--balloon-interval <ms>] [--balloon-lower-limit <MB>]\n"
     546    " [--balloon-max <MB>]\n",
    462547    /* pszOptions. */
    463548    "--balloon-dec          Sets the ballooning decrement in MB (128 MB).\n"
    464     "--balloon-groups       Sets the VM groups for ballooning (All).\n"
     549    "--balloon-groups       Sets the VM groups for ballooning (all).\n"
    465550    "--balloon-inc          Sets the ballooning increment in MB (256 MB).\n"
    466551    "--balloon-interval     Sets the check interval in ms (30 seconds).\n"
  • trunk/src/VBox/Frontends/VBoxBalloonCtrl/VBoxWatchdog.cpp

    r39942 r39986  
    6666
    6767/** External globals. */
    68 bool                 g_fVerbose    = false;
    69 ComPtr<IVirtualBox>  g_pVirtualBox = NULL;
    70 ComPtr<ISession>     g_pSession    = NULL;
     68bool                                g_fVerbose    = false;
     69ComPtr<IVirtualBox>                 g_pVirtualBox = NULL;
     70ComPtr<ISession>                    g_pSession    = NULL;
     71mapVM                               g_mapVM;
     72# ifdef VBOX_WATCHDOG_GLOBAL_PERFCOL
     73ComPtr<IPerformanceCollector>       g_pPerfCollector = NULL;
     74# endif
    7175
    7276/** The critical section for the machines map. */
     
    99103} g_aModules[] =
    100104{
    101     { &g_ModBallooning, false /* Pre-inited */, true /* Enabled */ }
     105    { &g_ModBallooning, false /* Pre-inited */, true /* Enabled */ },
     106    { &g_ModAPIMonitor, false /* Pre-inited */, true /* Enabled */ }
    102107};
    103108
     
    119124};
    120125
    121 static unsigned long g_ulTimeoutMS = 30 * 1000; /* Default is 30 seconds timeout. */
     126static unsigned long g_ulTimeoutMS = 500; /* Default is 500ms timeout. */
    122127static unsigned long g_ulMemoryBalloonIncrementMB = 256;
    123128static unsigned long g_ulMemoryBalloonDecrementMB = 128;
     
    132137static ComPtr<IEventSource> g_pEventSourceClient = NULL;
    133138static ComPtr<IEventListener> g_pVBoxEventListener = NULL;
    134 # ifdef VBOX_WATCHDOG_GLOBAL_PERFCOL
    135 static ComPtr<IPerformanceCollector> g_pPerfCollector = NULL;
    136 # endif
    137139static EventQueue *g_pEventQ = NULL;
    138 static mapVM g_mapVM;
    139140
    140141/* Prototypes. */
    141 static bool machineIsRunning(MachineState_T enmState);
    142 static bool machineHandled(const Bstr &strUuid);
    143142static int machineAdd(const Bstr &strUuid);
    144143static int machineRemove(const Bstr &strUuid);
    145144//static int machineUpdate(const Bstr &strUuid, MachineState_T enmState);
    146145static HRESULT watchdogSetup();
    147 static void watchdogTeardown();
     146static void watchdogShutdown();
    148147
    149148#ifdef RT_OS_WINDOWS
     
    195194                        if (RT_SUCCESS(rc))
    196195                        {
    197                             for (unsigned j = 0; j < RT_ELEMENTS(g_aModules); j++)
    198                                 if (g_aModules[j].fEnabled)
    199                                 {
    200                                     int rc2 = fRegistered
    201                                             ? g_aModules[j].pDesc->pfnOnMachineRegistered(uuid)
    202                                             : g_aModules[j].pDesc->pfnOnMachineUnregistered(uuid);
    203                                     if (RT_FAILURE(rc2))
    204                                         serviceLog("Module '%s' reported an error: %Rrc\n",
    205                                                    g_aModules[j].pDesc->pszName, rc);
    206                                     /* Keep going. */
    207                                 }
    208 
    209                             #if 0
    210                             if (fRegistered && machineHandled(uuid))
    211                                 rc = machineAdd(uuid);
    212                             else if (!fRegistered)
    213                                  rc = machineRemove(uuid);
    214                             #endif
     196                            rc = fRegistered
     197                               ? machineAdd(uuid)
     198                               : machineRemove(uuid);
    215199                            int rc2 = RTCritSectLeave(&g_csMachines);
    216200                            if (RT_SUCCESS(rc))
     
    250234                                }
    251235
    252                             //rc = machineUpdate(uuid, machineState);
    253236                            int rc2 = RTCritSectLeave(&g_csMachines);
    254237                            if (RT_SUCCESS(rc))
     
    282265                    {
    283266                        serviceLog("VBoxSVC became unavailable\n");
    284                         watchdogTeardown();
     267                        watchdogShutdown();
    285268                    }
    286269                    else
     
    352335
    353336/**
    354  * Indicates whether a VM is up and running (regardless of its running
    355  * state, could be paused as well).
    356  *
    357  * @return  bool            Flag indicating whether the VM is running or not.
    358  * @param   enmState        The VM's machine state to judge whether it's running or not.
    359  */
    360 static bool machineIsRunning(MachineState_T enmState)
    361 {
    362     switch (enmState)
    363     {
    364         case MachineState_Running:
    365 #if 0
    366         /* Not required for ballooning. */
    367         case MachineState_Teleporting:
    368         case MachineState_LiveSnapshotting:
    369         case MachineState_Paused:
    370         case MachineState_TeleportingPausedVM:
    371 #endif
    372             return true;
    373         default:
    374             break;
    375     }
    376     return false;
    377 }
    378 
    379 /**
    380  * Determines whether the specified machine needs to be handled
    381  * by this service.
    382  *
    383  * @return  bool                    True if the machine needs handling, false if not.
    384  * @param   strUuid                 UUID of the specified machine.
    385  */
    386 static bool machineHandled(const Bstr &strUuid)
    387 {
    388     bool fHandled = false;
    389 
    390     do
    391     {
    392         HRESULT rc;
    393 
    394         ComPtr <IMachine> machine;
    395         CHECK_ERROR_BREAK(g_pVirtualBox, FindMachine(strUuid.raw(), machine.asOutParam()));
    396 
    397         MachineState_T machineState;
    398         CHECK_ERROR_BREAK(machine, COMGETTER(State)(&machineState));
    399 
    400     #if 0
    401         if (   balloonGetMaxSize(machine)
    402             && machineIsRunning(machineState))
    403         {
    404             serviceLogVerbose(("Handling machine \"%ls\"\n", strUuid.raw()));
    405             fHandled = true;
    406         }
    407     #endif
    408     }
    409     while (0);
    410 
    411     return fHandled;
    412 }
    413 
    414 /**
    415337 * Adds a specified machine to the list (map) of handled machines.
    416338 * Does not do locking -- needs to be done by caller!
     
    431353        CHECK_ERROR_BREAK(machine, COMGETTER(State)(&machineState));
    432354
    433     #if 0
    434         if (   !balloonGetMaxSize(machine)
    435             || !machineIsRunning(machineState))
    436         {
    437             /* This machine does not need to be added, just skip it! */
    438             break;
    439         }
    440     #endif
    441 
    442355        VBOXWATCHDOG_MACHINE m;
    443356        m.machine = machine;
    444 
    445 ////// TODO: Put this in module!
    446 
    447         /*
    448          * Setup metrics.
    449          */
    450         com::SafeArray<BSTR> metricNames(1);
    451         com::SafeIfaceArray<IUnknown> metricObjects(1);
    452         com::SafeIfaceArray<IPerformanceMetric> metricAffected;
    453 
    454         Bstr strMetricNames(L"Guest/RAM/Usage");
    455         strMetricNames.cloneTo(&metricNames[0]);
    456 
    457         m.machine.queryInterfaceTo(&metricObjects[0]);
    458 
    459 #ifdef VBOX_WATCHDOG_GLOBAL_PERFCOL
    460         CHECK_ERROR_BREAK(g_pPerfCollector, SetupMetrics(ComSafeArrayAsInParam(metricNames),
    461                                                          ComSafeArrayAsInParam(metricObjects),
    462                                                          5 /* 5 seconds */,
    463                                                          1 /* One sample is enough */,
    464                                                          ComSafeArrayAsOutParam(metricAffected)));
    465 #else
    466         CHECK_ERROR_BREAK(g_pVirtualBox, COMGETTER(PerformanceCollector)(m.collector.asOutParam()));
    467         CHECK_ERROR_BREAK(m.collector, SetupMetrics(ComSafeArrayAsInParam(metricNames),
    468                                                     ComSafeArrayAsInParam(metricObjects),
    469                                                     5 /* 5 seconds */,
    470                                                     1 /* One sample is enough */,
    471                                                     ComSafeArrayAsOutParam(metricAffected)));
    472 #endif
    473 
    474 ///////////////// TODO END
    475357
    476358        /*
     
    479361        mapVMIter it = g_mapVM.find(strUuid);
    480362        Assert(it == g_mapVM.end());
    481 
    482         /* Register all module payloads. */
     363        g_mapVM.insert(std::make_pair(strUuid, m));
     364
     365        serviceLogVerbose(("Added machine \"%ls\"\n", strUuid.raw()));
     366
     367        /* Let all modules know. */
    483368        for (unsigned j = 0; j < RT_ELEMENTS(g_aModules); j++)
    484         {
    485             if (g_aModules[j].pDesc->pszOptions)
    486                 RTPrintf("%s", g_aModules[j].pDesc->pszOptions);
    487         }
    488 
    489         g_mapVM.insert(std::make_pair(strUuid, m));
    490 
    491         serviceLogVerbose(("Added machine \"%ls\"\n", strUuid.raw()));
     369            if (g_aModules[j].fEnabled)
     370            {
     371                int rc2 = g_aModules[j].pDesc->pfnOnMachineRegistered(strUuid);
     372                if (RT_FAILURE(rc2))
     373                    serviceLog("OnMachineRegistered: Module '%s' reported an error: %Rrc\n",
     374                               g_aModules[j].pDesc->pszName, rc);
     375                /* Keep going. */
     376            }
    492377
    493378    } while (0);
     
    496381
    497382    return SUCCEEDED(rc) ? VINF_SUCCESS : VERR_COM_IPRT_ERROR; /* @todo Find a better error! */
     383}
     384
     385static int machineDestroy(const Bstr &strUuid)
     386{
     387    AssertReturn(!strUuid.isEmpty(), VERR_INVALID_PARAMETER);
     388    int rc = VINF_SUCCESS;
     389
     390    /* Let all modules know. */
     391    for (unsigned j = 0; j < RT_ELEMENTS(g_aModules); j++)
     392        if (g_aModules[j].fEnabled)
     393        {
     394            int rc2 = g_aModules[j].pDesc->pfnOnMachineUnregistered(strUuid);
     395            if (RT_FAILURE(rc2))
     396                serviceLog("OnMachineUnregistered: Module '%s' reported an error: %Rrc\n",
     397                           g_aModules[j].pDesc->pszName, rc);
     398            /* Keep going. */
     399        }
     400
     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
     409    /* Must log before erasing the iterator because of the UUID ref! */
     410    serviceLogVerbose(("Removing machine \"%ls\"\n", strUuid.raw()));
     411
     412    /*
     413     * Remove machine from map.
     414     */
     415    g_mapVM.erase(it);
     416
     417    return rc;
    498418}
    499419
     
    507427static int machineRemove(const Bstr &strUuid)
    508428{
     429    AssertReturn(!strUuid.isEmpty(), VERR_INVALID_PARAMETER);
    509430    int rc = VINF_SUCCESS;
    510431
     
    512433    if (it != g_mapVM.end())
    513434    {
    514         /* Must log before erasing the iterator because of the UUID ref! */
    515         serviceLogVerbose(("Removing machine \"%ls\"\n", strUuid.raw()));
    516 
    517         /*
    518          * Remove machine from map.
    519          */
    520         g_mapVM.erase(it);
     435        int rc2 = machineDestroy(strUuid);
     436        if (RT_FAILURE(rc))
     437        {
     438            serviceLog(("Machine \"%ls\" failed to destroy, rc=%Rc\n"));
     439            if (RT_SUCCESS(rc))
     440                rc = rc2;
     441        }
     442
    521443    }
    522444    else
     
    529451}
    530452
    531 #if 0
    532 /**
    533  * Updates a specified machine according to its current machine state.
    534  * That currently also could mean that a machine gets removed if it doesn't
    535  * fit in our criteria anymore or a machine gets added if we need to handle
    536  * it now (and didn't before).
    537  * Does not do locking -- needs to be done by caller!
    538  *
    539  * @return  IPRT status code.
    540  * @param   strUuid                 UUID of the specified machine.
    541  * @param   enmState                The machine's current state.
    542  */
    543 static int machineUpdate(const Bstr &strUuid, MachineState_T enmState)
    544 {
    545     int rc = VINF_SUCCESS;
    546 
    547     mapVMIter it = g_mapVM.find(strUuid);
    548     if (it == g_mapVM.end())
    549     {
    550         if (machineHandled(strUuid))
    551         {
    552             rc  = machineAdd(strUuid);
    553             if (RT_SUCCESS(rc))
    554                 it = g_mapVM.find(strUuid);
    555         }
    556         else
    557         {
    558             serviceLogVerbose(("Machine \"%ls\" (state: %u) does not need to be updated\n",
    559                                strUuid.raw(), enmState));
    560         }
    561     }
    562 
    563     if (it != g_mapVM.end())
    564     {
    565         /*
    566          * Ballooning stuff - start.
    567          */
    568 #if 0
    569         /* Our actual ballooning criteria. */
    570         if (   !balloonIsRequired(&it->second)
    571             || !machineIsRunning(enmState))
    572         {
    573             /* Current machine is not suited for ballooning anymore -
    574              * remove it from our map. */
    575             rc = machineRemove(strUuid);
    576         }
    577         else
    578         {
    579             rc = balloonUpdate(strUuid, &it->second);
    580             AssertRC(rc);
    581         }
    582 #endif
    583     }
    584 
    585     /*
    586      * Ballooning stuff - end.
    587      */
    588 
    589     return rc;
    590 }
    591 #endif
    592 
    593453static void vmListDestroy()
    594454{
     
    601461        while (it != g_mapVM.end())
    602462        {
    603 #ifndef VBOX_WATCHDOG_GLOBAL_PERFCOL
    604             it->second.collector.setNull();
    605 #endif
    606             it->second.machine.setNull();
    607             it++;
     463            machineDestroy(it->first);
     464            it = g_mapVM.begin();
    608465        }
    609466
     
    763620        g_pEventQ = com::EventQueue::getMainEventQueue();
    764621
    765         RTCritSectInit(&g_csMachines);
    766 
    767622        /*
    768623         * Install signal handlers.
     
    806661             * Do the actual work.
    807662             */
    808             /*
    809             vrc = balloonCtrlCheck();
    810             if (RT_FAILURE(vrc))
     663
     664            int rc = RTCritSectEnter(&g_csMachines);
     665            if (RT_SUCCESS(rc))
    811666            {
    812                 serviceLog("Error while doing ballooning control; rc=%Rrc\n", vrc);
    813                 break;
    814             }*/
    815             for (unsigned j = 0; j < RT_ELEMENTS(g_aModules); j++)
    816                 if (g_aModules[j].fEnabled)
    817                 {
    818                     int rc2 = g_aModules[j].pDesc->pfnMain();
    819                     if (RT_FAILURE(rc2))
    820                         serviceLog("Module '%s' reported an error: %Rrc\n",
    821                                    g_aModules[j].pDesc->pszName, rc);
    822                     /* Keep going. */
    823                 }
     667                for (unsigned j = 0; j < RT_ELEMENTS(g_aModules); j++)
     668                    if (g_aModules[j].fEnabled)
     669                    {
     670                        int rc2 = g_aModules[j].pDesc->pfnMain();
     671                        if (RT_FAILURE(rc2))
     672                            serviceLog("Module '%s' reported an error: %Rrc\n",
     673                                       g_aModules[j].pDesc->pszName, rc);
     674                        /* Keep going. */
     675                    }
     676
     677                int rc2 = RTCritSectLeave(&g_csMachines);
     678                if (RT_SUCCESS(rc))
     679                    rc = rc2;
     680                AssertRC(rc);
     681            }
    824682
    825683            /*
     
    854712        vrc = watchdogShutdownModules();
    855713        AssertRC(vrc);
    856 
    857         RTCritSectDelete(&g_csMachines);
    858714
    859715        if (RT_FAILURE(vrc))
     
    964820    displayHeader();
    965821
    966     RTStrmPrintf(g_pStdErr, "Usage: %s [options]\n\nSupported options (default values in brackets):\n",
    967                  pszImage);
     822    RTStrmPrintf(g_pStdErr,
     823                 "Usage:\n"
     824                 " %s [-v|--verbose] [-h|-?|--help] [-P|--pidfile]\n"
     825                 " [-F|--logfile=<file>] [-R|--logrotate=<num>] [-S|--logsize=<bytes>]\n"
     826                 " [-I|--loginterval=<seconds>]\n", pszImage);
     827    for (unsigned j = 0; j < RT_ELEMENTS(g_aModules); j++)
     828        if (g_aModules[j].pDesc->pszUsage)
     829            RTStrmPrintf(g_pStdErr, "%s\n", g_aModules[j].pDesc->pszUsage);
     830
     831    RTStrmPrintf(g_pStdErr, "\n"
     832                 "Options:\n");
     833
    968834    for (unsigned i = 0;
    969835         i < RT_ELEMENTS(g_aOptions);
     
    1032898static HRESULT watchdogSetup()
    1033899{
    1034     serviceLogVerbose(("Creating local objects ...\n"));
     900    serviceLogVerbose(("Setting up ...\n"));
    1035901
    1036902    HRESULT rc = g_pVirtualBoxClient->COMGETTER(VirtualBox)(g_pVirtualBox.asOutParam());
     
    1055921#endif
    1056922
     923        int vrc = RTCritSectInit(&g_csMachines);
     924        if (RT_FAILURE(vrc))
     925        {
     926            rc = VBOX_E_IPRT_ERROR;
     927            break;
     928        }
     929
    1057930        /*
    1058931         * Build up initial VM list.
    1059932         */
    1060         int vrc = vmListBuild();
     933        vrc = vmListBuild();
    1061934        if (RT_FAILURE(vrc))
    1062935        {
     
    1070943}
    1071944
    1072 static void watchdogTeardown()
    1073 {
    1074     serviceLogVerbose(("Deleting local objects ...\n"));
     945static void watchdogShutdown()
     946{
     947    serviceLogVerbose(("Shutting down ...\n"));
    1075948
    1076949    vmListDestroy();
     950
     951    int rc = RTCritSectDelete(&g_csMachines);
     952    AssertRC(rc);
    1077953
    1078954#ifdef VBOX_WATCHDOG_GLOBAL_PERFCOL
     
    12761152    EventQueue::getMainEventQueue()->processEventQueue(0);
    12771153
    1278     watchdogTeardown();
     1154    watchdogShutdown();
    12791155
    12801156    g_pVirtualBoxClient.setNull();
  • trunk/src/VBox/Frontends/VBoxBalloonCtrl/VBoxWatchdogInternal.h

    r39943 r39986  
    2121#ifndef VBOX_ONLY_DOCS
    2222#include <VBox/com/com.h>
     23#include <VBox/com/assert.h>
    2324#include <VBox/com/string.h>
    2425#include <VBox/com/VirtualBox.h>
     
    5556    /* Pointer to allocated payload. Can be NULL if
    5657     * a module doesn't have an own payload. */
    57     void *pvPayload;
     58    void *pvData;
    5859    /* Size of payload (in bytes). */
    59     size_t cbPayload;
     60    size_t cbData;
    6061    /** @todo Add mutex for locking + getPayloadLocked(). */
    6162} VBOXWATCHDOG_MODULE_PAYLOAD, *PVBOXWATCHDOG_MODULE_PAYLOAD;
     
    195196
    196197extern bool g_fVerbose;
    197 extern ComPtr<IVirtualBox> g_pVirtualBox;
    198 extern ComPtr<ISession> g_pSession;
     198extern ComPtr<IVirtualBox>              g_pVirtualBox;
     199extern ComPtr<ISession>                 g_pSession;
     200extern mapVM                            g_mapVM;
     201# ifdef VBOX_WATCHDOG_GLOBAL_PERFCOL
     202extern ComPtr<IPerformanceCollector>    g_pPerfCollector;
     203# endif
    199204
    200205extern VBOXMODULE g_ModBallooning;
     206extern VBOXMODULE g_ModAPIMonitor;
    201207
    202208extern void serviceLog(const char *pszFormat, ...);
     
    205211extern int getMetric(PVBOXWATCHDOG_MACHINE pMachine, const Bstr& strName, LONG *pulData);
    206212void* getPayload(PVBOXWATCHDOG_MACHINE pMachine, const char *pszModule);
     213int payloadAlloc(PVBOXWATCHDOG_MACHINE pMachine, const char *pszModule, size_t cbSize, void **ppszPayload);
     214void payloadFree(PVBOXWATCHDOG_MACHINE pMachine, const char *pszModule);
     215PVBOXWATCHDOG_MACHINE getMachine(const Bstr& strUuid);
     216MachineState_T getMachineState(const PVBOXWATCHDOG_MACHINE pMachine);
    207217
    208218RT_C_DECLS_END
  • trunk/src/VBox/Frontends/VBoxBalloonCtrl/VBoxWatchdogUtils.cpp

    r39936 r39986  
    5454    /* Query current memory free. */
    5555    strName.cloneTo(&metricNames[0]);
    56 #ifdef VBOX_BALLOONCTRL_GLOBAL_PERFCOL
     56#ifdef VBOX_WATCHDOG_GLOBAL_PERFCOL
    5757    Assert(!g_pPerfCollector.isNull());
    5858    HRESULT hrc = g_pPerfCollector->QueryMetricsData(
     
    112112    if (it == pMachine->payload.end())
    113113        return NULL;
    114     Assert(it->second.cbPayload);
    115     return it->second.pvPayload;
     114    Assert(it->second.cbData);
     115    return it->second.pvData;
    116116}
    117117
     118int payloadAlloc(PVBOXWATCHDOG_MACHINE pMachine, const char *pszModule,
     119                 size_t cbSize, void **ppszPayload)
     120{
     121    AssertPtrReturn(pMachine, VERR_INVALID_POINTER);
     122    AssertPtrReturn(pszModule, VERR_INVALID_POINTER);
     123    AssertReturn(cbSize, VERR_INVALID_PARAMETER);
     124
     125    void *pvData = RTMemAlloc(cbSize);
     126    AssertPtrReturn(pvData, VERR_NO_MEMORY);
     127
     128    mapPayloadIter it = pMachine->payload.find(pszModule);
     129    AssertReturn(it == pMachine->payload.end(), VERR_INVALID_PARAMETER);
     130
     131    VBOXWATCHDOG_MODULE_PAYLOAD p;
     132    p.pvData = pvData;
     133    p.cbData = cbSize;
     134
     135    if (ppszPayload)
     136        *ppszPayload = p.pvData;
     137
     138    pMachine->payload.insert(std::make_pair(pszModule, p));
     139
     140    return VINF_SUCCESS;
     141}
     142
     143void payloadFree(PVBOXWATCHDOG_MACHINE pMachine, const char *pszModule)
     144{
     145    AssertPtrReturnVoid(pMachine);
     146    AssertPtrReturnVoid(pszModule);
     147
     148    mapPayloadIter it = pMachine->payload.find(pszModule);
     149    if (it != pMachine->payload.end())
     150    {
     151        RTMemFree(it->second.pvData);
     152        pMachine->payload.erase(it);
     153    }
     154}
     155
     156PVBOXWATCHDOG_MACHINE getMachine(const Bstr& strUuid)
     157{
     158    mapVMIter it = g_mapVM.find(strUuid);
     159    if (it != g_mapVM.end())
     160        return &it->second;
     161    return NULL;
     162}
     163
     164MachineState_T getMachineState(const PVBOXWATCHDOG_MACHINE pMachine)
     165{
     166    AssertPtrReturn(pMachine, MachineState_Null);
     167    MachineState_T machineState;
     168    Assert(!pMachine->machine.isNull());
     169    HRESULT rc = pMachine->machine->COMGETTER(State)(&machineState);
     170    if (SUCCEEDED(rc))
     171        return machineState;
     172    return MachineState_Null;
     173}
     174
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