summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorantirez <antirez@gmail.com>2011-05-07 12:10:47 +0200
committerantirez <antirez@gmail.com>2011-05-07 12:10:47 +0200
commit3554f09ddc44d1722c2f3687f006c0e3ff8d5f2c (patch)
treeb5bf0567ec0d6c22b195f73ea5f05be048d35394
parentccab83e729673021ed930e874c3da7401ddeb36a (diff)
parent97ddfbbfc3b1f7710e4a60989cf22519d7e50181 (diff)
downloadredis-3554f09ddc44d1722c2f3687f006c0e3ff8d5f2c.tar.gz
Merge branch '2.2' of github.com:antirez/redis into 2.2
-rw-r--r--00-RELEASENOTES9
-rw-r--r--src/networking.c14
-rw-r--r--src/version.h2
-rw-r--r--src/ziplist.c65
4 files changed, 54 insertions, 36 deletions
diff --git a/00-RELEASENOTES b/00-RELEASENOTES
index 59d8741c9..145629bc7 100644
--- a/00-RELEASENOTES
+++ b/00-RELEASENOTES
@@ -12,6 +12,15 @@ for 2.0.
CHANGELOG
---------
+What's new in Redis 2.2.6
+=========================
+
+* Fixed bug #543. If you saw Redis instances crashing on List operations
+ (only happening with a non-default max entry size ziplist setting in
+ redis.conf) it was almost certainly this problem.
+* Fixed a bug with replication where SLAVEOF NO ONE caused a slave to close the
+ connection with all its slaves.
+
What's new in Redis 2.2.5
=========================
diff --git a/src/networking.c b/src/networking.c
index 4f7c24064..9c250cdd6 100644
--- a/src/networking.c
+++ b/src/networking.c
@@ -523,10 +523,16 @@ void freeClient(redisClient *c) {
* close the connection with all our slaves if we have any, so
* when we'll resync with the master the other slaves will sync again
* with us as well. Note that also when the slave is not connected
- * to the master it will keep refusing connections by other slaves. */
- while (listLength(server.slaves)) {
- ln = listFirst(server.slaves);
- freeClient((redisClient*)ln->value);
+ * to the master it will keep refusing connections by other slaves.
+ *
+ * We do this only if server.masterhost != NULL. If it is NULL this
+ * means the user called SLAVEOF NO ONE and we are freeing our
+ * link with the master, so no need to close link with slaves. */
+ if (server.masterhost != NULL) {
+ while (listLength(server.slaves)) {
+ ln = listFirst(server.slaves);
+ freeClient((redisClient*)ln->value);
+ }
}
}
/* Release memory */
diff --git a/src/version.h b/src/version.h
index be662ce39..e48fe137f 100644
--- a/src/version.h
+++ b/src/version.h
@@ -1 +1 @@
-#define REDIS_VERSION "2.2.5"
+#define REDIS_VERSION "2.2.6"
diff --git a/src/ziplist.c b/src/ziplist.c
index 233fabefe..974428aa2 100644
--- a/src/ziplist.c
+++ b/src/ziplist.c
@@ -398,12 +398,17 @@ static unsigned char *__ziplistCascadeUpdate(unsigned char *zl, unsigned char *p
offset = p-zl;
extra = rawlensize-next.prevrawlensize;
zl = ziplistResize(zl,curlen+extra);
- ZIPLIST_TAIL_OFFSET(zl) += extra;
p = zl+offset;
- /* Move the tail to the back. */
+ /* Current pointer and offset for next element. */
np = p+rawlen;
noffset = np-zl;
+
+ /* Update tail offset when next element is not the tail element. */
+ if ((zl+ZIPLIST_TAIL_OFFSET(zl)) != np)
+ ZIPLIST_TAIL_OFFSET(zl) += extra;
+
+ /* Move the tail to the back. */
memmove(np+rawlensize,
np+next.prevrawlensize,
curlen-noffset-next.prevrawlensize-1);
@@ -877,7 +882,7 @@ void pop(unsigned char *zl, int where) {
}
}
-void randstring(char *target, unsigned int min, unsigned int max) {
+int randstring(char *target, unsigned int min, unsigned int max) {
int p, len = min+rand()%(max-min+1);
int minval, maxval;
switch(rand() % 3) {
@@ -899,10 +904,9 @@ void randstring(char *target, unsigned int min, unsigned int max) {
while(p < len)
target[p++] = minval+rand()%(maxval-minval+1);
- return;
+ return len;
}
-
int main(int argc, char **argv) {
unsigned char *zl, *p;
unsigned char *entry;
@@ -1235,6 +1239,7 @@ int main(int argc, char **argv) {
int i,j,len,where;
unsigned char *p;
char buf[1024];
+ int buflen;
list *ref;
listNode *refnode;
@@ -1243,10 +1248,6 @@ int main(int argc, char **argv) {
unsigned int slen;
long long sval;
- /* In the regression for the cascade bug, it was triggered
- * with a random seed of 2. */
- srand(2);
-
for (i = 0; i < 20000; i++) {
zl = ziplistNew();
ref = listCreate();
@@ -1256,31 +1257,32 @@ int main(int argc, char **argv) {
/* Create lists */
for (j = 0; j < len; j++) {
where = (rand() & 1) ? ZIPLIST_HEAD : ZIPLIST_TAIL;
- switch(rand() % 4) {
- case 0:
- sprintf(buf,"%lld",(0LL + rand()) >> 20);
- break;
- case 1:
- sprintf(buf,"%lld",(0LL + rand()));
- break;
- case 2:
- sprintf(buf,"%lld",(0LL + rand()) << 20);
- break;
- case 3:
- randstring(buf,0,256);
- break;
- default:
- assert(NULL);
+ if (rand() % 2) {
+ buflen = randstring(buf,1,sizeof(buf)-1);
+ } else {
+ switch(rand() % 3) {
+ case 0:
+ buflen = sprintf(buf,"%lld",(0LL + rand()) >> 20);
+ break;
+ case 1:
+ buflen = sprintf(buf,"%lld",(0LL + rand()));
+ break;
+ case 2:
+ buflen = sprintf(buf,"%lld",(0LL + rand()) << 20);
+ break;
+ default:
+ assert(NULL);
+ }
}
/* Add to ziplist */
- zl = ziplistPush(zl, (unsigned char*)buf, strlen(buf), where);
+ zl = ziplistPush(zl, (unsigned char*)buf, buflen, where);
/* Add to reference list */
if (where == ZIPLIST_HEAD) {
- listAddNodeHead(ref,sdsnew(buf));
+ listAddNodeHead(ref,sdsnewlen(buf, buflen));
} else if (where == ZIPLIST_TAIL) {
- listAddNodeTail(ref,sdsnew(buf));
+ listAddNodeTail(ref,sdsnewlen(buf, buflen));
} else {
assert(NULL);
}
@@ -1295,12 +1297,13 @@ int main(int argc, char **argv) {
assert(ziplistGet(p,&sstr,&slen,&sval));
if (sstr == NULL) {
- sprintf(buf,"%lld",sval);
+ buflen = sprintf(buf,"%lld",sval);
} else {
- memcpy(buf,sstr,slen);
- buf[slen] = '\0';
+ buflen = slen;
+ memcpy(buf,sstr,buflen);
+ buf[buflen] = '\0';
}
- assert(strcmp(buf,listNodeValue(refnode)) == 0);
+ assert(memcmp(buf,listNodeValue(refnode),buflen) == 0);
}
zfree(zl);
listRelease(ref);