Changeset 44288 in vbox for trunk/src/VBox/Main/src-client
- Timestamp:
- Jan 14, 2013 6:22:18 PM (12 years ago)
- svn:sync-xref-src-repo-rev:
- 83197
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Main/src-client/ConsoleImpl.cpp
r44191 r44288 5962 5962 AutoCaller autoCaller(this); 5963 5963 AssertComRCReturnVoid(autoCaller.rc()); 5964 5965 5964 fireStateChangedEvent(mEventSource, machineState); 5966 5965 } … … 6329 6328 HRESULT Console::powerUp(IProgress **aProgress, bool aPaused) 6330 6329 { 6330 6331 6331 LogFlowThisFuncEnter(); 6332 6332 LogFlowThisFunc(("mMachineState=%d\n", mMachineState)); … … 6343 6343 bool fBeganPoweringUp = false; 6344 6344 6345 LONG cOperations = 1; 6346 LONG ulTotalOperationsWeight = 1; 6347 6345 6348 try 6346 6349 { 6350 6347 6351 if (Global::IsOnlineOrTransient(mMachineState)) 6348 6352 throw setError(VBOX_E_INVALID_VM_STATE, … … 6361 6365 if (FAILED(rc)) 6362 6366 throw rc; 6367 6363 6368 #if 0 /** @todo we should save it afterwards, but that isn't necessarily a good idea. Find a better place for this (VBoxSVC). */ 6364 6369 if (fTeleporterEnabled) … … 6391 6396 else 6392 6397 progressDesc = tr("Starting virtual machine"); 6393 if ( mMachineState == MachineState_Saved 6398 6399 /* Check all types of shared folders and compose a single list */ 6400 SharedFolderDataMap sharedFolders; 6401 { 6402 /* first, insert global folders */ 6403 for (SharedFolderDataMap::const_iterator it = m_mapGlobalSharedFolders.begin(); 6404 it != m_mapGlobalSharedFolders.end(); 6405 ++it) 6406 { 6407 const SharedFolderData &d = it->second; 6408 sharedFolders[it->first] = d; 6409 } 6410 6411 /* second, insert machine folders */ 6412 for (SharedFolderDataMap::const_iterator it = m_mapMachineSharedFolders.begin(); 6413 it != m_mapMachineSharedFolders.end(); 6414 ++it) 6415 { 6416 const SharedFolderData &d = it->second; 6417 sharedFolders[it->first] = d; 6418 } 6419 6420 /* third, insert console folders */ 6421 for (SharedFolderMap::const_iterator it = m_mapSharedFolders.begin(); 6422 it != m_mapSharedFolders.end(); 6423 ++it) 6424 { 6425 SharedFolder *pSF = it->second; 6426 AutoCaller sfCaller(pSF); 6427 AutoReadLock sfLock(pSF COMMA_LOCKVAL_SRC_POS); 6428 sharedFolders[it->first] = SharedFolderData(pSF->getHostPath(), 6429 pSF->isWritable(), 6430 pSF->isAutoMounted()); 6431 } 6432 } 6433 6434 Bstr savedStateFile; 6435 6436 /* 6437 * Saved VMs will have to prove that their saved states seem kosher. 6438 */ 6439 if (mMachineState == MachineState_Saved) 6440 { 6441 rc = mMachine->COMGETTER(StateFilePath)(savedStateFile.asOutParam()); 6442 if (FAILED(rc)) 6443 throw rc; 6444 ComAssertRet(!savedStateFile.isEmpty(), E_FAIL); 6445 int vrc = SSMR3ValidateFile(Utf8Str(savedStateFile).c_str(), false /* fChecksumIt */); 6446 if (RT_FAILURE(vrc)) 6447 throw setError(VBOX_E_FILE_ERROR, 6448 tr("VM cannot start because the saved state file '%ls' is invalid (%Rrc). Delete the saved state prior to starting the VM"), 6449 savedStateFile.raw(), vrc); 6450 } 6451 6452 /* Setup task object and thread to carry out the operaton 6453 * Asycnhronously */ 6454 std::auto_ptr<VMPowerUpTask> task(new VMPowerUpTask(this, pPowerupProgress)); 6455 ComAssertComRCRetRC(task->rc()); 6456 6457 task->mConfigConstructor = configConstructor; 6458 task->mSharedFolders = sharedFolders; 6459 task->mStartPaused = aPaused; 6460 if (mMachineState == MachineState_Saved) 6461 task->mSavedStateFile = savedStateFile; 6462 task->mTeleporterEnabled = fTeleporterEnabled; 6463 task->mEnmFaultToleranceState = enmFaultToleranceState; 6464 6465 /* Reset differencing hard disks for which autoReset is true, 6466 * but only if the machine has no snapshots OR the current snapshot 6467 * is an OFFLINE snapshot; otherwise we would reset the current 6468 * differencing image of an ONLINE snapshot which contains the disk 6469 * state of the machine while it was previously running, but without 6470 * the corresponding machine state, which is equivalent to powering 6471 * off a running machine and not good idea 6472 */ 6473 ComPtr<ISnapshot> pCurrentSnapshot; 6474 rc = mMachine->COMGETTER(CurrentSnapshot)(pCurrentSnapshot.asOutParam()); 6475 if (FAILED(rc)) 6476 throw rc; 6477 6478 BOOL fCurrentSnapshotIsOnline = false; 6479 if (pCurrentSnapshot) 6480 { 6481 rc = pCurrentSnapshot->COMGETTER(Online)(&fCurrentSnapshotIsOnline); 6482 if (FAILED(rc)) 6483 throw rc; 6484 } 6485 6486 if (!fCurrentSnapshotIsOnline) 6487 { 6488 LogFlowThisFunc(("Looking for immutable images to reset\n")); 6489 6490 com::SafeIfaceArray<IMediumAttachment> atts; 6491 rc = mMachine->COMGETTER(MediumAttachments)(ComSafeArrayAsOutParam(atts)); 6492 if (FAILED(rc)) 6493 throw rc; 6494 6495 for (size_t i = 0; 6496 i < atts.size(); 6497 ++i) 6498 { 6499 DeviceType_T devType; 6500 rc = atts[i]->COMGETTER(Type)(&devType); 6501 /** @todo later applies to floppies as well */ 6502 if (devType == DeviceType_HardDisk) 6503 { 6504 ComPtr<IMedium> pMedium; 6505 rc = atts[i]->COMGETTER(Medium)(pMedium.asOutParam()); 6506 if (FAILED(rc)) 6507 throw rc; 6508 6509 /* needs autoreset? */ 6510 BOOL autoReset = FALSE; 6511 rc = pMedium->COMGETTER(AutoReset)(&autoReset); 6512 if (FAILED(rc)) 6513 throw rc; 6514 6515 if (autoReset) 6516 { 6517 ComPtr<IProgress> pResetProgress; 6518 rc = pMedium->Reset(pResetProgress.asOutParam()); 6519 if (FAILED(rc)) 6520 throw rc; 6521 6522 /* save for later use on the powerup thread */ 6523 task->hardDiskProgresses.push_back(pResetProgress); 6524 } 6525 } 6526 } 6527 } 6528 else 6529 LogFlowThisFunc(("Machine has a current snapshot which is online, skipping immutable images reset\n")); 6530 6531 /* setup task object and thread to carry out the operation 6532 * asynchronously */ 6533 6534 #ifdef VBOX_WITH_EXTPACK 6535 mptrExtPackManager->dumpAllToReleaseLog(); 6536 #endif 6537 6538 #ifdef RT_OS_SOLARIS 6539 /* setup host core dumper for the VM */ 6540 Bstr value; 6541 HRESULT hrc = mMachine->GetExtraData(Bstr("VBoxInternal2/CoreDumpEnabled").raw(), value.asOutParam()); 6542 if (SUCCEEDED(hrc) && value == "1") 6543 { 6544 Bstr coreDumpDir, coreDumpReplaceSys, coreDumpLive; 6545 mMachine->GetExtraData(Bstr("VBoxInternal2/CoreDumpDir").raw(), coreDumpDir.asOutParam()); 6546 mMachine->GetExtraData(Bstr("VBoxInternal2/CoreDumpReplaceSystemDump").raw(), coreDumpReplaceSys.asOutParam()); 6547 mMachine->GetExtraData(Bstr("VBoxInternal2/CoreDumpLive").raw(), coreDumpLive.asOutParam()); 6548 6549 uint32_t fCoreFlags = 0; 6550 if ( coreDumpReplaceSys.isEmpty() == false 6551 && Utf8Str(coreDumpReplaceSys).toUInt32() == 1) 6552 fCoreFlags |= RTCOREDUMPER_FLAGS_REPLACE_SYSTEM_DUMP; 6553 6554 if ( coreDumpLive.isEmpty() == false 6555 && Utf8Str(coreDumpLive).toUInt32() == 1) 6556 fCoreFlags |= RTCOREDUMPER_FLAGS_LIVE_CORE; 6557 6558 Utf8Str strDumpDir(coreDumpDir); 6559 const char *pszDumpDir = strDumpDir.c_str(); 6560 if ( pszDumpDir 6561 && *pszDumpDir == '\0') 6562 pszDumpDir = NULL; 6563 6564 int vrc; 6565 if ( pszDumpDir 6566 && !RTDirExists(pszDumpDir)) 6567 { 6568 /* 6569 * Try create the directory. 6570 */ 6571 vrc = RTDirCreateFullPath(pszDumpDir, 0700); 6572 if (RT_FAILURE(vrc)) 6573 throw setError(E_FAIL, "Failed to setup CoreDumper. Couldn't create dump directory '%s' (%Rrc)\n", pszDumpDir, vrc); 6574 } 6575 6576 vrc = RTCoreDumperSetup(pszDumpDir, fCoreFlags); 6577 if (RT_FAILURE(vrc)) 6578 throw setError(E_FAIL, "Failed to setup CoreDumper (%Rrc)", vrc); 6579 else 6580 LogRel(("CoreDumper setup successful. pszDumpDir=%s fFlags=%#x\n", pszDumpDir ? pszDumpDir : ".", fCoreFlags)); 6581 } 6582 #endif 6583 6584 6585 // If there is immutable drive the process that. 6586 VMPowerUpTask::ProgressList progresses(task->hardDiskProgresses); 6587 if (aProgress && progresses.size() > 0){ 6588 6589 for (VMPowerUpTask::ProgressList::const_iterator it = progresses.begin(); it != progresses.end(); ++it) 6590 { 6591 ++cOperations; 6592 ulTotalOperationsWeight += 1; 6593 } 6594 rc = pPowerupProgress->init(static_cast<IConsole *>(this), 6595 progressDesc.raw(), 6596 TRUE, // Cancelable 6597 cOperations, 6598 ulTotalOperationsWeight, 6599 Bstr(tr("Starting Hard Disk operations")).raw(), 6600 1, 6601 NULL); 6602 AssertComRCReturnRC(rc); 6603 } 6604 else if ( mMachineState == MachineState_Saved 6394 6605 || (!fTeleporterEnabled && !fFaultToleranceSyncEnabled)) 6606 { 6395 6607 rc = pPowerupProgress->init(static_cast<IConsole *>(this), 6396 6608 progressDesc.raw(), 6397 6609 FALSE /* aCancelable */); 6398 else 6399 if (fTeleporterEnabled) 6610 } 6611 else if (fTeleporterEnabled) 6612 { 6400 6613 rc = pPowerupProgress->init(static_cast<IConsole *>(this), 6401 6614 progressDesc.raw(), … … 6406 6619 1 /* ulFirstOperationWeight */, 6407 6620 NULL); 6408 else 6409 if (fFaultToleranceSyncEnabled) 6621 } 6622 else if (fFaultToleranceSyncEnabled) 6623 { 6410 6624 rc = pPowerupProgress->init(static_cast<IConsole *>(this), 6411 6625 progressDesc.raw(), … … 6416 6630 1 /* ulFirstOperationWeight */, 6417 6631 NULL); 6632 } 6418 6633 6419 6634 if (FAILED(rc)) … … 6430 6645 } 6431 6646 fBeganPoweringUp = true; 6647 6648 LogFlowThisFunc(("Checking if canceled...\n")); 6649 BOOL fCanceled; 6650 rc = pPowerupProgress->COMGETTER(Canceled)(&fCanceled); 6651 if (FAILED(rc)) 6652 throw rc; 6653 6654 if (fCanceled) 6655 { 6656 LogFlowThisFunc(("Canceled in BeginPowerUp\n")); 6657 throw setError(E_FAIL, tr("Powerup was canceled")); 6658 } 6659 LogFlowThisFunc(("Not canceled yet.\n")); 6432 6660 6433 6661 /** @todo this code prevents starting a VM with unavailable bridged … … 6490 6718 throw rc; 6491 6719 6492 /* Check all types of shared folders and compose a single list */6493 SharedFolderDataMap sharedFolders;6494 {6495 /* first, insert global folders */6496 for (SharedFolderDataMap::const_iterator it = m_mapGlobalSharedFolders.begin();6497 it != m_mapGlobalSharedFolders.end();6498 ++it)6499 {6500 const SharedFolderData &d = it->second;6501 sharedFolders[it->first] = d;6502 }6503 6504 /* second, insert machine folders */6505 for (SharedFolderDataMap::const_iterator it = m_mapMachineSharedFolders.begin();6506 it != m_mapMachineSharedFolders.end();6507 ++it)6508 {6509 const SharedFolderData &d = it->second;6510 sharedFolders[it->first] = d;6511 }6512 6513 /* third, insert console folders */6514 for (SharedFolderMap::const_iterator it = m_mapSharedFolders.begin();6515 it != m_mapSharedFolders.end();6516 ++it)6517 {6518 SharedFolder *pSF = it->second;6519 AutoCaller sfCaller(pSF);6520 AutoReadLock sfLock(pSF COMMA_LOCKVAL_SRC_POS);6521 sharedFolders[it->first] = SharedFolderData(pSF->getHostPath(),6522 pSF->isWritable(),6523 pSF->isAutoMounted());6524 }6525 }6526 6527 Bstr savedStateFile;6528 6529 /*6530 * Saved VMs will have to prove that their saved states seem kosher.6531 */6532 if (mMachineState == MachineState_Saved)6533 {6534 rc = mMachine->COMGETTER(StateFilePath)(savedStateFile.asOutParam());6535 if (FAILED(rc))6536 throw rc;6537 ComAssertRet(!savedStateFile.isEmpty(), E_FAIL);6538 int vrc = SSMR3ValidateFile(Utf8Str(savedStateFile).c_str(), false /* fChecksumIt */);6539 if (RT_FAILURE(vrc))6540 throw setError(VBOX_E_FILE_ERROR,6541 tr("VM cannot start because the saved state file '%ls' is invalid (%Rrc). Delete the saved state prior to starting the VM"),6542 savedStateFile.raw(), vrc);6543 }6544 6545 LogFlowThisFunc(("Checking if canceled...\n"));6546 BOOL fCanceled;6547 rc = pPowerupProgress->COMGETTER(Canceled)(&fCanceled);6548 if (FAILED(rc))6549 throw rc;6550 if (fCanceled)6551 {6552 LogFlowThisFunc(("Canceled in BeginPowerUp\n"));6553 throw setError(E_FAIL, tr("Powerup was canceled"));6554 }6555 LogFlowThisFunc(("Not canceled yet.\n"));6556 6557 6720 /* setup task object and thread to carry out the operation 6558 6721 * asynchronously */ 6559 6560 std::auto_ptr<VMPowerUpTask> task(new VMPowerUpTask(this, pPowerupProgress)); 6561 ComAssertComRCRetRC(task->rc()); 6562 6563 task->mConfigConstructor = configConstructor; 6564 task->mSharedFolders = sharedFolders; 6565 task->mStartPaused = aPaused; 6566 if (mMachineState == MachineState_Saved) 6567 task->mSavedStateFile = savedStateFile; 6568 task->mTeleporterEnabled = fTeleporterEnabled; 6569 task->mEnmFaultToleranceState = enmFaultToleranceState; 6570 6571 /* Reset differencing hard disks for which autoReset is true, 6572 * but only if the machine has no snapshots OR the current snapshot 6573 * is an OFFLINE snapshot; otherwise we would reset the current 6574 * differencing image of an ONLINE snapshot which contains the disk 6575 * state of the machine while it was previously running, but without 6576 * the corresponding machine state, which is equivalent to powering 6577 * off a running machine and not good idea 6578 */ 6579 ComPtr<ISnapshot> pCurrentSnapshot; 6580 rc = mMachine->COMGETTER(CurrentSnapshot)(pCurrentSnapshot.asOutParam()); 6581 if (FAILED(rc)) 6582 throw rc; 6583 6584 BOOL fCurrentSnapshotIsOnline = false; 6585 if (pCurrentSnapshot) 6586 { 6587 rc = pCurrentSnapshot->COMGETTER(Online)(&fCurrentSnapshotIsOnline); 6588 if (FAILED(rc)) 6589 throw rc; 6590 } 6591 6592 if (!fCurrentSnapshotIsOnline) 6593 { 6594 LogFlowThisFunc(("Looking for immutable images to reset\n")); 6595 6596 com::SafeIfaceArray<IMediumAttachment> atts; 6597 rc = mMachine->COMGETTER(MediumAttachments)(ComSafeArrayAsOutParam(atts)); 6598 if (FAILED(rc)) 6599 throw rc; 6600 6601 for (size_t i = 0; 6602 i < atts.size(); 6603 ++i) 6604 { 6605 DeviceType_T devType; 6606 rc = atts[i]->COMGETTER(Type)(&devType); 6607 /** @todo later applies to floppies as well */ 6608 if (devType == DeviceType_HardDisk) 6609 { 6610 ComPtr<IMedium> pMedium; 6611 rc = atts[i]->COMGETTER(Medium)(pMedium.asOutParam()); 6612 if (FAILED(rc)) 6613 throw rc; 6614 6615 /* needs autoreset? */ 6616 BOOL autoReset = FALSE; 6617 rc = pMedium->COMGETTER(AutoReset)(&autoReset); 6618 if (FAILED(rc)) 6619 throw rc; 6620 6621 if (autoReset) 6622 { 6623 ComPtr<IProgress> pResetProgress; 6624 rc = pMedium->Reset(pResetProgress.asOutParam()); 6625 if (FAILED(rc)) 6626 throw rc; 6627 6628 /* save for later use on the powerup thread */ 6629 task->hardDiskProgresses.push_back(pResetProgress); 6630 } 6631 } 6632 } 6633 } 6634 else 6635 LogFlowThisFunc(("Machine has a current snapshot which is online, skipping immutable images reset\n")); 6636 6637 #ifdef VBOX_WITH_EXTPACK 6638 mptrExtPackManager->dumpAllToReleaseLog(); 6639 #endif 6640 6641 #ifdef RT_OS_SOLARIS 6642 /* setup host core dumper for the VM */ 6643 Bstr value; 6644 HRESULT hrc = mMachine->GetExtraData(Bstr("VBoxInternal2/CoreDumpEnabled").raw(), value.asOutParam()); 6645 if (SUCCEEDED(hrc) && value == "1") 6646 { 6647 Bstr coreDumpDir, coreDumpReplaceSys, coreDumpLive; 6648 mMachine->GetExtraData(Bstr("VBoxInternal2/CoreDumpDir").raw(), coreDumpDir.asOutParam()); 6649 mMachine->GetExtraData(Bstr("VBoxInternal2/CoreDumpReplaceSystemDump").raw(), coreDumpReplaceSys.asOutParam()); 6650 mMachine->GetExtraData(Bstr("VBoxInternal2/CoreDumpLive").raw(), coreDumpLive.asOutParam()); 6651 6652 uint32_t fCoreFlags = 0; 6653 if ( coreDumpReplaceSys.isEmpty() == false 6654 && Utf8Str(coreDumpReplaceSys).toUInt32() == 1) 6655 { 6656 fCoreFlags |= RTCOREDUMPER_FLAGS_REPLACE_SYSTEM_DUMP; 6657 } 6658 6659 if ( coreDumpLive.isEmpty() == false 6660 && Utf8Str(coreDumpLive).toUInt32() == 1) 6661 { 6662 fCoreFlags |= RTCOREDUMPER_FLAGS_LIVE_CORE; 6663 } 6664 6665 Utf8Str strDumpDir(coreDumpDir); 6666 const char *pszDumpDir = strDumpDir.c_str(); 6667 if ( pszDumpDir 6668 && *pszDumpDir == '\0') 6669 pszDumpDir = NULL; 6670 6671 int vrc; 6672 if ( pszDumpDir 6673 && !RTDirExists(pszDumpDir)) 6674 { 6675 /* 6676 * Try create the directory. 6677 */ 6678 vrc = RTDirCreateFullPath(pszDumpDir, 0700); 6679 if (RT_FAILURE(vrc)) 6680 throw setError(E_FAIL, "Failed to setup CoreDumper. Couldn't create dump directory '%s' (%Rrc)\n", pszDumpDir, vrc); 6681 } 6682 6683 vrc = RTCoreDumperSetup(pszDumpDir, fCoreFlags); 6684 if (RT_FAILURE(vrc)) 6685 throw setError(E_FAIL, "Failed to setup CoreDumper (%Rrc)", vrc); 6686 else 6687 LogRel(("CoreDumper setup successful. pszDumpDir=%s fFlags=%#x\n", pszDumpDir ? pszDumpDir : ".", fCoreFlags)); 6688 } 6689 #endif 6690 6691 /* pass the progress object to the caller if requested */ 6692 if (aProgress) 6693 { 6694 if (task->hardDiskProgresses.size() == 0) 6695 { 6696 /* there are no other operations to track, return the powerup 6697 * progress only */ 6698 pPowerupProgress.queryInterfaceTo(aProgress); 6699 } 6700 else 6701 { 6702 // Create a simple progress object 6703 ComObjPtr<Progress> pProgress; 6704 pProgress.createObject(); 6705 6706 // Assign hard disk progresses to the progresses list 6707 VMPowerUpTask::ProgressList progresses(task->hardDiskProgresses); 6708 6709 // Setup params to be used to initialize Progress object properties. 6710 ULONG cOperations = 1; 6711 ULONG ulTotalOperationsWeight = 1; 6712 6713 // Go round them and set number of operations and weight. 6714 for (VMPowerUpTask::ProgressList::const_iterator it = progresses.begin(); it != progresses.end(); ++it) 6715 { 6716 ++cOperations; 6717 ulTotalOperationsWeight += 1; 6718 } 6719 6720 rc = pProgress->init(static_cast<IConsole *>(this), 6721 progressDesc.raw(), 6722 TRUE, // Cancelable 6723 cOperations, 6724 ulTotalOperationsWeight, 6725 Bstr(tr("Starting Hard Disk operations")).raw(), // first sub-op decription 6726 1 ); 6727 AssertComRCReturnRC(rc); 6728 6729 // Perform all the necessary operations. 6730 for (VMPowerUpTask::ProgressList::const_iterator it = progresses.begin(); it != progresses.end(); ++it) 6731 { 6732 rc = pProgress->SetNextOperation(BstrFmt(tr("Disk Image Reset Operation - Immutable Image")).raw(), 1); 6733 AssertComRCReturnRC(rc); 6734 rc = pProgress.queryInterfaceTo(aProgress); 6735 AssertComRCReturnRC(rc); 6736 } 6737 6738 // Now do the power up. 6722 if (aProgress){ 6739 6723 rc = pPowerupProgress.queryInterfaceTo(aProgress); 6740 6724 AssertComRCReturnRC(rc); 6741 }6742 6725 } 6743 6726 … … 6757 6740 setMachineState(MachineState_Restoring); 6758 6741 else if (fTeleporterEnabled) 6759 6742 setMachineState(MachineState_TeleportingIn); 6760 6743 else if (enmFaultToleranceState == FaultToleranceState_Standby) 6761 6744 setMachineState(MachineState_FaultTolerantSyncing); … … 8812 8795 HRESULT rc2 = (*it)->WaitForCompletion(-1); 8813 8796 AssertComRC(rc2); 8797 8798 rc = task->mProgress->SetNextOperation(BstrFmt(tr("Disk Image Reset Operation - Immutable Image")).raw(), 1); 8799 AssertComRCReturnRC(rc); 8814 8800 } 8815 8801
Note:
See TracChangeset
for help on using the changeset viewer.