Commit 209f266c authored by antirez's avatar antirez
Browse files

Merge branch '1906-merge' into unstable

parents c951c3ee 1f8a6d80
...@@ -60,10 +60,15 @@ endif ...@@ -60,10 +60,15 @@ endif
LUA_CFLAGS+= -O2 -Wall -DLUA_ANSI $(CFLAGS) LUA_CFLAGS+= -O2 -Wall -DLUA_ANSI $(CFLAGS)
LUA_LDFLAGS+= $(LDFLAGS) LUA_LDFLAGS+= $(LDFLAGS)
# lua's Makefile defines AR="ar rcu", which is unusual, and makes it more
# challenging to cross-compile lua (and redis). These defines make it easier
# to fit redis into cross-compilation environments, which typically set AR.
AR=ar
ARFLAGS=rcu
lua: .make-prerequisites lua: .make-prerequisites
@printf '%b %b\n' $(MAKECOLOR)MAKE$(ENDCOLOR) $(BINCOLOR)$@$(ENDCOLOR) @printf '%b %b\n' $(MAKECOLOR)MAKE$(ENDCOLOR) $(BINCOLOR)$@$(ENDCOLOR)
cd lua/src && $(MAKE) all CFLAGS="$(LUA_CFLAGS)" MYLDFLAGS="$(LUA_LDFLAGS)" cd lua/src && $(MAKE) all CFLAGS="$(LUA_CFLAGS)" MYLDFLAGS="$(LUA_LDFLAGS)" AR="$(AR) $(ARFLAGS)"
.PHONY: lua .PHONY: lua
......
...@@ -5,6 +5,10 @@ ...@@ -5,6 +5,10 @@
#define _BSD_SOURCE #define _BSD_SOURCE
#endif #endif
#if defined(_AIX)
#define _ALL_SOURCE
#endif
#if defined(__sun__) #if defined(__sun__)
#define _POSIX_C_SOURCE 200112L #define _POSIX_C_SOURCE 200112L
#elif defined(__linux__) || defined(__OpenBSD__) || defined(__NetBSD__) #elif defined(__linux__) || defined(__OpenBSD__) || defined(__NetBSD__)
......
...@@ -35,7 +35,7 @@ ...@@ -35,7 +35,7 @@
#include "hiredis.h" #include "hiredis.h"
#if defined(__sun) #if defined(__sun) || defined(_AIX)
#define AF_LOCAL AF_UNIX #define AF_LOCAL AF_UNIX
#endif #endif
......
...@@ -123,7 +123,7 @@ void sdsclear(sds s) { ...@@ -123,7 +123,7 @@ void sdsclear(sds s) {
/* Enlarge the free space at the end of the sds string so that the caller /* Enlarge the free space at the end of the sds string so that the caller
* is sure that after calling this function can overwrite up to addlen * is sure that after calling this function can overwrite up to addlen
* bytes after the end of the string, plus one more byte for nul term. * bytes after the end of the string, plus one more byte for nul term.
* *
* Note: this does not change the *length* of the sds string as returned * Note: this does not change the *length* of the sds string as returned
* by sdslen(), but only the free buffer space we have. */ * by sdslen(), but only the free buffer space we have. */
sds sdsMakeRoomFor(sds s, size_t addlen) { sds sdsMakeRoomFor(sds s, size_t addlen) {
...@@ -200,7 +200,10 @@ size_t sdsAllocSize(sds s) { ...@@ -200,7 +200,10 @@ size_t sdsAllocSize(sds s) {
void sdsIncrLen(sds s, int incr) { void sdsIncrLen(sds s, int incr) {
struct sdshdr *sh = (void*) (s-(sizeof(struct sdshdr))); struct sdshdr *sh = (void*) (s-(sizeof(struct sdshdr)));
assert(sh->free >= incr); if (incr >= 0)
assert(sh->free >= (unsigned int)incr);
else
assert(sh->len >= (unsigned int)(-incr));
sh->len += incr; sh->len += incr;
sh->free -= incr; sh->free -= incr;
assert(sh->free >= 0); assert(sh->free >= 0);
...@@ -457,7 +460,7 @@ sds sdscatfmt(sds s, char const *fmt, ...) { ...@@ -457,7 +460,7 @@ sds sdscatfmt(sds s, char const *fmt, ...) {
i = initlen; /* Position of the next byte to write to dest str. */ i = initlen; /* Position of the next byte to write to dest str. */
while(*f) { while(*f) {
char next, *str; char next, *str;
int l; unsigned int l;
long long num; long long num;
unsigned long long unum; unsigned long long unum;
......
...@@ -39,8 +39,8 @@ ...@@ -39,8 +39,8 @@
typedef char *sds; typedef char *sds;
struct sdshdr { struct sdshdr {
int len; unsigned int len;
int free; unsigned int free;
char buf[]; char buf[];
}; };
......
...@@ -68,7 +68,7 @@ tcp-backlog 511 ...@@ -68,7 +68,7 @@ tcp-backlog 511
# on a unix socket when not specified. # on a unix socket when not specified.
# #
# unixsocket /tmp/redis.sock # unixsocket /tmp/redis.sock
# unixsocketperm 755 # unixsocketperm 700
# Close the connection after a client is idle for N seconds (0 to disable) # Close the connection after a client is idle for N seconds (0 to disable)
timeout 0 timeout 0
......
...@@ -19,7 +19,7 @@ DEPENDENCY_TARGETS=hiredis linenoise lua ...@@ -19,7 +19,7 @@ DEPENDENCY_TARGETS=hiredis linenoise lua
# Default settings # Default settings
STD=-std=c99 -pedantic STD=-std=c99 -pedantic
WARN=-Wall WARN=-Wall -W
OPT=$(OPTIMIZATION) OPT=$(OPTIMIZATION)
PREFIX?=/usr/local PREFIX?=/usr/local
...@@ -58,17 +58,23 @@ ifeq ($(uname_S),SunOS) ...@@ -58,17 +58,23 @@ ifeq ($(uname_S),SunOS)
# SunOS # SunOS
INSTALL=cp -pf INSTALL=cp -pf
FINAL_CFLAGS+= -D__EXTENSIONS__ -D_XPG6 FINAL_CFLAGS+= -D__EXTENSIONS__ -D_XPG6
FINAL_LIBS+= -ldl -lnsl -lsocket -lpthread FINAL_LIBS+= -ldl -lnsl -lsocket -lresolv -lpthread
else else
ifeq ($(uname_S),Darwin) ifeq ($(uname_S),Darwin)
# Darwin (nothing to do) # Darwin (nothing to do)
else
ifeq ($(uname_S),AIX)
# AIX
FINAL_LDFLAGS+= -Wl,-bexpall
FINAL_LIBS+= -pthread -lcrypt -lbsd
else else
# All the other OSes (notably Linux) # All the other OSes (notably Linux)
FINAL_LDFLAGS+= -rdynamic FINAL_LDFLAGS+= -rdynamic
FINAL_LIBS+= -pthread FINAL_LIBS+= -pthread
endif endif
endif endif
endif
# Include paths to dependencies # Include paths to dependencies
FINAL_CFLAGS+= -I../deps/hiredis -I../deps/linenoise -I../deps/lua/src FINAL_CFLAGS+= -I../deps/hiredis -I../deps/linenoise -I../deps/lua/src
...@@ -119,7 +125,7 @@ REDIS_CHECK_AOF_OBJ=redis-check-aof.o ...@@ -119,7 +125,7 @@ REDIS_CHECK_AOF_OBJ=redis-check-aof.o
all: $(REDIS_SERVER_NAME) $(REDIS_SENTINEL_NAME) $(REDIS_CLI_NAME) $(REDIS_BENCHMARK_NAME) $(REDIS_CHECK_DUMP_NAME) $(REDIS_CHECK_AOF_NAME) all: $(REDIS_SERVER_NAME) $(REDIS_SENTINEL_NAME) $(REDIS_CLI_NAME) $(REDIS_BENCHMARK_NAME) $(REDIS_CHECK_DUMP_NAME) $(REDIS_CHECK_AOF_NAME)
@echo "" @echo ""
@echo "Hint: To run 'make test' is a good idea ;)" @echo "Hint: It's a good idea to run 'make test' ;)"
@echo "" @echo ""
.PHONY: all .PHONY: all
......
...@@ -156,8 +156,9 @@ void aeDeleteFileEvent(aeEventLoop *eventLoop, int fd, int mask) ...@@ -156,8 +156,9 @@ void aeDeleteFileEvent(aeEventLoop *eventLoop, int fd, int mask)
{ {
if (fd >= eventLoop->setsize) return; if (fd >= eventLoop->setsize) return;
aeFileEvent *fe = &eventLoop->events[fd]; aeFileEvent *fe = &eventLoop->events[fd];
if (fe->mask == AE_NONE) return; if (fe->mask == AE_NONE) return;
aeApiDelEvent(eventLoop, fd, mask);
fe->mask = fe->mask & (~mask); fe->mask = fe->mask & (~mask);
if (fd == eventLoop->maxfd && fe->mask == AE_NONE) { if (fd == eventLoop->maxfd && fe->mask == AE_NONE) {
/* Update the max fd */ /* Update the max fd */
...@@ -167,7 +168,6 @@ void aeDeleteFileEvent(aeEventLoop *eventLoop, int fd, int mask) ...@@ -167,7 +168,6 @@ void aeDeleteFileEvent(aeEventLoop *eventLoop, int fd, int mask)
if (eventLoop->events[j].mask != AE_NONE) break; if (eventLoop->events[j].mask != AE_NONE) break;
eventLoop->maxfd = j; eventLoop->maxfd = j;
} }
aeApiDelEvent(eventLoop, fd, mask);
} }
int aeGetFileEvents(aeEventLoop *eventLoop, int fd) { int aeGetFileEvents(aeEventLoop *eventLoop, int fd) {
......
...@@ -117,6 +117,8 @@ int anetKeepAlive(char *err, int fd, int interval) ...@@ -117,6 +117,8 @@ int anetKeepAlive(char *err, int fd, int interval)
anetSetError(err, "setsockopt TCP_KEEPCNT: %s\n", strerror(errno)); anetSetError(err, "setsockopt TCP_KEEPCNT: %s\n", strerror(errno));
return ANET_ERR; return ANET_ERR;
} }
#else
((void) interval); /* Avoid unused var warning for non Linux systems. */
#endif #endif
return ANET_OK; return ANET_OK;
...@@ -262,7 +264,8 @@ static int anetTcpGenericConnect(char *err, char *addr, int port, ...@@ -262,7 +264,8 @@ static int anetTcpGenericConnect(char *err, char *addr, int port,
if (source_addr) { if (source_addr) {
int bound = 0; int bound = 0;
/* Using getaddrinfo saves us from self-determining IPv4 vs IPv6 */ /* Using getaddrinfo saves us from self-determining IPv4 vs IPv6 */
if ((rv = getaddrinfo(source_addr, NULL, &hints, &bservinfo)) != 0) { if ((rv = getaddrinfo(source_addr, NULL, &hints, &bservinfo)) != 0)
{
anetSetError(err, "%s", gai_strerror(rv)); anetSetError(err, "%s", gai_strerror(rv));
goto end; goto end;
} }
...@@ -272,6 +275,7 @@ static int anetTcpGenericConnect(char *err, char *addr, int port, ...@@ -272,6 +275,7 @@ static int anetTcpGenericConnect(char *err, char *addr, int port,
break; break;
} }
} }
freeaddrinfo(bservinfo);
if (!bound) { if (!bound) {
anetSetError(err, "bind: %s", strerror(errno)); anetSetError(err, "bind: %s", strerror(errno));
goto end; goto end;
......
...@@ -39,10 +39,14 @@ ...@@ -39,10 +39,14 @@
#define ANET_NONE 0 #define ANET_NONE 0
#define ANET_IP_ONLY (1<<0) #define ANET_IP_ONLY (1<<0)
#if defined(__sun) #if defined(__sun) || defined(_AIX)
#define AF_LOCAL AF_UNIX #define AF_LOCAL AF_UNIX
#endif #endif
#ifdef _AIX
#undef ip_len
#endif
int anetTcpConnect(char *err, char *addr, int port); int anetTcpConnect(char *err, char *addr, int port);
int anetTcpNonBlockConnect(char *err, char *addr, int port); int anetTcpNonBlockConnect(char *err, char *addr, int port);
int anetTcpNonBlockBindConnect(char *err, char *addr, int port, char *source_addr); int anetTcpNonBlockBindConnect(char *err, char *addr, int port, char *source_addr);
......
...@@ -95,6 +95,10 @@ void aofChildWriteDiffData(aeEventLoop *el, int fd, void *privdata, int mask) { ...@@ -95,6 +95,10 @@ void aofChildWriteDiffData(aeEventLoop *el, int fd, void *privdata, int mask) {
listNode *ln; listNode *ln;
aofrwblock *block; aofrwblock *block;
ssize_t nwritten; ssize_t nwritten;
REDIS_NOTUSED(el);
REDIS_NOTUSED(fd);
REDIS_NOTUSED(privdata);
REDIS_NOTUSED(mask);
while(1) { while(1) {
ln = listFirst(server.aof_rewrite_buf_blocks); ln = listFirst(server.aof_rewrite_buf_blocks);
...@@ -177,7 +181,7 @@ ssize_t aofRewriteBufferWrite(int fd) { ...@@ -177,7 +181,7 @@ ssize_t aofRewriteBufferWrite(int fd) {
if (block->used) { if (block->used) {
nwritten = write(fd,block->buf,block->used); nwritten = write(fd,block->buf,block->used);
if (nwritten != block->used) { if (nwritten != (ssize_t)block->used) {
if (nwritten == 0) errno = EIO; if (nwritten == 0) errno = EIO;
return -1; return -1;
} }
...@@ -1128,6 +1132,9 @@ werr: ...@@ -1128,6 +1132,9 @@ werr:
* parent sends a '!' as well to acknowledge. */ * parent sends a '!' as well to acknowledge. */
void aofChildPipeReadable(aeEventLoop *el, int fd, void *privdata, int mask) { void aofChildPipeReadable(aeEventLoop *el, int fd, void *privdata, int mask) {
char byte; char byte;
REDIS_NOTUSED(el);
REDIS_NOTUSED(privdata);
REDIS_NOTUSED(mask);
if (read(fd,&byte,1) == 1 && byte == '!') { if (read(fd,&byte,1) == 1 && byte == '!') {
redisLog(REDIS_NOTICE,"AOF rewrite child asks to stop sending diffs."); redisLog(REDIS_NOTICE,"AOF rewrite child asks to stop sending diffs.");
......
...@@ -107,12 +107,12 @@ size_t redisPopcount(void *s, long count) { ...@@ -107,12 +107,12 @@ size_t redisPopcount(void *s, long count) {
* no zero bit is found, it returns count*8 assuming the string is zero * no zero bit is found, it returns count*8 assuming the string is zero
* padded on the right. However if 'bit' is 1 it is possible that there is * padded on the right. However if 'bit' is 1 it is possible that there is
* not a single set bit in the bitmap. In this special case -1 is returned. */ * not a single set bit in the bitmap. In this special case -1 is returned. */
long redisBitpos(void *s, long count, int bit) { long redisBitpos(void *s, unsigned long count, int bit) {
unsigned long *l; unsigned long *l;
unsigned char *c; unsigned char *c;
unsigned long skipval, word = 0, one; unsigned long skipval, word = 0, one;
long pos = 0; /* Position of bit, to return to the caller. */ long pos = 0; /* Position of bit, to return to the caller. */
int j; unsigned long j;
/* Process whole words first, seeking for first word that is not /* Process whole words first, seeking for first word that is not
* all ones or all zeros respectively if we are lookig for zeros * all ones or all zeros respectively if we are lookig for zeros
...@@ -276,11 +276,12 @@ void getbitCommand(redisClient *c) { ...@@ -276,11 +276,12 @@ void getbitCommand(redisClient *c) {
void bitopCommand(redisClient *c) { void bitopCommand(redisClient *c) {
char *opname = c->argv[1]->ptr; char *opname = c->argv[1]->ptr;
robj *o, *targetkey = c->argv[2]; robj *o, *targetkey = c->argv[2];
long op, j, numkeys; unsigned long op, j, numkeys;
robj **objects; /* Array of source objects. */ robj **objects; /* Array of source objects. */
unsigned char **src; /* Array of source strings pointers. */ unsigned char **src; /* Array of source strings pointers. */
long *len, maxlen = 0; /* Array of length of src strings, and max len. */ unsigned long *len, maxlen = 0; /* Array of length of src strings,
long minlen = 0; /* Min len among the input keys. */ and max len. */
unsigned long minlen = 0; /* Min len among the input keys. */
unsigned char *res = NULL; /* Resulting string. */ unsigned char *res = NULL; /* Resulting string. */
/* Parse the operation name. */ /* Parse the operation name. */
...@@ -320,9 +321,10 @@ void bitopCommand(redisClient *c) { ...@@ -320,9 +321,10 @@ void bitopCommand(redisClient *c) {
} }
/* Return an error if one of the keys is not a string. */ /* Return an error if one of the keys is not a string. */
if (checkType(c,o,REDIS_STRING)) { if (checkType(c,o,REDIS_STRING)) {
for (j = j-1; j >= 0; j--) { unsigned long i;
if (objects[j]) for (i = 0; i < j; i++) {
decrRefCount(objects[j]); if (objects[i])
decrRefCount(objects[i]);
} }
zfree(src); zfree(src);
zfree(len); zfree(len);
...@@ -340,7 +342,7 @@ void bitopCommand(redisClient *c) { ...@@ -340,7 +342,7 @@ void bitopCommand(redisClient *c) {
if (maxlen) { if (maxlen) {
res = (unsigned char*) sdsnewlen(NULL,maxlen); res = (unsigned char*) sdsnewlen(NULL,maxlen);
unsigned char output, byte; unsigned char output, byte;
long i; unsigned long i;
/* Fast path: as far as we have data for all the input bitmaps we /* Fast path: as far as we have data for all the input bitmaps we
* can take a fast path that performs much better than the * can take a fast path that performs much better than the
......
...@@ -72,6 +72,7 @@ void resetManualFailover(void); ...@@ -72,6 +72,7 @@ void resetManualFailover(void);
void clusterCloseAllSlots(void); void clusterCloseAllSlots(void);
void clusterSetNodeAsMaster(clusterNode *n); void clusterSetNodeAsMaster(clusterNode *n);
void clusterDelNode(clusterNode *delnode); void clusterDelNode(clusterNode *delnode);
sds representRedisNodeFlags(sds ci, uint16_t flags);
/* ----------------------------------------------------------------------------- /* -----------------------------------------------------------------------------
* Initialization * Initialization
...@@ -163,9 +164,13 @@ int clusterLoadConfig(char *filename) { ...@@ -163,9 +164,13 @@ int clusterLoadConfig(char *filename) {
argv[j]); argv[j]);
} }
} }
sdsfreesplitres(argv,argc);
continue; continue;
} }
/* Regular config lines have at least eight fields */
if (argc < 8) goto fmterr;
/* Create this node if it does not exist */ /* Create this node if it does not exist */
n = clusterLookupNode(argv[0]); n = clusterLookupNode(argv[0]);
if (!n) { if (!n) {
...@@ -266,11 +271,12 @@ int clusterLoadConfig(char *filename) { ...@@ -266,11 +271,12 @@ int clusterLoadConfig(char *filename) {
sdsfreesplitres(argv,argc); sdsfreesplitres(argv,argc);
} }
/* Config sanity check */
if (server.cluster->myself == NULL) goto fmterr;
zfree(line); zfree(line);
fclose(fp); fclose(fp);
/* Config sanity check */
redisAssert(server.cluster->myself != NULL);
redisLog(REDIS_NOTICE,"Node configuration loaded, I'm %.40s", myself->name); redisLog(REDIS_NOTICE,"Node configuration loaded, I'm %.40s", myself->name);
/* Something that should never happen: currentEpoch smaller than /* Something that should never happen: currentEpoch smaller than
...@@ -284,7 +290,8 @@ int clusterLoadConfig(char *filename) { ...@@ -284,7 +290,8 @@ int clusterLoadConfig(char *filename) {
fmterr: fmterr:
redisLog(REDIS_WARNING, redisLog(REDIS_WARNING,
"Unrecoverable error: corrupted cluster config file."); "Unrecoverable error: corrupted cluster config file.");
fclose(fp); zfree(line);
if (fp) fclose(fp);
exit(1); exit(1);
} }
...@@ -321,7 +328,7 @@ int clusterSaveConfig(int do_fsync) { ...@@ -321,7 +328,7 @@ int clusterSaveConfig(int do_fsync) {
/* Pad the new payload if the existing file length is greater. */ /* Pad the new payload if the existing file length is greater. */
if (fstat(fd,&sb) != -1) { if (fstat(fd,&sb) != -1) {
if (sb.st_size > content_size) { if (sb.st_size > (off_t)content_size) {
ci = sdsgrowzero(ci,sb.st_size); ci = sdsgrowzero(ci,sb.st_size);
memset(ci+content_size,'\n',sb.st_size-content_size); memset(ci+content_size,'\n',sb.st_size-content_size);
} }
...@@ -1144,20 +1151,11 @@ void clusterProcessGossipSection(clusterMsg *hdr, clusterLink *link) { ...@@ -1144,20 +1151,11 @@ void clusterProcessGossipSection(clusterMsg *hdr, clusterLink *link) {
clusterNode *sender = link->node ? link->node : clusterLookupNode(hdr->sender); clusterNode *sender = link->node ? link->node : clusterLookupNode(hdr->sender);
while(count--) { while(count--) {
sds ci = sdsempty();
uint16_t flags = ntohs(g->flags); uint16_t flags = ntohs(g->flags);
clusterNode *node; clusterNode *node;
sds ci;
if (flags == 0) ci = sdscat(ci,"noflags,"); ci = representRedisNodeFlags(sdsempty(), flags);
if (flags & REDIS_NODE_MYSELF) ci = sdscat(ci,"myself,");
if (flags & REDIS_NODE_MASTER) ci = sdscat(ci,"master,");
if (flags & REDIS_NODE_SLAVE) ci = sdscat(ci,"slave,");
if (flags & REDIS_NODE_PFAIL) ci = sdscat(ci,"fail?,");
if (flags & REDIS_NODE_FAIL) ci = sdscat(ci,"fail,");
if (flags & REDIS_NODE_HANDSHAKE) ci = sdscat(ci,"handshake,");
if (flags & REDIS_NODE_NOADDR) ci = sdscat(ci,"noaddr,");
if (ci[sdslen(ci)-1] == ',') ci[sdslen(ci)-1] = ' ';
redisLog(REDIS_DEBUG,"GOSSIP %.40s %s:%d %s", redisLog(REDIS_DEBUG,"GOSSIP %.40s %s:%d %s",
g->nodename, g->nodename,
g->ip, g->ip,
...@@ -1914,7 +1912,7 @@ void clusterReadHandler(aeEventLoop *el, int fd, void *privdata, int mask) { ...@@ -1914,7 +1912,7 @@ void clusterReadHandler(aeEventLoop *el, int fd, void *privdata, int mask) {
ssize_t nread; ssize_t nread;
clusterMsg *hdr; clusterMsg *hdr;
clusterLink *link = (clusterLink*) privdata; clusterLink *link = (clusterLink*) privdata;
int readlen, rcvbuflen; unsigned int readlen, rcvbuflen;
REDIS_NOTUSED(el); REDIS_NOTUSED(el);
REDIS_NOTUSED(mask); REDIS_NOTUSED(mask);
...@@ -3296,14 +3294,13 @@ int verifyClusterConfigWithData(void) { ...@@ -3296,14 +3294,13 @@ int verifyClusterConfigWithData(void) {
update_config++; update_config++;
/* Case A: slot is unassigned. Take responsability for it. */ /* Case A: slot is unassigned. Take responsability for it. */
if (server.cluster->slots[j] == NULL) { if (server.cluster->slots[j] == NULL) {
redisLog(REDIS_WARNING, "I've keys about slot %d that is " redisLog(REDIS_WARNING, "I have keys for unassigned slot %d. "
"unassigned. Taking responsability " "Taking responsibility for it.",j);
"for it.",j);
clusterAddSlot(myself,j); clusterAddSlot(myself,j);
} else { } else {
redisLog(REDIS_WARNING, "I've keys about slot %d that is " redisLog(REDIS_WARNING, "I have keys for slot %d, but the slot is "
"already assigned to a different node. " "assigned to another node. "
"Setting it in importing state.",j); "Setting it to importing state.",j);
server.cluster->importing_slots_from[j] = server.cluster->slots[j]; server.cluster->importing_slots_from[j] = server.cluster->slots[j];
} }
} }
...@@ -3336,9 +3333,40 @@ void clusterSetMaster(clusterNode *n) { ...@@ -3336,9 +3333,40 @@ void clusterSetMaster(clusterNode *n) {
} }
/* ----------------------------------------------------------------------------- /* -----------------------------------------------------------------------------
* CLUSTER command * Nodes to string representation functions.
* -------------------------------------------------------------------------- */ * -------------------------------------------------------------------------- */
struct redisNodeFlags {
uint16_t flag;
char *name;
};
static struct redisNodeFlags redisNodeFlagsTable[] = {
{REDIS_NODE_MYSELF, "myself,"},
{REDIS_NODE_MASTER, "master,"},
{REDIS_NODE_SLAVE, "slave,"},
{REDIS_NODE_PFAIL, "fail?,"},
{REDIS_NODE_FAIL, "fail,"},
{REDIS_NODE_HANDSHAKE, "handshake,"},
{REDIS_NODE_NOADDR, "noaddr,"}
};
/* Concatenate the comma separated list of node flags to the given SDS
* string 'ci'. */
sds representRedisNodeFlags(sds ci, uint16_t flags) {
if (flags == 0) {
ci = sdscat(ci,"noflags,");
} else {
int i, size = sizeof(redisNodeFlagsTable)/sizeof(struct redisNodeFlags);
for (i = 0; i < size; i++) {
struct redisNodeFlags *nodeflag = redisNodeFlagsTable + i;
if (flags & nodeflag->flag) ci = sdscat(ci, nodeflag->name);
}
}
sdsIncrLen(ci,-1); /* Remove trailing comma. */
return ci;
}
/* Generate a csv-alike representation of the specified cluster node. /* Generate a csv-alike representation of the specified cluster node.
* See clusterGenNodesDescription() top comment for more information. * See clusterGenNodesDescription() top comment for more information.
* *
...@@ -3354,21 +3382,13 @@ sds clusterGenNodeDescription(clusterNode *node) { ...@@ -3354,21 +3382,13 @@ sds clusterGenNodeDescription(clusterNode *node) {
node->port); node->port);
/* Flags */ /* Flags */
if (node->flags == 0) ci = sdscat(ci,"noflags,"); ci = representRedisNodeFlags(ci, node->flags);
if (node->flags & REDIS_NODE_MYSELF) ci = sdscat(ci,"myself,");
if (node->flags & REDIS_NODE_MASTER) ci = sdscat(ci,"master,");
if (node->flags & REDIS_NODE_SLAVE) ci = sdscat(ci,"slave,");
if (node->flags & REDIS_NODE_PFAIL) ci = sdscat(ci,"fail?,");
if (node->flags & REDIS_NODE_FAIL) ci = sdscat(ci,"fail,");
if (node->flags & REDIS_NODE_HANDSHAKE) ci =sdscat(ci,"handshake,");
if (node->flags & REDIS_NODE_NOADDR) ci = sdscat(ci,"noaddr,");
if (ci[sdslen(ci)-1] == ',') ci[sdslen(ci)-1] = ' ';
/* Slave of... or just "-" */ /* Slave of... or just "-" */
if (node->slaveof) if (node->slaveof)
ci = sdscatprintf(ci,"%.40s ",node->slaveof->name); ci = sdscatprintf(ci," %.40s ",node->slaveof->name);
else else
ci = sdscatprintf(ci,"- "); ci = sdscatlen(ci," - ",3);
/* Latency from the POV of this node, link status */ /* Latency from the POV of this node, link status */
ci = sdscatprintf(ci,"%lld %lld %llu %s", ci = sdscatprintf(ci,"%lld %lld %llu %s",
...@@ -3446,6 +3466,10 @@ sds clusterGenNodesDescription(int filter) { ...@@ -3446,6 +3466,10 @@ sds clusterGenNodesDescription(int filter) {
return ci; return ci;
} }
/* -----------------------------------------------------------------------------
* CLUSTER command
* -------------------------------------------------------------------------- */
int getSlotOrReply(redisClient *c, robj *o) { int getSlotOrReply(redisClient *c, robj *o) {
long long slot; long long slot;
...@@ -3962,7 +3986,7 @@ void clusterCommand(redisClient *c) { ...@@ -3962,7 +3986,7 @@ void clusterCommand(redisClient *c) {
"configEpoch set to %llu via CLUSTER SET-CONFIG-EPOCH", "configEpoch set to %llu via CLUSTER SET-CONFIG-EPOCH",
(unsigned long long) myself->configEpoch); (unsigned long long) myself->configEpoch);
if (server.cluster->currentEpoch < epoch) if (server.cluster->currentEpoch < (uint64_t)epoch)
server.cluster->currentEpoch = epoch; server.cluster->currentEpoch = epoch;
/* No need to fsync the config here since in the unlucky event /* No need to fsync the config here since in the unlucky event
* of a failure to persist the config, the conflict resolution code * of a failure to persist the config, the conflict resolution code
......
...@@ -73,7 +73,7 @@ void appendServerSaveParams(time_t seconds, int changes) { ...@@ -73,7 +73,7 @@ void appendServerSaveParams(time_t seconds, int changes) {
server.saveparamslen++; server.saveparamslen++;
} }
void resetServerSaveParams() { void resetServerSaveParams(void) {
zfree(server.saveparams); zfree(server.saveparams);
server.saveparams = NULL; server.saveparams = NULL;
server.saveparamslen = 0; server.saveparamslen = 0;
...@@ -629,7 +629,7 @@ void configSetCommand(redisClient *c) { ...@@ -629,7 +629,7 @@ void configSetCommand(redisClient *c) {
server.maxclients = orig_value; server.maxclients = orig_value;
return; return;
} }
if (aeGetSetSize(server.el) < if ((unsigned int) aeGetSetSize(server.el) <
server.maxclients + REDIS_EVENTLOOP_FDSET_INCR) server.maxclients + REDIS_EVENTLOOP_FDSET_INCR)
{ {
if (aeResizeSetSize(server.el, if (aeResizeSetSize(server.el,
......
...@@ -187,9 +187,14 @@ void setproctitle(const char *fmt, ...); ...@@ -187,9 +187,14 @@ void setproctitle(const char *fmt, ...);
#if (__i386 || __amd64 || __powerpc__) && __GNUC__ #if (__i386 || __amd64 || __powerpc__) && __GNUC__
#define GNUC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) #define GNUC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
#if (GNUC_VERSION >= 40100) || defined(__clang__) #if defined(__clang__)
#define HAVE_ATOMIC #define HAVE_ATOMIC
#endif #endif
#if (defined(__GLIBC__) && defined(__GLIBC_PREREQ))
#if (GNUC_VERSION >= 40100 && __GLIBC_PREREQ(2, 6))
#define HAVE_ATOMIC
#endif
#endif
#endif #endif
#endif #endif
...@@ -421,9 +421,7 @@ int parseScanCursorOrReply(redisClient *c, robj *o, unsigned long *cursor) { ...@@ -421,9 +421,7 @@ int parseScanCursorOrReply(redisClient *c, robj *o, unsigned long *cursor) {
* In the case of a Hash object the function returns both the field and value * In the case of a Hash object the function returns both the field and value
* of every element on the Hash. */ * of every element on the Hash. */
void scanGenericCommand(redisClient *c, robj *o, unsigned long cursor) { void scanGenericCommand(redisClient *c, robj *o, unsigned long cursor) {
int rv;
int i, j; int i, j;
char buf[REDIS_LONGSTR_SIZE];
list *keys = listCreate(); list *keys = listCreate();
listNode *node, *nextnode; listNode *node, *nextnode;
long count = 10; long count = 10;
...@@ -503,7 +501,7 @@ void scanGenericCommand(redisClient *c, robj *o, unsigned long cursor) { ...@@ -503,7 +501,7 @@ void scanGenericCommand(redisClient *c, robj *o, unsigned long cursor) {
privdata[1] = o; privdata[1] = o;
do { do {
cursor = dictScan(ht, cursor, scanCallback, privdata); cursor = dictScan(ht, cursor, scanCallback, privdata);
} while (cursor && listLength(keys) < count); } while (cursor && listLength(keys) < (unsigned long)count);
} else if (o->type == REDIS_SET) { } else if (o->type == REDIS_SET) {
int pos = 0; int pos = 0;
int64_t ll; int64_t ll;
...@@ -577,9 +575,7 @@ void scanGenericCommand(redisClient *c, robj *o, unsigned long cursor) { ...@@ -577,9 +575,7 @@ void scanGenericCommand(redisClient *c, robj *o, unsigned long cursor) {
/* Step 4: Reply to the client. */ /* Step 4: Reply to the client. */
addReplyMultiBulkLen(c, 2); addReplyMultiBulkLen(c, 2);
rv = snprintf(buf, sizeof(buf), "%lu", cursor); addReplyBulkLongLong(c,cursor);
redisAssert(rv < sizeof(buf));
addReplyBulkCBuffer(c, buf, rv);
addReplyMultiBulkLen(c, listLength(keys)); addReplyMultiBulkLen(c, listLength(keys));
while ((node = listFirst(keys)) != NULL) { while ((node = listFirst(keys)) != NULL) {
...@@ -707,6 +703,7 @@ void moveCommand(redisClient *c) { ...@@ -707,6 +703,7 @@ void moveCommand(redisClient *c) {
robj *o; robj *o;
redisDb *src, *dst; redisDb *src, *dst;
int srcid; int srcid;
long long dbid;
if (server.cluster_enabled) { if (server.cluster_enabled) {
addReplyError(c,"MOVE is not allowed in cluster mode"); addReplyError(c,"MOVE is not allowed in cluster mode");
...@@ -716,7 +713,11 @@ void moveCommand(redisClient *c) { ...@@ -716,7 +713,11 @@ void moveCommand(redisClient *c) {
/* Obtain source and target DB pointers */ /* Obtain source and target DB pointers */
src = c->db; src = c->db;
srcid = c->db->id; srcid = c->db->id;
if (selectDb(c,atoi(c->argv[2]->ptr)) == REDIS_ERR) {
if (getLongLongFromObject(c->argv[2],&dbid) == REDIS_ERR ||
dbid < INT_MIN || dbid > INT_MAX ||
selectDb(c,dbid) == REDIS_ERR)
{
addReply(c,shared.outofrangeerr); addReply(c,shared.outofrangeerr);
return; return;
} }
...@@ -1076,7 +1077,7 @@ int *evalGetKeys(struct redisCommand *cmd, robj **argv, int argc, int *numkeys) ...@@ -1076,7 +1077,7 @@ int *evalGetKeys(struct redisCommand *cmd, robj **argv, int argc, int *numkeys)
* follow in SQL-alike style. Here we parse just the minimum in order to * follow in SQL-alike style. Here we parse just the minimum in order to
* correctly identify keys in the "STORE" option. */ * correctly identify keys in the "STORE" option. */
int *sortGetKeys(struct redisCommand *cmd, robj **argv, int argc, int *numkeys) { int *sortGetKeys(struct redisCommand *cmd, robj **argv, int argc, int *numkeys) {
int i, j, num, *keys; int i, j, num, *keys, found_store = 0;
REDIS_NOTUSED(cmd); REDIS_NOTUSED(cmd);
num = 0; num = 0;
...@@ -1107,12 +1108,13 @@ int *sortGetKeys(struct redisCommand *cmd, robj **argv, int argc, int *numkeys) ...@@ -1107,12 +1108,13 @@ int *sortGetKeys(struct redisCommand *cmd, robj **argv, int argc, int *numkeys)
/* Note: we don't increment "num" here and continue the loop /* Note: we don't increment "num" here and continue the loop
* to be sure to process the *last* "STORE" option if multiple * to be sure to process the *last* "STORE" option if multiple
* ones are provided. This is same behavior as SORT. */ * ones are provided. This is same behavior as SORT. */
found_store = 1;
keys[num] = i+1; /* <store-key> */ keys[num] = i+1; /* <store-key> */
break; break;
} }
} }
} }
*numkeys = num; *numkeys = num + found_store;
return keys; return keys;
} }
......
...@@ -79,12 +79,6 @@ unsigned int dictIntHashFunction(unsigned int key) ...@@ -79,12 +79,6 @@ unsigned int dictIntHashFunction(unsigned int key)
return key; return key;
} }
/* Identity hash function for integer keys */
unsigned int dictIdentityHashFunction(unsigned int key)
{
return key;
}
static uint32_t dict_hash_function_seed = 5381; static uint32_t dict_hash_function_seed = 5381;
void dictSetHashFunctionSeed(uint32_t seed) { void dictSetHashFunctionSeed(uint32_t seed) {
...@@ -668,9 +662,9 @@ dictEntry *dictGetRandomKey(dict *d) ...@@ -668,9 +662,9 @@ dictEntry *dictGetRandomKey(dict *d)
* statistics. However the function is much faster than dictGetRandomKey() * statistics. However the function is much faster than dictGetRandomKey()
* at producing N elements, and the elements are guaranteed to be non * at producing N elements, and the elements are guaranteed to be non
* repeating. */ * repeating. */
int dictGetRandomKeys(dict *d, dictEntry **des, int count) { unsigned int dictGetRandomKeys(dict *d, dictEntry **des, unsigned int count) {
int j; /* internal hash table id, 0 or 1. */ int j; /* internal hash table id, 0 or 1. */
int stored = 0; unsigned int stored = 0;
if (dictSize(d) < count) count = dictSize(d); if (dictSize(d) < count) count = dictSize(d);
while(stored < count) { while(stored < count) {
......
...@@ -142,7 +142,7 @@ typedef void (dictScanFunction)(void *privdata, const dictEntry *de); ...@@ -142,7 +142,7 @@ typedef void (dictScanFunction)(void *privdata, const dictEntry *de);
#define dictGetDoubleVal(he) ((he)->v.d) #define dictGetDoubleVal(he) ((he)->v.d)
#define dictSlots(d) ((d)->ht[0].size+(d)->ht[1].size) #define dictSlots(d) ((d)->ht[0].size+(d)->ht[1].size)
#define dictSize(d) ((d)->ht[0].used+(d)->ht[1].used) #define dictSize(d) ((d)->ht[0].used+(d)->ht[1].used)
#define dictIsRehashing(ht) ((ht)->rehashidx != -1) #define dictIsRehashing(d) ((d)->rehashidx != -1)
/* API */ /* API */
dict *dictCreate(dictType *type, void *privDataPtr); dict *dictCreate(dictType *type, void *privDataPtr);
...@@ -162,7 +162,7 @@ dictIterator *dictGetSafeIterator(dict *d); ...@@ -162,7 +162,7 @@ dictIterator *dictGetSafeIterator(dict *d);
dictEntry *dictNext(dictIterator *iter); dictEntry *dictNext(dictIterator *iter);
void dictReleaseIterator(dictIterator *iter); void dictReleaseIterator(dictIterator *iter);
dictEntry *dictGetRandomKey(dict *d); dictEntry *dictGetRandomKey(dict *d);
int dictGetRandomKeys(dict *d, dictEntry **des, int count); unsigned int dictGetRandomKeys(dict *d, dictEntry **des, unsigned int count);
void dictPrintStats(dict *d); void dictPrintStats(dict *d);
unsigned int dictGenHashFunction(const void *key, int len); unsigned int dictGenHashFunction(const void *key, int len);
unsigned int dictGenCaseHashFunction(const unsigned char *buf, int len); unsigned int dictGenCaseHashFunction(const unsigned char *buf, int len);
......
...@@ -36,6 +36,10 @@ ...@@ -36,6 +36,10 @@
#define _GNU_SOURCE #define _GNU_SOURCE
#endif #endif
#if defined(_AIX)
#define _ALL_SOURCE
#endif
#if defined(__linux__) || defined(__OpenBSD__) #if defined(__linux__) || defined(__OpenBSD__)
#define _XOPEN_SOURCE 700 #define _XOPEN_SOURCE 700
/* /*
......
...@@ -1349,7 +1349,7 @@ void pfmergeCommand(redisClient *c) { ...@@ -1349,7 +1349,7 @@ void pfmergeCommand(redisClient *c) {
* Something that is not easy to test from within the outside. */ * Something that is not easy to test from within the outside. */
#define HLL_TEST_CYCLES 1000 #define HLL_TEST_CYCLES 1000
void pfselftestCommand(redisClient *c) { void pfselftestCommand(redisClient *c) {
int j, i; unsigned int j, i;
sds bitcounters = sdsnewlen(NULL,HLL_DENSE_SIZE); sds bitcounters = sdsnewlen(NULL,HLL_DENSE_SIZE);
struct hllhdr *hdr = (struct hllhdr*) bitcounters, *hdr2; struct hllhdr *hdr = (struct hllhdr*) bitcounters, *hdr2;
robj *o = NULL; robj *o = NULL;
...@@ -1431,7 +1431,7 @@ void pfselftestCommand(redisClient *c) { ...@@ -1431,7 +1431,7 @@ void pfselftestCommand(redisClient *c) {
if (j == 10) maxerr = 1; if (j == 10) maxerr = 1;
if (abserr < 0) abserr = -abserr; if (abserr < 0) abserr = -abserr;
if (abserr > maxerr) { if (abserr > (int64_t)maxerr) {
addReplyErrorFormat(c, addReplyErrorFormat(c,
"TESTFAILED Too big error. card:%llu abserr:%llu", "TESTFAILED Too big error. card:%llu abserr:%llu",
(unsigned long long) checkpoint, (unsigned long long) checkpoint,
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment