mirror of
https://github.com/fluencelabs/redis
synced 2025-04-24 18:12:13 +00:00
initial commit
This commit is contained in:
parent
ba5145b8e9
commit
4fd252b07c
58
.gitignore
vendored
58
.gitignore
vendored
@ -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
|
480
CMakeLists.txt
Normal file
480
CMakeLists.txt
Normal file
@ -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)
|
13
Dockerfile
Normal file
13
Dockerfile
Normal file
@ -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
|
3
Makefile
3
Makefile
@ -5,6 +5,9 @@ default: all
|
||||
.DEFAULT:
|
||||
cd src && $(MAKE) $@
|
||||
|
||||
wasm:
|
||||
cd src && $(MAKE) -f Makefile_wasm
|
||||
|
||||
install:
|
||||
cd src && $(MAKE) $@
|
||||
|
||||
|
4
deps/lua/src/lbaselib.c
vendored
4
deps/lua/src/lbaselib.c
vendored
@ -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},
|
||||
|
2
deps/lua/src/ldblib.c
vendored
2
deps/lua/src/ldblib.c
vendored
@ -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
|
||||
|
||||
|
6
deps/lua/src/ldo.c
vendored
6
deps/lua/src/ldo.c
vendored
@ -5,7 +5,9 @@
|
||||
*/
|
||||
|
||||
|
||||
#if __redis_unmodified_upstream // Currently setjmp/longjump cannot be translated to Wasm
|
||||
#include <setjmp.h>
|
||||
#endif
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
4
deps/lua/src/linit.c
vendored
4
deps/lua/src/linit.c
vendored
@ -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}
|
||||
};
|
||||
|
||||
|
3
deps/lua/src/loslib.c
vendored
3
deps/lua/src/loslib.c
vendored
@ -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
|
||||
|
||||
|
8
deps/lua/src/lua.c
vendored
8
deps/lua/src/lua.c
vendored
@ -5,7 +5,9 @@
|
||||
*/
|
||||
|
||||
|
||||
#if __redis_unmodified_upstream // Disable syscalls from some libs
|
||||
#include <signal.h>
|
||||
#endif
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@ -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);
|
||||
|
6
deps/lua/src/lua_cjson.c
vendored
6
deps/lua/src/lua_cjson.c
vendored
@ -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;
|
||||
|
11
deps/lua/src/luaconf.h
vendored
11
deps/lua/src/luaconf.h
vendored
@ -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
|
||||
|
||||
|
4
deps/lua/src/lualib.h
vendored
4
deps/lua/src/lualib.h
vendored
@ -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);
|
||||
|
5
deps/lua/src/strbuf.c
vendored
5
deps/lua/src/strbuf.c
vendored
@ -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)
|
||||
|
7
docker-compose.yml
Normal file
7
docker-compose.yml
Normal file
@ -0,0 +1,7 @@
|
||||
version: '3'
|
||||
services:
|
||||
redis:
|
||||
build:
|
||||
context: .
|
||||
volumes:
|
||||
- .:/code
|
23
src/Makefile_wasm
Normal file
23
src/Makefile_wasm
Normal file
@ -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
|
@ -57,11 +57,14 @@
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#if __redis_unmodified_upstream // Disable syscalls from pthread.h
|
||||
#include <pthread.h>
|
||||
#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 */
|
||||
|
@ -29,6 +29,11 @@
|
||||
*/
|
||||
|
||||
#include "server.h"
|
||||
#if __redis_unmodified_upstream // To make all implicit functions prototypes explicit
|
||||
#else
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#endif
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* Helpers and low level bit functions.
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
121
src/config.c
121
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
|
||||
|
@ -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 <sys/types.h> /* This will likely define BYTE_ORDER */
|
||||
|
83
src/db.c
83
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 <signal.h>
|
||||
#else
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <strings.h>
|
||||
#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
|
||||
|
39
src/debug.c
39
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 <arpa/inet.h>
|
||||
#include <signal.h>
|
||||
#include <dlfcn.h>
|
||||
@ -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 <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#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
|
||||
|
@ -30,6 +30,7 @@
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#if __redis_unmodified_upstream // Disable writing to files
|
||||
#include <stdio.h>
|
||||
#define D(...) \
|
||||
do { \
|
||||
@ -39,3 +40,9 @@
|
||||
fprintf(fp,"\n"); \
|
||||
fclose(fp); \
|
||||
} while (0);
|
||||
#else
|
||||
// TODO: add logs
|
||||
#define D(...) \
|
||||
do { \
|
||||
} while (0);
|
||||
#endif
|
||||
|
@ -35,7 +35,9 @@
|
||||
*/
|
||||
|
||||
#include "server.h"
|
||||
#if __redis_unmodified_upstream // Disable imports from time.h
|
||||
#include <time.h>
|
||||
#endif
|
||||
#include <assert.h>
|
||||
#include <stddef.h>
|
||||
|
||||
|
14
src/dict.c
14
src/dict.c
@ -41,7 +41,11 @@
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#include <limits.h>
|
||||
#if __redis_unmodified_upstream // Disable imports from time.h
|
||||
#include <sys/time.h>
|
||||
#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;
|
||||
}
|
||||
|
28
src/evict.c
28
src/evict.c
@ -34,6 +34,12 @@
|
||||
#include "bio.h"
|
||||
#include "atomicvar.h"
|
||||
|
||||
#if __redis_unmodified_upstream // Include some libs explicitly
|
||||
#else
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#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();
|
||||
}
|
||||
|
14
src/expire.c
14
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++;
|
||||
|
||||
|
@ -31,6 +31,12 @@
|
||||
#include "geo.h"
|
||||
#include "geohash_helper.h"
|
||||
#include "debugmacro.h"
|
||||
#if __redis_unmodified_upstream // Include some libs explicitly
|
||||
#else
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#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. */
|
||||
|
@ -33,6 +33,12 @@
|
||||
|
||||
#include <stdint.h>
|
||||
#include <math.h>
|
||||
#if __redis_unmodified_upstream // Include some libs explicitly
|
||||
#else
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <strings.h>
|
||||
#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;
|
||||
}
|
||||
|
@ -34,6 +34,12 @@
|
||||
*/
|
||||
|
||||
#include "server.h"
|
||||
#if __redis_unmodified_upstream // Include some libs explicitly
|
||||
#else
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <strings.h>
|
||||
#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)
|
||||
|
@ -36,6 +36,12 @@
|
||||
#include "server.h"
|
||||
#include <math.h>
|
||||
|
||||
#if __redis_unmodified_upstream // Include some libs explicitly
|
||||
#else
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#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. */
|
||||
|
26
src/module.c
26
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);
|
||||
|
17
src/multi.c
17
src/multi.c
@ -28,6 +28,10 @@
|
||||
*/
|
||||
|
||||
#include "server.h"
|
||||
#if __redis_unmodified_upstream // Include some libs explicitly
|
||||
#else
|
||||
#include <string.h>
|
||||
#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) ===================
|
||||
|
101
src/networking.c
101
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 <sys/uio.h>
|
||||
#else
|
||||
#include <math.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#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
|
||||
|
@ -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
|
||||
}
|
||||
|
22
src/object.c
22
src/object.c
@ -30,6 +30,13 @@
|
||||
|
||||
#include "server.h"
|
||||
#include <math.h>
|
||||
#if __redis_unmodified_upstream // Include some libs explicitly
|
||||
#else
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#endif
|
||||
#include <ctype.h>
|
||||
|
||||
#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++;
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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 <unistd.h> /* 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
|
||||
|
@ -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. */
|
||||
|
@ -38,6 +38,12 @@
|
||||
#include <ctype.h>
|
||||
#include <math.h>
|
||||
|
||||
#if __redis_unmodified_upstream // Include some libs explicitly
|
||||
#else
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#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(),"<error> %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("<redis>");
|
||||
@ -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 <sha1> [<sha1> ...] -- Return information about the existence of the scripts in the script cache.",
|
||||
@ -1492,13 +1538,23 @@ void scriptCommand(client *c) {
|
||||
"LOAD <script> -- Load a script into the scripts cache, without executing it.",
|
||||
NULL
|
||||
};
|
||||
#endif
|
||||
const char *help[] = {
|
||||
"EXISTS <sha1> [<sha1> ...] -- Return information about the existence of the scripts in the script cache.",
|
||||
"LOAD <script> -- Load a script into the scripts cache, without executing it.",
|
||||
NULL
|
||||
};
|
||||
addReplyHelp(c, help);
|
||||
} else if (c->argc == 2 && !strcasecmp(c->argv[1]->ptr,"flush")) {
|
||||
}
|
||||
#if __redis_unmodified_upstream // Disable the script FLUSH API of Redis
|
||||
else if (c->argc == 2 && !strcasecmp(c->argv[1]->ptr,"flush")) {
|
||||
scriptingReset();
|
||||
addReply(c,shared.ok);
|
||||
replicationScriptCacheFlush();
|
||||
server.dirty++; /* Propagating this command is a good idea. */
|
||||
} else if (c->argc >= 2 && !strcasecmp(c->argv[1]->ptr,"exists")) {
|
||||
}
|
||||
#endif
|
||||
else if (c->argc >= 2 && !strcasecmp(c->argv[1]->ptr,"exists")) {
|
||||
int j;
|
||||
|
||||
addReplyMultiBulkLen(c, c->argc-2);
|
||||
@ -1513,7 +1569,9 @@ NULL
|
||||
if (sha == NULL) return; /* The error was sent by luaCreateFunction(). */
|
||||
addReplyBulkCBuffer(c,sha,40);
|
||||
forceCommandPropagation(c,PROPAGATE_REPL|PROPAGATE_AOF);
|
||||
} else if (c->argc == 2 && !strcasecmp(c->argv[1]->ptr,"kill")) {
|
||||
}
|
||||
#if __redis_unmodified_upstream // Disable the script DEBUG, KILL API of Redis
|
||||
else if (c->argc == 2 && !strcasecmp(c->argv[1]->ptr,"kill")) {
|
||||
if (server.lua_caller == NULL) {
|
||||
addReplySds(c,sdsnew("-NOTBUSY No scripts in execution right now.\r\n"));
|
||||
} else if (server.lua_caller->flags & CLIENT_MASTER) {
|
||||
@ -1543,11 +1601,14 @@ NULL
|
||||
addReplyError(c,"Use SCRIPT DEBUG yes/sync/no");
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
}
|
||||
#endif
|
||||
else {
|
||||
addReplySubcommandSyntaxError(c);
|
||||
}
|
||||
}
|
||||
|
||||
#if __redis_unmodified_upstream // Disable the lua debugger API of Redis
|
||||
/* ---------------------------------------------------------------------------
|
||||
* LDB: Redis Lua debugging facilities
|
||||
* ------------------------------------------------------------------------- */
|
||||
@ -2447,4 +2508,4 @@ void luaLdbLineHook(lua_State *lua, lua_Debug *ar) {
|
||||
server.lua_time_start = mstime();
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
13
src/sdk/allocator.c
Normal file
13
src/sdk/allocator.c
Normal file
@ -0,0 +1,13 @@
|
||||
#include "allocator.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
#define UNUSED(x) (void)(x)
|
||||
|
||||
void *allocate(size_t size) {
|
||||
return malloc(size);
|
||||
}
|
||||
|
||||
void deallocate(void *ptr, size_t size) {
|
||||
UNUSED(size);
|
||||
free(ptr);
|
||||
}
|
27
src/sdk/allocator.h
Normal file
27
src/sdk/allocator.h
Normal file
@ -0,0 +1,27 @@
|
||||
#ifndef C_SDK_ALLOCATOR_H
|
||||
#define C_SDK_ALLOCATOR_H
|
||||
|
||||
#include <stddef.h> // for size_t
|
||||
|
||||
/**
|
||||
* Allocates a memory region of given size.
|
||||
*
|
||||
* Used by Wasm VM for byte array passing. Should be exported from module.
|
||||
*
|
||||
* @param size a size of needed memory region.
|
||||
* @return a pointer to allocated memory region.
|
||||
*/
|
||||
void *allocate(size_t size);
|
||||
|
||||
/**
|
||||
* Frees a memory region.
|
||||
*
|
||||
* Used by Wasm VM for freeing previous memory allocated by `allocate` function.
|
||||
* Should be exported from module.
|
||||
*
|
||||
* @param ptr the pointer to the previously allocated memory region.
|
||||
* @param size the size of the previously allocated memory region.
|
||||
*/
|
||||
void deallocate(void *ptr, size_t size);
|
||||
|
||||
#endif //C_SDK_ALLOCATOR_H
|
15
src/sdk/logger.c
Normal file
15
src/sdk/logger.c
Normal file
@ -0,0 +1,15 @@
|
||||
#include "logger.h"
|
||||
|
||||
#define __LOGGER_IMPORT(name) \
|
||||
__attribute__((__import_module__("logger"), __import_name__(#name)))
|
||||
|
||||
void __write(char ch) __LOGGER_IMPORT(write);
|
||||
void __flush() __LOGGER_IMPORT(flush);
|
||||
|
||||
void wasm_log(const char *str, int len) {
|
||||
for(int byteId = 0; byteId < len; ++byteId) {
|
||||
__write(str[byteId]);
|
||||
}
|
||||
|
||||
__flush();
|
||||
}
|
11
src/sdk/logger.h
Normal file
11
src/sdk/logger.h
Normal file
@ -0,0 +1,11 @@
|
||||
#ifndef C_SDK_LOGGER_H
|
||||
#define C_SDK_LOGGER_H
|
||||
|
||||
/**
|
||||
* Writes provided string to Wasm VM logger.
|
||||
*
|
||||
* @param log_message a message that should be logged.
|
||||
*/
|
||||
void wasm_log(const char *str, int len);
|
||||
|
||||
#endif //C_SDK_LOGGER_H
|
@ -34,7 +34,11 @@
|
||||
#define __SDS_H
|
||||
|
||||
#define SDS_MAX_PREALLOC (1024*1024)
|
||||
#if NOT_WAWSM
|
||||
const char *SDS_NOINIT;
|
||||
#else
|
||||
extern const char *SDS_NOINIT;
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <stdarg.h>
|
||||
|
@ -4514,4 +4514,3 @@ void sentinelTimer(void) {
|
||||
* election because of split brain voting). */
|
||||
server.hz = CONFIG_DEFAULT_HZ + rand() % CONFIG_DEFAULT_HZ;
|
||||
}
|
||||
|
||||
|
713
src/server.c
713
src/server.c
File diff suppressed because it is too large
Load Diff
90
src/server.h
90
src/server.h
@ -35,19 +35,26 @@
|
||||
#include "solarisfixes.h"
|
||||
#include "rio.h"
|
||||
|
||||
#if __redis_unmodified_upstream // Disable syscalls from some included libs
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
#include <time.h>
|
||||
#endif
|
||||
#include <limits.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#if __redis_unmodified_upstream // Disable syscalls from some included libs
|
||||
#include <inttypes.h>
|
||||
#include <pthread.h>
|
||||
#include <syslog.h>
|
||||
#include <netinet/in.h>
|
||||
#endif
|
||||
#include <lua.h>
|
||||
#if __redis_unmodified_upstream // Disable syscalls from signal.h
|
||||
#include <signal.h>
|
||||
#endif
|
||||
|
||||
typedef long long mstime_t; /* millisecond time type. */
|
||||
|
||||
@ -452,9 +459,15 @@ typedef long long mstime_t; /* millisecond time type. */
|
||||
#define run_with_period(_ms_) if ((_ms_ <= 1000/server.hz) || !(server.cronloops%((_ms_)/(1000/server.hz))))
|
||||
|
||||
/* We can print the stacktrace, so our assert is defined this way: */
|
||||
#if __redis_unmodified_upstream // Use the unreachable Wasm instruction instead of exit that can involve some syscalls
|
||||
#define serverAssertWithInfo(_c,_o,_e) ((_e)?(void)0 : (_serverAssertWithInfo(_c,_o,#_e,__FILE__,__LINE__),_exit(1)))
|
||||
#define serverAssert(_e) ((_e)?(void)0 : (_serverAssert(#_e,__FILE__,__LINE__),_exit(1)))
|
||||
#define serverPanic(...) _serverPanic(__FILE__,__LINE__,__VA_ARGS__),_exit(1)
|
||||
#else
|
||||
#define serverAssertWithInfo(_c,_o,_e) ((_e)?(void)0 : (_serverAssertWithInfo(_c,_o,#_e,__FILE__,__LINE__),__builtin_unreachable()))
|
||||
#define serverAssert(_e) ((_e)?(void)0 : (_serverAssert(#_e,__FILE__,__LINE__),__builtin_unreachable()))
|
||||
#define serverPanic(...) _serverPanic(__FILE__,__LINE__,__VA_ARGS__),__builtin_unreachable()
|
||||
#endif
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
* Data types
|
||||
@ -540,6 +553,7 @@ typedef struct moduleValue {
|
||||
void *value;
|
||||
} moduleValue;
|
||||
|
||||
#if __redis_unmodified_upstream // Disable the module API of Redis
|
||||
/* This is a wrapper for the 'rio' streams used inside rdb.c in Redis, so that
|
||||
* the user does not have to take the total count of the written bytes nor
|
||||
* to care about error conditions. */
|
||||
@ -552,6 +566,7 @@ typedef struct RedisModuleIO {
|
||||
* 2 (current version with opcodes annotation). */
|
||||
struct RedisModuleCtx *ctx; /* Optional context, see RM_GetContextFromIO()*/
|
||||
} RedisModuleIO;
|
||||
#endif
|
||||
|
||||
/* Macro to initialize an IO context. Note that the 'ver' field is populated
|
||||
* inside rdb.c according to the version of the value to load. */
|
||||
@ -736,6 +751,8 @@ typedef struct client {
|
||||
time_t obuf_soft_limit_reached_time;
|
||||
int flags; /* Client flags: CLIENT_* macros. */
|
||||
int authenticated; /* When requirepass is non-NULL. */
|
||||
|
||||
#if __redis_unmodified_upstream // Disable the replication API of Redis
|
||||
int replstate; /* Replication state if this is a slave. */
|
||||
int repl_put_online_on_ack; /* Install slave write handler on ACK. */
|
||||
int repldbfd; /* Replication DB file descriptor. */
|
||||
@ -753,10 +770,13 @@ typedef struct client {
|
||||
int slave_listening_port; /* As configured with: SLAVECONF listening-port */
|
||||
char slave_ip[NET_IP_STR_LEN]; /* Optionally given by REPLCONF ip-address */
|
||||
int slave_capa; /* Slave capabilities: SLAVE_CAPA_* bitwise OR. */
|
||||
#endif
|
||||
multiState mstate; /* MULTI/EXEC state */
|
||||
int btype; /* Type of blocking op if CLIENT_BLOCKED. */
|
||||
blockingState bpop; /* blocking state */
|
||||
#if __redis_unmodified_upstream // Disable the replication API of Redis
|
||||
long long woff; /* Last write global replication offset. */
|
||||
#endif
|
||||
list *watched_keys; /* Keys WATCHED for MULTI/EXEC CAS */
|
||||
dict *pubsub_channels; /* channels a client is interested in (SUBSCRIBE) */
|
||||
list *pubsub_patterns; /* patterns a client is interested in (SUBSCRIBE) */
|
||||
@ -913,8 +933,9 @@ struct malloc_stats {
|
||||
/*-----------------------------------------------------------------------------
|
||||
* Global server state
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
#if __redis_unmodified_upstream // Disable cluster API of redis
|
||||
struct clusterState;
|
||||
#endif
|
||||
|
||||
/* AIX defines hz to __hz, we don't use this define and in order to allow
|
||||
* Redis build on AIX we need to undef it. */
|
||||
@ -928,7 +949,9 @@ struct clusterState;
|
||||
|
||||
struct redisServer {
|
||||
/* General */
|
||||
#if __redis_unmodified_upstream // Disable pid file of Redis
|
||||
pid_t pid; /* Main process pid. */
|
||||
#endif
|
||||
char *configfile; /* Absolute config file path, or NULL */
|
||||
char *executable; /* Absolute executable file path. */
|
||||
char **exec_argv; /* Executable argv vector (copy). */
|
||||
@ -940,13 +963,17 @@ struct redisServer {
|
||||
redisDb *db;
|
||||
dict *commands; /* Command table */
|
||||
dict *orig_commands; /* Command table before command renaming. */
|
||||
#if __redis_unmodified_upstream // Disable the event engine API of Redis
|
||||
aeEventLoop *el;
|
||||
#endif
|
||||
unsigned int lruclock; /* Clock for LRU eviction */
|
||||
int shutdown_asap; /* SHUTDOWN needed ASAP */
|
||||
int activerehashing; /* Incremental rehash in serverCron() */
|
||||
int active_defrag_running; /* Active defragmentation running (holds current scan aggressiveness) */
|
||||
char *requirepass; /* Pass for AUTH command, or NULL */
|
||||
#if __redis_unmodified_upstream // Disable the pid file
|
||||
char *pidfile; /* PID file path */
|
||||
#endif
|
||||
int arch_bits; /* 32 or 64 depending on sizeof(long) */
|
||||
int cronloops; /* Number of times the cron function run */
|
||||
char runid[CONFIG_RUN_ID_SIZE+1]; /* ID always different at every exec. */
|
||||
@ -961,6 +988,7 @@ struct redisServer {
|
||||
int module_blocked_pipe[2]; /* Pipe used to awake the event loop if a
|
||||
client blocked on a module command needs
|
||||
to be processed. */
|
||||
#if __redis_unmodified_upstream // Disable the net API of Redis
|
||||
/* Networking */
|
||||
int port; /* TCP listening port */
|
||||
int tcp_backlog; /* TCP listen() backlog */
|
||||
@ -991,6 +1019,13 @@ struct redisServer {
|
||||
off_t loading_loaded_bytes;
|
||||
time_t loading_start_time;
|
||||
off_t loading_process_events_interval_bytes;
|
||||
#else
|
||||
list *clients; /* List of active clients */
|
||||
list *monitors; /* List of slaves and MONITORs */
|
||||
client *current_client; /* Current client, only used on crash report */
|
||||
rax *clients_index; /* Active clients dictionary by client ID. */
|
||||
uint64_t next_client_id; /* Next client unique ID. Incremental. */
|
||||
#endif
|
||||
/* Fast pointers to often looked up command */
|
||||
struct redisCommand *delCommand, *multiCommand, *lpushCommand,
|
||||
*lpopCommand, *rpopCommand, *zpopminCommand,
|
||||
@ -1054,6 +1089,8 @@ struct redisServer {
|
||||
int supervised_mode; /* See SUPERVISED_* */
|
||||
int daemonize; /* True if running as a daemon */
|
||||
clientBufferLimitsConfig client_obuf_limits[CLIENT_TYPE_OBUF_COUNT];
|
||||
|
||||
#if __redis_unmodified_upstream // Disable the replication API of Redis
|
||||
/* AOF persistence */
|
||||
int aof_state; /* AOF_(ON|OFF|WAIT_REWRITE) */
|
||||
int aof_fsync; /* Kind of fsync() policy */
|
||||
@ -1119,11 +1156,16 @@ struct redisServer {
|
||||
} child_info_data;
|
||||
/* Propagation of commands in AOF / replication */
|
||||
redisOpArray also_propagate; /* Additional command to propagate. */
|
||||
#else
|
||||
time_t lastsave; /* Unix time of last successful save */
|
||||
long long dirty; /* Changes to DB from the last save */
|
||||
#endif
|
||||
/* Logging */
|
||||
char *logfile; /* Path of log file */
|
||||
int syslog_enabled; /* Is syslog enabled? */
|
||||
char *syslog_ident; /* Syslog ident */
|
||||
int syslog_facility; /* Syslog facility */
|
||||
#if __redis_unmodified_upstream // Disable the replication API of Redis
|
||||
/* Replication (master) */
|
||||
char replid[CONFIG_RUN_ID_SIZE+1]; /* My current replication ID. */
|
||||
char replid2[CONFIG_RUN_ID_SIZE+1]; /* replid inherited from master*/
|
||||
@ -1184,6 +1226,9 @@ struct redisServer {
|
||||
/* Synchronous replication. */
|
||||
list *clients_waiting_acks; /* Clients waiting in WAIT command. */
|
||||
int get_ack_from_slaves; /* If true we send REPLCONF GETACK. */
|
||||
#else
|
||||
char *masterhost; /* Hostname of master */
|
||||
#endif
|
||||
/* Limits */
|
||||
unsigned int maxclients; /* Max number of simultaneous clients */
|
||||
unsigned long long maxmemory; /* Max number of memory bytes to use */
|
||||
@ -1225,6 +1270,7 @@ struct redisServer {
|
||||
list *pubsub_patterns; /* A list of pubsub_patterns */
|
||||
int notify_keyspace_events; /* Events to propagate via Pub/Sub. This is an
|
||||
xor of NOTIFY_... flags. */
|
||||
#if __redis_unmodified_upstream // Disable the cluster API of Redis
|
||||
/* Cluster */
|
||||
int cluster_enabled; /* Is cluster enabled? */
|
||||
mstime_t cluster_node_timeout; /* Cluster node timeout. */
|
||||
@ -1243,6 +1289,8 @@ struct redisServer {
|
||||
to set in order to suppress certain
|
||||
native Redis Cluster features. Check the
|
||||
REDISMODULE_CLUSTER_FLAG_*. */
|
||||
#endif
|
||||
|
||||
/* Scripting */
|
||||
lua_State *lua; /* The Lua interpreter. We use just one for all clients */
|
||||
client *lua_client; /* The "fake client" to query Redis from Lua */
|
||||
@ -1262,6 +1310,7 @@ struct redisServer {
|
||||
execution. */
|
||||
int lua_kill; /* Kill the script if true. */
|
||||
int lua_always_replicate_commands; /* Default replication type. */
|
||||
|
||||
/* Lazy free */
|
||||
int lazyfree_lazy_eviction;
|
||||
int lazyfree_lazy_expire;
|
||||
@ -1278,11 +1327,13 @@ struct redisServer {
|
||||
/* System hardware info */
|
||||
size_t system_memory_size; /* Total memory in system as reported by OS */
|
||||
|
||||
#if __redis_unmodified_upstream // Disable mutexes usage
|
||||
/* Mutexes used to protect atomic variables when atomic builtins are
|
||||
* not available. */
|
||||
pthread_mutex_t lruclock_mutex;
|
||||
pthread_mutex_t next_client_id_mutex;
|
||||
pthread_mutex_t unixtime_mutex;
|
||||
#endif
|
||||
};
|
||||
|
||||
typedef struct pubsubPattern {
|
||||
@ -1402,7 +1453,9 @@ void moduleFreeContext(struct RedisModuleCtx *ctx);
|
||||
void unblockClientFromModule(client *c);
|
||||
void moduleHandleBlockedClients(void);
|
||||
void moduleBlockedClientTimedOut(client *c);
|
||||
#if __redis_unmodified_upstream // Disable the event engine API of Redis
|
||||
void moduleBlockedClientPipeReadable(aeEventLoop *el, int fd, void *privdata, int mask);
|
||||
#endif
|
||||
size_t moduleCount(void);
|
||||
void moduleAcquireGIL(void);
|
||||
void moduleReleaseGIL(void);
|
||||
@ -1425,15 +1478,21 @@ void closeTimedoutClients(void);
|
||||
void freeClient(client *c);
|
||||
void freeClientAsync(client *c);
|
||||
void resetClient(client *c);
|
||||
#if __redis_unmodified_upstream // Disable the event engine API of Redis
|
||||
void sendReplyToClient(aeEventLoop *el, int fd, void *privdata, int mask);
|
||||
#endif
|
||||
void *addDeferredMultiBulkLength(client *c);
|
||||
void setDeferredMultiBulkLength(client *c, void *node, long length);
|
||||
void processInputBuffer(client *c);
|
||||
void processInputBufferAndReplicate(client *c);
|
||||
#if __redis_unmodified_upstream // Disable the event engine API of Redis
|
||||
void acceptHandler(aeEventLoop *el, int fd, void *privdata, int mask);
|
||||
void acceptTcpHandler(aeEventLoop *el, int fd, void *privdata, int mask);
|
||||
void acceptUnixHandler(aeEventLoop *el, int fd, void *privdata, int mask);
|
||||
void readQueryFromClient(aeEventLoop *el, int fd, void *privdata, int mask);
|
||||
#else
|
||||
void readQueryFromClient(client *c, int mask, const char *request, int req_length);
|
||||
#endif
|
||||
void addReplyString(client *c, const char *s, size_t len);
|
||||
void addReplyBulk(client *c, robj *obj);
|
||||
void addReplyBulkCString(client *c, const char *s);
|
||||
@ -1569,6 +1628,7 @@ unsigned long long estimateObjectIdleTime(robj *o);
|
||||
void trimStringObjectIfNeeded(robj *o);
|
||||
#define sdsEncodedObject(objptr) (objptr->encoding == OBJ_ENCODING_RAW || objptr->encoding == OBJ_ENCODING_EMBSTR)
|
||||
|
||||
#if __redis_unmodified_upstream // Disable the replication API of Redis
|
||||
/* Synchronous I/O with timeout */
|
||||
ssize_t syncWrite(int fd, char *ptr, ssize_t size, long long timeout);
|
||||
ssize_t syncRead(int fd, char *ptr, ssize_t size, long long timeout);
|
||||
@ -1608,16 +1668,20 @@ void feedReplicationBacklog(void *ptr, size_t len);
|
||||
void startLoading(FILE *fp);
|
||||
void loadingProgress(off_t pos);
|
||||
void stopLoading(void);
|
||||
#endif
|
||||
|
||||
#define DISK_ERROR_TYPE_AOF 1 /* Don't accept writes: AOF errors. */
|
||||
#define DISK_ERROR_TYPE_RDB 2 /* Don't accept writes: RDB errors. */
|
||||
#define DISK_ERROR_TYPE_NONE 0 /* No problems, we can accept writes. */
|
||||
int writeCommandsDeniedByDiskError(void);
|
||||
|
||||
#if __redis_unmodified_upstream // Disable the persistence API of Redis
|
||||
/* RDB persistence */
|
||||
#include "rdb.h"
|
||||
int rdbSaveRio(rio *rdb, int *error, int flags, rdbSaveInfo *rsi);
|
||||
#endif
|
||||
|
||||
#if __redis_unmodified_upstream // Disable the persistence API of Redis
|
||||
/* AOF persistence */
|
||||
void flushAppendOnlyFile(int force);
|
||||
void feedAppendOnlyFile(struct redisCommand *cmd, int dictid, robj **argv, int argc);
|
||||
@ -1636,6 +1700,7 @@ void openChildInfoPipe(void);
|
||||
void closeChildInfoPipe(void);
|
||||
void sendChildInfo(int process_type);
|
||||
void receiveChildInfo(void);
|
||||
#endif
|
||||
|
||||
/* Sorted sets data type */
|
||||
|
||||
@ -1883,16 +1948,20 @@ void sentinelTimer(void);
|
||||
char *sentinelHandleConfiguration(char **argv, int argc);
|
||||
void sentinelIsRunning(void);
|
||||
|
||||
#if __redis_unmodified_upstream // Disable the replication API of Redis
|
||||
/* redis-check-rdb & aof */
|
||||
int redis_check_rdb(char *rdbfilename, FILE *fp);
|
||||
int redis_check_rdb_main(int argc, char **argv, FILE *fp);
|
||||
int redis_check_aof_main(int argc, char **argv);
|
||||
#endif
|
||||
|
||||
/* Scripting */
|
||||
void scriptingInit(int setup);
|
||||
#if __redis_unmodified_upstream // Disable the lua debugger
|
||||
int ldbRemoveChild(pid_t pid);
|
||||
void ldbKillForkedSessions(void);
|
||||
int ldbPendingChildren(void);
|
||||
#endif
|
||||
sds luaCreateFunction(client *c, lua_State *lua, robj *body);
|
||||
|
||||
/* Blocked clients */
|
||||
@ -1960,7 +2029,9 @@ void randomkeyCommand(client *c);
|
||||
void keysCommand(client *c);
|
||||
void scanCommand(client *c);
|
||||
void dbsizeCommand(client *c);
|
||||
#if __redis_unmodified_upstream // Disable replication API of Redis
|
||||
void lastsaveCommand(client *c);
|
||||
#endif
|
||||
void saveCommand(client *c);
|
||||
void bgsaveCommand(client *c);
|
||||
void bgrewriteaofCommand(client *c);
|
||||
@ -2003,7 +2074,9 @@ void lremCommand(client *c);
|
||||
void rpoplpushCommand(client *c);
|
||||
void infoCommand(client *c);
|
||||
void mgetCommand(client *c);
|
||||
#if __redis_unmodified_upstream // Disable the monitor command
|
||||
void monitorCommand(client *c);
|
||||
#endif
|
||||
void expireCommand(client *c);
|
||||
void expireatCommand(client *c);
|
||||
void pexpireCommand(client *c);
|
||||
@ -2084,7 +2157,9 @@ void readwriteCommand(client *c);
|
||||
void dumpCommand(client *c);
|
||||
void objectCommand(client *c);
|
||||
void memoryCommand(client *c);
|
||||
#if __redis_unmodified_upstream // Disable client command
|
||||
void clientCommand(client *c);
|
||||
#endif
|
||||
void evalCommand(client *c);
|
||||
void evalShaCommand(client *c);
|
||||
void scriptCommand(client *c);
|
||||
@ -2140,7 +2215,9 @@ void _serverAssert(const char *estr, const char *file, int line);
|
||||
void _serverPanic(const char *file, int line, const char *msg, ...);
|
||||
void bugReportStart(void);
|
||||
void serverLogObjectDebugInfo(const robj *o);
|
||||
#if __redis_unmodified_upstream // Disable sigsegv handler
|
||||
void sigsegvHandler(int sig, siginfo_t *info, void *secret);
|
||||
#endif
|
||||
sds genRedisInfoString(char *section);
|
||||
void enableWatchdog(int period);
|
||||
void disableWatchdog(void);
|
||||
@ -2150,9 +2227,20 @@ int memtest_preserving_test(unsigned long *m, size_t bytes, int passes);
|
||||
void mixDigest(unsigned char *digest, void *ptr, size_t len);
|
||||
void xorDigest(unsigned char *digest, void *ptr, size_t len);
|
||||
|
||||
#if __redis_unmodified_upstream // Disable redis debug macros
|
||||
#define redisDebug(fmt, ...) \
|
||||
printf("DEBUG %s:%d > " fmt "\n", __FILE__, __LINE__, __VA_ARGS__)
|
||||
#define redisDebugMark() \
|
||||
printf("-- MARK %s:%d --\n", __FILE__, __LINE__)
|
||||
#endif
|
||||
|
||||
#if __redis_unmodified_upstream // Export some functions to use it our wrapper
|
||||
#else
|
||||
int serverCron();
|
||||
void afterSleep();
|
||||
void beforeSleep();
|
||||
int initRedis(int argc, char **argv);
|
||||
void freeClientArgv(client *c);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@ -41,6 +41,10 @@
|
||||
|
||||
#include "server.h"
|
||||
#include "slowlog.h"
|
||||
#if __redis_unmodified_upstream // Include some libs explicitly
|
||||
#else
|
||||
#include <strings.h>
|
||||
#endif
|
||||
|
||||
/* Create a new slowlog entry.
|
||||
* Incrementing the ref count of all the objects retained is up to
|
||||
@ -85,7 +89,11 @@ slowlogEntry *slowlogCreateEntry(client *c, robj **argv, int argc, long long dur
|
||||
}
|
||||
}
|
||||
}
|
||||
#if __redis_unmodified_upstream // Currently it is impossible to get the current time inside a Wasm module
|
||||
se->time = time(NULL);
|
||||
#else
|
||||
se->time = ustime();
|
||||
#endif
|
||||
se->duration = duration;
|
||||
se->id = server.slowlog_entry_id++;
|
||||
se->peerid = sdsnew(getClientPeerId(c));
|
||||
|
10
src/sort.c
10
src/sort.c
@ -32,6 +32,12 @@
|
||||
#include "server.h"
|
||||
#include "pqsort.h" /* Partial qsort for SORT+LIMIT */
|
||||
#include <math.h> /* isnan() */
|
||||
#if __redis_unmodified_upstream // Include some libs explicitly
|
||||
#else
|
||||
#include <string.h>
|
||||
#include <strings.h>
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
|
||||
zskiplistNode* zslGetElementByRank(zskiplist *zsl, unsigned long rank);
|
||||
|
||||
@ -253,19 +259,23 @@ void sortCommand(client *c) {
|
||||
} else {
|
||||
/* If BY is specified with a real patter, we can't accept
|
||||
* it in cluster mode. */
|
||||
#if __redis_unmodified_upstream // Disable the cluster API of Redis
|
||||
if (server.cluster_enabled) {
|
||||
addReplyError(c,"BY option of SORT denied in Cluster mode.");
|
||||
syntax_error++;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
j++;
|
||||
} else if (!strcasecmp(c->argv[j]->ptr,"get") && leftargs >= 1) {
|
||||
#if __redis_unmodified_upstream // Disable the cluster API of Redis
|
||||
if (server.cluster_enabled) {
|
||||
addReplyError(c,"GET option of SORT denied in Cluster mode.");
|
||||
syntax_error++;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
listAddNodeTail(operations,createSortOperation(
|
||||
SORT_OP_GET,c->argv[j+1]));
|
||||
getop++;
|
||||
|
@ -33,6 +33,10 @@
|
||||
#include "server.h"
|
||||
|
||||
#include <math.h>
|
||||
#if __redis_unmodified_upstream // Include some libs explicitly
|
||||
#else
|
||||
#include <string.h>
|
||||
#endif
|
||||
|
||||
/* This is the charset used to display the graphs, but multiple rows are used
|
||||
* to increase the resolution. */
|
||||
|
@ -483,8 +483,10 @@ void hashTypeConvertZiplist(robj *o, int enc) {
|
||||
value = hashTypeCurrentObjectNewSds(hi,OBJ_HASH_VALUE);
|
||||
ret = dictAdd(dict, key, value);
|
||||
if (ret != DICT_OK) {
|
||||
#if __redis_unmodified_upstream // Disable log hex dump
|
||||
serverLogHexDump(LL_WARNING,"ziplist with dup elements dump",
|
||||
o->ptr,ziplistBlobLen(o->ptr));
|
||||
#endif
|
||||
serverPanic("Ziplist corruption detected");
|
||||
}
|
||||
}
|
||||
|
@ -28,6 +28,10 @@
|
||||
*/
|
||||
|
||||
#include "server.h"
|
||||
#if __redis_unmodified_upstream // Include some libs explicitly
|
||||
#else
|
||||
#include <strings.h>
|
||||
#endif
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
* List API
|
||||
@ -596,12 +600,15 @@ void rpoplpushCommand(client *c) {
|
||||
signalModifiedKey(c->db,touchedkey);
|
||||
decrRefCount(touchedkey);
|
||||
server.dirty++;
|
||||
#if __redis_unmodified_upstream // Disable the blocking API of Redis
|
||||
if (c->cmd->proc == brpoplpushCommand) {
|
||||
rewriteClientCommandVector(c,3,shared.rpoplpush,c->argv[1],c->argv[2]);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#if __redis_unmodified_upstream // Disable the blocking API of Redis
|
||||
/*-----------------------------------------------------------------------------
|
||||
* Blocking POP operations
|
||||
*----------------------------------------------------------------------------*/
|
||||
@ -775,3 +782,4 @@ void brpoplpushCommand(client *c) {
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
@ -28,6 +28,10 @@
|
||||
*/
|
||||
|
||||
#include "server.h"
|
||||
#if __redis_unmodified_upstream // Include some libs explicitly
|
||||
#else
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
* Set Commands
|
||||
|
@ -31,6 +31,13 @@
|
||||
#include "endianconv.h"
|
||||
#include "stream.h"
|
||||
|
||||
#if __redis_unmodified_upstream // Include some libs explicitly
|
||||
#else
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <strings.h>
|
||||
#endif
|
||||
|
||||
#define STREAM_BYTES_PER_LISTPACK 2048
|
||||
|
||||
/* Every stream item inside the listpack, has a flags field that is used to
|
||||
@ -1251,10 +1258,12 @@ void xaddCommand(client *c) {
|
||||
rewriteClientCommandArgument(c,i,idarg);
|
||||
decrRefCount(idarg);
|
||||
|
||||
#if __redis_unmodified_upstream // Disable the cluster API of Redis
|
||||
/* We need to signal to blocked clients that there is new data on this
|
||||
* stream. */
|
||||
if (server.blocked_clients_by_type[BLOCKED_STREAM])
|
||||
signalKeyAsReady(c->db, c->argv[1]);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* XRANGE/XREVRANGE actual implementation. */
|
||||
@ -1343,11 +1352,14 @@ void xreadCommand(client *c) {
|
||||
for (int i = 1; i < c->argc; i++) {
|
||||
int moreargs = c->argc-i-1;
|
||||
char *o = c->argv[i]->ptr;
|
||||
#if __redis_unmodified_upstream // Disable the blocking API of Redis
|
||||
if (!strcasecmp(o,"BLOCK") && moreargs) {
|
||||
i++;
|
||||
if (getTimeoutFromObjectOrReply(c,c->argv[i],&timeout,
|
||||
UNIT_MILLISECONDS) != C_OK) return;
|
||||
} else if (!strcasecmp(o,"COUNT") && moreargs) {
|
||||
} else
|
||||
#endif
|
||||
if (!strcasecmp(o,"COUNT") && moreargs) {
|
||||
i++;
|
||||
if (getLongLongFromObjectOrReply(c,c->argv[i],&count,NULL) != C_OK)
|
||||
return;
|
||||
@ -1536,6 +1548,7 @@ void xreadCommand(client *c) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
#if __redis_unmodified_upstream // Disable the blocking API of Redis
|
||||
/* Block if needed. */
|
||||
if (timeout != -1) {
|
||||
/* If we are inside a MULTI/EXEC and the list is empty the only thing
|
||||
@ -1567,6 +1580,7 @@ void xreadCommand(client *c) {
|
||||
}
|
||||
goto cleanup;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* No BLOCK option, nor any stream we can serve. Reply as with a
|
||||
* timeout happened. */
|
||||
|
@ -29,6 +29,10 @@
|
||||
|
||||
#include "server.h"
|
||||
#include <math.h> /* isnan(), isinf() */
|
||||
#if __redis_unmodified_upstream // Include some libs explicitly
|
||||
#else
|
||||
#include <string.h>
|
||||
#endif
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
* String Commands
|
||||
@ -83,6 +87,7 @@ void setGenericCommand(client *c, int flags, robj *key, robj *val, robj *expire,
|
||||
addReply(c, abort_reply ? abort_reply : shared.nullbulk);
|
||||
return;
|
||||
}
|
||||
|
||||
setKey(c->db,key,val);
|
||||
server.dirty++;
|
||||
if (expire) setExpire(c,c->db,key,mstime()+milliseconds);
|
||||
|
@ -58,6 +58,11 @@
|
||||
|
||||
#include "server.h"
|
||||
#include <math.h>
|
||||
#if __redis_unmodified_upstream // Include some libs explicitly
|
||||
#else
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
* Skiplist implementation of the low level API
|
||||
@ -3256,6 +3261,7 @@ void zpopmaxCommand(client *c) {
|
||||
c->argc == 3 ? c->argv[2] : NULL);
|
||||
}
|
||||
|
||||
#if __redis_unmodified_upstream // Disable the blocking API of Redis
|
||||
/* BZPOPMIN / BZPOPMAX actual implementation. */
|
||||
void blockingGenericZpopCommand(client *c, int where) {
|
||||
robj *o;
|
||||
@ -3305,3 +3311,4 @@ void bzpopminCommand(client *c) {
|
||||
void bzpopmaxCommand(client *c) {
|
||||
blockingGenericZpopCommand(c,ZSET_MAX);
|
||||
}
|
||||
#endif
|
||||
|
20
src/util.c
20
src/util.c
@ -34,13 +34,16 @@
|
||||
#include <ctype.h>
|
||||
#include <limits.h>
|
||||
#include <math.h>
|
||||
#if __redis_unmodified_upstream // Disable syscalls from some included libs
|
||||
#include <unistd.h>
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
#include <float.h>
|
||||
#include <stdint.h>
|
||||
#include <errno.h>
|
||||
#if __redis_unmodified_upstream // Disable syscalls from some included libs
|
||||
#include <time.h>
|
||||
|
||||
#endif
|
||||
#include "util.h"
|
||||
#include "sha1.h"
|
||||
|
||||
@ -549,7 +552,7 @@ int ld2string(char *buf, size_t len, long double value, int humanfriendly) {
|
||||
if (*p == '.') l--;
|
||||
}
|
||||
} else {
|
||||
l = snprintf(buf,len,"%.17Lg", value);
|
||||
l = snprintf(buf,len,"%.17Lf", value);
|
||||
if (l+1 > len) return 0; /* No room. */
|
||||
}
|
||||
buf[l] = '\0';
|
||||
@ -567,6 +570,7 @@ void getRandomBytes(unsigned char *p, size_t len) {
|
||||
static unsigned char seed[20]; /* The SHA1 seed, from /dev/urandom. */
|
||||
static uint64_t counter = 0; /* The counter we hash with the seed. */
|
||||
|
||||
#if __redis_unmodified_upstream // Disable random initialization
|
||||
if (!seed_initialized) {
|
||||
/* Initialize a seed and use SHA1 in counter mode, where we hash
|
||||
* the same seed with a progressive counter. For the goals of this
|
||||
@ -587,6 +591,13 @@ void getRandomBytes(unsigned char *p, size_t len) {
|
||||
}
|
||||
if (fp) fclose(fp);
|
||||
}
|
||||
#else
|
||||
if (!seed_initialized) {
|
||||
for(int i = 0; i < 20; ++i) {
|
||||
seed[i] = rand() & 0xFF;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
while(len) {
|
||||
unsigned char digest[20];
|
||||
@ -617,6 +628,7 @@ void getRandomHexChars(char *p, size_t len) {
|
||||
for (j = 0; j < len; j++) p[j] = charset[p[j] & 0x0F];
|
||||
}
|
||||
|
||||
#if __redis_unmodified_upstream // Disable file API
|
||||
/* Given the filename, return the absolute path as an SDS string, or NULL
|
||||
* if it fails for some reason. Note that "filename" may be an absolute path
|
||||
* already, this will be detected and handled correctly.
|
||||
@ -668,12 +680,13 @@ sds getAbsolutePath(char *filename) {
|
||||
sdsfree(relpath);
|
||||
return abspath;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Gets the proper timezone in a more portable fashion
|
||||
* i.e timezone variables are linux specific.
|
||||
*/
|
||||
|
||||
#if __redis_unmodified_upstream // Currently it is impossible to get the current time inside a Wasm module
|
||||
unsigned long getTimeZone(void) {
|
||||
#ifdef __linux__
|
||||
return timezone;
|
||||
@ -686,6 +699,7 @@ unsigned long getTimeZone(void) {
|
||||
return tz.tz_minuteswest * 60UL;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Return true if the specified path is just a file basename without any
|
||||
* relative or absolute path. This function just checks that no / or \
|
||||
|
37
src/wasm_float.h
Normal file
37
src/wasm_float.h
Normal file
@ -0,0 +1,37 @@
|
||||
#ifndef REDIS_WASM_FLOAT_H
|
||||
#define REDIS_WASM_FLOAT_H
|
||||
|
||||
static __inline unsigned __FLOAT_BITS_(float __f)
|
||||
{
|
||||
union {float __f; unsigned __i;} __u;
|
||||
__u.__f = __f;
|
||||
return __u.__i;
|
||||
}
|
||||
static __inline unsigned long long __DOUBLE_BITS_(double __f)
|
||||
{
|
||||
union {double __f; unsigned long long __i;} __u;
|
||||
__u.__f = __f;
|
||||
return __u.__i;
|
||||
}
|
||||
|
||||
#undef fpclassify
|
||||
#define fpclassify(x) ( \
|
||||
sizeof(x) == sizeof(float) ? __fpclassifyf(x) : __fpclassify(x))
|
||||
|
||||
#undef isinf
|
||||
#define isinf(x) ( \
|
||||
sizeof(x) == sizeof(float) ? (__FLOAT_BITS_(x) & 0x7fffffff) == 0x7f800000 : (__DOUBLE_BITS_(x) & -1ULL>>1) == 0x7ffULL<<52)
|
||||
|
||||
#undef isnan
|
||||
#define isnan(x) ( \
|
||||
sizeof(x) == sizeof(float) ? (__FLOAT_BITS_(x) & 0x7fffffff) > 0x7f800000 : (__DOUBLE_BITS_(x) & -1ULL>>1) > 0x7ffULL<<52)
|
||||
|
||||
#undef isnormal
|
||||
#define isnormal(x) ( \
|
||||
sizeof(x) == sizeof(float) ? ((__FLOAT_BITS_(x)+0x00800000) & 0x7fffffff) >= 0x01000000 : ((__DOUBLE_BITS_(x)+(1ULL<<52)) & -1ULL>>1) >= 1ULL<<53)
|
||||
|
||||
#undef isfinite
|
||||
#define isfinite(x) ( \
|
||||
sizeof(x) == sizeof(float) ? (__FLOAT_BITS_(x) & 0x7fffffff) < 0x7f800000 : (__DOUBLE_BITS_(x) & -1ULL>>1) < 0x7ffULL<<52)
|
||||
|
||||
#endif //REDIS_WASM_FLOAT_H
|
123
src/wrapper.c
Normal file
123
src/wrapper.c
Normal file
@ -0,0 +1,123 @@
|
||||
#include <stdlib.h>
|
||||
#include "server.h"
|
||||
#include "atomicvar.h"
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
client *g_client;
|
||||
|
||||
// TODO: add handling of the initialization process errors
|
||||
void init() {
|
||||
initRedis(0, NULL);
|
||||
|
||||
// create a main client
|
||||
g_client = createClient(-1);
|
||||
}
|
||||
|
||||
int g_isInited = 0;
|
||||
|
||||
void* allocate(size_t size) {
|
||||
// allocate one more byte for adding the \n symbol that indicated the end of request
|
||||
return zmalloc(size + 1);
|
||||
}
|
||||
|
||||
void deallocate(void *ptr, int size) {
|
||||
zfree(ptr);
|
||||
}
|
||||
|
||||
// Cleans client output buffers to - client is blocked and
|
||||
// doesn't receive requests until output buffer isn't empty.
|
||||
void clean_client_buffer(client *c) {
|
||||
freeClientArgv(c);
|
||||
zfree(c->argv);
|
||||
freeClientMultiState(c);
|
||||
sdsfree(c->peerid);
|
||||
|
||||
c->reply_bytes = 0;
|
||||
c->bufpos = 0;
|
||||
c->argc = 0;
|
||||
c->argv = NULL;
|
||||
c->peerid = NULL;
|
||||
|
||||
// clear the query buffer state
|
||||
sdsclear(c->querybuf);
|
||||
c->qb_pos = 0;
|
||||
|
||||
// clear the client state
|
||||
c->flags = 0;
|
||||
|
||||
// set reqtype to unknown to force Redis determine it on every request
|
||||
c->reqtype = 0;
|
||||
}
|
||||
|
||||
char *write_response(client *c, size_t *response_size) {
|
||||
char *response = allocate(c->bufpos + c->reply_bytes + 4);
|
||||
*response_size = 0;
|
||||
|
||||
memcpy(response + 4, c->buf, c->bufpos);
|
||||
*response_size += c->bufpos;
|
||||
|
||||
while(listLength(c->reply)) {
|
||||
clientReplyBlock *o = listNodeValue(listFirst(c->reply));
|
||||
size_t objlen = o->used;
|
||||
|
||||
if (objlen == 0) {
|
||||
listDelNode(c->reply, listFirst(c->reply));
|
||||
continue;
|
||||
}
|
||||
|
||||
memcpy(response + 4 + *response_size, o->buf, objlen);
|
||||
|
||||
c->reply_bytes -= o->size;
|
||||
*response_size += objlen;
|
||||
listDelNode(c->reply, listFirst(c->reply));
|
||||
}
|
||||
|
||||
for(int i = 0; i < 4; ++i) {
|
||||
response[i] = (*response_size >> 8*i) & 0xFF;
|
||||
}
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
const char *invoke(char *request, int request_size) {
|
||||
serverLog(LL_DEBUG, "invoke started\n");
|
||||
if(g_isInited == 0) {
|
||||
init();
|
||||
serverLog(LL_DEBUG, "\nserver has been inited\n");
|
||||
g_isInited = 1;
|
||||
}
|
||||
|
||||
afterSleep();
|
||||
serverLog(LL_DEBUG, "afterSleep\n");
|
||||
|
||||
if(request_size > 0 && request[request_size - 1] != '\n') {
|
||||
// WasmVM always uses allocate function to inject requests to Wasm memory. And it always allocates one more byte
|
||||
// especially for '\n' symbol
|
||||
request[request_size] = '\n';
|
||||
readQueryFromClient(g_client, 0, request, request_size + 1);
|
||||
} else {
|
||||
readQueryFromClient(g_client, 0, request, request_size);
|
||||
}
|
||||
deallocate(request, 0);
|
||||
serverLog(LL_DEBUG, "readQueryFromClient\n");
|
||||
|
||||
const size_t reply_bytes_before = g_client->reply_bytes;
|
||||
size_t response_size = 0;
|
||||
const char *response = write_response(g_client, &response_size);
|
||||
serverLog(LL_DEBUG, "write_response, bufpos = %d, reply_bytes before = %d, reply_bytes after = %d, response_size = %d\n",
|
||||
g_client->bufpos,
|
||||
reply_bytes_before,
|
||||
g_client->reply_bytes,
|
||||
response_size
|
||||
);
|
||||
clean_client_buffer(g_client);
|
||||
|
||||
serverCron();
|
||||
serverLog(LL_DEBUG, "serverCron\n");
|
||||
|
||||
beforeSleep();
|
||||
serverLog(LL_DEBUG, "beforeSleep\n");
|
||||
|
||||
return response;
|
||||
}
|
@ -1188,6 +1188,7 @@ size_t ziplistBlobLen(unsigned char *zl) {
|
||||
}
|
||||
|
||||
void ziplistRepr(unsigned char *zl) {
|
||||
#if __redis_unmodified_upstream // Disable the debug printing of ziplist
|
||||
unsigned char *p;
|
||||
int index = 0;
|
||||
zlentry entry;
|
||||
@ -1243,6 +1244,7 @@ void ziplistRepr(unsigned char *zl) {
|
||||
index++;
|
||||
}
|
||||
printf("{end}\n\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef REDIS_TEST
|
||||
|
@ -41,7 +41,9 @@ void zlibc_free(void *ptr) {
|
||||
}
|
||||
|
||||
#include <string.h>
|
||||
#if __redis_unmodified_upstream // Disable syscalls from some libs
|
||||
#include <pthread.h>
|
||||
#endif
|
||||
#include "config.h"
|
||||
#include "zmalloc.h"
|
||||
#include "atomicvar.h"
|
||||
@ -84,13 +86,17 @@ void zlibc_free(void *ptr) {
|
||||
} while(0)
|
||||
|
||||
static size_t used_memory = 0;
|
||||
#if __redis_unmodified_upstream // Disable mutex usage
|
||||
pthread_mutex_t used_memory_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
#endif
|
||||
|
||||
static void zmalloc_default_oom(size_t size) {
|
||||
#if __redis_unmodified_upstream // Disable the debug printing of oom
|
||||
fprintf(stderr, "zmalloc: Out of memory trying to allocate %zu bytes\n",
|
||||
size);
|
||||
fflush(stderr);
|
||||
abort();
|
||||
#endif
|
||||
}
|
||||
|
||||
static void (*zmalloc_oom_handler)(size_t) = zmalloc_default_oom;
|
||||
|
Loading…
x
Reference in New Issue
Block a user