summaryrefslogtreecommitdiff
path: root/src/VBox/Main/src-server/MediumImpl.cpp
diff options
context:
space:
mode:
authorFelix Geyer <debfx-pkg@fobos.de>2011-06-28 12:27:03 +0200
committerFelix Geyer <debfx-pkg@fobos.de>2011-06-28 12:27:03 +0200
commit6a16f6900dd884e07125b51c9625f6be0a1f9b70 (patch)
treeca3a5bca20c886411320d15508fbd741cba63545 /src/VBox/Main/src-server/MediumImpl.cpp
parent0056814bdb2f8a457b56803fd24c72347173250d (diff)
downloadvirtualbox-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.cpp178
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: */