diff --git a/.gitignore b/.gitignore index a188cfc8..3cc7f580 100644 --- a/.gitignore +++ b/.gitignore @@ -28,3 +28,61 @@ deps/lua/src/liblua.a .prerequisites *.dSYM Makefile.dep + + +### C++ template +# Compiled Object files +*.slo +*.lo +*.o +*.obj + +# Precompiled Headers +*.gch +*.pch + +# Compiled Dynamic libraries +*.so +*.dylib +*.dll + +# Fortran module files +*.mod + +# Compiled Static libraries +*.lai +*.la +*.a +*.lib + +# Executables +*.exe +*.out +*.app + +### JetBrains template +# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm +# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 + +.idea/* +cmake-build-debug + +## File-based project format: +*.iws + +## Plugin-specific files: + +# IntelliJ +/out/ + +# mpeltonen/sbt-idea plugin +.idea_modules/ + +# JIRA plugin +atlassian-ide-plugin.xml + +# Crashlytics plugin (for Android Studio and IntelliJ) +com_crashlytics_export_strings.xml +crashlytics.properties +crashlytics-build.properties +fabric.properties \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 00000000..d8975741 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,480 @@ +cmake_minimum_required(VERSION 3.13) +project(redis) + +set(CMAKE_CXX_STANDARD 14) + +include_directories(deps/hiredis) +include_directories(deps/hiredis/adapters) +include_directories(deps/hiredis/examples) +include_directories(deps/jemalloc/include) +include_directories(deps/jemalloc/include/jemalloc) +include_directories(deps/jemalloc/include/jemalloc/internal) +include_directories(deps/jemalloc/include/msvc_compat) +include_directories(deps/jemalloc/include/msvc_compat/C99) +include_directories(deps/jemalloc/msvc/test_threads) +include_directories(deps/jemalloc/test/include) +include_directories(deps/jemalloc/test/include/test) +include_directories(deps/linenoise) +include_directories(deps/lua/etc) +include_directories(deps/lua/src) +include_directories(src) + +add_executable(redis + deps/hiredis/adapters/ae.h + deps/hiredis/adapters/glib.h + deps/hiredis/adapters/ivykis.h + deps/hiredis/adapters/libev.h + deps/hiredis/adapters/libevent.h + deps/hiredis/adapters/libuv.h + deps/hiredis/adapters/macosx.h + deps/hiredis/adapters/qt.h + deps/hiredis/examples/example-ae.c + deps/hiredis/examples/example-glib.c + deps/hiredis/examples/example-ivykis.c + deps/hiredis/examples/example-libev.c + deps/hiredis/examples/example-libevent.c + deps/hiredis/examples/example-libuv.c + deps/hiredis/examples/example-macosx.c + deps/hiredis/examples/example-qt.cpp + deps/hiredis/examples/example-qt.h + deps/hiredis/examples/example.c + deps/hiredis/async.c + deps/hiredis/async.h + deps/hiredis/dict.c + deps/hiredis/dict.h + deps/hiredis/fmacros.h + deps/hiredis/hiredis.c + deps/hiredis/hiredis.h + deps/hiredis/net.c + deps/hiredis/net.h + deps/hiredis/read.c + deps/hiredis/read.h + deps/hiredis/sds.c + deps/hiredis/sds.h + deps/hiredis/sdsalloc.h + deps/hiredis/test.c + deps/hiredis/win32.h + deps/jemalloc/include/jemalloc/internal/arena_externs.h + deps/jemalloc/include/jemalloc/internal/arena_inlines_a.h + deps/jemalloc/include/jemalloc/internal/arena_inlines_b.h + deps/jemalloc/include/jemalloc/internal/arena_stats.h + deps/jemalloc/include/jemalloc/internal/arena_structs_a.h + deps/jemalloc/include/jemalloc/internal/arena_structs_b.h + deps/jemalloc/include/jemalloc/internal/arena_types.h + deps/jemalloc/include/jemalloc/internal/assert.h + deps/jemalloc/include/jemalloc/internal/atomic.h + deps/jemalloc/include/jemalloc/internal/atomic_c11.h + deps/jemalloc/include/jemalloc/internal/atomic_gcc_atomic.h + deps/jemalloc/include/jemalloc/internal/atomic_gcc_sync.h + deps/jemalloc/include/jemalloc/internal/atomic_msvc.h + deps/jemalloc/include/jemalloc/internal/background_thread_externs.h + deps/jemalloc/include/jemalloc/internal/background_thread_inlines.h + deps/jemalloc/include/jemalloc/internal/background_thread_structs.h + deps/jemalloc/include/jemalloc/internal/base_externs.h + deps/jemalloc/include/jemalloc/internal/base_inlines.h + deps/jemalloc/include/jemalloc/internal/base_structs.h + deps/jemalloc/include/jemalloc/internal/base_types.h + deps/jemalloc/include/jemalloc/internal/bin.h + deps/jemalloc/include/jemalloc/internal/bin_stats.h + deps/jemalloc/include/jemalloc/internal/bit_util.h + deps/jemalloc/include/jemalloc/internal/bitmap.h + deps/jemalloc/include/jemalloc/internal/cache_bin.h + deps/jemalloc/include/jemalloc/internal/ckh.h + deps/jemalloc/include/jemalloc/internal/ctl.h + deps/jemalloc/include/jemalloc/internal/div.h + deps/jemalloc/include/jemalloc/internal/emitter.h + deps/jemalloc/include/jemalloc/internal/extent_dss.h + deps/jemalloc/include/jemalloc/internal/extent_externs.h + deps/jemalloc/include/jemalloc/internal/extent_inlines.h + deps/jemalloc/include/jemalloc/internal/extent_mmap.h + deps/jemalloc/include/jemalloc/internal/extent_structs.h + deps/jemalloc/include/jemalloc/internal/extent_types.h + deps/jemalloc/include/jemalloc/internal/hash.h + deps/jemalloc/include/jemalloc/internal/hooks.h + deps/jemalloc/include/jemalloc/internal/jemalloc_internal_decls.h + deps/jemalloc/include/jemalloc/internal/jemalloc_internal_externs.h + deps/jemalloc/include/jemalloc/internal/jemalloc_internal_includes.h + deps/jemalloc/include/jemalloc/internal/jemalloc_internal_inlines_a.h + deps/jemalloc/include/jemalloc/internal/jemalloc_internal_inlines_b.h + deps/jemalloc/include/jemalloc/internal/jemalloc_internal_inlines_c.h + deps/jemalloc/include/jemalloc/internal/jemalloc_internal_macros.h + deps/jemalloc/include/jemalloc/internal/jemalloc_internal_types.h + deps/jemalloc/include/jemalloc/internal/large_externs.h + deps/jemalloc/include/jemalloc/internal/log.h + deps/jemalloc/include/jemalloc/internal/malloc_io.h + deps/jemalloc/include/jemalloc/internal/mutex.h + deps/jemalloc/include/jemalloc/internal/mutex_pool.h + deps/jemalloc/include/jemalloc/internal/mutex_prof.h + deps/jemalloc/include/jemalloc/internal/nstime.h + deps/jemalloc/include/jemalloc/internal/pages.h + deps/jemalloc/include/jemalloc/internal/ph.h + deps/jemalloc/include/jemalloc/internal/prng.h + deps/jemalloc/include/jemalloc/internal/prof_externs.h + deps/jemalloc/include/jemalloc/internal/prof_inlines_a.h + deps/jemalloc/include/jemalloc/internal/prof_inlines_b.h + deps/jemalloc/include/jemalloc/internal/prof_structs.h + deps/jemalloc/include/jemalloc/internal/prof_types.h + deps/jemalloc/include/jemalloc/internal/ql.h + deps/jemalloc/include/jemalloc/internal/qr.h + deps/jemalloc/include/jemalloc/internal/rb.h + deps/jemalloc/include/jemalloc/internal/rtree.h + deps/jemalloc/include/jemalloc/internal/rtree_tsd.h + deps/jemalloc/include/jemalloc/internal/smoothstep.h + deps/jemalloc/include/jemalloc/internal/spin.h + deps/jemalloc/include/jemalloc/internal/stats.h + deps/jemalloc/include/jemalloc/internal/sz.h + deps/jemalloc/include/jemalloc/internal/tcache_externs.h + deps/jemalloc/include/jemalloc/internal/tcache_inlines.h + deps/jemalloc/include/jemalloc/internal/tcache_structs.h + deps/jemalloc/include/jemalloc/internal/tcache_types.h + deps/jemalloc/include/jemalloc/internal/ticker.h + deps/jemalloc/include/jemalloc/internal/tsd.h + deps/jemalloc/include/jemalloc/internal/tsd_generic.h + deps/jemalloc/include/jemalloc/internal/tsd_malloc_thread_cleanup.h + deps/jemalloc/include/jemalloc/internal/tsd_tls.h + deps/jemalloc/include/jemalloc/internal/tsd_types.h + deps/jemalloc/include/jemalloc/internal/tsd_win.h + deps/jemalloc/include/jemalloc/internal/util.h + deps/jemalloc/include/jemalloc/internal/witness.h + deps/jemalloc/include/msvc_compat/C99/stdbool.h + deps/jemalloc/include/msvc_compat/C99/stdint.h + deps/jemalloc/include/msvc_compat/strings.h + deps/jemalloc/include/msvc_compat/windows_extra.h + deps/jemalloc/msvc/test_threads/test_threads.cpp + deps/jemalloc/msvc/test_threads/test_threads.h + deps/jemalloc/msvc/test_threads/test_threads_main.cpp + deps/jemalloc/src/arena.c + deps/jemalloc/src/background_thread.c + deps/jemalloc/src/base.c + deps/jemalloc/src/bin.c + deps/jemalloc/src/bitmap.c + deps/jemalloc/src/ckh.c + deps/jemalloc/src/ctl.c + deps/jemalloc/src/div.c + deps/jemalloc/src/extent.c + deps/jemalloc/src/extent_dss.c + deps/jemalloc/src/extent_mmap.c + deps/jemalloc/src/hash.c + deps/jemalloc/src/hooks.c + deps/jemalloc/src/jemalloc.c + deps/jemalloc/src/jemalloc_cpp.cpp + deps/jemalloc/src/large.c + deps/jemalloc/src/log.c + deps/jemalloc/src/malloc_io.c + deps/jemalloc/src/mutex.c + deps/jemalloc/src/mutex_pool.c + deps/jemalloc/src/nstime.c + deps/jemalloc/src/pages.c + deps/jemalloc/src/prng.c + deps/jemalloc/src/prof.c + deps/jemalloc/src/rtree.c + deps/jemalloc/src/stats.c + deps/jemalloc/src/sz.c + deps/jemalloc/src/tcache.c + deps/jemalloc/src/ticker.c + deps/jemalloc/src/tsd.c + deps/jemalloc/src/witness.c + deps/jemalloc/src/zone.c + deps/jemalloc/test/include/test/btalloc.h + deps/jemalloc/test/include/test/extent_hooks.h + deps/jemalloc/test/include/test/math.h + deps/jemalloc/test/include/test/mq.h + deps/jemalloc/test/include/test/mtx.h + deps/jemalloc/test/include/test/SFMT-alti.h + deps/jemalloc/test/include/test/SFMT-params.h + deps/jemalloc/test/include/test/SFMT-params11213.h + deps/jemalloc/test/include/test/SFMT-params1279.h + deps/jemalloc/test/include/test/SFMT-params132049.h + deps/jemalloc/test/include/test/SFMT-params19937.h + deps/jemalloc/test/include/test/SFMT-params216091.h + deps/jemalloc/test/include/test/SFMT-params2281.h + deps/jemalloc/test/include/test/SFMT-params4253.h + deps/jemalloc/test/include/test/SFMT-params44497.h + deps/jemalloc/test/include/test/SFMT-params607.h + deps/jemalloc/test/include/test/SFMT-params86243.h + deps/jemalloc/test/include/test/SFMT-sse2.h + deps/jemalloc/test/include/test/SFMT.h + deps/jemalloc/test/include/test/test.h + deps/jemalloc/test/include/test/thd.h + deps/jemalloc/test/include/test/timer.h + deps/jemalloc/test/integration/cpp/basic.cpp + deps/jemalloc/test/integration/aligned_alloc.c + deps/jemalloc/test/integration/allocated.c + deps/jemalloc/test/integration/extent.c + deps/jemalloc/test/integration/mallocx.c + deps/jemalloc/test/integration/MALLOCX_ARENA.c + deps/jemalloc/test/integration/overflow.c + deps/jemalloc/test/integration/posix_memalign.c + deps/jemalloc/test/integration/rallocx.c + deps/jemalloc/test/integration/sdallocx.c + deps/jemalloc/test/integration/thread_arena.c + deps/jemalloc/test/integration/thread_tcache_enabled.c + deps/jemalloc/test/integration/xallocx.c + deps/jemalloc/test/src/btalloc.c + deps/jemalloc/test/src/btalloc_0.c + deps/jemalloc/test/src/btalloc_1.c + deps/jemalloc/test/src/math.c + deps/jemalloc/test/src/mq.c + deps/jemalloc/test/src/mtx.c + deps/jemalloc/test/src/SFMT.c + deps/jemalloc/test/src/test.c + deps/jemalloc/test/src/thd.c + deps/jemalloc/test/src/timer.c + deps/jemalloc/test/stress/microbench.c + deps/jemalloc/test/unit/a0.c + deps/jemalloc/test/unit/arena_reset.c + deps/jemalloc/test/unit/arena_reset_prof.c + deps/jemalloc/test/unit/atomic.c + deps/jemalloc/test/unit/background_thread.c + deps/jemalloc/test/unit/background_thread_enable.c + deps/jemalloc/test/unit/base.c + deps/jemalloc/test/unit/bit_util.c + deps/jemalloc/test/unit/bitmap.c + deps/jemalloc/test/unit/ckh.c + deps/jemalloc/test/unit/decay.c + deps/jemalloc/test/unit/div.c + deps/jemalloc/test/unit/emitter.c + deps/jemalloc/test/unit/extent_quantize.c + deps/jemalloc/test/unit/fork.c + deps/jemalloc/test/unit/hash.c + deps/jemalloc/test/unit/hooks.c + deps/jemalloc/test/unit/junk.c + deps/jemalloc/test/unit/junk_alloc.c + deps/jemalloc/test/unit/junk_free.c + deps/jemalloc/test/unit/log.c + deps/jemalloc/test/unit/mallctl.c + deps/jemalloc/test/unit/malloc_io.c + deps/jemalloc/test/unit/math.c + deps/jemalloc/test/unit/mq.c + deps/jemalloc/test/unit/mtx.c + deps/jemalloc/test/unit/nstime.c + deps/jemalloc/test/unit/pack.c + deps/jemalloc/test/unit/pages.c + deps/jemalloc/test/unit/ph.c + deps/jemalloc/test/unit/prng.c + deps/jemalloc/test/unit/prof_accum.c + deps/jemalloc/test/unit/prof_active.c + deps/jemalloc/test/unit/prof_gdump.c + deps/jemalloc/test/unit/prof_idump.c + deps/jemalloc/test/unit/prof_reset.c + deps/jemalloc/test/unit/prof_tctx.c + deps/jemalloc/test/unit/prof_thread_name.c + deps/jemalloc/test/unit/ql.c + deps/jemalloc/test/unit/qr.c + deps/jemalloc/test/unit/rb.c + deps/jemalloc/test/unit/retained.c + deps/jemalloc/test/unit/rtree.c + deps/jemalloc/test/unit/SFMT.c + deps/jemalloc/test/unit/size_classes.c + deps/jemalloc/test/unit/slab.c + deps/jemalloc/test/unit/smoothstep.c + deps/jemalloc/test/unit/spin.c + deps/jemalloc/test/unit/stats.c + deps/jemalloc/test/unit/stats_print.c + deps/jemalloc/test/unit/ticker.c + deps/jemalloc/test/unit/tsd.c + deps/jemalloc/test/unit/witness.c + deps/jemalloc/test/unit/zero.c + deps/linenoise/example.c + deps/linenoise/linenoise.c + deps/linenoise/linenoise.h + deps/lua/etc/all.c + deps/lua/etc/lua.hpp + deps/lua/etc/min.c + deps/lua/etc/noparser.c + deps/lua/src/fpconv.c + deps/lua/src/fpconv.h + deps/lua/src/lapi.c + deps/lua/src/lapi.h + deps/lua/src/lauxlib.c + deps/lua/src/lauxlib.h + deps/lua/src/lbaselib.c + deps/lua/src/lcode.c + deps/lua/src/lcode.h + deps/lua/src/ldblib.c + deps/lua/src/ldebug.c + deps/lua/src/ldebug.h + deps/lua/src/ldo.c + deps/lua/src/ldo.h + deps/lua/src/ldump.c + deps/lua/src/lfunc.c + deps/lua/src/lfunc.h + deps/lua/src/lgc.c + deps/lua/src/lgc.h + deps/lua/src/linit.c + deps/lua/src/liolib.c + deps/lua/src/llex.c + deps/lua/src/llex.h + deps/lua/src/llimits.h + deps/lua/src/lmathlib.c + deps/lua/src/lmem.c + deps/lua/src/lmem.h + deps/lua/src/loadlib.c + deps/lua/src/lobject.c + deps/lua/src/lobject.h + deps/lua/src/lopcodes.c + deps/lua/src/lopcodes.h + deps/lua/src/loslib.c + deps/lua/src/lparser.c + deps/lua/src/lparser.h + deps/lua/src/lstate.c + deps/lua/src/lstate.h + deps/lua/src/lstring.c + deps/lua/src/lstring.h + deps/lua/src/lstrlib.c + deps/lua/src/ltable.c + deps/lua/src/ltable.h + deps/lua/src/ltablib.c + deps/lua/src/ltm.c + deps/lua/src/ltm.h + deps/lua/src/lua.c + deps/lua/src/lua.h + deps/lua/src/lua_bit.c + deps/lua/src/lua_cjson.c + deps/lua/src/lua_cmsgpack.c + deps/lua/src/lua_struct.c + deps/lua/src/luac.c + deps/lua/src/luaconf.h + deps/lua/src/lualib.h + deps/lua/src/lundump.c + deps/lua/src/lundump.h + deps/lua/src/lvm.c + deps/lua/src/lvm.h + deps/lua/src/lzio.c + deps/lua/src/lzio.h + deps/lua/src/print.c + deps/lua/src/strbuf.c + deps/lua/src/strbuf.h + src/modules/helloblock.c + src/modules/hellocluster.c + src/modules/hellodict.c + src/modules/hellotimer.c + src/modules/hellotype.c + src/modules/helloworld.c + src/modules/testmodule.c + src/adlist.c + src/adlist.h + src/ae.c + src/ae.h + src/ae_epoll.c + src/ae_evport.c + src/ae_kqueue.c + src/ae_select.c + src/anet.c + src/anet.h + src/aof.c + src/asciilogo.h + src/atomicvar.h + src/bio.c + src/bio.h + src/bitops.c + src/blocked.c + src/childinfo.c + src/cluster.c + src/cluster.h + src/config.c + src/config.h + src/crc16.c + src/crc64.c + src/crc64.h + src/db.c + src/debug.c + src/debugmacro.h + src/defrag.c + src/dict.c + src/dict.h + src/endianconv.c + src/endianconv.h + src/evict.c + src/expire.c + src/fmacros.h + src/geo.c + src/geo.h + src/geohash.c + src/geohash.h + src/geohash_helper.c + src/geohash_helper.h + src/help.h + src/hyperloglog.c + src/intset.c + src/intset.h + src/latency.c + src/latency.h + src/lazyfree.c + src/listpack.c + src/listpack.h + src/listpack_malloc.h + src/localtime.c + src/lolwut.c + src/lolwut5.c + src/lzf.h + src/lzf_c.c + src/lzf_d.c + src/lzfP.h + src/memtest.c + src/module.c + src/multi.c + src/networking.c + src/notify.c + src/object.c + src/pqsort.c + src/pqsort.h + src/pubsub.c + src/quicklist.c + src/quicklist.h + src/rand.c + src/rand.h + src/rax.c + src/rax.h + src/rax_malloc.h + src/rdb.c + src/rdb.h + src/redis-benchmark.c + src/redis-check-aof.c + src/redis-check-rdb.c + src/redis-cli.c + src/redisassert.h + src/redismodule.h + src/release.c + src/release.h + src/replication.c + src/rio.c + src/rio.h + src/scripting.c + src/sds.c + src/sds.h + src/sdsalloc.h + src/sentinel.c + src/server.c + src/server.h + src/setproctitle.c + src/sha1.c + src/sha1.h + src/siphash.c + src/slowlog.c + src/slowlog.h + src/solarisfixes.h + src/sort.c + src/sparkline.c + src/sparkline.h + src/stream.h + src/syncio.c + src/t_hash.c + src/t_list.c + src/t_set.c + src/t_stream.c + src/t_string.c + src/t_zset.c + src/testhelp.h + src/util.c + src/util.h + src/version.h + src/ziplist.c + src/ziplist.h + src/zipmap.c + src/zipmap.h + src/zmalloc.c + src/zmalloc.h + utils/hashtable/rehashing.c + utils/lru/lfu-simulation.c + utils/corrupt_rdb.c src/wrapper.c) diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 00000000..bcaeb9f6 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,13 @@ +FROM ubuntu:19.04 + +RUN apt-get update \ + && apt-get install -y ca-certificates \ + curl \ + git \ + make + +RUN curl -L https://github.com/CraneStation/wasi-sdk/releases/download/wasi-sdk-5/wasi-sdk-5.0-linux.tar.gz | tar xz --strip-components=1 -C / + +VOLUME /code +WORKDIR /code +CMD make wasm diff --git a/Makefile b/Makefile index e614ede8..5a1a163a 100644 --- a/Makefile +++ b/Makefile @@ -5,6 +5,9 @@ default: all .DEFAULT: cd src && $(MAKE) $@ +wasm: + cd src && $(MAKE) -f Makefile_wasm + install: cd src && $(MAKE) $@ diff --git a/deps/lua/src/lbaselib.c b/deps/lua/src/lbaselib.c index 2ab550bd..a0c35a67 100644 --- a/deps/lua/src/lbaselib.c +++ b/deps/lua/src/lbaselib.c @@ -447,12 +447,16 @@ static int luaB_newproxy (lua_State *L) { static const luaL_Reg base_funcs[] = { {"assert", luaB_assert}, {"collectgarbage", luaB_collectgarbage}, +#if __redis_unmodified_upstream // Disable working with files {"dofile", luaB_dofile}, +#endif {"error", luaB_error}, {"gcinfo", luaB_gcinfo}, {"getfenv", luaB_getfenv}, {"getmetatable", luaB_getmetatable}, +#if __redis_unmodified_upstream // Disable working with files {"loadfile", luaB_loadfile}, +#endif {"load", luaB_load}, {"loadstring", luaB_loadstring}, {"next", luaB_next}, diff --git a/deps/lua/src/ldblib.c b/deps/lua/src/ldblib.c index 2027eda5..b3b2aca7 100644 --- a/deps/lua/src/ldblib.c +++ b/deps/lua/src/ldblib.c @@ -391,8 +391,10 @@ static const luaL_Reg dblib[] = { }; +#if __redis_unmodified_upstream // Disable lua debugging API of Redis LUALIB_API int luaopen_debug (lua_State *L) { luaL_register(L, LUA_DBLIBNAME, dblib); return 1; } +#endif diff --git a/deps/lua/src/ldo.c b/deps/lua/src/ldo.c index 514f7a2a..049fde39 100644 --- a/deps/lua/src/ldo.c +++ b/deps/lua/src/ldo.c @@ -5,7 +5,9 @@ */ +#if __redis_unmodified_upstream // Currently setjmp/longjump cannot be translated to Wasm #include +#endif #include #include @@ -103,7 +105,11 @@ void luaD_throw (lua_State *L, int errcode) { lua_unlock(L); G(L)->panic(L); } +#if __redis_unmodified_upstream // Disable a call to exit from libc exit(EXIT_FAILURE); +#else + __builtin_unreachable(); +#endif } } diff --git a/deps/lua/src/linit.c b/deps/lua/src/linit.c index c1f90dfa..9cc75ab2 100644 --- a/deps/lua/src/linit.c +++ b/deps/lua/src/linit.c @@ -19,10 +19,14 @@ static const luaL_Reg lualibs[] = { {LUA_LOADLIBNAME, luaopen_package}, {LUA_TABLIBNAME, luaopen_table}, {LUA_IOLIBNAME, luaopen_io}, +#if __redis_unmodified_upstream // Disable the lua os API of Redis {LUA_OSLIBNAME, luaopen_os}, +#endif {LUA_STRLIBNAME, luaopen_string}, {LUA_MATHLIBNAME, luaopen_math}, +#if __redis_unmodified_upstream // Disable the lua debugging API of Redis {LUA_DBLIBNAME, luaopen_debug}, +#endif {NULL, NULL} }; diff --git a/deps/lua/src/loslib.c b/deps/lua/src/loslib.c index da06a572..40f97587 100644 --- a/deps/lua/src/loslib.c +++ b/deps/lua/src/loslib.c @@ -235,9 +235,10 @@ static const luaL_Reg syslib[] = { /* }====================================================== */ - +#if __redis_unmodified_upstream // Disable lua os module LUALIB_API int luaopen_os (lua_State *L) { luaL_register(L, LUA_OSLIBNAME, syslib); return 1; } +#endif diff --git a/deps/lua/src/lua.c b/deps/lua/src/lua.c index 3a466093..7d526a26 100644 --- a/deps/lua/src/lua.c +++ b/deps/lua/src/lua.c @@ -5,7 +5,9 @@ */ +#if __redis_unmodified_upstream // Disable syscalls from some libs #include +#endif #include #include #include @@ -33,8 +35,10 @@ static void lstop (lua_State *L, lua_Debug *ar) { static void laction (int i) { +#if __redis_unmodified_upstream // Disable signal handler signal(i, SIG_DFL); /* if another SIGINT happens before lstop, terminate process (default action) */ +#endif lua_sethook(globalL, lstop, LUA_MASKCALL | LUA_MASKRET | LUA_MASKCOUNT, 1); } @@ -98,9 +102,13 @@ static int docall (lua_State *L, int narg, int clear) { int base = lua_gettop(L) - narg; /* function index */ lua_pushcfunction(L, traceback); /* push traceback function */ lua_insert(L, base); /* put it under chunk and args */ +#if __redis_unmodified_upstream // Disable signal handlers signal(SIGINT, laction); +#endif status = lua_pcall(L, narg, (clear ? 0 : LUA_MULTRET), base); +#if __redis_unmodified_upstream // Disable signal handlers signal(SIGINT, SIG_DFL); +#endif lua_remove(L, base); /* remove traceback function */ /* force a complete garbage collection in case of errors */ if (status != 0) lua_gc(L, LUA_GCCOLLECT, 0); diff --git a/deps/lua/src/lua_cjson.c b/deps/lua/src/lua_cjson.c index c26c0d7b..a8eafc84 100644 --- a/deps/lua/src/lua_cjson.c +++ b/deps/lua/src/lua_cjson.c @@ -1405,11 +1405,17 @@ int luaopen_cjson(lua_State *l) { lua_cjson_new(l); +#if __redis_unmodified_upstream // It could be built without explicit enabling of this macro #ifdef ENABLE_CJSON_GLOBAL /* Register a global "cjson" table. */ lua_pushvalue(l, -1); lua_setglobal(l, CJSON_MODNAME); #endif +#else + /* Register a global "cjson" table. */ + lua_pushvalue(l, -1); + lua_setglobal(l, CJSON_MODNAME); +#endif /* Return cjson table */ return 1; diff --git a/deps/lua/src/luaconf.h b/deps/lua/src/luaconf.h index e2cb2616..67d66d6a 100644 --- a/deps/lua/src/luaconf.h +++ b/deps/lua/src/luaconf.h @@ -617,11 +617,16 @@ union luai_Cast { double l_d; long l_l; }; #define luai_jmpbuf jmp_buf #else +#if __redis_unmodified_upstream // Currently setjmp/longjump cannot be translated to Wasm /* default handling with long jumps */ #define LUAI_THROW(L,c) longjmp((c)->b, 1) #define LUAI_TRY(L,c,a) if (setjmp((c)->b) == 0) { a } #define luai_jmpbuf jmp_buf - +#else +#define LUAI_THROW(L,c) +#define LUAI_TRY(L,c,a) { a } +#define luai_jmpbuf int +#endif #endif @@ -653,7 +658,11 @@ union luai_Cast { double l_d; long l_l; }; e = (e == -1); } #else +#if __redis_unmodified_upstream // Disable getting tmp folder #define LUA_TMPNAMBUFSIZE L_tmpnam +#else +#define LUA_TMPNAMBUFSIZE 260 +#endif #define lua_tmpnam(b,e) { e = (tmpnam(b) == NULL); } #endif diff --git a/deps/lua/src/lualib.h b/deps/lua/src/lualib.h index 469417f6..6d067b73 100644 --- a/deps/lua/src/lualib.h +++ b/deps/lua/src/lualib.h @@ -24,8 +24,10 @@ LUALIB_API int (luaopen_table) (lua_State *L); #define LUA_IOLIBNAME "io" LUALIB_API int (luaopen_io) (lua_State *L); +#if __redis_unmodified_upstream // Disable os module of lua #define LUA_OSLIBNAME "os" LUALIB_API int (luaopen_os) (lua_State *L); +#endif #define LUA_STRLIBNAME "string" LUALIB_API int (luaopen_string) (lua_State *L); @@ -33,8 +35,10 @@ LUALIB_API int (luaopen_string) (lua_State *L); #define LUA_MATHLIBNAME "math" LUALIB_API int (luaopen_math) (lua_State *L); +#if __redis_unmodified_upstream // Disable the debug module of lua #define LUA_DBLIBNAME "debug" LUALIB_API int (luaopen_debug) (lua_State *L); +#endif #define LUA_LOADLIBNAME "package" LUALIB_API int (luaopen_package) (lua_State *L); diff --git a/deps/lua/src/strbuf.c b/deps/lua/src/strbuf.c index f0f7f4b9..1a670c12 100644 --- a/deps/lua/src/strbuf.c +++ b/deps/lua/src/strbuf.c @@ -31,6 +31,7 @@ static void die(const char *fmt, ...) { +#if __redis_unmodified_upstream // Disable a call to exit from libc va_list arg; va_start(arg, fmt); @@ -39,6 +40,10 @@ static void die(const char *fmt, ...) fprintf(stderr, "\n"); exit(-1); +#else + // TODO: enable server logs + __builtin_unreachable(); +#endif } void strbuf_init(strbuf_t *s, int len) diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 00000000..c03188aa --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,7 @@ +version: '3' +services: + redis: + build: + context: . + volumes: + - .:/code diff --git a/src/Makefile_wasm b/src/Makefile_wasm new file mode 100644 index 00000000..89761dc4 --- /dev/null +++ b/src/Makefile_wasm @@ -0,0 +1,23 @@ +TARGET = redis +CC = /opt/wasi-sdk/bin/clang +SYSROOT = /opt/wasi-sdk/share/sysroot +TARGET_TRIPLE = wasm32-unknown-wasi +CFLAGS = -nostartfiles -fvisibility=hidden +LDFLAGS = -Wl,--no-entry,--demangle,--allow-undefined +EXPORT_FUNCS = --export=allocate,--export=deallocate,--export=invoke +SDK = sdk/allocator.cpp sdk/logger.cpp +LUA =/code/deps/lua/src +REDIS_SERVER = adlist.c quicklist.c dict.c server.c sds.c zmalloc.c lzf_c.c lzf_d.c pqsort.c zipmap.c sha1.c ziplist.c release.c networking.c util.c object.c db.c t_string.c t_list.c t_set.c t_zset.c t_hash.c multi.c sort.c intset.c crc16.c endianconv.c slowlog.c scripting.c rand.c crc64.c bitops.c notify.c hyperloglog.c latency.c sparkline.c geo.c evict.c expire.c geohash.c geohash_helper.c defrag.c siphash.c rax.c t_stream.c listpack.c lolwut.c lolwut5.c wrapper.c + +.PHONY: default all clean + +default: $(TARGET) +all: default + +$(TARGET): $(REDIS_SERVER) + $(CC) --sysroot=$(SYSROOT) --target=$(TARGET_TRIPLE) -I$(LUA) $(CFLAGS) $(LDFLAGS) -Wl,$(EXPORT_FUNCS) $^ -c + +.PRECIOUS: $(TARGET) + +clean: + -rm -f $(TARGET).wasm diff --git a/src/atomicvar.h b/src/atomicvar.h index 160056cd..8005e334 100644 --- a/src/atomicvar.h +++ b/src/atomicvar.h @@ -57,11 +57,14 @@ * POSSIBILITY OF SUCH DAMAGE. */ +#if __redis_unmodified_upstream // Disable syscalls from pthread.h #include +#endif #ifndef __ATOMIC_VAR_H #define __ATOMIC_VAR_H +#if __redis_unmodified_upstream // Make these macros independent on various flags /* To test Redis with Helgrind (a Valgrind tool) it is useful to define * the following macro, so that __sync macros are used: those can be detected * by Helgrind (even if they are less efficient) so that no false positive @@ -130,4 +133,26 @@ #define REDIS_ATOMIC_API "pthread-mutex" #endif + +#else + +#define atomicIncr(var,count) do { \ + var += (count); \ +} while(0) +#define atomicGetIncr(var,oldvalue_var,count) do { \ + oldvalue_var = var; \ + var += (count); \ +} while(0) +#define atomicDecr(var,count) do { \ + var -= (count); \ +} while(0) +#define atomicGet(var,dstvar) do { \ + dstvar = var; \ +} while(0) +#define atomicSet(var,value) do { \ + var = value; \ +} while(0) +#define REDIS_ATOMIC_API "wasm-atomic-api" +#endif + #endif /* __ATOMIC_VAR_H */ diff --git a/src/bitops.c b/src/bitops.c index 23f2266a..68126118 100644 --- a/src/bitops.c +++ b/src/bitops.c @@ -29,6 +29,11 @@ */ #include "server.h" +#if __redis_unmodified_upstream // To make all implicit functions prototypes explicit +#else +#include +#include +#endif /* ----------------------------------------------------------------------------- * Helpers and low level bit functions. diff --git a/src/blocked.c b/src/blocked.c index 2b43f2b7..14b5c10a 100644 --- a/src/blocked.c +++ b/src/blocked.c @@ -165,7 +165,9 @@ void unblockClient(client *c) { c->btype == BLOCKED_STREAM) { unblockClientWaitingData(c); } else if (c->btype == BLOCKED_WAIT) { +#if __redis_unmodified_upstream // Disable the cluster API of Redis unblockClientWaitingReplicas(c); +#endif } else if (c->btype == BLOCKED_MODULE) { unblockClientFromModule(c); } else { @@ -604,5 +606,3 @@ void signalKeyAsReady(redisDb *db, robj *key) { incrRefCount(key); serverAssert(dictAdd(db->ready_keys,key,NULL) == DICT_OK); } - - diff --git a/src/config.c b/src/config.c index 99f12f39..2738f880 100644 --- a/src/config.c +++ b/src/config.c @@ -143,16 +143,20 @@ int yesnotoi(char *s) { } void appendServerSaveParams(time_t seconds, int changes) { +#if __redis_unmodified_upstream // Disable saveparams server.saveparams = zrealloc(server.saveparams,sizeof(struct saveparam)*(server.saveparamslen+1)); server.saveparams[server.saveparamslen].seconds = seconds; server.saveparams[server.saveparamslen].changes = changes; server.saveparamslen++; +#endif } void resetServerSaveParams(void) { +#if __redis_unmodified_upstream // Disable saevparams zfree(server.saveparams); server.saveparams = NULL; server.saveparamslen = 0; +#endif } void queueLoadModule(sds path, sds *argv, int argc) { @@ -344,7 +348,9 @@ void loadServerConfigFromString(char *config) { err = "lfu-decay-time must be 0 or greater"; goto loaderr; } - } else if ((!strcasecmp(argv[0],"slaveof") || + } +#if __redis_unmodified_upstream // Disable the cluster and replication API of Redis + else if ((!strcasecmp(argv[0],"slaveof") || !strcasecmp(argv[0],"replicaof")) && argc == 3) { slaveof_linenum = linenum; server.masterhost = sdsnew(argv[1]); @@ -424,7 +430,9 @@ void loadServerConfigFromString(char *config) { if ((server.rdb_checksum = yesnotoi(argv[1])) == -1) { err = "argument must be 'yes' or 'no'"; goto loaderr; } - } else if (!strcasecmp(argv[0],"activerehashing") && argc == 2) { + } +#endif + else if (!strcasecmp(argv[0],"activerehashing") && argc == 2) { if ((server.activerehashing = yesnotoi(argv[1])) == -1) { err = "argument must be 'yes' or 'no'"; goto loaderr; } @@ -443,9 +451,11 @@ void loadServerConfigFromString(char *config) { } else if ((!strcasecmp(argv[0],"slave-lazy-flush") || !strcasecmp(argv[0],"replica-lazy-flush")) && argc == 2) { +#if __redis_unmodified_upstream // Disable the cluster API of Redis if ((server.repl_slave_lazy_flush = yesnotoi(argv[1])) == -1) { err = "argument must be 'yes' or 'no'"; goto loaderr; } +#endif } else if (!strcasecmp(argv[0],"activedefrag") && argc == 2) { if ((server.active_defrag_enabled = yesnotoi(argv[1])) == -1) { err = "argument must be 'yes' or 'no'"; goto loaderr; @@ -467,7 +477,9 @@ void loadServerConfigFromString(char *config) { server.config_hz = atoi(argv[1]); if (server.config_hz < CONFIG_MIN_HZ) server.config_hz = CONFIG_MIN_HZ; if (server.config_hz > CONFIG_MAX_HZ) server.config_hz = CONFIG_MAX_HZ; - } else if (!strcasecmp(argv[0],"appendonly") && argc == 2) { + } +#if __redis_unmodified_upstream // Disable the replication API of Redis + else if (!strcasecmp(argv[0],"appendonly") && argc == 2) { int yes; if ((yes = yesnotoi(argv[1])) == -1) { @@ -526,7 +538,9 @@ void loadServerConfigFromString(char *config) { if ((server.aof_use_rdb_preamble = yesnotoi(argv[1])) == -1) { err = "argument must be 'yes' or 'no'"; goto loaderr; } - } else if (!strcasecmp(argv[0],"requirepass") && argc == 2) { + } +#endif + else if (!strcasecmp(argv[0],"requirepass") && argc == 2) { if (strlen(argv[1]) > CONFIG_AUTHPASS_MAX_LEN) { err = "Password is longer than CONFIG_AUTHPASS_MAX_LEN"; goto loaderr; @@ -540,8 +554,10 @@ void loadServerConfigFromString(char *config) { err = "dbfilename can't be a path, just a filename"; goto loaderr; } +#if __redis_unmodified_upstream // Disable the replication API of Redis zfree(server.rdb_filename); server.rdb_filename = zstrdup(argv[1]); +#endif } else if (!strcasecmp(argv[0],"active-defrag-threshold-lower") && argc == 2) { server.active_defrag_threshold_lower = atoi(argv[1]); if (server.active_defrag_threshold_lower < 0 || @@ -628,7 +644,10 @@ void loadServerConfigFromString(char *config) { err = "Target command name already exists"; goto loaderr; } } - } else if (!strcasecmp(argv[0],"cluster-enabled") && argc == 2) { + } + +#if __redis_unmodified_upstream // Disable the cluster API of Redis + else if (!strcasecmp(argv[0],"cluster-enabled") && argc == 2) { if ((server.cluster_enabled = yesnotoi(argv[1])) == -1) { err = "argument must be 'yes' or 'no'"; goto loaderr; } @@ -696,7 +715,9 @@ void loadServerConfigFromString(char *config) { server.lua_time_limit = strtoll(argv[1],NULL,10); } else if (!strcasecmp(argv[0],"lua-replicate-commands") && argc == 2) { server.lua_always_replicate_commands = yesnotoi(argv[1]); - } else if (!strcasecmp(argv[0],"slowlog-log-slower-than") && + } +#endif + else if (!strcasecmp(argv[0],"slowlog-log-slower-than") && argc == 2) { server.slowlog_log_slower_than = strtoll(argv[1],NULL,10); @@ -796,7 +817,9 @@ void loadServerConfigFromString(char *config) { err = "sentinel directive while not in sentinel mode"; goto loaderr; } +#if __redis_unmodified_upstream // Disable sentinel mode err = sentinelHandleConfiguration(argv+1,argc-1); +#endif if (err) goto loaderr; } } else { @@ -805,6 +828,7 @@ void loadServerConfigFromString(char *config) { sdsfreesplitres(argv,argc); } +#if __redis_unmodified_upstream // Disable the cluster API of Redis /* Sanity checks. */ if (server.cluster_enabled && server.masterhost) { linenum = slaveof_linenum; @@ -812,7 +836,7 @@ void loadServerConfigFromString(char *config) { err = "replicaof directive not allowed in cluster mode"; goto loaderr; } - +#endif sdsfreesplitres(lines,totlines); return; @@ -924,10 +948,14 @@ void configSetCommand(client *c) { } config_set_special_field("masterauth") { zfree(server.masterauth); server.masterauth = ((char*)o->ptr)[0] ? zstrdup(o->ptr) : NULL; - } config_set_special_field("cluster-announce-ip") { + } +#if __redis_unmodified_upstream // Disable the cluster API of Redis + config_set_special_field("cluster-announce-ip") { zfree(server.cluster_announce_ip); server.cluster_announce_ip = ((char*)o->ptr)[0] ? zstrdup(o->ptr) : NULL; - } config_set_special_field("maxclients") { + } +#endif + config_set_special_field("maxclients") { int orig_value = server.maxclients; if (getLongLongFromObject(o,&ll) == C_ERR || ll < 1) goto badfmt; @@ -1056,7 +1084,9 @@ void configSetCommand(client *c) { if (flags == -1) goto badfmt; server.notify_keyspace_events = flags; - } config_set_special_field_with_alias("slave-announce-ip", + } +#if __redis_unmodified_upstream // Disable the cluster API of Redis + config_set_special_field_with_alias("slave-announce-ip", "replica-announce-ip") { zfree(server.slave_announce_ip); @@ -1070,13 +1100,15 @@ void configSetCommand(client *c) { "repl-disable-tcp-nodelay",server.repl_disable_tcp_nodelay) { } config_set_bool_field( "repl-diskless-sync",server.repl_diskless_sync) { - } config_set_bool_field( + } + config_set_bool_field( "cluster-require-full-coverage",server.cluster_require_full_coverage) { } config_set_bool_field( "cluster-slave-no-failover",server.cluster_slave_no_failover) { } config_set_bool_field( "cluster-replica-no-failover",server.cluster_slave_no_failover) { - } config_set_bool_field( + } + config_set_bool_field( "aof-rewrite-incremental-fsync",server.aof_rewrite_incremental_fsync) { } config_set_bool_field( "rdb-save-incremental-fsync",server.rdb_save_incremental_fsync) { @@ -1096,7 +1128,9 @@ void configSetCommand(client *c) { "slave-ignore-maxmemory",server.repl_slave_ignore_maxmemory) { } config_set_bool_field( "replica-ignore-maxmemory",server.repl_slave_ignore_maxmemory) { - } config_set_bool_field( + } +#endif + config_set_bool_field( "activerehashing",server.activerehashing) { } config_set_bool_field( "activedefrag",server.active_defrag_enabled) { @@ -1176,9 +1210,11 @@ void configSetCommand(client *c) { "zset-max-ziplist-value",server.zset_max_ziplist_value,0,LONG_MAX) { } config_set_numerical_field( "hll-sparse-max-bytes",server.hll_sparse_max_bytes,0,LONG_MAX) { - } config_set_numerical_field( + } + config_set_numerical_field( "lua-time-limit",server.lua_time_limit,0,LONG_MAX) { - } config_set_numerical_field( + } + config_set_numerical_field( "slowlog-log-slower-than",server.slowlog_log_slower_than,-1,LLONG_MAX) { } config_set_numerical_field( "slowlog-max-len",ll,0,LONG_MAX) { @@ -1216,7 +1252,9 @@ void configSetCommand(client *c) { } config_set_numerical_field( "min-replicas-max-lag",server.repl_min_slaves_max_lag,0,INT_MAX) { refreshGoodSlavesCount(); - } config_set_numerical_field( + } +#if __redis_unmodified_upstream // Disable the cluster API of Redis + config_set_numerical_field( "cluster-node-timeout",server.cluster_node_timeout,0,LLONG_MAX) { } config_set_numerical_field( "cluster-announce-port",server.cluster_announce_port,0,65535) { @@ -1228,7 +1266,9 @@ void configSetCommand(client *c) { "cluster-slave-validity-factor",server.cluster_slave_validity_factor,0,INT_MAX) { } config_set_numerical_field( "cluster-replica-validity-factor",server.cluster_slave_validity_factor,0,INT_MAX) { - } config_set_numerical_field( + } +#endif + config_set_numerical_field( "hz",server.config_hz,0,INT_MAX) { /* Hz is more an hint from the user, so we accept values out of range * but cap them to reasonable values. */ @@ -1331,15 +1371,21 @@ void configGetCommand(client *c) { serverAssertWithInfo(c,o,sdsEncodedObject(o)); /* String values */ +#if __redis_unmodified_upstream // Disable the replication API of Redis config_get_string_field("dbfilename",server.rdb_filename); +#endif config_get_string_field("requirepass",server.requirepass); +#if __redis_unmodified_upstream // Disable the cluster API of Redis config_get_string_field("masterauth",server.masterauth); config_get_string_field("cluster-announce-ip",server.cluster_announce_ip); +#endif config_get_string_field("unixsocket",server.unixsocket); config_get_string_field("logfile",server.logfile); config_get_string_field("pidfile",server.pidfile); +#if __redis_unmodified_upstream // Disable the replication API of Redis config_get_string_field("slave-announce-ip",server.slave_announce_ip); config_get_string_field("replica-announce-ip",server.slave_announce_ip); +#endif /* Numerical values */ config_get_numerical_field("maxmemory",server.maxmemory); @@ -1355,10 +1401,12 @@ void configGetCommand(client *c) { config_get_numerical_field("active-defrag-cycle-min",server.active_defrag_cycle_min); config_get_numerical_field("active-defrag-cycle-max",server.active_defrag_cycle_max); config_get_numerical_field("active-defrag-max-scan-fields",server.active_defrag_max_scan_fields); +#if __redis_unmodified_upstream // Disable the replication API of Redis config_get_numerical_field("auto-aof-rewrite-percentage", server.aof_rewrite_perc); config_get_numerical_field("auto-aof-rewrite-min-size", server.aof_rewrite_min_size); +#endif config_get_numerical_field("hash-max-ziplist-entries", server.hash_max_ziplist_entries); config_get_numerical_field("hash-max-ziplist-value", @@ -1387,10 +1435,14 @@ void configGetCommand(client *c) { config_get_numerical_field("slowlog-max-len", server.slowlog_max_len); config_get_numerical_field("port",server.port); + +#if __redis_unmodified_upstream // Disable the cluster API of Redis config_get_numerical_field("cluster-announce-port",server.cluster_announce_port); config_get_numerical_field("cluster-announce-bus-port",server.cluster_announce_bus_port); +#endif config_get_numerical_field("tcp-backlog",server.tcp_backlog); config_get_numerical_field("databases",server.dbnum); +#if __redis_unmodified_upstream // Disable the replication API of Redis config_get_numerical_field("repl-ping-slave-period",server.repl_ping_slave_period); config_get_numerical_field("repl-ping-replica-period",server.repl_ping_slave_period); config_get_numerical_field("repl-timeout",server.repl_timeout); @@ -1406,14 +1458,18 @@ void configGetCommand(client *c) { config_get_numerical_field("min-replicas-to-write",server.repl_min_slaves_to_write); config_get_numerical_field("min-slaves-max-lag",server.repl_min_slaves_max_lag); config_get_numerical_field("min-replicas-max-lag",server.repl_min_slaves_max_lag); +#endif config_get_numerical_field("hz",server.config_hz); +#if __redis_unmodified_upstream // Disable the cluster API of Redis config_get_numerical_field("cluster-node-timeout",server.cluster_node_timeout); config_get_numerical_field("cluster-migration-barrier",server.cluster_migration_barrier); config_get_numerical_field("cluster-slave-validity-factor",server.cluster_slave_validity_factor); config_get_numerical_field("cluster-replica-validity-factor",server.cluster_slave_validity_factor); config_get_numerical_field("repl-diskless-sync-delay",server.repl_diskless_sync_delay); +#endif config_get_numerical_field("tcp-keepalive",server.tcpkeepalive); +#if __redis_unmodified_upstream // Disable the cluster API of Redis /* Bool (yes/no) values */ config_get_bool_field("cluster-require-full-coverage", server.cluster_require_full_coverage); @@ -1437,12 +1493,16 @@ void configGetCommand(client *c) { server.repl_slave_ignore_maxmemory); config_get_bool_field("stop-writes-on-bgsave-error", server.stop_writes_on_bgsave_err); +#endif config_get_bool_field("daemonize", server.daemonize); +#if __redis_unmodified_upstream // DIsable the replication API of Redis config_get_bool_field("rdbcompression", server.rdb_compression); config_get_bool_field("rdbchecksum", server.rdb_checksum); +#endif config_get_bool_field("activerehashing", server.activerehashing); config_get_bool_field("activedefrag", server.active_defrag_enabled); config_get_bool_field("protected-mode", server.protected_mode); +#if __redis_unmodified_upstream // Disable the replication API of Redis config_get_bool_field("repl-disable-tcp-nodelay", server.repl_disable_tcp_nodelay); config_get_bool_field("repl-diskless-sync", @@ -1455,16 +1515,19 @@ void configGetCommand(client *c) { server.aof_load_truncated); config_get_bool_field("aof-use-rdb-preamble", server.aof_use_rdb_preamble); +#endif config_get_bool_field("lazyfree-lazy-eviction", server.lazyfree_lazy_eviction); config_get_bool_field("lazyfree-lazy-expire", server.lazyfree_lazy_expire); config_get_bool_field("lazyfree-lazy-server-del", server.lazyfree_lazy_server_del); +#if __redis_unmodified_upstream // Disable the cluster API of Redis config_get_bool_field("slave-lazy-flush", server.repl_slave_lazy_flush); config_get_bool_field("replica-lazy-flush", server.repl_slave_lazy_flush); +#endif config_get_bool_field("dynamic-hz", server.dynamic_hz); @@ -1475,8 +1538,10 @@ void configGetCommand(client *c) { server.verbosity,loglevel_enum); config_get_enum_field("supervised", server.supervised_mode,supervised_mode_enum); +#if __redis_unmodified_upstream // Disable the replication API of Redis config_get_enum_field("appendfsync", server.aof_fsync,aof_fsync_enum); +#endif config_get_enum_field("syslog-facility", server.syslog_facility,syslog_facility_enum); @@ -1588,9 +1653,11 @@ int dictSdsKeyCaseCompare(void *privdata, const void *key1, const void *key2); void dictSdsDestructor(void *privdata, void *val); void dictListDestructor(void *privdata, void *val); +#if __redis_unmodified_upstream // Disable the sentinel mode /* Sentinel config rewriting is implemented inside sentinel.c by * rewriteConfigSentinelOption(). */ void rewriteConfigSentinelOption(struct rewriteConfigState *state); +#endif dictType optionToLineDictType = { dictSdsCaseHash, /* hash function */ @@ -1903,7 +1970,7 @@ void rewriteConfigDirOption(struct rewriteConfigState *state) { /* Rewrite the slaveof option. */ void rewriteConfigSlaveofOption(struct rewriteConfigState *state, char *option) { sds line; - +#if __redis_unmodified_upstream // Disable the cluster API of Redis /* If this is a master, we want all the slaveof config options * in the file to be removed. Note that if this is a cluster instance * we don't want a slaveof directive inside redis.conf. */ @@ -1911,6 +1978,8 @@ void rewriteConfigSlaveofOption(struct rewriteConfigState *state, char *option) rewriteConfigMarkAsProcessed(state,option); return; } +#endif + line = sdscatprintf(sdsempty(),"%s %s %d", option, server.masterhost, server.masterport); rewriteConfigRewriteLine(state,option,line,1); @@ -2123,15 +2192,19 @@ int rewriteConfig(char *path) { rewriteConfigYesNoOption(state,"daemonize",server.daemonize,0); rewriteConfigStringOption(state,"pidfile",server.pidfile,CONFIG_DEFAULT_PID_FILE); rewriteConfigNumericalOption(state,"port",server.port,CONFIG_DEFAULT_SERVER_PORT); +#if __redis_unmodified_upstream // Disable the cluster API of Redis rewriteConfigNumericalOption(state,"cluster-announce-port",server.cluster_announce_port,CONFIG_DEFAULT_CLUSTER_ANNOUNCE_PORT); rewriteConfigNumericalOption(state,"cluster-announce-bus-port",server.cluster_announce_bus_port,CONFIG_DEFAULT_CLUSTER_ANNOUNCE_BUS_PORT); +#endif rewriteConfigNumericalOption(state,"tcp-backlog",server.tcp_backlog,CONFIG_DEFAULT_TCP_BACKLOG); rewriteConfigBindOption(state); rewriteConfigStringOption(state,"unixsocket",server.unixsocket,NULL); rewriteConfigOctalOption(state,"unixsocketperm",server.unixsocketperm,CONFIG_DEFAULT_UNIX_SOCKET_PERM); rewriteConfigNumericalOption(state,"timeout",server.maxidletime,CONFIG_DEFAULT_CLIENT_TIMEOUT); rewriteConfigNumericalOption(state,"tcp-keepalive",server.tcpkeepalive,CONFIG_DEFAULT_TCP_KEEPALIVE); +#if __redis_unmodified_upstream // Disable the replication APi of Redis rewriteConfigNumericalOption(state,"replica-announce-port",server.slave_announce_port,CONFIG_DEFAULT_SLAVE_ANNOUNCE_PORT); +#endif rewriteConfigEnumOption(state,"loglevel",server.verbosity,loglevel_enum,CONFIG_DEFAULT_VERBOSITY); rewriteConfigStringOption(state,"logfile",server.logfile,CONFIG_DEFAULT_LOGFILE); rewriteConfigYesNoOption(state,"syslog-enabled",server.syslog_enabled,CONFIG_DEFAULT_SYSLOG_ENABLED); @@ -2139,12 +2212,15 @@ int rewriteConfig(char *path) { rewriteConfigSyslogfacilityOption(state); rewriteConfigSaveOption(state); rewriteConfigNumericalOption(state,"databases",server.dbnum,CONFIG_DEFAULT_DBNUM); +#if __redis_unmodified_upstream // Disable the replication API of Redis rewriteConfigYesNoOption(state,"stop-writes-on-bgsave-error",server.stop_writes_on_bgsave_err,CONFIG_DEFAULT_STOP_WRITES_ON_BGSAVE_ERROR); rewriteConfigYesNoOption(state,"rdbcompression",server.rdb_compression,CONFIG_DEFAULT_RDB_COMPRESSION); rewriteConfigYesNoOption(state,"rdbchecksum",server.rdb_checksum,CONFIG_DEFAULT_RDB_CHECKSUM); rewriteConfigStringOption(state,"dbfilename",server.rdb_filename,CONFIG_DEFAULT_RDB_FILENAME); +#endif rewriteConfigDirOption(state); rewriteConfigSlaveofOption(state,"replicaof"); +#if __redis_unmodified_upstream // Disable the replication API of Redis rewriteConfigStringOption(state,"replica-announce-ip",server.slave_announce_ip,CONFIG_DEFAULT_SLAVE_ANNOUNCE_IP); rewriteConfigStringOption(state,"masterauth",server.masterauth,NULL); rewriteConfigStringOption(state,"cluster-announce-ip",server.cluster_announce_ip,NULL); @@ -2161,6 +2237,7 @@ int rewriteConfig(char *path) { rewriteConfigNumericalOption(state,"replica-priority",server.slave_priority,CONFIG_DEFAULT_SLAVE_PRIORITY); rewriteConfigNumericalOption(state,"min-replicas-to-write",server.repl_min_slaves_to_write,CONFIG_DEFAULT_MIN_SLAVES_TO_WRITE); rewriteConfigNumericalOption(state,"min-replicas-max-lag",server.repl_min_slaves_max_lag,CONFIG_DEFAULT_MIN_SLAVES_MAX_LAG); +#endif rewriteConfigStringOption(state,"requirepass",server.requirepass,NULL); rewriteConfigNumericalOption(state,"maxclients",server.maxclients,CONFIG_DEFAULT_MAX_CLIENTS); rewriteConfigBytesOption(state,"maxmemory",server.maxmemory,CONFIG_DEFAULT_MAXMEMORY); @@ -2176,6 +2253,7 @@ int rewriteConfig(char *path) { rewriteConfigNumericalOption(state,"active-defrag-cycle-min",server.active_defrag_cycle_min,CONFIG_DEFAULT_DEFRAG_CYCLE_MIN); rewriteConfigNumericalOption(state,"active-defrag-cycle-max",server.active_defrag_cycle_max,CONFIG_DEFAULT_DEFRAG_CYCLE_MAX); rewriteConfigNumericalOption(state,"active-defrag-max-scan-fields",server.active_defrag_max_scan_fields,CONFIG_DEFAULT_DEFRAG_MAX_SCAN_FIELDS); +#if __redis_unmodified_upstream // Disable the replication API of Redis rewriteConfigYesNoOption(state,"appendonly",server.aof_state != AOF_OFF,0); rewriteConfigStringOption(state,"appendfilename",server.aof_filename,CONFIG_DEFAULT_AOF_FILENAME); rewriteConfigEnumOption(state,"appendfsync",server.aof_fsync,aof_fsync_enum,CONFIG_DEFAULT_AOF_FSYNC); @@ -2190,6 +2268,7 @@ int rewriteConfig(char *path) { rewriteConfigNumericalOption(state,"cluster-node-timeout",server.cluster_node_timeout,CLUSTER_DEFAULT_NODE_TIMEOUT); rewriteConfigNumericalOption(state,"cluster-migration-barrier",server.cluster_migration_barrier,CLUSTER_DEFAULT_MIGRATION_BARRIER); rewriteConfigNumericalOption(state,"cluster-replica-validity-factor",server.cluster_slave_validity_factor,CLUSTER_DEFAULT_SLAVE_VALIDITY); +#endif rewriteConfigNumericalOption(state,"slowlog-log-slower-than",server.slowlog_log_slower_than,CONFIG_DEFAULT_SLOWLOG_LOG_SLOWER_THAN); rewriteConfigNumericalOption(state,"latency-monitor-threshold",server.latency_monitor_threshold,CONFIG_DEFAULT_LATENCY_MONITOR_THRESHOLD); rewriteConfigNumericalOption(state,"slowlog-max-len",server.slowlog_max_len,CONFIG_DEFAULT_SLOWLOG_MAX_LEN); @@ -2209,19 +2288,25 @@ int rewriteConfig(char *path) { rewriteConfigYesNoOption(state,"protected-mode",server.protected_mode,CONFIG_DEFAULT_PROTECTED_MODE); rewriteConfigClientoutputbufferlimitOption(state); rewriteConfigNumericalOption(state,"hz",server.config_hz,CONFIG_DEFAULT_HZ); +#if __redis_unmodified_upstream // Disable the replication API of Redis rewriteConfigYesNoOption(state,"aof-rewrite-incremental-fsync",server.aof_rewrite_incremental_fsync,CONFIG_DEFAULT_AOF_REWRITE_INCREMENTAL_FSYNC); rewriteConfigYesNoOption(state,"rdb-save-incremental-fsync",server.rdb_save_incremental_fsync,CONFIG_DEFAULT_RDB_SAVE_INCREMENTAL_FSYNC); rewriteConfigYesNoOption(state,"aof-load-truncated",server.aof_load_truncated,CONFIG_DEFAULT_AOF_LOAD_TRUNCATED); rewriteConfigYesNoOption(state,"aof-use-rdb-preamble",server.aof_use_rdb_preamble,CONFIG_DEFAULT_AOF_USE_RDB_PREAMBLE); +#endif rewriteConfigEnumOption(state,"supervised",server.supervised_mode,supervised_mode_enum,SUPERVISED_NONE); rewriteConfigYesNoOption(state,"lazyfree-lazy-eviction",server.lazyfree_lazy_eviction,CONFIG_DEFAULT_LAZYFREE_LAZY_EVICTION); rewriteConfigYesNoOption(state,"lazyfree-lazy-expire",server.lazyfree_lazy_expire,CONFIG_DEFAULT_LAZYFREE_LAZY_EXPIRE); rewriteConfigYesNoOption(state,"lazyfree-lazy-server-del",server.lazyfree_lazy_server_del,CONFIG_DEFAULT_LAZYFREE_LAZY_SERVER_DEL); +#if __redis_unmodified_upstream // Disable the replication API of Redis rewriteConfigYesNoOption(state,"replica-lazy-flush",server.repl_slave_lazy_flush,CONFIG_DEFAULT_SLAVE_LAZY_FLUSH); +#endif rewriteConfigYesNoOption(state,"dynamic-hz",server.dynamic_hz,CONFIG_DEFAULT_DYNAMIC_HZ); +#if __redis_unmodified_upstream // Disable the sentinel mode of Redis /* Rewrite Sentinel config if in Sentinel mode. */ if (server.sentinel_mode) rewriteConfigSentinelOption(state); +#endif /* Step 3: remove all the orphaned lines in the old file, that is, lines * that were used by a config option and are no longer used, like in case diff --git a/src/config.h b/src/config.h index efa9d11f..0aed23fa 100644 --- a/src/config.h +++ b/src/config.h @@ -116,6 +116,7 @@ #define rdb_fsync_range(fd,off,size) fsync(fd) #endif +#if __redis_unmodified_upstream // Disable setprotitle /* Check if we can use setproctitle(). * BSD systems have support for it, we provide an implementation for * Linux and osx. */ @@ -129,6 +130,7 @@ void spt_init(int argc, char *argv[]); void setproctitle(const char *fmt, ...); #endif +#endif /* Byte ordering detection */ #include /* This will likely define BYTE_ORDER */ diff --git a/src/db.c b/src/db.c index 62c8aa13..bb52ee35 100644 --- a/src/db.c +++ b/src/db.c @@ -31,8 +31,14 @@ #include "cluster.h" #include "atomicvar.h" +#if __redis_unmodified_upstream // Disable possible syscalls from signal.h and some libs explicitly #include +#else #include +#include +#include +#include +#endif /*----------------------------------------------------------------------------- * C-level DB API @@ -57,6 +63,7 @@ robj *lookupKey(redisDb *db, robj *key, int flags) { if (de) { robj *val = dictGetVal(de); +#if __redis_unmodified_upstream // Disable replication API of Redis /* Update the access time for the ageing algorithm. * Don't do it if we have a saving child, as this will trigger * a copy on write madness. */ @@ -70,6 +77,19 @@ robj *lookupKey(redisDb *db, robj *key, int flags) { val->lru = LRU_CLOCK(); } } +#else + /* Update the access time for the ageing algorithm. + * Don't do it if we have a saving child, as this will trigger + * a copy on write madness. */ + if (!(flags & LOOKUP_NOTOUCH)) + { + if (server.maxmemory_policy & MAXMEMORY_FLAG_LFU) { + updateLFU(val); + } else { + val->lru = LRU_CLOCK(); + } + } +#endif return val; } else { return NULL; @@ -109,6 +129,7 @@ robj *lookupKeyReadWithFlags(redisDb *db, robj *key, int flags) { return NULL; } +#if __redis_unmodified_upstream // Disable the cluster API of Redis /* However if we are in the context of a slave, expireIfNeeded() will * not really try to expire the key, it only returns information * about the "logical" status of the key: key expiring is up to the @@ -129,6 +150,7 @@ robj *lookupKeyReadWithFlags(redisDb *db, robj *key, int flags) { server.stat_keyspace_misses++; return NULL; } +#endif } val = lookupKey(db,key,flags); if (val == NULL) @@ -175,10 +197,12 @@ void dbAdd(redisDb *db, robj *key, robj *val) { int retval = dictAdd(db->dict, copy, val); serverAssertWithInfo(NULL,key,retval == DICT_OK); +#if __redis_unmodified_upstream // Disable the blocked API of Redis if (val->type == OBJ_LIST || val->type == OBJ_ZSET) signalKeyAsReady(db, key); if (server.cluster_enabled) slotToKeyAdd(key); +#endif } /* Overwrite an existing key with a new value. Incrementing the reference @@ -197,10 +221,12 @@ void dbOverwrite(redisDb *db, robj *key, robj *val) { } dictSetVal(db->dict, de, val); +#if __redis_unmodified_upstream // Disable the lazy free API of Redis if (server.lazyfree_lazy_server_del) { freeObjAsync(old); dictSetVal(db->dict, &auxentry, NULL); } +#endif dictFreeVal(db->dict, &auxentry); } @@ -273,7 +299,9 @@ int dbSyncDelete(redisDb *db, robj *key) { * the key, because it is shared with the main dictionary. */ if (dictSize(db->expires) > 0) dictDelete(db->expires,key->ptr); if (dictDelete(db->dict,key->ptr) == DICT_OK) { +#if __redis_unmodified_upstream // Disable the cluster API of Redis if (server.cluster_enabled) slotToKeyDel(key); +#endif return 1; } else { return 0; @@ -283,8 +311,12 @@ int dbSyncDelete(redisDb *db, robj *key) { /* This is a wrapper whose behavior depends on the Redis lazy free * configuration. Deletes the key synchronously or asynchronously. */ int dbDelete(redisDb *db, robj *key) { +#if __redis_unmodified_upstream // Disable the lazy free API of Redis return server.lazyfree_lazy_server_del ? dbAsyncDelete(db,key) : dbSyncDelete(db,key); +#else + return dbSyncDelete(db,key); +#endif } /* Prepare the string object stored at 'key' to be modified destructively @@ -340,7 +372,9 @@ robj *dbUnshareStringValue(redisDb *db, robj *key, robj *o) { * database(s). Otherwise -1 is returned in the specific case the * DB number is out of range, and errno is set to EINVAL. */ long long emptyDb(int dbnum, int flags, void(callback)(void*)) { +#if __redis_unmodified_upstream // Disable the lazy free API of Redis int async = (flags & EMPTYDB_ASYNC); +#endif long long removed = 0; if (dbnum < -1 || dbnum >= server.dbnum) { @@ -358,13 +392,19 @@ long long emptyDb(int dbnum, int flags, void(callback)(void*)) { for (int j = startdb; j <= enddb; j++) { removed += dictSize(server.db[j].dict); +#if __redis_unmodified_upstream // Disable the lazy free API of Redis if (async) { emptyDbAsync(&server.db[j]); } else { dictEmpty(server.db[j].dict,callback); dictEmpty(server.db[j].expires,callback); } +#else + dictEmpty(server.db[j].dict,callback); + dictEmpty(server.db[j].expires,callback); +#endif } +#if __redis_unmodified_upstream // Disable the cluster API of Redis if (server.cluster_enabled) { if (async) { slotToKeyFlushAsync(); @@ -372,6 +412,7 @@ long long emptyDb(int dbnum, int flags, void(callback)(void*)) { slotToKeyFlush(); } } +#endif if (dbnum == -1) flushSlaveKeysWithExpireList(); return removed; } @@ -448,6 +489,7 @@ void flushallCommand(client *c) { signalFlushedDb(-1); server.dirty += emptyDb(-1,flags,NULL); addReply(c,shared.ok); +#if __redis_unmodified_upstream // Disable the replication API of Redis if (server.rdb_child_pid != -1) { kill(server.rdb_child_pid,SIGUSR1); rdbRemoveTempFile(server.rdb_child_pid); @@ -461,6 +503,7 @@ void flushallCommand(client *c) { rdbSave(server.rdb_filename,rsiptr); server.dirty = saved_dirty; } +#endif server.dirty++; } @@ -470,8 +513,12 @@ void delGenericCommand(client *c, int lazy) { for (j = 1; j < c->argc; j++) { expireIfNeeded(c->db,c->argv[j]); +#if __redis_unmodified_upstream // Disable the lazy free API of Redis int deleted = lazy ? dbAsyncDelete(c->db,c->argv[j]) : dbSyncDelete(c->db,c->argv[j]); +#else + int deleted = dbSyncDelete(c->db,c->argv[j]); +#endif if (deleted) { signalModifiedKey(c->db,c->argv[j]); notifyKeyspaceEvent(NOTIFY_GENERIC, @@ -509,11 +556,12 @@ void selectCommand(client *c) { if (getLongFromObjectOrReply(c, c->argv[1], &id, "invalid DB index") != C_OK) return; - +#if __redis_unmodified_upstream // Disable the cluster API of Redis if (server.cluster_enabled && id != 0) { addReplyError(c,"SELECT is not allowed in cluster mode"); return; } +#endif if (selectDb(c,id) == C_ERR) { addReplyError(c,"DB index is out of range"); } else { @@ -809,9 +857,11 @@ void dbsizeCommand(client *c) { addReplyLongLong(c,dictSize(c->db->dict)); } +#if __redis_unmodified_upstream // Disable replication API of Redis void lastsaveCommand(client *c) { addReplyLongLong(c,server.lastsave); } +#endif void typeCommand(client *c) { robj *o; @@ -839,6 +889,7 @@ void typeCommand(client *c) { } void shutdownCommand(client *c) { +#if __redis_unmodified_upstream // Disable the replication API of Redis int flags = 0; if (c->argc > 2) { @@ -860,10 +911,15 @@ void shutdownCommand(client *c) { * with half-read data). * * Also when in Sentinel mode clear the SAVE flag and force NOSAVE. */ +#if __redis_unmodified_upstream // Disable the replication API of Redis if (server.loading || server.sentinel_mode) flags = (flags & ~SHUTDOWN_SAVE) | SHUTDOWN_NOSAVE; if (prepareForShutdown(flags) == C_OK) exit(0); +#endif addReplyError(c,"Errors trying to SHUTDOWN. Check logs."); +#else + addReplyError(c,"Currently SHUTDOWN command isn't supported."); +#endif } void renameGenericCommand(client *c, int nx) { @@ -922,10 +978,12 @@ void moveCommand(client *c) { int srcid; long long dbid, expire; +#if __redis_unmodified_upstream // Disable cluster API of Redis if (server.cluster_enabled) { addReplyError(c,"MOVE is not allowed in cluster mode"); return; } +#endif /* Obtain source and target DB pointers */ src = c->db; @@ -971,6 +1029,7 @@ void moveCommand(client *c) { addReply(c,shared.cone); } +#if __redis_unmodified_upstream // Disable the blocked API of Redis /* Helper function for dbSwapDatabases(): scans the list of keys that have * one or more blocked clients for B[LR]POP or other blocking commands * and signal the keys as ready if they are of the right type. See the comment @@ -988,6 +1047,7 @@ void scanDatabaseForReadyLists(redisDb *db) { } dictReleaseIterator(di); } +#endif /* Swap two databases at runtime so that all clients will magically see * the new database even if already connected. Note that the client @@ -1015,6 +1075,7 @@ int dbSwapDatabases(int id1, int id2) { db2->expires = aux.expires; db2->avg_ttl = aux.avg_ttl; +#if __redis_unmodified_upstream // Disable the blocked API of Redis /* Now we need to handle clients blocked on lists: as an effect * of swapping the two DBs, a client that was waiting for list * X in a given DB, may now actually be unblocked if X happens @@ -1026,6 +1087,7 @@ int dbSwapDatabases(int id1, int id2) { * if needed. */ scanDatabaseForReadyLists(db1); scanDatabaseForReadyLists(db2); +#endif return C_OK; } @@ -1033,11 +1095,13 @@ int dbSwapDatabases(int id1, int id2) { void swapdbCommand(client *c) { long id1, id2; +#if __redis_unmodified_upstream // Disable the cluster API of Redis /* Not allowed in cluster mode: we have just DB 0 there. */ if (server.cluster_enabled) { addReplyError(c,"SWAPDB is not allowed in cluster mode"); return; } +#endif /* Get the two DBs indexes. */ if (getLongFromObjectOrReply(c, c->argv[1], &id1, @@ -1082,9 +1146,11 @@ void setExpire(client *c, redisDb *db, robj *key, long long when) { de = dictAddOrFind(db->expires,dictGetKey(kde)); dictSetSignedIntegerVal(de,when); +#if __redis_unmodified_upstream // Disable the cluster API of Redis int writable_slave = server.masterhost && server.repl_slave_ro == 0; if (c && writable_slave && !(c->flags & CLIENT_MASTER)) rememberSlaveKeyWithExpire(db,key); +#endif } /* Return the expire time of the specified key, or -1 if no expire @@ -1118,9 +1184,11 @@ void propagateExpire(redisDb *db, robj *key, int lazy) { incrRefCount(argv[0]); incrRefCount(argv[1]); +#if __redis_unmodified_upstream // Disable the replication API of Redis if (server.aof_state != AOF_OFF) feedAppendOnlyFile(server.delCommand,db->id,argv,2); replicationFeedSlaves(server.slaves,db->id,argv,2); +#endif decrRefCount(argv[0]); decrRefCount(argv[1]); @@ -1132,8 +1200,10 @@ int keyIsExpired(redisDb *db, robj *key) { if (when < 0) return 0; /* No expire for this key */ +#if __redis_unmodified_upstream // Disable the expire API of Redis /* Don't expire anything while loading. It will be done later. */ if (server.loading) return 0; +#endif /* If we are in the context of a Lua script, we pretend that time is * blocked to when the Lua script started. This way a key can expire @@ -1141,7 +1211,6 @@ int keyIsExpired(redisDb *db, robj *key) { * script execution, making propagation to slaves / AOF consistent. * See issue #1525 on Github for more information. */ mstime_t now = server.lua_caller ? server.lua_time_start : mstime(); - return now > when; } @@ -1182,8 +1251,12 @@ int expireIfNeeded(redisDb *db, robj *key) { propagateExpire(db,key,server.lazyfree_lazy_expire); notifyKeyspaceEvent(NOTIFY_EXPIRED, "expired",key,db->id); +#if __redis_unmodified_upstream // Disable the lazy free API of Redis return server.lazyfree_lazy_expire ? dbAsyncDelete(db,key) : dbSyncDelete(db,key); +#else + return dbSyncDelete(db,key); +#endif } /* ----------------------------------------------------------------------------- @@ -1238,6 +1311,7 @@ int *getKeysUsingCommandTable(struct redisCommand *cmd,robj **argv, int argc, in * This function uses the command table if a command-specific helper function * is not required, otherwise it calls the command-specific function. */ int *getKeysFromCommand(struct redisCommand *cmd, robj **argv, int argc, int *numkeys) { +#if __redis_unmodified_upstream // Disable the module API of Redis if (cmd->flags & CMD_MODULE_GETKEYS) { return moduleGetCommandKeysViaAPI(cmd,argv,argc,numkeys); } else if (!(cmd->flags & CMD_MODULE) && cmd->getkeys_proc) { @@ -1245,6 +1319,9 @@ int *getKeysFromCommand(struct redisCommand *cmd, robj **argv, int argc, int *nu } else { return getKeysUsingCommandTable(cmd,argv,argc,numkeys); } +#else + return getKeysUsingCommandTable(cmd,argv,argc,numkeys); +#endif } /* Free the result of getKeysFromCommand. */ @@ -1463,6 +1540,7 @@ int *xreadGetKeys(struct redisCommand *cmd, robj **argv, int argc, int *numkeys) return keys; } +#if __redis_unmodified_upstream // Disable the cluster API of Redis /* Slot to Key API. This is used by Redis Cluster in order to obtain in * a fast way a key that belongs to a specified hash slot. This is useful * while rehashing the cluster and in other conditions when we need to @@ -1547,3 +1625,4 @@ unsigned int delKeysInSlot(unsigned int hashslot) { unsigned int countKeysInSlot(unsigned int hashslot) { return server.cluster->slots_keys_count[hashslot]; } +#endif diff --git a/src/debug.c b/src/debug.c index 1ec7c497..f0e7f252 100644 --- a/src/debug.c +++ b/src/debug.c @@ -31,6 +31,7 @@ #include "sha1.h" /* SHA1 is used for DEBUG DIGEST */ #include "crc64.h" +#if __redis_unmodified_upstream // Disable the debug API of Redis #include #include #include @@ -353,7 +354,9 @@ NULL } else if (!strcasecmp(c->argv[1]->ptr,"log") && c->argc == 3) { serverLog(LL_WARNING, "DEBUG LOG: %s", (char*)c->argv[2]->ptr); addReply(c,shared.ok); - } else if (!strcasecmp(c->argv[1]->ptr,"reload")) { + } +#if __redis_unmodified_upstream // Disable the replication API of Redis + else if (!strcasecmp(c->argv[1]->ptr,"reload")) { rdbSaveInfo rsi, *rsiptr; rsiptr = rdbPopulateSaveInfo(&rsi); if (rdbSave(server.rdb_filename,rsiptr) != C_OK) { @@ -383,7 +386,9 @@ NULL server.dirty = 0; /* Prevent AOF / replication */ serverLog(LL_WARNING,"Append Only File loaded by DEBUG LOADAOF"); addReply(c,shared.ok); - } else if (!strcasecmp(c->argv[1]->ptr,"object") && c->argc == 3) { + } +#endif + else if (!strcasecmp(c->argv[1]->ptr,"object") && c->argc == 3) { dictEntry *de; robj *val; char *strenc; @@ -427,7 +432,7 @@ NULL nextra += used; remaining -= used; } - +#if __redis_unmodified_upstream // Disable the replication API of Redis addReplyStatusFormat(c, "Value at:%p refcount:%d " "encoding:%s serializedlength:%zu " @@ -435,6 +440,7 @@ NULL (void*)val, val->refcount, strenc, rdbSavedObjectLen(val), val->lru, estimateObjectIdleTime(val)/1000, extra); +#endif } else if (!strcasecmp(c->argv[1]->ptr,"sdslen") && c->argc == 3) { dictEntry *de; robj *val; @@ -543,12 +549,16 @@ NULL { server.active_expire_enabled = atoi(c->argv[2]->ptr); addReply(c,shared.ok); - } else if (!strcasecmp(c->argv[1]->ptr,"lua-always-replicate-commands") && + } +#if __redis_unmodified_upstream // Disable the replication API of Redis + else if (!strcasecmp(c->argv[1]->ptr,"lua-always-replicate-commands") && c->argc == 3) { server.lua_always_replicate_commands = atoi(c->argv[2]->ptr); addReply(c,shared.ok); - } else if (!strcasecmp(c->argv[1]->ptr,"error") && c->argc == 3) { + } +#endif + else if (!strcasecmp(c->argv[1]->ptr,"error") && c->argc == 3) { sds errstr = sdsnewlen("-",1); errstr = sdscatsds(errstr,c->argv[2]->ptr); @@ -617,8 +627,10 @@ NULL } } else if (!strcasecmp(c->argv[1]->ptr,"change-repl-id") && c->argc == 2) { serverLog(LL_WARNING,"Changing replication IDs after receiving DEBUG change-repl-id"); +#if __redis_unmodified_upstream // Disable of replication API of Redis changeReplicationId(); clearReplicationId2(); +#endif addReply(c,shared.ok); } else if (!strcasecmp(c->argv[1]->ptr,"stringmatch-test") && c->argc == 2) { @@ -629,7 +641,10 @@ NULL return; } } - +#else +#include +#include +#endif /* =========================== Crash handling ============================== */ void _serverAssert(const char *estr, const char *file, int line) { @@ -642,7 +657,11 @@ void _serverAssert(const char *estr, const char *file, int line) { server.assert_line = line; serverLog(LL_WARNING,"(forcing SIGSEGV to print the bug report.)"); #endif +#if __redis_unmodified_upstream // Use unreachable Wasm instructions instead of invalid pointer dereference *((char*)-1) = 'x'; +#else + __builtin_unreachable(); +#endif } void _serverAssertPrintClientInfo(const client *c) { @@ -720,7 +739,11 @@ void _serverPanic(const char *file, int line, const char *msg, ...) { serverLog(LL_WARNING,"(forcing SIGSEGV in order to print the stack trace)"); #endif serverLog(LL_WARNING,"------------------------------------------------"); +#if __redis_unmodified_upstream // Use unreachable Wasm instructions instead of invalid pointer dereference *((char*)-1) = 'x'; +#else + __builtin_unreachable(); +#endif } void bugReportStart(void) { @@ -731,6 +754,7 @@ void bugReportStart(void) { } } +#if __redis_unmodified_upstream // Disable the extended bugreport since there are no such capabilities in Wasm yet #ifdef HAVE_BACKTRACE static void *getMcontextEip(ucontext_t *uc) { #if defined(__APPLE__) && !defined(MAC_OS_X_VERSION_10_6) @@ -1334,8 +1358,10 @@ void sigsegvHandler(int sig, siginfo_t *info, void *secret) { " Suspect RAM error? Use redis-server --test-memory to verify it.\n\n" ); +#if __redis_unmodified_upstream // Disable the deamonization of Redis /* free(messages); Don't call free() with possibly corrupted memory. */ if (server.daemonize && server.supervised == 0) unlink(server.pidfile); +#endif /* Make sure we exit with the right signal at the end. So for instance * the core will be dumped if enabled. */ @@ -1444,3 +1470,4 @@ void disableWatchdog(void) { sigaction(SIGALRM, &act, NULL); server.watchdog_period = 0; } +#endif diff --git a/src/debugmacro.h b/src/debugmacro.h index ded2d266..4fdaed28 100644 --- a/src/debugmacro.h +++ b/src/debugmacro.h @@ -30,6 +30,7 @@ * POSSIBILITY OF SUCH DAMAGE. */ +#if __redis_unmodified_upstream // Disable writing to files #include #define D(...) \ do { \ @@ -39,3 +40,9 @@ fprintf(fp,"\n"); \ fclose(fp); \ } while (0); +#else +// TODO: add logs +#define D(...) \ + do { \ + } while (0); +#endif diff --git a/src/defrag.c b/src/defrag.c index d67b6e25..b9a10734 100644 --- a/src/defrag.c +++ b/src/defrag.c @@ -35,7 +35,9 @@ */ #include "server.h" +#if __redis_unmodified_upstream // Disable imports from time.h #include +#endif #include #include diff --git a/src/dict.c b/src/dict.c index 2cf9d483..876cb727 100644 --- a/src/dict.c +++ b/src/dict.c @@ -41,7 +41,11 @@ #include #include #include +#if __redis_unmodified_upstream // Disable imports from time.h #include +#else +#include "server.h" +#endif #include "dict.h" #include "zmalloc.h" @@ -230,21 +234,27 @@ int dictRehash(dict *d, int n) { return 1; } +#if __redis_unmodified_upstream // Currently it is impossible to get the current time inside a Wasm module long long timeInMilliseconds(void) { struct timeval tv; gettimeofday(&tv,NULL); return (((long long)tv.tv_sec)*1000)+(tv.tv_usec/1000); } +#endif /* Rehash for an amount of time between ms milliseconds and ms+1 milliseconds */ int dictRehashMilliseconds(dict *d, int ms) { +#if __redis_unmodified_upstream // Disable the lazy, time-oriented rehashing long long start = timeInMilliseconds(); +#endif int rehashes = 0; while(dictRehash(d,100)) { rehashes += 100; +#if __redis_unmodified_upstream // Disable the lazy, time-oriented rehashing if (timeInMilliseconds()-start > ms) break; +#endif } return rehashes; } @@ -489,7 +499,9 @@ dictEntry *dictFind(dict *d, const void *key) return he; he = he->next; } - if (!dictIsRehashing(d)) return NULL; + if (!dictIsRehashing(d)) { + return NULL; + } } return NULL; } diff --git a/src/evict.c b/src/evict.c index 773916ce..d5029d0f 100644 --- a/src/evict.c +++ b/src/evict.c @@ -34,6 +34,12 @@ #include "bio.h" #include "atomicvar.h" +#if __redis_unmodified_upstream // Include some libs explicitly +#else +#include +#include +#endif + /* ---------------------------------------------------------------------------- * Data structures * --------------------------------------------------------------------------*/ @@ -351,6 +357,7 @@ unsigned long LFUDecrAndReturn(robj *o) { * returns the sum of AOF and slaves buffer. */ size_t freeMemoryGetNotCountedMemory(void) { size_t overhead = 0; +#if __redis_unmodified_upstream // Disable the cluster API of Redis int slaves = listLength(server.slaves); if (slaves) { @@ -366,6 +373,7 @@ size_t freeMemoryGetNotCountedMemory(void) { if (server.aof_state != AOF_OFF) { overhead += sdsalloc(server.aof_buf)+aofRewriteBufferSize(); } +#endif return overhead; } @@ -446,17 +454,25 @@ int getMaxmemoryState(size_t *total, size_t *logical, size_t *tofree, float *lev int freeMemoryIfNeeded(void) { /* By default replicas should ignore maxmemory * and just be masters exact copies. */ +#if __redis_unmodified_upstream // Disable the cluster API of Redis if (server.masterhost && server.repl_slave_ignore_maxmemory) return C_OK; +#endif size_t mem_reported, mem_tofree, mem_freed; mstime_t latency, eviction_latency; long long delta; +#if __redis_unmodified_upstream // Disable the cluster API of Redis int slaves = listLength(server.slaves); +#else + int slaves = 0; +#endif /* When clients are paused the dataset should be static not just from the * POV of clients not being able to write, but also from the POV of * expires and evictions of keys not being performed. */ +#if __redis_unmodified_upstream // Disable the cluster API of Redis if (clientsArePaused()) return C_OK; +#endif if (getMaxmemoryState(&mem_reported,NULL,&mem_tofree,NULL) == C_OK) return C_OK; @@ -564,10 +580,14 @@ int freeMemoryIfNeeded(void) { * we only care about memory used by the key space. */ delta = (long long) zmalloc_used_memory(); latencyStartMonitor(eviction_latency); +#if __redis_unmodified_upstream // Disable the lazy free API of Redis if (server.lazyfree_lazy_eviction) dbAsyncDelete(db,keyobj); else dbSyncDelete(db,keyobj); +#else + dbSyncDelete(db,keyobj); +#endif latencyEndMonitor(eviction_latency); latencyAddSampleIfNeeded("eviction-del",eviction_latency); latencyRemoveNestedEvent(latency,eviction_latency); @@ -583,7 +603,9 @@ int freeMemoryIfNeeded(void) { * start spending so much time here that is impossible to * deliver data to the slaves fast enough, so we force the * transmission here inside the loop. */ +#if __redis_unmodified_upstream // Disable the cluster API of Redis if (slaves) flushSlavesOutputBuffers(); +#endif /* Normally our stop condition is the ability to release * a fixed, pre-computed amount of memory. However when we @@ -611,6 +633,7 @@ int freeMemoryIfNeeded(void) { return C_OK; cant_free: +#if __redis_unmodified_upstream // Disable the lazy memory freeing /* We are here if we are not able to reclaim memory. There is only one * last thing we can try: check if the lazyfree thread has jobs in queue * and wait... */ @@ -619,6 +642,7 @@ cant_free: break; usleep(1000); } +#endif return C_ERR; } @@ -630,6 +654,10 @@ cant_free: * */ int freeMemoryIfNeededAndSafe(void) { +#if __redis_unmodified_upstream // Disable the replication API of Redis if (server.lua_timedout || server.loading) return C_OK; +#else + if (server.lua_timedout) return C_OK; +#endif return freeMemoryIfNeeded(); } diff --git a/src/expire.c b/src/expire.c index 0b92ee3f..ec7c57b8 100644 --- a/src/expire.c +++ b/src/expire.c @@ -58,10 +58,14 @@ int activeExpireCycleTryExpire(redisDb *db, dictEntry *de, long long now) { robj *keyobj = createStringObject(key,sdslen(key)); propagateExpire(db,keyobj,server.lazyfree_lazy_expire); +#if __redis_unmodified_upstream // Disable the lazy free API of Redis if (server.lazyfree_lazy_expire) dbAsyncDelete(db,keyobj); else dbSyncDelete(db,keyobj); +#else + dbSyncDelete(db,keyobj); +#endif notifyKeyspaceEvent(NOTIFY_EXPIRED, "expired",keyobj,db->id); decrRefCount(keyobj); @@ -105,10 +109,12 @@ void activeExpireCycle(int type) { int dbs_per_call = CRON_DBS_PER_CALL; long long start = ustime(), timelimit, elapsed; +#if __redis_unmodified_upstream // Disable the cluster API of Redis /* When clients are paused the dataset should be static not just from the * POV of clients not being able to write, but also from the POV of * expires and evictions of keys not being performed. */ if (clientsArePaused()) return; +#endif if (type == ACTIVE_EXPIRE_CYCLE_FAST) { /* Don't start a fast cycle if the previous cycle did not exit @@ -424,11 +430,19 @@ void expireGenericCommand(client *c, long long basetime, int unit) { * * Instead we take the other branch of the IF statement setting an expire * (possibly in the past) and wait for an explicit DEL from the master. */ +#if __redis_unmodified_upstream // Disable the replication API of Redis if (when <= mstime() && !server.loading && !server.masterhost) { +#else + if (when <= mstime() && !server.masterhost) { +#endif robj *aux; +#if __redis_unmodified_upstream // Disable the lazy free API of Redis int deleted = server.lazyfree_lazy_expire ? dbAsyncDelete(c->db,key) : dbSyncDelete(c->db,key); +#else + int deleted = dbSyncDelete(c->db,key); +#endif serverAssertWithInfo(c,key,deleted); server.dirty++; diff --git a/src/geo.c b/src/geo.c index f1d3f18d..c5e74fef 100644 --- a/src/geo.c +++ b/src/geo.c @@ -31,6 +31,12 @@ #include "geo.h" #include "geohash_helper.h" #include "debugmacro.h" +#if __redis_unmodified_upstream // Include some libs explicitly +#else +#include +#include +#include +#endif /* Things exported from t_zset.c only for geo.c, since it is the only other * part of Redis that requires close zset introspection. */ diff --git a/src/hyperloglog.c b/src/hyperloglog.c index ba3a3ab6..fde5e372 100644 --- a/src/hyperloglog.c +++ b/src/hyperloglog.c @@ -33,6 +33,12 @@ #include #include +#if __redis_unmodified_upstream // Include some libs explicitly +#else +#include +#include +#include +#endif /* The Redis HyperLogLog implementation is based on the following ideas: * @@ -1036,7 +1042,7 @@ uint64_t hllCount(struct hllhdr *hdr, int *invalid) { z *= 0.5; } z += m * hllSigma(reghisto[0]/(double)m); - E = llroundl(HLL_ALPHA_INF*m*m/z); + E = lround(HLL_ALPHA_INF*m*m/z); return (uint64_t) E; } diff --git a/src/latency.c b/src/latency.c index 97e6a702..ca009574 100644 --- a/src/latency.c +++ b/src/latency.c @@ -34,6 +34,12 @@ */ #include "server.h" +#if __redis_unmodified_upstream // Include some libs explicitly +#else +#include +#include +#include +#endif /* Dictionary type for latency events. */ int dictStringKeyCompare(void *privdata, const void *key1, const void *key2) { @@ -58,6 +64,7 @@ dictType latencyTimeSeriesDictType = { /* ------------------------- Utility functions ------------------------------ */ +#if __redis_unmodified_upstream // Disable writing to file #ifdef __linux__ /* Returns 1 if Transparent Huge Pages support is enabled in the kernel. * Otherwise (or if we are unable to check) 0 is returned. */ @@ -74,6 +81,7 @@ int THPIsEnabled(void) { return (strstr(buf,"[never]") == NULL) ? 1 : 0; } #endif +#endif /* Report the amount of AnonHugePages in smap, in bytes. If the return * value of the function is non-zero, the process is being targeted by @@ -97,7 +105,11 @@ void latencyMonitorInit(void) { * server.latency_monitor_threshold. */ void latencyAddSample(char *event, mstime_t latency) { struct latencyTimeSeries *ts = dictFetchValue(server.latency_events,event); +#if __redis_unmodified_upstream // Currently it is impossible to get the current time inside a Wasm module time_t now = time(NULL); +#else + time_t now = ustime(); +#endif int prev; /* Create the time series if it does not exist. */ @@ -120,7 +132,11 @@ void latencyAddSample(char *event, mstime_t latency) { return; } +#if __redis_unmodified_upstream // Currently it is impossible to get the current time inside a Wasm module ts->samples[ts->idx].time = time(NULL); +#else + ts->samples[ts->idx].time = ustime(); +#endif ts->samples[ts->idx].latency = latency; ts->idx++; @@ -196,7 +212,11 @@ void analyzeLatencyForEvent(char *event, struct latencyStats *ls) { * the second a range of seconds. */ if (ls->samples) { ls->avg = sum / ls->samples; +#if __redis_unmodified_upstream // Currently it is impossible to get the current time inside a Wasm module ls->period = time(NULL) - ls->period; +#else + ls->period = ustime() - ls->period; +#endif if (ls->period == 0) ls->period = 1; } @@ -442,11 +462,11 @@ sds createLatencyReport(void) { if (advise_no_appendfsync) { report = sdscat(report,"- Assuming from the point of view of data safety this is viable in your environment, you could try to enable the 'no-appendfsync-on-rewrite' option, so that fsync will not be performed while there is a child rewriting the AOF file or producing an RDB file (the moment where there is high disk contention).\n"); } - +#if __redis_unmodified_upstream // Disable the replication API of Redis if (advise_relax_fsync_policy && server.aof_fsync == AOF_FSYNC_ALWAYS) { report = sdscat(report,"- Your fsync policy is set to 'always'. It is very hard to get good performances with such a setup, if possible try to relax the fsync policy to 'onesec'.\n"); } - +#endif if (advise_write_load_info) { report = sdscat(report,"- Latency during the AOF atomic rename operation or when the final difference is flushed to the AOF file at the end of the rewrite, sometimes is caused by very high write load, causing the AOF buffer to get very large. If possible try to send less commands to accomplish the same work, or use Lua scripts to group multiple operations into a single EVALSHA call.\n"); } @@ -535,7 +555,11 @@ sds latencyCommandGenSparkeline(char *event, struct latencyTimeSeries *ts) { } /* Use as label the number of seconds / minutes / hours / days * ago the event happened. */ +#if __redis_unmodified_upstream // Currently it is impossible to get the current time inside a Wasm module elapsed = time(NULL) - ts->samples[i].time; +#else + elapsed = ustime() - ts->samples[i].time; +#endif if (elapsed < 60) snprintf(buf,sizeof(buf),"%ds",elapsed); else if (elapsed < 3600) diff --git a/src/lolwut5.c b/src/lolwut5.c index 8408b378..1b7ef58c 100644 --- a/src/lolwut5.c +++ b/src/lolwut5.c @@ -36,6 +36,12 @@ #include "server.h" #include +#if __redis_unmodified_upstream // Include some libs explicitly +#else +#include +#include +#endif + /* This structure represents our canvas. Drawing functions will take a pointer * to a canvas to write to it. Later the canvas can be rendered to a string * suitable to be printed on the screen, using unicode Braille characters. */ diff --git a/src/module.c b/src/module.c index b8498ad9..8e95cd87 100644 --- a/src/module.c +++ b/src/module.c @@ -676,8 +676,10 @@ int commandFlagsFromString(char *s) { int RM_CreateCommand(RedisModuleCtx *ctx, const char *name, RedisModuleCmdFunc cmdfunc, const char *strflags, int firstkey, int lastkey, int keystep) { int flags = strflags ? commandFlagsFromString((char*)strflags) : 0; if (flags == -1) return REDISMODULE_ERR; +#if __redis_unmodified_upstream // Disable the module API of Redis if ((flags & CMD_MODULE_NO_CLUSTER) && server.cluster_enabled) return REDISMODULE_ERR; +#endif struct redisCommand *rediscmd; RedisModuleCommandProxy *cp; @@ -1428,8 +1430,10 @@ int RM_GetContextFlags(RedisModuleCtx *ctx) { flags |= REDISMODULE_CTX_FLAGS_REPLICATED; } +#if __redis_unmodified_upstream // Disable the cluser API of Redis if (server.cluster_enabled) flags |= REDISMODULE_CTX_FLAGS_CLUSTER; +#endif /* Maxmemory and eviction policy */ if (server.maxmemory > 0) { @@ -1439,6 +1443,7 @@ int RM_GetContextFlags(RedisModuleCtx *ctx) { flags |= REDISMODULE_CTX_FLAGS_EVICT; } +#if __redis_unmodified_upstream // Disable the replication and cluster API of Redis /* Persistence flags */ if (server.aof_state != AOF_OFF) flags |= REDISMODULE_CTX_FLAGS_AOF; @@ -1453,6 +1458,7 @@ int RM_GetContextFlags(RedisModuleCtx *ctx) { if (server.repl_slave_ro) flags |= REDISMODULE_CTX_FLAGS_READONLY; } +#endif /* OOM flag. */ float level; @@ -2752,6 +2758,7 @@ RedisModuleCallReply *RM_Call(RedisModuleCtx *ctx, const char *cmdname, const ch goto cleanup; } +#if __redis_unmodified_upstream // Disable the cluster API of Redis /* If this is a Redis Cluster node, we need to make sure the module is not * trying to access non-local keys, with the exception of commands * received from our master. */ @@ -2766,6 +2773,7 @@ RedisModuleCallReply *RM_Call(RedisModuleCtx *ctx, const char *cmdname, const ch goto cleanup; } } +#endif /* If we are using single commands replication, we need to wrap what * we propagate into a MULTI/EXEC block, so that it will be atomic like @@ -3087,6 +3095,7 @@ void *RM_ModuleTypeGetValue(RedisModuleKey *key) { return mv->value; } +#if __redis_unmodified_upstream // Disable the replication API of Redis /* -------------------------------------------------------------------------- * RDB loading and saving functions * -------------------------------------------------------------------------- */ @@ -3306,6 +3315,7 @@ loaderr: moduleRDBLoadError(io); return 0; /* Never reached. */ } +#endif /* -------------------------------------------------------------------------- * Key digest API (DEBUG DIGEST interface for modules types) @@ -3367,6 +3377,7 @@ void RM_DigestEndSequence(RedisModuleDigest *md) { memset(md->o,0,sizeof(md->o)); } +#if __redis_unmodified_upstream // Disable the replication API of Redis /* -------------------------------------------------------------------------- * AOF API for modules data types * -------------------------------------------------------------------------- */ @@ -3421,6 +3432,7 @@ void RM_EmitAOF(RedisModuleIO *io, const char *cmdname, const char *fmt, ...) { zfree(argv); return; } +#endif /* -------------------------------------------------------------------------- * IO context handling @@ -3499,6 +3511,7 @@ void RM_LogIOError(RedisModuleIO *io, const char *levelstr, const char *fmt, ... va_end(ap); } +#if __redis_unmodified_upstream // Disable the blocking API of Redis /* -------------------------------------------------------------------------- * Blocking clients from modules * -------------------------------------------------------------------------- */ @@ -3793,6 +3806,7 @@ RedisModuleBlockedClient *RM_GetBlockedClientHandle(RedisModuleCtx *ctx) { int RM_BlockedClientDisconnected(RedisModuleCtx *ctx) { return (ctx->flags & REDISMODULE_CTX_BLOCKED_DISCONNECTED) != 0; } +#endif /* -------------------------------------------------------------------------- * Thread Safe Contexts @@ -3977,6 +3991,7 @@ void moduleUnsubscribeNotifications(RedisModule *module) { } } +#if __redis_unmodified_upstream // Disable the cluster API of Redis /* -------------------------------------------------------------------------- * Modules Cluster API * -------------------------------------------------------------------------- */ @@ -4229,6 +4244,7 @@ void RM_SetClusterFlags(RedisModuleCtx *ctx, uint64_t flags) { if (flags & REDISMODULE_CLUSTER_FLAG_NO_REDIRECTION) server.cluster_module_flags |= CLUSTER_MODULE_FLAG_NO_REDIRECTION; } +#endif /* -------------------------------------------------------------------------- * Modules Timers API @@ -5136,6 +5152,7 @@ void moduleRegisterCoreAPI(void) { REGISTER_API(ModuleTypeSetValue); REGISTER_API(ModuleTypeGetType); REGISTER_API(ModuleTypeGetValue); +#if __redis_unmodified_upstream // Disable the replication API of Redis REGISTER_API(SaveUnsigned); REGISTER_API(LoadUnsigned); REGISTER_API(SaveSigned); @@ -5149,18 +5166,21 @@ void moduleRegisterCoreAPI(void) { REGISTER_API(SaveFloat); REGISTER_API(LoadFloat); REGISTER_API(EmitAOF); +#endif REGISTER_API(Log); REGISTER_API(LogIOError); REGISTER_API(StringAppendBuffer); REGISTER_API(RetainString); REGISTER_API(StringCompare); REGISTER_API(GetContextFromIO); +#if __redis_unmodified_upstream // Disable the blocking API of Redis REGISTER_API(BlockClient); REGISTER_API(UnblockClient); REGISTER_API(IsBlockedReplyRequest); REGISTER_API(IsBlockedTimeoutRequest); REGISTER_API(GetBlockedClientPrivateData); REGISTER_API(AbortBlock); +#endif REGISTER_API(Milliseconds); REGISTER_API(GetThreadSafeContext); REGISTER_API(FreeThreadSafeContext); @@ -5170,22 +5190,28 @@ void moduleRegisterCoreAPI(void) { REGISTER_API(DigestAddLongLong); REGISTER_API(DigestEndSequence); REGISTER_API(SubscribeToKeyspaceEvents); +#if __redis_unmodified_upstream // Disable the cluster API of Redis REGISTER_API(RegisterClusterMessageReceiver); REGISTER_API(SendClusterMessage); REGISTER_API(GetClusterNodeInfo); REGISTER_API(GetClusterNodesList); REGISTER_API(FreeClusterNodesList); +#endif REGISTER_API(CreateTimer); REGISTER_API(StopTimer); REGISTER_API(GetTimerInfo); +#if __redis_unmodified_upstream // Disable the cluster API of Redis REGISTER_API(GetMyClusterID); REGISTER_API(GetClusterSize); +#endif REGISTER_API(GetRandomBytes); REGISTER_API(GetRandomHexChars); +#if __redis_unmodified_upstream // Disable the cluster API of Redis REGISTER_API(BlockedClientDisconnected); REGISTER_API(SetDisconnectCallback); REGISTER_API(GetBlockedClientHandle); REGISTER_API(SetClusterFlags); +#endif REGISTER_API(CreateDict); REGISTER_API(FreeDict); REGISTER_API(DictSize); diff --git a/src/multi.c b/src/multi.c index 5971f465..ca3d242d 100644 --- a/src/multi.c +++ b/src/multi.c @@ -28,6 +28,10 @@ */ #include "server.h" +#if __redis_unmodified_upstream // Include some libs explicitly +#else +#include +#endif /* ================================ MULTI/EXEC ============================== */ @@ -139,6 +143,7 @@ void execCommand(client *c) { goto handle_monitor; } +#if __redis_unmodified_upstream // Disable the cluster API of Redis /* If there are write commands inside the transaction, and this is a read * only slave, we want to send an error. This happens when the transaction * was initiated when the instance was a master or a writable replica and @@ -153,7 +158,7 @@ void execCommand(client *c) { discardTransaction(c); goto handle_monitor; } - +#endif /* Exec all the queued commands */ unwatchAllKeys(c); /* Unwatch ASAP otherwise we'll waste CPU cycles */ orig_argv = c->argv; @@ -175,7 +180,11 @@ void execCommand(client *c) { must_propagate = 1; } +#if __redis_unmodified_upstream // Disable the cluster API of Redis call(c,server.loading ? CMD_CALL_NONE : CMD_CALL_FULL); +#else + call(c, CMD_CALL_FULL); +#endif /* Commands may alter argc/argv, restore mstate. */ c->mstate.commands[j].argc = c->argc; @@ -187,11 +196,13 @@ void execCommand(client *c) { c->cmd = orig_cmd; discardTransaction(c); +#if __redis_unmodified_upstream // Disable the cluster API of Redis /* Make sure the EXEC command will be propagated as well if MULTI * was already propagated. */ if (must_propagate) { int is_master = server.masterhost == NULL; server.dirty++; + /* If inside the MULTI/EXEC block this instance was suddenly * switched from master to slave (using the SLAVEOF command), the * initial MULTI was propagated into the replication backlog, but the @@ -211,6 +222,10 @@ handle_monitor: * table, and we do it here with correct ordering. */ if (listLength(server.monitors) && !server.loading) replicationFeedMonitors(c,server.monitors,c->db->id,c->argv,c->argc); +#else +handle_monitor: + return; +#endif } /* ===================== WATCH (CAS alike for MULTI/EXEC) =================== diff --git a/src/networking.c b/src/networking.c index 74b857e0..3c9e138e 100644 --- a/src/networking.c +++ b/src/networking.c @@ -29,9 +29,14 @@ #include "server.h" #include "atomicvar.h" +#if __redis_unmodified_upstream // Disable imports from uio.h and include some libs explicitly #include +#else #include #include +#include +#include +#endif static void setProtocolError(const char *errstr, client *c); @@ -85,6 +90,7 @@ void linkClient(client *c) { client *createClient(int fd) { client *c = zmalloc(sizeof(client)); +#if __redis_unmodified_upstream // Disable the net API of Redis /* passing -1 as fd it is possible to create a non connected client. * This is useful since all the commands needs to be executed * in the context of a client. When commands are executed in other @@ -102,6 +108,7 @@ client *createClient(int fd) { return NULL; } } +#endif selectDb(c,0); uint64_t client_id; @@ -124,6 +131,7 @@ client *createClient(int fd) { c->flags = 0; c->ctime = c->lastinteraction = server.unixtime; c->authenticated = 0; +#if __redis_unmodified_upstream // Disable the replication API of Redis c->replstate = REPL_STATE_NONE; c->repl_put_online_on_ack = 0; c->reploff = 0; @@ -133,6 +141,7 @@ client *createClient(int fd) { c->slave_listening_port = 0; c->slave_ip[0] = '\0'; c->slave_capa = SLAVE_CAPA_NONE; +#endif c->reply = listCreate(); c->reply_bytes = 0; c->obuf_soft_limit_reached_time = 0; @@ -147,7 +156,9 @@ client *createClient(int fd) { c->bpop.xread_group_noack = 0; c->bpop.numreplicas = 0; c->bpop.reploffset = 0; +#if __redis_unmodified_upstream // Disable the replication API of Redis c->woff = 0; +#endif c->watched_keys = listCreate(); c->pubsub_channels = dictCreate(&objectKeyPointerValueDictType,NULL); c->pubsub_patterns = listCreate(); @@ -160,6 +171,7 @@ client *createClient(int fd) { return c; } +#if __redis_unmodified_upstream // Disable the replication API of Redis /* This funciton puts the client in the queue of clients that should write * their output buffers to the socket. Note that it does not *yet* install * the write handler, to start clients are put in a queue of clients that need @@ -185,6 +197,7 @@ void clientInstallWriteHandler(client *c) { listAddNodeHead(server.clients_pending_write,c); } } +#endif /* This function is called every time we are going to transmit new data * to the client. The behavior is the following: @@ -209,6 +222,7 @@ void clientInstallWriteHandler(client *c) { * data to the clients output buffers. If the function returns C_ERR no * data should be appended to the output buffers. */ int prepareClientToWrite(client *c) { +#if __redis_unmodified_upstream // Client has to be able to write output /* If it's the Lua client we always return ok without installing any * handler since there is no socket at all. */ if (c->flags & (CLIENT_LUA|CLIENT_MODULE)) return C_OK; @@ -226,6 +240,7 @@ int prepareClientToWrite(client *c) { /* Schedule the client to write the output buffers to the socket, unless * it should already be setup to do so (it has already pending data). */ if (!clientHasPendingReplies(c)) clientInstallWriteHandler(c); +#endif /* Authorize the caller to queue in the output buffer of this client. */ return C_OK; @@ -295,6 +310,7 @@ void _addReplyStringToList(client *c, const char *s, size_t len) { /* Add the object 'obj' string representation to the client output buffer. */ void addReply(client *c, robj *obj) { + if (prepareClientToWrite(c) != C_OK) return; if (sdsEncodedObject(obj)) { @@ -337,7 +353,7 @@ void addReplySds(client *c, sds s) { void addReplyString(client *c, const char *s, size_t len) { if (prepareClientToWrite(c) != C_OK) return; if (_addReplyToBuffer(c,s,len) != C_OK) - _addReplyStringToList(c,s,len); + _addReplyStringToList(c, s, len); } /* Low level function called by the addReplyError...() functions. @@ -471,6 +487,7 @@ void setDeferredMultiBulkLength(client *c, void *node, long length) { void addReplyDouble(client *c, double d) { char dbuf[128], sbuf[128]; int dlen, slen; + if (isinf(d)) { /* Libc in odd systems (Hi Solaris!) will format infinite in a * different way, so better to handle it in an explicit way. */ @@ -646,6 +663,7 @@ int clientHasPendingReplies(client *c) { return c->bufpos || listLength(c->reply); } +#if __redis_unmodified_upstream // Disable the net API of Redis #define MAX_ACCEPTS_PER_CALL 1000 static void acceptCommonHandler(int fd, int flags, char *ip) { client *c; @@ -755,8 +773,9 @@ void acceptUnixHandler(aeEventLoop *el, int fd, void *privdata, int mask) { acceptCommonHandler(cfd,CLIENT_UNIX_SOCKET,NULL); } } +#endif -static void freeClientArgv(client *c) { +void freeClientArgv(client *c) { int j; for (j = 0; j < c->argc; j++) decrRefCount(c->argv[j]); @@ -764,6 +783,7 @@ static void freeClientArgv(client *c) { c->cmd = NULL; } +#if __redis_unmodified_upstream // Disable the cluster API of Redis /* Close all the slaves connections. This is useful in chained replication * when we resync with our own master and want to force all our slaves to * resync with us as well. */ @@ -773,6 +793,7 @@ void disconnectSlaves(void) { freeClient((client*)ln->value); } } +#endif /* Remove the specified client from global lists where the client could * be referenced, not including the Pub/Sub channels. @@ -783,6 +804,7 @@ void unlinkClient(client *c) { /* If this is marked as current client unset it. */ if (server.current_client == c) server.current_client = NULL; +#if __redis_unmodified_upstream // Disable the net API of Redis /* Certain operations must be done only if the client has an active socket. * If the client was already unlinked or if it's a "fake client" the * fd is already set to -1. */ @@ -809,6 +831,7 @@ void unlinkClient(client *c) { listDelNode(server.clients_pending_write,ln); c->flags &= ~CLIENT_PENDING_WRITE; } +#endif /* When client was just unblocked because of a blocking operation, * remove it from the list of unblocked clients. */ @@ -821,6 +844,7 @@ void unlinkClient(client *c) { } void freeClient(client *c) { +#if __redis_unmodified_upstream // Disable client freeing listNode *ln; /* If a client is protected, yet we need to free it right now, make sure @@ -918,19 +942,22 @@ void freeClient(client *c) { freeClientMultiState(c); sdsfree(c->peerid); zfree(c); +#endif } - /* Schedule a client to free it at a safe time in the serverCron() function. * This function is useful when we need to terminate a client but we are in * a context where calling freeClient() is not possible, because the client * should be valid for the continuation of the flow of the program. */ void freeClientAsync(client *c) { +#if __redis_unmodified_upstream // Disable client freeing if (c->flags & CLIENT_CLOSE_ASAP || c->flags & CLIENT_LUA) return; c->flags |= CLIENT_CLOSE_ASAP; listAddNodeTail(server.clients_to_close,c); +#endif } void freeClientsInAsyncFreeQueue(void) { +#if __redis_unmodified_upstream // Disable client freeing while (listLength(server.clients_to_close)) { listNode *ln = listFirst(server.clients_to_close); client *c = listNodeValue(ln); @@ -939,6 +966,7 @@ void freeClientsInAsyncFreeQueue(void) { freeClient(c); listDelNode(server.clients_to_close,ln); } +#endif } /* Return a client by ID, or NULL if the client ID is not in the set @@ -950,6 +978,7 @@ client *lookupClientByID(uint64_t id) { return (c == raxNotFound) ? NULL : c; } +#if __redis_unmodified_upstream // Disable the net API of Redis /* Write data in output buffers to client. Return C_OK if the client * is still valid after the call, C_ERR if it was freed. */ int writeToClient(int fd, client *c, int handler_installed) { @@ -1082,6 +1111,7 @@ int handleClientsWithPendingWrites(void) { * so that in the middle of receiving the query, and serving it * to the client, we'll call beforeSleep() that will do the * actual fsync of AOF to disk. AE_BARRIER ensures that. */ +#if __redis_unmodified_upstream // Disable the replication API of Redis if (server.aof_state == AOF_ON && server.aof_fsync == AOF_FSYNC_ALWAYS) { @@ -1092,10 +1122,12 @@ int handleClientsWithPendingWrites(void) { { freeClientAsync(c); } +#endif } } return processed; } +#endif /* resetClient prepare the client to process the next command */ void resetClient(client *c) { @@ -1106,10 +1138,12 @@ void resetClient(client *c) { c->multibulklen = 0; c->bulklen = -1; +#if __redis_unmodified_upstream // Disable the cluster API of Redis /* We clear the ASKING flag as well if we are not inside a MULTI, and * if what we just executed is not the ASKING command itself. */ if (!(c->flags & CLIENT_MULTI) && prevcmd != askingCommand) c->flags &= ~CLIENT_ASKING; +#endif /* Remove the CLIENT_REPLY_SKIP flag if any so that the reply * to the next command will be sent, but set the flag if the command @@ -1121,6 +1155,7 @@ void resetClient(client *c) { } } +#if __redis_unmodified_upstream // Disable the event engine and net API of Redis /* This funciton is used when we want to re-enter the event loop but there * is the risk that the client we are dealing with will be freed in some * way. This happens for instance in: @@ -1145,9 +1180,12 @@ void unprotectClient(client *c) { if (c->flags & CLIENT_PROTECTED) { c->flags &= ~CLIENT_PROTECTED; aeCreateFileEvent(server.el,c->fd,AE_READABLE,readQueryFromClient,c); +#if __redis_unmodified_upstream // Disable the cluster API of Redis if (clientHasPendingReplies(c)) clientInstallWriteHandler(c); +#endif } } +#endif /* Like processMultibulkBuffer(), but for the inline protocol instead of RESP, * this function consumes the client query buffer and creates a command ready @@ -1189,11 +1227,13 @@ int processInlineBuffer(client *c) { return C_ERR; } +#if __redis_unmodified_upstream // Disable the replication API of Redis /* Newline from slaves can be used to refresh the last ACK time. * This is useful for a slave to ping back while loading a big * RDB file. */ if (querylen == 0 && c->flags & CLIENT_SLAVE) c->repl_ack_time = server.unixtime; +#endif /* Move querybuffer position to the next query in the buffer. */ c->qb_pos += querylen+linefeed_chars; @@ -1402,6 +1442,7 @@ void processInputBuffer(client *c) { /* Keep processing while there is something in the input buffer */ while(c->qb_pos < sdslen(c->querybuf)) { +#if __redis_unmodified_upstream // Disable the cluster API of Redis /* Return if clients are paused. */ if (!(c->flags & CLIENT_SLAVE) && clientsArePaused()) break; @@ -1413,6 +1454,7 @@ void processInputBuffer(client *c) { * stream (instead of replying -BUSY like we do with other clients) and * later resume the processing. */ if (server.lua_timedout && c->flags & CLIENT_MASTER) break; +#endif /* CLIENT_CLOSE_AFTER_REPLY closes the connection once the reply is * written to the client. Make sure to not let the reply grow after @@ -1444,6 +1486,8 @@ void processInputBuffer(client *c) { } else { /* Only reset the client when the command was executed. */ if (processCommand(c) == C_OK) { + // TODO: check the interconnection between CLIENT_MULTI and reploff +#if __redis_unmodified_upstream // Disable the replication API of Redis if (c->flags & CLIENT_MASTER && !(c->flags & CLIENT_MULTI)) { /* Update the applied replication offset of our master. */ c->reploff = c->read_reploff - sdslen(c->querybuf) + c->qb_pos; @@ -1455,6 +1499,7 @@ void processInputBuffer(client *c) { * The client will be reset in unblockClientFromModule(). */ if (!(c->flags & CLIENT_BLOCKED) || c->btype != BLOCKED_MODULE) resetClient(c); +#endif } /* freeMemoryIfNeeded may flush slave output buffers. This may * result into a slave, that may be the active client, to be @@ -1472,6 +1517,7 @@ void processInputBuffer(client *c) { server.current_client = NULL; } +#if __redis_unmodified_upstream // Disable the replication API of Redis /* This is a wrapper for processInputBuffer that also cares about handling * the replication forwarding to the sub-slaves, in case the client 'c' * is flagged as master. Usually you want to call this instead of the @@ -1490,14 +1536,21 @@ void processInputBufferAndReplicate(client *c) { } } } +#endif +#if __redis_unmodified_upstream // Disable the event engine of Redis void readQueryFromClient(aeEventLoop *el, int fd, void *privdata, int mask) { client *c = (client*) privdata; int nread, readlen; size_t qblen; UNUSED(el); UNUSED(mask); - +#else +void readQueryFromClient(client *c, int mask, const char *request, int req_length) { + int nread, readlen; + size_t qblen; + UNUSED(mask); +#endif readlen = PROTO_IOBUF_LEN; /* If this is a multi bulk request, and we are processing a bulk reply * that is large enough, try to maximize the probability that the query @@ -1518,6 +1571,7 @@ void readQueryFromClient(aeEventLoop *el, int fd, void *privdata, int mask) { qblen = sdslen(c->querybuf); if (c->querybuf_peak < qblen) c->querybuf_peak = qblen; c->querybuf = sdsMakeRoomFor(c->querybuf, readlen); +#if __redis_unmodified_upstream // Disable the net API of Redis nread = read(fd, c->querybuf+qblen, readlen); if (nread == -1) { if (errno == EAGAIN) { @@ -1538,11 +1592,23 @@ void readQueryFromClient(aeEventLoop *el, int fd, void *privdata, int mask) { c->pending_querybuf = sdscatlen(c->pending_querybuf, c->querybuf+qblen,nread); } +#else + nread = readlen < req_length ? readlen : req_length; + memcpy(c->querybuf+qblen, request, nread); +#endif sdsIncrLen(c->querybuf,nread); c->lastinteraction = server.unixtime; +#if __redis_unmodified_upstream // Disable the replication API of Redis if (c->flags & CLIENT_MASTER) c->read_reploff += nread; +#endif server.stat_net_input_bytes += nread; + +#if __redis_unmodified_upstream // Add some additional logging +#else + serverLog(1, "readlen = %d, req_length = %d, nread = %d, server.client_max_querybuf_len = %zu, sdslen(c->querybuf) = %zu\n", readlen, req_length, nread, server.client_max_querybuf_len, sdslen(c->querybuf)); +#endif + if (sdslen(c->querybuf) > server.client_max_querybuf_len) { sds ci = catClientInfoString(sdsempty(),c), bytes = sdsempty(); @@ -1554,6 +1620,7 @@ void readQueryFromClient(aeEventLoop *el, int fd, void *privdata, int mask) { return; } +#if __redis_unmodified_upstream // Disable the replication API of Redis /* Time to process the buffer. If the client is a master we need to * compute the difference between the applied offset before and after * processing the buffer, to understand how much of the replication stream @@ -1561,6 +1628,9 @@ void readQueryFromClient(aeEventLoop *el, int fd, void *privdata, int mask) { * corresponding part of the replication stream, will be propagated to * the sub-slaves and to the replication backlog. */ processInputBufferAndReplicate(c); +#else + processInputBuffer(c); +#endif } void getClientsMaxBuffers(unsigned long *longest_output_list, @@ -1581,6 +1651,7 @@ void getClientsMaxBuffers(unsigned long *longest_output_list, *biggest_input_buffer = bib; } +#if __redis_unmodified_upstream // Disable the net API of Redis /* A Redis "Peer ID" is a colon separated ip:port pair. * For IPv4 it's in the form x.y.z.k:port, example: "127.0.0.1:1234". * For IPv6 addresses we use [] around the IP part, like in "[::1]:1234". @@ -1602,6 +1673,7 @@ void genClientPeerId(client *client, char *peerid, anetFormatPeer(client->fd,peerid,peerid_len); } } +#endif /* This function returns the client peer id, by creating and caching it * if client->peerid is NULL, otherwise returning the cached value. @@ -1611,7 +1683,15 @@ char *getClientPeerId(client *c) { char peerid[NET_PEER_ID_LEN]; if (c->peerid == NULL) { +#if __redis_unmodified_upstream // Disable the net API of Redis genClientPeerId(c,peerid,sizeof(peerid)); +#else + peerid[0] = 'W'; + peerid[1] = 'a'; + peerid[2] = 's'; + peerid[3] = 'm'; + peerid[4] = '\x00'; +#endif c->peerid = sdsnew(peerid); } return c->peerid; @@ -1643,15 +1723,16 @@ sds catClientInfoString(sds s, client *client) { if (p == flags) *p++ = 'N'; *p++ = '\0'; +#if __redis_unmodified_upstream // Disable the event engine of Redis emask = client->fd == -1 ? 0 : aeGetFileEvents(server.el,client->fd); p = events; if (emask & AE_READABLE) *p++ = 'r'; if (emask & AE_WRITABLE) *p++ = 'w'; +#endif *p = '\0'; return sdscatfmt(s, - "id=%U addr=%s fd=%i name=%s age=%I idle=%I flags=%s db=%i sub=%i psub=%i multi=%i qbuf=%U qbuf-free=%U obl=%U oll=%U omem=%U events=%s cmd=%s", + "id=%U fd=%i name=%s age=%I idle=%I flags=%s db=%i sub=%i psub=%i multi=%i qbuf=%U qbuf-free=%U obl=%U oll=%U omem=%U events=%s cmd=%s", (unsigned long long) client->id, - getClientPeerId(client), client->fd, client->name ? (char*)client->name->ptr : "", (long long)(server.unixtime - client->ctime), @@ -1686,6 +1767,7 @@ sds getAllClientsInfoString(int type) { return o; } +#if __redis_unmodified_upstream // Disable client command void clientCommand(client *c) { listNode *ln; listIter li; @@ -1861,6 +1943,7 @@ NULL } else { addReply(c,shared.czero); } + addReply(c,shared.czero); } else if (!strcasecmp(c->argv[1]->ptr,"setname") && c->argc == 3) { int j, len = sdslen(c->argv[2]->ptr); char *p = c->argv[2]->ptr; @@ -1905,7 +1988,9 @@ NULL addReplyErrorFormat(c, "Unknown subcommand or wrong number of arguments for '%s'. Try CLIENT HELP", (char*)c->argv[1]->ptr); } } +#endif +#if __redis_unmodified_upstream // Disable the securityWarning command /* This callback is bound to POST and "Host:" command names. Those are not * really commands, but are used in security attacks in order to talk to * Redis instances via HTTP, with a technique called "cross protocol scripting" @@ -1925,6 +2010,7 @@ void securityWarningCommand(client *c) { } freeClientAsync(c); } +#endif /* Rewrite the command vector of the client. All the new objects ref count * is incremented. The old command vector is freed, and the old objects @@ -2115,6 +2201,7 @@ void asyncCloseClientOnOutputBufferLimitReached(client *c) { } } +#if __redis_unmodified_upstream // Disable the event engine and net API of Redis /* Helper function used by freeMemoryIfNeeded() in order to flush slaves * output buffers without returning control to the event loop. * This is also called by SHUTDOWN for a best-effort attempt to send @@ -2178,7 +2265,6 @@ int clientsArePaused(void) { client *c; server.clients_paused = 0; - /* Put all the clients in the unblocked clients queue in order to * force the re-processing of the input buffer if any. */ listRewind(server.clients,&li); @@ -2218,3 +2304,4 @@ int processEventsWhileBlocked(void) { } return count; } +#endif diff --git a/src/notify.c b/src/notify.c index 1afb36fc..f3ca193b 100644 --- a/src/notify.c +++ b/src/notify.c @@ -95,6 +95,7 @@ sds keyspaceEventsFlagsToString(int flags) { * 'key' is a Redis object representing the key name. * 'dbid' is the database ID where the key lives. */ void notifyKeyspaceEvent(int type, char *event, robj *key, int dbid) { +#if __redis_unmodified_upstream // Disable the event engine of Redis sds chan; robj *chanobj, *eventobj; int len = -1; @@ -135,4 +136,5 @@ void notifyKeyspaceEvent(int type, char *event, robj *key, int dbid) { decrRefCount(chanobj); } decrRefCount(eventobj); +#endif } diff --git a/src/object.c b/src/object.c index d5a22e65..ca60d785 100644 --- a/src/object.c +++ b/src/object.c @@ -30,6 +30,13 @@ #include "server.h" #include +#if __redis_unmodified_upstream // Include some libs explicitly +#else +#include +#include +#include +#include +#endif #include #ifdef __CYGWIN__ @@ -652,6 +659,7 @@ int getLongDoubleFromObject(robj *o, long double *target) { if (sdsEncodedObject(o)) { errno = 0; value = strtold(o->ptr, &eptr); + if (sdslen(o->ptr) == 0 || isspace(((const char*)o->ptr)[0]) || (size_t)(eptr-(char*)o->ptr) != sdslen(o->ptr) || @@ -978,12 +986,15 @@ struct redisMemOverhead *getMemoryOverheadData(void) { mem_total += server.initial_memory_usage; mem = 0; +#if __redis_unmodified_upstream // Disable the replication API of Redis if (server.repl_backlog) mem += zmalloc_size(server.repl_backlog); +#endif mh->repl_backlog = mem; mem_total += mem; mem = 0; +#if __redis_unmodified_upstream // Disable the cluster API of Redis if (listLength(server.slaves)) { listIter li; listNode *ln; @@ -996,6 +1007,7 @@ struct redisMemOverhead *getMemoryOverheadData(void) { mem += sizeof(client); } } +#endif mh->clients_slaves = mem; mem_total+=mem; @@ -1018,22 +1030,26 @@ struct redisMemOverhead *getMemoryOverheadData(void) { mem_total+=mem; mem = 0; +#if __redis_unmodified_upstream // Disable the replication API of Redis if (server.aof_state != AOF_OFF) { mem += sdsalloc(server.aof_buf); mem += aofRewriteBufferSize(); } mh->aof_buffer = mem; mem_total+=mem; +#endif mem = server.lua_scripts_mem; mem += dictSize(server.lua_scripts) * sizeof(dictEntry) + dictSlots(server.lua_scripts) * sizeof(dictEntry*); +#if __redis_unmodified_upstream // Disable the replication API of Redis mem += dictSize(server.repl_scriptcache_dict) * sizeof(dictEntry) + dictSlots(server.repl_scriptcache_dict) * sizeof(dictEntry*); if (listLength(server.repl_scriptcache_fifo) > 0) { mem += listLength(server.repl_scriptcache_fifo) * (sizeof(listNode) + sdsZmallocSize(listNodeValue(listFirst(server.repl_scriptcache_fifo)))); } +#endif mh->lua_caches = mem; mem_total+=mem; @@ -1132,9 +1148,15 @@ sds getMemoryDoctorReport(void) { num_reports++; } +#if __redis_unmodified_upstream // Disable the cluster API of Redis /* Clients using more than 200k each average? */ long numslaves = listLength(server.slaves); long numclients = listLength(server.clients)-numslaves; +#else + /* Clients using more than 200k each average? */ + long numslaves = 0; + long numclients = listLength(server.clients)-numslaves; +#endif if (mh->clients_normal / numclients > (1024*200)) { big_client_buf = 1; num_reports++; diff --git a/src/pubsub.c b/src/pubsub.c index 859eb46a..9082d4d7 100644 --- a/src/pubsub.c +++ b/src/pubsub.c @@ -316,10 +316,13 @@ void punsubscribeCommand(client *c) { void publishCommand(client *c) { int receivers = pubsubPublishMessage(c->argv[1],c->argv[2]); +#if __redis_unmodified_upstream // Disable the cluster API of Redis if (server.cluster_enabled) clusterPropagatePublish(c->argv[1],c->argv[2]); else forceCommandPropagation(c,PROPAGATE_REPL); +#endif + addReplyLongLong(c,receivers); } diff --git a/src/rax.c b/src/rax.c index fca60f17..e1e6d264 100644 --- a/src/rax.c +++ b/src/rax.c @@ -1817,6 +1817,7 @@ uint64_t raxSize(rax *rax) { return rax->numele; } +#if __redis_unmodified_upstream // Disable the radix tree debugging API of Redis /* ----------------------------- Introspection ------------------------------ */ /* This function is mostly used for debugging and learning purposes. @@ -1941,3 +1942,4 @@ unsigned long raxTouch(raxNode *n) { } return sum; } +#endif diff --git a/src/redisassert.h b/src/redisassert.h index 61ab35a1..ba1abec1 100644 --- a/src/redisassert.h +++ b/src/redisassert.h @@ -38,12 +38,17 @@ #ifndef __REDIS_ASSERT_H__ #define __REDIS_ASSERT_H__ +#if __redis_unmodified_upstream // Use the unreachable Wasm instruction instead of exit that can involve some syscalls #include /* for _exit() */ #define assert(_e) ((_e)?(void)0 : (_serverAssert(#_e,__FILE__,__LINE__),_exit(1))) #define panic(...) _serverPanic(__FILE__,__LINE__,__VA_ARGS__),_exit(1) +#else +#define assert(_e) ((_e)?(void)0 : (_serverAssert(#_e,__FILE__,__LINE__),__builtin_unreachable())) +#define panic(...) _serverPanic(__FILE__,__LINE__,__VA_ARGS__),__builtin_unreachable() +#endif -void _serverAssert(char *estr, char *file, int line); +void _serverAssert(const char *estr, const char *file, int line); void _serverPanic(const char *file, int line, const char *msg, ...); #endif diff --git a/src/replication.c b/src/replication.c index 6e22525c..f4b2b39f 100644 --- a/src/replication.c +++ b/src/replication.c @@ -2010,12 +2010,14 @@ void replicationHandleMasterDisconnection(void) { } void replicaofCommand(client *c) { - /* SLAVEOF is not allowed in cluster mode as replication is automatically +#if __redis_unmodified_upstream // Disable the cluster API of Redis +/* SLAVEOF is not allowed in cluster mode as replication is automatically * configured using the current address of the master node. */ if (server.cluster_enabled) { addReplyError(c,"REPLICAOF not allowed in cluster mode."); return; } +#endif /* The special host/port combination "NO" "ONE" turns the instance * into a master. Otherwise the new master address is set. */ diff --git a/src/scripting.c b/src/scripting.c index 260b3679..fe147767 100644 --- a/src/scripting.c +++ b/src/scripting.c @@ -38,6 +38,12 @@ #include #include +#if __redis_unmodified_upstream // Include some libs explicitly +#else +#include +#include +#endif + char *redisProtocolToLuaType_Int(lua_State *lua, char *reply); char *redisProtocolToLuaType_Bulk(lua_State *lua, char *reply); char *redisProtocolToLuaType_Status(lua_State *lua, char *reply); @@ -45,6 +51,7 @@ char *redisProtocolToLuaType_Error(lua_State *lua, char *reply); char *redisProtocolToLuaType_MultiBulk(lua_State *lua, char *reply); int redis_math_random (lua_State *L); int redis_math_randomseed (lua_State *L); +#if __redis_unmodified_upstream // Disable the lua debugger API of Redis void ldbInit(void); void ldbDisable(client *c); void ldbEnable(client *c); @@ -75,6 +82,7 @@ struct ldbState { size_t maxlen; /* Max var dump / reply length. */ int maxlen_hint_sent; /* Did we already hint about "set maxlen"? */ } ldb; +#endif /* --------------------------------------------------------------------------- * Utility functions. @@ -208,11 +216,13 @@ char *redisProtocolToLuaType_MultiBulk(lua_State *lua, char *reply) { void luaPushError(lua_State *lua, char *error) { lua_Debug dbg; +#if __redis_unmodified_upstream // Disable the lua debugger API of Redis /* If debugging is active and in step mode, log errors resulting from * Redis commands. */ if (ldb.active && ldb.step) { ldbLog(sdscatprintf(sdsempty()," %s",error)); } +#endif lua_newtable(lua); lua_pushstring(lua,"err"); @@ -443,6 +453,7 @@ int luaRedisGenericCommand(lua_State *lua, int raise_error) { c->argv = argv; c->argc = argc; +#if __redis_unmodified_upstream // Disable the lua debugger API of Redis /* Log the command if debugging is active. */ if (ldb.active && ldb.step) { sds cmdlog = sdsnew(""); @@ -458,6 +469,7 @@ int luaRedisGenericCommand(lua_State *lua, int raise_error) { } ldbLog(cmdlog); } +#endif /* Command lookup */ cmd = lookupCommand(argv[0]->ptr); @@ -479,6 +491,7 @@ int luaRedisGenericCommand(lua_State *lua, int raise_error) { goto cleanup; } +#if __redis_unmodified_upstream // Disable the cluster API of Redis /* Write commands are forbidden against read-only slaves, or if a * command marked as non-deterministic was already called in the context * of this script. */ @@ -488,7 +501,8 @@ int luaRedisGenericCommand(lua_State *lua, int raise_error) { luaPushError(lua, "Write commands not allowed after non deterministic commands. Call redis.replicate_commands() at the start of your script in order to switch to single commands replication mode."); goto cleanup; - } else if (server.masterhost && server.repl_slave_ro && + } + else if (server.masterhost && server.repl_slave_ro && !server.loading && !(server.lua_caller->flags & CLIENT_MASTER)) { @@ -507,13 +521,16 @@ int luaRedisGenericCommand(lua_State *lua, int raise_error) { goto cleanup; } } +#endif /* If we reached the memory limit configured via maxmemory, commands that * could enlarge the memory usage are not allowed, but only if this is the * first write in the context of this script, otherwise we can't stop * in the middle. */ if (server.maxmemory && /* Maxmemory is actually enabled. */ +#if __redis_unmodified_upstream // Disable the replication API of Redis !server.loading && /* Don't care about mem if loading. */ +#endif !server.masterhost && /* Slave must execute the script. */ server.lua_write_dirty == 0 && /* Script had no side effects so far. */ (cmd->flags & CMD_DENYOOM)) @@ -527,6 +544,7 @@ int luaRedisGenericCommand(lua_State *lua, int raise_error) { if (cmd->flags & CMD_RANDOM) server.lua_random_dirty = 1; if (cmd->flags & CMD_WRITE) server.lua_write_dirty = 1; +#if __redis_unmodified_upstream // Disable the cluster API of Redis /* If this is a Redis Cluster node, we need to make sure Lua is not * trying to access non-local keys, with the exception of commands * received from our master or when loading the AOF back in memory. */ @@ -545,6 +563,7 @@ int luaRedisGenericCommand(lua_State *lua, int raise_error) { goto cleanup; } } +#endif /* If we are using single commands replication, we need to wrap what * we propagate into a MULTI/EXEC block, so that it will be atomic like @@ -593,9 +612,11 @@ int luaRedisGenericCommand(lua_State *lua, int raise_error) { if (raise_error && reply[0] != '-') raise_error = 0; redisProtocolToLuaType(lua,reply); +#if __redis_unmodified_upstream // Disable the lua debugger API of Redis /* If the debugger is active, log the reply from Redis. */ if (ldb.active && ldb.step) ldbLogRedisReply(reply); +#endif /* Sort the output array if needed, assuming it is a non-null multi bulk * reply as expected. */ @@ -727,6 +748,7 @@ int luaRedisReplicateCommandsCommand(lua_State *lua) { return 1; } +#if __redis_unmodified_upstream // Disable the lua debugger API of Redis /* redis.breakpoint() * * Allows to stop execution during a debuggign session from within @@ -783,6 +805,7 @@ int luaRedisSetReplCommand(lua_State *lua) { server.lua_repl = flags; return 0; } +#endif /* redis.log() */ int luaLogCommand(lua_State *lua) { @@ -840,7 +863,9 @@ void luaLoadLibraries(lua_State *lua) { luaLoadLib(lua, LUA_TABLIBNAME, luaopen_table); luaLoadLib(lua, LUA_STRLIBNAME, luaopen_string); luaLoadLib(lua, LUA_MATHLIBNAME, luaopen_math); +#if __redis_unmodified_upstream // Disable the lua debugger API of Redis luaLoadLib(lua, LUA_DBLIBNAME, luaopen_debug); +#endif luaLoadLib(lua, "cjson", luaopen_cjson); luaLoadLib(lua, "struct", luaopen_struct); luaLoadLib(lua, "cmsgpack", luaopen_cmsgpack); @@ -855,10 +880,12 @@ void luaLoadLibraries(lua_State *lua) { /* Remove a functions that we don't want to expose to the Redis scripting * environment. */ void luaRemoveUnsupportedFunctions(lua_State *lua) { +#if __redis_unmodified_upstream // We use patched version of lua where these function has been already disabled lua_pushnil(lua); lua_setglobal(lua,"loadfile"); lua_pushnil(lua); lua_setglobal(lua,"dofile"); +#endif } /* This function installs metamethods in the global table _G that prevent @@ -917,7 +944,9 @@ void scriptingInit(int setup) { server.lua_client = NULL; server.lua_caller = NULL; server.lua_timedout = 0; +#if __redis_unmodified_upstream // Disable the lua debugger API of Redis ldbInit(); +#endif } luaLoadLibraries(lua); @@ -972,6 +1001,7 @@ void scriptingInit(int setup) { lua_pushstring(lua, "error_reply"); lua_pushcfunction(lua, luaRedisErrorReplyCommand); lua_settable(lua, -3); + lua_pushstring(lua, "status_reply"); lua_pushcfunction(lua, luaRedisStatusReplyCommand); lua_settable(lua, -3); @@ -981,10 +1011,12 @@ void scriptingInit(int setup) { lua_pushcfunction(lua, luaRedisReplicateCommandsCommand); lua_settable(lua, -3); +#if __redis_unmodified_upstream // Disable the replication API of Redis /* redis.set_repl and associated flags. */ lua_pushstring(lua,"set_repl"); lua_pushcfunction(lua,luaRedisSetReplCommand); lua_settable(lua,-3); +#endif lua_pushstring(lua,"REPL_NONE"); lua_pushnumber(lua,PROPAGATE_NONE); @@ -1006,6 +1038,7 @@ void scriptingInit(int setup) { lua_pushnumber(lua,PROPAGATE_AOF|PROPAGATE_REPL); lua_settable(lua,-3); +#if __redis_unmodified_upstream // Disable the lua debugger API of Redis /* redis.breakpoint */ lua_pushstring(lua,"breakpoint"); lua_pushcfunction(lua,luaRedisBreakpointCommand); @@ -1015,6 +1048,7 @@ void scriptingInit(int setup) { lua_pushstring(lua,"debug"); lua_pushcfunction(lua,luaRedisDebugCommand); lua_settable(lua,-3); +#endif /* Finally set the table as 'redis' global var. */ lua_setglobal(lua,"redis"); @@ -1074,10 +1108,12 @@ void scriptingInit(int setup) { server.lua_client->flags |= CLIENT_LUA; } +#if __redis_unmodified_upstream // Disable the lua debugger API of Redis /* Lua beginners often don't use "local", this is likely to introduce * subtle bugs in their code. To prevent problems we protect accesses * to global variables. */ scriptingEnableGlobalsProtection(lua); +#endif server.lua = lua; } @@ -1314,6 +1350,7 @@ void evalGenericCommand(client *c, int evalsha) { /* Try to lookup the Lua function */ lua_getglobal(lua, funcname); + if (lua_isnil(lua,-1)) { lua_pop(lua,1); /* remove the nil from the stack */ /* Function not defined... let's define it if we have the @@ -1353,6 +1390,7 @@ void evalGenericCommand(client *c, int evalsha) { server.lua_caller = c; server.lua_time_start = mstime(); server.lua_kill = 0; +#if __redis_unmodified_upstream // Disable the lua debugger API of Redis if (server.lua_time_limit > 0 && ldb.active == 0) { lua_sethook(lua,luaMaskCountHook,LUA_MASKCOUNT,100000); delhook = 1; @@ -1360,12 +1398,14 @@ void evalGenericCommand(client *c, int evalsha) { lua_sethook(server.lua,luaLdbLineHook,LUA_MASKLINE|LUA_MASKCOUNT,100000); delhook = 1; } +#endif /* At this point whether 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. */ err = lua_pcall(lua,0,1,-2); +#if __redis_unmodified_upstream // Disable the lua debugger and cluster API of Redis /* Perform some cleanup that we need to do both on error and success. */ if (delhook) lua_sethook(lua,NULL,0,0); /* Disable hook */ if (server.lua_timedout) { @@ -1376,6 +1416,7 @@ void evalGenericCommand(client *c, int evalsha) { if (server.masterhost && server.master) queueClientForReprocessing(server.master); } +#endif server.lua_caller = NULL; /* Call the Lua garbage collector from time to time to avoid a @@ -1406,6 +1447,7 @@ void evalGenericCommand(client *c, int evalsha) { lua_pop(lua,1); /* Remove the error handler. */ } +#if __redis_unmodified_upstream // Disable the replication API of Redis /* If we are using single commands replication, emit EXEC if there * was at least a write. */ if (server.lua_replicate_commands) { @@ -1456,13 +1498,16 @@ void evalGenericCommand(client *c, int evalsha) { forceCommandPropagation(c,PROPAGATE_REPL|PROPAGATE_AOF); } } +#endif } void evalCommand(client *c) { if (!(c->flags & CLIENT_LUA_DEBUG)) evalGenericCommand(c,0); +#if __redis_unmodified_upstream // Disable the lua debugger API of Redis else evalGenericCommandWithDebugging(c,0); +#endif } void evalShaCommand(client *c) { @@ -1484,6 +1529,7 @@ void evalShaCommand(client *c) { void scriptCommand(client *c) { if (c->argc == 2 && !strcasecmp(c->argv[1]->ptr,"help")) { +#if __redis_unmodified_upstream // Disable the script DEBUG, FLUSH, KILL API of Redis const char *help[] = { "DEBUG (yes|sync|no) -- Set the debug mode for subsequent scripts executed.", "EXISTS [ ...] -- Return information about the existence of the scripts in the script cache.", @@ -1492,13 +1538,23 @@ void scriptCommand(client *c) { "LOAD