Changeset 67252 in vbox
- Timestamp:
- Jun 2, 2017 3:54:22 PM (8 years ago)
- svn:sync-xref-src-repo-rev:
- 115947
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Main/src-server/ApplianceImplExport.cpp
r67249 r67252 2090 2090 */ 2091 2091 std::list<Utf8Str> lstTarballs; 2092 try 2093 { 2092 2093 /* 2094 * Use i_buildXML to build a stack of disk images. We don't care about the XML doc here. 2095 */ 2096 XMLStack stack; 2097 { 2098 xml::Document doc; 2099 i_buildXML(writeLock, doc, stack, pTask->locInfo.strPath, ovf::OVFVersion_2_0); 2100 } 2101 2102 /* 2103 * Process the disk images. 2104 */ 2105 unsigned cTarballs = 0; 2106 for (list<Utf8Str>::const_iterator it = stack.mapDiskSequence.begin(); 2107 it != stack.mapDiskSequence.end(); 2108 ++it) 2109 { 2110 const Utf8Str &strDiskID = *it; 2111 const VirtualSystemDescriptionEntry *pDiskEntry = stack.mapDisks[strDiskID]; 2112 const Utf8Str &strSrcFilePath = pDiskEntry->strVBoxCurrent; // where the VBox image is 2113 2094 2114 /* 2095 * Use i_buildXML to build a stack of disk images. We don't care about the XML doc here.2115 * Some skipping. 2096 2116 */ 2097 XMLStack stack; 2117 if (pDiskEntry->skipIt) 2118 continue; 2119 2120 /* Skip empty media (DVD-ROM, floppy). */ 2121 if (strSrcFilePath.isEmpty()) 2122 continue; 2123 2124 /* Only deal with harddisk and DVD-ROMs, skip any floppies for now. */ 2125 if ( pDiskEntry->type != VirtualSystemDescriptionType_HardDiskImage 2126 && pDiskEntry->type != VirtualSystemDescriptionType_CDROM) 2127 continue; 2128 2129 /* 2130 * Locate the Medium object for this entry (by location/path). 2131 */ 2132 Log(("Finding source disk \"%s\"\n", strSrcFilePath.c_str())); 2133 ComObjPtr<Medium> ptrSourceDisk; 2134 if (pDiskEntry->type == VirtualSystemDescriptionType_HardDiskImage) 2135 hrc = mVirtualBox->i_findHardDiskByLocation(strSrcFilePath, true /*aSetError*/, &ptrSourceDisk); 2136 else 2137 hrc = mVirtualBox->i_findDVDOrFloppyImage(DeviceType_DVD, NULL /*aId*/, strSrcFilePath, 2138 true /*aSetError*/, &ptrSourceDisk); 2139 if (FAILED(hrc)) 2140 break; 2141 if (strSrcFilePath.isEmpty()) 2142 continue; 2143 2144 /* 2145 * Figure out the names. 2146 */ 2147 2148 /* The name inside the tarball. Replace the suffix of harddisk images with ".img". */ 2149 Utf8Str strInsideName = pDiskEntry->strOvf; 2150 if (pDiskEntry->type == VirtualSystemDescriptionType_HardDiskImage) 2151 strInsideName.stripSuffix().append(".img"); 2152 2153 /* The first tarball we create uses the specified name. Subsequent 2154 takes the name from the disk entry or something. */ 2155 Utf8Str strTarballPath = pTask->locInfo.strPath; 2156 if (cTarballs > 0) 2098 2157 { 2099 xml::Document doc; 2100 i_buildXML(writeLock, doc, stack, pTask->locInfo.strPath, ovf::OVFVersion_2_0); 2158 const char *pszExt = RTPathSuffix(pDiskEntry->strOvf.c_str()); 2159 pszExt = !pszExt || *pszExt != '.' ? "" 2160 : pDiskEntry->type == VirtualSystemDescriptionType_HardDiskImage ? "img" : pszExt + 1; 2161 2162 strTarballPath.stripFilename().append(RTPATH_SLASH_STR).append(pDiskEntry->strOvf); 2163 if (*pszExt) 2164 strTarballPath.stripSuffix().append("_").append(pszExt); 2165 strTarballPath.append(".tar.gz"); 2101 2166 } 2167 cTarballs++; 2102 2168 2103 2169 /* 2104 * Process the disk images.2170 * Create the tar output stream. 2105 2171 */ 2106 unsigned cTarballs = 0; 2107 for (list<Utf8Str>::const_iterator it = stack.mapDiskSequence.begin(); 2108 it != stack.mapDiskSequence.end(); 2109 ++it) 2172 RTVFSIOSTREAM hVfsIosFile; 2173 int vrc = RTVfsIoStrmOpenNormal(strTarballPath.c_str(), 2174 RTFILE_O_CREATE | RTFILE_O_WRITE | RTFILE_O_DENY_WRITE, 2175 &hVfsIosFile); 2176 if (RT_SUCCESS(vrc)) 2110 2177 { 2111 const Utf8Str &strDiskID = *it;2112 const VirtualSystemDescriptionEntry *pDiskEntry = stack.mapDisks[strDiskID];2113 const Utf8Str &strSrcFilePath = pDiskEntry->strVBoxCurrent; // where the VBox image is2114 2115 /*2116 * Some skipping.2117 */2118 if (pDiskEntry->skipIt)2119 continue;2120 2121 /* Skip empty media (DVD-ROM, floppy). */2122 if (strSrcFilePath.isEmpty())2123 continue;2124 2125 /* Only deal with harddisk and DVD-ROMs, skip any floppies for now. */2126 if ( pDiskEntry->type != VirtualSystemDescriptionType_HardDiskImage2127 && pDiskEntry->type != VirtualSystemDescriptionType_CDROM)2128 continue;2129 2130 /*2131 * Locate the Medium object for this entry (by location/path).2132 */2133 Log(("Finding source disk \"%s\"\n", strSrcFilePath.c_str()));2134 ComObjPtr<Medium> ptrSourceDisk;2135 if (pDiskEntry->type == VirtualSystemDescriptionType_HardDiskImage)2136 hrc = mVirtualBox->i_findHardDiskByLocation(strSrcFilePath, true, &ptrSourceDisk);2137 else2138 hrc = mVirtualBox->i_findDVDOrFloppyImage(DeviceType_DVD, NULL /*aId*/, strSrcFilePath,2139 true /*aSetError*/, &ptrSourceDisk);2140 if (FAILED(hrc))2141 throw hrc;2142 if (strSrcFilePath.isEmpty())2143 continue;2144 2145 /*2146 * Figure out the names.2147 */2148 2149 /* The name inside the tarball. Replace the suffix of harddisk images with ".img". */2150 Utf8Str strInsideName = pDiskEntry->strOvf;2151 if (pDiskEntry->type == VirtualSystemDescriptionType_HardDiskImage)2152 strInsideName.stripSuffix().append(".img");2153 2154 /* The first tarball we create uses the specified name. Subsequent2155 takes the name from the disk entry or something. */2156 Utf8Str strTarballPath = pTask->locInfo.strPath;2157 if (cTarballs > 0)2158 {2159 /** @todo test this stuff */2160 const char *pszExt = RTPathSuffix(pDiskEntry->strOvf.c_str());2161 pszExt = !pszExt || *pszExt != '.' ? "" : pszExt + 1;2162 2163 strTarballPath.stripFilename().append(RTPATH_SLASH_STR).append(pDiskEntry->strOvf);2164 if (*pszExt)2165 strTarballPath.stripSuffix().append("_").append(pszExt);2166 strTarballPath.append(".tar.gz");2167 }2168 cTarballs++;2169 2170 /*2171 * Create the tar output stream.2172 */2173 RTVFSIOSTREAM hVfsIosFile;2174 int vrc = RTVfsIoStrmOpenNormal(strTarballPath.c_str(),2175 RTFILE_O_CREATE | RTFILE_O_WRITE | RTFILE_O_DENY_WRITE,2176 &hVfsIosFile);2177 if (RT_FAILURE(vrc))2178 throw setErrorVrc(vrc, tr("Failed to create '%s' (%Rrc)"), strTarballPath.c_str(), vrc);2179 2180 2178 RTVFSIOSTREAM hVfsIosGzip = NIL_RTVFSIOSTREAM; 2181 2179 vrc = RTZipGzipCompressIoStream(hVfsIosFile, 0 /*fFlags*/, 6 /*uLevel*/, &hVfsIosGzip); … … 2189 2187 vrc = RTZipTarFsStreamToIoStream(hVfsIosGzip, RTZIPTARFORMAT_GNU, RTZIPTAR_C_SPARSE, &hVfsFssTar); 2190 2188 RTVfsIoStrmRelease(hVfsIosGzip); 2191 2192 if (RT_FAILURE(vrc)) 2189 if (RT_SUCCESS(vrc)) 2193 2190 { 2194 RTFileDelete(strTarballPath.c_str()); 2195 throw setErrorVrc(vrc, tr("Failed to TAR creator instance for '%s' (%Rrc)"), strTarballPath.c_str(), vrc); 2196 } 2197 2198 /* 2199 * The exporting requests a lock on the media tree. So temporarily 2200 * leave the appliance lock. 2201 */ 2202 writeLock.release(); 2203 2204 try 2205 { 2206 /* advance to the next operation */ 2191 /* 2192 * Let the Medium code do the heavy work. 2193 * 2194 * The exporting requests a lock on the media tree. So temporarily 2195 * leave the appliance lock. 2196 */ 2197 writeLock.release(); 2198 2207 2199 pTask->pProgress->SetNextOperation(BstrFmt(tr("Exporting to disk image '%Rbn'"), strTarballPath.c_str()).raw(), 2208 2200 pDiskEntry->ulSizeMB); // operation's weight, as set up … … 2210 2202 hrc = ptrSourceDisk->i_addRawToFss(strInsideName.c_str(), m->m_pSecretKeyStore, hVfsFssTar, 2211 2203 pTask->pProgress, true /*fSparse*/); 2212 if (FAILED(hrc)) 2213 throw hrc; 2214 2215 /* 2216 * Complete and close the tarball. 2217 */ 2218 vrc = RTVfsFsStrmEnd(hVfsFssTar); 2219 RTVfsFsStrmRelease(hVfsFssTar); 2220 hVfsFssTar = NIL_RTVFSFSSTREAM; 2221 if (RT_FAILURE(vrc)) 2222 throw setErrorBoth(VBOX_E_FILE_ERROR, vrc, 2223 tr("Error completing TAR file '%s' (%Rrc)"), strTarballPath.c_str(), vrc); 2224 2225 /* Remember the tarball name for cleanup. */ 2226 try { lstTarballs.push_back(strTarballPath.c_str()); } 2227 catch (std::bad_alloc) { throw E_OUTOFMEMORY; } 2204 2205 writeLock.acquire(); 2206 if (SUCCEEDED(hrc)) 2207 { 2208 /* 2209 * Complete and close the tarball. 2210 */ 2211 vrc = RTVfsFsStrmEnd(hVfsFssTar); 2212 RTVfsFsStrmRelease(hVfsFssTar); 2213 hVfsFssTar = NIL_RTVFSFSSTREAM; 2214 if (RT_SUCCESS(vrc)) 2215 { 2216 /* Remember the tarball name for cleanup. */ 2217 try 2218 { 2219 lstTarballs.push_back(strTarballPath.c_str()); 2220 strTarballPath.setNull(); 2221 } 2222 catch (std::bad_alloc) 2223 { hrc = E_OUTOFMEMORY; } 2224 } 2225 else 2226 hrc = setErrorBoth(VBOX_E_FILE_ERROR, vrc, 2227 tr("Error completing TAR file '%s' (%Rrc)"), strTarballPath.c_str(), vrc); 2228 } 2228 2229 } 2229 catch (HRESULT hrc3)2230 {2231 writeLock.acquire(); 2232 RTVfsFsStrmRelease(hVfsFssTar);2230 else 2231 hrc = setErrorVrc(vrc, tr("Failed to TAR creator instance for '%s' (%Rrc)"), strTarballPath.c_str(), vrc); 2232 2233 if (FAILED(hrc) && strTarballPath.isNotEmpty()) 2233 2234 RTFileDelete(strTarballPath.c_str()); 2234 throw hrc3;2235 }2236 2237 // Finished, lock again (so nobody mess around with the medium tree2238 // in the meantime)2239 writeLock.acquire();2240 2235 } 2241 }2242 catch (HRESULT hrc2)2243 {2244 hrc = hrc2;2236 else 2237 hrc = setErrorVrc(vrc, tr("Failed to create '%s' (%Rrc)"), strTarballPath.c_str(), vrc); 2238 if (FAILED(hrc)) 2239 break; 2245 2240 } 2246 2241
Note:
See TracChangeset
for help on using the changeset viewer.