From a2c4706fc7b3f9478adf7eb077d419177e89c62f 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 dbe7bfa6d..236a98c48 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 1a472dbc7..eb27bfa7a 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 49875adb2bb34eee9e064cfc135b6ed1c015551c 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 c7739de8b..be1591c98 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 ======================= */