mirror of
https://github.com/isar/libmdbx.git
synced 2024-10-29 23:19:20 +08:00
mdbx: refine setup_debug(), add MDBX_DBG_LEGACY_MULTIOPEN.
Change-Id: I5d144f6fa27b8f5885fa0a0fbd11fe1d44bcc41c
This commit is contained in:
parent
33a4f31f92
commit
93f82f47bd
1
mdbx.h
1
mdbx.h
@ -1684,6 +1684,7 @@ LIBMDBX_API MDBX_oom_func *mdbx_env_get_oomfunc(MDBX_env *env);
|
||||
#define MDBX_DBG_AUDIT 16
|
||||
#define MDBX_DBG_JITTER 32
|
||||
#define MDBX_DBG_DUMP 64
|
||||
#define MDBX_DBG_LEGACY_MULTIOPEN 128
|
||||
|
||||
typedef void MDBX_debug_func(int type, const char *function, int line,
|
||||
const char *msg, va_list args);
|
||||
|
@ -37,12 +37,10 @@
|
||||
#endif
|
||||
#endif /* MDBX_USE_ROBUST */
|
||||
|
||||
uint32_t linux_kernel_version;
|
||||
static int op_setlk = F_SETLK, op_setlkw = F_SETLKW, op_getlk = F_GETLK;
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* global constructor/destructor */
|
||||
|
||||
uint32_t mdbx_linux_kernel_version;
|
||||
static __cold __attribute__((constructor)) void mdbx_global_constructor(void) {
|
||||
struct utsname buffer;
|
||||
if (uname(&buffer) == 0) {
|
||||
@ -54,7 +52,7 @@ static __cold __attribute__((constructor)) void mdbx_global_constructor(void) {
|
||||
if (number > 0) {
|
||||
if (number > 255)
|
||||
number = 255;
|
||||
linux_kernel_version += number << (24 - i * 8);
|
||||
mdbx_linux_kernel_version += number << (24 - i * 8);
|
||||
}
|
||||
++i;
|
||||
} else {
|
||||
@ -63,16 +61,6 @@ static __cold __attribute__((constructor)) void mdbx_global_constructor(void) {
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(F_OFD_SETLK) && defined(F_OFD_SETLKW) && defined(F_OFD_GETLK)
|
||||
if (linux_kernel_version >
|
||||
0x030f0000 /* OFD locks are available since 3.15, but engages here only
|
||||
for 3.16 and larer kernels (LTS) for reliability reasons */) {
|
||||
op_setlk = F_OFD_SETLK;
|
||||
op_setlkw = F_OFD_SETLKW;
|
||||
op_getlk = F_OFD_GETLK;
|
||||
}
|
||||
#endif /* OFD locks */
|
||||
|
||||
mdbx_rthc_global_init();
|
||||
}
|
||||
|
||||
@ -118,6 +106,25 @@ static __cold __attribute__((destructor)) void mdbx_global_destructor(void) {
|
||||
* и атомарным режимами блокировок.
|
||||
*/
|
||||
|
||||
static int op_setlk, op_setlkw, op_getlk;
|
||||
static void __cold choice_fcntl() {
|
||||
assert(!op_setlk && !op_setlkw && !op_getlk);
|
||||
#if defined(F_OFD_SETLK) && defined(F_OFD_SETLKW) && defined(F_OFD_GETLK)
|
||||
if (mdbx_linux_kernel_version >
|
||||
0x030f0000 /* OFD locks are available since 3.15, but engages here
|
||||
only for 3.16 and larer kernels (LTS) for reliability reasons */
|
||||
&& (mdbx_runtime_flags & MDBX_DBG_LEGACY_MULTIOPEN) == 0) {
|
||||
op_setlk = F_OFD_SETLK;
|
||||
op_setlkw = F_OFD_SETLKW;
|
||||
op_getlk = F_OFD_GETLK;
|
||||
return;
|
||||
}
|
||||
#endif /* OFD locks */
|
||||
op_setlk = F_SETLK;
|
||||
op_setlkw = F_SETLKW;
|
||||
op_getlk = F_GETLK;
|
||||
}
|
||||
|
||||
#ifndef OFF_T_MAX
|
||||
#define OFF_T_MAX \
|
||||
((sizeof(off_t) > 4 ? INT64_MAX : INT32_MAX) & ~(size_t)0xffff)
|
||||
@ -341,6 +348,8 @@ static int __cold internal_seize_lck(int lfd) {
|
||||
|
||||
int __cold mdbx_lck_seize(MDBX_env *env) {
|
||||
assert(env->me_fd != INVALID_HANDLE_VALUE);
|
||||
if (unlikely(op_setlk == 0))
|
||||
choice_fcntl();
|
||||
|
||||
if (env->me_lfd == INVALID_HANDLE_VALUE) {
|
||||
/* LY: without-lck mode (e.g. exclusive or on read-only filesystem) */
|
||||
|
61
src/mdbx.c
61
src/mdbx.c
@ -12917,36 +12917,51 @@ int __cold mdbx_reader_check0(MDBX_env *env, int rdt_locked, int *dead) {
|
||||
}
|
||||
|
||||
int __cold mdbx_setup_debug(int flags, MDBX_debug_func *logger) {
|
||||
unsigned ret = mdbx_runtime_flags;
|
||||
mdbx_runtime_flags = flags;
|
||||
|
||||
const int rc = mdbx_runtime_flags;
|
||||
if (flags != -1) {
|
||||
#if MDBX_DEBUG
|
||||
flags &= MDBX_DBG_DUMP | MDBX_DBG_LEGACY_MULTIOPEN;
|
||||
#else
|
||||
flags &= MDBX_DBG_ASSERT | MDBX_DBG_PRINT | MDBX_DBG_TRACE |
|
||||
MDBX_DBG_EXTRA | MDBX_DBG_AUDIT | MDBX_DBG_JITTER | MDBX_DBG_DUMP |
|
||||
MDBX_DBG_LEGACY_MULTIOPEN;
|
||||
#endif
|
||||
#if defined(__linux__) || defined(__gnu_linux__)
|
||||
if (flags & MDBX_DBG_DUMP) {
|
||||
int core_filter_fd = open("/proc/self/coredump_filter", O_TRUNC | O_RDWR);
|
||||
if (core_filter_fd >= 0) {
|
||||
char buf[32];
|
||||
const unsigned r = pread(core_filter_fd, buf, sizeof(buf), 0);
|
||||
if (r > 0 && r < sizeof(buf)) {
|
||||
buf[r] = 0;
|
||||
unsigned long mask = strtoul(buf, NULL, 16);
|
||||
if (mask != ULONG_MAX) {
|
||||
mask |= 1 << 3 /* Dump file-backed shared mappings */;
|
||||
mask |= 1 << 6 /* Dump shared huge pages */;
|
||||
mask |= 1 << 8 /* Dump shared DAX pages */;
|
||||
unsigned w = snprintf(buf, sizeof(buf), "0x%lx\n", mask);
|
||||
if (w > 0 && w < sizeof(buf)) {
|
||||
w = pwrite(core_filter_fd, buf, w, 0);
|
||||
(void)w;
|
||||
if ((mdbx_runtime_flags ^ flags) & MDBX_DBG_DUMP) {
|
||||
/* http://man7.org/linux/man-pages/man5/core.5.html */
|
||||
const unsigned long dump_bits =
|
||||
1 << 3 /* Dump file-backed shared mappings */
|
||||
| 1 << 6 /* Dump shared huge pages */
|
||||
| 1 << 8 /* Dump shared DAX pages */;
|
||||
const int core_filter_fd =
|
||||
open("/proc/self/coredump_filter", O_TRUNC | O_RDWR);
|
||||
if (core_filter_fd != -1) {
|
||||
char buf[32];
|
||||
intptr_t bytes = pread(core_filter_fd, buf, sizeof(buf), 0);
|
||||
if (bytes > 0 && (size_t)bytes < sizeof(buf)) {
|
||||
buf[bytes] = 0;
|
||||
const unsigned long present_mask = strtoul(buf, NULL, 16);
|
||||
const unsigned long wanna_mask = (flags & MDBX_DBG_DUMP)
|
||||
? present_mask | dump_bits
|
||||
: present_mask & ~dump_bits;
|
||||
if (wanna_mask != present_mask) {
|
||||
bytes = snprintf(buf, sizeof(buf), "0x%lx\n", wanna_mask);
|
||||
if (bytes > 0 && (size_t)bytes < sizeof(buf)) {
|
||||
bytes = pwrite(core_filter_fd, buf, bytes, 0);
|
||||
(void)bytes;
|
||||
}
|
||||
}
|
||||
}
|
||||
close(core_filter_fd);
|
||||
}
|
||||
close(core_filter_fd);
|
||||
}
|
||||
}
|
||||
#endif /* Linux */
|
||||
mdbx_runtime_flags = flags;
|
||||
}
|
||||
|
||||
mdbx_debug_logger = logger;
|
||||
return ret;
|
||||
if (-1 != (intptr_t)logger)
|
||||
mdbx_debug_logger = logger;
|
||||
return rc;
|
||||
}
|
||||
|
||||
static txnid_t __cold mdbx_oomkick(MDBX_env *env, const txnid_t laggard) {
|
||||
|
@ -674,7 +674,7 @@ int mdbx_filesync(mdbx_filehandle_t fd, enum mdbx_syncmode_bits mode_bits) {
|
||||
return likely(fcntl(fd, F_FULLFSYNC) != -1) ? MDBX_SUCCESS : errno;
|
||||
#endif /* MacOS */
|
||||
#if defined(__linux__) || defined(__gnu_linux__)
|
||||
if (mode_bits == MDBX_SYNC_SIZE && linux_kernel_version >= 0x03060000)
|
||||
if (mode_bits == MDBX_SYNC_SIZE && mdbx_linux_kernel_version >= 0x03060000)
|
||||
return MDBX_SUCCESS;
|
||||
#endif /* Linux */
|
||||
int rc;
|
||||
@ -789,7 +789,7 @@ int mdbx_msync(mdbx_mmap_t *map, size_t offset, size_t length, int async) {
|
||||
return GetLastError();
|
||||
#else
|
||||
#ifdef __linux__
|
||||
if (async && linux_kernel_version > 0x02061300)
|
||||
if (async && mdbx_linux_kernel_version > 0x02061300)
|
||||
/* Since Linux 2.6.19, MS_ASYNC is in fact a no-op,
|
||||
since the kernel properly tracks dirty pages and flushes them to storage
|
||||
as necessary. */
|
||||
|
@ -475,7 +475,7 @@ int mdbx_vasprintf(char **strp, const char *fmt, va_list ap);
|
||||
#define MAX_WRITE UINT32_C(0x3fff0000)
|
||||
|
||||
#if defined(__linux__) || defined(__gnu_linux__)
|
||||
extern uint32_t linux_kernel_version;
|
||||
extern uint32_t mdbx_linux_kernel_version;
|
||||
#endif /* Linux */
|
||||
|
||||
/* Get the size of a memory page for the system.
|
||||
|
Loading…
Reference in New Issue
Block a user