From b47b343fab3dd11eb983cef0a5d4de65dca2ed51 Mon Sep 17 00:00:00 2001 From: Matt Stancliff Date: Thu, 13 Mar 2014 14:40:25 -0400 Subject: [PATCH 1/2] Fix data loss when save AOF/RDB with no free space Previously, the (!fp) would only catch lack of free space under OS X. Linux waits to discover it can't write until it actually writes contents to disk. (fwrite() returns success even if the underlying file has no free space to write into. All the errors only show up at flush/sync/close time.) Fixes antirez/redis#1604 --- src/aof.c | 6 +++--- src/rdb.c | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/aof.c b/src/aof.c index dbe7bfa6..236a98c4 100644 --- a/src/aof.c +++ b/src/aof.c @@ -969,9 +969,9 @@ int rewriteAppendOnlyFile(char *filename) { } /* Make sure data will not remain on the OS's output buffers */ - fflush(fp); - aof_fsync(fileno(fp)); - fclose(fp); + if (fflush(fp) == EOF) goto werr; + if (aof_fsync(fileno(fp)) == -1) goto werr; + if (fclose(fp) == EOF) goto werr; /* Use RENAME to make sure the DB file is changed atomically only * if the generate DB file is ok. */ diff --git a/src/rdb.c b/src/rdb.c index 1a472dbc..eb27bfa7 100644 --- a/src/rdb.c +++ b/src/rdb.c @@ -690,9 +690,9 @@ int rdbSave(char *filename) { rioWrite(&rdb,&cksum,8); /* Make sure data will not remain on the OS's output buffers */ - fflush(fp); - fsync(fileno(fp)); - fclose(fp); + if (fflush(fp) == EOF) goto werr; + if (fsync(fileno(fp)) == -1) goto werr; + if (fclose(fp) == EOF) goto werr; /* Use RENAME to make sure the DB file is changed atomically only * if the generate DB file is ok. */ From 429045514512b2791a0297f08c7024c389d41981 Mon Sep 17 00:00:00 2001 From: Matt Stancliff Date: Fri, 14 Mar 2014 17:07:52 -0400 Subject: [PATCH 2/2] Sentinel: Notify user when config can't be saved --- src/sentinel.c | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/src/sentinel.c b/src/sentinel.c index c7739de8..be1591c9 100644 --- a/src/sentinel.c +++ b/src/sentinel.c @@ -1562,19 +1562,22 @@ void rewriteConfigSentinelOption(struct rewriteConfigState *state) { void sentinelFlushConfig(void) { int fd; int saved_hz = server.hz; + int rewrite_status; server.hz = REDIS_DEFAULT_HZ; - if (rewriteConfig(server.configfile) != -1) { - /* Rewrite succeded, fsync it. */ - if ((fd = open(server.configfile,O_RDONLY)) != -1) { - fsync(fd); - close(fd); - } - } else { - redisLog(REDIS_WARNING,"WARNING: Sentinel was not able to save the new configuration on disk!!!: %s", strerror(errno)); - } + rewrite_status = rewriteConfig(server.configfile); server.hz = saved_hz; + + if (rewrite_status == -1) goto werr; + if ((fd = open(server.configfile,O_RDONLY)) == -1) goto werr; + if (fsync(fd) == -1) goto werr; + if (close(fd) == EOF) goto werr; + return; + +werr: + if (fd != -1) close(fd); + redisLog(REDIS_WARNING,"WARNING: Sentinel was not able to save the new configuration on disk!!!: %s", strerror(errno)); } /* ====================== hiredis connection handling ======================= */