VirtualBox

Changeset 67252 in vbox


Ignore:
Timestamp:
Jun 2, 2017 3:54:22 PM (8 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
115947
Message:

Main/Appliance::i_writeFSOPC: Clean up. Drop the try/catch based goto-avoidance mess.

File:
1 edited

Legend:

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

    r67249 r67252  
    20902090     */
    20912091    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
    20942114        /*
    2095          * Use i_buildXML to build a stack of disk images.  We don't care about the XML doc here.
     2115         * Some skipping.
    20962116         */
    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)
    20982157        {
    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");
    21012166        }
     2167        cTarballs++;
    21022168
    21032169        /*
    2104          * Process the disk images.
     2170         * Create the tar output stream.
    21052171         */
    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))
    21102177        {
    2111             const Utf8Str                       &strDiskID = *it;
    2112             const VirtualSystemDescriptionEntry *pDiskEntry = stack.mapDisks[strDiskID];
    2113             const Utf8Str                       &strSrcFilePath = pDiskEntry->strVBoxCurrent;  // where the VBox image is
    2114 
    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_HardDiskImage
    2127                 && 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             else
    2138                 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. Subsequent
    2155                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 
    21802178            RTVFSIOSTREAM hVfsIosGzip = NIL_RTVFSIOSTREAM;
    21812179            vrc = RTZipGzipCompressIoStream(hVfsIosFile, 0 /*fFlags*/, 6 /*uLevel*/, &hVfsIosGzip);
     
    21892187                vrc = RTZipTarFsStreamToIoStream(hVfsIosGzip, RTZIPTARFORMAT_GNU, RTZIPTAR_C_SPARSE, &hVfsFssTar);
    21902188            RTVfsIoStrmRelease(hVfsIosGzip);
    2191 
    2192             if (RT_FAILURE(vrc))
     2189            if (RT_SUCCESS(vrc))
    21932190            {
    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
    22072199                pTask->pProgress->SetNextOperation(BstrFmt(tr("Exporting to disk image '%Rbn'"), strTarballPath.c_str()).raw(),
    22082200                                                   pDiskEntry->ulSizeMB);     // operation's weight, as set up
     
    22102202                hrc = ptrSourceDisk->i_addRawToFss(strInsideName.c_str(), m->m_pSecretKeyStore, hVfsFssTar,
    22112203                                                   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                }
    22282229            }
    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())
    22332234                RTFileDelete(strTarballPath.c_str());
    2234                 throw hrc3;
    2235             }
    2236 
    2237             // Finished, lock again (so nobody mess around with the medium tree
    2238             // in the meantime)
    2239             writeLock.acquire();
    22402235        }
    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;
    22452240    }
    22462241
Note: See TracChangeset for help on using the changeset viewer.

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