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