Changeset 37103 in vbox for trunk/src/VBox/Frontends/VBoxBalloonCtrl
- Timestamp:
- May 16, 2011 12:59:24 PM (14 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Frontends/VBoxBalloonCtrl/VBoxBalloonCtrl.cpp
r36847 r37103 156 156 157 157 static bool machineIsRunning(MachineState_T enmState); 158 static mapVMIter machineGetByUUID(const Bstr &strUUID); 159 static int machineAdd(const ComPtr<IMachine> &rptrMachine); 160 static int machineUpdate(const ComPtr<IMachine> &rptrMachine, MachineState_T enmState); 161 static int machineUpdate(mapVMIter it, MachineState_T enmState); 162 static void machineRemove(mapVMIter it); 158 static bool machineHandled(const Bstr &strUuid); 159 static int machineAdd(const Bstr &strUuid); 160 static int machineRemove(const Bstr &strUuid); 161 static int machineUpdate(const Bstr &strUuid, MachineState_T enmState); 163 162 164 163 static unsigned long balloonGetMaxSize(const ComPtr<IMachine> &rptrMachine); 165 static bool balloonIsRequired( mapVMIter it);166 static int balloonUpdate( mapVMIterConst it);164 static bool balloonIsRequired(PVBOXBALLOONCTRL_MACHINE pMachine); 165 static int balloonUpdate(const Bstr &strUuid, PVBOXBALLOONCTRL_MACHINE pMachine); 167 166 168 167 static HRESULT balloonCtrlSetup(); … … 220 219 if (RT_SUCCESS(rc)) 221 220 { 222 if (fRegistered) 223 { 224 ComPtr <IMachine> machine; 225 hr = g_pVirtualBox->FindMachine(uuid.raw(), machine.asOutParam()); 226 if (SUCCEEDED(hr)) 227 rc = machineAdd(machine); 228 else 229 rc = VERR_NOT_FOUND; 230 } 231 else 232 machineRemove(machineGetByUUID(uuid)); 233 AssertRC(rc); 221 if (fRegistered && machineHandled(uuid)) 222 rc = machineAdd(uuid); 223 else if (!fRegistered) 224 rc = machineRemove(uuid); 234 225 235 226 int rc2 = RTCritSectLeave(&g_MapCritSect); 236 227 if (RT_SUCCESS(rc)) 237 228 rc = rc2; 229 AssertRC(rc); 238 230 } 239 231 } … … 258 250 if (RT_SUCCESS(rc)) 259 251 { 260 mapVMIter it = machineGetByUUID(uuid); 261 if (it == g_mapVM.end()) 262 { 263 /* Use the machine object to figure out if we 264 * need to do something. */ 265 ComPtr <IMachine> machine; 266 hr = g_pVirtualBox->FindMachine(uuid.raw(), machine.asOutParam()); 267 if (SUCCEEDED(hr)) 268 rc = machineUpdate(machine, machineState); 269 } 270 else /* Update an existing machine. */ 271 rc = machineUpdate(it, machineState); 272 AssertRC(rc); 273 252 rc = machineUpdate(uuid, machineState); 274 253 int rc2 = RTCritSectLeave(&g_MapCritSect); 275 254 if (RT_SUCCESS(rc)) 276 255 rc = rc2; 256 AssertRC(rc); 277 257 } 278 258 } … … 289 269 { 290 270 serviceLog("VBoxSVC became unavailable\n"); 291 { 292 balloonCtrlShutdown(); 293 deleteGlobalObjects(); 294 } 271 272 balloonCtrlShutdown(); 273 deleteGlobalObjects(); 295 274 } 296 275 else … … 367 346 } 368 347 348 /** 349 * Retrieves the current delta value 350 * 351 * @return long Delta (MB) of the balloon to be deflated (<0) or inflated (>0). 352 * @param ulCurrentDesktopBalloonSize The balloon's current size. 353 * @param ulDesktopFreeMemory The VM's current free memory. 354 * @param ulMaxBalloonSize The maximum balloon size (MB) it can inflate to. 355 */ 369 356 static long getlBalloonDelta(unsigned long ulCurrentDesktopBalloonSize, unsigned long ulDesktopFreeMemory, unsigned long ulMaxBalloonSize) 370 357 { … … 427 414 } 428 415 429 static mapVMIter machineGetByUUID(const Bstr &strUUID) 430 { 431 return g_mapVM.find(strUUID); 432 } 433 434 static int machineAdd(const ComPtr<IMachine> &rptrMachine) 416 /** 417 * Determines whether the specified machine needs to be handled 418 * by this service. 419 * 420 * @return bool True if the machine needs handling, false if not. 421 * @param strUuid UUID of the specified machine. 422 */ 423 static bool machineHandled(const Bstr &strUuid) 424 { 425 bool fHandled = false; 426 427 do 428 { 429 HRESULT rc; 430 431 ComPtr <IMachine> machine; 432 CHECK_ERROR_BREAK(g_pVirtualBox, FindMachine(strUuid.raw(), machine.asOutParam())); 433 434 MachineState_T machineState; 435 CHECK_ERROR_BREAK(machine, COMGETTER(State)(&machineState)); 436 437 if ( balloonGetMaxSize(machine) 438 && machineIsRunning(machineState)) 439 { 440 serviceLogVerbose(("Handling machine \"%ls\"\n", strUuid.raw())); 441 fHandled = true; 442 } 443 } 444 while (0); 445 446 return fHandled; 447 } 448 449 /** 450 * Adds a specified machine to the list (map) of handled machines. 451 * 452 * @return IPRT status code. 453 * @param strUuid UUID of the specified machine. 454 */ 455 static int machineAdd(const Bstr &strUuid) 435 456 { 436 457 HRESULT rc; … … 438 459 do 439 460 { 461 ComPtr <IMachine> machine; 462 CHECK_ERROR_BREAK(g_pVirtualBox, FindMachine(strUuid.raw(), machine.asOutParam())); 463 464 MachineState_T machineState; 465 CHECK_ERROR_BREAK(machine, COMGETTER(State)(&machineState)); 466 467 if ( !balloonGetMaxSize(machine) 468 || !machineIsRunning(machineState)) 469 { 470 /* This machine does not need to be added, just skip it! */ 471 break; 472 } 473 440 474 VBOXBALLOONCTRL_MACHINE m; 441 m.machine = rptrMachine;475 m.machine = machine; 442 476 443 477 /* … … 470 504 * Add machine to map. 471 505 */ 472 Bstr strUUID; 473 CHECK_ERROR_BREAK(rptrMachine, COMGETTER(Id)(strUUID.asOutParam())); 474 475 mapVMIter it = g_mapVM.find(strUUID); 506 mapVMIter it = g_mapVM.find(strUuid); 476 507 Assert(it == g_mapVM.end()); 477 508 478 g_mapVM.insert(std::make_pair(strU UID, m));479 480 serviceLogVerbose(("Added machine \"%ls\"\n", strU UID.raw()));509 g_mapVM.insert(std::make_pair(strUuid, m)); 510 511 serviceLogVerbose(("Added machine \"%ls\"\n", strUuid.raw())); 481 512 482 513 } while (0); … … 485 516 } 486 517 487 static void machineRemove(mapVMIter it) 488 { 518 /** 519 * Removes a specified machine from the list of handled machines. 520 * 521 * @return IPRT status code. 522 * @param strUuid UUID of the specified machine. 523 */ 524 static int machineRemove(const Bstr &strUuid) 525 { 526 int rc = RTCritSectEnter(&g_MapCritSect); 527 if (RT_SUCCESS(rc)) 528 { 529 mapVMIter it = g_mapVM.find(strUuid); 530 if (it != g_mapVM.end()) 531 { 532 /* Must log before erasing the iterator because of the UUID ref! */ 533 serviceLogVerbose(("Removing machine \"%ls\"\n", strUuid.raw())); 534 535 /* 536 * Remove machine from map. 537 */ 538 g_mapVM.erase(it); 539 } 540 else 541 { 542 serviceLogVerbose(("Warning: Removing not added machine \"%ls\"\n", strUuid.raw())); 543 rc = VERR_NOT_FOUND; 544 } 545 546 int rc2 = RTCritSectLeave(&g_MapCritSect); 547 if (RT_SUCCESS(rc)) 548 rc = rc2; 549 } 550 551 return rc; 552 } 553 554 /** 555 * Updates a specified machine according to its current machine state. 556 * That currently also could mean that a machine gets removed if it doesn't 557 * fit in our criteria anymore or a machine gets added if we need to handle 558 * it now (and didn't before). 559 * 560 * @return IPRT status code. 561 * @param strUuid UUID of the specified machine. 562 * @param enmState The machine's current state. 563 */ 564 static int machineUpdate(const Bstr &strUuid, MachineState_T enmState) 565 { 566 int rc = VINF_SUCCESS; 567 568 mapVMIter it = g_mapVM.find(strUuid); 569 if (it == g_mapVM.end()) 570 { 571 if (machineHandled(strUuid)) 572 { 573 rc = machineAdd(strUuid); 574 if (RT_SUCCESS(rc)) 575 it = g_mapVM.find(strUuid); 576 } 577 else 578 { 579 serviceLogVerbose(("Machine \"%ls\" (state: %u) does not need to be updated\n", 580 strUuid.raw(), enmState)); 581 } 582 } 583 489 584 if (it != g_mapVM.end()) 490 585 { 491 /* Must log before erasing the iterator because of the UUID ref! */492 serviceLogVerbose(("Removing machine \"%ls\"\n", it->first.raw()));493 494 586 /* 495 * Remove machine from map.587 * Ballooning stuff - start. 496 588 */ 497 g_mapVM.erase(it); 498 } 499 } 500 501 static int machineUpdate(const ComPtr<IMachine> &rptrMachine, MachineState_T enmState) 502 { 503 if ( !balloonGetMaxSize(rptrMachine) 504 || !machineIsRunning(enmState)) 505 { 506 return VINF_SUCCESS; /* Machine is not required to be added. */ 507 } 508 return machineAdd(rptrMachine); 509 } 510 511 static int machineUpdate(mapVMIter it, MachineState_T enmState) 512 { 513 Assert(it != g_mapVM.end()); 514 515 if ( !balloonIsRequired(it) 516 || !machineIsRunning(enmState)) 517 { 518 machineRemove(it); 519 return VINF_SUCCESS; 520 } 521 522 return balloonUpdate(it); 523 } 524 525 static int getMetric(mapVMIterConst it, const Bstr& strName, LONG *pulData) 526 { 527 AssertPtrReturn(pulData, VERR_INVALID_PARAMETER); 589 590 /* Our actual ballooning criteria. */ 591 if ( !balloonIsRequired(&it->second) 592 || !machineIsRunning(enmState)) 593 { 594 /* Current machine is not suited for ballooning anymore - 595 * remove it from our map. */ 596 rc = machineRemove(strUuid); 597 } 598 else 599 { 600 rc = balloonUpdate(strUuid, &it->second); 601 AssertRC(rc); 602 } 603 } 604 605 /* 606 * Ballooning stuff - end. 607 */ 608 609 return rc; 610 } 611 612 /** 613 * Retrieves a metric from a specified machine. 614 * 615 * @return IPRT status code. 616 * @param pMachine Pointer to the machine's internal structure. 617 * @param strName Name of metric to retrieve. 618 * @param pulData Pointer to value to retrieve the actual metric value. 619 */ 620 static int getMetric(PVBOXBALLOONCTRL_MACHINE pMachine, const Bstr& strName, LONG *pulData) 621 { 622 AssertPtrReturn(pMachine, VERR_INVALID_POINTER); 623 AssertPtrReturn(pulData, VERR_INVALID_POINTER); 528 624 529 625 /* Input. */ 530 626 com::SafeArray<BSTR> metricNames(1); 531 627 com::SafeIfaceArray<IUnknown> metricObjects(1); 532 it->second.machine.queryInterfaceTo(&metricObjects[0]);628 pMachine->machine.queryInterfaceTo(&metricObjects[0]); 533 629 534 630 /* Output. */ … … 545 641 strName.cloneTo(&metricNames[0]); 546 642 #ifdef VBOX_BALLOONCTRL_GLOBAL_PERFCOL 643 Assert(!g_pPerfCollector.isNull()); 547 644 HRESULT hrc = g_pPerfCollector->QueryMetricsData( 548 645 #else 549 HRESULT hrc = it->second.collector->QueryMetricsData( 646 Assert(!pMachine->collector.isNull()); 647 HRESULT hrc = pMachine->collector->QueryMetricsData( 550 648 #endif 551 649 ComSafeArrayAsInParam(metricNames), … … 590 688 * 591 689 * @return unsigned long Balloon size (in MB) to set, 0 if no ballooning required. 592 * @param rptrMachine Pointer to specified machine.690 * @param rptrMachine Pointer to interface of specified machine. 593 691 */ 594 692 static unsigned long balloonGetMaxSize(const ComPtr<IMachine> &rptrMachine) … … 629 727 630 728 /** 631 * Determines whether ballooning is required to the sp cified VM.729 * Determines whether ballooning is required to the specified machine. 632 730 * 633 * @return bool True if ballooning is required, false if not. 634 * @param it Iterator pointing to the VM to be processed. 635 */ 636 static bool balloonIsRequired(mapVMIter it) 637 { 731 * @return bool True if ballooning is required, false if not. 732 * @param strUuid UUID of the specified machine. 733 */ 734 static bool balloonIsRequired(PVBOXBALLOONCTRL_MACHINE pMachine) 735 { 736 AssertPtrReturn(pMachine, false); 737 638 738 /* Only do ballooning if we have a maximum balloon size set. */ 639 it->second.ulBalloonSizeMax = balloonGetMaxSize(it->second.machine); 640 641 return it->second.ulBalloonSizeMax ? true : false; 739 pMachine->ulBalloonSizeMax = pMachine->machine.isNull() 740 ? 0 : balloonGetMaxSize(pMachine->machine); 741 742 return pMachine->ulBalloonSizeMax ? true : false; 642 743 } 643 744 … … 647 748 * 648 749 * @return IPRT status code. 649 * @param it Iterator pointing to the VM to be processed. 650 */ 651 static int balloonUpdate(mapVMIterConst it) 652 { 750 * @param strUuid UUID of the specified machine. 751 * @param pMachine Pointer to the machine's internal structure. 752 */ 753 static int balloonUpdate(const Bstr &strUuid, PVBOXBALLOONCTRL_MACHINE pMachine) 754 { 755 AssertPtrReturn(pMachine, VERR_INVALID_POINTER); 756 653 757 /* 654 758 * Get metrics collected at this point. 655 759 */ 656 760 LONG lMemFree, lBalloonCur; 657 int vrc = getMetric( it, L"Guest/RAM/Usage/Free", &lMemFree);761 int vrc = getMetric(pMachine, L"Guest/RAM/Usage/Free", &lMemFree); 658 762 if (RT_SUCCESS(vrc)) 659 vrc = getMetric( it, L"Guest/RAM/Usage/Balloon", &lBalloonCur);763 vrc = getMetric(pMachine, L"Guest/RAM/Usage/Balloon", &lBalloonCur); 660 764 661 765 if (RT_SUCCESS(vrc)) … … 666 770 { 667 771 #ifdef DEBUG 668 serviceLogVerbose(("%ls: No metrics available yet!\n", it->first.raw()));772 serviceLogVerbose(("%ls: No metrics available yet!\n", strUuid.raw())); 669 773 #endif 670 774 return VINF_SUCCESS; … … 675 779 676 780 serviceLogVerbose(("%ls: Balloon: %ld, Free mem: %ld, Max ballon: %ld\n", 677 it->first.raw(),678 lBalloonCur, lMemFree, it->second.ulBalloonSizeMax));781 strUuid.raw(), 782 lBalloonCur, lMemFree, pMachine->ulBalloonSizeMax)); 679 783 680 784 /* Calculate current balloon delta. */ 681 long lDelta = getlBalloonDelta(lBalloonCur, lMemFree, it->second.ulBalloonSizeMax);785 long lDelta = getlBalloonDelta(lBalloonCur, lMemFree, pMachine->ulBalloonSizeMax); 682 786 if (lDelta) /* Only do ballooning if there's really smth. to change ... */ 683 787 { … … 686 790 687 791 serviceLog("%ls: %s balloon by %ld to %ld ...\n", 688 it->first.raw(),792 strUuid.raw(), 689 793 lDelta > 0 ? "Inflating" : "Deflating", lDelta, lBalloonCur); 690 794 … … 692 796 693 797 /* Open a session for the VM. */ 694 CHECK_ERROR( it->second.machine, LockMachine(g_pSession, LockType_Shared));798 CHECK_ERROR(pMachine->machine, LockMachine(g_pSession, LockType_Shared)); 695 799 696 800 do … … 706 810 else 707 811 serviceLog("Error: Unable to set new balloon size %ld for machine \"%ls\", rc=%Rhrc", 708 lBalloonCur, it->first.raw(), rc);812 lBalloonCur, strUuid.raw(), rc); 709 813 } while (0); 710 814 … … 715 819 else 716 820 serviceLog("Error: Unable to retrieve metrics for machine \"%ls\", rc=%Rrc", 717 it->first.raw(), vrc);821 strUuid.raw(), vrc); 718 822 return vrc; 719 823 } … … 781 885 } 782 886 783 MachineState_T machineState; 784 CHECK_ERROR_BREAK(machines[i], COMGETTER(State)(&machineState)); 785 786 if (g_fVerbose) 787 serviceLogVerbose(("Processing machine \"%ls\" (state: %ld)\n", 788 strUUID.raw(), machineState)); 789 790 if (machineIsRunning(machineState)) 791 { 792 rc = machineAdd(machines[i]); 793 if (RT_FAILURE(rc)) 794 break; 795 } 887 rc = machineAdd(strUUID); 888 if (RT_FAILURE(rc)) 889 break; 796 890 } 797 891 } … … 826 920 if (SUCCEEDED(hrc)) 827 921 { 828 rc = machineUpdate(it , machineState);922 rc = machineUpdate(it->first /* UUID */, machineState); 829 923 if (RT_FAILURE(rc)) 830 924 break;
Note:
See TracChangeset
for help on using the changeset viewer.