Changeset 24433 in vbox
- Timestamp:
- Nov 6, 2009 11:58:54 AM (15 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Main/SnapshotImpl.cpp
r24354 r24433 2101 2101 LogFlowThisFunc(("1: Checking hard disk merge prerequisites...\n")); 2102 2102 2103 // go thru the attachments of the snapshot machine 2104 // (the media in here point to the disk states _before_ the snapshot 2105 // was taken, i.e. the state we're restoring to; for each such 2106 // medium, we will need to merge it with its one and only child (the 2107 // diff image holding the changes written after the snapshot was taken) 2103 2108 for (MediaData::AttachmentList::iterator it = pSnapMachine->mMediaData->mAttachments.begin(); 2104 2109 it != pSnapMachine->mMediaData->mAttachments.end(); … … 2111 2116 Assert(pAttach->medium()); 2112 2117 ComObjPtr<Medium> pHD = pAttach->medium(); 2113 // do not lock, prepareDiscared() has a write lock which will hang otherwise2118 // do not lock, prepareDiscared() has a write lock which will hang otherwise 2114 2119 2115 2120 Medium::MergeChain *chain = NULL; 2116 2121 2117 /* needs to be discarded (merged with the child if any), check 2118 * prerequisites */ 2122 // needs to be discarded (merged with the child if any), check prerequisites 2119 2123 rc = pHD->prepareDiscard(chain); 2120 2124 CheckComRCThrowRC(rc); 2121 2125 2122 if (pHD->parent().isNull() && chain != NULL) 2126 // for simplicity, we merge pHd onto its child (forward merge), not the 2127 // other way round, because that saves us from updating the attachments 2128 // for the machine that follows the snapshot (next snapshot or real machine), 2129 // unless it's a base image: 2130 2131 if ( pHD->parent().isNull() 2132 && chain != NULL 2133 ) 2123 2134 { 2124 /* it's a base hard disk so it will be a backward merge of its 2125 * only child to it (prepareDiscard() does necessary checks). We 2126 * need then to update the attachment that refers to the child 2127 * to refer to the parent instead. Don't forget to detach the 2128 * child (otherwise mergeTo() called by discard() will assert 2129 * because it will be going to delete the child) */ 2135 // parent is null -> this disk is a base hard disk: we will 2136 // then do a backward merge, i.e. merge its only child onto 2137 // the base disk; prepareDiscard() does necessary checks. 2138 // So here we need then to update the attachment that refers 2139 // to the child and have it point to the parent instead 2130 2140 2131 2141 /* The below assert would be nice but I don't want to move 2132 * Medium::MergeChain to the header just for that 2133 * Assert (!chain->isForward()); */ 2134 2142 * Medium::MergeChain to the header just for that 2143 * Assert (!chain->isForward()); */ 2144 2145 // prepareDiscard() should have raised an error already 2146 // if there was more than one child 2135 2147 Assert(pHD->children().size() == 1); 2136 2148 2137 ComObjPtr<Medium> replaceHd = pHD->children().front(); 2138 2139 const Guid *pReplaceMachineId = replaceHd->getFirstMachineBackrefId(); 2140 Assert(pReplaceMachineId && *pReplaceMachineId == mData->mUuid); 2149 ComObjPtr<Medium> pReplaceHD = pHD->children().front(); 2150 2151 const Guid *pReplaceMachineId = pReplaceHD->getFirstMachineBackrefId(); 2152 Assert(pReplaceMachineId); 2153 Assert(*pReplaceMachineId == mData->mUuid); 2141 2154 2142 2155 Guid snapshotId; 2143 const Guid *pSnapshotId = replaceHd->getFirstMachineBackrefSnapshotId();2156 const Guid *pSnapshotId = pReplaceHD->getFirstMachineBackrefSnapshotId(); 2144 2157 if (pSnapshotId) 2145 2158 snapshotId = *pSnapshotId; … … 2147 2160 HRESULT rc2 = S_OK; 2148 2161 2149 /* adjust back references */ 2150 rc2 = replaceHd->detachFrom(mData->mUuid, snapshotId); 2162 attachLock.unlock(); 2163 2164 // First we must detach the child (otherwise mergeTo() called 2165 // by discard() will assert because it will be going to delete 2166 // the child), so adjust the backreferences: 2167 // 1) detach the first child hard disk 2168 rc2 = pReplaceHD->detachFrom(mData->mUuid, snapshotId); 2151 2169 AssertComRC(rc2); 2152 2170 // 2) attach to machine and snapshot 2153 2171 rc2 = pHD->attachTo(mData->mUuid, snapshotId); 2154 2172 AssertComRC(rc2); … … 2158 2176 { 2159 2177 /* in current state */ 2160 AssertBreak(pAttach = findAttachment(mMediaData->mAttachments, replaceHd));2178 AssertBreak(pAttach = findAttachment(mMediaData->mAttachments, pReplaceHD)); 2161 2179 } 2162 2180 else … … 2169 2187 /* don't lock the snapshot; cannot be modified outside */ 2170 2188 MediaData::AttachmentList &snapAtts = snapshot->getSnapshotMachine()->mMediaData->mAttachments; 2171 AssertBreak(pAttach = findAttachment(snapAtts, replaceHd));2189 AssertBreak(pAttach = findAttachment(snapAtts, pReplaceHD)); 2172 2190 } 2173 2191 2174 attachLock.unlock();2175 2192 AutoWriteLock attLock(pAttach); 2176 2193 pAttach->updateMedium(pHD, false /* aImplicit */); … … 2178 2195 toDiscard.push_back(MediumDiscardRec(pHD, 2179 2196 chain, 2180 replaceHd,2197 pReplaceHD, 2181 2198 pAttach, 2182 2199 snapshotId));
Note:
See TracChangeset
for help on using the changeset viewer.