VirtualBox

Changeset 33060 in vbox


Ignore:
Timestamp:
Oct 12, 2010 12:17:49 PM (14 years ago)
Author:
vboxsync
Message:

Main;OVF/OVA: online calculation of the SHA1 sum; directly stream into the ova (no temporary files anymore); cache writing

Location:
trunk/src/VBox/Main
Files:
1 added
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Main/ApplianceImpl.cpp

    r32718 r33060  
    678678            break;
    679679        }
    680         /* Check if the current operation have changed. It is also possible
     680        /* Check if the current operation has changed. It is also possible
    681681           that in the meantime more than one async operation was finished. So
    682682           we have to loop as long as we reached the same operation count. */
     
    843843        case WriteFile:
    844844        {
    845             // assume that creating the manifest will take 10% of the time it takes to export the disks
     845            // assume that creating the manifest will take .1% of the time it takes to export the disks
    846846            if (m->fManifest)
    847847            {
    848848                ++cOperations;          // another one for creating the manifest
    849849
    850                 m->ulWeightForManifestOperation = m->ulTotalDisksMB / 10;
     850                m->ulWeightForManifestOperation = (ULONG)((double)m->ulTotalDisksMB * .1 / 100);    // use .5% of the progress for the manifest
    851851                ulTotalOperationsWeight += m->ulWeightForManifestOperation;
    852             }
    853             if (fOVA)
    854             {
    855                 // Another operation for packing
    856                 ++cOperations;
    857 
    858                 // assume that packing the files into the archive has the same weight than creating all files in the ovf exporting step
    859                 ulTotalOperationsWeight += m->ulTotalDisksMB;
    860852            }
    861853            break;
  • trunk/src/VBox/Main/ApplianceImplExport.cpp

    r32850 r33060  
    15771577HRESULT Appliance::writeFS(TaskOVF *pTask)
    15781578{
     1579    LogFlowFuncEnter();
     1580    LogFlowFunc(("ENTER appliance %p\n", this));
     1581
     1582    AutoCaller autoCaller(this);
     1583    if (FAILED(autoCaller.rc())) return autoCaller.rc();
     1584
     1585    HRESULT rc = S_OK;
     1586
     1587    // Lock the media tree early to make sure nobody else tries to make changes
     1588    // to the tree. Also lock the IAppliance object for writing.
     1589    AutoMultiWriteLock2 multiLock(&mVirtualBox->getMediaTreeLockHandle(), this->lockHandle() COMMA_LOCKVAL_SRC_POS);
     1590    // Additional protect the IAppliance object, cause we leave the lock
     1591    // when starting the disk export and we don't won't block other
     1592    // callers on this lengthy operations.
     1593    m->state = Data::ApplianceExporting;
     1594
    15791595    if (pTask->locInfo.strPath.endsWith(".ovf", Utf8Str::CaseInsensitive))
    1580         return writeFSOVF(pTask);
     1596        rc = writeFSOVF(pTask, multiLock);
    15811597    else
    1582         return writeFSOVA(pTask);
     1598        rc = writeFSOVA(pTask, multiLock);
     1599
     1600    // reset the state so others can call methods again
     1601    m->state = Data::ApplianceIdle;
     1602
     1603    LogFlowFunc(("rc=%Rhrc\n", rc));
     1604    LogFlowFuncLeave();
     1605    return rc;
    15831606}
    15841607
    1585 HRESULT Appliance::writeFSOVF(TaskOVF *pTask)
     1608HRESULT Appliance::writeFSOVF(TaskOVF *pTask, AutoWriteLockBase& writeLock)
    15861609{
    15871610    LogFlowFuncEnter();
    1588     LogFlowFunc(("ENTER appliance %p\n", this));
    1589 
    1590     AutoCaller autoCaller(this);
    1591     if (FAILED(autoCaller.rc())) return autoCaller.rc();
    15921611
    15931612    HRESULT rc = S_OK;
    15941613
     1614    PVDINTERFACEIO pSha1Callbacks = 0;
     1615    PVDINTERFACEIO pRTFileCallbacks = 0;
     1616    do
     1617    {
     1618        pSha1Callbacks = Sha1CreateInterface();
     1619        if (!pSha1Callbacks)
     1620        {
     1621            rc = E_OUTOFMEMORY;
     1622            break;
     1623        }
     1624        pRTFileCallbacks = RTFileCreateInterface();
     1625        if (!pRTFileCallbacks)
     1626        {
     1627            rc = E_OUTOFMEMORY;
     1628            break;
     1629        }
     1630
     1631        SHA1STORAGE storage;
     1632        RT_ZERO(storage);
     1633        storage.fCreateDigest = m->fManifest;
     1634        VDINTERFACE VDInterfaceIO;
     1635        int vrc = VDInterfaceAdd(&VDInterfaceIO, "Appliance::IORTFile",
     1636                                 VDINTERFACETYPE_IO, pRTFileCallbacks,
     1637                                 0, &storage.pVDImageIfaces);
     1638        if (RT_FAILURE(vrc))
     1639        {
     1640            rc = E_FAIL;
     1641            break;
     1642        }
     1643        rc = writeFSImpl(pTask, writeLock, pSha1Callbacks, &storage);
     1644    }while(0);
     1645
     1646    /* Cleanup */
     1647    if (pSha1Callbacks)
     1648        RTMemFree(pSha1Callbacks);
     1649    if (pRTFileCallbacks)
     1650        RTMemFree(pRTFileCallbacks);
     1651
     1652    LogFlowFuncLeave();
     1653    return rc;
     1654}
     1655
     1656HRESULT Appliance::writeFSOVA(TaskOVF *pTask, AutoWriteLockBase& writeLock)
     1657{
     1658    LogFlowFuncEnter();
     1659
     1660    RTTAR tar;
     1661    int vrc = RTTarOpen(&tar, pTask->locInfo.strPath.c_str(), RTFILE_O_CREATE | RTFILE_O_WRITE | RTFILE_O_DENY_ALL);
     1662    if (RT_FAILURE(vrc))
     1663        return setError(VBOX_E_FILE_ERROR,
     1664                        tr("Could not create OVA file '%s' (%Rrc)"),
     1665                        pTask->locInfo.strPath.c_str(), vrc);
     1666
     1667    HRESULT rc = S_OK;
     1668
     1669    PVDINTERFACEIO pSha1Callbacks = 0;
     1670    PVDINTERFACEIO pRTTarCallbacks = 0;
     1671    do
     1672    {
     1673        pSha1Callbacks = Sha1CreateInterface();
     1674        if (!pSha1Callbacks)
     1675        {
     1676            rc = E_OUTOFMEMORY;
     1677            break;
     1678        }
     1679        pRTTarCallbacks = RTTarCreateInterface();
     1680        if (!pRTTarCallbacks)
     1681        {
     1682            rc = E_OUTOFMEMORY;
     1683            break;
     1684        }
     1685        VDINTERFACE VDInterfaceIO;
     1686        SHA1STORAGE storage;
     1687        RT_ZERO(storage);
     1688        storage.fCreateDigest = m->fManifest;
     1689        vrc = VDInterfaceAdd(&VDInterfaceIO, "Appliance::IORTTar",
     1690                             VDINTERFACETYPE_IO, pRTTarCallbacks,
     1691                             tar, &storage.pVDImageIfaces);
     1692        if (RT_FAILURE(vrc))
     1693        {
     1694            rc = E_FAIL;
     1695            break;
     1696        }
     1697        rc = writeFSImpl(pTask, writeLock, pSha1Callbacks, &storage);
     1698    }while(0);
     1699
     1700    RTTarClose(tar);
     1701
     1702    /* Cleanup */
     1703    if (pSha1Callbacks)
     1704        RTMemFree(pSha1Callbacks);
     1705    if (pRTTarCallbacks)
     1706        RTMemFree(pRTTarCallbacks);
     1707
     1708    /* Delete ova file on error */
     1709    if(FAILED(rc))
     1710        RTFileDelete(pTask->locInfo.strPath.c_str());
     1711
     1712    LogFlowFuncLeave();
     1713    return rc;
     1714}
     1715
     1716HRESULT Appliance::writeFSImpl(TaskOVF *pTask, AutoWriteLockBase& writeLock, PVDINTERFACEIO pCallbacks, PSHA1STORAGE pStorage)
     1717{
     1718    LogFlowFuncEnter();
     1719
     1720    HRESULT rc = S_OK;
     1721
     1722    typedef pair<Utf8Str, Utf8Str> STRPAIR;
     1723    list<STRPAIR> fileList;
    15951724    try
    15961725    {
    1597         // Lock the media tree early to make sure nobody else tries to make changes
    1598         // to the tree. Also lock the IAppliance object for writing.
    1599         AutoMultiWriteLock2 multiLock(&mVirtualBox->getMediaTreeLockHandle(), this->lockHandle() COMMA_LOCKVAL_SRC_POS);
    1600         // Additional protect the IAppliance object, cause we leave the lock
    1601         // when starting the disk export and we don't won't block other
    1602         // callers on this lengthy operations.
    1603         m->state = Data::ApplianceExporting;
    1604 
     1726        int vrc;
    16051727        // the XML stack contains two maps for disks and networks, which allows us to
    16061728        // a) have a list of unique disk names (to make sure the same disk name is only added once)
     
    16121734            xml::Document doc;
    16131735            // Now fully build a valid ovf document in memory
    1614             buildXML(multiLock, doc, stack, pTask->locInfo.strPath, pTask->enFormat);
    1615             // Write the XML
    1616             xml::XmlFileWriter writer(doc);
    1617             writer.write(pTask->locInfo.strPath.c_str(), false /*fSafe*/);
     1736            buildXML(writeLock, doc, stack, pTask->locInfo.strPath, pTask->enFormat);
     1737            // Create a memory buffer containing the XML. */
     1738            void *pvBuf;
     1739            size_t cbSize;
     1740            xml::XmlMemWriter writer;
     1741            writer.write(doc, &pvBuf, &cbSize);
     1742            /* Extract the path */
     1743            Utf8Str tmpPath = pTask->locInfo.strPath;
     1744            /* Remove the extension and add ovf. */
     1745            tmpPath.stripExt()
     1746                .append(".ovf");
     1747            /* Write the ovf file to disk. */
     1748            vrc = Sha1WriteBuf(tmpPath.c_str(), pvBuf, cbSize, pCallbacks, pStorage);
     1749            if (RT_FAILURE(vrc))
     1750                throw setError(VBOX_E_FILE_ERROR,
     1751                               tr("Could not create OVF file '%s' (%Rrc)"),
     1752                               tmpPath.c_str(), vrc);
     1753            fileList.push_back(STRPAIR(tmpPath, pStorage->strDigest));
    16181754        }
    16191755
    16201756        // We need a proper format description
    16211757        ComObjPtr<MediumFormat> format;
    1622         { // Scope for the AutoReadLock
     1758        // Scope for the AutoReadLock
     1759        {
    16231760            SystemProperties *pSysProps = mVirtualBox->getSystemProperties();
    16241761            AutoReadLock propsLock(pSysProps COMMA_LOCKVAL_SRC_POS);
    16251762            // We are always exporting to VMDK stream optimized for now
    1626             format = pSysProps->mediumFormat("VMDK");
     1763            format = pSysProps->mediumFormat("VMDKstream");
    16271764            if (format.isNull())
    16281765                throw setError(VBOX_E_NOT_SUPPORTED,
     
    16311768
    16321769        // Finally, write out the disks!
    1633         list<Utf8Str> diskList;
    16341770        map<Utf8Str, const VirtualSystemDescriptionEntry*>::const_iterator itS;
    16351771        for (itS = stack.mapDisks.begin();
     
    16641800            // target path needs to be composed from where the output OVF is
    16651801            Utf8Str strTargetFilePath(pTask->locInfo.strPath);
    1666             strTargetFilePath.stripFilename();
    1667             strTargetFilePath.append("/");
    1668             strTargetFilePath.append(strTargetFileNameOnly);
     1802            strTargetFilePath.stripFilename()
     1803                .append("/")
     1804                .append(strTargetFileNameOnly);
    16691805
    16701806            // The exporting requests a lock on the media tree. So leave our lock temporary.
    1671             multiLock.release();
     1807            writeLock.release();
    16721808            try
    16731809            {
     
    16761812                rc = pProgress2->init(mVirtualBox, static_cast<IAppliance*>(this), BstrFmt(tr("Creating medium '%s'"), strTargetFilePath.c_str()).raw(), TRUE);
    16771813                if (FAILED(rc)) throw rc;
    1678                 // create a flat copy of the source disk image
    1679                 rc = pSourceDisk->exportFile(strTargetFilePath.c_str(), format, MediumVariant_VmdkStreamOptimized, NULL, NULL, pProgress2);
    1680                 if (FAILED(rc)) throw rc;
    16811814
    16821815                // advance to the next operation
    16831816                pTask->pProgress->SetNextOperation(BstrFmt(tr("Exporting to disk image '%s'"), RTPathFilename(strTargetFilePath.c_str())).raw(),
    1684                                                    pDiskEntry->ulSizeMB);     // operation's weight, as set up with the IProgress originally);
     1817                                                   pDiskEntry->ulSizeMB);     // operation's weight, as set up with the IProgress originally
     1818
     1819                // create a flat copy of the source disk image
     1820                rc = pSourceDisk->exportFile(strTargetFilePath.c_str(), format, MediumVariant_VmdkStreamOptimized, pCallbacks, pStorage, pProgress2);
     1821                if (FAILED(rc)) throw rc;
    16851822
    16861823                ComPtr<IProgress> pProgress3(pProgress2);
     
    16901827            catch (HRESULT rc3)
    16911828            {
     1829                writeLock.acquire();
    16921830                // Todo: file deletion on error? If not, we can remove that whole try/catch block.
    16931831                throw rc3;
     
    16951833            // Finished, lock again (so nobody mess around with the medium tree
    16961834            // in the meantime)
    1697             multiLock.acquire();
    1698             diskList.push_back(strTargetFilePath);
     1835            writeLock.acquire();
     1836            fileList.push_back(STRPAIR(strTargetFilePath, pStorage->strDigest));
    16991837        }
    17001838
     
    17021840        {
    17031841            // Create & write the manifest file
    1704             Utf8Str strMfFile = manifestFileName(pTask->locInfo.strPath.c_str());
    1705             const char *pcszManifestFileOnly = RTPathFilename(strMfFile.c_str());
    1706             pTask->pProgress->SetNextOperation(BstrFmt(tr("Creating manifest file '%s'"), pcszManifestFileOnly).raw(),
     1842            Utf8Str strMfFilePath = manifestFileName(pTask->locInfo.strPath.c_str());
     1843            Utf8Str strMfFileName = Utf8Str(strMfFilePath)
     1844                .stripPath();
     1845            pTask->pProgress->SetNextOperation(BstrFmt(tr("Creating manifest file '%s'"), strMfFileName.c_str()).raw(),
    17071846                                               m->ulWeightForManifestOperation);     // operation's weight, as set up with the IProgress originally);
    1708 
    1709             const char** ppManifestFiles = (const char**)RTMemAlloc(sizeof(char*)*diskList.size() + 1);
    1710             ppManifestFiles[0] = pTask->locInfo.strPath.c_str();
    1711             list<Utf8Str>::const_iterator it1;
    1712             size_t i = 1;
    1713             for (it1 = diskList.begin();
    1714                  it1 != diskList.end();
     1847            const char** ppManifestFiles = (const char**)RTMemAlloc(sizeof(char*) * fileList.size());
     1848            const char** ppManifestDigests = (const char**)RTMemAlloc(sizeof(char*) * fileList.size());
     1849            size_t i = 0;
     1850            list<STRPAIR>::const_iterator it1;
     1851            for (it1 = fileList.begin();
     1852                 it1 != fileList.end();
    17151853                 ++it1, ++i)
    1716                 ppManifestFiles[i] = (*it1).c_str();
    1717             int vrc = RTManifestWriteFiles(strMfFile.c_str(), ppManifestFiles, diskList.size()+1, NULL, NULL);
     1854            {
     1855                ppManifestFiles[i] = (*it1).first.c_str();
     1856                ppManifestDigests[i] = (*it1).second.c_str();
     1857            }
     1858            void *pvBuf;
     1859            size_t cbSize;
     1860            vrc = RTManifestWriteFilesBuf(&pvBuf, &cbSize, ppManifestFiles, ppManifestDigests, fileList.size());
    17181861            RTMemFree(ppManifestFiles);
     1862            RTMemFree(ppManifestDigests);
    17191863            if (RT_FAILURE(vrc))
    17201864                throw setError(VBOX_E_FILE_ERROR,
    17211865                               tr("Could not create manifest file '%s' (%Rrc)"),
    1722                                pcszManifestFileOnly, vrc);
     1866                               strMfFileName.c_str(), vrc);
     1867            /* Write the manifest file to disk. */
     1868            vrc = Sha1WriteBuf(strMfFilePath.c_str(), pvBuf, cbSize, pCallbacks, pStorage);
     1869            RTMemFree(pvBuf);
     1870            if (RT_FAILURE(vrc))
     1871                throw setError(VBOX_E_FILE_ERROR,
     1872                               tr("Could not create manifest file '%s' (%Rrc)"),
     1873                               strMfFilePath.c_str(), vrc);
    17231874        }
    17241875    }
     
    17331884    }
    17341885
    1735     AutoWriteLock appLock(this COMMA_LOCKVAL_SRC_POS);
    1736     // reset the state so others can call methods again
    1737     m->state = Data::ApplianceIdle;
    1738 
    1739     LogFlowFunc(("rc=%Rhrc\n", rc));
    1740     LogFlowFuncLeave();
    1741 
    1742     return rc;
    1743 }
    1744 
    1745 HRESULT Appliance::writeFSOVA(TaskOVF *pTask)
    1746 {
    1747     LogFlowFuncEnter();
    1748     LogFlowFunc(("Appliance %p\n", this));
    1749 
    1750     AutoCaller autoCaller(this);
    1751     if (FAILED(autoCaller.rc())) return autoCaller.rc();
    1752 
    1753     HRESULT rc = S_OK;
    1754 
    1755     AutoWriteLock appLock(this COMMA_LOCKVAL_SRC_POS);
    1756 
    1757     int vrc = VINF_SUCCESS;
    1758 
    1759     char szOSTmpDir[RTPATH_MAX];
    1760     RTPathTemp(szOSTmpDir, sizeof(szOSTmpDir));
    1761     /* The template for the temporary directory created below */
    1762     char *pszTmpDir;
    1763     RTStrAPrintf(&pszTmpDir, "%s"RTPATH_SLASH_STR"vbox-ovf-XXXXXX", szOSTmpDir);
    1764     list<Utf8Str> filesList;
    1765     const char** paFiles = 0;
    1766 
    1767     try
    1768     {
    1769         /* Extract the path */
    1770         Utf8Str tmpPath = pTask->locInfo.strPath;
    1771         /* Remove the ova extension */
    1772         tmpPath.stripExt();
    1773         tmpPath += ".ovf";
    1774 
    1775         /* We need a temporary directory which we can put the OVF file & all
    1776          * disk images in */
    1777         vrc = RTDirCreateTemp(pszTmpDir);
    1778         if (RT_FAILURE(vrc))
    1779             throw setError(VBOX_E_FILE_ERROR,
    1780                            tr("Cannot create temporary directory '%s' (%Rrc)"), pszTmpDir, vrc);
    1781 
    1782         /* The temporary name of the target OVF file */
    1783         Utf8StrFmt strTmpOvf("%s/%s", pszTmpDir, RTPathFilename(tmpPath.c_str()));
    1784 
    1785         /* Prepare the temporary writing of the OVF */
    1786         ComObjPtr<Progress> progress;
    1787         /* Create a temporary file based location info for the sub task */
    1788         LocationInfo li;
    1789         li.strPath = strTmpOvf;
    1790         rc = writeImpl(pTask->enFormat, li, progress);
    1791         if (FAILED(rc)) throw rc;
    1792 
    1793         /* Unlock the appliance for the writing thread */
    1794         appLock.release();
    1795         /* Wait until the writing is done, but report the progress back to the
    1796            caller */
    1797         ComPtr<IProgress> progressInt(progress);
    1798         waitForAsyncProgress(pTask->pProgress, progressInt); /* Any errors will be thrown */
    1799 
    1800         /* Again lock the appliance for the next steps */
    1801         appLock.acquire();
    1802 
    1803         vrc = RTPathExists(strTmpOvf.c_str()); /* Paranoid check */
    1804         if (RT_FAILURE(vrc))
    1805             throw setError(VBOX_E_FILE_ERROR,
    1806                            tr("Cannot find source file '%s' (%Rrc)"), strTmpOvf.c_str(), vrc);
    1807         ULONG ulWeight = m->ulWeightForXmlOperation;
    1808         /* Add the OVF file */
    1809         filesList.push_back(strTmpOvf); /* Use 1% of the total for the OVF file upload */
    1810         /* Add the manifest file */
    1811         if (m->fManifest)
    1812         {
    1813             Utf8Str strMfFile = manifestFileName(strTmpOvf);
    1814             filesList.push_back(strMfFile); /* Use 1% of the total for the manifest file upload */
    1815             ulWeight += m->ulWeightForXmlOperation;
    1816         }
    1817 
    1818         /* Now add every disks of every virtual system */
    1819         list< ComObjPtr<VirtualSystemDescription> >::const_iterator it;
    1820         for (it = m->virtualSystemDescriptions.begin();
    1821              it != m->virtualSystemDescriptions.end();
    1822              ++it)
    1823         {
    1824             ComObjPtr<VirtualSystemDescription> vsdescThis = (*it);
    1825             std::list<VirtualSystemDescriptionEntry*> avsdeHDs = vsdescThis->findByType(VirtualSystemDescriptionType_HardDiskImage);
    1826             std::list<VirtualSystemDescriptionEntry*>::const_iterator itH;
    1827             for (itH = avsdeHDs.begin();
    1828                  itH != avsdeHDs.end();
    1829                  ++itH)
    1830             {
    1831                 const Utf8Str &strTargetFileNameOnly = (*itH)->strOvf;
    1832                 /* Target path needs to be composed from where the output OVF is */
    1833                 Utf8Str strTargetFilePath(strTmpOvf);
    1834                 strTargetFilePath.stripFilename();
    1835                 strTargetFilePath.append("/");
    1836                 strTargetFilePath.append(strTargetFileNameOnly);
    1837                 vrc = RTPathExists(strTargetFilePath.c_str()); /* Paranoid check */
    1838                 if (RT_FAILURE(vrc))
    1839                     throw setError(VBOX_E_FILE_ERROR,
    1840                                    tr("Cannot find source file '%s' (%Rrc)"), strTargetFilePath.c_str(), vrc);
    1841                 filesList.push_back(strTargetFilePath);
    1842                 ulWeight += (*itH)->ulSizeMB;
    1843             }
    1844         }
    1845         ulWeight = m->ulTotalDisksMB;
    1846         paFiles = (const char**)RTMemAlloc(sizeof(char*) * filesList.size());
    1847         int i = 0;
    1848         for (list<Utf8Str>::const_iterator it1 = filesList.begin(); it1 != filesList.end(); ++it1, ++i)
    1849             paFiles[i] = (*it1).c_str();
    1850         pTask->pProgress->SetNextOperation(BstrFmt(tr("Packing into '%s'"), RTPathFilename(pTask->locInfo.strPath.c_str())).raw(), ulWeight);
    1851         /* Create the tar file out of our file list. */
    1852         vrc = RTTarCreate(pTask->locInfo.strPath.c_str(), paFiles, filesList.size(), pTask->updateProgress, &pTask);
    1853         if (RT_FAILURE(vrc))
    1854             throw setError(VBOX_E_FILE_ERROR,
    1855                            tr("Cannot create OVA file '%s' (%Rrc)"), pTask->locInfo.strPath.c_str(), vrc);
    1856     }
    1857     catch(HRESULT aRC)
    1858     {
    1859         rc = aRC;
    1860     }
    1861 
    1862     /* Delete the temporary files list */
    1863     if (paFiles)
    1864         RTMemFree(paFiles);
    1865     /* Delete all files which where temporary created */
    1866     for (list<Utf8Str>::const_iterator it1 = filesList.begin(); it1 != filesList.end(); ++it1)
    1867     {
    1868         const char *pszFilePath = (*it1).c_str();
    1869         if (RTPathExists(pszFilePath))
    1870         {
    1871             vrc = RTFileDelete(pszFilePath);
    1872             if (RT_FAILURE(vrc))
    1873                 rc = setError(VBOX_E_FILE_ERROR,
    1874                               tr("Cannot delete file '%s' (%Rrc)"), pszFilePath, vrc);
    1875         }
    1876     }
    1877     /* Delete the temporary directory */
    1878     if (RTPathExists(pszTmpDir))
    1879     {
    1880         vrc = RTDirRemove(pszTmpDir);
    1881         if (RT_FAILURE(vrc))
    1882             rc = setError(VBOX_E_FILE_ERROR,
    1883                           tr("Cannot delete temporary directory '%s' (%Rrc)"), pszTmpDir, vrc);
    1884     }
    1885     if (pszTmpDir)
    1886         RTStrFree(pszTmpDir);
     1886    /* Cleanup on error */
     1887    if (FAILED(rc))
     1888    {
     1889        list<STRPAIR>::const_iterator it1;
     1890        for (it1 = fileList.begin();
     1891             it1 != fileList.end();
     1892             ++it1)
     1893             pCallbacks->pfnDelete(pStorage, (*it1).first.c_str());
     1894    }
    18871895
    18881896    LogFlowFunc(("rc=%Rhrc\n", rc));
  • trunk/src/VBox/Main/Makefile.kmk

    r32866 r33060  
    284284        VirtualBoxImpl.cpp \
    285285        ApplianceImpl.cpp \
     286        ApplianceImplIO.cpp \
    286287        ApplianceImplExport.cpp \
    287288        ApplianceImplImport.cpp \
  • trunk/src/VBox/Main/include/ApplianceImpl.h

    r32965 r33060  
    2828class VirtualSystemDescription;
    2929struct VirtualSystemDescriptionEntry;
     30typedef struct VDINTERFACE   *PVDINTERFACE;
     31typedef struct VDINTERFACEIO *PVDINTERFACEIO;
     32typedef struct SHA1STORAGE   *PSHA1STORAGE;
    3033
    3134namespace ovf
     
    185188
    186189    HRESULT writeFS(TaskOVF *pTask);
    187     HRESULT writeFSOVF(TaskOVF *pTask);
    188     HRESULT writeFSOVA(TaskOVF *pTask);
     190    HRESULT writeFSOVF(TaskOVF *pTask, AutoWriteLockBase& writeLock);
     191    HRESULT writeFSOVA(TaskOVF *pTask, AutoWriteLockBase& writeLock);
     192    HRESULT writeFSImpl(TaskOVF *pTask, AutoWriteLockBase& writeLock, PVDINTERFACEIO pCallbacks, PSHA1STORAGE pStorage);
    189193    HRESULT writeS3(TaskOVF *pTask);
    190194
  • trunk/src/VBox/Main/include/ApplianceImplPrivate.h

    r32448 r33060  
    214214ovf::CIMOSType_T convertVBoxOSType2CIMOSType(const char *pcszVbox);
    215215
     216typedef struct SHA1STORAGE
     217{
     218    PVDINTERFACE pVDImageIfaces;
     219    bool         fCreateDigest;
     220    Utf8Str      strDigest;
     221} SHA1STORAGE, *PSHA1STORAGE;
     222
     223PVDINTERFACEIO Sha1CreateInterface();
     224PVDINTERFACEIO RTFileCreateInterface();
     225PVDINTERFACEIO RTTarCreateInterface();
     226int Sha1WriteBuf(const char *pcszFilename, void *pvBuf, size_t cbSize, PVDINTERFACEIO pCallbacks, void *pvUser);
     227
    216228#endif // ____H_APPLIANCEIMPLPRIVATE
     229
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