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.
This commit is contained in:
parent
e7f18432b8
commit
644d94558a
@ -697,3 +697,9 @@ int anetSetSockMarkId(char *err, int fd, uint32_t id) {
|
|||||||
return ANET_OK;
|
return ANET_OK;
|
||||||
#endif
|
#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 anetPipe(int fds[2], int read_flags, int write_flags);
|
||||||
int anetSetSockMarkId(char *err, int fd, uint32_t id);
|
int anetSetSockMarkId(char *err, int fd, uint32_t id);
|
||||||
int anetGetError(int fd);
|
int anetGetError(int fd);
|
||||||
|
int anetIsFifo(char *filepath);
|
||||||
|
|
||||||
#endif
|
#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) */
|
/* If we're loading an rdb file form disk, run rdb check (and exit) */
|
||||||
serverLog(LL_WARNING, "%s", msg);
|
serverLog(LL_WARNING, "%s", msg);
|
||||||
char *argv[2] = {"",rdbFileBeingLoaded};
|
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);
|
redis_check_rdb_main(2,argv,NULL);
|
||||||
} else if (corruption_error) {
|
} else if (corruption_error) {
|
||||||
/* In diskless loading, in case of corrupt file, log and exit. */
|
/* 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) {
|
if (preamble) {
|
||||||
char *argv[2] = {NULL, aof_filename};
|
char *argv[2] = {NULL, aof_filepath};
|
||||||
if (redis_check_rdb_main(2, argv, fp) == C_ERR) {
|
if (redis_check_rdb_main(2, argv, fp) == C_ERR) {
|
||||||
printf("RDB preamble of AOF file is not sane, aborting.\n");
|
printf("RDB preamble of AOF file is not sane, aborting.\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
|
@ -186,15 +186,9 @@ void rdbCheckSetupSignals(void) {
|
|||||||
sigaction(SIGABRT, &act, NULL);
|
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
|
/* Check the specified RDB file. Return 0 if the RDB looks sane, otherwise
|
||||||
* 1 is returned.
|
* 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. */
|
* otherwise the already open file 'fp' is checked. */
|
||||||
int redis_check_rdb(char *rdbfilename, FILE *fp) {
|
int redis_check_rdb(char *rdbfilename, FILE *fp) {
|
||||||
uint64_t dbid;
|
uint64_t dbid;
|
||||||
@ -205,11 +199,6 @@ int redis_check_rdb(char *rdbfilename, FILE *fp) {
|
|||||||
static rio rdb; /* Pointed by global struct riostate. */
|
static rio rdb; /* Pointed by global struct riostate. */
|
||||||
struct stat sb;
|
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);
|
int closefile = (fp == NULL);
|
||||||
if (fp == NULL && (fp = fopen(rdbfilename,"r")) == NULL) return 1;
|
if (fp == NULL && (fp = fopen(rdbfilename,"r")) == NULL) return 1;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user