diff options
author | Felix Geyer <debfx-pkg@fobos.de> | 2011-06-28 12:27:03 +0200 |
---|---|---|
committer | Felix Geyer <debfx-pkg@fobos.de> | 2011-06-28 12:27:03 +0200 |
commit | 6a16f6900dd884e07125b51c9625f6be0a1f9b70 (patch) | |
tree | ca3a5bca20c886411320d15508fbd741cba63545 /src/VBox/Main/src-server/MediumImpl.cpp | |
parent | 0056814bdb2f8a457b56803fd24c72347173250d (diff) | |
download | virtualbox-6a16f6900dd884e07125b51c9625f6be0a1f9b70.tar.gz |
Imported Upstream version 4.0.10-dfsgupstream/4.0.10-dfsg
Diffstat (limited to 'src/VBox/Main/src-server/MediumImpl.cpp')
-rw-r--r-- | src/VBox/Main/src-server/MediumImpl.cpp | 178 |
1 files changed, 104 insertions, 74 deletions
diff --git a/src/VBox/Main/src-server/MediumImpl.cpp b/src/VBox/Main/src-server/MediumImpl.cpp index 6e8322b4d..ab4daf457 100644 --- a/src/VBox/Main/src-server/MediumImpl.cpp +++ b/src/VBox/Main/src-server/MediumImpl.cpp @@ -238,7 +238,7 @@ public: PVDINTERFACE mVDOperationIfaces; - // Whether the caller needs to call VirtualBox::saveSettings() after + // Whether the caller needs to call VirtualBox::saveRegistries() after // the task function returns. Only used in synchronous (wait) mode; // otherwise the task will save the settings itself. GuidList *m_pllRegistriesThatNeedSaving; @@ -1307,8 +1307,6 @@ HRESULT Medium::init(VirtualBox *aVirtualBox, if (FAILED(rc)) return rc; m->strDescription = aDescription; -/// @todo generate uuid (similarly to host network interface uuid) from location and device type - autoInitSpan.setSucceeded(); return S_OK; } @@ -2252,11 +2250,11 @@ STDMETHODIMP Medium::Close() ComObjPtr<VirtualBox> pVirtualBox(m->pVirtualBox); GuidList llRegistriesThatNeedSaving; - HRESULT rc = close(&llRegistriesThatNeedSaving, autoCaller); - - pVirtualBox->saveRegistries(llRegistriesThatNeedSaving); + MultiResult mrc = close(&llRegistriesThatNeedSaving, autoCaller); + /* Must save the registries, since an entry was most likely removed. */ + mrc = pVirtualBox->saveRegistries(llRegistriesThatNeedSaving); - return rc; + return mrc; } STDMETHODIMP Medium::GetProperty(IN_BSTR aName, BSTR *aValue) @@ -2471,15 +2469,16 @@ STDMETHODIMP Medium::DeleteStorage(IProgress **aProgress) ComObjPtr<Progress> pProgress; GuidList llRegistriesThatNeedSaving; - HRESULT rc = deleteStorage(&pProgress, - false /* aWait */, - &llRegistriesThatNeedSaving); - m->pVirtualBox->saveRegistries(llRegistriesThatNeedSaving); + MultiResult mrc = deleteStorage(&pProgress, + false /* aWait */, + &llRegistriesThatNeedSaving); + /* Must save the registries in any case, since an entry was removed. */ + mrc = m->pVirtualBox->saveRegistries(llRegistriesThatNeedSaving); - if (SUCCEEDED(rc)) + if (SUCCEEDED(mrc)) pProgress.queryInterfaceTo(aProgress); - return rc; + return mrc; } STDMETHODIMP Medium::CreateDiffStorage(IMedium *aTarget, @@ -3302,7 +3301,12 @@ HRESULT Medium::addBackReference(const Guid &aMachineId, if (aSnapshotId.isEmpty()) { /* sanity: no duplicate attachments */ - AssertReturn(!it->fInCurState, E_FAIL); + if (it->fInCurState) + return setError(VBOX_E_OBJECT_IN_USE, + tr("Cannot attach medium '%s' {%RTuuid}: medium is already associated with the current state of machine uuid {%RTuuid}!"), + m->strLocationFull.c_str(), + m->id.raw(), + aMachineId.raw()); it->fInCurState = true; return S_OK; @@ -3326,8 +3330,7 @@ HRESULT Medium::addBackReference(const Guid &aMachineId, tr("Cannot attach medium '%s' {%RTuuid} from snapshot '%RTuuid': medium is already in use by this snapshot!"), m->strLocationFull.c_str(), m->id.raw(), - aSnapshotId.raw(), - idOldSnapshot.raw()); + aSnapshotId.raw()); } } @@ -3787,7 +3790,7 @@ HRESULT Medium::createMediumLockList(bool fFailIfInaccessible, * @param aWait @c true if this method should block instead of * creating an asynchronous thread. * @param pllRegistriesThatNeedSaving Optional pointer to a list of UUIDs that will receive the registry IDs that need saving. - * This only works in "wait" mode; otherwise saveSettings is called automatically by the thread that + * This only works in "wait" mode; otherwise saveRegistries is called automatically by the thread that * was created, and this parameter is ignored. * * @note Locks this object and @a aTarget for writing. @@ -3924,7 +3927,7 @@ Utf8Str Medium::getPreferredDiffFormat() /** * Implementation for the public Medium::Close() with the exception of calling - * VirtualBox::saveSettings(), in case someone wants to call this for several + * VirtualBox::saveRegistries(), in case someone wants to call this for several * media. * * After this returns with success, uninit() has been called on the medium, and @@ -4008,8 +4011,8 @@ HRESULT Medium::close(GuidList *pllRegistriesThatNeedSaving, * @param aWait @c true if this method should block instead of creating * an asynchronous thread. * @param pfNeedsGlobalSaveSettings Optional pointer to a bool that must have been initialized to false and that will be set to true - * by this function if the caller should invoke VirtualBox::saveSettings() because the global settings have changed. - * This only works in "wait" mode; otherwise saveSettings gets called automatically by the thread that was created, + * by this function if the caller should invoke VirtualBox::saveRegistries() because the global settings have changed. + * This only works in "wait" mode; otherwise saveRegistries gets called automatically by the thread that was created, * and this parameter is ignored. * * @note Locks mVirtualBox and this object for writing. Locks medium tree for @@ -4626,8 +4629,8 @@ HRESULT Medium::prepareMergeTo(const ComObjPtr<Medium> &pTarget, * @param aWait @c true if this method should block instead of creating * an asynchronous thread. * @param pfNeedsGlobalSaveSettings Optional pointer to a bool that must have been initialized to false and that will be set to true - * by this function if the caller should invoke VirtualBox::saveSettings() because the global settings have changed. - * This only works in "wait" mode; otherwise saveSettings gets called automatically by the thread that was created, + * by this function if the caller should invoke VirtualBox::saveRegistries() because the global settings have changed. + * This only works in "wait" mode; otherwise saveRegistries gets called automatically by the thread that was created, * and this parameter is ignored. * * @note Locks the tree lock for writing. Locks the media from the chain @@ -4840,10 +4843,10 @@ HRESULT Medium::fixParentUuidOfChildren(const MediaList &childrenToReparent) catch (HRESULT aRC) { rc = aRC; } catch (int aVRC) { - throw setError(E_FAIL, - tr("Could not update medium UUID references to parent '%s' (%s)"), - m->strLocationFull.c_str(), - vdError(aVRC).c_str()); + rc = setError(E_FAIL, + tr("Could not update medium UUID references to parent '%s' (%s)"), + m->strLocationFull.c_str(), + vdError(aVRC).c_str()); } VDDestroy(hdd); @@ -6269,7 +6272,7 @@ HRESULT Medium::taskCreateBaseHandler(Medium::CreateBaseTask &task) */ HRESULT Medium::taskCreateDiffHandler(Medium::CreateDiffTask &task) { - HRESULT rc = S_OK; + HRESULT rcTmp = S_OK; const ComObjPtr<Medium> &pTarget = task.mTarget; @@ -6352,7 +6355,7 @@ HRESULT Medium::taskCreateDiffHandler(Medium::CreateDiffTask &task) /* ensure the target directory exists */ if (capabilities & VD_CAP_FILE) { - rc = VirtualBox::ensureFilePathExists(targetLocation); + HRESULT rc = VirtualBox::ensureFilePathExists(targetLocation); if (FAILED(rc)) throw rc; } @@ -6379,13 +6382,15 @@ HRESULT Medium::taskCreateDiffHandler(Medium::CreateDiffTask &task) if (RT_SUCCESS(vrc)) variant = (MediumVariant_T)uImageFlags; } - catch (HRESULT aRC) { rc = aRC; } + catch (HRESULT aRC) { rcTmp = aRC; } VDDestroy(hdd); } - catch (HRESULT aRC) { rc = aRC; } + catch (HRESULT aRC) { rcTmp = aRC; } - if (SUCCEEDED(rc)) + MultiResult mrc(rcTmp); + + if (SUCCEEDED(mrc)) { AutoWriteLock treeLock(m->pVirtualBox->getMediaTreeLockHandle() COMMA_LOCKVAL_SRC_POS); @@ -6403,16 +6408,16 @@ HRESULT Medium::taskCreateDiffHandler(Medium::CreateDiffTask &task) /* register with mVirtualBox as the last step and move to * Created state only on success (leaving an orphan file is * better than breaking media registry consistency) */ - rc = m->pVirtualBox->registerHardDisk(pTarget, &llRegistriesThatNeedSaving); + mrc = m->pVirtualBox->registerHardDisk(pTarget, &llRegistriesThatNeedSaving); - if (FAILED(rc)) + if (FAILED(mrc)) /* break the parent association on failure to register */ deparent(); } AutoMultiWriteLock2 mediaLock(this, pTarget COMMA_LOCKVAL_SRC_POS); - if (SUCCEEDED(rc)) + if (SUCCEEDED(mrc)) { pTarget->m->state = MediumState_Created; @@ -6439,7 +6444,7 @@ HRESULT Medium::taskCreateDiffHandler(Medium::CreateDiffTask &task) if (task.isAsync()) { mediaLock.release(); - m->pVirtualBox->saveRegistries(llRegistriesThatNeedSaving); + mrc = m->pVirtualBox->saveRegistries(llRegistriesThatNeedSaving); } else // synchronous mode: report save settings result to caller @@ -6449,7 +6454,7 @@ HRESULT Medium::taskCreateDiffHandler(Medium::CreateDiffTask &task) /* Note that in sync mode, it's the caller's responsibility to * unlock the medium. */ - return rc; + return mrc; } /** @@ -6466,7 +6471,7 @@ HRESULT Medium::taskCreateDiffHandler(Medium::CreateDiffTask &task) */ HRESULT Medium::taskMergeHandler(Medium::MergeTask &task) { - HRESULT rc = S_OK; + HRESULT rcTmp = S_OK; const ComObjPtr<Medium> &pTarget = task.mTarget; @@ -6593,23 +6598,25 @@ HRESULT Medium::taskMergeHandler(Medium::MergeTask &task) } } } - catch (HRESULT aRC) { rc = aRC; } + catch (HRESULT aRC) { rcTmp = aRC; } catch (int aVRC) { - throw setError(VBOX_E_FILE_ERROR, - tr("Could not merge the medium '%s' to '%s'%s"), - m->strLocationFull.c_str(), - pTarget->m->strLocationFull.c_str(), - vdError(aVRC).c_str()); + rcTmp = setError(VBOX_E_FILE_ERROR, + tr("Could not merge the medium '%s' to '%s'%s"), + m->strLocationFull.c_str(), + pTarget->m->strLocationFull.c_str(), + vdError(aVRC).c_str()); } VDDestroy(hdd); } - catch (HRESULT aRC) { rc = aRC; } + catch (HRESULT aRC) { rcTmp = aRC; } + ErrorInfoKeeper eik; + MultiResult mrc(rcTmp); HRESULT rc2; - if (SUCCEEDED(rc)) + if (SUCCEEDED(mrc)) { /* all media but the target were successfully deleted by * VDMerge; reparent the last one and uninitialize deleted media. */ @@ -6726,19 +6733,22 @@ HRESULT Medium::taskMergeHandler(Medium::MergeTask &task) // in asynchronous mode, save settings now GuidList llRegistriesThatNeedSaving; addToRegistryIDList(llRegistriesThatNeedSaving); - rc = m->pVirtualBox->saveRegistries(llRegistriesThatNeedSaving); + /* collect multiple errors */ + eik.restore(); + mrc = m->pVirtualBox->saveRegistries(llRegistriesThatNeedSaving); + eik.fetch(); } else // synchronous mode: report save settings result to caller if (task.m_pllRegistriesThatNeedSaving) pTarget->addToRegistryIDList(*task.m_pllRegistriesThatNeedSaving); - if (FAILED(rc)) + if (FAILED(mrc)) { /* Here we come if either VDMerge() failed (in which case we * assume that it tried to do everything to make a further * retry possible -- e.g. not deleted intermediate media - * and so on) or VirtualBox::saveSettings() failed (where we + * and so on) or VirtualBox::saveRegistries() failed (where we * should have the original tree but with intermediate storage * units deleted by VDMerge()). We have to only restore states * (through the MergeChain dtor) unless we are run synchronously @@ -6752,7 +6762,7 @@ HRESULT Medium::taskMergeHandler(Medium::MergeTask &task) } } - return rc; + return mrc; } /** @@ -6766,7 +6776,7 @@ HRESULT Medium::taskMergeHandler(Medium::MergeTask &task) */ HRESULT Medium::taskCloneHandler(Medium::CloneTask &task) { - HRESULT rc = S_OK; + HRESULT rcTmp = S_OK; const ComObjPtr<Medium> &pTarget = task.mTarget; const ComObjPtr<Medium> &pParent = task.mParent; @@ -6848,7 +6858,7 @@ HRESULT Medium::taskCloneHandler(Medium::CloneTask &task) /* ensure the target directory exists */ if (capabilities & VD_CAP_FILE) { - rc = VirtualBox::ensureFilePathExists(targetLocation); + HRESULT rc = VirtualBox::ensureFilePathExists(targetLocation); if (FAILED(rc)) throw rc; } @@ -6927,18 +6937,21 @@ HRESULT Medium::taskCloneHandler(Medium::CloneTask &task) if (RT_SUCCESS(vrc)) variant = (MediumVariant_T)uImageFlags; } - catch (HRESULT aRC) { rc = aRC; } + catch (HRESULT aRC) { rcTmp = aRC; } VDDestroy(targetHdd); } - catch (HRESULT aRC) { rc = aRC; } + catch (HRESULT aRC) { rcTmp = aRC; } VDDestroy(hdd); } - catch (HRESULT aRC) { rc = aRC; } + catch (HRESULT aRC) { rcTmp = aRC; } + + ErrorInfoKeeper eik; + MultiResult mrc(rcTmp); /* Only do the parent changes for newly created media. */ - if (SUCCEEDED(rc) && fCreatingTarget) + if (SUCCEEDED(mrc) && fCreatingTarget) { /* we set mParent & children() */ AutoWriteLock alock2(m->pVirtualBox->getMediaTreeLockHandle() COMMA_LOCKVAL_SRC_POS); @@ -6955,16 +6968,20 @@ HRESULT Medium::taskCloneHandler(Medium::CloneTask &task) /* register with mVirtualBox as the last step and move to * Created state only on success (leaving an orphan file is * better than breaking media registry consistency) */ - rc = pParent->m->pVirtualBox->registerHardDisk(pTarget, NULL /* pllRegistriesThatNeedSaving */); + eik.restore(); + mrc = pParent->m->pVirtualBox->registerHardDisk(pTarget, NULL /* pllRegistriesThatNeedSaving */); + eik.fetch(); - if (FAILED(rc)) + if (FAILED(mrc)) /* break parent association on failure to register */ pTarget->deparent(); // removes target from parent } else { /* just register */ - rc = m->pVirtualBox->registerHardDisk(pTarget, NULL /* pllRegistriesThatNeedSaving */); + eik.restore(); + mrc = m->pVirtualBox->registerHardDisk(pTarget, NULL /* pllRegistriesThatNeedSaving */); + eik.fetch(); } } @@ -6972,7 +6989,7 @@ HRESULT Medium::taskCloneHandler(Medium::CloneTask &task) { AutoWriteLock mLock(pTarget COMMA_LOCKVAL_SRC_POS); - if (SUCCEEDED(rc)) + if (SUCCEEDED(mrc)) { pTarget->m->state = MediumState_Created; @@ -6996,7 +7013,10 @@ HRESULT Medium::taskCloneHandler(Medium::CloneTask &task) // save the settings GuidList llRegistriesThatNeedSaving; addToRegistryIDList(llRegistriesThatNeedSaving); - rc = m->pVirtualBox->saveRegistries(llRegistriesThatNeedSaving); + /* collect multiple errors */ + eik.restore(); + mrc = m->pVirtualBox->saveRegistries(llRegistriesThatNeedSaving); + eik.fetch(); } /* Everything is explicitly unlocked when the task exits, @@ -7007,7 +7027,7 @@ HRESULT Medium::taskCloneHandler(Medium::CloneTask &task) * is called & the source chain is released at the same time. */ task.mpSourceMediumLockList->Clear(); - return rc; + return mrc; } /** @@ -7507,7 +7527,7 @@ HRESULT Medium::taskExportHandler(Medium::ExportTask &task) 0 /* cbSize */, task.mVariant, NULL /* pDstUuid */, - VD_OPEN_FLAGS_NORMAL, + VD_OPEN_FLAGS_NORMAL | VD_OPEN_FLAGS_SEQUENTIAL, NULL /* pVDIfsOperation */, task.mVDImageIfaces, task.mVDOperationIfaces); @@ -7548,7 +7568,7 @@ HRESULT Medium::taskExportHandler(Medium::ExportTask &task) */ HRESULT Medium::taskImportHandler(Medium::ImportTask &task) { - HRESULT rc = S_OK; + HRESULT rcTmp = S_OK; const ComObjPtr<Medium> &pParent = task.mParent; @@ -7612,7 +7632,7 @@ HRESULT Medium::taskImportHandler(Medium::ImportTask &task) /* ensure the target directory exists */ if (capabilities & VD_CAP_FILE) { - rc = VirtualBox::ensureFilePathExists(targetLocation); + HRESULT rc = VirtualBox::ensureFilePathExists(targetLocation); if (FAILED(rc)) throw rc; } @@ -7691,18 +7711,21 @@ HRESULT Medium::taskImportHandler(Medium::ImportTask &task) if (RT_SUCCESS(vrc)) variant = (MediumVariant_T)uImageFlags; } - catch (HRESULT aRC) { rc = aRC; } + catch (HRESULT aRC) { rcTmp = aRC; } VDDestroy(targetHdd); } - catch (HRESULT aRC) { rc = aRC; } + catch (HRESULT aRC) { rcTmp = aRC; } VDDestroy(hdd); } - catch (HRESULT aRC) { rc = aRC; } + catch (HRESULT aRC) { rcTmp = aRC; } + + ErrorInfoKeeper eik; + MultiResult mrc(rcTmp); /* Only do the parent changes for newly created media. */ - if (SUCCEEDED(rc) && fCreatingTarget) + if (SUCCEEDED(mrc) && fCreatingTarget) { /* we set mParent & children() */ AutoWriteLock alock2(m->pVirtualBox->getMediaTreeLockHandle() COMMA_LOCKVAL_SRC_POS); @@ -7719,16 +7742,20 @@ HRESULT Medium::taskImportHandler(Medium::ImportTask &task) /* register with mVirtualBox as the last step and move to * Created state only on success (leaving an orphan file is * better than breaking media registry consistency) */ - rc = pParent->m->pVirtualBox->registerHardDisk(this, NULL /* llRegistriesThatNeedSaving */); + eik.restore(); + mrc = pParent->m->pVirtualBox->registerHardDisk(this, NULL /* llRegistriesThatNeedSaving */); + eik.fetch(); - if (FAILED(rc)) + if (FAILED(mrc)) /* break parent association on failure to register */ this->deparent(); // removes target from parent } else { /* just register */ - rc = m->pVirtualBox->registerHardDisk(this, NULL /* pllRegistriesThatNeedSaving */); + eik.restore(); + mrc = m->pVirtualBox->registerHardDisk(this, NULL /* pllRegistriesThatNeedSaving */); + eik.fetch(); } } @@ -7736,7 +7763,7 @@ HRESULT Medium::taskImportHandler(Medium::ImportTask &task) { AutoWriteLock mLock(this COMMA_LOCKVAL_SRC_POS); - if (SUCCEEDED(rc)) + if (SUCCEEDED(mrc)) { m->state = MediumState_Created; @@ -7760,7 +7787,10 @@ HRESULT Medium::taskImportHandler(Medium::ImportTask &task) // save the settings GuidList llRegistriesThatNeedSaving; addToRegistryIDList(llRegistriesThatNeedSaving); - rc = m->pVirtualBox->saveRegistries(llRegistriesThatNeedSaving); + /* collect multiple errors */ + eik.restore(); + mrc = m->pVirtualBox->saveRegistries(llRegistriesThatNeedSaving); + eik.fetch(); } /* Everything is explicitly unlocked when the task exits, @@ -7770,7 +7800,7 @@ HRESULT Medium::taskImportHandler(Medium::ImportTask &task) * lead to deadlocks with concurrent IAppliance activities. */ task.mpTargetMediumLockList->Clear(); - return rc; + return mrc; } /* vi: set tabstop=4 shiftwidth=4 expandtab: */ |