Changeset 39986 in vbox for trunk/src/VBox
- Timestamp:
- Feb 3, 2012 2:21:28 PM (13 years ago)
- Location:
- trunk/src/VBox/Frontends/VBoxBalloonCtrl
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Frontends/VBoxBalloonCtrl/Makefile.kmk
r39929 r39986 22 22 VBoxBalloonCtrl_TEMPLATE = VBOXMAINCLIENTEXE 23 23 VBoxBalloonCtrl_DEFS += \ 24 VBOX_ BUILD_TARGET=\"$(KBUILD_TARGET).$(KBUILD_TARGET_ARCH)\"24 VBOX_WATCHDOG_GLOBAL_PERFCOL VBOX_BUILD_TARGET=\"$(KBUILD_TARGET).$(KBUILD_TARGET_ARCH)\" 25 25 VBoxBalloonCtrl_DEFS.win = _WIN32_WINNT=0x0500 26 26 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 60 using namespace com; 61 62 #define VBOX_MOD_APIMONITOR_NAME "apimonitor" 63 64 /** 65 * The module's RTGetOpt-IDs for the command line. 66 */ 67 enum GETOPTDEF_APIMONITOR 68 { 69 GETOPTDEF_APIMONITOR_GROUPS = 1000, 70 }; 71 72 /** 73 * The module's command line arguments. 74 */ 75 static const RTGETOPTDEF g_aAPIMonitorOpts[] = { 76 { "--apimonitor-groups", GETOPTDEF_APIMONITOR_GROUPS, RTGETOPT_REQ_STRING } 77 }; 78 79 /* Callbacks. */ 80 static DECLCALLBACK(int) VBoxModAPIMonitorPreInit(void) 81 { 82 return VINF_SUCCESS; 83 } 84 85 static 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 119 static DECLCALLBACK(int) VBoxModAPIMonitorInit(void) 120 { 121 return VINF_SUCCESS; /* Nothing to do here right now. */ 122 } 123 124 static DECLCALLBACK(int) VBoxModAPIMonitorMain(void) 125 { 126 return VINF_SUCCESS; /* Nothing to do here right now. */ 127 } 128 129 static DECLCALLBACK(int) VBoxModAPIMonitorStop(void) 130 { 131 return VINF_SUCCESS; 132 } 133 134 static DECLCALLBACK(void) VBoxModAPIMonitorTerm(void) 135 { 136 } 137 138 static DECLCALLBACK(int) VBoxModAPIMonitorOnMachineRegistered(const Bstr &strUuid) 139 { 140 return VINF_SUCCESS; 141 } 142 143 static DECLCALLBACK(int) VBoxModAPIMonitorOnMachineUnregistered(const Bstr &strUuid) 144 { 145 return VINF_SUCCESS; 146 } 147 148 static DECLCALLBACK(int) VBoxModAPIMonitorOnMachineStateChanged(const Bstr &strUuid, 149 MachineState_T enmState) 150 { 151 return VINF_SUCCESS; 152 } 153 154 static DECLCALLBACK(int) VBoxModAPIMonitorOnServiceStateChanged(bool fAvailable) 155 { 156 return VINF_SUCCESS; 157 } 158 159 /** 160 * The 'apimonitor' module description. 161 */ 162 VBOXMODULE 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 199 199 200 200 /** 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 */ 207 static 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 /** 201 227 * Determines whether ballooning is required to the specified machine. 202 228 * … … 207 233 { 208 234 AssertPtrReturn(pMachine, false); 209 210 /** @todo Add grouping! */211 235 212 236 /* Only do ballooning if we have a maximum balloon size set. */ … … 217 241 ? 0 : balloonGetMaxSize(pMachine->machine); 218 242 243 /** @todo Add grouping as a criteria! */ 244 219 245 return pData->ulBalloonSizeMax ? true : false; 246 } 247 248 int 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; 220 293 } 221 294 … … 228 301 * @param pMachine Pointer to the machine's internal structure. 229 302 */ 230 static int balloon Update(const Bstr &strUuid, PVBOXWATCHDOG_MACHINE pMachine)303 static int balloonMachineUpdate(const Bstr &strUuid, PVBOXWATCHDOG_MACHINE pMachine) 231 304 { 232 305 AssertPtrReturn(pMachine, VERR_INVALID_POINTER); … … 304 377 } 305 378 379 /* Callbacks. */ 306 380 static DECLCALLBACK(int) VBoxModBallooningPreInit(void) 307 381 { 308 int rc = -1; 309 /* Not yet implemented. */ 310 return rc; 382 return VINF_SUCCESS; 311 383 } 312 384 … … 373 445 static DECLCALLBACK(int) VBoxModBallooningInit(void) 374 446 { 375 int rc = -1; 376 /* Not yet implemented. */ 377 return rc; 447 return VINF_SUCCESS; /* Nothing to do here right now. */ 378 448 } 379 449 … … 385 455 return VINF_SUCCESS; 386 456 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 483 static DECLCALLBACK(int) VBoxModBallooningStop(void) 484 { 485 return VINF_SUCCESS; 486 } 487 488 static DECLCALLBACK(void) VBoxModBallooningTerm(void) 489 { 490 } 491 492 static 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); 389 500 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); 409 502 410 503 return rc; 411 #endif412 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;427 504 } 428 505 429 506 static DECLCALLBACK(int) VBoxModBallooningOnMachineUnregistered(const Bstr &strUuid) 430 507 { 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; 432 514 } 433 515 … … 435 517 MachineState_T enmState) 436 518 { 437 return 0; 519 PVBOXWATCHDOG_MACHINE pMachine = getMachine(strUuid); 520 AssertPtrReturn(pMachine, VERR_INVALID_PARAMETER); 521 522 return balloonMachineUpdate(strUuid, pMachine); 438 523 } 439 524 440 525 static DECLCALLBACK(int) VBoxModBallooningOnServiceStateChanged(bool fAvailable) 441 526 { 442 return 0;527 return VINF_SUCCESS; 443 528 } 444 529 … … 457 542 0 /* Not used */, 458 543 /* pszUsage. */ 459 " [--balloon-dec <MB>] [--balloon-inc <MB>]\n"460 " 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", 462 547 /* pszOptions. */ 463 548 "--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" 465 550 "--balloon-inc Sets the ballooning increment in MB (256 MB).\n" 466 551 "--balloon-interval Sets the check interval in ms (30 seconds).\n" -
trunk/src/VBox/Frontends/VBoxBalloonCtrl/VBoxWatchdog.cpp
r39942 r39986 66 66 67 67 /** External globals. */ 68 bool g_fVerbose = false; 69 ComPtr<IVirtualBox> g_pVirtualBox = NULL; 70 ComPtr<ISession> g_pSession = NULL; 68 bool g_fVerbose = false; 69 ComPtr<IVirtualBox> g_pVirtualBox = NULL; 70 ComPtr<ISession> g_pSession = NULL; 71 mapVM g_mapVM; 72 # ifdef VBOX_WATCHDOG_GLOBAL_PERFCOL 73 ComPtr<IPerformanceCollector> g_pPerfCollector = NULL; 74 # endif 71 75 72 76 /** The critical section for the machines map. */ … … 99 103 } g_aModules[] = 100 104 { 101 { &g_ModBallooning, false /* Pre-inited */, true /* Enabled */ } 105 { &g_ModBallooning, false /* Pre-inited */, true /* Enabled */ }, 106 { &g_ModAPIMonitor, false /* Pre-inited */, true /* Enabled */ } 102 107 }; 103 108 … … 119 124 }; 120 125 121 static unsigned long g_ulTimeoutMS = 30 * 1000; /* Default is 30 seconds timeout. */126 static unsigned long g_ulTimeoutMS = 500; /* Default is 500ms timeout. */ 122 127 static unsigned long g_ulMemoryBalloonIncrementMB = 256; 123 128 static unsigned long g_ulMemoryBalloonDecrementMB = 128; … … 132 137 static ComPtr<IEventSource> g_pEventSourceClient = NULL; 133 138 static ComPtr<IEventListener> g_pVBoxEventListener = NULL; 134 # ifdef VBOX_WATCHDOG_GLOBAL_PERFCOL135 static ComPtr<IPerformanceCollector> g_pPerfCollector = NULL;136 # endif137 139 static EventQueue *g_pEventQ = NULL; 138 static mapVM g_mapVM;139 140 140 141 /* Prototypes. */ 141 static bool machineIsRunning(MachineState_T enmState);142 static bool machineHandled(const Bstr &strUuid);143 142 static int machineAdd(const Bstr &strUuid); 144 143 static int machineRemove(const Bstr &strUuid); 145 144 //static int machineUpdate(const Bstr &strUuid, MachineState_T enmState); 146 145 static HRESULT watchdogSetup(); 147 static void watchdog Teardown();146 static void watchdogShutdown(); 148 147 149 148 #ifdef RT_OS_WINDOWS … … 195 194 if (RT_SUCCESS(rc)) 196 195 { 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); 215 199 int rc2 = RTCritSectLeave(&g_csMachines); 216 200 if (RT_SUCCESS(rc)) … … 250 234 } 251 235 252 //rc = machineUpdate(uuid, machineState);253 236 int rc2 = RTCritSectLeave(&g_csMachines); 254 237 if (RT_SUCCESS(rc)) … … 282 265 { 283 266 serviceLog("VBoxSVC became unavailable\n"); 284 watchdog Teardown();267 watchdogShutdown(); 285 268 } 286 269 else … … 352 335 353 336 /** 354 * Indicates whether a VM is up and running (regardless of its running355 * 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 0366 /* Not required for ballooning. */367 case MachineState_Teleporting:368 case MachineState_LiveSnapshotting:369 case MachineState_Paused:370 case MachineState_TeleportingPausedVM:371 #endif372 return true;373 default:374 break;375 }376 return false;377 }378 379 /**380 * Determines whether the specified machine needs to be handled381 * 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 do391 {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 0401 if ( balloonGetMaxSize(machine)402 && machineIsRunning(machineState))403 {404 serviceLogVerbose(("Handling machine \"%ls\"\n", strUuid.raw()));405 fHandled = true;406 }407 #endif408 }409 while (0);410 411 return fHandled;412 }413 414 /**415 337 * Adds a specified machine to the list (map) of handled machines. 416 338 * Does not do locking -- needs to be done by caller! … … 431 353 CHECK_ERROR_BREAK(machine, COMGETTER(State)(&machineState)); 432 354 433 #if 0434 if ( !balloonGetMaxSize(machine)435 || !machineIsRunning(machineState))436 {437 /* This machine does not need to be added, just skip it! */438 break;439 }440 #endif441 442 355 VBOXWATCHDOG_MACHINE m; 443 356 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_PERFCOL460 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 #else466 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 #endif473 474 ///////////////// TODO END475 357 476 358 /* … … 479 361 mapVMIter it = g_mapVM.find(strUuid); 480 362 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. */ 483 368 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 } 492 377 493 378 } while (0); … … 496 381 497 382 return SUCCEEDED(rc) ? VINF_SUCCESS : VERR_COM_IPRT_ERROR; /* @todo Find a better error! */ 383 } 384 385 static 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; 498 418 } 499 419 … … 507 427 static int machineRemove(const Bstr &strUuid) 508 428 { 429 AssertReturn(!strUuid.isEmpty(), VERR_INVALID_PARAMETER); 509 430 int rc = VINF_SUCCESS; 510 431 … … 512 433 if (it != g_mapVM.end()) 513 434 { 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 521 443 } 522 444 else … … 529 451 } 530 452 531 #if 0532 /**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't535 * fit in our criteria anymore or a machine gets added if we need to handle536 * 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 else557 {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 0569 /* 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 else578 {579 rc = balloonUpdate(strUuid, &it->second);580 AssertRC(rc);581 }582 #endif583 }584 585 /*586 * Ballooning stuff - end.587 */588 589 return rc;590 }591 #endif592 593 453 static void vmListDestroy() 594 454 { … … 601 461 while (it != g_mapVM.end()) 602 462 { 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(); 608 465 } 609 466 … … 763 620 g_pEventQ = com::EventQueue::getMainEventQueue(); 764 621 765 RTCritSectInit(&g_csMachines);766 767 622 /* 768 623 * Install signal handlers. … … 806 661 * Do the actual work. 807 662 */ 808 /* 809 vrc = balloonCtrlCheck();810 if (RT_ FAILURE(vrc))663 664 int rc = RTCritSectEnter(&g_csMachines); 665 if (RT_SUCCESS(rc)) 811 666 { 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 } 824 682 825 683 /* … … 854 712 vrc = watchdogShutdownModules(); 855 713 AssertRC(vrc); 856 857 RTCritSectDelete(&g_csMachines);858 714 859 715 if (RT_FAILURE(vrc)) … … 964 820 displayHeader(); 965 821 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 968 834 for (unsigned i = 0; 969 835 i < RT_ELEMENTS(g_aOptions); … … 1032 898 static HRESULT watchdogSetup() 1033 899 { 1034 serviceLogVerbose((" Creating local objects...\n"));900 serviceLogVerbose(("Setting up ...\n")); 1035 901 1036 902 HRESULT rc = g_pVirtualBoxClient->COMGETTER(VirtualBox)(g_pVirtualBox.asOutParam()); … … 1055 921 #endif 1056 922 923 int vrc = RTCritSectInit(&g_csMachines); 924 if (RT_FAILURE(vrc)) 925 { 926 rc = VBOX_E_IPRT_ERROR; 927 break; 928 } 929 1057 930 /* 1058 931 * Build up initial VM list. 1059 932 */ 1060 intvrc = vmListBuild();933 vrc = vmListBuild(); 1061 934 if (RT_FAILURE(vrc)) 1062 935 { … … 1070 943 } 1071 944 1072 static void watchdog Teardown()1073 { 1074 serviceLogVerbose((" Deleting local objects...\n"));945 static void watchdogShutdown() 946 { 947 serviceLogVerbose(("Shutting down ...\n")); 1075 948 1076 949 vmListDestroy(); 950 951 int rc = RTCritSectDelete(&g_csMachines); 952 AssertRC(rc); 1077 953 1078 954 #ifdef VBOX_WATCHDOG_GLOBAL_PERFCOL … … 1276 1152 EventQueue::getMainEventQueue()->processEventQueue(0); 1277 1153 1278 watchdog Teardown();1154 watchdogShutdown(); 1279 1155 1280 1156 g_pVirtualBoxClient.setNull(); -
trunk/src/VBox/Frontends/VBoxBalloonCtrl/VBoxWatchdogInternal.h
r39943 r39986 21 21 #ifndef VBOX_ONLY_DOCS 22 22 #include <VBox/com/com.h> 23 #include <VBox/com/assert.h> 23 24 #include <VBox/com/string.h> 24 25 #include <VBox/com/VirtualBox.h> … … 55 56 /* Pointer to allocated payload. Can be NULL if 56 57 * a module doesn't have an own payload. */ 57 void *pv Payload;58 void *pvData; 58 59 /* Size of payload (in bytes). */ 59 size_t cb Payload;60 size_t cbData; 60 61 /** @todo Add mutex for locking + getPayloadLocked(). */ 61 62 } VBOXWATCHDOG_MODULE_PAYLOAD, *PVBOXWATCHDOG_MODULE_PAYLOAD; … … 195 196 196 197 extern bool g_fVerbose; 197 extern ComPtr<IVirtualBox> g_pVirtualBox; 198 extern ComPtr<ISession> g_pSession; 198 extern ComPtr<IVirtualBox> g_pVirtualBox; 199 extern ComPtr<ISession> g_pSession; 200 extern mapVM g_mapVM; 201 # ifdef VBOX_WATCHDOG_GLOBAL_PERFCOL 202 extern ComPtr<IPerformanceCollector> g_pPerfCollector; 203 # endif 199 204 200 205 extern VBOXMODULE g_ModBallooning; 206 extern VBOXMODULE g_ModAPIMonitor; 201 207 202 208 extern void serviceLog(const char *pszFormat, ...); … … 205 211 extern int getMetric(PVBOXWATCHDOG_MACHINE pMachine, const Bstr& strName, LONG *pulData); 206 212 void* getPayload(PVBOXWATCHDOG_MACHINE pMachine, const char *pszModule); 213 int payloadAlloc(PVBOXWATCHDOG_MACHINE pMachine, const char *pszModule, size_t cbSize, void **ppszPayload); 214 void payloadFree(PVBOXWATCHDOG_MACHINE pMachine, const char *pszModule); 215 PVBOXWATCHDOG_MACHINE getMachine(const Bstr& strUuid); 216 MachineState_T getMachineState(const PVBOXWATCHDOG_MACHINE pMachine); 207 217 208 218 RT_C_DECLS_END -
trunk/src/VBox/Frontends/VBoxBalloonCtrl/VBoxWatchdogUtils.cpp
r39936 r39986 54 54 /* Query current memory free. */ 55 55 strName.cloneTo(&metricNames[0]); 56 #ifdef VBOX_ BALLOONCTRL_GLOBAL_PERFCOL56 #ifdef VBOX_WATCHDOG_GLOBAL_PERFCOL 57 57 Assert(!g_pPerfCollector.isNull()); 58 58 HRESULT hrc = g_pPerfCollector->QueryMetricsData( … … 112 112 if (it == pMachine->payload.end()) 113 113 return NULL; 114 Assert(it->second.cb Payload);115 return it->second.pv Payload;114 Assert(it->second.cbData); 115 return it->second.pvData; 116 116 } 117 117 118 int 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 143 void 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 156 PVBOXWATCHDOG_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 164 MachineState_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.