... | ... |
@@ -56,6 +56,7 @@ extern int redis_disable_time_param; |
56 | 56 |
extern int redis_allowed_timeouts_param; |
57 | 57 |
extern int redis_flush_on_reconnect_param; |
58 | 58 |
extern int redis_allow_dynamic_nodes_param; |
59 |
+extern int ndb_redis_debug; |
|
59 | 60 |
|
60 | 61 |
/* backwards compatibility with hiredis < 0.12 */ |
61 | 62 |
#if (HIREDIS_MAJOR == 0) && (HIREDIS_MINOR < 12) |
... | ... |
@@ -198,8 +199,8 @@ int redisc_init(void) |
198 | 199 |
} |
199 | 200 |
} |
200 | 201 |
} |
201 |
- LM_DBG("slave for %s: %s:%d\n", sentinel_group, |
|
202 |
- addr, port); |
|
202 |
+ LOG(ndb_redis_debug, "slave for %s: %s:%d\n", |
|
203 |
+ sentinel_group, addr, port); |
|
203 | 204 |
} |
204 | 205 |
} |
205 | 206 |
} |
... | ... |
@@ -207,15 +208,15 @@ int redisc_init(void) |
207 | 208 |
} |
208 | 209 |
|
209 | 210 |
if(sock != 0) { |
210 |
- LM_DBG("Connecting to unix socket: %s\n", unix_sock_path); |
|
211 |
+ LOG(ndb_redis_debug, "Connecting to unix socket: %s\n", unix_sock_path); |
|
211 | 212 |
rsrv->ctxRedis = redisConnectUnixWithTimeout(unix_sock_path, |
212 | 213 |
tv_conn); |
213 | 214 |
} else { |
214 |
- LM_DBG("Connecting to %s:%d\n", addr, port); |
|
215 |
+ LOG(ndb_redis_debug, "Connecting to %s:%d\n", addr, port); |
|
215 | 216 |
rsrv->ctxRedis = redisConnectWithTimeout(addr, port, tv_conn); |
216 | 217 |
} |
217 | 218 |
|
218 |
- LM_DBG("rsrv->ctxRedis = %p\n", rsrv->ctxRedis); |
|
219 |
+ LOG(ndb_redis_debug, "rsrv->ctxRedis = %p\n", rsrv->ctxRedis); |
|
219 | 220 |
|
220 | 221 |
if(!rsrv->ctxRedis) { |
221 | 222 |
LM_ERR("Failed to create REDIS-Context.\n"); |
... | ... |
@@ -390,18 +391,21 @@ redisc_server_t *redisc_get_server(str *name) |
390 | 391 |
unsigned int hname; |
391 | 392 |
|
392 | 393 |
hname = get_hash1_raw(name->s, name->len); |
393 |
- LM_DBG("Hash %u (%.*s)\n", hname, name->len, name->s); |
|
394 |
+ LOG(ndb_redis_debug, "Hash %u (%.*s)\n", hname, name->len, name->s); |
|
394 | 395 |
rsrv=_redisc_srv_list; |
395 | 396 |
while(rsrv!=NULL) |
396 | 397 |
{ |
397 | 398 |
LM_DBG("Entry %u (%.*s)\n", rsrv->hname, |
398 | 399 |
rsrv->sname->len, rsrv->sname->s); |
399 | 400 |
if(rsrv->hname==hname && rsrv->sname->len==name->len |
400 |
- && strncmp(rsrv->sname->s, name->s, name->len)==0) |
|
401 |
+ && strncmp(rsrv->sname->s, name->s, name->len)==0) { |
|
402 |
+ LOG(ndb_redis_debug, "Using entry %u (%.*s)\n", rsrv->hname, |
|
403 |
+ rsrv->sname->len, rsrv->sname->s); |
|
401 | 404 |
return rsrv; |
405 |
+ } |
|
402 | 406 |
rsrv=rsrv->next; |
403 | 407 |
} |
404 |
- LM_DBG("No entry found.\n"); |
|
408 |
+ LOG(ndb_redis_debug, "No entry found.\n"); |
|
405 | 409 |
return NULL; |
406 | 410 |
} |
407 | 411 |
|
... | ... |
@@ -497,7 +501,7 @@ int redisc_reconnect_server(redisc_server_t *rsrv) |
497 | 501 |
strncpy(addr, res->element[0]->str, |
498 | 502 |
res->element[0]->len + 1); |
499 | 503 |
port = atoi(res->element[1]->str); |
500 |
- LM_DBG("sentinel replied: %s:%d\n", addr, port); |
|
504 |
+ LOG(ndb_redis_debug, "sentinel replied: %s:%d\n", addr, port); |
|
501 | 505 |
} |
502 | 506 |
} |
503 | 507 |
else { |
... | ... |
@@ -520,7 +524,7 @@ int redisc_reconnect_server(redisc_server_t *rsrv) |
520 | 524 |
} |
521 | 525 |
} |
522 | 526 |
} |
523 |
- LM_DBG("slave for %s: %s:%d\n", sentinel_group, |
|
527 |
+ LOG(ndb_redis_debug, "slave for %s: %s:%d\n", sentinel_group, |
|
524 | 528 |
addr, port); |
525 | 529 |
} |
526 | 530 |
} |
... | ... |
@@ -689,7 +693,7 @@ int redisc_create_pipelined_message(redisc_server_t *rsrv) |
689 | 693 |
|
690 | 694 |
if (rsrv->ctxRedis->err) |
691 | 695 |
{ |
692 |
- LM_DBG("Reconnecting server because of error %d: \"%s\"", |
|
696 |
+ LOG(ndb_redis_debug, "Reconnecting server because of error %d: \"%s\"", |
|
693 | 697 |
rsrv->ctxRedis->err,rsrv->ctxRedis->errstr); |
694 | 698 |
if (redisc_reconnect_server(rsrv)) |
695 | 699 |
{ |
... | ... |
@@ -868,10 +872,10 @@ int check_cluster_reply(redisReply *reply, redisc_server_t **rsrv) |
868 | 872 |
name.len = snprintf(buffername, sizeof(buffername), "%.*s:%i", |
869 | 873 |
addr.len, addr.s, port); |
870 | 874 |
name.s = buffername; |
871 |
- LM_DBG("Name of new connection: %.*s\n", name.len, name.s); |
|
875 |
+ LOG(ndb_redis_debug, "Name of new connection: %.*s\n", name.len, name.s); |
|
872 | 876 |
rsrv_new = redisc_get_server(&name); |
873 | 877 |
if(rsrv_new) { |
874 |
- LM_DBG("Reusing Connection\n"); |
|
878 |
+ LOG(ndb_redis_debug, "Reusing connection\n"); |
|
875 | 879 |
*rsrv = rsrv_new; |
876 | 880 |
return 1; |
877 | 881 |
} else if(redis_allow_dynamic_nodes_param) { |
... | ... |
@@ -908,8 +912,8 @@ int check_cluster_reply(redisReply *reply, redisc_server_t **rsrv) |
908 | 912 |
*rsrv = rsrv_new; |
909 | 913 |
/* Need to connect to the new server now */ |
910 | 914 |
if(redisc_reconnect_server(rsrv_new) == 0) { |
911 |
- LM_DBG("Connected to the new server with name: " |
|
912 |
- "%.*s\n", |
|
915 |
+ LOG(ndb_redis_debug, "Connected to the new server" |
|
916 |
+ " with name: %.*s\n", |
|
913 | 917 |
name.len, name.s); |
914 | 918 |
return 1; |
915 | 919 |
} else { |
... | ... |
@@ -1159,13 +1163,14 @@ again: |
1159 | 1163 |
/* null reply, reconnect and try again */ |
1160 | 1164 |
if(rsrv->ctxRedis->err) |
1161 | 1165 |
{ |
1162 |
- LM_DBG("Redis error: %s\n", rsrv->ctxRedis->errstr); |
|
1166 |
+ LOG(ndb_redis_debug, "Redis error: %s\n", rsrv->ctxRedis->errstr); |
|
1163 | 1167 |
} |
1164 | 1168 |
|
1165 | 1169 |
if(res) |
1166 | 1170 |
{ |
1167 | 1171 |
if (check_cluster_reply(res, &rsrv)) { |
1168 | 1172 |
freeReplyObject(res); |
1173 |
+ LOG(ndb_redis_debug, "Retrying the command directly\n"); |
|
1169 | 1174 |
goto again; |
1170 | 1175 |
} |
1171 | 1176 |
return res; |
... | ... |
@@ -1173,10 +1178,12 @@ again: |
1173 | 1178 |
|
1174 | 1179 |
if(redisc_reconnect_server(rsrv)==0) |
1175 | 1180 |
{ |
1181 |
+ LOG(ndb_redis_debug, "Trying to reconnect to server\n"); |
|
1176 | 1182 |
res = redisCommandArgv(rsrv->ctxRedis, argc, argv, argvlen); |
1177 | 1183 |
if (res) { |
1178 | 1184 |
if (check_cluster_reply(res, &rsrv)) { |
1179 | 1185 |
freeReplyObject(res); |
1186 |
+ LOG(ndb_redis_debug, "Retrying the command after reconnect\n"); |
|
1180 | 1187 |
goto again; |
1181 | 1188 |
} |
1182 | 1189 |
} |
... | ... |
@@ -1264,6 +1271,7 @@ int redisc_free_reply(str *name) |
1264 | 1271 |
} |
1265 | 1272 |
|
1266 | 1273 |
/* reply entry not found. */ |
1274 |
+ LOG(ndb_redis_debug, "reply entry not found: %.*s\n", name->len, name->s); |
|
1267 | 1275 |
return -1; |
1268 | 1276 |
} |
1269 | 1277 |
|
... | ... |
@@ -1165,6 +1165,7 @@ again: |
1165 | 1165 |
if(res) |
1166 | 1166 |
{ |
1167 | 1167 |
if (check_cluster_reply(res, &rsrv)) { |
1168 |
+ freeReplyObject(res); |
|
1168 | 1169 |
goto again; |
1169 | 1170 |
} |
1170 | 1171 |
return res; |
... | ... |
@@ -1175,6 +1176,7 @@ again: |
1175 | 1176 |
res = redisCommandArgv(rsrv->ctxRedis, argc, argv, argvlen); |
1176 | 1177 |
if (res) { |
1177 | 1178 |
if (check_cluster_reply(res, &rsrv)) { |
1179 |
+ freeReplyObject(res); |
|
1178 | 1180 |
goto again; |
1179 | 1181 |
} |
1180 | 1182 |
} |
... | ... |
@@ -39,8 +39,10 @@ |
39 | 39 |
|
40 | 40 |
#include "redis_client.h" |
41 | 41 |
|
42 |
-#define redisCommandNR(a...) (int)({ void *__tmp; __tmp = redisCommand(a); \ |
|
43 |
- if (__tmp) freeReplyObject(__tmp); __tmp ? 0 : -1;}) |
|
42 |
+#define redisCommandNR(a...) (int)({ \ |
|
43 |
+ void *__tmp; __tmp = redisCommand(a); \ |
|
44 |
+ if (__tmp) { freeReplyObject(__tmp); }; \ |
|
45 |
+ __tmp ? 0 : -1;}) |
|
44 | 46 |
|
45 | 47 |
static redisc_server_t * _redisc_srv_list=NULL; |
46 | 48 |
|
- Added the check for NULL pointer. When TCP session to redis reset,
redisCommand function can return NULL pointer.
... | ... |
@@ -1269,6 +1269,10 @@ int redisc_check_auth(redisc_server_t *rsrv, char *pass) |
1269 | 1269 |
int retval = 0; |
1270 | 1270 |
|
1271 | 1271 |
reply = redisCommand(rsrv->ctxRedis, "AUTH %s", pass); |
1272 |
+ if(!reply) { |
|
1273 |
+ LM_ERR("Redis authentication error\n"); |
|
1274 |
+ return -1; |
|
1275 |
+ } |
|
1272 | 1276 |
if (reply->type == REDIS_REPLY_ERROR) { |
1273 | 1277 |
LM_ERR("Redis authentication error\n"); |
1274 | 1278 |
retval = -1; |
Reported and provided solution by @kritarthh
follow-up #2461
... | ... |
@@ -1059,6 +1059,11 @@ int redisc_exec(str *srv, str *res, str *cmd, ...) |
1059 | 1059 |
if(redisc_reconnect_server(rsrv)==0) |
1060 | 1060 |
{ |
1061 | 1061 |
rpl->rplRedis = redisvCommand(rsrv->ctxRedis, cmd->s, ap4); |
1062 |
+ if(rpl->rplRedis == NULL) |
|
1063 |
+ { |
|
1064 |
+ redis_count_err_and_disable(rsrv); |
|
1065 |
+ goto error_exec; |
|
1066 |
+ } |
|
1062 | 1067 |
} else { |
1063 | 1068 |
LM_ERR("unable to reconnect to redis server: %.*s\n", |
1064 | 1069 |
srv->len, srv->s); |
* logging error makes no sense here since there's going
to be a reconnection afterwards
... | ... |
@@ -1011,7 +1011,7 @@ int redisc_exec(str *srv, str *res, str *cmd, ...) |
1011 | 1011 |
/* null reply, reconnect and try again */ |
1012 | 1012 |
if(rsrv->ctxRedis->err) |
1013 | 1013 |
{ |
1014 |
- LM_ERR("Redis error: %s\n", rsrv->ctxRedis->errstr); |
|
1014 |
+ LM_DBG("Redis error: %s\n", rsrv->ctxRedis->errstr); |
|
1015 | 1015 |
} |
1016 | 1016 |
if(redisc_reconnect_server(rsrv)==0) |
1017 | 1017 |
{ |
... | ... |
@@ -1054,7 +1054,7 @@ int redisc_exec(str *srv, str *res, str *cmd, ...) |
1054 | 1054 |
/* null reply, reconnect and try again */ |
1055 | 1055 |
if(rsrv->ctxRedis->err) |
1056 | 1056 |
{ |
1057 |
- LM_ERR("Redis error: %s\n", rsrv->ctxRedis->errstr); |
|
1057 |
+ LM_DBG("Redis error: %s\n", rsrv->ctxRedis->errstr); |
|
1058 | 1058 |
} |
1059 | 1059 |
if(redisc_reconnect_server(rsrv)==0) |
1060 | 1060 |
{ |
... | ... |
@@ -1152,7 +1152,7 @@ again: |
1152 | 1152 |
/* null reply, reconnect and try again */ |
1153 | 1153 |
if(rsrv->ctxRedis->err) |
1154 | 1154 |
{ |
1155 |
- LM_ERR("Redis error: %s\n", rsrv->ctxRedis->errstr); |
|
1155 |
+ LM_DBG("Redis error: %s\n", rsrv->ctxRedis->errstr); |
|
1156 | 1156 |
} |
1157 | 1157 |
|
1158 | 1158 |
if(res) |
* logging error makes no sense here since there's going
to be a reconnection afterwards
> ERROR: ndb_redis [redis_client.c:903]: redisc_exec_argv(): Redis error: Server closed the connection
... | ... |
@@ -770,7 +770,7 @@ int redisc_exec_pipelined(redisc_server_t *rsrv) |
770 | 770 |
/* null reply, reconnect and try again */ |
771 | 771 |
if (rsrv->ctxRedis->err) |
772 | 772 |
{ |
773 |
- LM_ERR("Redis error: %s\n", rsrv->ctxRedis->errstr); |
|
773 |
+ LM_DBG("Redis error: %s\n", rsrv->ctxRedis->errstr); |
|
774 | 774 |
} |
775 | 775 |
if (redisc_create_pipelined_message(rsrv) == 0) |
776 | 776 |
{ |
... | ... |
@@ -1032,13 +1032,6 @@ int redisc_exec(str *srv, str *res, str *cmd, ...) |
1032 | 1032 |
} |
1033 | 1033 |
} |
1034 | 1034 |
|
1035 |
- LM_DBG("rpl->rplRedis->type:%d\n", rpl->rplRedis->type); |
|
1036 |
- if(rpl->rplRedis->type == REDIS_REPLY_ERROR) { |
|
1037 |
- LM_ERR("Redis error:%.*s\n", |
|
1038 |
- (int)rpl->rplRedis->len, rpl->rplRedis->str); |
|
1039 |
- goto error_exec; |
|
1040 |
- } |
|
1041 |
- |
|
1042 | 1035 |
if (check_cluster_reply(rpl->rplRedis, &rsrv)) { |
1043 | 1036 |
LM_DBG("rsrv->ctxRedis = %p\n", rsrv->ctxRedis); |
1044 | 1037 |
if(rsrv->ctxRedis==NULL) |
... | ... |
@@ -1073,14 +1066,15 @@ int redisc_exec(str *srv, str *res, str *cmd, ...) |
1073 | 1066 |
goto error_exec; |
1074 | 1067 |
} |
1075 | 1068 |
} |
1069 |
+ } |
|
1076 | 1070 |
|
1077 |
- LM_DBG("rpl->rplRedis->type:%d\n", rpl->rplRedis->type); |
|
1078 |
- if(rpl->rplRedis->type == REDIS_REPLY_ERROR) { |
|
1079 |
- LM_ERR("Redis error:%.*s\n", |
|
1080 |
- (int)rpl->rplRedis->len, rpl->rplRedis->str); |
|
1081 |
- goto error_exec; |
|
1082 |
- } |
|
1071 |
+ LM_DBG("rpl->rplRedis->type:%d\n", rpl->rplRedis->type); |
|
1072 |
+ if(rpl->rplRedis->type == REDIS_REPLY_ERROR) { |
|
1073 |
+ LM_ERR("Redis error:%.*s\n", |
|
1074 |
+ (int)rpl->rplRedis->len, rpl->rplRedis->str); |
|
1075 |
+ goto error_exec; |
|
1083 | 1076 |
} |
1077 |
+ |
|
1084 | 1078 |
STR_ZTOV(cmd->s[cmd->len], c); |
1085 | 1079 |
rsrv->disable.consecutive_errors = 0; |
1086 | 1080 |
va_end(ap); |
- cc8e621 added sentinel support in initial redis connection.
- this commit replicates the logic into reconnection function.
... | ... |
@@ -408,8 +408,11 @@ redisc_server_t *redisc_get_server(str *name) |
408 | 408 |
*/ |
409 | 409 |
int redisc_reconnect_server(redisc_server_t *rsrv) |
410 | 410 |
{ |
411 |
- char addr[256], pass[256], unix_sock_path[256]; |
|
412 |
- unsigned int port, db, sock = 0, haspass = 0; |
|
411 |
+ char addr[256], pass[256], unix_sock_path[256], sentinel_group[256]; |
|
412 |
+ unsigned int port, db, sock = 0, haspass = 0, sentinel_master = 1; |
|
413 |
+ char sentinels[MAXIMUM_SENTINELS][256]; |
|
414 |
+ uint8_t sentinels_count = 0; |
|
415 |
+ int i, row; |
|
413 | 416 |
param_t *pit = NULL; |
414 | 417 |
struct timeval tv_conn; |
415 | 418 |
struct timeval tv_cmd; |
... | ... |
@@ -442,6 +445,84 @@ int redisc_reconnect_server(redisc_server_t *rsrv) |
442 | 445 |
} else if(pit->name.len==4 && strncmp(pit->name.s, "pass", 4)==0) { |
443 | 446 |
snprintf(pass, sizeof(pass)-1, "%.*s", pit->body.len, pit->body.s); |
444 | 447 |
haspass = 1; |
448 |
+ } else if(pit->name.len==14 && strncmp(pit->name.s, |
|
449 |
+ "sentinel_group", 14)==0) { |
|
450 |
+ snprintf(sentinel_group, sizeof(sentinel_group)-1, "%.*s", |
|
451 |
+ pit->body.len, pit->body.s); |
|
452 |
+ } else if(pit->name.len==15 && strncmp(pit->name.s, |
|
453 |
+ "sentinel_master", 15)==0) { |
|
454 |
+ if(str2int(&pit->body, &sentinel_master) < 0) |
|
455 |
+ sentinel_master = 1; |
|
456 |
+ } else if(pit->name.len==8 && strncmp(pit->name.s, |
|
457 |
+ "sentinel", 8)==0) { |
|
458 |
+ if( sentinels_count < MAXIMUM_SENTINELS ){ |
|
459 |
+ snprintf(sentinels[sentinels_count], |
|
460 |
+ sizeof(sentinels[sentinels_count])-1, "%.*s", |
|
461 |
+ pit->body.len, pit->body.s); |
|
462 |
+ sentinels_count++; |
|
463 |
+ } |
|
464 |
+ else { |
|
465 |
+ LM_ERR("too many sentinels, maximum %d supported.\n", |
|
466 |
+ MAXIMUM_SENTINELS); |
|
467 |
+ return -1; |
|
468 |
+ } |
|
469 |
+ } |
|
470 |
+ } |
|
471 |
+ |
|
472 |
+ // if sentinels are provided, we need to connect to them and retrieve the redis server |
|
473 |
+ // address / port |
|
474 |
+ if(sentinels_count > 0) { |
|
475 |
+ for(i= 0; i< sentinels_count; i++) { |
|
476 |
+ char *sentinelAddr = sentinels[i]; |
|
477 |
+ char *pos; |
|
478 |
+ redisContext *redis; |
|
479 |
+ redisReply *res, *res2; |
|
480 |
+ |
|
481 |
+ port = 6379; |
|
482 |
+ if( (pos = strchr(sentinelAddr, ':')) != NULL ) { |
|
483 |
+ port = atoi(pos+1); |
|
484 |
+ pos[i] = '\0'; |
|
485 |
+ } |
|
486 |
+ |
|
487 |
+ redis = redisConnectWithTimeout(sentinelAddr, port, tv_conn); |
|
488 |
+ if( redis ) { |
|
489 |
+ if(sentinel_master != 0) { |
|
490 |
+ res = redisCommand(redis, |
|
491 |
+ "SENTINEL get-master-addr-by-name %s", |
|
492 |
+ sentinel_group); |
|
493 |
+ if( res && (res->type == REDIS_REPLY_ARRAY) |
|
494 |
+ && (res->elements == 2) ) { |
|
495 |
+ strncpy(addr, res->element[0]->str, |
|
496 |
+ res->element[0]->len + 1); |
|
497 |
+ port = atoi(res->element[1]->str); |
|
498 |
+ LM_DBG("sentinel replied: %s:%d\n", addr, port); |
|
499 |
+ } |
|
500 |
+ } |
|
501 |
+ else { |
|
502 |
+ res = redisCommand(redis, "SENTINEL slaves %s", |
|
503 |
+ sentinel_group); |
|
504 |
+ if( res && (res->type == REDIS_REPLY_ARRAY) ) { |
|
505 |
+ for(row = 0; row< res->elements; row++){ |
|
506 |
+ res2 = res->element[row]; |
|
507 |
+ for(i= 0; i< res2->elements; i+= 2) { |
|
508 |
+ if( strncmp(res2->element[i]->str, |
|
509 |
+ "ip", 2) == 0 ) { |
|
510 |
+ strncpy(addr, res2->element[i+1]->str, |
|
511 |
+ res2->element[i+1]->len); |
|
512 |
+ addr[res2->element[i+1]->len] = '\0'; |
|
513 |
+ } |
|
514 |
+ else if( strncmp(res2->element[i]->str, |
|
515 |
+ "port", 4) == 0) { |
|
516 |
+ port = atoi(res2->element[i+1]->str); |
|
517 |
+ break; |
|
518 |
+ } |
|
519 |
+ } |
|
520 |
+ } |
|
521 |
+ LM_DBG("slave for %s: %s:%d\n", sentinel_group, |
|
522 |
+ addr, port); |
|
523 |
+ } |
|
524 |
+ } |
|
525 |
+ } |
|
445 | 526 |
} |
446 | 527 |
} |
447 | 528 |
|
... | ... |
@@ -950,6 +950,14 @@ int redisc_exec(str *srv, str *res, str *cmd, ...) |
950 | 950 |
goto error_exec; |
951 | 951 |
} |
952 | 952 |
} |
953 |
+ |
|
954 |
+ LM_DBG("rpl->rplRedis->type:%d\n", rpl->rplRedis->type); |
|
955 |
+ if(rpl->rplRedis->type == REDIS_REPLY_ERROR) { |
|
956 |
+ LM_ERR("Redis error:%.*s\n", |
|
957 |
+ (int)rpl->rplRedis->len, rpl->rplRedis->str); |
|
958 |
+ goto error_exec; |
|
959 |
+ } |
|
960 |
+ |
|
953 | 961 |
if (check_cluster_reply(rpl->rplRedis, &rsrv)) { |
954 | 962 |
LM_DBG("rsrv->ctxRedis = %p\n", rsrv->ctxRedis); |
955 | 963 |
if(rsrv->ctxRedis==NULL) |
... | ... |
@@ -984,6 +992,13 @@ int redisc_exec(str *srv, str *res, str *cmd, ...) |
984 | 992 |
goto error_exec; |
985 | 993 |
} |
986 | 994 |
} |
995 |
+ |
|
996 |
+ LM_DBG("rpl->rplRedis->type:%d\n", rpl->rplRedis->type); |
|
997 |
+ if(rpl->rplRedis->type == REDIS_REPLY_ERROR) { |
|
998 |
+ LM_ERR("Redis error:%.*s\n", |
|
999 |
+ (int)rpl->rplRedis->len, rpl->rplRedis->str); |
|
1000 |
+ goto error_exec; |
|
1001 |
+ } |
|
987 | 1002 |
} |
988 | 1003 |
STR_ZTOV(cmd->s[cmd->len], c); |
989 | 1004 |
rsrv->disable.consecutive_errors = 0; |
... | ... |
@@ -542,9 +542,7 @@ int redisc_append_cmd(str *srv, str *res, str *cmd, ...) |
542 | 542 |
LM_ERR("no redis reply id found: %.*s\n", res->len, res->s); |
543 | 543 |
goto error_cmd; |
544 | 544 |
} |
545 |
- |
|
546 |
- c = cmd->s[cmd->len]; |
|
547 |
- cmd->s[cmd->len] = '\0'; |
|
545 |
+ STR_VTOZ(cmd->s[cmd->len], c); |
|
548 | 546 |
rsrv->piped.commands[rsrv->piped.pending_commands].len = redisvFormatCommand( |
549 | 547 |
&rsrv->piped.commands[rsrv->piped.pending_commands].s, |
550 | 548 |
cmd->s, |
... | ... |
@@ -557,7 +555,7 @@ int redisc_append_cmd(str *srv, str *res, str *cmd, ...) |
557 | 555 |
rsrv->piped.replies[rsrv->piped.pending_commands]=rpl; |
558 | 556 |
rsrv->piped.pending_commands++; |
559 | 557 |
|
560 |
- cmd->s[cmd->len] = c; |
|
558 |
+ STR_ZTOV(cmd->s[cmd->len], c); |
|
561 | 559 |
va_end(ap); |
562 | 560 |
return 0; |
563 | 561 |
|
... | ... |
@@ -883,8 +881,7 @@ int redisc_exec(str *srv, str *res, str *cmd, ...) |
883 | 881 |
goto error; |
884 | 882 |
} |
885 | 883 |
|
886 |
- c = cmd->s[cmd->len]; |
|
887 |
- cmd->s[cmd->len] = '\0'; |
|
884 |
+ STR_VTOZ(cmd->s[cmd->len], c); |
|
888 | 885 |
|
889 | 886 |
rsrv = redisc_get_server(srv); |
890 | 887 |
if(rsrv==NULL) |
... | ... |
@@ -949,7 +946,7 @@ int redisc_exec(str *srv, str *res, str *cmd, ...) |
949 | 946 |
redis_count_err_and_disable(rsrv); |
950 | 947 |
LM_ERR("unable to reconnect to redis server: %.*s\n", |
951 | 948 |
srv->len, srv->s); |
952 |
- cmd->s[cmd->len] = c; |
|
949 |
+ STR_ZTOV(cmd->s[cmd->len], c); |
|
953 | 950 |
goto error_exec; |
954 | 951 |
} |
955 | 952 |
} |
... | ... |
@@ -983,12 +980,12 @@ int redisc_exec(str *srv, str *res, str *cmd, ...) |
983 | 980 |
} else { |
984 | 981 |
LM_ERR("unable to reconnect to redis server: %.*s\n", |
985 | 982 |
srv->len, srv->s); |
986 |
- cmd->s[cmd->len] = c; |
|
983 |
+ STR_ZTOV(cmd->s[cmd->len], c); |
|
987 | 984 |
goto error_exec; |
988 | 985 |
} |
989 | 986 |
} |
990 | 987 |
} |
991 |
- cmd->s[cmd->len] = c; |
|
988 |
+ STR_ZTOV(cmd->s[cmd->len], c); |
|
992 | 989 |
rsrv->disable.consecutive_errors = 0; |
993 | 990 |
va_end(ap); |
994 | 991 |
va_end(ap2); |
... | ... |
@@ -1000,12 +997,12 @@ int redisc_exec(str *srv, str *res, str *cmd, ...) |
1000 | 997 |
return 0; |
1001 | 998 |
|
1002 | 999 |
error_exec: |
1003 |
- cmd->s[cmd->len] = c; |
|
1000 |
+ STR_ZTOV(cmd->s[cmd->len], c); |
|
1004 | 1001 |
ret = -1; |
1005 | 1002 |
goto error; |
1006 | 1003 |
|
1007 | 1004 |
srv_disabled: |
1008 |
- cmd->s[cmd->len] = c; |
|
1005 |
+ STR_ZTOV(cmd->s[cmd->len], c); |
|
1009 | 1006 |
ret = -2; |
1010 | 1007 |
goto error; |
1011 | 1008 |
|
... | ... |
@@ -1019,12 +1019,12 @@ error: |
1019 | 1019 |
|
1020 | 1020 |
/** |
1021 | 1021 |
* Executes a redis command. |
1022 |
- * Command is coded using a vector of strings, and a vector of lenghts. |
|
1022 |
+ * Command is coded using a vector of strings, and a vector of lengths. |
|
1023 | 1023 |
* |
1024 | 1024 |
* @param rsrv Pointer to a redis_server_t structure. |
1025 | 1025 |
* @param argc number of elements in the command vector. |
1026 | 1026 |
* @param argv vector of zero terminated strings forming the command. |
1027 |
- * @param argvlen vector of command string lenghts or NULL. |
|
1027 |
+ * @param argvlen vector of command string lengths or NULL. |
|
1028 | 1028 |
* @return redisReply structure or NULL if there was an error. |
1029 | 1029 |
*/ |
1030 | 1030 |
redisReply* redisc_exec_argv(redisc_server_t *rsrv, int argc, const char **argv, |
> warning: field precision should have type 'int', but argument has type 'size_t' (aka 'unsigned long') [-Wformat]
... | ... |
@@ -758,7 +758,7 @@ int check_cluster_reply(redisReply *reply, redisc_server_t **rsrv) |
758 | 758 |
char spec_new[100]; |
759 | 759 |
|
760 | 760 |
if(redis_cluster_param) { |
761 |
- LM_DBG("Redis replied: \"%.*s\"\n", reply->len, reply->str); |
|
761 |
+ LM_DBG("Redis replied: \"%.*s\"\n", (int)reply->len, reply->str); |
|
762 | 762 |
if((reply->len > 7) && (strncmp(reply->str, "MOVED", 5) == 0)) { |
763 | 763 |
port = 6379; |
764 | 764 |
if(strchr(reply->str, ':') > 0) { |
... | ... |
@@ -769,7 +769,7 @@ int check_cluster_reply(redisReply *reply, redisc_server_t **rsrv) |
769 | 769 |
LM_DBG("Port \"%.*s\" [%i] => %i\n", tmpstr.len, tmpstr.s, |
770 | 770 |
tmpstr.len, port); |
771 | 771 |
} else { |
772 |
- LM_ERR("No Port in REDIS MOVED Reply (%.*s)\n", reply->len, |
|
772 |
+ LM_ERR("No Port in REDIS MOVED Reply (%.*s)\n", (int)reply->len, |
|
773 | 773 |
reply->str); |
774 | 774 |
return 0; |
775 | 775 |
} |
... | ... |
@@ -778,7 +778,7 @@ int check_cluster_reply(redisReply *reply, redisc_server_t **rsrv) |
778 | 778 |
addr.s = strchr(reply->str + 6, ' ') + 1; |
779 | 779 |
LM_DBG("Host \"%.*s\" [%i]\n", addr.len, addr.s, addr.len); |
780 | 780 |
} else { |
781 |
- LM_ERR("No Host in REDIS MOVED Reply (%.*s)\n", reply->len, |
|
781 |
+ LM_ERR("No Host in REDIS MOVED Reply (%.*s)\n", (int)reply->len, |
|
782 | 782 |
reply->str); |
783 | 783 |
return 0; |
784 | 784 |
} |
... | ... |
@@ -39,7 +39,8 @@ |
39 | 39 |
|
40 | 40 |
#include "redis_client.h" |
41 | 41 |
|
42 |
-#define redisCommandNR(a...) (int)({ void *__tmp; __tmp = redisCommand(a); if (__tmp) freeReplyObject(__tmp); __tmp ? 0 : -1;}) |
|
42 |
+#define redisCommandNR(a...) (int)({ void *__tmp; __tmp = redisCommand(a); \ |
|
43 |
+ if (__tmp) freeReplyObject(__tmp); __tmp ? 0 : -1;}) |
|
43 | 44 |
|
44 | 45 |
static redisc_server_t * _redisc_srv_list=NULL; |
45 | 46 |
|
... | ... |
@@ -93,7 +94,7 @@ int redisc_init(void) |
93 | 94 |
{ |
94 | 95 |
char sentinels[MAXIMUM_SENTINELS][256]; |
95 | 96 |
uint8_t sentinels_count = 0; |
96 |
- |
|
97 |
+ |
|
97 | 98 |
port = 6379; |
98 | 99 |
db = 0; |
99 | 100 |
haspass = 0; |
... | ... |
@@ -106,10 +107,12 @@ int redisc_init(void) |
106 | 107 |
for (pit = rsrv->attrs; pit; pit=pit->next) |
107 | 108 |
{ |
108 | 109 |
if(pit->name.len==4 && strncmp(pit->name.s, "unix", 4)==0) { |
109 |
- snprintf(unix_sock_path, sizeof(unix_sock_path)-1, "%.*s", pit->body.len, pit->body.s); |
|
110 |
+ snprintf(unix_sock_path, sizeof(unix_sock_path)-1, "%.*s", |
|
111 |
+ pit->body.len, pit->body.s); |
|
110 | 112 |
sock = 1; |
111 | 113 |
} else if(pit->name.len==4 && strncmp(pit->name.s, "addr", 4)==0) { |
112 |
- snprintf(addr, sizeof(addr)-1, "%.*s", pit->body.len, pit->body.s); |
|
114 |
+ snprintf(addr, sizeof(addr)-1, "%.*s", |
|
115 |
+ pit->body.len, pit->body.s); |
|
113 | 116 |
} else if(pit->name.len==4 && strncmp(pit->name.s, "port", 4)==0) { |
114 | 117 |
if(str2int(&pit->body, &port) < 0) |
115 | 118 |
port = 6379; |
... | ... |
@@ -117,25 +120,33 @@ int redisc_init(void) |
117 | 120 |
if(str2int(&pit->body, &db) < 0) |
118 | 121 |
db = 0; |
119 | 122 |
} else if(pit->name.len==4 && strncmp(pit->name.s, "pass", 4)==0) { |
120 |
- snprintf(pass, sizeof(pass)-1, "%.*s", pit->body.len, pit->body.s); |
|
123 |
+ snprintf(pass, sizeof(pass)-1, "%.*s", |
|
124 |
+ pit->body.len, pit->body.s); |
|
121 | 125 |
haspass = 1; |
122 |
- } else if(pit->name.len==14 && strncmp(pit->name.s, "sentinel_group", 14)==0) { |
|
123 |
- snprintf(sentinel_group, sizeof(sentinel_group)-1, "%.*s", pit->body.len, pit->body.s); |
|
124 |
- } else if(pit->name.len==15 && strncmp(pit->name.s, "sentinel_master", 15)==0) { |
|
126 |
+ } else if(pit->name.len==14 && strncmp(pit->name.s, |
|
127 |
+ "sentinel_group", 14)==0) { |
|
128 |
+ snprintf(sentinel_group, sizeof(sentinel_group)-1, "%.*s", |
|
129 |
+ pit->body.len, pit->body.s); |
|
130 |
+ } else if(pit->name.len==15 && strncmp(pit->name.s, |
|
131 |
+ "sentinel_master", 15)==0) { |
|
125 | 132 |
if(str2int(&pit->body, &sentinel_master) < 0) |
126 | 133 |
sentinel_master = 1; |
127 |
- } else if(pit->name.len==8 && strncmp(pit->name.s, "sentinel", 8)==0) { |
|
134 |
+ } else if(pit->name.len==8 && strncmp(pit->name.s, |
|
135 |
+ "sentinel", 8)==0) { |
|
128 | 136 |
if( sentinels_count < MAXIMUM_SENTINELS ){ |
129 |
- snprintf(sentinels[sentinels_count], sizeof(sentinels[sentinels_count])-1, "%.*s", pit->body.len, pit->body.s); |
|
137 |
+ snprintf(sentinels[sentinels_count], |
|
138 |
+ sizeof(sentinels[sentinels_count])-1, "%.*s", |
|
139 |
+ pit->body.len, pit->body.s); |
|
130 | 140 |
sentinels_count++; |
131 | 141 |
} |
132 | 142 |
else { |
133 |
- LM_ERR("too many sentinels, maximum %d supported.\n", MAXIMUM_SENTINELS); |
|
143 |
+ LM_ERR("too many sentinels, maximum %d supported.\n", |
|
144 |
+ MAXIMUM_SENTINELS); |
|
134 | 145 |
return -1; |
135 | 146 |
} |
136 | 147 |
} |
137 | 148 |
} |
138 |
- |
|
149 |
+ |
|
139 | 150 |
// if sentinels are provided, we need to connect to them and retrieve the redis server |
140 | 151 |
// address / port |
141 | 152 |
if(sentinels_count > 0) { |
... | ... |
@@ -144,46 +155,49 @@ int redisc_init(void) |
144 | 155 |
char *pos; |
145 | 156 |
redisContext *redis; |
146 | 157 |
redisReply *res, *res2; |
147 |
- |
|
158 |
+ |
|
148 | 159 |
port = 6379; |
149 | 160 |
if( (pos = strchr(sentinelAddr, ':')) != NULL ) { |
150 | 161 |
port = atoi(pos+1); |
151 | 162 |
pos[i] = '\0'; |
152 | 163 |
} |
153 |
- |
|
164 |
+ |
|
154 | 165 |
redis = redisConnectWithTimeout(sentinelAddr, port, tv_conn); |
155 | 166 |
if( redis ) { |
156 | 167 |
if(sentinel_master != 0) { |
157 |
- res = redisCommand(redis, "SENTINEL get-master-addr-by-name %s", sentinel_group); |
|
158 |
- if( res && (res->type == REDIS_REPLY_ARRAY) && (res->elements == 2) ) { |
|
159 |
- strncpy(addr, res->element[0]->str, res->element[0]->len + 1); |
|
168 |
+ res = redisCommand(redis, |
|
169 |
+ "SENTINEL get-master-addr-by-name %s", |
|
170 |
+ sentinel_group); |
|
171 |
+ if( res && (res->type == REDIS_REPLY_ARRAY) |
|
172 |
+ && (res->elements == 2) ) { |
|
173 |
+ strncpy(addr, res->element[0]->str, |
|
174 |
+ res->element[0]->len + 1); |
|
160 | 175 |
port = atoi(res->element[1]->str); |
161 |
- |
|
162 |
- |
|
163 |
- printf("sentinel replied: %s:%d\n", addr, port); |
|
176 |
+ LM_DBG("sentinel replied: %s:%d\n", addr, port); |
|
164 | 177 |
} |
165 | 178 |
} |
166 | 179 |
else { |
167 |
- res = redisCommand(redis, "SENTINEL slaves %s", sentinel_group); |
|
180 |
+ res = redisCommand(redis, "SENTINEL slaves %s", |
|
181 |
+ sentinel_group); |
|
168 | 182 |
if( res && (res->type == REDIS_REPLY_ARRAY) ) { |
169 |
- |
|
170 | 183 |
for(row = 0; row< res->elements; row++){ |
171 | 184 |
res2 = res->element[row]; |
172 |
- |
|
173 | 185 |
for(i= 0; i< res2->elements; i+= 2) { |
174 |
- if( strncmp(res2->element[i]->str, "ip", 2) == 0 ) { |
|
175 |
- strncpy(addr, res2->element[i+1]->str, res2->element[i+1]->len); |
|
186 |
+ if( strncmp(res2->element[i]->str, |
|
187 |
+ "ip", 2) == 0 ) { |
|
188 |
+ strncpy(addr, res2->element[i+1]->str, |
|
189 |
+ res2->element[i+1]->len); |
|
176 | 190 |
addr[res2->element[i+1]->len] = '\0'; |
177 | 191 |
} |
178 |
- else if( strncmp(res2->element[i]->str, "port", 4) == 0) { |
|
192 |
+ else if( strncmp(res2->element[i]->str, |
|
193 |
+ "port", 4) == 0) { |
|
179 | 194 |
port = atoi(res2->element[i+1]->str); |
180 | 195 |
break; |
181 | 196 |
} |
182 | 197 |
} |
183 |
- |
|
184 | 198 |
} |
185 |
- |
|
186 |
- printf("slave for %s: %s:%d\n", sentinel_group, addr, port); |
|
199 |
+ LM_DBG("slave for %s: %s:%d\n", sentinel_group, |
|
200 |
+ addr, port); |
|
187 | 201 |
} |
188 | 202 |
} |
189 | 203 |
} |
... | ... |
@@ -206,7 +220,8 @@ int redisc_init(void) |
206 | 220 |
goto err; |
207 | 221 |
} |
208 | 222 |
if (rsrv->ctxRedis->err) { |
209 |
- LM_ERR("Failed to create REDIS returned an error: %s\n", rsrv->ctxRedis->errstr); |
|
223 |
+ LM_ERR("Failed to create REDIS returned an error: %s\n", |
|
224 |
+ rsrv->ctxRedis->errstr); |
|
210 | 225 |
goto err2; |
211 | 226 |
} |
212 | 227 |
if ((haspass != 0) && redisc_check_auth(rsrv, pass)) { |
... | ... |
@@ -218,11 +233,14 @@ int redisc_init(void) |
218 | 233 |
goto err2; |
219 | 234 |
} |
220 | 235 |
if (redisCommandNR(rsrv->ctxRedis, "PING")) { |
221 |
- LM_ERR("Failed to send PING (REDIS returned %s).\n", rsrv->ctxRedis->errstr); |
|
236 |
+ LM_ERR("Failed to send PING (REDIS returned %s).\n", |
|
237 |
+ rsrv->ctxRedis->errstr); |
|
222 | 238 |
goto err2; |
223 | 239 |
} |
224 |
- if ((redis_cluster_param == 0) && redisCommandNR(rsrv->ctxRedis, "SELECT %i", db)) { |
|
225 |
- LM_ERR("Failed to send \"SELECT %i\" (REDIS returned \"%s\", and not in cluster mode).\n", db, rsrv->ctxRedis->errstr); |
|
240 |
+ if ((redis_cluster_param == 0) && redisCommandNR(rsrv->ctxRedis, |
|
241 |
+ "SELECT %i", db)) { |
|
242 |
+ LM_ERR("Failed to send \"SELECT %i\" (REDIS returned \"%s\"," |
|
243 |
+ " and not in cluster mode).\n", db, rsrv->ctxRedis->errstr); |
|
226 | 244 |
goto err2; |
227 | 245 |
} |
228 | 246 |
} |
... | ... |
@@ -374,7 +392,8 @@ redisc_server_t *redisc_get_server(str *name) |
374 | 392 |
rsrv=_redisc_srv_list; |
375 | 393 |
while(rsrv!=NULL) |
376 | 394 |
{ |
377 |
- LM_DBG("Entry %u (%.*s)\n", rsrv->hname, rsrv->sname->len, rsrv->sname->s); |
|
395 |
+ LM_DBG("Entry %u (%.*s)\n", rsrv->hname, |
|
396 |
+ rsrv->sname->len, rsrv->sname->s); |
|
378 | 397 |
if(rsrv->hname==hname && rsrv->sname->len==name->len |
379 | 398 |
&& strncmp(rsrv->sname->s, name->s, name->len)==0) |
380 | 399 |
return rsrv; |
... | ... |
@@ -409,7 +428,8 @@ int redisc_reconnect_server(redisc_server_t *rsrv) |
409 | 428 |
for (pit = rsrv->attrs; pit; pit=pit->next) |
410 | 429 |
{ |
411 | 430 |
if(pit->name.len==4 && strncmp(pit->name.s, "unix", 4)==0) { |
412 |
- snprintf(unix_sock_path, sizeof(unix_sock_path)-1, "%.*s", pit->body.len, pit->body.s); |
|
431 |
+ snprintf(unix_sock_path, sizeof(unix_sock_path)-1, "%.*s", |
|
432 |
+ pit->body.len, pit->body.s); |
|
413 | 433 |
sock = 1; |
414 | 434 |
} else if(pit->name.len==4 && strncmp(pit->name.s, "addr", 4)==0) { |
415 | 435 |
snprintf(addr, sizeof(addr)-1, "%.*s", pit->body.len, pit->body.s); |
... | ... |
@@ -447,7 +467,8 @@ int redisc_reconnect_server(redisc_server_t *rsrv) |
447 | 467 |
goto err2; |
448 | 468 |
if (redisCommandNR(rsrv->ctxRedis, "PING")) |
449 | 469 |
goto err2; |
450 |
- if ((redis_cluster_param == 0) && redisCommandNR(rsrv->ctxRedis, "SELECT %i", db)) |
|
470 |
+ if ((redis_cluster_param == 0) && redisCommandNR(rsrv->ctxRedis, |
|
471 |
+ "SELECT %i", db)) |
|
451 | 472 |
goto err2; |
452 | 473 |
if (redis_flush_on_reconnect_param) |
453 | 474 |
if (redisCommandNR(rsrv->ctxRedis, "FLUSHALL")) |
... | ... |
@@ -511,7 +532,8 @@ int redisc_append_cmd(str *srv, str *res, str *cmd, ...) |
511 | 532 |
} |
512 | 533 |
if (rsrv->piped.pending_commands >= MAXIMUM_PIPELINED_COMMANDS) |
513 | 534 |
{ |
514 |
- LM_ERR("Too many pipelined commands, maximum is %d\n",MAXIMUM_PIPELINED_COMMANDS); |
|
535 |
+ LM_ERR("Too many pipelined commands, maximum is %d\n", |
|
536 |
+ MAXIMUM_PIPELINED_COMMANDS); |
|
515 | 537 |
goto error_cmd; |
516 | 538 |
} |
517 | 539 |
rpl = redisc_get_reply(res); |
... | ... |
@@ -586,17 +608,21 @@ int redisc_create_pipelined_message(redisc_server_t *rsrv) |
586 | 608 |
|
587 | 609 |
if (rsrv->ctxRedis->err) |
588 | 610 |
{ |
589 |
- LM_DBG("Reconnecting server because of error %d: \"%s\"",rsrv->ctxRedis->err,rsrv->ctxRedis->errstr); |
|
611 |
+ LM_DBG("Reconnecting server because of error %d: \"%s\"", |
|
612 |
+ rsrv->ctxRedis->err,rsrv->ctxRedis->errstr); |
|
590 | 613 |
if (redisc_reconnect_server(rsrv)) |
591 | 614 |
{ |
592 |
- LM_ERR("unable to reconnect to REDIS server: %.*s\n", rsrv->sname->len,rsrv->sname->s); |
|
615 |
+ LM_ERR("unable to reconnect to REDIS server: %.*s\n", |
|
616 |
+ rsrv->sname->len,rsrv->sname->s); |
|
593 | 617 |
return -1; |
594 | 618 |
} |
595 | 619 |
} |
596 | 620 |
|
597 | 621 |
for (i=0;i<rsrv->piped.pending_commands;i++) |
598 | 622 |
{ |
599 |
- if (redis_append_formatted_command(rsrv->ctxRedis,rsrv->piped.commands[i].s,rsrv->piped.commands[i].len) != REDIS_OK) |
|
623 |
+ if (redis_append_formatted_command(rsrv->ctxRedis, |
|
624 |
+ rsrv->piped.commands[i].s,rsrv->piped.commands[i].len) |
|
625 |
+ != REDIS_OK) |
|
600 | 626 |
{ |
601 | 627 |
LM_ERR("Error while appending command %d",i); |
602 | 628 |
return -1; |
... | ... |
@@ -642,7 +668,8 @@ int redisc_exec_pipelined(redisc_server_t *rsrv) |
642 | 668 |
} |
643 | 669 |
if(rsrv->ctxRedis==NULL) |
644 | 670 |
{ |
645 |
- LM_ERR("no redis context for server: %.*s\n", rsrv->sname->len,rsrv->sname->s); |
|
671 |
+ LM_ERR("no redis context for server: %.*s\n", |
|
672 |
+ rsrv->sname->len,rsrv->sname->s); |
|
646 | 673 |
goto error_exec; |
647 | 674 |
} |
648 | 675 |
|
... | ... |
@@ -694,7 +721,8 @@ int redisc_exec_pipelined(redisc_server_t *rsrv) |
694 | 721 |
freeReplyObject(rpl->rplRedis); |
695 | 722 |
rpl->rplRedis = NULL; |
696 | 723 |
} |
697 |
- if (redisGetReplyFromReader(rsrv->ctxRedis, (void**) &rpl->rplRedis) != REDIS_OK) |
|
724 |
+ if (redisGetReplyFromReader(rsrv->ctxRedis, (void**) &rpl->rplRedis) |
|
725 |
+ != REDIS_OK) |
|
698 | 726 |
{ |
699 | 727 |
LM_ERR("Unable to read reply\n"); |
700 | 728 |
continue; |
... | ... |
@@ -1181,7 +1209,8 @@ int redis_check_server(redisc_server_t *rsrv) |
1181 | 1209 |
{ |
1182 | 1210 |
if (get_ticks() > rsrv->disable.restore_tick) |
1183 | 1211 |
{ |
1184 |
- LM_NOTICE("REDIS server %.*s re-enabled",rsrv->sname->len,rsrv->sname->s); |
|
1212 |
+ LM_NOTICE("REDIS server %.*s re-enabled", |
|
1213 |
+ rsrv->sname->len, rsrv->sname->s); |
|
1185 | 1214 |
rsrv->disable.disabled = 0; |
1186 | 1215 |
rsrv->disable.consecutive_errors = 0; |
1187 | 1216 |
} |
... | ... |
@@ -1205,7 +1234,8 @@ int redis_count_err_and_disable(redisc_server_t *rsrv) |
1205 | 1234 |
{ |
1206 | 1235 |
rsrv->disable.disabled=1; |
1207 | 1236 |
rsrv->disable.restore_tick=get_ticks() + redis_disable_time_param; |
1208 |
- LM_WARN("REDIS server %.*s disabled for %d seconds",rsrv->sname->len,rsrv->sname->s,redis_disable_time_param); |
|
1237 |
+ LM_WARN("REDIS server %.*s disabled for %d seconds", rsrv->sname->len, |
|
1238 |
+ rsrv->sname->s, redis_disable_time_param); |
|
1209 | 1239 |
return 1; |
1210 | 1240 |
} |
1211 | 1241 |
return 0; |
... | ... |
@@ -1246,7 +1276,8 @@ void print_redis_reply(int log_level, redisReply *rpl,int offset) |
1246 | 1276 |
LOG(log_level,"%sinteger reply: %lld", padding, rpl->integer); |
1247 | 1277 |
break; |
1248 | 1278 |
case REDIS_REPLY_ARRAY: |
1249 |
- LOG(log_level,"%sarray reply with %d elements", padding, (int)rpl->elements); |
|
1279 |
+ LOG(log_level,"%sarray reply with %d elements", padding, |
|
1280 |
+ (int)rpl->elements); |
|
1250 | 1281 |
for (i=0; i < rpl->elements; i++) |
1251 | 1282 |
{ |
1252 | 1283 |
LOG(log_level,"%selement %d:",padding,i); |
- fix error related to sentinel patch, introduced in commit 95cfa343857e4
- error: 'for' loop initial declarations are only allowed in C99 mode
... | ... |
@@ -71,6 +71,7 @@ int redisc_init(void) |
71 | 71 |
char addr[256], pass[256], unix_sock_path[256], sentinel_group[256]; |
72 | 72 |
|
73 | 73 |
unsigned int port, db, sock = 0, haspass = 0, sentinel_master = 1; |
74 |
+ int i, row; |
|
74 | 75 |
redisc_server_t *rsrv=NULL; |
75 | 76 |
param_t *pit = NULL; |
76 | 77 |
struct timeval tv_conn; |
... | ... |
@@ -138,7 +139,7 @@ int redisc_init(void) |
138 | 139 |
// if sentinels are provided, we need to connect to them and retrieve the redis server |
139 | 140 |
// address / port |
140 | 141 |
if(sentinels_count > 0) { |
141 |
- for(int i= 0; i< sentinels_count; i++) { |
|
142 |
+ for(i= 0; i< sentinels_count; i++) { |
|
142 | 143 |
char *sentinelAddr = sentinels[i]; |
143 | 144 |
char *pos; |
144 | 145 |
redisContext *redis; |
... | ... |
@@ -166,10 +167,10 @@ int redisc_init(void) |
166 | 167 |
res = redisCommand(redis, "SENTINEL slaves %s", sentinel_group); |
167 | 168 |
if( res && (res->type == REDIS_REPLY_ARRAY) ) { |
168 | 169 |
|
169 |
- for(int row = 0; row< res->elements; row++){ |
|
170 |
+ for(row = 0; row< res->elements; row++){ |
|
170 | 171 |
res2 = res->element[row]; |
171 | 172 |
|
172 |
- for(int i= 0; i< res2->elements; i+= 2) { |
|
173 |
+ for(i= 0; i< res2->elements; i+= 2) { |
|
173 | 174 |
if( strncmp(res2->element[i]->str, "ip", 2) == 0 ) { |
174 | 175 |
strncpy(addr, res2->element[i+1]->str, res2->element[i+1]->len); |
175 | 176 |
addr[res2->element[i+1]->len] = '\0'; |
... | ... |
@@ -68,9 +68,9 @@ int redis_append_formatted_command(redisContext *c, const char *cmd, size_t len) |
68 | 68 |
*/ |
69 | 69 |
int redisc_init(void) |
70 | 70 |
{ |
71 |
- char addr[256], pass[256], unix_sock_path[256]; |
|
71 |
+ char addr[256], pass[256], unix_sock_path[256], sentinel_group[256]; |
|
72 | 72 |
|
73 |
- unsigned int port, db, sock = 0, haspass = 0; |
|
73 |
+ unsigned int port, db, sock = 0, haspass = 0, sentinel_master = 1; |
|
74 | 74 |
redisc_server_t *rsrv=NULL; |
75 | 75 |
param_t *pit = NULL; |
76 | 76 |
struct timeval tv_conn; |
... | ... |
@@ -90,6 +90,9 @@ int redisc_init(void) |
90 | 90 |
|
91 | 91 |
for(rsrv=_redisc_srv_list; rsrv; rsrv=rsrv->next) |
92 | 92 |
{ |
93 |
+ char sentinels[MAXIMUM_SENTINELS][256]; |
|
94 |
+ uint8_t sentinels_count = 0; |
|
95 |
+ |
|
93 | 96 |
port = 6379; |
94 | 97 |
db = 0; |
95 | 98 |
haspass = 0; |
... | ... |
@@ -115,6 +118,74 @@ int redisc_init(void) |
115 | 118 |
} else if(pit->name.len==4 && strncmp(pit->name.s, "pass", 4)==0) { |
116 | 119 |
snprintf(pass, sizeof(pass)-1, "%.*s", pit->body.len, pit->body.s); |
117 | 120 |
haspass = 1; |
121 |
+ } else if(pit->name.len==14 && strncmp(pit->name.s, "sentinel_group", 14)==0) { |
|
122 |
+ snprintf(sentinel_group, sizeof(sentinel_group)-1, "%.*s", pit->body.len, pit->body.s); |
|
123 |
+ } else if(pit->name.len==15 && strncmp(pit->name.s, "sentinel_master", 15)==0) { |
|
124 |
+ if(str2int(&pit->body, &sentinel_master) < 0) |
|
125 |
+ sentinel_master = 1; |
|
126 |
+ } else if(pit->name.len==8 && strncmp(pit->name.s, "sentinel", 8)==0) { |
|
127 |
+ if( sentinels_count < MAXIMUM_SENTINELS ){ |
|
128 |
+ snprintf(sentinels[sentinels_count], sizeof(sentinels[sentinels_count])-1, "%.*s", pit->body.len, pit->body.s); |
|
129 |
+ sentinels_count++; |
|
130 |
+ } |
|
131 |
+ else { |
|
132 |
+ LM_ERR("too many sentinels, maximum %d supported.\n", MAXIMUM_SENTINELS); |
|
133 |
+ return -1; |
|
134 |
+ } |
|
135 |
+ } |
|
136 |
+ } |
|
137 |
+ |
|
138 |
+ // if sentinels are provided, we need to connect to them and retrieve the redis server |
|
139 |
+ // address / port |
|
140 |
+ if(sentinels_count > 0) { |
|
141 |
+ for(int i= 0; i< sentinels_count; i++) { |
|
142 |
+ char *sentinelAddr = sentinels[i]; |
|
143 |
+ char *pos; |
|
144 |
+ redisContext *redis; |
|
145 |
+ redisReply *res, *res2; |
|
146 |
+ |
|
147 |
+ port = 6379; |
|
148 |
+ if( (pos = strchr(sentinelAddr, ':')) != NULL ) { |
|
149 |
+ port = atoi(pos+1); |
|
150 |
+ pos[i] = '\0'; |
|
151 |
+ } |
|
152 |
+ |
|
153 |
+ redis = redisConnectWithTimeout(sentinelAddr, port, tv_conn); |
|
154 |
+ if( redis ) { |
|
155 |
+ if(sentinel_master != 0) { |
|
156 |
+ res = redisCommand(redis, "SENTINEL get-master-addr-by-name %s", sentinel_group); |
|
157 |
+ if( res && (res->type == REDIS_REPLY_ARRAY) && (res->elements == 2) ) { |
|
158 |
+ strncpy(addr, res->element[0]->str, res->element[0]->len + 1); |
|
159 |
+ port = atoi(res->element[1]->str); |
|
160 |
+ |
|
161 |
+ |
|
162 |
+ printf("sentinel replied: %s:%d\n", addr, port); |
|
163 |
+ } |
|
164 |