From d11dc0ead16845b07a068d3f2c0efb201a1b743f Mon Sep 17 00:00:00 2001 From: Brian Aker Date: Mon, 17 Sep 2012 01:48:49 -0700 Subject: This adds the "shutdown" command to the server. This allows for better automation (at least,... I find that it makes for better automation). --- memcached.c | 17 +++++++++++++++++ memcached.h | 1 + testapp.c | 27 ++++++++++++++++++++++++++- 3 files changed, 44 insertions(+), 1 deletion(-) diff --git a/memcached.c b/memcached.c index 23b771a..35f6f4d 100644 --- a/memcached.c +++ b/memcached.c @@ -225,6 +225,7 @@ static void settings_init(void) { settings.hashpower_init = 0; settings.slab_reassign = false; settings.slab_automove = 0; + settings.shutdown_command = false; } /* @@ -3329,6 +3330,15 @@ static void process_command(conn *c, char *command) { conn_set_state(c, conn_closing); + } else if (ntokens == 2 && (strcmp(tokens[COMMAND_TOKEN].value, "shutdown") == 0)) { + + if (settings.shutdown_command) { + conn_set_state(c, conn_closing); + raise(SIGINT); + } else { + out_string(c, "ERROR: shutdown not enabled"); + } + } else if (ntokens > 1 && strcmp(tokens[COMMAND_TOKEN].value, "slabs") == 0) { if (ntokens == 5 && strcmp(tokens[COMMAND_TOKEN + 1].value, "reassign") == 0) { int src, dst, rv; @@ -4445,6 +4455,7 @@ static void usage(void) { printf("-p TCP port number to listen on (default: 11211)\n" "-U UDP port number to listen on (default: 11211, 0 is off)\n" "-s UNIX socket path to listen on (disables network support)\n" + "-A enable ascii \"shutdown\" command\n" "-a access mask for UNIX socket, in octal (default: 0700)\n" "-l interface to listen on (default: INADDR_ANY, all addresses)\n" " may be specified as host:port. If you don't specify\n" @@ -4748,6 +4759,7 @@ int main (int argc, char **argv) { /* process arguments */ while (-1 != (c = getopt(argc, argv, "a:" /* access mask for unix socket */ + "A" /* enable admin shutdown commannd */ "p:" /* TCP port number to listen on */ "s:" /* unix socket path to listen on */ "U:" /* UDP port number to listen on */ @@ -4776,6 +4788,11 @@ int main (int argc, char **argv) { "o:" /* Extended generic options */ ))) { switch (c) { + case 'A': + /* enables "shutdown" command */ + settings.shutdown_command = true; + break; + case 'a': /* access for unix domain socket, as octal mask (like chmod)*/ settings.access= strtol(optarg,NULL,8); diff --git a/memcached.h b/memcached.h index 8a51352..91b6502 100644 --- a/memcached.h +++ b/memcached.h @@ -307,6 +307,7 @@ struct settings { bool slab_reassign; /* Whether or not slab reassignment is allowed */ int slab_automove; /* Whether or not to automatically move slabs */ int hashpower_init; /* Starting hash power level */ + bool shutdown_command; /* allow shutdown command */ }; extern struct stats stats; diff --git a/testapp.c b/testapp.c index 9faccf4..bb5304a 100644 --- a/testapp.c +++ b/testapp.c @@ -334,6 +334,7 @@ static pid_t start_server(in_port_t *port_out, bool daemon, int timeout) { argv[arg++] = tmo; } argv[arg++] = "./memcached-debug"; + argv[arg++] = "-A"; argv[arg++] = "-p"; argv[arg++] = "-1"; argv[arg++] = "-U"; @@ -636,7 +637,30 @@ static enum test_return start_memcached_server(void) { static enum test_return stop_memcached_server(void) { close(sock); - assert(kill(server_pid, SIGTERM) == 0); + if (server_pid != -1) { + assert(kill(server_pid, SIGTERM) == 0); + } + + return TEST_PASS; +} + +static enum test_return shutdown_memcached_server(void) { + char buffer[1024]; + + close(sock); + sock = connect_server("127.0.0.1", port, false); + + send_ascii_command("shutdown\r\n"); + /* verify that the server closed the connection */ + assert(read(sock, buffer, sizeof(buffer)) == 0); + + close(sock); + + /* We set server_pid to -1 so that we don't later call kill() */ + if (kill(server_pid, 0) == 0) { + server_pid = -1; + } + return TEST_PASS; } @@ -1905,6 +1929,7 @@ struct testcase testcases[] = { { "binary_stat", test_binary_stat }, { "binary_illegal", test_binary_illegal }, { "binary_pipeline_hickup", test_binary_pipeline_hickup }, + { "shutdown", shutdown_memcached_server }, { "stop_server", stop_memcached_server }, { NULL, NULL } }; -- cgit v1.2.1