Unverified Commit 644d9455 authored by Joe Hu's avatar Joe Hu Committed by GitHub
Browse files

Fix RDB check regression caused by PR 12022 (#12051)

The nightly tests showed that the recent PR #12022 caused random failures
in aof.tcl on checking RDB preamble inside an AOF file.

Root cause:
When checking RDB preamble in an AOF file, what's passed into redis_check_rdb is
aof_filename, not aof_filepath. The newly introduced isFifo function does not check return
status of the stat call and hence uses the uninitailized stat_p object.

Fix:
1. Fix isFifo by checking stat call's return code.
2. Pass aof_filepath instead of aof_filename to redis_check_rdb.
3. move the FIFO check to rdb.c since the limitation is the re-opening of the file, and not
  anything specific about redis-check-rdb.
parent e7f18432
......@@ -697,3 +697,9 @@ int anetSetSockMarkId(char *err, int fd, uint32_t id) {
return ANET_OK;
#endif
}
int anetIsFifo(char *filepath) {
struct stat sb;
if (stat(filepath, &sb) == -1) return 0;
return S_ISFIFO(sb.st_mode);
}
......@@ -70,5 +70,6 @@ int anetFormatAddr(char *fmt, size_t fmt_len, char *ip, int port);
int anetPipe(int fds[2], int read_flags, int write_flags);
int anetSetSockMarkId(char *err, int fd, uint32_t id);
int anetGetError(int fd);
int anetIsFifo(char *filepath);
#endif
......@@ -88,6 +88,11 @@ void rdbReportError(int corruption_error, int linenum, char *reason, ...) {
/* If we're loading an rdb file form disk, run rdb check (and exit) */
serverLog(LL_WARNING, "%s", msg);
char *argv[2] = {"",rdbFileBeingLoaded};
if (anetIsFifo(argv[1])) {
/* Cannot check RDB FIFO because we cannot reopen the FIFO and check already streamed data. */
rdbCheckError("Cannot check RDB that is a FIFO: %s", argv[1]);
return;
}
redis_check_rdb_main(2,argv,NULL);
} else if (corruption_error) {
/* In diskless loading, in case of corrupt file, log and exit. */
......
......@@ -242,7 +242,7 @@ int checkSingleAof(char *aof_filename, char *aof_filepath, int last_file, int fi
}
if (preamble) {
char *argv[2] = {NULL, aof_filename};
char *argv[2] = {NULL, aof_filepath};
if (redis_check_rdb_main(2, argv, fp) == C_ERR) {
printf("RDB preamble of AOF file is not sane, aborting.\n");
exit(1);
......
......@@ -186,15 +186,9 @@ void rdbCheckSetupSignals(void) {
sigaction(SIGABRT, &act, NULL);
}
static int isFifo(char *filename) {
struct stat stat_p;
stat(filename, &stat_p);
return S_ISFIFO(stat_p.st_mode);
}
/* Check the specified RDB file. Return 0 if the RDB looks sane, otherwise
* 1 is returned.
* The file is specified as a filename in 'rdbfilename' if 'fp' is not NULL,
* The file is specified as a filename in 'rdbfilename' if 'fp' is NULL,
* otherwise the already open file 'fp' is checked. */
int redis_check_rdb(char *rdbfilename, FILE *fp) {
uint64_t dbid;
......@@ -205,11 +199,6 @@ int redis_check_rdb(char *rdbfilename, FILE *fp) {
static rio rdb; /* Pointed by global struct riostate. */
struct stat sb;
if (isFifo(rdbfilename)) {
/* Cannot check RDB over named pipe because fopen blocks until another process opens the FIFO for writing. */
return 1;
}
int closefile = (fp == NULL);
if (fp == NULL && (fp = fopen(rdbfilename,"r")) == NULL) return 1;
......
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