Changeset 30287 in vbox
- Timestamp:
- Jun 17, 2010 3:46:47 PM (14 years ago)
- File:
-
- 1 edited
-
trunk/src/VBox/Main/ConsoleImpl2.cpp (modified) (4 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Main/ConsoleImpl2.cpp
r30177 r30287 49 49 # include <iprt/env.h> 50 50 #endif 51 #include <iprt/stream.h> 51 52 52 53 #include <VBox/vmapi.h> … … 1296 1297 false /* fAttachDetach */, 1297 1298 false /* fForceUnmount */, 1298 NULL /* pVM */,1299 pVM, 1299 1300 paLedDevType); RC_CHECK(); 1300 1301 } … … 2293 2294 } 2294 2295 2296 /* XXX introduce RT format specifier */ 2297 static 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 2295 2316 int Console::configMediumAttachment(PCFGMNODE pCtlInst, 2296 2317 const char *pcszDevice, … … 2393 2414 aMachineState, 2394 2415 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 } 2395 2529 2396 2530 if (fAttachDetach)
Note:
See TracChangeset
for help on using the changeset viewer.

