Changeset 19036 in vbox
- Timestamp:
- Apr 20, 2009 3:55:29 PM (16 years ago)
- Location:
- trunk/src/VBox/Main
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Main/HardDiskImpl.cpp
r18813 r19036 59 59 { 60 60 enum Operation { CreateBase, CreateDiff, 61 Merge, Clone, Delete, Reset };61 Merge, Clone, Delete, Reset, Compact }; 62 62 63 63 HardDisk *that; … … 104 104 } 105 105 106 void setData ( CloneChain *aSrcChain, CloneChain *aParentChain)106 void setData (ImageChain *aSrcChain, ImageChain *aParentChain) 107 107 { 108 108 AssertReturnVoid (aSrcChain != NULL); … … 112 112 } 113 113 114 void setData (ImageChain *aImgChain) 115 { 116 AssertReturnVoid (aImgChain != NULL); 117 d.images.reset (aImgChain); 118 } 119 114 120 HRESULT startThread(); 115 121 HRESULT runNow(); … … 134 140 135 141 /** Hard disks to open, in {parent,child} order */ 136 std::auto_ptr < CloneChain> source;142 std::auto_ptr <ImageChain> source; 137 143 /** Hard disks which are parent of target, in {parent,child} order */ 138 std::auto_ptr < CloneChain> parent;144 std::auto_ptr <ImageChain> parent; 139 145 /** The to-be parent hard disk object */ 140 146 ComObjPtr<HardDisk> parentDisk; … … 144 150 /** Hard disks to merge, in {parent,child} order */ 145 151 std::auto_ptr <MergeChain> chain; 152 153 /* Compact */ 154 155 /** Hard disks to open, in {parent,child} order */ 156 std::auto_ptr <ImageChain> images; 146 157 } 147 158 d; … … 458 469 459 470 /** 460 * Helper class for clone operations.471 * Helper class for image operations involving the entire parent chain. 461 472 * 462 473 * @note It is assumed that when modifying methods of this class are called, 463 474 * HardDisk::treeLock() is held in read mode. 464 475 */ 465 class HardDisk:: CloneChain : public HardDisk::List,476 class HardDisk::ImageChain : public HardDisk::List, 466 477 public com::SupportErrorInfoBase 467 478 { 468 479 public: 469 480 470 CloneChain () {} 471 472 ~CloneChain() 473 { 474 for (iterator it = begin(); it != end(); ++ it) 481 ImageChain () {} 482 483 ~ImageChain() 484 { 485 List::const_iterator last = end(); 486 last--; 487 for (List::const_iterator it = begin(); it != end(); ++ it) 475 488 { 476 489 AutoWriteLock alock (*it); 477 Assert ((*it)->m.state == MediaState_LockedRead); 478 if ((*it)->m.state == MediaState_LockedRead) 479 (*it)->UnlockRead (NULL); 490 if (it == last) 491 { 492 Assert ( (*it)->m.state == MediaState_LockedRead 493 || (*it)->m.state == MediaState_LockedWrite); 494 if ((*it)->m.state == MediaState_LockedRead) 495 (*it)->UnlockRead (NULL); 496 else if ((*it)->m.state == MediaState_LockedWrite) 497 (*it)->UnlockWrite (NULL); 498 } 499 else 500 { 501 Assert ((*it)->m.state == MediaState_LockedRead); 502 if ((*it)->m.state == MediaState_LockedRead) 503 (*it)->UnlockRead (NULL); 504 } 480 505 481 506 (*it)->releaseCaller(); … … 512 537 CheckComRCReturnRC (rc); 513 538 Assert (mediaState == MediaState_LockedRead); 539 540 /* Note that we locked the medium already, so use the error 541 * value to see if there was an accessibility failure */ 542 Bstr error; 543 rc = (*it)->COMGETTER(LastAccessError) (error.asOutParam()); 544 CheckComRCReturnRC (rc); 545 546 if (!error.isNull()) 547 { 548 Bstr loc; 549 rc = (*it)->COMGETTER(Location) (loc.asOutParam()); 550 CheckComRCThrowRC (rc); 551 552 /* collect multiple errors */ 553 eik.restore(); 554 555 /* be in sync with MediumBase::setStateError() */ 556 Assert (!error.isEmpty()); 557 mrc = setError (E_FAIL, 558 tr ("Medium '%ls' is not accessible. %ls"), 559 loc.raw(), error.raw()); 560 561 eik.fetch(); 562 } 563 } 564 } 565 566 eik.restore(); 567 CheckComRCReturnRC ((HRESULT) mrc); 568 569 return S_OK; 570 } 571 572 HRESULT lockImagesReadAndLastWrite () 573 { 574 /* Lock all disks in the chain in {parent, child} order, 575 * and make sure they are accessible. */ 576 /// @todo code duplication with SessionMachine::lockMedia, see below 577 ErrorInfoKeeper eik (true /* aIsNull */); 578 MultiResult mrc (S_OK); 579 List::const_iterator last = end(); 580 last--; 581 for (List::const_iterator it = begin(); it != end(); ++ it) 582 { 583 HRESULT rc = S_OK; 584 MediaState_T mediaState; 585 if (it == last) 586 rc = (*it)->LockWrite(&mediaState); 587 else 588 rc = (*it)->LockRead(&mediaState); 589 CheckComRCReturnRC (rc); 590 591 if (mediaState == MediaState_Inaccessible) 592 { 593 rc = (*it)->COMGETTER(State) (&mediaState); 594 CheckComRCReturnRC (rc); 595 if (it == last) 596 Assert (mediaState == MediaState_LockedWrite); 597 else 598 Assert (mediaState == MediaState_LockedRead); 514 599 515 600 /* Note that we locked the medium already, so use the error … … 1489 1574 1490 1575 /* Build the source chain and lock images in the proper order. */ 1491 std::auto_ptr < CloneChain> srcChain (new CloneChain ());1576 std::auto_ptr <ImageChain> srcChain (new ImageChain ()); 1492 1577 1493 1578 /* we walk the source tree */ … … 1502 1587 1503 1588 /* Build the parent chain and lock images in the proper order. */ 1504 std::auto_ptr < CloneChain> parentChain (new CloneChain ());1589 std::auto_ptr <ImageChain> parentChain (new ImageChain ()); 1505 1590 1506 1591 /* we walk the future parent tree */ … … 1563 1648 CheckComRCReturnRC (autoCaller.rc()); 1564 1649 1565 ReturnComNotImplemented(); 1650 AutoWriteLock alock (this); 1651 1652 ComObjPtr <Progress> progress; 1653 1654 HRESULT rc = S_OK; 1655 1656 try 1657 { 1658 /** @todo separate out creating/locking an image chain from 1659 * SessionMachine::lockMedia and use it from here too. 1660 * logically this belongs into HardDisk functionality. */ 1661 1662 /* Build the image chain and lock images in the proper order. */ 1663 std::auto_ptr <ImageChain> imgChain (new ImageChain ()); 1664 1665 /* we walk the image tree */ 1666 AutoReadLock srcTreeLock (this->treeLock()); 1667 for (HardDisk *hd = this; hd; hd = hd->mParent) 1668 { 1669 rc = imgChain->addImage(hd); 1670 CheckComRCThrowRC (rc); 1671 } 1672 rc = imgChain->lockImagesReadAndLastWrite(); 1673 CheckComRCThrowRC (rc); 1674 1675 progress.createObject(); 1676 rc = progress->init (mVirtualBox, static_cast <IHardDisk *> (this), 1677 BstrFmt (tr ("Compacting hard disk '%ls'"), m.locationFull.raw()), 1678 TRUE /* aCancelable */); 1679 CheckComRCThrowRC (rc); 1680 1681 /* setup task object and thread to carry out the operation 1682 * asynchronously */ 1683 1684 std::auto_ptr <Task> task (new Task (this, progress, Task::Compact)); 1685 AssertComRCThrowRC (task->autoCaller.rc()); 1686 1687 task->setData (imgChain.release()); 1688 1689 rc = task->startThread(); 1690 CheckComRCThrowRC (rc); 1691 1692 /* task is now owned (or already deleted) by taskThread() so release it */ 1693 task.release(); 1694 } 1695 catch (HRESULT aRC) 1696 { 1697 rc = aRC; 1698 } 1699 1700 if (SUCCEEDED (rc)) 1701 { 1702 /* return progress to the caller */ 1703 progress.queryInterfaceTo (aProgress); 1704 } 1705 1706 return rc; 1566 1707 } 1567 1708 … … 4109 4250 AutoMultiWriteLock3 thatLock (that, target, parent); 4110 4251 4111 CloneChain *srcChain = task->d.source.get();4112 CloneChain *parentChain = task->d.parent.get();4252 ImageChain *srcChain = task->d.source.get(); 4253 ImageChain *parentChain = task->d.parent.get(); 4113 4254 4114 4255 uint64_t size = 0, logicalSize = 0; … … 4457 4598 } 4458 4599 4600 //////////////////////////////////////////////////////////////////////// 4601 4602 case Task::Compact: 4603 { 4604 /* Lock all in {parent,child} order. The lock is also used as a 4605 * signal from the task initiator (which releases it only after 4606 * RTThreadCreate()) that we can start the job. */ 4607 AutoWriteLock thatLock (that); 4608 4609 ImageChain *imgChain = task->d.images.get(); 4610 4611 try 4612 { 4613 PVBOXHDD hdd; 4614 int vrc = VDCreate (that->mm.vdDiskIfaces, &hdd); 4615 ComAssertRCThrow (vrc, E_FAIL); 4616 4617 try 4618 { 4619 /* Open all hard disk images in the chain. */ 4620 List::const_iterator last = imgChain->end(); 4621 last--; 4622 for (List::const_iterator it = imgChain->begin(); 4623 it != imgChain->end(); ++ it) 4624 { 4625 /* sanity check */ 4626 if (it == last) 4627 Assert ((*it)->m.state == MediaState_LockedWrite); 4628 else 4629 Assert ((*it)->m.state == MediaState_LockedRead); 4630 4631 /** Open all images but last in read-only mode. */ 4632 vrc = VDOpen (hdd, Utf8Str ((*it)->mm.format), 4633 Utf8Str ((*it)->m.locationFull), 4634 (it == last) ? VD_OPEN_FLAGS_NORMAL : VD_OPEN_FLAGS_READONLY, 4635 (*it)->mm.vdDiskIfaces); 4636 if (RT_FAILURE (vrc)) 4637 { 4638 throw setError (E_FAIL, 4639 tr ("Could not open the hard disk storage " 4640 "unit '%s'%s"), 4641 Utf8Str ((*it)->m.locationFull).raw(), 4642 that->vdError (vrc).raw()); 4643 } 4644 } 4645 4646 /* unlock before the potentially lengthy operation */ 4647 thatLock.leave(); 4648 4649 Assert (that->m.state == MediaState_LockedWrite); 4650 4651 /* needed for vdProgressCallback */ 4652 that->mm.vdProgress = task->progress; 4653 4654 vrc = VDCompact (hdd, VD_LAST_IMAGE, that->mm.vdDiskIfaces); 4655 4656 that->mm.vdProgress = NULL; 4657 4658 if (RT_FAILURE (vrc)) 4659 { 4660 if (vrc == VERR_NOT_SUPPORTED) 4661 throw setError(VBOX_E_NOT_SUPPORTED, 4662 tr("Compacting is not supported yet for hard disk '%s'"), 4663 Utf8Str (that->m.locationFull).raw()); 4664 else if (vrc == VERR_NOT_IMPLEMENTED) 4665 throw setError(E_NOTIMPL, 4666 tr("Compacting is not implemented, hard disk '%s'"), 4667 Utf8Str (that->m.locationFull).raw()); 4668 else 4669 throw setError (E_FAIL, 4670 tr ("Could not compact hard disk '%s'%s"), 4671 Utf8Str (that->m.locationFull).raw(), 4672 that->vdError (vrc).raw()); 4673 } 4674 } 4675 catch (HRESULT aRC) { rc = aRC; } 4676 4677 VDDestroy (hdd); 4678 } 4679 catch (HRESULT aRC) { rc = aRC; } 4680 4681 /* Everything is explicitly unlocked when the task exits, 4682 * as the task destruction also destroys the image chain. */ 4683 4684 break; 4685 } 4686 4459 4687 default: 4460 4688 AssertFailedReturn (VERR_GENERAL_FAILURE); -
trunk/src/VBox/Main/include/HardDiskImpl.h
r18388 r19036 56 56 57 57 class MergeChain; 58 class CloneChain;58 class ImageChain; 59 59 60 60 VIRTUALBOXSUPPORTTRANSLATION_OVERRIDE (HardDisk)
Note:
See TracChangeset
for help on using the changeset viewer.