mdbx: crutch for WSL.

Fixes https://github.com/erthink/libmdbx/issues/97

Change-Id: Ia863ffc8cd939b1af65f21ab0c5c8197abf4e793
This commit is contained in:
Leonid Yuriev 2020-04-11 20:33:36 +03:00
parent 5a81413f17
commit f89c3eda17
3 changed files with 29 additions and 0 deletions

View File

@ -421,6 +421,12 @@ To build _libmdbx_ for iOS, we recommend using CMake using the
"[toolchain file](https://cmake.org/cmake/help/latest/variable/CMAKE_TOOLCHAIN_FILE.html)"
from the [ios-cmake](https://github.com/leetal/ios-cmake) project.
### Windows Subsystem for Linux
_libmdbx_ could be using in [WSL2](https://en.wikipedia.org/wiki/Windows_Subsystem_for_Linux#WSL_2)
but NOT in [WSL1](https://en.wikipedia.org/wiki/Windows_Subsystem_for_Linux#WSL_1) environment.
This is a consequence of the fundamental shortcomings of _WSL1_ and cannot be fixed.
To avoid data loss, _libmdbx_ returns the `ENOLCK` (37, "No record locks available")
error when opening the database in a _WSL1_ environment.
## API description
For more information and API description see the [mdbx.h](mdbx.h) header.

View File

@ -24,15 +24,25 @@
#include <sys/utsname.h>
#ifndef MDBX_ALLOY
uint32_t mdbx_linux_kernel_version;
bool mdbx_RunningOnWSL;
#endif /* MDBX_ALLOY */
#endif /* Linux */
static __cold unsigned probe_for_WSL(const char *tag) {
/* "Official" way of detecting WSL but not WSL2
* https://github.com/Microsoft/WSL/issues/423#issuecomment-221627364 */
return strstr(tag, "Microsoft") || strstr(tag, "WSL");
}
static __cold __attribute__((__constructor__)) void
mdbx_global_constructor(void) {
#if defined(__linux__) || defined(__gnu_linux__)
struct utsname buffer;
if (uname(&buffer) == 0) {
int i = 0;
mdbx_RunningOnWSL = probe_for_WSL(buffer.version) ||
probe_for_WSL(buffer.sysname) ||
probe_for_WSL(buffer.release);
char *p = buffer.release;
while (*p && i < 4) {
if (*p >= '0' && *p <= '9') {
@ -292,6 +302,17 @@ MDBX_INTERNAL_FUNC int __cold mdbx_lck_seize(MDBX_env *env) {
#endif /* MDBX_USE_OFDLOCKS */
int rc = MDBX_SUCCESS;
#if defined(__linux__) || defined(__gnu_linux__)
if (unlikely(mdbx_RunningOnWSL)) {
rc = ENOLCK;
mdbx_error("%s, err %u",
"WSL (Windows Subsystem for Linux) is mad and trouble-full, "
"injecting failure to avoid data loss",
rc);
return rc /* No record locks available */;
}
#endif /* Linux */
if (env->me_lfd == INVALID_HANDLE_VALUE) {
/* LY: without-lck mode (e.g. exclusive or on read-only filesystem) */
rc =

View File

@ -497,6 +497,8 @@ MDBX_INTERNAL_FUNC int mdbx_vasprintf(char **strp, const char *fmt, va_list ap);
#if defined(__linux__) || defined(__gnu_linux__)
MDBX_INTERNAL_VAR uint32_t mdbx_linux_kernel_version;
MDBX_INTERNAL_VAR bool
mdbx_RunningOnWSL /* Windows Subsystem for Linux is mad and trouble-full */;
#endif /* Linux */
/* Get the size of a memory page for the system.