VirtualBox

Changeset 2718 in vbox for trunk/src/VBox/Devices/Storage


Ignore:
Timestamp:
May 18, 2007 3:07:58 PM (18 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
21314
Message:

Implemented raw partition access.

Location:
trunk/src/VBox/Devices/Storage
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/Storage/VBoxHDD-new.cpp

    r2650 r2718  
    505505                          pszBackend);
    506506
    507     LogFlow(("%s: returns %vrc (pDisk=%#p)\n", __FUNCTION__, rc, pDisk));
     507    LogFlow(("%s: returns %Vrc (pDisk=%#p)\n", __FUNCTION__, rc, pDisk));
    508508    return rc;
    509509}
     
    10331033{
    10341034    /* sanity check */
     1035    LogFlow(("%s: offset=%llu cbRead=%u\n", __FUNCTION__, uOffset, (unsigned)cbRead));
    10351036    Assert(pDisk);
    10361037    AssertMsg(pDisk->u32Signature == VBOXHDDDISK_SIGNATURE, ("u32Signature=%08x\n", pDisk->u32Signature));
  • trunk/src/VBox/Devices/Storage/VmdkHDDCore.cpp

    r2661 r2718  
    547547static void vmdkFreeGrainDirectory(PVMDKEXTENT pExtent)
    548548{
    549     if (pExtent->pszBasename)
    550     {
    551         RTMemTmpFree((void *)pExtent->pszBasename);
    552         pExtent->pszBasename = NULL;
    553     }
    554549    if (pExtent->pGD)
    555550    {
     
    15731568            RTFileDelete(pExtent->pszFullname);
    15741569    }
     1570    if (pExtent->pszBasename)
     1571    {
     1572        RTMemTmpFree((void *)pExtent->pszBasename);
     1573        pExtent->pszBasename = NULL;
     1574    }
    15751575    if (pExtent->pszFullname)
    15761576    {
     
    17611761                 * extent descriptor is absolute. Doesn't always work, but
    17621762                 * should be good enough for now. */
     1763                char *pszFullname;
    17631764                /** @todo implement proper path absolute check. */
    17641765                if (pExtent->pszBasename[0] == RTPATH_SLASH)
    17651766                {
    1766                     pszFilename = RTStrDup(pExtent->pszBasename);
    1767                     if (!pszFilename)
     1767                    pszFullname = RTStrDup(pExtent->pszBasename);
     1768                    if (!pszFullname)
    17681769                    {
    17691770                        rc = VERR_NO_MEMORY;
     
    17821783                    RTPathStripFilename(pszDirname);
    17831784                    cbDirname = strlen(pszDirname);
    1784                     char *pszFullname;
    17851785                    rc = RTStrAPrintf(&pszFullname, "%s%c%s", pszDirname,
    17861786                                      RTPATH_SLASH, pExtent->pszBasename);
     
    17881788                    if (VBOX_FAILURE(rc))
    17891789                        goto out;
    1790                     pExtent->pszFullname = pszFullname;
    17911790                }
     1791                pExtent->pszFullname = pszFullname;
    17921792            }
    17931793            else
     
    19561956                pExtent->uSectorOffset = 0;
    19571957                pExtent->enmAccess = VMDKACCESS_READWRITE;
    1958                 pExtent->fMetaDirty = true;
     1958                pExtent->fMetaDirty = false;
    19591959
    19601960                pImage->enmImageType = enmType;
     
    19771977            else
    19781978            {
    1979                 /******* fixme. */
    1980                 rc = VERR_NOT_IMPLEMENTED;
    1981                 goto out;
     1979                /* Raw partition access. This requires setting up a descriptor
     1980                 * file, write the partition information to a flat extent and
     1981                 * open all the (flat) raw disk partitions. */
     1982
     1983                /* First pass over the partitions to determine how many
     1984                 * extents we need. One partition can require up to 4 extents.
     1985                 * One to skip over unpartitioned space, one for the
     1986                 * partitioning data, one to skip over unpartitioned space
     1987                 * and one for the partition data. */
     1988                unsigned cExtents = 0;
     1989                uint64_t uStart = 0;
     1990                for (unsigned i = 0; i < pRaw->cPartitions; i++)
     1991                {
     1992                    PVBOXHDDRAWPART pPart = &pRaw->pPartitions[i];
     1993                    if (pPart->cbPartitionData)
     1994                    {
     1995                        if (uStart > pPart->uPartitionDataStart)
     1996                        {
     1997                            rc = vmdkError(pImage, VERR_INVALID_PARAMETER, RT_SRC_POS, N_("VMDK: cannot go backwards for partitioning information in '%s'"), pszFilename);
     1998                            goto out;
     1999                        } else if (uStart != pPart->uPartitionDataStart)
     2000                            cExtents++;
     2001                        uStart = pPart->uPartitionDataStart + pPart->cbPartitionData;
     2002                        cExtents++;
     2003                    }
     2004                    if (pPart->cbPartition)
     2005                    {
     2006                        if (uStart > pPart->uPartitionStart)
     2007                        {
     2008                            rc = vmdkError(pImage, VERR_INVALID_PARAMETER, RT_SRC_POS, N_("VMDK: cannot go backwards for partition data in '%s'"), pszFilename);
     2009                            goto out;
     2010                        } else if (uStart != pPart->uPartitionStart)
     2011                            cExtents++;
     2012                        uStart = pPart->uPartitionStart + pPart->cbPartition;
     2013                        cExtents++;
     2014                    }
     2015                }
     2016                /* Another extent for filling up the rest of the image. */
     2017                if (uStart != cbSize)
     2018                    cExtents++;
     2019
     2020                rc = vmdkCreateExtents(pImage, cExtents);
     2021                if (VBOX_FAILURE(rc))
     2022                {
     2023                    rc = vmdkError(pImage, rc, RT_SRC_POS, N_("VMDK: could not create new extent list in '%s'"), pszFilename);
     2024                    goto out;
     2025                }
     2026
     2027                rc = RTFileOpen(&pImage->File, pszFilename,
     2028                                RTFILE_O_READWRITE | RTFILE_O_CREATE | RTFILE_O_DENY_WRITE);
     2029                if (VBOX_FAILURE(rc))
     2030                {
     2031                    rc = vmdkError(pImage, rc, RT_SRC_POS, N_("VMDK: could not create new file '%s'"), pszFilename);
     2032                    goto out;
     2033                }
     2034
     2035                /* Create base filename for the partition table extent. */
     2036                /** @todo remove fixed buffer. */
     2037                char pszPartition[1024];
     2038                const char *pszBase = RTPathFilename(pszFilename);
     2039                const char *pszExt = RTPathExt(pszBase);
     2040                if (pszExt == NULL)
     2041                {
     2042                    rc = vmdkError(pImage, rc, RT_SRC_POS, N_("VMDK: invalid filename '%s'"), pszFilename);
     2043                    goto out;
     2044                }
     2045                memcpy(pszPartition, pszBase, pszExt - pszBase);
     2046                memcpy(pszPartition + (pszExt - pszBase), "-pt", 3);
     2047                memcpy(pszPartition + (pszExt - pszBase) + 3, pszExt, strlen(pszExt) + 1);
     2048
     2049                /* Second pass over the partitions, now define all extents. */
     2050                uint64_t uPartOffset = 0;
     2051                cExtents = 0;
     2052                uStart = 0;
     2053                for (unsigned i = 0; i < pRaw->cPartitions; i++)
     2054                {
     2055                    PVBOXHDDRAWPART pPart = &pRaw->pPartitions[i];
     2056                    if (pPart->cbPartitionData)
     2057                    {
     2058                        if (uStart != pPart->uPartitionDataStart)
     2059                        {
     2060                            pExtent = &pImage->pExtents[cExtents++];
     2061                            pExtent->pszBasename = NULL;
     2062                            pExtent->pszFullname = NULL;
     2063                            pExtent->enmType = VMDKETYPE_ZERO;
     2064                            pExtent->cNominalSectors = VMDK_BYTE2SECTOR(pPart->uPartitionDataStart - uStart);
     2065                            pExtent->uSectorOffset = 0;
     2066                            pExtent->enmAccess = VMDKACCESS_READWRITE;
     2067                            pExtent->fMetaDirty = false;
     2068                        }
     2069                        uStart = pPart->uPartitionDataStart + pPart->cbPartitionData;
     2070                        pExtent = &pImage->pExtents[cExtents++];
     2071                        /* Set up basename for extent description. Cannot use StrDup. */
     2072                        size_t cbBasename = strlen(pszPartition) + 1;
     2073                        char *pszBasename = (char *)RTMemTmpAlloc(cbBasename);
     2074                        if (!pszBasename)
     2075                        {
     2076                            rc = VERR_NO_MEMORY;
     2077                            goto out;
     2078                        }
     2079                        memcpy(pszBasename, pszPartition, cbBasename);
     2080                        pExtent->pszBasename = pszBasename;
     2081
     2082                        /* Set up full name for partition extent. */
     2083                        size_t cbDirname;
     2084                        char *pszDirname = RTStrDup(pImage->pszFilename);
     2085                        if (!pszDirname)
     2086                        {
     2087                            rc = VERR_NO_MEMORY;
     2088                            goto out;
     2089                        }
     2090                        RTPathStripFilename(pszDirname);
     2091                        cbDirname = strlen(pszDirname);
     2092                        char *pszFullname;
     2093                        rc = RTStrAPrintf(&pszFullname, "%s%c%s", pszDirname,
     2094                                          RTPATH_SLASH, pExtent->pszBasename);
     2095                        RTStrFree(pszDirname);
     2096                        if (VBOX_FAILURE(rc))
     2097                            goto out;
     2098                        pExtent->pszFullname = pszFullname;
     2099                        pExtent->enmType = VMDKETYPE_FLAT;
     2100                        pExtent->cNominalSectors = VMDK_BYTE2SECTOR(pPart->cbPartitionData);
     2101                        pExtent->uSectorOffset = uPartOffset;
     2102                        pExtent->enmAccess = VMDKACCESS_READWRITE;
     2103                        pExtent->fMetaDirty = false;
     2104
     2105                        rc = RTFileOpen(&pExtent->File, pExtent->pszFullname,
     2106                                        RTFILE_O_READWRITE | RTFILE_O_OPEN_CREATE | RTFILE_O_DENY_WRITE);
     2107                        if (VBOX_FAILURE(rc))
     2108                        {
     2109                            rc = vmdkError(pImage, rc, RT_SRC_POS, N_("VMDK: could not create new partition data file '%s'"), pExtent->pszFullname);
     2110                            goto out;
     2111                        }
     2112                        rc = RTFileWriteAt(pExtent->File, VMDK_SECTOR2BYTE(uPartOffset), pPart->pvPartitionData, pPart->cbPartitionData, NULL);
     2113                        if (VBOX_FAILURE(rc))
     2114                        {
     2115                            rc = vmdkError(pImage, rc, RT_SRC_POS, N_("VMDK: could not write partition data to '%s'"), pExtent->pszFullname);
     2116                            goto out;
     2117                        }
     2118                        uPartOffset += VMDK_BYTE2SECTOR(pPart->cbPartitionData);
     2119                    }
     2120                    if (pPart->cbPartition)
     2121                    {
     2122                        if (uStart != pPart->uPartitionStart)
     2123                        {
     2124                            pExtent = &pImage->pExtents[cExtents++];
     2125                            pExtent->pszBasename = NULL;
     2126                            pExtent->pszFullname = NULL;
     2127                            pExtent->enmType = VMDKETYPE_ZERO;
     2128                            pExtent->cNominalSectors = VMDK_BYTE2SECTOR(pPart->uPartitionStart - uStart);
     2129                            pExtent->uSectorOffset = 0;
     2130                            pExtent->enmAccess = VMDKACCESS_READWRITE;
     2131                            pExtent->fMetaDirty = false;
     2132                        }
     2133                        uStart = pPart->uPartitionStart + pPart->cbPartition;
     2134                        pExtent = &pImage->pExtents[cExtents++];
     2135                        if (pPart->pszRawDevice)
     2136                        {
     2137                            /* Set up basename for extent description. Cannot use StrDup. */
     2138                            size_t cbBasename = strlen(pPart->pszRawDevice) + 1;
     2139                            char *pszBasename = (char *)RTMemTmpAlloc(cbBasename);
     2140                            if (!pszBasename)
     2141                            {
     2142                                rc = VERR_NO_MEMORY;
     2143                                goto out;
     2144                            }
     2145                            memcpy(pszBasename, pPart->pszRawDevice, cbBasename);
     2146                            pExtent->pszBasename = pszBasename;
     2147                            /* For raw disks the full name is identical to the base name. */
     2148                            pExtent->pszFullname = RTStrDup(pszBasename);
     2149                            if (!pExtent->pszFullname)
     2150                            {
     2151                                rc = VERR_NO_MEMORY;
     2152                                goto out;
     2153                            }
     2154                            pExtent->enmType = VMDKETYPE_FLAT;
     2155                            pExtent->cNominalSectors = VMDK_BYTE2SECTOR(pPart->cbPartition);
     2156                            pExtent->uSectorOffset = VMDK_BYTE2SECTOR(pPart->uPartitionStartOffset);
     2157                            pExtent->enmAccess = VMDKACCESS_READWRITE;
     2158                            pExtent->fMetaDirty = false;
     2159
     2160                            rc = RTFileOpen(&pExtent->File, pExtent->pszFullname,
     2161                                            RTFILE_O_READWRITE | RTFILE_O_OPEN | RTFILE_O_DENY_WRITE);
     2162                            if (VBOX_FAILURE(rc))
     2163                            {
     2164                                rc = vmdkError(pImage, rc, RT_SRC_POS, N_("VMDK: could not open raw partition file '%s'"), pExtent->pszFullname);
     2165                                goto out;
     2166                            }
     2167                        }
     2168                        else
     2169                        {
     2170                            pExtent->pszBasename = NULL;
     2171                            pExtent->pszFullname = NULL;
     2172                            pExtent->enmType = VMDKETYPE_ZERO;
     2173                            pExtent->cNominalSectors = VMDK_BYTE2SECTOR(pPart->cbPartition);
     2174                            pExtent->uSectorOffset = 0;
     2175                            pExtent->enmAccess = VMDKACCESS_READWRITE;
     2176                            pExtent->fMetaDirty = false;
     2177                        }
     2178                    }
     2179                }
     2180                /* Another extent for filling up the rest of the image. */
     2181                if (uStart != cbSize)
     2182                {
     2183                    pExtent = &pImage->pExtents[cExtents++];
     2184                    pExtent->pszBasename = NULL;
     2185                    pExtent->pszFullname = NULL;
     2186                    pExtent->enmType = VMDKETYPE_ZERO;
     2187                    pExtent->cNominalSectors = VMDK_BYTE2SECTOR(cbSize - uStart);
     2188                    pExtent->uSectorOffset = 0;
     2189                    pExtent->enmAccess = VMDKACCESS_READWRITE;
     2190                    pExtent->fMetaDirty = false;
     2191                }
     2192
     2193                pImage->enmImageType = enmType;
     2194                rc = vmdkDescSetStr(pImage, &pImage->Descriptor, pImage->Descriptor.uFirstDesc, "createType", "\"partitionedDevice\"");
     2195                if (VBOX_FAILURE(rc))
     2196                {
     2197                    rc = vmdkError(pImage, rc, RT_SRC_POS, N_("VMDK: could not set the image type in '%s'"), pszFilename);
     2198                    goto out;
     2199                }
    19822200            }
    19832201        }
     
    26192837
    26202838    /* Clip read range to remain in this extent. */
    2621     cbRead = RT_MIN(cbRead, VMDK_SECTOR2BYTE(pExtent->cNominalSectors - uSectorExtentRel));
     2839    cbRead = RT_MIN(cbRead, VMDK_SECTOR2BYTE(pExtent->uSectorOffset + pExtent->cNominalSectors - uSectorExtentRel));
    26222840
    26232841    /* Handle the read according to the current extent type. */
     
    27252943                {
    27262944                    /* Clip write range to remain in this extent. */
    2727                     cbWrite = RT_MIN(cbWrite, VMDK_SECTOR2BYTE(pExtent->cNominalSectors - uSectorExtentRel));
     2945                    cbWrite = RT_MIN(cbWrite, VMDK_SECTOR2BYTE(pExtent->uSectorOffset + pExtent->cNominalSectors - uSectorExtentRel));
    27282946                    *pcbPreRead = VMDK_SECTOR2BYTE(uSectorExtentRel % pExtent->cSectorsPerGrain);
    27292947                    *pcbPostRead = VMDK_SECTOR2BYTE(pExtent->cSectorsPerGrain) - cbWrite - *pcbPreRead;
     
    27382956        case VMDKETYPE_FLAT:
    27392957            /* Clip write range to remain in this extent. */
    2740             cbWrite = RT_MIN(cbWrite, VMDK_SECTOR2BYTE(pExtent->cNominalSectors - uSectorExtentRel));
     2958            cbWrite = RT_MIN(cbWrite, VMDK_SECTOR2BYTE(pExtent->uSectorOffset + pExtent->cNominalSectors - uSectorExtentRel));
    27412959            rc = RTFileWriteAt(pExtent->File, VMDK_SECTOR2BYTE(uSectorExtentRel), pvBuf, cbWrite, NULL);
    27422960            break;
    27432961        case VMDKETYPE_ZERO:
    27442962            /* Clip write range to remain in this extent. */
    2745             cbWrite = RT_MIN(cbWrite, VMDK_SECTOR2BYTE(pExtent->cNominalSectors - uSectorExtentRel));
     2963            cbWrite = RT_MIN(cbWrite, VMDK_SECTOR2BYTE(pExtent->uSectorOffset + pExtent->cNominalSectors - uSectorExtentRel));
    27462964            break;
    27472965    }
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