VirtualBox

Ignore:
Timestamp:
Jun 1, 2017 11:50:09 AM (8 years ago)
Author:
vboxsync
Message:

Main: ApplianceImplExport.cpp: More hacking on OPC exporting.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Main/src-server/ApplianceImplExport.cpp

    r67197 r67203  
    22062206{
    22072207    LogFlowFuncEnter();
     2208    HRESULT hrc = S_OK;
    22082209
    22092210    /*
    2210      * Open the output file, pipe it thru gzip and attach a TAR creator.
     2211     * We're duplicating parts of i_writeFSImpl here because that's simpler
     2212     * and creates less spaghetti code.
    22112213     */
    2212     HRESULT hrc;
    2213     RTVFSIOSTREAM hVfsIosFile;
    2214     int vrc = RTVfsIoStrmOpenNormal(pTask->locInfo.strPath.c_str(),
    2215                                     RTFILE_O_CREATE | RTFILE_O_WRITE | RTFILE_O_DENY_WRITE,
    2216                                     &hVfsIosFile);
    2217     if (RT_SUCCESS(vrc))
    2218     {
    2219 
    2220         RTVFSIOSTREAM hVfsIosGzip;
    2221         vrc = RTZipGzipCompressIoStream(hVfsIosFile, 0 /*fFlags*/, 6 /*uLevel*/, &hVfsIosGzip);
    2222         RTVfsIoStrmRelease(hVfsIosFile);
    2223         if (RT_SUCCESS(vrc))
    2224         {
    2225 
    2226             RTVFSFSSTREAM hVfsFssTar;
    2227             vrc = RTZipTarFsStreamToIoStream(hVfsIosGzip, RTZIPTARFORMAT_GNU, RTZIPTAR_C_SPARSE, &hVfsFssTar);
     2214    std::list<Utf8Str> lstTarballs;
     2215    try
     2216    {
     2217        /*
     2218         * Use i_buildXML to build a stack of disk images.  We don't care about the XML doc here.
     2219         */
     2220        XMLStack stack;
     2221        {
     2222            xml::Document doc;
     2223            i_buildXML(writeLock, doc, stack, pTask->locInfo.strPath, ovf::OVFVersion_2_0);
     2224        }
     2225
     2226        /*
     2227         * Process the disk images.
     2228         */
     2229        unsigned cTarballs = 0;
     2230        for (list<Utf8Str>::const_iterator it = stack.mapDiskSequence.begin();
     2231             it != stack.mapDiskSequence.end();
     2232             ++it)
     2233        {
     2234            const Utf8Str                       &strDiskID = *it;
     2235            const VirtualSystemDescriptionEntry *pDiskEntry = stack.mapDisks[strDiskID];
     2236            const Utf8Str                       &strSrcFilePath = pDiskEntry->strVBoxCurrent;  // where the VBox image is
     2237
     2238            /*
     2239             * Some skipping.
     2240             */
     2241            if (pDiskEntry->skipIt)
     2242                continue;
     2243
     2244            /* Skip empty media (DVD-ROM, floppy). */
     2245            if (strSrcFilePath.isEmpty())
     2246                continue;
     2247
     2248            /* Only deal with harddisk and DVD-ROMs, skip any floppies for now. */
     2249            if (   pDiskEntry->type != VirtualSystemDescriptionType_HardDiskImage
     2250                && pDiskEntry->type != VirtualSystemDescriptionType_CDROM)
     2251                continue;
     2252
     2253            /*
     2254             * Locate the Medium object for this entry (by location/path).
     2255             */
     2256            Log(("Finding source disk \"%s\"\n", strSrcFilePath.c_str()));
     2257            ComObjPtr<Medium> ptrSourceDisk;
     2258            if (pDiskEntry->type == VirtualSystemDescriptionType_HardDiskImage)
     2259                hrc = mVirtualBox->i_findHardDiskByLocation(strSrcFilePath, true, &ptrSourceDisk);
     2260            else
     2261                hrc = mVirtualBox->i_findDVDOrFloppyImage(DeviceType_DVD, NULL /*aId*/, strSrcFilePath,
     2262                                                          true /*aSetError*/, &ptrSourceDisk);
     2263            if (FAILED(hrc))
     2264                throw hrc;
     2265            if (strSrcFilePath.isEmpty())
     2266                continue;
     2267
     2268            /*
     2269             * Figure out the names.
     2270             */
     2271
     2272            /* The name inside the tarball.  Replace the suffix of harddisk images with ".img". */
     2273            Utf8Str strInsideName = pDiskEntry->strOvf;
     2274            if (pDiskEntry->type == VirtualSystemDescriptionType_HardDiskImage)
     2275                strInsideName.stripSuffix().append(".img");
     2276
     2277            /* The first tarball we create uses the specified name. Subsequent
     2278               takes the name from the disk entry or something. */
     2279            Utf8Str strTarballPath = pTask->locInfo.strPath;
     2280            if (cTarballs > 0)
     2281            {
     2282                /** @todo test this stuff   */
     2283                const char *pszExt = RTPathSuffix(pDiskEntry->strOvf.c_str());
     2284                pszExt = !pszExt || *pszExt == '.' ? "" : pszExt + 1;
     2285
     2286                strTarballPath.stripFilename().append(RTPATH_SLASH_STR).append(pDiskEntry->strOvf);
     2287                strTarballPath.stripSuffix().append("_").append(pszExt).append(".tar.gz");
     2288
     2289            }
     2290            cTarballs++;
     2291
     2292            /*
     2293             * Create the tar output stream.
     2294             */
     2295            RTVFSIOSTREAM hVfsIosFile;
     2296            int vrc = RTVfsIoStrmOpenNormal(strTarballPath.c_str(),
     2297                                            RTFILE_O_CREATE | RTFILE_O_WRITE | RTFILE_O_DENY_WRITE,
     2298                                            &hVfsIosFile);
     2299            if (RT_FAILURE(vrc))
     2300                throw setErrorVrc(vrc, tr("Failed to create '%s' (%Rrc)"), strTarballPath.c_str(), vrc);
     2301
     2302            RTVFSIOSTREAM hVfsIosGzip;
     2303            vrc = RTZipGzipCompressIoStream(hVfsIosFile, 0 /*fFlags*/, 6 /*uLevel*/, &hVfsIosGzip);
     2304            RTVfsIoStrmRelease(hVfsIosFile);
     2305
     2306            RTVFSFSSTREAM hVfsFssTar = NIL_RTVFSFSSTREAM;
     2307            if (RT_SUCCESS(vrc))
     2308                vrc = RTZipTarFsStreamToIoStream(hVfsIosGzip, RTZIPTARFORMAT_GNU, RTZIPTAR_C_SPARSE, &hVfsFssTar);
    22282309            RTVfsIoStrmRelease(hVfsIosGzip);
    2229             if (RT_SUCCESS(vrc))
     2310
     2311            if (RT_FAILURE(vrc))
    22302312            {
     2313                RTFileDelete(strTarballPath.c_str());
     2314                throw setErrorVrc(vrc, tr("Failed to TAR creator instance for '%s' (%Rrc)"), strTarballPath.c_str(), vrc);
     2315            }
     2316
     2317            /*
     2318             * The exporting requests a lock on the media tree. So temporarily
     2319             * leave the appliance lock.
     2320             */
     2321            writeLock.release();
     2322
     2323            try
     2324            {
     2325                /* advance to the next operation */
     2326                pTask->pProgress->SetNextOperation(BstrFmt(tr("Exporting to disk image '%Rbn'"), strTarballPath.c_str()).raw(),
     2327                                                   pDiskEntry->ulSizeMB);     // operation's weight, as set up
     2328                                                                              // with the IProgress originally
     2329                ///*
     2330                // * We threat the harddisks are raw images, but since they typically
     2331                // * require a lot more setup and configuration compares to ISOs, we
     2332                // * don't bother trying sharing code here (yet).
     2333                // */
     2334                //if (pDiskEntry->type == VirtualSystemDescriptionType_HardDiskImage)
     2335                    hrc = ptrSourceDisk->i_addRawToFss(strInsideName.c_str(), m->m_pSecretKeyStore, hVfsFssTar /*, pProgress2*/);
     2336                //else if (pDiskEntry->type == VirtualSystemDescriptionType_CDROM)
     2337                //{
     2338                //    /* Open the source image and cast it to a VFS base object. */
     2339                //    RTVFSFILE hVfsSrcFile;
     2340                //    vrc = RTVfsFileOpenNormal(strSrcFilePath.c_str(),
     2341                //                              RTFILE_O_OPEN | RTFILE_O_READ | RTFILE_O_DENY_NONE,
     2342                //                              &hVfsSrcFile);
     2343                //    if (RT_FAILURE(vrc))
     2344                //        throw setErrorBoth(VBOX_E_FILE_ERROR, vrc,
     2345                //                           tr("Could not create or open file '%s' (%Rrc)"), strSrcFilePath.c_str(), vrc);
     2346                //
     2347                //    RTVFSOBJ hVfsSrc = RTVfsObjFromFile(hVfsSrcFile);
     2348                //    RTVfsFileRelease(hVfsSrcFile);
     2349                //    AssertStmt(hVfsSrc != NIL_RTVFSOBJ, throw VERR_INTERNAL_ERROR);
     2350                //
     2351                //    /* Add it to the output stream.  This will pull in all the data from the object. */
     2352                //    vrc = RTVfsFsStrmAdd(hVfsFssTar, strInsideName.c_str(), hVfsSrc, 0 /*fFlags*/);
     2353                //    RTVfsObjRelease(hVfsSrc);
     2354                //    if (RT_FAILURE(vrc))
     2355                //        throw setErrorBoth(VBOX_E_FILE_ERROR, vrc,  tr("Error during copy CD/DVD image '%s' (%Rrc)"),
     2356                //                           strSrcFilePath.c_str(), vrc);
     2357                //}
     2358                //else
     2359                //    AssertFailedStmt(throw E_UNEXPECTED);
     2360                if (FAILED(hrc))
     2361                    throw hrc;
     2362
    22312363                /*
    2232                  * Before we do the actual writing, disable OVF and manifest creation.
     2364                 * Complete and close the tarball.
    22332365                 */
    2234                 bool fManifestSaved = m->fManifest;
    2235                 m->fManifest = false;
    2236 
    2237                 hrc = i_writeFSImpl(pTask, writeLock, hVfsFssTar, false /*fOvfFile*/, false /*fStreamOptimizedVmdk*/);
     2366                vrc = RTVfsFsStrmEnd(hVfsFssTar);
    22382367                RTVfsFsStrmRelease(hVfsFssTar);
    2239 
    2240                 m->fManifest = fManifestSaved;
     2368                hVfsFssTar = NIL_RTVFSFSSTREAM;
     2369                if (RT_FAILURE(vrc))
     2370                    throw setErrorBoth(VBOX_E_FILE_ERROR, vrc,
     2371                                       tr("Error completing TAR file '%s' (%Rrc)"), strTarballPath.c_str(), vrc);
     2372
     2373                /* Remember the tarball name for cleanup. */
     2374                try { lstTarballs.push_back(strTarballPath.c_str()); }
     2375                catch (std::bad_alloc) { throw E_OUTOFMEMORY; }
    22412376            }
    2242             else
    2243                 hrc = setErrorVrc(vrc, tr("Failed create TAR creator for '%s' (%Rrc)"), pTask->locInfo.strPath.c_str(), vrc);
    2244         }
    2245         else
    2246             hrc = setErrorVrc(vrc, tr("Failed create gzipper for '%s' (%Rrc)"), pTask->locInfo.strPath.c_str(), vrc);
    2247 
    2248         /* Delete the OVA on failure. */
    2249         if (FAILED(hrc))
    2250             RTFileDelete(pTask->locInfo.strPath.c_str());
    2251     }
    2252     else
    2253         hrc = setErrorVrc(vrc, tr("Failed to open '%s' for writing (%Rrc)"), pTask->locInfo.strPath.c_str(), vrc);
     2377            catch (HRESULT hrc3)
     2378            {
     2379                writeLock.acquire();
     2380                RTVfsFsStrmRelease(hVfsFssTar);
     2381                RTFileDelete(strTarballPath.c_str());
     2382                throw hrc3;
     2383            }
     2384
     2385            // Finished, lock again (so nobody mess around with the medium tree
     2386            // in the meantime)
     2387            writeLock.acquire();
     2388        }
     2389    }
     2390    catch (HRESULT hrc2)
     2391    {
     2392        hrc = hrc2;
     2393    }
     2394
     2395    /*
     2396     * Delete output files on failure.
     2397     */
     2398    if (FAILED(hrc))
     2399        for (list<Utf8Str>::const_iterator it = lstTarballs.begin(); it != lstTarballs.end(); ++it)
     2400            RTFileDelete(it->c_str());
    22542401
    22552402    LogFlowFuncLeave();
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette