diff --git a/doc/protocol.txt b/doc/protocol.txt index 55479b7..abe70b2 100644 --- a/doc/protocol.txt +++ b/doc/protocol.txt @@ -1509,23 +1509,6 @@ 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 ac03b93..3010236 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 int stop_main_loop = NOT_STOP; +static bool stop_main_loop = false; 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}; @@ -387,11 +387,7 @@ static void *conn_timeout_thread(void *arg) { char buf[TIMEOUT_MSG_SIZE]; rel_time_t oldest_last_cmd; int sleep_time; - int sleep_slice = max_fds / CONNS_PER_SLICE; - if (sleep_slice == 0) - sleep_slice = CONNS_PER_SLICE; - - useconds_t timeslice = 1000000 / sleep_slice; + useconds_t timeslice = 1000000 / (max_fds / CONNS_PER_SLICE); while(do_run_conn_timeout_thread) { if (settings.verbose > 2) @@ -1009,18 +1005,6 @@ 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. */ @@ -3440,7 +3424,6 @@ 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 @@ -4451,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 = "CLIENT_ERROR bad command line format"; + char *errstr; assert(c != NULL); @@ -6746,9 +6729,7 @@ static void drive_machine(conn *c) { if (settings.maxconns_fast) { STATS_LOCK(); reject = stats_state.curr_conns + stats_state.reserved_fds >= settings.maxconns - 1; - if (reject) { - stats.rejected_conns++; - } + stats.rejected_conns++; STATS_UNLOCK(); } else { reject = false; @@ -6784,7 +6765,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) { @@ -6792,9 +6773,6 @@ static void drive_machine(conn *c) { } SSL_free(ssl); close(sfd); - STATS_LOCK(); - stats.ssl_handshake_errors++; - STATS_UNLOCK(); break; } } @@ -7870,8 +7848,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) { @@ -7880,7 +7858,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 = GRACE_STOP; + stop_main_loop = true; } #ifndef HAVE_SIGIGNORE @@ -9859,20 +9837,16 @@ int main (int argc, char **argv) { } } - 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; - } - + fprintf(stderr, "Gracefully stopping\n"); stop_threads(); - if (memory_file != NULL && stop_main_loop == GRACE_STOP) { + 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) { restart_mmap_close(); } diff --git a/memcached.h b/memcached.h index bc2b395..77f52aa 100644 --- a/memcached.h +++ b/memcached.h @@ -236,12 +236,6 @@ 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) @@ -358,9 +352,6 @@ struct stats { 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 */ }; @@ -814,8 +805,9 @@ 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/restart.c b/restart.c index 9a83d3a..92a7295 100644 --- a/restart.c +++ b/restart.c @@ -148,7 +148,6 @@ 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) { @@ -199,7 +198,6 @@ 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/sasl_defs.c b/sasl_defs.c index 370f947..c60d1bf 100644 --- a/sasl_defs.c +++ b/sasl_defs.c @@ -16,23 +16,6 @@ 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 @@ -105,24 +88,12 @@ 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/scripts/memcached.service b/scripts/memcached.service index a328a9a..88a4b8a 100644 --- a/scripts/memcached.service +++ b/scripts/memcached.service @@ -11,7 +11,6 @@ [Unit] Description=memcached daemon -Before=httpd.service After=network.target [Service] diff --git a/slabs.c b/slabs.c index 21a556d..89a51ed 100644 --- a/slabs.c +++ b/slabs.c @@ -299,10 +299,6 @@ 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; @@ -451,8 +447,6 @@ 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/t/stats.t b/t/stats.t index f1dcd54..028a60a 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)), 73, "expected count of stats values"); + is(scalar(keys(%$stats)), 72, "expected count of stats values"); } else { is(scalar(keys(%$stats)), 71, "expected count of stats values"); } diff --git a/testapp.c b/testapp.c index 5a758b4..b670708 100644 --- a/testapp.c +++ b/testapp.c @@ -322,45 +322,38 @@ 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 *buf; - const char *expected; + char *expected; int keynum; int length; stats_prefix_clear(); - assert(strcmp("END\r\n", (buf = stats_prefix_dump(&length))) == 0); + assert(strcmp("END\r\n", 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, (buf = stats_prefix_dump(&length))) == 0); + assert(strcmp(expected, 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, (buf = stats_prefix_dump(&length))) == 0); + assert(strcmp(expected, 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, (buf = stats_prefix_dump(&length))) == 0); + assert(strcmp(expected, 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, (buf = stats_prefix_dump(&length))) == 0); + assert(strcmp(expected, 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); - 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); + 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); /* Find a key that hashes to the same bucket as "abc" */ bool found_match = false; @@ -374,16 +367,13 @@ static enum test_return test_stats_prefix_dump(void) { } assert(found_match); stats_prefix_record_set(tmp, strlen(tmp)); - 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(); + 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); return TEST_PASS; } diff --git a/thread.c b/thread.c index fb5d6d0..7cba01e 100644 --- a/thread.c +++ b/thread.c @@ -205,7 +205,6 @@ 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++) { @@ -217,8 +216,6 @@ 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"); @@ -227,16 +224,12 @@ void stop_threads(void) { stop_item_crawler_thread(CRAWLER_WAIT); if (settings.verbose > 0) fprintf(stderr, "stopped lru crawler\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"); - } + 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"); logger_stop(); if (settings.verbose > 0) fprintf(stderr, "stopped logger thread\n"); @@ -244,17 +237,6 @@ 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/tls.c b/tls.c index ae1cb4d..c440a7e 100644 --- a/tls.c +++ b/tls.c @@ -94,11 +94,6 @@ 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)) {