summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYossi Gottlieb <yossigo@gmail.com>2013-01-15 09:08:14 +0200
committerYossi Gottlieb <yossigo@gmail.com>2013-01-15 09:25:23 +0200
commitd195e8bb8225bae62b8a714b9c02a472bc601e2f (patch)
treeae7c709630eae475dcf276c505a1011c38756e18
parent142a8099cb36d194ed92d79b7b116a8c505da8c4 (diff)
parent78b175a241a4f86a427862acb71d1a2840e75671 (diff)
downloadredis-2.6.8-1.tar.gz
Merge upstream Redis 2.6.8.2.6.8-1
-rw-r--r--00-RELEASENOTES11
-rw-r--r--CONTRIBUTING3
-rw-r--r--deps/hiredis/adapters/ae.h30
-rw-r--r--deps/hiredis/adapters/libev.h30
-rw-r--r--deps/hiredis/adapters/libevent.h30
-rw-r--r--deps/hiredis/fmacros.h2
-rw-r--r--src/ae.c6
-rw-r--r--src/config.h17
-rw-r--r--src/endianconv.h1
-rw-r--r--src/fmacros.h2
-rw-r--r--src/networking.c4
-rw-r--r--src/redis-benchmark.c2
-rw-r--r--src/redis-cli.c2
-rwxr-xr-xsrc/redis.c5
-rwxr-xr-xsrc/replication.c4
-rwxr-xr-xsrc/scripting.c41
-rw-r--r--src/version.h2
-rw-r--r--tests/unit/scripting.tcl34
18 files changed, 186 insertions, 40 deletions
diff --git a/00-RELEASENOTES b/00-RELEASENOTES
index e6dd01d4c..5471baa3f 100644
--- a/00-RELEASENOTES
+++ b/00-RELEASENOTES
@@ -14,6 +14,17 @@ HIGH: There is a critical bug that may affect a subset of users. Upgrade!
CRITICAL: There is a critical bug affecting MOST USERS. Upgrade ASAP.
--------------------------------------------------------------------------------
+--[ Redis 2.6.8 ]
+
+UPGRADE URGENCY: MODERATE if you use Lua scripting. Otherwise LOW.
+
+* [BUGFIX] Multiple fixes for EVAL (issue #872).
+* [BUGFIX] Fix overflow in mstime() in redis-cli and benchmark.
+* [BUGFIX] Fix Linux / PPC64 behavior by correcting endianess detection.
+* [BUGFIX] Fix NetBSD build by defining _XOPEN_SOURCE appropriately.
+* [BUGFIX] Added missing license and copyright in a few places.
+* [BUGFIX] Better error reporting when fd event creation fails.
+
--[ Redis 2.6.7 ]
UPGRADE URGENCY: MODERATE (unless you BLPOP using the same key multiple times).
diff --git a/CONTRIBUTING b/CONTRIBUTING
index 17078749d..06e1e9660 100644
--- a/CONTRIBUTING
+++ b/CONTRIBUTING
@@ -2,7 +2,8 @@ Note: by contributing code to the Redis project in any form, including sending
a pull request via Github, a code fragment or patch via private email or
public discussion groups, you agree to release your code under the terms
of the BSD license that you can find in the COPYING file included in the Redis
-source distribution.
+source distribution. You will include BSD license in the COPYING file within
+each source file that you contribute.
# IMPORTANT: HOW TO USE REDIS GITHUB ISSUES
diff --git a/deps/hiredis/adapters/ae.h b/deps/hiredis/adapters/ae.h
index 65235f802..5c551c2ed 100644
--- a/deps/hiredis/adapters/ae.h
+++ b/deps/hiredis/adapters/ae.h
@@ -1,3 +1,33 @@
+/*
+ * Copyright (c) 2010-2011, Pieter Noordhuis <pcnoordhuis at gmail dot com>
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Redis nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
#ifndef __HIREDIS_AE_H__
#define __HIREDIS_AE_H__
#include <sys/types.h>
diff --git a/deps/hiredis/adapters/libev.h b/deps/hiredis/adapters/libev.h
index 534d74360..2bf8d521f 100644
--- a/deps/hiredis/adapters/libev.h
+++ b/deps/hiredis/adapters/libev.h
@@ -1,3 +1,33 @@
+/*
+ * Copyright (c) 2010-2011, Pieter Noordhuis <pcnoordhuis at gmail dot com>
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Redis nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
#ifndef __HIREDIS_LIBEV_H__
#define __HIREDIS_LIBEV_H__
#include <stdlib.h>
diff --git a/deps/hiredis/adapters/libevent.h b/deps/hiredis/adapters/libevent.h
index 4055ec0f1..1c2b271bb 100644
--- a/deps/hiredis/adapters/libevent.h
+++ b/deps/hiredis/adapters/libevent.h
@@ -1,3 +1,33 @@
+/*
+ * Copyright (c) 2010-2011, Pieter Noordhuis <pcnoordhuis at gmail dot com>
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Redis nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
#ifndef __HIREDIS_LIBEVENT_H__
#define __HIREDIS_LIBEVENT_H__
#include <event.h>
diff --git a/deps/hiredis/fmacros.h b/deps/hiredis/fmacros.h
index 21cd9cfee..96324eb49 100644
--- a/deps/hiredis/fmacros.h
+++ b/deps/hiredis/fmacros.h
@@ -7,7 +7,7 @@
#if defined(__sun__)
#define _POSIX_C_SOURCE 200112L
-#elif defined(__linux__)
+#elif defined(__linux__) || defined(__OpenBSD__) || defined(__NetBSD__)
#define _XOPEN_SOURCE 600
#else
#define _XOPEN_SOURCE
diff --git a/src/ae.c b/src/ae.c
index d2faed326..90be4e28f 100644
--- a/src/ae.c
+++ b/src/ae.c
@@ -38,6 +38,7 @@
#include <poll.h>
#include <string.h>
#include <time.h>
+#include <errno.h>
#include "ae.h"
#include "zmalloc.h"
@@ -104,7 +105,10 @@ void aeStop(aeEventLoop *eventLoop) {
int aeCreateFileEvent(aeEventLoop *eventLoop, int fd, int mask,
aeFileProc *proc, void *clientData)
{
- if (fd >= eventLoop->setsize) return AE_ERR;
+ if (fd >= eventLoop->setsize) {
+ errno = ERANGE;
+ return AE_ERR;
+ }
aeFileEvent *fe = &eventLoop->events[fd];
if (aeApiAddEvent(eventLoop, fd, mask) == -1)
diff --git a/src/config.h b/src/config.h
index db33407c5..b5c8284a0 100644
--- a/src/config.h
+++ b/src/config.h
@@ -137,13 +137,27 @@
#endif /* BSD */
#endif /* BYTE_ORDER */
-#if defined(__BYTE_ORDER) && !defined(BYTE_ORDER)
+/* Sometimes after including an OS-specific header that defines the
+ * endianess we end with __BYTE_ORDER but not with BYTE_ORDER that is what
+ * the Redis code uses. In this case let's define everything without the
+ * underscores. */
+#ifndef BYTE_ORDER
+#ifdef __BYTE_ORDER
+#if defined(__LITTLE_ENDIAN) && defined(__BIG_ENDIAN)
+#ifndef LITTLE_ENDIAN
+#define LITTLE_ENDIAN __LITTLE_ENDIAN
+#endif
+#ifndef BIG_ENDIAN
+#define BIG_ENDIAN __BIG_ENDIAN
+#endif
#if (__BYTE_ORDER == __LITTLE_ENDIAN)
#define BYTE_ORDER LITTLE_ENDIAN
#else
#define BYTE_ORDER BIG_ENDIAN
#endif
#endif
+#endif
+#endif
#if !defined(BYTE_ORDER) || \
(BYTE_ORDER != BIG_ENDIAN && BYTE_ORDER != LITTLE_ENDIAN)
@@ -162,5 +176,4 @@
#endif
#endif
-
#endif
diff --git a/src/endianconv.h b/src/endianconv.h
index f76e0e6b3..7afe61c62 100644
--- a/src/endianconv.h
+++ b/src/endianconv.h
@@ -33,6 +33,7 @@
#ifndef __ENDIANCONV_H
#define __ENDIANCONV_H
+#include "config.h"
#include <stdint.h>
void memrev16(void *p);
diff --git a/src/fmacros.h b/src/fmacros.h
index 6f3c4b4e8..a6cf3578c 100644
--- a/src/fmacros.h
+++ b/src/fmacros.h
@@ -36,7 +36,7 @@
#define _GNU_SOURCE
#endif
-#if defined(__linux__) || defined(__OpenBSD__)
+#if defined(__linux__) || defined(__OpenBSD__) || defined(__NetBSD__)
#define _XOPEN_SOURCE 700
#else
#define _XOPEN_SOURCE
diff --git a/src/networking.c b/src/networking.c
index 4365bc8ef..c23939c5c 100644
--- a/src/networking.c
+++ b/src/networking.c
@@ -517,7 +517,9 @@ void copyClientOutputBuffer(redisClient *dst, redisClient *src) {
static void acceptCommonHandler(int fd, int flags) {
redisClient *c;
if ((c = createClient(fd)) == NULL) {
- redisLog(REDIS_WARNING,"Error allocating resources for the client");
+ redisLog(REDIS_WARNING,
+ "Error registering fd event for the new client: %s (fd=%d)",
+ strerror(errno),fd);
close(fd); /* May be already closed, just ignore errors */
return;
}
diff --git a/src/redis-benchmark.c b/src/redis-benchmark.c
index 8d72573d5..ceab70723 100644
--- a/src/redis-benchmark.c
+++ b/src/redis-benchmark.c
@@ -106,7 +106,7 @@ static long long mstime(void) {
long long mst;
gettimeofday(&tv, NULL);
- mst = ((long)tv.tv_sec)*1000;
+ mst = ((long long)tv.tv_sec)*1000;
mst += tv.tv_usec/1000;
return mst;
}
diff --git a/src/redis-cli.c b/src/redis-cli.c
index e8c6be5e0..3969fbab5 100644
--- a/src/redis-cli.c
+++ b/src/redis-cli.c
@@ -95,7 +95,7 @@ static long long mstime(void) {
long long mst;
gettimeofday(&tv, NULL);
- mst = ((long)tv.tv_sec)*1000;
+ mst = ((long long)tv.tv_sec)*1000;
mst += tv.tv_usec/1000;
return mst;
}
diff --git a/src/redis.c b/src/redis.c
index e6731ba8b..04289db23 100755
--- a/src/redis.c
+++ b/src/redis.c
@@ -1655,8 +1655,9 @@ void call(redisClient *c, int flags) {
if (flags != REDIS_PROPAGATE_NONE)
propagate(c->cmd,c->db->id,c->argv,c->argc,flags);
}
- /* Commands such as LPUSH or BRPOPLPUSH may propagate an additional
- * PUSH command. */
+
+ /* Handle the alsoPropagate() API to handle commands that want to propagate
+ * multiple separated commands. */
if (server.also_propagate.numops) {
int j;
redisOp *rop;
diff --git a/src/replication.c b/src/replication.c
index 9e2aed268..0a4321095 100755
--- a/src/replication.c
+++ b/src/replication.c
@@ -758,7 +758,9 @@ void syncWithMaster(aeEventLoop *el, int fd, void *privdata, int mask) {
if (aeCreateFileEvent(server.el,fd, AE_READABLE,readSyncBulkPayload,NULL)
== AE_ERR)
{
- redisLog(REDIS_WARNING,"Can't create readable event for SYNC");
+ redisLog(REDIS_WARNING,
+ "Can't create readable event for SYNC: %s (fd=%d)",
+ strerror(errno),fd);
goto error;
}
diff --git a/src/scripting.c b/src/scripting.c
index b8d3f519c..e3f810815 100755
--- a/src/scripting.c
+++ b/src/scripting.c
@@ -791,7 +791,7 @@ void evalGenericCommand(redisClient *c, int evalsha) {
lua_State *lua = server.lua;
char funcname[43];
long long numkeys;
- int delhook = 0;
+ int delhook = 0, err;
/* We want the same PRNG sequence at every call so that our PRNG is
* not affected by external state. */
@@ -873,30 +873,31 @@ void evalGenericCommand(redisClient *c, int evalsha) {
/* At this point whatever this script was never seen before or if it was
* already defined, we can call it. We have zero arguments and expect
* a single return value. */
- if (lua_pcall(lua,0,1,0)) {
- if (delhook) lua_sethook(lua,luaMaskCountHook,0,0); /* Disable hook */
- if (server.lua_timedout) {
- server.lua_timedout = 0;
- /* Restore the readable handler that was unregistered when the
- * script timeout was detected. */
- aeCreateFileEvent(server.el,c->fd,AE_READABLE,
- readQueryFromClient,c);
- }
- server.lua_caller = NULL;
- selectDb(c,server.lua_client->db->id); /* set DB ID from Lua client */
- addReplyErrorFormat(c,"Error running script (call to %s): %s\n",
- funcname, lua_tostring(lua,-1));
- lua_pop(lua,1);
- lua_gc(lua,LUA_GCCOLLECT,0);
- return;
- }
+ err = lua_pcall(lua,0,1,0);
+
+ /* Perform some cleanup that we need to do both on error and success. */
if (delhook) lua_sethook(lua,luaMaskCountHook,0,0); /* Disable hook */
- server.lua_timedout = 0;
+ if (server.lua_timedout) {
+ server.lua_timedout = 0;
+ /* Restore the readable handler that was unregistered when the
+ * script timeout was detected. */
+ aeCreateFileEvent(server.el,c->fd,AE_READABLE,
+ readQueryFromClient,c);
+ }
server.lua_caller = NULL;
selectDb(c,server.lua_client->db->id); /* set DB ID from Lua client */
- luaReplyToRedisReply(c,lua);
lua_gc(lua,LUA_GCSTEP,1);
+ if (err) {
+ addReplyErrorFormat(c,"Error running script (call to %s): %s\n",
+ funcname, lua_tostring(lua,-1));
+ lua_pop(lua,1); /* Consume the Lua reply. */
+ } else {
+ /* On success convert the Lua return value into Redis protocol, and
+ * send it to * the client. */
+ luaReplyToRedisReply(c,lua);
+ }
+
/* If we have slaves attached we want to replicate this command as
* EVAL instead of EVALSHA. We do this also in the AOF as currently there
* is no easy way to propagate a command in a different way in the AOF
diff --git a/src/version.h b/src/version.h
index 32b61ccbc..c0881950f 100644
--- a/src/version.h
+++ b/src/version.h
@@ -1 +1 @@
-#define REDIS_VERSION "2.6.7"
+#define REDIS_VERSION "2.6.8"
diff --git a/tests/unit/scripting.tcl b/tests/unit/scripting.tcl
index 953807cb3..4333fb64e 100644
--- a/tests/unit/scripting.tcl
+++ b/tests/unit/scripting.tcl
@@ -297,6 +297,12 @@ start_server {tags {"scripting"}} {
assert_equal [r ping] "PONG"
}
+ test {Timedout script link is still usable after Lua returns} {
+ r config set lua-time-limit 10
+ r eval {for i=1,100000 do redis.call('ping') end return 'ok'} 0
+ r ping
+ } {PONG}
+
test {Timedout scripts that modified data can't be killed by SCRIPT KILL} {
set rd [redis_deferring_client]
r config set lua-time-limit 10
@@ -310,6 +316,8 @@ start_server {tags {"scripting"}} {
assert_match {BUSY*} $e
}
+ # Note: keep this test at the end of this server stanza because it
+ # kills the server.
test {SHUTDOWN NOSAVE can kill a timedout script anyway} {
# The server sould be still unresponding to normal commands.
catch {r ping} e
@@ -323,9 +331,16 @@ start_server {tags {"scripting"}} {
start_server {tags {"scripting repl"}} {
start_server {} {
- test {Before the slave connects we issue an EVAL command} {
+ test {Before the slave connects we issue two EVAL commands} {
+ # One with an error, but still executing a command.
+ # SHA is: 6e8bd6bdccbe78899e3cc06b31b6dbf4324c2e56
+ catch {
+ r eval {redis.call('incr','x'); redis.call('nonexisting')} 0
+ }
+ # One command is correct:
+ # SHA is: ae3477e27be955de7e1bc9adfdca626b478d3cb2
r eval {return redis.call('incr','x')} 0
- } {1}
+ } {2}
test {Connect a slave to the main instance} {
r -1 slaveof [srv 0 host] [srv 0 port]
@@ -337,15 +352,20 @@ start_server {tags {"scripting repl"}} {
}
}
- test {Now use EVALSHA against the master} {
+ test {Now use EVALSHA against the master, with both SHAs} {
+ # The server should replicate successful and unsuccessful
+ # commands as EVAL instead of EVALSHA.
+ catch {
+ r evalsha 6e8bd6bdccbe78899e3cc06b31b6dbf4324c2e56 0
+ }
r evalsha ae3477e27be955de7e1bc9adfdca626b478d3cb2 0
- } {2}
+ } {4}
- test {If EVALSHA was replicated as EVAL the slave should be ok} {
+ test {If EVALSHA was replicated as EVAL, 'x' should be '4'} {
wait_for_condition 50 100 {
- [r -1 get x] eq {2}
+ [r -1 get x] eq {4}
} else {
- fail "Expected 2 in x, but value is '[r -1 get x]'"
+ fail "Expected 4 in x, but value is '[r -1 get x]'"
}
}