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