VirtualBox

Changeset 47716 in vbox


Ignore:
Timestamp:
Aug 14, 2013 5:33:22 AM (11 years ago)
Author:
vboxsync
Message:

pr6022. 3rd variant (using VFS streaming feature) of GZIP support for reading the gzipped storage images from OVA/OVF package has been added.

Location:
trunk/src/VBox
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/build/VBoxDDUDeps.cpp

    r35353 r47716  
    3636{
    3737    (PFNRT)VDInit,
     38    (PFNRT)VDIfCreateVfsStream,
    3839#ifdef VBOX_WITH_USB
    3940    (PFNRT)USBFilterInit,
  • trunk/src/VBox/Main/include/ApplianceImpl.h

    r47340 r47716  
    4343typedef struct SHASTORAGE    *PSHASTORAGE;
    4444
    45 typedef enum applianceIOName { applianceIOTar, applianceIOFile } APPLIANCEIONAME;
     45typedef enum applianceIOName { applianceIOTar, applianceIOFile, applianceIOSha } APPLIANCEIONAME;
    4646
    4747namespace ovf
  • trunk/src/VBox/Main/src-server/ApplianceImpl.cpp

    r46822 r47716  
    5454
    5555static const char* const applianceIOTarName = "Appliance::IOTar";
     56static const char* const applianceIOShaName = "Appliance::IOSha";
    5657static const char* const applianceIOFileName = "Appliance::IOFile";
    5758
     
    704705        applianceIONameMap.insert(std::make_pair(applianceIOTar, applianceIOTarName));
    705706        applianceIONameMap.insert(std::make_pair(applianceIOFile, applianceIOFileName));
     707        applianceIONameMap.insert(std::make_pair(applianceIOSha, applianceIOShaName));
    706708
    707709    return rc;
  • trunk/src/VBox/Main/src-server/ApplianceImplIO.cpp

    r47516 r47716  
    3333#include <iprt/circbuf.h>
    3434#include <iprt/vfs.h>
     35#include <iprt/manifest.h>
     36#include <VBox/vd-ifs.h>
    3537#include <VBox/vd.h>
    36 #include <zlib.h>
    37 //#define VBOX_MAIN_USE_VFS /** @todo Replace as much as possible with IPRT VFS. */
    3838
    3939/******************************************************************************
     
    13401340}
    13411341
    1342 static int zipDecompressBuffer(z_stream streamIn,
    1343                                       uint32_t *cbDecompressed,
    1344                                       bool *finished)
    1345 {
    1346     int rc;
    1347     int sh = streamIn.avail_out;
    1348 
    1349     *cbDecompressed = 0;
    1350 
    1351     do
    1352     {
    1353         rc = inflate(&streamIn, Z_NO_FLUSH);
    1354 
    1355         if (rc < 0)
    1356         {
    1357             switch (rc)
    1358             {
    1359                 case Z_STREAM_ERROR:
    1360                     rc = VERR_ZIP_CORRUPTED;
    1361                     break;
    1362                 case Z_DATA_ERROR:
    1363                     rc = VERR_ZIP_CORRUPTED;
    1364                     break;
    1365                 case Z_MEM_ERROR:
    1366                     rc = VERR_ZIP_NO_MEMORY;
    1367                     break;
    1368                 case Z_BUF_ERROR:
    1369                     rc = VERR_ZIP_ERROR;
    1370                     break;
    1371                 case Z_VERSION_ERROR:
    1372                     rc = VERR_ZIP_UNSUPPORTED_VERSION;
    1373                     break;
    1374                 case Z_ERRNO: /* We shouldn't see this status! */
    1375                 default:
    1376                     AssertMsgFailed(("%d\n", rc));
    1377                     if (rc >= 0)
    1378                         rc = VINF_SUCCESS;
    1379                     rc = VERR_ZIP_ERROR;
    1380             }
    1381 
    1382             break;
    1383         }
    1384 
    1385         *cbDecompressed += (sh - streamIn.avail_out);
    1386         sh = streamIn.avail_out;
    1387     }
    1388     while (streamIn.avail_out > 0 && streamIn.avail_in > 0 );
    1389 
    1390     if (RT_SUCCESS(rc))
    1391     {
    1392         if (streamIn.avail_in == 0)
    1393             *finished = true;
    1394         else
    1395         {
    1396             if (streamIn.avail_out == 0)
    1397                 *finished = false;
    1398         }
    1399     }
    1400 
    1401     return rc;
    1402 }
    1403 
    14041342int decompressImageAndSave(const char *pcszFullFilenameIn, const char *pcszFullFilenameOut, PVDINTERFACEIO pIfIo, void *pvUser)
    14051343{
     
    14071345    AssertPtrReturn(pIfIo, VERR_INVALID_POINTER);
    14081346
     1347    PSHASTORAGE pShaStorage = (PSHASTORAGE)pvUser;
    14091348    /*
    14101349     * Open the source file.
     
    14161355    if (RT_FAILURE(rc))
    14171356        return rc;
    1418 #ifdef VBOX_MAIN_USE_VFS
    14191357
    14201358    /* Turn the source file handle/whatever into a VFS stream. */
    14211359    RTVFSIOSTREAM hVfsIosCompressedSrc;
     1360
    14221361    rc = VDIfCreateVfsStream(pIfIo, pvStorage, RTFILE_O_READ, &hVfsIosCompressedSrc);
    14231362    if (RT_SUCCESS(rc))
     
    14441383                     * Pump the bytes thru. If we fail, delete the output file.
    14451384                     */
    1446                     rc = RTVfsUtilPumpIoStreams(hVfsIosSrc, hVfsIosDst, 0);
     1385                    RTMANIFEST hFileManifest = NIL_RTMANIFEST;
     1386                    rc = RTManifestCreate(0 /*fFlags*/, &hFileManifest);
     1387                    if (RT_SUCCESS(rc))
     1388                    {
     1389                        RTVFSIOSTREAM hVfsIosMfst;
     1390
     1391                        uint32_t digestType = (pShaStorage->fSha256 == true) ? RTMANIFEST_ATTR_SHA256: RTMANIFEST_ATTR_SHA1;
     1392
     1393                        rc = RTManifestEntryAddPassthruIoStream(hFileManifest,
     1394                                                                hVfsIosSrc,
     1395                                                                "ovf import",
     1396                                                                digestType,
     1397                                                                true /*read*/, &hVfsIosMfst);
     1398                        if (RT_SUCCESS(rc))
     1399                        {
     1400                            rc = RTVfsUtilPumpIoStreams(hVfsIosMfst, hVfsIosDst, 0);
     1401                        }
     1402
     1403                        RTVfsIoStrmRelease(hVfsIosMfst);
     1404                    }
    14471405
    14481406                    RTVfsIoStrmRelease(hVfsIosDst);
    1449                     RTFileDelete(pcszFullFilenameOut);
    14501407                }
    14511408            }
     
    14531410            RTVfsIoStrmRelease(hVfsIosSrc);
    14541411        }
    1455         RTVfsIoStrmRelease(hVfsIosCompressedSrc);
    14561412    }
    14571413    pIfIo->pfnClose(pvUser, pvStorage);
    14581414
    1459 #else
    1460 
    1461     Bytef *decompressedBuffer = 0;
    1462     Bytef *compressedBuffer = 0;
    1463     uint64_t cbTmpSize = _1M;
    1464     size_t cbAllRead = 0;
    1465     size_t cbAllWritten = 0;
    1466     RTFILE pFile = NULL;
    1467     z_stream gzipStream;
    1468 
    1469     Utf8Str pathOut(pcszFullFilenameOut);
    1470     pathOut = pathOut.stripFilename();
    1471 
    1472     Utf8Str fileIn(pcszFullFilenameIn);
    1473     fileIn = fileIn.stripPath();
    1474 
    1475     do
    1476     {
    1477         if (RTFileExists(pcszFullFilenameOut) == false)
    1478         {
    1479             /* ensure the directory exists */
    1480             rc = VirtualBox::ensureFilePathExists(Utf8Str(pcszFullFilenameOut), true);
    1481             if (FAILED(rc))
    1482             {
    1483                 rc = VBOX_E_FILE_ERROR; /** @todo r=bird: You're mixing COM and VBox status codes... */
    1484                 break;
    1485             }
    1486 
    1487             rc = RTFileOpen(&pFile, pcszFullFilenameOut, RTFILE_O_OPEN_CREATE | RTFILE_O_WRITE | RTFILE_O_DENY_NONE);
    1488         }
    1489         else
    1490         {
    1491             rc = RTFileOpen(&pFile, pcszFullFilenameOut, RTFILE_O_CREATE_REPLACE | RTFILE_O_WRITE | RTFILE_O_DENY_NONE);
    1492         }
    1493 
    1494         if (FAILED(rc) || pFile == NULL)
    1495         {
    1496             rc = VBOX_E_FILE_ERROR;
    1497             break;
    1498         }
    1499 
    1500         compressedBuffer = (Bytef *)RTMemAlloc(cbTmpSize);
    1501 
    1502         if (!compressedBuffer)
    1503         {
    1504             rc = VERR_NO_MEMORY;
    1505             break;
    1506         }
    1507 
    1508 
    1509         decompressedBuffer = (Bytef *)RTMemAlloc(cbTmpSize*10);
    1510 
    1511         if (!decompressedBuffer)
    1512         {
    1513             rc = VERR_NO_MEMORY;
    1514             break;
    1515         }
    1516 
    1517         gzipStream.zalloc = Z_NULL;
    1518         gzipStream.zfree = Z_NULL;
    1519         gzipStream.opaque = Z_NULL;
    1520         gzipStream.next_in = compressedBuffer;
    1521         gzipStream.avail_in = 0;
    1522         gzipStream.next_out = decompressedBuffer;
    1523         gzipStream.avail_out = cbTmpSize*10;
    1524 
    1525         rc = inflateInit2(&gzipStream, MAX_WBITS + 16 /* autodetect gzip header */);
    1526 
    1527         if (rc < 0)
    1528         {
    1529             break;
    1530         }
    1531 
    1532         size_t cbRead = 0;
    1533         size_t cbDecompressed = 0;
    1534         bool fFinished = true;
    1535 
    1536         for (;;)
    1537         {
    1538             if (fFinished == true)
    1539             {
    1540                 rc = pIfIo->pfnReadSync(pvUser, pvStorage, cbAllRead, compressedBuffer, cbTmpSize, &cbRead);
    1541                 if (   RT_FAILURE(rc)
    1542                     || cbRead == 0)
    1543                     break;
    1544 
    1545                 gzipStream.avail_in = cbRead;
    1546                 gzipStream.avail_out = cbTmpSize*10;
    1547             }
    1548 
    1549             /* decompress the buffer */
    1550             rc = zipDecompressBuffer(gzipStream,
    1551                                            (uint32_t *)(&cbDecompressed),
    1552                                            &fFinished);
    1553 
    1554             if (RT_FAILURE(rc))
    1555                 break;
    1556 
    1557             rc = RTFileWrite(pFile, decompressedBuffer, cbDecompressed, &cbDecompressed);
    1558 
    1559             if (RT_FAILURE(rc))
    1560                 break;
    1561 
    1562             cbAllWritten += cbDecompressed;
    1563             cbAllRead += cbRead;
    1564         }
    1565     } while (0);
    1566 
    1567     pIfIo->pfnClose(pvUser, pvStorage);
    1568 
    1569     if (rc == VERR_EOF)
    1570         rc = VINF_SUCCESS;
    1571 
    1572     rc = inflateEnd(&gzipStream);
    1573 
    1574     rc = RTFileClose(pFile);
    1575 
    1576     if (decompressedBuffer)
    1577         RTMemFree(decompressedBuffer);
    1578     if (compressedBuffer)
    1579         RTMemFree(compressedBuffer);
    1580 #endif /* !VBOX_MAIN_USE_VFS */
    1581 
    15821415    return rc;
    15831416}
  • trunk/src/VBox/Main/src-server/ApplianceImplImport.cpp

    r47516 r47716  
    15441544                throw setError(E_OUTOFMEMORY);
    15451545
     1546            Utf8Str nameSha = applianceIOName(applianceIOSha);
     1547            /* Fill out interface descriptor. */
     1548            pShaIo->Core.u32Magic         = VDINTERFACE_MAGIC;
     1549            pShaIo->Core.cbSize           = sizeof(VDINTERFACEIO);
     1550            pShaIo->Core.pszInterfaceName = nameSha.c_str();
     1551            pShaIo->Core.enmInterface     = VDINTERFACETYPE_IO;
     1552            pShaIo->Core.pvUser           = &storage;
     1553            pShaIo->Core.pNext            = NULL;
     1554
    15461555            storage.fCreateDigest = true;
    15471556
     
    16351644        RT_ZERO(storage);
    16361645
    1637         Utf8Str name = applianceIOName(applianceIOTar);
    1638 
    1639         vrc = VDInterfaceAdd(&pTarIo->Core, name.c_str(),
     1646        Utf8Str nameTar = applianceIOName(applianceIOTar);
     1647
     1648        vrc = VDInterfaceAdd(&pTarIo->Core, nameTar.c_str(),
    16401649                             VDINTERFACETYPE_IO, tar, sizeof(VDINTERFACEIO),
    16411650                             &storage.pVDImageIfaces);
     
    16431652            throw setError(VBOX_E_IPRT_ERROR,
    16441653                           tr("Creation of the VD interface failed (%Rrc)"), vrc);
     1654
     1655        Utf8Str nameSha = applianceIOName(applianceIOSha);
     1656        /* Fill out interface descriptor. */
     1657        pShaIo->Core.u32Magic         = VDINTERFACE_MAGIC;
     1658        pShaIo->Core.cbSize           = sizeof(VDINTERFACEIO);
     1659        pShaIo->Core.pszInterfaceName = nameSha.c_str();
     1660        pShaIo->Core.enmInterface     = VDINTERFACETYPE_IO;
     1661        pShaIo->Core.pvUser           = &storage;
     1662        pShaIo->Core.pNext            = NULL;
    16451663
    16461664        /* Read the file name of the first file (need to be the ovf file). This
     
    22902308
    22912309                /* Create the necessary file access interfaces. */
     2310
    22922311                pFileIo = FileCreateInterface();
    22932312                if (!pFileIo)
  • trunk/src/VBox/Storage/VDIfVfs.cpp

    r47665 r47716  
    154154}
    155155
    156 
    157 
    158 
    159156/**
    160157 * Standard file operations.
     
    164161    { /* Obj */
    165162        RTVFSOBJOPS_VERSION,
    166         RTVFSOBJTYPE_FILE,
     163        RTVFSOBJTYPE_IO_STREAM,
    167164        "VDIfIos",
    168165        vdIfVfsIos_Close,
     
    180177    NULL /*ZeroFill*/,
    181178    RTVFSIOSTREAMOPS_VERSION,
     179
    182180};
    183 
    184181
    185182VBOXDDU_DECL(int) VDIfCreateVfsStream(PVDINTERFACEIO pVDIfsIo, void *pvStorage, uint32_t fFlags, PRTVFSIOSTREAM phVfsIos)
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