Commit Graph

6347 Commits

Author SHA1 Message Date
sunhe
949a274817 bitops.c/bitfieldCommand: update higest_write_offset with check 2016-10-22 01:54:46 +08:00
antirez
f39e7d4d7e Remove "Hey!" warning... 2016-10-19 10:43:40 +02:00
antirez
a9f50a389b Better target MacOS on __atomic macros conditional compilation. 2016-10-17 16:41:39 +02:00
Salvatore Sanfilippo
ea95262d8d Merge pull request #3560 from melo/fix-macos-10-8-compile
Fixes compilation on MacOS 10.8.5, Clang tags/Apple/clang-421.0.57
2016-10-17 16:11:00 +02:00
Pedro Melo
2000abc86f Fixes compilation on MacOS 10.8.5, Clang tags/Apple/clang-421.0.57
Redis fails to compile on MacOS 10.8.5 with Clang 4, version 421.0.57
(based on LLVM 3.1svn).

When compiling zmalloc.c, we get these warnings:

        CC zmalloc.o
    zmalloc.c:109:5: warning: implicit declaration of function '__atomic_add_fetch' is invalid in C99 [-Wimplicit-function-declaration]
        update_zmalloc_stat_alloc(zmalloc_size(ptr));
        ^
    zmalloc.c:75:9: note: expanded from macro 'update_zmalloc_stat_alloc'
            atomicIncr(used_memory,__n,used_memory_mutex); \
            ^
    ./atomicvar.h:57:37: note: expanded from macro 'atomicIncr'
    #define atomicIncr(var,count,mutex) __atomic_add_fetch(&var,(count),__ATOMIC_RELAXED)
                                        ^
    zmalloc.c:145:5: warning: implicit declaration of function '__atomic_sub_fetch' is invalid in C99 [-Wimplicit-function-declaration]
        update_zmalloc_stat_free(oldsize);
        ^
    zmalloc.c:85:9: note: expanded from macro 'update_zmalloc_stat_free'
            atomicDecr(used_memory,__n,used_memory_mutex); \
            ^
    ./atomicvar.h:58:37: note: expanded from macro 'atomicDecr'
    #define atomicDecr(var,count,mutex) __atomic_sub_fetch(&var,(count),__ATOMIC_RELAXED)
                                        ^
    zmalloc.c:205:9: warning: implicit declaration of function '__atomic_load_n' is invalid in C99 [-Wimplicit-function-declaration]
            atomicGet(used_memory,um,used_memory_mutex);
            ^
    ./atomicvar.h:60:14: note: expanded from macro 'atomicGet'
        dstvar = __atomic_load_n(&var,__ATOMIC_RELAXED); \
                 ^
    3 warnings generated.

Also on lazyfree.c:

        CC lazyfree.o
    lazyfree.c:68:13: warning: implicit declaration of function '__atomic_add_fetch' is invalid in C99 [-Wimplicit-function-declaration]
                atomicIncr(lazyfree_objects,1,lazyfree_objects_mutex);
                ^
    ./atomicvar.h:57:37: note: expanded from macro 'atomicIncr'
    #define atomicIncr(var,count,mutex) __atomic_add_fetch(&var,(count),__ATOMIC_RELAXED)
                                        ^
    lazyfree.c:111:5: warning: implicit declaration of function '__atomic_sub_fetch' is invalid in C99 [-Wimplicit-function-declaration]
        atomicDecr(lazyfree_objects,1,lazyfree_objects_mutex);
        ^
    ./atomicvar.h:58:37: note: expanded from macro 'atomicDecr'
    #define atomicDecr(var,count,mutex) __atomic_sub_fetch(&var,(count),__ATOMIC_RELAXED)
                                        ^
    2 warnings generated.

Then in the linking stage:

        LINK redis-server
    Undefined symbols for architecture x86_64:
      "___atomic_add_fetch", referenced from:
          _zmalloc in zmalloc.o
          _zcalloc in zmalloc.o
          _zrealloc in zmalloc.o
          _dbAsyncDelete in lazyfree.o
          _emptyDbAsync in lazyfree.o
          _slotToKeyFlushAsync in lazyfree.o
      "___atomic_load_n", referenced from:
          _zmalloc_used_memory in zmalloc.o
          _zmalloc_get_fragmentation_ratio in zmalloc.o
      "___atomic_sub_fetch", referenced from:
          _zrealloc in zmalloc.o
          _zfree in zmalloc.o
          _lazyfreeFreeObjectFromBioThread in lazyfree.o
          _lazyfreeFreeDatabaseFromBioThread in lazyfree.o
          _lazyfreeFreeSlotsMapFromBioThread in lazyfree.o
    ld: symbol(s) not found for architecture x86_64
    clang: error: linker command failed with exit code 1 (use -v to see invocation)
    make[1]: *** [redis-server] Error 1
    make: *** [all] Error 2

With this patch, the compilation is sucessful, no warnings.

Running `make test` we get a almost clean bill of health. Test pass with
one exception:

    [err]: Check for memory leaks (pid 52793) in tests/unit/dump.tcl
    [err]: Check for memory leaks (pid 53103) in tests/unit/auth.tcl
    [err]: Check for memory leaks (pid 53117) in tests/unit/auth.tcl
    [err]: Check for memory leaks (pid 53131) in tests/unit/protocol.tcl
    [err]: Check for memory leaks (pid 53145) in tests/unit/protocol.tcl
    [ok]: Check for memory leaks (pid 53160)
    [err]: Check for memory leaks (pid 53175) in tests/unit/scan.tcl
    [ok]: Check for memory leaks (pid 53189)
    [err]: Check for memory leaks (pid 53221) in tests/unit/type/incr.tcl
    .
    .
    .

Full debug log (289MB, uncompressed) available at
https://dl.dropboxusercontent.com/u/75548/logs/redis-debug-log-macos-10.8.5.log.xz

Most if not all of the memory leak tests fail. Not sure if this is
related. They are the only ones that fail. I belive they are not related,
but just the memory leak detector is not working properly on 10.8.5.

Signed-off-by: Pedro Melo <melo@simplicidade.org>
2016-10-17 14:58:23 +01:00
antirez
f633212073 Fix SELECT test, broken cause change in error msg. 2016-10-14 15:48:11 +02:00
antirez
c7a4e694ad SWAPDB command.
This new command swaps two Redis databases, so that immediately all the
clients connected to a given DB will see the data of the other DB, and
the other way around. Example:

    SWAPDB 0 1

This will swap DB 0 with DB 1. All the clients connected with DB 0 will
immediately see the new data, exactly like all the clients connected
with DB 1 will see the data that was formerly of DB 0.

MOTIVATION AND HISTORY
---

The command was recently demanded by Pedro Melo, but was suggested in
the past multiple times, and always refused by me.

The reason why it was asked: Imagine you have clients operating in DB 0.
At the same time, you create a new version of the dataset in DB 1.
When the new version of the dataset is available, you immediately want
to swap the two views, so that the clients will transparently use the
new version of the data. At the same time you'll likely destroy the
DB 1 dataset (that contains the old data) and start to build a new
version, to repeat the process.

This is an interesting pattern, but the reason why I always opposed to
implement this, was that FLUSHDB was a blocking command in Redis before
Redis 4.0 improvements. Now we have FLUSHDB ASYNC that releases the
old data in O(1) from the point of view of the client, to reclaim memory
incrementally in a different thread.

At this point, the pattern can really be supported without latency
spikes, so I'm providing this implementation for the users to comment.
In case a very compelling argument will be made against this new command
it may be removed.

BEHAVIOR WITH BLOCKING OPERATIONS
---

If a client is blocking for a list in a given DB, after the swap it will
still be blocked in the same DB ID, since this is the most logical thing
to do: if I was blocked for a list push to list "foo", even after the
swap I want still a LPUSH to reach the key "foo" in the same DB in order
to unblock.

However an interesting thing happens when a client is, for instance,
blocked waiting for new elements in list "foo" of DB 0. Then the DB
0 and 1 are swapped with SWAPDB. However the DB 1 happened to have
a list called "foo" containing elements. When this happens, this
implementation can correctly unblock the client.

It is possible that there are subtle corner cases that are not covered
in the implementation, but since the command is self-contained from the
POV of the implementation and the Redis core, it cannot cause anything
bad if not used.

Tests and documentation are yet to be provided.
2016-10-14 15:28:04 +02:00
antirez
a3b3ca7c21 Modules: use RedisModule_AbortBlock() in the example. 2016-10-13 17:00:45 +02:00
antirez
95c17c0cb2 Modules: AbortBlock() API implemented. 2016-10-13 16:57:40 +02:00
antirez
58601c8f7d Modules: blocking API documented. 2016-10-13 16:57:28 +02:00
antirez
553aa0e259 module.c: trim comment to 80 cols. 2016-10-13 12:48:36 +02:00
antirez
870274bea8 Example modules: remove warnings about types and not used args. 2016-10-13 12:43:18 +02:00
jybaek
c76b9b644c Remove Duplicate Processing 2016-10-13 15:17:07 +09:00
yyoshiki41
16f65068b0 Refactor redis-trib.rb 2016-10-10 01:13:20 +09:00
antirez
7dde8bf3ab Modules: blocking command example added. 2016-10-07 16:35:06 +02:00
antirez
34599691b3 Modules: fixes to the blocking commands API: examples now works. 2016-10-07 16:34:40 +02:00
antirez
f156038db8 Modules: RM_Milliseconds() API added. 2016-10-07 16:34:19 +02:00
antirez
ffb00fbcbe Modules: blocking commands WIP: API exported, a first example. 2016-10-07 13:48:14 +02:00
antirez
3aa816e61a Modules: introduce warning suppression macro for unused args. 2016-10-07 13:10:31 +02:00
antirez
3879923db8 Enable warning in example modules Makefile. 2016-10-07 13:07:13 +02:00
antirez
8fadfe52a2 Module: API to block clients with threading support.
Just a draft to align the main ideas, never executed code. Compiles.
2016-10-07 11:55:35 +02:00
antirez
a5998d1fda Fix typos in GetContextFromIO API declaration. 2016-10-06 18:26:04 +02:00
antirez
799208de85 Fix name of mispelled function. 2016-10-06 17:10:47 +02:00
antirez
152c1b6802 Module: Ability to get context from IO context.
It was noted by @dvirsky that it is not possible to use string functions
when writing the AOF file. This sometimes is critical since the command
rewriting may need to be built in the context of the AOF callback, and
without access to the context, and the limited types that the AOF
production functions will accept, this can be an issue.

Moreover there are other needs that we can't anticipate regarding the
ability to use Redis Modules APIs using the context in order to build
representations to emit AOF / RDB.

Because of this a new API was added that allows the user to get a
temporary context from the IO context. The context is auto released
if obtained when the RDB / AOF callback returns.

Calling multiple time the function to get the context, always returns
the same one, since it is invalid to have more than a single context.
2016-10-06 17:09:26 +02:00
antirez
72279e3ea4 Copyright notice added to module.c. 2016-10-06 08:48:21 +02:00
antirez
3dc84c5300 Modules: API to save/load single precision floating point numbers.
When double precision is not needed, to take 2x space in the
serialization is not good.
2016-10-03 00:08:35 +02:00
antirez
a1b1fd4f39 Modules: API to log from module I/O callbacks. 2016-10-02 16:51:37 +02:00
antirez
4674efdee2 Merge branch 'unstable' of github.com:/antirez/redis into unstable 2016-10-02 16:50:37 +02:00
antirez
0d9febf6a0 Add compiler optimizations to example module makefile. 2016-10-02 11:01:36 +02:00
antirez
6782e774f1 debug.c: include dlfcn.h regardless of BACKTRACE support. 2016-09-27 00:29:47 +02:00
antirez
2564031a15 Merge branch 'unstable' of github.com:/antirez/redis into unstable 2016-09-26 09:10:52 +02:00
antirez
6d9f8e2462 Security: CONFIG SET client-output-buffer-limit overflow fixed.
This commit fixes a vunlerability reported by Cory Duplantis
of Cisco Talos, see TALOS-2016-0206 for reference.

CONFIG SET client-output-buffer-limit accepts as client class "master"
which is actually only used to implement CLIENT KILL. The "master" class
has ID 3. What happens is that the global structure:

    server.client_obuf_limits[class]

Is accessed with class = 3. However it is a 3 elements array, so writing
the 4th element means to write up to 24 bytes of memory *after* the end
of the array, since the structure is defined as:

    typedef struct clientBufferLimitsConfig {
        unsigned long long hard_limit_bytes;
        unsigned long long soft_limit_bytes;
        time_t soft_limit_seconds;
    } clientBufferLimitsConfig;

EVALUATION OF IMPACT:

Checking what's past the boundaries of the array in the global
'server' structure, we find AOF state fields:

    clientBufferLimitsConfig client_obuf_limits[CLIENT_TYPE_OBUF_COUNT];
    /* AOF persistence */
    int aof_state;                  /* AOF_(ON|OFF|WAIT_REWRITE) */
    int aof_fsync;                  /* Kind of fsync() policy */
    char *aof_filename;             /* Name of the AOF file */
    int aof_no_fsync_on_rewrite;    /* Don't fsync if a rewrite is in prog. */
    int aof_rewrite_perc;           /* Rewrite AOF if % growth is > M and... */
    off_t aof_rewrite_min_size;     /* the AOF file is at least N bytes. */
    off_t aof_rewrite_base_size;    /* AOF size on latest startup or rewrite. */
    off_t aof_current_size;         /* AOF current size. */

Writing to most of these fields should be harmless and only cause problems in
Redis persistence that should not escalate to security problems.
However unfortunately writing to "aof_filename" could be potentially a
security issue depending on the access pattern.

Searching for "aof.filename" accesses in the source code returns many different
usages of the field, including using it as input for open(), logging to the
Redis log file or syslog, and calling the rename() syscall.

It looks possible that attacks could lead at least to informations
disclosure of the state and data inside Redis. However note that the
attacker must already have access to the server. But, worse than that,
it looks possible that being able to change the AOF filename can be used
to mount more powerful attacks: like overwriting random files with AOF
data (easily a potential security issue as demostrated here:
http://antirez.com/news/96), or even more subtle attacks where the
AOF filename is changed to a path were a malicious AOF file is loaded
in order to exploit other potential issues when the AOF parser is fed
with untrusted input (no known issue known currently).

The fix checks the places where the 'master' class is specifiedf in
order to access configuration data structures, and return an error in
this cases.

WHO IS AT RISK?

The "master" client class was introduced in Redis in Jul 28 2015.
Every Redis instance released past this date is not vulnerable
while all the releases after this date are. Notably:

    Redis 3.0.x is NOT vunlerable.
    Redis 3.2.x IS vulnerable.
    Redis unstable is vulnerable.

In order for the instance to be at risk, at least one of the following
conditions must be true:

    1. The attacker can access Redis remotely and is able to send
       the CONFIG SET command (often banned in managed Redis instances).

    2. The attacker is able to control the "redis.conf" file and
       can wait or trigger a server restart.

The problem was fixed 26th September 2016 in all the releases affected.
2016-09-26 08:47:52 +02:00
charsyam
ca6fc4f031 Simple change just using slaves instead of server.slaves 2016-09-24 15:53:57 +09:00
Salvatore Sanfilippo
6e866ee05e Merge pull request #3511 from dvirsky/create_string_printf
added RM_CreateStringPrintf
2016-09-21 11:46:53 +02:00
Dvir Volk
a91650fc57 added RM_CreateStringPrintf 2016-09-21 12:30:38 +03:00
antirez
670586715a dict.c: fix dictGenericDelete() return ASAP condition.
Recently we moved the "return ASAP" condition for the Delete() function
from checking .size to checking .used, which is smarter, however while
testing the first table alone always works to ensure the dict is totally
emtpy, when we test the .size field, testing .used requires testing both
T0 and T1, since a rehashing could be in progress.
2016-09-20 17:22:30 +02:00
antirez
e9d861ec69 Clear child data when opening the pipes.
This is important both to reset the magic to 0, so that it will not
match if the structure is not explicitly set, and to initialize other
things we may add like counters and such.
2016-09-19 14:11:17 +02:00
antirez
e565632e59 Child -> Parent pipe for COW info transferring. 2016-09-19 13:45:20 +02:00
antirez
e1eccf9a6b zmalloc: Make fp var non local to fix build. 2016-09-19 10:34:39 +02:00
antirez
945a2f948e zmalloc: zmalloc_get_smap_bytes_by_field() modified to work for any PID.
The goal is to get copy-on-write amount of the child from the parent.
2016-09-19 10:28:42 +02:00
antirez
b13759e90a redis-cli: "allocator-stats" -> "malloc-stats".
It was changed in Redis but not in redis-cli.
Thanks to @oranagra for signaling.
2016-09-19 09:47:35 +02:00
antirez
4263b12147 Typo fixed from MEMORY DOCTOR output. 2016-09-16 16:52:00 +02:00
antirez
8a00ffc0e6 Surround allocator name with quotes in MEMORY DOCTOR output. 2016-09-16 16:40:25 +02:00
antirez
44e714a59c MEMORY DOCTOR initial implementation. 2016-09-16 16:36:53 +02:00
antirez
d9325ac6c8 Provide percentage of memory peak used info. 2016-09-16 10:43:19 +02:00
oranagra
309c2bcd1b add zmalloc used mem to DEBUG SDSLEN 2016-09-16 10:29:27 +02:00
antirez
78f35f8d2c Memory related subcommands of DEBUG moved to MEMORY. 2016-09-16 10:26:23 +02:00
antirez
123891dbbf Group MEMORY command related APIs together in the source code. 2016-09-16 10:12:04 +02:00
antirez
adcfb77b5b objectComputeSize(): skiplist nodes have different sizes.
The size of the node depends on the node level, however it is not stored
into the node itself, is an implicit information, so we use
zmalloc_size() in order to compute the sorted set size.
2016-09-15 17:43:13 +02:00
antirez
e9629e148b MEMORY command: HELP + dataset percentage (like in INFO). 2016-09-15 17:33:16 +02:00