Changeset 13580 in vbox for trunk/src/VBox/Main/ConsoleImpl.cpp
- Timestamp:
- Oct 27, 2008 2:04:18 PM (16 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Main/ConsoleImpl.cpp
r13556 r13580 1 /* $Id$ */ 2 1 3 /** @file 2 4 * … … 5 7 6 8 /* 7 * Copyright (C) 2006-200 7Sun Microsystems, Inc.9 * Copyright (C) 2006-2008 Sun Microsystems, Inc. 8 10 * 9 11 * This file is part of VirtualBox Open Source Edition (OSE), as … … 60 62 #include "Logging.h" 61 63 64 #include <VBox/com/array.h> 65 62 66 #include <iprt/string.h> 63 67 #include <iprt/asm.h> … … 187 191 , mSetVMErrorCallback (NULL), mConfigConstructor (NULL), mStartPaused (false) {} 188 192 193 ~VMPowerUpTask() 194 { 195 /* No null output parameters in IPC*/ 196 MediaState_T dummy; 197 198 /* if the locked media list is not empty, treat as a failure and 199 * unlock all */ 200 for (LockedMedia::const_iterator it = lockedMedia.begin(); 201 it != lockedMedia.end(); ++ it) 202 { 203 if (it->second) 204 it->first->UnlockWrite (&dummy); 205 else 206 it->first->UnlockRead (&dummy); 207 } 208 } 209 189 210 PFNVMATERROR mSetVMErrorCallback; 190 211 PFNCFGMCONSTRUCTOR mConfigConstructor; … … 192 213 Console::SharedFolderDataMap mSharedFolders; 193 214 bool mStartPaused; 215 216 /** 217 * Successfully locked media list. The 2nd value in the pair is true if the 218 * medium is locked for writing and false if locked for reading. 219 */ 220 typedef std::list <std::pair <ComPtr <IMedium>, bool > > LockedMedia; 221 LockedMedia lockedMedia; 222 223 /** Media that need an accessibility check */ 224 typedef std::list <ComPtr <IMedium> > Media; 225 Media mediaToCheck; 194 226 }; 195 227 … … 2481 2513 case DriveState_ImageMounted: 2482 2514 { 2483 ComPtr <IDVDImage > ImagePtr;2515 ComPtr <IDVDImage2> ImagePtr; 2484 2516 rc = mDVDDrive->GetImage (ImagePtr.asOutParam()); 2485 2517 if (SUCCEEDED (rc)) 2486 rc = ImagePtr->COMGETTER( FilePath) (Path.asOutParam());2518 rc = ImagePtr->COMGETTER(Location) (Path.asOutParam()); 2487 2519 break; 2488 2520 } … … 2588 2620 case DriveState_ImageMounted: 2589 2621 { 2590 ComPtr <IFloppyImage > ImagePtr;2622 ComPtr <IFloppyImage2> ImagePtr; 2591 2623 rc = mFloppyDrive->GetImage (ImagePtr.asOutParam()); 2592 2624 if (SUCCEEDED (rc)) 2593 rc = ImagePtr->COMGETTER( FilePath) (Path.asOutParam());2625 rc = ImagePtr->COMGETTER(Location) (Path.asOutParam()); 2594 2626 break; 2595 2627 } … … 4235 4267 mMachineState); 4236 4268 4237 /* 4238 * First check whether all disks are accessible. This is not a 100% 4239 * bulletproof approach (race condition, it might become inaccessible 4240 * right after the check) but it's convenient as it will cover 99.9% 4241 * of the cases and here, we're able to provide meaningful error 4242 * information. 4243 */ 4244 ComPtr<IHardDiskAttachmentCollection> coll; 4245 mMachine->COMGETTER(HardDiskAttachments)(coll.asOutParam()); 4246 ComPtr<IHardDiskAttachmentEnumerator> enumerator; 4247 coll->Enumerate(enumerator.asOutParam()); 4248 BOOL fHasMore; 4249 while (SUCCEEDED(enumerator->HasMore(&fHasMore)) && fHasMore) 4250 { 4251 ComPtr<IHardDiskAttachment> attach; 4252 enumerator->GetNext(attach.asOutParam()); 4253 ComPtr<IHardDisk> hdd; 4254 attach->COMGETTER(HardDisk)(hdd.asOutParam()); 4255 Assert(hdd); 4256 BOOL fAccessible; 4257 HRESULT rc = hdd->COMGETTER(AllAccessible)(&fAccessible); 4258 CheckComRCReturnRC (rc); 4259 if (!fAccessible) 4260 { 4261 Bstr loc; 4262 hdd->COMGETTER(Location) (loc.asOutParam()); 4263 Bstr errMsg; 4264 hdd->COMGETTER(LastAccessError) (errMsg.asOutParam()); 4265 return setError (E_FAIL, 4266 tr ("VM cannot start because the hard disk '%ls' is not accessible " 4267 "(%ls)"), 4268 loc.raw(), errMsg.raw()); 4269 } 4270 } 4271 4272 /* now perform the same check if a ISO is mounted */ 4273 ComPtr<IDVDDrive> dvdDrive; 4274 mMachine->COMGETTER(DVDDrive)(dvdDrive.asOutParam()); 4275 ComPtr<IDVDImage> dvdImage; 4276 dvdDrive->GetImage(dvdImage.asOutParam()); 4277 if (dvdImage) 4278 { 4279 BOOL fAccessible; 4280 HRESULT rc = dvdImage->COMGETTER(Accessible)(&fAccessible); 4281 CheckComRCReturnRC (rc); 4282 if (!fAccessible) 4283 { 4284 Bstr filePath; 4285 dvdImage->COMGETTER(FilePath)(filePath.asOutParam()); 4286 /// @todo (r=dmik) grab the last access error once 4287 // IDVDImage::lastAccessError is there 4288 return setError (E_FAIL, 4289 tr ("The virtual machine could not be started because the DVD image '%ls' which is attached to it could not be found or could not be opened. Please detach the image and try again"), 4290 filePath.raw()); 4291 } 4292 } 4293 4294 /* now perform the same check if a floppy is mounted */ 4295 ComPtr<IFloppyDrive> floppyDrive; 4296 mMachine->COMGETTER(FloppyDrive)(floppyDrive.asOutParam()); 4297 ComPtr<IFloppyImage> floppyImage; 4298 floppyDrive->GetImage(floppyImage.asOutParam()); 4299 if (floppyImage) 4300 { 4301 BOOL fAccessible; 4302 HRESULT rc = floppyImage->COMGETTER(Accessible)(&fAccessible); 4303 CheckComRCReturnRC (rc); 4304 if (!fAccessible) 4305 { 4306 Bstr filePath; 4307 floppyImage->COMGETTER(FilePath)(filePath.asOutParam()); 4308 /// @todo (r=dmik) grab the last access error once 4309 // IDVDImage::lastAccessError is there 4310 return setError (E_FAIL, 4311 tr ("The virtual machine could not be started because the floppy image '%ls' which is attached to it could not be found or could not be opened. Please detach the image and try again"), 4312 filePath.raw()); 4313 } 4314 } 4315 4316 /* now the network cards will undergo a quick consistency check */ 4269 HRESULT rc = S_OK; 4270 4271 /* the network cards will undergo a quick consistency check */ 4317 4272 for (ULONG slot = 0; slot < SchemaDefs::NetworkAdapterCount; slot ++) 4318 4273 { … … 4363 4318 4364 4319 /* Read console data stored in the saved state file (if not yet done) */ 4365 { 4366 HRESULT rc = loadDataFromSavedState(); 4367 CheckComRCReturnRC (rc); 4368 } 4320 rc = loadDataFromSavedState(); 4321 CheckComRCReturnRC (rc); 4369 4322 4370 4323 /* Check all types of shared folders and compose a single list */ … … 4394 4347 if (mMachineState == MachineState_Saved) 4395 4348 { 4396 HRESULTrc = mMachine->COMGETTER(StateFilePath) (savedStateFile.asOutParam());4349 rc = mMachine->COMGETTER(StateFilePath) (savedStateFile.asOutParam()); 4397 4350 CheckComRCReturnRC (rc); 4398 4351 ComAssertRet (!!savedStateFile, E_FAIL); … … 4413 4366 else 4414 4367 progressDesc = tr ("Starting virtual machine"); 4415 progress->init (static_cast <IConsole *> (this), 4416 progressDesc, FALSE /* aCancelable */); 4368 rc = progress->init (static_cast <IConsole *> (this), 4369 progressDesc, FALSE /* aCancelable */); 4370 CheckComRCReturnRC (rc); 4417 4371 4418 4372 /* pass reference to caller if requested */ … … 4420 4374 progress.queryInterfaceTo (aProgress); 4421 4375 4422 /* setup task object and thread to carry out the operation asynchronously */ 4376 /* setup task object and thread to carry out the operation 4377 * asynchronously */ 4378 4423 4379 std::auto_ptr <VMPowerUpTask> task (new VMPowerUpTask (this, progress)); 4424 4380 ComAssertComRCRetRC (task->rc()); … … 4431 4387 task->mSavedStateFile = savedStateFile; 4432 4388 4433 HRESULT hrc = consoleInitReleaseLog (mMachine); 4434 if (FAILED (hrc)) 4435 return hrc; 4389 /* Lock all attached media in necessary mode. Note that until 4390 * setMachineState() is called below, it is OUR responsibility to unlock 4391 * media on failure (and VMPowerUpTask::lockedMedia is used for that). After 4392 * the setMachineState() call, VBoxSVC (SessionMachine::setMachineState()) 4393 * will unlock all the media upon the appropriate state change. Note that 4394 * media accessibility checks are performed on the powerup thread because 4395 * they may block. */ 4396 4397 MediaState_T mediaState; 4398 4399 /* lock all hard disks for writing and their parents for reading */ 4400 { 4401 com::SafeIfaceArray <IHardDisk2Attachment> atts; 4402 rc = mMachine-> 4403 COMGETTER(HardDisk2Attachments) (ComSafeArrayAsOutParam (atts)); 4404 CheckComRCReturnRC (rc); 4405 4406 for (size_t i = 0; i < atts.size(); ++ i) 4407 { 4408 ComPtr <IHardDisk2> hardDisk; 4409 rc = atts [i]->COMGETTER(HardDisk) (hardDisk.asOutParam()); 4410 CheckComRCReturnRC (rc); 4411 4412 bool first = true; 4413 4414 while (!hardDisk.isNull()) 4415 { 4416 if (first) 4417 { 4418 rc = hardDisk->LockWrite (&mediaState); 4419 CheckComRCReturnRC (rc); 4420 4421 task->lockedMedia.push_back (VMPowerUpTask::LockedMedia:: 4422 value_type (hardDisk, true)); 4423 first = false; 4424 } 4425 else 4426 { 4427 rc = hardDisk->LockRead (&mediaState); 4428 CheckComRCReturnRC (rc); 4429 4430 task->lockedMedia.push_back (VMPowerUpTask::LockedMedia:: 4431 value_type (hardDisk, false)); 4432 } 4433 4434 if (mediaState == MediaState_Inaccessible) 4435 task->mediaToCheck.push_back (hardDisk); 4436 4437 ComPtr <IHardDisk2> parent; 4438 rc = hardDisk->COMGETTER(Parent) (parent.asOutParam()); 4439 CheckComRCReturnRC (rc); 4440 hardDisk = parent; 4441 } 4442 } 4443 } 4444 /* lock the DVD image for reading if mounted */ 4445 { 4446 ComPtr <IDVDDrive> drive; 4447 rc = mMachine->COMGETTER(DVDDrive) (drive.asOutParam()); 4448 CheckComRCReturnRC (rc); 4449 4450 DriveState_T driveState; 4451 rc = drive->COMGETTER(State) (&driveState); 4452 CheckComRCReturnRC (rc); 4453 4454 if (driveState == DriveState_ImageMounted) 4455 { 4456 ComPtr <IDVDImage2> image; 4457 rc = drive->GetImage (image.asOutParam()); 4458 CheckComRCReturnRC (rc); 4459 4460 rc = image->LockRead (&mediaState); 4461 CheckComRCReturnRC (rc); 4462 4463 task->lockedMedia.push_back (VMPowerUpTask::LockedMedia:: 4464 value_type (image, false)); 4465 4466 if (mediaState == MediaState_Inaccessible) 4467 task->mediaToCheck.push_back (image); 4468 } 4469 } 4470 /* lock the floppy image for reading if mounted */ 4471 { 4472 ComPtr <IFloppyDrive> drive; 4473 rc = mMachine->COMGETTER(FloppyDrive) (drive.asOutParam()); 4474 CheckComRCReturnRC (rc); 4475 4476 DriveState_T driveState; 4477 rc = drive->COMGETTER(State) (&driveState); 4478 CheckComRCReturnRC (rc); 4479 4480 if (driveState == DriveState_ImageMounted) 4481 { 4482 ComPtr <IFloppyImage2> image; 4483 rc = drive->GetImage (image.asOutParam()); 4484 CheckComRCReturnRC (rc); 4485 4486 rc = image->LockRead (&mediaState); 4487 CheckComRCReturnRC (rc); 4488 4489 task->lockedMedia.push_back (VMPowerUpTask::LockedMedia:: 4490 value_type (image, false)); 4491 4492 if (mediaState == MediaState_Inaccessible) 4493 task->mediaToCheck.push_back (image); 4494 } 4495 } 4496 /* SUCCEEDED locking all media */ 4497 4498 rc = consoleInitReleaseLog (mMachine); 4499 CheckComRCReturnRC (rc); 4436 4500 4437 4501 int vrc = RTThreadCreate (NULL, Console::powerUpThread, (void *) task.get(), … … 4441 4505 E_FAIL); 4442 4506 4507 /* clear the locked media list to prevent unlocking on task destruction as 4508 * we are not going to fail after this point */ 4509 task->lockedMedia.clear(); 4510 4443 4511 /* task is now owned by powerUpThread(), so release it */ 4444 4512 task.release(); 4513 4514 /* finally, set the state: no right to fail in this method afterwards! */ 4445 4515 4446 4516 if (mMachineState == MachineState_Saved) … … 6121 6191 /* we ignore RT_SRC_POS_DECL arguments to avoid confusion of end-users */ 6122 6192 va_list va2; 6123 va_copy(va2, args); /* Have to make a copy here or GCC will break. */ 6124 Utf8Str errorMsg = Utf8StrFmt (tr ("%N.\n" 6125 "VBox status code: %d (%Vrc)"), 6126 pszFormat, &va2, rc, rc); 6127 va_end(va2); 6128 6129 /* For now, this may be called only once. Ignore subsequent calls. */ 6130 if (!task->mErrorMsg.isNull()) 6131 { 6132 #if !defined(DEBUG_bird) 6133 AssertMsgFailed (("Cannot set error to '%s': it is already set to '%s'", 6134 errorMsg.raw(), task->mErrorMsg.raw())); 6135 #endif 6136 return; 6137 } 6138 6139 task->mErrorMsg = errorMsg; 6193 va_copy (va2, args); /* Have to make a copy here or GCC will break. */ 6194 6195 /* append to the existing error message if any */ 6196 if (!task->mErrorMsg.isEmpty()) 6197 task->mErrorMsg = Utf8StrFmt ("%s.\n%N (%Vrc)", task->mErrorMsg.raw(), 6198 pszFormat, &va2, rc, rc); 6199 else 6200 task->mErrorMsg = Utf8StrFmt ("%N (%Vrc)", 6201 pszFormat, &va2, rc, rc); 6202 6203 va_end (va2); 6140 6204 } 6141 6205 … … 6432 6496 #endif 6433 6497 6434 HRESULT hrc = S_OK;6498 HRESULT rc = S_OK; 6435 6499 int vrc = VINF_SUCCESS; 6436 6500 … … 6445 6509 /* Note: no need to use addCaller() because VMPowerUpTask does that */ 6446 6510 6511 /* The lock is also used as a signal from the task initiator (which 6512 * releases it only after RTThreadCreate()) that we can start the job */ 6447 6513 AutoWriteLock alock (console); 6448 6514 … … 6450 6516 Assert (console->mpVM == NULL); 6451 6517 6452 do 6453 { 6518 try 6519 { 6520 { 6521 ErrorInfoKeeper eik (true /* aIsNull */); 6522 MultiResult mrc (S_OK); 6523 6524 /* perform a check of inaccessible media deferred in PowerUp() */ 6525 for (VMPowerUpTask::Media::const_iterator 6526 it = task->mediaToCheck.begin(); 6527 it != task->mediaToCheck.end(); ++ it) 6528 { 6529 MediaState_T mediaState; 6530 rc = (*it)->COMGETTER(State) (&mediaState); 6531 CheckComRCThrowRC (rc); 6532 6533 Assert (mediaState == MediaState_LockedRead || 6534 mediaState == MediaState_LockedWrite); 6535 6536 /* Note that we locked the medium already, so use the error 6537 * value to see if there was an accessibility failure */ 6538 6539 Bstr error; 6540 rc = (*it)->COMGETTER(LastAccessError) (error.asOutParam()); 6541 CheckComRCThrowRC (rc); 6542 6543 if (!error.isNull()) 6544 { 6545 Bstr loc; 6546 rc = (*it)->COMGETTER(Location) (loc.asOutParam()); 6547 CheckComRCThrowRC (rc); 6548 6549 /* collect multiple errors */ 6550 eik.restore(); 6551 6552 /* be in sync with MediumBase::setStateError() */ 6553 Assert (!error.isEmpty()); 6554 mrc = setError (E_FAIL, 6555 tr ("Medium '%ls' is not accessible. %ls"), 6556 loc.raw(), error.raw()); 6557 6558 eik.fetch(); 6559 } 6560 } 6561 6562 eik.restore(); 6563 CheckComRCThrowRC ((HRESULT) mrc); 6564 } 6565 6454 6566 #ifdef VBOX_WITH_VRDP 6567 6455 6568 /* Create the VRDP server. In case of headless operation, this will 6456 6569 * also create the framebuffer, required at VM creation. … … 6458 6571 ConsoleVRDPServer *server = console->consoleVRDPServer(); 6459 6572 Assert (server); 6573 6460 6574 /// @todo (dmik) 6461 6575 // does VRDP server call Console from the other thread? … … 6464 6578 vrc = server->Launch(); 6465 6579 alock.enter(); 6580 6466 6581 if (VBOX_FAILURE (vrc)) 6467 6582 { … … 6488 6603 LogRel (("Failed to launch VRDP server (%Vrc), error message: '%s'\n", 6489 6604 vrc, errMsg.raw())); 6490 hrc =setError (E_FAIL, errMsg);6491 break;6492 } 6605 throw setError (E_FAIL, errMsg); 6606 } 6607 6493 6608 #endif /* VBOX_WITH_VRDP */ 6494 6609 … … 6554 6669 ++ it) 6555 6670 { 6556 hrc = console->createSharedFolder ((*it).first, (*it).second);6557 CheckComRCBreakRC ( hrc);6671 rc = console->createSharedFolder ((*it).first, (*it).second); 6672 CheckComRCBreakRC (rc); 6558 6673 } 6559 6674 … … 6561 6676 alock.enter(); 6562 6677 6563 CheckComRCBreakRC ( hrc);6678 CheckComRCBreakRC (rc); 6564 6679 } 6565 6680 … … 6567 6682 * Capture USB devices. 6568 6683 */ 6569 hrc = console->captureUSBDevices (pVM);6570 CheckComRCBreakRC ( hrc);6684 rc = console->captureUSBDevices (pVM); 6685 CheckComRCBreakRC (rc); 6571 6686 6572 6687 /* leave the lock before a lengthy operation */ … … 6619 6734 6620 6735 /* On failure, destroy the VM */ 6621 if (FAILED ( hrc) || VBOX_FAILURE (vrc))6736 if (FAILED (rc) || VBOX_FAILURE (vrc)) 6622 6737 { 6623 6738 /* preserve existing error info */ … … 6626 6741 /* powerDown() will call VMR3Destroy() and do all necessary 6627 6742 * cleanup (VRDP, USB devices) */ 6628 HRESULT hrc2 = console->powerDown();6629 AssertComRC ( hrc2);6743 HRESULT rc2 = console->powerDown(); 6744 AssertComRC (rc2); 6630 6745 } 6631 6746 } … … 6638 6753 } 6639 6754 6640 if (SUCCEEDED ( hrc) && VBOX_FAILURE (vrc))6755 if (SUCCEEDED (rc) && VBOX_FAILURE (vrc)) 6641 6756 { 6642 6757 /* If VMR3Create() or one of the other calls in this function fail, 6643 6758 * an appropriate error message has been set in task->mErrorMsg. 6644 * However since that happens via a callback, the hrc status code in6759 * However since that happens via a callback, the rc status code in 6645 6760 * this function is not updated. 6646 6761 */ … … 6660 6775 /* Set the error message as the COM error. 6661 6776 * Progress::notifyComplete() will pick it up later. */ 6662 hrc = setError (E_FAIL, task->mErrorMsg); 6663 break; 6664 } 6665 } 6666 while (0); 6777 throw setError (E_FAIL, task->mErrorMsg); 6778 } 6779 } 6780 catch (HRESULT aRC) { rc = aRC; } 6667 6781 6668 6782 if (console->mMachineState == MachineState_Starting || … … 6695 6809 alock.leave(); 6696 6810 6697 if (SUCCEEDED ( hrc))6811 if (SUCCEEDED (rc)) 6698 6812 { 6699 6813 /* Notify the progress object of the success */ … … 6703 6817 { 6704 6818 /* The progress object will fetch the current error info */ 6705 task->mProgress->notifyComplete ( hrc);6706 6707 LogRel (("Power up failed (vrc=%Vrc, hrc=%Rhrc (%#08X))\n", vrc, hrc, hrc));6819 task->mProgress->notifyComplete (rc); 6820 6821 LogRel (("Power up failed (vrc=%Vrc, rc=%Rhrc (%#08X))\n", vrc, rc, rc)); 6708 6822 } 6709 6823 … … 6727 6841 * @return VBox status code. 6728 6842 */ 6729 static DECLCALLBACK(int) reconfigureVDI(PVM pVM, IHardDiskAttachment *hda, HRESULT *phrc) 6843 static DECLCALLBACK(int) reconfigureHardDisks(PVM pVM, IHardDisk2Attachment *hda, 6844 HRESULT *phrc) 6730 6845 { 6731 6846 LogFlowFunc (("pVM=%p hda=%p phrc=%p\n", pVM, hda, phrc)); … … 6733 6848 int rc; 6734 6849 HRESULT hrc; 6735 char *psz = NULL; 6736 BSTR str = NULL; 6850 Bstr bstr; 6737 6851 *phrc = S_OK; 6738 #define STR_CONV() do { rc = RTUtf16ToUtf8(str, &psz); RC_CHECK(); } while (0) 6739 #define STR_FREE() do { if (str) { SysFreeString(str); str = NULL; } if (psz) { RTStrFree(psz); psz = NULL; } } while (0) 6740 #define RC_CHECK() do { if (VBOX_FAILURE(rc)) { AssertMsgFailed(("rc=%Vrc\n", rc)); STR_FREE(); return rc; } } while (0) 6741 #define H() do { if (FAILED(hrc)) { AssertMsgFailed(("hrc=%Rhrc (%#x)\n", hrc, hrc)); STR_FREE(); *phrc = hrc; return VERR_GENERAL_FAILURE; } } while (0) 6852 #define RC_CHECK() do { if (VBOX_FAILURE(rc)) { AssertMsgFailed(("rc=%Vrc\n", rc)); return rc; } } while (0) 6853 #define H() do { if (FAILED(hrc)) { AssertMsgFailed(("hrc=%Rhrc (%#x)\n", hrc, hrc)); *phrc = hrc; return VERR_GENERAL_FAILURE; } } while (0) 6742 6854 6743 6855 /* 6744 6856 * Figure out which IDE device this is. 6745 6857 */ 6746 ComPtr<IHardDisk > hardDisk;6858 ComPtr<IHardDisk2> hardDisk; 6747 6859 hrc = hda->COMGETTER(HardDisk)(hardDisk.asOutParam()); H(); 6748 6860 StorageBus_T enmBus; … … 6758 6870 case StorageBus_IDE: 6759 6871 { 6760 if (lChannel >= 2 )6872 if (lChannel >= 2 || lChannel < 0) 6761 6873 { 6762 6874 AssertMsgFailed(("invalid controller channel number: %d\n", lChannel)); … … 6764 6876 } 6765 6877 6766 if (lDev >= 2 )6878 if (lDev >= 2 || lDev < 0) 6767 6879 { 6768 6880 AssertMsgFailed(("invalid controller device number: %d\n", lDev)); 6769 6881 return VERR_GENERAL_FAILURE; 6770 6882 } 6883 6771 6884 iLUN = 2*lChannel + lDev; 6772 }6773 break;6885 break; 6886 } 6774 6887 case StorageBus_SATA: 6888 { 6775 6889 iLUN = lChannel; 6776 6890 break; 6891 } 6777 6892 default: 6893 { 6778 6894 AssertMsgFailed(("invalid disk controller type: %d\n", enmBus)); 6779 6895 return VERR_GENERAL_FAILURE; 6896 } 6780 6897 } 6781 6898 … … 6799 6916 6800 6917 rc = CFGMR3InsertNode(pLunL0, "AttachedDriver", &pLunL1); RC_CHECK(); 6801 rc = CFGMR3InsertString(pLunL1, "Driver", "V BoxHDD");RC_CHECK();6918 rc = CFGMR3InsertString(pLunL1, "Driver", "VD"); RC_CHECK(); 6802 6919 rc = CFGMR3InsertNode(pLunL1, "Config", &pCfg); RC_CHECK(); 6803 6920 } … … 6807 6924 char *pszDriver; 6808 6925 rc = CFGMR3QueryStringAlloc(pLunL1, "Driver", &pszDriver); RC_CHECK(); 6809 Assert(!strcmp(pszDriver, "V BoxHDD"));6926 Assert(!strcmp(pszDriver, "VD")); 6810 6927 MMR3HeapFree(pszDriver); 6811 6928 #endif … … 6817 6934 AssertReturn(pCfg, VERR_INTERNAL_ERROR); 6818 6935 6819 /* the image */ 6820 /// @todo (dmik) we temporarily use the location property to 6821 // determine the image file name. This is subject to change 6822 // when iSCSI disks are here (we should either query a 6823 // storage-specific interface from IHardDisk, or "standardize" 6824 // the location property) 6825 hrc = hardDisk->COMGETTER(Location)(&str); H(); 6826 STR_CONV(); 6827 char *pszPath; 6828 rc = CFGMR3QueryStringAlloc(pCfg, "Path", &pszPath); RC_CHECK(); 6829 if (!strcmp(psz, pszPath)) 6830 { 6831 /* parent images. */ 6832 ComPtr<IHardDisk> parentHardDisk = hardDisk; 6833 for (PCFGMNODE pParent = pCfg;;) 6936 /* the format */ 6937 hrc = hardDisk->COMGETTER(Format)(bstr.asOutParam()); H(); 6938 char *pszFormat; 6939 rc = CFGMR3QueryStringAlloc(pCfg, "Format", &pszFormat); RC_CHECK(); 6940 if (bstr == pszFormat) 6941 { 6942 /* the image */ 6943 hrc = hardDisk->COMGETTER(Location)(bstr.asOutParam()); H(); 6944 char *pszPath; 6945 rc = CFGMR3QueryStringAlloc(pCfg, "Path", &pszPath); RC_CHECK(); 6946 if (bstr == pszPath) 6834 6947 { 6835 MMR3HeapFree(pszPath); 6836 pszPath = NULL; 6837 STR_FREE(); 6838 6839 /* get parent */ 6840 ComPtr<IHardDisk> curHardDisk; 6841 hrc = parentHardDisk->COMGETTER(Parent)(curHardDisk.asOutParam()); H(); 6842 PCFGMNODE pCur; 6843 pCur = CFGMR3GetChild(pParent, "Parent"); 6844 if (!pCur && !curHardDisk) 6948 /* parent images. */ 6949 ComPtr<IHardDisk2> parentHardDisk = hardDisk; 6950 for (PCFGMNODE pParent = pCfg;;) 6845 6951 { 6846 /* no change */ 6847 LogFlowFunc (("No change!\n")); 6848 return VINF_SUCCESS; 6952 MMR3HeapFree(pszPath); 6953 pszPath = NULL; 6954 6955 MMR3HeapFree(pszFormat); 6956 pszFormat = NULL; 6957 6958 /* get parent */ 6959 ComPtr<IHardDisk2> curHardDisk; 6960 hrc = parentHardDisk->COMGETTER(Parent)(curHardDisk.asOutParam()); H(); 6961 PCFGMNODE pCur; 6962 pCur = CFGMR3GetChild(pParent, "Parent"); 6963 if (!pCur && !curHardDisk) 6964 { 6965 /* no change */ 6966 LogFlowFunc (("No change!\n")); 6967 return VINF_SUCCESS; 6968 } 6969 if (!pCur || !curHardDisk) 6970 break; 6971 6972 /* compare formats. */ 6973 hrc = curHardDisk->COMGETTER(Format)(bstr.asOutParam()); H(); 6974 rc = CFGMR3QueryStringAlloc(pCfg, "Format", &pszPath); RC_CHECK(); 6975 if (bstr != pszFormat) 6976 break; 6977 6978 /* compare paths. */ 6979 hrc = curHardDisk->COMGETTER(Location)(bstr.asOutParam()); H(); 6980 rc = CFGMR3QueryStringAlloc(pCfg, "Path", &pszPath); RC_CHECK(); 6981 if (bstr != pszPath) 6982 break; 6983 6984 /* next */ 6985 pParent = pCur; 6986 parentHardDisk = curHardDisk; 6849 6987 } 6850 if (!pCur || !curHardDisk) 6851 break; 6852 6853 /* compare paths. */ 6854 /// @todo (dmik) we temporarily use the location property to 6855 // determine the image file name. This is subject to change 6856 // when iSCSI disks are here (we should either query a 6857 // storage-specific interface from IHardDisk, or "standardize" 6858 // the location property) 6859 hrc = curHardDisk->COMGETTER(Location)(&str); H(); 6860 STR_CONV(); 6861 rc = CFGMR3QueryStringAlloc(pCfg, "Path", &pszPath); RC_CHECK(); 6862 if (strcmp(psz, pszPath)) 6863 break; 6864 6865 /* next */ 6866 pParent = pCur; 6867 parentHardDisk = curHardDisk; 6988 6868 6989 } 6869 6990 else 6991 LogFlowFunc (("LUN#%d: old leaf location '%s'\n", iLUN, pszPath)); 6992 6993 MMR3HeapFree(pszPath); 6870 6994 } 6871 6995 else 6872 LogFlowFunc (("LUN#%d: old leaf image '%s'\n", iLUN, pszPath)); 6873 6874 MMR3HeapFree(pszPath); 6875 STR_FREE(); 6996 LogFlowFunc (("LUN#%d: old leaf format '%s'\n", iLUN, pszFormat)); 6997 6998 MMR3HeapFree(pszFormat); 6876 6999 6877 7000 /* … … 6886 7009 * Create the driver configuration. 6887 7010 */ 6888 /// @todo (dmik) we temporarily use the location property to 6889 // determine the image file name. This is subject to change 6890 // when iSCSI disks are here (we should either query a 6891 // storage-specific interface from IHardDisk, or "standardize" 6892 // the location property) 6893 hrc = hardDisk->COMGETTER(Location)(&str); H(); 6894 STR_CONV(); 6895 LogFlowFunc (("LUN#%d: leaf image '%s'\n", iLUN, psz)); 6896 rc = CFGMR3InsertString(pCfg, "Path", psz); RC_CHECK(); 6897 STR_FREE(); 7011 hrc = hardDisk->COMGETTER(Format)(bstr.asOutParam()); H(); 7012 LogFlowFunc (("LUN#%d: leaf format '%ls'\n", iLUN, bstr.raw())); 7013 rc = CFGMR3InsertString(pCfg, "Format", Utf8Str(bstr)); RC_CHECK(); 7014 hrc = hardDisk->COMGETTER(Location)(bstr.asOutParam()); H(); 7015 LogFlowFunc (("LUN#%d: leaf location '%ls'\n", iLUN, bstr.raw())); 7016 rc = CFGMR3InsertString(pCfg, "Path", Utf8Str(bstr)); RC_CHECK(); 6898 7017 /* Create an inversed tree of parents. */ 6899 ComPtr<IHardDisk > parentHardDisk = hardDisk;7018 ComPtr<IHardDisk2> parentHardDisk = hardDisk; 6900 7019 for (PCFGMNODE pParent = pCfg;;) 6901 7020 { 6902 ComPtr<IHardDisk > curHardDisk;7021 ComPtr<IHardDisk2> curHardDisk; 6903 7022 hrc = parentHardDisk->COMGETTER(Parent)(curHardDisk.asOutParam()); H(); 6904 7023 if (!curHardDisk) … … 6907 7026 PCFGMNODE pCur; 6908 7027 rc = CFGMR3InsertNode(pParent, "Parent", &pCur); RC_CHECK(); 6909 /// @todo (dmik) we temporarily use the location property to 6910 // determine the image file name. This is subject to change 6911 // when iSCSI disks are here (we should either query a 6912 // storage-specific interface from IHardDisk, or "standardize" 6913 // the location property) 6914 hrc = curHardDisk->COMGETTER(Location)(&str); H(); 6915 STR_CONV(); 6916 rc = CFGMR3InsertString(pCur, "Path", psz); RC_CHECK(); 6917 STR_FREE(); 7028 hrc = curHardDisk->COMGETTER(Format)(bstr.asOutParam()); H(); 7029 rc = CFGMR3InsertString(pCur, "Format", Utf8Str(bstr)); RC_CHECK(); 7030 hrc = curHardDisk->COMGETTER(Location)(bstr.asOutParam()); H(); 7031 rc = CFGMR3InsertString(pCur, "Path", Utf8Str(bstr)); RC_CHECK(); 6918 7032 6919 7033 /* next */ … … 7001 7115 do 7002 7116 { 7003 LogFlowFunc (("Reattaching new differencing VDIs...\n")); 7004 7005 ComPtr <IHardDiskAttachmentCollection> hdaColl; 7006 rc = that->mMachine->COMGETTER(HardDiskAttachments) (hdaColl.asOutParam()); 7117 LogFlowFunc (("Reattaching new differencing hard disks...\n")); 7118 7119 com::SafeIfaceArray <IHardDisk2Attachment> atts; 7120 rc = that->mMachine-> 7121 COMGETTER(HardDisk2Attachments) (ComSafeArrayAsOutParam (atts)); 7007 7122 if (FAILED (rc)) 7008 7123 break; 7009 ComPtr <IHardDiskAttachmentEnumerator> hdaEn; 7010 rc = hdaColl->Enumerate (hdaEn.asOutParam()); 7011 if (FAILED (rc)) 7012 break; 7013 BOOL more = FALSE; 7014 while (SUCCEEDED (rc = hdaEn->HasMore (&more)) && more) 7124 for (size_t i = 0; i < atts.size(); ++ i) 7015 7125 { 7016 ComPtr <IHardDiskAttachment> hda;7017 rc = hdaEn->GetNext (hda.asOutParam());7018 if (FAILED (rc))7019 break;7020 7021 7126 PVMREQ pReq; 7022 IHardDiskAttachment *pHda = hda;7023 7127 /* 7024 * don't leave the lock since reconfigure VDI isn't going to7025 * access Console.7128 * don't leave the lock since reconfigureHardDisks isn't going 7129 * to access Console. 7026 7130 */ 7027 7131 int vrc = VMR3ReqCall (that->mpVM, &pReq, RT_INDEFINITE_WAIT, 7028 (PFNRT)reconfigure VDI, 3, that->mpVM,7029 pHda, &rc);7132 (PFNRT)reconfigureHardDisks, 3, that->mpVM, 7133 atts [i], &rc); 7030 7134 if (VBOX_SUCCESS (rc)) 7031 7135 rc = pReq->iStatus;
Note:
See TracChangeset
for help on using the changeset viewer.