VirtualBox

Ignore:
Timestamp:
Jan 24, 2014 12:48:20 AM (11 years ago)
Author:
vboxsync
Message:

Main: Fixed bug preventing exporting ISOs/DMGs larger than 4GB on 32-bit hosts. Cleaned up the TAR write backend.

File:
1 edited

Legend:

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

    r50200 r50204  
    5454{
    5555    /** Tar handle. */
    56     RTTARFILE      file;
     56    RTTARFILE      hTarFile;
    5757    /** Completion callback. */
    5858    PFNVDCOMPLETED pfnCompleted;
     
    328328}
    329329
    330 /******************************************************************************
    331  *   Internal: RTTar interface
    332  ******************************************************************************/
    333 
    334 static int tarOpenCallback(void *pvUser, const char *pszLocation, uint32_t fOpen,
    335                              PFNVDCOMPLETED pfnCompleted, void **ppInt)
     330
     331/** @name VDINTERFACEIO implementation that writes TAR files via RTTar.
     332 * @{ */
     333
     334static DECLCALLBACK(int) tarWriter_Open(void *pvUser, const char *pszLocation, uint32_t fOpen,
     335                                        PFNVDCOMPLETED pfnCompleted, void **ppInt)
    336336{
    337337    /* Validate input. */
     
    339339    AssertPtrReturn(ppInt, VERR_INVALID_POINTER);
    340340    AssertPtrNullReturn(pfnCompleted, VERR_INVALID_PARAMETER);
    341 //    AssertReturn(!(fOpen & RTFILE_O_READWRITE), VERR_INVALID_PARAMETER);
    342 
    343     RTTAR tar = (RTTAR)pvUser;
    344 
    345     DEBUG_PRINT_FLOW();
    346 
     341    AssertReturn(fOpen & RTFILE_O_WRITE, VERR_INVALID_PARAMETER); /* Only for writing. */
     342
     343    DEBUG_PRINT_FLOW();
     344
     345    /*
     346     * Allocate a storage handle.
     347     */
     348    int rc;
    347349    PTARSTORAGEINTERNAL pInt = (PTARSTORAGEINTERNAL)RTMemAllocZ(sizeof(TARSTORAGEINTERNAL));
    348     if (!pInt)
    349         return VERR_NO_MEMORY;
    350 
    351     pInt->pfnCompleted = pfnCompleted;
    352 
    353     int rc = VINF_SUCCESS;
    354 
    355     if (fOpen & RTFILE_O_READ
    356         && !(fOpen & RTFILE_O_WRITE))
    357     {
    358         /* Read only is a little bit more complicated than writing, cause we
    359          * need streaming functionality. First try to open the file on the
    360          * current file position. If this is the file the caller requested, we
    361          * are fine. If not seek to the next file in the stream and check
    362          * again. This is repeated until EOF of the OVA. */
     350    if (pInt)
     351    {
     352        pInt->pfnCompleted = pfnCompleted;
     353
    363354        /*
    364          *
    365          *
    366          *  TODO: recheck this with more VDMKs (or what else) in an test OVA.
    367          *
    368          *
     355         * Try open the file.
    369356         */
    370         bool fFound = false;
    371 
    372         for (;;)
    373         {
    374             char *pszFilename;
    375             rc = RTTarCurrentFile(tar, &pszFilename);
    376             if (RT_SUCCESS(rc))
    377             {
    378                 if (rc == VINF_TAR_DIR_PATH)
    379                 {
    380                     RTStrFree(pszFilename);
    381                     break;
    382                 }
    383 
    384                 fFound = !RTStrICmp(pszFilename, pszLocation);
    385 
    386                 RTStrFree(pszFilename);
    387                 if (fFound)
    388                     break;
    389                 rc = RTTarSeekNextFile(tar);
    390                 if (RT_FAILURE(rc))
    391                     break;
    392             }
    393             else
    394                 break;
    395         }
    396         if (fFound)
    397             rc = RTTarFileOpenCurrentFile(tar, &pInt->file, 0, fOpen);
     357        rc = RTTarFileOpen((RTTAR)pvUser, &pInt->hTarFile, RTPathFilename(pszLocation), fOpen);
     358        if (RT_SUCCESS(rc))
     359            *ppInt = pInt;
     360        else
     361            RTMemFree(pInt);
    398362    }
    399363    else
    400         rc = RTTarFileOpen(tar, &pInt->file, RTPathFilename(pszLocation), fOpen);
    401 
    402     if (RT_FAILURE(rc))
    403         RTMemFree(pInt);
    404     else
    405         *ppInt = pInt;
    406 
     364        rc = VERR_NO_MEMORY;
    407365    return rc;
    408366}
    409367
    410 static int tarCloseCallback(void *pvUser, void *pvStorage)
     368static DECLCALLBACK(int) tarWriter_Close(void *pvUser, void *pvStorage)
    411369{
    412370    /* Validate input. */
     
    418376    DEBUG_PRINT_FLOW();
    419377
    420     int rc = RTTarFileClose(pInt->file);
     378    int rc = RTTarFileClose(pInt->hTarFile);
     379    pInt->hTarFile = NIL_RTTARFILE;
    421380
    422381    /* Cleanup */
     
    426385}
    427386
    428 static int tarDeleteCallback(void *pvUser, const char *pcszFilename)
    429 {
    430     /* Validate input. */
    431     AssertPtrReturn(pvUser, VERR_INVALID_POINTER);
    432     AssertPtrReturn(pcszFilename, VERR_INVALID_POINTER);
    433 
    434     DEBUG_PRINT_FLOW();
    435 
    436     return VERR_NOT_IMPLEMENTED;
    437 }
    438 
    439 static int tarMoveCallback(void *pvUser, const char *pcszSrc, const char *pcszDst, unsigned /* fMove */)
    440 {
    441     /* Validate input. */
    442     AssertPtrReturn(pvUser, VERR_INVALID_POINTER);
    443     AssertPtrReturn(pcszSrc, VERR_INVALID_POINTER);
    444     AssertPtrReturn(pcszDst, VERR_INVALID_POINTER);
    445 
    446     DEBUG_PRINT_FLOW();
    447 
    448     return VERR_NOT_IMPLEMENTED;
    449 }
    450 
    451 static int tarGetFreeSpaceCallback(void *pvUser, const char *pcszFilename, int64_t *pcbFreeSpace)
    452 {
    453     /* Validate input. */
    454     AssertPtrReturn(pvUser, VERR_INVALID_POINTER);
    455     AssertPtrReturn(pcszFilename, VERR_INVALID_POINTER);
    456     AssertPtrReturn(pcbFreeSpace, VERR_INVALID_POINTER);
    457 
    458     DEBUG_PRINT_FLOW();
    459 
    460     return VERR_NOT_IMPLEMENTED;
    461 }
    462 
    463 static int tarGetModificationTimeCallback(void *pvUser, const char *pcszFilename, PRTTIMESPEC pModificationTime)
    464 {
    465     /* Validate input. */
    466     AssertPtrReturn(pvUser, VERR_INVALID_POINTER);
    467     AssertPtrReturn(pcszFilename, VERR_INVALID_POINTER);
    468     AssertPtrReturn(pModificationTime, VERR_INVALID_POINTER);
    469 
    470     DEBUG_PRINT_FLOW();
    471 
    472     return VERR_NOT_IMPLEMENTED;
    473 }
    474 
    475 static int tarGetSizeCallback(void *pvUser, void *pvStorage, uint64_t *pcbSize)
    476 {
     387static DECLCALLBACK(int) tarWriter_GetSize(void *pvUser, void *pvStorage, uint64_t *pcbSize)
     388{
     389    /** @todo Not sure if this is really required, but it's not a biggie to keep
     390     *        around. */
    477391    /* Validate input. */
    478392    AssertPtrReturn(pvUser, VERR_INVALID_POINTER);
     
    483397    DEBUG_PRINT_FLOW();
    484398
    485     return RTTarFileGetSize(pInt->file, pcbSize);
    486 }
    487 
    488 static int tarSetSizeCallback(void *pvUser, void *pvStorage, uint64_t cbSize)
     399    return RTTarFileGetSize(pInt->hTarFile, pcbSize);
     400}
     401
     402static DECLCALLBACK(int) tarWriter_SetSize(void *pvUser, void *pvStorage, uint64_t cbSize)
    489403{
    490404    /* Validate input. */
     
    496410    DEBUG_PRINT_FLOW();
    497411
    498     return RTTarFileSetSize(pInt->file, cbSize);
    499 }
    500 
    501 static int tarWriteSyncCallback(void *pvUser, void *pvStorage, uint64_t uOffset,
    502                                   const void *pvBuf, size_t cbWrite, size_t *pcbWritten)
     412    return RTTarFileSetSize(pInt->hTarFile, cbSize);
     413}
     414
     415static DECLCALLBACK(int) tarWriter_WriteSync(void *pvUser, void *pvStorage, uint64_t uOffset,
     416                                             const void *pvBuf, size_t cbWrite, size_t *pcbWritten)
    503417{
    504418    /* Validate input. */
     
    510424    DEBUG_PRINT_FLOW();
    511425
    512     return RTTarFileWriteAt(pInt->file, uOffset, pvBuf, cbWrite, pcbWritten);
    513 }
    514 
    515 static int tarReadSyncCallback(void *pvUser, void *pvStorage, uint64_t uOffset,
    516                                  void *pvBuf, size_t cbRead, size_t *pcbRead)
    517 {
     426    return RTTarFileWriteAt(pInt->hTarFile, uOffset, pvBuf, cbWrite, pcbWritten);
     427}
     428
     429static DECLCALLBACK(int) tarWriter_ReadSync(void *pvUser, void *pvStorage, uint64_t uOffset,
     430                                            void *pvBuf, size_t cbRead, size_t *pcbRead)
     431{
     432    /** @todo Not sure if this is really required, but it's not a biggie to keep
     433     *        around. */
    518434    /* Validate input. */
    519435    AssertPtrReturn(pvUser, VERR_INVALID_POINTER);
     
    524440//    DEBUG_PRINT_FLOW();
    525441
    526     return RTTarFileReadAt(pInt->file, uOffset, pvBuf, cbRead, pcbRead);
    527 }
    528 
    529 static int tarFlushSyncCallback(void *pvUser, void *pvStorage)
    530 {
    531     /* Validate input. */
    532     AssertPtrReturn(pvUser, VERR_INVALID_POINTER);
    533     AssertPtrReturn(pvStorage, VERR_INVALID_POINTER);
    534 
    535     DEBUG_PRINT_FLOW();
    536 
    537     return VERR_NOT_IMPLEMENTED;
    538 }
     442    return RTTarFileReadAt(pInt->hTarFile, uOffset, pvBuf, cbRead, pcbRead);
     443}
     444
     445
     446PVDINTERFACEIO tarWriterCreateInterface(void)
     447{
     448    PVDINTERFACEIO pCallbacks = (PVDINTERFACEIO)RTMemAllocZ(sizeof(VDINTERFACEIO));
     449    if (!pCallbacks)
     450        return NULL;
     451
     452    pCallbacks->pfnOpen                = tarWriter_Open;
     453    pCallbacks->pfnClose               = tarWriter_Close;
     454    pCallbacks->pfnDelete              = notImpl_Delete;
     455    pCallbacks->pfnMove                = notImpl_Move;
     456    pCallbacks->pfnGetFreeSpace        = notImpl_GetFreeSpace;
     457    pCallbacks->pfnGetModificationTime = notImpl_GetModificationTime;
     458    pCallbacks->pfnGetSize             = tarWriter_GetSize;
     459    pCallbacks->pfnSetSize             = tarWriter_SetSize;
     460    pCallbacks->pfnReadSync            = tarWriter_ReadSync;
     461    pCallbacks->pfnWriteSync           = tarWriter_WriteSync;
     462    pCallbacks->pfnFlushSync           = notImpl_FlushSync;
     463
     464    return pCallbacks;
     465}
     466
     467/** @} */
    539468
    540469
    541470/** @name VDINTERFACEIO implementation on top of an IPRT file system stream.
    542471 * @{ */
    543 
    544472
    545473/**
     
    16311559}
    16321560
    1633 PVDINTERFACEIO TarCreateInterface()
    1634 {
    1635     PVDINTERFACEIO pCallbacks = (PVDINTERFACEIO)RTMemAllocZ(sizeof(VDINTERFACEIO));
    1636     if (!pCallbacks)
    1637         return NULL;
    1638 
    1639     pCallbacks->pfnOpen                = tarOpenCallback;
    1640     pCallbacks->pfnClose               = tarCloseCallback;
    1641     pCallbacks->pfnDelete              = tarDeleteCallback;
    1642     pCallbacks->pfnMove                = tarMoveCallback;
    1643     pCallbacks->pfnGetFreeSpace        = tarGetFreeSpaceCallback;
    1644     pCallbacks->pfnGetModificationTime = tarGetModificationTimeCallback;
    1645     pCallbacks->pfnGetSize             = tarGetSizeCallback;
    1646     pCallbacks->pfnSetSize             = tarSetSizeCallback;
    1647     pCallbacks->pfnReadSync            = tarReadSyncCallback;
    1648     pCallbacks->pfnWriteSync           = tarWriteSyncCallback;
    1649     pCallbacks->pfnFlushSync           = tarFlushSyncCallback;
    1650 
    1651     return pCallbacks;
    1652 }
    1653 
    16541561int readFileIntoBuffer(const char *pcszFilename, void **ppvBuf, size_t *pcbSize, PVDINTERFACEIO pIfIo, void *pvUser)
    16551562{
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