VirtualBox

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


Ignore:
Timestamp:
Oct 18, 2012 9:41:20 AM (12 years ago)
Author:
vboxsync
Message:

Main/Snapshot: issue 4386. Check available free space on the storages before merging.

File:
1 edited

Legend:

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

    r42889 r43677  
    24822482                                                   fNeedsOnlineMerge,
    24832483                                                   pMediumLockList));
     2484        }
     2485
     2486        {/* issue 4386 */
     2487            /*check available place on the storage*/
     2488            RTFOFF pcbTotal=0;
     2489            RTFOFF pcbFree=0;
     2490            uint32_t pcbBlock=0;
     2491            uint32_t pcbSector=0;
     2492            std::multimap<uint32_t,uint64_t> neededStorageFreeSpace;
     2493            std::map<uint32_t,const char*> serialMapToStoragePath;
     2494
     2495            MediumDeleteRecList::const_iterator it_md = toDelete.begin();
     2496
     2497            while(it_md!=toDelete.end())
     2498            {
     2499                uint64_t diskSize=0;
     2500                uint32_t pu32Serial=0;
     2501                ComObjPtr<Medium> pSource_local = it_md->mpSource;
     2502                ComObjPtr<Medium> pTarget_local = it_md->mpTarget;
     2503
     2504                rc = RTFsQuerySerial(pTarget_local->getLocationFull().c_str(), &pu32Serial);
     2505                if (FAILED(rc))
     2506                    throw rc;
     2507
     2508                /* 0xc0ffee - some magic number from the file fs-stubs-generic.cpp. Case of using stub */
     2509                if(pu32Serial==0xc0ffee)
     2510                {
     2511                    LogFlowThisFunc(("Can't find storage UID, function isn't implemented...\n"));
     2512                    rc = setError(VERR_NOT_IMPLEMENTED,
     2513                                      tr(" Impossible merging with '%s'. Can't find storage UID, function isn't implemented."),
     2514                                      pTarget_local->getLocationFull().c_str());
     2515                    throw rc;
     2516                }
     2517
     2518                pSource_local->COMGETTER(Size)((LONG64*)&diskSize);
     2519
     2520                /* store needed free space in multimap */
     2521                neededStorageFreeSpace.insert(std::make_pair(pu32Serial,diskSize));
     2522                /* linking storage UID with snapshot path, it is a helper container (just for easy finding needed path) */
     2523                serialMapToStoragePath.insert(std::make_pair(pu32Serial,pTarget_local->getLocationFull().c_str()));
     2524                ++it_md;
     2525            }
     2526
     2527            while(!neededStorageFreeSpace.empty())
     2528            {
     2529                std::pair<std::multimap<uint32_t,uint64_t>::iterator,std::multimap<uint32_t,uint64_t>::iterator> ret;
     2530                uint64_t commonSourceStoragesSize = 0;
     2531
     2532                /* find all records in multimap with identical storage UID*/
     2533                ret = neededStorageFreeSpace.equal_range(neededStorageFreeSpace.begin()->first);
     2534                std::multimap<uint32_t,uint64_t>::const_iterator it_ns = ret.first;
     2535
     2536                for(;it_ns!=ret.second;++it_ns)
     2537                {
     2538                    commonSourceStoragesSize+=it_ns->second;
     2539                }
     2540
     2541                /* find appropriate path by storage UID*/
     2542                std::map<uint32_t,const char*>::const_iterator it_sm = serialMapToStoragePath.find(it_ns->first);
     2543                /* get info about storage */
     2544                rc = RTFsQuerySizes(it_sm->second, &pcbTotal, &pcbFree,&pcbBlock, &pcbSector);
     2545                if (FAILED(rc))
     2546                    throw rc;
     2547
     2548                if(commonSourceStoragesSize > (uint64_t)pcbFree)
     2549                {
     2550                    LogFlowThisFunc(("Free space on the target disk less than needed for merging ...\n"));
     2551                    //what is more suitable?
     2552                    //VERR_NO_TMP_MEMORY, VERR_NO_PHYS_MEMORY, VERR_FILE_AIO_INSUFFICIENT_RESSOURCES, VERR_FILE_AIO_LIMIT_EXCE
     2553                    rc = setError(VERR_FILE_AIO_INSUFFICIENT_RESSOURCES,
     2554                                      tr(" Impossible merging with '%s'. Free space on the target disk less than needed for merging"),
     2555                                      it_sm->second);
     2556                    throw rc;
     2557                }
     2558
     2559                neededStorageFreeSpace.erase(ret.first, ret.second);
     2560            }
     2561
     2562            serialMapToStoragePath.clear();
    24842563        }
    24852564
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