From 496fb5b51fbc8f0c7ce568b3331a7db2c5cb98a9 Mon Sep 17 00:00:00 2001 From: Emanuele Danovaro Date: Fri, 21 Aug 2026 07:41:27 +0000 Subject: [PATCH 1/3] FDB-735 while reading subtoc, do not check the current directory for the toc of an overlay --- src/fdb5/toc/TocHandler.cc | 10 +++++++++- tests/fdb/api/test_auxiliary.cc | 2 +- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/fdb5/toc/TocHandler.cc b/src/fdb5/toc/TocHandler.cc index 68f769578..5cd6bf4ad 100644 --- a/src/fdb5/toc/TocHandler.cc +++ b/src/fdb5/toc/TocHandler.cc @@ -674,6 +674,7 @@ eckit::LocalPathName TocHandler::parseSubTocRecord(const TocRecord& r, bool read eckit::MemoryStream s(&r.payload_[0], r.maxPayloadSize); eckit::LocalPathName path; s >> path; + // Handle both path and absPath for compatibility as we move from storing // absolute paths to relative paths. Either may exist in either the TOC_SUB_TOC // or TOC_CLEAR entries. @@ -682,7 +683,14 @@ eckit::LocalPathName TocHandler::parseSubTocRecord(const TocRecord& r, bool read if (path.path()[0] == '/') { absPath = findRealPath(path); if (!absPath.exists()) { - absPath = currentDirectory() / path.baseName(); + // the DB may have been moved, so try to find the subtoc in the current directory + // except in case of an overlay (subtoc name = "toc") + if (path.baseName() != "toc") { + absPath = currentDirectory() / path.baseName(); + } + else { + absPath = ""; + } } } else { diff --git a/tests/fdb/api/test_auxiliary.cc b/tests/fdb/api/test_auxiliary.cc index 3c5be890b..4bd249db1 100644 --- a/tests/fdb/api/test_auxiliary.cc +++ b/tests/fdb/api/test_auxiliary.cc @@ -199,7 +199,7 @@ CASE("Ensure wipe fails if extensions are unknown") { auto iter = fdb.wipe(request, doit, false, unsafeWipeAll); while (iter.next(elem)) {} } - catch (eckit::Exception) { + catch (eckit::Exception&) { error_was_thrown = true; } EXPECT(error_was_thrown); From 688e80b35fe01825002edb43c5d1efe5ab6eeaba Mon Sep 17 00:00:00 2001 From: Emanuele Danovaro Date: Fri, 21 Aug 2026 08:35:11 +0000 Subject: [PATCH 2/3] FDB-735 error message --- src/fdb5/toc/TocHandler.cc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/fdb5/toc/TocHandler.cc b/src/fdb5/toc/TocHandler.cc index 5cd6bf4ad..7b94c4830 100644 --- a/src/fdb5/toc/TocHandler.cc +++ b/src/fdb5/toc/TocHandler.cc @@ -689,6 +689,9 @@ eckit::LocalPathName TocHandler::parseSubTocRecord(const TocRecord& r, bool read absPath = currentDirectory() / path.baseName(); } else { + eckit::Log::error() + << "Skipping an FDB overlay database that is no longer available. Original path was: " << path + << std::endl; absPath = ""; } } From 48533e3d9cc99be50657e17a92687f442b219c37 Mon Sep 17 00:00:00 2001 From: Emanuele Danovaro Date: Wed, 26 Aug 2026 08:58:26 +0200 Subject: [PATCH 3/3] FDB-735 non regression test --- tests/regressions/CMakeLists.txt | 1 + tests/regressions/FDB-735/CMakeLists.txt | 5 +++ tests/regressions/FDB-735/FDB-735.sh.in | 56 ++++++++++++++++++++++++ tests/regressions/FDB-735/config.yaml | 8 ++++ tests/regressions/FDB-735/schema | 12 +++++ 5 files changed, 82 insertions(+) create mode 100644 tests/regressions/FDB-735/CMakeLists.txt create mode 100755 tests/regressions/FDB-735/FDB-735.sh.in create mode 100644 tests/regressions/FDB-735/config.yaml create mode 100644 tests/regressions/FDB-735/schema diff --git a/tests/regressions/CMakeLists.txt b/tests/regressions/CMakeLists.txt index 207b6c486..b1d253f2f 100644 --- a/tests/regressions/CMakeLists.txt +++ b/tests/regressions/CMakeLists.txt @@ -32,6 +32,7 @@ if (HAVE_FDB_BUILD_TOOLS) # test scripts use the fdb tools endif() add_subdirectory(FDB-241) + add_subdirectory(FDB-735) if (HAVE_FDB_REMOTE) add_subdirectory(FDB-419) diff --git a/tests/regressions/FDB-735/CMakeLists.txt b/tests/regressions/FDB-735/CMakeLists.txt new file mode 100644 index 000000000..30547fdff --- /dev/null +++ b/tests/regressions/FDB-735/CMakeLists.txt @@ -0,0 +1,5 @@ +ecbuild_configure_file( FDB-735.sh.in FDB-735.sh @ONLY ) +ecbuild_add_test( + TYPE SCRIPT + COMMAND FDB-735.sh + ENVIRONMENT "${test_environment}" ) diff --git a/tests/regressions/FDB-735/FDB-735.sh.in b/tests/regressions/FDB-735/FDB-735.sh.in new file mode 100755 index 000000000..ed4e0d15e --- /dev/null +++ b/tests/regressions/FDB-735/FDB-735.sh.in @@ -0,0 +1,56 @@ +#!/usr/bin/env bash + +# A 'type: select' FDB whose lanes share the same physical root can, for a +# partial (ambiguous) list/wipe request that omits the keyword used to +# discriminate between lanes, have every matching lane independently +# rediscover the *same* on-disk catalogue and process it more than once. +# +# Two lanes ("stream=oper" and "stream=dcda") share the same root. +# A request that omits "stream" entirely legitimately matches both lanes +# (SelectFDB's MatchOnMissing policy), so both are queried -- but each lane +# then scans the *shared* root and finds *both* catalogues (the per-lane +# selector is not used to filter which catalogues are relevant), so every +# catalogue is reported/wiped once per lane instead of once overall. + +set -euxo pipefail + +yell() { printf "$(basename "$0"): \033[0;31m!!! %s !!!\033[0m\\n" "$*" >&2; } +die() { yell "$*"; exit 1; } + +fdbroot="$" +fdboverlay="$" +fdbwipe="$" + +srcdir=@CMAKE_CURRENT_SOURCE_DIR@ +bindir=@CMAKE_CURRENT_BINARY_DIR@ +wdir=$bindir/FDB-735 + +### cleanup and prepare test + +rm -rf "$wdir" +mkdir -p "$wdir/etc/fdb" +mkdir -p "$wdir/root" + +cd "$wdir" + +for f in config.yaml schema +do + cp "$srcdir/$f" "$wdir/etc/fdb" +done + +export FDB_HOME="$wdir" +unset FDB5_CONFIG_FILE +unset FDB_CONFIG_FILE + +# create empty expver 1234 +$fdbroot class=od,expver=1234,stream=oper,domain=g,date=-1,time=0 --create + +# overlay 1235 --> 1234 +$fdboverlay class=od,expver=1234,stream=oper,domain=g,date=-1,time=0 class=od,expver=1235,stream=oper,domain=g,date=-1,time=0 + +# remove 1234 (dangerous, since we have an overlay!) +$fdbwipe class=od,expver=1234,stream=oper,domain=g,date=-1,time=0 --doit + +# segfault while removing 1235 +$fdbwipe class=od,expver=1235,stream=oper,domain=g,date=-1,time=0 + diff --git a/tests/regressions/FDB-735/config.yaml b/tests/regressions/FDB-735/config.yaml new file mode 100644 index 000000000..4dd904599 --- /dev/null +++ b/tests/regressions/FDB-735/config.yaml @@ -0,0 +1,8 @@ +--- +type: local +schema: ~fdb/etc/fdb/schema +engine: toc +spaces: +- handler: Default + roots: + - path: ./root diff --git a/tests/regressions/FDB-735/schema b/tests/regressions/FDB-735/schema new file mode 100644 index 000000000..36abb37fc --- /dev/null +++ b/tests/regressions/FDB-735/schema @@ -0,0 +1,12 @@ + +param: Param; +step: Step; +date: Date; +levelist: Double; +expver: Expver; +time: Time; + +[ class, expver, stream, date, time, domain + [ type, levtype + [ step, levelist, param ]] +]