Index: /trunk/src/VBox/Main/ConsoleImpl2.cpp
===================================================================
--- /trunk/src/VBox/Main/ConsoleImpl2.cpp	(revision 30286)
+++ /trunk/src/VBox/Main/ConsoleImpl2.cpp	(revision 30287)
@@ -49,4 +49,5 @@
 # include <iprt/env.h>
 #endif
+#include <iprt/stream.h>
 
 #include <VBox/vmapi.h>
@@ -1296,5 +1297,5 @@
                                                   false /* fAttachDetach */,
                                                   false /* fForceUnmount */,
-                                                  NULL /* pVM */,
+                                                  pVM,
                                                   paLedDevType);                        RC_CHECK();
         }
@@ -2293,4 +2294,24 @@
 }
 
+/* XXX introduce RT format specifier */
+static uint64_t formatDiskSize(uint64_t u64Size, const char **pszUnit)
+{
+    if (u64Size > INT64_C(5000)*_1G)
+    {
+        *pszUnit = "TB";
+        return u64Size / _1T;
+    }
+    else if (u64Size > INT64_C(5000)*_1M)
+    {
+        *pszUnit = "GB";
+        return u64Size / _1G;
+    }
+    else
+    {
+        *pszUnit = "MB";
+        return u64Size / _1M;
+    }
+}
+
 int Console::configMediumAttachment(PCFGMNODE pCtlInst,
                                     const char *pcszDevice,
@@ -2393,4 +2414,117 @@
                       aMachineState,
                       phrc);                                                            RC_CHECK();
+
+    if (lType == DeviceType_HardDisk)
+    {
+        /*
+         * Some sanity checks.
+         */
+        ComPtr<IMediumFormat> pMediumFormat;
+        hrc = pMedium->COMGETTER(MediumFormat)(pMediumFormat.asOutParam());             H();
+        ULONG uCaps;
+        hrc = pMediumFormat->COMGETTER(Capabilities)(&uCaps);                           H();
+        if (uCaps & MediumFormatCapabilities_File)
+        {
+            Bstr strFile;
+            hrc = pMedium->COMGETTER(Location)(strFile.asOutParam());                   H();
+            Utf8Str utfFile = Utf8Str(strFile);
+            Bstr strSnap;
+            ComPtr<IMachine> pMachine = machine();
+            hrc = pMachine->COMGETTER(SnapshotFolder)(strSnap.asOutParam());            H();
+            Utf8Str utfSnap = Utf8Str(strSnap);
+            uint32_t typeFile, typeSnap;
+            rc = RTFsQueryType(utfFile.c_str(), &typeFile);
+            if (RT_SUCCESS(rc))
+                rc = RTFsQueryType(utfSnap.c_str(), &typeSnap);
+            ULONG64 u64Size;
+            hrc = pMedium->COMGETTER(LogicalSize)(&u64Size);                            H();
+            u64Size *= _1M;
+            if (RT_SUCCESS(rc))
+            {
+#ifdef RT_OS_WINDOWS
+                if (   typeFile == RTFS_FS_TYPE_FAT
+                    && u64Size >= _4G)
+                {
+                    const char *pszUnit;
+                    uint64_t u64Print = formatDiskSize(u64Size, &pszUnit);
+                    return VMSetError(pVM, VERR_FILE_TOO_BIG, RT_SRC_POS,
+                                      N_("The medium '%ls' has a logical size of %RU64%s "
+                                         "but the file system the medium is located on seems "
+                                         "to be FAT(32) which cannot handle files bigger than 4GB"),
+                                      strFile.raw(), u64Print, pszUnit);
+                }
+#else /* !RT_OS_WINDOWS */
+                if (   typeFile == RTFS_FS_TYPE_FAT
+                    || typeFile == RTFS_FS_TYPE_EXT
+                    || typeFile == RTFS_FS_TYPE_EXT2
+                    || typeFile == RTFS_FS_TYPE_EXT3
+                    || typeFile == RTFS_FS_TYPE_EXT4)
+                {
+                    RTFILE file;
+                    rc = RTFileOpen(&file, utfFile.c_str(), RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_NONE);
+                    if (RT_SUCCESS(rc))
+                    {
+                        RTFOFF maxSize;
+                        /* Careful: This function will work only on selected local file systems! */
+                        rc = RTFileGetMaxSizeEx(file, &maxSize);
+                        RTFileClose(file);
+                        if (   RT_SUCCESS(rc)
+                            && maxSize > 0
+                            && u64Size > (ULONG64)maxSize)
+                        {
+                            const char *pszUnitSiz;
+                            const char *pszUnitMax;
+                            uint64_t u64PrintSiz = formatDiskSize(u64Size, &pszUnitSiz);
+                            uint64_t u64PrintMax = formatDiskSize(maxSize, &pszUnitMax);
+                            return VMSetError(pVM, VERR_FILE_TOO_BIG, RT_SRC_POS,
+                                              N_("The medium '%ls' has a logical size of %RU64%s "
+                                                 "but the file system the medium is located on can "
+                                                 "only handle files up to %RU64%s in theory"),
+                                              strFile.raw(), u64PrintSiz, pszUnitSiz, u64PrintMax, pszUnitMax);
+                        }
+                    }
+                }
+#endif /* !RT_OS_WINDOWS */
+            }
+            /*
+             * Snapshot folder:
+             * Here we test only for a FAT partition as we had to create a dummy file otherwise
+             */
+            if (   typeSnap == RTFS_FS_TYPE_FAT
+                && u64Size >= _4G)
+            {
+                const char *pszUnit;
+                uint64_t u64Print = formatDiskSize(u64Size, &pszUnit);
+                return VMSetError(pVM, VERR_FILE_TOO_BIG, RT_SRC_POS,
+                                  N_("The snapshot folder of this VM '%ls' seems to be located on "
+                                     "a FAT(32) file system. The logical size of the medium '%ls' "
+                                     "(%RU64%s) is bigger than the maximum file size this file "
+                                     "system can handle (4GB)"),
+                                  strSnap.raw(), strFile.raw(), u64Print, pszUnit);
+            }
+#ifdef RT_OS_LINUX
+            /*
+             * Ext4 bug: Check if the host I/O cache is disabled and the disk image is located
+             *           on an ext4 partition. Later we have to check the Linux kernel version!
+             */
+            if (   (uCaps & MediumFormatCapabilities_Asynchronous)
+                && !fUseHostIOCache
+                && (   typeFile == RTFS_FS_TYPE_EXT4
+                    || typeSnap == RTFS_FS_TYPE_EXT4))
+            {
+                return VMSetError(pVM, VERR_GENERAL_FAILURE /*XXX*/, RT_SRC_POS,
+                                  N_("The host I/O cache for at least one controller is disabled "
+                                     "but the medium '%ls' or the snapshot folder for this VM "
+                                     "is located on an ext4 partition. There is a known Linux "
+                                     "kernel bug "
+                                     "which can lead to the corruption of the virtual disk image "
+                                     "under these conditions.\n"
+                                     "Either enable the host I/O cache or put the disk image and "
+                                     "the snapshot folder onto a different file system"),
+                                  strFile.raw());
+            }
+#endif
+        }
+    }
 
     if (fAttachDetach)
