VirtualBox

Changeset 42892 in vbox for trunk/src/VBox/VMM


Ignore:
Timestamp:
Aug 20, 2012 8:48:06 PM (12 years ago)
Author:
vboxsync
Message:

BlockCache: Relax check when restoring a state. It is allowed to have more cache users in the saved state than there are registered currently if the missig users don't have any data saved. Should fix restore errors if a VM with snapshots was moved to a filesystem with known data corruption bugs which disables async I/O whe the VM starts

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMR3/PDMBlkCache.cpp

    r40806 r42892  
    884884     * because that means that there are only new ones which don't have any saved state
    885885     * which can get lost.
    886      * More saved entries that current ones are not allowed because this could result in
    887      * lost data.
     886     * More saved state entries than registered cache users are only allowed if the
     887     * missing users don't have any data saved in the cache.
    888888     */
    889889    int rc = VINF_SUCCESS;
    890     if (cRefs <= pBlkCacheGlobal->cRefs)
    891     {
    892         char *pszId = NULL;
    893 
    894         while (   cRefs > 0
    895                && RT_SUCCESS(rc))
    896         {
    897             PPDMBLKCACHE pBlkCache = NULL;
    898             uint32_t cbId = 0;
    899 
    900             SSMR3GetU32(pSSM, &cbId);
    901             Assert(cbId > 0);
    902 
    903             cbId++; /* Include terminator */
    904             pszId = (char *)RTMemAllocZ(cbId * sizeof(char));
    905             if (!pszId)
     890    char *pszId = NULL;
     891
     892    while (   cRefs > 0
     893           && RT_SUCCESS(rc))
     894    {
     895        PPDMBLKCACHE pBlkCache = NULL;
     896        uint32_t cbId = 0;
     897
     898        SSMR3GetU32(pSSM, &cbId);
     899        Assert(cbId > 0);
     900
     901        cbId++; /* Include terminator */
     902        pszId = (char *)RTMemAllocZ(cbId * sizeof(char));
     903        if (!pszId)
     904        {
     905            rc = VERR_NO_MEMORY;
     906            break;
     907        }
     908
     909        rc = SSMR3GetStrZ(pSSM, pszId, cbId);
     910        AssertRC(rc);
     911
     912        /* Search for the block cache with the provided id. */
     913        pBlkCache = pdmR3BlkCacheFindById(pBlkCacheGlobal, pszId);
     914
     915        /* Get the entries */
     916        uint32_t cEntries;
     917        SSMR3GetU32(pSSM, &cEntries);
     918
     919        if (!pBlkCache && (cEntries > 0))
     920        {
     921            rc = SSMR3SetCfgError(pSSM, RT_SRC_POS,
     922                                  N_("The VM is missing a block device and there is data in the cache. Please make sure the source and target VMs have compatible storage configurations"));
     923            break;
     924        }
     925
     926        RTStrFree(pszId);
     927        pszId = NULL;
     928
     929        while (cEntries > 0)
     930        {
     931            PPDMBLKCACHEENTRY pEntry;
     932            uint64_t off;
     933            uint32_t cbEntry;
     934
     935            SSMR3GetU64(pSSM, &off);
     936            SSMR3GetU32(pSSM, &cbEntry);
     937
     938            pEntry = pdmBlkCacheEntryAlloc(pBlkCache, off, cbEntry, NULL);
     939            if (!pEntry)
    906940            {
    907941                rc = VERR_NO_MEMORY;
     
    909943            }
    910944
    911             rc = SSMR3GetStrZ(pSSM, pszId, cbId);
    912             AssertRC(rc);
    913 
    914             /* Search for the block cache with the provided id. */
    915             pBlkCache = pdmR3BlkCacheFindById(pBlkCacheGlobal, pszId);
    916             if (!pBlkCache)
     945            rc = SSMR3GetMem(pSSM, pEntry->pbData, cbEntry);
     946            if (RT_FAILURE(rc))
    917947            {
    918                 rc = SSMR3SetCfgError(pSSM, RT_SRC_POS,
    919                                       N_("The VM is missing a block device. Please make sure the source and target VMs have compatible storage configurations"));
     948                RTMemFree(pEntry->pbData);
     949                RTMemFree(pEntry);
    920950                break;
    921951            }
    922952
    923             RTStrFree(pszId);
    924             pszId = NULL;
    925 
    926             /* Get the entries */
    927             uint32_t cEntries;
    928             SSMR3GetU32(pSSM, &cEntries);
    929 
    930             while (cEntries > 0)
    931             {
    932                 PPDMBLKCACHEENTRY pEntry;
    933                 uint64_t off;
    934                 uint32_t cbEntry;
    935 
    936                 SSMR3GetU64(pSSM, &off);
    937                 SSMR3GetU32(pSSM, &cbEntry);
    938 
    939                 pEntry = pdmBlkCacheEntryAlloc(pBlkCache, off, cbEntry, NULL);
    940                 if (!pEntry)
    941                 {
    942                     rc = VERR_NO_MEMORY;
    943                     break;
    944                 }
    945 
    946                 rc = SSMR3GetMem(pSSM, pEntry->pbData, cbEntry);
    947                 if (RT_FAILURE(rc))
    948                 {
    949                     RTMemFree(pEntry->pbData);
    950                     RTMemFree(pEntry);
    951                     break;
    952                 }
    953 
    954                 /* Insert into the tree. */
    955                 bool fInserted = RTAvlrU64Insert(pBlkCache->pTree, &pEntry->Core);
    956                 Assert(fInserted); NOREF(fInserted);
    957 
    958                 /* Add to the dirty list. */
    959                 pdmBlkCacheAddDirtyEntry(pBlkCache, pEntry);
    960                 pdmBlkCacheEntryAddToList(&pBlkCacheGlobal->LruRecentlyUsedIn, pEntry);
    961                 pdmBlkCacheAdd(pBlkCacheGlobal, cbEntry);
    962                 pdmBlkCacheEntryRelease(pEntry);
    963                 cEntries--;
    964             }
    965 
    966             cRefs--;
    967         }
    968 
    969         if (pszId)
    970             RTStrFree(pszId);
    971     }
    972     else
     953            /* Insert into the tree. */
     954            bool fInserted = RTAvlrU64Insert(pBlkCache->pTree, &pEntry->Core);
     955            Assert(fInserted); NOREF(fInserted);
     956
     957            /* Add to the dirty list. */
     958            pdmBlkCacheAddDirtyEntry(pBlkCache, pEntry);
     959            pdmBlkCacheEntryAddToList(&pBlkCacheGlobal->LruRecentlyUsedIn, pEntry);
     960            pdmBlkCacheAdd(pBlkCacheGlobal, cbEntry);
     961            pdmBlkCacheEntryRelease(pEntry);
     962            cEntries--;
     963        }
     964
     965        cRefs--;
     966    }
     967
     968    if (pszId)
     969        RTStrFree(pszId);
     970
     971    if (cRefs && RT_SUCCESS(rc))
    973972        rc = SSMR3SetCfgError(pSSM, RT_SRC_POS,
    974                               N_("The VM is missing a block device. Please make sure the source and target VMs have compatible storage configurations"));
     973                              N_("Unexpected error while restoring state. Please make sure the source and target VMs have compatible storage configurations"));
    975974
    976975    pdmBlkCacheLockLeave(pBlkCacheGlobal);
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