- Timestamp:
- May 22, 2008 5:35:37 AM (17 years ago)
- Location:
- trunk/src/VBox
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Storage/VmdkHDDCore.cpp
r8509 r9047 3645 3645 } 3646 3646 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 */ 3653 static 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 3647 3663 /** @copydoc VBOXHDDBACKEND::pfnRename */ 3648 3664 static int vmdkRename(void *pBackendData, const char *pszFilename) 3649 3665 { 3650 3666 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 3877 out: 3653 3878 LogFlowFunc(("returns %Vrc\n", rc)); 3654 3879 return rc; -
trunk/src/VBox/Frontends/VBoxManage/VBoxInternalManage.cpp
r8982 r9047 166 166 "\n" 167 167 : "", 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 168 175 #ifdef RT_OS_WINDOWS 169 176 (u64Cmd & USAGE_MODINSTALL) ? … … 1131 1138 } 1132 1139 1140 #if 0 1141 HRESULT 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 1133 1206 /** 1134 1207 * Unloads the neccessary driver. … … 1191 1264 if (!strcmp(pszCmd, "createrawvmdk")) 1192 1265 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 1193 1270 1194 1271 if (!strcmp(pszCmd, "modinstall")) -
trunk/src/VBox/Frontends/VBoxManage/VBoxManage.h
r8155 r9047 74 74 #define USAGE_MODINSTALL RT_BIT_64(37) 75 75 #define USAGE_MODUNINSTALL RT_BIT_64(38) 76 #ifndef VBOX_OSE 77 # define USAGE_RENAMEVMDK RT_BIT_64(39) 78 #endif /* !VBOX_OSE */ 76 79 #define USAGE_ALL (~(uint64_t)0) 77 80 /** @} */
Note:
See TracChangeset
for help on using the changeset viewer.