VirtualBox

Changeset 30287 in vbox


Ignore:
Timestamp:
Jun 17, 2010 3:46:47 PM (14 years ago)
Author:
vboxsync
Message:

Main: added some host partition sanity checks for all virtual disk images and for the snapshot folder

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Main/ConsoleImpl2.cpp

    r30177 r30287  
    4949# include <iprt/env.h>
    5050#endif
     51#include <iprt/stream.h>
    5152
    5253#include <VBox/vmapi.h>
     
    12961297                                                  false /* fAttachDetach */,
    12971298                                                  false /* fForceUnmount */,
    1298                                                   NULL /* pVM */,
     1299                                                  pVM,
    12991300                                                  paLedDevType);                        RC_CHECK();
    13001301        }
     
    22932294}
    22942295
     2296/* XXX introduce RT format specifier */
     2297static uint64_t formatDiskSize(uint64_t u64Size, const char **pszUnit)
     2298{
     2299    if (u64Size > INT64_C(5000)*_1G)
     2300    {
     2301        *pszUnit = "TB";
     2302        return u64Size / _1T;
     2303    }
     2304    else if (u64Size > INT64_C(5000)*_1M)
     2305    {
     2306        *pszUnit = "GB";
     2307        return u64Size / _1G;
     2308    }
     2309    else
     2310    {
     2311        *pszUnit = "MB";
     2312        return u64Size / _1M;
     2313    }
     2314}
     2315
    22952316int Console::configMediumAttachment(PCFGMNODE pCtlInst,
    22962317                                    const char *pcszDevice,
     
    23932414                      aMachineState,
    23942415                      phrc);                                                            RC_CHECK();
     2416
     2417    if (lType == DeviceType_HardDisk)
     2418    {
     2419        /*
     2420         * Some sanity checks.
     2421         */
     2422        ComPtr<IMediumFormat> pMediumFormat;
     2423        hrc = pMedium->COMGETTER(MediumFormat)(pMediumFormat.asOutParam());             H();
     2424        ULONG uCaps;
     2425        hrc = pMediumFormat->COMGETTER(Capabilities)(&uCaps);                           H();
     2426        if (uCaps & MediumFormatCapabilities_File)
     2427        {
     2428            Bstr strFile;
     2429            hrc = pMedium->COMGETTER(Location)(strFile.asOutParam());                   H();
     2430            Utf8Str utfFile = Utf8Str(strFile);
     2431            Bstr strSnap;
     2432            ComPtr<IMachine> pMachine = machine();
     2433            hrc = pMachine->COMGETTER(SnapshotFolder)(strSnap.asOutParam());            H();
     2434            Utf8Str utfSnap = Utf8Str(strSnap);
     2435            uint32_t typeFile, typeSnap;
     2436            rc = RTFsQueryType(utfFile.c_str(), &typeFile);
     2437            if (RT_SUCCESS(rc))
     2438                rc = RTFsQueryType(utfSnap.c_str(), &typeSnap);
     2439            ULONG64 u64Size;
     2440            hrc = pMedium->COMGETTER(LogicalSize)(&u64Size);                            H();
     2441            u64Size *= _1M;
     2442            if (RT_SUCCESS(rc))
     2443            {
     2444#ifdef RT_OS_WINDOWS
     2445                if (   typeFile == RTFS_FS_TYPE_FAT
     2446                    && u64Size >= _4G)
     2447                {
     2448                    const char *pszUnit;
     2449                    uint64_t u64Print = formatDiskSize(u64Size, &pszUnit);
     2450                    return VMSetError(pVM, VERR_FILE_TOO_BIG, RT_SRC_POS,
     2451                                      N_("The medium '%ls' has a logical size of %RU64%s "
     2452                                         "but the file system the medium is located on seems "
     2453                                         "to be FAT(32) which cannot handle files bigger than 4GB"),
     2454                                      strFile.raw(), u64Print, pszUnit);
     2455                }
     2456#else /* !RT_OS_WINDOWS */
     2457                if (   typeFile == RTFS_FS_TYPE_FAT
     2458                    || typeFile == RTFS_FS_TYPE_EXT
     2459                    || typeFile == RTFS_FS_TYPE_EXT2
     2460                    || typeFile == RTFS_FS_TYPE_EXT3
     2461                    || typeFile == RTFS_FS_TYPE_EXT4)
     2462                {
     2463                    RTFILE file;
     2464                    rc = RTFileOpen(&file, utfFile.c_str(), RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_NONE);
     2465                    if (RT_SUCCESS(rc))
     2466                    {
     2467                        RTFOFF maxSize;
     2468                        /* Careful: This function will work only on selected local file systems! */
     2469                        rc = RTFileGetMaxSizeEx(file, &maxSize);
     2470                        RTFileClose(file);
     2471                        if (   RT_SUCCESS(rc)
     2472                            && maxSize > 0
     2473                            && u64Size > (ULONG64)maxSize)
     2474                        {
     2475                            const char *pszUnitSiz;
     2476                            const char *pszUnitMax;
     2477                            uint64_t u64PrintSiz = formatDiskSize(u64Size, &pszUnitSiz);
     2478                            uint64_t u64PrintMax = formatDiskSize(maxSize, &pszUnitMax);
     2479                            return VMSetError(pVM, VERR_FILE_TOO_BIG, RT_SRC_POS,
     2480                                              N_("The medium '%ls' has a logical size of %RU64%s "
     2481                                                 "but the file system the medium is located on can "
     2482                                                 "only handle files up to %RU64%s in theory"),
     2483                                              strFile.raw(), u64PrintSiz, pszUnitSiz, u64PrintMax, pszUnitMax);
     2484                        }
     2485                    }
     2486                }
     2487#endif /* !RT_OS_WINDOWS */
     2488            }
     2489            /*
     2490             * Snapshot folder:
     2491             * Here we test only for a FAT partition as we had to create a dummy file otherwise
     2492             */
     2493            if (   typeSnap == RTFS_FS_TYPE_FAT
     2494                && u64Size >= _4G)
     2495            {
     2496                const char *pszUnit;
     2497                uint64_t u64Print = formatDiskSize(u64Size, &pszUnit);
     2498                return VMSetError(pVM, VERR_FILE_TOO_BIG, RT_SRC_POS,
     2499                                  N_("The snapshot folder of this VM '%ls' seems to be located on "
     2500                                     "a FAT(32) file system. The logical size of the medium '%ls' "
     2501                                     "(%RU64%s) is bigger than the maximum file size this file "
     2502                                     "system can handle (4GB)"),
     2503                                  strSnap.raw(), strFile.raw(), u64Print, pszUnit);
     2504            }
     2505#ifdef RT_OS_LINUX
     2506            /*
     2507             * Ext4 bug: Check if the host I/O cache is disabled and the disk image is located
     2508             *           on an ext4 partition. Later we have to check the Linux kernel version!
     2509             */
     2510            if (   (uCaps & MediumFormatCapabilities_Asynchronous)
     2511                && !fUseHostIOCache
     2512                && (   typeFile == RTFS_FS_TYPE_EXT4
     2513                    || typeSnap == RTFS_FS_TYPE_EXT4))
     2514            {
     2515                return VMSetError(pVM, VERR_GENERAL_FAILURE /*XXX*/, RT_SRC_POS,
     2516                                  N_("The host I/O cache for at least one controller is disabled "
     2517                                     "but the medium '%ls' or the snapshot folder for this VM "
     2518                                     "is located on an ext4 partition. There is a known Linux "
     2519                                     "kernel bug "
     2520                                     "which can lead to the corruption of the virtual disk image "
     2521                                     "under these conditions.\n"
     2522                                     "Either enable the host I/O cache or put the disk image and "
     2523                                     "the snapshot folder onto a different file system"),
     2524                                  strFile.raw());
     2525            }
     2526#endif
     2527        }
     2528    }
    23952529
    23962530    if (fAttachDetach)
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