Commit 82e32055 authored by antirez's avatar antirez
Browse files

RDB files now embed a crc64 checksum. Version of RDB bumped to 5.

parent 8491f1d9
#include "redis.h" #include "redis.h"
#include "lzf.h" /* LZF compression library */ #include "lzf.h" /* LZF compression library */
#include "zipmap.h" #include "zipmap.h"
#include "endianconv.h"
#include <math.h> #include <math.h>
#include <sys/types.h> #include <sys/types.h>
...@@ -602,6 +603,7 @@ int rdbSave(char *filename) { ...@@ -602,6 +603,7 @@ int rdbSave(char *filename) {
long long now = mstime(); long long now = mstime();
FILE *fp; FILE *fp;
rio rdb; rio rdb;
uint64_t cksum;
snprintf(tmpfile,256,"temp-%d.rdb", (int) getpid()); snprintf(tmpfile,256,"temp-%d.rdb", (int) getpid());
fp = fopen(tmpfile,"w"); fp = fopen(tmpfile,"w");
...@@ -612,6 +614,7 @@ int rdbSave(char *filename) { ...@@ -612,6 +614,7 @@ int rdbSave(char *filename) {
} }
rioInitWithFile(&rdb,fp); rioInitWithFile(&rdb,fp);
rdb.update_cksum = rioGenericUpdateChecksum;
snprintf(magic,sizeof(magic),"REDIS%04d",REDIS_RDB_VERSION); snprintf(magic,sizeof(magic),"REDIS%04d",REDIS_RDB_VERSION);
if (rdbWriteRaw(&rdb,magic,9) == -1) goto werr; if (rdbWriteRaw(&rdb,magic,9) == -1) goto werr;
...@@ -641,9 +644,16 @@ int rdbSave(char *filename) { ...@@ -641,9 +644,16 @@ int rdbSave(char *filename) {
} }
dictReleaseIterator(di); dictReleaseIterator(di);
} }
di = NULL; /* So that we don't release it again on error. */
/* EOF opcode */ /* EOF opcode */
if (rdbSaveType(&rdb,REDIS_RDB_OPCODE_EOF) == -1) goto werr; if (rdbSaveType(&rdb,REDIS_RDB_OPCODE_EOF) == -1) goto werr;
/* CRC64 checksum */
cksum = rdb.cksum;
memrev64ifbe(&cksum);
rioWrite(&rdb,&cksum,8);
/* Make sure data will not remain on the OS's output buffers */ /* Make sure data will not remain on the OS's output buffers */
fflush(fp); fflush(fp);
fsync(fileno(fp)); fsync(fileno(fp));
...@@ -1016,6 +1026,7 @@ int rdbLoad(char *filename) { ...@@ -1016,6 +1026,7 @@ int rdbLoad(char *filename) {
return REDIS_ERR; return REDIS_ERR;
} }
rioInitWithFile(&rdb,fp); rioInitWithFile(&rdb,fp);
rdb.update_cksum = rioGenericUpdateChecksum;
if (rioRead(&rdb,buf,9) == 0) goto eoferr; if (rioRead(&rdb,buf,9) == 0) goto eoferr;
buf[9] = '\0'; buf[9] = '\0';
if (memcmp(buf,"REDIS",5) != 0) { if (memcmp(buf,"REDIS",5) != 0) {
...@@ -1025,7 +1036,7 @@ int rdbLoad(char *filename) { ...@@ -1025,7 +1036,7 @@ int rdbLoad(char *filename) {
return REDIS_ERR; return REDIS_ERR;
} }
rdbver = atoi(buf+5); rdbver = atoi(buf+5);
if (rdbver < 1 || rdbver > 4) { if (rdbver < 1 || rdbver > 5) {
fclose(fp); fclose(fp);
redisLog(REDIS_WARNING,"Can't handle RDB format version %d",rdbver); redisLog(REDIS_WARNING,"Can't handle RDB format version %d",rdbver);
errno = EINVAL; errno = EINVAL;
...@@ -1096,6 +1107,18 @@ int rdbLoad(char *filename) { ...@@ -1096,6 +1107,18 @@ int rdbLoad(char *filename) {
decrRefCount(key); decrRefCount(key);
} }
/* Verify the checksum if RDB version is >= 5 */
if (rdbver >= 5) {
uint64_t cksum, expected = rdb.cksum;
if (rioRead(&rdb,&cksum,8) == 0) goto eoferr;
memrev64ifbe(&cksum);
if (cksum != expected) {
redisLog(REDIS_WARNING,"Wrong RDB checksum. Aborting now.");
exit(1);
}
}
fclose(fp); fclose(fp);
stopLoading(); stopLoading();
return REDIS_OK; return REDIS_OK;
......
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
/* The current RDB version. When the format changes in a way that is no longer /* The current RDB version. When the format changes in a way that is no longer
* backward compatible this number gets incremented. */ * backward compatible this number gets incremented. */
#define REDIS_RDB_VERSION 4 #define REDIS_RDB_VERSION 5
/* Defines related to the dump file format. To store 32 bits lengths for short /* Defines related to the dump file format. To store 32 bits lengths for short
* keys requires a lot of space, so we check the most significant 2 bits of * keys requires a lot of space, so we check the most significant 2 bits of
......
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