summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordormando <dormando@rydia.net>2019-09-17 20:06:09 -0700
committerdormando <dormando@rydia.net>2019-09-17 20:08:44 -0700
commit9485db55edf2dc6b75b2024770ae41ad6b68de18 (patch)
tree85fe3eef417a6d24d0419eea9d8549ce43e60388
parentb5ea90160579ba060b8e1d269595b3ec5d77d740 (diff)
downloadmemcached-9485db55edf2dc6b75b2024770ae41ad6b68de18.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.ac14
-rw-r--r--memcached.c5
-rw-r--r--restart.c24
-rw-r--r--restart.h7
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
diff --git a/restart.c b/restart.c
index e27057b..46f8cc2 100644
--- a/restart.c
+++ b/restart.c
@@ -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);
}
}
diff --git a/restart.h b/restart.h
index a8bc67e..76cd0a8 100644
--- a/restart.h
+++ b/restart.h
@@ -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
};