@@ -44,7 +44,7 @@ LDFLAGS_BASE := $(CMOCKA_LIBS)
4444
4545# Tests list
4646ALL_TESTS := test_ff_dpdk_if_integration test_ff_kni_integration \
47- test_ff_reload_integration
47+ test_ff_reload_integration test_ff_gendir_mp_integration
4848
4949# Common stub objects
5050COMMON_OBJS := $(COMMON_DIR ) /rte_stub.o
@@ -66,10 +66,25 @@ help:
6666 @echo " make coverage_clean - remove gcov/.gcda/.gcno + coverage_report/"
6767
6868test : all
69- @for t in $(ALL_TESTS ) ; do \
70- echo " ==> running $$ t" ; $(RUN_ENV ) ./$$ t || exit 1; \
71- done
72- @echo " ALL INTEGRATION TESTS PASS ($( words $( ALL_TESTS) ) binaries)"
69+ @# The hugepage cleanup below must run even when a test FAILS (review
70+ @# P2-1): a failed run leaks 256 pages (512 MB) and ~7 failures would
71+ @# exhaust the 2048-page pool, so record the failure, clean, then exit.
72+ @fail=0; for t in $( ALL_TESTS) ; do \
73+ echo " ==> running $$ t" ; $(RUN_ENV ) ./$$ t || { fail=1; break ; }; \
74+ done ; \
75+ if ls /dev/hugepages/ff_gendir_mpmap_* > /dev/null 2>&1 ; then \
76+ echo " ==> cleaning ff_gendir_mp hugepage files" ; \
77+ ls /dev/hugepages/ff_gendir_mpmap_* | while read f; do \
78+ /data/workspace/rm_tmp_file.sh " $$ f" > /dev/null; \
79+ done ; \
80+ fi ; \
81+ if [ -d /var/run/dpdk/ff_gendir_mp ]; then \
82+ /data/workspace/rm_tmp_file.sh /var/run/dpdk/ff_gendir_mp > /dev/null; \
83+ fi ; \
84+ if [ $$ fail -ne 0 ]; then \
85+ echo " INTEGRATION TESTS FAILED" ; exit 1; \
86+ fi ; \
87+ echo " ALL INTEGRATION TESTS PASS ($( words $( ALL_TESTS) ) binaries)"
7388
7489# ----- check (valgrind memcheck on integration tests) -------------------
7590VALGRIND ?= valgrind
@@ -137,6 +152,7 @@ INT_LIB_OBJS := \
137152 $(LIB_OBJS_DIR ) /ff_log.o \
138153 $(LIB_OBJS_DIR ) /ff_host_interface.o \
139154 $(LIB_OBJS_DIR ) /ff_reload.o \
155+ $(LIB_OBJS_DIR ) /ff_reload_gendir.o \
140156 $(LIB_OBJS_DIR ) /ff_drain_ring.o \
141157 $(LIB_OBJS_DIR ) /ff_flow_map.o
142158
@@ -173,6 +189,7 @@ RELOAD_LIB_OBJS := \
173189 $(LIB_OBJS_DIR ) /ff_log.o \
174190 $(LIB_OBJS_DIR ) /ff_host_interface.o \
175191 $(LIB_OBJS_DIR ) /ff_reload.o \
192+ $(LIB_OBJS_DIR ) /ff_reload_gendir.o \
176193 $(LIB_OBJS_DIR ) /ff_drain_ring.o \
177194 $(LIB_OBJS_DIR ) /ff_flow_map.o
178195
@@ -181,6 +198,19 @@ test_ff_reload_integration: test_ff_reload_integration.o $(RELOAD_LIB_OBJS) $(CO
181198 $(DPDK_LIBS ) -lrte_net_bond -Wl,-rpath=$(DPDK_RUNPATH ) \
182199 -lpthread -lcrypto -ldl -lm
183200
201+ # ----- M5 Batch C: cross-master generation directory, real two-process EAL --
202+ # (IT-NR-A14, nginx_reload_spec 08). Unlike the harnesses above this one
203+ # boots a real PRIMARY (huge mode, no --no-huge: a DPDK 24.11 secondary
204+ # needs the runtime-dir hugepage_data the primary only writes in that mode)
205+ # and forks master->worker chains that attach as real secondaries with the
206+ # same --file-prefix. NIC exclusivity is kept via --no-pci + net_null0.
207+ MP_LIB_OBJS := $(RELOAD_LIB_OBJS )
208+
209+ test_ff_gendir_mp_integration : test_ff_gendir_mp_integration.o $(MP_LIB_OBJS ) $(COMMON_OBJS )
210+ $(CC ) -o $@ $^ $(LDFLAGS_BASE ) $(BASE_WRAPS ) \
211+ $(DPDK_LIBS ) -lrte_net_bond -Wl,-rpath=$(DPDK_RUNPATH ) \
212+ -lpthread -lcrypto -ldl -lm
213+
184214# ----- clean (NFR-U-7: must use workspace wrapper, no direct rm) -----
185215clean :
186216 @find . -name ' *.o' -type f -print 2> /dev/null | while read f; do \
0 commit comments