mirror of
https://github.com/isar/libmdbx.git
synced 2024-10-29 23:19:20 +08:00
mdbx: контроль отсутствия дубликатов LCK-файла с альтернативными именами.
This commit is contained in:
parent
08fb7d5838
commit
61e77e7b70
3
mdbx.h
3
mdbx.h
@ -1932,6 +1932,9 @@ enum MDBX_error_t {
|
||||
* равнозначна \ref MDBX_PROBLEM. */
|
||||
MDBX_BACKLOG_DEPLETED = -30414,
|
||||
|
||||
/** Alternative/Duplicate LCK-file is exists and should be removed manually */
|
||||
MDBX_DUPLICATED_CLK = -30413,
|
||||
|
||||
/* The last of MDBX-added error codes */
|
||||
MDBX_LAST_ADDED_ERRCODE = MDBX_TXN_OVERLAPPING,
|
||||
|
||||
|
50
src/core.c
50
src/core.c
@ -3471,6 +3471,9 @@ __cold const char *mdbx_liberr2str(int errnum) {
|
||||
case MDBX_TXN_OVERLAPPING:
|
||||
return "MDBX_TXN_OVERLAPPING: Overlapping read and write transactions for"
|
||||
" the current thread";
|
||||
case MDBX_DUPLICATED_CLK:
|
||||
return "MDBX_DUPLICATED_CLK: Alternative/Duplicate LCK-file is exists, "
|
||||
"please keep one and remove unused other";
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
@ -14461,6 +14464,17 @@ typedef struct {
|
||||
size_t ent_len;
|
||||
} MDBX_handle_env_pathname;
|
||||
|
||||
__cold static int check_alternative_lck_absent(const pathchar_t *lck_pathname) {
|
||||
int err = osal_fileexists(lck_pathname);
|
||||
if (unlikely(err != MDBX_RESULT_FALSE)) {
|
||||
if (err == MDBX_RESULT_TRUE)
|
||||
err = MDBX_DUPLICATED_CLK;
|
||||
ERROR("Alternative/Duplicate LCK-file '%" MDBX_PRIsPATH "' error %d",
|
||||
lck_pathname, err);
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
__cold static int handle_env_pathname(MDBX_handle_env_pathname *ctx,
|
||||
const pathchar_t *pathname,
|
||||
MDBX_env_flags_t *flags,
|
||||
@ -14562,23 +14576,45 @@ __cold static int handle_env_pathname(MDBX_handle_env_pathname *ctx,
|
||||
return MDBX_ENOMEM;
|
||||
|
||||
ctx->dxb = ctx->buffer_for_free;
|
||||
ctx->lck = ctx->dxb + ctx->ent_len + dxb_name_len + 1;
|
||||
pathchar_t *const buf = ctx->buffer_for_free;
|
||||
rc = MDBX_SUCCESS;
|
||||
if (ctx->ent_len) {
|
||||
ctx->lck = ctx->dxb + ctx->ent_len + 1;
|
||||
memcpy(buf, pathname, sizeof(pathchar_t) * pathname_len);
|
||||
if (*flags & MDBX_NOSUBDIR) {
|
||||
const pathchar_t *const lck_ext =
|
||||
osal_fileext(lck_name, ARRAY_LENGTH(lck_name));
|
||||
if (lck_ext) {
|
||||
pathchar_t *pathname_ext = osal_fileext(buf, pathname_len);
|
||||
memcpy(pathname_ext ? pathname_ext : buf + pathname_len, lck_ext,
|
||||
sizeof(pathchar_t) * (ARRAY_END(lck_name) - lck_ext));
|
||||
rc = check_alternative_lck_absent(buf);
|
||||
}
|
||||
} else {
|
||||
memcpy(buf + ctx->ent_len, dxb_name, sizeof(dxb_name));
|
||||
memcpy(buf + ctx->ent_len + dxb_name_len, lock_suffix,
|
||||
sizeof(lock_suffix));
|
||||
rc = check_alternative_lck_absent(buf);
|
||||
}
|
||||
|
||||
memcpy(ctx->dxb, pathname, sizeof(pathchar_t) * (ctx->ent_len + 1));
|
||||
memcpy(ctx->lck, pathname, sizeof(pathchar_t) * ctx->ent_len);
|
||||
if (*flags & MDBX_NOSUBDIR) {
|
||||
memcpy(ctx->lck + ctx->ent_len, lock_suffix, sizeof(lock_suffix));
|
||||
} else {
|
||||
ctx->lck += dxb_name_len;
|
||||
memcpy(ctx->lck + ctx->ent_len, lck_name, sizeof(lck_name));
|
||||
memcpy(ctx->dxb + ctx->ent_len, dxb_name, sizeof(dxb_name));
|
||||
memcpy(ctx->lck + ctx->ent_len, lck_name, sizeof(lck_name));
|
||||
}
|
||||
memcpy(ctx->lck, pathname, sizeof(pathchar_t) * ctx->ent_len);
|
||||
} else {
|
||||
ctx->lck = ctx->dxb + dxb_name_len;
|
||||
memcpy(ctx->lck, lck_name + 1, sizeof(lck_name) - sizeof(pathchar_t));
|
||||
assert(!(*flags & MDBX_NOSUBDIR));
|
||||
memcpy(buf, dxb_name + 1, sizeof(dxb_name) - sizeof(pathchar_t));
|
||||
memcpy(buf + dxb_name_len - 1, lock_suffix, sizeof(lock_suffix));
|
||||
rc = check_alternative_lck_absent(buf);
|
||||
|
||||
memcpy(ctx->dxb, dxb_name + 1, sizeof(dxb_name) - sizeof(pathchar_t));
|
||||
memcpy(ctx->lck, lck_name + 1, sizeof(lck_name) - sizeof(pathchar_t));
|
||||
}
|
||||
return MDBX_SUCCESS;
|
||||
return rc;
|
||||
}
|
||||
|
||||
__cold int mdbx_env_delete(const char *pathname, MDBX_env_delete_mode_t mode) {
|
||||
|
27
src/osal.c
27
src/osal.c
@ -1185,6 +1185,33 @@ MDBX_INTERNAL_FUNC int osal_removedirectory(const pathchar_t *pathname) {
|
||||
#endif
|
||||
}
|
||||
|
||||
MDBX_INTERNAL_FUNC int osal_fileexists(const pathchar_t *pathname) {
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
if (GetFileAttributesW(pathname) != INVALID_FILE_ATTRIBUTES)
|
||||
return MDBX_RESULT_TRUE;
|
||||
int err = GetLastError();
|
||||
return (err == ERROR_FILE_NOT_FOUND || err == ERROR_PATH_NOT_FOUND)
|
||||
? MDBX_RESULT_FALSE
|
||||
: err;
|
||||
#else
|
||||
if (access(pathname, F_OK) == 0)
|
||||
return MDBX_RESULT_TRUE;
|
||||
int err = errno;
|
||||
return (err == ENOENT || err == ENOTDIR) ? MDBX_RESULT_FALSE : err;
|
||||
#endif
|
||||
}
|
||||
|
||||
MDBX_INTERNAL_FUNC pathchar_t *osal_fileext(const pathchar_t *pathname,
|
||||
size_t len) {
|
||||
const pathchar_t *ext = nullptr;
|
||||
for (size_t i = 0; i < len && pathname[i]; i++)
|
||||
if (pathname[i] == '.')
|
||||
ext = pathname + i;
|
||||
else if (osal_isdirsep(pathname[i]))
|
||||
ext = nullptr;
|
||||
return (pathchar_t *)ext;
|
||||
}
|
||||
|
||||
MDBX_INTERNAL_FUNC bool osal_pathequal(const pathchar_t *l, const pathchar_t *r,
|
||||
size_t len) {
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
|
@ -225,8 +225,10 @@ osal_syspagesize(void) {
|
||||
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
typedef wchar_t pathchar_t;
|
||||
#define MDBX_PRIsPATH "ls"
|
||||
#else
|
||||
typedef char pathchar_t;
|
||||
#define MDBX_PRIsPATH "s"
|
||||
#endif
|
||||
|
||||
typedef struct osal_mmap {
|
||||
@ -559,6 +561,9 @@ MDBX_MAYBE_UNUSED static __inline bool osal_isdirsep(pathchar_t c) {
|
||||
|
||||
MDBX_INTERNAL_FUNC bool osal_pathequal(const pathchar_t *l, const pathchar_t *r,
|
||||
size_t len);
|
||||
MDBX_INTERNAL_FUNC pathchar_t *osal_fileext(const pathchar_t *pathname,
|
||||
size_t len);
|
||||
MDBX_INTERNAL_FUNC int osal_fileexists(const pathchar_t *pathname);
|
||||
MDBX_INTERNAL_FUNC int osal_openfile(const enum osal_openfile_purpose purpose,
|
||||
const MDBX_env *env,
|
||||
const pathchar_t *pathname,
|
||||
|
Loading…
Reference in New Issue
Block a user