VirtualBox

Changeset 94514 in vbox


Ignore:
Timestamp:
Apr 7, 2022 1:49:30 PM (2 years ago)
Author:
vboxsync
Message:

Main/NvramStore: Implement SSM handlers so the state doesn't get written out to the file if the VM state is saved, bugref:10098

Location:
trunk/src/VBox/Main
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Main/include/NvramStoreImpl.h

    r93115 r94514  
    9595
    9696#ifdef VBOX_COM_INPROC
     97    static DECLCALLBACK(int)    i_SsmSaveExec(PPDMDRVINS pDrvIns, PSSMHANDLE pSSM);
     98    static DECLCALLBACK(int)    i_SsmLoadExec(PPDMDRVINS pDrvIns, PSSMHANDLE pSSM, uint32_t uVersion, uint32_t uPass);
     99
    97100    static DECLCALLBACK(int)    i_nvramStoreQuerySize(PPDMIVFSCONNECTOR pInterface, const char *pszNamespace, const char *pszPath,
    98101                                                      uint64_t *pcb);
  • trunk/src/VBox/Main/src-all/NvramStoreImpl.cpp

    r93570 r94514  
    4545////////////////////////////////////////////////////////////////////////////////
    4646
     47/** Version of the NVRAM saved state unit. */
     48#define NVRAM_STORE_SAVED_STATE_VERSION 1
     49
     50
    4751// globals
    4852////////////////////////////////////////////////////////////////////////////////
     
    9599    /** Number of references held to this NVRAM store from the various devices/drivers. */
    96100    volatile uint32_t       cRefs;
     101    /** Flag whether the NVRAM data was saved during a save state operation
     102     * preventing it from getting written to the backing file. */
     103    bool                    fSsmSaved;
    97104#else
    98105    /** The Machine object owning this NVRAM store. */
     
    10001007
    10011008
     1009/*static*/
     1010DECLCALLBACK(int) NvramStore::i_SsmSaveExec(PPDMDRVINS pDrvIns, PSSMHANDLE pSSM)
     1011{
     1012    PDMDRV_CHECK_VERSIONS_RETURN(pDrvIns);
     1013    PDRVMAINNVRAMSTORE pThis = PDMINS_2_DATA(pDrvIns, PDRVMAINNVRAMSTORE);
     1014    PCPDMDRVHLPR3      pHlp  = pDrvIns->pHlpR3;
     1015
     1016    AutoWriteLock wlock(pThis->pNvramStore COMMA_LOCKVAL_SRC_POS);
     1017
     1018    size_t cEntries = pThis->pNvramStore->m->bd->mapNvram.size();
     1019    AssertReturn(cEntries < 32, VERR_OUT_OF_RANGE); /* Some sanity checking. */
     1020    pHlp->pfnSSMPutU32(pSSM, (uint32_t)cEntries);
     1021
     1022    void *pvData = NULL;
     1023    size_t cbDataMax = 0;
     1024    NvramStoreIter it = pThis->pNvramStore->m->bd->mapNvram.begin();
     1025
     1026    while (it != pThis->pNvramStore->m->bd->mapNvram.end())
     1027    {
     1028        RTVFSFILE hVfsFile = it->second;
     1029        uint64_t cbFile;
     1030
     1031        int rc = RTVfsFileQuerySize(hVfsFile, &cbFile);
     1032        AssertRCReturn(rc, rc);
     1033        AssertReturn(cbFile < _1M, VERR_OUT_OF_RANGE);
     1034
     1035        if (cbDataMax < cbFile)
     1036        {
     1037            pvData = RTMemRealloc(pvData, cbFile);
     1038            AssertPtrReturn(pvData, VERR_NO_MEMORY);
     1039            cbDataMax = cbFile;
     1040        }
     1041
     1042        rc = RTVfsFileReadAt(hVfsFile, 0 /*off*/, pvData, cbFile, NULL /*pcbRead*/);
     1043        AssertRCReturn(rc, rc);
     1044
     1045        pHlp->pfnSSMPutStrZ(pSSM, it->first.c_str());
     1046        pHlp->pfnSSMPutU64(pSSM, cbFile);
     1047        pHlp->pfnSSMPutMem(pSSM, pvData, cbFile);
     1048        it++;
     1049    }
     1050
     1051    if (pvData)
     1052        RTMemFree(pvData);
     1053
     1054    pThis->pNvramStore->m->fSsmSaved = true;
     1055    return pHlp->pfnSSMPutU32(pSSM, UINT32_MAX); /* sanity/terminator */
     1056}
     1057
     1058
     1059/*static*/
     1060DECLCALLBACK(int) NvramStore::i_SsmLoadExec(PPDMDRVINS pDrvIns, PSSMHANDLE pSSM, uint32_t uVersion, uint32_t uPass)
     1061{
     1062    PDMDRV_CHECK_VERSIONS_RETURN(pDrvIns);
     1063    PDRVMAINNVRAMSTORE pThis = PDMINS_2_DATA(pDrvIns, PDRVMAINNVRAMSTORE);
     1064    PCPDMDRVHLPR3      pHlp  = pDrvIns->pHlpR3;
     1065
     1066    AssertMsgReturn(uVersion >= NVRAM_STORE_SAVED_STATE_VERSION, ("%d\n", uVersion),
     1067                    VERR_SSM_UNSUPPORTED_DATA_UNIT_VERSION);
     1068
     1069    if (uPass == SSM_PASS_FINAL)
     1070    {
     1071        AutoWriteLock wlock(pThis->pNvramStore COMMA_LOCKVAL_SRC_POS);
     1072
     1073        /* Clear any content first. */
     1074        NvramStoreIter it = pThis->pNvramStore->m->bd->mapNvram.begin();
     1075        while (it != pThis->pNvramStore->m->bd->mapNvram.end())
     1076        {
     1077            RTVfsFileRelease(it->second);
     1078            it++;
     1079        }
     1080
     1081        pThis->pNvramStore->m->bd->mapNvram.clear();
     1082
     1083        uint32_t cEntries = 0;
     1084        int rc = pHlp->pfnSSMGetU32(pSSM, &cEntries);
     1085        AssertRCReturn(rc, rc);
     1086        AssertReturn(cEntries < 32, VERR_OUT_OF_RANGE);
     1087
     1088        void *pvData = NULL;
     1089        size_t cbDataMax = 0;
     1090        while (cEntries--)
     1091        {
     1092            char szId[_1K]; /* Lazy developer */
     1093            uint64_t cbFile = 0;
     1094
     1095            rc = pHlp->pfnSSMGetStrZ(pSSM, &szId[0], sizeof(szId));
     1096            AssertRCReturn(rc, rc);
     1097
     1098            rc = pHlp->pfnSSMGetU64(pSSM, &cbFile);
     1099            AssertRCReturn(rc, rc);
     1100            AssertReturn(cbFile < _1M, VERR_OUT_OF_RANGE);
     1101
     1102            if (cbDataMax < cbFile)
     1103            {
     1104                pvData = RTMemRealloc(pvData, cbFile);
     1105                AssertPtrReturn(pvData, VERR_NO_MEMORY);
     1106                cbDataMax = cbFile;
     1107            }
     1108
     1109            rc = pHlp->pfnSSMGetMem(pSSM, pvData, cbFile);
     1110            AssertRCReturn(rc, rc);
     1111
     1112            RTVFSFILE hVfsFile;
     1113            rc = RTVfsFileFromBuffer(RTFILE_O_READWRITE, pvData, cbFile, &hVfsFile);
     1114            AssertRCReturn(rc, rc);
     1115
     1116            pThis->pNvramStore->m->bd->mapNvram[Utf8Str(szId)] = hVfsFile;
     1117        }
     1118
     1119        if (pvData)
     1120            RTMemFree(pvData);
     1121
     1122        /* The marker. */
     1123        uint32_t u32;
     1124        rc = pHlp->pfnSSMGetU32(pSSM, &u32);
     1125        AssertRCReturn(rc, rc);
     1126        AssertMsgReturn(u32 == UINT32_MAX, ("%#x\n", u32), VERR_SSM_DATA_UNIT_FORMAT_CHANGED);
     1127    }
     1128
     1129    return VINF_SUCCESS;
     1130}
     1131
     1132
    10021133/**
    10031134 * @interface_method_impl{PDMIBASE,pfnQueryInterface}
     
    10291160    {
    10301161        uint32_t cRefs = ASMAtomicDecU32(&pThis->pNvramStore->m->cRefs);
    1031         if (!cRefs)
     1162        if (   !cRefs
     1163            && !pThis->pNvramStore->m->fSsmSaved)
    10321164        {
    10331165            int rc = pThis->pNvramStore->i_saveStore();
     
    10771209        AssertMsgFailed(("Configuration error: No/bad NVRAM store object!\n"));
    10781210        return VERR_NOT_FOUND;
     1211    }
     1212
     1213    /*
     1214     * Only the first instance will register the SSM handlers and will do the work on behalf
     1215     * of all other NVRAM store driver instances when it comes to SSM.
     1216     */
     1217    if (pDrvIns->iInstance == 0)
     1218    {
     1219        int rc = PDMDrvHlpSSMRegister(pDrvIns, NVRAM_STORE_SAVED_STATE_VERSION, 0 /*cbGuess*/,
     1220                                      NvramStore::i_SsmSaveExec, NvramStore::i_SsmLoadExec);
     1221        if (RT_FAILURE(rc))
     1222            return PDMDrvHlpVMSetError(pDrvIns, rc, RT_SRC_POS,
     1223                                       N_("Failed to register the saved state unit for the NVRAM store"));
    10791224    }
    10801225
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