Skip to content

Commit 92248c1

Browse files
RDMA: provide kernel-symbol stub so RDMA_Transporter-t links in CI
`RDMA_Transporter-t` is registered via `NDB_ADD_TEST` in `storage/ndb/src/common/transporter/CMakeLists.txt`. The target returns silently from the macro when `WITH_UNIT_TESTS=OFF`, but the option defaults to ON whenever `WITHOUT_SERVER=OFF` (see `CMakeLists.txt:843-849`), which is the standard configure RonDB CI uses for a release build. Under that combination the test executable is created, and the link step has been failing since the target was first added: storage/ndb/src/common/transporter/CMakeFiles/ RDMA_Transporter-t.dir/build.make:130: undefined reference to `copy(unsigned int*&, SectionSegmentPool&, SegmentedSectionPtr const&)' Root cause is independent of the RDMA-side code. `Packer.cpp` (part of the `ndbtransport` convenience library that the test binary links against) emits an unconditional explicit instantiation: template void Packer::pack<Packer::SegmentedSectionArg>( Uint32 *theData, SegmentedSectionArg section) const; That instantiation references the free function bool copy(unsigned int *&, SectionSegmentPool &, SegmentedSectionPtr const &); whose definition lives on the kernel side of the build, alongside the `SegmentSubPool` / `SegmentedSectionPtr` implementations. None of the libraries the test depends on (`ndbtransport`, `ndbmgmapi`, `ndbgeneral`, `ndbportlib`, `${NDB_RDMA_LIBRARIES}`, `mytap`) define the symbol, so the linker cannot resolve it. Whether or not the call path is reachable at runtime is irrelevant -- the explicit template instantiation forces emission of the reference at compile time. The standalone harness `build_scripts/build_and_test_rdma_ transporter.sh` already works around the same issue by generating a tiny stub source on the fly and linking it into a hand-built test binary. This change bakes the same stub into the regular CMake build so the `WITH_UNIT_TESTS=ON` CI path can link `RDMA_Transporter-t` without dragging in any kernel-side libraries. Changes ------- `storage/ndb/src/common/transporter/RDMA_Transporter_test_stubs.cpp` (new file) - Defines `bool copy(unsigned int *&, SectionSegmentPool &, SegmentedSectionPtr const &)` as an abort-stub. The wire-format TAP cases exercised by the test executable touch only the pure helpers `encode_msg_header` / `validate_msg_header` and small in-anonymous-namespace routines; none of those paths invoke `Packer::pack<SegmentedSectionArg>`, so the stub is never reached at runtime. If a future test addition does hit it the abort produces a clear diagnostic identifying the stub by name. Opaque forward declarations of `SectionSegmentPool` / `SegmentedSectionPtr` keep the file free of kernel-side header dependencies. `storage/ndb/src/common/transporter/CMakeLists.txt` - Adds `RDMA_Transporter_test_stubs.cpp` as a second source file to the existing `NDB_ADD_TEST(RDMA_Transporter-t ...)` block. The stub is compiled per-target only -- it does not enter the `ndbtransport` convenience library and so cannot leak into any non-test code path. A comment block above the `NDB_ADD_TEST` call documents why the companion source exists. Verification ------------ Built with the exact configure command from the original bug report: cmake -S . -B build-lab \ -DCMAKE_BUILD_TYPE=Release \ -DWITH_NDB_RDMA=ON \ -DWITHOUT_SERVER=OFF \ -DWITH_NDBCLUSTER_STORAGE_ENGINE=ON \ -DCMAKE_INSTALL_PREFIX=/opt/rondb-24.10-rdma-port cmake --build build-lab --target RDMA_Transporter-t Result: `RDMA_Transporter-t` builds and links cleanly. Running the binary: 1..1 ok 1 - RDMA_Transporter The standalone harness `build_scripts/build_and_test_rdma_transporter.sh` is unchanged; it still works because its hand-built link line already includes its own runtime-generated stub, and the new in-tree companion source is gated on the regular CMake `NDB_ADD_TEST` target. No runtime behaviour changes. The production `ndbtransport` library is byte-identical; only the standalone test binary gains the additional translation unit.
1 parent 7c38fe7 commit 92248c1

2 files changed

Lines changed: 94 additions & 1 deletion

File tree

storage/ndb/src/common/transporter/CMakeLists.txt

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,8 +60,22 @@ ENDIF()
6060
# validate_msg_header logic exercised by the tests does not touch any
6161
# verbs or socket APIs, but the rest of the translation unit still does,
6262
# so we link against ${NDB_RDMA_LIBRARIES} to resolve those references.
63+
#
64+
# RDMA_Transporter_test_stubs.cpp is a tiny companion source that
65+
# provides an abort-stub for the kernel-side `copy(SectionSegmentPool&,
66+
# SegmentedSectionPtr const&)` symbol that Packer.cpp's explicit
67+
# `Packer::pack<SegmentedSectionArg>` instantiation references. None
68+
# of the wire-format helpers exercised by the TAP cases actually call
69+
# into that code path, but without the stub the test executable fails
70+
# to link because none of the libraries we depend on define the
71+
# kernel-side symbol. The same workaround is applied at runtime by
72+
# build_scripts/build_and_test_rdma_transporter.sh; this baked-in
73+
# stub keeps the WITH_UNIT_TESTS=ON CI build working too. See
74+
# RDMA_Transporter_test_stubs.cpp for the rationale.
6375
IF(NDB_RDMA_TRANSPORTER_SUPPORTED)
64-
NDB_ADD_TEST(RDMA_Transporter-t RDMA_Transporter.cpp
76+
NDB_ADD_TEST(RDMA_Transporter-t
77+
RDMA_Transporter.cpp
78+
RDMA_Transporter_test_stubs.cpp
6579
LIBS ndbtransport ndbmgmapi ndbgeneral ndbportlib
6680
${NDB_RDMA_LIBRARIES})
6781
ENDIF()
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
/*
2+
Copyright (c) 2026, Hopsworks and/or its affiliates.
3+
4+
This program is free software; you can redistribute it and/or modify
5+
it under the terms of the GNU General Public License, version 2.0,
6+
as published by the Free Software Foundation.
7+
8+
This program is distributed in the hope that it will be useful,
9+
but WITHOUT ANY WARRANTY; without even the implied warranty of
10+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+
GNU General Public License, version 2.0, for more details.
12+
13+
You should have received a copy of the GNU General Public License
14+
along with this program; if not, write to the Free Software
15+
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
16+
*/
17+
18+
/*
19+
* Kernel-only symbol stubs for the RDMA_Transporter-t test binary.
20+
*
21+
* Why this file exists
22+
* --------------------
23+
* Packer.cpp (compiled into the ndbtransport convenience library that
24+
* the test executable links against) emits an unconditional explicit
25+
* template instantiation:
26+
*
27+
* template void Packer::pack<Packer::SegmentedSectionArg>(
28+
* Uint32 *theData, SegmentedSectionArg section) const;
29+
*
30+
* That instantiation references the free function
31+
* bool copy(unsigned int *&, SectionSegmentPool &,
32+
* SegmentedSectionPtr const &);
33+
* which is defined on the kernel side of the build (alongside the
34+
* SegmentSubPool / SegmentedSectionPtr implementations) and is NOT
35+
* part of any of the libraries the RDMA_Transporter-t target links
36+
* against (ndbtransport, ndbmgmapi, ndbgeneral, ndbportlib,
37+
* ${NDB_RDMA_LIBRARIES}, mytap). The result is an unresolved-symbol
38+
* link error at the test binary even though the wire-format helpers
39+
* exercised by the unit tests never invoke this code path.
40+
*
41+
* `build_scripts/build_and_test_rdma_transporter.sh` already works
42+
* around this for its standalone build by generating an equivalent
43+
* stub file on the fly. This source file bakes the same stub into
44+
* the regular CMake build so the WITH_UNIT_TESTS=ON CI build can
45+
* also link RDMA_Transporter-t without dragging in any kernel-side
46+
* libraries.
47+
*
48+
* Safety
49+
* ------
50+
* If anything ever reaches the stubbed function at runtime the
51+
* program aborts with a diagnostic message identifying which stub
52+
* fired. The wire-format TAP suite must never reach it: the test
53+
* exercises only `encode_msg_header` / `validate_msg_header` and
54+
* pure helpers in the anonymous namespace; none of those paths call
55+
* into `Packer::pack` at all. The abort is purely a defensive
56+
* tripwire for a future test addition that would otherwise silently
57+
* link against a sentinel.
58+
*/
59+
#include <cstdio>
60+
#include <cstdlib>
61+
62+
/*
63+
* Opaque forward declarations of the kernel-side types so the stub
64+
* signature matches the symbol expected by Packer.cpp's template
65+
* instantiation without dragging in the actual kernel headers.
66+
*/
67+
struct SectionSegmentPool;
68+
struct SegmentedSectionPtr;
69+
70+
extern "C" void __rdma_test_abort_stub(const char *name) {
71+
std::fprintf(stderr, "rdma test stub called: %s\n", name);
72+
std::abort();
73+
}
74+
75+
bool copy(unsigned int *& /*dst*/, SectionSegmentPool & /*pool*/,
76+
SegmentedSectionPtr const & /*src*/) {
77+
__rdma_test_abort_stub("copy(SegmentedSectionPtr)");
78+
return false;
79+
}

0 commit comments

Comments
 (0)