VirtualBox

Changeset 31333 in vbox


Ignore:
Timestamp:
Aug 3, 2010 1:00:54 PM (15 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
64371
Message:

Main: rework new implementation of Machine::Unregister() and Machine::Delete() to be more flexible and still easy to use

Location:
trunk/src/VBox
Files:
13 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Frontends/VBoxManage/VBoxManageMisc.cpp

    r31220 r31333  
    159159    if (machine)
    160160    {
    161         SafeArray<BSTR> abstrFiles;
    162         CHECK_ERROR(machine, Unregister(fDelete /* fAutoCleanup */,
    163                                         ComSafeArrayAsOutParam(abstrFiles)));
     161        SafeIfaceArray<IMedium> aMedia;
     162        CleanupMode_T cleanupMode = CleanupMode_DetachAllReturnNone;
     163        if (fDelete)
     164            cleanupMode = CleanupMode_DetachAllReturnHardDisksOnly;
     165        CHECK_ERROR(machine, Unregister(cleanupMode,
     166                                        ComSafeArrayAsOutParam(aMedia)));
    164167        if (SUCCEEDED(rc))
    165168        {
    166             for (size_t u = 0;
    167                  u < abstrFiles.size();
    168                  ++u)
    169             {
    170                 Utf8Str strFile(abstrFiles[u]);
    171                 if (fDelete)
    172                 {
    173                     RTPrintf("Deleting '%s'\n", strFile.c_str());
    174                     RTFileDelete(strFile.c_str());
    175                 }
    176                 else
    177                     RTPrintf("File '%s' is now obsolete and can be deleted\n", strFile.c_str());
    178             }
    179 
    180169            if (fDelete)
    181170            {
    182                 CHECK_ERROR(machine, Delete());
     171                ComPtr<IProgress> pProgress;
     172                CHECK_ERROR(machine, Delete(ComSafeArrayAsInParam(aMedia), pProgress.asOutParam()));
     173                CHECK_ERROR(pProgress, WaitForCompletion(-1));
    183174            }
    184175        }
  • trunk/src/VBox/Frontends/VirtualBox/src/selector/VBoxSelectorWnd.cpp

    r31240 r31333  
    680680        {
    681681            CMachine machine = item->machine();
    682             QVector<QString> files = machine.Unregister(false /*fDetachMedia*/);
     682            QVector<CMedium> aMedia = machine.Unregister(KCleanupMode_UnregisterOnly);          //  @todo replace with DetachAllReturnHardDisksOnly once a progress dialog is in place below
    683683            if (machine.isOk() && item->accessible())
    684684            {
    685685                /* delete machine settings */
    686                 machine.Delete();
     686                CProgress progress = machine.Delete(aMedia);
     687                progress.WaitForCompletion(-1);         // @todo do this nicely with a progress dialog, this can delete many files!
     688
    687689                /* remove the item shortly: cmachine it refers to is no longer valid! */
    688690                int row = mVMModel->rowById (item->id());
  • trunk/src/VBox/Frontends/VirtualBox/src/wizards/newvm/UINewVMWzd.cpp

    r31070 r31333  
    782782        {
    783783            /* Unregister on failure */
    784             QVector<QString> files = m_Machine.Unregister(false /*fDetachMedia*/);
     784            QVector<CMedium> aMedia = m_Machine.Unregister(KCleanupMode_UnregisterOnly);   //  @todo replace with DetachAllReturnHardDisksOnly once a progress dialog is in place below
    785785            if (vbox.isOk())
    786                 m_Machine.Delete();
     786            {
     787                CProgress progress = m_Machine.Delete(aMedia);
     788                progress.WaitForCompletion(-1);         // @todo do this nicely with a progress dialog, this can delete lots of files
     789            }
    787790            return false;
    788791        }
  • trunk/src/VBox/Main/ApplianceImplImport.cpp

    r31070 r31333  
    12231223    {
    12241224        // with _whatever_ error we've had, do a complete roll-back of
    1225         // machines and disks we've created; unfortunately this is
    1226         // not so trivially done...
    1227 
    1228         HRESULT rc2;
    1229         // detach all hard disks from all machines we created
    1230         for (list<MyHardDiskAttachment>::iterator itM = stack.llHardDiskAttachments.begin();
    1231              itM != stack.llHardDiskAttachments.end();
    1232              ++itM)
    1233         {
    1234             const MyHardDiskAttachment &mhda = *itM;
    1235             rc2 = mhda.pMachine->LockMachine(stack.pSession, LockType_Write);
    1236             if (SUCCEEDED(rc2))
    1237             {
    1238                 ComPtr<IMachine> sMachine;
    1239                 rc2 = stack.pSession->COMGETTER(Machine)(sMachine.asOutParam());
    1240                 if (SUCCEEDED(rc2))
    1241                 {
    1242                     rc2 = sMachine->DetachDevice(Bstr(mhda.controllerType), mhda.lControllerPort, mhda.lDevice);
    1243                     rc2 = sMachine->SaveSettings();
    1244                 }
    1245                 stack.pSession->UnlockMachine();
    1246             }
    1247         }
    1248 
    1249         // now clean up all hard disks we created
    1250         for (list< ComPtr<IMedium> >::iterator itHD = stack.llHardDisksCreated.begin();
    1251              itHD != stack.llHardDisksCreated.end();
    1252              ++itHD)
    1253         {
    1254             ComPtr<IMedium> pDisk = *itHD;
    1255             ComPtr<IProgress> pProgress2;
    1256             rc2 = pDisk->DeleteStorage(pProgress2.asOutParam());
    1257             rc2 = pProgress2->WaitForCompletion(-1);
    1258         }
    1259 
    1260         // finally, deregister and remove all machines
     1225        // machines and disks we've created
     1226
    12611227        for (list<Guid>::iterator itID = m->llGuidsMachinesCreated.begin();
    12621228             itID != m->llGuidsMachinesCreated.end();
     
    12661232            Bstr bstrGuid = guid.toUtf16();
    12671233            ComPtr<IMachine> failedMachine;
    1268             SafeArray<BSTR> abstrPaths;
    1269             rc2 = mVirtualBox->GetMachine(bstrGuid, failedMachine.asOutParam());
     1234            HRESULT rc2 = mVirtualBox->GetMachine(bstrGuid, failedMachine.asOutParam());
    12701235            if (SUCCEEDED(rc2))
    12711236            {
    1272                 rc2 = failedMachine->Unregister(false, ComSafeArrayAsOutParam(abstrPaths));
    1273                 rc2 = failedMachine->Delete();
     1237                SafeIfaceArray<IMedium> aMedia;
     1238                rc2 = failedMachine->Unregister(CleanupMode_DetachAllReturnHardDisksOnly, ComSafeArrayAsOutParam(aMedia));
     1239                ComPtr<IProgress> pProgress2;
     1240                rc2 = failedMachine->Delete(ComSafeArrayAsInParam(aMedia), pProgress2.asOutParam());
     1241                pProgress2->WaitForCompletion(-1);
    12741242            }
    12751243        }
  • trunk/src/VBox/Main/MachineImpl.cpp

    r31332 r31333  
    39743974
    39753975/** @note Locks objects! */
    3976 STDMETHODIMP Machine::Unregister(BOOL fAutoCleanup,
    3977                                  ComSafeArrayOut(BSTR, aFiles))
     3976STDMETHODIMP Machine::Unregister(CleanupMode_T cleanupMode,
     3977                                 ComSafeArrayOut(IMedium*, aMedia))
    39783978{
    39793979    AutoCaller autoCaller(this);
     
    39893989    HRESULT rc = S_OK;
    39903990
    3991     // this list collects the files that should be reported
    3992     // as to be deleted to the caller in aFiles (this includes the
    3993     // media files in llMedia below)
    3994     std::list<Utf8Str> llFilesForCaller;
    3995 
    39963991    // discard saved state
    39973992    if (mData->mMachineState == MachineState_Saved)
     
    39993994        // add the saved state file to the list of files the caller should delete
    40003995        Assert(!mSSData->mStateFilePath.isEmpty());
    4001         llFilesForCaller.push_back(mSSData->mStateFilePath);
     3996        mData->llFilesToDelete.push_back(mSSData->mStateFilePath);
    40023997
    40033998        mSSData->mStateFilePath.setNull();
     
    40114006    if (mData->mFirstSnapshot)
    40124007        cSnapshots = mData->mFirstSnapshot->getAllChildrenCount() + 1;
    4013     if (cSnapshots && !fAutoCleanup)
     4008    if (cSnapshots && cleanupMode == CleanupMode_UnregisterOnly)
    40144009        // fail now before we start detaching media
    40154010        return setError(VBOX_E_INVALID_OBJECT_STATE,
     
    40344029    {
    40354030        // we have media attachments: detach them all and add the Medium objects to our list
    4036         if (fAutoCleanup)
    4037             detachAllMedia(alock, NULL /* pSnapshot */, llMedia);
     4031        if (cleanupMode != CleanupMode_UnregisterOnly)
     4032            detachAllMedia(alock, NULL /* pSnapshot */, cleanupMode, llMedia);
    40384033        else
    40394034            return setError(VBOX_E_INVALID_OBJECT_STATE,
     
    40614056
    40624057        // GO!
    4063         pFirstSnapshot->uninitRecursively(alock, llMedia, llFilesForCaller);
     4058        pFirstSnapshot->uninitRecursively(alock, cleanupMode, llMedia, mData->llFilesToDelete);
    40644059
    40654060        mData->mMachineState = oldState;
    40664061    }
    4067 
    40684062
    40694063    if (FAILED(rc))
     
    40814075    alock.release();
    40824076
    4083     if (fAutoCleanup)
    4084     {
    4085         // now go thru the list of attached media reported by prepareUnregister() and close them all
    4086         for (MediaList::const_iterator it = llMedia.begin();
    4087              it != llMedia.end();
    4088              ++it)
    4089         {
    4090             ComObjPtr<Medium> pMedium = *it;
    4091             Utf8Str strFile = pMedium->getLocationFull();
    4092 
    4093             AutoCaller autoCaller2(pMedium);
    4094             if (FAILED(autoCaller2.rc())) return autoCaller2.rc();
    4095 
    4096             ErrorInfoKeeper eik;
    4097             rc = pMedium->close(NULL /*fNeedsSaveSettings*/,     // we'll call saveSettings() in any case below
    4098                                 autoCaller2);
    4099                 // this uninitializes the medium
    4100 
    4101             LogFlowThisFunc(("Medium::close() on %s yielded rc (%Rhra)\n", strFile.c_str(), rc));
    4102 
    4103             if (rc == VBOX_E_OBJECT_IN_USE)
    4104                 // can happen if the medium was still attached to another machine;
    4105                 // do not report the file to the caller then, but don't report
    4106                 // an error either
    4107                 eik.setNull();
    4108             else if (SUCCEEDED(rc))
    4109                 // report the path to the caller
    4110                 llFilesForCaller.push_back(strFile);
    4111         }
    4112     }
    4113 
    4114     // report all paths to the caller
    4115     SafeArray<BSTR> sfaFiles(llFilesForCaller.size());
    4116     size_t i = 0;
    4117     for (std::list<Utf8Str>::iterator it = llFilesForCaller.begin();
    4118          it != llFilesForCaller.end();
    4119          ++it)
    4120         Bstr(*it).detachTo(&sfaFiles[i++]);
    4121     sfaFiles.detachTo(ComSafeArrayOutArg(aFiles));
     4077    // return media to caller
     4078    SafeIfaceArray<IMedium> sfaMedia(llMedia);
     4079    sfaMedia.detachTo(ComSafeArrayOutArg(aMedia));
    41224080
    41234081    mParent->unregisterMachine(this);
     
    41274085}
    41284086
    4129 STDMETHODIMP Machine::Delete()
    4130 {
     4087struct Machine::DeleteTask
     4088{
     4089    ComObjPtr<Machine>          pMachine;
     4090    std::list<Utf8Str>          llFilesToDelete;
     4091    ComObjPtr<Progress>         pProgress;
     4092};
     4093
     4094STDMETHODIMP Machine::Delete(ComSafeArrayIn(IMedium*, aMedia), IProgress **aProgress)
     4095{
     4096    LogFlowFuncEnter();
     4097
    41314098    AutoCaller autoCaller(this);
    41324099    if (FAILED(autoCaller.rc())) return autoCaller.rc();
    41334100
    41344101    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
     4102
     4103    bool fNeedsGlobalSaveSettings = false;
    41354104
    41364105    HRESULT rc = checkStateDependency(MutableStateDep);
     
    41404109        return setError(VBOX_E_INVALID_VM_STATE,
    41414110                        tr("Cannot delete settings of a registered machine"));
     4111
     4112    DeleteTask *pTask = new DeleteTask;
     4113    pTask->pMachine = this;
     4114    com::SafeIfaceArray<IMedium> sfaMedia(ComSafeArrayInArg(aMedia));
     4115
     4116    // collect files to delete
     4117    pTask->llFilesToDelete = mData->llFilesToDelete;            // saved states pushed here by Unregister()
     4118    for (size_t i = 0; i < sfaMedia.size(); ++i)
     4119    {
     4120        IMedium *pIMedium(sfaMedia[i]);
     4121        Medium *pMedium = static_cast<Medium*>(pIMedium);
     4122        AutoCaller mediumAutoCaller(pMedium);
     4123        if (FAILED(mediumAutoCaller.rc())) return mediumAutoCaller.rc();
     4124
     4125        Utf8Str bstrLocation = pMedium->getLocationFull();
     4126        // close the medium now; if that succeeds, then that means the medium is no longer
     4127        // in use and we can add it to the list of files to delete
     4128        rc = pMedium->close(&fNeedsGlobalSaveSettings, mediumAutoCaller);
     4129        if (SUCCEEDED(rc))
     4130            pTask->llFilesToDelete.push_back(bstrLocation);
     4131    }
     4132    if (mData->pMachineConfigFile->fileExists())
     4133        pTask->llFilesToDelete.push_back(mData->m_strConfigFileFull);
     4134
     4135    pTask->pProgress.createObject();
     4136    pTask->pProgress->init(getVirtualBox(),
     4137                           this /* aInitiator */,
     4138                           Bstr(tr("Deleting files")),
     4139                           true /* fCancellable */,
     4140                           pTask->llFilesToDelete.size() + 1,   // cOperations
     4141                           BstrFmt(tr("Deleting '%s'"), pTask->llFilesToDelete.front().c_str()));
     4142
     4143    int vrc = RTThreadCreate(NULL,
     4144                             Machine::deleteThread,
     4145                             (void*)pTask,
     4146                             0,
     4147                             RTTHREADTYPE_MAIN_WORKER,
     4148                             0,
     4149                             "MachineDelete");
     4150
     4151    alock.release();
     4152
     4153    if (fNeedsGlobalSaveSettings)
     4154    {
     4155        AutoWriteLock vboxlock(mParent COMMA_LOCKVAL_SRC_POS);
     4156        mParent->saveSettings();
     4157    }
     4158
     4159    if (RT_FAILURE(vrc))
     4160    {
     4161        delete pTask;
     4162        return setError(E_FAIL, "Could not create MachineDelete thread (%Rrc)", vrc);
     4163    }
     4164
     4165    pTask->pProgress.queryInterfaceTo(aProgress);
     4166
     4167    LogFlowFuncLeave();
     4168
     4169    return S_OK;
     4170}
     4171
     4172/**
     4173 * Static task wrapper passed to RTThreadCreate() in Machine::Delete() which then
     4174 * calls Machine::deleteTaskWorker() on the actual machine object.
     4175 * @param Thread
     4176 * @param pvUser
     4177 * @return
     4178 */
     4179/*static*/
     4180DECLCALLBACK(int) Machine::deleteThread(RTTHREAD Thread, void *pvUser)
     4181{
     4182    LogFlowFuncEnter();
     4183
     4184    DeleteTask *pTask = (DeleteTask*)pvUser;
     4185    Assert(pTask);
     4186    Assert(pTask->pMachine);
     4187    Assert(pTask->pProgress);
     4188
     4189    HRESULT rc = pTask->pMachine->deleteTaskWorker(*pTask);
     4190    pTask->pProgress->notifyComplete(rc);
     4191
     4192    delete pTask;
     4193
     4194    LogFlowFuncLeave();
     4195
     4196    NOREF(Thread);
     4197
     4198    return VINF_SUCCESS;
     4199}
     4200
     4201/**
     4202 * Task thread implementation for Machine::Delete(), called from Machine::deleteThread().
     4203 * @param task
     4204 * @return
     4205 */
     4206HRESULT Machine::deleteTaskWorker(DeleteTask &task)
     4207{
     4208    AutoCaller autoCaller(this);
     4209    if (FAILED(autoCaller.rc())) return autoCaller.rc();
     4210
     4211    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
    41424212
    41434213    ULONG uLogHistoryCount = 3;
     
    41474217        systemProperties->COMGETTER(LogHistoryCount)(&uLogHistoryCount);
    41484218
     4219    // delete the files pushed on the task list by Machine::Delete()
     4220    // (this includes saved states of the machine and snapshots and
     4221    // medium storage files from the IMedium list passed in, and the
     4222    // machine XML file)
     4223    std::list<Utf8Str>::const_iterator it = task.llFilesToDelete.begin();
     4224    while (it != task.llFilesToDelete.end())
     4225    {
     4226        const Utf8Str &strFile = *it;
     4227        LogFunc(("Deleting file %s\n", strFile.c_str()));
     4228        RTFileDelete(strFile.c_str());
     4229
     4230        ++it;
     4231        if (it == task.llFilesToDelete.end())
     4232        {
     4233            task.pProgress->SetNextOperation(Bstr(tr("Cleaning up machine directory")), 1);
     4234            break;
     4235        }
     4236
     4237        task.pProgress->SetNextOperation(BstrFmt(tr("Deleting '%s'"), it->c_str()), 1);
     4238    }
     4239
    41494240    /* delete the settings only when the file actually exists */
    41504241    if (mData->pMachineConfigFile->fileExists())
    41514242    {
    4152         int vrc = RTFileDelete(mData->m_strConfigFileFull.c_str());
    4153         if (RT_FAILURE(vrc))
    4154             return setError(VBOX_E_IPRT_ERROR,
    4155                             tr("Could not delete the settings file '%s' (%Rrc)"),
    4156                             mData->m_strConfigFileFull.raw(),
    4157                             vrc);
    4158 
    41594243        /* Delete any backup or uncommitted XML files. Ignore failures.
    41604244           See the fSafe parameter of xml::XmlFileWriter::write for details. */
     
    86528736/**
    86538737 * Goes thru all medium attachments of the list and calls detachDevice() on each
    8654  * of them and attaches all Medium objects found in the process to the given list.
     8738 * of them and attaches all Medium objects found in the process to the given list,
     8739 * depending on cleanupMode.
    86558740 *
    86568741 * This gets called from Machine::Unregister, both for the actual Machine and
     
    86608745 *
    86618746 * @param writeLock Machine lock from top-level caller; this gets passed to detachDevice.
    8662  * @param llMedia Caller's list to receive Medium objects which got detached so caller can close() them.
    86638747 * @param pSnapshot Must be NULL when called for a "real" Machine or a snapshot object if called for a SnapshotMachine.
     8748 * @param cleanupMode If DetachAllReturnHardDisksOnly, only hard disk media get added to llMedia; if Full, then all media get added;
     8749 *          otherwise no media get added.
     8750 * @param llMedia Caller's list to receive Medium objects which got detached so caller can close() them, depending on cleanupMode.
    86648751 * @return
    86658752 */
    86668753HRESULT Machine::detachAllMedia(AutoWriteLock &writeLock,
    86678754                                Snapshot *pSnapshot,
     8755                                CleanupMode_T cleanupMode,
    86688756                                MediaList &llMedia)
    86698757{
     
    86848772
    86858773        if (!pMedium.isNull())
    8686             llMedia.push_back(pMedium);
     8774        {
     8775            DeviceType_T devType = pMedium->getDeviceType();
     8776            if (    (    cleanupMode == CleanupMode_DetachAllReturnHardDisksOnly
     8777                      && devType == DeviceType_HardDisk)
     8778                 || (cleanupMode == CleanupMode_Full)
     8779               )
     8780                llMedia.push_back(pMedium);
     8781        }
    86878782
    86888783        // real machine: then we need to use the proper method
  • trunk/src/VBox/Main/MediumImpl.cpp

    r31308 r31333  
    38673867    // we're accessing parent/child and backrefs, so lock the tree first, then ourselves
    38683868    AutoMultiWriteLock2 multilock(&m->pVirtualBox->getMediaTreeLockHandle(),
    3869                                    this->lockHandle()
    3870                                            COMMA_LOCKVAL_SRC_POS);
     3869                                  this->lockHandle()
     3870                                  COMMA_LOCKVAL_SRC_POS);
     3871
     3872    LogFlowFunc(("ENTER for %s\n", getLocationFull().c_str()));
    38713873
    38723874    bool wasCreated = true;
     
    38863888    if (m->backRefs.size() != 0)
    38873889        return setError(VBOX_E_OBJECT_IN_USE,
    3888                         tr("Medium '%s' is attached to %d virtual machines"),
     3890                        tr("Medium '%s' cannot be closed because it is still attached to %d virtual machines"),
    38893891                           m->strLocationFull.raw(), m->backRefs.size());
    38903892
     
    39083910    // of the medium tree cannot be guaranteed.
    39093911    uninit();
     3912
     3913    LogFlowFuncLeave();
    39103914
    39113915    return rc;
  • trunk/src/VBox/Main/ProgressImpl.cpp

    r30714 r31333  
    10841084    AssertReturn(mCompleted == FALSE, E_FAIL);
    10851085
     1086    LogFunc(("aResultCode=%d\n", aResultCode));
     1087
    10861088    if (mCanceled && SUCCEEDED(aResultCode))
    10871089        aResultCode = E_FAIL;
     
    11051107    /* wake up all waiting threads */
    11061108    if (mWaitersCount > 0)
    1107         RTSemEventMultiSignal (mCompletedSem);
     1109        RTSemEventMultiSignal(mCompletedSem);
    11081110
    11091111    return rc;
  • trunk/src/VBox/Main/SnapshotImpl.cpp

    r31307 r31333  
    828828 * Caller must hold the machine write lock (which protects the snapshots tree!)
    829829 *
     830 * @param writeLock Machine write lock, which can get released temporarily here.
     831 * @param cleanupMode Cleanup mode; see Machine::detachAllMedia().
     832 * @param llMedia List of media returned to caller, depending on cleanupMode.
    830833 * @param llFilenames
    831834 * @return
    832835 */
    833836HRESULT Snapshot::uninitRecursively(AutoWriteLock &writeLock,
     837                                    CleanupMode_T cleanupMode,
    834838                                    MediaList &llMedia,
    835839                                    std::list<Utf8Str> &llFilenames)
     
    858862    {
    859863        Snapshot *pChild = *it;
    860         rc = pChild->uninitRecursively(writeLock, llMedia, llFilenames);
     864        rc = pChild->uninitRecursively(writeLock, cleanupMode, llMedia, llFilenames);
    861865        if (FAILED(rc))
    862866            return rc;
     
    866870    rc = m->pMachine->detachAllMedia(writeLock,
    867871                                     this /* pSnapshot */,
     872                                     cleanupMode,
    868873                                     llMedia);
    869874    if (FAILED(rc))
  • trunk/src/VBox/Main/idl/VirtualBox.xidl

    r31332 r31333  
    27842784      </param>
    27852785      <param name="aProgress" type="IProgress" dir="return">
    2786         <desc></desc>
     2786        <desc>Progress object to track the operation completion.</desc>
    27872787      </param>
    27882788    </method>
     
    28242824
    28252825      <param name="aProgress" type="IProgress" dir="return">
    2826         <desc></desc>
     2826        <desc>Progress object to track the operation completion.</desc>
    28272827      </param>
    28282828    </method>
     
    32223222        to signal the completion of the progress object.
    32233223      </desc>
    3224       <param name="progress" type="IProgress" dir="in"/>
     3224      <param name="aProgress" type="IProgress" dir="in" />
    32253225    </method>
    32263226
     
    36363636  </interface>
    36373637
     3638  <enum name="CleanupMode"
     3639        uuid="67897c50-7cca-47a9-83f6-ce8fd8eb5441">
     3640    <desc>Cleanup mode, used with <link to="IMachine::unregister" />.
     3641    </desc>
     3642    <const name="UnregisterOnly"                  value="1">
     3643      <desc>Unregister only the machine, but neither delete snapshots nor detach media.</desc>
     3644    </const>
     3645    <const name="DetachAllReturnNone"             value="2">
     3646      <desc>Delete all snapshots and detach all media but return none; this will keep all media registered.</desc>
     3647    </const>
     3648    <const name="DetachAllReturnHardDisksOnly"    value="3">
     3649      <desc>Delete all snapshots, detach all media and return hard disks for closing, but not removeable media.</desc>
     3650    </const>
     3651    <const name="Full"                            value="4">
     3652      <desc>Delete all snapshots, detach all media and return all media for closing.</desc>
     3653    </const>
     3654  </enum>
     3655
    36383656  <interface
    36393657     name="IMachine" extends="$unknown"
    3640      uuid="e2d8679e-b144-41d9-9dfa-bbe2fd0ab2d1"
     3658     uuid="082c38ff-d9b3-4b12-b540-01516a931f17"
    36413659     wsmap="managed"
    36423660     >
     
    38393857         Priority of the virtual CPUs. Means to limit the number of CPU cycles
    38403858         a guest can use. The unit is percentage of host CPU cycles per second.
    3841          The valid range is 1 - 100. 100 (the default) implies no limit. 
     3859         The valid range is 1 - 100. 100 (the default) implies no limit.
    38423860       </desc>
    38433861    </attribute>
     
    51865204      <desc>
    51875205        Unregisters the machine, which must have been previously registered using
    5188         <link to="IVirtualBox::registerMachine"/>.
    5189 
    5190         This method will succeed even if the machine currently has media attachments or
    5191         is in the <link to="MachineState::Saved">Saved</link> state. In those cases,
    5192         the caller receives the names of all files that have been made obsolete by the
    5193         call in the @a aFiles array parameter. This list will consist of the saved
    5194         state file and all storage files by media that were detached from the machine.
    5195 
    5196         <note>
    5197           The @a fAutoCleanup parameter is temporary to avoid substantial changes to the
    5198           frontends in SVN trunk.It will go away before the 3.3 release and
    5199           always be true then. If fAutoCleanup is false, the API currently behaves like
    5200           the old VirtualBox::UnregisterMachine API. Cleaning up snapshots does not work
    5201           yet, so the method will still fail if the machine has snapshots.
    5202         </note>
    5203 
    5204         The settings XML file of the machine object itself will not be included in that
    5205         list; call <link to="#delete" /> for that.
     5206        <link to="IVirtualBox::registerMachine"/>, and optionally do additional
     5207        cleanup before the machine is unregistered.
     5208
     5209        This method does not delete any files. It only changes the machine configuration and
     5210        the list of registered machines in the VirtualBox object. To delete the files which
     5211        belonged to the machine, including the XML file of the machine itself, call
     5212        <link to="#delete"/>, optionally with the array of IMedium objects that have been
     5213        returned from this method.
     5214
     5215        Depending on the @a cleanupMode argument, the thoroughness with with this
     5216        method cleans up the machine configuration before unregistering the machine
     5217        will vary.
     5218
     5219        <ul>
     5220          <li>With "UnregisterOnly", the machine will only be unregistered, but no additional
     5221            cleanup will be performed. The call will fail if the machine is in "Saved" state
     5222            or has any snapshots or any media attached (see <link to="IMediumAttachment" />.
     5223            It is the responsibility of the caller to delete all such configuration in this mode.
     5224            In this mode, the API behaves like the former @c IVirtualBox::unregisterMachine() API
     5225            which it replaces.</li>
     5226          <li>With "DetachAllReturnNone", the call will succeed even if the machine is in "Saved"
     5227            state or if it has snapshots or media attached. All media attached to the current machine
     5228            state or in snapshots will be detached. No medium objects will be closed or returned; all
     5229            of the machine's media will remain opened.</li>
     5230          <li>With "DetachAllReturnHardDisksOnly", the call will behave like with "DetachAllReturnNone",
     5231            except that all the hard disk medium objects which were detached from the machine will
     5232            be returned as an array. This allows for quickly passing them to the <link to="#delete" />
     5233            API for closing and deletion.</li>
     5234          <li>With "Full", the call will behave like with "DetachAllReturnHardDisksOnly", except
     5235            that all media will be returned in the array, including removeable media like DVDs and
     5236            floppies. This might be useful if the user wants to inspect in detail which media were
     5237            attached to the machine.</li>
     5238        </ul>
    52065239
    52075240        The call will fail if the machine is currently locked (see <link to="ISession" />).
     
    52095242        before unregistering it.
    52105243
    5211         After successful method invocation,
    5212         the <link to="IMachineRegisteredEvent"/> event is fired.
     5244        After successful method invocation, the <link to="IMachineRegisteredEvent"/> event
     5245        is fired.
    52135246
    52145247        <note>
     
    52205253
    52215254        <result name="VBOX_E_INVALID_OBJECT_STATE">
    5222           Machine has snapshot or is locked.
    5223         </result>
    5224       </desc>
    5225 
    5226       <param name="fAutoCleanup" type="boolean" dir="in">
    5227         <desc>If true, the method will automatically detach all media from the
    5228           machine and its snapshots, call <link to="IMedium::close" /> on each
    5229           medium, and the paths of all media files involved will be reported to
    5230           the caller in the @a aFiles array so the caller can then delete the
    5231           image files.
    5232           If false, the method will fail if media attachments are present.
    5233         </desc>
    5234       </param>
    5235       <param name="aFiles" type="wstring" safearray="yes" dir="return">
    5236         <desc>
    5237           List of all files detached from medium attachments of the machine, if
    5238           @a fCloseMedia is true.
    5239         </desc>
     5255          Machine is currently locked for a session.
     5256        </result>
     5257      </desc>
     5258
     5259      <param name="cleanupMode" type="CleanupMode" dir="in">
     5260        <desc>How to clean up after the machine has been unregistered.</desc>
     5261      </param>
     5262      <param name="aMedia" type="IMedium" safearray="yes" dir="return">
     5263        <desc>List of media detached from the machine, depending on the @a cleanupMode parameter.</desc>
    52405264      </param>
    52415265    </method>
     
    52435267    <method name="delete">
    52445268      <desc>
    5245         Deletes the settings (machine XML) file of this machine from disk. The machine
    5246         must not be registered in order for this operation to succeed.
     5269        Deletes the files associated with this machine from disk. If medium objects are passed
     5270        in with the @a aMedia argument, they are closed and their storage files are deleted as well.
     5271        For convenience, this array of media files can be the same as the one returned from
     5272        a previous <a link="#unregister" /> call.
     5273
     5274        This method must only be called on machines which are either write-locked (i.e. on instances
     5275        returned by <link to="ISession::machine"/>) or on unregistered machines (i.e. not yet
     5276        registered machines created by <link to="IVirtualBox::createMachine"/> or opened by
     5277        <link to="IVirtualBox::openMachine"/>, or after having called <link to="#unregister"/>).
     5278
     5279        The following files will be deleted by this method:
     5280        <ul>
     5281          <li>If <link to="#unregister" /> had been previously called with a @a cleanupMode
     5282            argument other than "UnregisterOnly", this will delete all saved state files that
     5283            the machine had in use; possibly one if the machine was in "Saved" state and one
     5284            for each online snapshot that the machine had.</li>
     5285          <li>On each medium object passed in the @a aMedia array, this will call
     5286            <link to="IMedium::close" /> and then attempt to delete the medium's storage
     5287            on disk. The close() call will fail if the medium is still in use, e.g. because
     5288            it is still attached to a second machine.</li>
     5289          <li>Finally, the machine's own XML file will be deleted.</li>
     5290        </ul>
     5291
     5292        Since deleting large disk image files can be a time-consuming I/O operation, this
     5293        method operates asynchronously and returns an IProgress object to allow the caller
     5294        to monitor the progress. There will be one sub-operation for each file that is
     5295        being deleted (saved state or medium storage file).
     5296
    52475297        <note>
    52485298          <link to="#settingsModified"/> will return @c true after this
    52495299          method successfully returns.
    52505300        </note>
    5251         <note>
    5252           Calling this method is only valid on instances returned
    5253           by <link to="ISession::machine"/> and on new machines
    5254           created by <link to="IVirtualBox::createMachine"/> or
    5255           opened by <link to="IVirtualBox::openMachine"/> but not
    5256           yet registered, or on unregistered machines after calling
    5257           <link to="IMachine::unregister"/>.
    5258         </note>
    5259         <note>
    5260           The deleted machine settings file can be restored (saved again)
    5261           by calling <link to="#saveSettings"/>.
    5262         </note>
    52635301
    52645302        <result name="VBOX_E_INVALID_VM_STATE">
    5265           Cannot delete settings of a registered machine or
    5266           machine not mutable.
     5303          Machine is registered but not write-locked.
    52675304        </result>
    52685305        <result name="VBOX_E_IPRT_ERROR">
    52695306          Could not delete the settings file.
    52705307        </result>
    5271 
    5272       </desc>
     5308      </desc>
     5309      <param name="aMedia" type="IMedium" safearray="yes" dir="in">
     5310        <desc>List of media to be closed and whose storage files will be deleted.</desc>
     5311      </param>
     5312      <param name="aProgress" type="IProgress" dir="return">
     5313        <desc>Progress object to track the operation completion.</desc>
     5314      </param>
    52735315    </method>
    52745316
    52755317    <method name="export">
    5276         <desc>Exports the machine to an OVF appliance. See <link to="IAppliance" /> for the
    5277               steps required to export VirtualBox machines to OVF.
    5278         </desc>
    5279 
    5280         <param name="aAppliance" type="IAppliance" dir="in">
    5281             <desc>Appliance to export this machine to.</desc>
    5282         </param>
    5283         <param name="aDescription" type="IVirtualSystemDescription" dir="return">
    5284             <desc>VirtualSystemDescription object which is created for this machine.</desc>
    5285         </param>
     5318      <desc>Exports the machine to an OVF appliance. See <link to="IAppliance" /> for the
     5319            steps required to export VirtualBox machines to OVF.
     5320      </desc>
     5321
     5322      <param name="aAppliance" type="IAppliance" dir="in">
     5323        <desc>Appliance to export this machine to.</desc>
     5324      </param>
     5325      <param name="aDescription" type="IVirtualSystemDescription" dir="return">
     5326        <desc>VirtualSystemDescription object which is created for this machine.</desc>
     5327      </param>
    52865328    </method >
    52875329
  • trunk/src/VBox/Main/include/MachineImpl.h

    r31332 r31333  
    181181        ComObjPtr<Snapshot> mFirstSnapshot;
    182182        ComObjPtr<Snapshot> mCurrentSnapshot;
     183
     184        // list of files to delete in Delete(); this list is filled by Unregister()
     185        std::list<Utf8Str>  llFilesToDelete;
    183186    };
    184187
     
    484487    STDMETHOD(SaveSettings)();
    485488    STDMETHOD(DiscardSettings)();
    486     STDMETHOD(Unregister) (BOOL fAutoCleanup, ComSafeArrayOut(BSTR, aFiles));
    487     STDMETHOD(Delete)();
     489    STDMETHOD(Unregister)(CleanupMode_T cleanupMode, ComSafeArrayOut(IMedium*, aMedia));
     490    STDMETHOD(Delete)(ComSafeArrayIn(IMedium*, aMedia), IProgress **aProgress);
    488491    STDMETHOD(Export)(IAppliance *aAppliance, IVirtualSystemDescription **aDescription);
    489492    STDMETHOD(GetSnapshot)(IN_BSTR aId, ISnapshot **aSnapshot);
     
    782785    HRESULT detachAllMedia(AutoWriteLock &writeLock,
    783786                           Snapshot *pSnapshot,
     787                           CleanupMode_T cleanupMode,
    784788                           MediaList &llMedia);
    785789
     
    792796    void commit();
    793797    void copyFrom(Machine *aThat);
     798
     799    struct DeleteTask;
     800    static DECLCALLBACK(int) deleteThread(RTTHREAD Thread, void *pvUser);
     801    HRESULT deleteTaskWorker(DeleteTask &task);
    794802
    795803#ifdef VBOX_WITH_GUEST_PROPS
  • trunk/src/VBox/Main/include/SnapshotImpl.h

    r31228 r31333  
    125125
    126126    HRESULT uninitRecursively(AutoWriteLock &writeLock,
     127                              CleanupMode_T cleanupMode,
    127128                              MediaList &llMedia,
    128129                              std::list<Utf8Str> &llFilenames);
  • trunk/src/VBox/Main/testcase/tstOVF.cpp

    r30956 r31333  
    349349
    350350            RTPrintf("  Deleting machine %ls...\n", bstrUUID.raw());
    351             SafeArray<BSTR> sfaFiles;
    352             rc = pMachine->Unregister(true /* fDetachMedia */,
    353                                       ComSafeArrayAsOutParam(sfaFiles));
     351            SafeIfaceArray<IMedium> sfaMedia;
     352            rc = pMachine->Unregister(CleanupMode_DetachAllReturnHardDisksOnly,
     353                                      ComSafeArrayAsOutParam(sfaMedia));
    354354            if (FAILED(rc)) throw MyError(rc, "Machine::Unregister() failed\n");
    355355
    356             for (size_t u = 0;
    357                  u < sfaFiles.size();
    358                  ++u)
    359             {
    360                 RTPrintf("    UnregisterMachine reported disk image %ls\n", sfaFiles[u]);
    361                 llFiles2Delete.push_back(sfaFiles[u]);
    362             }
    363 
    364             rc = pMachine->Delete();
     356            ComPtr<IProgress> pProgress;
     357            rc = pMachine->Delete(ComSafeArrayAsInParam(sfaMedia), pProgress.asOutParam());
    365358            if (FAILED(rc)) throw MyError(rc, "Machine::DeleteSettings() failed\n");
     359            rc = pProgress->WaitForCompletion(-1);
     360            if (FAILED(rc)) throw MyError(rc, "Progress::WaitForCompletion() failed\n");
    366361        }
    367362    }
  • trunk/src/VBox/Main/webservice/websrv-cpp.xsl

    r30577 r31333  
    568568          <xsl:call-template name="emitNewlineIndent8" />
    569569          <xsl:value-of select="concat('    IUnknown *tmpObject2(tmpObject); tmpObject2->AddRef(); comcall_', $name, '[i] = tmpObject;')" />
     570        </xsl:when>
     571        <xsl:when test="//interface[@name=$type]">
     572          <xsl:value-of select="concat('    ComPtr&lt;', $type, '&gt; tmpObject;')" />
     573          <xsl:call-template name="emitNewlineIndent8" />
     574          <xsl:value-of select="concat('    if ((rc = findComPtrFromId(soap, ', $structprefix, $name, '[i], tmpObject, true)))')" />
     575          <xsl:call-template name="emitNewlineIndent8" />
     576          <xsl:text>        break;</xsl:text>
     577          <xsl:call-template name="emitNewlineIndent8" />
     578          <xsl:value-of select="concat('    ', $type, ' *tmpObject2(tmpObject); tmpObject2->AddRef(); comcall_', $name, '[i] = tmpObject;')" />
    570579        </xsl:when>
    571580        <xsl:when test="$type='wstring'">
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette