xref: /redis-3.2.3/src/sentinel.c (revision d06d8d6f)
1 /* Redis Sentinel implementation
2  *
3  * Copyright (c) 2009-2012, Salvatore Sanfilippo <antirez at gmail dot com>
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions are met:
8  *
9  *   * Redistributions of source code must retain the above copyright notice,
10  *     this list of conditions and the following disclaimer.
11  *   * Redistributions in binary form must reproduce the above copyright
12  *     notice, this list of conditions and the following disclaimer in the
13  *     documentation and/or other materials provided with the distribution.
14  *   * Neither the name of Redis nor the names of its contributors may be used
15  *     to endorse or promote products derived from this software without
16  *     specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
22  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28  * POSSIBILITY OF SUCH DAMAGE.
29  */
30 
31 #include "redis.h"
32 #include "hiredis.h"
33 #include "async.h"
34 
35 #include <ctype.h>
36 #include <arpa/inet.h>
37 #include <sys/socket.h>
38 #include <sys/wait.h>
39 #include <fcntl.h>
40 
41 extern char **environ;
42 
43 #define REDIS_SENTINEL_PORT 26379
44 
45 /* ======================== Sentinel global state =========================== */
46 
47 /* Address object, used to describe an ip:port pair. */
48 typedef struct sentinelAddr {
49     char *ip;
50     int port;
51 } sentinelAddr;
52 
53 /* A Sentinel Redis Instance object is monitoring. */
54 #define SRI_MASTER  (1<<0)
55 #define SRI_SLAVE   (1<<1)
56 #define SRI_SENTINEL (1<<2)
57 #define SRI_DISCONNECTED (1<<3)
58 #define SRI_S_DOWN (1<<4)   /* Subjectively down (no quorum). */
59 #define SRI_O_DOWN (1<<5)   /* Objectively down (confirmed by others). */
60 #define SRI_MASTER_DOWN (1<<6) /* A Sentinel with this flag set thinks that
61                                    its master is down. */
62 #define SRI_FAILOVER_IN_PROGRESS (1<<7) /* Failover is in progress for
63                                            this master. */
64 #define SRI_PROMOTED (1<<8)            /* Slave selected for promotion. */
65 #define SRI_RECONF_SENT (1<<9)     /* SLAVEOF <newmaster> sent. */
66 #define SRI_RECONF_INPROG (1<<10)   /* Slave synchronization in progress. */
67 #define SRI_RECONF_DONE (1<<11)     /* Slave synchronized with new master. */
68 #define SRI_FORCE_FAILOVER (1<<12)  /* Force failover with master up. */
69 #define SRI_SCRIPT_KILL_SENT (1<<13) /* SCRIPT KILL already sent on -BUSY */
70 
71 /* Note: times are in milliseconds. */
72 #define SENTINEL_INFO_PERIOD 10000
73 #define SENTINEL_PING_PERIOD 1000
74 #define SENTINEL_ASK_PERIOD 1000
75 #define SENTINEL_PUBLISH_PERIOD 2000
76 #define SENTINEL_DEFAULT_DOWN_AFTER 30000
77 #define SENTINEL_HELLO_CHANNEL "__sentinel__:hello"
78 #define SENTINEL_TILT_TRIGGER 2000
79 #define SENTINEL_TILT_PERIOD (SENTINEL_PING_PERIOD*30)
80 #define SENTINEL_DEFAULT_SLAVE_PRIORITY 100
81 #define SENTINEL_SLAVE_RECONF_TIMEOUT 10000
82 #define SENTINEL_DEFAULT_PARALLEL_SYNCS 1
83 #define SENTINEL_MIN_LINK_RECONNECT_PERIOD 15000
84 #define SENTINEL_DEFAULT_FAILOVER_TIMEOUT (60*3*1000)
85 #define SENTINEL_MAX_PENDING_COMMANDS 100
86 #define SENTINEL_ELECTION_TIMEOUT 10000
87 #define SENTINEL_MAX_DESYNC 1000
88 
89 /* Failover machine different states. */
90 #define SENTINEL_FAILOVER_STATE_NONE 0  /* No failover in progress. */
91 #define SENTINEL_FAILOVER_STATE_WAIT_START 1  /* Wait for failover_start_time*/
92 #define SENTINEL_FAILOVER_STATE_SELECT_SLAVE 2 /* Select slave to promote */
93 #define SENTINEL_FAILOVER_STATE_SEND_SLAVEOF_NOONE 3 /* Slave -> Master */
94 #define SENTINEL_FAILOVER_STATE_WAIT_PROMOTION 4 /* Wait slave to change role */
95 #define SENTINEL_FAILOVER_STATE_RECONF_SLAVES 5 /* SLAVEOF newmaster */
96 #define SENTINEL_FAILOVER_STATE_UPDATE_CONFIG 6 /* Monitor promoted slave. */
97 
98 #define SENTINEL_MASTER_LINK_STATUS_UP 0
99 #define SENTINEL_MASTER_LINK_STATUS_DOWN 1
100 
101 /* Generic flags that can be used with different functions.
102  * They use higher bits to avoid colliding with the function specific
103  * flags. */
104 #define SENTINEL_NO_FLAGS 0
105 #define SENTINEL_GENERATE_EVENT (1<<16)
106 #define SENTINEL_LEADER (1<<17)
107 #define SENTINEL_OBSERVER (1<<18)
108 
109 /* Script execution flags and limits. */
110 #define SENTINEL_SCRIPT_NONE 0
111 #define SENTINEL_SCRIPT_RUNNING 1
112 #define SENTINEL_SCRIPT_MAX_QUEUE 256
113 #define SENTINEL_SCRIPT_MAX_RUNNING 16
114 #define SENTINEL_SCRIPT_MAX_RUNTIME 60000 /* 60 seconds max exec time. */
115 #define SENTINEL_SCRIPT_MAX_RETRY 10
116 #define SENTINEL_SCRIPT_RETRY_DELAY 30000 /* 30 seconds between retries. */
117 
118 typedef struct sentinelRedisInstance {
119     int flags;      /* See SRI_... defines */
120     char *name;     /* Master name from the point of view of this sentinel. */
121     char *runid;    /* run ID of this instance. */
122     uint64_t config_epoch;  /* Configuration epoch. */
123     sentinelAddr *addr; /* Master host. */
124     redisAsyncContext *cc; /* Hiredis context for commands. */
125     redisAsyncContext *pc; /* Hiredis context for Pub / Sub. */
126     int pending_commands;   /* Number of commands sent waiting for a reply. */
127     mstime_t cc_conn_time; /* cc connection time. */
128     mstime_t pc_conn_time; /* pc connection time. */
129     mstime_t pc_last_activity; /* Last time we received any message. */
130     mstime_t last_avail_time; /* Last time the instance replied to ping with
131                                  a reply we consider valid. */
132     mstime_t last_ping_time;  /* Last time a pending ping was sent in the
133                                  context of the current command connection
134                                  with the instance. 0 if still not sent or
135                                  if pong already received. */
136     mstime_t last_pong_time;  /* Last time the instance replied to ping,
137                                  whatever the reply was. That's used to check
138                                  if the link is idle and must be reconnected. */
139     mstime_t last_pub_time;   /* Last time we sent hello via Pub/Sub. */
140     mstime_t last_hello_time; /* Only used if SRI_SENTINEL is set. Last time
141                                  we received a hello from this Sentinel
142                                  via Pub/Sub. */
143     mstime_t last_master_down_reply_time; /* Time of last reply to
144                                              SENTINEL is-master-down command. */
145     mstime_t s_down_since_time; /* Subjectively down since time. */
146     mstime_t o_down_since_time; /* Objectively down since time. */
147     mstime_t down_after_period; /* Consider it down after that period. */
148     mstime_t info_refresh;  /* Time at which we received INFO output from it. */
149 
150     /* Role and the first time we observed it.
151      * This is useful in order to delay replacing what the instance reports
152      * with our own configuration. We need to always wait some time in order
153      * to give a chance to the leader to report the new configuration before
154      * we do silly things. */
155     int role_reported;
156     mstime_t role_reported_time;
157     mstime_t slave_conf_change_time; /* Last time slave master addr changed. */
158 
159     /* Master specific. */
160     dict *sentinels;    /* Other sentinels monitoring the same master. */
161     dict *slaves;       /* Slaves for this master instance. */
162     int quorum;         /* Number of sentinels that need to agree on failure. */
163     int parallel_syncs; /* How many slaves to reconfigure at same time. */
164     char *auth_pass;    /* Password to use for AUTH against master & slaves. */
165 
166     /* Slave specific. */
167     mstime_t master_link_down_time; /* Slave replication link down time. */
168     int slave_priority; /* Slave priority according to its INFO output. */
169     mstime_t slave_reconf_sent_time; /* Time at which we sent SLAVE OF <new> */
170     struct sentinelRedisInstance *master; /* Master instance if it's slave. */
171     char *slave_master_host;    /* Master host as reported by INFO */
172     int slave_master_port;      /* Master port as reported by INFO */
173     int slave_master_link_status; /* Master link status as reported by INFO */
174     unsigned long long slave_repl_offset; /* Slave replication offset. */
175     /* Failover */
176     char *leader;       /* If this is a master instance, this is the runid of
177                            the Sentinel that should perform the failover. If
178                            this is a Sentinel, this is the runid of the Sentinel
179                            that this Sentinel voted as leader. */
180     uint64_t leader_epoch; /* Epoch of the 'leader' field. */
181     uint64_t failover_epoch; /* Epoch of the currently started failover. */
182     int failover_state; /* See SENTINEL_FAILOVER_STATE_* defines. */
183     mstime_t failover_state_change_time;
184     mstime_t failover_start_time;   /* Last failover attempt start time. */
185     mstime_t failover_timeout;      /* Max time to refresh failover state. */
186     mstime_t failover_delay_logged; /* For what failover_start_time value we
187                                        logged the failover delay. */
188     struct sentinelRedisInstance *promoted_slave; /* Promoted slave instance. */
189     /* Scripts executed to notify admin or reconfigure clients: when they
190      * are set to NULL no script is executed. */
191     char *notification_script;
192     char *client_reconfig_script;
193 } sentinelRedisInstance;
194 
195 /* Main state. */
196 struct sentinelState {
197     uint64_t current_epoch;     /* Current epoch. */
198     dict *masters;      /* Dictionary of master sentinelRedisInstances.
199                            Key is the instance name, value is the
200                            sentinelRedisInstance structure pointer. */
201     int tilt;           /* Are we in TILT mode? */
202     int running_scripts;    /* Number of scripts in execution right now. */
203     mstime_t tilt_start_time;   /* When TITL started. */
204     mstime_t previous_time;     /* Last time we ran the time handler. */
205     list *scripts_queue;    /* Queue of user scripts to execute. */
206 } sentinel;
207 
208 /* A script execution job. */
209 typedef struct sentinelScriptJob {
210     int flags;              /* Script job flags: SENTINEL_SCRIPT_* */
211     int retry_num;          /* Number of times we tried to execute it. */
212     char **argv;            /* Arguments to call the script. */
213     mstime_t start_time;    /* Script execution time if the script is running,
214                                otherwise 0 if we are allowed to retry the
215                                execution at any time. If the script is not
216                                running and it's not 0, it means: do not run
217                                before the specified time. */
218     pid_t pid;              /* Script execution pid. */
219 } sentinelScriptJob;
220 
221 /* ======================= hiredis ae.c adapters =============================
222  * Note: this implementation is taken from hiredis/adapters/ae.h, however
223  * we have our modified copy for Sentinel in order to use our allocator
224  * and to have full control over how the adapter works. */
225 
226 typedef struct redisAeEvents {
227     redisAsyncContext *context;
228     aeEventLoop *loop;
229     int fd;
230     int reading, writing;
231 } redisAeEvents;
232 
233 static void redisAeReadEvent(aeEventLoop *el, int fd, void *privdata, int mask) {
234     ((void)el); ((void)fd); ((void)mask);
235 
236     redisAeEvents *e = (redisAeEvents*)privdata;
237     redisAsyncHandleRead(e->context);
238 }
239 
240 static void redisAeWriteEvent(aeEventLoop *el, int fd, void *privdata, int mask) {
241     ((void)el); ((void)fd); ((void)mask);
242 
243     redisAeEvents *e = (redisAeEvents*)privdata;
244     redisAsyncHandleWrite(e->context);
245 }
246 
247 static void redisAeAddRead(void *privdata) {
248     redisAeEvents *e = (redisAeEvents*)privdata;
249     aeEventLoop *loop = e->loop;
250     if (!e->reading) {
251         e->reading = 1;
252         aeCreateFileEvent(loop,e->fd,AE_READABLE,redisAeReadEvent,e);
253     }
254 }
255 
256 static void redisAeDelRead(void *privdata) {
257     redisAeEvents *e = (redisAeEvents*)privdata;
258     aeEventLoop *loop = e->loop;
259     if (e->reading) {
260         e->reading = 0;
261         aeDeleteFileEvent(loop,e->fd,AE_READABLE);
262     }
263 }
264 
265 static void redisAeAddWrite(void *privdata) {
266     redisAeEvents *e = (redisAeEvents*)privdata;
267     aeEventLoop *loop = e->loop;
268     if (!e->writing) {
269         e->writing = 1;
270         aeCreateFileEvent(loop,e->fd,AE_WRITABLE,redisAeWriteEvent,e);
271     }
272 }
273 
274 static void redisAeDelWrite(void *privdata) {
275     redisAeEvents *e = (redisAeEvents*)privdata;
276     aeEventLoop *loop = e->loop;
277     if (e->writing) {
278         e->writing = 0;
279         aeDeleteFileEvent(loop,e->fd,AE_WRITABLE);
280     }
281 }
282 
283 static void redisAeCleanup(void *privdata) {
284     redisAeEvents *e = (redisAeEvents*)privdata;
285     redisAeDelRead(privdata);
286     redisAeDelWrite(privdata);
287     zfree(e);
288 }
289 
290 static int redisAeAttach(aeEventLoop *loop, redisAsyncContext *ac) {
291     redisContext *c = &(ac->c);
292     redisAeEvents *e;
293 
294     /* Nothing should be attached when something is already attached */
295     if (ac->ev.data != NULL)
296         return REDIS_ERR;
297 
298     /* Create container for context and r/w events */
299     e = (redisAeEvents*)zmalloc(sizeof(*e));
300     e->context = ac;
301     e->loop = loop;
302     e->fd = c->fd;
303     e->reading = e->writing = 0;
304 
305     /* Register functions to start/stop listening for events */
306     ac->ev.addRead = redisAeAddRead;
307     ac->ev.delRead = redisAeDelRead;
308     ac->ev.addWrite = redisAeAddWrite;
309     ac->ev.delWrite = redisAeDelWrite;
310     ac->ev.cleanup = redisAeCleanup;
311     ac->ev.data = e;
312 
313     return REDIS_OK;
314 }
315 
316 /* ============================= Prototypes ================================= */
317 
318 void sentinelLinkEstablishedCallback(const redisAsyncContext *c, int status);
319 void sentinelDisconnectCallback(const redisAsyncContext *c, int status);
320 void sentinelReceiveHelloMessages(redisAsyncContext *c, void *reply, void *privdata);
321 sentinelRedisInstance *sentinelGetMasterByName(char *name);
322 char *sentinelGetSubjectiveLeader(sentinelRedisInstance *master);
323 char *sentinelGetObjectiveLeader(sentinelRedisInstance *master);
324 int yesnotoi(char *s);
325 void sentinelDisconnectInstanceFromContext(const redisAsyncContext *c);
326 void sentinelKillLink(sentinelRedisInstance *ri, redisAsyncContext *c);
327 const char *sentinelRedisInstanceTypeStr(sentinelRedisInstance *ri);
328 void sentinelAbortFailover(sentinelRedisInstance *ri);
329 void sentinelEvent(int level, char *type, sentinelRedisInstance *ri, const char *fmt, ...);
330 sentinelRedisInstance *sentinelSelectSlave(sentinelRedisInstance *master);
331 void sentinelScheduleScriptExecution(char *path, ...);
332 void sentinelStartFailover(sentinelRedisInstance *master);
333 void sentinelDiscardReplyCallback(redisAsyncContext *c, void *reply, void *privdata);
334 int sentinelSendSlaveOf(sentinelRedisInstance *ri, char *host, int port);
335 char *sentinelVoteLeader(sentinelRedisInstance *master, uint64_t req_epoch, char *req_runid, uint64_t *leader_epoch);
336 void sentinelFlushConfig(void);
337 void sentinelGenerateInitialMonitorEvents(void);
338 int sentinelSendPing(sentinelRedisInstance *ri);
339 int sentinelForceHelloUpdateForMaster(sentinelRedisInstance *master);
340 
341 /* ========================= Dictionary types =============================== */
342 
343 unsigned int dictSdsHash(const void *key);
344 int dictSdsKeyCompare(void *privdata, const void *key1, const void *key2);
345 void releaseSentinelRedisInstance(sentinelRedisInstance *ri);
346 
347 void dictInstancesValDestructor (void *privdata, void *obj) {
348     releaseSentinelRedisInstance(obj);
349 }
350 
351 /* Instance name (sds) -> instance (sentinelRedisInstance pointer)
352  *
353  * also used for: sentinelRedisInstance->sentinels dictionary that maps
354  * sentinels ip:port to last seen time in Pub/Sub hello message. */
355 dictType instancesDictType = {
356     dictSdsHash,               /* hash function */
357     NULL,                      /* key dup */
358     NULL,                      /* val dup */
359     dictSdsKeyCompare,         /* key compare */
360     NULL,                      /* key destructor */
361     dictInstancesValDestructor /* val destructor */
362 };
363 
364 /* Instance runid (sds) -> votes (long casted to void*)
365  *
366  * This is useful into sentinelGetObjectiveLeader() function in order to
367  * count the votes and understand who is the leader. */
368 dictType leaderVotesDictType = {
369     dictSdsHash,               /* hash function */
370     NULL,                      /* key dup */
371     NULL,                      /* val dup */
372     dictSdsKeyCompare,         /* key compare */
373     NULL,                      /* key destructor */
374     NULL                       /* val destructor */
375 };
376 
377 /* =========================== Initialization =============================== */
378 
379 void sentinelCommand(redisClient *c);
380 void sentinelInfoCommand(redisClient *c);
381 void sentinelSetCommand(redisClient *c);
382 void sentinelPublishCommand(redisClient *c);
383 
384 struct redisCommand sentinelcmds[] = {
385     {"ping",pingCommand,1,"",0,NULL,0,0,0,0,0},
386     {"sentinel",sentinelCommand,-2,"",0,NULL,0,0,0,0,0},
387     {"subscribe",subscribeCommand,-2,"",0,NULL,0,0,0,0,0},
388     {"unsubscribe",unsubscribeCommand,-1,"",0,NULL,0,0,0,0,0},
389     {"psubscribe",psubscribeCommand,-2,"",0,NULL,0,0,0,0,0},
390     {"punsubscribe",punsubscribeCommand,-1,"",0,NULL,0,0,0,0,0},
391     {"publish",sentinelPublishCommand,3,"",0,NULL,0,0,0,0,0},
392     {"info",sentinelInfoCommand,-1,"",0,NULL,0,0,0,0,0},
393     {"shutdown",shutdownCommand,-1,"",0,NULL,0,0,0,0,0}
394 };
395 
396 /* This function overwrites a few normal Redis config default with Sentinel
397  * specific defaults. */
398 void initSentinelConfig(void) {
399     server.port = REDIS_SENTINEL_PORT;
400 }
401 
402 /* Perform the Sentinel mode initialization. */
403 void initSentinel(void) {
404     int j;
405 
406     /* Remove usual Redis commands from the command table, then just add
407      * the SENTINEL command. */
408     dictEmpty(server.commands,NULL);
409     for (j = 0; j < sizeof(sentinelcmds)/sizeof(sentinelcmds[0]); j++) {
410         int retval;
411         struct redisCommand *cmd = sentinelcmds+j;
412 
413         retval = dictAdd(server.commands, sdsnew(cmd->name), cmd);
414         redisAssert(retval == DICT_OK);
415     }
416 
417     /* Initialize various data structures. */
418     sentinel.current_epoch = 0;
419     sentinel.masters = dictCreate(&instancesDictType,NULL);
420     sentinel.tilt = 0;
421     sentinel.tilt_start_time = 0;
422     sentinel.previous_time = mstime();
423     sentinel.running_scripts = 0;
424     sentinel.scripts_queue = listCreate();
425 }
426 
427 /* This function gets called when the server is in Sentinel mode, started,
428  * loaded the configuration, and is ready for normal operations. */
429 void sentinelIsRunning(void) {
430     redisLog(REDIS_WARNING,"Sentinel runid is %s", server.runid);
431 
432     if (server.configfile == NULL) {
433         redisLog(REDIS_WARNING,
434             "Sentinel started without a config file. Exiting...");
435         exit(1);
436     } else if (access(server.configfile,W_OK) == -1) {
437         redisLog(REDIS_WARNING,
438             "Sentinel config file %s is not writable: %s. Exiting...",
439             server.configfile,strerror(errno));
440         exit(1);
441     }
442 
443     /* We want to generate a +monitor event for every configured master
444      * at startup. */
445     sentinelGenerateInitialMonitorEvents();
446 }
447 
448 /* ============================== sentinelAddr ============================== */
449 
450 /* Create a sentinelAddr object and return it on success.
451  * On error NULL is returned and errno is set to:
452  *  ENOENT: Can't resolve the hostname.
453  *  EINVAL: Invalid port number.
454  */
455 sentinelAddr *createSentinelAddr(char *hostname, int port) {
456     char buf[32];
457     sentinelAddr *sa;
458 
459     if (port <= 0 || port > 65535) {
460         errno = EINVAL;
461         return NULL;
462     }
463     if (anetResolve(NULL,hostname,buf,sizeof(buf)) == ANET_ERR) {
464         errno = ENOENT;
465         return NULL;
466     }
467     sa = zmalloc(sizeof(*sa));
468     sa->ip = sdsnew(buf);
469     sa->port = port;
470     return sa;
471 }
472 
473 /* Return a duplicate of the source address. */
474 sentinelAddr *dupSentinelAddr(sentinelAddr *src) {
475     sentinelAddr *sa;
476 
477     sa = zmalloc(sizeof(*sa));
478     sa->ip = sdsnew(src->ip);
479     sa->port = src->port;
480     return sa;
481 }
482 
483 /* Free a Sentinel address. Can't fail. */
484 void releaseSentinelAddr(sentinelAddr *sa) {
485     sdsfree(sa->ip);
486     zfree(sa);
487 }
488 
489 /* Return non-zero if two addresses are equal. */
490 int sentinelAddrIsEqual(sentinelAddr *a, sentinelAddr *b) {
491     return a->port == b->port && !strcasecmp(a->ip,b->ip);
492 }
493 
494 /* =========================== Events notification ========================== */
495 
496 /* Send an event to log, pub/sub, user notification script.
497  *
498  * 'level' is the log level for logging. Only REDIS_WARNING events will trigger
499  * the execution of the user notification script.
500  *
501  * 'type' is the message type, also used as a pub/sub channel name.
502  *
503  * 'ri', is the redis instance target of this event if applicable, and is
504  * used to obtain the path of the notification script to execute.
505  *
506  * The remaining arguments are printf-alike.
507  * If the format specifier starts with the two characters "%@" then ri is
508  * not NULL, and the message is prefixed with an instance identifier in the
509  * following format:
510  *
511  *  <instance type> <instance name> <ip> <port>
512  *
513  *  If the instance type is not master, than the additional string is
514  *  added to specify the originating master:
515  *
516  *  @ <master name> <master ip> <master port>
517  *
518  *  Any other specifier after "%@" is processed by printf itself.
519  */
520 void sentinelEvent(int level, char *type, sentinelRedisInstance *ri,
521                    const char *fmt, ...) {
522     va_list ap;
523     char msg[REDIS_MAX_LOGMSG_LEN];
524     robj *channel, *payload;
525 
526     /* Handle %@ */
527     if (fmt[0] == '%' && fmt[1] == '@') {
528         sentinelRedisInstance *master = (ri->flags & SRI_MASTER) ?
529                                          NULL : ri->master;
530 
531         if (master) {
532             snprintf(msg, sizeof(msg), "%s %s %s %d @ %s %s %d",
533                 sentinelRedisInstanceTypeStr(ri),
534                 ri->name, ri->addr->ip, ri->addr->port,
535                 master->name, master->addr->ip, master->addr->port);
536         } else {
537             snprintf(msg, sizeof(msg), "%s %s %s %d",
538                 sentinelRedisInstanceTypeStr(ri),
539                 ri->name, ri->addr->ip, ri->addr->port);
540         }
541         fmt += 2;
542     } else {
543         msg[0] = '\0';
544     }
545 
546     /* Use vsprintf for the rest of the formatting if any. */
547     if (fmt[0] != '\0') {
548         va_start(ap, fmt);
549         vsnprintf(msg+strlen(msg), sizeof(msg)-strlen(msg), fmt, ap);
550         va_end(ap);
551     }
552 
553     /* Log the message if the log level allows it to be logged. */
554     if (level >= server.verbosity)
555         redisLog(level,"%s %s",type,msg);
556 
557     /* Publish the message via Pub/Sub if it's not a debugging one. */
558     if (level != REDIS_DEBUG) {
559         channel = createStringObject(type,strlen(type));
560         payload = createStringObject(msg,strlen(msg));
561         pubsubPublishMessage(channel,payload);
562         decrRefCount(channel);
563         decrRefCount(payload);
564     }
565 
566     /* Call the notification script if applicable. */
567     if (level == REDIS_WARNING && ri != NULL) {
568         sentinelRedisInstance *master = (ri->flags & SRI_MASTER) ?
569                                          ri : ri->master;
570         if (master->notification_script) {
571             sentinelScheduleScriptExecution(master->notification_script,
572                 type,msg,NULL);
573         }
574     }
575 }
576 
577 /* This function is called only at startup and is used to generate a
578  * +monitor event for every configured master. The same events are also
579  * generated when a master to monitor is added at runtime via the
580  * SENTINEL MONITOR command. */
581 void sentinelGenerateInitialMonitorEvents(void) {
582     dictIterator *di;
583     dictEntry *de;
584 
585     di = dictGetIterator(sentinel.masters);
586     while((de = dictNext(di)) != NULL) {
587         sentinelRedisInstance *ri = dictGetVal(de);
588         sentinelEvent(REDIS_WARNING,"+monitor",ri,"%@ quorum %d",ri->quorum);
589     }
590     dictReleaseIterator(di);
591 }
592 
593 /* ============================ script execution ============================ */
594 
595 /* Release a script job structure and all the associated data. */
596 void sentinelReleaseScriptJob(sentinelScriptJob *sj) {
597     int j = 0;
598 
599     while(sj->argv[j]) sdsfree(sj->argv[j++]);
600     zfree(sj->argv);
601     zfree(sj);
602 }
603 
604 #define SENTINEL_SCRIPT_MAX_ARGS 16
605 void sentinelScheduleScriptExecution(char *path, ...) {
606     va_list ap;
607     char *argv[SENTINEL_SCRIPT_MAX_ARGS+1];
608     int argc = 1;
609     sentinelScriptJob *sj;
610 
611     va_start(ap, path);
612     while(argc < SENTINEL_SCRIPT_MAX_ARGS) {
613         argv[argc] = va_arg(ap,char*);
614         if (!argv[argc]) break;
615         argv[argc] = sdsnew(argv[argc]); /* Copy the string. */
616         argc++;
617     }
618     va_end(ap);
619     argv[0] = sdsnew(path);
620 
621     sj = zmalloc(sizeof(*sj));
622     sj->flags = SENTINEL_SCRIPT_NONE;
623     sj->retry_num = 0;
624     sj->argv = zmalloc(sizeof(char*)*(argc+1));
625     sj->start_time = 0;
626     sj->pid = 0;
627     memcpy(sj->argv,argv,sizeof(char*)*(argc+1));
628 
629     listAddNodeTail(sentinel.scripts_queue,sj);
630 
631     /* Remove the oldest non running script if we already hit the limit. */
632     if (listLength(sentinel.scripts_queue) > SENTINEL_SCRIPT_MAX_QUEUE) {
633         listNode *ln;
634         listIter li;
635 
636         listRewind(sentinel.scripts_queue,&li);
637         while ((ln = listNext(&li)) != NULL) {
638             sj = ln->value;
639 
640             if (sj->flags & SENTINEL_SCRIPT_RUNNING) continue;
641             /* The first node is the oldest as we add on tail. */
642             listDelNode(sentinel.scripts_queue,ln);
643             sentinelReleaseScriptJob(sj);
644             break;
645         }
646         redisAssert(listLength(sentinel.scripts_queue) <=
647                     SENTINEL_SCRIPT_MAX_QUEUE);
648     }
649 }
650 
651 /* Lookup a script in the scripts queue via pid, and returns the list node
652  * (so that we can easily remove it from the queue if needed). */
653 listNode *sentinelGetScriptListNodeByPid(pid_t pid) {
654     listNode *ln;
655     listIter li;
656 
657     listRewind(sentinel.scripts_queue,&li);
658     while ((ln = listNext(&li)) != NULL) {
659         sentinelScriptJob *sj = ln->value;
660 
661         if ((sj->flags & SENTINEL_SCRIPT_RUNNING) && sj->pid == pid)
662             return ln;
663     }
664     return NULL;
665 }
666 
667 /* Run pending scripts if we are not already at max number of running
668  * scripts. */
669 void sentinelRunPendingScripts(void) {
670     listNode *ln;
671     listIter li;
672     mstime_t now = mstime();
673 
674     /* Find jobs that are not running and run them, from the top to the
675      * tail of the queue, so we run older jobs first. */
676     listRewind(sentinel.scripts_queue,&li);
677     while (sentinel.running_scripts < SENTINEL_SCRIPT_MAX_RUNNING &&
678            (ln = listNext(&li)) != NULL)
679     {
680         sentinelScriptJob *sj = ln->value;
681         pid_t pid;
682 
683         /* Skip if already running. */
684         if (sj->flags & SENTINEL_SCRIPT_RUNNING) continue;
685 
686         /* Skip if it's a retry, but not enough time has elapsed. */
687         if (sj->start_time && sj->start_time > now) continue;
688 
689         sj->flags |= SENTINEL_SCRIPT_RUNNING;
690         sj->start_time = mstime();
691         sj->retry_num++;
692         pid = fork();
693 
694         if (pid == -1) {
695             /* Parent (fork error).
696              * We report fork errors as signal 99, in order to unify the
697              * reporting with other kind of errors. */
698             sentinelEvent(REDIS_WARNING,"-script-error",NULL,
699                           "%s %d %d", sj->argv[0], 99, 0);
700             sj->flags &= ~SENTINEL_SCRIPT_RUNNING;
701             sj->pid = 0;
702         } else if (pid == 0) {
703             /* Child */
704             execve(sj->argv[0],sj->argv,environ);
705             /* If we are here an error occurred. */
706             _exit(2); /* Don't retry execution. */
707         } else {
708             sentinel.running_scripts++;
709             sj->pid = pid;
710             sentinelEvent(REDIS_DEBUG,"+script-child",NULL,"%ld",(long)pid);
711         }
712     }
713 }
714 
715 /* How much to delay the execution of a script that we need to retry after
716  * an error?
717  *
718  * We double the retry delay for every further retry we do. So for instance
719  * if RETRY_DELAY is set to 30 seconds and the max number of retries is 10
720  * starting from the second attempt to execute the script the delays are:
721  * 30 sec, 60 sec, 2 min, 4 min, 8 min, 16 min, 32 min, 64 min, 128 min. */
722 mstime_t sentinelScriptRetryDelay(int retry_num) {
723     mstime_t delay = SENTINEL_SCRIPT_RETRY_DELAY;
724 
725     while (retry_num-- > 1) delay *= 2;
726     return delay;
727 }
728 
729 /* Check for scripts that terminated, and remove them from the queue if the
730  * script terminated successfully. If instead the script was terminated by
731  * a signal, or returned exit code "1", it is scheduled to run again if
732  * the max number of retries did not already elapsed. */
733 void sentinelCollectTerminatedScripts(void) {
734     int statloc;
735     pid_t pid;
736 
737     while ((pid = wait3(&statloc,WNOHANG,NULL)) > 0) {
738         int exitcode = WEXITSTATUS(statloc);
739         int bysignal = 0;
740         listNode *ln;
741         sentinelScriptJob *sj;
742 
743         if (WIFSIGNALED(statloc)) bysignal = WTERMSIG(statloc);
744         sentinelEvent(REDIS_DEBUG,"-script-child",NULL,"%ld %d %d",
745             (long)pid, exitcode, bysignal);
746 
747         ln = sentinelGetScriptListNodeByPid(pid);
748         if (ln == NULL) {
749             redisLog(REDIS_WARNING,"wait3() returned a pid (%ld) we can't find in our scripts execution queue!", (long)pid);
750             continue;
751         }
752         sj = ln->value;
753 
754         /* If the script was terminated by a signal or returns an
755          * exit code of "1" (that means: please retry), we reschedule it
756          * if the max number of retries is not already reached. */
757         if ((bysignal || exitcode == 1) &&
758             sj->retry_num != SENTINEL_SCRIPT_MAX_RETRY)
759         {
760             sj->flags &= ~SENTINEL_SCRIPT_RUNNING;
761             sj->pid = 0;
762             sj->start_time = mstime() +
763                              sentinelScriptRetryDelay(sj->retry_num);
764         } else {
765             /* Otherwise let's remove the script, but log the event if the
766              * execution did not terminated in the best of the ways. */
767             if (bysignal || exitcode != 0) {
768                 sentinelEvent(REDIS_WARNING,"-script-error",NULL,
769                               "%s %d %d", sj->argv[0], bysignal, exitcode);
770             }
771             listDelNode(sentinel.scripts_queue,ln);
772             sentinelReleaseScriptJob(sj);
773             sentinel.running_scripts--;
774         }
775     }
776 }
777 
778 /* Kill scripts in timeout, they'll be collected by the
779  * sentinelCollectTerminatedScripts() function. */
780 void sentinelKillTimedoutScripts(void) {
781     listNode *ln;
782     listIter li;
783     mstime_t now = mstime();
784 
785     listRewind(sentinel.scripts_queue,&li);
786     while ((ln = listNext(&li)) != NULL) {
787         sentinelScriptJob *sj = ln->value;
788 
789         if (sj->flags & SENTINEL_SCRIPT_RUNNING &&
790             (now - sj->start_time) > SENTINEL_SCRIPT_MAX_RUNTIME)
791         {
792             sentinelEvent(REDIS_WARNING,"-script-timeout",NULL,"%s %ld",
793                 sj->argv[0], (long)sj->pid);
794             kill(sj->pid,SIGKILL);
795         }
796     }
797 }
798 
799 /* Implements SENTINEL PENDING-SCRIPTS command. */
800 void sentinelPendingScriptsCommand(redisClient *c) {
801     listNode *ln;
802     listIter li;
803 
804     addReplyMultiBulkLen(c,listLength(sentinel.scripts_queue));
805     listRewind(sentinel.scripts_queue,&li);
806     while ((ln = listNext(&li)) != NULL) {
807         sentinelScriptJob *sj = ln->value;
808         int j = 0;
809 
810         addReplyMultiBulkLen(c,10);
811 
812         addReplyBulkCString(c,"argv");
813         while (sj->argv[j]) j++;
814         addReplyMultiBulkLen(c,j);
815         j = 0;
816         while (sj->argv[j]) addReplyBulkCString(c,sj->argv[j++]);
817 
818         addReplyBulkCString(c,"flags");
819         addReplyBulkCString(c,
820             (sj->flags & SENTINEL_SCRIPT_RUNNING) ? "running" : "scheduled");
821 
822         addReplyBulkCString(c,"pid");
823         addReplyBulkLongLong(c,sj->pid);
824 
825         if (sj->flags & SENTINEL_SCRIPT_RUNNING) {
826             addReplyBulkCString(c,"run-time");
827             addReplyBulkLongLong(c,mstime() - sj->start_time);
828         } else {
829             mstime_t delay = sj->start_time ? (sj->start_time-mstime()) : 0;
830             if (delay < 0) delay = 0;
831             addReplyBulkCString(c,"run-delay");
832             addReplyBulkLongLong(c,delay);
833         }
834 
835         addReplyBulkCString(c,"retry-num");
836         addReplyBulkLongLong(c,sj->retry_num);
837     }
838 }
839 
840 /* This function calls, if any, the client reconfiguration script with the
841  * following parameters:
842  *
843  * <master-name> <role> <state> <from-ip> <from-port> <to-ip> <to-port>
844  *
845  * It is called every time a failover is performed.
846  *
847  * <state> is currently always "failover".
848  * <role> is either "leader" or "observer".
849  *
850  * from/to fields are respectively master -> promoted slave addresses for
851  * "start" and "end". */
852 void sentinelCallClientReconfScript(sentinelRedisInstance *master, int role, char *state, sentinelAddr *from, sentinelAddr *to) {
853     char fromport[32], toport[32];
854 
855     if (master->client_reconfig_script == NULL) return;
856     ll2string(fromport,sizeof(fromport),from->port);
857     ll2string(toport,sizeof(toport),to->port);
858     sentinelScheduleScriptExecution(master->client_reconfig_script,
859         master->name,
860         (role == SENTINEL_LEADER) ? "leader" : "observer",
861         state, from->ip, fromport, to->ip, toport, NULL);
862 }
863 
864 /* ========================== sentinelRedisInstance ========================= */
865 
866 /* Create a redis instance, the following fields must be populated by the
867  * caller if needed:
868  * runid: set to NULL but will be populated once INFO output is received.
869  * info_refresh: is set to 0 to mean that we never received INFO so far.
870  *
871  * If SRI_MASTER is set into initial flags the instance is added to
872  * sentinel.masters table.
873  *
874  * if SRI_SLAVE or SRI_SENTINEL is set then 'master' must be not NULL and the
875  * instance is added into master->slaves or master->sentinels table.
876  *
877  * If the instance is a slave or sentinel, the name parameter is ignored and
878  * is created automatically as hostname:port.
879  *
880  * The function fails if hostname can't be resolved or port is out of range.
881  * When this happens NULL is returned and errno is set accordingly to the
882  * createSentinelAddr() function.
883  *
884  * The function may also fail and return NULL with errno set to EBUSY if
885  * a master or slave with the same name already exists. */
886 sentinelRedisInstance *createSentinelRedisInstance(char *name, int flags, char *hostname, int port, int quorum, sentinelRedisInstance *master) {
887     sentinelRedisInstance *ri;
888     sentinelAddr *addr;
889     dict *table = NULL;
890     char slavename[128], *sdsname;
891 
892     redisAssert(flags & (SRI_MASTER|SRI_SLAVE|SRI_SENTINEL));
893     redisAssert((flags & SRI_MASTER) || master != NULL);
894 
895     /* Check address validity. */
896     addr = createSentinelAddr(hostname,port);
897     if (addr == NULL) return NULL;
898 
899     /* For slaves and sentinel we use ip:port as name. */
900     if (flags & (SRI_SLAVE|SRI_SENTINEL)) {
901         snprintf(slavename,sizeof(slavename),
902             strchr(hostname,':') ? "[%s]:%d" : "%s:%d",
903             hostname,port);
904         name = slavename;
905     }
906 
907     /* Make sure the entry is not duplicated. This may happen when the same
908      * name for a master is used multiple times inside the configuration or
909      * if we try to add multiple times a slave or sentinel with same ip/port
910      * to a master. */
911     if (flags & SRI_MASTER) table = sentinel.masters;
912     else if (flags & SRI_SLAVE) table = master->slaves;
913     else if (flags & SRI_SENTINEL) table = master->sentinels;
914     sdsname = sdsnew(name);
915     if (dictFind(table,sdsname)) {
916         sdsfree(sdsname);
917         errno = EBUSY;
918         return NULL;
919     }
920 
921     /* Create the instance object. */
922     ri = zmalloc(sizeof(*ri));
923     /* Note that all the instances are started in the disconnected state,
924      * the event loop will take care of connecting them. */
925     ri->flags = flags | SRI_DISCONNECTED;
926     ri->name = sdsname;
927     ri->runid = NULL;
928     ri->config_epoch = 0;
929     ri->addr = addr;
930     ri->cc = NULL;
931     ri->pc = NULL;
932     ri->pending_commands = 0;
933     ri->cc_conn_time = 0;
934     ri->pc_conn_time = 0;
935     ri->pc_last_activity = 0;
936     /* We set the last_ping_time to "now" even if we actually don't have yet
937      * a connection with the node, nor we sent a ping.
938      * This is useful to detect a timeout in case we'll not be able to connect
939      * with the node at all. */
940     ri->last_ping_time = mstime();
941     ri->last_avail_time = mstime();
942     ri->last_pong_time = mstime();
943     ri->last_pub_time = mstime();
944     ri->last_hello_time = mstime();
945     ri->last_master_down_reply_time = mstime();
946     ri->s_down_since_time = 0;
947     ri->o_down_since_time = 0;
948     ri->down_after_period = master ? master->down_after_period :
949                             SENTINEL_DEFAULT_DOWN_AFTER;
950     ri->master_link_down_time = 0;
951     ri->auth_pass = NULL;
952     ri->slave_priority = SENTINEL_DEFAULT_SLAVE_PRIORITY;
953     ri->slave_reconf_sent_time = 0;
954     ri->slave_master_host = NULL;
955     ri->slave_master_port = 0;
956     ri->slave_master_link_status = SENTINEL_MASTER_LINK_STATUS_DOWN;
957     ri->slave_repl_offset = 0;
958     ri->sentinels = dictCreate(&instancesDictType,NULL);
959     ri->quorum = quorum;
960     ri->parallel_syncs = SENTINEL_DEFAULT_PARALLEL_SYNCS;
961     ri->master = master;
962     ri->slaves = dictCreate(&instancesDictType,NULL);
963     ri->info_refresh = 0;
964 
965     /* Failover state. */
966     ri->leader = NULL;
967     ri->leader_epoch = 0;
968     ri->failover_epoch = 0;
969     ri->failover_state = SENTINEL_FAILOVER_STATE_NONE;
970     ri->failover_state_change_time = 0;
971     ri->failover_start_time = 0;
972     ri->failover_timeout = SENTINEL_DEFAULT_FAILOVER_TIMEOUT;
973     ri->failover_delay_logged = 0;
974     ri->promoted_slave = NULL;
975     ri->notification_script = NULL;
976     ri->client_reconfig_script = NULL;
977 
978     /* Role */
979     ri->role_reported = ri->flags & (SRI_MASTER|SRI_SLAVE);
980     ri->role_reported_time = mstime();
981     ri->slave_conf_change_time = mstime();
982 
983     /* Add into the right table. */
984     dictAdd(table, ri->name, ri);
985     return ri;
986 }
987 
988 /* Release this instance and all its slaves, sentinels, hiredis connections.
989  * This function does not take care of unlinking the instance from the main
990  * masters table (if it is a master) or from its master sentinels/slaves table
991  * if it is a slave or sentinel. */
992 void releaseSentinelRedisInstance(sentinelRedisInstance *ri) {
993     /* Release all its slaves or sentinels if any. */
994     dictRelease(ri->sentinels);
995     dictRelease(ri->slaves);
996 
997     /* Release hiredis connections. */
998     if (ri->cc) sentinelKillLink(ri,ri->cc);
999     if (ri->pc) sentinelKillLink(ri,ri->pc);
1000 
1001     /* Free other resources. */
1002     sdsfree(ri->name);
1003     sdsfree(ri->runid);
1004     sdsfree(ri->notification_script);
1005     sdsfree(ri->client_reconfig_script);
1006     sdsfree(ri->slave_master_host);
1007     sdsfree(ri->leader);
1008     sdsfree(ri->auth_pass);
1009     releaseSentinelAddr(ri->addr);
1010 
1011     /* Clear state into the master if needed. */
1012     if ((ri->flags & SRI_SLAVE) && (ri->flags & SRI_PROMOTED) && ri->master)
1013         ri->master->promoted_slave = NULL;
1014 
1015     zfree(ri);
1016 }
1017 
1018 /* Lookup a slave in a master Redis instance, by ip and port. */
1019 sentinelRedisInstance *sentinelRedisInstanceLookupSlave(
1020                 sentinelRedisInstance *ri, char *ip, int port)
1021 {
1022     sds key;
1023     sentinelRedisInstance *slave;
1024 
1025     redisAssert(ri->flags & SRI_MASTER);
1026     key = sdscatprintf(sdsempty(),
1027         strchr(ip,':') ? "[%s]:%d" : "%s:%d",
1028         ip,port);
1029     slave = dictFetchValue(ri->slaves,key);
1030     sdsfree(key);
1031     return slave;
1032 }
1033 
1034 /* Return the name of the type of the instance as a string. */
1035 const char *sentinelRedisInstanceTypeStr(sentinelRedisInstance *ri) {
1036     if (ri->flags & SRI_MASTER) return "master";
1037     else if (ri->flags & SRI_SLAVE) return "slave";
1038     else if (ri->flags & SRI_SENTINEL) return "sentinel";
1039     else return "unknown";
1040 }
1041 
1042 /* This function removes all the instances found in the dictionary of
1043  * sentinels in the specified 'master', having either:
1044  *
1045  * 1) The same ip/port as specified.
1046  * 2) The same runid.
1047  *
1048  * "1" and "2" don't need to verify at the same time, just one is enough.
1049  * If "runid" is NULL it is not checked.
1050  * Similarly if "ip" is NULL it is not checked.
1051  *
1052  * This function is useful because every time we add a new Sentinel into
1053  * a master's Sentinels dictionary, we want to be very sure about not
1054  * having duplicated instances for any reason. This is important because
1055  * other sentinels are needed to reach ODOWN quorum, and later to get
1056  * voted for a given configuration epoch in order to perform the failover.
1057  *
1058  * The function returns the number of Sentinels removed. */
1059 int removeMatchingSentinelsFromMaster(sentinelRedisInstance *master, char *ip, int port, char *runid) {
1060     dictIterator *di;
1061     dictEntry *de;
1062     int removed = 0;
1063 
1064     di = dictGetSafeIterator(master->sentinels);
1065     while((de = dictNext(di)) != NULL) {
1066         sentinelRedisInstance *ri = dictGetVal(de);
1067 
1068         if ((ri->runid && runid && strcmp(ri->runid,runid) == 0) ||
1069             (ip && strcmp(ri->addr->ip,ip) == 0 && port == ri->addr->port))
1070         {
1071             dictDelete(master->sentinels,ri->name);
1072             removed++;
1073         }
1074     }
1075     dictReleaseIterator(di);
1076     return removed;
1077 }
1078 
1079 /* Search an instance with the same runid, ip and port into a dictionary
1080  * of instances. Return NULL if not found, otherwise return the instance
1081  * pointer.
1082  *
1083  * runid or ip can be NULL. In such a case the search is performed only
1084  * by the non-NULL field. */
1085 sentinelRedisInstance *getSentinelRedisInstanceByAddrAndRunID(dict *instances, char *ip, int port, char *runid) {
1086     dictIterator *di;
1087     dictEntry *de;
1088     sentinelRedisInstance *instance = NULL;
1089 
1090     redisAssert(ip || runid);   /* User must pass at least one search param. */
1091     di = dictGetIterator(instances);
1092     while((de = dictNext(di)) != NULL) {
1093         sentinelRedisInstance *ri = dictGetVal(de);
1094 
1095         if (runid && !ri->runid) continue;
1096         if ((runid == NULL || strcmp(ri->runid, runid) == 0) &&
1097             (ip == NULL || (strcmp(ri->addr->ip, ip) == 0 &&
1098                             ri->addr->port == port)))
1099         {
1100             instance = ri;
1101             break;
1102         }
1103     }
1104     dictReleaseIterator(di);
1105     return instance;
1106 }
1107 
1108 /* Master lookup by name */
1109 sentinelRedisInstance *sentinelGetMasterByName(char *name) {
1110     sentinelRedisInstance *ri;
1111     sds sdsname = sdsnew(name);
1112 
1113     ri = dictFetchValue(sentinel.masters,sdsname);
1114     sdsfree(sdsname);
1115     return ri;
1116 }
1117 
1118 /* Add the specified flags to all the instances in the specified dictionary. */
1119 void sentinelAddFlagsToDictOfRedisInstances(dict *instances, int flags) {
1120     dictIterator *di;
1121     dictEntry *de;
1122 
1123     di = dictGetIterator(instances);
1124     while((de = dictNext(di)) != NULL) {
1125         sentinelRedisInstance *ri = dictGetVal(de);
1126         ri->flags |= flags;
1127     }
1128     dictReleaseIterator(di);
1129 }
1130 
1131 /* Remove the specified flags to all the instances in the specified
1132  * dictionary. */
1133 void sentinelDelFlagsToDictOfRedisInstances(dict *instances, int flags) {
1134     dictIterator *di;
1135     dictEntry *de;
1136 
1137     di = dictGetIterator(instances);
1138     while((de = dictNext(di)) != NULL) {
1139         sentinelRedisInstance *ri = dictGetVal(de);
1140         ri->flags &= ~flags;
1141     }
1142     dictReleaseIterator(di);
1143 }
1144 
1145 /* Reset the state of a monitored master:
1146  * 1) Remove all slaves.
1147  * 2) Remove all sentinels.
1148  * 3) Remove most of the flags resulting from runtime operations.
1149  * 4) Reset timers to their default value.
1150  * 5) In the process of doing this undo the failover if in progress.
1151  * 6) Disconnect the connections with the master (will reconnect automatically).
1152  */
1153 
1154 #define SENTINEL_RESET_NO_SENTINELS (1<<0)
1155 void sentinelResetMaster(sentinelRedisInstance *ri, int flags) {
1156     redisAssert(ri->flags & SRI_MASTER);
1157     dictRelease(ri->slaves);
1158     ri->slaves = dictCreate(&instancesDictType,NULL);
1159     if (!(flags & SENTINEL_RESET_NO_SENTINELS)) {
1160         dictRelease(ri->sentinels);
1161         ri->sentinels = dictCreate(&instancesDictType,NULL);
1162     }
1163     if (ri->cc) sentinelKillLink(ri,ri->cc);
1164     if (ri->pc) sentinelKillLink(ri,ri->pc);
1165     ri->flags &= SRI_MASTER|SRI_DISCONNECTED;
1166     if (ri->leader) {
1167         sdsfree(ri->leader);
1168         ri->leader = NULL;
1169     }
1170     ri->failover_state = SENTINEL_FAILOVER_STATE_NONE;
1171     ri->failover_state_change_time = 0;
1172     ri->failover_start_time = 0;
1173     ri->promoted_slave = NULL;
1174     sdsfree(ri->runid);
1175     sdsfree(ri->slave_master_host);
1176     ri->runid = NULL;
1177     ri->slave_master_host = NULL;
1178     ri->last_ping_time = mstime();
1179     ri->last_avail_time = mstime();
1180     ri->last_pong_time = mstime();
1181     ri->role_reported_time = mstime();
1182     ri->role_reported = SRI_MASTER;
1183     if (flags & SENTINEL_GENERATE_EVENT)
1184         sentinelEvent(REDIS_WARNING,"+reset-master",ri,"%@");
1185 }
1186 
1187 /* Call sentinelResetMaster() on every master with a name matching the specified
1188  * pattern. */
1189 int sentinelResetMastersByPattern(char *pattern, int flags) {
1190     dictIterator *di;
1191     dictEntry *de;
1192     int reset = 0;
1193 
1194     di = dictGetIterator(sentinel.masters);
1195     while((de = dictNext(di)) != NULL) {
1196         sentinelRedisInstance *ri = dictGetVal(de);
1197 
1198         if (ri->name) {
1199             if (stringmatch(pattern,ri->name,0)) {
1200                 sentinelResetMaster(ri,flags);
1201                 reset++;
1202             }
1203         }
1204     }
1205     dictReleaseIterator(di);
1206     return reset;
1207 }
1208 
1209 /* Reset the specified master with sentinelResetMaster(), and also change
1210  * the ip:port address, but take the name of the instance unmodified.
1211  *
1212  * This is used to handle the +switch-master event.
1213  *
1214  * The function returns REDIS_ERR if the address can't be resolved for some
1215  * reason. Otherwise REDIS_OK is returned.  */
1216 int sentinelResetMasterAndChangeAddress(sentinelRedisInstance *master, char *ip, int port) {
1217     sentinelAddr *oldaddr, *newaddr;
1218     sentinelAddr **slaves = NULL;
1219     int numslaves = 0, j;
1220     dictIterator *di;
1221     dictEntry *de;
1222 
1223     newaddr = createSentinelAddr(ip,port);
1224     if (newaddr == NULL) return REDIS_ERR;
1225 
1226     /* Make a list of slaves to add back after the reset.
1227      * Don't include the one having the address we are switching to. */
1228     di = dictGetIterator(master->slaves);
1229     while((de = dictNext(di)) != NULL) {
1230         sentinelRedisInstance *slave = dictGetVal(de);
1231 
1232         if (sentinelAddrIsEqual(slave->addr,newaddr)) continue;
1233         slaves = zrealloc(slaves,sizeof(sentinelAddr*)*(numslaves+1));
1234         slaves[numslaves++] = createSentinelAddr(slave->addr->ip,
1235                                                  slave->addr->port);
1236     }
1237     dictReleaseIterator(di);
1238 
1239     /* If we are switching to a different address, include the old address
1240      * as a slave as well, so that we'll be able to sense / reconfigure
1241      * the old master. */
1242     if (!sentinelAddrIsEqual(newaddr,master->addr)) {
1243         slaves = zrealloc(slaves,sizeof(sentinelAddr*)*(numslaves+1));
1244         slaves[numslaves++] = createSentinelAddr(master->addr->ip,
1245                                                  master->addr->port);
1246     }
1247 
1248     /* Reset and switch address. */
1249     sentinelResetMaster(master,SENTINEL_RESET_NO_SENTINELS);
1250     oldaddr = master->addr;
1251     master->addr = newaddr;
1252     master->o_down_since_time = 0;
1253     master->s_down_since_time = 0;
1254 
1255     /* Add slaves back. */
1256     for (j = 0; j < numslaves; j++) {
1257         sentinelRedisInstance *slave;
1258 
1259         slave = createSentinelRedisInstance(NULL,SRI_SLAVE,slaves[j]->ip,
1260                     slaves[j]->port, master->quorum, master);
1261         releaseSentinelAddr(slaves[j]);
1262         if (slave) {
1263             sentinelEvent(REDIS_NOTICE,"+slave",slave,"%@");
1264             sentinelFlushConfig();
1265         }
1266     }
1267     zfree(slaves);
1268 
1269     /* Release the old address at the end so we are safe even if the function
1270      * gets the master->addr->ip and master->addr->port as arguments. */
1271     releaseSentinelAddr(oldaddr);
1272     sentinelFlushConfig();
1273     return REDIS_OK;
1274 }
1275 
1276 /* Return non-zero if there was no SDOWN or ODOWN error associated to this
1277  * instance in the latest 'ms' milliseconds. */
1278 int sentinelRedisInstanceNoDownFor(sentinelRedisInstance *ri, mstime_t ms) {
1279     mstime_t most_recent;
1280 
1281     most_recent = ri->s_down_since_time;
1282     if (ri->o_down_since_time > most_recent)
1283         most_recent = ri->o_down_since_time;
1284     return most_recent == 0 || (mstime() - most_recent) > ms;
1285 }
1286 
1287 /* Return the current master address, that is, its address or the address
1288  * of the promoted slave if already operational. */
1289 sentinelAddr *sentinelGetCurrentMasterAddress(sentinelRedisInstance *master) {
1290     /* If we are failing over the master, and the state is already
1291      * SENTINEL_FAILOVER_STATE_RECONF_SLAVES or greater, it means that we
1292      * already have the new configuration epoch in the master, and the
1293      * slave acknowledged the configuration switch. Advertise the new
1294      * address. */
1295     if ((master->flags & SRI_FAILOVER_IN_PROGRESS) &&
1296         master->promoted_slave &&
1297         master->failover_state >= SENTINEL_FAILOVER_STATE_RECONF_SLAVES)
1298     {
1299         return master->promoted_slave->addr;
1300     } else {
1301         return master->addr;
1302     }
1303 }
1304 
1305 /* This function sets the down_after_period field value in 'master' to all
1306  * the slaves and sentinel instances connected to this master. */
1307 void sentinelPropagateDownAfterPeriod(sentinelRedisInstance *master) {
1308     dictIterator *di;
1309     dictEntry *de;
1310     int j;
1311     dict *d[] = {master->slaves, master->sentinels, NULL};
1312 
1313     for (j = 0; d[j]; j++) {
1314         di = dictGetIterator(d[j]);
1315         while((de = dictNext(di)) != NULL) {
1316             sentinelRedisInstance *ri = dictGetVal(de);
1317             ri->down_after_period = master->down_after_period;
1318         }
1319         dictReleaseIterator(di);
1320     }
1321 }
1322 
1323 /* ============================ Config handling ============================= */
1324 char *sentinelHandleConfiguration(char **argv, int argc) {
1325     sentinelRedisInstance *ri;
1326 
1327     if (!strcasecmp(argv[0],"monitor") && argc == 5) {
1328         /* monitor <name> <host> <port> <quorum> */
1329         int quorum = atoi(argv[4]);
1330 
1331         if (quorum <= 0) return "Quorum must be 1 or greater.";
1332         if (createSentinelRedisInstance(argv[1],SRI_MASTER,argv[2],
1333                                         atoi(argv[3]),quorum,NULL) == NULL)
1334         {
1335             switch(errno) {
1336             case EBUSY: return "Duplicated master name.";
1337             case ENOENT: return "Can't resolve master instance hostname.";
1338             case EINVAL: return "Invalid port number";
1339             }
1340         }
1341     } else if (!strcasecmp(argv[0],"down-after-milliseconds") && argc == 3) {
1342         /* down-after-milliseconds <name> <milliseconds> */
1343         ri = sentinelGetMasterByName(argv[1]);
1344         if (!ri) return "No such master with specified name.";
1345         ri->down_after_period = atoi(argv[2]);
1346         if (ri->down_after_period <= 0)
1347             return "negative or zero time parameter.";
1348         sentinelPropagateDownAfterPeriod(ri);
1349     } else if (!strcasecmp(argv[0],"failover-timeout") && argc == 3) {
1350         /* failover-timeout <name> <milliseconds> */
1351         ri = sentinelGetMasterByName(argv[1]);
1352         if (!ri) return "No such master with specified name.";
1353         ri->failover_timeout = atoi(argv[2]);
1354         if (ri->failover_timeout <= 0)
1355             return "negative or zero time parameter.";
1356    } else if (!strcasecmp(argv[0],"parallel-syncs") && argc == 3) {
1357         /* parallel-syncs <name> <milliseconds> */
1358         ri = sentinelGetMasterByName(argv[1]);
1359         if (!ri) return "No such master with specified name.";
1360         ri->parallel_syncs = atoi(argv[2]);
1361    } else if (!strcasecmp(argv[0],"notification-script") && argc == 3) {
1362         /* notification-script <name> <path> */
1363         ri = sentinelGetMasterByName(argv[1]);
1364         if (!ri) return "No such master with specified name.";
1365         if (access(argv[2],X_OK) == -1)
1366             return "Notification script seems non existing or non executable.";
1367         ri->notification_script = sdsnew(argv[2]);
1368    } else if (!strcasecmp(argv[0],"client-reconfig-script") && argc == 3) {
1369         /* client-reconfig-script <name> <path> */
1370         ri = sentinelGetMasterByName(argv[1]);
1371         if (!ri) return "No such master with specified name.";
1372         if (access(argv[2],X_OK) == -1)
1373             return "Client reconfiguration script seems non existing or "
1374                    "non executable.";
1375         ri->client_reconfig_script = sdsnew(argv[2]);
1376    } else if (!strcasecmp(argv[0],"auth-pass") && argc == 3) {
1377         /* auth-pass <name> <password> */
1378         ri = sentinelGetMasterByName(argv[1]);
1379         if (!ri) return "No such master with specified name.";
1380         ri->auth_pass = sdsnew(argv[2]);
1381     } else if (!strcasecmp(argv[0],"current-epoch") && argc == 2) {
1382         /* current-epoch <epoch> */
1383         unsigned long long current_epoch = strtoull(argv[1],NULL,10);
1384         if (current_epoch > sentinel.current_epoch)
1385             sentinel.current_epoch = current_epoch;
1386     } else if (!strcasecmp(argv[0],"config-epoch") && argc == 3) {
1387         /* config-epoch <name> <epoch> */
1388         ri = sentinelGetMasterByName(argv[1]);
1389         if (!ri) return "No such master with specified name.";
1390         ri->config_epoch = strtoull(argv[2],NULL,10);
1391         /* The following update of current_epoch is not really useful as
1392          * now the current epoch is persisted on the config file, but
1393          * we leave this check here for redundancy. */
1394         if (ri->config_epoch > sentinel.current_epoch)
1395             sentinel.current_epoch = ri->config_epoch;
1396     } else if (!strcasecmp(argv[0],"leader-epoch") && argc == 3) {
1397         /* leader-epoch <name> <epoch> */
1398         ri = sentinelGetMasterByName(argv[1]);
1399         if (!ri) return "No such master with specified name.";
1400         ri->leader_epoch = strtoull(argv[2],NULL,10);
1401     } else if (!strcasecmp(argv[0],"known-slave") && argc == 4) {
1402         sentinelRedisInstance *slave;
1403 
1404         /* known-slave <name> <ip> <port> */
1405         ri = sentinelGetMasterByName(argv[1]);
1406         if (!ri) return "No such master with specified name.";
1407         if ((slave = createSentinelRedisInstance(NULL,SRI_SLAVE,argv[2],
1408                     atoi(argv[3]), ri->quorum, ri)) == NULL)
1409         {
1410             return "Wrong hostname or port for slave.";
1411         }
1412     } else if (!strcasecmp(argv[0],"known-sentinel") &&
1413                (argc == 4 || argc == 5)) {
1414         sentinelRedisInstance *si;
1415 
1416         /* known-sentinel <name> <ip> <port> [runid] */
1417         ri = sentinelGetMasterByName(argv[1]);
1418         if (!ri) return "No such master with specified name.";
1419         if ((si = createSentinelRedisInstance(NULL,SRI_SENTINEL,argv[2],
1420                     atoi(argv[3]), ri->quorum, ri)) == NULL)
1421         {
1422             return "Wrong hostname or port for sentinel.";
1423         }
1424         if (argc == 5) si->runid = sdsnew(argv[4]);
1425     } else {
1426         return "Unrecognized sentinel configuration statement.";
1427     }
1428     return NULL;
1429 }
1430 
1431 /* Implements CONFIG REWRITE for "sentinel" option.
1432  * This is used not just to rewrite the configuration given by the user
1433  * (the configured masters) but also in order to retain the state of
1434  * Sentinel across restarts: config epoch of masters, associated slaves
1435  * and sentinel instances, and so forth. */
1436 void rewriteConfigSentinelOption(struct rewriteConfigState *state) {
1437     dictIterator *di, *di2;
1438     dictEntry *de;
1439     sds line;
1440 
1441     /* For every master emit a "sentinel monitor" config entry. */
1442     di = dictGetIterator(sentinel.masters);
1443     while((de = dictNext(di)) != NULL) {
1444         sentinelRedisInstance *master, *ri;
1445         sentinelAddr *master_addr;
1446 
1447         /* sentinel monitor */
1448         master = dictGetVal(de);
1449         master_addr = sentinelGetCurrentMasterAddress(master);
1450         line = sdscatprintf(sdsempty(),"sentinel monitor %s %s %d %d",
1451             master->name, master_addr->ip, master_addr->port,
1452             master->quorum);
1453         rewriteConfigRewriteLine(state,"sentinel",line,1);
1454 
1455         /* sentinel down-after-milliseconds */
1456         if (master->down_after_period != SENTINEL_DEFAULT_DOWN_AFTER) {
1457             line = sdscatprintf(sdsempty(),
1458                 "sentinel down-after-milliseconds %s %ld",
1459                 master->name, (long) master->down_after_period);
1460             rewriteConfigRewriteLine(state,"sentinel",line,1);
1461         }
1462 
1463         /* sentinel failover-timeout */
1464         if (master->failover_timeout != SENTINEL_DEFAULT_FAILOVER_TIMEOUT) {
1465             line = sdscatprintf(sdsempty(),
1466                 "sentinel failover-timeout %s %ld",
1467                 master->name, (long) master->failover_timeout);
1468             rewriteConfigRewriteLine(state,"sentinel",line,1);
1469         }
1470 
1471         /* sentinel parallel-syncs */
1472         if (master->parallel_syncs != SENTINEL_DEFAULT_PARALLEL_SYNCS) {
1473             line = sdscatprintf(sdsempty(),
1474                 "sentinel parallel-syncs %s %d",
1475                 master->name, master->parallel_syncs);
1476             rewriteConfigRewriteLine(state,"sentinel",line,1);
1477         }
1478 
1479         /* sentinel notification-script */
1480         if (master->notification_script) {
1481             line = sdscatprintf(sdsempty(),
1482                 "sentinel notification-script %s %s",
1483                 master->name, master->notification_script);
1484             rewriteConfigRewriteLine(state,"sentinel",line,1);
1485         }
1486 
1487         /* sentinel client-reconfig-script */
1488         if (master->client_reconfig_script) {
1489             line = sdscatprintf(sdsempty(),
1490                 "sentinel client-reconfig-script %s %s",
1491                 master->name, master->client_reconfig_script);
1492             rewriteConfigRewriteLine(state,"sentinel",line,1);
1493         }
1494 
1495         /* sentinel auth-pass */
1496         if (master->auth_pass) {
1497             line = sdscatprintf(sdsempty(),
1498                 "sentinel auth-pass %s %s",
1499                 master->name, master->auth_pass);
1500             rewriteConfigRewriteLine(state,"sentinel",line,1);
1501         }
1502 
1503         /* sentinel config-epoch */
1504         line = sdscatprintf(sdsempty(),
1505             "sentinel config-epoch %s %llu",
1506             master->name, (unsigned long long) master->config_epoch);
1507         rewriteConfigRewriteLine(state,"sentinel",line,1);
1508 
1509         /* sentinel leader-epoch */
1510         line = sdscatprintf(sdsempty(),
1511             "sentinel leader-epoch %s %llu",
1512             master->name, (unsigned long long) master->leader_epoch);
1513         rewriteConfigRewriteLine(state,"sentinel",line,1);
1514 
1515         /* sentinel known-slave */
1516         di2 = dictGetIterator(master->slaves);
1517         while((de = dictNext(di2)) != NULL) {
1518             sentinelAddr *slave_addr;
1519 
1520             ri = dictGetVal(de);
1521             slave_addr = ri->addr;
1522 
1523             /* If master_addr (obtained using sentinelGetCurrentMasterAddress()
1524              * so it may be the address of the promoted slave) is equal to this
1525              * slave's address, a failover is in progress and the slave was
1526              * already successfully promoted. So as the address of this slave
1527              * we use the old master address instead. */
1528             if (sentinelAddrIsEqual(slave_addr,master_addr))
1529                 slave_addr = master->addr;
1530             line = sdscatprintf(sdsempty(),
1531                 "sentinel known-slave %s %s %d",
1532                 master->name, ri->addr->ip, ri->addr->port);
1533             rewriteConfigRewriteLine(state,"sentinel",line,1);
1534         }
1535         dictReleaseIterator(di2);
1536 
1537         /* sentinel known-sentinel */
1538         di2 = dictGetIterator(master->sentinels);
1539         while((de = dictNext(di2)) != NULL) {
1540             ri = dictGetVal(de);
1541             line = sdscatprintf(sdsempty(),
1542                 "sentinel known-sentinel %s %s %d%s%s",
1543                 master->name, ri->addr->ip, ri->addr->port,
1544                 ri->runid ? " " : "",
1545                 ri->runid ? ri->runid : "");
1546             rewriteConfigRewriteLine(state,"sentinel",line,1);
1547         }
1548         dictReleaseIterator(di2);
1549     }
1550 
1551     /* sentinel current-epoch is a global state valid for all the masters. */
1552     line = sdscatprintf(sdsempty(),
1553         "sentinel current-epoch %llu", (unsigned long long) sentinel.current_epoch);
1554     rewriteConfigRewriteLine(state,"sentinel",line,1);
1555 
1556     dictReleaseIterator(di);
1557 }
1558 
1559 /* This function uses the config rewriting Redis engine in order to persist
1560  * the state of the Sentinel in the current configuration file.
1561  *
1562  * Before returning the function calls fsync() against the generated
1563  * configuration file to make sure changes are committed to disk.
1564  *
1565  * On failure the function logs a warning on the Redis log. */
1566 void sentinelFlushConfig(void) {
1567     int fd = -1;
1568     int saved_hz = server.hz;
1569     int rewrite_status;
1570 
1571     server.hz = REDIS_DEFAULT_HZ;
1572     rewrite_status = rewriteConfig(server.configfile);
1573     server.hz = saved_hz;
1574 
1575     if (rewrite_status == -1) goto werr;
1576     if ((fd = open(server.configfile,O_RDONLY)) == -1) goto werr;
1577     if (fsync(fd) == -1) goto werr;
1578     if (close(fd) == EOF) goto werr;
1579     return;
1580 
1581 werr:
1582     if (fd != -1) close(fd);
1583     redisLog(REDIS_WARNING,"WARNING: Sentinel was not able to save the new configuration on disk!!!: %s", strerror(errno));
1584 }
1585 
1586 /* ====================== hiredis connection handling ======================= */
1587 
1588 /* Completely disconnect a hiredis link from an instance. */
1589 void sentinelKillLink(sentinelRedisInstance *ri, redisAsyncContext *c) {
1590     if (ri->cc == c) {
1591         ri->cc = NULL;
1592         ri->pending_commands = 0;
1593     }
1594     if (ri->pc == c) ri->pc = NULL;
1595     c->data = NULL;
1596     ri->flags |= SRI_DISCONNECTED;
1597     redisAsyncFree(c);
1598 }
1599 
1600 /* This function takes a hiredis context that is in an error condition
1601  * and make sure to mark the instance as disconnected performing the
1602  * cleanup needed.
1603  *
1604  * Note: we don't free the hiredis context as hiredis will do it for us
1605  * for async connections. */
1606 void sentinelDisconnectInstanceFromContext(const redisAsyncContext *c) {
1607     sentinelRedisInstance *ri = c->data;
1608     int pubsub;
1609 
1610     if (ri == NULL) return; /* The instance no longer exists. */
1611 
1612     pubsub = (ri->pc == c);
1613     sentinelEvent(REDIS_DEBUG, pubsub ? "-pubsub-link" : "-cmd-link", ri,
1614         "%@ #%s", c->errstr);
1615     if (pubsub)
1616         ri->pc = NULL;
1617     else
1618         ri->cc = NULL;
1619     ri->flags |= SRI_DISCONNECTED;
1620 }
1621 
1622 void sentinelLinkEstablishedCallback(const redisAsyncContext *c, int status) {
1623     if (status != REDIS_OK) {
1624         sentinelDisconnectInstanceFromContext(c);
1625     } else {
1626         sentinelRedisInstance *ri = c->data;
1627         int pubsub = (ri->pc == c);
1628 
1629         sentinelEvent(REDIS_DEBUG, pubsub ? "+pubsub-link" : "+cmd-link", ri,
1630             "%@");
1631     }
1632 }
1633 
1634 void sentinelDisconnectCallback(const redisAsyncContext *c, int status) {
1635     sentinelDisconnectInstanceFromContext(c);
1636 }
1637 
1638 /* Send the AUTH command with the specified master password if needed.
1639  * Note that for slaves the password set for the master is used.
1640  *
1641  * We don't check at all if the command was successfully transmitted
1642  * to the instance as if it fails Sentinel will detect the instance down,
1643  * will disconnect and reconnect the link and so forth. */
1644 void sentinelSendAuthIfNeeded(sentinelRedisInstance *ri, redisAsyncContext *c) {
1645     char *auth_pass = (ri->flags & SRI_MASTER) ? ri->auth_pass :
1646                                                  ri->master->auth_pass;
1647 
1648     if (auth_pass) {
1649         if (redisAsyncCommand(c, sentinelDiscardReplyCallback, NULL, "AUTH %s",
1650             auth_pass) == REDIS_OK) ri->pending_commands++;
1651     }
1652 }
1653 
1654 /* Use CLIENT SETNAME to name the connection in the Redis instance as
1655  * sentinel-<first_8_chars_of_runid>-<connection_type>
1656  * The connection type is "cmd" or "pubsub" as specified by 'type'.
1657  *
1658  * This makes it possible to list all the sentinel instances connected
1659  * to a Redis servewr with CLIENT LIST, grepping for a specific name format. */
1660 void sentinelSetClientName(sentinelRedisInstance *ri, redisAsyncContext *c, char *type) {
1661     char name[64];
1662 
1663     snprintf(name,sizeof(name),"sentinel-%.8s-%s",server.runid,type);
1664     if (redisAsyncCommand(c, sentinelDiscardReplyCallback, NULL,
1665         "CLIENT SETNAME %s", name) == REDIS_OK)
1666     {
1667         ri->pending_commands++;
1668     }
1669 }
1670 
1671 /* Create the async connections for the specified instance if the instance
1672  * is disconnected. Note that the SRI_DISCONNECTED flag is set even if just
1673  * one of the two links (commands and pub/sub) is missing. */
1674 void sentinelReconnectInstance(sentinelRedisInstance *ri) {
1675     if (!(ri->flags & SRI_DISCONNECTED)) return;
1676 
1677     /* Commands connection. */
1678     if (ri->cc == NULL) {
1679         ri->cc = redisAsyncConnect(ri->addr->ip,ri->addr->port);
1680         if (ri->cc->err) {
1681             sentinelEvent(REDIS_DEBUG,"-cmd-link-reconnection",ri,"%@ #%s",
1682                 ri->cc->errstr);
1683             sentinelKillLink(ri,ri->cc);
1684         } else {
1685             ri->cc_conn_time = mstime();
1686             ri->cc->data = ri;
1687             redisAeAttach(server.el,ri->cc);
1688             redisAsyncSetConnectCallback(ri->cc,
1689                                             sentinelLinkEstablishedCallback);
1690             redisAsyncSetDisconnectCallback(ri->cc,
1691                                             sentinelDisconnectCallback);
1692             sentinelSendAuthIfNeeded(ri,ri->cc);
1693             sentinelSetClientName(ri,ri->cc,"cmd");
1694 
1695             /* Send a PING ASAP when reconnecting. */
1696             sentinelSendPing(ri);
1697         }
1698     }
1699     /* Pub / Sub */
1700     if ((ri->flags & (SRI_MASTER|SRI_SLAVE)) && ri->pc == NULL) {
1701         ri->pc = redisAsyncConnect(ri->addr->ip,ri->addr->port);
1702         if (ri->pc->err) {
1703             sentinelEvent(REDIS_DEBUG,"-pubsub-link-reconnection",ri,"%@ #%s",
1704                 ri->pc->errstr);
1705             sentinelKillLink(ri,ri->pc);
1706         } else {
1707             int retval;
1708 
1709             ri->pc_conn_time = mstime();
1710             ri->pc->data = ri;
1711             redisAeAttach(server.el,ri->pc);
1712             redisAsyncSetConnectCallback(ri->pc,
1713                                             sentinelLinkEstablishedCallback);
1714             redisAsyncSetDisconnectCallback(ri->pc,
1715                                             sentinelDisconnectCallback);
1716             sentinelSendAuthIfNeeded(ri,ri->pc);
1717             sentinelSetClientName(ri,ri->pc,"pubsub");
1718             /* Now we subscribe to the Sentinels "Hello" channel. */
1719             retval = redisAsyncCommand(ri->pc,
1720                 sentinelReceiveHelloMessages, NULL, "SUBSCRIBE %s",
1721                     SENTINEL_HELLO_CHANNEL);
1722             if (retval != REDIS_OK) {
1723                 /* If we can't subscribe, the Pub/Sub connection is useless
1724                  * and we can simply disconnect it and try again. */
1725                 sentinelKillLink(ri,ri->pc);
1726                 return;
1727             }
1728         }
1729     }
1730     /* Clear the DISCONNECTED flags only if we have both the connections
1731      * (or just the commands connection if this is a sentinel instance). */
1732     if (ri->cc && (ri->flags & SRI_SENTINEL || ri->pc))
1733         ri->flags &= ~SRI_DISCONNECTED;
1734 }
1735 
1736 /* ======================== Redis instances pinging  ======================== */
1737 
1738 /* Return true if master looks "sane", that is:
1739  * 1) It is actually a master in the current configuration.
1740  * 2) It reports itself as a master.
1741  * 3) It is not SDOWN or ODOWN.
1742  * 4) We obtained last INFO no more than two times the INFO period time ago. */
1743 int sentinelMasterLooksSane(sentinelRedisInstance *master) {
1744     return
1745         master->flags & SRI_MASTER &&
1746         master->role_reported == SRI_MASTER &&
1747         (master->flags & (SRI_S_DOWN|SRI_O_DOWN)) == 0 &&
1748         (mstime() - master->info_refresh) < SENTINEL_INFO_PERIOD*2;
1749 }
1750 
1751 /* Process the INFO output from masters. */
1752 void sentinelRefreshInstanceInfo(sentinelRedisInstance *ri, const char *info) {
1753     sds *lines;
1754     int numlines, j;
1755     int role = 0;
1756 
1757     /* The following fields must be reset to a given value in the case they
1758      * are not found at all in the INFO output. */
1759     ri->master_link_down_time = 0;
1760 
1761     /* Process line by line. */
1762     lines = sdssplitlen(info,strlen(info),"\r\n",2,&numlines);
1763     for (j = 0; j < numlines; j++) {
1764         sentinelRedisInstance *slave;
1765         sds l = lines[j];
1766 
1767         /* run_id:<40 hex chars>*/
1768         if (sdslen(l) >= 47 && !memcmp(l,"run_id:",7)) {
1769             if (ri->runid == NULL) {
1770                 ri->runid = sdsnewlen(l+7,40);
1771             } else {
1772                 if (strncmp(ri->runid,l+7,40) != 0) {
1773                     sentinelEvent(REDIS_NOTICE,"+reboot",ri,"%@");
1774                     sdsfree(ri->runid);
1775                     ri->runid = sdsnewlen(l+7,40);
1776                 }
1777             }
1778         }
1779 
1780         /* old versions: slave0:<ip>,<port>,<state>
1781          * new versions: slave0:ip=127.0.0.1,port=9999,... */
1782         if ((ri->flags & SRI_MASTER) &&
1783             sdslen(l) >= 7 &&
1784             !memcmp(l,"slave",5) && isdigit(l[5]))
1785         {
1786             char *ip, *port, *end;
1787 
1788             if (strstr(l,"ip=") == NULL) {
1789                 /* Old format. */
1790                 ip = strchr(l,':'); if (!ip) continue;
1791                 ip++; /* Now ip points to start of ip address. */
1792                 port = strchr(ip,','); if (!port) continue;
1793                 *port = '\0'; /* nul term for easy access. */
1794                 port++; /* Now port points to start of port number. */
1795                 end = strchr(port,','); if (!end) continue;
1796                 *end = '\0'; /* nul term for easy access. */
1797             } else {
1798                 /* New format. */
1799                 ip = strstr(l,"ip="); if (!ip) continue;
1800                 ip += 3; /* Now ip points to start of ip address. */
1801                 port = strstr(l,"port="); if (!port) continue;
1802                 port += 5; /* Now port points to start of port number. */
1803                 /* Nul term both fields for easy access. */
1804                 end = strchr(ip,','); if (end) *end = '\0';
1805                 end = strchr(port,','); if (end) *end = '\0';
1806             }
1807 
1808             /* Check if we already have this slave into our table,
1809              * otherwise add it. */
1810             if (sentinelRedisInstanceLookupSlave(ri,ip,atoi(port)) == NULL) {
1811                 if ((slave = createSentinelRedisInstance(NULL,SRI_SLAVE,ip,
1812                             atoi(port), ri->quorum, ri)) != NULL)
1813                 {
1814                     sentinelEvent(REDIS_NOTICE,"+slave",slave,"%@");
1815                 }
1816             }
1817         }
1818 
1819         /* master_link_down_since_seconds:<seconds> */
1820         if (sdslen(l) >= 32 &&
1821             !memcmp(l,"master_link_down_since_seconds",30))
1822         {
1823             ri->master_link_down_time = strtoll(l+31,NULL,10)*1000;
1824         }
1825 
1826         /* role:<role> */
1827         if (!memcmp(l,"role:master",11)) role = SRI_MASTER;
1828         else if (!memcmp(l,"role:slave",10)) role = SRI_SLAVE;
1829 
1830         if (role == SRI_SLAVE) {
1831             /* master_host:<host> */
1832             if (sdslen(l) >= 12 && !memcmp(l,"master_host:",12)) {
1833                 if (ri->slave_master_host == NULL ||
1834                     strcasecmp(l+12,ri->slave_master_host))
1835                 {
1836                     sdsfree(ri->slave_master_host);
1837                     ri->slave_master_host = sdsnew(l+12);
1838                     ri->slave_conf_change_time = mstime();
1839                 }
1840             }
1841 
1842             /* master_port:<port> */
1843             if (sdslen(l) >= 12 && !memcmp(l,"master_port:",12)) {
1844                 int slave_master_port = atoi(l+12);
1845 
1846                 if (ri->slave_master_port != slave_master_port) {
1847                     ri->slave_master_port = slave_master_port;
1848                     ri->slave_conf_change_time = mstime();
1849                 }
1850             }
1851 
1852             /* master_link_status:<status> */
1853             if (sdslen(l) >= 19 && !memcmp(l,"master_link_status:",19)) {
1854                 ri->slave_master_link_status =
1855                     (strcasecmp(l+19,"up") == 0) ?
1856                     SENTINEL_MASTER_LINK_STATUS_UP :
1857                     SENTINEL_MASTER_LINK_STATUS_DOWN;
1858             }
1859 
1860             /* slave_priority:<priority> */
1861             if (sdslen(l) >= 15 && !memcmp(l,"slave_priority:",15))
1862                 ri->slave_priority = atoi(l+15);
1863 
1864             /* slave_repl_offset:<offset> */
1865             if (sdslen(l) >= 18 && !memcmp(l,"slave_repl_offset:",18))
1866                 ri->slave_repl_offset = strtoull(l+18,NULL,10);
1867         }
1868     }
1869     ri->info_refresh = mstime();
1870     sdsfreesplitres(lines,numlines);
1871 
1872     /* ---------------------------- Acting half -----------------------------
1873      * Some things will not happen if sentinel.tilt is true, but some will
1874      * still be processed. */
1875 
1876     /* Remember when the role changed. */
1877     if (role != ri->role_reported) {
1878         ri->role_reported_time = mstime();
1879         ri->role_reported = role;
1880         if (role == SRI_SLAVE) ri->slave_conf_change_time = mstime();
1881         /* Log the event with +role-change if the new role is coherent or
1882          * with -role-change if there is a mismatch with the current config. */
1883         sentinelEvent(REDIS_VERBOSE,
1884             ((ri->flags & (SRI_MASTER|SRI_SLAVE)) == role) ?
1885             "+role-change" : "-role-change",
1886             ri, "%@ new reported role is %s",
1887             role == SRI_MASTER ? "master" : "slave",
1888             ri->flags & SRI_MASTER ? "master" : "slave");
1889     }
1890 
1891     /* None of the following conditions are processed when in tilt mode, so
1892      * return asap. */
1893     if (sentinel.tilt) return;
1894 
1895     /* Handle master -> slave role switch. */
1896     if ((ri->flags & SRI_MASTER) && role == SRI_SLAVE) {
1897         /* Nothing to do, but masters claiming to be slaves are
1898          * considered to be unreachable by Sentinel, so eventually
1899          * a failover will be triggered. */
1900     }
1901 
1902     /* Handle slave -> master role switch. */
1903     if ((ri->flags & SRI_SLAVE) && role == SRI_MASTER) {
1904         /* If this is a promoted slave we can change state to the
1905          * failover state machine. */
1906         if ((ri->flags & SRI_PROMOTED) &&
1907             (ri->master->flags & SRI_FAILOVER_IN_PROGRESS) &&
1908             (ri->master->failover_state ==
1909                 SENTINEL_FAILOVER_STATE_WAIT_PROMOTION))
1910         {
1911             /* Now that we are sure the slave was reconfigured as a master
1912              * set the master configuration epoch to the epoch we won the
1913              * election to perform this failover. This will force the other
1914              * Sentinels to update their config (assuming there is not
1915              * a newer one already available). */
1916             ri->master->config_epoch = ri->master->failover_epoch;
1917             ri->master->failover_state = SENTINEL_FAILOVER_STATE_RECONF_SLAVES;
1918             ri->master->failover_state_change_time = mstime();
1919             sentinelFlushConfig();
1920             sentinelEvent(REDIS_WARNING,"+promoted-slave",ri,"%@");
1921             sentinelEvent(REDIS_WARNING,"+failover-state-reconf-slaves",
1922                 ri->master,"%@");
1923             sentinelCallClientReconfScript(ri->master,SENTINEL_LEADER,
1924                 "start",ri->master->addr,ri->addr);
1925             sentinelForceHelloUpdateForMaster(ri->master);
1926         } else {
1927             /* A slave turned into a master. We want to force our view and
1928              * reconfigure as slave. Wait some time after the change before
1929              * going forward, to receive new configs if any. */
1930             mstime_t wait_time = SENTINEL_PUBLISH_PERIOD*4;
1931 
1932             if (!(ri->flags & SRI_PROMOTED) &&
1933                  sentinelMasterLooksSane(ri->master) &&
1934                  sentinelRedisInstanceNoDownFor(ri,wait_time) &&
1935                  mstime() - ri->role_reported_time > wait_time)
1936             {
1937                 int retval = sentinelSendSlaveOf(ri,
1938                         ri->master->addr->ip,
1939                         ri->master->addr->port);
1940                 if (retval == REDIS_OK)
1941                     sentinelEvent(REDIS_NOTICE,"+convert-to-slave",ri,"%@");
1942             }
1943         }
1944     }
1945 
1946     /* Handle slaves replicating to a different master address. */
1947     if ((ri->flags & SRI_SLAVE) &&
1948         role == SRI_SLAVE &&
1949         (ri->slave_master_port != ri->master->addr->port ||
1950          strcasecmp(ri->slave_master_host,ri->master->addr->ip)))
1951     {
1952         mstime_t wait_time = ri->master->failover_timeout;
1953 
1954         /* Make sure the master is sane before reconfiguring this instance
1955          * into a slave. */
1956         if (sentinelMasterLooksSane(ri->master) &&
1957             sentinelRedisInstanceNoDownFor(ri,wait_time) &&
1958             mstime() - ri->slave_conf_change_time > wait_time)
1959         {
1960             int retval = sentinelSendSlaveOf(ri,
1961                     ri->master->addr->ip,
1962                     ri->master->addr->port);
1963             if (retval == REDIS_OK)
1964                 sentinelEvent(REDIS_NOTICE,"+fix-slave-config",ri,"%@");
1965         }
1966     }
1967 
1968     /* Detect if the slave that is in the process of being reconfigured
1969      * changed state. */
1970     if ((ri->flags & SRI_SLAVE) && role == SRI_SLAVE &&
1971         (ri->flags & (SRI_RECONF_SENT|SRI_RECONF_INPROG)))
1972     {
1973         /* SRI_RECONF_SENT -> SRI_RECONF_INPROG. */
1974         if ((ri->flags & SRI_RECONF_SENT) &&
1975             ri->slave_master_host &&
1976             strcmp(ri->slave_master_host,
1977                     ri->master->promoted_slave->addr->ip) == 0 &&
1978             ri->slave_master_port == ri->master->promoted_slave->addr->port)
1979         {
1980             ri->flags &= ~SRI_RECONF_SENT;
1981             ri->flags |= SRI_RECONF_INPROG;
1982             sentinelEvent(REDIS_NOTICE,"+slave-reconf-inprog",ri,"%@");
1983         }
1984 
1985         /* SRI_RECONF_INPROG -> SRI_RECONF_DONE */
1986         if ((ri->flags & SRI_RECONF_INPROG) &&
1987             ri->slave_master_link_status == SENTINEL_MASTER_LINK_STATUS_UP)
1988         {
1989             ri->flags &= ~SRI_RECONF_INPROG;
1990             ri->flags |= SRI_RECONF_DONE;
1991             sentinelEvent(REDIS_NOTICE,"+slave-reconf-done",ri,"%@");
1992         }
1993     }
1994 }
1995 
1996 void sentinelInfoReplyCallback(redisAsyncContext *c, void *reply, void *privdata) {
1997     sentinelRedisInstance *ri = c->data;
1998     redisReply *r;
1999 
2000     if (ri) ri->pending_commands--;
2001     if (!reply || !ri) return;
2002     r = reply;
2003 
2004     if (r->type == REDIS_REPLY_STRING) {
2005         sentinelRefreshInstanceInfo(ri,r->str);
2006     }
2007 }
2008 
2009 /* Just discard the reply. We use this when we are not monitoring the return
2010  * value of the command but its effects directly. */
2011 void sentinelDiscardReplyCallback(redisAsyncContext *c, void *reply, void *privdata) {
2012     sentinelRedisInstance *ri = c->data;
2013 
2014     if (ri) ri->pending_commands--;
2015 }
2016 
2017 void sentinelPingReplyCallback(redisAsyncContext *c, void *reply, void *privdata) {
2018     sentinelRedisInstance *ri = c->data;
2019     redisReply *r;
2020 
2021     if (ri) ri->pending_commands--;
2022     if (!reply || !ri) return;
2023     r = reply;
2024 
2025     if (r->type == REDIS_REPLY_STATUS ||
2026         r->type == REDIS_REPLY_ERROR) {
2027         /* Update the "instance available" field only if this is an
2028          * acceptable reply. */
2029         if (strncmp(r->str,"PONG",4) == 0 ||
2030             strncmp(r->str,"LOADING",7) == 0 ||
2031             strncmp(r->str,"MASTERDOWN",10) == 0)
2032         {
2033             ri->last_avail_time = mstime();
2034             ri->last_ping_time = 0; /* Flag the pong as received. */
2035         } else {
2036             /* Send a SCRIPT KILL command if the instance appears to be
2037              * down because of a busy script. */
2038             if (strncmp(r->str,"BUSY",4) == 0 &&
2039                 (ri->flags & SRI_S_DOWN) &&
2040                 !(ri->flags & SRI_SCRIPT_KILL_SENT))
2041             {
2042                 if (redisAsyncCommand(ri->cc,
2043                         sentinelDiscardReplyCallback, NULL,
2044                         "SCRIPT KILL") == REDIS_OK)
2045                     ri->pending_commands++;
2046                 ri->flags |= SRI_SCRIPT_KILL_SENT;
2047             }
2048         }
2049     }
2050     ri->last_pong_time = mstime();
2051 }
2052 
2053 /* This is called when we get the reply about the PUBLISH command we send
2054  * to the master to advertise this sentinel. */
2055 void sentinelPublishReplyCallback(redisAsyncContext *c, void *reply, void *privdata) {
2056     sentinelRedisInstance *ri = c->data;
2057     redisReply *r;
2058 
2059     if (ri) ri->pending_commands--;
2060     if (!reply || !ri) return;
2061     r = reply;
2062 
2063     /* Only update pub_time if we actually published our message. Otherwise
2064      * we'll retry again in 100 milliseconds. */
2065     if (r->type != REDIS_REPLY_ERROR)
2066         ri->last_pub_time = mstime();
2067 }
2068 
2069 /* Process an hello message received via Pub/Sub in master or slave instance,
2070  * or sent directly to this sentinel via the (fake) PUBLISH command of Sentinel.
2071  *
2072  * If the master name specified in the message is not known, the message is
2073  * discareded. */
2074 void sentinelProcessHelloMessage(char *hello, int hello_len) {
2075     /* Format is composed of 8 tokens:
2076      * 0=ip,1=port,2=runid,3=current_epoch,4=master_name,
2077      * 5=master_ip,6=master_port,7=master_config_epoch. */
2078     int numtokens, port, removed, master_port;
2079     uint64_t current_epoch, master_config_epoch;
2080     char **token = sdssplitlen(hello, hello_len, ",", 1, &numtokens);
2081     sentinelRedisInstance *si, *master;
2082 
2083     if (numtokens == 8) {
2084         /* Obtain a reference to the master this hello message is about */
2085         master = sentinelGetMasterByName(token[4]);
2086         if (!master) goto cleanup; /* Unknown master, skip the message. */
2087 
2088         /* First, try to see if we already have this sentinel. */
2089         port = atoi(token[1]);
2090         master_port = atoi(token[6]);
2091         si = getSentinelRedisInstanceByAddrAndRunID(
2092                         master->sentinels,token[0],port,token[2]);
2093         current_epoch = strtoull(token[3],NULL,10);
2094         master_config_epoch = strtoull(token[7],NULL,10);
2095 
2096         if (!si) {
2097             /* If not, remove all the sentinels that have the same runid
2098              * OR the same ip/port, because it's either a restart or a
2099              * network topology change. */
2100             removed = removeMatchingSentinelsFromMaster(master,token[0],port,
2101                             token[2]);
2102             if (removed) {
2103                 sentinelEvent(REDIS_NOTICE,"-dup-sentinel",master,
2104                     "%@ #duplicate of %s:%d or %s",
2105                     token[0],port,token[2]);
2106             }
2107 
2108             /* Add the new sentinel. */
2109             si = createSentinelRedisInstance(NULL,SRI_SENTINEL,
2110                             token[0],port,master->quorum,master);
2111             if (si) {
2112                 sentinelEvent(REDIS_NOTICE,"+sentinel",si,"%@");
2113                 /* The runid is NULL after a new instance creation and
2114                  * for Sentinels we don't have a later chance to fill it,
2115                  * so do it now. */
2116                 si->runid = sdsnew(token[2]);
2117                 sentinelFlushConfig();
2118             }
2119         }
2120 
2121         /* Update local current_epoch if received current_epoch is greater.*/
2122         if (current_epoch > sentinel.current_epoch) {
2123             sentinel.current_epoch = current_epoch;
2124             sentinelFlushConfig();
2125             sentinelEvent(REDIS_WARNING,"+new-epoch",master,"%llu",
2126                 (unsigned long long) sentinel.current_epoch);
2127         }
2128 
2129         /* Update master info if received configuration is newer. */
2130         if (master->config_epoch < master_config_epoch) {
2131             master->config_epoch = master_config_epoch;
2132             if (master_port != master->addr->port ||
2133                 strcmp(master->addr->ip, token[5]))
2134             {
2135                 sentinelAddr *old_addr;
2136 
2137                 sentinelEvent(REDIS_WARNING,"+config-update-from",si,"%@");
2138                 sentinelEvent(REDIS_WARNING,"+switch-master",
2139                     master,"%s %s %d %s %d",
2140                     master->name,
2141                     master->addr->ip, master->addr->port,
2142                     token[5], master_port);
2143 
2144                 old_addr = dupSentinelAddr(master->addr);
2145                 sentinelResetMasterAndChangeAddress(master, token[5], master_port);
2146                 sentinelCallClientReconfScript(master,
2147                     SENTINEL_OBSERVER,"start",
2148                     old_addr,master->addr);
2149                 releaseSentinelAddr(old_addr);
2150             }
2151         }
2152 
2153         /* Update the state of the Sentinel. */
2154         if (si) si->last_hello_time = mstime();
2155     }
2156 
2157 cleanup:
2158     sdsfreesplitres(token,numtokens);
2159 }
2160 
2161 
2162 /* This is our Pub/Sub callback for the Hello channel. It's useful in order
2163  * to discover other sentinels attached at the same master. */
2164 void sentinelReceiveHelloMessages(redisAsyncContext *c, void *reply, void *privdata) {
2165     sentinelRedisInstance *ri = c->data;
2166     redisReply *r;
2167 
2168     if (!reply || !ri) return;
2169     r = reply;
2170 
2171     /* Update the last activity in the pubsub channel. Note that since we
2172      * receive our messages as well this timestamp can be used to detect
2173      * if the link is probably disconnected even if it seems otherwise. */
2174     ri->pc_last_activity = mstime();
2175 
2176     /* Sanity check in the reply we expect, so that the code that follows
2177      * can avoid to check for details. */
2178     if (r->type != REDIS_REPLY_ARRAY ||
2179         r->elements != 3 ||
2180         r->element[0]->type != REDIS_REPLY_STRING ||
2181         r->element[1]->type != REDIS_REPLY_STRING ||
2182         r->element[2]->type != REDIS_REPLY_STRING ||
2183         strcmp(r->element[0]->str,"message") != 0) return;
2184 
2185     /* We are not interested in meeting ourselves */
2186     if (strstr(r->element[2]->str,server.runid) != NULL) return;
2187 
2188     sentinelProcessHelloMessage(r->element[2]->str, r->element[2]->len);
2189 }
2190 
2191 /* Send an "Hello" message via Pub/Sub to the specified 'ri' Redis
2192  * instance in order to broadcast the current configuraiton for this
2193  * master, and to advertise the existence of this Sentinel at the same time.
2194  *
2195  * The message has the following format:
2196  *
2197  * sentinel_ip,sentinel_port,sentinel_runid,current_epoch,
2198  * master_name,master_ip,master_port,master_config_epoch.
2199  *
2200  * Returns REDIS_OK if the PUBLISH was queued correctly, otherwise
2201  * REDIS_ERR is returned. */
2202 int sentinelSendHello(sentinelRedisInstance *ri) {
2203     char ip[REDIS_IP_STR_LEN];
2204     char payload[REDIS_IP_STR_LEN+1024];
2205     int retval;
2206     sentinelRedisInstance *master = (ri->flags & SRI_MASTER) ? ri : ri->master;
2207     sentinelAddr *master_addr = sentinelGetCurrentMasterAddress(master);
2208 
2209     /* Try to obtain our own IP address. */
2210     if (anetSockName(ri->cc->c.fd,ip,sizeof(ip),NULL) == -1) return REDIS_ERR;
2211     if (ri->flags & SRI_DISCONNECTED) return REDIS_ERR;
2212 
2213     /* Format and send the Hello message. */
2214     snprintf(payload,sizeof(payload),
2215         "%s,%d,%s,%llu," /* Info about this sentinel. */
2216         "%s,%s,%d,%llu", /* Info about current master. */
2217         ip, server.port, server.runid,
2218         (unsigned long long) sentinel.current_epoch,
2219         /* --- */
2220         master->name,master_addr->ip,master_addr->port,
2221         (unsigned long long) master->config_epoch);
2222     retval = redisAsyncCommand(ri->cc,
2223         sentinelPublishReplyCallback, NULL, "PUBLISH %s %s",
2224             SENTINEL_HELLO_CHANNEL,payload);
2225     if (retval != REDIS_OK) return REDIS_ERR;
2226     ri->pending_commands++;
2227     return REDIS_OK;
2228 }
2229 
2230 /* Reset last_pub_time in all the instances in the specified dictionary
2231  * in order to force the delivery of an Hello update ASAP. */
2232 void sentinelForceHelloUpdateDictOfRedisInstances(dict *instances) {
2233     dictIterator *di;
2234     dictEntry *de;
2235 
2236     di = dictGetSafeIterator(instances);
2237     while((de = dictNext(di)) != NULL) {
2238         sentinelRedisInstance *ri = dictGetVal(de);
2239         if (ri->last_pub_time >= (SENTINEL_PUBLISH_PERIOD+1))
2240             ri->last_pub_time -= (SENTINEL_PUBLISH_PERIOD+1);
2241     }
2242     dictReleaseIterator(di);
2243 }
2244 
2245 /* This function forces the delivery of an "Hello" message (see
2246  * sentinelSendHello() top comment for further information) to all the Redis
2247  * and Sentinel instances related to the specified 'master'.
2248  *
2249  * It is technically not needed since we send an update to every instance
2250  * with a period of SENTINEL_PUBLISH_PERIOD milliseconds, however when a
2251  * Sentinel upgrades a configuration it is a good idea to deliever an update
2252  * to the other Sentinels ASAP. */
2253 int sentinelForceHelloUpdateForMaster(sentinelRedisInstance *master) {
2254     if (!(master->flags & SRI_MASTER)) return REDIS_ERR;
2255     if (master->last_pub_time >= (SENTINEL_PUBLISH_PERIOD+1))
2256         master->last_pub_time -= (SENTINEL_PUBLISH_PERIOD+1);
2257     sentinelForceHelloUpdateDictOfRedisInstances(master->sentinels);
2258     sentinelForceHelloUpdateDictOfRedisInstances(master->slaves);
2259     return REDIS_OK;
2260 }
2261 
2262 /* Send a PING to the specified instance and refresh the last_ping_time
2263  * if it is zero (that is, if we received a pong for the previous ping).
2264  *
2265  * On error zero is returned, and we can't consider the PING command
2266  * queued in the connection. */
2267 int sentinelSendPing(sentinelRedisInstance *ri) {
2268     int retval = redisAsyncCommand(ri->cc,
2269         sentinelPingReplyCallback, NULL, "PING");
2270     if (retval == REDIS_OK) {
2271         ri->pending_commands++;
2272         /* We update the ping time only if we received the pong for
2273          * the previous ping, otherwise we are technically waiting
2274          * since the first ping that did not received a reply. */
2275         if (ri->last_ping_time == 0) ri->last_ping_time = mstime();
2276         return 1;
2277     } else {
2278         return 0;
2279     }
2280 }
2281 
2282 /* Send periodic PING, INFO, and PUBLISH to the Hello channel to
2283  * the specified master or slave instance. */
2284 void sentinelSendPeriodicCommands(sentinelRedisInstance *ri) {
2285     mstime_t now = mstime();
2286     mstime_t info_period, ping_period;
2287     int retval;
2288 
2289     /* Return ASAP if we have already a PING or INFO already pending, or
2290      * in the case the instance is not properly connected. */
2291     if (ri->flags & SRI_DISCONNECTED) return;
2292 
2293     /* For INFO, PING, PUBLISH that are not critical commands to send we
2294      * also have a limit of SENTINEL_MAX_PENDING_COMMANDS. We don't
2295      * want to use a lot of memory just because a link is not working
2296      * properly (note that anyway there is a redundant protection about this,
2297      * that is, the link will be disconnected and reconnected if a long
2298      * timeout condition is detected. */
2299     if (ri->pending_commands >= SENTINEL_MAX_PENDING_COMMANDS) return;
2300 
2301     /* If this is a slave of a master in O_DOWN condition we start sending
2302      * it INFO every second, instead of the usual SENTINEL_INFO_PERIOD
2303      * period. In this state we want to closely monitor slaves in case they
2304      * are turned into masters by another Sentinel, or by the sysadmin. */
2305     if ((ri->flags & SRI_SLAVE) &&
2306         (ri->master->flags & (SRI_O_DOWN|SRI_FAILOVER_IN_PROGRESS))) {
2307         info_period = 1000;
2308     } else {
2309         info_period = SENTINEL_INFO_PERIOD;
2310     }
2311 
2312     /* We ping instances every time the last received pong is older than
2313      * the configured 'down-after-milliseconds' time, but every second
2314      * anyway if 'down-after-milliseconds' is greater than 1 second. */
2315     ping_period = ri->down_after_period;
2316     if (ping_period > SENTINEL_PING_PERIOD) ping_period = SENTINEL_PING_PERIOD;
2317 
2318     if ((ri->flags & SRI_SENTINEL) == 0 &&
2319         (ri->info_refresh == 0 ||
2320         (now - ri->info_refresh) > info_period))
2321     {
2322         /* Send INFO to masters and slaves, not sentinels. */
2323         retval = redisAsyncCommand(ri->cc,
2324             sentinelInfoReplyCallback, NULL, "INFO");
2325         if (retval == REDIS_OK) ri->pending_commands++;
2326     } else if ((now - ri->last_pong_time) > ping_period) {
2327         /* Send PING to all the three kinds of instances. */
2328         sentinelSendPing(ri);
2329     } else if ((now - ri->last_pub_time) > SENTINEL_PUBLISH_PERIOD) {
2330         /* PUBLISH hello messages to all the three kinds of instances. */
2331         sentinelSendHello(ri);
2332     }
2333 }
2334 
2335 /* =========================== SENTINEL command ============================= */
2336 
2337 const char *sentinelFailoverStateStr(int state) {
2338     switch(state) {
2339     case SENTINEL_FAILOVER_STATE_NONE: return "none";
2340     case SENTINEL_FAILOVER_STATE_WAIT_START: return "wait_start";
2341     case SENTINEL_FAILOVER_STATE_SELECT_SLAVE: return "select_slave";
2342     case SENTINEL_FAILOVER_STATE_SEND_SLAVEOF_NOONE: return "send_slaveof_noone";
2343     case SENTINEL_FAILOVER_STATE_WAIT_PROMOTION: return "wait_promotion";
2344     case SENTINEL_FAILOVER_STATE_RECONF_SLAVES: return "reconf_slaves";
2345     case SENTINEL_FAILOVER_STATE_UPDATE_CONFIG: return "update_config";
2346     default: return "unknown";
2347     }
2348 }
2349 
2350 /* Redis instance to Redis protocol representation. */
2351 void addReplySentinelRedisInstance(redisClient *c, sentinelRedisInstance *ri) {
2352     char *flags = sdsempty();
2353     void *mbl;
2354     int fields = 0;
2355 
2356     mbl = addDeferredMultiBulkLength(c);
2357 
2358     addReplyBulkCString(c,"name");
2359     addReplyBulkCString(c,ri->name);
2360     fields++;
2361 
2362     addReplyBulkCString(c,"ip");
2363     addReplyBulkCString(c,ri->addr->ip);
2364     fields++;
2365 
2366     addReplyBulkCString(c,"port");
2367     addReplyBulkLongLong(c,ri->addr->port);
2368     fields++;
2369 
2370     addReplyBulkCString(c,"runid");
2371     addReplyBulkCString(c,ri->runid ? ri->runid : "");
2372     fields++;
2373 
2374     addReplyBulkCString(c,"flags");
2375     if (ri->flags & SRI_S_DOWN) flags = sdscat(flags,"s_down,");
2376     if (ri->flags & SRI_O_DOWN) flags = sdscat(flags,"o_down,");
2377     if (ri->flags & SRI_MASTER) flags = sdscat(flags,"master,");
2378     if (ri->flags & SRI_SLAVE) flags = sdscat(flags,"slave,");
2379     if (ri->flags & SRI_SENTINEL) flags = sdscat(flags,"sentinel,");
2380     if (ri->flags & SRI_DISCONNECTED) flags = sdscat(flags,"disconnected,");
2381     if (ri->flags & SRI_MASTER_DOWN) flags = sdscat(flags,"master_down,");
2382     if (ri->flags & SRI_FAILOVER_IN_PROGRESS)
2383         flags = sdscat(flags,"failover_in_progress,");
2384     if (ri->flags & SRI_PROMOTED) flags = sdscat(flags,"promoted,");
2385     if (ri->flags & SRI_RECONF_SENT) flags = sdscat(flags,"reconf_sent,");
2386     if (ri->flags & SRI_RECONF_INPROG) flags = sdscat(flags,"reconf_inprog,");
2387     if (ri->flags & SRI_RECONF_DONE) flags = sdscat(flags,"reconf_done,");
2388 
2389     if (sdslen(flags) != 0) sdsrange(flags,0,-2); /* remove last "," */
2390     addReplyBulkCString(c,flags);
2391     sdsfree(flags);
2392     fields++;
2393 
2394     addReplyBulkCString(c,"pending-commands");
2395     addReplyBulkLongLong(c,ri->pending_commands);
2396     fields++;
2397 
2398     if (ri->flags & SRI_FAILOVER_IN_PROGRESS) {
2399         addReplyBulkCString(c,"failover-state");
2400         addReplyBulkCString(c,(char*)sentinelFailoverStateStr(ri->failover_state));
2401         fields++;
2402     }
2403 
2404     addReplyBulkCString(c,"last-ping-sent");
2405     addReplyBulkLongLong(c,
2406         ri->last_ping_time ? (mstime() - ri->last_ping_time) : 0);
2407     fields++;
2408 
2409     addReplyBulkCString(c,"last-ok-ping-reply");
2410     addReplyBulkLongLong(c,mstime() - ri->last_avail_time);
2411     fields++;
2412 
2413     addReplyBulkCString(c,"last-ping-reply");
2414     addReplyBulkLongLong(c,mstime() - ri->last_pong_time);
2415     fields++;
2416 
2417     if (ri->flags & SRI_S_DOWN) {
2418         addReplyBulkCString(c,"s-down-time");
2419         addReplyBulkLongLong(c,mstime()-ri->s_down_since_time);
2420         fields++;
2421     }
2422 
2423     if (ri->flags & SRI_O_DOWN) {
2424         addReplyBulkCString(c,"o-down-time");
2425         addReplyBulkLongLong(c,mstime()-ri->o_down_since_time);
2426         fields++;
2427     }
2428 
2429     addReplyBulkCString(c,"down-after-milliseconds");
2430     addReplyBulkLongLong(c,ri->down_after_period);
2431     fields++;
2432 
2433     /* Masters and Slaves */
2434     if (ri->flags & (SRI_MASTER|SRI_SLAVE)) {
2435         addReplyBulkCString(c,"info-refresh");
2436         addReplyBulkLongLong(c,mstime() - ri->info_refresh);
2437         fields++;
2438 
2439         addReplyBulkCString(c,"role-reported");
2440         addReplyBulkCString(c, (ri->role_reported == SRI_MASTER) ? "master" :
2441                                                                    "slave");
2442         fields++;
2443 
2444         addReplyBulkCString(c,"role-reported-time");
2445         addReplyBulkLongLong(c,mstime() - ri->role_reported_time);
2446         fields++;
2447     }
2448 
2449     /* Only masters */
2450     if (ri->flags & SRI_MASTER) {
2451         addReplyBulkCString(c,"config-epoch");
2452         addReplyBulkLongLong(c,ri->config_epoch);
2453         fields++;
2454 
2455         addReplyBulkCString(c,"num-slaves");
2456         addReplyBulkLongLong(c,dictSize(ri->slaves));
2457         fields++;
2458 
2459         addReplyBulkCString(c,"num-other-sentinels");
2460         addReplyBulkLongLong(c,dictSize(ri->sentinels));
2461         fields++;
2462 
2463         addReplyBulkCString(c,"quorum");
2464         addReplyBulkLongLong(c,ri->quorum);
2465         fields++;
2466 
2467         addReplyBulkCString(c,"failover-timeout");
2468         addReplyBulkLongLong(c,ri->failover_timeout);
2469         fields++;
2470 
2471         addReplyBulkCString(c,"parallel-syncs");
2472         addReplyBulkLongLong(c,ri->parallel_syncs);
2473         fields++;
2474 
2475         if (ri->notification_script) {
2476             addReplyBulkCString(c,"notification-script");
2477             addReplyBulkCString(c,ri->notification_script);
2478             fields++;
2479         }
2480 
2481         if (ri->client_reconfig_script) {
2482             addReplyBulkCString(c,"client-reconfig-script");
2483             addReplyBulkCString(c,ri->client_reconfig_script);
2484             fields++;
2485         }
2486     }
2487 
2488     /* Only slaves */
2489     if (ri->flags & SRI_SLAVE) {
2490         addReplyBulkCString(c,"master-link-down-time");
2491         addReplyBulkLongLong(c,ri->master_link_down_time);
2492         fields++;
2493 
2494         addReplyBulkCString(c,"master-link-status");
2495         addReplyBulkCString(c,
2496             (ri->slave_master_link_status == SENTINEL_MASTER_LINK_STATUS_UP) ?
2497             "ok" : "err");
2498         fields++;
2499 
2500         addReplyBulkCString(c,"master-host");
2501         addReplyBulkCString(c,
2502             ri->slave_master_host ? ri->slave_master_host : "?");
2503         fields++;
2504 
2505         addReplyBulkCString(c,"master-port");
2506         addReplyBulkLongLong(c,ri->slave_master_port);
2507         fields++;
2508 
2509         addReplyBulkCString(c,"slave-priority");
2510         addReplyBulkLongLong(c,ri->slave_priority);
2511         fields++;
2512 
2513         addReplyBulkCString(c,"slave-repl-offset");
2514         addReplyBulkLongLong(c,ri->slave_repl_offset);
2515         fields++;
2516     }
2517 
2518     /* Only sentinels */
2519     if (ri->flags & SRI_SENTINEL) {
2520         addReplyBulkCString(c,"last-hello-message");
2521         addReplyBulkLongLong(c,mstime() - ri->last_hello_time);
2522         fields++;
2523 
2524         addReplyBulkCString(c,"voted-leader");
2525         addReplyBulkCString(c,ri->leader ? ri->leader : "?");
2526         fields++;
2527 
2528         addReplyBulkCString(c,"voted-leader-epoch");
2529         addReplyBulkLongLong(c,ri->leader_epoch);
2530         fields++;
2531     }
2532 
2533     setDeferredMultiBulkLength(c,mbl,fields*2);
2534 }
2535 
2536 /* Output a number of instances contained inside a dictionary as
2537  * Redis protocol. */
2538 void addReplyDictOfRedisInstances(redisClient *c, dict *instances) {
2539     dictIterator *di;
2540     dictEntry *de;
2541 
2542     di = dictGetIterator(instances);
2543     addReplyMultiBulkLen(c,dictSize(instances));
2544     while((de = dictNext(di)) != NULL) {
2545         sentinelRedisInstance *ri = dictGetVal(de);
2546 
2547         addReplySentinelRedisInstance(c,ri);
2548     }
2549     dictReleaseIterator(di);
2550 }
2551 
2552 /* Lookup the named master into sentinel.masters.
2553  * If the master is not found reply to the client with an error and returns
2554  * NULL. */
2555 sentinelRedisInstance *sentinelGetMasterByNameOrReplyError(redisClient *c,
2556                         robj *name)
2557 {
2558     sentinelRedisInstance *ri;
2559 
2560     ri = dictFetchValue(sentinel.masters,c->argv[2]->ptr);
2561     if (!ri) {
2562         addReplyError(c,"No such master with that name");
2563         return NULL;
2564     }
2565     return ri;
2566 }
2567 
2568 void sentinelCommand(redisClient *c) {
2569     if (!strcasecmp(c->argv[1]->ptr,"masters")) {
2570         /* SENTINEL MASTERS */
2571         if (c->argc != 2) goto numargserr;
2572         addReplyDictOfRedisInstances(c,sentinel.masters);
2573     } else if (!strcasecmp(c->argv[1]->ptr,"master")) {
2574         /* SENTINEL MASTER <name> */
2575         sentinelRedisInstance *ri;
2576 
2577         if (c->argc != 3) goto numargserr;
2578         if ((ri = sentinelGetMasterByNameOrReplyError(c,c->argv[2]))
2579             == NULL) return;
2580         addReplySentinelRedisInstance(c,ri);
2581     } else if (!strcasecmp(c->argv[1]->ptr,"slaves")) {
2582         /* SENTINEL SLAVES <master-name> */
2583         sentinelRedisInstance *ri;
2584 
2585         if (c->argc != 3) goto numargserr;
2586         if ((ri = sentinelGetMasterByNameOrReplyError(c,c->argv[2])) == NULL)
2587             return;
2588         addReplyDictOfRedisInstances(c,ri->slaves);
2589     } else if (!strcasecmp(c->argv[1]->ptr,"sentinels")) {
2590         /* SENTINEL SENTINELS <master-name> */
2591         sentinelRedisInstance *ri;
2592 
2593         if (c->argc != 3) goto numargserr;
2594         if ((ri = sentinelGetMasterByNameOrReplyError(c,c->argv[2])) == NULL)
2595             return;
2596         addReplyDictOfRedisInstances(c,ri->sentinels);
2597     } else if (!strcasecmp(c->argv[1]->ptr,"is-master-down-by-addr")) {
2598         /* SENTINEL IS-MASTER-DOWN-BY-ADDR <ip> <port> <current-epoch> <runid>*/
2599         sentinelRedisInstance *ri;
2600         long long req_epoch;
2601         uint64_t leader_epoch = 0;
2602         char *leader = NULL;
2603         long port;
2604         int isdown = 0;
2605 
2606         if (c->argc != 6) goto numargserr;
2607         if (getLongFromObjectOrReply(c,c->argv[3],&port,NULL) != REDIS_OK ||
2608             getLongLongFromObjectOrReply(c,c->argv[4],&req_epoch,NULL)
2609                                                               != REDIS_OK)
2610             return;
2611         ri = getSentinelRedisInstanceByAddrAndRunID(sentinel.masters,
2612             c->argv[2]->ptr,port,NULL);
2613 
2614         /* It exists? Is actually a master? Is subjectively down? It's down.
2615          * Note: if we are in tilt mode we always reply with "0". */
2616         if (!sentinel.tilt && ri && (ri->flags & SRI_S_DOWN) &&
2617                                     (ri->flags & SRI_MASTER))
2618             isdown = 1;
2619 
2620         /* Vote for the master (or fetch the previous vote) if the request
2621          * includes a runid, otherwise the sender is not seeking for a vote. */
2622         if (ri && ri->flags & SRI_MASTER && strcasecmp(c->argv[5]->ptr,"*")) {
2623             leader = sentinelVoteLeader(ri,(uint64_t)req_epoch,
2624                                             c->argv[5]->ptr,
2625                                             &leader_epoch);
2626         }
2627 
2628         /* Reply with a three-elements multi-bulk reply:
2629          * down state, leader, vote epoch. */
2630         addReplyMultiBulkLen(c,3);
2631         addReply(c, isdown ? shared.cone : shared.czero);
2632         addReplyBulkCString(c, leader ? leader : "*");
2633         addReplyLongLong(c, (long long)leader_epoch);
2634         if (leader) sdsfree(leader);
2635     } else if (!strcasecmp(c->argv[1]->ptr,"reset")) {
2636         /* SENTINEL RESET <pattern> */
2637         if (c->argc != 3) goto numargserr;
2638         addReplyLongLong(c,sentinelResetMastersByPattern(c->argv[2]->ptr,SENTINEL_GENERATE_EVENT));
2639     } else if (!strcasecmp(c->argv[1]->ptr,"get-master-addr-by-name")) {
2640         /* SENTINEL GET-MASTER-ADDR-BY-NAME <master-name> */
2641         sentinelRedisInstance *ri;
2642 
2643         if (c->argc != 3) goto numargserr;
2644         ri = sentinelGetMasterByName(c->argv[2]->ptr);
2645         if (ri == NULL) {
2646             addReply(c,shared.nullmultibulk);
2647         } else {
2648             sentinelAddr *addr = sentinelGetCurrentMasterAddress(ri);
2649 
2650             addReplyMultiBulkLen(c,2);
2651             addReplyBulkCString(c,addr->ip);
2652             addReplyBulkLongLong(c,addr->port);
2653         }
2654     } else if (!strcasecmp(c->argv[1]->ptr,"failover")) {
2655         /* SENTINEL FAILOVER <master-name> */
2656         sentinelRedisInstance *ri;
2657 
2658         if (c->argc != 3) goto numargserr;
2659         if ((ri = sentinelGetMasterByNameOrReplyError(c,c->argv[2])) == NULL)
2660             return;
2661         if (ri->flags & SRI_FAILOVER_IN_PROGRESS) {
2662             addReplySds(c,sdsnew("-INPROG Failover already in progress\r\n"));
2663             return;
2664         }
2665         if (sentinelSelectSlave(ri) == NULL) {
2666             addReplySds(c,sdsnew("-NOGOODSLAVE No suitable slave to promote\r\n"));
2667             return;
2668         }
2669         redisLog(REDIS_WARNING,"Executing user requested FAILOVER of '%s'",
2670             ri->name);
2671         sentinelStartFailover(ri);
2672         ri->flags |= SRI_FORCE_FAILOVER;
2673         addReply(c,shared.ok);
2674     } else if (!strcasecmp(c->argv[1]->ptr,"pending-scripts")) {
2675         /* SENTINEL PENDING-SCRIPTS */
2676 
2677         if (c->argc != 2) goto numargserr;
2678         sentinelPendingScriptsCommand(c);
2679     } else if (!strcasecmp(c->argv[1]->ptr,"monitor")) {
2680         /* SENTINEL MONITOR <name> <ip> <port> <quorum> */
2681         sentinelRedisInstance *ri;
2682         long quorum, port;
2683         char buf[32];
2684 
2685         if (c->argc != 6) goto numargserr;
2686         if (getLongFromObjectOrReply(c,c->argv[5],&quorum,"Invalid quorum")
2687             != REDIS_OK) return;
2688         if (getLongFromObjectOrReply(c,c->argv[4],&port,"Invalid port")
2689             != REDIS_OK) return;
2690         /* Make sure the IP field is actually a valid IP before passing it
2691          * to createSentinelRedisInstance(), otherwise we may trigger a
2692          * DNS lookup at runtime. */
2693         if (anetResolveIP(NULL,c->argv[3]->ptr,buf,sizeof(buf)) == ANET_ERR) {
2694             addReplyError(c,"Invalid IP address specified");
2695             return;
2696         }
2697 
2698         /* Parameters are valid. Try to create the master instance. */
2699         ri = createSentinelRedisInstance(c->argv[2]->ptr,SRI_MASTER,
2700                 c->argv[3]->ptr,port,quorum,NULL);
2701         if (ri == NULL) {
2702             switch(errno) {
2703             case EBUSY:
2704                 addReplyError(c,"Duplicated master name");
2705                 break;
2706             case EINVAL:
2707                 addReplyError(c,"Invalid port number");
2708                 break;
2709             default:
2710                 addReplyError(c,"Unspecified error adding the instance");
2711                 break;
2712             }
2713         } else {
2714             sentinelFlushConfig();
2715             sentinelEvent(REDIS_WARNING,"+monitor",ri,"%@ quorum %d",ri->quorum);
2716             addReply(c,shared.ok);
2717         }
2718     } else if (!strcasecmp(c->argv[1]->ptr,"remove")) {
2719         /* SENTINEL REMOVE <name> */
2720         sentinelRedisInstance *ri;
2721 
2722         if ((ri = sentinelGetMasterByNameOrReplyError(c,c->argv[2]))
2723             == NULL) return;
2724         sentinelEvent(REDIS_WARNING,"-monitor",ri,"%@");
2725         dictDelete(sentinel.masters,c->argv[2]->ptr);
2726         sentinelFlushConfig();
2727         addReply(c,shared.ok);
2728     } else if (!strcasecmp(c->argv[1]->ptr,"set")) {
2729         if (c->argc < 3 || c->argc % 2 == 0) goto numargserr;
2730         sentinelSetCommand(c);
2731     } else {
2732         addReplyErrorFormat(c,"Unknown sentinel subcommand '%s'",
2733                                (char*)c->argv[1]->ptr);
2734     }
2735     return;
2736 
2737 numargserr:
2738     addReplyErrorFormat(c,"Wrong number of arguments for 'sentinel %s'",
2739                           (char*)c->argv[1]->ptr);
2740 }
2741 
2742 /* SENTINEL INFO [section] */
2743 void sentinelInfoCommand(redisClient *c) {
2744     char *section = c->argc == 2 ? c->argv[1]->ptr : "default";
2745     sds info = sdsempty();
2746     int defsections = !strcasecmp(section,"default");
2747     int sections = 0;
2748 
2749     if (c->argc > 2) {
2750         addReply(c,shared.syntaxerr);
2751         return;
2752     }
2753 
2754     if (!strcasecmp(section,"server") || defsections) {
2755         if (sections++) info = sdscat(info,"\r\n");
2756         sds serversection = genRedisInfoString("server");
2757         info = sdscatlen(info,serversection,sdslen(serversection));
2758         sdsfree(serversection);
2759     }
2760 
2761     if (!strcasecmp(section,"sentinel") || defsections) {
2762         dictIterator *di;
2763         dictEntry *de;
2764         int master_id = 0;
2765 
2766         if (sections++) info = sdscat(info,"\r\n");
2767         info = sdscatprintf(info,
2768             "# Sentinel\r\n"
2769             "sentinel_masters:%lu\r\n"
2770             "sentinel_tilt:%d\r\n"
2771             "sentinel_running_scripts:%d\r\n"
2772             "sentinel_scripts_queue_length:%ld\r\n",
2773             dictSize(sentinel.masters),
2774             sentinel.tilt,
2775             sentinel.running_scripts,
2776             listLength(sentinel.scripts_queue));
2777 
2778         di = dictGetIterator(sentinel.masters);
2779         while((de = dictNext(di)) != NULL) {
2780             sentinelRedisInstance *ri = dictGetVal(de);
2781             char *status = "ok";
2782 
2783             if (ri->flags & SRI_O_DOWN) status = "odown";
2784             else if (ri->flags & SRI_S_DOWN) status = "sdown";
2785             info = sdscatprintf(info,
2786                 "master%d:name=%s,status=%s,address=%s:%d,"
2787                 "slaves=%lu,sentinels=%lu\r\n",
2788                 master_id++, ri->name, status,
2789                 ri->addr->ip, ri->addr->port,
2790                 dictSize(ri->slaves),
2791                 dictSize(ri->sentinels)+1);
2792         }
2793         dictReleaseIterator(di);
2794     }
2795 
2796     addReplySds(c,sdscatprintf(sdsempty(),"$%lu\r\n",
2797         (unsigned long)sdslen(info)));
2798     addReplySds(c,info);
2799     addReply(c,shared.crlf);
2800 }
2801 
2802 /* SENTINEL SET <mastername> [<option> <value> ...] */
2803 void sentinelSetCommand(redisClient *c) {
2804     sentinelRedisInstance *ri;
2805     int j, changes = 0;
2806     char *option, *value;
2807 
2808     if ((ri = sentinelGetMasterByNameOrReplyError(c,c->argv[2]))
2809         == NULL) return;
2810 
2811     /* Process option - value pairs. */
2812     for (j = 3; j < c->argc; j += 2) {
2813         option = c->argv[j]->ptr;
2814         value = c->argv[j+1]->ptr;
2815         robj *o = c->argv[j+1];
2816         long long ll;
2817 
2818         if (!strcasecmp(option,"down-after-milliseconds")) {
2819             /* down-after-millisecodns <milliseconds> */
2820             if (getLongLongFromObject(o,&ll) == REDIS_ERR || ll <= 0)
2821                 goto badfmt;
2822             ri->down_after_period = ll;
2823             sentinelPropagateDownAfterPeriod(ri);
2824             changes++;
2825         } else if (!strcasecmp(option,"failover-timeout")) {
2826             /* failover-timeout <milliseconds> */
2827             if (getLongLongFromObject(o,&ll) == REDIS_ERR || ll <= 0)
2828                 goto badfmt;
2829             ri->failover_timeout = ll;
2830             changes++;
2831        } else if (!strcasecmp(option,"parallel-syncs")) {
2832             /* parallel-syncs <milliseconds> */
2833             if (getLongLongFromObject(o,&ll) == REDIS_ERR || ll <= 0)
2834                 goto badfmt;
2835             ri->parallel_syncs = ll;
2836             changes++;
2837        } else if (!strcasecmp(option,"notification-script")) {
2838             /* notification-script <path> */
2839             if (strlen(value) && access(value,X_OK) == -1) {
2840                 addReplyError(c,
2841                     "Notification script seems non existing or non executable");
2842                 if (changes) sentinelFlushConfig();
2843                 return;
2844             }
2845             sdsfree(ri->notification_script);
2846             ri->notification_script = strlen(value) ? sdsnew(value) : NULL;
2847             changes++;
2848        } else if (!strcasecmp(option,"client-reconfig-script")) {
2849             /* client-reconfig-script <path> */
2850             if (strlen(value) && access(value,X_OK) == -1) {
2851                 addReplyError(c,
2852                     "Client reconfiguration script seems non existing or "
2853                     "non executable");
2854                 if (changes) sentinelFlushConfig();
2855                 return;
2856             }
2857             sdsfree(ri->client_reconfig_script);
2858             ri->client_reconfig_script = strlen(value) ? sdsnew(value) : NULL;
2859             changes++;
2860        } else if (!strcasecmp(option,"auth-pass")) {
2861             /* auth-pass <password> */
2862             sdsfree(ri->auth_pass);
2863             ri->auth_pass = strlen(value) ? sdsnew(value) : NULL;
2864             changes++;
2865        } else if (!strcasecmp(option,"quorum")) {
2866             /* quorum <count> */
2867             if (getLongLongFromObject(o,&ll) == REDIS_ERR || ll <= 0)
2868                 goto badfmt;
2869             ri->quorum = ll;
2870             changes++;
2871         } else {
2872             addReplyErrorFormat(c,"Unknown option '%s' for SENTINEL SET",
2873                 option);
2874             if (changes) sentinelFlushConfig();
2875             return;
2876         }
2877         sentinelEvent(REDIS_WARNING,"+set",ri,"%@ %s %s",option,value);
2878     }
2879 
2880     if (changes) sentinelFlushConfig();
2881     addReply(c,shared.ok);
2882     return;
2883 
2884 badfmt: /* Bad format errors */
2885     if (changes) sentinelFlushConfig();
2886     addReplyErrorFormat(c,"Invalid argument '%s' for SENTINEL SET '%s'",
2887             value, option);
2888 }
2889 
2890 /* Our fake PUBLISH command: it is actually useful only to receive hello messages
2891  * from the other sentinel instances, and publishing to a channel other than
2892  * SENTINEL_HELLO_CHANNEL is forbidden.
2893  *
2894  * Because we have a Sentinel PUBLISH, the code to send hello messages is the same
2895  * for all the three kind of instances: masters, slaves, sentinels. */
2896 void sentinelPublishCommand(redisClient *c) {
2897     if (strcmp(c->argv[1]->ptr,SENTINEL_HELLO_CHANNEL)) {
2898         addReplyError(c, "Only HELLO messages are accepted by Sentinel instances.");
2899         return;
2900     }
2901     sentinelProcessHelloMessage(c->argv[2]->ptr,sdslen(c->argv[2]->ptr));
2902     addReplyLongLong(c,1);
2903 }
2904 
2905 /* ===================== SENTINEL availability checks ======================= */
2906 
2907 /* Is this instance down from our point of view? */
2908 void sentinelCheckSubjectivelyDown(sentinelRedisInstance *ri) {
2909     mstime_t elapsed = 0;
2910 
2911     if (ri->last_ping_time)
2912         elapsed = mstime() - ri->last_ping_time;
2913 
2914     /* Check if we are in need for a reconnection of one of the
2915      * links, because we are detecting low activity.
2916      *
2917      * 1) Check if the command link seems connected, was connected not less
2918      *    than SENTINEL_MIN_LINK_RECONNECT_PERIOD, but still we have a
2919      *    pending ping for more than half the timeout. */
2920     if (ri->cc &&
2921         (mstime() - ri->cc_conn_time) > SENTINEL_MIN_LINK_RECONNECT_PERIOD &&
2922         ri->last_ping_time != 0 && /* Ther is a pending ping... */
2923         /* The pending ping is delayed, and we did not received
2924          * error replies as well. */
2925         (mstime() - ri->last_ping_time) > (ri->down_after_period/2) &&
2926         (mstime() - ri->last_pong_time) > (ri->down_after_period/2))
2927     {
2928         sentinelKillLink(ri,ri->cc);
2929     }
2930 
2931     /* 2) Check if the pubsub link seems connected, was connected not less
2932      *    than SENTINEL_MIN_LINK_RECONNECT_PERIOD, but still we have no
2933      *    activity in the Pub/Sub channel for more than
2934      *    SENTINEL_PUBLISH_PERIOD * 3.
2935      */
2936     if (ri->pc &&
2937         (mstime() - ri->pc_conn_time) > SENTINEL_MIN_LINK_RECONNECT_PERIOD &&
2938         (mstime() - ri->pc_last_activity) > (SENTINEL_PUBLISH_PERIOD*3))
2939     {
2940         sentinelKillLink(ri,ri->pc);
2941     }
2942 
2943     /* Update the SDOWN flag. We believe the instance is SDOWN if:
2944      *
2945      * 1) It is not replying.
2946      * 2) We believe it is a master, it reports to be a slave for enough time
2947      *    to meet the down_after_period, plus enough time to get two times
2948      *    INFO report from the instance. */
2949     if (elapsed > ri->down_after_period ||
2950         (ri->flags & SRI_MASTER &&
2951          ri->role_reported == SRI_SLAVE &&
2952          mstime() - ri->role_reported_time >
2953           (ri->down_after_period+SENTINEL_INFO_PERIOD*2)))
2954     {
2955         /* Is subjectively down */
2956         if ((ri->flags & SRI_S_DOWN) == 0) {
2957             sentinelEvent(REDIS_WARNING,"+sdown",ri,"%@");
2958             ri->s_down_since_time = mstime();
2959             ri->flags |= SRI_S_DOWN;
2960         }
2961     } else {
2962         /* Is subjectively up */
2963         if (ri->flags & SRI_S_DOWN) {
2964             sentinelEvent(REDIS_WARNING,"-sdown",ri,"%@");
2965             ri->flags &= ~(SRI_S_DOWN|SRI_SCRIPT_KILL_SENT);
2966         }
2967     }
2968 }
2969 
2970 /* Is this instance down according to the configured quorum?
2971  *
2972  * Note that ODOWN is a weak quorum, it only means that enough Sentinels
2973  * reported in a given time range that the instance was not reachable.
2974  * However messages can be delayed so there are no strong guarantees about
2975  * N instances agreeing at the same time about the down state. */
2976 void sentinelCheckObjectivelyDown(sentinelRedisInstance *master) {
2977     dictIterator *di;
2978     dictEntry *de;
2979     int quorum = 0, odown = 0;
2980 
2981     if (master->flags & SRI_S_DOWN) {
2982         /* Is down for enough sentinels? */
2983         quorum = 1; /* the current sentinel. */
2984         /* Count all the other sentinels. */
2985         di = dictGetIterator(master->sentinels);
2986         while((de = dictNext(di)) != NULL) {
2987             sentinelRedisInstance *ri = dictGetVal(de);
2988 
2989             if (ri->flags & SRI_MASTER_DOWN) quorum++;
2990         }
2991         dictReleaseIterator(di);
2992         if (quorum >= master->quorum) odown = 1;
2993     }
2994 
2995     /* Set the flag accordingly to the outcome. */
2996     if (odown) {
2997         if ((master->flags & SRI_O_DOWN) == 0) {
2998             sentinelEvent(REDIS_WARNING,"+odown",master,"%@ #quorum %d/%d",
2999                 quorum, master->quorum);
3000             master->flags |= SRI_O_DOWN;
3001             master->o_down_since_time = mstime();
3002         }
3003     } else {
3004         if (master->flags & SRI_O_DOWN) {
3005             sentinelEvent(REDIS_WARNING,"-odown",master,"%@");
3006             master->flags &= ~SRI_O_DOWN;
3007         }
3008     }
3009 }
3010 
3011 /* Receive the SENTINEL is-master-down-by-addr reply, see the
3012  * sentinelAskMasterStateToOtherSentinels() function for more information. */
3013 void sentinelReceiveIsMasterDownReply(redisAsyncContext *c, void *reply, void *privdata) {
3014     sentinelRedisInstance *ri = c->data;
3015     redisReply *r;
3016 
3017     if (ri) ri->pending_commands--;
3018     if (!reply || !ri) return;
3019     r = reply;
3020 
3021     /* Ignore every error or unexpected reply.
3022      * Note that if the command returns an error for any reason we'll
3023      * end clearing the SRI_MASTER_DOWN flag for timeout anyway. */
3024     if (r->type == REDIS_REPLY_ARRAY && r->elements == 3 &&
3025         r->element[0]->type == REDIS_REPLY_INTEGER &&
3026         r->element[1]->type == REDIS_REPLY_STRING &&
3027         r->element[2]->type == REDIS_REPLY_INTEGER)
3028     {
3029         ri->last_master_down_reply_time = mstime();
3030         if (r->element[0]->integer == 1) {
3031             ri->flags |= SRI_MASTER_DOWN;
3032         } else {
3033             ri->flags &= ~SRI_MASTER_DOWN;
3034         }
3035         if (strcmp(r->element[1]->str,"*")) {
3036             /* If the runid in the reply is not "*" the Sentinel actually
3037              * replied with a vote. */
3038             sdsfree(ri->leader);
3039             if (ri->leader_epoch != r->element[2]->integer)
3040                 redisLog(REDIS_WARNING,
3041                     "%s voted for %s %llu", ri->name,
3042                     r->element[1]->str,
3043                     (unsigned long long) r->element[2]->integer);
3044             ri->leader = sdsnew(r->element[1]->str);
3045             ri->leader_epoch = r->element[2]->integer;
3046         }
3047     }
3048 }
3049 
3050 /* If we think the master is down, we start sending
3051  * SENTINEL IS-MASTER-DOWN-BY-ADDR requests to other sentinels
3052  * in order to get the replies that allow to reach the quorum
3053  * needed to mark the master in ODOWN state and trigger a failover. */
3054 #define SENTINEL_ASK_FORCED (1<<0)
3055 void sentinelAskMasterStateToOtherSentinels(sentinelRedisInstance *master, int flags) {
3056     dictIterator *di;
3057     dictEntry *de;
3058 
3059     di = dictGetIterator(master->sentinels);
3060     while((de = dictNext(di)) != NULL) {
3061         sentinelRedisInstance *ri = dictGetVal(de);
3062         mstime_t elapsed = mstime() - ri->last_master_down_reply_time;
3063         char port[32];
3064         int retval;
3065 
3066         /* If the master state from other sentinel is too old, we clear it. */
3067         if (elapsed > SENTINEL_ASK_PERIOD*5) {
3068             ri->flags &= ~SRI_MASTER_DOWN;
3069             sdsfree(ri->leader);
3070             ri->leader = NULL;
3071         }
3072 
3073         /* Only ask if master is down to other sentinels if:
3074          *
3075          * 1) We believe it is down, or there is a failover in progress.
3076          * 2) Sentinel is connected.
3077          * 3) We did not received the info within SENTINEL_ASK_PERIOD ms. */
3078         if ((master->flags & SRI_S_DOWN) == 0) continue;
3079         if (ri->flags & SRI_DISCONNECTED) continue;
3080         if (!(flags & SENTINEL_ASK_FORCED) &&
3081             mstime() - ri->last_master_down_reply_time < SENTINEL_ASK_PERIOD)
3082             continue;
3083 
3084         /* Ask */
3085         ll2string(port,sizeof(port),master->addr->port);
3086         retval = redisAsyncCommand(ri->cc,
3087                     sentinelReceiveIsMasterDownReply, NULL,
3088                     "SENTINEL is-master-down-by-addr %s %s %llu %s",
3089                     master->addr->ip, port,
3090                     sentinel.current_epoch,
3091                     (master->failover_state > SENTINEL_FAILOVER_STATE_NONE) ?
3092                     server.runid : "*");
3093         if (retval == REDIS_OK) ri->pending_commands++;
3094     }
3095     dictReleaseIterator(di);
3096 }
3097 
3098 /* =============================== FAILOVER ================================= */
3099 
3100 /* Vote for the sentinel with 'req_runid' or return the old vote if already
3101  * voted for the specifed 'req_epoch' or one greater.
3102  *
3103  * If a vote is not available returns NULL, otherwise return the Sentinel
3104  * runid and populate the leader_epoch with the epoch of the vote. */
3105 char *sentinelVoteLeader(sentinelRedisInstance *master, uint64_t req_epoch, char *req_runid, uint64_t *leader_epoch) {
3106     if (req_epoch > sentinel.current_epoch) {
3107         sentinel.current_epoch = req_epoch;
3108         sentinelFlushConfig();
3109         sentinelEvent(REDIS_WARNING,"+new-epoch",master,"%llu",
3110             (unsigned long long) sentinel.current_epoch);
3111     }
3112 
3113     if (master->leader_epoch < req_epoch && sentinel.current_epoch <= req_epoch)
3114     {
3115         sdsfree(master->leader);
3116         master->leader = sdsnew(req_runid);
3117         master->leader_epoch = sentinel.current_epoch;
3118         sentinelFlushConfig();
3119         sentinelEvent(REDIS_WARNING,"+vote-for-leader",master,"%s %llu",
3120             master->leader, (unsigned long long) master->leader_epoch);
3121         /* If we did not voted for ourselves, set the master failover start
3122          * time to now, in order to force a delay before we can start a
3123          * failover for the same master. */
3124         if (strcasecmp(master->leader,server.runid))
3125             master->failover_start_time = mstime()+rand()%SENTINEL_MAX_DESYNC;
3126     }
3127 
3128     *leader_epoch = master->leader_epoch;
3129     return master->leader ? sdsnew(master->leader) : NULL;
3130 }
3131 
3132 struct sentinelLeader {
3133     char *runid;
3134     unsigned long votes;
3135 };
3136 
3137 /* Helper function for sentinelGetLeader, increment the counter
3138  * relative to the specified runid. */
3139 int sentinelLeaderIncr(dict *counters, char *runid) {
3140     dictEntry *de = dictFind(counters,runid);
3141     uint64_t oldval;
3142 
3143     if (de) {
3144         oldval = dictGetUnsignedIntegerVal(de);
3145         dictSetUnsignedIntegerVal(de,oldval+1);
3146         return oldval+1;
3147     } else {
3148         de = dictAddRaw(counters,runid);
3149         redisAssert(de != NULL);
3150         dictSetUnsignedIntegerVal(de,1);
3151         return 1;
3152     }
3153 }
3154 
3155 /* Scan all the Sentinels attached to this master to check if there
3156  * is a leader for the specified epoch.
3157  *
3158  * To be a leader for a given epoch, we should have the majorify of
3159  * the Sentinels we know that reported the same instance as
3160  * leader for the same epoch. */
3161 char *sentinelGetLeader(sentinelRedisInstance *master, uint64_t epoch) {
3162     dict *counters;
3163     dictIterator *di;
3164     dictEntry *de;
3165     unsigned int voters = 0, voters_quorum;
3166     char *myvote;
3167     char *winner = NULL;
3168     uint64_t leader_epoch;
3169     uint64_t max_votes = 0;
3170 
3171     redisAssert(master->flags & (SRI_O_DOWN|SRI_FAILOVER_IN_PROGRESS));
3172     counters = dictCreate(&leaderVotesDictType,NULL);
3173 
3174     /* Count other sentinels votes */
3175     di = dictGetIterator(master->sentinels);
3176     while((de = dictNext(di)) != NULL) {
3177         sentinelRedisInstance *ri = dictGetVal(de);
3178         if (ri->leader != NULL && ri->leader_epoch == sentinel.current_epoch)
3179             sentinelLeaderIncr(counters,ri->leader);
3180         voters++;
3181     }
3182     dictReleaseIterator(di);
3183 
3184     /* Check what's the winner. For the winner to win, it needs two conditions:
3185      * 1) Absolute majority between voters (50% + 1).
3186      * 2) And anyway at least master->quorum votes. */
3187     di = dictGetIterator(counters);
3188     while((de = dictNext(di)) != NULL) {
3189         uint64_t votes = dictGetUnsignedIntegerVal(de);
3190 
3191         if (votes > max_votes) {
3192             max_votes = votes;
3193             winner = dictGetKey(de);
3194         }
3195     }
3196     dictReleaseIterator(di);
3197 
3198     /* Count this Sentinel vote:
3199      * if this Sentinel did not voted yet, either vote for the most
3200      * common voted sentinel, or for itself if no vote exists at all. */
3201     if (winner)
3202         myvote = sentinelVoteLeader(master,epoch,winner,&leader_epoch);
3203     else
3204         myvote = sentinelVoteLeader(master,epoch,server.runid,&leader_epoch);
3205 
3206     if (myvote && leader_epoch == epoch) {
3207         uint64_t votes = sentinelLeaderIncr(counters,myvote);
3208 
3209         if (votes > max_votes) {
3210             max_votes = votes;
3211             winner = myvote;
3212         }
3213     }
3214     voters++; /* Anyway, count me as one of the voters. */
3215 
3216     voters_quorum = voters/2+1;
3217     if (winner && (max_votes < voters_quorum || max_votes < master->quorum))
3218         winner = NULL;
3219 
3220     winner = winner ? sdsnew(winner) : NULL;
3221     sdsfree(myvote);
3222     dictRelease(counters);
3223     return winner;
3224 }
3225 
3226 /* Send SLAVEOF to the specified instance, always followed by a
3227  * CONFIG REWRITE command in order to store the new configuration on disk
3228  * when possible (that is, if the Redis instance is recent enough to support
3229  * config rewriting, and if the server was started with a configuration file).
3230  *
3231  * If Host is NULL the function sends "SLAVEOF NO ONE".
3232  *
3233  * The command returns REDIS_OK if the SLAVEOF command was accepted for
3234  * (later) delivery otherwise REDIS_ERR. The command replies are just
3235  * discarded. */
3236 int sentinelSendSlaveOf(sentinelRedisInstance *ri, char *host, int port) {
3237     char portstr[32];
3238     int retval;
3239 
3240     ll2string(portstr,sizeof(portstr),port);
3241 
3242     /* If host is NULL we send SLAVEOF NO ONE that will turn the instance
3243      * into a master. */
3244     if (host == NULL) {
3245         host = "NO";
3246         memcpy(portstr,"ONE",4);
3247     }
3248 
3249     /* In order to send SLAVEOF in a safe way, we send a transaction performing
3250      * the following tasks:
3251      * 1) Reconfigure the instance according to the specified host/port params.
3252      * 2) Rewrite the configuraiton.
3253      * 3) Disconnect all clients (but this one sending the commnad) in order
3254      *    to trigger the ask-master-on-reconnection protocol for connected
3255      *    clients.
3256      *
3257      * Note that we don't check the replies returned by commands, since we
3258      * will observe instead the effects in the next INFO output. */
3259     retval = redisAsyncCommand(ri->cc,
3260         sentinelDiscardReplyCallback, NULL, "MULTI");
3261     if (retval == REDIS_ERR) return retval;
3262     ri->pending_commands++;
3263 
3264     retval = redisAsyncCommand(ri->cc,
3265         sentinelDiscardReplyCallback, NULL, "SLAVEOF %s %s", host, portstr);
3266     if (retval == REDIS_ERR) return retval;
3267     ri->pending_commands++;
3268 
3269     retval = redisAsyncCommand(ri->cc,
3270         sentinelDiscardReplyCallback, NULL, "CONFIG REWRITE");
3271     if (retval == REDIS_ERR) return retval;
3272     ri->pending_commands++;
3273 
3274     /* CLIENT KILL TYPE <type> is only supported starting from Redis 2.8.12,
3275      * however sending it to an instance not understanding this command is not
3276      * an issue because CLIENT is variadic command, so Redis will not
3277      * recognized as a syntax error, and the transaction will not fail (but
3278      * only the unsupported command will fail). */
3279     retval = redisAsyncCommand(ri->cc,
3280         sentinelDiscardReplyCallback, NULL, "CLIENT KILL TYPE normal");
3281     if (retval == REDIS_ERR) return retval;
3282     ri->pending_commands++;
3283 
3284     retval = redisAsyncCommand(ri->cc,
3285         sentinelDiscardReplyCallback, NULL, "EXEC");
3286     if (retval == REDIS_ERR) return retval;
3287     ri->pending_commands++;
3288 
3289     return REDIS_OK;
3290 }
3291 
3292 /* Setup the master state to start a failover. */
3293 void sentinelStartFailover(sentinelRedisInstance *master) {
3294     redisAssert(master->flags & SRI_MASTER);
3295 
3296     master->failover_state = SENTINEL_FAILOVER_STATE_WAIT_START;
3297     master->flags |= SRI_FAILOVER_IN_PROGRESS;
3298     master->failover_epoch = ++sentinel.current_epoch;
3299     sentinelEvent(REDIS_WARNING,"+new-epoch",master,"%llu",
3300         (unsigned long long) sentinel.current_epoch);
3301     sentinelEvent(REDIS_WARNING,"+try-failover",master,"%@");
3302     master->failover_start_time = mstime()+rand()%SENTINEL_MAX_DESYNC;
3303     master->failover_state_change_time = mstime();
3304 }
3305 
3306 /* This function checks if there are the conditions to start the failover,
3307  * that is:
3308  *
3309  * 1) Master must be in ODOWN condition.
3310  * 2) No failover already in progress.
3311  * 3) No failover already attempted recently.
3312  *
3313  * We still don't know if we'll win the election so it is possible that we
3314  * start the failover but that we'll not be able to act.
3315  *
3316  * Return non-zero if a failover was started. */
3317 int sentinelStartFailoverIfNeeded(sentinelRedisInstance *master) {
3318     /* We can't failover if the master is not in O_DOWN state. */
3319     if (!(master->flags & SRI_O_DOWN)) return 0;
3320 
3321     /* Failover already in progress? */
3322     if (master->flags & SRI_FAILOVER_IN_PROGRESS) return 0;
3323 
3324     /* Last failover attempt started too little time ago? */
3325     if (mstime() - master->failover_start_time <
3326         master->failover_timeout*2)
3327     {
3328         if (master->failover_delay_logged != master->failover_start_time) {
3329             time_t clock = (master->failover_start_time +
3330                             master->failover_timeout*2) / 1000;
3331             char ctimebuf[26];
3332 
3333             ctime_r(&clock,ctimebuf);
3334             ctimebuf[24] = '\0'; /* Remove newline. */
3335             master->failover_delay_logged = master->failover_start_time;
3336             redisLog(REDIS_WARNING,
3337                 "Next failover delay: I will not start a failover before %s",
3338                 ctimebuf);
3339         }
3340         return 0;
3341     }
3342 
3343     sentinelStartFailover(master);
3344     return 1;
3345 }
3346 
3347 /* Select a suitable slave to promote. The current algorithm only uses
3348  * the following parameters:
3349  *
3350  * 1) None of the following conditions: S_DOWN, O_DOWN, DISCONNECTED.
3351  * 2) Last time the slave replied to ping no more than 5 times the PING period.
3352  * 3) info_refresh not older than 3 times the INFO refresh period.
3353  * 4) master_link_down_time no more than:
3354  *     (now - master->s_down_since_time) + (master->down_after_period * 10).
3355  *    Basically since the master is down from our POV, the slave reports
3356  *    to be disconnected no more than 10 times the configured down-after-period.
3357  *    This is pretty much black magic but the idea is, the master was not
3358  *    available so the slave may be lagging, but not over a certain time.
3359  *    Anyway we'll select the best slave according to replication offset.
3360  * 5) Slave priority can't be zero, otherwise the slave is discarded.
3361  *
3362  * Among all the slaves matching the above conditions we select the slave
3363  * with, in order of sorting key:
3364  *
3365  * - lower slave_priority.
3366  * - bigger processed replication offset.
3367  * - lexicographically smaller runid.
3368  *
3369  * Basically if runid is the same, the slave that processed more commands
3370  * from the master is selected.
3371  *
3372  * The function returns the pointer to the selected slave, otherwise
3373  * NULL if no suitable slave was found.
3374  */
3375 
3376 /* Helper for sentinelSelectSlave(). This is used by qsort() in order to
3377  * sort suitable slaves in a "better first" order, to take the first of
3378  * the list. */
3379 int compareSlavesForPromotion(const void *a, const void *b) {
3380     sentinelRedisInstance **sa = (sentinelRedisInstance **)a,
3381                           **sb = (sentinelRedisInstance **)b;
3382     char *sa_runid, *sb_runid;
3383 
3384     if ((*sa)->slave_priority != (*sb)->slave_priority)
3385         return (*sa)->slave_priority - (*sb)->slave_priority;
3386 
3387     /* If priority is the same, select the slave with greater replication
3388      * offset (processed more data frmo the master). */
3389     if ((*sa)->slave_repl_offset > (*sb)->slave_repl_offset) {
3390         return -1; /* a < b */
3391     } else if ((*sa)->slave_repl_offset < (*sb)->slave_repl_offset) {
3392         return 1; /* b > a */
3393     }
3394 
3395     /* If the replication offset is the same select the slave with that has
3396      * the lexicographically smaller runid. Note that we try to handle runid
3397      * == NULL as there are old Redis versions that don't publish runid in
3398      * INFO. A NULL runid is considered bigger than any other runid. */
3399     sa_runid = (*sa)->runid;
3400     sb_runid = (*sb)->runid;
3401     if (sa_runid == NULL && sb_runid == NULL) return 0;
3402     else if (sa_runid == NULL) return 1;  /* a > b */
3403     else if (sb_runid == NULL) return -1; /* a < b */
3404     return strcasecmp(sa_runid, sb_runid);
3405 }
3406 
3407 sentinelRedisInstance *sentinelSelectSlave(sentinelRedisInstance *master) {
3408     sentinelRedisInstance **instance =
3409         zmalloc(sizeof(instance[0])*dictSize(master->slaves));
3410     sentinelRedisInstance *selected = NULL;
3411     int instances = 0;
3412     dictIterator *di;
3413     dictEntry *de;
3414     mstime_t max_master_down_time = 0;
3415 
3416     if (master->flags & SRI_S_DOWN)
3417         max_master_down_time += mstime() - master->s_down_since_time;
3418     max_master_down_time += master->down_after_period * 10;
3419 
3420     di = dictGetIterator(master->slaves);
3421     while((de = dictNext(di)) != NULL) {
3422         sentinelRedisInstance *slave = dictGetVal(de);
3423         mstime_t info_validity_time;
3424 
3425         if (slave->flags & (SRI_S_DOWN|SRI_O_DOWN|SRI_DISCONNECTED)) continue;
3426         if (mstime() - slave->last_avail_time > SENTINEL_PING_PERIOD*5) continue;
3427         if (slave->slave_priority == 0) continue;
3428 
3429         /* If the master is in SDOWN state we get INFO for slaves every second.
3430          * Otherwise we get it with the usual period so we need to account for
3431          * a larger delay. */
3432         if (master->flags & SRI_S_DOWN)
3433             info_validity_time = SENTINEL_PING_PERIOD*5;
3434         else
3435             info_validity_time = SENTINEL_INFO_PERIOD*3;
3436         if (mstime() - slave->info_refresh > info_validity_time) continue;
3437         if (slave->master_link_down_time > max_master_down_time) continue;
3438         instance[instances++] = slave;
3439     }
3440     dictReleaseIterator(di);
3441     if (instances) {
3442         qsort(instance,instances,sizeof(sentinelRedisInstance*),
3443             compareSlavesForPromotion);
3444         selected = instance[0];
3445     }
3446     zfree(instance);
3447     return selected;
3448 }
3449 
3450 /* ---------------- Failover state machine implementation ------------------- */
3451 void sentinelFailoverWaitStart(sentinelRedisInstance *ri) {
3452     char *leader;
3453     int isleader;
3454 
3455     /* Check if we are the leader for the failover epoch. */
3456     leader = sentinelGetLeader(ri, ri->failover_epoch);
3457     isleader = leader && strcasecmp(leader,server.runid) == 0;
3458     sdsfree(leader);
3459 
3460     /* If I'm not the leader, and it is not a forced failover via
3461      * SENTINEL FAILOVER, then I can't continue with the failover. */
3462     if (!isleader && !(ri->flags & SRI_FORCE_FAILOVER)) {
3463         int election_timeout = SENTINEL_ELECTION_TIMEOUT;
3464 
3465         /* The election timeout is the MIN between SENTINEL_ELECTION_TIMEOUT
3466          * and the configured failover timeout. */
3467         if (election_timeout > ri->failover_timeout)
3468             election_timeout = ri->failover_timeout;
3469         /* Abort the failover if I'm not the leader after some time. */
3470         if (mstime() - ri->failover_start_time > election_timeout) {
3471             sentinelEvent(REDIS_WARNING,"-failover-abort-not-elected",ri,"%@");
3472             sentinelAbortFailover(ri);
3473         }
3474         return;
3475     }
3476     sentinelEvent(REDIS_WARNING,"+elected-leader",ri,"%@");
3477     ri->failover_state = SENTINEL_FAILOVER_STATE_SELECT_SLAVE;
3478     ri->failover_state_change_time = mstime();
3479     sentinelEvent(REDIS_WARNING,"+failover-state-select-slave",ri,"%@");
3480 }
3481 
3482 void sentinelFailoverSelectSlave(sentinelRedisInstance *ri) {
3483     sentinelRedisInstance *slave = sentinelSelectSlave(ri);
3484 
3485     /* We don't handle the timeout in this state as the function aborts
3486      * the failover or go forward in the next state. */
3487     if (slave == NULL) {
3488         sentinelEvent(REDIS_WARNING,"-failover-abort-no-good-slave",ri,"%@");
3489         sentinelAbortFailover(ri);
3490     } else {
3491         sentinelEvent(REDIS_WARNING,"+selected-slave",slave,"%@");
3492         slave->flags |= SRI_PROMOTED;
3493         ri->promoted_slave = slave;
3494         ri->failover_state = SENTINEL_FAILOVER_STATE_SEND_SLAVEOF_NOONE;
3495         ri->failover_state_change_time = mstime();
3496         sentinelEvent(REDIS_NOTICE,"+failover-state-send-slaveof-noone",
3497             slave, "%@");
3498     }
3499 }
3500 
3501 void sentinelFailoverSendSlaveOfNoOne(sentinelRedisInstance *ri) {
3502     int retval;
3503 
3504     /* We can't send the command to the promoted slave if it is now
3505      * disconnected. Retry again and again with this state until the timeout
3506      * is reached, then abort the failover. */
3507     if (ri->promoted_slave->flags & SRI_DISCONNECTED) {
3508         if (mstime() - ri->failover_state_change_time > ri->failover_timeout) {
3509             sentinelEvent(REDIS_WARNING,"-failover-abort-slave-timeout",ri,"%@");
3510             sentinelAbortFailover(ri);
3511         }
3512         return;
3513     }
3514 
3515     /* Send SLAVEOF NO ONE command to turn the slave into a master.
3516      * We actually register a generic callback for this command as we don't
3517      * really care about the reply. We check if it worked indirectly observing
3518      * if INFO returns a different role (master instead of slave). */
3519     retval = sentinelSendSlaveOf(ri->promoted_slave,NULL,0);
3520     if (retval != REDIS_OK) return;
3521     sentinelEvent(REDIS_NOTICE, "+failover-state-wait-promotion",
3522         ri->promoted_slave,"%@");
3523     ri->failover_state = SENTINEL_FAILOVER_STATE_WAIT_PROMOTION;
3524     ri->failover_state_change_time = mstime();
3525 }
3526 
3527 /* We actually wait for promotion indirectly checking with INFO when the
3528  * slave turns into a master. */
3529 void sentinelFailoverWaitPromotion(sentinelRedisInstance *ri) {
3530     /* Just handle the timeout. Switching to the next state is handled
3531      * by the function parsing the INFO command of the promoted slave. */
3532     if (mstime() - ri->failover_state_change_time > ri->failover_timeout) {
3533         sentinelEvent(REDIS_WARNING,"-failover-abort-slave-timeout",ri,"%@");
3534         sentinelAbortFailover(ri);
3535     }
3536 }
3537 
3538 void sentinelFailoverDetectEnd(sentinelRedisInstance *master) {
3539     int not_reconfigured = 0, timeout = 0;
3540     dictIterator *di;
3541     dictEntry *de;
3542     mstime_t elapsed = mstime() - master->failover_state_change_time;
3543 
3544     /* We can't consider failover finished if the promoted slave is
3545      * not reachable. */
3546     if (master->promoted_slave == NULL ||
3547         master->promoted_slave->flags & SRI_S_DOWN) return;
3548 
3549     /* The failover terminates once all the reachable slaves are properly
3550      * configured. */
3551     di = dictGetIterator(master->slaves);
3552     while((de = dictNext(di)) != NULL) {
3553         sentinelRedisInstance *slave = dictGetVal(de);
3554 
3555         if (slave->flags & (SRI_PROMOTED|SRI_RECONF_DONE)) continue;
3556         if (slave->flags & SRI_S_DOWN) continue;
3557         not_reconfigured++;
3558     }
3559     dictReleaseIterator(di);
3560 
3561     /* Force end of failover on timeout. */
3562     if (elapsed > master->failover_timeout) {
3563         not_reconfigured = 0;
3564         timeout = 1;
3565         sentinelEvent(REDIS_WARNING,"+failover-end-for-timeout",master,"%@");
3566     }
3567 
3568     if (not_reconfigured == 0) {
3569         sentinelEvent(REDIS_WARNING,"+failover-end",master,"%@");
3570         master->failover_state = SENTINEL_FAILOVER_STATE_UPDATE_CONFIG;
3571         master->failover_state_change_time = mstime();
3572     }
3573 
3574     /* If I'm the leader it is a good idea to send a best effort SLAVEOF
3575      * command to all the slaves still not reconfigured to replicate with
3576      * the new master. */
3577     if (timeout) {
3578         dictIterator *di;
3579         dictEntry *de;
3580 
3581         di = dictGetIterator(master->slaves);
3582         while((de = dictNext(di)) != NULL) {
3583             sentinelRedisInstance *slave = dictGetVal(de);
3584             int retval;
3585 
3586             if (slave->flags &
3587                 (SRI_RECONF_DONE|SRI_RECONF_SENT|SRI_DISCONNECTED)) continue;
3588 
3589             retval = sentinelSendSlaveOf(slave,
3590                     master->promoted_slave->addr->ip,
3591                     master->promoted_slave->addr->port);
3592             if (retval == REDIS_OK) {
3593                 sentinelEvent(REDIS_NOTICE,"+slave-reconf-sent-be",slave,"%@");
3594                 slave->flags |= SRI_RECONF_SENT;
3595             }
3596         }
3597         dictReleaseIterator(di);
3598     }
3599 }
3600 
3601 /* Send SLAVE OF <new master address> to all the remaining slaves that
3602  * still don't appear to have the configuration updated. */
3603 void sentinelFailoverReconfNextSlave(sentinelRedisInstance *master) {
3604     dictIterator *di;
3605     dictEntry *de;
3606     int in_progress = 0;
3607 
3608     di = dictGetIterator(master->slaves);
3609     while((de = dictNext(di)) != NULL) {
3610         sentinelRedisInstance *slave = dictGetVal(de);
3611 
3612         if (slave->flags & (SRI_RECONF_SENT|SRI_RECONF_INPROG))
3613             in_progress++;
3614     }
3615     dictReleaseIterator(di);
3616 
3617     di = dictGetIterator(master->slaves);
3618     while(in_progress < master->parallel_syncs &&
3619           (de = dictNext(di)) != NULL)
3620     {
3621         sentinelRedisInstance *slave = dictGetVal(de);
3622         int retval;
3623 
3624         /* Skip the promoted slave, and already configured slaves. */
3625         if (slave->flags & (SRI_PROMOTED|SRI_RECONF_DONE)) continue;
3626 
3627         /* If too much time elapsed without the slave moving forward to
3628          * the next state, consider it reconfigured even if it is not.
3629          * Sentinels will detect the slave as misconfigured and fix its
3630          * configuration later. */
3631         if ((slave->flags & SRI_RECONF_SENT) &&
3632             (mstime() - slave->slave_reconf_sent_time) >
3633             SENTINEL_SLAVE_RECONF_TIMEOUT)
3634         {
3635             sentinelEvent(REDIS_NOTICE,"-slave-reconf-sent-timeout",slave,"%@");
3636             slave->flags &= ~SRI_RECONF_SENT;
3637             slave->flags |= SRI_RECONF_DONE;
3638         }
3639 
3640         /* Nothing to do for instances that are disconnected or already
3641          * in RECONF_SENT state. */
3642         if (slave->flags & (SRI_DISCONNECTED|SRI_RECONF_SENT|SRI_RECONF_INPROG))
3643             continue;
3644 
3645         /* Send SLAVEOF <new master>. */
3646         retval = sentinelSendSlaveOf(slave,
3647                 master->promoted_slave->addr->ip,
3648                 master->promoted_slave->addr->port);
3649         if (retval == REDIS_OK) {
3650             slave->flags |= SRI_RECONF_SENT;
3651             slave->slave_reconf_sent_time = mstime();
3652             sentinelEvent(REDIS_NOTICE,"+slave-reconf-sent",slave,"%@");
3653             in_progress++;
3654         }
3655     }
3656     dictReleaseIterator(di);
3657 
3658     /* Check if all the slaves are reconfigured and handle timeout. */
3659     sentinelFailoverDetectEnd(master);
3660 }
3661 
3662 /* This function is called when the slave is in
3663  * SENTINEL_FAILOVER_STATE_UPDATE_CONFIG state. In this state we need
3664  * to remove it from the master table and add the promoted slave instead. */
3665 void sentinelFailoverSwitchToPromotedSlave(sentinelRedisInstance *master) {
3666     sentinelRedisInstance *ref = master->promoted_slave ?
3667                                  master->promoted_slave : master;
3668 
3669     sentinelEvent(REDIS_WARNING,"+switch-master",master,"%s %s %d %s %d",
3670         master->name, master->addr->ip, master->addr->port,
3671         ref->addr->ip, ref->addr->port);
3672 
3673     sentinelResetMasterAndChangeAddress(master,ref->addr->ip,ref->addr->port);
3674 }
3675 
3676 void sentinelFailoverStateMachine(sentinelRedisInstance *ri) {
3677     redisAssert(ri->flags & SRI_MASTER);
3678 
3679     if (!(ri->flags & SRI_FAILOVER_IN_PROGRESS)) return;
3680 
3681     switch(ri->failover_state) {
3682         case SENTINEL_FAILOVER_STATE_WAIT_START:
3683             sentinelFailoverWaitStart(ri);
3684             break;
3685         case SENTINEL_FAILOVER_STATE_SELECT_SLAVE:
3686             sentinelFailoverSelectSlave(ri);
3687             break;
3688         case SENTINEL_FAILOVER_STATE_SEND_SLAVEOF_NOONE:
3689             sentinelFailoverSendSlaveOfNoOne(ri);
3690             break;
3691         case SENTINEL_FAILOVER_STATE_WAIT_PROMOTION:
3692             sentinelFailoverWaitPromotion(ri);
3693             break;
3694         case SENTINEL_FAILOVER_STATE_RECONF_SLAVES:
3695             sentinelFailoverReconfNextSlave(ri);
3696             break;
3697     }
3698 }
3699 
3700 /* Abort a failover in progress:
3701  *
3702  * This function can only be called before the promoted slave acknowledged
3703  * the slave -> master switch. Otherwise the failover can't be aborted and
3704  * will reach its end (possibly by timeout). */
3705 void sentinelAbortFailover(sentinelRedisInstance *ri) {
3706     redisAssert(ri->flags & SRI_FAILOVER_IN_PROGRESS);
3707     redisAssert(ri->failover_state <= SENTINEL_FAILOVER_STATE_WAIT_PROMOTION);
3708 
3709     ri->flags &= ~(SRI_FAILOVER_IN_PROGRESS|SRI_FORCE_FAILOVER);
3710     ri->failover_state = SENTINEL_FAILOVER_STATE_NONE;
3711     ri->failover_state_change_time = mstime();
3712     if (ri->promoted_slave) {
3713         ri->promoted_slave->flags &= ~SRI_PROMOTED;
3714         ri->promoted_slave = NULL;
3715     }
3716 }
3717 
3718 /* ======================== SENTINEL timer handler ==========================
3719  * This is the "main" our Sentinel, being sentinel completely non blocking
3720  * in design. The function is called every second.
3721  * -------------------------------------------------------------------------- */
3722 
3723 /* Perform scheduled operations for the specified Redis instance. */
3724 void sentinelHandleRedisInstance(sentinelRedisInstance *ri) {
3725     /* ========== MONITORING HALF ============ */
3726     /* Every kind of instance */
3727     sentinelReconnectInstance(ri);
3728     sentinelSendPeriodicCommands(ri);
3729 
3730     /* ============== ACTING HALF ============= */
3731     /* We don't proceed with the acting half if we are in TILT mode.
3732      * TILT happens when we find something odd with the time, like a
3733      * sudden change in the clock. */
3734     if (sentinel.tilt) {
3735         if (mstime()-sentinel.tilt_start_time < SENTINEL_TILT_PERIOD) return;
3736         sentinel.tilt = 0;
3737         sentinelEvent(REDIS_WARNING,"-tilt",NULL,"#tilt mode exited");
3738     }
3739 
3740     /* Every kind of instance */
3741     sentinelCheckSubjectivelyDown(ri);
3742 
3743     /* Masters and slaves */
3744     if (ri->flags & (SRI_MASTER|SRI_SLAVE)) {
3745         /* Nothing so far. */
3746     }
3747 
3748     /* Only masters */
3749     if (ri->flags & SRI_MASTER) {
3750         sentinelCheckObjectivelyDown(ri);
3751         if (sentinelStartFailoverIfNeeded(ri))
3752             sentinelAskMasterStateToOtherSentinels(ri,SENTINEL_ASK_FORCED);
3753         sentinelFailoverStateMachine(ri);
3754         sentinelAskMasterStateToOtherSentinels(ri,SENTINEL_NO_FLAGS);
3755     }
3756 }
3757 
3758 /* Perform scheduled operations for all the instances in the dictionary.
3759  * Recursively call the function against dictionaries of slaves. */
3760 void sentinelHandleDictOfRedisInstances(dict *instances) {
3761     dictIterator *di;
3762     dictEntry *de;
3763     sentinelRedisInstance *switch_to_promoted = NULL;
3764 
3765     /* There are a number of things we need to perform against every master. */
3766     di = dictGetIterator(instances);
3767     while((de = dictNext(di)) != NULL) {
3768         sentinelRedisInstance *ri = dictGetVal(de);
3769 
3770         sentinelHandleRedisInstance(ri);
3771         if (ri->flags & SRI_MASTER) {
3772             sentinelHandleDictOfRedisInstances(ri->slaves);
3773             sentinelHandleDictOfRedisInstances(ri->sentinels);
3774             if (ri->failover_state == SENTINEL_FAILOVER_STATE_UPDATE_CONFIG) {
3775                 switch_to_promoted = ri;
3776             }
3777         }
3778     }
3779     if (switch_to_promoted)
3780         sentinelFailoverSwitchToPromotedSlave(switch_to_promoted);
3781     dictReleaseIterator(di);
3782 }
3783 
3784 /* This function checks if we need to enter the TITL mode.
3785  *
3786  * The TILT mode is entered if we detect that between two invocations of the
3787  * timer interrupt, a negative amount of time, or too much time has passed.
3788  * Note that we expect that more or less just 100 milliseconds will pass
3789  * if everything is fine. However we'll see a negative number or a
3790  * difference bigger than SENTINEL_TILT_TRIGGER milliseconds if one of the
3791  * following conditions happen:
3792  *
3793  * 1) The Sentiel process for some time is blocked, for every kind of
3794  * random reason: the load is huge, the computer was frozen for some time
3795  * in I/O or alike, the process was stopped by a signal. Everything.
3796  * 2) The system clock was altered significantly.
3797  *
3798  * Under both this conditions we'll see everything as timed out and failing
3799  * without good reasons. Instead we enter the TILT mode and wait
3800  * for SENTINEL_TILT_PERIOD to elapse before starting to act again.
3801  *
3802  * During TILT time we still collect information, we just do not act. */
3803 void sentinelCheckTiltCondition(void) {
3804     mstime_t now = mstime();
3805     mstime_t delta = now - sentinel.previous_time;
3806 
3807     if (delta < 0 || delta > SENTINEL_TILT_TRIGGER) {
3808         sentinel.tilt = 1;
3809         sentinel.tilt_start_time = mstime();
3810         sentinelEvent(REDIS_WARNING,"+tilt",NULL,"#tilt mode entered");
3811     }
3812     sentinel.previous_time = mstime();
3813 }
3814 
3815 void sentinelTimer(void) {
3816     sentinelCheckTiltCondition();
3817     sentinelHandleDictOfRedisInstances(sentinel.masters);
3818     sentinelRunPendingScripts();
3819     sentinelCollectTerminatedScripts();
3820     sentinelKillTimedoutScripts();
3821 
3822     /* We continuously change the frequency of the Redis "timer interrupt"
3823      * in order to desynchronize every Sentinel from every other.
3824      * This non-determinism avoids that Sentinels started at the same time
3825      * exactly continue to stay synchronized asking to be voted at the
3826      * same time again and again (resulting in nobody likely winning the
3827      * election because of split brain voting). */
3828     server.hz = REDIS_DEFAULT_HZ + rand() % REDIS_DEFAULT_HZ;
3829 }
3830 
3831