From a13a21de44c4addf162092640f4f334c93387be3 Mon Sep 17 00:00:00 2001 From: CentOS Sources Date: Tue, 3 Nov 2020 06:59:00 -0500 Subject: [PATCH] import memcached-1.5.22-2.el8 --- .gitignore | 1 + .memcached.metadata | 1 + SOURCES/memcached-fix-rejconn-counting.patch | 23 + SOURCES/memcached-issue685.patch | 39 ++ SOURCES/memcached-low-conns-segfault.patch | 26 ++ SOURCES/memcached-metaget-errstr-init.patch | 19 + SOURCES/memcached-restart-corrupted.patch | 30 ++ .../memcached-restart-del-items-fail.patch | 13 + SOURCES/memcached-restart-double-free.patch | 26 ++ .../memcached-restart-shutdown-segfault.patch | 97 ++++ SOURCES/memcached-sasl-config.patch | 62 +++ SOURCES/memcached-sig-handler.patch | 84 ++++ SOURCES/memcached-stats.patch | 83 ++++ SOURCES/memcached-test-cache-dump.patch | 94 ++++ SOURCES/memcached-tls-crt-refresh-crash.patch | 25 + SOURCES/memcached-tls-hand-errs.patch | 22 + SOURCES/memcached-unit.patch | 12 + SOURCES/memcached.sysconfig | 5 + SPECS/memcached.spec | 431 ++++++++++++++++++ 19 files changed, 1093 insertions(+) create mode 100644 .gitignore create mode 100644 .memcached.metadata create mode 100644 SOURCES/memcached-fix-rejconn-counting.patch create mode 100644 SOURCES/memcached-issue685.patch create mode 100644 SOURCES/memcached-low-conns-segfault.patch create mode 100644 SOURCES/memcached-metaget-errstr-init.patch create mode 100644 SOURCES/memcached-restart-corrupted.patch create mode 100644 SOURCES/memcached-restart-del-items-fail.patch create mode 100644 SOURCES/memcached-restart-double-free.patch create mode 100644 SOURCES/memcached-restart-shutdown-segfault.patch create mode 100644 SOURCES/memcached-sasl-config.patch create mode 100644 SOURCES/memcached-sig-handler.patch create mode 100644 SOURCES/memcached-stats.patch create mode 100644 SOURCES/memcached-test-cache-dump.patch create mode 100644 SOURCES/memcached-tls-crt-refresh-crash.patch create mode 100644 SOURCES/memcached-tls-hand-errs.patch create mode 100644 SOURCES/memcached-unit.patch create mode 100644 SOURCES/memcached.sysconfig create mode 100644 SPECS/memcached.spec diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..855d624 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +SOURCES/memcached-1.5.22.tar.gz diff --git a/.memcached.metadata b/.memcached.metadata new file mode 100644 index 0000000..2531f40 --- /dev/null +++ b/.memcached.metadata @@ -0,0 +1 @@ +3fe5d3929130e860efcfde18d4d396a29db006b7 SOURCES/memcached-1.5.22.tar.gz diff --git a/SOURCES/memcached-fix-rejconn-counting.patch b/SOURCES/memcached-fix-rejconn-counting.patch new file mode 100644 index 0000000..b7beb8b --- /dev/null +++ b/SOURCES/memcached-fix-rejconn-counting.patch @@ -0,0 +1,23 @@ +commit d5b1c3f5f8abc2f51ed493e5a41826d510f95cbb +Author: dormando +Date: Fri Mar 6 00:36:39 2020 -0800 + + fix: all new connections were counted as rejected + + from an earlier patch from a static analyzer... :( + +diff --git a/memcached.c b/memcached.c +index b560b32..ed3fc7d 100644 +--- a/memcached.c ++++ b/memcached.c +@@ -6668,7 +6668,9 @@ static void drive_machine(conn *c) { + if (settings.maxconns_fast) { + STATS_LOCK(); + reject = stats_state.curr_conns + stats_state.reserved_fds >= settings.maxconns - 1; +- stats.rejected_conns++; ++ if (reject) { ++ stats.rejected_conns++; ++ } + STATS_UNLOCK(); + } else { + reject = false; diff --git a/SOURCES/memcached-issue685.patch b/SOURCES/memcached-issue685.patch new file mode 100644 index 0000000..c637bd7 --- /dev/null +++ b/SOURCES/memcached-issue685.patch @@ -0,0 +1,39 @@ +commit 48c2d30efef24270ea94fa133945b8ecd3a015e3 +Author: Tomas Korbar +Date: Wed May 20 15:28:10 2020 +0200 + + Do not join lru and slab maintainer threads if they do not exist + + If no_modern option was supplied then these threads did not run + but memcached still attempted to join them, which resulted in a + segfault. + + resolve #685 + +diff --git a/thread.c b/thread.c +index f162d26..abbfca1 100644 +--- a/thread.c ++++ b/thread.c +@@ -226,12 +226,16 @@ void stop_threads(void) { + stop_item_crawler_thread(CRAWLER_WAIT); + if (settings.verbose > 0) + fprintf(stderr, "stopped lru crawler\n"); +- stop_lru_maintainer_thread(); +- if (settings.verbose > 0) +- fprintf(stderr, "stopped maintainer\n"); +- stop_slab_maintenance_thread(); +- if (settings.verbose > 0) +- fprintf(stderr, "stopped slab mover\n"); ++ if (settings.lru_maintainer_thread) { ++ stop_lru_maintainer_thread(); ++ if (settings.verbose > 0) ++ fprintf(stderr, "stopped maintainer\n"); ++ } ++ if (settings.slab_reassign) { ++ stop_slab_maintenance_thread(); ++ if (settings.verbose > 0) ++ fprintf(stderr, "stopped slab mover\n"); ++ } + logger_stop(); + if (settings.verbose > 0) + fprintf(stderr, "stopped logger thread\n"); diff --git a/SOURCES/memcached-low-conns-segfault.patch b/SOURCES/memcached-low-conns-segfault.patch new file mode 100644 index 0000000..126451f --- /dev/null +++ b/SOURCES/memcached-low-conns-segfault.patch @@ -0,0 +1,26 @@ +commit dfb7eb468f06dbcb9abca68c0ff3a89eb3bf80de +Author: dormando +Date: Thu Mar 26 12:51:27 2020 -0700 + + fix startup segfault for low conns + idle thread + + < 100 connection limit plus idle_timeout feature caused a fault. Set a + minimum sleep instead. + +diff --git a/memcached.c b/memcached.c +index dd52dd0..6bfa131 100644 +--- a/memcached.c ++++ b/memcached.c +@@ -341,7 +341,11 @@ static void *conn_timeout_thread(void *arg) { + char buf[TIMEOUT_MSG_SIZE]; + rel_time_t oldest_last_cmd; + int sleep_time; +- useconds_t timeslice = 1000000 / (max_fds / CONNS_PER_SLICE); ++ int sleep_slice = max_fds / CONNS_PER_SLICE; ++ if (sleep_slice == 0) ++ sleep_slice = CONNS_PER_SLICE; ++ ++ useconds_t timeslice = 1000000 / sleep_slice; + + while(do_run_conn_timeout_thread) { + if (settings.verbose > 2) diff --git a/SOURCES/memcached-metaget-errstr-init.patch b/SOURCES/memcached-metaget-errstr-init.patch new file mode 100644 index 0000000..3ad8477 --- /dev/null +++ b/SOURCES/memcached-metaget-errstr-init.patch @@ -0,0 +1,19 @@ +commit 7e0270468aa4da5c82826c3c903442b8d6a670c4 +Author: Tomas Korbar +Date: Mon May 18 15:23:12 2020 +0200 + + crash fix: errstr wasn't initialized in metaget + +diff --git a/memcached.c b/memcached.c +index 3010236..2af1738 100644 +--- a/memcached.c ++++ b/memcached.c +@@ -4434,7 +4434,7 @@ static void process_mget_command(conn *c, token_t *tokens, const size_t ntokens) + bool item_created = false; + bool won_token = false; + bool ttl_set = false; +- char *errstr; ++ char *errstr = "CLIENT_ERROR bad command line format"; + + assert(c != NULL); + diff --git a/SOURCES/memcached-restart-corrupted.patch b/SOURCES/memcached-restart-corrupted.patch new file mode 100644 index 0000000..dfa9e63 --- /dev/null +++ b/SOURCES/memcached-restart-corrupted.patch @@ -0,0 +1,30 @@ +commit fa40655b49cc73194acc0e2410930f3e9a8322a7 +Author: dormando +Date: Thu Mar 26 11:59:22 2020 -0700 + + 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. + +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; diff --git a/SOURCES/memcached-restart-del-items-fail.patch b/SOURCES/memcached-restart-del-items-fail.patch new file mode 100644 index 0000000..2174216 --- /dev/null +++ b/SOURCES/memcached-restart-del-items-fail.patch @@ -0,0 +1,13 @@ +diff --git a/slabs.c b/slabs.c +index 047d45a..577304d 100644 +--- a/slabs.c ++++ b/slabs.c +@@ -456,6 +456,8 @@ static void do_slabs_free_chunked(item *it, const size_t size) { + it->prev = 0; + // header object's original classid is stored in chunk. + p = &slabclass[chunk->orig_clsid]; ++ // original class id needs to be set on free memory. ++ it->slabs_clsid = chunk->orig_clsid; + if (chunk->next) { + chunk = chunk->next; + chunk->prev = 0; diff --git a/SOURCES/memcached-restart-double-free.patch b/SOURCES/memcached-restart-double-free.patch new file mode 100644 index 0000000..89d3cd1 --- /dev/null +++ b/SOURCES/memcached-restart-double-free.patch @@ -0,0 +1,26 @@ +commit 0d4901071c74f9c3b63162ef5887a5c5b981f385 +Author: David Carlier +Date: Sat Feb 22 01:24:54 2020 +0000 + + restart: fix potential double free + +diff --git a/restart.c b/restart.c +index 92a7295..9a83d3a 100644 +--- a/restart.c ++++ b/restart.c +@@ -148,6 +148,7 @@ enum restart_get_kv_ret restart_get_kv(void *ctx, char **key, char **val) { + // have to re-assign it into the structure anyway. + if (c->line != NULL) { + free(c->line); ++ c->line = NULL; + } + + if (getline(&line, &len, c->f) != -1) { +@@ -198,6 +199,7 @@ enum restart_get_kv_ret restart_get_kv(void *ctx, char **key, char **val) { + } else { + // FIXME: proper error chain. + fprintf(stderr, "[restart] invalid metadata line:\n\n%s\n", line); ++ free(line); + return RESTART_BADLINE; + } + } else { diff --git a/SOURCES/memcached-restart-shutdown-segfault.patch b/SOURCES/memcached-restart-shutdown-segfault.patch new file mode 100644 index 0000000..255f993 --- /dev/null +++ b/SOURCES/memcached-restart-shutdown-segfault.patch @@ -0,0 +1,97 @@ +commit e360e34b1fd2cd69c3a08bfb7fa4fe75281b942a +Author: Tomas Korbar +Date: Tue May 19 08:42:12 2020 +0200 + + restart: fix rare segfault on shutdown + +diff --git a/memcached.c b/memcached.c +index d769b4a..ac03b93 100644 +--- a/memcached.c ++++ b/memcached.c +@@ -1009,6 +1009,18 @@ static void conn_shrink(conn *c) { + } + } + ++// Since some connections might be off on side threads and some are managed as ++// listeners we need to walk through them all from a central point. ++// Must be called with all worker threads hung or in the process of closing. ++void conn_close_all(void) { ++ int i; ++ for (i = 0; i < max_fds; i++) { ++ if (conns[i] && conns[i]->state != conn_closed) { ++ conn_close(conns[i]); ++ } ++ } ++} ++ + /** + * Convert a state name to a human readable form. + */ +@@ -9860,13 +9872,6 @@ int main (int argc, char **argv) { + } + + stop_threads(); +- int i; +- // FIXME: make a function callable from threads.c +- for (i = 0; i < max_fds; i++) { +- if (conns[i] && conns[i]->state != conn_closed) { +- conn_close(conns[i]); +- } +- } + if (memory_file != NULL && stop_main_loop == GRACE_STOP) { + restart_mmap_close(); + } +diff --git a/memcached.h b/memcached.h +index 6b1fe4a..bc2b395 100644 +--- a/memcached.h ++++ b/memcached.h +@@ -814,9 +814,8 @@ enum delta_result_type add_delta(conn *c, const char *key, + const int64_t delta, char *buf, + uint64_t *cas); + void accept_new_conns(const bool do_accept); +-conn *conn_from_freelist(void); +-bool conn_add_to_freelist(conn *c); + void conn_close_idle(conn *c); ++void conn_close_all(void); + item *item_alloc(char *key, size_t nkey, int flags, rel_time_t exptime, int nbytes); + #define DO_UPDATE true + #define DONT_UPDATE false +diff --git a/thread.c b/thread.c +index 7cba01e..6e19a2e 100644 +--- a/thread.c ++++ b/thread.c +@@ -205,6 +205,7 @@ void stop_threads(void) { + if (settings.verbose > 0) + fprintf(stderr, "asking workers to stop\n"); + buf[0] = 's'; ++ pthread_mutex_lock(&worker_hang_lock); + pthread_mutex_lock(&init_lock); + init_count = 0; + for (i = 0; i < settings.num_threads; i++) { +@@ -216,6 +217,8 @@ void stop_threads(void) { + wait_for_thread_registration(settings.num_threads); + pthread_mutex_unlock(&init_lock); + ++ // All of the workers are hung but haven't done cleanup yet. ++ + if (settings.verbose > 0) + fprintf(stderr, "asking background threads to stop\n"); + +@@ -237,6 +240,17 @@ void stop_threads(void) { + if (settings.verbose > 0) + fprintf(stderr, "stopped idle timeout thread\n"); + ++ // Close all connections then let the workers finally exit. ++ if (settings.verbose > 0) ++ fprintf(stderr, "closing connections\n"); ++ conn_close_all(); ++ pthread_mutex_unlock(&worker_hang_lock); ++ if (settings.verbose > 0) ++ fprintf(stderr, "reaping worker threads\n"); ++ for (i = 0; i < settings.num_threads; i++) { ++ pthread_join(threads[i].thread_id, NULL); ++ } ++ + if (settings.verbose > 0) + fprintf(stderr, "all background threads stopped\n"); + diff --git a/SOURCES/memcached-sasl-config.patch b/SOURCES/memcached-sasl-config.patch new file mode 100644 index 0000000..9d2eb58 --- /dev/null +++ b/SOURCES/memcached-sasl-config.patch @@ -0,0 +1,62 @@ +commit 6207330c2705fdb5f02de13b99a0d994f7c4f14a +Author: Zheng Gu +Date: Fri Nov 22 22:34:16 2019 +0800 + + fix bug where sasl will load config the wrong path + + /etc/sasl2/memcached.conf/memcached.conf instead of + /etc/sasl2/memcached.conf + +diff --git a/sasl_defs.c b/sasl_defs.c +index c60d1bf..370f947 100644 +--- a/sasl_defs.c ++++ b/sasl_defs.c +@@ -16,6 +16,23 @@ const char * const locations[] = { + "/etc/sasl2/memcached.conf", + NULL + }; ++ ++/* If the element of locations is file, locations_dir_path stores the ++ * directory path of these elements */ ++const char *const locations_dir_path[] = { ++ "/etc/sasl", ++ "/etc/sasl2", ++ NULL ++}; ++ ++/* If the element of locations is directory, locations_file_path stores ++ * the actual configue file which used by sasl, when GETCONFPATH is ++ * enabled */ ++const char *const locations_file_path[] = { ++ "/etc/sasl/memcached.conf/memcached.conf", ++ "/etc/sasl2/memcached.conf/memcached.conf", ++ NULL ++}; + #endif + + #ifndef HAVE_SASL_CALLBACK_FT +@@ -88,12 +105,24 @@ static int sasl_getconf(void *context, const char **path) + *path = getenv("SASL_CONF_PATH"); + + if (*path == NULL) { ++#if defined(HAVE_SASL_CB_GETCONF) + for (int i = 0; locations[i] != NULL; ++i) { + if (access(locations[i], F_OK) == 0) { + *path = locations[i]; + break; + } + } ++#elif defined(HAVE_SASL_CB_GETCONFPATH) ++ for (int i = 0; locations[i] != NULL; ++i) { ++ if (access(locations_file_path[i], F_OK) == 0) { ++ *path = locations[i]; ++ break; ++ } else if (access(locations[i], F_OK) == 0) { ++ *path = locations_dir_path[i]; ++ break; ++ } ++ } ++#endif + } + + if (settings.verbose) { diff --git a/SOURCES/memcached-sig-handler.patch b/SOURCES/memcached-sig-handler.patch new file mode 100644 index 0000000..a22cfb6 --- /dev/null +++ b/SOURCES/memcached-sig-handler.patch @@ -0,0 +1,84 @@ +commit 8bbf383316f1bb16e45b05ad6e2ba9def88ba420 +Author: Tomas Korbar +Date: Mon May 18 14:57:39 2020 +0200 + + improve sig_handler function + +diff --git a/memcached.c b/memcached.c +index 3916a8c..2547305 100644 +--- a/memcached.c ++++ b/memcached.c +@@ -189,7 +189,7 @@ static enum transmit_result transmit(conn *c); + * can block the listener via a condition. + */ + static volatile bool allow_new_conns = true; +-static bool stop_main_loop = false; ++static int stop_main_loop = NOT_STOP; + static struct event maxconnsevent; + static void maxconns_handler(const int fd, const short which, void *arg) { + struct timeval t = {.tv_sec = 0, .tv_usec = 10000}; +@@ -7850,8 +7850,8 @@ static void remove_pidfile(const char *pid_file) { + } + + static void sig_handler(const int sig) { ++ stop_main_loop = EXIT_NORMALLY; + printf("Signal handled: %s.\n", strsignal(sig)); +- exit(EXIT_SUCCESS); + } + + static void sighup_handler(const int sig) { +@@ -7860,7 +7860,7 @@ static void sighup_handler(const int sig) { + + static void sig_usrhandler(const int sig) { + printf("Graceful shutdown signal handled: %s.\n", strsignal(sig)); +- stop_main_loop = true; ++ stop_main_loop = GRACE_STOP; + } + + #ifndef HAVE_SIGIGNORE +@@ -9839,7 +9839,18 @@ int main (int argc, char **argv) { + } + } + +- fprintf(stderr, "Gracefully stopping\n"); ++ switch (stop_main_loop) { ++ case GRACE_STOP: ++ fprintf(stderr, "Gracefully stopping\n"); ++ break; ++ case EXIT_NORMALLY: ++ fprintf(stderr, "Exiting normally\n"); ++ break; ++ default: ++ fprintf(stderr, "Exiting on error\n"); ++ break; ++ } ++ + stop_threads(); + int i; + // FIXME: make a function callable from threads.c +@@ -9848,7 +9859,7 @@ int main (int argc, char **argv) { + conn_close(conns[i]); + } + } +- if (memory_file != NULL) { ++ if (memory_file != NULL && stop_main_loop == GRACE_STOP) { + restart_mmap_close(); + } + +diff --git a/memcached.h b/memcached.h +index 77f52aa..795ea8f 100644 +--- a/memcached.h ++++ b/memcached.h +@@ -236,6 +236,12 @@ enum pause_thread_types { + RESUME_WORKER_THREADS + }; + ++enum stop_reasons { ++ NOT_STOP, ++ GRACE_STOP, ++ EXIT_NORMALLY ++}; ++ + #define IS_TCP(x) (x == tcp_transport) + #define IS_UDP(x) (x == udp_transport) + diff --git a/SOURCES/memcached-stats.patch b/SOURCES/memcached-stats.patch new file mode 100644 index 0000000..74e2e7a --- /dev/null +++ b/SOURCES/memcached-stats.patch @@ -0,0 +1,83 @@ +commit 3b78790b2575daf0e8b3c2822a7e160273df20bd +Author: Tomas Korbar +Date: Tue May 19 08:35:29 2020 +0200 + + Include ssl errors in the stats + +diff --git a/doc/protocol.txt b/doc/protocol.txt +index abe70b2..55479b7 100644 +--- a/doc/protocol.txt ++++ b/doc/protocol.txt +@@ -1509,6 +1509,23 @@ The value of the "state" stat may be one of the following: + | | sending back multiple lines of response data). | + |----------------+-----------------------------------------------------------| + ++TLS statistics ++-------------- ++ ++TLS is a compile-time opt-in feature available in versions 1.5.13 and later. ++When compiled with TLS support and TLS termination is enabled at runtime, the ++following additional statistics are available via the "stats" command. ++ ++|--------------------------------+----------+--------------------------------| ++| Name | Type | Meaning | ++|--------------------------------+----------+--------------------------------| ++| ssl_handshake_errors | 64u | Number of times the server has | ++| | | encountered an OpenSSL error | ++| | | during handshake (SSL_accept). | ++| time_since_server_cert_refresh | 32u | Number of seconds that have | ++| | | elapsed since the last time | ++| | | certs were reloaded from disk. | ++|--------------------------------+----------+--------------------------------| + + + Other commands +diff --git a/memcached.c b/memcached.c +index d81a71f..d769b4a 100644 +--- a/memcached.c ++++ b/memcached.c +@@ -3428,6 +3428,7 @@ static void server_stats(ADD_STAT add_stats, conn *c) { + #endif + #ifdef TLS + if (settings.ssl_enabled) { ++ APPEND_STAT("ssl_handshake_errors", "%llu", (unsigned long long)stats.ssl_handshake_errors); + APPEND_STAT("time_since_server_cert_refresh", "%u", now - settings.ssl_last_cert_refresh_time); + } + #endif +@@ -6779,6 +6780,9 @@ static void drive_machine(conn *c) { + } + SSL_free(ssl); + close(sfd); ++ STATS_LOCK(); ++ stats.ssl_handshake_errors++; ++ STATS_UNLOCK(); + break; + } + } +diff --git a/memcached.h b/memcached.h +index 795ea8f..6b1fe4a 100644 +--- a/memcached.h ++++ b/memcached.h +@@ -357,6 +357,9 @@ struct stats { + uint64_t extstore_compact_lost; /* items lost because they were locked */ + uint64_t extstore_compact_rescues; /* items re-written during compaction */ + uint64_t extstore_compact_skipped; /* unhit items skipped during compaction */ ++#endif ++#ifdef TLS ++ uint64_t ssl_handshake_errors; /* TLS failures at accept/handshake time */ + #endif + struct timeval maxconns_entered; /* last time maxconns entered */ + }; +diff --git a/t/stats.t b/t/stats.t +index 028a60a..f1dcd54 100755 +--- a/t/stats.t ++++ b/t/stats.t +@@ -26,7 +26,7 @@ my $stats = mem_stats($sock); + # Test number of keys + if (MemcachedTest::enabled_tls_testing()) { + # when TLS is enabled, stats contains time_since_server_cert_refresh +- is(scalar(keys(%$stats)), 72, "expected count of stats values"); ++ is(scalar(keys(%$stats)), 73, "expected count of stats values"); + } else { + is(scalar(keys(%$stats)), 71, "expected count of stats values"); + } diff --git a/SOURCES/memcached-test-cache-dump.patch b/SOURCES/memcached-test-cache-dump.patch new file mode 100644 index 0000000..357bd10 --- /dev/null +++ b/SOURCES/memcached-test-cache-dump.patch @@ -0,0 +1,94 @@ +commit 026ca5390c4ee5e3674e3c8fcb7e5b4a940e7725 +Author: Tomas Korbar +Date: Thu Jun 4 19:17:57 2020 +0200 + + Update test_stats_prefix_dump + + - the test was failing on big endian architectures + +diff --git a/testapp.c b/testapp.c +index b670708..5a758b4 100644 +--- a/testapp.c ++++ b/testapp.c +@@ -322,38 +322,45 @@ static enum test_return test_stats_prefix_record_set(void) { + static enum test_return test_stats_prefix_dump(void) { + int hashval = hash("abc", 3) % PREFIX_HASH_SIZE; + char tmp[500]; +- char *expected; ++ char *buf; ++ const char *expected; + int keynum; + int length; + + stats_prefix_clear(); + +- assert(strcmp("END\r\n", stats_prefix_dump(&length)) == 0); ++ assert(strcmp("END\r\n", (buf = stats_prefix_dump(&length))) == 0); + assert(5 == length); + stats_prefix_record_set("abc:123", 7); ++ free(buf); + expected = "PREFIX abc get 0 hit 0 set 1 del 0\r\nEND\r\n"; +- assert(strcmp(expected, stats_prefix_dump(&length)) == 0); ++ assert(strcmp(expected, (buf = stats_prefix_dump(&length))) == 0); + assert(strlen(expected) == length); + stats_prefix_record_get("abc:123", 7, false); ++ free(buf); + expected = "PREFIX abc get 1 hit 0 set 1 del 0\r\nEND\r\n"; +- assert(strcmp(expected, stats_prefix_dump(&length)) == 0); ++ assert(strcmp(expected, (buf = stats_prefix_dump(&length))) == 0); + assert(strlen(expected) == length); + stats_prefix_record_get("abc:123", 7, true); ++ free(buf); + expected = "PREFIX abc get 2 hit 1 set 1 del 0\r\nEND\r\n"; +- assert(strcmp(expected, stats_prefix_dump(&length)) == 0); ++ assert(strcmp(expected, (buf = stats_prefix_dump(&length))) == 0); + assert(strlen(expected) == length); + stats_prefix_record_delete("abc:123", 7); ++ free(buf); + expected = "PREFIX abc get 2 hit 1 set 1 del 1\r\nEND\r\n"; +- assert(strcmp(expected, stats_prefix_dump(&length)) == 0); ++ assert(strcmp(expected, (buf = stats_prefix_dump(&length))) == 0); + assert(strlen(expected) == length); + +- /* The order of results might change if we switch hash functions. */ + stats_prefix_record_delete("def:123", 7); +- expected = "PREFIX abc get 2 hit 1 set 1 del 1\r\n" +- "PREFIX def get 0 hit 0 set 0 del 1\r\n" +- "END\r\n"; +- assert(strcmp(expected, stats_prefix_dump(&length)) == 0); +- assert(strlen(expected) == length); ++ free(buf); ++ /* NOTE: Prefixes can be dumped in any order, so we verify that ++ each expected line is present in the string. */ ++ buf = stats_prefix_dump(&length); ++ assert(strstr(buf, "PREFIX abc get 2 hit 1 set 1 del 1\r\n") != NULL); ++ assert(strstr(buf, "PREFIX def get 0 hit 0 set 0 del 1\r\n") != NULL); ++ assert(strstr(buf, "END\r\n") != NULL); ++ free(buf); + + /* Find a key that hashes to the same bucket as "abc" */ + bool found_match = false; +@@ -367,13 +374,16 @@ static enum test_return test_stats_prefix_dump(void) { + } + assert(found_match); + stats_prefix_record_set(tmp, strlen(tmp)); +- snprintf(tmp, sizeof(tmp), +- "PREFIX %d get 0 hit 0 set 1 del 0\r\n" +- "PREFIX abc get 2 hit 1 set 1 del 1\r\n" +- "PREFIX def get 0 hit 0 set 0 del 1\r\n" +- "END\r\n", keynum); +- assert(strcmp(tmp, stats_prefix_dump(&length)) == 0); +- assert(strlen(tmp) == length); ++ buf = stats_prefix_dump(&length); ++ assert(strstr(buf, "PREFIX abc get 2 hit 1 set 1 del 1\r\n") != NULL); ++ assert(strstr(buf, "PREFIX def get 0 hit 0 set 0 del 1\r\n") != NULL); ++ assert(strstr(buf, "END\r\n") != NULL); ++ snprintf(tmp, sizeof(tmp), "PREFIX %d get 0 hit 0 set 1 del 0\r\n", keynum); ++ assert(strstr(buf, tmp) != NULL); ++ free(buf); ++ ++ /* Marking the end of these tests */ ++ stats_prefix_clear(); + + return TEST_PASS; + } diff --git a/SOURCES/memcached-tls-crt-refresh-crash.patch b/SOURCES/memcached-tls-crt-refresh-crash.patch new file mode 100644 index 0000000..e8ec497 --- /dev/null +++ b/SOURCES/memcached-tls-crt-refresh-crash.patch @@ -0,0 +1,25 @@ +commit 79140c7033519cdbcc9d59f08425ddda0a79bff7 +Author: dormando +Date: Mon Mar 23 14:40:34 2020 -0700 + + tls: fix refresh_certs crash when disabled + + segfaults server if refresh_certs command is run with TLS compiled in + but not enabled. + +diff --git a/tls.c b/tls.c +index c440a7e..ae1cb4d 100644 +--- a/tls.c ++++ b/tls.c +@@ -94,6 +94,11 @@ static bool load_server_certificates(char **errmsg) { + *errmsg = NULL; + return false; + } ++ if (settings.ssl_ctx == NULL) { ++ snprintf(error_msg, errmax, "Error TLS not enabled\r\n"); ++ *errmsg = error_msg; ++ return false; ++ } + SSL_LOCK(); + if (!SSL_CTX_use_certificate_chain_file(settings.ssl_ctx, + settings.ssl_chain_cert)) { diff --git a/SOURCES/memcached-tls-hand-errs.patch b/SOURCES/memcached-tls-hand-errs.patch new file mode 100644 index 0000000..75f80a5 --- /dev/null +++ b/SOURCES/memcached-tls-hand-errs.patch @@ -0,0 +1,22 @@ +commit aac7d69207fa08c0114625fbfb35a11d88a0cace +Author: dormando +Date: Mon Mar 16 19:46:12 2020 -0700 + + tls: handle accept errors properly + + 0 return from accept is also an error. pointed out by @tharanga on + review. + +diff --git a/memcached.c b/memcached.c +index be93474..b9ce8b1 100644 +--- a/memcached.c ++++ b/memcached.c +@@ -7021,7 +7021,7 @@ static void drive_machine(conn *c) { + } + SSL_set_fd(ssl, sfd); + int ret = SSL_accept(ssl); +- if (ret < 0) { ++ if (ret <= 0) { + int err = SSL_get_error(ssl, ret); + if (err == SSL_ERROR_SYSCALL || err == SSL_ERROR_SSL) { + if (settings.verbose) { diff --git a/SOURCES/memcached-unit.patch b/SOURCES/memcached-unit.patch new file mode 100644 index 0000000..29a1d0a --- /dev/null +++ b/SOURCES/memcached-unit.patch @@ -0,0 +1,12 @@ +diff --git a/scripts/memcached.service b/scripts/memcached.service +index 88a4b8a..a328a9a 100644 +--- a/scripts/memcached.service ++++ b/scripts/memcached.service +@@ -11,6 +11,7 @@ + + [Unit] + Description=memcached daemon ++Before=httpd.service + After=network.target + + [Service] diff --git a/SOURCES/memcached.sysconfig b/SOURCES/memcached.sysconfig new file mode 100644 index 0000000..d065678 --- /dev/null +++ b/SOURCES/memcached.sysconfig @@ -0,0 +1,5 @@ +PORT="11211" +USER="memcached" +MAXCONN="1024" +CACHESIZE="64" +OPTIONS="-l 127.0.0.1,::1" diff --git a/SPECS/memcached.spec b/SPECS/memcached.spec new file mode 100644 index 0000000..6a6d1e1 --- /dev/null +++ b/SPECS/memcached.spec @@ -0,0 +1,431 @@ +%define username memcached +%define groupname memcached +%bcond_without sasl +%bcond_without tls +%bcond_with seccomp +%bcond_with tests + +Name: memcached +Version: 1.5.22 +Release: 2%{?dist} +Epoch: 0 +Summary: High Performance, Distributed Memory Object Cache + +Group: System Environment/Daemons +License: BSD +URL: https://www.memcached.org/ +Source0: https://www.memcached.org/files/%{name}-%{version}.tar.gz +Source1: memcached.sysconfig + +Patch1: memcached-unit.patch +# patches which fix severe known issues found until version 1.6.6 +Patch2: memcached-restart-corrupted.patch +Patch3: memcached-fix-rejconn-counting.patch +Patch4: memcached-low-conns-segfault.patch +Patch5: memcached-metaget-errstr-init.patch +Patch6: memcached-sasl-config.patch +Patch7: memcached-sig-handler.patch +Patch8: memcached-tls-crt-refresh-crash.patch +Patch9: memcached-tls-hand-errs.patch +Patch10: memcached-stats.patch +Patch11: memcached-restart-shutdown-segfault.patch +Patch12: memcached-restart-del-items-fail.patch +Patch13: memcached-restart-double-free.patch +Patch14: memcached-issue685.patch +Patch15: memcached-test-cache-dump.patch + +BuildRequires: gcc libevent-devel systemd +BuildRequires: perl-generators +BuildRequires: perl(Test::More), perl(Test::Harness) +%{?with_sasl:BuildRequires: cyrus-sasl-devel} +%{?with_seccomp:BuildRequires: libseccomp-devel} +%{?with_tls:BuildRequires: openssl-devel} + +Requires(pre): shadow-utils +%{?systemd_requires} + +%description +memcached is a high-performance, distributed memory object caching +system, generic in nature, but intended for use in speeding up dynamic +web applications by alleviating database load. + +%package devel +Summary: Files needed for development using memcached protocol +Group: Development/Libraries +Requires: %{name} = %{epoch}:%{version}-%{release} + +%description devel +Install memcached-devel if you are developing C/C++ applications that require +access to the memcached binary include files. + +%prep +%autosetup -p1 + +%build +# compile with full RELRO +export CFLAGS="%{optflags} -pie -fpie" +export LDFLAGS="-Wl,-z,relro,-z,now" + +%configure \ + %{?with_sasl: --enable-sasl} \ + %{?with_seccomp: --enable-seccomp} \ + %{?with_tls: --enable-tls} +make %{?_smp_mflags} + +%check +# tests are disabled by default as they are unreliable on build systems +%{!?with_tests: exit 0} + +# whitespace tests fail locally on fedpkg systems now that they use git +rm -f t/whitespace.t + +# Parts of the test suite only succeed as non-root. +if [ `id -u` -ne 0 ]; then + # remove failing test that doesn't work in + # build systems + rm -f t/daemonize.t t/watcher.t t/expirations.t +fi +make test + +%install +make install DESTDIR=%{buildroot} INSTALL="%{__install} -p" +# remove memcached-debug +rm -f %{buildroot}/%{_bindir}/memcached-debug + +# Perl script for monitoring memcached +install -Dp -m0755 scripts/memcached-tool %{buildroot}%{_bindir}/memcached-tool +install -Dp -m0644 scripts/memcached-tool.1 \ + %{buildroot}%{_mandir}/man1/memcached-tool.1 + +# Unit file +install -Dp -m0644 scripts/memcached.service \ + %{buildroot}%{_unitdir}/memcached.service + +# Default configs +install -Dp -m0644 %{SOURCE1} %{buildroot}/%{_sysconfdir}/sysconfig/%{name} + + +%pre +getent group %{groupname} >/dev/null || groupadd -r %{groupname} +getent passwd %{username} >/dev/null || \ +useradd -r -g %{groupname} -d /run/memcached \ + -s /sbin/nologin -c "Memcached daemon" %{username} +exit 0 + + +%post +%systemd_post memcached.service + + +%preun +%systemd_preun memcached.service + + +%postun +%systemd_postun_with_restart memcached.service + + +%files +%doc AUTHORS ChangeLog COPYING NEWS README.md doc/CONTRIBUTORS doc/*.txt +%config(noreplace) %{_sysconfdir}/sysconfig/%{name} +%{_bindir}/memcached-tool +%{_bindir}/memcached +%{_mandir}/man1/memcached-tool.1* +%{_mandir}/man1/memcached.1* +%{_unitdir}/memcached.service + + +%files devel +%{_includedir}/memcached/* + +%changelog +* Thu Jun 04 2020 Tomas Korbar - 0:1.5.22-2 +- Update testing (#1809536) + +* Mon May 18 2020 Tomas Korbar - 0:1.5.22-1 +- Rebase to version 1.5.22 (#1809536) + +* Mon Mar 30 2020 Tomas Korbar - 0:1.5.16-1 +- Rebase to version 1.5.16 (#1809536) + +* Mon Sep 30 2019 Tomas Korbar - 0:1.5.9-3 +- fix null-pointer dereference in "lru mode" and "lru temp_ttl" (#1709408) +- CVE-2019-11596 + +* Fri Feb 08 2019 Miroslav Lichvar - 0:1.5.9-2 +- fix lru-maintainer test (#1671666) + +* Wed Aug 08 2018 Miroslav Lichvar - 0:1.5.9-1 +- update to 1.5.9 (#1613690) + +* Wed Aug 01 2018 Miroslav Lichvar - 0:1.5.7-3 +- disable tests in check stage by default (#1610006) + +* Tue Jul 24 2018 Miroslav Lichvar - 0:1.5.7-2 +- add missing va_end() call (#1602616) +- enable tests in check stage again + +* Thu Mar 29 2018 Miroslav Lichvar - 0:1.5.7-1 +- update to 1.5.7 +- use https URLs in spec + +* Thu Mar 01 2018 Miroslav Lichvar - 0:1.5.6-1 +- update to 1.5.6 (UDP port disabled by default) +- add gcc to build requirements + +* Thu Feb 15 2018 Miroslav Lichvar - 0:1.5.5-2 +- rebuild for new libevent + +* Tue Feb 13 2018 Miroslav Lichvar - 0:1.5.5-1 +- update to 1.5.5 + +* Thu Feb 08 2018 Fedora Release Engineering - 0:1.5.4-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild + +* Tue Jan 30 2018 Miroslav Lichvar - 0:1.5.4-2 +- fix building with new gcc +- use macro for systemd scriptlet dependencies + +* Thu Jan 04 2018 Miroslav Lichvar - 0:1.5.4-1 +- update to 1.5.4 + +* Mon Nov 06 2017 Miroslav Lichvar - 0:1.5.3-1 +- update to 1.5.3 +- add build condition for seccomp support + +* Mon Oct 02 2017 Miroslav Lichvar - 0:1.5.2-1 +- update to 1.5.2 + +* Fri Aug 25 2017 Miroslav Lichvar - 0:1.5.1-1 +- update to 1.5.1 + +* Thu Aug 03 2017 Fedora Release Engineering - 0:1.5.0-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Binutils_Mass_Rebuild + +* Wed Jul 26 2017 Fedora Release Engineering - 0:1.5.0-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Mass_Rebuild + +* Mon Jul 24 2017 Miroslav Lichvar - 0:1.5.0-1 +- update to 1.5.0 + +* Tue Jul 11 2017 Miroslav Lichvar - 0:1.4.39-1 +- update to 1.4.39 (CVE-2017-9951) + +* Tue Jun 27 2017 Miroslav Lichvar - 0:1.4.38-1 +- update to 1.4.38 + +* Fri Jun 09 2017 Miroslav Lichvar - 0:1.4.37-1 +- update to 1.4.37 + +* Wed Mar 22 2017 Miroslav Lichvar - 0:1.4.36-1 +- update to 1.4.36 + +* Mon Feb 27 2017 Miroslav Lichvar - 0:1.4.35-1 +- update to 1.4.35 + +* Wed Feb 15 2017 Joe Orton - 0:1.4.34-3 +- fix gcc 7 format-truncation error (#1423934) + +* Fri Feb 10 2017 Fedora Release Engineering - 0:1.4.34-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_26_Mass_Rebuild + +* Mon Jan 16 2017 Miroslav Lichvar - 0:1.4.34-1 +- update to 1.4.34 + +* Tue Nov 01 2016 Miroslav Lichvar - 0:1.4.33-1 +- update to 1.4.33 (CVE-2016-8704, CVE-2016-8705, CVE-2016-8706) + +* Thu Oct 13 2016 Miroslav Lichvar - 0:1.4.32-1 +- update to 1.4.32 + +* Wed Sep 07 2016 Miroslav Lichvar - 0:1.4.31-1 +- update to 1.4.31 +- disable testing for now + +* Fri Aug 12 2016 Miroslav Lichvar - 0:1.4.30-1 +- update to 1.4.30 + +* Thu Jul 14 2016 Miroslav Lichvar - 0:1.4.29-1 +- update to 1.4.29 + +* Tue Jul 12 2016 Miroslav Lichvar - 0:1.4.28-1 +- update to 1.4.28 +- listen only on loopback interface by default (#1182542) +- use upstream unit file (#1350939) +- remove obsolete macros and scriptlet + +* Tue Jun 21 2016 Miroslav Lichvar - 0:1.4.26-1 +- update to 1.4.26 + +* Tue Feb 23 2016 Miroslav Lichvar - 0:1.4.25-1 +- update to 1.4.25 +- enable SASL support (#815050) +- remove obsolete macros + +* Thu Feb 04 2016 Fedora Release Engineering - 0:1.4.17-5 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_24_Mass_Rebuild + +* Wed Jun 17 2015 Fedora Release Engineering - 0:1.4.17-4 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_23_Mass_Rebuild + +* Sun Aug 17 2014 Fedora Release Engineering - 0:1.4.17-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_22_Mass_Rebuild + +* Sat Jun 07 2014 Fedora Release Engineering - 0:1.4.17-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_Mass_Rebuild + +* Wed Jan 15 2014 Miroslav Lichvar - 0:1.4.17-1 +- update to 1.4.17 +- fix building with -Werror=format-security in CFLAGS + +* Wed Aug 07 2013 Miroslav Lichvar - 0:1.4.15-7 +- buildrequire systemd-units (#992221) +- update memcached man page +- add memcached-tool man page + +* Sat Aug 03 2013 Fedora Release Engineering - 0:1.4.15-6 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_20_Mass_Rebuild + +* Wed Jul 17 2013 Petr Pisar - 0:1.4.15-5 +- Perl 5.18 rebuild + +* Thu Feb 14 2013 Fedora Release Engineering - 0:1.4.15-4 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_19_Mass_Rebuild + +* Thu Dec 20 2012 Miroslav Lichvar - 0:1.4.15-3 +- compile with full RELRO + +* Tue Nov 20 2012 Joe Orton - 0:1.4.15-2 +- BR perl(Test::Harness) + +* Tue Nov 20 2012 Joe Orton - 0:1.4.15-1 +- update to 1.4.15 (#782395) +- switch to simple systemd service (#878198) +- use systemd scriptlet macros (Václav Pavlín, #850204) + +* Fri Jul 20 2012 Fedora Release Engineering - 0:1.4.13-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_18_Mass_Rebuild + +* Fri May 04 2012 Jon Ciesla - 0:1.4.13-2 +- Migrate to systemd, 783112. + +* Tue Feb 7 2012 Paul Lindner - 0:1.4.13-1 +- Upgrade to memcached 1.4.13 +- http://code.google.com/p/memcached/wiki/ReleaseNotes1413 +- http://code.google.com/p/memcached/wiki/ReleaseNotes1412 +- http://code.google.com/p/memcached/wiki/ReleaseNotes1411 + +* Fri Jan 13 2012 Fedora Release Engineering - 0:1.4.10-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_17_Mass_Rebuild + +* Wed Nov 9 2011 Paul Lindner - 0:1.4.10-1 +- Upgrade to memcached 1.4.10 (http://code.google.com/p/memcached/wiki/ReleaseNotes1410) + +* Tue Aug 16 2011 Paul Lindner - 0:1.4.7-1 +- Upgrade to memcached 1.4.7 (http://code.google.com/p/memcached/wiki/ReleaseNotes147) +- Fix some rpmlint errors/warnings. + +* Tue Aug 2 2011 Paul Lindner - 0:1.4.6-1 +- Upgrade to memcached-1.4.6 + +* Wed Feb 16 2011 Joe Orton - 0:1.4.5-7 +- fix build + +* Mon Feb 14 2011 Paul Lindner - 0:1.4.5-6 +- Rebuild for updated libevent + +* Tue Feb 08 2011 Fedora Release Engineering - 0:1.4.5-5 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_15_Mass_Rebuild + +* Sun Nov 28 2010 Paul Lindner - 0:1.4.5-4 +- Add code to deal with /var/run/memcached on tmpfs + +* Wed Sep 8 2010 Paul Lindner - 0:1.4.5-3 +- Apply patch from memcached issue #60, solves Bugzilla 631051 + +* Wed May 26 2010 Joe Orton - 0:1.4.5-2 +- LSB compliance fixes for init script +- don't run the test suite as root +- ensure a constant timestamp on the sysconfig file + +* Sun Apr 4 2010 Paul Lindner - 0:1.4.5-1 +- Upgrade to upstream memcached-1.4.5 (http://code.google.com/p/memcached/wiki/ReleaseNotes145) + +* Wed Jan 20 2010 Paul Lindner - 0:1.4.4-2 +- Remove SELinux policies fixes Bugzilla 557073 + +* Sat Nov 28 2009 Paul Lindner - 0:1.4.4-1 +- Upgraded to upstream memcached-1.4.4 (http://code.google.com/p/memcached/wiki/ReleaseNotes144) +- Add explicit Epoch to fix issue with broken devel dependencies (resolves 542001) + +* Thu Nov 12 2009 Paul Lindner - 1.4.3-1 +- Add explicit require on memcached for memcached-devel (resolves 537046) +- enable-threads option no longer needed +- Update web site address + +* Wed Nov 11 2009 Paul Lindner - 1.4.3-1 +- Upgrade to memcached-1.4.3 + +* Mon Oct 12 2009 Paul Lindner - 1.4.2-1 +- Upgrade to memcached-1.4.2 +- Addresses CVE-2009-2415 + +* Sat Aug 29 2009 Paul Lindner - 1.4.1-1 +- Upgrade to 1.4.1 +- http://code.google.com/p/memcached/wiki/ReleaseNotes141 + +* Wed Apr 29 2009 Paul Lindner - 1.2.8-1 +- Upgrade to memcached-1.2.8 +- Addresses CVE-2009-1255 + +* Wed Feb 25 2009 Fedora Release Engineering - 1.2.6-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_11_Mass_Rebuild + +* Tue Jul 29 2008 Paul Lindner - 1.2.6-1 +- Upgrade to memcached-1.2.6 + +* Tue Mar 4 2008 Paul Lindner - 1.2.5-1 +- Upgrade to memcached-1.2.5 + +* Tue Feb 19 2008 Fedora Release Engineering - 1.2.4-4 +- Autorebuild for GCC 4.3 + +* Sun Jan 27 2008 Paul Lindner - 1.2.4-3 +- Adjust libevent dependencies + +* Sat Dec 22 2007 Paul Lindner - 1.2.4-2 +- Upgrade to memcached-1.2.4 + +* Fri Sep 07 2007 Konstantin Ryabitsev - 1.2.3-8 +- Add selinux policies +- Create our own system user + +* Mon Aug 6 2007 Paul Lindner - 1.2.3-7 +- Fix problem with -P and -d flag combo on x86_64 +- Fix init script for FC-6 + +* Fri Jul 13 2007 Paul Lindner - 1.2.3-4 +- Remove test that fails in fedora build system on ppc64 + +* Sat Jul 7 2007 root - 1.2.3-2 +- Upgrade to 1.2.3 upstream +- Adjust make install to preserve man page timestamp +- Conform with LSB init scripts standards, add force-reload + +* Wed Jul 4 2007 Paul Lindner - 1.2.2-5 +- Use /var/run/memcached/ directory to hold PID file + +* Sat May 12 2007 Paul Lindner - 1.2.2-4 +- Remove tabs from spec file, rpmlint reports no more errors + +* Thu May 10 2007 Paul Lindner - 1.2.2-3 +- Enable build-time regression tests +- add dependency on initscripts +- remove memcached-debug (not needed in dist) +- above suggestions from Bernard Johnson + +* Mon May 7 2007 Paul Lindner - 1.2.2-2 +- Tidyness improvements suggested by Ruben Kerkhof in bugzilla #238994 + +* Fri May 4 2007 Paul Lindner - 1.2.2-1 +- Initial spec file created via rpmdev-newspec