summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMadelyn Olson <matolson@amazon.com>2019-10-30 00:11:17 -0700
committerMadelyn Olson <matolson@amazon.com>2019-12-16 23:34:37 -0800
commit576a08908b0fcf85a01803507238c4cc14bd85d1 (patch)
treee2642852135bf6305c17bc3e45a5aaf32e8e456d
parent44aa22c63553d6be2879c51161feb50c1b31eab8 (diff)
downloadredis-576a08908b0fcf85a01803507238c4cc14bd85d1.tar.gz
Split error message so dependandent callers give a useful result
-rw-r--r--src/cluster.c23
-rw-r--r--src/cluster.h1
-rw-r--r--src/module.c5
-rw-r--r--src/scripting.c10
4 files changed, 27 insertions, 12 deletions
diff --git a/src/cluster.c b/src/cluster.c
index 4024035e9..a18543e0b 100644
--- a/src/cluster.c
+++ b/src/cluster.c
@@ -5476,8 +5476,8 @@ void readwriteCommand(client *c) {
* already "down" but it is fragile to rely on the update of the global state,
* so we also handle it here.
*
- * CLUSTER_REDIR_DOWN_STATE if the cluster is down but the user attempts to
- * execute a command that addresses one or more keys. */
+ * CLUSTER_REDIR_DOWN_STATE and CLUSTER_REDIR_DOWN_RO_STATE if the cluster is
+ * down but the user attempts to execute a command that addresses one or more keys. */
clusterNode *getNodeByQuery(client *c, struct redisCommand *cmd, robj **argv, int argc, int *hashslot, int *error_code) {
clusterNode *n = NULL;
robj *firstkey = NULL;
@@ -5597,12 +5597,17 @@ clusterNode *getNodeByQuery(client *c, struct redisCommand *cmd, robj **argv, in
/* Cluster is globally down but we got keys? We only serve the request
* if it is a read command and when allow_reads_when_down is enabled. */
- if ((server.cluster->state != CLUSTER_OK) &&
- !(server.cluster_allow_reads_when_down && ((cmd->flags & CMD_READONLY)
- || (cmd->proc == evalCommand) || (cmd->proc == evalShaCommand))))
- {
- if (error_code) *error_code = CLUSTER_REDIR_DOWN_STATE;
- return NULL;
+ if (server.cluster->state != CLUSTER_OK) {
+ if (!server.cluster_allow_reads_when_down) {
+ if (error_code) *error_code = CLUSTER_REDIR_DOWN_STATE;
+ return NULL;
+ }
+
+ if (!(cmd->flags & CMD_READONLY) && !(cmd->proc == evalCommand)
+ && !(cmd->proc == evalShaCommand)) {
+ if (error_code) *error_code = CLUSTER_REDIR_DOWN_RO_STATE;
+ return NULL;
+ }
}
/* Return the hashslot by reference. */
@@ -5671,6 +5676,8 @@ void clusterRedirectClient(client *c, clusterNode *n, int hashslot, int error_co
addReplySds(c,sdsnew("-TRYAGAIN Multiple keys request during rehashing of slot\r\n"));
} else if (error_code == CLUSTER_REDIR_DOWN_STATE) {
addReplySds(c,sdsnew("-CLUSTERDOWN The cluster is down\r\n"));
+ } else if (error_code == CLUSTER_REDIR_DOWN_RO_STATE) {
+ addReplySds(c,sdsnew("-CLUSTERDOWN The cluster is down and only accepts read commands\r\n"));
} else if (error_code == CLUSTER_REDIR_DOWN_UNBOUND) {
addReplySds(c,sdsnew("-CLUSTERDOWN Hash slot not served\r\n"));
} else if (error_code == CLUSTER_REDIR_MOVED ||
diff --git a/src/cluster.h b/src/cluster.h
index 3ba60df6e..35fc0cbfa 100644
--- a/src/cluster.h
+++ b/src/cluster.h
@@ -29,6 +29,7 @@
#define CLUSTER_REDIR_MOVED 4 /* -MOVED redirection required. */
#define CLUSTER_REDIR_DOWN_STATE 5 /* -CLUSTERDOWN, global state. */
#define CLUSTER_REDIR_DOWN_UNBOUND 6 /* -CLUSTERDOWN, unbound slot. */
+#define CLUSTER_REDIR_DOWN_RO_STATE 7 /* -CLUSTERDOWN, allow reads. */
struct clusterNode;
diff --git a/src/module.c b/src/module.c
index 31d337b14..a4e7cbe2c 100644
--- a/src/module.c
+++ b/src/module.c
@@ -3176,6 +3176,7 @@ fmterr:
* EPERM: operation in Cluster instance with key in non local slot.
* EROFS: operation in Cluster instance when a write command is sent
* in a readonly state.
+ * ENETDOWN: operation in Cluster instance when cluster is down.
*
* This API is documented here: https://redis.io/topics/modules-intro
*/
@@ -3240,8 +3241,10 @@ RedisModuleCallReply *RM_Call(RedisModuleCtx *ctx, const char *cmdname, const ch
if (getNodeByQuery(c,c->cmd,c->argv,c->argc,NULL,&error_code) !=
server.cluster->myself)
{
- if (error_code == CLUSTER_REDIR_DOWN_STATE) {
+ if (error_code == CLUSTER_REDIR_DOWN_RO_STATE) {
errno = EROFS;
+ } else if (error_code == CLUSTER_REDIR_DOWN_STATE) {
+ errno = ENETDOWN;
} else {
errno = EPERM;
}
diff --git a/src/scripting.c b/src/scripting.c
index c627207d5..96eb9681d 100644
--- a/src/scripting.c
+++ b/src/scripting.c
@@ -686,11 +686,15 @@ int luaRedisGenericCommand(lua_State *lua, int raise_error) {
if (getNodeByQuery(c,c->cmd,c->argv,c->argc,NULL,&error_code) !=
server.cluster->myself)
{
- if (error_code == CLUSTER_REDIR_DOWN_STATE) {
+ if (error_code == CLUSTER_REDIR_DOWN_RO_STATE) {
luaPushError(lua,
- "Lua script attempted execute a write command while "
+ "Lua script attempted to execute a write command while the"
+ "cluster is down and readonly");
+ } else if (error_code == CLUSTER_REDIR_DOWN_STATE) {
+ luaPushError(lua,
+ "Lua script attempted to execute a command while the"
"cluster is down");
- } else {
+ } else {}
luaPushError(lua,
"Lua script attempted to access a non local key in a "
"cluster node");