Changeset 28165 in vbox for trunk/src/VBox/Main
- Timestamp:
- Apr 11, 2010 7:15:06 PM (15 years ago)
- Location:
- trunk/src/VBox/Main
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Main/ApplianceImpl.cpp
r28162 r28165 564 564 565 565 /** 566 * Little shortcut to SystemProperties::DefaultHardDiskFolder. 567 * @param str 568 * @return 569 */ 570 HRESULT Appliance::getDefaultHardDiskFolder(Utf8Str &str) const 571 { 572 /* We need the default path for storing disk images */ 573 ComPtr<ISystemProperties> systemProps; 574 HRESULT rc = mVirtualBox->COMGETTER(SystemProperties)(systemProps.asOutParam()); 575 if (FAILED(rc)) return rc; 576 Bstr bstrDefaultHardDiskFolder; 577 rc = systemProps->COMGETTER(DefaultHardDiskFolder)(bstrDefaultHardDiskFolder.asOutParam()); 578 if (FAILED(rc)) return rc; 579 str = bstrDefaultHardDiskFolder; 580 581 return S_OK; 582 } 583 584 /** 566 585 * Called from the import and export background threads to synchronize the second 567 586 * background disk thread's progress object with the current progress object so -
trunk/src/VBox/Main/ApplianceImplImport.cpp
r28162 r28165 125 125 m->virtualSystemDescriptions.clear(); 126 126 127 /* We need the default path for storing disk images */ 128 ComPtr<ISystemProperties> systemProps; 129 rc = mVirtualBox->COMGETTER(SystemProperties)(systemProps.asOutParam()); 130 if (FAILED(rc)) return rc; 131 Bstr bstrDefaultHardDiskLocation; 132 rc = systemProps->COMGETTER(DefaultHardDiskFolder)(bstrDefaultHardDiskLocation.asOutParam()); 127 Utf8Str strDefaultHardDiskFolder; 128 rc = getDefaultHardDiskFolder(strDefaultHardDiskFolder); 133 129 if (FAILED(rc)) return rc; 134 130 … … 505 501 // - we need a url specifier for the vdi format 506 502 if ( di.strFormat.compare("http://www.vmware.com/specifications/vmdk.html#sparse", Utf8Str::CaseInsensitive) 507 || di.strFormat.compare("http://www.vmware.com/specifications/vmdk.html#compressed", Utf8Str::CaseInsensitive)) 503 || di.strFormat.compare("http://www.vmware.com/specifications/vmdk.html#compressed", Utf8Str::CaseInsensitive) 504 ) 508 505 { 509 506 /* If the href is empty use the VM name as filename */ … … 512 509 strFilename = Utf8StrFmt("%s.vmdk", nameVBox.c_str()); 513 510 /* Construct a unique target path */ 514 Utf8StrFmt strPath("% ls%c%s",515 bstrDefaultHardDiskLocation.raw(),511 Utf8StrFmt strPath("%s%c%s", 512 strDefaultHardDiskFolder.raw(), 516 513 RTPATH_DELIMITER, 517 514 strFilename.c_str()); … … 531 528 pController->ulIndex, 532 529 hd.ulAddressOnParent); 533 ULONG ulSize = 0;534 if (di.iCapacity != -1)535 ulSize = (ULONG)(di.iCapacity / _1M);536 else if (di.iPopulatedSize != -1)537 ulSize = (ULONG)(di.iPopulatedSize / _1M);538 else if (di.iSize != -1)539 ulSize = (ULONG)(di.iSize / _1M);540 if (ulSize == 0)541 ulSize = 10000; // assume 10 GB, this is for the progress bar only anyway542 530 pNewDesc->addEntry(VirtualSystemDescriptionType_HardDiskImage, 543 531 hd.strDiskId, 544 532 di.strHref, 545 533 strPath, 546 ulSize,534 di.ulSuggestedSizeMB, 547 535 strExtraConfig); 548 536 } … … 1153 1141 1154 1142 if (vsdescThis->m->pConfig) 1155 importVBoxMachine(vs ysThis, vsdescThis, pNewMachine, stack);1143 importVBoxMachine(vsdescThis, pNewMachine, stack); 1156 1144 else 1157 1145 importMachineGeneric(vsysThis, vsdescThis, pNewMachine, stack); … … 1230 1218 1231 1219 /** 1232 * 1233 * @param vsysThis OVF virtual system containing the VirtualDisksMap. We don't pass that directly 1234 * because it's a typedef which requires the whole ovfreader.h to be included otherwise. 1235 * @param vsdeHD 1236 * @param dstHdVBox 1220 * Imports one disk image. This is common code shared between 1221 * -- importMachineGeneric() for the OVF case; in that case the information comes from 1222 * the OVF virtual systems; 1223 * -- importVBoxMachine(); in that case, the information comes from the <vbox:Machine> 1224 * tag. 1225 * 1226 * Both ways of describing machines use the OVF disk references section, so in both cases 1227 * the caller needs to pass in the ovf::DiskImage structure from ovfreader.cpp. 1228 * 1229 * As a result, in both cases, if di.strHref is empty, we create a new disk as per the OVF 1230 * spec, even though this cannot really happen in the vbox:Machine case since such data 1231 * would never have been exported. 1232 * 1233 * This advances stack.pProgress by one operation with the disk's weight. 1234 * 1235 * @param di ovfreader.cpp structure describing the disk image from the OVF that is to be imported 1236 * @param ulSizeMB Size of the disk image (for progress reporting) 1237 * @param strTargetPath Where to create the target image. 1238 * @param pTargetHD out: The newly created target disk. This also gets pushed on stack.llHardDisksCreated for cleanup. 1237 1239 * @param stack 1238 1240 */ 1239 1241 void Appliance::importOneDiskImage(const ovf::DiskImage &di, 1240 uint32_t ulSizeMB,1241 1242 const Utf8Str &strTargetPath, 1242 1243 ComPtr<IMedium> &pTargetHD, … … 1286 1287 // advance to the next operation 1287 1288 stack.pProgress->SetNextOperation(BstrFmt(tr("Creating virtual disk image '%s'"), strTargetPath.c_str()), 1288 ulSizeMB); // operation's weight, as set up with the IProgress originally1289 di.ulSuggestedSizeMB); // operation's weight, as set up with the IProgress originally 1289 1290 } 1290 1291 else … … 1326 1327 /* Advance to the next operation */ 1327 1328 stack.pProgress->SetNextOperation(BstrFmt(tr("Importing virtual disk image '%s'"), strSrcFilePath.c_str()), 1328 ulSizeMB); // operation's weight, as set up with the IProgress originally);1329 di.ulSuggestedSizeMB); // operation's weight, as set up with the IProgress originally); 1329 1330 } 1330 1331 … … 1845 1846 ComPtr<IMedium> pTargetHD; 1846 1847 importOneDiskImage(di, 1847 vsdeHD->ulSizeMB,1848 1848 vsdeHD->strVbox, 1849 1849 pTargetHD, … … 1910 1910 * about what needs cleaning up (to support rollback). 1911 1911 * 1912 * The machine config stored in the settings::MachineConfigFile structure contains the UUIDs of 1913 * the disk attachments used by the machine when it was exported. We also add vbox:uuid attributes 1914 * to the OVF disks sections so we can look them up. While importing these UUIDs into a second host 1915 * will most probably work, reimporting them into the same host will cause conflicts, so we always 1916 * generate new ones on import. This involves the following: 1917 * 1918 * 1) Scan the machine config for disk attachments. 1919 * 1920 * 2) For each disk attachment found, look up the OVF disk image from the disk references section 1921 * and import the disk into VirtualBox, which creates a new UUID for it. In the machine config, 1922 * replace the old UUID with the new one. 1923 * 1924 * 3) Create the VirtualBox machine with the modfified machine config. 1925 * 1912 1926 * @param config 1913 1927 * @param pNewMachine 1914 1928 * @param stack 1915 1929 */ 1916 void Appliance::importVBoxMachine(const ovf::VirtualSystem &vsysThis, 1917 ComObjPtr<VirtualSystemDescription> &vsdescThis, 1930 void Appliance::importVBoxMachine(ComObjPtr<VirtualSystemDescription> &vsdescThis, 1918 1931 ComPtr<IMachine> &pReturnNewMachine, 1919 1932 ImportStack &stack) 1920 1933 { 1921 1934 Assert(vsdescThis->m->pConfig); 1922 const settings::MachineConfigFile &config = *vsdescThis->m->pConfig; 1935 1936 // make a deep copy of the machine settings here because we will tinker 1937 // with it by replacing disk UUIDs 1938 settings::MachineConfigFile config = *vsdescThis->m->pConfig; 1939 1940 Utf8Str strDefaultHardDiskFolder; 1941 HRESULT rc = getDefaultHardDiskFolder(strDefaultHardDiskFolder); 1942 if (FAILED(rc)) throw rc; 1943 1944 // step 1): scan the machine config for UUIDs 1945 for (settings::StorageControllersList::iterator sit = config.storageMachine.llStorageControllers.begin(); 1946 sit != config.storageMachine.llStorageControllers.end(); 1947 ++sit) 1948 { 1949 settings::StorageController &sc = *sit; 1950 1951 for (settings::AttachedDevicesList::iterator dit = sc.llAttachedDevices.begin(); 1952 dit != sc.llAttachedDevices.end(); 1953 ++dit) 1954 { 1955 settings::AttachedDevice &d = *dit; 1956 1957 if (d.uuid.isEmpty()) 1958 // empty DVD and floppy media 1959 continue; 1960 1961 // convert the Guid to string 1962 Utf8Str strUuid = d.uuid.toString(); 1963 1964 // there must be an image in the OVF disk structs with the same UUID 1965 bool fFound = false; 1966 for (ovf::DiskImagesMap::const_iterator oit = stack.mapDisks.begin(); 1967 oit != stack.mapDisks.end(); 1968 ++oit) 1969 { 1970 const ovf::DiskImage &di = oit->second; 1971 1972 if (di.uuidVbox == strUuid) 1973 { 1974 Utf8Str strTargetPath(strDefaultHardDiskFolder); 1975 strTargetPath.append(RTPATH_DELIMITER); 1976 strTargetPath.append(di.strHref); 1977 searchUniqueDiskImageFilePath(strTargetPath); 1978 1979 // step 2): import disks and map the old and new UUIDs 1980 ComPtr<IMedium> pTargetHD; 1981 importOneDiskImage(di, 1982 strTargetPath, 1983 pTargetHD, 1984 stack); 1985 1986 Bstr hdId; 1987 rc = pTargetHD->COMGETTER(Id)(hdId.asOutParam()); 1988 if (FAILED(rc)) throw rc; 1989 1990 // replace the old UUID in the machine config with the new one 1991 d.uuid = hdId; 1992 fFound = true; 1993 break; 1994 } 1995 } 1996 1997 // no disk with such a UUID found: 1998 if (!fFound) 1999 throw setError(E_FAIL, 2000 tr("<vbox:Machine> element in OVF contains a medium attachment for the disk image %s but the OVF describes no such image"), 2001 strUuid.raw()); 2002 } // for (settings::AttachedDevicesList::const_iterator dit = sc.llAttachedDevices.begin(); 2003 } // for (settings::StorageControllersList::const_iterator sit = config.storageMachine.llStorageControllers.begin(); 2004 2005 // step 3): create the machine and have it import the config 1923 2006 1924 2007 // use the name that we computed in the OVF fields to avoid duplicates … … 1930 2013 1931 2014 ComObjPtr<Machine> pNewMachine; 1932 HRESULTrc = pNewMachine.createObject();2015 rc = pNewMachine.createObject(); 1933 2016 if (FAILED(rc)) throw rc; 1934 2017 -
trunk/src/VBox/Main/include/ApplianceImpl.h
r28162 r28165 119 119 HRESULT searchUniqueVMName(Utf8Str& aName) const; 120 120 HRESULT searchUniqueDiskImageFilePath(Utf8Str& aName) const; 121 HRESULT getDefaultHardDiskFolder(Utf8Str &str) const; 121 122 void waitForAsyncProgress(ComObjPtr<Progress> &pProgressThis, ComPtr<IProgress> &pProgressAsync); 122 123 void addWarning(const char* aWarning, ...); … … 154 155 struct ImportStack; 155 156 void importOneDiskImage(const ovf::DiskImage &di, 156 uint32_t ulSizeMB,157 157 const Utf8Str &strTargetPath, 158 158 ComPtr<IMedium> &pTargetHD, … … 162 162 ComPtr<IMachine> &pNewMachine, 163 163 ImportStack &stack); 164 void importVBoxMachine(const ovf::VirtualSystem &vsysThis, 165 ComObjPtr<VirtualSystemDescription> &vsdescThis, 164 void importVBoxMachine(ComObjPtr<VirtualSystemDescription> &vsdescThis, 166 165 ComPtr<IMachine> &pNewMachine, 167 166 ImportStack &stack); … … 192 191 Utf8Str strExtraConfig; // extra configuration key=value strings (type-dependent) 193 192 194 uint32_t ulSizeMB; // hard disk images only: size of the uncompressed image inMB193 uint32_t ulSizeMB; // hard disk images only: a copy of ovf::DiskImage::ulSuggestedSizeMB 195 194 }; 196 195 -
trunk/src/VBox/Main/include/ovfreader.h
r27918 r28165 152 152 struct DiskImage 153 153 { 154 // fields from /DiskSection/Disk 154 155 iprt::MiniString strDiskId; // value from DiskSection/Disk/@diskId 155 156 int64_t iCapacity; // value from DiskSection/Disk/@capacity; … … 160 161 iprt::MiniString strFormat; // value from DiskSection/Disk/@format 161 162 // typically http://www.vmware.com/specifications/vmdk.html#sparse 163 iprt::MiniString uuidVbox; // optional; if the file was exported by VirtualBox >= 3.2, 164 // then this has the UUID with which the disk was registered 162 165 163 166 // fields from /References/File; the spec says the file reference from disk can be empty, … … 167 170 int64_t iChunkSize; // value from /References/File/@chunkSize (optional, unsupported) 168 171 iprt::MiniString strCompression; // value from /References/File/@compression (optional, can be "gzip" according to spec) 172 173 // additional field which has a descriptive size in megabytes derived from the above; this can be used for progress reports 174 uint32_t ulSuggestedSizeMB; 169 175 }; 170 176 … … 383 389 OVFReader(const iprt::MiniString &path); 384 390 391 // Data fields 392 iprt::MiniString m_strPath; // file name given to constructor 393 DiskImagesMap m_mapDisks; // map of DiskImage structs, sorted by DiskImage.strDiskId 394 std::list<VirtualSystem> m_llVirtualSystems; // list of virtual systems, created by and valid after read() 395 396 private: 397 xml::Document m_doc; 398 385 399 void LoopThruSections(const xml::ElementNode *pReferencesElem, const xml::ElementNode *pCurElem); 386 400 void HandleDiskSection(const xml::ElementNode *pReferencesElem, const xml::ElementNode *pSectionElem); 387 401 void HandleNetworkSection(const xml::ElementNode *pSectionElem); 388 402 void HandleVirtualSystemContent(const xml::ElementNode *pContentElem); 389 390 // Data fields391 iprt::MiniString m_strPath; // file name given to constructor392 DiskImagesMap m_mapDisks; // map of DiskImage structs, sorted by DiskImage.strDiskId393 std::list<VirtualSystem> m_llVirtualSystems; // list of virtual systems, created by and valid after read()394 395 private:396 xml::Document m_doc;397 403 }; 398 404 -
trunk/src/VBox/Main/xml/Settings.cpp
r28127 r28165 122 122 { 123 123 Data() 124 : pParser(NULL), 125 pDoc(NULL), 124 : pDoc(NULL), 126 125 pelmRoot(NULL), 127 126 sv(SettingsVersion_Null), … … 137 136 bool fFileExists; 138 137 139 xml::XmlFileParser *pParser;140 138 xml::Document *pDoc; 141 139 xml::ElementNode *pelmRoot; … … 164 162 pelmRoot = NULL; 165 163 } 166 167 if (pParser)168 {169 delete pParser;170 pParser = NULL;171 }172 164 } 173 165 }; … … 228 220 m->strFilename = *pstrFilename; 229 221 230 m->pParser = new xml::XmlFileParser;222 xml::XmlFileParser parser; 231 223 m->pDoc = new xml::Document; 232 m->pParser->read(*pstrFilename,233 224 parser.read(*pstrFilename, 225 *m->pDoc); 234 226 235 227 m->fFileExists = true; … … 3942 3934 } 3943 3935 } 3936 -
trunk/src/VBox/Main/xml/ovfreader.cpp
r27918 r28165 183 183 d.iPopulatedSize = -1; 184 184 185 // optional vbox:uuid attribute (if OVF was exported by VirtualBox != 3.2) 186 pelmDisk->getAttributeValue("vbox:uuid", d.uuidVbox); 187 185 188 const char *pcszFileRef; 186 189 if (pelmDisk->getAttributeValue("fileRef", pcszFileRef)) // optional … … 227 230 pcszBad, 228 231 pelmDisk->getLineNumber()); 232 233 // suggest a size in megabytes to help callers with progress reports 234 d.ulSuggestedSizeMB = 0; 235 if (d.iCapacity != -1) 236 d.ulSuggestedSizeMB = d.iCapacity / _1M; 237 else if (d.iPopulatedSize != -1) 238 d.ulSuggestedSizeMB = d.iPopulatedSize / _1M; 239 else if (d.iSize != -1) 240 d.ulSuggestedSizeMB = d.iSize / _1M; 241 if (d.ulSuggestedSizeMB == 0) 242 d.ulSuggestedSizeMB = 10000; // assume 10 GB, this is for the progress bar only anyway 229 243 230 244 m_mapDisks[d.strDiskId] = d;
Note:
See TracChangeset
for help on using the changeset viewer.