2  * Copyright (c) 2009-2010, Salvatore Sanfilippo <antirez at gmail dot com> 
   5  * Redistribution and use in source and binary forms, with or without 
   6  * modification, are permitted provided that the following conditions are met: 
   8  *   * Redistributions of source code must retain the above copyright notice, 
   9  *     this list of conditions and the following disclaimer. 
  10  *   * Redistributions in binary form must reproduce the above copyright 
  11  *     notice, this list of conditions and the following disclaimer in the 
  12  *     documentation and/or other materials provided with the distribution. 
  13  *   * Neither the name of Redis nor the names of its contributors may be used 
  14  *     to endorse or promote products derived from this software without 
  15  *     specific prior written permission. 
  17  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
  18  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
  19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
  20  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 
  21  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 
  22  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
  23  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
  24  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
  25  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
  26  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
  27  * POSSIBILITY OF SUCH DAMAGE. 
  41 #include <arpa/inet.h> 
  45 #include <sys/resource.h> 
  50 #include <sys/resource.h> 
  51 #include <sys/utsname.h> 
  53 /* Our shared "common" objects */ 
  55 struct sharedObjectsStruct shared
; 
  57 /* Global vars that are actually used as constants. The following double 
  58  * values are used for double on-disk serialization, and are initialized 
  59  * at runtime to avoid strange compiler optimizations. */ 
  61 double R_Zero
, R_PosInf
, R_NegInf
, R_Nan
; 
  63 /*================================= Globals ================================= */ 
  66 struct redisServer server
; /* server global state */ 
  67 struct redisCommand 
*commandTable
; 
  71  * Every entry is composed of the following fields: 
  73  * name: a string representing the command name. 
  74  * function: pointer to the C function implementing the command. 
  75  * arity: number of arguments, it is possible to use -N to say >= N 
  76  * sflags: command flags as string. See below for a table of flags. 
  77  * flags: flags as bitmask. Computed by Redis using the 'sflags' field. 
  78  * get_keys_proc: an optional function to get key arguments from a command. 
  79  *                This is only used when the following three fields are not 
  80  *                enough to specify what arguments are keys. 
  81  * first_key_index: first argument that is a key 
  82  * last_key_index: last argument that is a key 
  83  * key_step: step to get all the keys from first to last argument. For instance 
  84  *           in MSET the step is two since arguments are key,val,key,val,... 
  85  * microseconds: microseconds of total execution time for this command. 
  86  * calls: total number of calls of this command. 
  88  * The flags, microseconds and calls fields are computed by Redis and should 
  89  * always be set to zero. 
  91  * Command flags are expressed using strings where every character represents 
  92  * a flag. Later the populateCommandTable() function will take care of 
  93  * populating the real 'flags' field using this characters. 
  95  * This is the meaning of the flags: 
  97  * w: write command (may modify the key space). 
  98  * r: read command  (will never modify the key space). 
  99  * m: may increase memory usage once called. Don't allow if out of memory. 
 100  * a: admin command, like SAVE or SHUTDOWN. 
 101  * p: Pub/Sub related command. 
 102  * f: force replication of this command, regarless of server.dirty. 
 103  * s: command not allowed in scripts. 
 104  * R: random command. Command is not deterministic, that is, the same command 
 105  *    with the same arguments, with the same key space, may have different 
 106  *    results. For instance SPOP and RANDOMKEY are two random commands. 
 107  * S: Sort command output array if called from script, so that the output 
 109  * l: Allow command while loading the database. 
 110  * t: Allow command while a slave has stale data but is not allowed to 
 111  *    server this data. Normally no command is accepted in this condition 
 113  * M: Do not automatically propagate the command on MONITOR. 
 115 struct redisCommand redisCommandTable
[] = { 
 116     {"get",getCommand
,2,"r",0,NULL
,1,1,1,0,0}, 
 117     {"set",setCommand
,3,"wm",0,noPreloadGetKeys
,1,1,1,0,0}, 
 118     {"setnx",setnxCommand
,3,"wm",0,noPreloadGetKeys
,1,1,1,0,0}, 
 119     {"setex",setexCommand
,4,"wm",0,noPreloadGetKeys
,1,1,1,0,0}, 
 120     {"psetex",psetexCommand
,4,"wm",0,noPreloadGetKeys
,1,1,1,0,0}, 
 121     {"append",appendCommand
,3,"wm",0,NULL
,1,1,1,0,0}, 
 122     {"strlen",strlenCommand
,2,"r",0,NULL
,1,1,1,0,0}, 
 123     {"del",delCommand
,-2,"w",0,noPreloadGetKeys
,1,-1,1,0,0}, 
 124     {"exists",existsCommand
,2,"r",0,NULL
,1,1,1,0,0}, 
 125     {"setbit",setbitCommand
,4,"wm",0,NULL
,1,1,1,0,0}, 
 126     {"getbit",getbitCommand
,3,"r",0,NULL
,1,1,1,0,0}, 
 127     {"setrange",setrangeCommand
,4,"wm",0,NULL
,1,1,1,0,0}, 
 128     {"getrange",getrangeCommand
,4,"r",0,NULL
,1,1,1,0,0}, 
 129     {"substr",getrangeCommand
,4,"r",0,NULL
,1,1,1,0,0}, 
 130     {"incr",incrCommand
,2,"wm",0,NULL
,1,1,1,0,0}, 
 131     {"decr",decrCommand
,2,"wm",0,NULL
,1,1,1,0,0}, 
 132     {"mget",mgetCommand
,-2,"r",0,NULL
,1,-1,1,0,0}, 
 133     {"rpush",rpushCommand
,-3,"wm",0,NULL
,1,1,1,0,0}, 
 134     {"lpush",lpushCommand
,-3,"wm",0,NULL
,1,1,1,0,0}, 
 135     {"rpushx",rpushxCommand
,3,"wm",0,NULL
,1,1,1,0,0}, 
 136     {"lpushx",lpushxCommand
,3,"wm",0,NULL
,1,1,1,0,0}, 
 137     {"linsert",linsertCommand
,5,"wm",0,NULL
,1,1,1,0,0}, 
 138     {"rpop",rpopCommand
,2,"w",0,NULL
,1,1,1,0,0}, 
 139     {"lpop",lpopCommand
,2,"w",0,NULL
,1,1,1,0,0}, 
 140     {"brpop",brpopCommand
,-3,"ws",0,NULL
,1,1,1,0,0}, 
 141     {"brpoplpush",brpoplpushCommand
,4,"wms",0,NULL
,1,2,1,0,0}, 
 142     {"blpop",blpopCommand
,-3,"ws",0,NULL
,1,-2,1,0,0}, 
 143     {"llen",llenCommand
,2,"r",0,NULL
,1,1,1,0,0}, 
 144     {"lindex",lindexCommand
,3,"r",0,NULL
,1,1,1,0,0}, 
 145     {"lset",lsetCommand
,4,"wm",0,NULL
,1,1,1,0,0}, 
 146     {"lrange",lrangeCommand
,4,"r",0,NULL
,1,1,1,0,0}, 
 147     {"ltrim",ltrimCommand
,4,"w",0,NULL
,1,1,1,0,0}, 
 148     {"lrem",lremCommand
,4,"w",0,NULL
,1,1,1,0,0}, 
 149     {"rpoplpush",rpoplpushCommand
,3,"wm",0,NULL
,1,2,1,0,0}, 
 150     {"sadd",saddCommand
,-3,"wm",0,NULL
,1,1,1,0,0}, 
 151     {"srem",sremCommand
,-3,"w",0,NULL
,1,1,1,0,0}, 
 152     {"smove",smoveCommand
,4,"w",0,NULL
,1,2,1,0,0}, 
 153     {"sismember",sismemberCommand
,3,"r",0,NULL
,1,1,1,0,0}, 
 154     {"scard",scardCommand
,2,"r",0,NULL
,1,1,1,0,0}, 
 155     {"spop",spopCommand
,2,"wRs",0,NULL
,1,1,1,0,0}, 
 156     {"srandmember",srandmemberCommand
,-2,"rR",0,NULL
,1,1,1,0,0}, 
 157     {"sinter",sinterCommand
,-2,"rS",0,NULL
,1,-1,1,0,0}, 
 158     {"sinterstore",sinterstoreCommand
,-3,"wm",0,NULL
,1,-1,1,0,0}, 
 159     {"sunion",sunionCommand
,-2,"rS",0,NULL
,1,-1,1,0,0}, 
 160     {"sunionstore",sunionstoreCommand
,-3,"wm",0,NULL
,1,-1,1,0,0}, 
 161     {"sdiff",sdiffCommand
,-2,"rS",0,NULL
,1,-1,1,0,0}, 
 162     {"sdiffstore",sdiffstoreCommand
,-3,"wm",0,NULL
,1,-1,1,0,0}, 
 163     {"smembers",sinterCommand
,2,"rS",0,NULL
,1,1,1,0,0}, 
 164     {"zadd",zaddCommand
,-4,"wm",0,NULL
,1,1,1,0,0}, 
 165     {"zincrby",zincrbyCommand
,4,"wm",0,NULL
,1,1,1,0,0}, 
 166     {"zrem",zremCommand
,-3,"w",0,NULL
,1,1,1,0,0}, 
 167     {"zremrangebyscore",zremrangebyscoreCommand
,4,"w",0,NULL
,1,1,1,0,0}, 
 168     {"zremrangebyrank",zremrangebyrankCommand
,4,"w",0,NULL
,1,1,1,0,0}, 
 169     {"zunionstore",zunionstoreCommand
,-4,"wm",0,zunionInterGetKeys
,0,0,0,0,0}, 
 170     {"zinterstore",zinterstoreCommand
,-4,"wm",0,zunionInterGetKeys
,0,0,0,0,0}, 
 171     {"zrange",zrangeCommand
,-4,"r",0,NULL
,1,1,1,0,0}, 
 172     {"zrangebyscore",zrangebyscoreCommand
,-4,"r",0,NULL
,1,1,1,0,0}, 
 173     {"zrevrangebyscore",zrevrangebyscoreCommand
,-4,"r",0,NULL
,1,1,1,0,0}, 
 174     {"zcount",zcountCommand
,4,"r",0,NULL
,1,1,1,0,0}, 
 175     {"zrevrange",zrevrangeCommand
,-4,"r",0,NULL
,1,1,1,0,0}, 
 176     {"zcard",zcardCommand
,2,"r",0,NULL
,1,1,1,0,0}, 
 177     {"zscore",zscoreCommand
,3,"r",0,NULL
,1,1,1,0,0}, 
 178     {"zrank",zrankCommand
,3,"r",0,NULL
,1,1,1,0,0}, 
 179     {"zrevrank",zrevrankCommand
,3,"r",0,NULL
,1,1,1,0,0}, 
 180     {"hset",hsetCommand
,4,"wm",0,NULL
,1,1,1,0,0}, 
 181     {"hsetnx",hsetnxCommand
,4,"wm",0,NULL
,1,1,1,0,0}, 
 182     {"hget",hgetCommand
,3,"r",0,NULL
,1,1,1,0,0}, 
 183     {"hmset",hmsetCommand
,-4,"wm",0,NULL
,1,1,1,0,0}, 
 184     {"hmget",hmgetCommand
,-3,"r",0,NULL
,1,1,1,0,0}, 
 185     {"hincrby",hincrbyCommand
,4,"wm",0,NULL
,1,1,1,0,0}, 
 186     {"hincrbyfloat",hincrbyfloatCommand
,4,"wm",0,NULL
,1,1,1,0,0}, 
 187     {"hdel",hdelCommand
,-3,"w",0,NULL
,1,1,1,0,0}, 
 188     {"hlen",hlenCommand
,2,"r",0,NULL
,1,1,1,0,0}, 
 189     {"hkeys",hkeysCommand
,2,"rS",0,NULL
,1,1,1,0,0}, 
 190     {"hvals",hvalsCommand
,2,"rS",0,NULL
,1,1,1,0,0}, 
 191     {"hgetall",hgetallCommand
,2,"r",0,NULL
,1,1,1,0,0}, 
 192     {"hexists",hexistsCommand
,3,"r",0,NULL
,1,1,1,0,0}, 
 193     {"incrby",incrbyCommand
,3,"wm",0,NULL
,1,1,1,0,0}, 
 194     {"decrby",decrbyCommand
,3,"wm",0,NULL
,1,1,1,0,0}, 
 195     {"incrbyfloat",incrbyfloatCommand
,3,"wm",0,NULL
,1,1,1,0,0}, 
 196     {"getset",getsetCommand
,3,"wm",0,NULL
,1,1,1,0,0}, 
 197     {"mset",msetCommand
,-3,"wm",0,NULL
,1,-1,2,0,0}, 
 198     {"msetnx",msetnxCommand
,-3,"wm",0,NULL
,1,-1,2,0,0}, 
 199     {"randomkey",randomkeyCommand
,1,"rR",0,NULL
,0,0,0,0,0}, 
 200     {"select",selectCommand
,2,"r",0,NULL
,0,0,0,0,0}, 
 201     {"move",moveCommand
,3,"w",0,NULL
,1,1,1,0,0}, 
 202     {"rename",renameCommand
,3,"w",0,renameGetKeys
,1,2,1,0,0}, 
 203     {"renamenx",renamenxCommand
,3,"w",0,renameGetKeys
,1,2,1,0,0}, 
 204     {"expire",expireCommand
,3,"w",0,NULL
,1,1,1,0,0}, 
 205     {"expireat",expireatCommand
,3,"w",0,NULL
,1,1,1,0,0}, 
 206     {"pexpire",pexpireCommand
,3,"w",0,NULL
,1,1,1,0,0}, 
 207     {"pexpireat",pexpireatCommand
,3,"w",0,NULL
,1,1,1,0,0}, 
 208     {"keys",keysCommand
,2,"rS",0,NULL
,0,0,0,0,0}, 
 209     {"dbsize",dbsizeCommand
,1,"r",0,NULL
,0,0,0,0,0}, 
 210     {"auth",authCommand
,2,"rs",0,NULL
,0,0,0,0,0}, 
 211     {"ping",pingCommand
,1,"r",0,NULL
,0,0,0,0,0}, 
 212     {"echo",echoCommand
,2,"r",0,NULL
,0,0,0,0,0}, 
 213     {"save",saveCommand
,1,"ars",0,NULL
,0,0,0,0,0}, 
 214     {"bgsave",bgsaveCommand
,1,"ar",0,NULL
,0,0,0,0,0}, 
 215     {"bgrewriteaof",bgrewriteaofCommand
,1,"ar",0,NULL
,0,0,0,0,0}, 
 216     {"shutdown",shutdownCommand
,-1,"ar",0,NULL
,0,0,0,0,0}, 
 217     {"lastsave",lastsaveCommand
,1,"r",0,NULL
,0,0,0,0,0}, 
 218     {"type",typeCommand
,2,"r",0,NULL
,1,1,1,0,0}, 
 219     {"multi",multiCommand
,1,"rs",0,NULL
,0,0,0,0,0}, 
 220     {"exec",execCommand
,1,"sM",0,NULL
,0,0,0,0,0}, 
 221     {"discard",discardCommand
,1,"rs",0,NULL
,0,0,0,0,0}, 
 222     {"sync",syncCommand
,1,"ars",0,NULL
,0,0,0,0,0}, 
 223     {"replconf",replconfCommand
,-1,"ars",0,NULL
,0,0,0,0,0}, 
 224     {"flushdb",flushdbCommand
,1,"w",0,NULL
,0,0,0,0,0}, 
 225     {"flushall",flushallCommand
,1,"w",0,NULL
,0,0,0,0,0}, 
 226     {"sort",sortCommand
,-2,"wm",0,NULL
,1,1,1,0,0}, 
 227     {"info",infoCommand
,-1,"rlt",0,NULL
,0,0,0,0,0}, 
 228     {"monitor",monitorCommand
,1,"ars",0,NULL
,0,0,0,0,0}, 
 229     {"ttl",ttlCommand
,2,"r",0,NULL
,1,1,1,0,0}, 
 230     {"pttl",pttlCommand
,2,"r",0,NULL
,1,1,1,0,0}, 
 231     {"persist",persistCommand
,2,"w",0,NULL
,1,1,1,0,0}, 
 232     {"slaveof",slaveofCommand
,3,"ast",0,NULL
,0,0,0,0,0}, 
 233     {"debug",debugCommand
,-2,"as",0,NULL
,0,0,0,0,0}, 
 234     {"config",configCommand
,-2,"ar",0,NULL
,0,0,0,0,0}, 
 235     {"subscribe",subscribeCommand
,-2,"rpslt",0,NULL
,0,0,0,0,0}, 
 236     {"unsubscribe",unsubscribeCommand
,-1,"rpslt",0,NULL
,0,0,0,0,0}, 
 237     {"psubscribe",psubscribeCommand
,-2,"rpslt",0,NULL
,0,0,0,0,0}, 
 238     {"punsubscribe",punsubscribeCommand
,-1,"rpslt",0,NULL
,0,0,0,0,0}, 
 239     {"publish",publishCommand
,3,"pflt",0,NULL
,0,0,0,0,0}, 
 240     {"watch",watchCommand
,-2,"rs",0,noPreloadGetKeys
,1,-1,1,0,0}, 
 241     {"unwatch",unwatchCommand
,1,"rs",0,NULL
,0,0,0,0,0}, 
 242     {"restore",restoreCommand
,4,"awm",0,NULL
,1,1,1,0,0}, 
 243     {"migrate",migrateCommand
,6,"aw",0,NULL
,0,0,0,0,0}, 
 244     {"dump",dumpCommand
,2,"ar",0,NULL
,1,1,1,0,0}, 
 245     {"object",objectCommand
,-2,"r",0,NULL
,2,2,2,0,0}, 
 246     {"client",clientCommand
,-2,"ar",0,NULL
,0,0,0,0,0}, 
 247     {"eval",evalCommand
,-3,"s",0,zunionInterGetKeys
,0,0,0,0,0}, 
 248     {"evalsha",evalShaCommand
,-3,"s",0,zunionInterGetKeys
,0,0,0,0,0}, 
 249     {"slowlog",slowlogCommand
,-2,"r",0,NULL
,0,0,0,0,0}, 
 250     {"script",scriptCommand
,-2,"ras",0,NULL
,0,0,0,0,0}, 
 251     {"time",timeCommand
,1,"rR",0,NULL
,0,0,0,0,0}, 
 252     {"bitop",bitopCommand
,-4,"wm",0,NULL
,2,-1,1,0,0}, 
 253     {"bitcount",bitcountCommand
,-2,"r",0,NULL
,1,1,1,0,0} 
 256 /*============================ Utility functions ============================ */ 
 258 /* Low level logging. To use only for very big messages, otherwise 
 259  * redisLog() is to prefer. */ 
 260 void redisLogRaw(int level
, const char *msg
) { 
 261     const int syslogLevelMap
[] = { LOG_DEBUG
, LOG_INFO
, LOG_NOTICE
, LOG_WARNING 
}; 
 262     const char *c 
= ".-*#"; 
 265     int rawmode 
= (level 
& REDIS_LOG_RAW
); 
 267     level 
&= 0xff; /* clear flags */ 
 268     if (level 
< server
.verbosity
) return; 
 270     fp 
= (server
.logfile 
== NULL
) ? stdout 
: fopen(server
.logfile
,"a"); 
 274         fprintf(fp
,"%s",msg
); 
 279         gettimeofday(&tv
,NULL
); 
 280         off 
= strftime(buf
,sizeof(buf
),"%d %b %H:%M:%S.",localtime(&tv
.tv_sec
)); 
 281         snprintf(buf
+off
,sizeof(buf
)-off
,"%03d",(int)tv
.tv_usec
/1000); 
 282         fprintf(fp
,"[%d] %s %c %s\n",(int)getpid(),buf
,c
[level
],msg
); 
 286     if (server
.logfile
) fclose(fp
); 
 288     if (server
.syslog_enabled
) syslog(syslogLevelMap
[level
], "%s", msg
); 
 291 /* Like redisLogRaw() but with printf-alike support. This is the funciton that 
 292  * is used across the code. The raw version is only used in order to dump 
 293  * the INFO output on crash. */ 
 294 void redisLog(int level
, const char *fmt
, ...) { 
 296     char msg
[REDIS_MAX_LOGMSG_LEN
]; 
 298     if ((level
&0xff) < server
.verbosity
) return; 
 301     vsnprintf(msg
, sizeof(msg
), fmt
, ap
); 
 304     redisLogRaw(level
,msg
); 
 307 /* Log a fixed message without printf-alike capabilities, in a way that is 
 308  * safe to call from a signal handler. 
 310  * We actually use this only for signals that are not fatal from the point 
 311  * of view of Redis. Signals that are going to kill the server anyway and 
 312  * where we need printf-alike features are served by redisLog(). */ 
 313 void redisLogFromHandler(int level
, const char *msg
) { 
 317     if ((level
&0xff) < server
.verbosity 
|| 
 318         (server
.logfile 
== NULL 
&& server
.daemonize
)) return; 
 319     fd 
= server
.logfile 
? 
 320         open(server
.logfile
, O_APPEND
|O_CREAT
|O_WRONLY
, 0644) : 
 322     if (fd 
== -1) return; 
 323     ll2string(buf
,sizeof(buf
),getpid()); 
 324     if (write(fd
,"[",1) == -1) goto err
; 
 325     if (write(fd
,buf
,strlen(buf
)) == -1) goto err
; 
 326     if (write(fd
," | signal handler] (",20) == -1) goto err
; 
 327     ll2string(buf
,sizeof(buf
),time(NULL
)); 
 328     if (write(fd
,buf
,strlen(buf
)) == -1) goto err
; 
 329     if (write(fd
,") ",2) == -1) goto err
; 
 330     if (write(fd
,msg
,strlen(msg
)) == -1) goto err
; 
 331     if (write(fd
,"\n",1) == -1) goto err
; 
 333     if (server
.logfile
) close(fd
); 
 336 /* Return the UNIX time in microseconds */ 
 337 long long ustime(void) { 
 341     gettimeofday(&tv
, NULL
); 
 342     ust 
= ((long long)tv
.tv_sec
)*1000000; 
 347 /* Return the UNIX time in milliseconds */ 
 348 long long mstime(void) { 
 349     return ustime()/1000; 
 352 /* After an RDB dump or AOF rewrite we exit from children using _exit() instead of 
 353  * exit(), because the latter may interact with the same file objects used by 
 354  * the parent process. However if we are testing the coverage normal exit() is 
 355  * used in order to obtain the right coverage information. */ 
 356 void exitFromChild(int retcode
) { 
 364 /*====================== Hash table type implementation  ==================== */ 
 366 /* This is an hash table type that uses the SDS dynamic strings libary as 
 367  * keys and radis objects as values (objects can hold SDS strings, 
 370 void dictVanillaFree(void *privdata
, void *val
) 
 372     DICT_NOTUSED(privdata
); 
 376 void dictListDestructor(void *privdata
, void *val
) 
 378     DICT_NOTUSED(privdata
); 
 379     listRelease((list
*)val
); 
 382 int dictSdsKeyCompare(void *privdata
, const void *key1
, 
 386     DICT_NOTUSED(privdata
); 
 388     l1 
= sdslen((sds
)key1
); 
 389     l2 
= sdslen((sds
)key2
); 
 390     if (l1 
!= l2
) return 0; 
 391     return memcmp(key1
, key2
, l1
) == 0; 
 394 /* A case insensitive version used for the command lookup table. */ 
 395 int dictSdsKeyCaseCompare(void *privdata
, const void *key1
, 
 398     DICT_NOTUSED(privdata
); 
 400     return strcasecmp(key1
, key2
) == 0; 
 403 void dictRedisObjectDestructor(void *privdata
, void *val
) 
 405     DICT_NOTUSED(privdata
); 
 407     if (val 
== NULL
) return; /* Values of swapped out keys as set to NULL */ 
 411 void dictSdsDestructor(void *privdata
, void *val
) 
 413     DICT_NOTUSED(privdata
); 
 418 int dictObjKeyCompare(void *privdata
, const void *key1
, 
 421     const robj 
*o1 
= key1
, *o2 
= key2
; 
 422     return dictSdsKeyCompare(privdata
,o1
->ptr
,o2
->ptr
); 
 425 unsigned int dictObjHash(const void *key
) { 
 427     return dictGenHashFunction(o
->ptr
, sdslen((sds
)o
->ptr
)); 
 430 unsigned int dictSdsHash(const void *key
) { 
 431     return dictGenHashFunction((unsigned char*)key
, sdslen((char*)key
)); 
 434 unsigned int dictSdsCaseHash(const void *key
) { 
 435     return dictGenCaseHashFunction((unsigned char*)key
, sdslen((char*)key
)); 
 438 int dictEncObjKeyCompare(void *privdata
, const void *key1
, 
 441     robj 
*o1 
= (robj
*) key1
, *o2 
= (robj
*) key2
; 
 444     if (o1
->encoding 
== REDIS_ENCODING_INT 
&& 
 445         o2
->encoding 
== REDIS_ENCODING_INT
) 
 446             return o1
->ptr 
== o2
->ptr
; 
 448     o1 
= getDecodedObject(o1
); 
 449     o2 
= getDecodedObject(o2
); 
 450     cmp 
= dictSdsKeyCompare(privdata
,o1
->ptr
,o2
->ptr
); 
 456 unsigned int dictEncObjHash(const void *key
) { 
 457     robj 
*o 
= (robj
*) key
; 
 459     if (o
->encoding 
== REDIS_ENCODING_RAW
) { 
 460         return dictGenHashFunction(o
->ptr
, sdslen((sds
)o
->ptr
)); 
 462         if (o
->encoding 
== REDIS_ENCODING_INT
) { 
 466             len 
= ll2string(buf
,32,(long)o
->ptr
); 
 467             return dictGenHashFunction((unsigned char*)buf
, len
); 
 471             o 
= getDecodedObject(o
); 
 472             hash 
= dictGenHashFunction(o
->ptr
, sdslen((sds
)o
->ptr
)); 
 479 /* Sets type hash table */ 
 480 dictType setDictType 
= { 
 481     dictEncObjHash
,            /* hash function */ 
 484     dictEncObjKeyCompare
,      /* key compare */ 
 485     dictRedisObjectDestructor
, /* key destructor */ 
 486     NULL                       
/* val destructor */ 
 489 /* Sorted sets hash (note: a skiplist is used in addition to the hash table) */ 
 490 dictType zsetDictType 
= { 
 491     dictEncObjHash
,            /* hash function */ 
 494     dictEncObjKeyCompare
,      /* key compare */ 
 495     dictRedisObjectDestructor
, /* key destructor */ 
 496     NULL                       
/* val destructor */ 
 499 /* Db->dict, keys are sds strings, vals are Redis objects. */ 
 500 dictType dbDictType 
= { 
 501     dictSdsHash
,                /* hash function */ 
 504     dictSdsKeyCompare
,          /* key compare */ 
 505     dictSdsDestructor
,          /* key destructor */ 
 506     dictRedisObjectDestructor   
/* val destructor */ 
 510 dictType keyptrDictType 
= { 
 511     dictSdsHash
,               /* hash function */ 
 514     dictSdsKeyCompare
,         /* key compare */ 
 515     NULL
,                      /* key destructor */ 
 516     NULL                       
/* val destructor */ 
 519 /* Command table. sds string -> command struct pointer. */ 
 520 dictType commandTableDictType 
= { 
 521     dictSdsCaseHash
,           /* hash function */ 
 524     dictSdsKeyCaseCompare
,     /* key compare */ 
 525     dictSdsDestructor
,         /* key destructor */ 
 526     NULL                       
/* val destructor */ 
 529 /* Hash type hash table (note that small hashes are represented with zimpaps) */ 
 530 dictType hashDictType 
= { 
 531     dictEncObjHash
,             /* hash function */ 
 534     dictEncObjKeyCompare
,       /* key compare */ 
 535     dictRedisObjectDestructor
,  /* key destructor */ 
 536     dictRedisObjectDestructor   
/* val destructor */ 
 539 /* Keylist hash table type has unencoded redis objects as keys and 
 540  * lists as values. It's used for blocking operations (BLPOP) and to 
 541  * map swapped keys to a list of clients waiting for this keys to be loaded. */ 
 542 dictType keylistDictType 
= { 
 543     dictObjHash
,                /* hash function */ 
 546     dictObjKeyCompare
,          /* key compare */ 
 547     dictRedisObjectDestructor
,  /* key destructor */ 
 548     dictListDestructor          
/* val destructor */ 
 551 int htNeedsResize(dict 
*dict
) { 
 552     long long size
, used
; 
 554     size 
= dictSlots(dict
); 
 555     used 
= dictSize(dict
); 
 556     return (size 
&& used 
&& size 
> DICT_HT_INITIAL_SIZE 
&& 
 557             (used
*100/size 
< REDIS_HT_MINFILL
)); 
 560 /* If the percentage of used slots in the HT reaches REDIS_HT_MINFILL 
 561  * we resize the hash table to save memory */ 
 562 void tryResizeHashTables(void) { 
 565     for (j 
= 0; j 
< server
.dbnum
; j
++) { 
 566         if (htNeedsResize(server
.db
[j
].dict
)) 
 567             dictResize(server
.db
[j
].dict
); 
 568         if (htNeedsResize(server
.db
[j
].expires
)) 
 569             dictResize(server
.db
[j
].expires
); 
 573 /* Our hash table implementation performs rehashing incrementally while 
 574  * we write/read from the hash table. Still if the server is idle, the hash 
 575  * table will use two tables for a long time. So we try to use 1 millisecond 
 576  * of CPU time at every serverCron() loop in order to rehash some key. */ 
 577 void incrementallyRehash(void) { 
 580     for (j 
= 0; j 
< server
.dbnum
; j
++) { 
 581         /* Keys dictionary */ 
 582         if (dictIsRehashing(server
.db
[j
].dict
)) { 
 583             dictRehashMilliseconds(server
.db
[j
].dict
,1); 
 584             break; /* already used our millisecond for this loop... */ 
 587         if (dictIsRehashing(server
.db
[j
].expires
)) { 
 588             dictRehashMilliseconds(server
.db
[j
].expires
,1); 
 589             break; /* already used our millisecond for this loop... */ 
 594 /* This function is called once a background process of some kind terminates, 
 595  * as we want to avoid resizing the hash tables when there is a child in order 
 596  * to play well with copy-on-write (otherwise when a resize happens lots of 
 597  * memory pages are copied). The goal of this function is to update the ability 
 598  * for dict.c to resize the hash tables accordingly to the fact we have o not 
 600 void updateDictResizePolicy(void) { 
 601     if (server
.rdb_child_pid 
== -1 && server
.aof_child_pid 
== -1) 
 607 /* ======================= Cron: called every 100 ms ======================== */ 
 609 /* Try to expire a few timed out keys. The algorithm used is adaptive and 
 610  * will use few CPU cycles if there are few expiring keys, otherwise 
 611  * it will get more aggressive to avoid that too much memory is used by 
 612  * keys that can be removed from the keyspace. */ 
 613 void activeExpireCycle(void) { 
 614     int j
, iteration 
= 0; 
 615     long long start 
= ustime(), timelimit
; 
 617     /* We can use at max REDIS_EXPIRELOOKUPS_TIME_PERC percentage of CPU time 
 618      * per iteration. Since this function gets called with a frequency of 
 619      * REDIS_HZ times per second, the following is the max amount of 
 620      * microseconds we can spend in this function. */ 
 621     timelimit 
= 1000000*REDIS_EXPIRELOOKUPS_TIME_PERC
/REDIS_HZ
/100; 
 622     if (timelimit 
<= 0) timelimit 
= 1; 
 624     for (j 
= 0; j 
< server
.dbnum
; j
++) { 
 626         redisDb 
*db 
= server
.db
+j
; 
 628         /* Continue to expire if at the end of the cycle more than 25% 
 629          * of the keys were expired. */ 
 631             unsigned long num 
= dictSize(db
->expires
); 
 632             unsigned long slots 
= dictSlots(db
->expires
); 
 633             long long now 
= mstime(); 
 635             /* When there are less than 1% filled slots getting random 
 636              * keys is expensive, so stop here waiting for better times... 
 637              * The dictionary will be resized asap. */ 
 638             if (num 
&& slots 
> DICT_HT_INITIAL_SIZE 
&& 
 639                 (num
*100/slots 
< 1)) break; 
 641             /* The main collection cycle. Sample random keys among keys 
 642              * with an expire set, checking for expired ones. */ 
 644             if (num 
> REDIS_EXPIRELOOKUPS_PER_CRON
) 
 645                 num 
= REDIS_EXPIRELOOKUPS_PER_CRON
; 
 650                 if ((de 
= dictGetRandomKey(db
->expires
)) == NULL
) break; 
 651                 t 
= dictGetSignedIntegerVal(de
); 
 653                     sds key 
= dictGetKey(de
); 
 654                     robj 
*keyobj 
= createStringObject(key
,sdslen(key
)); 
 656                     propagateExpire(db
,keyobj
); 
 658                     decrRefCount(keyobj
); 
 660                     server
.stat_expiredkeys
++; 
 663             /* We can't block forever here even if there are many keys to 
 664              * expire. So after a given amount of milliseconds return to the 
 665              * caller waiting for the other active expire cycle. */ 
 667             if ((iteration 
& 0xf) == 0 && /* check once every 16 cycles. */ 
 668                 (ustime()-start
) > timelimit
) return; 
 669         } while (expired 
> REDIS_EXPIRELOOKUPS_PER_CRON
/4); 
 673 void updateLRUClock(void) { 
 674     server
.lruclock 
= (server
.unixtime
/REDIS_LRU_CLOCK_RESOLUTION
) & 
 679 /* Add a sample to the operations per second array of samples. */ 
 680 void trackOperationsPerSecond(void) { 
 681     long long t 
= mstime() - server
.ops_sec_last_sample_time
; 
 682     long long ops 
= server
.stat_numcommands 
- server
.ops_sec_last_sample_ops
; 
 685     ops_sec 
= t 
> 0 ? (ops
*1000/t
) : 0; 
 687     server
.ops_sec_samples
[server
.ops_sec_idx
] = ops_sec
; 
 688     server
.ops_sec_idx 
= (server
.ops_sec_idx
+1) % REDIS_OPS_SEC_SAMPLES
; 
 689     server
.ops_sec_last_sample_time 
= mstime(); 
 690     server
.ops_sec_last_sample_ops 
= server
.stat_numcommands
; 
 693 /* Return the mean of all the samples. */ 
 694 long long getOperationsPerSecond(void) { 
 698     for (j 
= 0; j 
< REDIS_OPS_SEC_SAMPLES
; j
++) 
 699         sum 
+= server
.ops_sec_samples
[j
]; 
 700     return sum 
/ REDIS_OPS_SEC_SAMPLES
; 
 703 /* Check for timeouts. Returns non-zero if the client was terminated */ 
 704 int clientsCronHandleTimeout(redisClient 
*c
) { 
 705     time_t now 
= server
.unixtime
; 
 707     if (server
.maxidletime 
&& 
 708         !(c
->flags 
& REDIS_SLAVE
) &&    /* no timeout for slaves */ 
 709         !(c
->flags 
& REDIS_MASTER
) &&   /* no timeout for masters */ 
 710         !(c
->flags 
& REDIS_BLOCKED
) &&  /* no timeout for BLPOP */ 
 711         dictSize(c
->pubsub_channels
) == 0 && /* no timeout for pubsub */ 
 712         listLength(c
->pubsub_patterns
) == 0 && 
 713         (now 
- c
->lastinteraction 
> server
.maxidletime
)) 
 715         redisLog(REDIS_VERBOSE
,"Closing idle client"); 
 718     } else if (c
->flags 
& REDIS_BLOCKED
) { 
 719         if (c
->bpop
.timeout 
!= 0 && c
->bpop
.timeout 
< now
) { 
 720             addReply(c
,shared
.nullmultibulk
); 
 721             unblockClientWaitingData(c
); 
 727 /* The client query buffer is an sds.c string that can end with a lot of 
 728  * free space not used, this function reclaims space if needed. 
 730  * The funciton always returns 0 as it never terminates the client. */ 
 731 int clientsCronResizeQueryBuffer(redisClient 
*c
) { 
 732     size_t querybuf_size 
= sdsAllocSize(c
->querybuf
); 
 733     time_t idletime 
= server
.unixtime 
- c
->lastinteraction
; 
 735     /* There are two conditions to resize the query buffer: 
 736      * 1) Query buffer is > BIG_ARG and too big for latest peak. 
 737      * 2) Client is inactive and the buffer is bigger than 1k. */ 
 738     if (((querybuf_size 
> REDIS_MBULK_BIG_ARG
) && 
 739          (querybuf_size
/(c
->querybuf_peak
+1)) > 2) || 
 740          (querybuf_size 
> 1024 && idletime 
> 2)) 
 742         /* Only resize the query buffer if it is actually wasting space. */ 
 743         if (sdsavail(c
->querybuf
) > 1024) { 
 744             c
->querybuf 
= sdsRemoveFreeSpace(c
->querybuf
); 
 747     /* Reset the peak again to capture the peak memory usage in the next 
 749     c
->querybuf_peak 
= 0; 
 753 void clientsCron(void) { 
 754     /* Make sure to process at least 1/(REDIS_HZ*10) of clients per call. 
 755      * Since this function is called REDIS_HZ times per second we are sure that 
 756      * in the worst case we process all the clients in 10 seconds. 
 757      * In normal conditions (a reasonable number of clients) we process 
 758      * all the clients in a shorter time. */ 
 759     int numclients 
= listLength(server
.clients
); 
 760     int iterations 
= numclients
/(REDIS_HZ
*10); 
 763         iterations 
= (numclients 
< 50) ? numclients 
: 50; 
 764     while(listLength(server
.clients
) && iterations
--) { 
 768         /* Rotate the list, take the current head, process. 
 769          * This way if the client must be removed from the list it's the 
 770          * first element and we don't incur into O(N) computation. */ 
 771         listRotate(server
.clients
); 
 772         head 
= listFirst(server
.clients
); 
 773         c 
= listNodeValue(head
); 
 774         /* The following functions do different service checks on the client. 
 775          * The protocol is that they return non-zero if the client was 
 777         if (clientsCronHandleTimeout(c
)) continue; 
 778         if (clientsCronResizeQueryBuffer(c
)) continue; 
 782 /* This is our timer interrupt, called REDIS_HZ times per second. 
 783  * Here is where we do a number of things that need to be done asynchronously. 
 786  * - Active expired keys collection (it is also performed in a lazy way on 
 788  * - Software watchdong. 
 789  * - Update some statistic. 
 790  * - Incremental rehashing of the DBs hash tables. 
 791  * - Triggering BGSAVE / AOF rewrite, and handling of terminated children. 
 792  * - Clients timeout of differnet kinds. 
 793  * - Replication reconnection. 
 796  * Everything directly called here will be called REDIS_HZ times per second, 
 797  * so in order to throttle execution of things we want to do less frequently 
 798  * a macro is used: run_with_period(milliseconds) { .... } 
 801 int serverCron(struct aeEventLoop 
*eventLoop
, long long id
, void *clientData
) { 
 803     REDIS_NOTUSED(eventLoop
); 
 805     REDIS_NOTUSED(clientData
); 
 807     /* Software watchdog: deliver the SIGALRM that will reach the signal 
 808      * handler if we don't return here fast enough. */ 
 809     if (server
.watchdog_period
) watchdogScheduleSignal(server
.watchdog_period
); 
 811     /* We take a cached value of the unix time in the global state because 
 812      * with virtual memory and aging there is to store the current time 
 813      * in objects at every object access, and accuracy is not needed. 
 814      * To access a global var is faster than calling time(NULL) */ 
 815     server
.unixtime 
= time(NULL
); 
 817     run_with_period(100) trackOperationsPerSecond(); 
 819     /* We have just 22 bits per object for LRU information. 
 820      * So we use an (eventually wrapping) LRU clock with 10 seconds resolution. 
 821      * 2^22 bits with 10 seconds resoluton is more or less 1.5 years. 
 823      * Note that even if this will wrap after 1.5 years it's not a problem, 
 824      * everything will still work but just some object will appear younger 
 825      * to Redis. But for this to happen a given object should never be touched 
 828      * Note that you can change the resolution altering the 
 829      * REDIS_LRU_CLOCK_RESOLUTION define. 
 833     /* Record the max memory used since the server was started. */ 
 834     if (zmalloc_used_memory() > server
.stat_peak_memory
) 
 835         server
.stat_peak_memory 
= zmalloc_used_memory(); 
 837     /* We received a SIGTERM, shutting down here in a safe way, as it is 
 838      * not ok doing so inside the signal handler. */ 
 839     if (server
.shutdown_asap
) { 
 840         if (prepareForShutdown(0) == REDIS_OK
) exit(0); 
 841         redisLog(REDIS_WARNING
,"SIGTERM received but errors trying to shut down the server, check the logs for more information"); 
 844     /* Show some info about non-empty databases */ 
 845     run_with_period(5000) { 
 846         for (j 
= 0; j 
< server
.dbnum
; j
++) { 
 847             long long size
, used
, vkeys
; 
 849             size 
= dictSlots(server
.db
[j
].dict
); 
 850             used 
= dictSize(server
.db
[j
].dict
); 
 851             vkeys 
= dictSize(server
.db
[j
].expires
); 
 853                 redisLog(REDIS_VERBOSE
,"DB %d: %lld keys (%lld volatile) in %lld slots HT.",j
,used
,vkeys
,size
); 
 854                 /* dictPrintStats(server.dict); */ 
 859     /* We don't want to resize the hash tables while a bacground saving 
 860      * is in progress: the saving child is created using fork() that is 
 861      * implemented with a copy-on-write semantic in most modern systems, so 
 862      * if we resize the HT while there is the saving child at work actually 
 863      * a lot of memory movements in the parent will cause a lot of pages 
 865     if (server
.rdb_child_pid 
== -1 && server
.aof_child_pid 
== -1) { 
 866         tryResizeHashTables(); 
 867         if (server
.activerehashing
) incrementallyRehash(); 
 870     /* Show information about connected clients */ 
 871     if (!server
.sentinel_mode
) { 
 872         run_with_period(5000) { 
 873             redisLog(REDIS_VERBOSE
, 
 874                 "%d clients connected (%d slaves), %zu bytes in use", 
 875                 listLength(server
.clients
)-listLength(server
.slaves
), 
 876                 listLength(server
.slaves
), 
 877                 zmalloc_used_memory()); 
 881     /* We need to do a few operations on clients asynchronously. */ 
 884     /* Start a scheduled AOF rewrite if this was requested by the user while 
 885      * a BGSAVE was in progress. */ 
 886     if (server
.rdb_child_pid 
== -1 && server
.aof_child_pid 
== -1 && 
 887         server
.aof_rewrite_scheduled
) 
 889         rewriteAppendOnlyFileBackground(); 
 892     /* Check if a background saving or AOF rewrite in progress terminated. */ 
 893     if (server
.rdb_child_pid 
!= -1 || server
.aof_child_pid 
!= -1) { 
 897         if ((pid 
= wait3(&statloc
,WNOHANG
,NULL
)) != 0) { 
 898             int exitcode 
= WEXITSTATUS(statloc
); 
 901             if (WIFSIGNALED(statloc
)) bysignal 
= WTERMSIG(statloc
); 
 903             if (pid 
== server
.rdb_child_pid
) { 
 904                 backgroundSaveDoneHandler(exitcode
,bysignal
); 
 906                 backgroundRewriteDoneHandler(exitcode
,bysignal
); 
 908             updateDictResizePolicy(); 
 911         /* If there is not a background saving/rewrite in progress check if 
 912          * we have to save/rewrite now */ 
 913          for (j 
= 0; j 
< server
.saveparamslen
; j
++) { 
 914             struct saveparam 
*sp 
= server
.saveparams
+j
; 
 916             if (server
.dirty 
>= sp
->changes 
&& 
 917                 server
.unixtime
-server
.lastsave 
> sp
->seconds
) { 
 918                 redisLog(REDIS_NOTICE
,"%d changes in %d seconds. Saving...", 
 919                     sp
->changes
, sp
->seconds
); 
 920                 rdbSaveBackground(server
.rdb_filename
); 
 925          /* Trigger an AOF rewrite if needed */ 
 926          if (server
.rdb_child_pid 
== -1 && 
 927              server
.aof_child_pid 
== -1 && 
 928              server
.aof_rewrite_perc 
&& 
 929              server
.aof_current_size 
> server
.aof_rewrite_min_size
) 
 931             long long base 
= server
.aof_rewrite_base_size 
? 
 932                             server
.aof_rewrite_base_size 
: 1; 
 933             long long growth 
= (server
.aof_current_size
*100/base
) - 100; 
 934             if (growth 
>= server
.aof_rewrite_perc
) { 
 935                 redisLog(REDIS_NOTICE
,"Starting automatic rewriting of AOF on %lld%% growth",growth
); 
 936                 rewriteAppendOnlyFileBackground(); 
 942     /* If we postponed an AOF buffer flush, let's try to do it every time the 
 943      * cron function is called. */ 
 944     if (server
.aof_flush_postponed_start
) flushAppendOnlyFile(0); 
 946     /* Expire a few keys per cycle, only if this is a master. 
 947      * On slaves we wait for DEL operations synthesized by the master 
 948      * in order to guarantee a strict consistency. */ 
 949     if (server
.masterhost 
== NULL
) activeExpireCycle(); 
 951     /* Close clients that need to be closed asynchronous */ 
 952     freeClientsInAsyncFreeQueue(); 
 954     /* Replication cron function -- used to reconnect to master and 
 955      * to detect transfer failures. */ 
 956     run_with_period(1000) replicationCron(); 
 958     /* Run the sentinel timer if we are in sentinel mode. */ 
 959     run_with_period(100) { 
 960         if (server
.sentinel_mode
) sentinelTimer(); 
 964     return 1000/REDIS_HZ
; 
 967 /* This function gets called every time Redis is entering the 
 968  * main loop of the event driven library, that is, before to sleep 
 969  * for ready file descriptors. */ 
 970 void beforeSleep(struct aeEventLoop 
*eventLoop
) { 
 971     REDIS_NOTUSED(eventLoop
); 
 975     /* Try to process pending commands for clients that were just unblocked. */ 
 976     while (listLength(server
.unblocked_clients
)) { 
 977         ln 
= listFirst(server
.unblocked_clients
); 
 978         redisAssert(ln 
!= NULL
); 
 980         listDelNode(server
.unblocked_clients
,ln
); 
 981         c
->flags 
&= ~REDIS_UNBLOCKED
; 
 983         /* Process remaining data in the input buffer. */ 
 984         if (c
->querybuf 
&& sdslen(c
->querybuf
) > 0) { 
 985             server
.current_client 
= c
; 
 986             processInputBuffer(c
); 
 987             server
.current_client 
= NULL
; 
 991     /* Write the AOF buffer on disk */ 
 992     flushAppendOnlyFile(0); 
 995 /* =========================== Server initialization ======================== */ 
 997 void createSharedObjects(void) { 
1000     shared
.crlf 
= createObject(REDIS_STRING
,sdsnew("\r\n")); 
1001     shared
.ok 
= createObject(REDIS_STRING
,sdsnew("+OK\r\n")); 
1002     shared
.err 
= createObject(REDIS_STRING
,sdsnew("-ERR\r\n")); 
1003     shared
.emptybulk 
= createObject(REDIS_STRING
,sdsnew("$0\r\n\r\n")); 
1004     shared
.czero 
= createObject(REDIS_STRING
,sdsnew(":0\r\n")); 
1005     shared
.cone 
= createObject(REDIS_STRING
,sdsnew(":1\r\n")); 
1006     shared
.cnegone 
= createObject(REDIS_STRING
,sdsnew(":-1\r\n")); 
1007     shared
.nullbulk 
= createObject(REDIS_STRING
,sdsnew("$-1\r\n")); 
1008     shared
.nullmultibulk 
= createObject(REDIS_STRING
,sdsnew("*-1\r\n")); 
1009     shared
.emptymultibulk 
= createObject(REDIS_STRING
,sdsnew("*0\r\n")); 
1010     shared
.pong 
= createObject(REDIS_STRING
,sdsnew("+PONG\r\n")); 
1011     shared
.queued 
= createObject(REDIS_STRING
,sdsnew("+QUEUED\r\n")); 
1012     shared
.wrongtypeerr 
= createObject(REDIS_STRING
,sdsnew( 
1013         "-ERR Operation against a key holding the wrong kind of value\r\n")); 
1014     shared
.nokeyerr 
= createObject(REDIS_STRING
,sdsnew( 
1015         "-ERR no such key\r\n")); 
1016     shared
.syntaxerr 
= createObject(REDIS_STRING
,sdsnew( 
1017         "-ERR syntax error\r\n")); 
1018     shared
.sameobjecterr 
= createObject(REDIS_STRING
,sdsnew( 
1019         "-ERR source and destination objects are the same\r\n")); 
1020     shared
.outofrangeerr 
= createObject(REDIS_STRING
,sdsnew( 
1021         "-ERR index out of range\r\n")); 
1022     shared
.noscripterr 
= createObject(REDIS_STRING
,sdsnew( 
1023         "-NOSCRIPT No matching script. Please use EVAL.\r\n")); 
1024     shared
.loadingerr 
= createObject(REDIS_STRING
,sdsnew( 
1025         "-LOADING Redis is loading the dataset in memory\r\n")); 
1026     shared
.slowscripterr 
= createObject(REDIS_STRING
,sdsnew( 
1027         "-BUSY Redis is busy running a script. You can only call SCRIPT KILL or SHUTDOWN NOSAVE.\r\n")); 
1028     shared
.masterdownerr 
= createObject(REDIS_STRING
,sdsnew( 
1029         "-MASTERDOWN Link with MASTER is down and slave-serve-stale-data is set to 'no'.\r\n")); 
1030     shared
.bgsaveerr 
= createObject(REDIS_STRING
,sdsnew( 
1031         "-MISCONF Redis is configured to save RDB snapshots, but is currently not able to persist on disk. Commands that may modify the data set are disabled. Please check Redis logs for details about the error.\r\n")); 
1032     shared
.roslaveerr 
= createObject(REDIS_STRING
,sdsnew( 
1033         "-READONLY You can't write against a read only slave.\r\n")); 
1034     shared
.oomerr 
= createObject(REDIS_STRING
,sdsnew( 
1035         "-OOM command not allowed when used memory > 'maxmemory'.\r\n")); 
1036     shared
.space 
= createObject(REDIS_STRING
,sdsnew(" ")); 
1037     shared
.colon 
= createObject(REDIS_STRING
,sdsnew(":")); 
1038     shared
.plus 
= createObject(REDIS_STRING
,sdsnew("+")); 
1040     for (j 
= 0; j 
< REDIS_SHARED_SELECT_CMDS
; j
++) { 
1041         shared
.select
[j
] = createObject(REDIS_STRING
, 
1042             sdscatprintf(sdsempty(),"select %d\r\n", j
)); 
1044     shared
.messagebulk 
= createStringObject("$7\r\nmessage\r\n",13); 
1045     shared
.pmessagebulk 
= createStringObject("$8\r\npmessage\r\n",14); 
1046     shared
.subscribebulk 
= createStringObject("$9\r\nsubscribe\r\n",15); 
1047     shared
.unsubscribebulk 
= createStringObject("$11\r\nunsubscribe\r\n",18); 
1048     shared
.psubscribebulk 
= createStringObject("$10\r\npsubscribe\r\n",17); 
1049     shared
.punsubscribebulk 
= createStringObject("$12\r\npunsubscribe\r\n",19); 
1050     shared
.del 
= createStringObject("DEL",3); 
1051     shared
.rpop 
= createStringObject("RPOP",4); 
1052     shared
.lpop 
= createStringObject("LPOP",4); 
1053     shared
.lpush 
= createStringObject("LPUSH",5); 
1054     for (j 
= 0; j 
< REDIS_SHARED_INTEGERS
; j
++) { 
1055         shared
.integers
[j
] = createObject(REDIS_STRING
,(void*)(long)j
); 
1056         shared
.integers
[j
]->encoding 
= REDIS_ENCODING_INT
; 
1058     for (j 
= 0; j 
< REDIS_SHARED_BULKHDR_LEN
; j
++) { 
1059         shared
.mbulkhdr
[j
] = createObject(REDIS_STRING
, 
1060             sdscatprintf(sdsempty(),"*%d\r\n",j
)); 
1061         shared
.bulkhdr
[j
] = createObject(REDIS_STRING
, 
1062             sdscatprintf(sdsempty(),"$%d\r\n",j
)); 
1066 void initServerConfig() { 
1067     getRandomHexChars(server
.runid
,REDIS_RUN_ID_SIZE
); 
1068     server
.runid
[REDIS_RUN_ID_SIZE
] = '\0'; 
1069     server
.arch_bits 
= (sizeof(long) == 8) ? 64 : 32; 
1070     server
.port 
= REDIS_SERVERPORT
; 
1071     server
.bindaddr 
= NULL
; 
1072     server
.unixsocket 
= NULL
; 
1073     server
.unixsocketperm 
= 0; 
1076     server
.dbnum 
= REDIS_DEFAULT_DBNUM
; 
1077     server
.verbosity 
= REDIS_NOTICE
; 
1078     server
.maxidletime 
= REDIS_MAXIDLETIME
; 
1079     server
.client_max_querybuf_len 
= REDIS_MAX_QUERYBUF_LEN
; 
1080     server
.saveparams 
= NULL
; 
1082     server
.logfile 
= NULL
; /* NULL = log on standard output */ 
1083     server
.syslog_enabled 
= 0; 
1084     server
.syslog_ident 
= zstrdup("redis"); 
1085     server
.syslog_facility 
= LOG_LOCAL0
; 
1086     server
.daemonize 
= 0; 
1087     server
.aof_state 
= REDIS_AOF_OFF
; 
1088     server
.aof_fsync 
= AOF_FSYNC_EVERYSEC
; 
1089     server
.aof_no_fsync_on_rewrite 
= 0; 
1090     server
.aof_rewrite_perc 
= REDIS_AOF_REWRITE_PERC
; 
1091     server
.aof_rewrite_min_size 
= REDIS_AOF_REWRITE_MIN_SIZE
; 
1092     server
.aof_rewrite_base_size 
= 0; 
1093     server
.aof_rewrite_scheduled 
= 0; 
1094     server
.aof_last_fsync 
= time(NULL
); 
1095     server
.aof_rewrite_time_last 
= -1; 
1096     server
.aof_rewrite_time_start 
= -1; 
1097     server
.aof_lastbgrewrite_status 
= REDIS_OK
; 
1098     server
.aof_delayed_fsync 
= 0; 
1100     server
.aof_selected_db 
= -1; /* Make sure the first time will not match */ 
1101     server
.aof_flush_postponed_start 
= 0; 
1102     server
.pidfile 
= zstrdup("/var/run/redis.pid"); 
1103     server
.rdb_filename 
= zstrdup("dump.rdb"); 
1104     server
.aof_filename 
= zstrdup("appendonly.aof"); 
1105     server
.requirepass 
= NULL
; 
1106     server
.rdb_compression 
= 1; 
1107     server
.rdb_checksum 
= 1; 
1108     server
.activerehashing 
= 1; 
1109     server
.maxclients 
= REDIS_MAX_CLIENTS
; 
1110     server
.bpop_blocked_clients 
= 0; 
1111     server
.maxmemory 
= 0; 
1112     server
.maxmemory_policy 
= REDIS_MAXMEMORY_VOLATILE_LRU
; 
1113     server
.maxmemory_samples 
= 3; 
1114     server
.hash_max_ziplist_entries 
= REDIS_HASH_MAX_ZIPLIST_ENTRIES
; 
1115     server
.hash_max_ziplist_value 
= REDIS_HASH_MAX_ZIPLIST_VALUE
; 
1116     server
.list_max_ziplist_entries 
= REDIS_LIST_MAX_ZIPLIST_ENTRIES
; 
1117     server
.list_max_ziplist_value 
= REDIS_LIST_MAX_ZIPLIST_VALUE
; 
1118     server
.set_max_intset_entries 
= REDIS_SET_MAX_INTSET_ENTRIES
; 
1119     server
.zset_max_ziplist_entries 
= REDIS_ZSET_MAX_ZIPLIST_ENTRIES
; 
1120     server
.zset_max_ziplist_value 
= REDIS_ZSET_MAX_ZIPLIST_VALUE
; 
1121     server
.shutdown_asap 
= 0; 
1122     server
.repl_ping_slave_period 
= REDIS_REPL_PING_SLAVE_PERIOD
; 
1123     server
.repl_timeout 
= REDIS_REPL_TIMEOUT
; 
1124     server
.lua_caller 
= NULL
; 
1125     server
.lua_time_limit 
= REDIS_LUA_TIME_LIMIT
; 
1126     server
.lua_client 
= NULL
; 
1127     server
.lua_timedout 
= 0; 
1130     resetServerSaveParams(); 
1132     appendServerSaveParams(60*60,1);  /* save after 1 hour and 1 change */ 
1133     appendServerSaveParams(300,100);  /* save after 5 minutes and 100 changes */ 
1134     appendServerSaveParams(60,10000); /* save after 1 minute and 10000 changes */ 
1135     /* Replication related */ 
1136     server
.masterauth 
= NULL
; 
1137     server
.masterhost 
= NULL
; 
1138     server
.masterport 
= 6379; 
1139     server
.master 
= NULL
; 
1140     server
.repl_state 
= REDIS_REPL_NONE
; 
1141     server
.repl_syncio_timeout 
= REDIS_REPL_SYNCIO_TIMEOUT
; 
1142     server
.repl_serve_stale_data 
= 1; 
1143     server
.repl_slave_ro 
= 1; 
1144     server
.repl_down_since 
= time(NULL
); 
1145     server
.slave_priority 
= REDIS_DEFAULT_SLAVE_PRIORITY
; 
1147     /* Client output buffer limits */ 
1148     server
.client_obuf_limits
[REDIS_CLIENT_LIMIT_CLASS_NORMAL
].hard_limit_bytes 
= 0; 
1149     server
.client_obuf_limits
[REDIS_CLIENT_LIMIT_CLASS_NORMAL
].soft_limit_bytes 
= 0; 
1150     server
.client_obuf_limits
[REDIS_CLIENT_LIMIT_CLASS_NORMAL
].soft_limit_seconds 
= 0; 
1151     server
.client_obuf_limits
[REDIS_CLIENT_LIMIT_CLASS_SLAVE
].hard_limit_bytes 
= 1024*1024*256; 
1152     server
.client_obuf_limits
[REDIS_CLIENT_LIMIT_CLASS_SLAVE
].soft_limit_bytes 
= 1024*1024*64; 
1153     server
.client_obuf_limits
[REDIS_CLIENT_LIMIT_CLASS_SLAVE
].soft_limit_seconds 
= 60; 
1154     server
.client_obuf_limits
[REDIS_CLIENT_LIMIT_CLASS_PUBSUB
].hard_limit_bytes 
= 1024*1024*32; 
1155     server
.client_obuf_limits
[REDIS_CLIENT_LIMIT_CLASS_PUBSUB
].soft_limit_bytes 
= 1024*1024*8; 
1156     server
.client_obuf_limits
[REDIS_CLIENT_LIMIT_CLASS_PUBSUB
].soft_limit_seconds 
= 60; 
1158     /* Double constants initialization */ 
1160     R_PosInf 
= 1.0/R_Zero
; 
1161     R_NegInf 
= -1.0/R_Zero
; 
1162     R_Nan 
= R_Zero
/R_Zero
; 
1164     /* Command table -- we intiialize it here as it is part of the 
1165      * initial configuration, since command names may be changed via 
1166      * redis.conf using the rename-command directive. */ 
1167     server
.commands 
= dictCreate(&commandTableDictType
,NULL
); 
1168     populateCommandTable(); 
1169     server
.delCommand 
= lookupCommandByCString("del"); 
1170     server
.multiCommand 
= lookupCommandByCString("multi"); 
1171     server
.lpushCommand 
= lookupCommandByCString("lpush"); 
1172     server
.lpopCommand 
= lookupCommandByCString("lpop"); 
1173     server
.rpopCommand 
= lookupCommandByCString("rpop"); 
1176     server
.slowlog_log_slower_than 
= REDIS_SLOWLOG_LOG_SLOWER_THAN
; 
1177     server
.slowlog_max_len 
= REDIS_SLOWLOG_MAX_LEN
; 
1180     server
.assert_failed 
= "<no assertion failed>"; 
1181     server
.assert_file 
= "<no file>"; 
1182     server
.assert_line 
= 0; 
1183     server
.bug_report_start 
= 0; 
1184     server
.watchdog_period 
= 0; 
1187 /* This function will try to raise the max number of open files accordingly to 
1188  * the configured max number of clients. It will also account for 32 additional 
1189  * file descriptors as we need a few more for persistence, listening 
1190  * sockets, log files and so forth. 
1192  * If it will not be possible to set the limit accordingly to the configured 
1193  * max number of clients, the function will do the reverse setting 
1194  * server.maxclients to the value that we can actually handle. */ 
1195 void adjustOpenFilesLimit(void) { 
1196     rlim_t maxfiles 
= server
.maxclients
+32; 
1197     struct rlimit limit
; 
1199     if (getrlimit(RLIMIT_NOFILE
,&limit
) == -1) { 
1200         redisLog(REDIS_WARNING
,"Unable to obtain the current NOFILE limit (%s), assuming 1024 and setting the max clients configuration accordingly.", 
1202         server
.maxclients 
= 1024-32; 
1204         rlim_t oldlimit 
= limit
.rlim_cur
; 
1206         /* Set the max number of files if the current limit is not enough 
1208         if (oldlimit 
< maxfiles
) { 
1212             while(f 
> oldlimit
) { 
1215                 if (setrlimit(RLIMIT_NOFILE
,&limit
) != -1) break; 
1218             if (f 
< oldlimit
) f 
= oldlimit
; 
1219             if (f 
!= maxfiles
) { 
1220                 server
.maxclients 
= f
-32; 
1221                 redisLog(REDIS_WARNING
,"Unable to set the max number of files limit to %d (%s), setting the max clients configuration to %d.", 
1222                     (int) maxfiles
, strerror(errno
), (int) server
.maxclients
); 
1224                 redisLog(REDIS_NOTICE
,"Max number of open files set to %d", 
1234     signal(SIGHUP
, SIG_IGN
); 
1235     signal(SIGPIPE
, SIG_IGN
); 
1236     setupSignalHandlers(); 
1238     if (server
.syslog_enabled
) { 
1239         openlog(server
.syslog_ident
, LOG_PID 
| LOG_NDELAY 
| LOG_NOWAIT
, 
1240             server
.syslog_facility
); 
1243     server
.current_client 
= NULL
; 
1244     server
.clients 
= listCreate(); 
1245     server
.clients_to_close 
= listCreate(); 
1246     server
.slaves 
= listCreate(); 
1247     server
.monitors 
= listCreate(); 
1248     server
.unblocked_clients 
= listCreate(); 
1249     server
.ready_keys 
= listCreate(); 
1251     createSharedObjects(); 
1252     adjustOpenFilesLimit(); 
1253     server
.el 
= aeCreateEventLoop(server
.maxclients
+1024); 
1254     server
.db 
= zmalloc(sizeof(redisDb
)*server
.dbnum
); 
1256     if (server
.port 
!= 0) { 
1257         server
.ipfd 
= anetTcpServer(server
.neterr
,server
.port
,server
.bindaddr
); 
1258         if (server
.ipfd 
== ANET_ERR
) { 
1259             redisLog(REDIS_WARNING
, "Opening port %d: %s", 
1260                 server
.port
, server
.neterr
); 
1264     if (server
.unixsocket 
!= NULL
) { 
1265         unlink(server
.unixsocket
); /* don't care if this fails */ 
1266         server
.sofd 
= anetUnixServer(server
.neterr
,server
.unixsocket
,server
.unixsocketperm
); 
1267         if (server
.sofd 
== ANET_ERR
) { 
1268             redisLog(REDIS_WARNING
, "Opening socket: %s", server
.neterr
); 
1272     if (server
.ipfd 
< 0 && server
.sofd 
< 0) { 
1273         redisLog(REDIS_WARNING
, "Configured to not listen anywhere, exiting."); 
1276     for (j 
= 0; j 
< server
.dbnum
; j
++) { 
1277         server
.db
[j
].dict 
= dictCreate(&dbDictType
,NULL
); 
1278         server
.db
[j
].expires 
= dictCreate(&keyptrDictType
,NULL
); 
1279         server
.db
[j
].blocking_keys 
= dictCreate(&keylistDictType
,NULL
); 
1280         server
.db
[j
].ready_keys 
= dictCreate(&setDictType
,NULL
); 
1281         server
.db
[j
].watched_keys 
= dictCreate(&keylistDictType
,NULL
); 
1282         server
.db
[j
].id 
= j
; 
1284     server
.pubsub_channels 
= dictCreate(&keylistDictType
,NULL
); 
1285     server
.pubsub_patterns 
= listCreate(); 
1286     listSetFreeMethod(server
.pubsub_patterns
,freePubsubPattern
); 
1287     listSetMatchMethod(server
.pubsub_patterns
,listMatchPubsubPattern
); 
1288     server
.cronloops 
= 0; 
1289     server
.rdb_child_pid 
= -1; 
1290     server
.aof_child_pid 
= -1; 
1291     aofRewriteBufferReset(); 
1292     server
.aof_buf 
= sdsempty(); 
1293     server
.lastsave 
= time(NULL
); 
1294     server
.rdb_save_time_last 
= -1; 
1295     server
.rdb_save_time_start 
= -1; 
1297     server
.stat_numcommands 
= 0; 
1298     server
.stat_numconnections 
= 0; 
1299     server
.stat_expiredkeys 
= 0; 
1300     server
.stat_evictedkeys 
= 0; 
1301     server
.stat_starttime 
= time(NULL
); 
1302     server
.stat_keyspace_misses 
= 0; 
1303     server
.stat_keyspace_hits 
= 0; 
1304     server
.stat_peak_memory 
= 0; 
1305     server
.stat_fork_time 
= 0; 
1306     server
.stat_rejected_conn 
= 0; 
1307     memset(server
.ops_sec_samples
,0,sizeof(server
.ops_sec_samples
)); 
1308     server
.ops_sec_idx 
= 0; 
1309     server
.ops_sec_last_sample_time 
= mstime(); 
1310     server
.ops_sec_last_sample_ops 
= 0; 
1311     server
.unixtime 
= time(NULL
); 
1312     server
.lastbgsave_status 
= REDIS_OK
; 
1313     server
.stop_writes_on_bgsave_err 
= 1; 
1314     aeCreateTimeEvent(server
.el
, 1, serverCron
, NULL
, NULL
); 
1315     if (server
.ipfd 
> 0 && aeCreateFileEvent(server
.el
,server
.ipfd
,AE_READABLE
, 
1316         acceptTcpHandler
,NULL
) == AE_ERR
) redisPanic("Unrecoverable error creating server.ipfd file event."); 
1317     if (server
.sofd 
> 0 && aeCreateFileEvent(server
.el
,server
.sofd
,AE_READABLE
, 
1318         acceptUnixHandler
,NULL
) == AE_ERR
) redisPanic("Unrecoverable error creating server.sofd file event."); 
1320     if (server
.aof_state 
== REDIS_AOF_ON
) { 
1321         server
.aof_fd 
= open(server
.aof_filename
, 
1322                                O_WRONLY
|O_APPEND
|O_CREAT
,0644); 
1323         if (server
.aof_fd 
== -1) { 
1324             redisLog(REDIS_WARNING
, "Can't open the append-only file: %s", 
1330     /* 32 bit instances are limited to 4GB of address space, so if there is 
1331      * no explicit limit in the user provided configuration we set a limit 
1332      * at 3 GB using maxmemory with 'noeviction' policy'. This avoids 
1333      * useless crashes of the Redis instance for out of memory. */ 
1334     if (server
.arch_bits 
== 32 && server
.maxmemory 
== 0) { 
1335         redisLog(REDIS_WARNING
,"Warning: 32 bit instance detected but no memory limit set. Setting 3 GB maxmemory limit with 'noeviction' policy now."); 
1336         server
.maxmemory 
= 3072LL*(1024*1024); /* 3 GB */ 
1337         server
.maxmemory_policy 
= REDIS_MAXMEMORY_NO_EVICTION
; 
1345 /* Populates the Redis Command Table starting from the hard coded list 
1346  * we have on top of redis.c file. */ 
1347 void populateCommandTable(void) { 
1349     int numcommands 
= sizeof(redisCommandTable
)/sizeof(struct redisCommand
); 
1351     for (j 
= 0; j 
< numcommands
; j
++) { 
1352         struct redisCommand 
*c 
= redisCommandTable
+j
; 
1353         char *f 
= c
->sflags
; 
1358             case 'w': c
->flags 
|= REDIS_CMD_WRITE
; break; 
1359             case 'r': c
->flags 
|= REDIS_CMD_READONLY
; break; 
1360             case 'm': c
->flags 
|= REDIS_CMD_DENYOOM
; break; 
1361             case 'a': c
->flags 
|= REDIS_CMD_ADMIN
; break; 
1362             case 'p': c
->flags 
|= REDIS_CMD_PUBSUB
; break; 
1363             case 'f': c
->flags 
|= REDIS_CMD_FORCE_REPLICATION
; break; 
1364             case 's': c
->flags 
|= REDIS_CMD_NOSCRIPT
; break; 
1365             case 'R': c
->flags 
|= REDIS_CMD_RANDOM
; break; 
1366             case 'S': c
->flags 
|= REDIS_CMD_SORT_FOR_SCRIPT
; break; 
1367             case 'l': c
->flags 
|= REDIS_CMD_LOADING
; break; 
1368             case 't': c
->flags 
|= REDIS_CMD_STALE
; break; 
1369             case 'M': c
->flags 
|= REDIS_CMD_SKIP_MONITOR
; break; 
1370             default: redisPanic("Unsupported command flag"); break; 
1375         retval 
= dictAdd(server
.commands
, sdsnew(c
->name
), c
); 
1376         assert(retval 
== DICT_OK
); 
1380 void resetCommandTableStats(void) { 
1381     int numcommands 
= sizeof(redisCommandTable
)/sizeof(struct redisCommand
); 
1384     for (j 
= 0; j 
< numcommands
; j
++) { 
1385         struct redisCommand 
*c 
= redisCommandTable
+j
; 
1387         c
->microseconds 
= 0; 
1392 /* ========================== Redis OP Array API ============================ */ 
1394 void redisOpArrayInit(redisOpArray 
*oa
) { 
1399 int redisOpArrayAppend(redisOpArray 
*oa
, struct redisCommand 
*cmd
, int dbid
, 
1400                        robj 
**argv
, int argc
, int target
) 
1404     oa
->ops 
= zrealloc(oa
->ops
,sizeof(redisOp
)*(oa
->numops
+1)); 
1405     op 
= oa
->ops
+oa
->numops
; 
1410     op
->target 
= target
; 
1415 void redisOpArrayFree(redisOpArray 
*oa
) { 
1421         op 
= oa
->ops
+oa
->numops
; 
1422         for (j 
= 0; j 
< op
->argc
; j
++) 
1423             decrRefCount(op
->argv
[j
]); 
1429 /* ====================== Commands lookup and execution ===================== */ 
1431 struct redisCommand 
*lookupCommand(sds name
) { 
1432     return dictFetchValue(server
.commands
, name
); 
1435 struct redisCommand 
*lookupCommandByCString(char *s
) { 
1436     struct redisCommand 
*cmd
; 
1437     sds name 
= sdsnew(s
); 
1439     cmd 
= dictFetchValue(server
.commands
, name
); 
1444 /* Propagate the specified command (in the context of the specified database id) 
1445  * to AOF and Slaves. 
1447  * flags are an xor between: 
1448  * + REDIS_PROPAGATE_NONE (no propagation of command at all) 
1449  * + REDIS_PROPAGATE_AOF (propagate into the AOF file if is enabled) 
1450  * + REDIS_PROPAGATE_REPL (propagate into the replication link) 
1452 void propagate(struct redisCommand 
*cmd
, int dbid
, robj 
**argv
, int argc
, 
1455     if (server
.aof_state 
!= REDIS_AOF_OFF 
&& flags 
& REDIS_PROPAGATE_AOF
) 
1456         feedAppendOnlyFile(cmd
,dbid
,argv
,argc
); 
1457     if (flags 
& REDIS_PROPAGATE_REPL 
&& listLength(server
.slaves
)) 
1458         replicationFeedSlaves(server
.slaves
,dbid
,argv
,argc
); 
1461 /* Used inside commands to schedule the propagation of additional commands 
1462  * after the current command is propagated to AOF / Replication. */ 
1463 void alsoPropagate(struct redisCommand 
*cmd
, int dbid
, robj 
**argv
, int argc
, 
1466     redisOpArrayAppend(&server
.also_propagate
,cmd
,dbid
,argv
,argc
,target
); 
1469 /* Call() is the core of Redis execution of a command */ 
1470 void call(redisClient 
*c
, int flags
) { 
1471     long long dirty
, start 
= ustime(), duration
; 
1473     /* Sent the command to clients in MONITOR mode, only if the commands are 
1474      * not geneated from reading an AOF. */ 
1475     if (listLength(server
.monitors
) && 
1477         !(c
->cmd
->flags 
& REDIS_CMD_SKIP_MONITOR
)) 
1479         replicationFeedMonitors(c
,server
.monitors
,c
->db
->id
,c
->argv
,c
->argc
); 
1482     /* Call the command. */ 
1483     redisOpArrayInit(&server
.also_propagate
); 
1484     dirty 
= server
.dirty
; 
1486     dirty 
= server
.dirty
-dirty
; 
1487     duration 
= ustime()-start
; 
1489     /* When EVAL is called loading the AOF we don't want commands called 
1490      * from Lua to go into the slowlog or to populate statistics. */ 
1491     if (server
.loading 
&& c
->flags 
& REDIS_LUA_CLIENT
) 
1492         flags 
&= ~(REDIS_CALL_SLOWLOG 
| REDIS_CALL_STATS
); 
1494     /* Log the command into the Slow log if needed, and populate the 
1495      * per-command statistics that we show in INFO commandstats. */ 
1496     if (flags 
& REDIS_CALL_SLOWLOG
) 
1497         slowlogPushEntryIfNeeded(c
->argv
,c
->argc
,duration
); 
1498     if (flags 
& REDIS_CALL_STATS
) { 
1499         c
->cmd
->microseconds 
+= duration
; 
1503     /* Propagate the command into the AOF and replication link */ 
1504     if (flags 
& REDIS_CALL_PROPAGATE
) { 
1505         int flags 
= REDIS_PROPAGATE_NONE
; 
1507         if (c
->cmd
->flags 
& REDIS_CMD_FORCE_REPLICATION
) 
1508             flags 
|= REDIS_PROPAGATE_REPL
; 
1510             flags 
|= (REDIS_PROPAGATE_REPL 
| REDIS_PROPAGATE_AOF
); 
1511         if (flags 
!= REDIS_PROPAGATE_NONE
) 
1512             propagate(c
->cmd
,c
->db
->id
,c
->argv
,c
->argc
,flags
); 
1514     /* Commands such as LPUSH or BRPOPLPUSH may propagate an additional 
1516     if (server
.also_propagate
.numops
) { 
1520         for (j 
= 0; j 
< server
.also_propagate
.numops
; j
++) { 
1521             rop 
= &server
.also_propagate
.ops
[j
]; 
1522             propagate(rop
->cmd
, rop
->dbid
, rop
->argv
, rop
->argc
, rop
->target
); 
1524         redisOpArrayFree(&server
.also_propagate
); 
1526     server
.stat_numcommands
++; 
1529 /* If this function gets called we already read a whole 
1530  * command, argments are in the client argv/argc fields. 
1531  * processCommand() execute the command or prepare the 
1532  * server for a bulk read from the client. 
1534  * If 1 is returned the client is still alive and valid and 
1535  * and other operations can be performed by the caller. Otherwise 
1536  * if 0 is returned the client was destroied (i.e. after QUIT). */ 
1537 int processCommand(redisClient 
*c
) { 
1538     /* The QUIT command is handled separately. Normal command procs will 
1539      * go through checking for replication and QUIT will cause trouble 
1540      * when FORCE_REPLICATION is enabled and would be implemented in 
1541      * a regular command proc. */ 
1542     if (!strcasecmp(c
->argv
[0]->ptr
,"quit")) { 
1543         addReply(c
,shared
.ok
); 
1544         c
->flags 
|= REDIS_CLOSE_AFTER_REPLY
; 
1548     /* Now lookup the command and check ASAP about trivial error conditions 
1549      * such as wrong arity, bad command name and so forth. */ 
1550     c
->cmd 
= c
->lastcmd 
= lookupCommand(c
->argv
[0]->ptr
); 
1552         addReplyErrorFormat(c
,"unknown command '%s'", 
1553             (char*)c
->argv
[0]->ptr
); 
1555     } else if ((c
->cmd
->arity 
> 0 && c
->cmd
->arity 
!= c
->argc
) || 
1556                (c
->argc 
< -c
->cmd
->arity
)) { 
1557         addReplyErrorFormat(c
,"wrong number of arguments for '%s' command", 
1562     /* Check if the user is authenticated */ 
1563     if (server
.requirepass 
&& !c
->authenticated 
&& c
->cmd
->proc 
!= authCommand
) 
1565         addReplyError(c
,"operation not permitted"); 
1569     /* Handle the maxmemory directive. 
1571      * First we try to free some memory if possible (if there are volatile 
1572      * keys in the dataset). If there are not the only thing we can do 
1573      * is returning an error. */ 
1574     if (server
.maxmemory
) { 
1575         int retval 
= freeMemoryIfNeeded(); 
1576         if ((c
->cmd
->flags 
& REDIS_CMD_DENYOOM
) && retval 
== REDIS_ERR
) { 
1577             addReply(c
, shared
.oomerr
); 
1582     /* Don't accept write commands if there are problems persisting on disk. */ 
1583     if (server
.stop_writes_on_bgsave_err 
&& 
1584         server
.saveparamslen 
> 0 
1585         && server
.lastbgsave_status 
== REDIS_ERR 
&& 
1586         c
->cmd
->flags 
& REDIS_CMD_WRITE
) 
1588         addReply(c
, shared
.bgsaveerr
); 
1592     /* Don't accept write commands if this is a read only slave. But 
1593      * accept write commands if this is our master. */ 
1594     if (server
.masterhost 
&& server
.repl_slave_ro 
&& 
1595         !(c
->flags 
& REDIS_MASTER
) && 
1596         c
->cmd
->flags 
& REDIS_CMD_WRITE
) 
1598         addReply(c
, shared
.roslaveerr
); 
1602     /* Only allow SUBSCRIBE and UNSUBSCRIBE in the context of Pub/Sub */ 
1603     if ((dictSize(c
->pubsub_channels
) > 0 || listLength(c
->pubsub_patterns
) > 0) 
1605         c
->cmd
->proc 
!= subscribeCommand 
&& 
1606         c
->cmd
->proc 
!= unsubscribeCommand 
&& 
1607         c
->cmd
->proc 
!= psubscribeCommand 
&& 
1608         c
->cmd
->proc 
!= punsubscribeCommand
) { 
1609         addReplyError(c
,"only (P)SUBSCRIBE / (P)UNSUBSCRIBE / QUIT allowed in this context"); 
1613     /* Only allow INFO and SLAVEOF when slave-serve-stale-data is no and 
1614      * we are a slave with a broken link with master. */ 
1615     if (server
.masterhost 
&& server
.repl_state 
!= REDIS_REPL_CONNECTED 
&& 
1616         server
.repl_serve_stale_data 
== 0 && 
1617         !(c
->cmd
->flags 
& REDIS_CMD_STALE
)) 
1619         addReply(c
, shared
.masterdownerr
); 
1623     /* Loading DB? Return an error if the command has not the 
1624      * REDIS_CMD_LOADING flag. */ 
1625     if (server
.loading 
&& !(c
->cmd
->flags 
& REDIS_CMD_LOADING
)) { 
1626         addReply(c
, shared
.loadingerr
); 
1630     /* Lua script too slow? Only allow commands with REDIS_CMD_STALE flag. */ 
1631     if (server
.lua_timedout 
&& 
1632           c
->cmd
->proc 
!= authCommand 
&& 
1633         !(c
->cmd
->proc 
== shutdownCommand 
&& 
1635           tolower(((char*)c
->argv
[1]->ptr
)[0]) == 'n') && 
1636         !(c
->cmd
->proc 
== scriptCommand 
&& 
1638           tolower(((char*)c
->argv
[1]->ptr
)[0]) == 'k')) 
1640         addReply(c
, shared
.slowscripterr
); 
1644     /* Exec the command */ 
1645     if (c
->flags 
& REDIS_MULTI 
&& 
1646         c
->cmd
->proc 
!= execCommand 
&& c
->cmd
->proc 
!= discardCommand 
&& 
1647         c
->cmd
->proc 
!= multiCommand 
&& c
->cmd
->proc 
!= watchCommand
) 
1649         queueMultiCommand(c
); 
1650         addReply(c
,shared
.queued
); 
1652         call(c
,REDIS_CALL_FULL
); 
1653         if (listLength(server
.ready_keys
)) 
1654             handleClientsBlockedOnLists(); 
1659 /*================================== Shutdown =============================== */ 
1661 int prepareForShutdown(int flags
) { 
1662     int save 
= flags 
& REDIS_SHUTDOWN_SAVE
; 
1663     int nosave 
= flags 
& REDIS_SHUTDOWN_NOSAVE
; 
1665     redisLog(REDIS_WARNING
,"User requested shutdown..."); 
1666     /* Kill the saving child if there is a background saving in progress. 
1667        We want to avoid race conditions, for instance our saving child may 
1668        overwrite the synchronous saving did by SHUTDOWN. */ 
1669     if (server
.rdb_child_pid 
!= -1) { 
1670         redisLog(REDIS_WARNING
,"There is a child saving an .rdb. Killing it!"); 
1671         kill(server
.rdb_child_pid
,SIGKILL
); 
1672         rdbRemoveTempFile(server
.rdb_child_pid
); 
1674     if (server
.aof_state 
!= REDIS_AOF_OFF
) { 
1675         /* Kill the AOF saving child as the AOF we already have may be longer 
1676          * but contains the full dataset anyway. */ 
1677         if (server
.aof_child_pid 
!= -1) { 
1678             redisLog(REDIS_WARNING
, 
1679                 "There is a child rewriting the AOF. Killing it!"); 
1680             kill(server
.aof_child_pid
,SIGKILL
); 
1682         /* Append only file: fsync() the AOF and exit */ 
1683         redisLog(REDIS_NOTICE
,"Calling fsync() on the AOF file."); 
1684         aof_fsync(server
.aof_fd
); 
1686     if ((server
.saveparamslen 
> 0 && !nosave
) || save
) { 
1687         redisLog(REDIS_NOTICE
,"Saving the final RDB snapshot before exiting."); 
1688         /* Snapshotting. Perform a SYNC SAVE and exit */ 
1689         if (rdbSave(server
.rdb_filename
) != REDIS_OK
) { 
1690             /* Ooops.. error saving! The best we can do is to continue 
1691              * operating. Note that if there was a background saving process, 
1692              * in the next cron() Redis will be notified that the background 
1693              * saving aborted, handling special stuff like slaves pending for 
1694              * synchronization... */ 
1695             redisLog(REDIS_WARNING
,"Error trying to save the DB, can't exit."); 
1699     if (server
.daemonize
) { 
1700         redisLog(REDIS_NOTICE
,"Removing the pid file."); 
1701         unlink(server
.pidfile
); 
1703     /* Close the listening sockets. Apparently this allows faster restarts. */ 
1704     if (server
.ipfd 
!= -1) close(server
.ipfd
); 
1705     if (server
.sofd 
!= -1) close(server
.sofd
); 
1706     if (server
.unixsocket
) { 
1707         redisLog(REDIS_NOTICE
,"Removing the unix socket file."); 
1708         unlink(server
.unixsocket
); /* don't care if this fails */ 
1711     redisLog(REDIS_WARNING
,"Redis is now ready to exit, bye bye..."); 
1715 /*================================== Commands =============================== */ 
1717 /* Return zero if strings are the same, non-zero if they are not. 
1718  * The comparison is performed in a way that prevents an attacker to obtain 
1719  * information about the nature of the strings just monitoring the execution 
1720  * time of the function. 
1722  * Note that limiting the comparison length to strings up to 512 bytes we 
1723  * can avoid leaking any information about the password length and any 
1724  * possible branch misprediction related leak. 
1726 int time_independent_strcmp(char *a
, char *b
) { 
1727     char bufa
[REDIS_AUTHPASS_MAX_LEN
], bufb
[REDIS_AUTHPASS_MAX_LEN
]; 
1728     /* The above two strlen perform len(a) + len(b) operations where either 
1729      * a or b are fixed (our password) length, and the difference is only 
1730      * relative to the length of the user provided string, so no information 
1731      * leak is possible in the following two lines of code. */ 
1732     int alen 
= strlen(a
); 
1733     int blen 
= strlen(b
); 
1737     /* We can't compare strings longer than our static buffers. 
1738      * Note that this will never pass the first test in practical circumstances 
1739      * so there is no info leak. */ 
1740     if (alen 
> sizeof(bufa
) || blen 
> sizeof(bufb
)) return 1; 
1742     memset(bufa
,0,sizeof(bufa
));        /* Constant time. */ 
1743     memset(bufb
,0,sizeof(bufb
));        /* Constant time. */ 
1744     /* Again the time of the following two copies is proportional to 
1745      * len(a) + len(b) so no info is leaked. */ 
1746     memcpy(bufa
,a
,alen
); 
1747     memcpy(bufb
,b
,blen
); 
1749     /* Always compare all the chars in the two buffers without 
1750      * conditional expressions. */ 
1751     for (j 
= 0; j 
< sizeof(bufa
); j
++) { 
1752         diff 
|= (bufa
[j
] ^ bufb
[j
]); 
1754     /* Length must be equal as well. */ 
1755     diff 
|= alen 
^ blen
; 
1756     return diff
; /* If zero strings are the same. */ 
1759 void authCommand(redisClient 
*c
) { 
1760     if (!server
.requirepass
) { 
1761         addReplyError(c
,"Client sent AUTH, but no password is set"); 
1762     } else if (!time_independent_strcmp(c
->argv
[1]->ptr
, server
.requirepass
)) { 
1763       c
->authenticated 
= 1; 
1764       addReply(c
,shared
.ok
); 
1766       c
->authenticated 
= 0; 
1767       addReplyError(c
,"invalid password"); 
1771 void pingCommand(redisClient 
*c
) { 
1772     addReply(c
,shared
.pong
); 
1775 void echoCommand(redisClient 
*c
) { 
1776     addReplyBulk(c
,c
->argv
[1]); 
1779 void timeCommand(redisClient 
*c
) { 
1782     /* gettimeofday() can only fail if &tv is a bad addresss so we 
1783      * don't check for errors. */ 
1784     gettimeofday(&tv
,NULL
); 
1785     addReplyMultiBulkLen(c
,2); 
1786     addReplyBulkLongLong(c
,tv
.tv_sec
); 
1787     addReplyBulkLongLong(c
,tv
.tv_usec
); 
1790 /* Convert an amount of bytes into a human readable string in the form 
1791  * of 100B, 2G, 100M, 4K, and so forth. */ 
1792 void bytesToHuman(char *s
, unsigned long long n
) { 
1797         sprintf(s
,"%lluB",n
); 
1799     } else if (n 
< (1024*1024)) { 
1800         d 
= (double)n
/(1024); 
1801         sprintf(s
,"%.2fK",d
); 
1802     } else if (n 
< (1024LL*1024*1024)) { 
1803         d 
= (double)n
/(1024*1024); 
1804         sprintf(s
,"%.2fM",d
); 
1805     } else if (n 
< (1024LL*1024*1024*1024)) { 
1806         d 
= (double)n
/(1024LL*1024*1024); 
1807         sprintf(s
,"%.2fG",d
); 
1811 /* Create the string returned by the INFO command. This is decoupled 
1812  * by the INFO command itself as we need to report the same information 
1813  * on memory corruption problems. */ 
1814 sds 
genRedisInfoString(char *section
) { 
1815     sds info 
= sdsempty(); 
1816     time_t uptime 
= server
.unixtime
-server
.stat_starttime
; 
1818     struct rusage self_ru
, c_ru
; 
1819     unsigned long lol
, bib
; 
1820     int allsections 
= 0, defsections 
= 0; 
1824         allsections 
= strcasecmp(section
,"all") == 0; 
1825         defsections 
= strcasecmp(section
,"default") == 0; 
1828     getrusage(RUSAGE_SELF
, &self_ru
); 
1829     getrusage(RUSAGE_CHILDREN
, &c_ru
); 
1830     getClientsMaxBuffers(&lol
,&bib
); 
1833     if (allsections 
|| defsections 
|| !strcasecmp(section
,"server")) { 
1834         struct utsname name
; 
1837         if (server
.sentinel_mode
) mode 
= "sentinel"; 
1838         else mode 
= "standalone"; 
1840         if (sections
++) info 
= sdscat(info
,"\r\n"); 
1842         info 
= sdscatprintf(info
, 
1844             "redis_version:%s\r\n" 
1845             "redis_git_sha1:%s\r\n" 
1846             "redis_git_dirty:%d\r\n" 
1850             "multiplexing_api:%s\r\n" 
1851             "gcc_version:%d.%d.%d\r\n" 
1852             "process_id:%ld\r\n" 
1855             "uptime_in_seconds:%ld\r\n" 
1856             "uptime_in_days:%ld\r\n" 
1857             "lru_clock:%ld\r\n", 
1860             strtol(redisGitDirty(),NULL
,10) > 0, 
1862             name
.sysname
, name
.release
, name
.machine
, 
1866             __GNUC__
,__GNUC_MINOR__
,__GNUC_PATCHLEVEL__
, 
1875             (unsigned long) server
.lruclock
); 
1879     if (allsections 
|| defsections 
|| !strcasecmp(section
,"clients")) { 
1880         if (sections
++) info 
= sdscat(info
,"\r\n"); 
1881         info 
= sdscatprintf(info
, 
1883             "connected_clients:%lu\r\n" 
1884             "client_longest_output_list:%lu\r\n" 
1885             "client_biggest_input_buf:%lu\r\n" 
1886             "blocked_clients:%d\r\n", 
1887             listLength(server
.clients
)-listLength(server
.slaves
), 
1889             server
.bpop_blocked_clients
); 
1893     if (allsections 
|| defsections 
|| !strcasecmp(section
,"memory")) { 
1897         bytesToHuman(hmem
,zmalloc_used_memory()); 
1898         bytesToHuman(peak_hmem
,server
.stat_peak_memory
); 
1899         if (sections
++) info 
= sdscat(info
,"\r\n"); 
1900         info 
= sdscatprintf(info
, 
1902             "used_memory:%zu\r\n" 
1903             "used_memory_human:%s\r\n" 
1904             "used_memory_rss:%zu\r\n" 
1905             "used_memory_peak:%zu\r\n" 
1906             "used_memory_peak_human:%s\r\n" 
1907             "used_memory_lua:%lld\r\n" 
1908             "mem_fragmentation_ratio:%.2f\r\n" 
1909             "mem_allocator:%s\r\n", 
1910             zmalloc_used_memory(), 
1913             server
.stat_peak_memory
, 
1915             ((long long)lua_gc(server
.lua
,LUA_GCCOUNT
,0))*1024LL, 
1916             zmalloc_get_fragmentation_ratio(), 
1922     if (allsections 
|| defsections 
|| !strcasecmp(section
,"persistence")) { 
1923         if (sections
++) info 
= sdscat(info
,"\r\n"); 
1924         info 
= sdscatprintf(info
, 
1927             "rdb_changes_since_last_save:%lld\r\n" 
1928             "rdb_bgsave_in_progress:%d\r\n" 
1929             "rdb_last_save_time:%ld\r\n" 
1930             "rdb_last_bgsave_status:%s\r\n" 
1931             "rdb_last_bgsave_time_sec:%ld\r\n" 
1932             "rdb_current_bgsave_time_sec:%ld\r\n" 
1933             "aof_enabled:%d\r\n" 
1934             "aof_rewrite_in_progress:%d\r\n" 
1935             "aof_rewrite_scheduled:%d\r\n" 
1936             "aof_last_rewrite_time_sec:%ld\r\n" 
1937             "aof_current_rewrite_time_sec:%ld\r\n" 
1938             "aof_last_bgrewrite_status:%s\r\n", 
1941             server
.rdb_child_pid 
!= -1, 
1943             (server
.lastbgsave_status 
== REDIS_OK
) ? "ok" : "err", 
1944             server
.rdb_save_time_last
, 
1945             (server
.rdb_child_pid 
== -1) ? 
1946                 -1 : time(NULL
)-server
.rdb_save_time_start
, 
1947             server
.aof_state 
!= REDIS_AOF_OFF
, 
1948             server
.aof_child_pid 
!= -1, 
1949             server
.aof_rewrite_scheduled
, 
1950             server
.aof_rewrite_time_last
, 
1951             (server
.aof_child_pid 
== -1) ? 
1952                 -1 : time(NULL
)-server
.aof_rewrite_time_start
, 
1953             (server
.aof_lastbgrewrite_status 
== REDIS_OK
) ? "ok" : "err"); 
1955         if (server
.aof_state 
!= REDIS_AOF_OFF
) { 
1956             info 
= sdscatprintf(info
, 
1957                 "aof_current_size:%lld\r\n" 
1958                 "aof_base_size:%lld\r\n" 
1959                 "aof_pending_rewrite:%d\r\n" 
1960                 "aof_buffer_length:%zu\r\n" 
1961                 "aof_rewrite_buffer_length:%lu\r\n" 
1962                 "aof_pending_bio_fsync:%llu\r\n" 
1963                 "aof_delayed_fsync:%lu\r\n", 
1964                 (long long) server
.aof_current_size
, 
1965                 (long long) server
.aof_rewrite_base_size
, 
1966                 server
.aof_rewrite_scheduled
, 
1967                 sdslen(server
.aof_buf
), 
1968                 aofRewriteBufferSize(), 
1969                 bioPendingJobsOfType(REDIS_BIO_AOF_FSYNC
), 
1970                 server
.aof_delayed_fsync
); 
1973         if (server
.loading
) { 
1975             time_t eta
, elapsed
; 
1976             off_t remaining_bytes 
= server
.loading_total_bytes
- 
1977                                     server
.loading_loaded_bytes
; 
1979             perc 
= ((double)server
.loading_loaded_bytes 
/ 
1980                    server
.loading_total_bytes
) * 100; 
1982             elapsed 
= server
.unixtime
-server
.loading_start_time
; 
1984                 eta 
= 1; /* A fake 1 second figure if we don't have 
1987                 eta 
= (elapsed
*remaining_bytes
)/server
.loading_loaded_bytes
; 
1990             info 
= sdscatprintf(info
, 
1991                 "loading_start_time:%ld\r\n" 
1992                 "loading_total_bytes:%llu\r\n" 
1993                 "loading_loaded_bytes:%llu\r\n" 
1994                 "loading_loaded_perc:%.2f\r\n" 
1995                 "loading_eta_seconds:%ld\r\n" 
1996                 ,(unsigned long) server
.loading_start_time
, 
1997                 (unsigned long long) server
.loading_total_bytes
, 
1998                 (unsigned long long) server
.loading_loaded_bytes
, 
2006     if (allsections 
|| defsections 
|| !strcasecmp(section
,"stats")) { 
2007         if (sections
++) info 
= sdscat(info
,"\r\n"); 
2008         info 
= sdscatprintf(info
, 
2010             "total_connections_received:%lld\r\n" 
2011             "total_commands_processed:%lld\r\n" 
2012             "instantaneous_ops_per_sec:%lld\r\n" 
2013             "rejected_connections:%lld\r\n" 
2014             "expired_keys:%lld\r\n" 
2015             "evicted_keys:%lld\r\n" 
2016             "keyspace_hits:%lld\r\n" 
2017             "keyspace_misses:%lld\r\n" 
2018             "pubsub_channels:%ld\r\n" 
2019             "pubsub_patterns:%lu\r\n" 
2020             "latest_fork_usec:%lld\r\n", 
2021             server
.stat_numconnections
, 
2022             server
.stat_numcommands
, 
2023             getOperationsPerSecond(), 
2024             server
.stat_rejected_conn
, 
2025             server
.stat_expiredkeys
, 
2026             server
.stat_evictedkeys
, 
2027             server
.stat_keyspace_hits
, 
2028             server
.stat_keyspace_misses
, 
2029             dictSize(server
.pubsub_channels
), 
2030             listLength(server
.pubsub_patterns
), 
2031             server
.stat_fork_time
); 
2035     if (allsections 
|| defsections 
|| !strcasecmp(section
,"replication")) { 
2036         if (sections
++) info 
= sdscat(info
,"\r\n"); 
2037         info 
= sdscatprintf(info
, 
2040             server
.masterhost 
== NULL 
? "master" : "slave"); 
2041         if (server
.masterhost
) { 
2042             info 
= sdscatprintf(info
, 
2043                 "master_host:%s\r\n" 
2044                 "master_port:%d\r\n" 
2045                 "master_link_status:%s\r\n" 
2046                 "master_last_io_seconds_ago:%d\r\n" 
2047                 "master_sync_in_progress:%d\r\n" 
2050                 (server
.repl_state 
== REDIS_REPL_CONNECTED
) ? 
2053                 ((int)(server
.unixtime
-server
.master
->lastinteraction
)) : -1, 
2054                 server
.repl_state 
== REDIS_REPL_TRANSFER
 
2057             if (server
.repl_state 
== REDIS_REPL_TRANSFER
) { 
2058                 info 
= sdscatprintf(info
, 
2059                     "master_sync_left_bytes:%lld\r\n" 
2060                     "master_sync_last_io_seconds_ago:%d\r\n" 
2062                         (server
.repl_transfer_size 
- server
.repl_transfer_read
), 
2063                     (int)(server
.unixtime
-server
.repl_transfer_lastio
) 
2067             if (server
.repl_state 
!= REDIS_REPL_CONNECTED
) { 
2068                 info 
= sdscatprintf(info
, 
2069                     "master_link_down_since_seconds:%ld\r\n", 
2070                     (long)server
.unixtime
-server
.repl_down_since
); 
2072             info 
= sdscatprintf(info
, 
2073                 "slave_priority:%d\r\n", server
.slave_priority
); 
2075         info 
= sdscatprintf(info
, 
2076             "connected_slaves:%lu\r\n", 
2077             listLength(server
.slaves
)); 
2078         if (listLength(server
.slaves
)) { 
2083             listRewind(server
.slaves
,&li
); 
2084             while((ln 
= listNext(&li
))) { 
2085                 redisClient 
*slave 
= listNodeValue(ln
); 
2090                 if (anetPeerToString(slave
->fd
,ip
,&port
) == -1) continue; 
2091                 switch(slave
->replstate
) { 
2092                 case REDIS_REPL_WAIT_BGSAVE_START
: 
2093                 case REDIS_REPL_WAIT_BGSAVE_END
: 
2094                     state 
= "wait_bgsave"; 
2096                 case REDIS_REPL_SEND_BULK
: 
2097                     state 
= "send_bulk"; 
2099                 case REDIS_REPL_ONLINE
: 
2103                 if (state 
== NULL
) continue; 
2104                 info 
= sdscatprintf(info
,"slave%d:%s,%d,%s\r\n", 
2105                     slaveid
,ip
,slave
->slave_listening_port
,state
); 
2112     if (allsections 
|| defsections 
|| !strcasecmp(section
,"cpu")) { 
2113         if (sections
++) info 
= sdscat(info
,"\r\n"); 
2114         info 
= sdscatprintf(info
, 
2116         "used_cpu_sys:%.2f\r\n" 
2117         "used_cpu_user:%.2f\r\n" 
2118         "used_cpu_sys_children:%.2f\r\n" 
2119         "used_cpu_user_children:%.2f\r\n", 
2120         (float)self_ru
.ru_stime
.tv_sec
+(float)self_ru
.ru_stime
.tv_usec
/1000000, 
2121         (float)self_ru
.ru_utime
.tv_sec
+(float)self_ru
.ru_utime
.tv_usec
/1000000, 
2122         (float)c_ru
.ru_stime
.tv_sec
+(float)c_ru
.ru_stime
.tv_usec
/1000000, 
2123         (float)c_ru
.ru_utime
.tv_sec
+(float)c_ru
.ru_utime
.tv_usec
/1000000); 
2127     if (allsections 
|| !strcasecmp(section
,"commandstats")) { 
2128         if (sections
++) info 
= sdscat(info
,"\r\n"); 
2129         info 
= sdscatprintf(info
, "# Commandstats\r\n"); 
2130         numcommands 
= sizeof(redisCommandTable
)/sizeof(struct redisCommand
); 
2131         for (j 
= 0; j 
< numcommands
; j
++) { 
2132             struct redisCommand 
*c 
= redisCommandTable
+j
; 
2134             if (!c
->calls
) continue; 
2135             info 
= sdscatprintf(info
, 
2136                 "cmdstat_%s:calls=%lld,usec=%lld,usec_per_call=%.2f\r\n", 
2137                 c
->name
, c
->calls
, c
->microseconds
, 
2138                 (c
->calls 
== 0) ? 0 : ((float)c
->microseconds
/c
->calls
)); 
2143     if (allsections 
|| defsections 
|| !strcasecmp(section
,"keyspace")) { 
2144         if (sections
++) info 
= sdscat(info
,"\r\n"); 
2145         info 
= sdscatprintf(info
, "# Keyspace\r\n"); 
2146         for (j 
= 0; j 
< server
.dbnum
; j
++) { 
2147             long long keys
, vkeys
; 
2149             keys 
= dictSize(server
.db
[j
].dict
); 
2150             vkeys 
= dictSize(server
.db
[j
].expires
); 
2151             if (keys 
|| vkeys
) { 
2152                 info 
= sdscatprintf(info
, "db%d:keys=%lld,expires=%lld\r\n", 
2160 void infoCommand(redisClient 
*c
) { 
2161     char *section 
= c
->argc 
== 2 ? c
->argv
[1]->ptr 
: "default"; 
2164         addReply(c
,shared
.syntaxerr
); 
2167     sds info 
= genRedisInfoString(section
); 
2168     addReplySds(c
,sdscatprintf(sdsempty(),"$%lu\r\n", 
2169         (unsigned long)sdslen(info
))); 
2170     addReplySds(c
,info
); 
2171     addReply(c
,shared
.crlf
); 
2174 void monitorCommand(redisClient 
*c
) { 
2175     /* ignore MONITOR if aleady slave or in monitor mode */ 
2176     if (c
->flags 
& REDIS_SLAVE
) return; 
2178     c
->flags 
|= (REDIS_SLAVE
|REDIS_MONITOR
); 
2180     listAddNodeTail(server
.monitors
,c
); 
2181     addReply(c
,shared
.ok
); 
2184 /* ============================ Maxmemory directive  ======================== */ 
2186 /* This function gets called when 'maxmemory' is set on the config file to limit 
2187  * the max memory used by the server, before processing a command. 
2189  * The goal of the function is to free enough memory to keep Redis under the 
2190  * configured memory limit. 
2192  * The function starts calculating how many bytes should be freed to keep 
2193  * Redis under the limit, and enters a loop selecting the best keys to 
2194  * evict accordingly to the configured policy. 
2196  * If all the bytes needed to return back under the limit were freed the 
2197  * function returns REDIS_OK, otherwise REDIS_ERR is returned, and the caller 
2198  * should block the execution of commands that will result in more memory 
2199  * used by the server. 
2201 int freeMemoryIfNeeded(void) { 
2202     size_t mem_used
, mem_tofree
, mem_freed
; 
2203     int slaves 
= listLength(server
.slaves
); 
2205     /* Remove the size of slaves output buffers and AOF buffer from the 
2206      * count of used memory. */ 
2207     mem_used 
= zmalloc_used_memory(); 
2212         listRewind(server
.slaves
,&li
); 
2213         while((ln 
= listNext(&li
))) { 
2214             redisClient 
*slave 
= listNodeValue(ln
); 
2215             unsigned long obuf_bytes 
= getClientOutputBufferMemoryUsage(slave
); 
2216             if (obuf_bytes 
> mem_used
) 
2219                 mem_used 
-= obuf_bytes
; 
2222     if (server
.aof_state 
!= REDIS_AOF_OFF
) { 
2223         mem_used 
-= sdslen(server
.aof_buf
); 
2224         mem_used 
-= aofRewriteBufferSize(); 
2227     /* Check if we are over the memory limit. */ 
2228     if (mem_used 
<= server
.maxmemory
) return REDIS_OK
; 
2230     if (server
.maxmemory_policy 
== REDIS_MAXMEMORY_NO_EVICTION
) 
2231         return REDIS_ERR
; /* We need to free memory, but policy forbids. */ 
2233     /* Compute how much memory we need to free. */ 
2234     mem_tofree 
= mem_used 
- server
.maxmemory
; 
2236     while (mem_freed 
< mem_tofree
) { 
2237         int j
, k
, keys_freed 
= 0; 
2239         for (j 
= 0; j 
< server
.dbnum
; j
++) { 
2240             long bestval 
= 0; /* just to prevent warning */ 
2242             struct dictEntry 
*de
; 
2243             redisDb 
*db 
= server
.db
+j
; 
2246             if (server
.maxmemory_policy 
== REDIS_MAXMEMORY_ALLKEYS_LRU 
|| 
2247                 server
.maxmemory_policy 
== REDIS_MAXMEMORY_ALLKEYS_RANDOM
) 
2249                 dict 
= server
.db
[j
].dict
; 
2251                 dict 
= server
.db
[j
].expires
; 
2253             if (dictSize(dict
) == 0) continue; 
2255             /* volatile-random and allkeys-random policy */ 
2256             if (server
.maxmemory_policy 
== REDIS_MAXMEMORY_ALLKEYS_RANDOM 
|| 
2257                 server
.maxmemory_policy 
== REDIS_MAXMEMORY_VOLATILE_RANDOM
) 
2259                 de 
= dictGetRandomKey(dict
); 
2260                 bestkey 
= dictGetKey(de
); 
2263             /* volatile-lru and allkeys-lru policy */ 
2264             else if (server
.maxmemory_policy 
== REDIS_MAXMEMORY_ALLKEYS_LRU 
|| 
2265                 server
.maxmemory_policy 
== REDIS_MAXMEMORY_VOLATILE_LRU
) 
2267                 for (k 
= 0; k 
< server
.maxmemory_samples
; k
++) { 
2272                     de 
= dictGetRandomKey(dict
); 
2273                     thiskey 
= dictGetKey(de
); 
2274                     /* When policy is volatile-lru we need an additonal lookup 
2275                      * to locate the real key, as dict is set to db->expires. */ 
2276                     if (server
.maxmemory_policy 
== REDIS_MAXMEMORY_VOLATILE_LRU
) 
2277                         de 
= dictFind(db
->dict
, thiskey
); 
2279                     thisval 
= estimateObjectIdleTime(o
); 
2281                     /* Higher idle time is better candidate for deletion */ 
2282                     if (bestkey 
== NULL 
|| thisval 
> bestval
) { 
2290             else if (server
.maxmemory_policy 
== REDIS_MAXMEMORY_VOLATILE_TTL
) { 
2291                 for (k 
= 0; k 
< server
.maxmemory_samples
; k
++) { 
2295                     de 
= dictGetRandomKey(dict
); 
2296                     thiskey 
= dictGetKey(de
); 
2297                     thisval 
= (long) dictGetVal(de
); 
2299                     /* Expire sooner (minor expire unix timestamp) is better 
2300                      * candidate for deletion */ 
2301                     if (bestkey 
== NULL 
|| thisval 
< bestval
) { 
2308             /* Finally remove the selected key. */ 
2312                 robj 
*keyobj 
= createStringObject(bestkey
,sdslen(bestkey
)); 
2313                 propagateExpire(db
,keyobj
); 
2314                 /* We compute the amount of memory freed by dbDelete() alone. 
2315                  * It is possible that actually the memory needed to propagate 
2316                  * the DEL in AOF and replication link is greater than the one 
2317                  * we are freeing removing the key, but we can't account for 
2318                  * that otherwise we would never exit the loop. 
2320                  * AOF and Output buffer memory will be freed eventually so 
2321                  * we only care about memory used by the key space. */ 
2322                 delta 
= (long long) zmalloc_used_memory(); 
2323                 dbDelete(db
,keyobj
); 
2324                 delta 
-= (long long) zmalloc_used_memory(); 
2326                 server
.stat_evictedkeys
++; 
2327                 decrRefCount(keyobj
); 
2330                 /* When the memory to free starts to be big enough, we may 
2331                  * start spending so much time here that is impossible to 
2332                  * deliver data to the slaves fast enough, so we force the 
2333                  * transmission here inside the loop. */ 
2334                 if (slaves
) flushSlavesOutputBuffers(); 
2337         if (!keys_freed
) return REDIS_ERR
; /* nothing to free... */ 
2342 /* =================================== Main! ================================ */ 
2345 int linuxOvercommitMemoryValue(void) { 
2346     FILE *fp 
= fopen("/proc/sys/vm/overcommit_memory","r"); 
2350     if (fgets(buf
,64,fp
) == NULL
) { 
2359 void linuxOvercommitMemoryWarning(void) { 
2360     if (linuxOvercommitMemoryValue() == 0) { 
2361         redisLog(REDIS_WARNING
,"WARNING overcommit_memory is set to 0! Background save may fail under low memory condition. To fix this issue add 'vm.overcommit_memory = 1' to /etc/sysctl.conf and then reboot or run the command 'sysctl vm.overcommit_memory=1' for this to take effect."); 
2364 #endif /* __linux__ */ 
2366 void createPidFile(void) { 
2367     /* Try to write the pid file in a best-effort way. */ 
2368     FILE *fp 
= fopen(server
.pidfile
,"w"); 
2370         fprintf(fp
,"%d\n",(int)getpid()); 
2375 void daemonize(void) { 
2378     if (fork() != 0) exit(0); /* parent exits */ 
2379     setsid(); /* create a new session */ 
2381     /* Every output goes to /dev/null. If Redis is daemonized but 
2382      * the 'logfile' is set to 'stdout' in the configuration file 
2383      * it will not log at all. */ 
2384     if ((fd 
= open("/dev/null", O_RDWR
, 0)) != -1) { 
2385         dup2(fd
, STDIN_FILENO
); 
2386         dup2(fd
, STDOUT_FILENO
); 
2387         dup2(fd
, STDERR_FILENO
); 
2388         if (fd 
> STDERR_FILENO
) close(fd
); 
2393     printf("Redis server v=%s sha=%s:%d malloc=%s bits=%d\n", 
2396         atoi(redisGitDirty()) > 0, 
2398         sizeof(long) == 4 ? 32 : 64); 
2403     fprintf(stderr
,"Usage: ./redis-server [/path/to/redis.conf] [options]\n"); 
2404     fprintf(stderr
,"       ./redis-server - (read config from stdin)\n"); 
2405     fprintf(stderr
,"       ./redis-server -v or --version\n"); 
2406     fprintf(stderr
,"       ./redis-server -h or --help\n"); 
2407     fprintf(stderr
,"       ./redis-server --test-memory <megabytes>\n\n"); 
2408     fprintf(stderr
,"Examples:\n"); 
2409     fprintf(stderr
,"       ./redis-server (run the server with default conf)\n"); 
2410     fprintf(stderr
,"       ./redis-server /etc/redis/6379.conf\n"); 
2411     fprintf(stderr
,"       ./redis-server --port 7777\n"); 
2412     fprintf(stderr
,"       ./redis-server --port 7777 --slaveof 127.0.0.1 8888\n"); 
2413     fprintf(stderr
,"       ./redis-server /etc/myredis.conf --loglevel verbose\n\n"); 
2414     fprintf(stderr
,"Sentinel mode:\n"); 
2415     fprintf(stderr
,"       ./redis-server /etc/sentinel.conf --sentinel\n"); 
2419 void redisAsciiArt(void) { 
2420 #include "asciilogo.h" 
2421     char *buf 
= zmalloc(1024*16); 
2422     char *mode 
= "stand alone"; 
2424     if (server
.sentinel_mode
) mode 
= "sentinel"; 
2426     snprintf(buf
,1024*16,ascii_logo
, 
2429         strtol(redisGitDirty(),NULL
,10) > 0, 
2430         (sizeof(long) == 8) ? "64" : "32", 
2434     redisLogRaw(REDIS_NOTICE
|REDIS_LOG_RAW
,buf
); 
2438 static void sigtermHandler(int sig
) { 
2441     redisLogFromHandler(REDIS_WARNING
,"Received SIGTERM, scheduling shutdown..."); 
2442     server
.shutdown_asap 
= 1; 
2445 void setupSignalHandlers(void) { 
2446     struct sigaction act
; 
2448     /* When the SA_SIGINFO flag is set in sa_flags then sa_sigaction is used. 
2449      * Otherwise, sa_handler is used. */ 
2450     sigemptyset(&act
.sa_mask
); 
2452     act
.sa_handler 
= sigtermHandler
; 
2453     sigaction(SIGTERM
, &act
, NULL
); 
2455 #ifdef HAVE_BACKTRACE 
2456     sigemptyset(&act
.sa_mask
); 
2457     act
.sa_flags 
= SA_NODEFER 
| SA_RESETHAND 
| SA_SIGINFO
; 
2458     act
.sa_sigaction 
= sigsegvHandler
; 
2459     sigaction(SIGSEGV
, &act
, NULL
); 
2460     sigaction(SIGBUS
, &act
, NULL
); 
2461     sigaction(SIGFPE
, &act
, NULL
); 
2462     sigaction(SIGILL
, &act
, NULL
); 
2467 void memtest(size_t megabytes
, int passes
); 
2469 /* Returns 1 if there is --sentinel among the arguments or if 
2470  * argv[0] is exactly "redis-sentinel". */ 
2471 int checkForSentinelMode(int argc
, char **argv
) { 
2474     if (strstr(argv
[0],"redis-sentinel") != NULL
) return 1; 
2475     for (j 
= 1; j 
< argc
; j
++) 
2476         if (!strcmp(argv
[j
],"--sentinel")) return 1; 
2480 /* Function called at startup to load RDB or AOF file in memory. */ 
2481 void loadDataFromDisk(void) { 
2482     long long start 
= ustime(); 
2483     if (server
.aof_state 
== REDIS_AOF_ON
) { 
2484         if (loadAppendOnlyFile(server
.aof_filename
) == REDIS_OK
) 
2485             redisLog(REDIS_NOTICE
,"DB loaded from append only file: %.3f seconds",(float)(ustime()-start
)/1000000); 
2487         if (rdbLoad(server
.rdb_filename
) == REDIS_OK
) { 
2488             redisLog(REDIS_NOTICE
,"DB loaded from disk: %.3f seconds", 
2489                 (float)(ustime()-start
)/1000000); 
2490         } else if (errno 
!= ENOENT
) { 
2491             redisLog(REDIS_WARNING
,"Fatal error loading the DB. Exiting."); 
2497 void redisOutOfMemoryHandler(size_t allocation_size
) { 
2498     redisLog(REDIS_WARNING
,"Out Of Memory allocating %zu bytes!", 
2503 int main(int argc
, char **argv
) { 
2506     /* We need to initialize our libraries, and the server configuration. */ 
2507     zmalloc_enable_thread_safeness(); 
2508     zmalloc_set_oom_handler(redisOutOfMemoryHandler
); 
2509     srand(time(NULL
)^getpid()); 
2510     gettimeofday(&tv
,NULL
); 
2511     dictSetHashFunctionSeed(tv
.tv_sec
^tv
.tv_usec
^getpid()); 
2512     server
.sentinel_mode 
= checkForSentinelMode(argc
,argv
); 
2515     /* We need to init sentinel right now as parsing the configuration file 
2516      * in sentinel mode will have the effect of populating the sentinel 
2517      * data structures with master nodes to monitor. */ 
2518     if (server
.sentinel_mode
) { 
2519         initSentinelConfig(); 
2524         int j 
= 1; /* First option to parse in argv[] */ 
2525         sds options 
= sdsempty(); 
2526         char *configfile 
= NULL
; 
2528         /* Handle special options --help and --version */ 
2529         if (strcmp(argv
[1], "-v") == 0 || 
2530             strcmp(argv
[1], "--version") == 0) version(); 
2531         if (strcmp(argv
[1], "--help") == 0 || 
2532             strcmp(argv
[1], "-h") == 0) usage(); 
2533         if (strcmp(argv
[1], "--test-memory") == 0) { 
2535                 memtest(atoi(argv
[2]),50); 
2538                 fprintf(stderr
,"Please specify the amount of memory to test in megabytes.\n"); 
2539                 fprintf(stderr
,"Example: ./redis-server --test-memory 4096\n\n"); 
2544         /* First argument is the config file name? */ 
2545         if (argv
[j
][0] != '-' || argv
[j
][1] != '-') 
2546             configfile 
= argv
[j
++]; 
2547         /* All the other options are parsed and conceptually appended to the 
2548          * configuration file. For instance --port 6380 will generate the 
2549          * string "port 6380\n" to be parsed after the actual file name 
2550          * is parsed, if any. */ 
2552             if (argv
[j
][0] == '-' && argv
[j
][1] == '-') { 
2554                 if (sdslen(options
)) options 
= sdscat(options
,"\n"); 
2555                 options 
= sdscat(options
,argv
[j
]+2); 
2556                 options 
= sdscat(options
," "); 
2558                 /* Option argument */ 
2559                 options 
= sdscatrepr(options
,argv
[j
],strlen(argv
[j
])); 
2560                 options 
= sdscat(options
," "); 
2564         resetServerSaveParams(); 
2565         loadServerConfig(configfile
,options
); 
2568         redisLog(REDIS_WARNING
, "Warning: no config file specified, using the default config. In order to specify a config file use %s /path/to/%s.conf", argv
[0], server
.sentinel_mode 
? "sentinel" : "redis"); 
2570     if (server
.daemonize
) daemonize(); 
2572     if (server
.daemonize
) createPidFile(); 
2575     if (!server
.sentinel_mode
) { 
2576         /* Things only needed when not runnign in Sentinel mode. */ 
2577         redisLog(REDIS_WARNING
,"Server started, Redis version " REDIS_VERSION
); 
2579         linuxOvercommitMemoryWarning(); 
2582         if (server
.ipfd 
> 0) 
2583             redisLog(REDIS_NOTICE
,"The server is now ready to accept connections on port %d", server
.port
); 
2584         if (server
.sofd 
> 0) 
2585             redisLog(REDIS_NOTICE
,"The server is now ready to accept connections at %s", server
.unixsocket
); 
2588     /* Warning the user about suspicious maxmemory setting. */ 
2589     if (server
.maxmemory 
> 0 && server
.maxmemory 
< 1024*1024) { 
2590         redisLog(REDIS_WARNING
,"WARNING: You specified a maxmemory value that is less than 1MB (current value is %llu bytes). Are you sure this is what you really want?", server
.maxmemory
); 
2593     aeSetBeforeSleepProc(server
.el
,beforeSleep
); 
2595     aeDeleteEventLoop(server
.el
);