From ae3ef964c1f75999499c2d35f7485aea1c0a70b1 Mon Sep 17 00:00:00 2001 From: antirez Date: Fri, 27 Sep 2019 11:39:40 +0200 Subject: [PATCH] Modules fork: improve SIGUSR1 handling, fix include. We can't expect SIGUSR1 to have any specific value range, so let's define an exit code that we can handle in a special way. This also fixes an #include that is not standard. --- src/module.c | 2 +- src/server.c | 14 ++++++++++---- src/server.h | 8 ++++++++ 3 files changed, 19 insertions(+), 5 deletions(-) diff --git a/src/module.c b/src/module.c index 854989e73..d3b37a3d8 100644 --- a/src/module.c +++ b/src/module.c @@ -31,7 +31,7 @@ #include "cluster.h" #include "rdb.h" #include -#include +#include #define REDISMODULE_CORE 1 #include "redismodule.h" diff --git a/src/server.c b/src/server.c index f38ed7897..046694e1f 100644 --- a/src/server.c +++ b/src/server.c @@ -1913,8 +1913,11 @@ int serverCron(struct aeEventLoop *eventLoop, long long id, void *clientData) { if (WIFSIGNALED(statloc)) bysignal = WTERMSIG(statloc); /* sigKillChildHandler catches the signal and calls exit(), but we - * must make sure not to flag lastbgsave_status, etc incorrectly. */ - if (exitcode == SIGUSR1) { + * must make sure not to flag lastbgsave_status, etc incorrectly. + * We could directly terminate the child process via SIGUSR1 + * without handling it, but in this case Valgrind will log an + * annoying error. */ + if (exitcode == SERVER_CHILD_NOERROR_RETVAL) { bysignal = SIGUSR1; exitcode = 1; } @@ -4618,11 +4621,14 @@ void setupSignalHandlers(void) { return; } +/* This is the signal handler for children process. It is currently useful + * in order to track the SIGUSR1, that we send to a child in order to terminate + * it in a clean way, without the parent detecting an error and stop + * accepting writes because of a write error condition. */ static void sigKillChildHandler(int sig) { UNUSED(sig); - /* this handler is needed to resolve a valgrind warning */ serverLogFromHandler(LL_WARNING, "Received SIGUSR1 in child, exiting now."); - exitFromChild(SIGUSR1); + exitFromChild(SERVER_CHILD_NOERROR_RETVAL); } void setupChildSignalHandlers(void) { diff --git a/src/server.h b/src/server.h index d132cf09c..c701d6d21 100644 --- a/src/server.h +++ b/src/server.h @@ -179,6 +179,14 @@ typedef long long mstime_t; /* millisecond time type. */ #define ACTIVE_EXPIRE_CYCLE_SLOW 0 #define ACTIVE_EXPIRE_CYCLE_FAST 1 +/* Children process will exit with this status code to signal that the + * process terminated without an error: this is useful in order to kill + * a saving child (RDB or AOF one), without triggering in the parent the + * write protection that is normally turned on on write errors. + * Usually children that are terminated with SIGUSR1 will exit with this + * special code. */ +#define SERVER_CHILD_NOERROR_RETVAL 255 + /* Instantaneous metrics tracking. */ #define STATS_METRIC_SAMPLES 16 /* Number of samples per metric. */ #define STATS_METRIC_COMMAND 0 /* Number of commands executed. */