check for known-slave in sentinel rewrite config (#11775)
Fix the following config file error ``` *** FATAL CONFIG FILE ERROR (Redis 6.2.7) *** Reading the configuration file, at line 152 >>> 'sentinel known-replica XXXX 127.0.0.1 5001' Duplicate hostname and port for replica. ``` that is happening when a user uses the legacy key "known-slave" in the config file and a config rewrite occurs. The config rewrite logic won't replace the old line "sentinel known-slave XXXX 127.0.0.1 5001" and would add a new line with "sentinel known-replica XXXX 127.0.0.1 5001" which results in the error above "Duplicate hostname and port for replica." example: Current sentinal.conf ``` ... sentinel known-slave XXXX 127.0.0.1 5001 sentinel example-random-option X ... ``` after the config rewrite logic runs: ``` .... sentinel known-slave XXXX 127.0.0.1 5001 sentinel example-random-option X # Generated by CONFIG REWRITE sentinel known-replica XXXX 127.0.0.1 5001 ``` This bug only exists in Redis versions >=6.2 because prior to that it was hidden by the effects of this bug https://github.com/redis/redis/issues/5388 that was fixed in https://github.com/redis/redis/pull/8271 and was released in versions >=6.2
This commit is contained in:
parent
e1da724117
commit
74b29985ce
@ -1221,7 +1221,7 @@ struct rewriteConfigState *rewriteConfigReadOldFile(char *path) {
|
||||
*
|
||||
* "line" is either used, or freed, so the caller does not need to free it
|
||||
* in any way. */
|
||||
void rewriteConfigRewriteLine(struct rewriteConfigState *state, const char *option, sds line, int force) {
|
||||
int rewriteConfigRewriteLine(struct rewriteConfigState *state, const char *option, sds line, int force) {
|
||||
sds o = sdsnew(option);
|
||||
list *l = dictFetchValue(state->option_to_line,o);
|
||||
|
||||
@ -1231,7 +1231,7 @@ void rewriteConfigRewriteLine(struct rewriteConfigState *state, const char *opti
|
||||
/* Option not used previously, and we are not forced to use it. */
|
||||
sdsfree(line);
|
||||
sdsfree(o);
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (l) {
|
||||
@ -1254,6 +1254,7 @@ void rewriteConfigRewriteLine(struct rewriteConfigState *state, const char *opti
|
||||
rewriteConfigAppendLine(state,line);
|
||||
}
|
||||
sdsfree(o);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Write the long long 'bytes' value as a string in a way that is parsable
|
||||
|
@ -2176,7 +2176,12 @@ void rewriteConfigSentinelOption(struct rewriteConfigState *state) {
|
||||
line = sdscatprintf(sdsempty(),
|
||||
"sentinel known-replica %s %s %d",
|
||||
master->name, announceSentinelAddr(slave_addr), slave_addr->port);
|
||||
rewriteConfigRewriteLine(state,"sentinel known-replica",line,1);
|
||||
/* try to replace any known-slave option first if found */
|
||||
if (rewriteConfigRewriteLine(state, "sentinel known-slave", sdsdup(line), 0) == 0) {
|
||||
rewriteConfigRewriteLine(state, "sentinel known-replica", line, 1);
|
||||
} else {
|
||||
sdsfree(line);
|
||||
}
|
||||
/* rewriteConfigMarkAsProcessed is handled after the loop */
|
||||
}
|
||||
dictReleaseIterator(di2);
|
||||
|
@ -3171,7 +3171,7 @@ void loadServerConfig(char *filename, char config_from_stdin, char *options);
|
||||
void appendServerSaveParams(time_t seconds, int changes);
|
||||
void resetServerSaveParams(void);
|
||||
struct rewriteConfigState; /* Forward declaration to export API. */
|
||||
void rewriteConfigRewriteLine(struct rewriteConfigState *state, const char *option, sds line, int force);
|
||||
int rewriteConfigRewriteLine(struct rewriteConfigState *state, const char *option, sds line, int force);
|
||||
void rewriteConfigMarkAsProcessed(struct rewriteConfigState *state, const char *option);
|
||||
int rewriteConfig(char *path, int force_write);
|
||||
void initConfigValues();
|
||||
|
Loading…
x
Reference in New Issue
Block a user