Changeset 93480 in vbox for trunk/src/VBox/Main
- Timestamp:
- Jan 28, 2022 4:09:52 PM (3 years ago)
- Location:
- trunk/src/VBox/Main
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Main/include/ApplianceImpl.h
r93115 r93480 220 220 ImportStack &stack); 221 221 void i_importMachines(ImportStack &stack); 222 HRESULT i_verifyStorageControllerPortValid(const StorageControllerType_T aStorageControllerType, 223 const uint32_t aControllerPort, 224 ULONG *ulMaxPorts); 222 225 223 226 HRESULT i_preCheckImageAvailability(ImportStack &stack); … … 310 313 std::list<VirtualSystemDescriptionEntry*> i_findByType(VirtualSystemDescriptionType_T aType); 311 314 const VirtualSystemDescriptionEntry* i_findControllerFromID(const Utf8Str &id); 315 const VirtualSystemDescriptionEntry* i_findByIndex(const uint32_t aIndex); 312 316 313 317 void i_importVBoxMachineXML(const xml::ElementNode &elmMachine); -
trunk/src/VBox/Main/include/Global.h
r93410 r93480 168 168 static const char *stringifySessionState(SessionState_T aState); 169 169 170 /** 171 * Stringify a device type. 172 * 173 * Drop the Global:: prefix and include StringifyEnums.h for an untranslated 174 * version of this method. 175 * 176 * @returns Pointer to a read only string. 177 * @param aType The device type. 178 */ 179 static const char *stringifyDeviceType(DeviceType_T aType); 180 181 /** 182 * Stringify a storage controller type. 183 * 184 * Drop the Global:: prefix and include StringifyEnums.h for an untranslated 185 * version of this method. 186 * 187 * @returns Pointer to a read only string. 188 * @param aType The storage controller type. 189 */ 190 static const char *stringifyStorageControllerType(StorageControllerType_T aType); 191 170 192 #if 0 /* unused */ 171 193 /** … … 179 201 */ 180 202 static const char *stringifyStorageBus(StorageBus_T aBus); 181 182 /**183 * Stringify a device type.184 *185 * Drop the Global:: prefix and include StringifyEnums.h for an untranslated186 * version of this method.187 *188 * @returns Pointer to a read only string.189 * @param aType The device type.190 */191 static const char *stringifyDeviceType(DeviceType_T aType);192 203 193 204 /** -
trunk/src/VBox/Main/src-all/Global.cpp
r93410 r93480 635 635 } 636 636 637 /*static*/ const char * 638 Global::stringifyStorageControllerType(StorageControllerType_T aType) 639 { 640 switch (aType) 641 { 642 case StorageControllerType_Null: return GlobalCtx::tr("Null"); 643 case StorageControllerType_LsiLogic: return GlobalCtx::tr("LsiLogic"); 644 case StorageControllerType_BusLogic: return GlobalCtx::tr("BusLogic"); 645 case StorageControllerType_IntelAhci: return GlobalCtx::tr("AHCI"); 646 case StorageControllerType_PIIX3: return GlobalCtx::tr("PIIX3"); 647 case StorageControllerType_PIIX4 : return GlobalCtx::tr("PIIX4"); 648 case StorageControllerType_ICH6: return GlobalCtx::tr("ICH6"); 649 case StorageControllerType_I82078: return GlobalCtx::tr("I82078"); 650 case StorageControllerType_LsiLogicSas: return GlobalCtx::tr("LsiLogicSas"); 651 case StorageControllerType_USB: return GlobalCtx::tr("USB"); 652 case StorageControllerType_NVMe: return GlobalCtx::tr("NVMe"); 653 case StorageControllerType_VirtioSCSI: return GlobalCtx::tr("VirtioSCSI"); 654 default: 655 AssertMsgFailedReturn(("%d (%#x)\n", aType, aType), ::stringifyStorageControllerType(aType)); 656 } 657 } 658 659 /*static*/ const char * 660 Global::stringifyDeviceType(DeviceType_T aType) 661 { 662 switch (aType) 663 { 664 case DeviceType_Null: return GlobalCtx::tr("Null"); 665 case DeviceType_Floppy: return GlobalCtx::tr("Floppy"); 666 case DeviceType_DVD: return GlobalCtx::tr("DVD"); 667 case DeviceType_HardDisk: return GlobalCtx::tr("HardDisk"); 668 case DeviceType_Network: return GlobalCtx::tr("Network"); 669 case DeviceType_USB: return GlobalCtx::tr("USB"); 670 case DeviceType_SharedFolder: return GlobalCtx::tr("ShardFolder"); 671 default: 672 AssertMsgFailedReturn(("%d (%#x)\n", aType, aType), ::stringifyDeviceType(aType)); 673 } 674 } 675 637 676 #if 0 /* unused */ 638 677 … … 656 695 657 696 /*static*/ const char * 658 Global::stringifyDeviceType(DeviceType_T aType)659 {660 switch (aType)661 {662 case DeviceType_Null: return GlobalCtx::tr("Null");663 case DeviceType_Floppy: return GlobalCtx::tr("Floppy");664 case DeviceType_DVD: return GlobalCtx::tr("DVD");665 case DeviceType_HardDisk: return GlobalCtx::tr("HardDisk");666 case DeviceType_Network: return GlobalCtx::tr("Network");667 case DeviceType_USB: return GlobalCtx::tr("USB");668 case DeviceType_SharedFolder: return GlobalCtx::tr("ShardFolder");669 default:670 AssertMsgFailedReturn(("%d (%#x)\n", aType, aType), ::stringifyDeviceType(aType));671 }672 }673 674 /*static*/ const char *675 697 Global::stringifyReason(Reason_T aReason) 676 698 { -
trunk/src/VBox/Main/src-server/ApplianceImpl.cpp
r93115 r93480 1828 1828 } 1829 1829 1830 /** 1831 * Private method; walks through the array of VirtualSystemDescriptionEntry entries 1832 * and returns the one matching the given index. 1833 */ 1834 const VirtualSystemDescriptionEntry* VirtualSystemDescription::i_findByIndex(const uint32_t aIndex) 1835 { 1836 vector<VirtualSystemDescriptionEntry>::const_iterator it; 1837 for (it = m->maDescriptions.begin(); 1838 it != m->maDescriptions.end(); 1839 ++it) 1840 { 1841 const VirtualSystemDescriptionEntry &d = *it; 1842 if (d.ulIndex == aIndex) 1843 return &d; 1844 } 1845 1846 return NULL; 1847 } 1848 -
trunk/src/VBox/Main/src-server/ApplianceImplImport.cpp
r93115 r93480 4305 4305 4306 4306 /** 4307 * Helper routine to parse the ExtraData Utf8Str for a storage controller's 4308 * value or channel value. 4309 * 4310 * @param aExtraData The ExtraData string with a format of 4311 * 'controller=13;channel=3'. 4312 * @param pszKey The string being looked up, either 'controller' or 4313 * 'channel'. 4314 * @param puVal The integer value of the 'controller=' or 'channel=' 4315 * key in the ExtraData string. 4316 * @returns COM status code. 4317 * @throws Nothing. 4318 */ 4319 static int getStorageControllerDetailsFromStr(const com::Utf8Str &aExtraData, const char *pszKey, uint32_t *puVal) 4320 { 4321 size_t posKey = aExtraData.find(pszKey); 4322 if (posKey == Utf8Str::npos) 4323 return VERR_INVALID_PARAMETER; 4324 4325 int vrc = RTStrToUInt32Ex(aExtraData.c_str() + posKey + strlen(pszKey), NULL, 0, puVal); 4326 if (vrc == VWRN_NUMBER_TOO_BIG || vrc == VWRN_NEGATIVE_UNSIGNED) 4327 return VERR_INVALID_PARAMETER; 4328 4329 return vrc; 4330 } 4331 4332 /** 4333 * Verifies the validity of a storage controller's channel (aka controller port). 4334 * 4335 * @param aStorageControllerType The type of storage controller as idenfitied 4336 * by the enum of type StorageControllerType_T. 4337 * @param uControllerPort The controller port value. 4338 * @param aMaxPortCount The maximum number of ports allowed for this 4339 * storage controller type. 4340 * @returns COM status code. 4341 * @throws Nothing. 4342 */ 4343 HRESULT Appliance::i_verifyStorageControllerPortValid(const StorageControllerType_T aStorageControllerType, 4344 const uint32_t uControllerPort, 4345 ULONG *aMaxPortCount) 4346 { 4347 SystemProperties *pSysProps; 4348 pSysProps = mVirtualBox->i_getSystemProperties(); 4349 if (pSysProps == NULL) 4350 return VBOX_E_OBJECT_NOT_FOUND; 4351 4352 StorageBus_T enmStorageBus = StorageBus_Null; 4353 HRESULT vrc = pSysProps->GetStorageBusForStorageControllerType(aStorageControllerType, &enmStorageBus); 4354 if (FAILED(vrc)) 4355 return vrc; 4356 4357 vrc = pSysProps->GetMaxPortCountForStorageBus(enmStorageBus, aMaxPortCount); 4358 if (FAILED(vrc)) 4359 return vrc; 4360 4361 if (uControllerPort >= *aMaxPortCount) 4362 return E_INVALIDARG; 4363 4364 return S_OK; 4365 } 4366 4367 /** 4307 4368 * Imports one OVF virtual system (described by the given ovf::VirtualSystem and VirtualSystemDescription) 4308 4369 * into VirtualBox by creating an IMachine instance, which is returned. … … 5014 5075 throw rc; 5015 5076 5016 // find the hard disk controller to which we should attach5017 ovf::HardDiskController hdc = (*vsysThis.mapControllers.find(ovfVdisk.strIdController)).second;5018 5019 5077 // this is for rollback later 5020 5078 MyHardDiskAttachment mhda; 5021 5079 mhda.pMachine = pNewMachine; 5080 5081 // find the hard disk controller to which we should attach 5082 ovf::HardDiskController hdc; 5083 5084 /* 5085 * Before importing the virtual hard disk found above (diCurrent/vsdeTargetHD) first 5086 * check if the user requested to change either the controller it is to be attached 5087 * to and/or the controller port (aka 'channel') on the controller. 5088 */ 5089 if ( !vsdeTargetHD->strExtraConfigCurrent.isEmpty() 5090 && vsdeTargetHD->strExtraConfigSuggested != vsdeTargetHD->strExtraConfigCurrent) 5091 { 5092 int vrc; 5093 uint32_t uTargetControllerIndex; 5094 vrc = getStorageControllerDetailsFromStr(vsdeTargetHD->strExtraConfigCurrent, "controller=", 5095 &uTargetControllerIndex); 5096 if (RT_FAILURE(vrc)) 5097 throw setError(E_FAIL, 5098 tr("Target controller value invalid or missing: '%s'"), 5099 vsdeTargetHD->strExtraConfigCurrent.c_str()); 5100 5101 uint32_t uNewControllerPortValue; 5102 vrc = getStorageControllerDetailsFromStr(vsdeTargetHD->strExtraConfigCurrent, "channel=", 5103 &uNewControllerPortValue); 5104 if (RT_FAILURE(vrc)) 5105 throw setError(E_FAIL, 5106 tr("Target controller port ('channel=') invalid or missing: '%s'"), 5107 vsdeTargetHD->strExtraConfigCurrent.c_str()); 5108 5109 const VirtualSystemDescriptionEntry *vsdeTargetController; 5110 vsdeTargetController = vsdescThis->i_findByIndex(uTargetControllerIndex); 5111 if (!vsdeTargetController) 5112 throw setError(E_FAIL, 5113 tr("Failed to find storage controller '%u' in the System Description list"), 5114 uTargetControllerIndex); 5115 5116 hdc = (*vsysThis.mapControllers.find(vsdeTargetController->strRef.c_str())).second; 5117 5118 StorageControllerType_T hdStorageControllerType = StorageControllerType_Null; 5119 switch (hdc.system) 5120 { 5121 case ovf::HardDiskController::IDE: 5122 hdStorageControllerType = StorageControllerType_PIIX3; 5123 break; 5124 case ovf::HardDiskController::SATA: 5125 hdStorageControllerType = StorageControllerType_IntelAhci; 5126 break; 5127 case ovf::HardDiskController::SCSI: 5128 { 5129 if (hdc.strControllerType.compare("lsilogicsas")==0) 5130 hdStorageControllerType = StorageControllerType_LsiLogicSas; 5131 else 5132 hdStorageControllerType = StorageControllerType_LsiLogic; 5133 break; 5134 } 5135 case ovf::HardDiskController::VIRTIOSCSI: 5136 hdStorageControllerType = StorageControllerType_VirtioSCSI; 5137 break; 5138 default: 5139 throw setError(E_FAIL, 5140 tr("Invalid hard disk contoller type: '%d'"), 5141 hdc.system); 5142 break; 5143 } 5144 5145 ULONG ulMaxPorts; 5146 rc = i_verifyStorageControllerPortValid(hdStorageControllerType, 5147 uNewControllerPortValue, 5148 &ulMaxPorts); 5149 if (FAILED(rc)) 5150 { 5151 if (rc == E_INVALIDARG) 5152 { 5153 const char *pcszSCType = Global::stringifyStorageControllerType(hdStorageControllerType); 5154 throw setError(E_INVALIDARG, 5155 tr("Illegal channel: '%u'. For %s controllers the valid values are " 5156 "0 to %lu (inclusive).\n"), uNewControllerPortValue, pcszSCType, ulMaxPorts-1); 5157 } 5158 else 5159 throw rc; 5160 } 5161 5162 unconst(ovfVdisk.ulAddressOnParent) = uNewControllerPortValue; 5163 } 5164 else 5165 hdc = (*vsysThis.mapControllers.find(ovfVdisk.strIdController)).second; 5166 5022 5167 5023 5168 i_convertDiskAttachmentValues(hdc, … … 5262 5407 * failures. A long fixed bug, however the OVF files are long lived. */ 5263 5408 settings::StorageControllersList &llControllers = config.hardwareMachine.storage.llStorageControllers; 5264 Guid hdUuid;5265 5409 uint32_t cDisks = 0; 5266 5410 bool fInconsistent = false; … … 5271 5415 ++it3) 5272 5416 { 5417 Guid hdUuid; 5273 5418 settings::AttachedDevicesList &llAttachments = it3->llAttachedDevices; 5274 5419 settings::AttachedDevicesList::iterator it4 = llAttachments.begin(); … … 5364 5509 continue; 5365 5510 } 5366 5367 5368 5369 5370 5371 5372 5373 5374 5511 5375 5512 /* … … 5444 5581 tr("Internal inconsistency looking up disk image '%s'"), 5445 5582 diCurrent.strHref.c_str()); 5446 5447 5448 5449 5450 5451 5583 } 5452 5584 else … … 5473 5605 bool fFound = false; 5474 5606 Utf8Str strUuid; 5607 5608 /* 5609 * Before importing the virtual hard disk found above (diCurrent/vsdeTargetHD) first 5610 * check if the user requested to change either the controller it is to be attached 5611 * to and/or the controller port (aka 'channel') on the controller. 5612 */ 5613 if ( !vsdeTargetHD->strExtraConfigCurrent.isEmpty() 5614 && vsdeTargetHD->strExtraConfigSuggested != vsdeTargetHD->strExtraConfigCurrent) 5615 { 5616 /* 5617 * First, we examine the extra configuration values for this vdisk: 5618 * vsdeTargetHD->strExtraConfigSuggested 5619 * vsdeTargetHD->strExtraConfigCurrent 5620 * in order to extract both the "before" and "after" storage controller and port 5621 * details. The strExtraConfigSuggested string contains the current controller 5622 * and port the vdisk is attached to and is populated by Appliance::interpret() 5623 * when processing the OVF data; it is in the following format: 5624 * 'controller=12;channel=0' (the 'channel=' label for the controller port is 5625 * historical and is documented as such in the SDK so can't be changed). The 5626 * strExtraConfigSuggested string contains the target controller and port specified 5627 * by the user and it has the same format. The 'controller=' value is not a 5628 * controller-ID but rather it is the index for the corresponding storage controller 5629 * in the array of VirtualSystemDescriptionEntry entries. 5630 */ 5631 int vrc; 5632 uint32_t uOrigControllerIndex; 5633 vrc = getStorageControllerDetailsFromStr(vsdeTargetHD->strExtraConfigSuggested, "controller=", &uOrigControllerIndex); 5634 if (RT_FAILURE(vrc)) 5635 throw setError(E_FAIL, 5636 tr("Original controller value invalid or missing: '%s'"), 5637 vsdeTargetHD->strExtraConfigSuggested.c_str()); 5638 5639 uint32_t uTargetControllerIndex; 5640 vrc = getStorageControllerDetailsFromStr(vsdeTargetHD->strExtraConfigCurrent, "controller=", &uTargetControllerIndex); 5641 if (RT_FAILURE(vrc)) 5642 throw setError(E_FAIL, 5643 tr("Target controller value invalid or missing: '%s'"), 5644 vsdeTargetHD->strExtraConfigCurrent.c_str()); 5645 5646 uint32_t uOrigControllerPortValue; 5647 vrc = getStorageControllerDetailsFromStr(vsdeTargetHD->strExtraConfigSuggested, "channel=", 5648 &uOrigControllerPortValue); 5649 if (RT_FAILURE(vrc)) 5650 throw setError(E_FAIL, 5651 tr("Original controller port ('channel=') invalid or missing: '%s'"), 5652 vsdeTargetHD->strExtraConfigSuggested.c_str()); 5653 5654 uint32_t uNewControllerPortValue; 5655 vrc = getStorageControllerDetailsFromStr(vsdeTargetHD->strExtraConfigCurrent, "channel=", &uNewControllerPortValue); 5656 if (RT_FAILURE(vrc)) 5657 throw setError(E_FAIL, 5658 tr("Target controller port ('channel=') invalid or missing: '%s'"), 5659 vsdeTargetHD->strExtraConfigCurrent.c_str()); 5660 5661 /* 5662 * Second, now that we have the storage controller indexes we locate the corresponding 5663 * VirtualSystemDescriptionEntry (VSDE) for both storage controllers which contain 5664 * identifying details which will be needed later when walking the list of storage 5665 * controllers. 5666 */ 5667 const VirtualSystemDescriptionEntry *vsdeOrigController; 5668 vsdeOrigController = vsdescThis->i_findByIndex(uOrigControllerIndex); 5669 if (!vsdeOrigController) 5670 throw setError(E_FAIL, 5671 tr("Failed to find storage controller '%u' in the System Description list"), 5672 uOrigControllerIndex); 5673 5674 const VirtualSystemDescriptionEntry *vsdeTargetController; 5675 vsdeTargetController = vsdescThis->i_findByIndex(uTargetControllerIndex); 5676 if (!vsdeTargetController) 5677 throw setError(E_FAIL, 5678 tr("Failed to find storage controller '%u' in the System Description list"), 5679 uTargetControllerIndex); 5680 5681 /* 5682 * Third, grab the UUID of the current vdisk so we can identify which device 5683 * attached to the original storage controller needs to be updated (channel) and/or 5684 * removed. 5685 */ 5686 ovf::DiskImagesMap::const_iterator itDiskImageMap = stack.mapDisks.find(vsdeTargetHD->strRef); 5687 if (itDiskImageMap == stack.mapDisks.end()) 5688 throw setError(E_FAIL, 5689 tr("Failed to find virtual disk '%s' in DiskImagesMap"), 5690 vsdeTargetHD->strVBoxCurrent.c_str()); 5691 const ovf::DiskImage &targetDiskImage = itDiskImageMap->second; 5692 Utf8Str strTargetDiskUuid = targetDiskImage.uuidVBox;; 5693 5694 /* 5695 * Fourth, walk the attached devices of the original storage controller to find the 5696 * current vdisk and update the controller port (aka channel) value if necessary and 5697 * also remove the vdisk from this controller if needed. 5698 * 5699 * A short note on the choice of which items to compare when determining the type of 5700 * storage controller here and below in the vdisk addition scenario: 5701 * + The VirtualSystemDescriptionEntry 'strOvf' field is populated from the OVF 5702 * data which can contain a value like 'vmware.sata.ahci' if created by VMWare so 5703 * it isn't a reliable choice. 5704 * + The settings::StorageController 'strName' field can have varying content based 5705 * on the version of the settings file, e.g. 'IDE Controller' vs. 'IDE' so it 5706 * isn't a reliable choice. Further, this field can contain 'SATA' whereas 5707 * 'AHCI' is used in 'strOvf' and 'strVBoxSuggested'. 5708 * + The VirtualSystemDescriptionEntry 'strVBoxSuggested' field is populated by 5709 * Appliance::interpret()->VirtualSystemDescription::i_addEntry() and is thus 5710 * under VBox's control and has a fixed format and predictable content. 5711 */ 5712 bool fDiskRemoved = false; 5713 settings::AttachedDevice originalAttachedDevice; 5714 settings::StorageControllersList::iterator itSCL; 5715 for (itSCL = config.hardwareMachine.storage.llStorageControllers.begin(); 5716 itSCL != config.hardwareMachine.storage.llStorageControllers.end(); 5717 ++itSCL) 5718 { 5719 settings::StorageController &SC = *itSCL; 5720 const char *pcszSCType = Global::stringifyStorageControllerType(SC.controllerType); 5721 5722 /* There can only be one storage controller of each type in the OVF data. */ 5723 if (!vsdeOrigController->strVBoxSuggested.compare(pcszSCType, Utf8Str::CaseInsensitive)) 5724 { 5725 settings::AttachedDevicesList::iterator itAD; 5726 for (itAD = SC.llAttachedDevices.begin(); 5727 itAD != SC.llAttachedDevices.end(); 5728 ++itAD) 5729 { 5730 settings::AttachedDevice &AD = *itAD; 5731 5732 if (AD.uuid.toString() == strTargetDiskUuid) 5733 { 5734 ULONG ulMaxPorts; 5735 rc = i_verifyStorageControllerPortValid(SC.controllerType, 5736 uNewControllerPortValue, 5737 &ulMaxPorts); 5738 if (FAILED(rc)) 5739 { 5740 if (rc == E_INVALIDARG) 5741 throw setError(E_INVALIDARG, 5742 tr("Illegal channel: '%u'. For %s controllers the valid values are " 5743 "0 to %lu (inclusive).\n"), uNewControllerPortValue, pcszSCType, ulMaxPorts-1); 5744 else 5745 throw rc; 5746 } 5747 5748 if (uOrigControllerPortValue != uNewControllerPortValue) 5749 { 5750 AD.lPort = uNewControllerPortValue; 5751 } 5752 if (uOrigControllerIndex != uTargetControllerIndex) 5753 { 5754 LogFunc(("Removing vdisk '%s' (uuid = %RTuuid) from the %s storage controller.\n", 5755 vsdeTargetHD->strVBoxCurrent.c_str(), 5756 itAD->uuid.raw(), 5757 SC.strName.c_str())); 5758 originalAttachedDevice = AD; 5759 SC.llAttachedDevices.erase(itAD); 5760 fDiskRemoved = true; 5761 } 5762 } 5763 } 5764 } 5765 } 5766 5767 /* 5768 * Fifth, if we are moving the vdisk to a different controller and not just changing 5769 * the channel then we walk the attached devices of the target controller and check 5770 * for conflicts before adding the vdisk detached/removed above. 5771 */ 5772 bool fDiskAdded = false; 5773 if (fDiskRemoved) 5774 { 5775 for (itSCL = config.hardwareMachine.storage.llStorageControllers.begin(); 5776 itSCL != config.hardwareMachine.storage.llStorageControllers.end(); 5777 ++itSCL) 5778 { 5779 settings::StorageController &SC = *itSCL; 5780 const char *pcszSCType = Global::stringifyStorageControllerType(SC.controllerType); 5781 5782 /* There can only be one storage controller of each type in the OVF data. */ 5783 if (!vsdeTargetController->strVBoxSuggested.compare(pcszSCType, Utf8Str::CaseInsensitive)) 5784 { 5785 settings::AttachedDevicesList::iterator itAD; 5786 for (itAD = SC.llAttachedDevices.begin(); 5787 itAD != SC.llAttachedDevices.end(); 5788 ++itAD) 5789 { 5790 settings::AttachedDevice &AD = *itAD; 5791 if ( AD.lDevice == originalAttachedDevice.lDevice 5792 && AD.lPort == originalAttachedDevice.lPort) 5793 throw setError(E_FAIL, 5794 tr("Device of type '%s' already attached to the %s controller at this " 5795 "port/channel (%d)."), 5796 Global::stringifyDeviceType(AD.deviceType), pcszSCType, AD.lPort); 5797 } 5798 5799 LogFunc(("Adding vdisk '%s' (uuid = %RTuuid) to the %s storage controller\n", 5800 vsdeTargetHD->strVBoxCurrent.c_str(), 5801 originalAttachedDevice.uuid.raw(), 5802 SC.strName.c_str())); 5803 SC.llAttachedDevices.push_back(originalAttachedDevice); 5804 fDiskAdded = true; 5805 } 5806 } 5807 5808 if (!fDiskAdded) 5809 throw setError(E_FAIL, 5810 tr("Failed to add disk '%s' (uuid=%RTuuid) to the %s storage controller."), 5811 vsdeTargetHD->strVBoxCurrent.c_str(), 5812 originalAttachedDevice.uuid.raw(), 5813 vsdeTargetController->strVBoxSuggested.c_str()); 5814 } 5815 5816 /* 5817 * Sixth, update the machine settings since we've changed the storage controller 5818 * and/or controller port for this vdisk. 5819 */ 5820 AutoWriteLock vboxLock(mVirtualBox COMMA_LOCKVAL_SRC_POS); 5821 mVirtualBox->i_saveSettings(); 5822 vboxLock.release(); 5823 } 5475 5824 5476 5825 // for each storage controller... … … 5656 6005 VirtualSystemDescriptionEntry *vsdeSF1 = vsdeSettingsFile.front(); 5657 6006 if (vsdeSF1->strVBoxCurrent != vsdeSF1->strVBoxSuggested) 5658 stack.strSettingsFilename = vsdeSF1->strVBoxCurrent;6007 stack.strSettingsFilename = vsdeSF1->strVBoxCurrent; 5659 6008 } 5660 6009 if (stack.strSettingsFilename.isEmpty())
Note:
See TracChangeset
for help on using the changeset viewer.