Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package redis for openSUSE:Factory checked in at 2026-08-06 16:18:07 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/redis (Old) and /work/SRC/openSUSE:Factory/.redis.new.16738 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "redis" Thu Aug 6 16:18:07 2026 rev:19 rq:1369604 version:8.10.0 Changes: -------- --- /work/SRC/openSUSE:Factory/redis/redis.changes 2026-08-01 18:29:55.112974056 +0200 +++ /work/SRC/openSUSE:Factory/.redis.new.16738/redis.changes 2026-08-06 16:18:17.252248083 +0200 @@ -1,0 +2,123 @@ +Tue Aug 4 18:57:49 UTC 2026 - Martin Pluskal <[email protected]> + +- Add lazyfree-test-explicit-stream-ids.patch: "lazy free a stream with + all types of metadata" builds its stream with server-generated IDs, so + the number of nodes in the stream's radix tree is the number of + distinct milliseconds the 1000 XADDs happened to span -- entries + sharing a millisecond share an ID prefix and collapse into one + compressed node. That node count is what lazyfreeGetFreeEffort() + weighs against LAZYFREE_THRESHOLD, so a builder quick enough to run + the loop in well under 64ms frees the stream inline instead of lazily + and the test's lazyfreed_objects stays 0. It measured how fast the + worker was rather than lazyfree, and duly failed on the faster + aarch64 workers while passing on the slower ones. Adding the entries + with explicit IDs gives the radix tree the same shape everywhere + +------------------------------------------------------------------- +Fri Jul 31 18:36:51 UTC 2026 - Marcus Rueckert <[email protected]> + +- Update redis-conf.patch + Do not load modules which we split out into subpackages in the + default config + +------------------------------------------------------------------- +Fri Jul 31 17:54:00 UTC 2026 - Andreas Schneider <[email protected]> + +- Fix building for Leap + +------------------------------------------------------------------- +Fri Jul 31 13:06:02 UTC 2026 - Martin Pluskal <[email protected]> + +- Run the test suite with four clients instead of the default sixteen: + each of those starts several servers, which oversubscribes an OBS + worker badly enough that a run whose per-unit times sum to about + 2900s finishes in 600s of wall clock. What then fails is whatever has + a fixed deadline -- a cluster MEET handshake that must complete + inside cluster-node-timeout, an AOF child that must be reaped before + a shutdown -- and each architecture lost a different one, which is + contention rather than a bug in any of them +- Add scripting-test-disable-aof-after-use.patch: a test switches + appendonly on and never switches it back, leaving an AOF rewrite + child that serverCron cannot reap while a busy script runs, so the + next test's SHUTDOWN NOSAVE is refused and the server it expects to + die stays up. Same fix valkey made, which redis has not picked up +- Skip the "Active defrag IDMP streams" tests on 32-bit x86, where + residual small-bin waste settles just above the thresholds the test + itself sets, so the defrag cycle never reaches its stop condition + +------------------------------------------------------------------- +Fri Jul 31 10:47:04 UTC 2026 - Martin Pluskal <[email protected]> + +- Restrict the "modules" flavour to x86_64 and aarch64 -- RedisBloom and + RedisTimeSeries abort on anything else with "only supports 64-bit + architectures (x64, arm64v8)", redisjson's vendored redis-module is + 64-bit only, and modules/common.mk maps no other architecture at all +- Do not build the "test" flavour on s390x -- hash field TTLs do not + survive an RDB reload and a cluster test aborts the run there, both + upstream big-endian bugs on a platform upstream does not support +- Invoke the test suite directly rather than through "make test", which + hardcodes a bare runtest, so it can be given --no-latency and skips for + the tests that measure the build worker rather than redis: + * two tests bounding wall-clock time that --no-latency does not cover + * the crash-report tests (integration/logging, unit/moduleapi/crash) on + architectures upstream never gated them on + * the active-defrag replicaof test on ppc64le, which does not converge + there + +------------------------------------------------------------------- +Thu Jul 30 13:42:15 UTC 2026 - Martin Pluskal <[email protected]> + +- Split the build into three multibuild flavours: + * The default flavour builds and packages only the server, and no longer + runs the test suite -- a rebuild is down from about 24 minutes to a + little over two, which is the wait everything that build-depends on + redis pays. tcl and procps are no longer build dependencies of it, and + %%check now does a cheap smoke test instead of the suite + * New "test" flavour runs the tcl test suite, and runs it for real: it + used to be invoked with "|| true" because it kept failing to start a + server with 'child process exited abnormally', which turns out to be + servers leaked by an earlier run of the suite still sitting on ports + handed to the test clients. In a fresh build root there are none and + all 6054 tests pass. The flavour packages nothing, so a red test run + blocks no rebuild + * New "modules" flavour builds the four modules upstream vendors under + modules/ since 8.x and ships them as redis-bloom, redis-search, + redis-json and redis-timeseries, installed below + %%{_libdir}/redis/modules. It needs cmake, rust, autotools, boost and a + python3 with pip on top of the server's own dependencies, which is + exactly why it has to be kept out of the server flavour +- Add _service with two cargo_vendor runs, plus the resulting + vendor-redisearch.tar.zst and vendor-redisjson.tar.zst: the Rust parts of + redisearch and redisjson fetch from crates.io and from three git + repositories, which cannot work in an offline build root +- Build the modules with IGNORE_MISSING_DEPS=1, upstream's own escape hatch: + redisearch refuses to build unless it recognises the distribution, and its + checker only knows dpkg, rpm-on-rhel, apk and tdnf systems +- Do not let the module build reach the network for its own dependencies: + * point redisearch at the system boost headers rather than the boost + release it downloads from github; everything it uses is header-only + * build with USE_SVS=OFF, which drops the eve, fmt, spdlog, tomlplusplus + and robin-map git clones and the pre-compiled ScalableVectorSearch + shared library redisearch would otherwise download from Intel; + VectorSimilarity then uses its own HNSW and flat indexes + * add cpu_features 0.10.1 as a source, the one dependency VectorSimilarity + still clones once SVS is off +- Add vectorsimilarity-guard-svs-include.patch: USE_SVS=OFF does not compile, + because two translation units reach for the SVS headers unconditionally + (upstream pull request 1006) +- Disable LTO for the modules: modules.yaml asks redisearch for it, which + there means clang driving ld.bfd through LLVMgold.so, a plugin that is not + shipped, so every compiler probe failed before a line was compiled +- Build the modules with -Wno-error=return-type and -fPIC: a function in the + redismodule.h of the vendored redismodule-rs falls off the end, and + redistimeseries links a bundled libevent whose own build produces a + non-PIC static library, which on aarch64 is a hard relocation error +- Build redisjson without --all-targets: that includes its test executables, + which reference the RedisModule_* API the server only provides at load time + and so cannot link +- Let rpm extract the debug info of the Rust modules: both split it out into + a .so.debug sibling themselves and leave a dangling .gnu_debuglink, which + made find-debuginfo skip the module altogether +- Drop the openSUSE Leap 15.x conditionals, 15.6 is out of support + +------------------------------------------------------------------- @@ -26 +149 @@ -- Update to 8.10.1 +- Update to 8.10.0 New: ---- _multibuild _service cpu_features-0.10.1.tar.gz lazyfree-test-explicit-stream-ids.patch scripting-test-disable-aof-after-use.patch vectorsimilarity-guard-svs-include.patch vendor-redisearch.tar.zst vendor-redisjson.tar.zst ----------(New B)---------- New: - Add lazyfree-test-explicit-stream-ids.patch: "lazy free a stream with all types of metadata" builds its stream with server-generated IDs, so New: contention rather than a bug in any of them - Add scripting-test-disable-aof-after-use.patch: a test switches appendonly on and never switches it back, leaving an AOF rewrite New: still clones once SVS is off - Add vectorsimilarity-guard-svs-include.patch: USE_SVS=OFF does not compile, because two translation units reach for the SVS headers unconditionally ----------(New E)---------- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ redis.spec ++++++ --- /var/tmp/diff_new_pack.wafZ8T/_old 2026-08-06 16:18:23.504466882 +0200 +++ /var/tmp/diff_new_pack.wafZ8T/_new 2026-08-06 16:18:23.504466882 +0200 @@ -15,76 +15,304 @@ # Please submit bugfixes or comments via https://bugs.opensuse.org/ # +%define requires_file() %( readlink -f '%*' | LC_ALL=C xargs -r rpm -q --qf 'Requires: %%{name} >= %%{epoch}:%%{version}\\n' -f | sed -e 's/ (none):/ /' -e 's/ 0:/ /' | grep -v "is not") -%define _data_dir %{_localstatedir}/lib/%{name} -%define _log_dir %{_localstatedir}/log/%{name} -%define _conf_dir %{_sysconfdir}/%{name} -Name: redis +# Three multibuild flavours share this spec: +# +# "" the server itself -- the only flavour anything else in the +# distribution build-depends on, so it is kept deliberately cheap: +# no cmake, no rust, no python, and no test suite. +# "test" runs upstream's tcl test suite (~25 minutes). Split out so a +# server rebuild during bootstrap does not have to wait for it. +# "modules" the four modules upstream vendors under modules/ since 8.x. +# They need cmake, rust and python on top of the server's own +# dependencies, which is exactly why they must not be part of the +# server flavour. +%global flavor @BUILD_FLAVOR@%{nil} +%if "%{flavor}" == "test" +%define psuffix -test +# This flavour packages nothing at all -- it exists to run the test suite -- +# so do not leave a redis-test-debugsource behind either +%global debug_package %{nil} +%endif +%if "%{flavor}" == "modules" +%define psuffix -modules +%endif +%if "%{flavor}" == "" +%define psuffix %{nil} +%endif +# %%{name} carries the flavour suffix, so everything that names the upstream +# project -- paths, sources, the service units, the sysusers account -- has to +# go through %%{origname} instead. +%define origname redis +%define _data_dir %{_localstatedir}/lib/%{origname} +%define _log_dir %{_localstatedir}/log/%{origname} +%define _conf_dir %{_sysconfdir}/%{origname} +%define _module_dir %{_libdir}/%{origname}/modules +Name: %{origname}%{psuffix} Version: 8.10.0 Release: 0 Summary: Persistent key-value database License: AGPL-3.0-only URL: https://github.com/redis/redis -Source0: https://download.redis.io/releases/%{name}-%{version}.tar.gz -Source1: %{name}.logrotate -Source2: %{name}.target -Source3: %{name}@.service -Source4: %{name}.tmpfiles.d +Source0: https://download.redis.io/releases/%{origname}-%{version}.tar.gz +Source1: %{origname}.logrotate +Source2: %{origname}.target +Source3: %{origname}@.service +Source4: %{origname}.tmpfiles.d Source5: README.SUSE -Source6: %{name}.sysctl -Source7: %{name}[email protected] -Source8: %{name}-sentinel.target -Source9: %{name}-user.conf -Source10: https://raw.githubusercontent.com/redis/redis-hashes/master/README#/%{name}.hashes +Source6: %{origname}.sysctl +Source7: %{origname}[email protected] +Source8: %{origname}-sentinel.target +Source9: %{origname}-user.conf +Source10: https://raw.githubusercontent.com/redis/redis-hashes/master/README#/%{origname}.hashes # PATCH-MISSING-TAG -- See https://wiki.opensuse.org/openSUSE:Packaging_Patches_guidelines Source11: series -Patch0: %{name}-conf.patch +# Generated by the two cargo_vendor runs in _service, "modules" flavour only +Source20: vendor-redisearch.tar.zst +Source21: vendor-redisjson.tar.zst +# The one dependency redisearch's bundled VectorSimilarity still clones from +# git once the SVS backend is off; there is no cpu_features package to build +# against. "modules" flavour only. +Source22: https://github.com/google/cpu_features/archive/refs/tags/v0.10.1.tar.gz#/cpu_features-0.10.1.tar.gz +Patch0: %{origname}-conf.patch Patch1: reproducible.patch Patch2: ppc-atomic.patch +# PATCH-FIX-UPSTREAM vectorsimilarity-guard-svs-include.patch [email protected] -- USE_SVS=OFF does not compile, https://github.com/RedisAI/VectorSimilarity/pull/1006 +Patch3: vectorsimilarity-guard-svs-include.patch +# PATCH-FIX-UPSTREAM scripting-test-disable-aof-after-use.patch [email protected] -- test leaves AOF on, racing the next test's SHUTDOWN NOSAVE, https://github.com/valkey-io/valkey/pull/1156 +Patch4: scripting-test-disable-aof-after-use.patch +# PATCH-FIX-UPSTREAM lazyfree-test-explicit-stream-ids.patch [email protected] -- lazyfree stream test measures how fast the builder is, not lazyfree, https://github.com/redis/redis/pull/15585 +Patch5: lazyfree-test-explicit-stream-ids.patch BuildRequires: gcc-c++ +BuildRequires: python3 BuildRequires: pkgconfig -BuildRequires: procps -BuildRequires: sysuser-shadow -BuildRequires: sysuser-tools -# there is no tcl-tls package yet, which is said to be needed for testing tls support -BuildRequires: tcl BuildRequires: pkgconfig(jemalloc) BuildRequires: pkgconfig(libsystemd) BuildRequires: pkgconfig(openssl) BuildRequires: pkgconfig(systemd) +%if "%{flavor}" == "" +BuildRequires: sysuser-shadow +BuildRequires: sysuser-tools Recommends: logrotate -Conflicts: valkey-compat-%{name} +Conflicts: valkey-compat-%{origname} %sysusers_requires +%endif +%if "%{flavor}" == "test" +BuildRequires: procps +# there is no tcl-tls package yet, which is said to be needed for testing tls support +BuildRequires: tcl +# Upstream does not support s390x -- "Add s390x support" (redis/redis#3359) has +# been open since 2024 -- and the suite finds it: hash field TTLs do not survive +# an RDB reload there (HPEXPIRETIME comes back as -2, the field is gone) and a +# cluster test aborts the whole run with an unhandled MOVED. Those are real +# big-endian bugs upstream, not something this package can patch around, and a +# permanently red flavour is worth less than one that is not built at all. +ExcludeArch: s390x +%endif +%if "%{flavor}" == "modules" +# The module builds drive themselves through upstream's "readies" harness: +# cmake for redisbloom/redisearch/redistimeseries, cargo for the Rust parts of +# redisearch and redisjson, and a python3 that can run "pip --version" -- +# readies' getpy3 probes for pip, not just for the interpreter. redistimeseries +# additionally builds a bundled libevent from a git checkout with no configure +# script in it, hence the autotools. +BuildRequires: autoconf +BuildRequires: automake +BuildRequires: cargo +BuildRequires: cmake +BuildRequires: libboost_headers-devel +# redisearch's and redisjson's vendored redis-module crate runs bindgen at +# build time to generate the RedisModule_* FFI bindings, and bindgen dlopen()s +# libclang.so.* itself. +BuildRequires: clang-devel +BuildRequires: libtool +BuildRequires: python3-pip +BuildRequires: python3-setuptools +BuildRequires: rust +# for unpacking the vendor tarballs in %%prep +BuildRequires: zstd +# The modules are 64-bit x86/ARM only, and that is upstream's own limit rather +# than a packaging one: RedisBloom and RedisTimeSeries abort outright with +# "only supports 64-bit architectures (x64, arm64v8)", and redisjson's vendored +# redis-module declares the defrag cursor as u32 where a 64-bit build needs u64. +# modules/common.mk maps only x86_64, i386/i686 and aarch64/arm64 to a build +# variant anyway; everywhere else ARCH comes out empty and its tab-indented +# $(error) is read as a recipe, so make reports the unhelpful "recipe commences +# before first target" instead of naming the architecture. +ExclusiveArch: x86_64 aarch64 +%endif %description -%{name} is an advanced key-value store. It is similar to memcached but the dataset +%{origname} is an advanced key-value store. It is similar to memcached but the dataset is not volatile, and values can be strings, exactly like in memcached, but also lists, sets, and ordered sets. All this data types can be manipulated with atomic operations to push/pop elements, add/remove elements, perform server side union, intersection, difference between sets, and so forth. Redis supports different kind of sorting abilities. +%if "%{flavor}" == "modules" +%package -n %{origname}-bloom +Summary: Probabilistic data structures for Redis +Requires: %{origname} = %{version} +Provides: redisbloom = %{version} +%requires_file %{_libdir}/libclang.so + +%description -n %{origname}-bloom +RedisBloom adds Bloom filter, Cuckoo filter, count-min sketch, t-digest and +top-k data structures to Redis. + +Load it by adding the following to a configuration file below +%{_conf_dir}/includes: + + loadmodule %{_module_dir}/redisbloom.so + +%package -n %{origname}-search +Summary: Query, secondary index and full-text search for Redis +Requires: %{origname} = %{version} +Provides: redisearch = %{version} +%requires_file %{_libdir}/libclang.so + +%description -n %{origname}-search +RediSearch turns Redis into a document database with a secondary index, +full-text search, vector similarity search and aggregation. + +Load it by adding the following to a configuration file below +%{_conf_dir}/includes: + + loadmodule %{_module_dir}/redisearch.so + +%package -n %{origname}-json +Summary: JSON data type for Redis +Requires: %{origname} = %{version} +Provides: redisjson = %{version} +%requires_file %{_libdir}/libclang.so + +%description -n %{origname}-json +RedisJSON adds a native JSON data type to Redis, letting JSON documents be +stored, updated and queried down to individual paths. + +Load it by adding the following to a configuration file below +%{_conf_dir}/includes: + + loadmodule %{_module_dir}/rejson.so + +%package -n %{origname}-timeseries +Summary: Time series data type for Redis +Requires: %{origname} = %{version} +Provides: redistimeseries = %{version} +%requires_file %{_libdir}/libclang.so + +%description -n %{origname}-timeseries +RedisTimeSeries adds a time series data type to Redis, with downsampling, +compaction rules, aggregation and secondary indexing by label. + +Load it by adding the following to a configuration file below +%{_conf_dir}/includes: + + loadmodule %{_module_dir}/redistimeseries.so +%endif + %prep -echo "`grep -F %{name}-%{version}.tar.gz %{SOURCE10} | cut -d' ' -f4` %{SOURCE0}" | sha256sum -c -%autosetup -p1 +echo "`grep -F %{origname}-%{version}.tar.gz %{SOURCE10} | cut -d' ' -f4` %{SOURCE0}" | sha256sum -c +%autosetup -p1 -n %{origname}-%{version} +%if "%{flavor}" == "modules" +# Vendored crates for the two Rust modules. Both tarballs already carry the +# path they belong at, plus a .cargo/config.toml that merges upstream's own +# settings with the vendor redirect, so they unpack straight over the tree. +tar -xf %{SOURCE20} +tar -xf %{SOURCE21} +# redisearch downloads a boost release from github when the directory it +# expects boost in does not exist. Everything it uses of boost is header-only +# (geometry, optional, smart_ptr, unordered, uuid, version) and the path ends +# up as a plain -I, so pointing it at the system headers both keeps the build +# offline and avoids carrying a second copy of boost. +ln -s %{_includedir} modules/redisearch/src/.install/boost +# redisjson builds with --all-targets, which includes the test executables. +# Those reference the RedisModule_* API that only exists inside the server that +# dlopen()s the module, so they cannot link -- and the module itself, a cdylib, +# does not need them. Build the libraries only. +sed -i 's/ --all-targets//' modules/redisjson/src/Makefile +# Both Rust modules split their own debug info out into a .so.debug sibling and +# leave a .gnu_debuglink behind. That sibling is not something a package should +# ship, and the debuglink makes rpm's find-debuginfo skip the file entirely, so +# the module ends up with no debuginfo package, a dangling debuglink and its +# symbol table still in place. Leave the binaries alone and let rpm do it. +sed -i '/extract_symbols_safe.sh/d' modules/redisjson/src/Makefile +sed -i 's/^\( *\)if(CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo" AND NOT APPLE)$/\1if(FALSE) # debug symbols are extracted by rpm, see redis.spec/' \ + modules/redisearch/src/CMakeLists.txt +tar -xf %{SOURCE22} +%endif %build export HOST=OBS # for reproducible builds +%if "%{flavor}" == "modules" +export CARGO_NET_OFFLINE=true +# redisearch refuses to build unless it recognises the distribution, and its +# checker only knows dpkg, rpm-on-rhel, apk and tdnf systems. The dependencies +# it looks for are BuildRequires above, so skipping its check is safe -- this +# is upstream's own documented escape hatch. +export IGNORE_MISSING_DEPS=1 +# redisearch bundles VectorSimilarity, which by default builds Intel's +# ScalableVectorSearch backend. That pulls eve, fmt, spdlog, tomlplusplus and +# robin-map from git at configure time, and its SVS_SHARED_LIB path downloads a +# pre-compiled shared library from Intel -- none of which belongs in a +# distribution package. Without it VectorSimilarity uses its own HNSW and flat +# indexes, so vector search still works. redisearch's build.sh appends to +# CMAKE_ARGS without initialising it, so the environment is the way in. +# FETCHCONTENT_SOURCE_DIR_* is cmake's own way of satisfying a FetchContent +# dependency from a local tree instead of the network; cpu_features is the only +# one left once SVS is off. +export CMAKE_ARGS="-DUSE_SVS=OFF -DFETCHCONTENT_SOURCE_DIR_CPU_FEATURES=$(pwd)/cpu_features-0.10.1" +# modules.yaml asks for LTO on redisearch, which there means clang driving +# ld.bfd through LLVMgold.so -- a plugin openSUSE's clang does not ship, so +# every compiler probe fails before a line is compiled. common.mk applies the +# manifest defaults with ?=, so a value from the environment wins. +export LTO=0 +# -Wno-error=return-type: the redismodule.h in the vendored redismodule-rs -- a +# git dependency of redisjson -- has a function that falls off the end, and +# cc-rs picks CFLAGS up from the environment, so -Werror=return-type out of +# %%{optflags} turns that into a build failure. +# -fPIC: redistimeseries links a bundled libevent it builds itself into its +# shared module, and libevent's own build produces a non-PIC static library, +# which on aarch64 is a hard "dangerous relocation" link error. +# Everything else %%{optflags} asks for is kept. +CFLAGS="%{optflags} -Wno-error=return-type -fPIC" +export CFLAGS +export CXXFLAGS="${CFLAGS}" +# Upstream's "build" wrapper always builds the server first and only then the +# selected modules; the server binaries this produces are thrown away below, +# the redis package proper is built by the "" flavour. The modules are named +# one by one rather than via the "all" selector because "all" is also a real +# target in the top-level Makefile and would be built as a second goal. +%make_build build redisbloom redisearch redisjson redistimeseries \ + CFLAGS="${CFLAGS}" +%else # Build the server only. Since 8.x upstream vendors redisbloom, redisearch, # redisjson and redistimeseries into modules/ and the default target builds -# them, turning any module failure into a hard error. None of them is -# packaged here (see %%files), and each needs build tooling the server does -# not: cmake and a python3 with pip for redisbloom, an OS-detection fix for -# redisearch, and vendored crates for the Rust redisjson, which otherwise -# tries to reach crates.io and cannot work in an offline build root. -# "build core" selects just the server; adding the modules belongs in a -# separate multibuild flavour so the server's own rebuilds stay cheap. +# them, turning any module failure into a hard error. "build core" selects +# just the server; the modules are the "modules" flavour's job. %make_build build core CFLAGS="%{optflags}" \ BUILD_WITH_SYSTEMD=yes \ BUILD_TLS=yes -%sysusers_generate_pre %{SOURCE9} %{name} +%endif +%if "%{flavor}" == "" +%sysusers_generate_pre %{SOURCE9} %{origname} +%endif %install +%if "%{flavor}" == "modules" +install -Dpm0755 modules/redisbloom/redisbloom.so \ + %{buildroot}%{_module_dir}/redisbloom.so +install -Dpm0755 modules/redisearch/redisearch.so \ + %{buildroot}%{_module_dir}/redisearch.so +install -Dpm0755 modules/redisjson/rejson.so \ + %{buildroot}%{_module_dir}/rejson.so +install -Dpm0755 modules/redistimeseries/redistimeseries.so \ + %{buildroot}%{_module_dir}/redistimeseries.so +%endif + +%if "%{flavor}" == "" install -pm0750 -d \ %{buildroot}%{_sbindir} \ %{buildroot}%{_log_dir} \ @@ -93,16 +321,16 @@ %{buildroot}%{_log_dir}/default \ %{buildroot}%{_data_dir}/default -install -Dpm0755 src/%{name}-benchmark %{buildroot}%{_bindir}/%{name}-benchmark -install -Dpm0755 src/%{name}-cli %{buildroot}%{_bindir}/%{name}-cli +install -Dpm0755 src/%{origname}-benchmark %{buildroot}%{_bindir}/%{origname}-benchmark +install -Dpm0755 src/%{origname}-cli %{buildroot}%{_bindir}/%{origname}-cli -install -Dpm0755 src/%{name}-server %{buildroot}%{_sbindir}/%{name}-server +install -Dpm0755 src/%{origname}-server %{buildroot}%{_sbindir}/%{origname}-server -ln -sfv ../sbin/redis-server %{buildroot}%{_bindir}/%{name}-check-aof -ln -sfv ../sbin/redis-server %{buildroot}%{_bindir}/%{name}-check-rdb -ln -sfv ../sbin/redis-server %{buildroot}%{_sbindir}/%{name}-check-aof -ln -sfv ../sbin/redis-server %{buildroot}%{_sbindir}/%{name}-check-rdb -ln -sfv ../sbin/redis-server %{buildroot}%{_sbindir}/%{name}-sentinel +ln -sfv ../sbin/redis-server %{buildroot}%{_bindir}/%{origname}-check-aof +ln -sfv ../sbin/redis-server %{buildroot}%{_bindir}/%{origname}-check-rdb +ln -sfv ../sbin/redis-server %{buildroot}%{_sbindir}/%{origname}-check-aof +ln -sfv ../sbin/redis-server %{buildroot}%{_sbindir}/%{origname}-check-rdb +ln -sfv ../sbin/redis-server %{buildroot}%{_sbindir}/%{origname}-sentinel install -Dpm0640 redis.conf %{buildroot}%{_conf_dir}/includes/redis.defaults.conf install -Dpm0640 sentinel.conf %{buildroot}%{_conf_dir}/includes/sentinel.defaults.conf @@ -111,87 +339,192 @@ install -Dpm0660 sentinel.default.conf %{buildroot}%{_conf_dir}/sentinel.default.conf.template # some sysctl stuff -install -Dpm0644 %{SOURCE6} %{buildroot}/%{_prefix}/lib/sysctl.d/00-%{name}.conf -%if 0%{?suse_version} > 1500 +install -Dpm0644 %{SOURCE6} %{buildroot}%{_prefix}/lib/sysctl.d/00-%{origname}.conf mkdir -p %{buildroot}%{_distconfdir}/logrotate.d -install -Dpm0644 %{SOURCE1} %{buildroot}%{_distconfdir}/logrotate.d/%{name} -%else -install -Dpm0644 %{SOURCE1} %{buildroot}%{_sysconfdir}/logrotate.d/%{name} -%endif -install -Dpm0644 %{SOURCE2} %{buildroot}%{_unitdir}/%{name}.target -install -Dpm0644 %{SOURCE3} %{buildroot}%{_unitdir}/%{name}@.service -install -Dpm0644 %{SOURCE4} %{buildroot}%{_tmpfilesdir}/%{name}.conf -install -Dpm0644 %{SOURCE7} %{buildroot}%{_unitdir}/%{name}[email protected] -install -Dpm0644 %{SOURCE8} %{buildroot}%{_unitdir}/%{name}-sentinel.target +install -Dpm0644 %{SOURCE1} %{buildroot}%{_distconfdir}/logrotate.d/%{origname} +install -Dpm0644 %{SOURCE2} %{buildroot}%{_unitdir}/%{origname}.target +install -Dpm0644 %{SOURCE3} %{buildroot}%{_unitdir}/%{origname}@.service +install -Dpm0644 %{SOURCE4} %{buildroot}%{_tmpfilesdir}/%{origname}.conf +install -Dpm0644 %{SOURCE7} %{buildroot}%{_unitdir}/%{origname}[email protected] +install -Dpm0644 %{SOURCE8} %{buildroot}%{_unitdir}/%{origname}-sentinel.target -ln -s %{_sbindir}/service %{buildroot}%{_sbindir}/rc%{name} +ln -s %{_sbindir}/service %{buildroot}%{_sbindir}/rc%{origname} cp %{SOURCE5} README.SUSE mkdir -p %{buildroot}%{_sysusersdir} install -pm0644 %{SOURCE9} %{buildroot}%{_sysusersdir}/ +%endif %check -cat <<EOF ---------------------------------------------------- -The test suite often fails to start a server, with -'child process exited abnormally' -- sometimes it works. ---------------------------------------------------- -EOF +%if "%{flavor}" == "test" +# The suite used to be run with "|| true" here because it kept failing to start +# a server with 'child process exited abnormally'. That turns out to be servers +# leaked by an earlier run of the suite still sitting on ports in the range the +# test clients are handed; in a fresh build root there are none and the suite +# passes. So let a failure be a failure -- this flavour ships nothing, so a +# red test run blocks no rebuild. +# Cap the run: a test client that wedges rather than failing would otherwise sit +# on the worker until the global build timeout, and "make -C src test" gives no +# way to pass the suite's own --timeout through to runtest. The suite needs +# about 25 minutes here, so two hours is a generous ceiling that still fails in +# bounded time; -k makes sure a client ignoring SIGTERM is killed. +# +# runtest is called directly instead of through "make test": src/Makefile's test +# target hardcodes a bare "./runtest", and the skip options below have to reach +# it. That target also depends on the helper modules the moduleapi tests +# dlopen(); %%build's "build core" already produces them, so the line below is +# only a cheap guarantee that they exist however %%build is later changed. # Variable assignments need to match in all make invocations, otherwise it might recomplie. See https://github.com/redis/redis/issues/7337 -%make_build test CFLAGS="%{optflags}" BUILD_WITH_SYSTEMD=yes BUILD_TLS=yes || true +%make_build -C src module_tests CFLAGS="%{optflags}" BUILD_WITH_SYSTEMD=yes BUILD_TLS=yes +# --no-latency is upstream's own switch for the assertions that bound how long +# an operation took (LATENCY HISTORY/LATEST, the active-defrag max_latency +# ceilings). Those measure the builder's load rather than redis, and a shared +# OBS worker misses them on the slower architectures. +# +# Two more tests bound wall-clock time with no switch to turn them off, so they +# are named here. --skipfile takes one test name per line, matched literally. +cat > obs-skiptests <<'EOF' +BZPOPMIN unblock but the key is expired and then block again - reprocessing command +XREADGROUP CLAIM block times out with no claimable messages +EOF +%ifarch ppc64le +# "defrag didn't stop" -- the active-defrag cycle does not converge inside the +# suite's wait on ppc64le. Long-standing and not specific to this version: +# boo#1247364 records the same failure against redis 6.0.14 and 7.0.8 there in +# 2025. It is a wait_for_condition timeout, so --no-latency does not cover it. +cat >> obs-skiptests <<'EOF' +Active defrag can't be triggered during replicaof database flush. See issue #14267 +EOF +%endif +%ifarch %{ix86} +# "defrag didn't stop or failed to achieve expected frag ratio" -- on 32-bit x86 +# the fragmentation target is actually met (1.06 against the 1.1 asked for); it +# is the other half of the condition that never comes true. Residual small-bin +# waste settles around 6% / 1.6MB, just above both the active-defrag-threshold- +# lower (5) and active-defrag-ignore-bytes (1500kb) the test itself sets, so +# activeDefragCycle never reaches its stop condition and the 50s wait expires. +# A three percent margin, so it is not something --no-latency covers. Entries +# beginning with '/' are regexps, which catches both ": cluster" and +# ": standalone". +cat >> obs-skiptests <<'EOF' +/^Active defrag IDMP streams: +EOF +%endif +# tests/integration/logging.tcl and tests/unit/moduleapi/crash.tcl assert on the +# contents of redis' own crash report -- the stack trace, the frame for the +# command that crashed, one "STACK TRACE" block per thread. Upstream gates them +# on system_backtrace_supported (tests/support/util.tcl), which only asks +# whether this is Linux with a non-musl libc and never looks at the +# architecture, so they also run where the crash reporter cannot deliver what +# they expect. x86_64 and aarch64 do, and keep running them. +# Unquoted on purpose below: the value is meant to split into words. +%ifarch x86_64 aarch64 +skipunits= +%else +skipunits="--skipunit integration/logging --skipunit unit/moduleapi/crash" +%endif +# runtest defaults to 16 parallel clients, each starting several servers. On an +# OBS worker that oversubscribes the machine badly -- a run whose per-unit times +# sum to about 2900s finishes in 600s of wall clock -- and the tests that then +# fail are the ones with a fixed deadline: a cluster MEET handshake has to +# complete inside cluster-node-timeout or the node is dropped, an AOF child has +# to be reaped before a shutdown, and so on. Each architecture lost a different +# one of these, which is the signature of contention rather than of a bug in any +# of them. Upstream has a guard for exactly this (is_a_slow_computer, which +# drops to a single client) but it times a Tcl loop and so cannot see load. +# Four clients keeps the run comfortably inside the timeout above. +timeout -k 60 7200 \ +./runtest --no-latency --clients 4 --skipfile obs-skiptests ${skipunits} +%endif +%if "%{flavor}" == "modules" +# A module that did not finish linking still produces a file, so check that +# each one actually exports the entry point the server dlsym()s. +for so in %{buildroot}%{_module_dir}/*.so; do + nm -D --defined-only "${so}" | grep -qw RedisModule_OnLoad || + { echo "error: ${so} does not export RedisModule_OnLoad" >&2; exit 1; } +done +%endif +%if "%{flavor}" == "" +src/%{origname}-server --version +src/%{origname}-cli --version +%endif -%pre -f %{name}.pre -%service_add_pre %{name}.target %{name}@.service %{name}-sentinel.target %{name}[email protected] -%if 0%{?suse_version} > 1500 +%if "%{flavor}" == "" +%pre -f %{origname}.pre +%service_add_pre %{origname}.target %{origname}@.service %{origname}-sentinel.target %{origname}[email protected] # Prepare for migration to /usr/etc; save any old .rpmsave -for i in logrotate.d/%{name} ; do +for i in logrotate.d/%{origname} ; do test -f %{_sysconfdir}/${i}.rpmsave && mv -v %{_sysconfdir}/${i}.rpmsave %{_sysconfdir}/${i}.rpmsave.old ||: done -%endif -%if 0%{?suse_version} > 1500 %posttrans # Migration to /usr/etc, restore just created .rpmsave -for i in logrotate.d/%{name} ; do +for i in logrotate.d/%{origname} ; do test -f %{_sysconfdir}/${i}.rpmsave && mv -v %{_sysconfdir}/${i}.rpmsave %{_sysconfdir}/${i} ||: done -%endif %post -%tmpfiles_create %{_tmpfilesdir}/%{name}.conf -%service_add_post %{name}.target %{name}@.service %{name}-sentinel.target %{name}[email protected] -echo "See %{_docdir}/%{name}/README.SUSE to continue" +%tmpfiles_create %{_tmpfilesdir}/%{origname}.conf +%service_add_post %{origname}.target %{origname}@.service %{origname}-sentinel.target %{origname}[email protected] +echo "See %{_docdir}/%{origname}/README.SUSE to continue" %preun -%service_del_preun %{name}.target %{name}@.service %{name}-sentinel.target %{name}[email protected] +%service_del_preun %{origname}.target %{origname}@.service %{origname}-sentinel.target %{origname}[email protected] %postun -%service_del_postun %{name}.target %{name}@.service %{name}-sentinel.target %{name}[email protected] +%service_del_postun %{origname}.target %{origname}@.service %{origname}-sentinel.target %{origname}[email protected] %files %license LICENSE.txt # redis-full.conf is generated only by the module build (it carries the # loadmodule lines) and would reference modules this package does not ship %doc 00-RELEASENOTES BUGS REDISCONTRIBUTIONS.txt *.md -%if 0%{?suse_version} > 1500 -%{_distconfdir}/logrotate.d/%{name} -%else -%config(noreplace) %{_sysconfdir}/logrotate.d/%{name} -%endif -%{_prefix}/lib/sysctl.d/00-%{name}.conf -%{_bindir}/%{name}-* -%{_sbindir}/%{name}-* -%{_sbindir}/rc%{name} -%{_tmpfilesdir}/%{name}.conf -%{_sysusersdir}/%{name}-user.conf -%{_unitdir}/%{name}@.service -%{_unitdir}/%{name}.target -%{_unitdir}/%{name}[email protected] -%{_unitdir}/%{name}-sentinel.target +%{_distconfdir}/logrotate.d/%{origname} +%{_prefix}/lib/sysctl.d/00-%{origname}.conf +%{_bindir}/%{origname}-* +%{_sbindir}/%{origname}-* +%{_sbindir}/rc%{origname} +%{_tmpfilesdir}/%{origname}.conf +%{_sysusersdir}/%{origname}-user.conf +%{_unitdir}/%{origname}@.service +%{_unitdir}/%{origname}.target +%{_unitdir}/%{origname}[email protected] +%{_unitdir}/%{origname}-sentinel.target %doc README.SUSE -%config(noreplace) %attr(-,root,%{name}) %{_conf_dir}/ -%dir %attr(0750,%{name},%{name}) %{_data_dir} -%dir %attr(0750,%{name},%{name}) %{_data_dir}/default -%dir %attr(0750,%{name},%{name}) %{_log_dir} -%ghost %dir %attr(0755,%{name},%{name}) /run/%{name} +%config(noreplace) %attr(-,root,%{origname}) %{_conf_dir}/ +%dir %attr(0750,%{origname},%{origname}) %{_data_dir} +%dir %attr(0750,%{origname},%{origname}) %{_data_dir}/default +%dir %attr(0750,%{origname},%{origname}) %{_log_dir} +%ghost %dir %attr(0755,%{origname},%{origname}) /run/%{origname} +%endif + +%if "%{flavor}" == "modules" +%files -n %{origname}-bloom +%license modules/redisbloom/src/LICENSE.txt +%doc modules/redisbloom/src/README.md +%dir %{_libdir}/%{origname} +%dir %{_module_dir} +%{_module_dir}/redisbloom.so + +%files -n %{origname}-search +%license modules/redisearch/src/LICENSE.txt +%doc modules/redisearch/src/README.md +%dir %{_libdir}/%{origname} +%dir %{_module_dir} +%{_module_dir}/redisearch.so + +%files -n %{origname}-json +%license modules/redisjson/src/LICENSE.txt +%doc modules/redisjson/src/README.md +%dir %{_libdir}/%{origname} +%dir %{_module_dir} +%{_module_dir}/rejson.so + +%files -n %{origname}-timeseries +%license modules/redistimeseries/src/LICENSE.txt +%doc modules/redistimeseries/src/README.md +%dir %{_libdir}/%{origname} +%dir %{_module_dir} +%{_module_dir}/redistimeseries.so +%endif ++++++ _multibuild ++++++ <multibuild> <flavor>modules</flavor> <flavor>test</flavor> </multibuild> ++++++ _service ++++++ <services> <!-- Only the "modules" multibuild flavour needs these: two of the modules upstream vendors under modules/ are (partly) written in Rust and would otherwise reach out to crates.io and to three git repositories at build time. They are separate workspaces, hence two runs distinguished by "tag"; each produces vendor-<tag>.tar.zst plus a merged .cargo config already rooted at the right directory inside the source tree, so %prep only has to unpack them. Both are mode="manual" (they need network access): after a version bump run "osc service manualrun" and remember to update the tarball name in the "src" parameter below. --> <service name="cargo_vendor" mode="manual"> <param name="src">redis-8.10.0.tar.gz</param> <param name="custom-root">modules/redisjson/src</param> <param name="tag">redisjson</param> <param name="update">false</param> <param name="respect-lockfile">true</param> </service> <service name="cargo_vendor" mode="manual"> <param name="src">redis-8.10.0.tar.gz</param> <param name="custom-root">modules/redisearch/src/src/redisearch_rs</param> <param name="tag">redisearch</param> <param name="update">false</param> <param name="respect-lockfile">true</param> </service> </services> ++++++ lazyfree-test-explicit-stream-ids.patch ++++++ From: Martin Pluskal <[email protected]> Subject: tests: give the lazyfree stream test explicit IDs "lazy free a stream with all types of metadata" builds a 1000-entry stream with stream-node-max-entries 5, UNLINKs it and asserts it was freed by the lazyfree thread rather than inline. Whether that happens is decided by lazyfreeGetFreeEffort(), which for a stream is effort = s->rax->numnodes + raxSize(cgroups) * (1 + raxSize(pel)) and is freed asynchronously only when it exceeds LAZYFREE_THRESHOLD, 64. With one consumer group holding a two-entry PEL the second term contributes 3, so the test rests entirely on the stream's radix tree having more than 61 nodes. It does not have a fixed number of nodes. The keys are the 200 master entry IDs, and with server-generated IDs their high 8 bytes are the wall-clock millisecond: entries added inside the same millisecond share that prefix and collapse into a single compressed node. So numnodes is not the number of entries, it is roughly the number of distinct milliseconds the XADD loop spanned -- i.e. how long the loop took. Measured on one aarch64 machine: loop spans ~200ms (200 distinct ms) numnodes = 204 -> lazy freed, passes loop spans a few ms (pipelined) numnodes = 18 -> freed inline, fails loop spans one ms (inside EVAL) numnodes = 6 -> freed inline, fails Any host that gets through 1000 XADD round trips in appreciably less than 64ms fails the test, and one just fast enough sits on the boundary and fails intermittently. That is what it does on the faster of openSUSE's aarch64 build workers: the same source passes on one worker and fails on another. Add the entries with explicit IDs a millisecond apart instead. The radix tree then has the same shape everywhere, 206 nodes, and the test measures lazyfree rather than the speed of the machine it runs on. Nothing in the test's intent changes -- the stream still carries a consumer group, a PEL, an acknowledged entry and a tombstone. --- a/tests/unit/lazyfree.tcl +++ b/tests/unit/lazyfree.tcl @@ -50,11 +50,20 @@ r config resetstat r config set stream-node-max-entries 5 + # Use explicit IDs one millisecond apart. What decides whether UNLINK + # frees the stream lazily is lazyfreeGetFreeEffort(), which for a stream + # is dominated by the number of nodes in its radix tree, and with + # server-generated IDs that is the number of distinct milliseconds these + # 1000 XADDs happen to span -- keys sharing a millisecond share a prefix + # and collapse into one compressed node. On a machine fast enough to run + # the loop in well under 64ms the whole stream fits in a handful of + # nodes, the effort falls below LAZYFREE_THRESHOLD, the stream is freed + # synchronously and lazyfreed_objects stays 0. for {set j 0} {$j < 1000} {incr j} { if {rand() < 0.9} { - r xadd stream * foo $j + r xadd stream $j-1 foo $j } else { - r xadd stream * bar $j + r xadd stream $j-1 bar $j } } r xgroup create stream mygroup 0 ++++++ redis-conf.patch ++++++ --- /var/tmp/diff_new_pack.wafZ8T/_old 2026-08-06 16:18:23.652472061 +0200 +++ /var/tmp/diff_new_pack.wafZ8T/_new 2026-08-06 16:18:23.656472201 +0200 @@ -1,7 +1,7 @@ -Index: redis-7.4.2/redis.conf +Index: redis-8.10.0/redis.conf =================================================================== ---- redis-7.4.2.orig/redis.conf -+++ redis-7.4.2/redis.conf +--- redis-8.10.0.orig/redis.conf ++++ redis-8.10.0/redis.conf @@ -136,7 +136,7 @@ protected-mode yes # Accept connections on the specified port, default is 6379 (IANA #815344). @@ -11,7 +11,7 @@ # TCP listen() backlog. # -@@ -307,7 +307,7 @@ tcp-keepalive 300 +@@ -359,7 +359,7 @@ tcp-keepalive 300 # By default Redis does not run as a daemon. Use 'yes' if you need it. # Note that Redis will write a pid file in /var/run/redis.pid when daemonized. # When Redis is supervised by upstart or systemd, this parameter has no impact. @@ -20,7 +20,7 @@ # If you run Redis from upstart or systemd, Redis can interact with your # supervision tree. Options: -@@ -325,7 +325,7 @@ daemonize no +@@ -377,7 +377,7 @@ daemonize no # The default is "no". To run under upstart/systemd, you can simply uncomment # the line below: # @@ -29,7 +29,7 @@ # If a pid file is specified, Redis writes it where specified at startup # and removes it at exit. -@@ -339,7 +339,7 @@ daemonize no +@@ -391,7 +391,7 @@ daemonize no # # Note that on modern Linux systems "/run/redis.pid" is more conforming # and should be used instead. @@ -38,7 +38,7 @@ # Specify the server verbosity level. # This can be one of: -@@ -353,7 +353,8 @@ loglevel notice +@@ -405,7 +405,8 @@ loglevel notice # Specify the log file name. Also the empty string can be used to force # Redis to log on the standard output. Note that if you use standard # output for logging but daemonize, logs will be sent to /dev/null @@ -48,7 +48,7 @@ # To enable logging to the system logger, just set 'syslog-enabled' to yes, # and optionally update the other syslog parameters to suit your needs. -@@ -513,7 +514,7 @@ rdb-del-sync-files no +@@ -565,7 +566,7 @@ rdb-del-sync-files no # The Append Only File will also be created inside this directory. # # Note that you must specify a directory here, not a file name. @@ -57,10 +57,25 @@ ################################# REPLICATION ################################# -Index: redis-7.4.2/sentinel.conf +@@ -2715,10 +2716,10 @@ jemalloc-bg-thread yes + # Bad manifest: <none> + + # >>> BEGIN: loadmodule paths (replaced by make deploy) <<< +-loadmodule ./modules/redisbloom/redisbloom.so +-loadmodule ./modules/redisearch/redisearch.so +-loadmodule ./modules/redisjson/rejson.so +-loadmodule ./modules/redistimeseries/redistimeseries.so ++# loadmodule ./modules/redisbloom/redisbloom.so ++# loadmodule ./modules/redisearch/redisearch.so ++# loadmodule ./modules/redisjson/rejson.so ++# loadmodule ./modules/redistimeseries/redistimeseries.so + # <<< END: loadmodule paths <<< + + # >>> BEGIN module: redisbloom <<< +Index: redis-8.10.0/sentinel.conf =================================================================== ---- redis-7.4.2.orig/sentinel.conf -+++ redis-7.4.2/sentinel.conf +--- redis-8.10.0.orig/sentinel.conf ++++ redis-8.10.0/sentinel.conf @@ -7,17 +7,18 @@ protected-mode no # port <sentinel-port> @@ -91,22 +106,30 @@ # To enable logging to the system logger, just set 'syslog-enabled' to yes, # and optionally update the other syslog parameters to suit your needs. -Index: redis-7.4.2/redis.default.conf +Index: redis-8.10.0/redis.default.conf =================================================================== --- /dev/null -+++ redis-7.4.2/redis.default.conf -@@ -0,0 +1,7 @@ ++++ redis-8.10.0/redis.default.conf +@@ -0,0 +1,15 @@ +include /etc/redis/includes/redis.defaults.conf + ++# modules loaded by default before. But since we got the modules split out into packages, ++# we removed them in the default config and you need to enable them here. ++# ++# loadmodule ./modules/redisbloom/redisbloom.so ++# loadmodule ./modules/redisearch/redisearch.so ++# loadmodule ./modules/redisjson/rejson.so ++# loadmodule ./modules/redistimeseries/redistimeseries.so ++ +port 6379 +dir /var/lib/redis/default/ +pidfile /run/redis/default.pid +logfile /var/log/redis/default.log + -Index: redis-7.4.2/sentinel.default.conf +Index: redis-8.10.0/sentinel.default.conf =================================================================== --- /dev/null -+++ redis-7.4.2/sentinel.default.conf ++++ redis-8.10.0/sentinel.default.conf @@ -0,0 +1,6 @@ +include /etc/redis/includes/sentinel.defaults.conf + ++++++ scripting-test-disable-aof-after-use.patch ++++++ From: Martin Pluskal <[email protected]> Subject: tests: turn AOF back off after "Timedout scripts and unblocked command" That test switches appendonly on and never switches it back, so it leaves an initial AOF rewrite child behind. The child is only reaped by checkChildrenDone() from serverCron, and serverCron does not run while a busy Lua script is executing -- whileBlockedCron() does not reap children. The next test in the file leaves an unkillable infinite script running and then expects SHUTDOWN NOSAVE to kill the server. If the AOF child has not been reaped by then, finishShutdown() takes the "Writing initial AOF, can't exit." path and refuses, so the server survives and the test sees a BUSY reply where it expected the connection to be refused. Whether that happens is purely a matter of how much CPU the fork got, which makes the test flaky on loaded build workers. Turn appendonly back off at the end of the test that enabled it. This is the same fix valkey made in valkey-io/valkey#1156; redis has not picked it up. --- a/tests/unit/scripting.tcl +++ b/tests/unit/scripting.tcl @@ -1476,6 +1476,7 @@ $rd close $rd2 close $r3 close + r config set appendonly no r DEBUG set-disable-deny-scripts 0 } {OK} {external:skip needs:debug} ++++++ series ++++++ --- /var/tmp/diff_new_pack.wafZ8T/_old 2026-08-06 16:18:23.832478361 +0200 +++ /var/tmp/diff_new_pack.wafZ8T/_new 2026-08-06 16:18:23.836478501 +0200 @@ -1,4 +1,7 @@ redis-conf.patch reproducible.patch ppc-atomic.patch +vectorsimilarity-guard-svs-include.patch +scripting-test-disable-aof-after-use.patch +lazyfree-test-explicit-stream-ids.patch ++++++ vectorsimilarity-guard-svs-include.patch ++++++ From: Martin Pluskal <[email protected]> Subject: VectorSimilarity: guard the SVS code paths so USE_SVS=OFF builds Upstream PR: https://github.com/RedisAI/VectorSimilarity/pull/1006 Building redisearch with -DUSE_SVS=OFF -- an option VectorSimilarity offers itself, via cmake_dependent_option(USE_SVS ...) in cmake/svs.cmake -- does not compile. HAVE_SVS is then 0 and the ScalableVectorSearch sources are never fetched, but two translation units still reach for SVS unconditionally: src/VecSim/algorithms/svs/svs.h:21:10: fatal error: svs/index/vamana/dynamic_index.h: No such file or directory (via tiered_factory.h -> svs_tiered.h -> svs.h) src/VecSim/algorithms/svs/svs_utils.h:16:10: fatal error: svs/core/distance.h: No such file or directory (via vec_sim.cpp) tiered_factory.h needs nothing from svs_tiered.h -- none of its declarations mention an SVS type -- so that include is simply guarded, the way tiered_factory.cpp and svs_factory.cpp already guard the same headers. vec_sim.cpp does use VecSimSVSThreadPool, in two functions that are part of the public C API and so have to keep existing either way: with no SVS there is no shared pool for VecSim_UpdateThreadPoolSize() to resize, and no shared allocation for VecSim_GetSharedMemory() to report. diff --git a/modules/redisearch/src/deps/VectorSimilarity/src/VecSim/index_factories/tiered_factory.h b/modules/redisearch/src/deps/VectorSimilarity/src/VecSim/index_factories/tiered_factory.h index fbb55d3..3cf0d5d 100644 --- a/modules/redisearch/src/deps/VectorSimilarity/src/VecSim/index_factories/tiered_factory.h +++ b/modules/redisearch/src/deps/VectorSimilarity/src/VecSim/index_factories/tiered_factory.h @@ -13,7 +13,9 @@ #include "VecSim/memory/vecsim_malloc.h" #include "VecSim/vec_sim_index.h" #include "VecSim/algorithms/hnsw/hnsw_tiered.h" +#if HAVE_SVS #include "VecSim/algorithms/svs/svs_tiered.h" +#endif #include "VecSim/algorithms/brute_force/brute_force.h" #include "VecSim/index_factories/factory_utils.h" diff --git a/modules/redisearch/src/deps/VectorSimilarity/src/VecSim/vec_sim.cpp b/modules/redisearch/src/deps/VectorSimilarity/src/VecSim/vec_sim.cpp index 4fed53a..9da4eb3 100644 --- a/modules/redisearch/src/deps/VectorSimilarity/src/VecSim/vec_sim.cpp +++ b/modules/redisearch/src/deps/VectorSimilarity/src/VecSim/vec_sim.cpp @@ -15,7 +15,9 @@ #include "VecSim/vec_sim_index.h" #include "VecSim/vec_sim_adhoc_bf_ctx.h" #include "VecSim/types/bfloat16.h" +#if HAVE_SVS #include "VecSim/algorithms/svs/svs_utils.h" +#endif #include <cassert> #include "memory.h" @@ -41,10 +43,16 @@ extern "C" void VecSim_UpdateThreadPoolSize(size_t new_size) { } else { VecSimIndex::setWriteMode(VecSim_WriteAsync); } +#if HAVE_SVS // Resize the shared SVS pool. Clamped to a minimum of 1. OS threads are spawned // lazily on first SVS index creation; once an index exists this resizes the // shared pool immediately (cooperating with the deferred-shrink protocol). VecSimSVSThreadPool::resize(new_size); +#else + // No SVS, so there is no shared pool to resize; the write mode set above is + // all this call has to do. + (void)new_size; +#endif } static VecSimResolveCode _ResolveParams_EFRuntime(VecSimAlgo index_type, VecSimRawParam rparam, @@ -392,7 +400,13 @@ extern "C" VecSimDebugInfoIterator *VecSimIndex_DebugInfoIterator(VecSimIndex *i } extern "C" size_t VecSim_GetSharedMemory(void) { +#if HAVE_SVS return VecSimSVSThreadPool::getSharedAllocationSize(); +#else + // The shared pool is an SVS construct; without it no memory is held outside + // the individual indexes, which already report their own. + return 0; +#endif } extern "C" VecSimIndexBasicInfo VecSimIndex_BasicInfo(VecSimIndex *index) {
