Skip to content

Commit

Permalink
'shutdown graceful' command for raising SIGUSR1
Browse files Browse the repository at this point in the history
  • Loading branch information
LINKIWI authored and dormando committed Nov 20, 2020
1 parent 2d118d4 commit 1332f52
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 4 deletions.
6 changes: 6 additions & 0 deletions doc/protocol.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1695,6 +1695,12 @@ be released back to the OS asynchronously.
The argument is in megabytes, not bytes. Input gets multiplied out into
megabytes internally.

"shutdown" is a command with an optional argument used to stop memcached with
a kill signal. By default, "shutdown" alone raises SIGINT, though "graceful"
may be specified as the single argument to instead trigger a graceful shutdown
with SIGUSR1. The shutdown command is disabled by default, and can be enabled
with the -A/--enable-shutdown flag.

"version" is a command with no arguments:

version\r\n
Expand Down
16 changes: 12 additions & 4 deletions proto_text.c
Original file line number Diff line number Diff line change
Expand Up @@ -2348,12 +2348,20 @@ static void process_quit_command(conn *c) {
c->close_after_write = true;
}

static void process_shutdown_command(conn *c) {
if (settings.shutdown_command) {
static void process_shutdown_command(conn *c, token_t *tokens, const size_t ntokens) {
if (!settings.shutdown_command) {
out_string(c, "ERROR: shutdown not enabled");
return;
}

if (ntokens == 2) {
conn_set_state(c, conn_closing);
raise(SIGINT);
} else if (ntokens == 3 && strcmp(tokens[SUBCOMMAND_TOKEN].value, "graceful") == 0) {
conn_set_state(c, conn_closing);
raise(SIGUSR1);
} else {
out_string(c, "ERROR: shutdown not enabled");
out_string(c, "CLIENT_ERROR invalid shutdown mode");
}
}

Expand Down Expand Up @@ -2620,7 +2628,7 @@ static void process_command(conn *c, char *command) {
process_stat(c, tokens, ntokens);
} else if (strcmp(tokens[COMMAND_TOKEN].value, "shutdown") == 0) {

process_shutdown_command(c);
process_shutdown_command(c, tokens, ntokens);
} else if (strcmp(tokens[COMMAND_TOKEN].value, "slabs") == 0) {

process_slabs_command(c, tokens, ntokens);
Expand Down
49 changes: 49 additions & 0 deletions t/shutdown.t
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
#!/usr/bin/perl

use strict;
use warnings;
use Test::More;
use FindBin qw($Bin);
use lib "$Bin/lib";
use MemcachedTest;

# Disabled shutdown (default)
{
my $server = new_memcached();
my $sock = $server->sock;
print $sock "shutdown\r\n";
is(scalar <$sock>, "ERROR: shutdown not enabled\r\n",
"error when shutdown is not enabled");
}

# Shutdown command error
{
my$server = new_memcached("-A");
my $sock = $server->sock;
print $sock "shutdown foo\r\n";
like(scalar <$sock>, qr/CLIENT_ERROR/, "rejected invalid shutdown mode");
}

# Normal shutdown
{
my $server = new_memcached("-A");
my $sock = $server->sock;
print $sock "version\r\n";
like(scalar <$sock>, qr/VERSION/, "server is initially alive");
print $sock "shutdown\r\n";
print $sock "version\r\n";
is(scalar <$sock>, undef, "server has been normally shut down");
}

# Graceful shutdown
{
my $server = new_memcached("-A");
my $sock = $server->sock;
print $sock "version\r\n";
like(scalar <$sock>, qr/VERSION/, "server is initially alive");
print $sock "shutdown graceful\r\n";
print $sock "version\r\n";
is(scalar <$sock>, undef, "server has been gracefully shut down");
}

done_testing();

0 comments on commit 1332f52

Please sign in to comment.