summaryrefslogtreecommitdiff
path: root/src/script.c
diff options
context:
space:
mode:
authorOran Agra <oran@redislabs.com>2022-02-28 15:35:46 +0200
committerGitHub <noreply@github.com>2022-02-28 15:35:46 +0200
commitd2b5a579dd8b785690aa7714df8776ffc452d242 (patch)
tree1c54c71bae68eaa44efbf89020d75399a88dee40 /src/script.c
parentd5915a167f696644e210ee85e549c7ceb41b5791 (diff)
parent10dc57ab226155bbdbfb0b0d914e681aa346d7de (diff)
downloadredis-7.0-rc2.tar.gz
Merge pull request #10355 from oranagra/release-7.0-rc27.0-rc2
Release 7.0 RC2
Diffstat (limited to 'src/script.c')
-rw-r--r--src/script.c47
1 files changed, 38 insertions, 9 deletions
diff --git a/src/script.c b/src/script.c
index 14a64b961..d78d9fd6b 100644
--- a/src/script.c
+++ b/src/script.c
@@ -146,6 +146,7 @@ int scriptPrepareForRun(scriptRunCtx *run_ctx, client *engine_client, client *ca
return C_ERR;
}
+ /* Deny writes if we're unale to persist. */
int deny_write_type = writeCommandsDeniedByDiskError();
if (deny_write_type != DISK_ERROR_TYPE_NONE && server.masterhost == NULL) {
if (deny_write_type == DISK_ERROR_TYPE_RDB)
@@ -164,6 +165,17 @@ int scriptPrepareForRun(scriptRunCtx *run_ctx, client *engine_client, client *ca
addReplyError(caller, "Can not execute a script with write flag using *_ro command.");
return C_ERR;
}
+
+ /* Don't accept write commands if there are not enough good slaves and
+ * user configured the min-slaves-to-write option. */
+ if (server.masterhost == NULL &&
+ server.repl_min_slaves_max_lag &&
+ server.repl_min_slaves_to_write &&
+ server.repl_good_slaves_count < server.repl_min_slaves_to_write)
+ {
+ addReplyErrorObject(caller, shared.noreplicaserr);
+ return C_ERR;
+ }
}
} else {
/* Special handling for backwards compatibility (no shebang eval[sha]) mode */
@@ -359,6 +371,19 @@ static int scriptVerifyWriteCommandAllow(scriptRunCtx *run_ctx, char **err) {
return C_ERR;
}
+ /* Don't accept write commands if there are not enough good slaves and
+ * user configured the min-slaves-to-write option. Note this only reachable
+ * for Eval scripts that didn't declare flags, see the other check in
+ * scriptPrepareForRun */
+ if (server.masterhost == NULL &&
+ server.repl_min_slaves_max_lag &&
+ server.repl_min_slaves_to_write &&
+ server.repl_good_slaves_count < server.repl_min_slaves_to_write)
+ {
+ *err = sdsdup(shared.noreplicaserr->ptr);
+ return C_ERR;
+ }
+
return C_OK;
}
@@ -480,32 +505,31 @@ void scriptCall(scriptRunCtx *run_ctx, robj* *argv, int argc, sds *err) {
argc = c->argc;
struct redisCommand *cmd = lookupCommand(argv, argc);
+ c->cmd = c->lastcmd = c->realcmd = cmd;
if (scriptVerifyCommandArity(cmd, argc, err) != C_OK) {
- return;
+ goto error;
}
- c->cmd = c->lastcmd = cmd;
-
/* There are commands that are not allowed inside scripts. */
if (!server.script_disable_deny_script && (cmd->flags & CMD_NOSCRIPT)) {
*err = sdsnew("This Redis command is not allowed from script");
- return;
+ goto error;
}
if (scriptVerifyAllowStale(c, err) != C_OK) {
- return;
+ goto error;
}
if (scriptVerifyACL(c, err) != C_OK) {
- return;
+ goto error;
}
if (scriptVerifyWriteCommandAllow(run_ctx, err) != C_OK) {
- return;
+ goto error;
}
if (scriptVerifyOOM(run_ctx, err) != C_OK) {
- return;
+ goto error;
}
if (cmd->flags & CMD_WRITE) {
@@ -514,7 +538,7 @@ void scriptCall(scriptRunCtx *run_ctx, robj* *argv, int argc, sds *err) {
}
if (scriptVerifyClusterState(c, run_ctx->original_client, err) != C_OK) {
- return;
+ goto error;
}
int call_flags = CMD_CALL_SLOWLOG | CMD_CALL_STATS;
@@ -526,6 +550,11 @@ void scriptCall(scriptRunCtx *run_ctx, robj* *argv, int argc, sds *err) {
}
call(c, call_flags);
serverAssert((c->flags & CLIENT_BLOCKED) == 0);
+ return;
+
+error:
+ afterErrorReply(c, *err, sdslen(*err), 0);
+ incrCommandStatsOnError(cmd, ERROR_COMMAND_REJECTED);
}
/* Returns the time when the script invocation started */