diff --git a/src/controller/config_repl.c b/src/controller/config_repl.c index a079574f..7ddb296f 100644 --- a/src/controller/config_repl.c +++ b/src/controller/config_repl.c @@ -20,8 +20,10 @@ #include "byteorder.h" #include "clusterconfig.h" +#include "cluster.h" #include "ha.h" #include "utils.h" +#include "wobj.h" #include "xce/cluster_def.h" /* ── config load helpers (shared with myconf.c logic) ─────── */ @@ -536,21 +538,46 @@ int load_primary_config_for_test(cluster_t *c) void create_lost_and_found(cluster_t *c) { - /* - * Ensure the synthetic "lost_and_found" queue exists before - * persist_recover() runs. Jobs whose queue was removed by a config - * upgrade are re-queued here so they survive the WAL replay. - * - * Phase 2 concern: the full kvmgr queue-insertion API requires a - * complete config context that is not yet available at the point this - * function is called (pre-recovery). Leave as a documented no-op stub; - * the core config-replication feature is fully functional without it. - * Track lost-and-found job count via c->lost_and_found_job_count. - */ - (void)c; - WARN("create_lost_and_found: synthetic queue insertion deferred to Phase 2" - " -- lost-and-found jobs will not be preserved across config upgrades" - " until that phase is complete"); + if (!c->qmgr || !c->workermgr) + return; + +#ifndef XCE_TESTING + /* key_find, create_queue, and makeWorker require librtti + queue.c which + * are not linked into the unit test binary. The !qmgr guard above means + * this block is unreachable in tests regardless. */ + + /* Synthetic queue — receives jobs whose queue was removed by a config + * upgrade. Created before persist_recover() so WAL replay can route + * unknown queue IDs here instead of failing. */ + { + void *existing = NULL; + if (key_find(c->qmgr, (void *)"lost_and_found", &existing) <= 0) { + xce_queue_t lf = {0}; + lf.queue = "lost_and_found"; + queue_t *q = create_queue(c, &lf); + if (q) + INFO("Created synthetic 'lost_and_found' queue"); + else + ERROR("Failed to create synthetic 'lost_and_found' queue"); + } + } + + /* Synthetic host — receives jobs whose host was removed by a config + * upgrade. Uses makeWorker directly; no hostconfig entry is required + * for this sentinel host. */ + { + void *existing = NULL; + if (key_find(c->workermgr, (void *)"lost_and_found", &existing) <= 0) { + xce_worker_t lf_host = {0}; + lf_host.name = "lost_and_found"; + worker_t *w = makeWorker(c->workermgr, &lf_host); + if (w) + INFO("Created synthetic 'lost_and_found' host"); + else + ERROR("Failed to create synthetic 'lost_and_found' host"); + } + } +#endif /* XCE_TESTING */ } /* ── handle_config_request ──────────────────────── */