0
0
mirror of https://github.com/mongodb/mongo.git synced 2024-11-30 17:10:48 +01:00

SERVER-14992: Checking ntfs.sys version to figure out if it's necessary to zero out data files.

Closes #894

Signed-off-by: Mark Benvenuto <mark.benvenuto@mongodb.com>
This commit is contained in:
agherardi 2014-12-28 18:34:43 -07:00 committed by Mark Benvenuto
parent bc274534b8
commit aee446a97d
3 changed files with 136 additions and 3 deletions

View File

@ -886,7 +886,8 @@ elif windows:
'Psapi.lib',
'DbgHelp.lib',
'shell32.lib',
'Iphlpapi.lib'])
'Iphlpapi.lib',
'version.lib'])
# v8 calls timeGetTime()
if usev8:

View File

@ -84,6 +84,18 @@ namespace mongo {
static inline long lseek(int fd, long offset, int origin) { return _lseek(fd, offset, origin); }
static inline int write(int fd, const void *data, int count) { return _write(fd, data, count); }
static inline int close(int fd) { return _close(fd); }
typedef BOOL (CALLBACK *GetVolumeInformationByHandleWPtr)(HANDLE, LPWSTR, DWORD, LPDWORD, LPDWORD, LPDWORD, LPWSTR, DWORD);
GetVolumeInformationByHandleWPtr GetVolumeInformationByHandleWFunc;
MONGO_INITIALIZER(InitGetVolumeInformationByHandleW)(InitializerContext *context) {
HMODULE kernelLib = LoadLibraryA("kernel32.dll");
if (kernelLib) {
GetVolumeInformationByHandleWFunc = reinterpret_cast<GetVolumeInformationByHandleWPtr>
(GetProcAddress(kernelLib, "GetVolumeInformationByHandleW"));
}
return Status::OK();
}
#endif
boost::filesystem::path ensureParentDirCreated(const boost::filesystem::path& p){
@ -195,6 +207,30 @@ namespace mongo {
#endif
}
#if defined(_WIN32)
static bool isFileOnNTFSVolume(int fd) {
if (!GetVolumeInformationByHandleWFunc) {
warning() << "Could not retrieve pointer to GetVolumeInformationByHandleW function";
return false;
}
HANDLE fileHandle = (HANDLE)_get_osfhandle(fd);
if (fileHandle == INVALID_HANDLE_VALUE) {
warning() << "_get_osfhandle() failed with " << _strerror(NULL);
return false;
}
WCHAR fileSystemName[MAX_PATH + 1];
if (!GetVolumeInformationByHandleWFunc(fileHandle, NULL, 0, NULL, 0, NULL, fileSystemName, sizeof(fileSystemName))) {
DWORD gle = GetLastError();
warning() << "GetVolumeInformationByHandleW failed with " << errnoWithDescription(gle);
return false;
}
return lstrcmpW(fileSystemName, L"NTFS") == 0;
}
#endif
void FileAllocator::ensureLength(int fd , long size) {
// Test running out of disk scenarios
if (MONGO_FAIL_POINT(allocateDiskFull)) {
@ -240,6 +276,13 @@ namespace mongo {
return;
}
#if defined(_WIN32)
if (!isFileOnNTFSVolume(fd)) {
log() << "No need to zero out datafile on non-NTFS volume" << endl;
return;
}
#endif
lseek(fd, 0, SEEK_SET);
const long z = 256 * 1024;
@ -301,7 +344,7 @@ namespace mongo {
return fn;
}
return "";
}
}
void FileAllocator::run( FileAllocator * fa ) {
setThreadName( "FileAllocator" );

View File

@ -121,6 +121,89 @@ namespace mongo {
#endif
}
bool getFileVersion(const char *filePath, DWORD &fileVersionMS, DWORD &fileVersionLS) {
DWORD verSize = GetFileVersionInfoSizeA(filePath, NULL);
if (verSize == 0) {
DWORD gle = GetLastError();
warning() << "GetFileVersionInfoSizeA on " << filePath << " failed with " << errnoWithDescription(gle);
return false;
}
boost::scoped_array<char> verData(new char[verSize]);
if (GetFileVersionInfoA(filePath, NULL, verSize, verData.get()) == 0) {
DWORD gle = GetLastError();
warning() << "GetFileVersionInfoSizeA on " << filePath << " failed with " << errnoWithDescription(gle);
return false;
}
UINT size;
VS_FIXEDFILEINFO *verInfo;
if (VerQueryValueA(verData.get(), "\\", (LPVOID *)&verInfo, &size) == 0) {
DWORD gle = GetLastError();
warning() << "VerQueryValueA on " << filePath << " failed with " << errnoWithDescription(gle);
return false;
}
if (size != sizeof(VS_FIXEDFILEINFO)) {
warning() << "VerQueryValueA on " << filePath << " returned structure with unexpected size";
return false;
}
fileVersionMS = verInfo->dwFileVersionMS;
fileVersionLS = verInfo->dwFileVersionLS;
return true;
}
// If the version of the ntfs.sys driver shows that the KB2731284 hotfix or a later update
// is installed, zeroing out data files is unnecessary. The file version numbers used below
// are taken from the Hotfix File Information at http://support.microsoft.com/kb/2731284.
bool isKB2731284OrLaterUpdateInstalled() {
UINT pathBufferSize = GetSystemDirectoryA(NULL, 0);
if (pathBufferSize == 0) {
DWORD gle = GetLastError();
warning() << "GetSystemDirectoryA failed with " << errnoWithDescription(gle);
return false;
}
boost::scoped_array<char> systemDirectory(new char[pathBufferSize]);
UINT systemDirectoryPathLen;
systemDirectoryPathLen = GetSystemDirectoryA(systemDirectory.get(), pathBufferSize);
if (systemDirectoryPathLen == 0) {
DWORD gle = GetLastError();
warning() << "GetSystemDirectoryA failed with " << errnoWithDescription(gle);
return false;
}
if (systemDirectoryPathLen != pathBufferSize - 1) {
warning() << "GetSystemDirectoryA returned unexpected path length";
return false;
}
string ntfsDotSysPath = systemDirectory.get();
if (ntfsDotSysPath.back() != '\\') {
ntfsDotSysPath.append("\\");
}
ntfsDotSysPath.append("drivers\\ntfs.sys");
DWORD fileVersionMS;
DWORD fileVersionLS;
if (getFileVersion(ntfsDotSysPath.c_str(), fileVersionMS, fileVersionLS)) {
WORD fileVersionFirstNumber = HIWORD(fileVersionMS);
WORD fileVersionSecondNumber = LOWORD(fileVersionMS);
WORD fileVersionThirdNumber = HIWORD(fileVersionLS);
WORD fileVersionFourthNumber = LOWORD(fileVersionLS);
if (fileVersionFirstNumber == 6 && fileVersionSecondNumber == 1 && fileVersionThirdNumber == 7600 &&
fileVersionFourthNumber >= 21296 && fileVersionFourthNumber <= 21999) {
return true;
} else if (fileVersionFirstNumber == 6 && fileVersionSecondNumber == 1 && fileVersionThirdNumber == 7601 &&
fileVersionFourthNumber >= 22083 && fileVersionFourthNumber <= 22999) {
return true;
}
}
return false;
}
void ProcessInfo::SystemInfo::collectSystemInfo() {
BSONObjBuilder bExtra;
stringstream verstr;
@ -179,7 +262,13 @@ namespace mongo {
// http://support.microsoft.com/kb/2731284.
//
if ((osvi.wServicePackMajor >= 0) && (osvi.wServicePackMajor < 2)) {
fileZeroNeeded = true;
if (isKB2731284OrLaterUpdateInstalled()) {
log() << "Hotfix KB2731284 or later update is installed, no need to zero-out data files";
fileZeroNeeded = false;
} else {
log() << "Hotfix KB2731284 or later update is not installed, will zero-out data files";
fileZeroNeeded = true;
}
}
break;
case 0: