VirtualBox

Changeset 67184 in vbox


Ignore:
Timestamp:
May 31, 2017 8:32:04 PM (8 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
115861
Message:

Main: Reworking IAppliance export to use new TAR creator. Changes protected by VBOX_WITH_NEW_TAR_CREATOR define (currently not defined).

Location:
trunk/src/VBox/Main
Files:
9 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Main/Makefile.kmk

    r67067 r67184  
    373373        $(if $(VBOX_WITH_EHCI),VBOX_WITH_EHCI,) \
    374374        $(if $(VBOX_WITH_NEW_USB_CODE_ON_DARWIN),VBOX_WITH_NEW_USB_CODE_ON_DARWIN,)
     375endif
     376if defined(VBOX_WITH_NEW_TAR_CREATOR) #|| "$(USERNAME)" == "bird" # temporary
     377 VBoxSVC_DEFS += VBOX_WITH_NEW_TAR_CREATOR
    375378endif
    376379VBoxSVC_DEFS.win += VBOX_COM_OUTOFPROC_MODULE
  • trunk/src/VBox/Main/include/ApplianceImpl.h

    r67142 r67184  
    148148
    149149    HRESULT i_findMediumFormatFromDiskImage(const ovf::DiskImage &di, ComObjPtr<MediumFormat>& mf);
     150
     151    RTVFSIOSTREAM i_manifestSetupDigestCalculationForGivenIoStream(RTVFSIOSTREAM hVfsIos, const char *pszManifestEntry,
     152                                                                   bool fRead = true);
    150153    /** @}  */
    151154
     
    198201    HRESULT i_preCheckImageAvailability(ImportStack &stack);
    199202    bool    i_importEnsureOvaLookAhead(ImportStack &stack);
    200     RTVFSIOSTREAM i_importSetupDigestCalculationForGivenIoStream(RTVFSIOSTREAM hVfsIos, const char *pszManifestEntry);
    201203    RTVFSIOSTREAM i_importOpenSourceFile(ImportStack &stack, Utf8Str const &rstrSrcPath, const char *pszManifestEntry);
    202204    HRESULT i_importCreateAndWriteDestinationFile(Utf8Str const &rstrDstPath,
     
    217219    HRESULT i_writeFSOVF(TaskOVF *pTask, AutoWriteLockBase& writeLock);
    218220    HRESULT i_writeFSOVA(TaskOVF *pTask, AutoWriteLockBase& writeLock);
    219     HRESULT i_writeFSImpl(TaskOVF *pTask, AutoWriteLockBase &writeLock, RTVFSFSSTREAM hVfsFss,
    220                           PVDINTERFACEIO pCallbacks, PSHASTORAGE pStorage);
     221#ifdef VBOX_WITH_NEW_TAR_CREATOR
     222    HRESULT i_writeFSImpl(TaskOVF *pTask, AutoWriteLockBase &writeLock, RTVFSFSSTREAM hVfsFssDst);
     223    HRESULT i_writeBufferToFile(RTVFSFSSTREAM hVfsFssDst, const char *pszFilename, const void *pvContent, size_t cbContent);
     224#else
     225    HRESULT i_writeFSImpl(TaskOVF *pTask, AutoWriteLockBase &writeLock, PVDINTERFACEIO pCallbacks, PSHASTORAGE pStorage);
     226#endif
    221227
    222228    struct XMLStack;
  • trunk/src/VBox/Main/include/ApplianceImplPrivate.h

    r67142 r67184  
    1919#define ____H_APPLIANCEIMPLPRIVATE
    2020
    21 #ifdef DEBUG_bird
    22 # define MAIN_WITH_NEW_TAR_CREATOR
    23 #endif
    2421
    2522class VirtualSystemDescription;
     
    7471      , hOurManifest(NIL_RTMANIFEST)
    7572      , fManifest(true)
     73#ifndef VBOX_WITH_NEW_TAR_CREATOR
    7674      , fSha256(false)
     75#endif
    7776      , fDeterminedDigestTypes(false)
    7877      , hTheirManifest(NIL_RTMANIFEST)
     
    163162     * @{ */
    164163    bool                fManifest;      // Create a manifest file on export
     164#ifndef VBOX_WITH_NEW_TAR_CREATOR
    165165    bool                fSha256;        // true = SHA256 (OVF 2.0), false = SHA1 (OVF 1.0)
     166#endif
    166167    /** @} */
    167168
  • trunk/src/VBox/Main/include/MediumImpl.h

    r62810 r67184  
    207207                         MediumVariant_T aVariant,
    208208                         SecretKeyStore *pKeyStore,
     209#ifdef VBOX_WITH_NEW_TAR_CREATOR
     210                         RTVFSIOSTREAM hVfsIosDst,
     211#else
    209212                         PVDINTERFACEIO aVDImageIOIf, void *aVDImageIOUser,
     213#endif
    210214                         const ComObjPtr<Progress> &aProgress);
    211215    HRESULT i_importFile(const char *aFilename,
  • trunk/src/VBox/Main/src-server/ApplianceImpl.cpp

    r65186 r67184  
    872872
    873873/**
     874 * Setup automatic I/O stream digest calculation, adding it to hOurManifest.
     875 *
     876 * @returns Passthru I/O stream, of @a hVfsIos if no digest calc needed.
     877 * @param   hVfsIos             The stream to wrap. Always consumed.
     878 * @param   pszManifestEntry    The manifest entry.
     879 * @param   fRead               Set if read stream, clear if write.
     880 * @throws  Nothing.
     881 */
     882RTVFSIOSTREAM Appliance::i_manifestSetupDigestCalculationForGivenIoStream(RTVFSIOSTREAM hVfsIos, const char *pszManifestEntry,
     883                                                                          bool fRead /*= true */)
     884{
     885    int vrc;
     886    Assert(!RTManifestPtIosIsInstanceOf(hVfsIos));
     887
     888    if (m->fDigestTypes == 0)
     889        return hVfsIos;
     890
     891    /* Create the manifest if necessary. */
     892    if (m->hOurManifest == NIL_RTMANIFEST)
     893    {
     894        vrc = RTManifestCreate(0 /*fFlags*/, &m->hOurManifest);
     895        AssertRCReturnStmt(vrc, RTVfsIoStrmRelease(hVfsIos), NIL_RTVFSIOSTREAM);
     896    }
     897
     898    /* Setup the stream. */
     899    RTVFSIOSTREAM hVfsIosPt;
     900    vrc = RTManifestEntryAddPassthruIoStream(m->hOurManifest, hVfsIos, pszManifestEntry, m->fDigestTypes, fRead, &hVfsIosPt);
     901
     902    RTVfsIoStrmRelease(hVfsIos);        /* always consumed! */
     903    if (RT_SUCCESS(vrc))
     904        return hVfsIosPt;
     905
     906    setErrorVrc(vrc, "RTManifestEntryAddPassthruIoStream failed with rc=%Rrc", vrc);
     907    return NIL_RTVFSIOSTREAM;
     908}
     909
     910/**
    874911 * Returns true if the appliance is in "idle" state. This should always be the
    875912 * case unless an import or export is currently in progress. Similar to machine
  • trunk/src/VBox/Main/src-server/ApplianceImplExport.cpp

    r67142 r67184  
    2121#include <iprt/s3.h>
    2222#include <iprt/manifest.h>
    23 #include <iprt/tar.h>
    2423#include <iprt/stream.h>
     24#ifndef VBOX_WITH_NEW_TAR_CREATOR
     25# include <iprt/tar.h>
     26#else
     27# include <iprt/zip.h>
     28#endif
    2529
    2630#include <VBox/version.h>
     
    675679                        tr("Appliance file must have .ovf or .ova extension"));
    676680
    677     m->fManifest = m->optListExport.contains(ExportOptions_CreateManifest);
    678 
    679681    ovf::OVFVersion_T ovfF;
    680682    if (aFormat == "ovf-0.9")
    681     {
    682683        ovfF = ovf::OVFVersion_0_9;
    683     }
    684684    else if (aFormat == "ovf-1.0")
    685     {
    686685        ovfF = ovf::OVFVersion_1_0;
    687     }
    688686    else if (aFormat == "ovf-2.0")
    689     {
    690687        ovfF = ovf::OVFVersion_2_0;
    691     }
    692688    else
    693689        return setError(VBOX_E_FILE_ERROR,
    694690                        tr("Invalid format \"%s\" specified"), aFormat.c_str());
     691
     692    /* As of OVF 2.0 we have to use SHA-256 in the manifest. */
     693    m->fManifest = m->optListExport.contains(ExportOptions_CreateManifest);
     694    if (m->fManifest)
     695        m->fDigestTypes = ovfF >= ovf::OVFVersion_2_0 ? RTMANIFEST_ATTR_SHA256 : RTMANIFEST_ATTR_SHA1;
     696#ifndef VBOX_WITH_NEW_TAR_CREATOR
     697    m->fSha256 = ovfF >= ovf::OVFVersion_2_0;
     698#endif
     699    Assert(m->hOurManifest == NIL_RTMANIFEST);
    695700
    696701    /* Check whether all passwords are supplied or error out. */
     
    698703        return setError(VBOX_E_INVALID_OBJECT_STATE,
    699704                        tr("Appliance export failed because not all passwords were provided for all encrypted media"));
    700 
    701     /* as of OVF 2.0 we have to use SHA256 */
    702     m->fSha256 = ovfF >= ovf::OVFVersion_2_0;
    703705
    704706    ComObjPtr<Progress> progress;
     
    19911993    LogFlowFuncEnter();
    19921994
     1995#ifdef VBOX_WITH_NEW_TAR_CREATOR
     1996    HRESULT hrc = E_NOTIMPL;
     1997    AssertFailed();
     1998    RT_NOREF(pTask, writeLock);
     1999
     2000    /** @todo need a FSS creator wrapper around a directory here.   */
     2001
     2002    LogFlowFuncLeave();
     2003    return hrc;
     2004
     2005#else /* VBOX_WITH_NEW_TAR_CREATOR */
    19932006    HRESULT rc = S_OK;
    19942007
     
    20262039            break;
    20272040        }
    2028         rc = i_writeFSImpl(pTask, writeLock, NIL_RTVFSFSSTREAM, pShaIo, &storage);
     2041        rc = i_writeFSImpl(pTask, writeLock, pShaIo, &storage);
    20292042    } while (0);
    20302043
     
    20372050    LogFlowFuncLeave();
    20382051    return rc;
     2052#endif
    20392053}
    20402054
    2041 HRESULT Appliance::i_writeFSOVA(TaskOVF *pTask, AutoWriteLockBase& writeLock)
     2055HRESULT Appliance::i_writeFSOVA(TaskOVF *pTask, AutoWriteLockBase &writeLock)
    20422056{
    20432057    LogFlowFuncEnter();
     2058
     2059#ifdef VBOX_WITH_NEW_TAR_CREATOR
     2060    /*
     2061     * Open the output file and attach a TAR creator to it.
     2062     */
     2063    HRESULT hrc;
     2064    RTVFSIOSTREAM hVfsIosTar;
     2065    int vrc = RTVfsIoStrmOpenNormal(pTask->locInfo.strPath.c_str(),
     2066                                    RTFILE_O_CREATE | RTFILE_O_WRITE | RTFILE_O_DENY_WRITE,
     2067                                    &hVfsIosTar);
     2068    if (RT_SUCCESS(vrc))
     2069    {
     2070        /** @todo which format does the standard dicate here actually?
     2071         *  GNU or USTAR/POSIX? */
     2072        RTVFSFSSTREAM hVfsFssTar;
     2073        vrc = RTZipTarFsStreamToIoStream(hVfsIosTar, RTZIPTARFORMAT_GNU, 0 /*fFlags*/, &hVfsFssTar);
     2074        RTVfsIoStrmRelease(hVfsIosTar);
     2075        if (RT_SUCCESS(vrc))
     2076        {
     2077            hrc = i_writeFSImpl(pTask, writeLock, hVfsFssTar);
     2078            RTVfsFsStrmRelease(hVfsFssTar);
     2079        }
     2080        else
     2081            hrc = setErrorVrc(vrc, tr("Failed create TAR creator for '%s' (%Rrc)"), pTask->locInfo.strPath.c_str(), vrc);
     2082
     2083        /* Delete the OVA on failure. */
     2084        if (FAILED(hrc))
     2085            RTFileDelete(pTask->locInfo.strPath.c_str());
     2086    }
     2087    else
     2088        hrc = setErrorVrc(vrc, tr("Failed to open '%s' for writing (%Rrc)"), pTask->locInfo.strPath.c_str(), vrc);
     2089
     2090    LogFlowFuncLeave();
     2091    return hrc;
     2092
     2093#else /* VBOX_WITH_NEW_TAR_CREATOR */
    20442094
    20452095    RTTAR tar;
     
    20842134            break;
    20852135        }
    2086         rc = i_writeFSImpl(pTask, writeLock, NIL_RTVFSFSSTREAM, pShaIo, &storage);
     2136        rc = i_writeFSImpl(pTask, writeLock, pShaIo, &storage);
    20872137    } while (0);
    20882138
     
    21012151    LogFlowFuncLeave();
    21022152    return rc;
     2153#endif
    21032154}
    21042155
    2105 HRESULT Appliance::i_writeFSImpl(TaskOVF *pTask, AutoWriteLockBase& writeLock, RTVFSFSSTREAM hVfsFssOut,
    2106                                  PVDINTERFACEIO pIfIo, PSHASTORAGE pStorage)
     2156#ifdef VBOX_WITH_NEW_TAR_CREATOR
     2157HRESULT Appliance::i_writeFSImpl(TaskOVF *pTask, AutoWriteLockBase &writeLock, RTVFSFSSTREAM hVfsFssDst)
     2158#else
     2159HRESULT Appliance::i_writeFSImpl(TaskOVF *pTask, AutoWriteLockBase& writeLock, PVDINTERFACEIO pIfIo, PSHASTORAGE pStorage)
     2160#endif
    21072161{
    21082162    LogFlowFuncEnter();
    21092163
    21102164    HRESULT rc = S_OK;
    2111 
     2165#ifdef VBOX_WITH_NEW_TAR_CREATOR
     2166    RTMANIFEST hManifest;
     2167    int vrc = RTManifestCreate(0 /*fFlags*/, &hManifest);
     2168
     2169#else
     2170    int vrc;
    21122171    list<STRPAIR> fileList;
     2172#endif
    21132173    try
    21142174    {
    2115         int vrc;
    21162175        // the XML stack contains two maps for disks and networks, which allows us to
    21172176        // a) have a list of unique disk names (to make sure the same disk name is only added once)
     
    21202179        // Scope this to free the memory as soon as this is finished
    21212180        {
    2122             // Create a xml document
     2181            /* Construct the OVF name. */
     2182            Utf8Str strOvfFile(pTask->locInfo.strPath);
     2183            strOvfFile.stripSuffix().append(".ovf");
     2184
     2185            /* Render a valid ovf document into a memory buffer. */
    21232186            xml::Document doc;
    2124             // Now fully build a valid ovf document in memory
    21252187            i_buildXML(writeLock, doc, stack, pTask->locInfo.strPath, pTask->enFormat);
    2126             /* Extract the OVA file name */
    2127             Utf8Str strOvaFile = pTask->locInfo.strPath;
    2128             /* Extract the path */
    2129             Utf8Str strOvfFile = strOvaFile.stripSuffix().append(".ovf");
    2130             // Create a memory buffer containing the XML. */
    2131             void *pvBuf = 0;
    2132             size_t cbSize;
     2188
     2189            void *pvBuf = NULL;
     2190            size_t cbSize = 0;
    21332191            xml::XmlMemWriter writer;
    21342192            writer.write(doc, &pvBuf, &cbSize);
     
    21372195                               tr("Could not create OVF file '%s'"),
    21382196                               strOvfFile.c_str());
    2139             /* Write the ovf file to disk. */
    2140             if (hVfsFssOut != NIL_RTVFSFSSTREAM)
    2141                 vrc = writeBufferToFile(strOvfFile.c_str(), pvBuf, cbSize, hVfsFssOut);
    2142             else
    2143                 vrc = writeBufferToFile(strOvfFile.c_str(), pvBuf, cbSize, pIfIo, pStorage);
     2197
     2198            /* Write the ovf file to "disk". */
     2199#ifdef VBOX_WITH_NEW_TAR_CREATOR
     2200            rc = i_writeBufferToFile(hVfsFssDst, strOvfFile.c_str(), pvBuf, cbSize);
     2201            if (FAILED(rc))
     2202                throw rc;
     2203#else
     2204            vrc = writeBufferToFile(strOvfFile.c_str(), pvBuf, cbSize, pIfIo, pStorage);
    21442205            if (RT_FAILURE(vrc))
    2145 
    2146                 throw setError(VBOX_E_FILE_ERROR,
    2147                                tr("Could not create OVF file '%s' (%Rrc)"),
    2148                                strOvfFile.c_str(), vrc);
     2206                throw setErrorVrc(vrc, tr("Could not create OVF file '%s' (%Rrc)"), strOvfFile.c_str(), vrc);
     2207#endif
     2208
     2209#ifndef VBOX_WITH_NEW_TAR_CREATOR
    21492210            fileList.push_back(STRPAIR(strOvfFile, pStorage->strDigest));
     2211#endif
    21502212        }
    21512213
     
    22492311                    if (FAILED(rc)) throw rc;
    22502312
    2251                     if (hVfsFssOut != NIL_RTVFSFSSTREAM)
    2252                         rc = E_NOTIMPL; /** @todo Continue here later. Need to (1) wrap the FSS thing (in the caller?)
    2253                                          *        and (2) provide a push API for adding streams.  (RTVfsFsStrmAdd is a pull API,
    2254                                          *        in that it pulls in the data bytes itself.) */
    2255                     else
     2313#ifdef VBOX_WITH_NEW_TAR_CREATOR
     2314                    /* For compressed VMDK fun, we let i_exportFile produce the image bytes. */
     2315                    if (true)
    22562316                    {
     2317                        RTVFSIOSTREAM hVfsIosDst;
     2318                        vrc = RTVfsFsStrmPushFile(hVfsFssDst, strTargetFilePath.c_str(), UINT64_MAX,
     2319                                                  NULL /*paObjInfo*/, 0 /*cObjInfo*/, RTVFSFSSTRM_PUSH_F_STREAM, &hVfsIosDst);
     2320                        if (RT_FAILURE(vrc))
     2321                            throw setErrorVrc(vrc, tr("RTVfsFsStrmPushFile failed for '%s' (%Rrc)"), strTargetFilePath.c_str(), vrc);
     2322                        hVfsIosDst = i_manifestSetupDigestCalculationForGivenIoStream(hVfsIosDst, strTargetFilePath.c_str(),
     2323                                                                                      false /*fRead*/);
     2324                        if (hVfsIosDst == NIL_RTVFSIOSTREAM)
     2325                            throw setError(E_FAIL, "i_manifestSetupDigestCalculationForGivenIoStream(%s)", strTargetFilePath.c_str());
     2326
    22572327                        rc = pSourceDisk->i_exportFile(strTargetFilePath.c_str(),
    22582328                                                       format,
    22592329                                                       MediumVariant_VmdkStreamOptimized,
    22602330                                                       m->m_pSecretKeyStore,
    2261                                                        pIfIo,
    2262                                                        pStorage,
     2331                                                       hVfsIosDst,
    22632332                                                       pProgress2);
     2333                        RTVfsIoStrmRelease(hVfsIosDst);
     2334                        if (FAILED(rc)) throw rc;
    22642335                    }
     2336                    /* When creating sparse raw images, the tar creator stream pulls the data
     2337                       out of the disk image.  It will scan for empty space first, then copy
     2338                       the non-empty segments into the tar stream. */
     2339                    else
     2340                    {
     2341                        throw E_NOTIMPL;
     2342                    }
     2343#else
     2344                    rc = pSourceDisk->i_exportFile(strTargetFilePath.c_str(),
     2345                                                   format,
     2346                                                   MediumVariant_VmdkStreamOptimized,
     2347                                                   m->m_pSecretKeyStore,
     2348                                                   pIfIo,
     2349                                                   pStorage,
     2350                                                   pProgress2);
    22652351                    if (FAILED(rc)) throw rc;
     2352#endif
    22662353
    22672354                    ComPtr<IProgress> pProgress3(pProgress2);
     
    22762363                    Assert(pDiskEntry->type == VirtualSystemDescriptionType_CDROM);
    22772364
    2278                     if (hVfsFssOut != NIL_RTVFSFSSTREAM)
     2365#ifdef VBOX_WITH_NEW_TAR_CREATOR
     2366                    /* Open the source image and cast it to a VFS base object. */
     2367                    RTVFSFILE hVfsSrcFile;
     2368                    vrc = RTVfsFileOpenNormal(strSrcFilePath.c_str(),
     2369                                              RTFILE_O_OPEN | RTFILE_O_READ | RTFILE_O_DENY_NONE,
     2370                                              &hVfsSrcFile);
     2371                    if (RT_FAILURE(vrc))
     2372                        throw setErrorBoth(VBOX_E_FILE_ERROR, vrc,
     2373                                           tr("Could not create or open file '%s' (%Rrc)"), strSrcFilePath.c_str(), vrc);
     2374
     2375                    RTVFSOBJ hVfsSrc = RTVfsObjFromFile(hVfsSrcFile);
     2376                    RTVfsFileRelease(hVfsSrcFile);
     2377                    AssertStmt(hVfsSrc != NIL_RTVFSOBJ, throw VERR_INTERNAL_ERROR);
     2378
     2379                    /* Add it to the output stream.  This will pull in all the data from the object. */
     2380                    vrc = RTVfsFsStrmAdd(hVfsFssDst, strTargetFilePath.c_str(), hVfsSrc, 0 /*fFlags*/);
     2381                    RTVfsObjRelease(hVfsSrc);
     2382                    if (RT_FAILURE(vrc))
     2383                        throw setErrorBoth(VBOX_E_FILE_ERROR, vrc,  tr("Error during copy CD/DVD image '%s' (%Rrc)"),
     2384                                           strSrcFilePath.c_str(), vrc);
     2385#else
     2386                    /* Read the ISO file and add one to OVA/OVF package */
     2387                    void *pvStorage;
     2388                    RTFILE pFile = NULL;
     2389                    void *pvUser = pStorage;
     2390
     2391                    vrc = pIfIo->pfnOpen(pvUser, strTargetFilePath.c_str(),
     2392                                         RTFILE_O_OPEN_CREATE | RTFILE_O_WRITE | RTFILE_O_DENY_NONE,
     2393                                         0,
     2394                                         &pvStorage);
     2395                    if (RT_FAILURE(vrc))
     2396                        throw setError(VBOX_E_FILE_ERROR,
     2397                                       tr("Could not create or open file '%s' (%Rrc)"),
     2398                                       strTargetFilePath.c_str(), vrc);
     2399
     2400                    vrc = RTFileOpen(&pFile,
     2401                                     strSrcFilePath.c_str(),
     2402                                     RTFILE_O_OPEN | RTFILE_O_READ | RTFILE_O_DENY_NONE);
     2403
     2404                    if (RT_FAILURE(vrc) || pFile == NULL)
    22792405                    {
    2280                         /* Open the source image and cast it to a VFS base object. */
    2281                         RTVFSFILE hVfsSrcFile;
    2282                         vrc = RTVfsFileOpenNormal(strSrcFilePath.c_str(),
    2283                                                   RTFILE_O_OPEN | RTFILE_O_READ | RTFILE_O_DENY_NONE,
    2284                                                   &hVfsSrcFile);
    2285                         if (RT_FAILURE(vrc))
    2286                             throw setErrorBoth(VBOX_E_FILE_ERROR, vrc,
    2287                                                tr("Could not create or open file '%s' (%Rrc)"), strSrcFilePath.c_str(), vrc);
    2288 
    2289                         RTVFSOBJ hVfsSrc = RTVfsObjFromFile(hVfsSrcFile);
    2290                         RTVfsFileRelease(hVfsSrcFile);
    2291                         AssertStmt(hVfsSrc != NIL_RTVFSOBJ, throw VERR_INTERNAL_ERROR);
    2292 
    2293                         /* Add it to the output stream.  This will pull in all the data from the object. */
    2294                         vrc = RTVfsFsStrmAdd(hVfsFssOut, strTargetFilePath.c_str(), hVfsSrc, 0 /*fFlags*/);
    2295                         RTVfsObjRelease(hVfsSrc);
    2296                         if (RT_FAILURE(vrc))
    2297                             throw setErrorBoth(VBOX_E_FILE_ERROR, vrc,  tr("Error during copy CD/DVD image '%s' (%Rrc)"),
    2298                                                strSrcFilePath.c_str(), vrc);
     2406                        pIfIo->pfnClose(pvUser, pvStorage);
     2407                        throw setError(VBOX_E_FILE_ERROR,
     2408                                       tr("Could not create or open file '%s' (%Rrc)"),
     2409                                       strSrcFilePath.c_str(), vrc);
    22992410                    }
    2300                     else
     2411
     2412                    uint64_t cbFile = 0;
     2413                    vrc = RTFileGetSize(pFile, &cbFile);
     2414                    if (RT_SUCCESS(vrc))
    23012415                    {
    2302                         /* Read the ISO file and add one to OVA/OVF package */
    2303                         void *pvStorage;
    2304                         RTFILE pFile = NULL;
    2305                         void *pvUser = pStorage;
    2306 
    2307                         vrc = pIfIo->pfnOpen(pvUser, strTargetFilePath.c_str(),
    2308                                              RTFILE_O_OPEN_CREATE | RTFILE_O_WRITE | RTFILE_O_DENY_NONE,
    2309                                              0,
    2310                                              &pvStorage);
    2311                         if (RT_FAILURE(vrc))
     2416                        size_t const cbTmpSize = _1M;
     2417                        void *pvTmpBuf = RTMemAlloc(cbTmpSize);
     2418                        if (pvTmpBuf)
     2419                        {
     2420                            /* The copy loop. */
     2421                            uint64_t offDstFile = 0;
     2422                            for (;;)
     2423                            {
     2424                                size_t cbChunk = 0;
     2425                                vrc = RTFileRead(pFile, pvTmpBuf, cbTmpSize, &cbChunk);
     2426                                if (RT_FAILURE(vrc) || cbChunk == 0)
     2427                                    break;
     2428
     2429                                size_t cbWritten = 0;
     2430                                vrc = pIfIo->pfnWriteSync(pvUser,
     2431                                                          pvStorage,
     2432                                                          offDstFile,
     2433                                                          pvTmpBuf,
     2434                                                          cbChunk,
     2435                                                          &cbWritten);
     2436                                if (RT_FAILURE(vrc))
     2437                                    break;
     2438                                Assert(cbWritten == cbChunk);
     2439
     2440                                offDstFile += cbWritten;
     2441                            }
     2442
     2443                            RTMemFree(pvTmpBuf);
     2444                        }
     2445                        else
     2446                            vrc = VERR_NO_MEMORY;
     2447                    }
     2448
     2449                    pIfIo->pfnClose(pvUser, pvStorage);
     2450                    RTFileClose(pFile);
     2451
     2452                    if (RT_FAILURE(vrc))
     2453                    {
     2454                        if (vrc == VERR_EOF)
     2455                            vrc = VINF_SUCCESS;
     2456                        else
    23122457                            throw setError(VBOX_E_FILE_ERROR,
    2313                                            tr("Could not create or open file '%s' (%Rrc)"),
    2314                                            strTargetFilePath.c_str(), vrc);
    2315 
    2316                         vrc = RTFileOpen(&pFile,
    2317                                          strSrcFilePath.c_str(),
    2318                                          RTFILE_O_OPEN | RTFILE_O_READ | RTFILE_O_DENY_NONE);
    2319 
    2320                         if (RT_FAILURE(vrc) || pFile == NULL)
    2321                         {
    2322                             pIfIo->pfnClose(pvUser, pvStorage);
    2323                             throw setError(VBOX_E_FILE_ERROR,
    2324                                            tr("Could not create or open file '%s' (%Rrc)"),
     2458                                           tr("Error during copy CD/DVD image '%s' (%Rrc)"),
    23252459                                           strSrcFilePath.c_str(), vrc);
    2326                         }
    2327 
    2328                         uint64_t cbFile = 0;
    2329                         vrc = RTFileGetSize(pFile, &cbFile);
    2330                         if (RT_SUCCESS(vrc))
    2331                         {
    2332                             size_t const cbTmpSize = _1M;
    2333                             void *pvTmpBuf = RTMemAlloc(cbTmpSize);
    2334                             if (pvTmpBuf)
    2335                             {
    2336                                 /* The copy loop. */
    2337                                 uint64_t offDstFile = 0;
    2338                                 for (;;)
    2339                                 {
    2340                                     size_t cbChunk = 0;
    2341                                     vrc = RTFileRead(pFile, pvTmpBuf, cbTmpSize, &cbChunk);
    2342                                     if (RT_FAILURE(vrc) || cbChunk == 0)
    2343                                         break;
    2344 
    2345                                     size_t cbWritten = 0;
    2346                                     vrc = pIfIo->pfnWriteSync(pvUser,
    2347                                                               pvStorage,
    2348                                                               offDstFile,
    2349                                                               pvTmpBuf,
    2350                                                               cbChunk,
    2351                                                               &cbWritten);
    2352                                     if (RT_FAILURE(vrc))
    2353                                         break;
    2354                                     Assert(cbWritten == cbChunk);
    2355 
    2356                                     offDstFile += cbWritten;
    2357                                 }
    2358 
    2359                                 RTMemFree(pvTmpBuf);
    2360                             }
    2361                             else
    2362                                 vrc = VERR_NO_MEMORY;
    2363                         }
    2364 
    2365                         pIfIo->pfnClose(pvUser, pvStorage);
    2366                         RTFileClose(pFile);
    2367 
    2368                         if (RT_FAILURE(vrc))
    2369                         {
    2370                             if (vrc == VERR_EOF)
    2371                                 vrc = VINF_SUCCESS;
    2372                             else
    2373                                 throw setError(VBOX_E_FILE_ERROR,
    2374                                                tr("Error during copy CD/DVD image '%s' (%Rrc)"),
    2375                                                strSrcFilePath.c_str(), vrc);
    2376                         }
    23772460                    }
     2461#endif
    23782462                }
    23792463            }
     
    23872471            // in the meantime)
    23882472            writeLock.acquire();
     2473#ifndef VBOX_WITH_NEW_TAR_CREATOR
    23892474            fileList.push_back(STRPAIR(strTargetFilePath, pStorage->strDigest));
     2475#endif
    23902476        }
    23912477
     
    23982484                                               m->ulWeightForManifestOperation);     // operation's weight, as set up
    23992485                                                                                     // with the IProgress originally);
     2486#ifdef VBOX_WITH_NEW_TAR_CREATOR
     2487            /* Create a memory I/O stream and write the manifest to it. */
     2488            RTVFSIOSTREAM hVfsIosManifest;
     2489            vrc = RTVfsMemIoStrmCreate(NIL_RTVFSIOSTREAM, _1K, &hVfsIosManifest);
     2490            if (RT_FAILURE(vrc))
     2491                throw setErrorVrc(vrc, tr("RTVfsMemIoStrmCreate failed (%Rrc)"), vrc);
     2492            if (m->hOurManifest != NIL_RTMANIFEST) /* In case it's empty. */
     2493                vrc = RTManifestWriteStandard(m->hOurManifest, hVfsIosManifest);
     2494            if (RT_SUCCESS(vrc))
     2495            {
     2496                /* Rewind the stream and add it to the output. */
     2497                size_t cbIgnored;
     2498                vrc = RTVfsIoStrmReadAt(hVfsIosManifest, 0 /*offset*/, &cbIgnored, 0, true /*fBlocking*/, &cbIgnored);
     2499                if (RT_SUCCESS(vrc))
     2500                {
     2501                    RTVFSOBJ hVfsObjManifest = RTVfsObjFromIoStream(hVfsIosManifest);
     2502                    vrc = RTVfsFsStrmAdd(hVfsFssDst, strMfFilePath.c_str(), hVfsObjManifest, 0 /*fFlags*/);
     2503                    if (RT_SUCCESS(vrc))
     2504                        rc = S_OK;
     2505                    else
     2506                        rc = setErrorVrc(vrc, tr("RTVfsFsStrmAdd failed for the manifest (%Rrc)"), vrc);
     2507                }
     2508                else
     2509                    rc = setErrorVrc(vrc, tr("RTManifestWriteStandard failed (%Rrc)"), vrc);
     2510            }
     2511            else
     2512                rc = setErrorVrc(vrc, tr("RTManifestWriteStandard failed (%Rrc)"), vrc);
     2513            RTVfsIoStrmRelease(hVfsIosManifest);
     2514            if (FAILED(rc))
     2515                throw rc;
     2516#else
    24002517            PRTMANIFESTTEST paManifestFiles = (PRTMANIFESTTEST)RTMemAlloc(sizeof(RTMANIFESTTEST) * fileList.size());
    24012518            size_t i = 0;
     
    24202537            pStorage->fCreateDigest = false;
    24212538            /* Write the manifest file to disk. */
    2422             if (hVfsFssOut != NIL_RTVFSFSSTREAM)
    2423                 vrc = writeBufferToFile(strMfFilePath.c_str(), pvBuf, cbSize, hVfsFssOut);
    2424             else
    2425                 vrc = writeBufferToFile(strMfFilePath.c_str(), pvBuf, cbSize, pIfIo, pStorage);
     2539            vrc = writeBufferToFile(strMfFilePath.c_str(), pvBuf, cbSize, pIfIo, pStorage);
    24262540            RTMemFree(pvBuf);
    24272541            if (RT_FAILURE(vrc))
     
    24292543                               tr("Could not create manifest file '%s' (%Rrc)"),
    24302544                               strMfFilePath.c_str(), vrc);
     2545#endif
    24312546        }
    24322547    }
     
    24412556    }
    24422557
     2558#ifndef VBOX_WITH_NEW_TAR_CREATOR /* done in caller now */
    24432559    /* Cleanup on error */
    24442560    if (FAILED(rc))
     
    24502566             pIfIo->pfnDelete(pStorage, (*it).first.c_str());
    24512567    }
     2568#endif
    24522569
    24532570    LogFlowFunc(("rc=%Rhrc\n", rc));
     
    24572574}
    24582575
     2576
     2577#ifdef VBOX_WITH_NEW_TAR_CREATOR
     2578/**
     2579 * Writes a memory buffer to a file in the output file system stream.
     2580 *
     2581 * @returns COM status code.
     2582 * @param   hVfsFssDst      The file system stream to add the file to.
     2583 * @param   pszFilename     The file name (w/ path if desired).
     2584 * @param   pvContent       Pointer to buffer containing the file content.
     2585 * @param   cbContent       Size of the content.
     2586 */
     2587HRESULT Appliance::i_writeBufferToFile(RTVFSFSSTREAM hVfsFssDst, const char *pszFilename, const void *pvContent, size_t cbContent)
     2588{
     2589    /*
     2590     * Create a VFS file around the memory, converting it to a base VFS object handle.
     2591     */
     2592    HRESULT hrc;
     2593    RTVFSIOSTREAM hVfsIosSrc;
     2594    int vrc = RTVfsIoStrmFromBuffer(RTFILE_O_READ, pvContent, cbContent, &hVfsIosSrc);
     2595    if (RT_SUCCESS(vrc))
     2596    {
     2597        hVfsIosSrc = i_manifestSetupDigestCalculationForGivenIoStream(hVfsIosSrc, pszFilename);
     2598        AssertReturn(hVfsIosSrc != NIL_RTVFSIOSTREAM,
     2599                     setErrorVrc(vrc, "i_manifestSetupDigestCalculationForGivenIoStream"));
     2600
     2601        RTVFSOBJ hVfsObj = RTVfsObjFromIoStream(hVfsIosSrc);
     2602        RTVfsIoStrmRelease(hVfsIosSrc);
     2603        AssertReturn(hVfsObj != NIL_RTVFSOBJ, E_FAIL);
     2604
     2605        /*
     2606         * Add it to the stream.
     2607         */
     2608        vrc = RTVfsFsStrmAdd(hVfsFssDst, pszFilename, hVfsObj, 0);
     2609        RTVfsObjRelease(hVfsObj);
     2610        if (RT_SUCCESS(vrc))
     2611            hrc = S_OK;
     2612        else
     2613            hrc = setErrorVrc(vrc, tr("RTVfsFsStrmAdd failed for '%s' (%Rrc)"), pszFilename, vrc);
     2614    }
     2615    else
     2616        hrc = setErrorVrc(vrc, "RTVfsIoStrmFromBuffer");
     2617    return hrc;
     2618}
     2619#endif
     2620
  • trunk/src/VBox/Main/src-server/ApplianceImplIO.cpp

    r67142 r67184  
    12301230
    12311231
    1232 /**
    1233  * Writes a memory buffer to a file in the output file system stream.
    1234  *
    1235  * @returns IPRT status code.
    1236  * @param   pszFilename     The file name (w/ path if desired).
    1237  * @param   pvContent       Pointer to buffer containing the file content.
    1238  * @param   cbContent       Size of the content.
    1239  * @param   hVfsFss         The file system stream to add the file to.
    1240  */
    1241 int writeBufferToFile(const char *pszFilename, const void *pvContent, size_t cbContent, RTVFSFSSTREAM hVfsFss)
    1242 {
    1243     /*
    1244      * Create a VFS file around the memory, converting it to a base VFS object handle.
    1245      */
    1246     RTVFSFILE hVfsFile;
    1247     int rc = RTVfsFileFromBuffer(RTFILE_O_READ, pvContent, cbContent, &hVfsFile);
    1248     if (RT_SUCCESS(rc))
    1249     {
    1250         RTVFSOBJ hVfsObj = RTVfsObjFromFile(hVfsFile);
    1251         RTVfsFileRelease(hVfsFile);
    1252         AssertReturn(hVfsObj != NIL_RTVFSOBJ, VERR_INTERNAL_ERROR_2);
    1253 
    1254         /*
    1255          * Add it to the stream.
    1256          */
    1257         rc = RTVfsFsStrmAdd(hVfsFss, pszFilename, hVfsObj, 0);
    1258         RTVfsObjRelease(hVfsObj);
    1259     }
    1260 
    1261     return rc;
    1262 }
    1263 
     1232#ifndef VBOX_WITH_NEW_TAR_CREATOR
    12641233int writeBufferToFile(const char *pcszFilename, void *pvBuf, size_t cbSize, PVDINTERFACEIO pIfIo, void *pvUser)
    12651234{
     
    12931262    return rc;
    12941263}
    1295 
     1264#endif /* !VBOX_WITH_NEW_TAR_CREATOR */
     1265
  • trunk/src/VBox/Main/src-server/ApplianceImplImport.cpp

    r65887 r67184  
    856856
    857857/**
    858  * Setup automatic I/O stream digest calculation, adding it to hOurManifest.
    859  *
    860  * @returns Passthru I/O stream, of @a hVfsIos if no digest calc needed.
    861  * @param   hVfsIos             The stream to wrap. Always consumed.
    862  * @param   pszManifestEntry    The manifest entry.
    863  * @throws  Nothing.
    864  */
    865 RTVFSIOSTREAM Appliance::i_importSetupDigestCalculationForGivenIoStream(RTVFSIOSTREAM hVfsIos, const char *pszManifestEntry)
    866 {
    867     int vrc;
    868     Assert(!RTManifestPtIosIsInstanceOf(hVfsIos));
    869 
    870     if (m->fDigestTypes == 0)
    871         return hVfsIos;
    872 
    873     /* Create the manifest if necessary. */
    874     if (m->hOurManifest == NIL_RTMANIFEST)
    875     {
    876         vrc = RTManifestCreate(0 /*fFlags*/, &m->hOurManifest);
    877         AssertRCReturnStmt(vrc, RTVfsIoStrmRelease(hVfsIos), NIL_RTVFSIOSTREAM);
    878     }
    879 
    880     /* Setup the stream. */
    881     RTVFSIOSTREAM hVfsIosPt;
    882     vrc = RTManifestEntryAddPassthruIoStream(m->hOurManifest, hVfsIos, pszManifestEntry, m->fDigestTypes,
    883                                              true /*fReadOrWrite*/, &hVfsIosPt);
    884 
    885     RTVfsIoStrmRelease(hVfsIos);        /* always consumed! */
    886     if (RT_SUCCESS(vrc))
    887         return hVfsIosPt;
    888 
    889     setErrorVrc(vrc, "RTManifestEntryAddPassthruIoStream failed with rc=%Rrc", vrc);
    890     return NIL_RTVFSIOSTREAM;
    891 }
    892 
    893 /**
    894858 * Opens a source file (for reading obviously).
    895859 *
     
    934898     * Digest calculation filtering.
    935899     */
    936     hVfsIosSrc = i_importSetupDigestCalculationForGivenIoStream(hVfsIosSrc, pszManifestEntry);
     900    hVfsIosSrc = i_manifestSetupDigestCalculationForGivenIoStream(hVfsIosSrc, pszManifestEntry);
    937901    if (hVfsIosSrc == NIL_RTVFSIOSTREAM)
    938902        throw E_FAIL;
     
    14451409     * Set up digest calculation.
    14461410     */
    1447     hVfsIosOvf = i_importSetupDigestCalculationForGivenIoStream(hVfsIosOvf, pszManifestEntry);
     1411    hVfsIosOvf = i_manifestSetupDigestCalculationForGivenIoStream(hVfsIosOvf, pszManifestEntry);
    14481412    if (hVfsIosOvf == NIL_RTVFSIOSTREAM)
    14491413        return VBOX_E_FILE_ERROR;
     
    15431507    m->fDeterminedDigestTypes = true;
    15441508
     1509#ifndef VBOX_WITH_NEW_TAR_CREATOR
    15451510    m->fSha256 = RT_BOOL(m->fDigestTypes & RTMANIFEST_ATTR_SHA256); /** @todo retire this member */
     1511#endif
    15461512    return S_OK;
    15471513}
  • trunk/src/VBox/Main/src-server/MediumImpl.cpp

    r67172 r67184  
    660660               MediumVariant_T aVariant,
    661661               SecretKeyStore *pSecretKeyStore,
     662#ifdef VBOX_WITH_NEW_TAR_CREATOR
     663               RTVFSIOSTREAM aVfsIosDst,
     664#else
    662665               VDINTERFACEIO *aVDImageIOIf,
    663666               void *aVDImageIOUser,
     667#endif
    664668               MediumLockList *aSourceMediumLockList,
    665669               bool fKeepSourceMediumLockList = false)
     
    675679
    676680        mVDImageIfaces = aMedium->m->vdImageIfaces;
     681
     682#ifdef VBOX_WITH_NEW_TAR_CREATOR
     683        int vrc = VDIfCreateFromVfsStream(aVfsIosDst, RTFILE_O_WRITE, &mpVfsIoIf);
     684        AssertRCReturnVoidStmt(vrc, mRC = E_FAIL);
     685
     686        vrc = VDInterfaceAdd(&mpVfsIoIf->Core, "Medium::ExportTaskVfsIos",
     687                             VDINTERFACETYPE_IO, mpVfsIoIf,
     688                             sizeof(VDINTERFACEIO), &mVDImageIfaces);
     689        AssertRCReturnVoidStmt(vrc, mRC = E_FAIL);
     690#else
     691
    677692        if (aVDImageIOIf)
    678693        {
     
    682697            AssertRCReturnVoidStmt(vrc, mRC = E_FAIL);
    683698        }
     699#endif
    684700        m_strTaskName = "createExport";
    685701    }
     
    689705        if (!mfKeepSourceMediumLockList && mpSourceMediumLockList)
    690706            delete mpSourceMediumLockList;
     707#ifdef VBOX_WITH_NEW_TAR_CREATOR
     708        if (mpVfsIoIf)
     709        {
     710            VDIfDestroyFromVfsStream(mpVfsIoIf);
     711            mpVfsIoIf = NULL;
     712        }
     713#endif
    691714    }
    692715
     
    696719    MediumVariant_T mVariant;
    697720    PVDINTERFACE mVDImageIfaces;
     721    PVDINTERFACEIO mpVfsIoIf; /**< Pointer to the VFS I/O stream to VD I/O interface wrapper. */
    698722    SecretKeyStore *m_pSecretKeyStore;
    699723
     
    60966120                             MediumVariant_T aVariant,
    60976121                             SecretKeyStore *pKeyStore,
     6122#ifdef VBOX_WITH_NEW_TAR_CREATOR
     6123                             RTVFSIOSTREAM hVfsIosDst,
     6124#else
    60986125                             PVDINTERFACEIO aVDImageIOIf, void *aVDImageIOUser,
     6126#endif
    60996127                             const ComObjPtr<Progress> &aProgress)
    61006128{
     
    61366164
    61376165        /* setup task object to carry out the operation asynchronously */
    6138         pTask = new Medium::ExportTask(this, aProgress, aFilename, aFormat,
    6139                                        aVariant, pKeyStore, aVDImageIOIf,
    6140                                        aVDImageIOUser, pSourceMediumLockList);
     6166        pTask = new Medium::ExportTask(this, aProgress, aFilename, aFormat, aVariant,
     6167#ifdef VBOX_WITH_NEW_TAR_CREATOR
     6168                                       pKeyStore, hVfsIosDst, pSourceMediumLockList);
     6169#else
     6170                                       pKeyStore, aVDImageIOIf, aVDImageIOUser, pSourceMediumLockList);
     6171#endif
    61416172        rc = pTask->rc();
    61426173        AssertComRC(rc);
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