mirror of
				https://github.com/isar/libmdbx.git
				synced 2025-11-01 03:48:57 +08:00 
			
		
		
		
	mdbx: добавление UUID для идентификации БД.
This commit is contained in:
		| @@ -826,7 +826,7 @@ macro(libmdbx_setup_libs TARGET MODE) | |||||||
|     target_link_libraries(${TARGET} ${MODE} Threads::Threads) |     target_link_libraries(${TARGET} ${MODE} Threads::Threads) | ||||||
|   endif() |   endif() | ||||||
|   if(${CMAKE_SYSTEM_NAME} STREQUAL "Windows") |   if(${CMAKE_SYSTEM_NAME} STREQUAL "Windows") | ||||||
|     target_link_libraries(${TARGET} ${MODE} ntdll user32 kernel32 advapi32) |     target_link_libraries(${TARGET} ${MODE} ntdll user32 kernel32 advapi32 ole32) | ||||||
|     if(MDBX_NTDLL_EXTRA_IMPLIB AND MDBX_WITHOUT_MSVC_CRT) |     if(MDBX_NTDLL_EXTRA_IMPLIB AND MDBX_WITHOUT_MSVC_CRT) | ||||||
|       target_link_libraries(${TARGET} ${MODE} ntdll_extra) |       target_link_libraries(${TARGET} ${MODE} ntdll_extra) | ||||||
|     endif() |     endif() | ||||||
|   | |||||||
							
								
								
									
										5
									
								
								mdbx.h
									
									
									
									
									
								
							
							
						
						
									
										5
									
								
								mdbx.h
									
									
									
									
									
								
							| @@ -2745,6 +2745,11 @@ struct MDBX_envinfo { | |||||||
|     uint64_t |     uint64_t | ||||||
|         fsync; /**< Number of explicit fsync-to-disk operations (not a pages) */ |         fsync; /**< Number of explicit fsync-to-disk operations (not a pages) */ | ||||||
|   } mi_pgop_stat; |   } mi_pgop_stat; | ||||||
|  |  | ||||||
|  |   /* GUID of the database DXB file. */ | ||||||
|  |   struct { | ||||||
|  |     uint64_t x, y; | ||||||
|  |   } mi_dxbid; | ||||||
| }; | }; | ||||||
| #ifndef __cplusplus | #ifndef __cplusplus | ||||||
| /** \ingroup c_statinfo */ | /** \ingroup c_statinfo */ | ||||||
|   | |||||||
| @@ -727,6 +727,7 @@ static int env_info_snap(const MDBX_env *env, const MDBX_txn *txn, | |||||||
|                          troika_t *const troika) { |                          troika_t *const troika) { | ||||||
|   const size_t size_before_bootid = offsetof(MDBX_envinfo, mi_bootid); |   const size_t size_before_bootid = offsetof(MDBX_envinfo, mi_bootid); | ||||||
|   const size_t size_before_pgop_stat = offsetof(MDBX_envinfo, mi_pgop_stat); |   const size_t size_before_pgop_stat = offsetof(MDBX_envinfo, mi_pgop_stat); | ||||||
|  |   const size_t size_before_dxbid = offsetof(MDBX_envinfo, mi_dxbid); | ||||||
|   if (unlikely(env->flags & ENV_FATAL_ERROR)) |   if (unlikely(env->flags & ENV_FATAL_ERROR)) | ||||||
|     return MDBX_PANIC; |     return MDBX_PANIC; | ||||||
|  |  | ||||||
| @@ -773,6 +774,8 @@ static int env_info_snap(const MDBX_env *env, const MDBX_txn *txn, | |||||||
|     memcpy(&out->mi_bootid.meta[0], &meta0->bootid, 16); |     memcpy(&out->mi_bootid.meta[0], &meta0->bootid, 16); | ||||||
|     memcpy(&out->mi_bootid.meta[1], &meta1->bootid, 16); |     memcpy(&out->mi_bootid.meta[1], &meta1->bootid, 16); | ||||||
|     memcpy(&out->mi_bootid.meta[2], &meta2->bootid, 16); |     memcpy(&out->mi_bootid.meta[2], &meta2->bootid, 16); | ||||||
|  |     if (likely(bytes > size_before_dxbid)) | ||||||
|  |       memcpy(&out->mi_dxbid, &meta0->dxbid, 16); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   const volatile meta_t *txn_meta = head.ptr_v; |   const volatile meta_t *txn_meta = head.ptr_v; | ||||||
| @@ -895,8 +898,9 @@ __cold int mdbx_env_info_ex(const MDBX_env *env, const MDBX_txn *txn, | |||||||
|  |  | ||||||
|   const size_t size_before_bootid = offsetof(MDBX_envinfo, mi_bootid); |   const size_t size_before_bootid = offsetof(MDBX_envinfo, mi_bootid); | ||||||
|   const size_t size_before_pgop_stat = offsetof(MDBX_envinfo, mi_pgop_stat); |   const size_t size_before_pgop_stat = offsetof(MDBX_envinfo, mi_pgop_stat); | ||||||
|  |   const size_t size_before_dxbid = offsetof(MDBX_envinfo, mi_dxbid); | ||||||
|   if (unlikely(bytes != sizeof(MDBX_envinfo)) && bytes != size_before_bootid && |   if (unlikely(bytes != sizeof(MDBX_envinfo)) && bytes != size_before_bootid && | ||||||
|       bytes != size_before_pgop_stat) |       bytes != size_before_pgop_stat && bytes != size_before_dxbid) | ||||||
|     return MDBX_EINVAL; |     return MDBX_EINVAL; | ||||||
|  |  | ||||||
|   if (txn) { |   if (txn) { | ||||||
| @@ -938,8 +942,9 @@ __cold int mdbx_preopen_snapinfoW(const wchar_t *pathname, MDBX_envinfo *out, | |||||||
|  |  | ||||||
|   const size_t size_before_bootid = offsetof(MDBX_envinfo, mi_bootid); |   const size_t size_before_bootid = offsetof(MDBX_envinfo, mi_bootid); | ||||||
|   const size_t size_before_pgop_stat = offsetof(MDBX_envinfo, mi_pgop_stat); |   const size_t size_before_pgop_stat = offsetof(MDBX_envinfo, mi_pgop_stat); | ||||||
|  |   const size_t size_before_dxbid = offsetof(MDBX_envinfo, mi_dxbid); | ||||||
|   if (unlikely(bytes != sizeof(MDBX_envinfo)) && bytes != size_before_bootid && |   if (unlikely(bytes != sizeof(MDBX_envinfo)) && bytes != size_before_bootid && | ||||||
|       bytes != size_before_pgop_stat) |       bytes != size_before_pgop_stat && bytes != size_before_dxbid) | ||||||
|     return MDBX_EINVAL; |     return MDBX_EINVAL; | ||||||
|  |  | ||||||
|   memset(out, 0, bytes); |   memset(out, 0, bytes); | ||||||
| @@ -993,8 +998,11 @@ __cold int mdbx_preopen_snapinfoW(const wchar_t *pathname, MDBX_envinfo *out, | |||||||
|   const unsigned n = 0; |   const unsigned n = 0; | ||||||
|   out->mi_recent_txnid = constmeta_txnid(&header); |   out->mi_recent_txnid = constmeta_txnid(&header); | ||||||
|   out->mi_meta_sign[n] = unaligned_peek_u64(4, &header.sign); |   out->mi_meta_sign[n] = unaligned_peek_u64(4, &header.sign); | ||||||
|   if (likely(bytes > size_before_bootid)) |   if (likely(bytes > size_before_bootid)) { | ||||||
|     memcpy(&out->mi_bootid.meta[n], &header.bootid, 16); |     memcpy(&out->mi_bootid.meta[n], &header.bootid, 16); | ||||||
|  |     if (likely(bytes > size_before_dxbid)) | ||||||
|  |       memcpy(&out->mi_dxbid, &header.dxbid, 16); | ||||||
|  |   } | ||||||
|  |  | ||||||
| bailout: | bailout: | ||||||
|   env_close(&env, false); |   env_close(&env, false); | ||||||
|   | |||||||
							
								
								
									
										14
									
								
								src/chk.c
									
									
									
									
									
								
							
							
						
						
									
										14
									
								
								src/chk.c
									
									
									
									
									
								
							| @@ -1590,13 +1590,23 @@ __cold static int env_chk(MDBX_chk_scope_t *const scope) { | |||||||
|     return chk_error_rc(scope, err, "env_info"); |     return chk_error_rc(scope, err, "env_info"); | ||||||
|  |  | ||||||
|   MDBX_chk_line_t *line = |   MDBX_chk_line_t *line = | ||||||
|       chk_puts(chk_line_begin(scope, MDBX_chk_info), "current boot-id "); |       chk_puts(chk_line_begin(scope, MDBX_chk_info - | ||||||
|  |                                          (1 << MDBX_chk_severity_prio_shift)), | ||||||
|  |                "dxb-id "); | ||||||
|  |   if (chk->envinfo.mi_dxbid.x | chk->envinfo.mi_dxbid.y) | ||||||
|  |     line = chk_print(line, "%016" PRIx64 "-%016" PRIx64, | ||||||
|  |                      chk->envinfo.mi_dxbid.x, chk->envinfo.mi_dxbid.y); | ||||||
|  |   else | ||||||
|  |     line = chk_puts(line, "is absent"); | ||||||
|  |   chk_line_end(line); | ||||||
|  |  | ||||||
|  |   line = chk_puts(chk_line_begin(scope, MDBX_chk_info), "current boot-id "); | ||||||
|   if (chk->envinfo.mi_bootid.current.x | chk->envinfo.mi_bootid.current.y) |   if (chk->envinfo.mi_bootid.current.x | chk->envinfo.mi_bootid.current.y) | ||||||
|     line = chk_print(line, "%016" PRIx64 "-%016" PRIx64, |     line = chk_print(line, "%016" PRIx64 "-%016" PRIx64, | ||||||
|                      chk->envinfo.mi_bootid.current.x, |                      chk->envinfo.mi_bootid.current.x, | ||||||
|                      chk->envinfo.mi_bootid.current.y); |                      chk->envinfo.mi_bootid.current.y); | ||||||
|   else |   else | ||||||
|     line = chk_puts(line, "unavailable"); |     line = chk_puts(line, "is unavailable"); | ||||||
|   chk_line_end(line); |   chk_line_end(line); | ||||||
|  |  | ||||||
|   err = osal_filesize(env->lazy_fd, &env->dxb_mmap.filesize); |   err = osal_filesize(env->lazy_fd, &env->dxb_mmap.filesize); | ||||||
|   | |||||||
							
								
								
									
										10
									
								
								src/dxb.c
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								src/dxb.c
									
									
									
									
									
								
							| @@ -1045,14 +1045,16 @@ __cold int dxb_setup(MDBX_env *env, const int lck_rc, | |||||||
|  |  | ||||||
|     if ((env->flags & MDBX_RDONLY) == 0 && env->stuck_meta < 0 && |     if ((env->flags & MDBX_RDONLY) == 0 && env->stuck_meta < 0 && | ||||||
|         (globals.runtime_flags & MDBX_DBG_DONT_UPGRADE) == 0) { |         (globals.runtime_flags & MDBX_DBG_DONT_UPGRADE) == 0) { | ||||||
|       for (int n = 0; n < NUM_METAS; ++n) { |       for (unsigned n = 0; n < NUM_METAS; ++n) { | ||||||
|         meta_t *const meta = METAPAGE(env, n); |         meta_t *const meta = METAPAGE(env, n); | ||||||
|         if (unlikely(unaligned_peek_u64(4, &meta->magic_and_version) != |         if (unlikely(unaligned_peek_u64(4, &meta->magic_and_version) != | ||||||
|                      MDBX_DATA_MAGIC)) { |                      MDBX_DATA_MAGIC) || | ||||||
|           const txnid_t txnid = constmeta_txnid(meta); |             (meta->dxbid.x | meta->dxbid.y) == 0) { | ||||||
|  |           const txnid_t txnid = | ||||||
|  |               meta_is_used(&troika, n) ? constmeta_txnid(meta) : 0; | ||||||
|           NOTICE("%s %s" |           NOTICE("%s %s" | ||||||
|                  "meta[%u], txnid %" PRIaTXN, |                  "meta[%u], txnid %" PRIaTXN, | ||||||
|                  "updating db-format signature for", |                  "updating db-format/guid signature for", | ||||||
|                  meta_is_steady(meta) ? "stead-" : "weak-", n, txnid); |                  meta_is_steady(meta) ? "stead-" : "weak-", n, txnid); | ||||||
|           err = meta_override(env, n, txnid, meta); |           err = meta_override(env, n, txnid, meta); | ||||||
|           if (unlikely(err != MDBX_SUCCESS) && |           if (unlikely(err != MDBX_SUCCESS) && | ||||||
|   | |||||||
| @@ -91,15 +91,6 @@ typedef struct geo { | |||||||
|   }; |   }; | ||||||
| } geo_t; | } geo_t; | ||||||
|  |  | ||||||
| typedef union bin128 { |  | ||||||
|   __anonymous_struct_extension__ struct { |  | ||||||
|     uint64_t x, y; |  | ||||||
|   }; |  | ||||||
|   __anonymous_struct_extension__ struct { |  | ||||||
|     uint32_t a, b, c, d; |  | ||||||
|   }; |  | ||||||
| } bin128_t; |  | ||||||
|  |  | ||||||
| /* Meta page content. | /* Meta page content. | ||||||
|  * A meta page is the start point for accessing a database snapshot. |  * A meta page is the start point for accessing a database snapshot. | ||||||
|  * Pages 0-2 are meta pages. */ |  * Pages 0-2 are meta pages. */ | ||||||
| @@ -158,6 +149,9 @@ typedef struct meta { | |||||||
|    * steady sync point. Zeros mean that no relevant information is available |    * steady sync point. Zeros mean that no relevant information is available | ||||||
|    * from the system. */ |    * from the system. */ | ||||||
|   bin128_t bootid; |   bin128_t bootid; | ||||||
|  |  | ||||||
|  |   /* GUID базы данных, начиная с v0.13.1 */ | ||||||
|  |   bin128_t dxbid; | ||||||
| } meta_t; | } meta_t; | ||||||
|  |  | ||||||
| #pragma pack(1) | #pragma pack(1) | ||||||
|   | |||||||
							
								
								
									
										21
									
								
								src/meta.c
									
									
									
									
									
								
							
							
						
						
									
										21
									
								
								src/meta.c
									
									
									
									
									
								
							| @@ -332,8 +332,8 @@ int meta_sync(const MDBX_env *env, const meta_ptr_t head) { | |||||||
|   return rc; |   return rc; | ||||||
| } | } | ||||||
|  |  | ||||||
| __cold static page_t *meta_model(const MDBX_env *env, page_t *model, | __cold static page_t *meta_model(const MDBX_env *env, page_t *model, size_t num, | ||||||
|                                  size_t num) { |                                  const bin128_t *guid) { | ||||||
|   ENSURE(env, is_powerof2(env->ps)); |   ENSURE(env, is_powerof2(env->ps)); | ||||||
|   ENSURE(env, env->ps >= MDBX_MIN_PAGESIZE); |   ENSURE(env, env->ps >= MDBX_MIN_PAGESIZE); | ||||||
|   ENSURE(env, env->ps <= MDBX_MAX_PAGESIZE); |   ENSURE(env, env->ps <= MDBX_MAX_PAGESIZE); | ||||||
| @@ -373,6 +373,7 @@ __cold static page_t *meta_model(const MDBX_env *env, page_t *model, | |||||||
|   model_meta->trees.gc.flags = MDBX_INTEGERKEY; |   model_meta->trees.gc.flags = MDBX_INTEGERKEY; | ||||||
|   model_meta->trees.gc.root = P_INVALID; |   model_meta->trees.gc.root = P_INVALID; | ||||||
|   model_meta->trees.main.root = P_INVALID; |   model_meta->trees.main.root = P_INVALID; | ||||||
|  |   memcpy(&model_meta->dxbid, guid, sizeof(model_meta->dxbid)); | ||||||
|   meta_set_txnid(env, model_meta, MIN_TXNID + num); |   meta_set_txnid(env, model_meta, MIN_TXNID + num); | ||||||
|   unaligned_poke_u64(4, model_meta->sign, meta_sign_calculate(model_meta)); |   unaligned_poke_u64(4, model_meta->sign, meta_sign_calculate(model_meta)); | ||||||
|   eASSERT(env, coherency_check_meta(env, model_meta, true)); |   eASSERT(env, coherency_check_meta(env, model_meta, true)); | ||||||
| @@ -380,10 +381,11 @@ __cold static page_t *meta_model(const MDBX_env *env, page_t *model, | |||||||
| } | } | ||||||
|  |  | ||||||
| __cold meta_t *meta_init_triplet(const MDBX_env *env, void *buffer) { | __cold meta_t *meta_init_triplet(const MDBX_env *env, void *buffer) { | ||||||
|  |   const bin128_t guid = osal_guid(env); | ||||||
|   page_t *page0 = (page_t *)buffer; |   page_t *page0 = (page_t *)buffer; | ||||||
|   page_t *page1 = meta_model(env, page0, 0); |   page_t *page1 = meta_model(env, page0, 0, &guid); | ||||||
|   page_t *page2 = meta_model(env, page1, 1); |   page_t *page2 = meta_model(env, page1, 1, &guid); | ||||||
|   meta_model(env, page2, 2); |   meta_model(env, page2, 2, &guid); | ||||||
|   return page_meta(page2); |   return page_meta(page2); | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -394,7 +396,8 @@ __cold int __must_check_result meta_override(MDBX_env *env, size_t target, | |||||||
|   if (unlikely(rc != MDBX_SUCCESS)) |   if (unlikely(rc != MDBX_SUCCESS)) | ||||||
|     return rc; |     return rc; | ||||||
|   page_t *const page = env->page_auxbuf; |   page_t *const page = env->page_auxbuf; | ||||||
|   meta_model(env, page, target); |   meta_model(env, page, target, | ||||||
|  |              &((target == 0 && shape) ? shape : METAPAGE(env, 0))->dxbid); | ||||||
|   meta_t *const model = page_meta(page); |   meta_t *const model = page_meta(page); | ||||||
|   meta_set_txnid(env, model, txnid); |   meta_set_txnid(env, model, txnid); | ||||||
|   if (txnid) |   if (txnid) | ||||||
| @@ -430,6 +433,12 @@ __cold int __must_check_result meta_override(MDBX_env *env, size_t target, | |||||||
|       } |       } | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   if (target == 0 && (model->dxbid.x | model->dxbid.y) == 0) { | ||||||
|  |     const bin128_t guid = osal_guid(env); | ||||||
|  |     memcpy(&model->dxbid, &guid, sizeof(model->dxbid)); | ||||||
|  |   } | ||||||
|  |  | ||||||
|   meta_sign_as_steady(model); |   meta_sign_as_steady(model); | ||||||
|   rc = meta_validate(env, model, page, (pgno_t)target, nullptr); |   rc = meta_validate(env, model, page, (pgno_t)target, nullptr); | ||||||
|   if (unlikely(MDBX_IS_ERROR(rc))) |   if (unlikely(MDBX_IS_ERROR(rc))) | ||||||
|   | |||||||
| @@ -83,7 +83,12 @@ static inline meta_ptr_t meta_tail(const MDBX_env *env, | |||||||
|   return r; |   return r; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | static inline bool meta_is_used(const troika_t *troika, unsigned n) { | ||||||
|  |   return n == troika->recent || n == troika->prefer_steady; | ||||||
|  | } | ||||||
|  |  | ||||||
| static inline bool meta_bootid_match(const meta_t *meta) { | static inline bool meta_bootid_match(const meta_t *meta) { | ||||||
|  |  | ||||||
|   return memcmp(&meta->bootid, &globals.bootid, 16) == 0 && |   return memcmp(&meta->bootid, &globals.bootid, 16) == 0 && | ||||||
|          (globals.bootid.x | globals.bootid.y) != 0; |          (globals.bootid.x | globals.bootid.y) != 0; | ||||||
| } | } | ||||||
|   | |||||||
							
								
								
									
										215
									
								
								src/osal.c
									
									
									
									
									
								
							
							
						
						
									
										215
									
								
								src/osal.c
									
									
									
									
									
								
							| @@ -2931,17 +2931,40 @@ __cold static void bootid_collect(bin128_t *p, const void *s, size_t n) { | |||||||
|   bootid_shake(p); |   bootid_shake(p); | ||||||
|  |  | ||||||
|   /* minor non-linear tomfoolery */ |   /* minor non-linear tomfoolery */ | ||||||
|   const unsigned z = p->x % 61; |   const unsigned z = p->x % 61 + 1; | ||||||
|   p->y = p->y << z | p->y >> (64 - z); |   p->y = p->y << z | p->y >> (64 - z); | ||||||
|   bootid_shake(p); |   bootid_shake(p); | ||||||
|   bootid_shake(p); |   bootid_shake(p); | ||||||
|   const unsigned q = p->x % 59; |   const unsigned q = p->x % 59 + 1; | ||||||
|   p->y = p->y << q | p->y >> (64 - q); |   p->y = p->y << q | p->y >> (64 - q); | ||||||
|   bootid_shake(p); |   bootid_shake(p); | ||||||
|   bootid_shake(p); |   bootid_shake(p); | ||||||
|   bootid_shake(p); |   bootid_shake(p); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | static size_t hamming_weight(size_t v) { | ||||||
|  |   const size_t m1 = (size_t)UINT64_C(0x5555555555555555); | ||||||
|  |   const size_t m2 = (size_t)UINT64_C(0x3333333333333333); | ||||||
|  |   const size_t m4 = (size_t)UINT64_C(0x0f0f0f0f0f0f0f0f); | ||||||
|  |   const size_t h01 = (size_t)UINT64_C(0x0101010101010101); | ||||||
|  |   v -= (v >> 1) & m1; | ||||||
|  |   v = (v & m2) + ((v >> 2) & m2); | ||||||
|  |   v = (v + (v >> 4)) & m4; | ||||||
|  |   return (v * h01) >> (sizeof(v) * 8 - 8); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static inline size_t hw64(uint64_t v) { | ||||||
|  |   size_t r = hamming_weight((size_t)v); | ||||||
|  |   if (sizeof(v) > sizeof(r)) | ||||||
|  |     r += hamming_weight((size_t)(v >> sizeof(r) * 4 >> sizeof(r) * 4)); | ||||||
|  |   return r; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static bool check_uuid(bin128_t uuid) { | ||||||
|  |   size_t hw = hw64(uuid.x) + hw64(uuid.y) + hw64(uuid.x ^ uuid.y); | ||||||
|  |   return (hw >> 6) == 1; | ||||||
|  | } | ||||||
|  |  | ||||||
| #if defined(_WIN32) || defined(_WIN64) | #if defined(_WIN32) || defined(_WIN64) | ||||||
|  |  | ||||||
| __cold static uint64_t windows_systemtime_ms() { | __cold static uint64_t windows_systemtime_ms() { | ||||||
| @@ -3043,7 +3066,7 @@ bootid_parse_uuid(bin128_t *s, const void *p, const size_t n) { | |||||||
|       s->y += aligned.y; |       s->y += aligned.y; | ||||||
|     } else |     } else | ||||||
|       bootid_collect(s, p, n); |       bootid_collect(s, p, n); | ||||||
|     return true; |     return check_uuid(*s); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   if (n) |   if (n) | ||||||
| @@ -3051,28 +3074,33 @@ bootid_parse_uuid(bin128_t *s, const void *p, const size_t n) { | |||||||
|   return false; |   return false; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | #if defined(__linux__) || defined(__gnu_linux__) | ||||||
|  | __cold static bool proc_read_uuid(const char *path, bin128_t *target) { | ||||||
|  |   const int fd = open(path, O_RDONLY | O_NOFOLLOW); | ||||||
|  |   if (fd != -1) { | ||||||
|  |     struct statfs fs; | ||||||
|  |     char buf[42]; | ||||||
|  |     const ssize_t len = | ||||||
|  |         (fstatfs(fd, &fs) == 0 && fs.f_type == /* procfs */ 0x9FA0) | ||||||
|  |             ? read(fd, buf, sizeof(buf)) | ||||||
|  |             : -1; | ||||||
|  |     const int err = close(fd); | ||||||
|  |     assert(err == 0); | ||||||
|  |     (void)err; | ||||||
|  |     if (len > 0) | ||||||
|  |       return bootid_parse_uuid(target, buf, len); | ||||||
|  |   } | ||||||
|  |   return false; | ||||||
|  | } | ||||||
|  | #endif /* Linux */ | ||||||
|  |  | ||||||
| __cold static bin128_t osal_bootid(void) { | __cold static bin128_t osal_bootid(void) { | ||||||
|   bin128_t bin = {{0, 0}}; |   bin128_t uuid = {{0, 0}}; | ||||||
|   bool got_machineid = false, got_boottime = false, got_bootseq = false; |   bool got_machineid = false, got_boottime = false, got_bootseq = false; | ||||||
|  |  | ||||||
| #if defined(__linux__) || defined(__gnu_linux__) | #if defined(__linux__) || defined(__gnu_linux__) | ||||||
|   { |   if (proc_read_uuid("/proc/sys/kernel/random/boot_id", &uuid)) | ||||||
|     const int fd = |     return uuid; | ||||||
|         open("/proc/sys/kernel/random/boot_id", O_RDONLY | O_NOFOLLOW); |  | ||||||
|     if (fd != -1) { |  | ||||||
|       struct statfs fs; |  | ||||||
|       char buf[42]; |  | ||||||
|       const ssize_t len = |  | ||||||
|           (fstatfs(fd, &fs) == 0 && fs.f_type == /* procfs */ 0x9FA0) |  | ||||||
|               ? read(fd, buf, sizeof(buf)) |  | ||||||
|               : -1; |  | ||||||
|       const int err = close(fd); |  | ||||||
|       assert(err == 0); |  | ||||||
|       (void)err; |  | ||||||
|       if (len > 0 && bootid_parse_uuid(&bin, buf, len)) |  | ||||||
|         return bin; |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
| #endif /* Linux */ | #endif /* Linux */ | ||||||
|  |  | ||||||
| #if defined(__APPLE__) || defined(__MACH__) | #if defined(__APPLE__) || defined(__MACH__) | ||||||
| @@ -3080,16 +3108,15 @@ __cold static bin128_t osal_bootid(void) { | |||||||
|     char buf[42]; |     char buf[42]; | ||||||
|     size_t len = sizeof(buf); |     size_t len = sizeof(buf); | ||||||
|     if (!sysctlbyname("kern.bootsessionuuid", buf, &len, nullptr, 0) && |     if (!sysctlbyname("kern.bootsessionuuid", buf, &len, nullptr, 0) && | ||||||
|         bootid_parse_uuid(&bin, buf, len)) |         bootid_parse_uuid(&uuid, buf, len)) | ||||||
|       return bin; |       return uuid; | ||||||
|  |  | ||||||
| #if defined(__MAC_OS_X_VERSION_MIN_REQUIRED) &&                                \ | #if defined(__MAC_OS_X_VERSION_MIN_REQUIRED) &&                                \ | ||||||
|     __MAC_OS_X_VERSION_MIN_REQUIRED > 1050 |     __MAC_OS_X_VERSION_MIN_REQUIRED > 1050 | ||||||
|     uuid_t uuid; |     uuid_t hostuuid; | ||||||
|     struct timespec wait = {0, 1000000000u / 42}; |     struct timespec wait = {0, 1000000000u / 42}; | ||||||
|     if (!gethostuuid(uuid, &wait) && |     if (!gethostuuid(hostuuid, &wait)) | ||||||
|         bootid_parse_uuid(&bin, uuid, sizeof(uuid))) |       got_machineid = bootid_parse_uuid(&uuid, hostuuid, sizeof(hostuuid)); | ||||||
|       got_machineid = true; |  | ||||||
| #endif /* > 10.5 */ | #endif /* > 10.5 */ | ||||||
|  |  | ||||||
|     struct timeval boottime; |     struct timeval boottime; | ||||||
| @@ -3127,7 +3154,7 @@ __cold static bin128_t osal_bootid(void) { | |||||||
|                          "MachineGuid", &buf.MachineGuid, |                          "MachineGuid", &buf.MachineGuid, | ||||||
|                          &len) == ERROR_SUCCESS && |                          &len) == ERROR_SUCCESS && | ||||||
|         len < sizeof(buf)) |         len < sizeof(buf)) | ||||||
|       got_machineid = bootid_parse_uuid(&bin, &buf.MachineGuid, len); |       got_machineid = bootid_parse_uuid(&uuid, &buf.MachineGuid, len); | ||||||
|  |  | ||||||
|     if (!got_machineid) { |     if (!got_machineid) { | ||||||
|       /* again, Windows is madness */ |       /* again, Windows is madness */ | ||||||
| @@ -3145,7 +3172,7 @@ __cold static bin128_t osal_bootid(void) { | |||||||
|                            "DigitalProductId", &buf.DigitalProductId, |                            "DigitalProductId", &buf.DigitalProductId, | ||||||
|                            &len) == ERROR_SUCCESS && |                            &len) == ERROR_SUCCESS && | ||||||
|           len > 42 && len < sizeof(buf)) { |           len > 42 && len < sizeof(buf)) { | ||||||
|         bootid_collect(&bin, &buf.DigitalProductId, len); |         bootid_collect(&uuid, &buf.DigitalProductId, len); | ||||||
|         got_machineid = true; |         got_machineid = true; | ||||||
|       } |       } | ||||||
|       len = sizeof(buf); |       len = sizeof(buf); | ||||||
| @@ -3153,7 +3180,7 @@ __cold static bin128_t osal_bootid(void) { | |||||||
|                            "DigitalProductId", &buf.DigitalProductId, |                            "DigitalProductId", &buf.DigitalProductId, | ||||||
|                            &len) == ERROR_SUCCESS && |                            &len) == ERROR_SUCCESS && | ||||||
|           len > 42 && len < sizeof(buf)) { |           len > 42 && len < sizeof(buf)) { | ||||||
|         bootid_collect(&bin, &buf.DigitalProductId, len); |         bootid_collect(&uuid, &buf.DigitalProductId, len); | ||||||
|         got_machineid = true; |         got_machineid = true; | ||||||
|       } |       } | ||||||
|       len = sizeof(buf); |       len = sizeof(buf); | ||||||
| @@ -3161,7 +3188,7 @@ __cold static bin128_t osal_bootid(void) { | |||||||
|                            "DigitalProductId", &buf.DigitalProductId, |                            "DigitalProductId", &buf.DigitalProductId, | ||||||
|                            &len) == ERROR_SUCCESS && |                            &len) == ERROR_SUCCESS && | ||||||
|           len > 42 && len < sizeof(buf)) { |           len > 42 && len < sizeof(buf)) { | ||||||
|         bootid_collect(&bin, &buf.DigitalProductId, len); |         bootid_collect(&uuid, &buf.DigitalProductId, len); | ||||||
|         got_machineid = true; |         got_machineid = true; | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
| @@ -3173,7 +3200,7 @@ __cold static bin128_t osal_bootid(void) { | |||||||
|     if (mdbx_RegGetValue(HKEY_LOCAL_MACHINE, HKLM_PrefetcherParams, "BootId", |     if (mdbx_RegGetValue(HKEY_LOCAL_MACHINE, HKLM_PrefetcherParams, "BootId", | ||||||
|                          &buf.BootId, &len) == ERROR_SUCCESS && |                          &buf.BootId, &len) == ERROR_SUCCESS && | ||||||
|         len > 1 && len < sizeof(buf)) { |         len > 1 && len < sizeof(buf)) { | ||||||
|       bootid_collect(&bin, &buf.BootId, len); |       bootid_collect(&uuid, &buf.BootId, len); | ||||||
|       got_bootseq = true; |       got_bootseq = true; | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -3181,7 +3208,7 @@ __cold static bin128_t osal_bootid(void) { | |||||||
|     if (mdbx_RegGetValue(HKEY_LOCAL_MACHINE, HKLM_PrefetcherParams, "BaseTime", |     if (mdbx_RegGetValue(HKEY_LOCAL_MACHINE, HKLM_PrefetcherParams, "BaseTime", | ||||||
|                          &buf.BaseTime, &len) == ERROR_SUCCESS && |                          &buf.BaseTime, &len) == ERROR_SUCCESS && | ||||||
|         len >= sizeof(buf.BaseTime) && buf.BaseTime) { |         len >= sizeof(buf.BaseTime) && buf.BaseTime) { | ||||||
|       bootid_collect(&bin, &buf.BaseTime, len); |       bootid_collect(&uuid, &buf.BaseTime, len); | ||||||
|       got_boottime = true; |       got_boottime = true; | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -3197,7 +3224,7 @@ __cold static bin128_t osal_bootid(void) { | |||||||
|           buf.SysTimeOfDayInfoHacked.BootTime.QuadPart - |           buf.SysTimeOfDayInfoHacked.BootTime.QuadPart - | ||||||
|           buf.SysTimeOfDayInfoHacked.BootTimeBias; |           buf.SysTimeOfDayInfoHacked.BootTimeBias; | ||||||
|       if (UnbiasedBootTime) { |       if (UnbiasedBootTime) { | ||||||
|         bootid_collect(&bin, &UnbiasedBootTime, sizeof(UnbiasedBootTime)); |         bootid_collect(&uuid, &UnbiasedBootTime, sizeof(UnbiasedBootTime)); | ||||||
|         got_boottime = true; |         got_boottime = true; | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
| @@ -3205,7 +3232,7 @@ __cold static bin128_t osal_bootid(void) { | |||||||
|     if (!got_boottime) { |     if (!got_boottime) { | ||||||
|       uint64_t boottime = windows_bootime(); |       uint64_t boottime = windows_bootime(); | ||||||
|       if (boottime) { |       if (boottime) { | ||||||
|         bootid_collect(&bin, &boottime, sizeof(boottime)); |         bootid_collect(&uuid, &boottime, sizeof(boottime)); | ||||||
|         got_boottime = true; |         got_boottime = true; | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
| @@ -3223,7 +3250,7 @@ __cold static bin128_t osal_bootid(void) { | |||||||
| #endif | #endif | ||||||
|                 mib, |                 mib, | ||||||
|             ARRAY_LENGTH(mib), &buf, &len, nullptr, 0) == 0) |             ARRAY_LENGTH(mib), &buf, &len, nullptr, 0) == 0) | ||||||
|       got_machineid = bootid_parse_uuid(&bin, buf, len); |       got_machineid = bootid_parse_uuid(&uuid, buf, len); | ||||||
|   } |   } | ||||||
| #endif /* CTL_HW && HW_UUID */ | #endif /* CTL_HW && HW_UUID */ | ||||||
|  |  | ||||||
| @@ -3238,7 +3265,7 @@ __cold static bin128_t osal_bootid(void) { | |||||||
| #endif | #endif | ||||||
|                 mib, |                 mib, | ||||||
|             ARRAY_LENGTH(mib), &buf, &len, nullptr, 0) == 0) |             ARRAY_LENGTH(mib), &buf, &len, nullptr, 0) == 0) | ||||||
|       got_machineid = bootid_parse_uuid(&bin, buf, len); |       got_machineid = bootid_parse_uuid(&uuid, buf, len); | ||||||
|   } |   } | ||||||
| #endif /* CTL_KERN && KERN_HOSTUUID */ | #endif /* CTL_KERN && KERN_HOSTUUID */ | ||||||
|  |  | ||||||
| @@ -3247,7 +3274,7 @@ __cold static bin128_t osal_bootid(void) { | |||||||
|     char buf[42]; |     char buf[42]; | ||||||
|     size_t len = sizeof(buf); |     size_t len = sizeof(buf); | ||||||
|     if (sysctlbyname("machdep.dmi.system-uuid", buf, &len, nullptr, 0) == 0) |     if (sysctlbyname("machdep.dmi.system-uuid", buf, &len, nullptr, 0) == 0) | ||||||
|       got_machineid = bootid_parse_uuid(&bin, buf, len); |       got_machineid = bootid_parse_uuid(&uuid, buf, len); | ||||||
|   } |   } | ||||||
| #endif /* __NetBSD__ */ | #endif /* __NetBSD__ */ | ||||||
|  |  | ||||||
| @@ -3255,7 +3282,7 @@ __cold static bin128_t osal_bootid(void) { | |||||||
|   if (!got_machineid) { |   if (!got_machineid) { | ||||||
|     const int hostid = gethostid(); |     const int hostid = gethostid(); | ||||||
|     if (hostid > 0) { |     if (hostid > 0) { | ||||||
|       bootid_collect(&bin, &hostid, sizeof(hostid)); |       bootid_collect(&uuid, &hostid, sizeof(hostid)); | ||||||
|       got_machineid = true; |       got_machineid = true; | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
| @@ -3263,8 +3290,8 @@ __cold static bin128_t osal_bootid(void) { | |||||||
|  |  | ||||||
|   if (!got_machineid) { |   if (!got_machineid) { | ||||||
|   lack: |   lack: | ||||||
|     bin.x = bin.y = 0; |     uuid.x = uuid.y = 0; | ||||||
|     return bin; |     return uuid; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   /*--------------------------------------------------------------------------*/ |   /*--------------------------------------------------------------------------*/ | ||||||
| @@ -3281,7 +3308,7 @@ __cold static bin128_t osal_bootid(void) { | |||||||
|                 mib, |                 mib, | ||||||
|             ARRAY_LENGTH(mib), &boottime, &len, nullptr, 0) == 0 && |             ARRAY_LENGTH(mib), &boottime, &len, nullptr, 0) == 0 && | ||||||
|         len == sizeof(boottime) && boottime.tv_sec) { |         len == sizeof(boottime) && boottime.tv_sec) { | ||||||
|       bootid_collect(&bin, &boottime, len); |       bootid_collect(&uuid, &boottime, len); | ||||||
|       got_boottime = true; |       got_boottime = true; | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
| @@ -3298,11 +3325,11 @@ __cold static bin128_t osal_bootid(void) { | |||||||
|           switch (kn->data_type) { |           switch (kn->data_type) { | ||||||
|           case KSTAT_DATA_INT32: |           case KSTAT_DATA_INT32: | ||||||
|           case KSTAT_DATA_UINT32: |           case KSTAT_DATA_UINT32: | ||||||
|             bootid_collect(&bin, &kn->value, sizeof(int32_t)); |             bootid_collect(&uuid, &kn->value, sizeof(int32_t)); | ||||||
|             got_boottime = true; |             got_boottime = true; | ||||||
|           case KSTAT_DATA_INT64: |           case KSTAT_DATA_INT64: | ||||||
|           case KSTAT_DATA_UINT64: |           case KSTAT_DATA_UINT64: | ||||||
|             bootid_collect(&bin, &kn->value, sizeof(int64_t)); |             bootid_collect(&uuid, &kn->value, sizeof(int64_t)); | ||||||
|             got_boottime = true; |             got_boottime = true; | ||||||
|           } |           } | ||||||
|         } |         } | ||||||
| @@ -3318,12 +3345,12 @@ __cold static bin128_t osal_bootid(void) { | |||||||
|     const struct utmpx id = {.ut_type = BOOT_TIME}; |     const struct utmpx id = {.ut_type = BOOT_TIME}; | ||||||
|     const struct utmpx *entry = getutxid(&id); |     const struct utmpx *entry = getutxid(&id); | ||||||
|     if (entry) { |     if (entry) { | ||||||
|       bootid_collect(&bin, entry, sizeof(*entry)); |       bootid_collect(&uuid, entry, sizeof(*entry)); | ||||||
|       got_boottime = true; |       got_boottime = true; | ||||||
|       while (unlikely((entry = getutxid(&id)) != nullptr)) { |       while (unlikely((entry = getutxid(&id)) != nullptr)) { | ||||||
|         /* have multiple reboot records, assuming we can distinguish next |         /* have multiple reboot records, assuming we can distinguish next | ||||||
|          * bootsession even if RTC is wrong or absent */ |          * bootsession even if RTC is wrong or absent */ | ||||||
|         bootid_collect(&bin, entry, sizeof(*entry)); |         bootid_collect(&uuid, entry, sizeof(*entry)); | ||||||
|         got_bootseq = true; |         got_bootseq = true; | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
| @@ -3352,7 +3379,7 @@ __cold static bin128_t osal_bootid(void) { | |||||||
|       goto lack; |       goto lack; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   return bin; |   return uuid; | ||||||
| } | } | ||||||
|  |  | ||||||
| __cold int mdbx_get_sysraminfo(intptr_t *page_size, intptr_t *total_pages, | __cold int mdbx_get_sysraminfo(intptr_t *page_size, intptr_t *total_pages, | ||||||
| @@ -3474,6 +3501,100 @@ __cold int mdbx_get_sysraminfo(intptr_t *page_size, intptr_t *total_pages, | |||||||
|   return MDBX_SUCCESS; |   return MDBX_SUCCESS; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | /*----------------------------------------------------------------------------*/ | ||||||
|  |  | ||||||
|  | #ifdef __FreeBSD__ | ||||||
|  | #include <sys/uuid.h> | ||||||
|  | #endif /* FreeBSD */ | ||||||
|  |  | ||||||
|  | #if __GLIBC_PREREQ(2, 25) || defined(__FreeBSD__) || defined(__NetBSD__) ||    \ | ||||||
|  |     defined(__BSD__) || defined(__bsdi__) || defined(__DragonFly__) ||         \ | ||||||
|  |     defined(__APPLE__) || __has_include(<sys/random.h>) | ||||||
|  | #include <sys/random.h> | ||||||
|  | #endif /* sys/random.h */ | ||||||
|  |  | ||||||
|  | MDBX_INTERNAL bin128_t osal_guid(const MDBX_env *env) { | ||||||
|  |   struct { | ||||||
|  |     uint64_t begin, end, cputime; | ||||||
|  |     uintptr_t thread, pid; | ||||||
|  |     const void *x, *y; | ||||||
|  |     bin128_t (*z)(const MDBX_env *env); | ||||||
|  |   } salt; | ||||||
|  |  | ||||||
|  |   salt.begin = osal_monotime(); | ||||||
|  |   bin128_t uuid = {{0, 0}}; | ||||||
|  |  | ||||||
|  | #if defined(__linux__) || defined(__gnu_linux__) | ||||||
|  |   if (proc_read_uuid("/proc/sys/kernel/random/uuid", &uuid) && check_uuid(uuid)) | ||||||
|  |     return uuid; | ||||||
|  | #endif /* Linux */ | ||||||
|  |  | ||||||
|  | #ifdef __FreeBSD__ | ||||||
|  |   STATIC_ASSERT(sizeof(uuid) == sizeof(struct uuid)); | ||||||
|  |   if (uuidgen((struct uuid *)&uuid, 1) == 0 && check_uuid(uuid)) | ||||||
|  |     return uuid; | ||||||
|  | #endif /* FreeBSD */ | ||||||
|  |  | ||||||
|  | #if defined(_WIN32) || defined(_WIN64) | ||||||
|  |   if (imports.CoCreateGuid && imports.CoCreateGuid(&uuid) == 0 && | ||||||
|  |       check_uuid(uuid)) | ||||||
|  |     return uuid; | ||||||
|  |  | ||||||
|  |   HCRYPTPROV hCryptProv = 0; | ||||||
|  |   if (CryptAcquireContextW(&hCryptProv, nullptr, nullptr, PROV_RSA_FULL, | ||||||
|  |                            CRYPT_VERIFYCONTEXT | CRYPT_SILENT)) { | ||||||
|  |     const BOOL ok = | ||||||
|  |         CryptGenRandom(hCryptProv, sizeof(uuid), (unsigned char *)&uuid); | ||||||
|  |     CryptReleaseContext(hCryptProv, 0); | ||||||
|  |     if (ok && check_uuid(uuid)) | ||||||
|  |       return uuid; | ||||||
|  |   } | ||||||
|  | #elif defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && defined(__IPHONE_8_0) | ||||||
|  | #if __IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_8_0 | ||||||
|  |   if (CCRandomGenerateBytes(&uuid, sizeof(uuid)) == kCCSuccess && | ||||||
|  |       check_uuid(uuid)) | ||||||
|  |     return uuid; | ||||||
|  | #endif /* iOS >= 8.x */ | ||||||
|  | #else | ||||||
|  |   const int fd = open("/dev/urandom", O_RDONLY); | ||||||
|  |   if (fd != -1) { | ||||||
|  |     const ssize_t len = read(fd, &uuid, sizeof(uuid)); | ||||||
|  |     const int err = close(fd); | ||||||
|  |     assert(err == 0); | ||||||
|  |     (void)err; | ||||||
|  |     if (len == sizeof(uuid) && check_uuid(uuid)) | ||||||
|  |       return uuid; | ||||||
|  |   } | ||||||
|  | #if (__GLIBC_PREREQ(2, 25) || defined(__FreeBSD__) || defined(__NetBSD__) ||   \ | ||||||
|  |      defined(__BSD__) || defined(__bsdi__) || defined(__DragonFly__)) &&       \ | ||||||
|  |     !defined(__APPLE__) && !defined(__ANDROID_API__) | ||||||
|  |   if (getrandom(&uuid, sizeof(uuid), 0) == sizeof(uuid) && check_uuid(uuid)) | ||||||
|  |     return uuid; | ||||||
|  | #elif defined(__OpenBSD__) || (defined(__sun) && defined(__SVR4)) ||           \ | ||||||
|  |     (defined(__MAC_OS_X_VERSION_MIN_REQUIRED) &&                               \ | ||||||
|  |      __MAC_OS_X_VERSION_MIN_REQUIRED >= 101200) | ||||||
|  |   if (getentropy(&uuid, sizeof(uuid)) == 0 && check_uuid(uuid)) | ||||||
|  |     return uuid; | ||||||
|  | #endif /* getrandom() / getentropy() */ | ||||||
|  | #endif /* !Windows */ | ||||||
|  |  | ||||||
|  |   uuid = globals.bootid; | ||||||
|  |   bootid_collect(&uuid, env, sizeof(*env)); | ||||||
|  |   salt.thread = osal_thread_self(); | ||||||
|  |   salt.pid = osal_getpid(); | ||||||
|  |   salt.x = &salt; | ||||||
|  |   salt.y = env; | ||||||
|  |   salt.z = &osal_guid; | ||||||
|  |   do { | ||||||
|  |     salt.cputime = osal_cputime(nullptr); | ||||||
|  |     salt.end = osal_monotime(); | ||||||
|  |     bootid_collect(&uuid, &salt, sizeof(salt)); | ||||||
|  |   } while (!check_uuid(uuid)); | ||||||
|  |   return uuid; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /*--------------------------------------------------------------------------*/ | ||||||
|  |  | ||||||
| void osal_ctor(void) { | void osal_ctor(void) { | ||||||
| #if MDBX_HAVE_PWRITEV && defined(_SC_IOV_MAX) | #if MDBX_HAVE_PWRITEV && defined(_SC_IOV_MAX) | ||||||
|   osal_iov_max = sysconf(_SC_IOV_MAX); |   osal_iov_max = sysconf(_SC_IOV_MAX); | ||||||
|   | |||||||
							
								
								
									
										11
									
								
								src/osal.h
									
									
									
									
									
								
							
							
						
						
									
										11
									
								
								src/osal.h
									
									
									
									
									
								
							| @@ -576,6 +576,17 @@ MDBX_INTERNAL void osal_dtor(void); | |||||||
| MDBX_INTERNAL int osal_mb2w(const char *const src, wchar_t **const pdst); | MDBX_INTERNAL int osal_mb2w(const char *const src, wchar_t **const pdst); | ||||||
| #endif /* Windows */ | #endif /* Windows */ | ||||||
|  |  | ||||||
|  | typedef union bin128 { | ||||||
|  |   __anonymous_struct_extension__ struct { | ||||||
|  |     uint64_t x, y; | ||||||
|  |   }; | ||||||
|  |   __anonymous_struct_extension__ struct { | ||||||
|  |     uint32_t a, b, c, d; | ||||||
|  |   }; | ||||||
|  | } bin128_t; | ||||||
|  |  | ||||||
|  | MDBX_INTERNAL bin128_t osal_guid(const MDBX_env *); | ||||||
|  |  | ||||||
| /*----------------------------------------------------------------------------*/ | /*----------------------------------------------------------------------------*/ | ||||||
|  |  | ||||||
| MDBX_MAYBE_UNUSED MDBX_NOTHROW_PURE_FUNCTION static inline uint64_t | MDBX_MAYBE_UNUSED MDBX_NOTHROW_PURE_FUNCTION static inline uint64_t | ||||||
|   | |||||||
| @@ -839,6 +839,7 @@ int mdbx_txn_commit_ex(MDBX_txn *txn, MDBX_commit_latency *latency) { | |||||||
|   meta.trees.gc = txn->dbs[FREE_DBI]; |   meta.trees.gc = txn->dbs[FREE_DBI]; | ||||||
|   meta.trees.main = txn->dbs[MAIN_DBI]; |   meta.trees.main = txn->dbs[MAIN_DBI]; | ||||||
|   meta.canary = txn->canary; |   meta.canary = txn->canary; | ||||||
|  |   memcpy(&meta.dxbid, &head.ptr_c->dxbid, sizeof(meta.dxbid)); | ||||||
|  |  | ||||||
|   txnid_t commit_txnid = txn->txnid; |   txnid_t commit_txnid = txn->txnid; | ||||||
| #if MDBX_ENABLE_BIGFOOT | #if MDBX_ENABLE_BIGFOOT | ||||||
|   | |||||||
| @@ -147,6 +147,11 @@ void windows_import(void) { | |||||||
|   if (hAdvapi32dll) { |   if (hAdvapi32dll) { | ||||||
|     MDBX_IMPORT(hAdvapi32dll, RegGetValueA); |     MDBX_IMPORT(hAdvapi32dll, RegGetValueA); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   const HINSTANCE hOle32dll = GetModuleHandleA("ole32.dll"); | ||||||
|  |   if (hOle32dll) { | ||||||
|  |     MDBX_IMPORT(hOle32dll, CoCreateGuid); | ||||||
|  |   } | ||||||
| } | } | ||||||
|  |  | ||||||
| #undef MDBX_IMPORT | #undef MDBX_IMPORT | ||||||
|   | |||||||
| @@ -109,6 +109,8 @@ typedef LSTATUS(WINAPI *MDBX_RegGetValueA)(HKEY hkey, LPCSTR lpSubKey, | |||||||
|                                            LPDWORD pdwType, PVOID pvData, |                                            LPDWORD pdwType, PVOID pvData, | ||||||
|                                            LPDWORD pcbData); |                                            LPDWORD pcbData); | ||||||
|  |  | ||||||
|  | typedef long(WINAPI *MDBX_CoCreateGuid)(bin128_t *guid); | ||||||
|  |  | ||||||
| NTSYSAPI ULONG RtlRandomEx(PULONG Seed); | NTSYSAPI ULONG RtlRandomEx(PULONG Seed); | ||||||
|  |  | ||||||
| typedef BOOL(WINAPI *MDBX_SetFileIoOverlappedRange)(HANDLE FileHandle, | typedef BOOL(WINAPI *MDBX_SetFileIoOverlappedRange)(HANDLE FileHandle, | ||||||
| @@ -131,6 +133,7 @@ struct libmdbx_imports { | |||||||
|   MDBX_GetTickCount64 GetTickCount64; |   MDBX_GetTickCount64 GetTickCount64; | ||||||
|   MDBX_RegGetValueA RegGetValueA; |   MDBX_RegGetValueA RegGetValueA; | ||||||
|   MDBX_SetFileIoOverlappedRange SetFileIoOverlappedRange; |   MDBX_SetFileIoOverlappedRange SetFileIoOverlappedRange; | ||||||
|  |   MDBX_CoCreateGuid CoCreateGuid; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| MDBX_INTERNAL void windows_import(void); | MDBX_INTERNAL void windows_import(void); | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user