VirtualBox

Ignore:
Timestamp:
Aug 30, 2019 11:03:01 AM (5 years ago)
Author:
vboxsync
Message:

vboximg-mount: Switch to using a VFS file instead of the VDISK container directly so we can get builtin unaligned access handling without the need to duplicate the code, some memory leak fixes

Location:
trunk/src/VBox/ImageMounter/vboximg-mount
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/ImageMounter/vboximg-mount/SelfSizingTable.h

    r76585 r80511  
    159159        {
    160160            COLDATA *pColDataNext = pColData->next;
    161             delete pColData->pszData;
     161            delete[] pColData->pszData;
    162162            delete pColData;
    163163            pColData = pColDataNext;
  • trunk/src/VBox/ImageMounter/vboximg-mount/vboximg-mount.cpp

    r79966 r80511  
    7474#include <iprt/utf16.h>
    7575#include <iprt/base64.h>
     76#include <iprt/vfs.h>
    7677
    7778#include "vboximg-mount.h"
     
    119120/* Global variables */
    120121
    121 static PVDISK                g_pVDisk;              /** Handle for Virtual Disk in contet */
     122static RTVFSFILE             g_hVfsFileDisk;        /** Disk as VFS file handle. */
    122123static char                 *g_pszDiskUuid;          /** UUID of image (if known, otherwise NULL) */
    123124static off_t                 g_vDiskOffset;         /** Biases r/w from start of VD */
     
    400401}
    401402
    402 /**
    403  * VD read Sanitizer taking care of unaligned accesses.
    404  *
    405  * @return  VBox bootIndicator code.
    406  * @param   pDisk    VD disk container.
    407  * @param   off      Offset to start reading from.
    408  * @param   pvBuf    Pointer to the buffer to read into.
    409  * @param   cbRead   Amount of bytes to read.
    410  */
    411 static int vdReadSanitizer(PVDISK pDisk, uint64_t off, void *pvBuf, size_t cbRead)
    412 {
    413     int rc;
    414 
    415     uint64_t const cbMisalignmentOfStart = off & VD_SECTOR_MASK;
    416     uint64_t const cbMisalignmentOfEnd  = (off + cbRead) & VD_SECTOR_MASK;
    417 
    418     if (cbMisalignmentOfStart + cbMisalignmentOfEnd == 0) /* perfectly aligned request; just read it and done */
    419         rc = VDRead(pDisk, off, pvBuf, cbRead);
    420     else
    421     {
    422         uint8_t *pbBuf = (uint8_t *)pvBuf;
    423         uint8_t abBuf[VD_SECTOR_SIZE];
    424 
    425         /* If offset not @ sector boundary, read whole sector, then copy unaligned
    426          * bytes (requested by user), only up to sector boundary, into user's buffer
    427          */
    428         if (cbMisalignmentOfStart)
    429         {
    430             rc = VDRead(pDisk, off - cbMisalignmentOfStart, abBuf, VD_SECTOR_SIZE);
    431             if (RT_SUCCESS(rc))
    432             {
    433                 size_t const cbPartial = RT_MIN(VD_SECTOR_SIZE - cbMisalignmentOfStart, cbRead);
    434                 memcpy(pbBuf, &abBuf[cbMisalignmentOfStart], cbPartial);
    435                 pbBuf  += cbPartial;
    436                 off    += cbPartial; /* Beginning of next sector or EOD */
    437                 cbRead -= cbPartial; /* # left to read */
    438             }
    439         }
    440         else /* user's offset already aligned, did nothing */
    441             rc = VINF_SUCCESS;
    442 
    443         /* Read remaining aligned sectors, deferring any tail-skewed bytes */
    444         if (RT_SUCCESS(rc) && cbRead >= VD_SECTOR_SIZE)
    445         {
    446             Assert(!(off % VD_SECTOR_SIZE));
    447 
    448             size_t cbPartial = cbRead - cbMisalignmentOfEnd;
    449             Assert(!(cbPartial % VD_SECTOR_SIZE));
    450             rc = VDRead(pDisk, off, pbBuf, cbPartial);
    451             if (RT_SUCCESS(rc))
    452             {
    453                 pbBuf  += cbPartial;
    454                 off    += cbPartial;
    455                 cbRead -= cbPartial;
    456             }
    457         }
    458 
    459         /* Unaligned buffered read of tail. */
    460         if (RT_SUCCESS(rc) && cbRead)
    461         {
    462             Assert(cbRead == cbMisalignmentOfEnd);
    463             Assert(cbRead < VD_SECTOR_SIZE);
    464             Assert(!(off % VD_SECTOR_SIZE));
    465 
    466             rc = VDRead(pDisk, off, abBuf, VD_SECTOR_SIZE);
    467             if (RT_SUCCESS(rc))
    468                 memcpy(pbBuf, abBuf, cbRead);
    469         }
    470     }
    471 
    472     if (RT_FAILURE(rc))
    473     {
    474         int sysrc = -RTErrConvertToErrno(rc);
    475         LogFlowFunc(("error: %s (vbox err: %d)\n", strerror(sysrc), rc));
    476         rc = sysrc;
    477     }
    478     return cbRead;
    479 }
    480 
    481 /**
    482  * VD write Sanitizer taking care of unaligned accesses.
    483  *
    484  * @return  VBox bootIndicator code.
    485  * @param   pDisk    VD disk container.
    486  * @param   off      Offset to start writing to.
    487  * @param   pvSrc    Pointer to the buffer to read from.
    488  * @param   cbWrite  Amount of bytes to write.
    489  */
    490 static int vdWriteSanitizer(PVDISK pDisk, uint64_t off, const void *pvSrc, size_t cbWrite)
    491 {
    492     uint8_t const *pbSrc = (uint8_t const *)pvSrc;
    493     uint8_t        abBuf[4096];
    494     int rc;
    495     int cbRemaining = cbWrite;
    496 
    497     /*
    498      * Take direct route if the request is sector aligned.
    499      */
    500     uint64_t const cbMisalignmentOfStart = off & VD_SECTOR_MASK;
    501     size_t   const cbMisalignmentOfEnd  = (off + cbWrite) & VD_SECTOR_MASK;
    502     if (!cbMisalignmentOfStart && !cbMisalignmentOfEnd)
    503     {
    504           rc = VDWrite(pDisk, off, pbSrc, cbWrite);
    505           do
    506             {
    507                 size_t cbThisWrite = RT_MIN(cbWrite, sizeof(abBuf));
    508                 rc = VDWrite(pDisk, off, memcpy(abBuf, pbSrc, cbThisWrite), cbThisWrite);
    509                 if (RT_SUCCESS(rc))
    510                 {
    511                     pbSrc   += cbThisWrite;
    512                     off     += cbThisWrite;
    513                     cbRemaining -= cbThisWrite;
    514                 }
    515                 else
    516                     break;
    517             } while (cbRemaining > 0);
    518     }
    519     else
    520     {
    521         /*
    522          * Unaligned buffered read+write of head.  Aligns the offset.
    523          */
    524         if (cbMisalignmentOfStart)
    525         {
    526             rc = VDRead(pDisk, off - cbMisalignmentOfStart, abBuf, VD_SECTOR_SIZE);
    527             if (RT_SUCCESS(rc))
    528             {
    529                 size_t const cbPartial = RT_MIN(VD_SECTOR_SIZE - cbMisalignmentOfStart, cbWrite);
    530                 memcpy(&abBuf[cbMisalignmentOfStart], pbSrc, cbPartial);
    531                 rc = VDWrite(pDisk, off - cbMisalignmentOfStart, abBuf, VD_SECTOR_SIZE);
    532                 if (RT_SUCCESS(rc))
    533                 {
    534                     pbSrc   += cbPartial;
    535                     off     += cbPartial;
    536                     cbRemaining -= cbPartial;
    537                 }
    538             }
    539         }
    540         else
    541             rc = VINF_SUCCESS;
    542 
    543         /*
    544          * Aligned direct write.
    545          */
    546         if (RT_SUCCESS(rc) && cbWrite >= VD_SECTOR_SIZE)
    547         {
    548             Assert(!(off % VD_SECTOR_SIZE));
    549             size_t cbPartial = cbWrite - cbMisalignmentOfEnd;
    550             Assert(!(cbPartial % VD_SECTOR_SIZE));
    551             rc = VDWrite(pDisk, off, pbSrc, cbPartial);
    552             if (RT_SUCCESS(rc))
    553             {
    554                 pbSrc   += cbPartial;
    555                 off     += cbPartial;
    556                 cbRemaining -= cbPartial;
    557             }
    558         }
    559 
    560         /*
    561          * Unaligned buffered read + write of tail.
    562          */
    563         if (   RT_SUCCESS(rc) && cbWrite > 0)
    564         {
    565             Assert(cbWrite == cbMisalignmentOfEnd);
    566             Assert(cbWrite < VD_SECTOR_SIZE);
    567             Assert(!(off % VD_SECTOR_SIZE));
    568             rc = VDRead(pDisk, off, abBuf, VD_SECTOR_SIZE);
    569             if (RT_SUCCESS(rc))
    570             {
    571                 memcpy(abBuf, pbSrc, cbWrite);
    572                 rc = VDWrite(pDisk, off, abBuf, VD_SECTOR_SIZE);
    573             }
    574         }
    575     }
    576     if (RT_FAILURE(rc))
    577     {
    578         int sysrc = -RTErrConvertToErrno(rc);
    579         LogFlowFunc(("error: %s (vbox err: %d)\n", strerror(sysrc), rc));
    580         return sysrc;
    581     }
    582     return cbWrite - cbRemaining;
    583 }
    584 
    585403
    586404/** @copydoc fuse_operations::read */
     
    609427
    610428    if (rc >= 0)
    611         rc = vdReadSanitizer(g_pVDisk, adjOff, pbBuf, cbBuf);
     429    {
     430        int rcIprt = RTVfsFileReadAt(g_hVfsFileDisk, adjOff, pbBuf, cbBuf, NULL);
     431        if (RT_FAILURE(rc))
     432            rc = -RTErrConvertToErrno(rcIprt);
     433        else
     434            rc = cbBuf;
     435    }
    612436    if (rc < 0)
    613437        LogFlowFunc(("%s\n", strerror(rc)));
     
    643467
    644468    if (rc >= 0)
    645         rc = vdWriteSanitizer(g_pVDisk, adjOff, pbBuf, cbBuf);
     469    {
     470        int rcIprt = RTVfsFileWriteAt(g_hVfsFileDisk, adjOff, pbBuf, cbBuf, NULL);
     471        if (RT_FAILURE(rc))
     472            rc = -RTErrConvertToErrno(rcIprt);
     473        else
     474            rc = cbBuf;
     475    }
    646476    if (rc < 0)
    647477        LogFlowFunc(("%s\n", strerror(rc)));
     
    768598    g_aParsedPartitionInfo[0].idxPartition = 0;
    769599    g_aParsedPartitionInfo[0].offPartition = 0;
    770     g_aParsedPartitionInfo[0].cbPartition = VDGetSize(g_pVDisk, 0);
    771600    g_aParsedPartitionInfo[0].pszName = RTStrDup("EntireDisk");
    772601
     602    int rc = RTVfsFileGetSize(g_hVfsFileDisk, &g_aParsedPartitionInfo[0].cbPartition);
     603    if (RT_FAILURE(rc))
     604        return RTMsgErrorExitFailure("Error querying disk image size\n");
     605
    773606    /*
    774607     * Currently only DOS partitioned disks are supported. Ensure this one conforms
    775608     */
    776     int rc = vdReadSanitizer(g_pVDisk, 0, &mbr, sizeof (mbr));
     609    rc = RTVfsFileReadAt(g_hVfsFileDisk, 0, &mbr, sizeof (mbr), NULL);
    777610    if (RT_FAILURE(rc))
    778611        return RTMsgErrorExitFailure("Error reading MBR block from disk\n");
     
    827660        g_lastPartNbr = 2;  /* from the 'protective MBR' */
    828661
    829         rc = vdReadSanitizer(g_pVDisk, LBA(1), &parTblHdr, sizeof (parTblHdr));
     662        rc = RTVfsFileReadAt(g_hVfsFileDisk, LBA(1), &parTblHdr, sizeof (parTblHdr), NULL);
    830663        if (RT_FAILURE(rc))
    831664            return RTMsgErrorExitFailure("Error reading Partition Table Header (LBA 1) from disk\n");
     
    836669            return RTMsgErrorExitFailure("Out of memory\n");
    837670
    838         rc = vdReadSanitizer(g_pVDisk, LBA(2), pTblBuf, GPT_PTABLE_SIZE);
     671        rc = RTVfsFileReadAt(g_hVfsFileDisk, LBA(2), pTblBuf, GPT_PTABLE_SIZE, NULL);
    839672        if (RT_FAILURE(rc))
    840673            return RTMsgErrorExitFailure("Error reading Partition Table blocks from disk\n");
     
    887720
    888721            off_t currentEbrOffset = firstEbrOffset + chainedEbrOffset;
    889             vdReadSanitizer(g_pVDisk, currentEbrOffset, &ebr, sizeof (ebr));
     722            RTVfsFileReadAt(g_hVfsFileDisk, currentEbrOffset, &ebr, sizeof (ebr), NULL);
    890723
    891724            if (ebr.signature != DOS_BOOT_RECORD_SIGNATURE)
     
    13821215        RTPrintf("\nCreating container for base image of format %s\n", pszFormat);
    13831216
    1384     g_pVDisk = NULL;
    1385     rc = VDCreate(g_pVdIfs, enmType, &g_pVDisk);
     1217    PVDISK pVDisk = NULL;
     1218    rc = VDCreate(g_pVdIfs, enmType, &pVDisk);
    13861219    if ((rc))
    13871220        return RTMsgErrorExitFailure("ERROR: Couldn't create virtual disk container\n");
     
    13981231            RTPrintf("  Open: %s\n", CSTR(pCurMedium->pImagePath));
    13991232
    1400         rc = VDOpen(g_pVDisk,
     1233        rc = VDOpen(pVDisk,
    14011234                    CSTR(pszFormat),
    14021235                    CSTR(pCurMedium->pImagePath),
     
    14111244    }
    14121245
    1413     g_cReaders  = VDIsReadOnly(g_pVDisk) ? INT32_MAX / 2 : 0;
     1246    RTStrFree(pszFormat);
     1247
     1248    /* Create the VFS file to use for the disk image access. */
     1249    rc = VDCreateVfsFileFromDisk(pVDisk, VD_VFSFILE_DESTROY_ON_RELEASE, &g_hVfsFileDisk);
     1250    if (RT_FAILURE(rc))
     1251        return RTMsgErrorExitFailure("Error creating VFS file wrapper for disk image\n");
     1252
     1253    g_cReaders  = VDIsReadOnly(pVDisk) ? INT32_MAX / 2 : 0;
    14141254    g_cWriters  = 0;
    1415     g_cbEntireVDisk  = VDGetSize(g_pVDisk, 0 /* base */);
     1255    rc = RTVfsFileGetSize(g_hVfsFileDisk, (uint64_t *)&g_cbEntireVDisk);
     1256    if (RT_FAILURE(rc))
     1257        return RTMsgErrorExitFailure("Error querying disk image size from VFS wrapper\n");
    14161258
    14171259    if (g_vboximgOpts.fList)
    14181260    {
    1419         if (g_pVDisk == NULL)
     1261        if (g_hVfsFileDisk == NIL_RTVFSFILE)
    14201262            return RTMsgErrorExitFailure("No valid --image to list partitions from\n");
    14211263
     
    14591301        {
    14601302            g_vDiskOffset = 0;
    1461             g_vDiskSize = VDGetSize(g_pVDisk, 0);
     1303            g_vDiskSize = g_cbEntireVDisk;
    14621304            if (VERBOSE)
    14631305                RTPrintf("\nPartition 0 specified - Whole disk will be accessible\n");
     
    15131355    rc = fuse_main(args.argc, args.argv, &g_vboximgOps, NULL);
    15141356
    1515     int rc2 = VDClose(g_pVDisk, false /* fDelete */);
     1357    int rc2 = RTVfsFileRelease(g_hVfsFileDisk);
    15161358    AssertRC(rc2);
    15171359    RTPrintf("vboximg-mount: fuse_main -> %d\n", rc);
  • trunk/src/VBox/ImageMounter/vboximg-mount/vboximgMedia.cpp

    r76553 r80511  
    203203static void displayMediumInfo(MEDIUMINFO *pInfo, int nestLevel, bool fLast)
    204204{
    205 
    206     char *cbScaled = vboximgScaledSize(pInfo->cbSize);
     205    char *pszSzScaled = vboximgScaledSize(pInfo->cbSize);
    207206    int cPad = nestLevel * 2;
    208207    if (g_vboximgOpts.fWide && !g_vboximgOpts.fVerbose)
     
    211210            !fLast ? (pInfo->fSnapshot ? " | " : " +-") : (pInfo->fSnapshot ? "   " : " +-"),
    212211            VM_MAX_NAME, pInfo->fSnapshot ? "+- <snapshot>" : pInfo->pszName,
    213             cbScaled,
     212            pszSzScaled,
    214213            pInfo->pszFormat,
    215214            pInfo->pszState,
    216215            cPad, "", pInfo->pszUuid);
    217         RTMemFree(cbScaled);
    218216    }
    219217    else
     
    229227                RTPrintf("    Path:    %s\n", pInfo->pszPath);
    230228                RTPrintf("    Format:  %s\n", pInfo->pszFormat);
    231                 RTPrintf("    Size:    %s\n", cbScaled);
     229                RTPrintf("    Size:    %s\n", pszSzScaled);
    232230                RTPrintf("    State:   %s\n", pInfo->pszState);
    233231                RTPrintf("    Type:    %s\n", pInfo->pszType);
     
    243241                RTPrintf("         Desc:     %s\n", pInfo->pszDescription);
    244242            }
    245             RTPrintf("         Size:     %s\n", cbScaled);
     243            RTPrintf("         Size:     %s\n", pszSzScaled);
    246244            if (g_vboximgOpts.fVerbose)
    247245                RTPrintf("         Path:     %s\n", pInfo->pszPath);
     
    249247        }
    250248    }
     249    RTMemFree(pszSzScaled);
    251250}
    252251
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