Unverified Commit 65ef543f authored by Wen Hui's avatar Wen Hui Committed by GitHub
Browse files

Sentinel: return an error if configuration save fails (#10151)



When performing `SENTINEL SET`, Sentinel updates the local configuration file. Before this commit, failure to update the file would still result with an `+OK` reply. Now, a `-ERR Failed to save config file` error will be returned.
Co-authored-by: default avatarYossi Gottlieb <yossigo@gmail.com>
parent 53c43fcc
...@@ -2281,6 +2281,16 @@ werr: ...@@ -2281,6 +2281,16 @@ werr:
return C_ERR; return C_ERR;
} }
/* Call sentinelFlushConfig() produce a success/error reply to the
* calling client.
*/
static void sentinelFlushConfigAndReply(client *c) {
if (sentinelFlushConfig() == C_ERR)
addReplyErrorFormat(c,"Failed to save config file");
else
addReply(c, shared.ok);
}
/* ====================== hiredis connection handling ======================= */ /* ====================== hiredis connection handling ======================= */
/* Send the AUTH command with the specified master password if needed. /* Send the AUTH command with the specified master password if needed.
...@@ -3174,8 +3184,7 @@ void sentinelConfigSetCommand(client *c) { ...@@ -3174,8 +3184,7 @@ void sentinelConfigSetCommand(client *c) {
return; return;
} }
sentinelFlushConfig(); sentinelFlushConfigAndReply(c);
addReply(c, shared.ok);
/* Drop Sentinel connections to initiate a reconnect if needed. */ /* Drop Sentinel connections to initiate a reconnect if needed. */
if (drop_conns) if (drop_conns)
...@@ -3929,14 +3938,12 @@ NULL ...@@ -3929,14 +3938,12 @@ NULL
if (ri == NULL) { if (ri == NULL) {
addReplyError(c,sentinelCheckCreateInstanceErrors(SRI_MASTER)); addReplyError(c,sentinelCheckCreateInstanceErrors(SRI_MASTER));
} else { } else {
sentinelFlushConfig(); sentinelFlushConfigAndReply(c);
sentinelEvent(LL_WARNING,"+monitor",ri,"%@ quorum %d",ri->quorum); sentinelEvent(LL_WARNING,"+monitor",ri,"%@ quorum %d",ri->quorum);
addReply(c,shared.ok);
} }
} else if (!strcasecmp(c->argv[1]->ptr,"flushconfig")) { } else if (!strcasecmp(c->argv[1]->ptr,"flushconfig")) {
if (c->argc != 2) goto numargserr; if (c->argc != 2) goto numargserr;
sentinelFlushConfig(); sentinelFlushConfigAndReply(c);
addReply(c,shared.ok);
return; return;
} else if (!strcasecmp(c->argv[1]->ptr,"remove")) { } else if (!strcasecmp(c->argv[1]->ptr,"remove")) {
/* SENTINEL REMOVE <name> */ /* SENTINEL REMOVE <name> */
...@@ -3947,8 +3954,7 @@ NULL ...@@ -3947,8 +3954,7 @@ NULL
== NULL) return; == NULL) return;
sentinelEvent(LL_WARNING,"-monitor",ri,"%@"); sentinelEvent(LL_WARNING,"-monitor",ri,"%@");
dictDelete(sentinel.masters,c->argv[2]->ptr); dictDelete(sentinel.masters,c->argv[2]->ptr);
sentinelFlushConfig(); sentinelFlushConfigAndReply(c);
addReply(c,shared.ok);
} else if (!strcasecmp(c->argv[1]->ptr,"ckquorum")) { } else if (!strcasecmp(c->argv[1]->ptr,"ckquorum")) {
/* SENTINEL CKQUORUM <name> */ /* SENTINEL CKQUORUM <name> */
sentinelRedisInstance *ri; sentinelRedisInstance *ri;
...@@ -4348,22 +4354,16 @@ void sentinelSetCommand(client *c) { ...@@ -4348,22 +4354,16 @@ void sentinelSetCommand(client *c) {
break; break;
} }
} }
if (changes && sentinelFlushConfig() == C_ERR) { if (changes) sentinelFlushConfigAndReply(c);
addReplyErrorFormat(c,"Failed to save Sentinel new configuration on disk");
return;
}
addReply(c,shared.ok);
return; return;
badfmt: /* Bad format errors */ badfmt: /* Bad format errors */
addReplyErrorFormat(c,"Invalid argument '%s' for SENTINEL SET '%s'", addReplyErrorFormat(c,"Invalid argument '%s' for SENTINEL SET '%s'",
(char*)c->argv[badarg]->ptr,option); (char*)c->argv[badarg]->ptr,option);
seterr: seterr:
if (changes && sentinelFlushConfig() == C_ERR) { /* TODO: Handle the case of both bad input and save error, possibly handling
addReplyErrorFormat(c,"Failed to save Sentinel new configuration on disk"); * SENTINEL SET atomically. */
return; if (changes) sentinelFlushConfig();
}
return;
} }
/* Our fake PUBLISH command: it is actually useful only to receive hello messages /* Our fake PUBLISH command: it is actually useful only to receive hello messages
......
...@@ -44,5 +44,17 @@ test "Sentinel Set with other error situations" { ...@@ -44,5 +44,17 @@ test "Sentinel Set with other error situations" {
# unknown parameter option # unknown parameter option
assert_error "ERR Unknown option or number of arguments for SENTINEL SET 'fakeoption'" {S 0 SENTINEL SET mymaster fakeoption fakevalue} assert_error "ERR Unknown option or number of arguments for SENTINEL SET 'fakeoption'" {S 0 SENTINEL SET mymaster fakeoption fakevalue}
# save new config to disk failed
set info [S 0 SENTINEL master mymaster]
set origin_quorum [dict get $info quorum]
set update_quorum [expr $origin_quorum+1]
set sentinel_id 0
set configfilename [file join "sentinel_$sentinel_id" "sentinel.conf"]
exec chmod 000 $configfilename
catch {[S 0 SENTINEL SET mymaster quorum $update_quorum]} err
exec chmod 644 $configfilename
assert_equal "ERR Failed to save config file" $err
} }
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