371 lines
14 KiB
Diff
371 lines
14 KiB
Diff
|
|
diff -Nurp memcached-1.5.10/assoc.c memcached-1.5.10-old/assoc.c
|
||
|
|
--- memcached-1.5.10/assoc.c 2018-07-18 16:39:52.000000000 -0400
|
||
|
|
+++ memcached-1.5.10-old/assoc.c 2019-05-31 04:34:02.477000000 -0400
|
||
|
|
@@ -28,7 +28,7 @@
|
||
|
|
static pthread_cond_t maintenance_cond = PTHREAD_COND_INITIALIZER;
|
||
|
|
static pthread_mutex_t maintenance_lock = PTHREAD_MUTEX_INITIALIZER;
|
||
|
|
|
||
|
|
-typedef unsigned long int ub4; /* unsigned 4-byte quantities */
|
||
|
|
+typedef uint32_t ub4; /* unsigned 4-byte quantities */
|
||
|
|
typedef unsigned char ub1; /* unsigned 1-byte quantities */
|
||
|
|
|
||
|
|
/* how many powers of 2's worth of buckets we use */
|
||
|
|
diff -Nurp memcached-1.5.10/cache.h memcached-1.5.10-old/cache.h
|
||
|
|
--- memcached-1.5.10/cache.h 2018-07-18 16:39:52.000000000 -0400
|
||
|
|
+++ memcached-1.5.10-old/cache.h 2019-05-31 04:34:36.887000000 -0400
|
||
|
|
@@ -34,8 +34,7 @@ typedef int cache_constructor_t(void* ob
|
||
|
|
* returned to the operating system.
|
||
|
|
*
|
||
|
|
* @param obj pointer to the object to clean up.
|
||
|
|
- * @param notused1 This parameter is currently not used.
|
||
|
|
- * @param notused2 This parameter is currently not used.
|
||
|
|
+ * @param notused This parameter is currently not used.
|
||
|
|
* @return you should return 0, but currently this is not checked
|
||
|
|
*/
|
||
|
|
typedef void cache_destructor_t(void* obj, void* notused);
|
||
|
|
diff -Nurp memcached-1.5.10/configure.ac memcached-1.5.10-old/configure.ac
|
||
|
|
--- memcached-1.5.10/configure.ac 2018-07-18 16:39:52.000000000 -0400
|
||
|
|
+++ memcached-1.5.10-old/configure.ac 2019-05-31 04:35:28.038000000 -0400
|
||
|
|
@@ -629,9 +629,18 @@ AC_CHECK_FUNCS(pledge, [
|
||
|
|
], [])
|
||
|
|
],[])
|
||
|
|
|
||
|
|
+AC_CHECK_FUNCS(cap_enter, [
|
||
|
|
+ AC_CHECK_HEADER(sys/capsicum.h, [
|
||
|
|
+ AC_DEFINE([HAVE_DROP_PRIVILEGES], 1,
|
||
|
|
+ [Define this if you have an implementation of drop_privileges()])
|
||
|
|
+ build_freebsd_privs=yes
|
||
|
|
+ ], [])
|
||
|
|
+],[])
|
||
|
|
+
|
||
|
|
AM_CONDITIONAL([BUILD_SOLARIS_PRIVS],[test "$build_solaris_privs" = "yes"])
|
||
|
|
AM_CONDITIONAL([BUILD_LINUX_PRIVS],[test "$build_linux_privs" = "yes"])
|
||
|
|
AM_CONDITIONAL([BUILD_OPENBSD_PRIVS],[test "$build_openbsd_privs" = "yes"])
|
||
|
|
+AM_CONDITIONAL([BUILD_FREEBSD_PRIVS],[test "$build_freebsd_privs" = "yes"])
|
||
|
|
|
||
|
|
AC_CHECK_HEADER(umem.h, [
|
||
|
|
AC_DEFINE([HAVE_UMEM_H], 1,
|
||
|
|
diff -Nurp memcached-1.5.10/doc/protocol.txt memcached-1.5.10-old/doc/protocol.txt
|
||
|
|
--- memcached-1.5.10/doc/protocol.txt 2018-07-18 16:39:52.000000000 -0400
|
||
|
|
+++ memcached-1.5.10-old/doc/protocol.txt 2019-05-31 04:35:50.981000000 -0400
|
||
|
|
@@ -633,7 +633,7 @@ memcache developers.
|
||
|
|
General-purpose statistics
|
||
|
|
--------------------------
|
||
|
|
|
||
|
|
-Upon receiving the "stats" command without arguments, the server sents
|
||
|
|
+Upon receiving the "stats" command without arguments, the server sends
|
||
|
|
a number of lines which look like this:
|
||
|
|
|
||
|
|
STAT <name> <value>\r\n
|
||
|
|
diff -Nurp memcached-1.5.10/extstore.c memcached-1.5.10-old/extstore.c
|
||
|
|
--- memcached-1.5.10/extstore.c 2018-08-10 16:36:38.000000000 -0400
|
||
|
|
+++ memcached-1.5.10-old/extstore.c 2019-05-31 04:37:14.321000000 -0400
|
||
|
|
@@ -183,6 +183,9 @@ const char *extstore_err(enum extstore_r
|
||
|
|
case EXTSTORE_INIT_PAGE_WBUF_ALIGNMENT:
|
||
|
|
rv = "page_size and wbuf_size must be divisible by 1024*1024*2";
|
||
|
|
break;
|
||
|
|
+ case EXTSTORE_INIT_TOO_MANY_PAGES:
|
||
|
|
+ rv = "page_count must total to < 65536. Increase page_size or lower path sizes";
|
||
|
|
+ break;
|
||
|
|
case EXTSTORE_INIT_OOM:
|
||
|
|
rv = "failed calloc for engine";
|
||
|
|
break;
|
||
|
|
@@ -230,6 +233,7 @@ void *extstore_init(struct extstore_conf
|
||
|
|
}
|
||
|
|
|
||
|
|
e->page_size = cf->page_size;
|
||
|
|
+ uint64_t temp_page_count = 0;
|
||
|
|
for (f = fh; f != NULL; f = f->next) {
|
||
|
|
f->fd = open(f->file, O_RDWR | O_CREAT | O_TRUNC, 0644);
|
||
|
|
if (f->fd < 0) {
|
||
|
|
@@ -240,10 +244,17 @@ void *extstore_init(struct extstore_conf
|
||
|
|
free(e);
|
||
|
|
return NULL;
|
||
|
|
}
|
||
|
|
- e->page_count += f->page_count;
|
||
|
|
+ temp_page_count += f->page_count;
|
||
|
|
f->offset = 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
+ if (temp_page_count >= UINT16_MAX) {
|
||
|
|
+ *res = EXTSTORE_INIT_TOO_MANY_PAGES;
|
||
|
|
+ free(e);
|
||
|
|
+ return NULL;
|
||
|
|
+ }
|
||
|
|
+ e->page_count = temp_page_count;
|
||
|
|
+
|
||
|
|
e->pages = calloc(e->page_count, sizeof(store_page));
|
||
|
|
if (e->pages == NULL) {
|
||
|
|
*res = EXTSTORE_INIT_OOM;
|
||
|
|
diff -Nurp memcached-1.5.10/extstore.h memcached-1.5.10-old/extstore.h
|
||
|
|
--- memcached-1.5.10/extstore.h 2018-08-10 16:36:38.000000000 -0400
|
||
|
|
+++ memcached-1.5.10-old/extstore.h 2019-05-31 04:37:35.803000000 -0400
|
||
|
|
@@ -93,6 +93,7 @@ enum extstore_res {
|
||
|
|
EXTSTORE_INIT_NEED_MORE_WBUF,
|
||
|
|
EXTSTORE_INIT_NEED_MORE_BUCKETS,
|
||
|
|
EXTSTORE_INIT_PAGE_WBUF_ALIGNMENT,
|
||
|
|
+ EXTSTORE_INIT_TOO_MANY_PAGES,
|
||
|
|
EXTSTORE_INIT_OOM,
|
||
|
|
EXTSTORE_INIT_OPEN_FAIL,
|
||
|
|
EXTSTORE_INIT_THREAD_FAIL
|
||
|
|
diff -Nurp memcached-1.5.10/freebsd_priv.c memcached-1.5.10-old/freebsd_priv.c
|
||
|
|
--- memcached-1.5.10/freebsd_priv.c 1969-12-31 19:00:00.000000000 -0500
|
||
|
|
+++ memcached-1.5.10-old/freebsd_priv.c 2019-05-31 04:37:52.842000000 -0400
|
||
|
|
@@ -0,0 +1,18 @@
|
||
|
|
+#include <sys/capsicum.h>
|
||
|
|
+#include <errno.h>
|
||
|
|
+#include <stdlib.h>
|
||
|
|
+#include <stdio.h>
|
||
|
|
+#include <string.h>
|
||
|
|
+#include <unistd.h>
|
||
|
|
+#include "memcached.h"
|
||
|
|
+
|
||
|
|
+/*
|
||
|
|
+ * * dropping privileges is entering in capability mode
|
||
|
|
+ * * in FreeBSD vocabulary.
|
||
|
|
+ * */
|
||
|
|
+void drop_privileges() {
|
||
|
|
+ if (cap_enter() != 0) {
|
||
|
|
+ fprintf(stderr, "cap_enter failed: %s\n", strerror(errno));
|
||
|
|
+ exit(EXIT_FAILURE);
|
||
|
|
+ }
|
||
|
|
+}
|
||
|
|
diff -Nurp memcached-1.5.10/logger.c memcached-1.5.10-old/logger.c
|
||
|
|
--- memcached-1.5.10/logger.c 2018-08-10 16:36:38.000000000 -0400
|
||
|
|
+++ memcached-1.5.10-old/logger.c 2019-05-31 04:38:14.125000000 -0400
|
||
|
|
@@ -6,6 +6,7 @@
|
||
|
|
#include <errno.h>
|
||
|
|
#include <poll.h>
|
||
|
|
#include <ctype.h>
|
||
|
|
+#include <stdarg.h>
|
||
|
|
|
||
|
|
#if defined(__sun)
|
||
|
|
#include <atomic.h>
|
||
|
|
diff -Nurp memcached-1.5.10/Makefile.am memcached-1.5.10-old/Makefile.am
|
||
|
|
--- memcached-1.5.10/Makefile.am 2018-07-18 16:39:52.000000000 -0400
|
||
|
|
+++ memcached-1.5.10-old/Makefile.am 2019-05-31 04:33:27.162000000 -0400
|
||
|
|
@@ -42,6 +42,10 @@ if BUILD_OPENBSD_PRIVS
|
||
|
|
memcached_SOURCES += openbsd_priv.c
|
||
|
|
endif
|
||
|
|
|
||
|
|
+if BUILD_FREEBSD_PRIVS
|
||
|
|
+memcached_SOURCES += freebsd_priv.c
|
||
|
|
+endif
|
||
|
|
+
|
||
|
|
if ENABLE_SASL
|
||
|
|
memcached_SOURCES += sasl_defs.c
|
||
|
|
endif
|
||
|
|
diff -Nurp memcached-1.5.10/memcached.c memcached-1.5.10-old/memcached.c
|
||
|
|
--- memcached-1.5.10/memcached.c 2018-08-10 16:36:38.000000000 -0400
|
||
|
|
+++ memcached-1.5.10-old/memcached.c 2019-05-31 04:48:48.677000000 -0400
|
||
|
|
@@ -55,6 +55,10 @@
|
||
|
|
#include <getopt.h>
|
||
|
|
#endif
|
||
|
|
|
||
|
|
+#if defined(__FreeBSD__)
|
||
|
|
+#include <sys/sysctl.h>
|
||
|
|
+#endif
|
||
|
|
+
|
||
|
|
/* FreeBSD 4.x doesn't have IOV_MAX exposed. */
|
||
|
|
#ifndef IOV_MAX
|
||
|
|
#if defined(__FreeBSD__) || defined(__APPLE__) || defined(__GNU__)
|
||
|
|
@@ -2599,6 +2603,7 @@ static void process_bin_flush(conn *c) {
|
||
|
|
|
||
|
|
static void process_bin_delete(conn *c) {
|
||
|
|
item *it;
|
||
|
|
+ uint32_t hv;
|
||
|
|
|
||
|
|
protocol_binary_request_delete* req = binary_get_request(c);
|
||
|
|
|
||
|
|
@@ -2620,7 +2625,7 @@ static void process_bin_delete(conn *c)
|
||
|
|
stats_prefix_record_delete(key, nkey);
|
||
|
|
}
|
||
|
|
|
||
|
|
- it = item_get(key, nkey, c, DONT_UPDATE);
|
||
|
|
+ it = item_get_locked(key, nkey, c, DONT_UPDATE, &hv);
|
||
|
|
if (it) {
|
||
|
|
uint64_t cas = ntohll(req->message.header.request.cas);
|
||
|
|
if (cas == 0 || cas == ITEM_get_cas(it)) {
|
||
|
|
@@ -2628,19 +2633,20 @@ static void process_bin_delete(conn *c)
|
||
|
|
pthread_mutex_lock(&c->thread->stats.mutex);
|
||
|
|
c->thread->stats.slab_stats[ITEM_clsid(it)].delete_hits++;
|
||
|
|
pthread_mutex_unlock(&c->thread->stats.mutex);
|
||
|
|
- item_unlink(it);
|
||
|
|
+ do_item_unlink(it, hv);
|
||
|
|
STORAGE_delete(c->thread->storage, it);
|
||
|
|
write_bin_response(c, NULL, 0, 0, 0);
|
||
|
|
} else {
|
||
|
|
write_bin_error(c, PROTOCOL_BINARY_RESPONSE_KEY_EEXISTS, NULL, 0);
|
||
|
|
}
|
||
|
|
- item_remove(it); /* release our reference */
|
||
|
|
+ do_item_remove(it); /* release our reference */
|
||
|
|
} else {
|
||
|
|
write_bin_error(c, PROTOCOL_BINARY_RESPONSE_KEY_ENOENT, NULL, 0);
|
||
|
|
pthread_mutex_lock(&c->thread->stats.mutex);
|
||
|
|
c->thread->stats.delete_misses++;
|
||
|
|
pthread_mutex_unlock(&c->thread->stats.mutex);
|
||
|
|
}
|
||
|
|
+ item_unlock(hv);
|
||
|
|
}
|
||
|
|
|
||
|
|
static void complete_nread_binary(conn *c) {
|
||
|
|
@@ -4323,6 +4329,7 @@ static void process_delete_command(conn
|
||
|
|
char *key;
|
||
|
|
size_t nkey;
|
||
|
|
item *it;
|
||
|
|
+ uint32_t hv;
|
||
|
|
|
||
|
|
assert(c != NULL);
|
||
|
|
|
||
|
|
@@ -4351,7 +4358,7 @@ static void process_delete_command(conn
|
||
|
|
stats_prefix_record_delete(key, nkey);
|
||
|
|
}
|
||
|
|
|
||
|
|
- it = item_get(key, nkey, c, DONT_UPDATE);
|
||
|
|
+ it = item_get_locked(key, nkey, c, DONT_UPDATE, &hv);
|
||
|
|
if (it) {
|
||
|
|
MEMCACHED_COMMAND_DELETE(c->sfd, ITEM_key(it), it->nkey);
|
||
|
|
|
||
|
|
@@ -4359,9 +4366,9 @@ static void process_delete_command(conn
|
||
|
|
c->thread->stats.slab_stats[ITEM_clsid(it)].delete_hits++;
|
||
|
|
pthread_mutex_unlock(&c->thread->stats.mutex);
|
||
|
|
|
||
|
|
- item_unlink(it);
|
||
|
|
+ do_item_unlink(it, hv);
|
||
|
|
STORAGE_delete(c->thread->storage, it);
|
||
|
|
- item_remove(it); /* release our reference */
|
||
|
|
+ do_item_remove(it); /* release our reference */
|
||
|
|
out_string(c, "DELETED");
|
||
|
|
} else {
|
||
|
|
pthread_mutex_lock(&c->thread->stats.mutex);
|
||
|
|
@@ -4370,6 +4377,7 @@ static void process_delete_command(conn
|
||
|
|
|
||
|
|
out_string(c, "NOT_FOUND");
|
||
|
|
}
|
||
|
|
+ item_unlock(hv);
|
||
|
|
}
|
||
|
|
|
||
|
|
static void process_verbosity_command(conn *c, token_t *tokens, const size_t ntokens) {
|
||
|
|
@@ -4536,7 +4544,7 @@ static void process_lru_command(conn *c,
|
||
|
|
out_string(c, "OK");
|
||
|
|
}
|
||
|
|
}
|
||
|
|
- } else if (strcmp(tokens[1].value, "mode") == 0 && ntokens >= 3 &&
|
||
|
|
+ } else if (strcmp(tokens[1].value, "mode") == 0 && ntokens >= 4 &&
|
||
|
|
settings.lru_maintainer_thread) {
|
||
|
|
if (strcmp(tokens[2].value, "flat") == 0) {
|
||
|
|
settings.lru_segmented = false;
|
||
|
|
@@ -4547,7 +4555,7 @@ static void process_lru_command(conn *c,
|
||
|
|
} else {
|
||
|
|
out_string(c, "ERROR");
|
||
|
|
}
|
||
|
|
- } else if (strcmp(tokens[1].value, "temp_ttl") == 0 && ntokens >= 3 &&
|
||
|
|
+ } else if (strcmp(tokens[1].value, "temp_ttl") == 0 && ntokens >= 4 &&
|
||
|
|
settings.lru_maintainer_thread) {
|
||
|
|
if (!safe_strtol(tokens[2].value, &ttl)) {
|
||
|
|
out_string(c, "ERROR");
|
||
|
|
@@ -6233,7 +6241,7 @@ static void usage(void) {
|
||
|
|
printf("-b, --listen-backlog=<num> set the backlog queue limit (default: 1024)\n");
|
||
|
|
printf("-B, --protocol=<name> protocol - one of ascii, binary, or auto (default)\n");
|
||
|
|
printf("-I, --max-item-size=<num> adjusts max item size\n"
|
||
|
|
- " (default: 1mb, min: 1k, max: 128m)\n");
|
||
|
|
+ " (default: 1mb, min: 1k, max: 1024m)\n");
|
||
|
|
#ifdef ENABLE_SASL
|
||
|
|
printf("-S, --enable-sasl turn on Sasl authentication\n");
|
||
|
|
#endif
|
||
|
|
@@ -6491,6 +6499,21 @@ static int enable_large_pages(void) {
|
||
|
|
return -1;
|
||
|
|
}
|
||
|
|
return 0;
|
||
|
|
+#elif defined(__FreeBSD__)
|
||
|
|
+ int spages;
|
||
|
|
+ size_t spagesl = sizeof(spages);
|
||
|
|
+
|
||
|
|
+ if (sysctlbyname("vm.pmap.pg_ps_enabled", &spages,
|
||
|
|
+ &spagesl, NULL, 0) != 0) {
|
||
|
|
+ fprintf(stderr, "Could not evaluate the presence of superpages features.");
|
||
|
|
+ return -1;
|
||
|
|
+ }
|
||
|
|
+ if (spages != 1) {
|
||
|
|
+ fprintf(stderr, "Superpages support not detected.\n");
|
||
|
|
+ fprintf(stderr, "Will use default page size.\n");
|
||
|
|
+ return -1;
|
||
|
|
+ }
|
||
|
|
+ return 0;
|
||
|
|
#else
|
||
|
|
return -1;
|
||
|
|
#endif
|
||
|
|
@@ -6951,7 +6974,7 @@ int main (int argc, char **argv) {
|
||
|
|
preallocate = true;
|
||
|
|
} else {
|
||
|
|
fprintf(stderr, "Cannot enable large pages on this system\n"
|
||
|
|
- "(There is no Linux support as of this version)\n");
|
||
|
|
+ "(There is no support as of this version)\n");
|
||
|
|
return 1;
|
||
|
|
}
|
||
|
|
break;
|
||
|
|
@@ -7247,6 +7270,10 @@ int main (int argc, char **argv) {
|
||
|
|
break;
|
||
|
|
#ifdef EXTSTORE
|
||
|
|
case EXT_PAGE_SIZE:
|
||
|
|
+ if (storage_file) {
|
||
|
|
+ fprintf(stderr, "Must specify ext_page_size before any ext_path arguments\n");
|
||
|
|
+ return 1;
|
||
|
|
+ }
|
||
|
|
if (subopts_value == NULL) {
|
||
|
|
fprintf(stderr, "Missing ext_page_size argument\n");
|
||
|
|
return 1;
|
||
|
|
diff -Nurp memcached-1.5.10/memcached.h memcached-1.5.10-old/memcached.h
|
||
|
|
--- memcached-1.5.10/memcached.h 2018-08-10 16:36:38.000000000 -0400
|
||
|
|
+++ memcached-1.5.10-old/memcached.h 2019-05-31 04:49:17.529000000 -0400
|
||
|
|
@@ -756,6 +756,7 @@ item *item_alloc(char *key, size_t nkey,
|
||
|
|
#define DO_UPDATE true
|
||
|
|
#define DONT_UPDATE false
|
||
|
|
item *item_get(const char *key, const size_t nkey, conn *c, const bool do_update);
|
||
|
|
+item *item_get_locked(const char *key, const size_t nkey, conn *c, const bool do_update, uint32_t *hv);
|
||
|
|
item *item_touch(const char *key, const size_t nkey, uint32_t exptime, conn *c);
|
||
|
|
int item_link(item *it);
|
||
|
|
void item_remove(item *it);
|
||
|
|
diff -Nurp memcached-1.5.10/scripts/memcached-tool memcached-1.5.10-old/scripts/memcached-tool
|
||
|
|
--- memcached-1.5.10/scripts/memcached-tool 2018-07-18 16:39:52.000000000 -0400
|
||
|
|
+++ memcached-1.5.10-old/scripts/memcached-tool 2019-05-31 05:40:26.276000000 -0400
|
||
|
|
@@ -98,13 +98,13 @@ if ($mode eq 'dump') {
|
||
|
|
# return format looks like this
|
||
|
|
# key=foo exp=2147483647 la=1521046038 cas=717111 fetch=no cls=13 size=1232
|
||
|
|
if (/^key=(\S+) exp=(-?\d+) .*/) {
|
||
|
|
- my $k = $1;
|
||
|
|
+ my ($k, $exp) = ($1, $2);
|
||
|
|
$k =~ s/%(.{2})/chr hex $1/eg;
|
||
|
|
|
||
|
|
- if ($2 == -1) {
|
||
|
|
+ if ($exp == -1) {
|
||
|
|
$keyexp{$k} = 0;
|
||
|
|
} else {
|
||
|
|
- $keyexp{$k} = $2;
|
||
|
|
+ $keyexp{$k} = $exp;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
$keycount++;
|
||
|
|
diff -Nurp memcached-1.5.10/thread.c memcached-1.5.10-old/thread.c
|
||
|
|
--- memcached-1.5.10/thread.c 2018-08-10 16:36:38.000000000 -0400
|
||
|
|
+++ memcached-1.5.10-old/thread.c 2019-05-31 05:42:46.727000000 -0400
|
||
|
|
@@ -566,6 +566,17 @@ item *item_get(const char *key, const si
|
||
|
|
return it;
|
||
|
|
}
|
||
|
|
|
||
|
|
+// returns an item with the item lock held.
|
||
|
|
+// lock will still be held even if return is NULL, allowing caller to replace
|
||
|
|
+// an item atomically if desired.
|
||
|
|
+item *item_get_locked(const char *key, const size_t nkey, conn *c, const bool do_update, uint32_t *hv) {
|
||
|
|
+ item *it;
|
||
|
|
+ *hv = hash(key, nkey);
|
||
|
|
+ item_lock(*hv);
|
||
|
|
+ it = do_item_get(key, nkey, *hv, c, do_update);
|
||
|
|
+ return it;
|
||
|
|
+}
|
||
|
|
+
|
||
|
|
item *item_touch(const char *key, size_t nkey, uint32_t exptime, conn *c) {
|
||
|
|
item *it;
|
||
|
|
uint32_t hv;
|
||
|
|
|