diff options
author | dormando <dormando@rydia.net> | 2019-09-17 20:06:09 -0700 |
---|---|---|
committer | dormando <dormando@rydia.net> | 2019-09-17 20:08:44 -0700 |
commit | 9485db55edf2dc6b75b2024770ae41ad6b68de18 (patch) | |
tree | 85fe3eef417a6d24d0419eea9d8549ce43e60388 | |
parent | b5ea90160579ba060b8e1d269595b3ec5d77d740 (diff) | |
download | memcached-1.5.18.tar.gz |
restart: fixes for 32bit and chunked items.1.5.18
severe bug in item chunk fixup (wasn't doing it at all!)
failed to check on my 32bit builders... and 32bit platforms weren't
working at all. This is a bit of a kludge since I'm still working
around having ptrdiff, but it seems to work.
also fixes a bug with missing null byte for meta filename.
-rw-r--r-- | configure.ac | 14 | ||||
-rw-r--r-- | memcached.c | 5 | ||||
-rw-r--r-- | restart.c | 24 | ||||
-rw-r--r-- | restart.h | 7 |
4 files changed, 37 insertions, 13 deletions
diff --git a/configure.ac b/configure.ac index 4d960a5..fb78fc5 100644 --- a/configure.ac +++ b/configure.ac @@ -268,6 +268,20 @@ return sizeof(void*) == 8 ? 0 : 1; ]) fi +dnl If data pointer is 64bit or not. +AC_RUN_IFELSE( + [AC_LANG_PROGRAM([], [dnl +return sizeof(void*) == 8 ? 0 : 1; + ]) +],[ + have_64bit_ptr=yes +],[ +]) + +if test $have_64bit_ptr = yes; then + AC_DEFINE(HAVE_64BIT_PTR, 1, [data pointer is 64bit]) +fi + # Issue 213: Search for clock_gettime to help people linking # with a static version of libevent AC_SEARCH_LIBS(clock_gettime, rt) diff --git a/memcached.c b/memcached.c index 19b6b1d..884469c 100644 --- a/memcached.c +++ b/memcached.c @@ -8624,13 +8624,16 @@ int main (int argc, char **argv) { slabs_prefill_global(); /* In restartable mode and we've decided to issue a fixup on memory */ if (memory_file != NULL && reuse_mem) { + mc_ptr_t old_base = meta->old_base; + assert(old_base == meta->old_base); + // should've pulled in process_started from meta file. process_started = meta->process_started; // TODO: must be a more canonical way of serializing/deserializing // pointers? passing through uint64_t should work, and we're not // annotating the pointer with anything, but it's still slightly // insane. - restart_fixup((void *)meta->old_base); + restart_fixup((void *)old_base); } /* * ignore SIGPIPE signals; we can use errno == EPIPE if we @@ -68,7 +68,7 @@ static int restart_check(const char *file) { // metadata is kept in a separate file. size_t flen = strlen(file); const char *ext = ".meta"; - char *metafile = malloc(flen + strlen(ext)); + char *metafile = calloc(1, flen + strlen(ext) + 1); memcpy(metafile, file, flen); memcpy(metafile+flen, ext, strlen(ext)); @@ -201,7 +201,7 @@ static int restart_save(const char *file) { // FIXME: function. size_t flen = strlen(file); const char *ext = ".meta"; - char *metafile = malloc(flen + strlen(ext)); + char *metafile = calloc(1, flen + strlen(ext) + 1); memcpy(metafile, file, flen); memcpy(metafile+flen, ext, strlen(ext)); @@ -351,12 +351,12 @@ unsigned int restart_fixup(void *orig_addr) { if (it->it_flags & ITEM_LINKED) { // fixup next/prev links while on LRU. if (it->next) { - it->next = (item *)((uint64_t)it->next - (uint64_t)orig_addr); - it->next = (item *)((uint64_t)it->next + (uint64_t)mmap_base); + it->next = (item *)((mc_ptr_t)it->next - (mc_ptr_t)orig_addr); + it->next = (item *)((mc_ptr_t)it->next + (mc_ptr_t)mmap_base); } if (it->prev) { - it->prev = (item *)((uint64_t)it->prev - (uint64_t)orig_addr); - it->prev = (item *)((uint64_t)it->prev + (uint64_t)mmap_base); + it->prev = (item *)((mc_ptr_t)it->prev - (mc_ptr_t)orig_addr); + it->prev = (item *)((mc_ptr_t)it->prev + (mc_ptr_t)mmap_base); } //fprintf(stderr, "item was linked\n"); @@ -378,16 +378,16 @@ unsigned int restart_fixup(void *orig_addr) { ch = (item_chunk *) it; } if (ch->next) { - ch->next = (item_chunk *)((uint64_t)ch->next - (uint64_t)orig_addr); - ch->next = (item_chunk *)((uint64_t)ch->next + (uint64_t)mmap_base); + ch->next = (item_chunk *)((mc_ptr_t)ch->next - (mc_ptr_t)orig_addr); + ch->next = (item_chunk *)((mc_ptr_t)ch->next + (mc_ptr_t)mmap_base); } if (ch->prev) { - ch->prev = (item_chunk *)((uint64_t)ch->prev - (uint64_t)orig_addr); - ch->prev = (item_chunk *)((uint64_t)ch->prev + (uint64_t)mmap_base); + ch->prev = (item_chunk *)((mc_ptr_t)ch->prev - (mc_ptr_t)orig_addr); + ch->prev = (item_chunk *)((mc_ptr_t)ch->prev + (mc_ptr_t)mmap_base); } if (ch->head) { - ch->head = (item *)((uint64_t)it->prev - (uint64_t)orig_addr); - ch->head = (item *)((uint64_t)it->prev + (uint64_t)mmap_base); + ch->head = (item *)((mc_ptr_t)ch->head - (mc_ptr_t)orig_addr); + ch->head = (item *)((mc_ptr_t)ch->head + (mc_ptr_t)mmap_base); } } @@ -3,6 +3,13 @@ #define RESTART_TAG_MAXLEN 255 +// Track the pointer size for restart fiddling. +#ifdef HAVE_64BIT_PTR + typedef uint64_t mc_ptr_t; +#else + typedef uint32_t mc_ptr_t; +#endif + enum restart_get_kv_ret { RESTART_OK=0, RESTART_NOTAG, RESTART_BADLINE, RESTART_DONE }; |