summaryrefslogtreecommitdiff
path: root/src/VBox/Main/src-server/SnapshotImpl.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/VBox/Main/src-server/SnapshotImpl.cpp')
-rw-r--r--src/VBox/Main/src-server/SnapshotImpl.cpp343
1 files changed, 144 insertions, 199 deletions
diff --git a/src/VBox/Main/src-server/SnapshotImpl.cpp b/src/VBox/Main/src-server/SnapshotImpl.cpp
index 747641aa6..aa3520f51 100644
--- a/src/VBox/Main/src-server/SnapshotImpl.cpp
+++ b/src/VBox/Main/src-server/SnapshotImpl.cpp
@@ -1,4 +1,4 @@
-/* $Id: SnapshotImpl.cpp $ */
+/* $Id: SnapshotImpl.cpp 37985 2011-07-15 15:04:39Z vboxsync $ */
/** @file
*
@@ -44,30 +44,6 @@
////////////////////////////////////////////////////////////////////////////////
//
-// Globals
-//
-////////////////////////////////////////////////////////////////////////////////
-
-/**
- * Progress callback handler for lengthy operations
- * (corresponds to the FNRTPROGRESS typedef).
- *
- * @param uPercentage Completion percentage (0-100).
- * @param pvUser Pointer to the Progress instance.
- */
-static DECLCALLBACK(int) progressCallback(unsigned uPercentage, void *pvUser)
-{
- IProgress *progress = static_cast<IProgress*>(pvUser);
-
- /* update the progress object */
- if (progress)
- progress->SetCurrentOperationProgress(uPercentage);
-
- return VINF_SUCCESS;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-//
// Snapshot private data definition
//
////////////////////////////////////////////////////////////////////////////////
@@ -108,13 +84,14 @@ struct Snapshot::Data
HRESULT Snapshot::FinalConstruct()
{
LogFlowThisFunc(("\n"));
- return S_OK;
+ return BaseFinalConstruct();
}
void Snapshot::FinalRelease()
{
LogFlowThisFunc(("\n"));
uninit();
+ BaseFinalRelease();
}
/**
@@ -348,6 +325,12 @@ STDMETHODIMP Snapshot::COMSETTER(Name)(IN_BSTR aName)
HRESULT rc = S_OK;
CheckComArgStrNotEmptyOrNull(aName);
+ // prohibit setting a UUID only as the machine name, or else it can
+ // never be found by findMachine()
+ Guid test(aName);
+ if (test.isNotEmpty())
+ return setError(E_INVALIDARG, tr("A machine cannot have a UUID as its name"));
+
AutoCaller autoCaller(this);
if (FAILED(autoCaller.rc())) return autoCaller.rc();
@@ -420,7 +403,7 @@ STDMETHODIMP Snapshot::COMGETTER(Online)(BOOL *aOnline)
AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
- *aOnline = !stateFilePath().isEmpty();
+ *aOnline = getStateFilePath().isNotEmpty();
return S_OK;
}
@@ -466,6 +449,15 @@ STDMETHODIMP Snapshot::COMGETTER(Children)(ComSafeArrayOut(ISnapshot *, aChildre
return S_OK;
}
+STDMETHODIMP Snapshot::GetChildrenCount(ULONG* count)
+{
+ CheckComArgOutPointerValid(count);
+
+ *count = getChildrenCount();
+
+ return S_OK;
+}
+
////////////////////////////////////////////////////////////////////////////////
//
// Snapshot public internal methods
@@ -496,21 +488,9 @@ const ComObjPtr<Snapshot> Snapshot::getFirstChild() const
* @note
* Must be called from under the object's lock!
*/
-const Utf8Str& Snapshot::stateFilePath() const
+const Utf8Str& Snapshot::getStateFilePath() const
{
- return m->pMachine->mSSData->mStateFilePath;
-}
-
-/**
- * @note
- * Must be called from under the object's write lock!
- */
-HRESULT Snapshot::deleteStateFile()
-{
- int vrc = RTFileDelete(m->pMachine->mSSData->mStateFilePath.c_str());
- if (RT_SUCCESS(vrc))
- m->pMachine->mSSData->mStateFilePath.setNull();
- return RT_SUCCESS(vrc) ? S_OK : E_FAIL;
+ return m->pMachine->mSSData->strStateFilePath;
}
/**
@@ -680,7 +660,7 @@ void Snapshot::updateSavedStatePathsImpl(const Utf8Str &strOldPath,
{
AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
- const Utf8Str &path = m->pMachine->mSSData->mStateFilePath;
+ const Utf8Str &path = m->pMachine->mSSData->strStateFilePath;
LogFlowThisFunc(("Snap[%s].statePath={%s}\n", m->strName.c_str(), path.c_str()));
/* state file may be NULL (for offline snapshots) */
@@ -688,9 +668,9 @@ void Snapshot::updateSavedStatePathsImpl(const Utf8Str &strOldPath,
&& RTPathStartsWith(path.c_str(), strOldPath.c_str())
)
{
- m->pMachine->mSSData->mStateFilePath = Utf8StrFmt("%s%s",
- strNewPath.c_str(),
- path.c_str() + strOldPath.length());
+ m->pMachine->mSSData->strStateFilePath = Utf8StrFmt("%s%s",
+ strNewPath.c_str(),
+ path.c_str() + strOldPath.length());
LogFlowThisFunc(("-> updated: {%s}\n", path.c_str()));
}
@@ -704,6 +684,44 @@ void Snapshot::updateSavedStatePathsImpl(const Utf8Str &strOldPath,
}
/**
+ * Returns true if this snapshot or one of its children uses the given file,
+ * whose path must be fully qualified, as its saved state. When invoked on a
+ * machine's first snapshot, this can be used to check if a saved state file
+ * is shared with any snapshots.
+ *
+ * Caller must hold the machine lock, which protects the snapshots tree.
+ *
+ * @param strPath
+ * @param pSnapshotToIgnore If != NULL, this snapshot is ignored during the checks.
+ * @return
+ */
+bool Snapshot::sharesSavedStateFile(const Utf8Str &strPath,
+ Snapshot *pSnapshotToIgnore)
+{
+ AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
+ const Utf8Str &path = m->pMachine->mSSData->strStateFilePath;
+
+ if (!pSnapshotToIgnore || pSnapshotToIgnore != this)
+ if (path.isNotEmpty())
+ if (path == strPath)
+ return true; // no need to recurse then
+
+ // but otherwise we must check children
+ for (SnapshotsList::const_iterator it = m->llChildren.begin();
+ it != m->llChildren.end();
+ ++it)
+ {
+ Snapshot *pChild = *it;
+ if (!pSnapshotToIgnore || pSnapshotToIgnore != pChild)
+ if (pChild->sharesSavedStateFile(strPath, pSnapshotToIgnore))
+ return true;
+ }
+
+ return false;
+}
+
+
+/**
* Checks if the specified path change affects the saved state file path of
* this snapshot or any of its (grand-)children and updates it accordingly.
*
@@ -749,9 +767,9 @@ HRESULT Snapshot::saveSnapshotImpl(settings::Snapshot &data, bool aAttrsOnly)
if (aAttrsOnly)
return S_OK;
- /* stateFile (optional) */
- if (!stateFilePath().isEmpty())
- m->pMachine->copyPathRelativeToMachine(stateFilePath(), data.strStateFile);
+ // state file (only if this snapshot is online)
+ if (getStateFilePath().isNotEmpty())
+ m->pMachine->copyPathRelativeToMachine(getStateFilePath(), data.strStateFile);
else
data.strStateFile.setNull();
@@ -862,9 +880,24 @@ HRESULT Snapshot::uninitRecursively(AutoWriteLock &writeLock,
if (FAILED(rc))
return rc;
- // now report the saved state file
- if (!m->pMachine->mSSData->mStateFilePath.isEmpty())
- llFilenames.push_back(m->pMachine->mSSData->mStateFilePath);
+ // report the saved state file if it's not on the list yet
+ if (!m->pMachine->mSSData->strStateFilePath.isEmpty())
+ {
+ bool fFound = false;
+ for (std::list<Utf8Str>::const_iterator it = llFilenames.begin();
+ it != llFilenames.end();
+ ++it)
+ {
+ const Utf8Str &str = *it;
+ if (str == m->pMachine->mSSData->strStateFilePath)
+ {
+ fFound = true;
+ break;
+ }
+ }
+ if (!fFound)
+ llFilenames.push_back(m->pMachine->mSSData->strStateFilePath);
+ }
this->beginSnapshotDelete();
this->uninit();
@@ -888,7 +921,7 @@ HRESULT SnapshotMachine::FinalConstruct()
{
LogFlowThisFunc(("\n"));
- return S_OK;
+ return BaseFinalConstruct();
}
void SnapshotMachine::FinalRelease()
@@ -896,6 +929,8 @@ void SnapshotMachine::FinalRelease()
LogFlowThisFunc(("\n"));
uninit();
+
+ BaseFinalRelease();
}
/**
@@ -942,7 +977,7 @@ HRESULT SnapshotMachine::init(SessionMachine *aSessionMachine,
/* SSData is always unique for SnapshotMachine */
mSSData.allocate();
- mSSData->mStateFilePath = aStateFilePath;
+ mSSData->strStateFilePath = aStateFilePath;
HRESULT rc = S_OK;
@@ -1080,7 +1115,7 @@ HRESULT SnapshotMachine::init(Machine *aMachine,
/* SSData is always unique for SnapshotMachine */
mSSData.allocate();
- mSSData->mStateFilePath = aStateFilePath;
+ mSSData->strStateFilePath = aStateFilePath;
/* create all other child objects that will be immutable private copies */
@@ -1252,18 +1287,14 @@ struct SessionMachine::RestoreSnapshotTask
{
RestoreSnapshotTask(SessionMachine *m,
Progress *p,
- Snapshot *s,
- ULONG ulStateFileSizeMB)
- : SnapshotTask(m, p, s),
- m_ulStateFileSizeMB(ulStateFileSizeMB)
+ Snapshot *s)
+ : SnapshotTask(m, p, s)
{}
void handler()
{
pMachine->restoreSnapshotHandler(*this);
}
-
- ULONG m_ulStateFileSizeMB;
};
/** Delete snapshot task */
@@ -1389,16 +1420,16 @@ STDMETHODIMP SessionMachine::BeginTakingSnapshot(IConsole *aInitiator,
Utf8Str strStateFilePath;
/* stateFilePath is null when the machine is not online nor saved */
- if ( fTakingSnapshotOnline
- || mData->mMachineState == MachineState_Saved)
- {
- Utf8Str strFullSnapshotFolder;
- calculateFullPath(mUserData->s.strSnapshotFolder, strFullSnapshotFolder);
- strStateFilePath = Utf8StrFmt("%s%c{%RTuuid}.sav",
- strFullSnapshotFolder.c_str(),
- RTPATH_DELIMITER,
- snapshotId.raw());
- /* ensure the directory for the saved state file exists */
+ if (fTakingSnapshotOnline)
+ // creating a new online snapshot: then we need a fresh saved state file
+ composeSavedStateFilename(strStateFilePath);
+ else if (mData->mMachineState == MachineState_Saved)
+ // taking an online snapshot from machine in "saved" state: then use existing state file
+ strStateFilePath = mSSData->strStateFilePath;
+
+ if (strStateFilePath.isNotEmpty())
+ {
+ // ensure the directory for the saved state file exists
HRESULT rc = VirtualBox::ensureFilePathExists(strStateFilePath);
if (FAILED(rc)) return rc;
}
@@ -1454,38 +1485,6 @@ STDMETHODIMP SessionMachine::BeginTakingSnapshot(IConsole *aInitiator,
if (FAILED(rc))
throw rc;
- if (mConsoleTaskData.mLastState == MachineState_Saved)
- {
- Utf8Str stateFrom = mSSData->mStateFilePath;
- Utf8Str stateTo = mConsoleTaskData.mSnapshot->stateFilePath();
-
- LogFlowThisFunc(("Copying the execution state from '%s' to '%s'...\n",
- stateFrom.c_str(), stateTo.c_str()));
-
- aConsoleProgress->SetNextOperation(Bstr(tr("Copying the execution state")).raw(),
- 1); // weight
-
- /* Leave the lock before a lengthy operation (machine is protected
- * by "Saving" machine state now) */
- alock.release();
-
- /* copy the state file */
- int vrc = RTFileCopyEx(stateFrom.c_str(),
- stateTo.c_str(),
- 0,
- progressCallback,
- aConsoleProgress);
- alock.acquire();
-
- if (RT_FAILURE(vrc))
- /** @todo r=bird: Delete stateTo when appropriate. */
- throw setError(E_FAIL,
- tr("Could not copy the state file '%s' to '%s' (%Rrc)"),
- stateFrom.c_str(),
- stateTo.c_str(),
- vrc);
- }
-
// if we got this far without an error, then save the media registries
// that got modified for the diff images
alock.release();
@@ -1586,8 +1585,6 @@ STDMETHODIMP SessionMachine::EndTakingSnapshot(BOOL aSuccess)
flSaveSettings |= SaveS_ResetCurStateModified;
rc = saveSettings(NULL, flSaveSettings);
- // no need to change for whether VirtualBox.xml needs saving since
- // we'll save the global settings below anyway
}
if (aSuccess && SUCCEEDED(rc))
@@ -1608,9 +1605,12 @@ STDMETHODIMP SessionMachine::EndTakingSnapshot(BOOL aSuccess)
mData->mFirstSnapshot = pOldFirstSnap; // might have been changed above
mData->mCurrentSnapshot = pOldCurrentSnap; // might have been changed above
- /* delete the saved state file (it might have been already created) */
- if (mConsoleTaskData.mSnapshot->stateFilePath().length())
- RTFileDelete(mConsoleTaskData.mSnapshot->stateFilePath().c_str());
+ // delete the saved state file (it might have been already created)
+ if (fOnline)
+ // no need to test for whether the saved state file is shared: an online
+ // snapshot means that a new saved state file was created, which we must
+ // clean up now
+ RTFileDelete(mConsoleTaskData.mSnapshot->getStateFilePath().c_str());
mConsoleTaskData.mSnapshot->uninit();
}
@@ -1619,12 +1619,6 @@ STDMETHODIMP SessionMachine::EndTakingSnapshot(BOOL aSuccess)
mConsoleTaskData.mLastState = MachineState_Null;
mConsoleTaskData.mSnapshot.setNull();
- // save VirtualBox.xml (media registry most probably changed with diff image);
- // for that we should hold only the VirtualBox lock
- machineLock.release();
- AutoWriteLock vboxLock(mParent COMMA_LOCKVAL_SRC_POS);
- mParent->saveSettings();
-
return rc;
}
@@ -1698,26 +1692,6 @@ STDMETHODIMP SessionMachine::RestoreSnapshot(IConsole *aInitiator,
}
}
- ULONG ulStateFileSizeMB = 0;
- if (pSnapshot->stateFilePath().length())
- {
- ++ulOpCount; // one for the saved state
-
- uint64_t ullSize;
- int irc = RTFileQuerySize(pSnapshot->stateFilePath().c_str(), &ullSize);
- if (!RT_SUCCESS(irc))
- // if we can't access the file here, then we'll be doomed later also, so fail right away
- setError(E_FAIL, tr("Cannot access state file '%s', runtime error, %Rra"), pSnapshot->stateFilePath().c_str(), irc);
- if (ullSize == 0) // avoid division by zero
- ullSize = _1M;
-
- ulStateFileSizeMB = (ULONG)(ullSize / _1M);
- LogFlowThisFunc(("op %d: saved state file '%s' has %RI64 bytes (%d MB)\n",
- ulOpCount, pSnapshot->stateFilePath().c_str(), ullSize, ulStateFileSizeMB));
-
- ulTotalWeight += ulStateFileSizeMB;
- }
-
ComObjPtr<Progress> pProgress;
pProgress.createObject();
pProgress->init(mParent, aInitiator,
@@ -1732,8 +1706,7 @@ STDMETHODIMP SessionMachine::RestoreSnapshot(IConsole *aInitiator,
* start working until we release alock) */
RestoreSnapshotTask *task = new RestoreSnapshotTask(this,
pProgress,
- pSnapshot,
- ulStateFileSizeMB);
+ pSnapshot);
int vrc = RTThreadCreate(NULL,
taskHandler,
(void*)task,
@@ -1812,10 +1785,16 @@ void SessionMachine::restoreSnapshotHandler(RestoreSnapshotTask &aTask)
* operation */
if (aTask.machineStateBackup == MachineState_Saved)
{
- Assert(!mSSData->mStateFilePath.isEmpty());
- RTFileDelete(mSSData->mStateFilePath.c_str());
- mSSData->mStateFilePath.setNull();
+ Assert(!mSSData->strStateFilePath.isEmpty());
+
+ // release the saved state file AFTER unsetting the member variable
+ // so that releaseSavedStateFile() won't think it's still in use
+ Utf8Str strStateFile(mSSData->strStateFilePath);
+ mSSData->strStateFilePath.setNull();
+ releaseSavedStateFile(strStateFile, NULL /* pSnapshotToIgnore */ );
+
aTask.modifyBackedUpState(MachineState_PoweredOff);
+
rc = saveStateSettings(SaveSTS_StateFilePath);
if (FAILED(rc))
throw rc;
@@ -1862,49 +1841,13 @@ void SessionMachine::restoreSnapshotHandler(RestoreSnapshotTask &aTask)
* deleted by #rollback() at the end. */
/* should not have a saved state file associated at this point */
- Assert(mSSData->mStateFilePath.isEmpty());
+ Assert(mSSData->strStateFilePath.isEmpty());
- if (!aTask.pSnapshot->stateFilePath().isEmpty())
- {
- Utf8Str snapStateFilePath = aTask.pSnapshot->stateFilePath();
-
- Utf8Str strFullSnapshotFolder;
- calculateFullPath(mUserData->s.strSnapshotFolder, strFullSnapshotFolder);
- Utf8Str stateFilePath = Utf8StrFmt("%s%c{%RTuuid}.sav",
- strFullSnapshotFolder.c_str(),
- RTPATH_DELIMITER,
- mData->mUuid.raw());
-
- LogFlowThisFunc(("Copying saved state file from '%s' to '%s'...\n",
- snapStateFilePath.c_str(), stateFilePath.c_str()));
-
- aTask.pProgress->SetNextOperation(Bstr(tr("Restoring the execution state")).raw(),
- aTask.m_ulStateFileSizeMB); // weight
-
- /* leave the lock before the potentially lengthy operation */
- snapshotLock.release();
- alock.leave();
-
- /* copy the state file */
- RTFileDelete(stateFilePath.c_str());
- int vrc = RTFileCopyEx(snapStateFilePath.c_str(),
- stateFilePath.c_str(),
- 0,
- progressCallback,
- static_cast<IProgress*>(aTask.pProgress));
-
- alock.enter();
- snapshotLock.acquire();
-
- if (RT_SUCCESS(vrc))
- mSSData->mStateFilePath = stateFilePath;
- else
- throw setError(E_FAIL,
- tr("Could not copy the state file '%s' to '%s' (%Rrc)"),
- snapStateFilePath.c_str(),
- stateFilePath.c_str(),
- vrc);
- }
+ const Utf8Str &strSnapshotStateFile = aTask.pSnapshot->getStateFilePath();
+
+ if (strSnapshotStateFile.isNotEmpty())
+ // online snapshot: then share the state file
+ mSSData->strStateFilePath = strSnapshotStateFile;
LogFlowThisFunc(("Setting new current snapshot {%RTuuid}\n", aTask.pSnapshot->getId().raw()));
/* make the snapshot we restored from the current snapshot */
@@ -1940,7 +1883,7 @@ void SessionMachine::restoreSnapshotHandler(RestoreSnapshotTask &aTask)
/* we have already deleted the current state, so set the execution
* state accordingly no matter of the delete snapshot result */
- if (!mSSData->mStateFilePath.isEmpty())
+ if (mSSData->strStateFilePath.isNotEmpty())
setMachineState(MachineState_Saved);
else
setMachineState(MachineState_PoweredOff);
@@ -1992,7 +1935,7 @@ void SessionMachine::restoreSnapshotHandler(RestoreSnapshotTask &aTask)
throw rc;
// unconditionally add the parent registry. We do similar in SessionMachine::EndTakingSnapshot
// (mParent->saveSettings())
- mParent->addGuidToListUniquely(llRegistriesThatNeedSaving, mParent->getGlobalRegistryId());
+ VirtualBox::addGuidToListUniquely(llRegistriesThatNeedSaving, mParent->getGlobalRegistryId());
// let go of the locks while we're deleting image files below
alock.leave();
@@ -2070,16 +2013,23 @@ void SessionMachine::restoreSnapshotHandler(RestoreSnapshotTask &aTask)
* @note Locks mParent + this + children objects for writing!
*/
STDMETHODIMP SessionMachine::DeleteSnapshot(IConsole *aInitiator,
- IN_BSTR aId,
+ IN_BSTR aStartId,
+ IN_BSTR aEndId,
+ BOOL fDeleteAllChildren,
MachineState_T *aMachineState,
IProgress **aProgress)
{
LogFlowThisFuncEnter();
- Guid id(aId);
- AssertReturn(aInitiator && !id.isEmpty(), E_INVALIDARG);
+ Guid startId(aStartId);
+ Guid endId(aEndId);
+ AssertReturn(aInitiator && !startId.isEmpty() && !endId.isEmpty(), E_INVALIDARG);
AssertReturn(aMachineState && aProgress, E_POINTER);
+ /** @todo implement the "and all children" and "range" variants */
+ if (fDeleteAllChildren || startId != endId)
+ ReturnComNotImplemented();
+
AutoCaller autoCaller(this);
AssertComRCReturn(autoCaller.rc(), autoCaller.rc());
@@ -2098,7 +2048,7 @@ STDMETHODIMP SessionMachine::DeleteSnapshot(IConsole *aInitiator,
Global::stringifyMachineState(mData->mMachineState));
ComObjPtr<Snapshot> pSnapshot;
- HRESULT rc = findSnapshotById(id, pSnapshot, true /* aSetError */);
+ HRESULT rc = findSnapshotById(startId, pSnapshot, true /* aSetError */);
if (FAILED(rc)) return rc;
AutoWriteLock snapshotLock(pSnapshot COMMA_LOCKVAL_SRC_POS);
@@ -2135,7 +2085,7 @@ STDMETHODIMP SessionMachine::DeleteSnapshot(IConsole *aInitiator,
ULONG ulOpCount = 1; // one for preparations
ULONG ulTotalWeight = 1; // one for preparations
- if (pSnapshot->stateFilePath().length())
+ if (pSnapshot->getStateFilePath().length())
{
++ulOpCount;
++ulTotalWeight; // assume 1 MB for deleting the state file
@@ -2420,12 +2370,6 @@ void SessionMachine::deleteSnapshotHandler(DeleteSnapshotTask &aTask)
}
else
fOnlineMergePossible = false;
-/// @todo remove this once the fix for windows/64bit API crashes for
-// SafeIfaceArray has been backported
-#if defined(RT_OS_WINDOWS) && defined(RT_ARCH_AMD64)
- if (fOnlineMergePossible)
- throw setError(E_NOTIMPL, tr("Live snapshot deletion on Windows/x64 is disabled to prevent a crash (will be fixed in the next release)"));
-#endif
}
rc = prepareDeleteSnapshotMedium(pHD, machineId, snapshotId,
fOnlineMergePossible,
@@ -2526,15 +2470,16 @@ void SessionMachine::deleteSnapshotHandler(DeleteSnapshotTask &aTask)
// tree is protected by the machine lock as well
AutoWriteLock machineLock(this COMMA_LOCKVAL_SRC_POS);
- Utf8Str stateFilePath = aTask.pSnapshot->stateFilePath();
+ Utf8Str stateFilePath = aTask.pSnapshot->getStateFilePath();
if (!stateFilePath.isEmpty())
{
aTask.pProgress->SetNextOperation(Bstr(tr("Deleting the execution state")).raw(),
1); // weight
- aTask.pSnapshot->deleteStateFile();
- // machine needs saving now
- mParent->addGuidToListUniquely(llRegistriesThatNeedSaving, getId());
+ releaseSavedStateFile(stateFilePath, aTask.pSnapshot /* pSnapshotToIgnore */);
+
+ // machine will need saving now
+ VirtualBox::addGuidToListUniquely(llRegistriesThatNeedSaving, getId());
}
}
@@ -2709,7 +2654,7 @@ void SessionMachine::deleteSnapshotHandler(DeleteSnapshotTask &aTask)
it->mpSource->uninit();
// One attachment is merged, must save the settings
- mParent->addGuidToListUniquely(llRegistriesThatNeedSaving, getId());
+ VirtualBox::addGuidToListUniquely(llRegistriesThatNeedSaving, getId());
// prevent calling cancelDeleteSnapshotMedium() for this attachment
it = toDelete.erase(it);
@@ -2728,7 +2673,7 @@ void SessionMachine::deleteSnapshotHandler(DeleteSnapshotTask &aTask)
aTask.pSnapshot->beginSnapshotDelete();
aTask.pSnapshot->uninit();
- mParent->addGuidToListUniquely(llRegistriesThatNeedSaving, getId());
+ VirtualBox::addGuidToListUniquely(llRegistriesThatNeedSaving, getId());
}
}
catch (HRESULT aRC) { rc = aRC; }