VirtualBox

Changeset 9047 in vbox for trunk


Ignore:
Timestamp:
May 22, 2008 5:35:37 AM (17 years ago)
Author:
vboxsync
Message:

Partially implemented rename vmdk api call.

Location:
trunk/src/VBox
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/Storage/VmdkHDDCore.cpp

    r8509 r9047  
    36453645}
    36463646
     3647/**
     3648 * Allocates a new copy of the given UTF-8 string using RTMemTmpAlloc().
     3649 *
     3650 * @returns Pointer to the allocated UTF-8 string.
     3651 * @param   pszString       UTF-8 string to duplicate.
     3652 */
     3653static char * vmdkStrTmpDup(const char *pszString)
     3654{
     3655    Assert(VALID_PTR(pszString));
     3656    size_t cch = strlen(pszString) + 1;
     3657    char *psz = (char *)RTMemTmpAlloc(cch);
     3658    if (psz)
     3659        memcpy(psz, pszString, cch);
     3660    return psz;
     3661}
     3662
    36473663/** @copydoc VBOXHDDBACKEND::pfnRename */
    36483664static int vmdkRename(void *pBackendData, const char *pszFilename)
    36493665{
    36503666    LogFlowFunc(("pBackendData=%#p pszFilename=%#p\n", pBackendData, pszFilename));
    3651     int rc = VERR_NOT_IMPLEMENTED;
    3652 
     3667    PVMDKIMAGE pImage = (PVMDKIMAGE)pBackendData;
     3668    int rc = VINF_SUCCESS;
     3669    char **apszOldExtentBaseNames;
     3670    char **apszOldExtentFullNames;
     3671    char **apszNewExtentFullNames;
     3672    char *pszOldImageName;
     3673    char *pszNewImageName;
     3674    bool fImageFreed = false;
     3675
     3676    /* Check arguments. */
     3677    if (   !pImage
     3678        || (pImage->uImageFlags & VD_VMDK_IMAGE_FLAGS_RAWDISK)
     3679        || !VALID_PTR(pszFilename)
     3680        || !*pszFilename)
     3681    {
     3682        rc = VERR_INVALID_PARAMETER;
     3683        goto out;
     3684    }
     3685
     3686    /*
     3687     * Allocate an array to store old extent names in case we have to roll back the changes.
     3688     * Everything is initialized with zeros. We actually save stuff when and if we change it.
     3689     */
     3690    apszOldExtentBaseNames = (char **)RTMemTmpAllocZ(pImage->cExtents * sizeof(char*));
     3691    apszOldExtentFullNames = (char **)RTMemTmpAllocZ(pImage->cExtents * sizeof(char*));
     3692    apszNewExtentFullNames = (char **)RTMemTmpAllocZ(pImage->cExtents * sizeof(char*));
     3693    if (!apszOldExtentBaseNames || !apszOldExtentFullNames || !apszNewExtentFullNames)
     3694    {
     3695        if (apszOldExtentBaseNames)
     3696            RTMemTmpFree(apszOldExtentBaseNames);
     3697        if (apszOldExtentFullNames)
     3698            RTMemTmpFree(apszOldExtentFullNames);
     3699        if (apszNewExtentFullNames)
     3700            RTMemTmpFree(apszNewExtentFullNames);
     3701        rc = VERR_NO_MEMORY;
     3702        goto out;
     3703    }
     3704    pszOldImageName = NULL;
     3705    pszNewImageName = NULL;
     3706
     3707    do {
     3708        /* Basename strings needed for constructing the extent names. */
     3709        char *pszBasenameSubstr = RTPathFilename(pszFilename);
     3710        Assert(pszBasenameSubstr);
     3711        size_t cbBasenameSubstr = strlen(pszBasenameSubstr) + 1;
     3712
     3713        /* Loop through each VMDKEXTENT in VMDKIMAGE->pExtents using VMDKIMAGE->cExtents. */
     3714        for (unsigned i = 0; i < pImage->cExtents; i++)
     3715        {
     3716            PVMDKEXTENT pExtent = &pImage->pExtents[i];
     3717
     3718            /* @todo Store pExtent->pszFullname in array for future reference. */
     3719            /* @todo Store pExtent->pszBasename in array for future reference. */
     3720
     3721            /* @todo This is copy/paste code, move to seperate function. */
     3722            /* Determine the new file name. */
     3723            /* Set up fullname/basename for extent description. Cannot use StrDup
     3724             * for basename, as it is not guaranteed that the memory can be freed
     3725             * with RTMemTmpFree, which must be used as in other code paths
     3726             * StrDup is not usable. */
     3727            if (pImage->cExtents == 1 && pImage->enmImageType != VD_IMAGE_TYPE_FIXED)
     3728            {
     3729                char *pszBasename = (char *)RTMemTmpAlloc(cbBasenameSubstr);
     3730                if (!pszBasename)
     3731                {
     3732                    rc = VERR_NO_MEMORY;
     3733                    break;
     3734                }
     3735                memcpy(pszBasename, pszBasenameSubstr, cbBasenameSubstr);
     3736                /* Save the old name in case we need to roll back. */
     3737                apszOldExtentBaseNames[i] = vmdkStrTmpDup(pExtent->pszBasename);
     3738                pExtent->pszBasename = pszBasename;
     3739            }
     3740            else
     3741            {
     3742                char *pszBasenameExt = RTPathExt(pszBasenameSubstr);
     3743                char *pszBasenameBase = RTStrDup(pszBasenameSubstr);
     3744                RTPathStripExt(pszBasenameBase);
     3745                char *pszTmp;
     3746                size_t cbTmp;
     3747                if (pImage->enmImageType == VD_IMAGE_TYPE_FIXED)
     3748                {
     3749                    if (pImage->cExtents == 1)
     3750                        rc = RTStrAPrintf(&pszTmp, "%s-flat%s", pszBasenameBase,
     3751                                          pszBasenameExt);
     3752                    else
     3753                        rc = RTStrAPrintf(&pszTmp, "%s-f%03d%s", pszBasenameBase,
     3754                                          i+1, pszBasenameExt);
     3755                }
     3756                else
     3757                    rc = RTStrAPrintf(&pszTmp, "%s-s%03d%s", pszBasenameBase, i+1,
     3758                                      pszBasenameExt);
     3759                RTStrFree(pszBasenameBase);
     3760                if (VBOX_FAILURE(rc))
     3761                    break;
     3762                cbTmp = strlen(pszTmp) + 1;
     3763                char *pszBasename = (char *)RTMemTmpAlloc(cbTmp);
     3764                if (!pszBasename)
     3765                {
     3766                    rc = VERR_NO_MEMORY;
     3767                    break;
     3768                }
     3769                memcpy(pszBasename, pszTmp, cbTmp);
     3770                RTStrFree(pszTmp);
     3771                /* Save the old name in case we need to roll back. */
     3772                apszOldExtentBaseNames[i] = vmdkStrTmpDup(pExtent->pszBasename);
     3773                pExtent->pszBasename = pszBasename;
     3774                /* @todo ??? cbExtent = RT_MIN(cbRemaining, VMDK_2G_SPLIT_SIZE); */
     3775            }
     3776            char *pszBasedirectory = RTStrDup(pImage->pszFilename);
     3777            RTPathStripFilename(pszBasedirectory);
     3778            char *pszFN;
     3779            rc = RTStrAPrintf(&pszFN, "%s%c%s", pszBasedirectory, RTPATH_SLASH,
     3780                              pExtent->pszBasename);
     3781            RTStrFree(pszBasedirectory);
     3782            if (VBOX_FAILURE(rc))
     3783                break;
     3784
     3785            /* Close the VMDKEXTENT. */
     3786            vmdkFileClose(pImage, &pExtent->File, false);
     3787
     3788            /* Rename the file. */
     3789            rc = RTFileMove(pExtent->pszFullname, pszFN, 0);
     3790            if (VBOX_FAILURE(rc))
     3791                break;
     3792
     3793            /* Save both names in case we need to roll back. */
     3794            apszOldExtentFullNames[i] = RTStrDup(pExtent->pszFullname);
     3795            apszNewExtentFullNames[i] = RTStrDup(pszFN);
     3796            pExtent->pszFullname = pszFN;
     3797        }
     3798
     3799        if (VBOX_FAILURE(rc))
     3800            break;
     3801
     3802        /* After looping through all of them close the VMDKIMAGE. */
     3803        vmdkFreeImage(pImage, false);
     3804
     3805        fImageFreed = true;
     3806
     3807        /* Rename the descriptor file if it's separate. */
     3808        if (pImage->pDescData)
     3809        {
     3810            rc = RTFileCopy(pImage->pszFilename, pszFilename);
     3811            if (VBOX_FAILURE(rc))
     3812                break;
     3813            /* Save new name only if we may need to change it back. */
     3814            pszNewImageName = RTStrDup(pszFilename);
     3815        }
     3816
     3817        /* Save the old name in case we need to roll back. */
     3818        pszOldImageName = RTStrDup(pImage->pszFilename);
     3819        /* Update pImage with the new information. */
     3820        pImage->pszFilename = pszFilename;
     3821
     3822        /* Open the new image. */
     3823        rc = vmdkOpenImage(pImage, pImage->uOpenFlags);
     3824        if (VBOX_FAILURE(rc))
     3825            break;
     3826        /* Remove the old descriptor file. */
     3827        if (pszNewImageName)
     3828        {
     3829            rc = RTFileDelete(pszOldImageName);
     3830            AssertRC(rc);
     3831        }
     3832    } while (0);
     3833
     3834    /* Roll back all changes in case of failure. */
     3835    if (VBOX_FAILURE(rc))
     3836    {
     3837        int rrc;
     3838        if (!fImageFreed)
     3839        {
     3840            /*
     3841             * Some extents may have been closed, close the rest. We will
     3842             * re-open the whole thing later.
     3843             */
     3844            vmdkFreeImage(pImage, false);
     3845        }
     3846        if (pszNewImageName)
     3847        {
     3848            /* The image was actually copied, destroy the copy. */
     3849            rrc = RTFileDelete(pszNewImageName);
     3850            AssertRC(rrc);
     3851            RTStrFree(pszNewImageName);
     3852        }
     3853        if (pszOldImageName)
     3854        {
     3855            /* We end up here only if vmdkOpenImage() has failed, restore the old image name. */
     3856            pImage->pszFilename = pszOldImageName;
     3857        }
     3858        /* Restore renamed extents. */
     3859        for (unsigned i = 0; i < pImage->cExtents; i++)
     3860        {
     3861            if (apszOldExtentFullNames[i])
     3862            {
     3863                rrc = RTFileMove(apszNewExtentFullNames[i], apszOldExtentFullNames[i], 0);
     3864                AssertRC(rrc);
     3865                RTStrFree(apszNewExtentFullNames[i]);
     3866                RTStrFree(apszOldExtentFullNames[i]);
     3867            }
     3868        }
     3869        rrc = vmdkOpenImage(pImage, pImage->uOpenFlags);
     3870        AssertRC(rrc);
     3871    }
     3872
     3873    RTMemTmpFree(apszOldExtentBaseNames);
     3874    RTMemTmpFree(apszOldExtentFullNames);
     3875    RTMemTmpFree(apszNewExtentFullNames);
     3876
     3877out:
    36533878    LogFlowFunc(("returns %Vrc\n", rc));
    36543879    return rc;
  • trunk/src/VBox/Frontends/VBoxManage/VBoxInternalManage.cpp

    r8982 r9047  
    166166                "\n"
    167167                : "",
     168#if 0
     169             (u64Cmd & USAGE_RENAMEVMDK) ?
     170                 "  renamevmdk -from <filename> -to <filename>\n"
     171                 "       Renames an existing VMDK image, including the base file and all its extents.\n"
     172                 "\n"
     173                 : "",
     174#endif
    168175#ifdef RT_OS_WINDOWS
    169176            (u64Cmd & USAGE_MODINSTALL) ?
     
    11311138}
    11321139
     1140#if 0
     1141HRESULT CmdRenameVMDK(int argc, char **argv, ComPtr<IVirtualBox> aVirtualBox, ComPtr<ISession> aSession)
     1142{
     1143    Bstr src;
     1144    Bstr dst;
     1145    /* Parse the arguments. */
     1146    for (int i = 0; i < argc; i++)
     1147    {
     1148        if (strcmp(argv[i], "-from") == 0)
     1149        {
     1150            if (argc <= i + 1)
     1151            {
     1152                return errorArgument("Missing argument to '%s'", argv[i]);
     1153            }
     1154            i++;
     1155            src = argv[i];
     1156        }
     1157        else if (strcmp(argv[i], "-to") == 0)
     1158        {
     1159            if (argc <= i + 1)
     1160            {
     1161                return errorArgument("Missing argument to '%s'", argv[i]);
     1162            }
     1163            i++;
     1164            dst = argv[i];
     1165        }
     1166        else
     1167        {
     1168            return errorSyntax(USAGE_RENAMEVMDK, "Invalid parameter '%s'", Utf8Str(argv[i]).raw());
     1169        }
     1170    }
     1171
     1172    if (src.isEmpty())
     1173        return errorSyntax(USAGE_RENAMEVMDK, "Mandatory parameter -from missing");
     1174    if (dst.isEmpty())
     1175        return errorSyntax(USAGE_RENAMEVMDK, "Mandatory parameter -to missing");
     1176
     1177    PVBOXHDD pDisk = NULL;
     1178
     1179    int vrc = VDCreate(handleVDError, NULL, &pDisk);
     1180    if (VBOX_FAILURE(vrc))
     1181    {
     1182        RTPrintf("Error while creating the virtual disk container: %Vrc\n", vrc);
     1183        return vrc;
     1184    }
     1185    else
     1186    {
     1187        vrc = VDOpen(pDisk, "VMDK", Utf8Str(src).raw(), VD_OPEN_FLAGS_NORMAL);
     1188        if (VBOX_FAILURE(vrc))
     1189        {
     1190            RTPrintf("Error while opening the source image: %Vrc\n", vrc);
     1191        }
     1192        else
     1193        {
     1194            vrc = VDCopy(pDisk, 0, pDisk, "VMDK", Utf8Str(dst).raw(), true, 0, NULL, NULL);
     1195            if (VBOX_FAILURE(vrc))
     1196            {
     1197                RTPrintf("Error while renaming the image: %Vrc\n", vrc);
     1198            }
     1199        }
     1200    }
     1201    VDCloseAll(pDisk);
     1202    return vrc;
     1203}
     1204#endif
     1205
    11331206/**
    11341207 * Unloads the neccessary driver.
     
    11911264    if (!strcmp(pszCmd, "createrawvmdk"))
    11921265        return CmdCreateRawVMDK(argc - 1, &argv[1], aVirtualBox, aSession);
     1266#if 0
     1267    if (!strcmp(pszCmd, "renamevmdk"))
     1268        return CmdRenameVMDK(argc - 1, &argv[1], aVirtualBox, aSession);
     1269#endif
    11931270
    11941271    if (!strcmp(pszCmd, "modinstall"))
  • trunk/src/VBox/Frontends/VBoxManage/VBoxManage.h

    r8155 r9047  
    7474#define USAGE_MODINSTALL            RT_BIT_64(37)
    7575#define USAGE_MODUNINSTALL          RT_BIT_64(38)
     76#ifndef VBOX_OSE
     77# define USAGE_RENAMEVMDK           RT_BIT_64(39)
     78#endif /* !VBOX_OSE */
    7679#define USAGE_ALL                   (~(uint64_t)0)
    7780/** @} */
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