VirtualBox

Changeset 36707 in vbox for trunk/src/VBox/Frontends


Ignore:
Timestamp:
Apr 18, 2011 12:17:33 PM (14 years ago)
Author:
vboxsync
Message:

VBoxBalloonCtrl: Update (Survive VBoxSVC crash, bugfixes).

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

Legend:

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

    r36702 r36707  
    128128unsigned long g_ulLowerMemoryLimitMB = 64;
    129129
    130 /** Global weak references (for event handlers). */
    131 static IVirtualBox *g_pVirtualBox = NULL;
    132 static ISession *g_pSession = NULL;
     130/** Global objects. */
     131static ComPtr<IVirtualBoxClient> g_pVirtualBoxClient = NULL;
     132static ComPtr<IVirtualBox> g_pVirtualBox = NULL;
     133static ComPtr<ISession> g_pSession = NULL;
     134static ComPtr<IEventSource> g_pEventSource = NULL;
     135static ComPtr<IEventSource> g_pEventSourceClient = NULL;
     136static ComPtr<IEventListener> g_pVBoxEventListener = NULL;
     137# ifdef VBOX_BALLOONCTRL_GLOBAL_PERFCOL
     138static ComPtr<IPerformanceCollector> g_pPerfCollector = NULL;
     139# endif
    133140static EventQueue *g_pEventQ = NULL;
    134 #ifdef VBOX_BALLOONCTRL_GLOBAL_PERFCOL
    135 static IPerformanceCollector *g_pPerfCollector = NULL;
    136 #endif
    137141
    138142/** A machine's internal entry. */
     
    164168bool balloonIsRequired(mapVMIter it);
    165169int balloonUpdate(mapVMIterConst it);
     170
     171HRESULT balloonCtrlSetup();
     172void balloonCtrlShutdown();
     173
     174HRESULT createGlobalObjects();
     175void deleteGlobalObjects();
    166176
    167177#ifdef RT_OS_WINDOWS
     
    273283                }
    274284
     285                case VBoxEventType_OnVBoxSVCAvailabilityChanged:
     286                {
     287                    ComPtr<IVBoxSVCAvailabilityChangedEvent> pVSACEv = aEvent;
     288                    Assert(pVSACEv);
     289                    BOOL fAvailable = FALSE;
     290                    pVSACEv->COMGETTER(Available)(&fAvailable);
     291                    if (!fAvailable)
     292                    {
     293                        serviceLog("VBoxSVC became unavailable\n");
     294                        {
     295                            balloonCtrlShutdown();
     296                            deleteGlobalObjects();
     297                        }
     298                    }
     299                    else
     300                    {
     301                        serviceLog("VBoxSVC became available\n");
     302                        HRESULT hrc = createGlobalObjects();
     303                        if (FAILED(hrc))
     304                            serviceLog("Unable to re-create local COM objects (rc=%Rhrc)!\n", hrc);
     305                        else
     306                        {
     307                            hrc = balloonCtrlSetup();
     308                            if (FAILED(hrc))
     309                                serviceLog("Unable to re-set up ballooning (rc=%Rhrc)!\n", hrc);
     310                        }
     311                    }
     312                    break;
     313                }
     314
    275315                default:
    276316                    /* Not handled event, just skip it. */
     
    433473        CHECK_ERROR_BREAK(rptrMachine, COMGETTER(Id)(strUUID.asOutParam()));
    434474
    435         if (!metricAffected.size())
    436             serviceLogVerbose(("%s: No metrics available yet!\n", Utf8Str(strUUID).c_str()));
    437 
    438475        mapVMIter it = g_mapVM.find(strUUID);
    439476        Assert(it == g_mapVM.end());
     
    549586}
    550587
     588/**
     589 * Determines the maximum balloon size to set for the specified machine.
     590 *
     591 * @return  unsigned long           Balloon size (in MB) to set, 0 if no ballooning required.
     592 * @param   rptrMachine             Pointer to specified machine.
     593 */
    551594unsigned long balloonGetMaxSize(const ComPtr<IMachine> &rptrMachine)
    552595{
     
    585628}
    586629
     630/**
     631 * Determines whether ballooning is required to the spcified VM.
     632 *
     633 * @return  bool        True if ballooning is required, false if not.
     634 * @param   it          Iterator pointing to the VM to be processed.
     635 */
    587636bool balloonIsRequired(mapVMIter it)
    588637{
     
    593642}
    594643
    595 /* Does the actual ballooning and assumes the machine is
    596  * capable and ready for ballooning. */
     644/**
     645 * Does the actual ballooning and assumes the machine is
     646 * capable and ready for ballooning.
     647 *
     648 * @return  IPRT status code.
     649 * @param   it          Iterator pointing to the VM to be processed.
     650 */
    597651int balloonUpdate(mapVMIterConst it)
    598652{
     
    682736        }
    683737
     738        g_mapVM.clear();
     739
    684740        rc = RTCritSectLeave(&g_MapCritSect);
    685741    }
     
    689745int vmListBuild()
    690746{
    691     vmListDestroy();
    692 
    693747    serviceLogVerbose(("Building VM list ...\n"));
    694748
     
    716770                {
    717771                    MachineState_T machineState;
    718                     hrc = machines[i]->COMGETTER(State)(&machineState);
    719                     if (   SUCCEEDED(hrc)
    720                         && machineIsRunning(machineState))
     772                    CHECK_ERROR_BREAK(machines[i], COMGETTER(State)(&machineState));
     773
     774                    if (g_fVerbose)
     775                    {
     776                        Bstr strUUID;
     777                        CHECK_ERROR_BREAK(machines[i], COMGETTER(Id)(strUUID.asOutParam()));
     778
     779                        serviceLogVerbose(("Processing machine \"%s\" (state: %ld)\n",
     780                                           Utf8Str(strUUID).c_str(), machineState));
     781                    }
     782
     783                    if (machineIsRunning(machineState))
    721784                    {
    722785                        rc = machineAdd(machines[i]);
     
    726789                }
    727790            }
     791
     792            if (!machines.size())
     793                serviceLogVerbose(("No machines to add found at the moment!\n"));
    728794        }
    729795
     
    762828}
    763829
    764 RTEXITCODE balloonCtrlMain(HandlerArg *a)
     830HRESULT balloonCtrlSetup()
    765831{
    766832    HRESULT rc = S_OK;
    767833
     834    serviceLog("Setting up ballooning ...\n");
     835
    768836    do
    769837    {
    770         /* Initialize global weak references. */
    771         g_pVirtualBox = a->virtualBox;
    772         g_pSession = a->session;
    773         g_pEventQ = com::EventQueue::getMainEventQueue();
    774 
    775         RTCritSectInit(&g_MapCritSect);
    776 
    777         int vrc = RTSemEventMultiCreate(&g_BalloonControlEvent);
    778         AssertRCReturn(vrc, RTEXITCODE_FAILURE);
    779 
    780         /*
    781          * Setup the global event listener.
    782          */
    783         ComPtr<IEventSource> es;
    784         CHECK_ERROR_BREAK(a->virtualBox, COMGETTER(EventSource)(es.asOutParam()));
    785 
    786         ComObjPtr<VirtualBoxEventListenerImpl> vboxListenerImpl;
    787         vboxListenerImpl.createObject();
    788         vboxListenerImpl->init(new VirtualBoxEventListener());
    789 
    790         com::SafeArray <VBoxEventType_T> eventTypes(1);
    791         eventTypes.push_back(VBoxEventType_OnMachineRegistered);
    792         eventTypes.push_back(VBoxEventType_OnMachineStateChanged);
    793 
    794         ComPtr<IEventListener> vboxListener;
    795         vboxListener = vboxListenerImpl;
    796 
    797         CHECK_ERROR_BREAK(es, RegisterListener(vboxListener, ComSafeArrayAsInParam(eventTypes), true /* Active listener */));
    798 
    799838        /*
    800839         * Setup metrics.
    801840         */
    802841#ifdef VBOX_BALLOONCTRL_GLOBAL_PERFCOL
    803         ComPtr<IPerformanceCollector> perfCol;
    804         CHECK_ERROR_BREAK(g_pVirtualBox, COMGETTER(PerformanceCollector)(perfCol.asOutParam()));
    805         g_pPerfCollector = perfCol;
    806 #endif
     842        CHECK_ERROR_BREAK(g_pVirtualBox, COMGETTER(PerformanceCollector)(g_pPerfCollector.asOutParam()));
     843#endif
     844
     845        /*
     846         * Build up initial VM list.
     847         */
     848        int vrc = vmListBuild();
     849        if (RT_FAILURE(vrc))
     850        {
     851            rc = VBOX_E_IPRT_ERROR;
     852            break;
     853        }
     854
     855    } while (0);
     856
     857    return rc;
     858}
     859
     860void balloonCtrlShutdown()
     861{
     862    serviceLog("Shutting down ballooning ...\n");
     863
     864    vmListDestroy();
     865
     866#ifdef VBOX_BALLOONCTRL_GLOBAL_PERFCOL
     867    g_pPerfCollector.setNull();
     868#endif
     869}
     870
     871RTEXITCODE balloonCtrlMain(HandlerArg *a)
     872{
     873    HRESULT rc = S_OK;
     874
     875    do
     876    {
     877        /* Initialize global weak references. */
     878        g_pEventQ = com::EventQueue::getMainEventQueue();
     879
     880        RTCritSectInit(&g_MapCritSect);
     881
     882        int vrc = RTSemEventMultiCreate(&g_BalloonControlEvent);
     883        AssertRCReturn(vrc, RTEXITCODE_FAILURE);
    807884
    808885        /*
     
    815892
    816893        /*
    817          * Build up initial VM list.
     894         * Setup the global event listeners:
     895         * - g_pEventSource for machine events
     896         * - g_pEventSourceClient for VBoxClient events (like VBoxSVC handling)
    818897         */
    819         vrc = vmListBuild();
    820         if (FAILED(vrc)) break;
     898        CHECK_ERROR_BREAK(g_pVirtualBox, COMGETTER(EventSource)(g_pEventSource.asOutParam()));
     899        CHECK_ERROR_BREAK(g_pVirtualBoxClient, COMGETTER(EventSource)(g_pEventSourceClient.asOutParam()));
     900
     901        ComObjPtr<VirtualBoxEventListenerImpl> vboxListenerImpl;
     902        vboxListenerImpl.createObject();
     903        vboxListenerImpl->init(new VirtualBoxEventListener());
     904
     905        com::SafeArray <VBoxEventType_T> eventTypes;
     906        eventTypes.push_back(VBoxEventType_OnMachineRegistered);
     907        eventTypes.push_back(VBoxEventType_OnMachineStateChanged);
     908        eventTypes.push_back(VBoxEventType_OnVBoxSVCAvailabilityChanged); /* Processed by g_pEventSourceClient. */
     909
     910        g_pVBoxEventListener = vboxListenerImpl;
     911        CHECK_ERROR_BREAK(g_pEventSource, RegisterListener(g_pVBoxEventListener, ComSafeArrayAsInParam(eventTypes), true /* Active listener */));
     912        CHECK_ERROR_BREAK(g_pEventSourceClient, RegisterListener(g_pVBoxEventListener, ComSafeArrayAsInParam(eventTypes), true /* Active listener */));
     913
     914        /*
     915         * Set up ballooning stuff.
     916         */
     917        rc = balloonCtrlSetup();
     918        if (FAILED(rc))
     919            break;
    821920
    822921        for (;;)
     
    858957
    859958        /* VirtualBox callback unregistration. */
    860         if (vboxListener)
    861         {
    862             if (!es.isNull())
    863                 CHECK_ERROR_BREAK(es, UnregisterListener(vboxListener));
    864             vboxListener.setNull();
    865         }
    866 
    867         vmListDestroy();
    868 
    869 #ifdef VBOX_BALLOONCTRL_GLOBAL_PERFCOL
    870         perfCol.setNull();
    871 #endif
     959        if (g_pVBoxEventListener)
     960        {
     961            HRESULT rc;
     962            if (!g_pEventSource.isNull())
     963                CHECK_ERROR(g_pEventSource, UnregisterListener(g_pVBoxEventListener));
     964            g_pVBoxEventListener.setNull();
     965        }
     966
     967        g_pEventSource.setNull();
     968        g_pEventSourceClient.setNull();
     969
     970        balloonCtrlShutdown();
    872971
    873972        RTCritSectDelete(&g_MapCritSect);
     
    10401139}
    10411140
     1141void deleteGlobalObjects()
     1142{
     1143    serviceLogVerbose(("Deleting local objects ...\n"));
     1144
     1145    g_pSession.setNull();
     1146    g_pVirtualBox.setNull();
     1147}
     1148
     1149/**
     1150 * Creates all global COM objects.
     1151 *
     1152 * @return  HRESULT
     1153 */
     1154HRESULT createGlobalObjects()
     1155{
     1156    serviceLogVerbose(("Creating local objects ...\n"));
     1157
     1158    HRESULT hrc = g_pVirtualBoxClient->COMGETTER(VirtualBox)(g_pVirtualBox.asOutParam());
     1159    if (FAILED(hrc))
     1160    {
     1161        RTMsgError("Failed to get VirtualBox object (rc=%Rhrc)!", hrc);
     1162    }
     1163    else
     1164    {
     1165        hrc = g_pSession.createInprocObject(CLSID_Session);
     1166        if (FAILED(hrc))
     1167            RTMsgError("Failed to create a session object (rc=%Rhrc)!", hrc);
     1168    }
     1169
     1170    return hrc;
     1171}
     1172
    10421173int main(int argc, char *argv[])
    10431174{
     
    12041335        return RTMsgErrorExit(RTEXITCODE_FAILURE, "Failed to initialize COM!");
    12051336
    1206     RTEXITCODE rcExit = RTEXITCODE_FAILURE;
    1207     do
    1208     {
    1209         ComPtr<IVirtualBox> virtualBox;
    1210         ComPtr<ISession> session;
    1211 
    1212         hrc = virtualBox.createLocalObject(CLSID_VirtualBox);
    1213         if (FAILED(hrc))
    1214             RTMsgError("Failed to create the VirtualBox object!");
     1337    hrc = g_pVirtualBoxClient.createInprocObject(CLSID_VirtualBoxClient);
     1338    if (FAILED(hrc))
     1339    {
     1340        RTMsgError("failed to create the VirtualBoxClient object!");
     1341        com::ErrorInfo info;
     1342        if (!info.isFullAvailable() && !info.isBasicAvailable())
     1343        {
     1344            com::GluePrintRCMessage(hrc);
     1345            RTMsgError("Most likely, the VirtualBox COM server is not running or failed to start.");
     1346        }
    12151347        else
    1216         {
    1217             hrc = session.createInprocObject(CLSID_Session);
    1218             if (FAILED(hrc))
    1219                 RTMsgError("Failed to create a session object!");
    1220         }
    1221         if (FAILED(hrc))
    1222         {
    1223             com::ErrorInfo info;
    1224             if (!info.isFullAvailable() && !info.isBasicAvailable())
    1225             {
    1226                 com::GluePrintRCMessage(hrc);
    1227                 RTMsgError("Most likely, the VirtualBox COM server is not running or failed to start.");
    1228             }
    1229             else
    1230                 com::GluePrintErrorInfo(info);
    1231             break;
    1232         }
    1233 
    1234         HandlerArg handlerArg = { 0, NULL, virtualBox, session };
    1235         handlerArg.argc = argc;
    1236         handlerArg.argv = argv;
    1237 
    1238         rcExit = balloonCtrlMain(&handlerArg);
    1239 
    1240         EventQueue::getMainEventQueue()->processEventQueue(0);
    1241 
    1242         session.setNull();
    1243         virtualBox.setNull();
    1244 
    1245     } while (0);
     1348            com::GluePrintErrorInfo(info);
     1349        return RTEXITCODE_FAILURE;
     1350    }
     1351
     1352    hrc = createGlobalObjects();
     1353    if (FAILED(hrc))
     1354        return RTEXITCODE_FAILURE;
     1355
     1356    HandlerArg handlerArg = { argc, argv };
     1357    RTEXITCODE rcExit = balloonCtrlMain(&handlerArg);
     1358
     1359    EventQueue::getMainEventQueue()->processEventQueue(0);
     1360
     1361    deleteGlobalObjects();
     1362
     1363    g_pVirtualBoxClient.setNull();
    12461364
    12471365    com::Shutdown();
  • trunk/src/VBox/Frontends/VBoxBalloonCtrl/VBoxBalloonCtrl.h

    r36693 r36707  
    4141    int argc;
    4242    char **argv;
    43 
    44 #ifndef VBOX_ONLY_DOCS
    45     ComPtr<IVirtualBox> virtualBox;
    46     ComPtr<ISession> session;
    47 #endif
    4843};
    4944
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