mdbx: добавление опции сборки MDBX_ENABLE_NON_READONLY_EXPORT и логирование соответствующих ситуаций.

Закрывает [запрос](https://gitflic.ru/project/erthink/libmdbx/issue/16).
This commit is contained in:
Леонид Юрьев (Leonid Yuriev) 2025-01-13 23:13:24 +03:00
parent e4054b56c3
commit 0accf98ff7
5 changed files with 46 additions and 17 deletions

View File

@ -676,7 +676,7 @@ __cold int dxb_setup(MDBX_env *env, const int lck_rc, const mdbx_mode_t mode_bit
!(env->flags & MDBX_NORDAHEAD) && mdbx_is_readahead_reasonable(used_bytes, 0) == MDBX_RESULT_TRUE; !(env->flags & MDBX_NORDAHEAD) && mdbx_is_readahead_reasonable(used_bytes, 0) == MDBX_RESULT_TRUE;
err = osal_mmap(env->flags, &env->dxb_mmap, env->geo_in_bytes.now, env->geo_in_bytes.upper, err = osal_mmap(env->flags, &env->dxb_mmap, env->geo_in_bytes.now, env->geo_in_bytes.upper,
(lck_rc && env->stuck_meta < 0) ? MMAP_OPTION_TRUNCATE : 0); (lck_rc && env->stuck_meta < 0) ? MMAP_OPTION_TRUNCATE : 0, env->pathname.dxb);
if (unlikely(err != MDBX_SUCCESS)) if (unlikely(err != MDBX_SUCCESS))
return err; return err;

View File

@ -62,8 +62,9 @@ __cold static int lck_setup_locked(MDBX_env *env) {
} }
env->max_readers = (maxreaders <= MDBX_READERS_LIMIT) ? (unsigned)maxreaders : (unsigned)MDBX_READERS_LIMIT; env->max_readers = (maxreaders <= MDBX_READERS_LIMIT) ? (unsigned)maxreaders : (unsigned)MDBX_READERS_LIMIT;
err = osal_mmap((env->flags & MDBX_EXCLUSIVE) | MDBX_WRITEMAP, &env->lck_mmap, (size_t)size, (size_t)size, err =
lck_seize_rc ? MMAP_OPTION_TRUNCATE | MMAP_OPTION_SEMAPHORE : MMAP_OPTION_SEMAPHORE); osal_mmap((env->flags & MDBX_EXCLUSIVE) | MDBX_WRITEMAP, &env->lck_mmap, (size_t)size, (size_t)size,
lck_seize_rc ? MMAP_OPTION_TRUNCATE | MMAP_OPTION_SEMAPHORE : MMAP_OPTION_SEMAPHORE, env->pathname.lck);
if (unlikely(err != MDBX_SUCCESS)) if (unlikely(err != MDBX_SUCCESS))
return err; return err;

View File

@ -265,6 +265,14 @@
#error MDBX_NOSUCCESS_PURE_COMMIT must be defined as 0 or 1 #error MDBX_NOSUCCESS_PURE_COMMIT must be defined as 0 or 1
#endif /* MDBX_NOSUCCESS_PURE_COMMIT */ #endif /* MDBX_NOSUCCESS_PURE_COMMIT */
/** if enabled then instead of the returned error `MDBX_REMOTE`, only a warning is issued, when
* the database being opened in non-read-only mode is located in a file system exported via NFS. */
#ifndef MDBX_ENABLE_NON_READONLY_EXPORT
#define MDBX_ENABLE_NON_READONLY_EXPORT 0
#elif !(MDBX_ENABLE_NON_READONLY_EXPORT == 0 || MDBX_ENABLE_NON_READONLY_EXPORT == 1)
#error MDBX_ENABLE_NON_READONLY_EXPORT must be defined as 0 or 1
#endif /* MDBX_ENABLE_NON_READONLY_EXPORT */
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
/** Win32 File Locking API for \ref MDBX_LOCKING */ /** Win32 File Locking API for \ref MDBX_LOCKING */

View File

@ -1760,7 +1760,7 @@ static int osal_check_fs_local(mdbx_filehandle_t handle, int flags) {
if ((RemoteProtocolInfo.Flags & REMOTE_PROTOCOL_INFO_FLAG_OFFLINE) && !(flags & MDBX_RDONLY)) if ((RemoteProtocolInfo.Flags & REMOTE_PROTOCOL_INFO_FLAG_OFFLINE) && !(flags & MDBX_RDONLY))
return ERROR_FILE_OFFLINE; return ERROR_FILE_OFFLINE;
if (!(RemoteProtocolInfo.Flags & REMOTE_PROTOCOL_INFO_FLAG_LOOPBACK) && !(flags & MDBX_EXCLUSIVE)) if (!(RemoteProtocolInfo.Flags & REMOTE_PROTOCOL_INFO_FLAG_LOOPBACK) && !(flags & MDBX_EXCLUSIVE))
return ERROR_REMOTE_STORAGE_MEDIA_ERROR; return MDBX_EREMOTE;
} }
} }
@ -1779,7 +1779,7 @@ static int osal_check_fs_local(mdbx_filehandle_t handle, int flags) {
0, &GetExternalBacking_OutputBuffer, sizeof(GetExternalBacking_OutputBuffer)); 0, &GetExternalBacking_OutputBuffer, sizeof(GetExternalBacking_OutputBuffer));
if (NT_SUCCESS(rc)) { if (NT_SUCCESS(rc)) {
if (!(flags & MDBX_EXCLUSIVE)) if (!(flags & MDBX_EXCLUSIVE))
return ERROR_REMOTE_STORAGE_MEDIA_ERROR; return MDBX_EREMOTE;
} else if (rc != STATUS_OBJECT_NOT_EXTERNALLY_BACKED && rc != STATUS_INVALID_DEVICE_REQUEST && } else if (rc != STATUS_OBJECT_NOT_EXTERNALLY_BACKED && rc != STATUS_INVALID_DEVICE_REQUEST &&
rc != STATUS_NOT_SUPPORTED) rc != STATUS_NOT_SUPPORTED)
return ntstatus2errcode(rc); return ntstatus2errcode(rc);
@ -1800,7 +1800,7 @@ static int osal_check_fs_local(mdbx_filehandle_t handle, int flags) {
if ((flags & MDBX_RDONLY) == 0) { if ((flags & MDBX_RDONLY) == 0) {
if (FileSystemFlags & (FILE_SEQUENTIAL_WRITE_ONCE | FILE_READ_ONLY_VOLUME | FILE_VOLUME_IS_COMPRESSED)) { if (FileSystemFlags & (FILE_SEQUENTIAL_WRITE_ONCE | FILE_READ_ONLY_VOLUME | FILE_VOLUME_IS_COMPRESSED)) {
rc = ERROR_REMOTE_STORAGE_MEDIA_ERROR; rc = MDBX_EREMOTE;
goto bailout; goto bailout;
} }
} }
@ -1808,7 +1808,7 @@ static int osal_check_fs_local(mdbx_filehandle_t handle, int flags) {
if (imports.GetFinalPathNameByHandleW(handle, PathBuffer, INT16_MAX, FILE_NAME_NORMALIZED | VOLUME_NAME_NT)) { if (imports.GetFinalPathNameByHandleW(handle, PathBuffer, INT16_MAX, FILE_NAME_NORMALIZED | VOLUME_NAME_NT)) {
if (_wcsnicmp(PathBuffer, L"\\Device\\Mup\\", 12) == 0) { if (_wcsnicmp(PathBuffer, L"\\Device\\Mup\\", 12) == 0) {
if (!(flags & MDBX_EXCLUSIVE)) { if (!(flags & MDBX_EXCLUSIVE)) {
rc = ERROR_REMOTE_STORAGE_MEDIA_ERROR; rc = MDBX_EREMOTE;
goto bailout; goto bailout;
} }
} }
@ -1836,7 +1836,7 @@ static int osal_check_fs_local(mdbx_filehandle_t handle, int flags) {
case DRIVE_REMOTE: case DRIVE_REMOTE:
default: default:
if (!(flags & MDBX_EXCLUSIVE)) if (!(flags & MDBX_EXCLUSIVE))
rc = ERROR_REMOTE_STORAGE_MEDIA_ERROR; rc = MDBX_EREMOTE;
// fall through // fall through
case DRIVE_REMOVABLE: case DRIVE_REMOVABLE:
case DRIVE_FIXED: case DRIVE_FIXED:
@ -1968,11 +1968,11 @@ static int osal_check_fs_local(mdbx_filehandle_t handle, int flags) {
#endif /* ST/MNT_LOCAL */ #endif /* ST/MNT_LOCAL */
#ifdef ST_EXPORTED #ifdef ST_EXPORTED
if ((st_flags & ST_EXPORTED) != 0 && !(flags & MDBX_RDONLY)) if ((st_flags & ST_EXPORTED) != 0 && !(flags & (MDBX_RDONLY | MDBX_EXCLUSIVE))))
return MDBX_EREMOTE; return MDBX_RESULT_TRUE;
#elif defined(MNT_EXPORTED) #elif defined(MNT_EXPORTED)
if ((mnt_flags & MNT_EXPORTED) != 0 && !(flags & MDBX_RDONLY)) if ((mnt_flags & MNT_EXPORTED) != 0 && !(flags & (MDBX_RDONLY | MDBX_EXCLUSIVE)))
return MDBX_EREMOTE; return MDBX_RESULT_TRUE;
#endif /* ST/MNT_EXPORTED */ #endif /* ST/MNT_EXPORTED */
switch (type) { switch (type) {
@ -2023,8 +2023,8 @@ static int check_mmap_limit(const size_t limit) {
return MDBX_SUCCESS; return MDBX_SUCCESS;
} }
MDBX_INTERNAL int osal_mmap(const int flags, osal_mmap_t *map, size_t size, const size_t limit, MDBX_INTERNAL int osal_mmap(const int flags, osal_mmap_t *map, size_t size, const size_t limit, const unsigned options,
const unsigned options) { const pathchar_t *pathname4logging) {
assert(size <= limit); assert(size <= limit);
map->limit = 0; map->limit = 0;
map->current = 0; map->current = 0;
@ -2035,8 +2035,27 @@ MDBX_INTERNAL int osal_mmap(const int flags, osal_mmap_t *map, size_t size, cons
#endif /* Windows */ #endif /* Windows */
int err = osal_check_fs_local(map->fd, flags); int err = osal_check_fs_local(map->fd, flags);
if (unlikely(err != MDBX_SUCCESS)) if (unlikely(err != MDBX_SUCCESS)) {
return err; #if defined(_WIN32) || defined(_WIN64)
if (globals.running_under_Wine)
NOTICE("%s", "Please use native Linux application or WSL at least, instead of trouble-full Wine!");
#endif /* Windows */
switch (err) {
case MDBX_RESULT_TRUE:
#if MDBX_ENABLE_NON_READONLY_EXPORT
WARNING("%" MDBX_PRIsPATH " is exported via NFS, avoid using the file on a remote side!", pathname4logging);
break;
#else
ERROR("%" MDBX_PRIsPATH " is exported via NFS", pathname4logging);
return MDBX_EREMOTE;
#endif /* MDBX_PROHIBIT_NON_READONLY_EXPORT */
case MDBX_EREMOTE:
ERROR("%" MDBX_PRIsPATH " is on a remote file system, the %s is required", pathname4logging, "MDBX_EXCLUSIVE");
__fallthrough /* fall through */;
default:
return err;
}
}
err = check_mmap_limit(limit); err = check_mmap_limit(limit);
if (unlikely(err != MDBX_SUCCESS)) if (unlikely(err != MDBX_SUCCESS))

View File

@ -464,7 +464,8 @@ MDBX_INTERNAL int osal_lockfile(mdbx_filehandle_t fd, bool wait);
#define MMAP_OPTION_TRUNCATE 1 #define MMAP_OPTION_TRUNCATE 1
#define MMAP_OPTION_SEMAPHORE 2 #define MMAP_OPTION_SEMAPHORE 2
MDBX_INTERNAL int osal_mmap(const int flags, osal_mmap_t *map, size_t size, const size_t limit, const unsigned options); MDBX_INTERNAL int osal_mmap(const int flags, osal_mmap_t *map, size_t size, const size_t limit, const unsigned options,
const pathchar_t *pathname4logging);
MDBX_INTERNAL int osal_munmap(osal_mmap_t *map); MDBX_INTERNAL int osal_munmap(osal_mmap_t *map);
#define MDBX_MRESIZE_MAY_MOVE 0x00000100 #define MDBX_MRESIZE_MAY_MOVE 0x00000100
#define MDBX_MRESIZE_MAY_UNMAP 0x00000200 #define MDBX_MRESIZE_MAY_UNMAP 0x00000200