Changeset 49795 in vbox for trunk/src/VBox/Main/src-server/SnapshotImpl.cpp
- Timestamp:
- Dec 5, 2013 6:53:18 PM (11 years ago)
- svn:sync-xref-src-repo-rev:
- 91125
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Main/src-server/SnapshotImpl.cpp
r49687 r49795 1048 1048 if (pMedium) // can be NULL for non-harddisk 1049 1049 { 1050 rc = pMedium-> addBackReference(mData->mUuid, mSnapshotId);1050 rc = pMedium->i_addBackReference(mData->mUuid, mSnapshotId); 1051 1051 AssertComRC(rc); 1052 1052 } … … 1782 1782 ++ulTotalWeight; // assume one MB weight for each differencing hard disk to manage 1783 1783 Assert(pAttach->getMedium()); 1784 LogFlowThisFunc(("op %d: considering hard disk attachment %s\n", ulOpCount, pAttach->getMedium()-> getName().c_str()));1784 LogFlowThisFunc(("op %d: considering hard disk attachment %s\n", ulOpCount, pAttach->getMedium()->i_getName().c_str())); 1785 1785 } 1786 1786 } … … 1970 1970 if ( !pMedium.isNull() 1971 1971 && pAttach->getType() == DeviceType_HardDisk 1972 && !pMedium-> getParent().isNull()1973 && pMedium-> getChildren().size() == 01972 && !pMedium->i_getParent().isNull() 1973 && pMedium->i_getChildren().size() == 0 1974 1974 ) 1975 1975 { 1976 LogFlowThisFunc(("Picked differencing image '%s' for deletion\n", pMedium-> getName().c_str()));1976 LogFlowThisFunc(("Picked differencing image '%s' for deletion\n", pMedium->i_getName().c_str())); 1977 1977 1978 1978 llDiffAttachmentsToDelete.push_back(pAttach); … … 2012 2012 AutoWriteLock mlock(pMedium COMMA_LOCKVAL_SRC_POS); 2013 2013 2014 LogFlowThisFunc(("Detaching old current state in differencing image '%s'\n", pMedium-> getName().c_str()));2014 LogFlowThisFunc(("Detaching old current state in differencing image '%s'\n", pMedium->i_getName().c_str())); 2015 2015 2016 2016 // Normally we "detach" the medium by removing the attachment object … … 2028 2028 mMediaData.backedUpData()->mAttachments.remove(pAttach); 2029 2029 // then clean up backrefs 2030 pMedium-> removeBackReference(mData->mUuid);2030 pMedium->i_removeBackReference(mData->mUuid); 2031 2031 2032 2032 llDiffsToDelete.push_back(pMedium); … … 2054 2054 { 2055 2055 ComObjPtr<Medium> &pMedium = *it; 2056 LogFlowThisFunc(("Deleting old current state in differencing image '%s'\n", pMedium-> getName().c_str()));2057 2058 HRESULT rc2 = pMedium-> deleteStorage(NULL /* aProgress */,2059 true /* aWait */);2056 LogFlowThisFunc(("Deleting old current state in differencing image '%s'\n", pMedium->i_getName().c_str())); 2057 2058 HRESULT rc2 = pMedium->i_deleteStorage(NULL /* aProgress */, 2059 true /* aWait */); 2060 2060 // ignore errors here because we cannot roll back after saveSettings() above 2061 2061 if (SUCCEEDED(rc2)) … … 2169 2169 mUserData->s.strName.c_str(), 2170 2170 childrenCount); 2171 2171 2172 if (pSnapshot == mData->mCurrentSnapshot && childrenCount >= 1) 2172 2173 return setError(VBOX_E_INVALID_OBJECT_STATE, … … 2175 2176 mUserData->s.strName.c_str()); 2176 2177 2178 2177 2179 /* If the snapshot being deleted is the current one, ensure current 2178 2180 * settings are committed and saved. … … 2218 2220 AutoReadLock mlock(pHD COMMA_LOCKVAL_SRC_POS); 2219 2221 2220 MediumType_T type = pHD-> getType();2222 MediumType_T type = pHD->i_getType(); 2221 2223 // writethrough and shareable images are unaffected by snapshots, 2222 2224 // so do nothing for them … … 2227 2229 // normal or immutable media need attention 2228 2230 ++ulOpCount; 2229 ulTotalWeight += (ULONG)(pHD-> getSize() / _1M);2231 ulTotalWeight += (ULONG)(pHD->i_getSize() / _1M); 2230 2232 } 2231 LogFlowThisFunc(("op %d: considering hard disk attachment %s\n", ulOpCount, pHD-> getName().c_str()));2233 LogFlowThisFunc(("op %d: considering hard disk attachment %s\n", ulOpCount, pHD->i_getName().c_str())); 2232 2234 } 2233 2235 } … … 2445 2447 // unaffected by snapshots, skip them 2446 2448 AutoReadLock medlock(pHD COMMA_LOCKVAL_SRC_POS); 2447 MediumType_T type = pHD-> getType();2449 MediumType_T type = pHD->i_getType(); 2448 2450 if ( type == MediumType_Writethrough 2449 2451 || type == MediumType_Shareable … … 2453 2455 2454 2456 #ifdef DEBUG 2455 pHD-> dumpBackRefs();2457 pHD->i_dumpBackRefs(); 2456 2458 #endif 2457 2459 … … 2525 2527 // base disk. Here we need then to update the attachment that 2526 2528 // refers to the child and have it point to the parent instead 2527 Assert(pHD-> getChildren().size() == 1);2528 2529 ComObjPtr<Medium> pReplaceHD = pHD-> getChildren().front();2529 Assert(pHD->i_getChildren().size() == 1); 2530 2531 ComObjPtr<Medium> pReplaceHD = pHD->i_getChildren().front(); 2530 2532 2531 2533 ComAssertThrow(pReplaceHD == pSource, E_FAIL); … … 2535 2537 Guid replaceSnapshotId; 2536 2538 2537 const Guid *pReplaceMachineId = pSource-> getFirstMachineBackrefId();2539 const Guid *pReplaceMachineId = pSource->i_getFirstMachineBackrefId(); 2538 2540 // minimal sanity checking 2539 2541 Assert(!pReplaceMachineId || *pReplaceMachineId == mData->mUuid); … … 2541 2543 replaceMachineId = *pReplaceMachineId; 2542 2544 2543 const Guid *pSnapshotId = pSource-> getFirstMachineBackrefSnapshotId();2545 const Guid *pSnapshotId = pSource->i_getFirstMachineBackrefSnapshotId(); 2544 2546 if (pSnapshotId) 2545 2547 replaceSnapshotId = *pSnapshotId; … … 2551 2553 // with the snapshot until the merge was successful. 2552 2554 HRESULT rc2 = S_OK; 2553 rc2 = pSource-> removeBackReference(replaceMachineId, replaceSnapshotId);2555 rc2 = pSource->i_removeBackReference(replaceMachineId, replaceSnapshotId); 2554 2556 AssertComRC(rc2); 2555 2557 … … 2608 2610 throw rc; 2609 2611 2610 if(pTarget_local->i sMediumFormatFile())2612 if(pTarget_local->i_isMediumFormatFile()) 2611 2613 { 2612 int vrc = RTFsQuerySerial(pTarget_local-> getLocationFull().c_str(), &pu32Serial);2614 int vrc = RTFsQuerySerial(pTarget_local->i_getLocationFull().c_str(), &pu32Serial); 2613 2615 if (RT_FAILURE(vrc)) 2614 2616 { 2615 2617 rc = setError(E_FAIL, 2616 2618 tr(" Unable to merge storage '%s'. Can't get storage UID "), 2617 pTarget_local-> getLocationFull().c_str());2619 pTarget_local->i_getLocationFull().c_str()); 2618 2620 throw rc; 2619 2621 } … … 2624 2626 neededStorageFreeSpace.insert(std::make_pair(pu32Serial,diskSize)); 2625 2627 /* linking storage UID with snapshot path, it is a helper container (just for easy finding needed path) */ 2626 serialMapToStoragePath.insert(std::make_pair(pu32Serial,pTarget_local-> getLocationFull().c_str()));2628 serialMapToStoragePath.insert(std::make_pair(pu32Serial,pTarget_local->i_getLocationFull().c_str())); 2627 2629 } 2628 2630 … … 2729 2731 { 2730 2732 AutoReadLock alock(pMedium COMMA_LOCKVAL_SRC_POS); 2731 ulWeight = (ULONG)(pMedium-> getSize() / _1M);2733 ulWeight = (ULONG)(pMedium->i_getSize() / _1M); 2732 2734 } 2733 2735 2734 2736 aTask.pProgress->SetNextOperation(BstrFmt(tr("Merging differencing image '%s'"), 2735 pMedium-> getName().c_str()).raw(),2737 pMedium->i_getName().c_str()).raw(), 2736 2738 ulWeight); 2737 2739 … … 2745 2747 2746 2748 Assert( !it->mfMergeForward 2747 || pMedium-> getChildren().size() == 0);2749 || pMedium->i_getChildren().size() == 0); 2748 2750 2749 2751 /* Delete the differencing hard disk (has no children). Two … … 2752 2754 * In both cases leave the image in place. If it's the first 2753 2755 * exception the user can delete it later if he wants. */ 2754 if (!pMedium-> getParent().isNull())2756 if (!pMedium->i_getParent().isNull()) 2755 2757 { 2756 Assert(pMedium-> getState() == MediumState_Deleting);2758 Assert(pMedium->i_getState() == MediumState_Deleting); 2757 2759 /* No need to hold the lock any longer. */ 2758 2760 mLock.release(); 2759 rc = pMedium-> deleteStorage(&aTask.pProgress,2760 true /* aWait */);2761 rc = pMedium->i_deleteStorage(&aTask.pProgress, 2762 true /* aWait */); 2761 2763 if (FAILED(rc)) 2762 2764 throw rc; … … 2791 2793 { 2792 2794 // normal medium merge, in the direction decided earlier 2793 rc = it->mpSource-> mergeTo(it->mpTarget,2794 it->mfMergeForward,2795 it->mpParentForTarget,2796 it->mpChildrenToReparent,2797 it->mpMediumLockList,2798 &aTask.pProgress,2799 true /* aWait */);2795 rc = it->mpSource->i_mergeTo(it->mpTarget, 2796 it->mfMergeForward, 2797 it->mpParentForTarget, 2798 it->mpChildrenToReparent, 2799 it->mpMediumLockList, 2800 &aTask.pProgress, 2801 true /* aWait */); 2800 2802 } 2801 2803 … … 2809 2811 { 2810 2812 AutoReadLock mlock(it->mpSource COMMA_LOCKVAL_SRC_POS); 2811 if (!it->mpSource->i sMediumFormatFile())2813 if (!it->mpSource->i_isMediumFormatFile()) 2812 2814 // Diff medium not backed by a file - cannot get status so 2813 2815 // be pessimistic. 2814 2816 throw rc; 2815 const Utf8Str &loc = it->mpSource-> getLocationFull();2817 const Utf8Str &loc = it->mpSource->i_getLocationFull(); 2816 2818 // Source medium is still there, so merge failed early. 2817 2819 if (RTFileExists(loc.c_str())) … … 2848 2850 pAtt = findAttachment(pSnapMachine->mMediaData->mAttachments, 2849 2851 it->mpTarget); 2850 it->mpTarget-> removeBackReference(machineId, snapshotId);2852 it->mpTarget->i_removeBackReference(machineId, snapshotId); 2851 2853 } 2852 2854 else … … 2872 2874 AutoWriteLock attLock(pAtt COMMA_LOCKVAL_SRC_POS); 2873 2875 pAtt->updateMedium(it->mpTarget); 2874 it->mpTarget-> addBackReference(pMachine->mData->mUuid, childSnapshotId);2876 it->mpTarget->i_addBackReference(pMachine->mData->mUuid, childSnapshotId); 2875 2877 } 2876 2878 else … … 2882 2884 // Needs a bit of special treatment due to this difference. 2883 2885 if (it->mfNeedsOnlineMerge) 2884 it->mpTarget-> addBackReference(pMachine->mData->mUuid, childSnapshotId);2886 it->mpTarget->i_addBackReference(pMachine->mData->mUuid, childSnapshotId); 2885 2887 } 2886 2888 } … … 3021 3023 3022 3024 // Medium must not be writethrough/shareable/readonly at this point 3023 MediumType_T type = aHD-> getType();3025 MediumType_T type = aHD->i_getType(); 3024 3026 AssertReturn( type != MediumType_Writethrough 3025 3027 && type != MediumType_Shareable … … 3030 3032 fNeedsOnlineMerge = false; 3031 3033 3032 if (aHD-> getChildren().size() == 0)3034 if (aHD->i_getChildren().size() == 0) 3033 3035 { 3034 3036 /* This technically is no merge, set those values nevertheless. … … 3038 3040 3039 3041 /* special treatment of the last hard disk in the chain: */ 3040 if (aHD-> getParent().isNull())3042 if (aHD->i_getParent().isNull()) 3041 3043 { 3042 3044 /* lock only, to prevent any usage until the snapshot deletion … … 3048 3050 /* the differencing hard disk w/o children will be deleted, protect it 3049 3051 * from attaching to other VMs (this is why Deleting) */ 3050 return aHD-> markForDeletion();3052 return aHD->i_markForDeletion(); 3051 3053 } 3052 3054 3053 3055 /* not going multi-merge as it's too expensive */ 3054 if (aHD-> getChildren().size() > 1)3056 if (aHD->i_getChildren().size() > 1) 3055 3057 return setError(E_FAIL, 3056 3058 tr("Hard disk '%s' has more than one child hard disk (%d)"), 3057 aHD-> getLocationFull().c_str(),3058 aHD-> getChildren().size());3059 3060 ComObjPtr<Medium> pChild = aHD-> getChildren().front();3059 aHD->i_getLocationFull().c_str(), 3060 aHD->i_getChildren().size()); 3061 3062 ComObjPtr<Medium> pChild = aHD->i_getChildren().front(); 3061 3063 3062 3064 AutoWriteLock childLock(pChild COMMA_LOCKVAL_SRC_POS); 3063 3065 3064 3066 /* the rest is a normal merge setup */ 3065 if (aHD-> getParent().isNull())3067 if (aHD->i_getParent().isNull()) 3066 3068 { 3067 3069 /* base hard disk, backward merge */ 3068 const Guid *pMachineId1 = pChild-> getFirstMachineBackrefId();3069 const Guid *pMachineId2 = aHD-> getFirstMachineBackrefId();3070 const Guid *pMachineId1 = pChild->i_getFirstMachineBackrefId(); 3071 const Guid *pMachineId2 = aHD->i_getFirstMachineBackrefId(); 3070 3072 if (pMachineId1 && pMachineId2 && *pMachineId1 != *pMachineId2) 3071 3073 { … … 3087 3089 childLock.release(); 3088 3090 alock.release(); 3089 HRESULT rc = aHD-> queryPreferredMergeDirection(pChild, fMergeForward);3091 HRESULT rc = aHD->i_queryPreferredMergeDirection(pChild, fMergeForward); 3090 3092 alock.acquire(); 3091 3093 childLock.acquire(); … … 3111 3113 childLock.release(); 3112 3114 alock.release(); 3113 rc = aSource-> prepareMergeTo(aTarget, &aMachineId, &aSnapshotId,3115 rc = aSource->i_prepareMergeTo(aTarget, &aMachineId, &aSnapshotId, 3114 3116 !fOnlineMergePossible /* fLockMedia */, 3115 3117 aMergeForward, aParentForTarget, … … 3221 3223 if (FAILED(rc)) 3222 3224 { 3223 aSource-> cancelMergeTo(aChildrenToReparent, aMediumLockList);3225 aSource->i_cancelMergeTo(aChildrenToReparent, aMediumLockList); 3224 3226 rc = setError(rc, 3225 3227 tr("Cannot lock hard disk '%s' for a live merge"), 3226 aHD-> getLocationFull().c_str());3228 aHD->i_getLocationFull().c_str()); 3227 3229 } 3228 3230 else … … 3235 3237 else 3236 3238 { 3237 aSource-> cancelMergeTo(aChildrenToReparent, aMediumLockList);3239 aSource->i_cancelMergeTo(aChildrenToReparent, aMediumLockList); 3238 3240 rc = setError(rc, 3239 3241 tr("Failed to construct lock list for a live merge of hard disk '%s'"), 3240 aHD-> getLocationFull().c_str());3242 aHD->i_getLocationFull().c_str()); 3241 3243 } 3242 3244 … … 3261 3263 // blindly apply this, only needed for medium objects which 3262 3264 // would be deleted as part of the merge 3263 pMedium-> unmarkLockedForDeletion();3265 pMedium->i_unmarkLockedForDeletion(); 3264 3266 } 3265 3267 } … … 3268 3270 else 3269 3271 { 3270 aSource-> cancelMergeTo(aChildrenToReparent, aMediumLockList);3272 aSource->i_cancelMergeTo(aChildrenToReparent, aMediumLockList); 3271 3273 rc = setError(rc, 3272 3274 tr("Cannot lock hard disk '%s' for an offline merge"), 3273 aHD-> getLocationFull().c_str());3275 aHD->i_getLocationFull().c_str()); 3274 3276 } 3275 3277 } … … 3307 3309 AutoMultiWriteLock2 mLock(&mParent->getMediaTreeLockHandle(), aHD->lockHandle() COMMA_LOCKVAL_SRC_POS); 3308 3310 3309 Assert(aHD-> getChildren().size() == 0);3310 3311 if (aHD-> getParent().isNull())3311 Assert(aHD->i_getChildren().size() == 0); 3312 3313 if (aHD->i_getParent().isNull()) 3312 3314 { 3313 3315 Assert(!aHDLockToken.isNull()); … … 3320 3322 else 3321 3323 { 3322 HRESULT rc = aHD-> unmarkForDeletion();3324 HRESULT rc = aHD->i_unmarkForDeletion(); 3323 3325 AssertComRC(rc); 3324 3326 } … … 3330 3332 // Online merge uses the medium lock list of the VM, so give 3331 3333 // an empty list to cancelMergeTo so that it works as designed. 3332 aSource-> cancelMergeTo(aChildrenToReparent, new MediumLockList());3334 aSource->i_cancelMergeTo(aChildrenToReparent, new MediumLockList()); 3333 3335 3334 3336 // clean up the VM medium lock list ourselves … … 3345 3347 ComObjPtr<Medium> pMedium = it->GetMedium(); 3346 3348 AutoWriteLock mediumLock(pMedium COMMA_LOCKVAL_SRC_POS); 3347 if (pMedium-> getState() == MediumState_Deleting)3348 pMedium-> unmarkForDeletion();3349 if (pMedium->i_getState() == MediumState_Deleting) 3350 pMedium->i_unmarkForDeletion(); 3349 3351 else 3350 3352 { 3351 3353 // blindly apply this, only needed for medium objects which 3352 3354 // would be deleted as part of the merge 3353 pMedium-> unmarkLockedForDeletion();3355 pMedium->i_unmarkLockedForDeletion(); 3354 3356 } 3355 3357 mediumLock.release(); … … 3360 3362 else 3361 3363 { 3362 aSource-> cancelMergeTo(aChildrenToReparent, aMediumLockList);3364 aSource->i_cancelMergeTo(aChildrenToReparent, aMediumLockList); 3363 3365 } 3364 3366 } … … 3367 3369 { 3368 3370 // reattach the source media to the snapshot 3369 HRESULT rc = aSource-> addBackReference(aMachineId, aSnapshotId);3371 HRESULT rc = aSource->i_addBackReference(aMachineId, aSnapshotId); 3370 3372 AssertComRC(rc); 3371 3373 } … … 3512 3514 // then, reparent it and disconnect the deleted branch at 3513 3515 // both ends (chain->parent() is source's parent) 3514 pDeleteRec->mpTarget-> deparent();3515 pDeleteRec->mpTarget-> setParent(pDeleteRec->mpParentForTarget);3516 pDeleteRec->mpTarget->i_deparent(); 3517 pDeleteRec->mpTarget->i_setParent(pDeleteRec->mpParentForTarget); 3516 3518 if (pDeleteRec->mpParentForTarget) 3517 pDeleteRec->mpSource-> deparent();3519 pDeleteRec->mpSource->i_deparent(); 3518 3520 3519 3521 // then, register again … … 3523 3525 else 3524 3526 { 3525 Assert(pDeleteRec->mpTarget-> getChildren().size() == 1);3526 targetChild = pDeleteRec->mpTarget-> getChildren().front();3527 Assert(pDeleteRec->mpTarget->i_getChildren().size() == 1); 3528 targetChild = pDeleteRec->mpTarget->i_getChildren().front(); 3527 3529 3528 3530 // disconnect the deleted branch at the elder end 3529 targetChild-> deparent();3531 targetChild->i_deparent(); 3530 3532 3531 3533 // Update parent UUIDs of the source's children, reparent them and … … 3540 3542 // need manual fixing via VBoxManage to adjust the parent UUID. 3541 3543 treeLock.release(); 3542 pDeleteRec->mpTarget-> fixParentUuidOfChildren(pDeleteRec->mpChildrenToReparent);3544 pDeleteRec->mpTarget->i_fixParentUuidOfChildren(pDeleteRec->mpChildrenToReparent); 3543 3545 // The childen are still write locked, unlock them now and don't 3544 3546 // rely on the destructor doing it very late. … … 3558 3560 AutoWriteLock childLock(pMedium COMMA_LOCKVAL_SRC_POS); 3559 3561 3560 pMedium-> deparent(); // removes pMedium from source3561 pMedium-> setParent(pDeleteRec->mpTarget);3562 pMedium->i_deparent(); // removes pMedium from source 3563 pMedium->i_setParent(pDeleteRec->mpTarget); 3562 3564 } 3563 3565 } … … 3584 3586 /* The target and all images not merged (readonly) are skipped */ 3585 3587 if ( pMedium == pDeleteRec->mpTarget 3586 || pMedium-> getState() == MediumState_LockedRead)3588 || pMedium->i_getState() == MediumState_LockedRead) 3587 3589 { 3588 3590 ++it; … … 3607 3609 if (pMedium == pDeleteRec->mpSource) 3608 3610 { 3609 Assert(pDeleteRec->mpSource-> getChildren().size() == 0);3610 Assert(pDeleteRec->mpSource-> getFirstMachineBackrefId() == NULL);3611 Assert(pDeleteRec->mpSource->i_getChildren().size() == 0); 3612 Assert(pDeleteRec->mpSource->i_getFirstMachineBackrefId() == NULL); 3611 3613 } 3612 3614
Note:
See TracChangeset
for help on using the changeset viewer.