VirtualBox

Changeset 81425 in vbox for trunk/src/VBox/Main/src-server


Ignore:
Timestamp:
Oct 21, 2019 6:19:39 PM (5 years ago)
Author:
vboxsync
Message:

Main/Machine+BIOSSettings+Console: Full implementation of NVRAM handling (part of VM delete, rename, clone and move code in combination with taking, deleting and restoring snapshots). Corresponding console update (ripping out old, never really used NVRAM handling).

Location:
trunk/src/VBox/Main/src-server
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Main/src-server/BIOSSettingsImpl.cpp

    r81299 r81425  
    153153    m->bd.attachCopy(that->m->bd);
    154154
     155    // Intentionally "forget" the NVRAM file since it must be unique and set
     156    // to the correct value before the copy of the settings makes sense.
     157    m->bd->strNVRAMPath.setNull();
     158
    155159    autoInitSpan.setSucceeded();
    156160
     
    373377
    374378    m->bd.backup();
    375 
    376379    m->bd->fIOAPICEnabled = RT_BOOL(aIOAPICEnabled);
     380
    377381    alock.release();
    378382    AutoWriteLock mlock(m->pMachine COMMA_LOCKVAL_SRC_POS);  // mParent is const, needs no locking
     
    401405
    402406    m->bd.backup();
    403 
    404407    m->bd->apicMode = aAPICMode;
     408
    405409    alock.release();
    406410    AutoWriteLock mlock(m->pMachine COMMA_LOCKVAL_SRC_POS);  // mParent is const, needs no locking
     
    591595    /* this will back up current data */
    592596    m->bd.assignCopy(aThat->m->bd);
     597
     598    // Intentionally "forget" the NVRAM file since it must be unique and set
     599    // to the correct value before the copy of the settings makes sense.
     600    m->bd->strNVRAMPath.setNull();
     601
    593602}
    594603
     
    608617}
    609618
     619Utf8Str BIOSSettings::i_getNonVolatileStorageFile()
     620{
     621    AutoCaller autoCaller(this);
     622    AssertComRCReturn(autoCaller.rc(), Utf8Str::Empty);
     623
     624    Utf8Str strTmp;
     625    BIOSSettings::getNonVolatileStorageFile(strTmp);
     626    return strTmp;
     627}
     628
    610629void BIOSSettings::i_updateNonVolatileStorageFile(const Utf8Str &aNonVolatileStorageFile)
    611630{
  • trunk/src/VBox/Main/src-server/MachineImpl.cpp

    r81422 r81425  
    50255025    if (!mData->mAccessible)
    50265026    {
    5027         // inaccessible maschines can only be unregistered; uninitialize ourselves
     5027        // inaccessible machines can only be unregistered; uninitialize ourselves
    50285028        // here because currently there may be no unregistered that are inaccessible
    50295029        // (this state combination is not supported). Note releasing the caller and
     
    50415041
    50425042    HRESULT rc = S_OK;
    5043 
    5044     /// @todo r=klaus this is stupid... why is the saved state always deleted?
    5045     // discard saved state
    5046     if (mData->mMachineState == MachineState_Saved)
    5047     {
    5048         // add the saved state file to the list of files the caller should delete
    5049         Assert(!mSSData->strStateFilePath.isEmpty());
     5043    mData->llFilesToDelete.clear();
     5044
     5045    if (!mSSData->strStateFilePath.isEmpty())
    50505046        mData->llFilesToDelete.push_back(mSSData->strStateFilePath);
    50515047
    5052         mSSData->strStateFilePath.setNull();
    5053 
    5054         // unconditionally set the machine state to powered off, we now
    5055         // know no session has locked the machine
    5056         mData->mMachineState = MachineState_PoweredOff;
    5057     }
    5058 
    5059     size_t cSnapshots = 0;
    5060     if (mData->mFirstSnapshot)
    5061         cSnapshots = mData->mFirstSnapshot->i_getAllChildrenCount() + 1;
    5062     if (cSnapshots && aCleanupMode == CleanupMode_UnregisterOnly)
    5063         // fail now before we start detaching media
    5064         return setError(VBOX_E_INVALID_OBJECT_STATE,
    5065                         tr("Cannot unregister the machine '%s' because it has %d snapshots"),
    5066                            mUserData->s.strName.c_str(), cSnapshots);
     5048    Utf8Str strNVRAMFile = mBIOSSettings->i_getNonVolatileStorageFile();
     5049    if (!strNVRAMFile.isEmpty() && RTFileExists(strNVRAMFile.c_str()))
     5050        mData->llFilesToDelete.push_back(strNVRAMFile);
    50675051
    50685052    // This list collects the medium objects from all medium attachments
     
    50825066    {
    50835067        // we have media attachments: detach them all and add the Medium objects to our list
    5084         if (aCleanupMode != CleanupMode_UnregisterOnly)
    5085             i_detachAllMedia(alock, NULL /* pSnapshot */, aCleanupMode, llMedia);
    5086         else
    5087             return setError(VBOX_E_INVALID_OBJECT_STATE,
    5088                             tr("Cannot unregister the machine '%s' because it has %d media attachments"),
    5089                             mUserData->s.strName.c_str(), mMediumAttachments->size());
    5090     }
    5091 
    5092     if (cSnapshots)
     5068        i_detachAllMedia(alock, NULL /* pSnapshot */, aCleanupMode, llMedia);
     5069    }
     5070
     5071    if (mData->mFirstSnapshot)
    50935072    {
    50945073        // add the media from the medium attachments of the snapshots to llMedia
     
    51015080        mData->mMachineState = MachineState_DeletingSnapshot;
    51025081
    5103         // make a copy of the first snapshot so the refcount does not drop to 0
    5104         // in beginDeletingSnapshot, which sets pFirstSnapshot to 0 (that hangs
    5105         // because of the AutoCaller voodoo)
     5082        // make a copy of the first snapshot reference so the refcount does not
     5083        // drop to 0 in beginDeletingSnapshot, which sets pFirstSnapshot to 0
     5084        // (would hang due to the AutoCaller voodoo)
    51065085        ComObjPtr<Snapshot> pFirstSnapshot = mData->mFirstSnapshot;
    51075086
     
    51255104    // machine lock no longer needed
    51265105    alock.release();
     5106
     5107    /* Make sure that the settings of the current VM are not saved, because
     5108     * they are rather crippled at this point to meet the cleanup expectations
     5109     * and there's no point destroying the VM config on disk just because. */
     5110    mParent->i_unmarkRegistryModified(id);
    51275111
    51285112    // return media to caller
     
    53655349
    53665350    // collect files to delete
    5367     StringsList llFilesToDelete(mData->llFilesToDelete);    // saved states pushed here by Unregister()
     5351    StringsList llFilesToDelete(mData->llFilesToDelete);    // saved states and NVRAM files pushed here by Unregister()
     5352    // machine config file
    53685353    if (mData->pMachineConfigFile->fileExists())
    53695354        llFilesToDelete.push_back(mData->m_strConfigFileFull);
     5355    // backup of machine config file
     5356    Utf8Str strTmp(mData->m_strConfigFileFull);
     5357    strTmp.append("-prev");
     5358    if (RTFileExists(strTmp.c_str()))
     5359        llFilesToDelete.push_back(strTmp);
    53705360
    53715361    RTCList<ComPtr<IMedium> > llMediums;
     
    73627352/**
    73637353 * Returns the default NVRAM filename based on the location of the VM config.
    7364  * This intentionally works differently than the saved state file naming since
    7365  * it is part of the current state. Taking a snapshot will use a similar naming
    7366  * as for saved state, because these are actually read-only, retaining a
    7367  * a specific state just like saved state. Note that this is a relative path.
     7354 * Note that this is a relative path.
    73687355 */
    7369 
    73707356Utf8Str Machine::i_getDefaultNVRAMFilename()
    73717357{
     
    73757361    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
    73767362
    7377     if (mHWData->mFirmwareType == FirmwareType_BIOS)
     7363    if (   mHWData->mFirmwareType == FirmwareType_BIOS
     7364        || i_isSnapshotMachine())
    73787365        return Utf8Str::Empty;
    73797366
     
    73867373}
    73877374
     7375/**
     7376 * Returns the NVRAM filename for a new snapshot. This intentionally works
     7377 * similarly to the saved state file naming. Note that this is usually
     7378 * a relative path, unless the snapshot folder is absolute.
     7379 */
     7380Utf8Str Machine::i_getSnapshotNVRAMFilename()
     7381{
     7382    AutoCaller autoCaller(this);
     7383    AssertComRCReturn(autoCaller.rc(), Utf8Str::Empty);
     7384
     7385    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
     7386
     7387    if (mHWData->mFirmwareType == FirmwareType_BIOS)
     7388        return Utf8Str::Empty;
     7389
     7390    RTTIMESPEC ts;
     7391    RTTimeNow(&ts);
     7392    RTTIME time;
     7393    RTTimeExplode(&time, &ts);
     7394
     7395    Utf8Str strNVRAMFilePath = mUserData->s.strSnapshotFolder;
     7396    strNVRAMFilePath += RTPATH_DELIMITER;
     7397    strNVRAMFilePath += Utf8StrFmt("%04d-%02u-%02uT%02u-%02u-%02u-%09uZ.nvram",
     7398                                   time.i32Year, time.u8Month, time.u8MonthDay,
     7399                                   time.u8Hour, time.u8Minute, time.u8Second, time.u32Nanosecond);
     7400
     7401    return strNVRAMFilePath;
     7402}
    73887403
    73897404/**
     
    97279742        Utf8Str configFile, newConfigFile;
    97289743        Utf8Str configFilePrev, newConfigFilePrev;
     9744        Utf8Str NVRAMFile, newNVRAMFile;
    97299745        Utf8Str configDir, newConfigDir;
    97309746
     
    98369852                    newConfigFilePrev += "-prev";
    98379853                    RTFileRename(configFilePrev.c_str(), newConfigFilePrev.c_str(), 0);
     9854                    NVRAMFile = mBIOSSettings->i_getNonVolatileStorageFile();
     9855                    if (NVRAMFile.isNotEmpty())
     9856                    {
     9857                        // in the NVRAM file path, replace the old directory with the new directory
     9858                        if (RTPathStartsWith(NVRAMFile.c_str(), configDir.c_str()))
     9859                        {
     9860                            Utf8Str strNVRAMFile = NVRAMFile.c_str() + configDir.length();
     9861                            NVRAMFile = newConfigDir + strNVRAMFile;
     9862                        }
     9863                        newNVRAMFile = newConfigFile;
     9864                        newNVRAMFile.stripSuffix();
     9865                        newNVRAMFile += ".nvram";
     9866                        RTFileRename(NVRAMFile.c_str(), newNVRAMFile.c_str(), 0);
     9867                    }
    98389868                }
    98399869            }
     
    98619891                mSSData->strStateFilePath = newConfigDir + strStateFileName;
    98629892            }
    9863 
    9864             // and do the same thing for the saved state file paths of all the online snapshots
     9893            if (newNVRAMFile.isNotEmpty())
     9894                mBIOSSettings->i_updateNonVolatileStorageFile(newNVRAMFile);
     9895
     9896            // and do the same thing for the saved state file paths of all the online snapshots and NVRAM files of all snapshots
    98659897            if (mData->mFirstSnapshot)
     9898            {
    98669899                mData->mFirstSnapshot->i_updateSavedStatePaths(configDir.c_str(),
    98679900                                                               newConfigDir.c_str());
     9901                mData->mFirstSnapshot->i_updateNVRAMPaths(configDir.c_str(),
     9902                                                          newConfigDir.c_str());
     9903            }
    98689904        }
    98699905        while (0);
     
    98769912                RTFileRename(newConfigFilePrev.c_str(), configFilePrev.c_str(), 0);
    98779913                RTFileRename(newConfigFile.c_str(), configFile.c_str(), 0);
     9914                if (NVRAMFile.isNotEmpty() && newNVRAMFile.isNotEmpty())
     9915                    RTFileRename(newNVRAMFile.c_str(), NVRAMFile.c_str(), 0);
    98789916            }
    98799917            if (dirRenamed)
  • trunk/src/VBox/Main/src-server/MachineImplCloneVM.cpp

    r80585 r81425  
    5656{
    5757    Guid                    snapshotUuid;
    58     Utf8Str                 strSaveStateFile;
     58    Utf8Str                 strFile;
    5959    ULONG                   uWeight;
    60 } SAVESTATETASK;
     60} FILECOPYTASK;
    6161
    6262// The private class
     
    107107    inline void updateProgressStats(MEDIUMTASKCHAIN &mtc, bool fAttachLinked, ULONG &uCount, ULONG &uTotalWeight) const;
    108108    inline HRESULT addSaveState(const ComObjPtr<Machine> &machine, bool fAttachCurrent, ULONG &uCount, ULONG &uTotalWeight);
     109    inline HRESULT addNVRAM(const ComObjPtr<Machine> &machine, bool fAttachCurrent, ULONG &uCount, ULONG &uTotalWeight);
    109110    inline HRESULT queryBaseName(const ComPtr<IMedium> &pMedium, Utf8Str &strBaseName) const;
    110111    HRESULT queryMediasForMachineState(const RTCList<ComObjPtr<Machine> > &machineList,
     
    121122    void updateStorageLists(settings::StorageControllersList &sc, const Bstr &bstrOldId, const Bstr &bstrNewId) const;
    122123    void updateSnapshotStorageLists(settings::SnapshotsList &sl, const Bstr &bstrOldId, const Bstr &bstrNewId) const;
    123     void updateStateFile(settings::SnapshotsList &snl, const Guid &id, const Utf8Str &strFile) const;
     124    void updateSaveStateFile(settings::SnapshotsList &snl, const Guid &id, const Utf8Str &strFile) const;
     125    void updateNVRAMFile(settings::SnapshotsList &snl, const Guid &id, const Utf8Str &strFile) const;
    124126    HRESULT createDifferencingMedium(const ComObjPtr<Machine> &pMachine, const ComObjPtr<Medium> &pParent,
    125127                                     const Utf8Str &strSnapshotFolder, RTCList<ComObjPtr<Medium> > &newMedia,
    126128                                     ComObjPtr<Medium> *ppDiff) const;
    127     static DECLCALLBACK(int) copyStateFileProgress(unsigned uPercentage, void *pvUser);
     129    static DECLCALLBACK(int) copyFileProgress(unsigned uPercentage, void *pvUser);
    128130    static void updateSnapshotHardwareUUIDs(settings::SnapshotsList &snapshot_list, const Guid &id);
    129131
     
    141143    RTCList<CloneOptions_T>     options;
    142144    RTCList<MEDIUMTASKCHAIN>    llMedias;
    143     RTCList<SAVESTATETASK>      llSaveStateFiles; /* Snapshot UUID -> File path */
     145    RTCList<FILECOPYTASK>       llSaveStateFiles; /* Snapshot UUID -> File path */
     146    RTCList<FILECOPYTASK>       llNVRAMFiles; /* Snapshot UUID -> File path */
    144147};
    145148
     
    211214    if (!bstrSrcSaveStatePath.isEmpty())
    212215    {
    213         SAVESTATETASK sst;
     216        FILECOPYTASK fct;
    214217        if (fAttachCurrent)
    215218        {
    216219            /* Make this saved state part of "current state" of the target
    217220             * machine, whether it is part of a snapshot or not. */
    218             sst.snapshotUuid.clear();
     221            fct.snapshotUuid.clear();
    219222        }
    220223        else
    221             sst.snapshotUuid = machine->i_getSnapshotId();
    222         sst.strSaveStateFile = bstrSrcSaveStatePath;
     224            fct.snapshotUuid = machine->i_getSnapshotId();
     225        fct.strFile = bstrSrcSaveStatePath;
    223226        uint64_t cbSize;
    224         int vrc = RTFileQuerySizeByPath(sst.strSaveStateFile.c_str(), &cbSize);
     227        int vrc = RTFileQuerySizeByPath(fct.strFile.c_str(), &cbSize);
    225228        if (RT_FAILURE(vrc))
    226229            return p->setErrorBoth(VBOX_E_IPRT_ERROR, vrc, p->tr("Could not query file size of '%s' (%Rrc)"),
    227                                    sst.strSaveStateFile.c_str(), vrc);
    228         /*  same rule as above: count both the data which needs to
     230                                   fct.strFile.c_str(), vrc);
     231        /* same rule as above: count both the data which needs to
    229232         * be read and written */
    230         sst.uWeight = (ULONG)(2 * (cbSize + _1M - 1) / _1M);
    231         llSaveStateFiles.append(sst);
     233        fct.uWeight = (ULONG)(2 * (cbSize + _1M - 1) / _1M);
     234        llSaveStateFiles.append(fct);
    232235        ++uCount;
    233         uTotalWeight += sst.uWeight;
     236        uTotalWeight += fct.uWeight;
     237    }
     238    return S_OK;
     239}
     240
     241HRESULT MachineCloneVMPrivate::addNVRAM(const ComObjPtr<Machine> &machine, bool fAttachCurrent, ULONG &uCount, ULONG &uTotalWeight)
     242{
     243    Bstr bstrSrcNVRAMPath;
     244    ComPtr<IBIOSSettings> pBIOSSettings;
     245    HRESULT rc = machine->COMGETTER(BIOSSettings)(pBIOSSettings.asOutParam());
     246    if (FAILED(rc)) return rc;
     247    rc = pBIOSSettings->COMGETTER(NonVolatileStorageFile)(bstrSrcNVRAMPath.asOutParam());
     248    if (FAILED(rc)) return rc;
     249    if (!bstrSrcNVRAMPath.isEmpty())
     250    {
     251        FILECOPYTASK fct;
     252        if (fAttachCurrent)
     253        {
     254            /* Make this saved state part of "current state" of the target
     255             * machine, whether it is part of a snapshot or not. */
     256            fct.snapshotUuid.clear();
     257        }
     258        else
     259            fct.snapshotUuid = machine->i_getSnapshotId();
     260        fct.strFile = bstrSrcNVRAMPath;
     261        if (!RTFileExists(fct.strFile.c_str()))
     262            return S_OK;
     263        uint64_t cbSize;
     264        int vrc = RTFileQuerySizeByPath(fct.strFile.c_str(), &cbSize);
     265        if (RT_FAILURE(vrc))
     266            return p->setErrorBoth(VBOX_E_IPRT_ERROR, vrc, p->tr("Could not query file size of '%s' (%Rrc)"),
     267                                   fct.strFile.c_str(), vrc);
     268        /* same rule as above: count both the data which needs to
     269         * be read and written */
     270        fct.uWeight = (ULONG)(2 * (cbSize + _1M - 1) / _1M);
     271        llNVRAMFiles.append(fct);
     272        ++uCount;
     273        uTotalWeight += fct.uWeight;
    234274    }
    235275    return S_OK;
     
    322362            llMedias.append(mtc);
    323363        }
    324         /* Add the save state files of this machine if there is one. */
     364        /* Add the save state file of this machine if there is one. */
    325365        rc = addSaveState(machine, true /*fAttachCurrent*/, uCount, uTotalWeight);
     366        if (FAILED(rc)) return rc;
     367        /* Add the NVRAM file of this machine if there is one. */
     368        rc = addNVRAM(machine, true /*fAttachCurrent*/, uCount, uTotalWeight);
    326369        if (FAILED(rc)) return rc;
    327370    }
     
    428471            llMedias.append(mtc);
    429472        }
    430         /* Add the save state files of this machine if there is one. */
     473        /* Add the save state file of this machine if there is one. */
    431474        rc = addSaveState(machine, false /*fAttachCurrent*/, uCount, uTotalWeight);
    432475        if (FAILED(rc)) return rc;
     476        /* Add the NVRAM file of this machine if there is one. */
     477        rc = addNVRAM(machine, false /*fAttachCurrent*/, uCount, uTotalWeight);
     478        if (FAILED(rc)) return rc;
    433479        /* If this is the newly created current state, make sure that the
    434          * saved state is also attached to it. */
     480         * saved state and NVRAM is also attached to it. */
    435481        if (fCreateDiffs)
    436482        {
    437483            rc = addSaveState(machine, true /*fAttachCurrent*/, uCount, uTotalWeight);
     484            if (FAILED(rc)) return rc;
     485            rc = addNVRAM(machine, true /*fAttachCurrent*/, uCount, uTotalWeight);
    438486            if (FAILED(rc)) return rc;
    439487        }
     
    576624            llMedias.append(mtc);
    577625        }
    578         /* Add the save state files of this machine if there is one. */
     626        /* Add the save state file of this machine if there is one. */
    579627        rc = addSaveState(machine, false /*fAttachCurrent*/, uCount, uTotalWeight);
     628        if (FAILED(rc)) return rc;
     629        /* Add the NVRAM file of this machine if there is one. */
     630        rc = addNVRAM(machine, false /*fAttachCurrent*/, uCount, uTotalWeight);
    580631        if (FAILED(rc)) return rc;
    581632        /* If this is the newly created current state, make sure that the
     
    584635        {
    585636            rc = addSaveState(machine, true /*fAttachCurrent*/, uCount, uTotalWeight);
     637            if (FAILED(rc)) return rc;
     638            rc = addNVRAM(machine, true /*fAttachCurrent*/, uCount, uTotalWeight);
    586639            if (FAILED(rc)) return rc;
    587640        }
     
    682735}
    683736
    684 void MachineCloneVMPrivate::updateStateFile(settings::SnapshotsList &snl, const Guid &id, const Utf8Str &strFile) const
     737void MachineCloneVMPrivate::updateSaveStateFile(settings::SnapshotsList &snl, const Guid &id, const Utf8Str &strFile) const
    685738{
    686739    settings::SnapshotsList::iterator it;
     
    690743            it->strStateFile = strFile;
    691744        else if (!it->llChildSnapshots.empty())
    692             updateStateFile(it->llChildSnapshots, id, strFile);
     745            updateSaveStateFile(it->llChildSnapshots, id, strFile);
     746    }
     747}
     748
     749void MachineCloneVMPrivate::updateNVRAMFile(settings::SnapshotsList &snl, const Guid &id, const Utf8Str &strFile) const
     750{
     751    settings::SnapshotsList::iterator it;
     752    for (it = snl.begin(); it != snl.end(); ++it)
     753    {
     754        if (it->uuid == id)
     755            it->hardware.biosSettings.strNVRAMPath = strFile;
     756        else if (!it->llChildSnapshots.empty())
     757            updateNVRAMFile(it->llChildSnapshots, id, strFile);
    693758    }
    694759}
     
    753818
    754819/* static */
    755 DECLCALLBACK(int) MachineCloneVMPrivate::copyStateFileProgress(unsigned uPercentage, void *pvUser)
     820DECLCALLBACK(int) MachineCloneVMPrivate::copyFileProgress(unsigned uPercentage, void *pvUser)
    756821{
    757822    ComObjPtr<Progress> pProgress = *static_cast< ComObjPtr<Progress>* >(pvUser);
     
    14291494        for (size_t i = 0; i < d->llSaveStateFiles.size(); ++i)
    14301495        {
    1431             SAVESTATETASK sst = d->llSaveStateFiles.at(i);
     1496            FILECOPYTASK fct = d->llSaveStateFiles.at(i);
    14321497            const Utf8Str &strTrgSaveState = Utf8StrFmt("%s%c%s", strTrgSnapshotFolder.c_str(), RTPATH_DELIMITER,
    1433                                                         RTPathFilename(sst.strSaveStateFile.c_str()));
     1498                                                        RTPathFilename(fct.strFile.c_str()));
    14341499
    14351500            /* Move to next sub-operation. */
    14361501            rc = d->pProgress->SetNextOperation(BstrFmt(p->tr("Copy save state file '%s' ..."),
    1437                                                         RTPathFilename(sst.strSaveStateFile.c_str())).raw(), sst.uWeight);
     1502                                                        RTPathFilename(fct.strFile.c_str())).raw(), fct.uWeight);
    14381503            if (FAILED(rc)) throw rc;
    14391504            /* Copy the file only if it was not copied already. */
    14401505            if (!newFiles.contains(strTrgSaveState.c_str()))
    14411506            {
    1442                 int vrc = RTFileCopyEx(sst.strSaveStateFile.c_str(), strTrgSaveState.c_str(), 0,
    1443                                        MachineCloneVMPrivate::copyStateFileProgress, &d->pProgress);
     1507                int vrc = RTFileCopyEx(fct.strFile.c_str(), strTrgSaveState.c_str(), 0,
     1508                                       MachineCloneVMPrivate::copyFileProgress, &d->pProgress);
    14441509                if (RT_FAILURE(vrc))
    14451510                    throw p->setErrorBoth(VBOX_E_IPRT_ERROR, vrc,
    14461511                                          p->tr("Could not copy state file '%s' to '%s' (%Rrc)"),
    1447                                           sst.strSaveStateFile.c_str(), strTrgSaveState.c_str(), vrc);
     1512                                          fct.strFile.c_str(), strTrgSaveState.c_str(), vrc);
    14481513                newFiles.append(strTrgSaveState);
    14491514            }
    14501515            /* Update the path in the configuration either for the current
    14511516             * machine state or the snapshots. */
    1452             if (!sst.snapshotUuid.isValid() || sst.snapshotUuid.isZero())
     1517            if (!fct.snapshotUuid.isValid() || fct.snapshotUuid.isZero())
    14531518                trgMCF.strStateFile = strTrgSaveState;
    14541519            else
    1455                 d->updateStateFile(trgMCF.llFirstSnapshot, sst.snapshotUuid, strTrgSaveState);
     1520                d->updateSaveStateFile(trgMCF.llFirstSnapshot, fct.snapshotUuid, strTrgSaveState);
     1521        }
     1522
     1523        /* Clone all NVRAM files. */
     1524        for (size_t i = 0; i < d->llNVRAMFiles.size(); ++i)
     1525        {
     1526            FILECOPYTASK fct = d->llNVRAMFiles.at(i);
     1527            Utf8Str strTrgNVRAM;
     1528            if (!fct.snapshotUuid.isValid() || fct.snapshotUuid.isZero())
     1529                strTrgNVRAM = Utf8StrFmt("%s%c%s.nvram", strTrgMachineFolder.c_str(), RTPATH_DELIMITER,
     1530                                         trgMCF.machineUserData.strName.c_str());
     1531            else
     1532                strTrgNVRAM = Utf8StrFmt("%s%c%s", strTrgSnapshotFolder.c_str(), RTPATH_DELIMITER,
     1533                                         RTPathFilename(fct.strFile.c_str()));
     1534
     1535            /* Move to next sub-operation. */
     1536            rc = d->pProgress->SetNextOperation(BstrFmt(p->tr("Copy NVRAM file '%s' ..."),
     1537                                                        RTPathFilename(fct.strFile.c_str())).raw(), fct.uWeight);
     1538            if (FAILED(rc)) throw rc;
     1539            /* Copy the file only if it was not copied already. */
     1540            if (!newFiles.contains(strTrgNVRAM.c_str()))
     1541            {
     1542                rc = p->i_getVirtualBox()->i_ensureFilePathExists(strTrgNVRAM.c_str(), true);
     1543                if (FAILED(rc)) throw rc;
     1544                int vrc = RTFileCopyEx(fct.strFile.c_str(), strTrgNVRAM.c_str(), 0,
     1545                                       MachineCloneVMPrivate::copyFileProgress, &d->pProgress);
     1546                if (RT_FAILURE(vrc))
     1547                    throw p->setErrorBoth(VBOX_E_IPRT_ERROR, vrc,
     1548                                          p->tr("Could not copy NVRAM file '%s' to '%s' (%Rrc)"),
     1549                                          fct.strFile.c_str(), strTrgNVRAM.c_str(), vrc);
     1550                newFiles.append(strTrgNVRAM);
     1551            }
     1552            /* Update the path in the configuration either for the current
     1553             * machine state or the snapshots. */
     1554            if (!fct.snapshotUuid.isValid() || fct.snapshotUuid.isZero())
     1555                trgMCF.hardwareMachine.biosSettings.strNVRAMPath = strTrgNVRAM;
     1556            else
     1557                d->updateNVRAMFile(trgMCF.llFirstSnapshot, fct.snapshotUuid, strTrgNVRAM);
    14561558        }
    14571559
  • trunk/src/VBox/Main/src-server/MachineImplMoveVM.cpp

    r81420 r81425  
    315315    ULONG uTotalWeight = 1;
    316316
    317     /* The lists m_llMedias and m_llSaveStateFiles are filled in the queryMediasForAllStates() */
     317    /* The lists m_llMedias, m_llSaveStateFiles and m_llNVRAMFiles are filled in the queryMediasForAllStates() */
    318318    hrc = queryMediasForAllStates();
    319319    if (FAILED(hrc))
     
    371371        {
    372372            uint64_t cbFile = 0;
    373             SAVESTATETASKMOVE &sst = m_llSaveStateFiles.at(i);
    374 
    375             Utf8Str name = sst.strSaveStateFile;
     373            SNAPFILETASKMOVE &sft = m_llSaveStateFiles.at(i);
     374
     375            Utf8Str name = sft.strFile;
    376376            /* if a state file is located in the actual VM folder it will be added to the actual list */
    377377            if (RTPathStartsWith(name.c_str(), strSettingsFilePath.c_str()))
     
    380380                if (RT_SUCCESS(vrc))
    381381                {
    382                     std::pair<std::map<Utf8Str, SAVESTATETASKMOVE>::iterator,bool> ret;
    383                     ret = m_finalSaveStateFilesMap.insert(std::make_pair(name, sst));
     382                    std::pair<std::map<Utf8Str, SNAPFILETASKMOVE>::iterator,bool> ret;
     383                    ret = m_finalSaveStateFilesMap.insert(std::make_pair(name, sft));
    384384                    if (ret.second == true)
    385385                    {
    386386                        totalStateSize += cbFile;
    387387                        ++uCount;
    388                         uTotalWeight += sst.uWeight;
     388                        uTotalWeight += sft.uWeight;
    389389                        Log2(("The state file %s was added into the moved list\n", name.c_str()));
    390390                    }
     
    402402
    403403        neededFreeSpace += totalStateSize;
     404    }
     405
     406    /* Prepare data for moving ".nvram" files */
     407    {
     408        uint64_t totalNVRAMSize = 0;
     409
     410        for (size_t i = 0; i < m_llNVRAMFiles.size(); ++i)
     411        {
     412            uint64_t cbFile = 0;
     413            SNAPFILETASKMOVE &sft = m_llNVRAMFiles.at(i);
     414
     415            Utf8Str name = sft.strFile;
     416            /* if a NVRAM file is located in the actual VM folder it will be added to the actual list */
     417            if (RTPathStartsWith(name.c_str(), strSettingsFilePath.c_str()))
     418            {
     419                vrc = RTFileQuerySizeByPath(name.c_str(), &cbFile);
     420                if (RT_SUCCESS(vrc))
     421                {
     422                    std::pair<std::map<Utf8Str, SNAPFILETASKMOVE>::iterator,bool> ret;
     423                    ret = m_finalNVRAMFilesMap.insert(std::make_pair(name, sft));
     424                    if (ret.second == true)
     425                    {
     426                        totalNVRAMSize += cbFile;
     427                        ++uCount;
     428                        uTotalWeight += sft.uWeight;
     429                        Log2(("The NVRAM file %s was added into the moved list\n", name.c_str()));
     430                    }
     431                }
     432                else
     433                {
     434                    Log2(("The NVRAM file %s wasn't added into the moved list. Couldn't get the file size.\n",
     435                          name.c_str()));
     436                    return m_pMachine->setErrorVrc(vrc,
     437                                                   m_pMachine->tr("Failed to get file size for '%s': %Rrc"),
     438                                                   name.c_str(), vrc);
     439                }
     440            }
     441        }
     442
     443        neededFreeSpace += totalNVRAMSize;
    404444    }
    405445
     
    643683            /* Check if a snapshot folder is necessary and if so doesn't already
    644684             * exists. */
    645             if (   taskMoveVM->m_finalSaveStateFilesMap.size() != 0
     685            if (   (   taskMoveVM->m_finalSaveStateFilesMap.size() > 0
     686                    || taskMoveVM->m_finalNVRAMFilesMap.size() > 1)
    646687                && !RTDirExists(strTrgSnapshotFolder.c_str()))
    647688            {
     
    653694            }
    654695
    655             std::map<Utf8Str, SAVESTATETASKMOVE>::iterator itState = taskMoveVM->m_finalSaveStateFilesMap.begin();
     696            std::map<Utf8Str, SNAPFILETASKMOVE>::iterator itState = taskMoveVM->m_finalSaveStateFilesMap.begin();
    656697            while (itState != taskMoveVM->m_finalSaveStateFilesMap.end())
    657698            {
    658                 const SAVESTATETASKMOVE &sst = itState->second;
     699                const SNAPFILETASKMOVE &sft = itState->second;
    659700                const Utf8Str &strTrgSaveState = Utf8StrFmt("%s%c%s", strTrgSnapshotFolder.c_str(), RTPATH_DELIMITER,
    660                                                             RTPathFilename(sst.strSaveStateFile.c_str()));
     701                                                            RTPathFilename(sft.strFile.c_str()));
    661702
    662703                /* Move to next sub-operation. */
    663704                hrc = taskMoveVM->m_pProgress->SetNextOperation(BstrFmt(machine->tr("Copy the save state file '%s' ..."),
    664                                                                         RTPathFilename(sst.strSaveStateFile.c_str())).raw(),
    665                                                                 sst.uWeight);
     705                                                                        RTPathFilename(sft.strFile.c_str())).raw(),
     706                                                                sft.uWeight);
    666707                if (FAILED(hrc))
    667708                    throw hrc;
    668709
    669                 int vrc = RTFileCopyEx(sst.strSaveStateFile.c_str(), strTrgSaveState.c_str(), 0,
     710                int vrc = RTFileCopyEx(sft.strFile.c_str(), strTrgSaveState.c_str(), 0,
    670711                                       MachineMoveVM::copyFileProgress, &taskMoveVM->m_pProgress);
    671712                if (RT_FAILURE(vrc))
    672713                    throw machine->setErrorBoth(VBOX_E_IPRT_ERROR, vrc,
    673714                                                taskMoveVM->m_pMachine->tr("Could not copy state file '%s' to '%s' (%Rrc)"),
    674                                                 sst.strSaveStateFile.c_str(),
     715                                                sft.strFile.c_str(),
    675716                                                strTrgSaveState.c_str(),
    676717                                                vrc);
     
    679720                newFiles.append(strTrgSaveState);
    680721                /* save original file for deletion in the end */
    681                 originalFiles.append(sst.strSaveStateFile);
     722                originalFiles.append(sft.strFile);
    682723                ++itState;
     724            }
     725
     726            std::map<Utf8Str, SNAPFILETASKMOVE>::iterator itNVRAM = taskMoveVM->m_finalNVRAMFilesMap.begin();
     727            while (itNVRAM != taskMoveVM->m_finalNVRAMFilesMap.end())
     728            {
     729                const SNAPFILETASKMOVE &sft = itNVRAM->second;
     730                const Utf8Str &strTrgNVRAM = Utf8StrFmt("%s%c%s", sft.snapshotUuid.isZero() ? strTargetFolder.c_str() : strTrgSnapshotFolder.c_str(),
     731                                                        RTPATH_DELIMITER, RTPathFilename(sft.strFile.c_str()));
     732
     733                /* Move to next sub-operation. */
     734                hrc = taskMoveVM->m_pProgress->SetNextOperation(BstrFmt(machine->tr("Copy the NVRAM file '%s' ..."),
     735                                                                        RTPathFilename(sft.strFile.c_str())).raw(),
     736                                                                sft.uWeight);
     737                if (FAILED(hrc))
     738                    throw hrc;
     739
     740                int vrc = RTFileCopyEx(sft.strFile.c_str(), strTrgNVRAM.c_str(), 0,
     741                                       MachineMoveVM::copyFileProgress, &taskMoveVM->m_pProgress);
     742                if (RT_FAILURE(vrc))
     743                    throw machine->setErrorBoth(VBOX_E_IPRT_ERROR, vrc,
     744                                                taskMoveVM->m_pMachine->tr("Could not copy NVRAM file '%s' to '%s' (%Rrc)"),
     745                                                sft.strFile.c_str(),
     746                                                strTrgNVRAM.c_str(),
     747                                                vrc);
     748
     749                /* save new file in case of restoring */
     750                newFiles.append(strTrgNVRAM);
     751                /* save original file for deletion in the end */
     752                originalFiles.append(sft.strFile);
     753                ++itNVRAM;
    683754            }
    684755        }
     
    695766
    696767        /*
     768         * Update NVRAM file paths
     769         * very important step!
     770         */
     771        Log2(("Update NVRAM paths\n"));
     772        /** @todo r=klaus: this update is not necessarily matching what the
     773         * above code has set as the new folders, so it needs reimplementing.
     774         * What's good about this implementation: it does not look at the
     775         * list of NVRAM files, because that only lists the existing ones,
     776         * but all paths need fixing. */
     777        taskMoveVM->updatePathsToNVRAMFiles(taskMoveVM->m_vmFolders[VBox_SettingFolder],
     778                                            strTargetFolder);
     779
     780        /*
    697781         * Moving Machine settings file
    698782         * The settings file are moved after all disks and snapshots because this file should be updated
     
    753837            /* save original file for deletion in the end */
    754838            originalFiles.append(strSettingsFilePath);
     839
     840            Utf8Str strPrevSettingsFilePath = strSettingsFilePath;
     841            strPrevSettingsFilePath.append("-prev");
     842            if (RTFileExists(strPrevSettingsFilePath.c_str()))
     843                originalFiles.append(strPrevSettingsFilePath);
    755844        }
    756845
     
    9211010                                                taskMoveVM->m_vmFolders[VBox_SettingFolder]);
    9221011
     1012            /* Revert original paths to the NVRAM files */
     1013            taskMoveVM->updatePathsToNVRAMFiles(strTargetFolder,
     1014                                                taskMoveVM->m_vmFolders[VBox_SettingFolder]);
     1015
    9231016            /* Delete all created files. Here we update progress object */
    9241017            hrc = taskMoveVM->deleteFiles(newFiles);
     
    11591252                                                               RTPATH_DELIMITER,
    11601253                                                               RTPathFilename(m_pMachine->mSSData->strStateFilePath.c_str()));
     1254    }
     1255}
     1256
     1257void MachineMoveVM::updatePathsToNVRAMFiles(const Utf8Str &sourcePath, const Utf8Str &targetPath)
     1258{
     1259    ComObjPtr<Snapshot> pSnapshot;
     1260    HRESULT rc = m_pMachine->i_findSnapshotById(Guid() /* zero */, pSnapshot, true);
     1261    if (SUCCEEDED(rc) && !pSnapshot.isNull())
     1262        pSnapshot->i_updateNVRAMPaths(sourcePath.c_str(),
     1263                                      targetPath.c_str());
     1264    ComObjPtr<BIOSSettings> pBIOSSettings(m_pMachine->mBIOSSettings);
     1265    const Utf8Str NVRAMFile(pBIOSSettings->i_getNonVolatileStorageFile());
     1266    if (NVRAMFile.isNotEmpty())
     1267    {
     1268        Utf8Str newNVRAMFile;
     1269        if (RTPathStartsWith(NVRAMFile.c_str(), sourcePath.c_str()))
     1270            newNVRAMFile = Utf8StrFmt("%s%s", targetPath.c_str(), NVRAMFile.c_str() + sourcePath.length());
     1271        else
     1272            newNVRAMFile = Utf8StrFmt("%s%c%s", targetPath.c_str(), RTPATH_DELIMITER, RTPathFilename(newNVRAMFile.c_str()));
     1273        pBIOSSettings->i_updateNonVolatileStorageFile(newNVRAMFile);
    11611274    }
    11621275}
     
    14201533        rc = addSaveState(machine);
    14211534        if (FAILED(rc)) return rc;
     1535
     1536        /* Add the NVRAM files of this machine if there is one. */
     1537        rc = addNVRAM(machine);
     1538        if (FAILED(rc)) return rc;
    14221539    }
    14231540
     
    14431560    if (!bstrSrcSaveStatePath.isEmpty())
    14441561    {
    1445         SAVESTATETASKMOVE sst;
    1446 
    1447         sst.snapshotUuid = machine->i_getSnapshotId();
    1448         sst.strSaveStateFile = bstrSrcSaveStatePath;
     1562        SNAPFILETASKMOVE sft;
     1563
     1564        sft.snapshotUuid = machine->i_getSnapshotId();
     1565        sft.strFile = bstrSrcSaveStatePath;
    14491566        uint64_t cbSize;
    14501567
    1451         int vrc = RTFileQuerySizeByPath(sst.strSaveStateFile.c_str(), &cbSize);
     1568        int vrc = RTFileQuerySizeByPath(sft.strFile.c_str(), &cbSize);
    14521569        if (RT_FAILURE(vrc))
    14531570            return m_pMachine->setErrorBoth(VBOX_E_IPRT_ERROR, vrc,
    14541571                                            m_pMachine->tr("Could not get file size of '%s': %Rrc"),
    1455                                             sst.strSaveStateFile.c_str(),
     1572                                            sft.strFile.c_str(),
    14561573                                            vrc);
    14571574
    14581575        /* same rule as above: count both the data which needs to
    14591576         * be read and written */
    1460         sst.uWeight = (ULONG)(2 * (cbSize + _1M - 1) / _1M);
    1461         m_llSaveStateFiles.append(sst);
     1577        sft.uWeight = (ULONG)(2 * (cbSize + _1M - 1) / _1M);
     1578        m_llSaveStateFiles.append(sft);
     1579    }
     1580    return S_OK;
     1581}
     1582
     1583HRESULT MachineMoveVM::addNVRAM(const ComObjPtr<Machine> &machine)
     1584{
     1585    ComPtr<IBIOSSettings> pBIOSSettings;
     1586    HRESULT rc = machine->COMGETTER(BIOSSettings)(pBIOSSettings.asOutParam());
     1587    if (FAILED(rc)) return rc;
     1588    Bstr bstrSrcNVRAMPath;
     1589    rc = pBIOSSettings->COMGETTER(NonVolatileStorageFile)(bstrSrcNVRAMPath.asOutParam());
     1590    if (FAILED(rc)) return rc;
     1591    Utf8Str strSrcNVRAMPath(bstrSrcNVRAMPath);
     1592    if (!strSrcNVRAMPath.isEmpty() && RTFileExists(strSrcNVRAMPath.c_str()))
     1593    {
     1594        SNAPFILETASKMOVE sft;
     1595
     1596        sft.snapshotUuid = machine->i_getSnapshotId();
     1597        sft.strFile = strSrcNVRAMPath;
     1598        uint64_t cbSize;
     1599
     1600        int vrc = RTFileQuerySizeByPath(sft.strFile.c_str(), &cbSize);
     1601        if (RT_FAILURE(vrc))
     1602            return m_pMachine->setErrorBoth(VBOX_E_IPRT_ERROR, vrc,
     1603                                            m_pMachine->tr("Could not get file size of '%s': %Rrc"),
     1604                                            sft.strFile.c_str(),
     1605                                            vrc);
     1606
     1607        /* same rule as above: count both the data which needs to
     1608         * be read and written */
     1609        sft.uWeight = (ULONG)(2 * (cbSize + _1M - 1) / _1M);
     1610        m_llNVRAMFiles.append(sft);
    14621611    }
    14631612    return S_OK;
  • trunk/src/VBox/Main/src-server/SnapshotImpl.cpp

    r79154 r81425  
    656656
    657657    /* state file may be NULL (for offline snapshots) */
    658     if (    path.length()
     658    if (    path.isNotEmpty()
    659659         && RTPathStartsWith(path.c_str(), strOldPath.c_str())
    660660       )
     
    663663                                                            strNewPath.c_str(),
    664664                                                            path.c_str() + strOldPath.length());
    665         LogFlowThisFunc(("-> updated: {%s}\n", path.c_str()));
     665        LogFlowThisFunc(("-> updated: {%s}\n", m->pMachine->mSSData->strStateFilePath.c_str()));
    666666    }
    667667
     
    673673        pChild->i_updateSavedStatePathsImpl(strOldPath, strNewPath);
    674674    }
     675}
     676
     677/**
     678 *  Checks if the specified path change affects the saved state file path of
     679 *  this snapshot or any of its (grand-)children and updates it accordingly.
     680 *
     681 *  Intended to be called by Machine::openConfigLoader() only.
     682 *
     683 *  @param  strOldPath old path (full)
     684 *  @param  strNewPath new path (full)
     685 *
     686 *  @note Locks the machine (for the snapshots tree) +  this object + children for writing.
     687 */
     688void Snapshot::i_updateSavedStatePaths(const Utf8Str &strOldPath,
     689                                       const Utf8Str &strNewPath)
     690{
     691    LogFlowThisFunc(("aOldPath={%s} aNewPath={%s}\n", strOldPath.c_str(), strNewPath.c_str()));
     692
     693    AutoCaller autoCaller(this);
     694    AssertComRC(autoCaller.rc());
     695
     696    // snapshots tree is protected by machine lock
     697    AutoWriteLock alock(m->pMachine COMMA_LOCKVAL_SRC_POS);
     698
     699    // call the implementation under the tree lock
     700    i_updateSavedStatePathsImpl(strOldPath, strNewPath);
    675701}
    676702
     
    714740
    715741/**
    716  *  Checks if the specified path change affects the saved state file path of
     742 * Internal implementation for Snapshot::updateNVRAMPaths (below).
     743 * @param   strOldPath
     744 * @param   strNewPath
     745 */
     746void Snapshot::i_updateNVRAMPathsImpl(const Utf8Str &strOldPath,
     747                                      const Utf8Str &strNewPath)
     748{
     749    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
     750
     751    const Utf8Str path = m->pMachine->mBIOSSettings->i_getNonVolatileStorageFile();
     752    LogFlowThisFunc(("Snap[%s].nvramPath={%s}\n", m->strName.c_str(), path.c_str()));
     753
     754    /* NVRAM filename may be empty */
     755    if (    path.isNotEmpty()
     756         && RTPathStartsWith(path.c_str(), strOldPath.c_str())
     757       )
     758    {
     759        m->pMachine->mBIOSSettings->i_updateNonVolatileStorageFile(Utf8StrFmt("%s%s",
     760                                                                              strNewPath.c_str(),
     761                                                                              path.c_str() + strOldPath.length()));
     762        LogFlowThisFunc(("-> updated: {%s}\n", m->pMachine->mBIOSSettings->i_getNonVolatileStorageFile().c_str()));
     763    }
     764
     765    for (SnapshotsList::const_iterator it = m->llChildren.begin();
     766         it != m->llChildren.end();
     767         ++it)
     768    {
     769        Snapshot *pChild = *it;
     770        pChild->i_updateNVRAMPathsImpl(strOldPath, strNewPath);
     771    }
     772}
     773
     774/**
     775 *  Checks if the specified path change affects the NVRAM file path of
    717776 *  this snapshot or any of its (grand-)children and updates it accordingly.
    718777 *
     
    724783 *  @note Locks the machine (for the snapshots tree) +  this object + children for writing.
    725784 */
    726 void Snapshot::i_updateSavedStatePaths(const Utf8Str &strOldPath,
    727                                        const Utf8Str &strNewPath)
     785void Snapshot::i_updateNVRAMPaths(const Utf8Str &strOldPath,
     786                                  const Utf8Str &strNewPath)
    728787{
    729788    LogFlowThisFunc(("aOldPath={%s} aNewPath={%s}\n", strOldPath.c_str(), strNewPath.c_str()));
     
    844903
    845904    // report the saved state file if it's not on the list yet
    846     if (!m->pMachine->mSSData->strStateFilePath.isEmpty())
     905    if (m->pMachine->mSSData->strStateFilePath.isNotEmpty())
    847906    {
    848907        bool fFound = false;
     
    861920            llFilenames.push_back(m->pMachine->mSSData->strStateFilePath);
    862921    }
     922
     923    Utf8Str strNVRAMFile = m->pMachine->mBIOSSettings->i_getNonVolatileStorageFile();
     924    if (strNVRAMFile.isNotEmpty() && RTFileExists(strNVRAMFile.c_str()))
     925        llFilenames.push_back(strNVRAMFile);
    863926
    864927    i_beginSnapshotDelete();
     
    17821845            if (FAILED(rc))
    17831846                throw rc;
     1847        }
     1848
     1849        // Handle NVRAM file snapshotting
     1850        Utf8Str strNVRAM = mBIOSSettings->i_getNonVolatileStorageFile();
     1851        Utf8Str strNVRAMSnap = pSnapshotMachine->i_getSnapshotNVRAMFilename();
     1852        Utf8Str strNVRAMSnapAbs;
     1853        i_calculateFullPath(strNVRAMSnap, strNVRAMSnapAbs);
     1854        if (strNVRAM.isNotEmpty() && strNVRAMSnap.isNotEmpty() && RTFileExists(strNVRAM.c_str()))
     1855        {
     1856            rc = VirtualBox::i_ensureFilePathExists(strNVRAMSnapAbs, true /* fCreate */);
     1857            if (FAILED(rc))
     1858                throw rc;
     1859            int vrc = RTFileCopy(strNVRAM.c_str(), strNVRAMSnapAbs.c_str());
     1860            if (RT_FAILURE(vrc))
     1861                throw setErrorBoth(VBOX_E_IPRT_ERROR, vrc,
     1862                                   tr("Could not copy NVRAM file '%s' to '%s' (%Rrc)"),
     1863                                   strNVRAM.c_str(), strNVRAMSnapAbs.c_str(), vrc);
     1864            pSnapshotMachine->mBIOSSettings->i_updateNonVolatileStorageFile(strNVRAMSnap);
    17841865        }
    17851866
     
    22762357                mSSData->strStateFilePath = strSnapshotStateFile;
    22772358
     2359            const Utf8Str srcNVRAM(pSnapshotMachine->mBIOSSettings->i_getNonVolatileStorageFile());
     2360            const Utf8Str dstNVRAM(mBIOSSettings->i_getNonVolatileStorageFile());
     2361            if (dstNVRAM.isNotEmpty() && RTFileExists(dstNVRAM.c_str()))
     2362                RTFileDelete(dstNVRAM.c_str());
     2363            if (srcNVRAM.isNotEmpty() && dstNVRAM.isNotEmpty() && RTFileExists(srcNVRAM.c_str()))
     2364                RTFileCopy(srcNVRAM.c_str(), dstNVRAM.c_str());
     2365
    22782366            LogFlowThisFunc(("Setting new current snapshot {%RTuuid}\n", task.m_pSnapshot->i_getId().raw()));
    22792367            /* make the snapshot we restored from the current snapshot */
     
    26212709    ULONG ulTotalWeight = 1;        // one for preparations
    26222710
    2623     if (pSnapshot->i_getStateFilePath().length())
     2711    if (pSnapshot->i_getStateFilePath().isNotEmpty())
    26242712    {
    26252713        ++ulOpCount;
     
    33913479        }
    33923480
     3481        /* 3a: delete NVRAM file if present. */
     3482        {
     3483            Utf8Str NVRAMPath = pSnapMachine->mBIOSSettings->i_getNonVolatileStorageFile();
     3484            if (NVRAMPath.isNotEmpty() && RTFileExists(NVRAMPath.c_str()))
     3485                RTFileDelete(NVRAMPath.c_str());
     3486        }
     3487
     3488        /* third pass: */
    33933489        {
    33943490            // beginSnapshotDelete() needs the machine lock, and the snapshots
Note: See TracChangeset for help on using the changeset viewer.

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