summaryrefslogtreecommitdiff
path: root/slabs.c
diff options
context:
space:
mode:
authordormando <dormando@rydia.net>2020-03-26 11:59:22 -0700
committerdormando <dormando@rydia.net>2020-03-26 11:59:22 -0700
commitfa40655b49cc73194acc0e2410930f3e9a8322a7 (patch)
tree1e45ed34fad207681d668e3fa1d627e1ee1da1e3 /slabs.c
parentcb0de8114921f09adf97397b08b238fbcb9f8ab4 (diff)
downloadmemcached-fa40655b49cc73194acc0e2410930f3e9a8322a7.tar.gz
restart: fix corrupted restart in some scenarios
If the mmap file is reused but the memory isn't supposed to be reused, pages are thrown into the global page pool. Normally when pages are released into the pool the header of the page is zero'ed so the restart_check() code will know to place it back into the global pool. When restarting multiple times the slabs_prefill() part of the startup code was missing this zero'ing step, so the _next_ time restart happens properly restart_check() could attempt to recover that memory.
Diffstat (limited to 'slabs.c')
-rw-r--r--slabs.c4
1 files changed, 4 insertions, 0 deletions
diff --git a/slabs.c b/slabs.c
index 56b5840..ca8a8f2 100644
--- a/slabs.c
+++ b/slabs.c
@@ -299,6 +299,10 @@ void slabs_prefill_global(void) {
while (mem_malloced < mem_limit
&& (ptr = memory_allocate(len)) != NULL) {
grow_slab_list(0);
+ // Ensure the front header is zero'd to avoid confusing restart code.
+ // It's probably good enough to cast it and just zero slabs_clsid, but
+ // this is extra paranoid.
+ memset(ptr, 0, sizeof(item));
p->slab_list[p->slabs++] = ptr;
}
mem_limit_reached = true;