Changeset 27392 in vbox for trunk/src/VBox/Main
- Timestamp:
- Mar 16, 2010 11:02:33 AM (15 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Main/MediumImpl.cpp
r27279 r27392 404 404 AutoWriteLock alock(*it COMMA_LOCKVAL_SRC_POS); 405 405 Assert((*it)->m->state == MediumState_LockedWrite || 406 (*it)->m->state == MediumState_LockedRead || 406 407 (*it)->m->state == MediumState_Deleting); 407 408 if ((*it)->m->state == MediumState_LockedWrite) 408 409 (*it)->UnlockWrite(NULL); 410 else if ((*it)->m->state == MediumState_LockedRead) 411 (*it)->UnlockRead(NULL); 409 412 else 410 413 (*it)->m->state = MediumState_Created; … … 461 464 462 465 mParent = aMedium->m->pParent; 466 } 467 468 /* Include all images from base to source. */ 469 ComObjPtr<Medium> pParent = aMedium->m->pParent; 470 while (!pParent.isNull()) 471 { 472 rc = pParent->addCaller(); 473 if (FAILED(rc)) return rc; 474 475 rc = pParent->LockRead(NULL); 476 if (FAILED(rc)) return rc; 477 478 push_front(pParent); 479 pParent = pParent->m->pParent; 463 480 } 464 481 } … … 485 502 } 486 503 504 mSource = aMedium; 505 487 506 return S_OK; 488 507 } … … 515 534 push_front(aMedium); 516 535 536 mTarget = aMedium; 537 517 538 return S_OK; 518 539 } … … 548 569 } 549 570 571 int targetIdx() 572 { 573 Assert(!mTarget.isNull()); 574 int idx = 0; 575 576 for (MediaList::const_iterator it = begin(); it != end(); ++it) 577 { 578 ComObjPtr<Medium> pMedium = *it; 579 580 /* Do we have the target? */ 581 if (pMedium == mTarget) 582 break; 583 584 idx++; 585 } 586 587 return idx; 588 } 589 590 int sourceIdx() 591 { 592 Assert(!mSource.isNull()); 593 int idx = 0; 594 595 for (MediaList::const_iterator it = begin(); it != end(); ++it) 596 { 597 ComObjPtr<Medium> pMedium = *it; 598 599 /* Do we have the source? */ 600 if (pMedium == mSource) 601 break; 602 603 idx++; 604 } 605 606 return idx; 607 } 608 550 609 bool isForward() const { return mForward; } 551 610 Medium *parent() const { return mParent; } … … 553 612 554 613 Medium *source() const 555 { AssertReturn(size() > 0, NULL); return m Forward ? front() : back(); }614 { AssertReturn(size() > 0, NULL); return mSource; } 556 615 557 616 Medium *target() const 558 { AssertReturn(size() > 0, NULL); return m Forward ? back() : front(); }617 { AssertReturn(size() > 0, NULL); return mTarget; } 559 618 560 619 protected: … … 622 681 /** Children of the source when backward merge (if any) */ 623 682 MediaList mChildren; 683 /** Source image */ 684 ComObjPtr <Medium> mSource; 685 /** Target image */ 686 ComObjPtr <Medium> mTarget; 624 687 }; 625 688 … … 5235 5298 ++it) 5236 5299 { 5237 /* complex sanity (sane complexity) */ 5238 Assert((chain->isForward() && 5239 ((*it != chain->back() && 5240 (*it)->m->state == MediumState_Deleting) || 5241 (*it == chain->back() && 5242 (*it)->m->state == MediumState_LockedWrite))) || 5243 (!chain->isForward() && 5244 ((*it != chain->front() && 5245 (*it)->m->state == MediumState_Deleting) || 5246 (*it == chain->front() && 5247 (*it)->m->state == MediumState_LockedWrite)))); 5248 5249 Assert(*it == chain->target() || 5250 (*it)->m->backRefs.size() == 0); 5251 5252 /* open the first image with VDOPEN_FLAGS_INFO because 5253 * it's not necessarily the base one */ 5300 /* 5301 * complex sanity (sane complexity) 5302 * 5303 * The current image must be in the Deleting (image is merged) 5304 * or LockedRead (parent image) state if it is not the target. 5305 * If it is the target it must be in the LockedWrite state. 5306 */ 5307 Assert( ( *it != chain->target() 5308 && ( (*it)->m->state == MediumState_Deleting 5309 || (*it)->m->state == MediumState_LockedRead)) 5310 || ( *it == chain->target() 5311 && (*it)->m->state == MediumState_LockedWrite)); 5312 5313 /* 5314 * Image must be the target, in the LockedRead state 5315 * or Deleting state where it is not allowed to be attached 5316 * to a virtual machine. 5317 */ 5318 Assert( *it == chain->target() 5319 || (*it)->m->state == MediumState_LockedRead 5320 || ( (*it)->m->backRefs.size() == 0 5321 && (*it)->m->state == MediumState_Deleting) 5322 ); 5323 5324 unsigned uOpenFlags = 0; 5325 5326 if ( (*it)->m->state == MediumState_LockedRead 5327 || (*it)->m->state == MediumState_Deleting) 5328 uOpenFlags = VD_OPEN_FLAGS_READONLY; 5329 5330 /* Open the image */ 5254 5331 vrc = VDOpen(hdd, 5255 5332 (*it)->m->strFormat.c_str(), 5256 5333 (*it)->m->strLocationFull.c_str(), 5257 it == chain->begin() ? VD_OPEN_FLAGS_INFO : 0,5334 uOpenFlags, 5258 5335 (*it)->m->vdDiskIfaces); 5259 5336 if (RT_FAILURE(vrc)) … … 5261 5338 } 5262 5339 5263 unsigned start = chain->isForward() ? 5264 0 : (unsigned)chain->size() - 1; 5265 unsigned end = chain->isForward() ? 5266 (unsigned)chain->size() - 1 : 0; 5267 5268 vrc = VDMerge(hdd, start, end, vdOperationIfaces); 5340 vrc = VDMerge(hdd, chain->sourceIdx(), chain->targetIdx(), vdOperationIfaces); 5269 5341 if (RT_FAILURE(vrc)) 5270 5342 throw vrc; 5271 5343 5272 5344 /* update parent UUIDs */ 5273 /// @todo VDMerge should be taught to do so, includingthe5345 /// @todo VDMerge should handle the 5274 5346 /// multiple children case 5275 if (chain->isForward()) 5276 { 5277 /* target's UUID needs to be updated (note that target 5278 * is the only image in the container on success) */ 5279 vrc = VDSetParentUuid(hdd, 0, chain->parent()->m->id); 5280 if (RT_FAILURE(vrc)) 5281 throw vrc; 5282 } 5283 else 5347 if (!chain->isForward()) 5284 5348 { 5285 5349 /* we need to update UUIDs of all source's children … … 5396 5460 ) 5397 5461 { 5398 if (*it == chain->target()) 5462 /* The target and all images not merged (readonly) are skipped */ 5463 if ( *it == chain->target() 5464 || (*it)->m->state == MediumState_LockedRead) 5399 5465 { 5400 5466 ++it;
Note:
See TracChangeset
for help on using the changeset viewer.