mirror of
https://github.com/mongodb/mongo.git
synced 2024-12-01 01:21:03 +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:
parent
bc274534b8
commit
aee446a97d
@ -886,7 +886,8 @@ elif windows:
|
|||||||
'Psapi.lib',
|
'Psapi.lib',
|
||||||
'DbgHelp.lib',
|
'DbgHelp.lib',
|
||||||
'shell32.lib',
|
'shell32.lib',
|
||||||
'Iphlpapi.lib'])
|
'Iphlpapi.lib',
|
||||||
|
'version.lib'])
|
||||||
|
|
||||||
# v8 calls timeGetTime()
|
# v8 calls timeGetTime()
|
||||||
if usev8:
|
if usev8:
|
||||||
|
@ -84,6 +84,18 @@ namespace mongo {
|
|||||||
static inline long lseek(int fd, long offset, int origin) { return _lseek(fd, offset, origin); }
|
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 write(int fd, const void *data, int count) { return _write(fd, data, count); }
|
||||||
static inline int close(int fd) { return _close(fd); }
|
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
|
#endif
|
||||||
|
|
||||||
boost::filesystem::path ensureParentDirCreated(const boost::filesystem::path& p){
|
boost::filesystem::path ensureParentDirCreated(const boost::filesystem::path& p){
|
||||||
@ -195,6 +207,30 @@ namespace mongo {
|
|||||||
#endif
|
#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) {
|
void FileAllocator::ensureLength(int fd , long size) {
|
||||||
// Test running out of disk scenarios
|
// Test running out of disk scenarios
|
||||||
if (MONGO_FAIL_POINT(allocateDiskFull)) {
|
if (MONGO_FAIL_POINT(allocateDiskFull)) {
|
||||||
@ -240,6 +276,13 @@ namespace mongo {
|
|||||||
return;
|
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);
|
lseek(fd, 0, SEEK_SET);
|
||||||
|
|
||||||
const long z = 256 * 1024;
|
const long z = 256 * 1024;
|
||||||
@ -301,7 +344,7 @@ namespace mongo {
|
|||||||
return fn;
|
return fn;
|
||||||
}
|
}
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
void FileAllocator::run( FileAllocator * fa ) {
|
void FileAllocator::run( FileAllocator * fa ) {
|
||||||
setThreadName( "FileAllocator" );
|
setThreadName( "FileAllocator" );
|
||||||
|
@ -121,6 +121,89 @@ namespace mongo {
|
|||||||
#endif
|
#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() {
|
void ProcessInfo::SystemInfo::collectSystemInfo() {
|
||||||
BSONObjBuilder bExtra;
|
BSONObjBuilder bExtra;
|
||||||
stringstream verstr;
|
stringstream verstr;
|
||||||
@ -179,7 +262,13 @@ namespace mongo {
|
|||||||
// http://support.microsoft.com/kb/2731284.
|
// http://support.microsoft.com/kb/2731284.
|
||||||
//
|
//
|
||||||
if ((osvi.wServicePackMajor >= 0) && (osvi.wServicePackMajor < 2)) {
|
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;
|
break;
|
||||||
case 0:
|
case 0:
|
||||||
|
Loading…
Reference in New Issue
Block a user