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