Commit da540228 authored by antirez's avatar antirez
Browse files

Whitelist SIGUSR1 to avoid auto-triggering errors.

This commit fixes issue #875 that was caused by the following events:

1) There is an active child doing BGSAVE.
2) flushall is called (or any other condition that makes Redis killing
the saving child process).
3) An error is sensed by Redis as the child exited with an error (killed
by a singal), that stops accepting write commands until a BGSAVE happens
to be executed with success.

Whitelisting SIGUSR1 and making sure Redis always uses this signal in
order to kill its own children fixes the issue.
parent 9e5b7016
...@@ -177,7 +177,7 @@ void stopAppendOnly(void) { ...@@ -177,7 +177,7 @@ void stopAppendOnly(void) {
redisLog(REDIS_NOTICE,"Killing running AOF rewrite child: %ld", redisLog(REDIS_NOTICE,"Killing running AOF rewrite child: %ld",
(long) server.aof_child_pid); (long) server.aof_child_pid);
if (kill(server.aof_child_pid,SIGKILL) != -1) if (kill(server.aof_child_pid,SIGUSR1) != -1)
wait3(&statloc,0,NULL); wait3(&statloc,0,NULL);
/* reset the buffer accumulating changes while the child saves */ /* reset the buffer accumulating changes while the child saves */
aofRewriteBufferReset(); aofRewriteBufferReset();
......
...@@ -219,7 +219,7 @@ void flushallCommand(redisClient *c) { ...@@ -219,7 +219,7 @@ void flushallCommand(redisClient *c) {
server.dirty += emptyDb(); server.dirty += emptyDb();
addReply(c,shared.ok); addReply(c,shared.ok);
if (server.rdb_child_pid != -1) { if (server.rdb_child_pid != -1) {
kill(server.rdb_child_pid,SIGKILL); kill(server.rdb_child_pid,SIGUSR1);
rdbRemoveTempFile(server.rdb_child_pid); rdbRemoveTempFile(server.rdb_child_pid);
} }
if (server.saveparamslen > 0) { if (server.saveparamslen > 0) {
......
...@@ -1194,7 +1194,10 @@ void backgroundSaveDoneHandler(int exitcode, int bysignal) { ...@@ -1194,7 +1194,10 @@ void backgroundSaveDoneHandler(int exitcode, int bysignal) {
redisLog(REDIS_WARNING, redisLog(REDIS_WARNING,
"Background saving terminated by signal %d", bysignal); "Background saving terminated by signal %d", bysignal);
rdbRemoveTempFile(server.rdb_child_pid); rdbRemoveTempFile(server.rdb_child_pid);
server.lastbgsave_status = REDIS_ERR; /* SIGUSR1 is whitelisted, so we have a way to kill a child without
* tirggering an error conditon. */
if (bysignal != SIGUSR1)
server.lastbgsave_status = REDIS_ERR;
} }
server.rdb_child_pid = -1; server.rdb_child_pid = -1;
server.rdb_save_time_last = time(NULL)-server.rdb_save_time_start; server.rdb_save_time_last = time(NULL)-server.rdb_save_time_start;
......
...@@ -1694,7 +1694,7 @@ int prepareForShutdown(int flags) { ...@@ -1694,7 +1694,7 @@ int prepareForShutdown(int flags) {
overwrite the synchronous saving did by SHUTDOWN. */ overwrite the synchronous saving did by SHUTDOWN. */
if (server.rdb_child_pid != -1) { if (server.rdb_child_pid != -1) {
redisLog(REDIS_WARNING,"There is a child saving an .rdb. Killing it!"); redisLog(REDIS_WARNING,"There is a child saving an .rdb. Killing it!");
kill(server.rdb_child_pid,SIGKILL); kill(server.rdb_child_pid,SIGUSR1);
rdbRemoveTempFile(server.rdb_child_pid); rdbRemoveTempFile(server.rdb_child_pid);
} }
if (server.aof_state != REDIS_AOF_OFF) { if (server.aof_state != REDIS_AOF_OFF) {
...@@ -1703,7 +1703,7 @@ int prepareForShutdown(int flags) { ...@@ -1703,7 +1703,7 @@ int prepareForShutdown(int flags) {
if (server.aof_child_pid != -1) { if (server.aof_child_pid != -1) {
redisLog(REDIS_WARNING, redisLog(REDIS_WARNING,
"There is a child rewriting the AOF. Killing it!"); "There is a child rewriting the AOF. Killing it!");
kill(server.aof_child_pid,SIGKILL); kill(server.aof_child_pid,SIGUSR1);
} }
/* Append only file: fsync() the AOF and exit */ /* Append only file: fsync() the AOF and exit */
redisLog(REDIS_NOTICE,"Calling fsync() on the AOF file."); redisLog(REDIS_NOTICE,"Calling fsync() on the AOF file.");
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment