summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorantirez <antirez@gmail.com>2019-09-27 11:39:40 +0200
committerantirez <antirez@gmail.com>2019-09-27 11:39:45 +0200
commitae3ef964c1f75999499c2d35f7485aea1c0a70b1 (patch)
tree4ee6f0d5fcf59c351d2c93e8babf216de7b46ad2
parentb7c33af4a56ccc00b90318a91d3676d3c789a723 (diff)
downloadredis-ae3ef964c1f75999499c2d35f7485aea1c0a70b1.tar.gz
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 <wait.h> that is not standard.
-rw-r--r--src/module.c2
-rw-r--r--src/server.c14
-rw-r--r--src/server.h8
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 <dlfcn.h>
-#include <wait.h>
+#include <sys/wait.h>
#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. */