fix(worker): bug-1569 periodic resval reports tagged with wrong host
collect_load_indices() (resource_sync.c) tagged every periodic mem/r1m/r15m/r15s/ut/pg/ls/it/swp/io/tmp report with gethostname()'s raw OS/container hostname instead of the worker's own join identity (xcecd_ctx.virtual_name, the -n/--name value). Every other worker-keyed lookup downstream (scheduler's sched_get_worker(), and the same HOOK_DETAIL_RESOURCE_UPDATE payload forwarded on to the Go apiserver) matches by that join identity, so the mismatch silently dropped every periodic resource report for the real worker. Also adds a startup INFO log (main.c) naming the resolved job picker plugin, used to rule out a legacy-picker hypothesis while chasing a related (still-open) dispatch issue. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
parent
0d1ab09eb7
commit
6e5c3a891a
4 changed files with 180 additions and 3 deletions
|
|
@ -327,6 +327,10 @@ int main(int argc, char* argv[])
|
|||
|
||||
sched_init(&sched, &config, cluster_cfg_ptr, scheduler_req_handler);
|
||||
|
||||
INFO("active job picker plugin: %s", sched.core.job_pick_plugin
|
||||
? sched.core.job_pick_plugin
|
||||
: "(null)");
|
||||
|
||||
/* Req 5 AC 10 (scheduler-core spec, task 9.1): stash the resolved
|
||||
* --record-dir value on the live xce_scheduler_t -- see scheduler.h's
|
||||
* field comment. Not consumed anywhere yet (task 9.2's job); this
|
||||
|
|
|
|||
|
|
@ -203,9 +203,29 @@ static xce_resval_t* collect_load_indices(int* count)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
char hostname[256];
|
||||
if (gethostname(hostname, sizeof(hostname)) != 0) {
|
||||
strcpy(hostname, "unknown");
|
||||
/* bug-1569: this worker's JOIN identity (the -n/--name value, e.g.
|
||||
* "pc13v" -- xcecd_ctx.virtual_name, set from config->virutal_name in
|
||||
* xcecd_init(), xcecd.c) is what the controller/scheduler key every
|
||||
* OTHER per-worker resource value by (mark_host_res()/update_val_res(),
|
||||
* worker.c; sched_get_worker(), core_events.c). Using gethostname()
|
||||
* (the raw OS/container hostname, which is NOT the same value and can
|
||||
* be identical across every worker in a multi-worker-per-host test
|
||||
* setup, or simply a generic sandbox/container name unrelated to any
|
||||
* configured worker identity) here instead made every periodic load-
|
||||
* index report's .host wrong -- the controller forwards it to the
|
||||
* scheduler unmodified (do_update_resvals(), opupd.c), which then
|
||||
* fails sched_get_worker(core, rv->host) for the REAL worker and
|
||||
* silently drops the value ("RESVALS_DELTA: unknown worker <host>,
|
||||
* skipping", core_events.c) -- live-confirmed: gethostname() here
|
||||
* returned "xce" in this sandbox, not "pc13v". */
|
||||
const char* hostname = xcecd_ctx.virtual_name;
|
||||
char hostname_buf[256];
|
||||
|
||||
if (hostname == NULL || hostname[0] == '\0') {
|
||||
if (gethostname(hostname_buf, sizeof(hostname_buf)) != 0) {
|
||||
strcpy(hostname_buf, "unknown");
|
||||
}
|
||||
hostname = hostname_buf;
|
||||
}
|
||||
|
||||
for (int i = 0; i < rescount; i++) {
|
||||
|
|
|
|||
|
|
@ -26,6 +26,21 @@ test('worker controller_connector test', controller_connector_test,
|
|||
timeout: 60,
|
||||
env: ['ASAN_OPTIONS=detect_leaks=0'])
|
||||
|
||||
# bug-1569: collect_load_indices() (resource_sync.c) must tag every periodic
|
||||
# resource report with xcecd_ctx.virtual_name (the worker's own join
|
||||
# identity), not gethostname()'s raw OS/container hostname -- see
|
||||
# test_resource_sync.c's own header comment for the full mechanism trace.
|
||||
resource_sync_test = executable('resource_sync_test',
|
||||
'test_resource_sync.c',
|
||||
include_directories: [worker_test_incdir],
|
||||
dependencies: worker_test_deps,
|
||||
install: false)
|
||||
|
||||
test('worker resource_sync test', resource_sync_test,
|
||||
suite: 'worker',
|
||||
timeout: 60,
|
||||
env: ['ASAN_OPTIONS=detect_leaks=0'])
|
||||
|
||||
# component-failover-adoption task 2.2: worker startup-ordering white-box
|
||||
# test. #include's xcecd.c directly (same technique as controller_connector_
|
||||
# test above, but a separate binary/file -- xcecd.c and controller_connector.c
|
||||
|
|
|
|||
138
src/worker/testsuite/test_resource_sync.c
Normal file
138
src/worker/testsuite/test_resource_sync.c
Normal file
|
|
@ -0,0 +1,138 @@
|
|||
/*
|
||||
* test_resource_sync.c - regression test for bug-1569: collect_load_indices()
|
||||
* (resource_sync.c) must tag every periodic resource value with the
|
||||
* worker's own JOIN identity (xcecd_ctx.virtual_name -- the -n/--name value,
|
||||
* set from config->virutal_name in xcecd_init(), xcecd.c), not
|
||||
* gethostname()'s raw OS/container hostname.
|
||||
*
|
||||
* Why this matters: the controller forwards each report's .host field to
|
||||
* the scheduler UNMODIFIED (do_update_resvals(), src/controller/opupd.c),
|
||||
* which keys EVERY other per-worker resource value by this SAME join
|
||||
* identity (mark_host_res()/update_val_res(), src/controller/worker.c;
|
||||
* sched_get_worker(), src/scheduler/src/core_events.c). A mismatch here
|
||||
* silently drops every periodic ("mem"/"r15s"/etc.) resource report for the
|
||||
* real worker -- live-confirmed against two independent deployments in this
|
||||
* sandbox: gethostname() returned a generic container hostname ("xce"), not
|
||||
* the worker's configured "-n pc13v" identity, so the scheduler's own
|
||||
* "unknown worker xce, skipping" WARN fired every ~15s (resource_sync's own
|
||||
* LOAD_INDICES_INTERVAL_DEFAULT) and "info worker pc13v" never showed real
|
||||
* mem/r15s/etc values despite xce_test's live `resval` query showing them
|
||||
* correctly (a DIFFERENT, correctly-addressed query path).
|
||||
*
|
||||
* White-box #include of ../src/resource_sync.c (same convention this
|
||||
* suite already establishes for controller_connector.c/xcecd.c). The 11
|
||||
* builtin load-index getters (node_info_get_15s/etc., real implementations
|
||||
* in node_information.c, not linked here) are stubbed as trivial
|
||||
* deterministic returns -- this test is about collect_load_indices()'s own
|
||||
* .host-tagging logic, not the real /proc-reading getters' own values.
|
||||
*/
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <unity/unity.h>
|
||||
|
||||
#include "xcecd.h"
|
||||
|
||||
/* Real globals this white-box TU's resource_sync.c references
|
||||
* (xcecd_ctx.virtual_name) -- not linking xcecd.c itself (its own
|
||||
* main()/full daemon init is out of scope for this narrow test), so a
|
||||
* plain definition here satisfies the linker, matching this suite's own
|
||||
* "provide just the global a white-box #include needs" idiom
|
||||
* (test_xcecd_startup_order.c's g_dummy_subsystem-style stubs). */
|
||||
xcecd_context_t xcecd_ctx;
|
||||
|
||||
/* Stubs for the 11 builtin load-index getters (node_information.c, not
|
||||
* linked here) -- deterministic, non-NULL so collect_load_indices() never
|
||||
* takes its own NULL-getter fallback path (out of scope for this test). */
|
||||
static char* stub_getter(void)
|
||||
{
|
||||
return strdup("1.0");
|
||||
}
|
||||
|
||||
char* node_info_get_15s(void) { return stub_getter(); }
|
||||
char* node_info_get_1m(void) { return stub_getter(); }
|
||||
char* node_info_get_15m(void) { return stub_getter(); }
|
||||
char* node_info_get_ut(void) { return stub_getter(); }
|
||||
char* node_info_get_pg(void) { return stub_getter(); }
|
||||
char* node_info_get_ls(void) { return stub_getter(); }
|
||||
char* node_info_get_it(void) { return stub_getter(); }
|
||||
char* node_info_get_swap(void) { return stub_getter(); }
|
||||
char* node_info_get_mem(void) { return stub_getter(); }
|
||||
char* node_info_get_tmp(void) { return stub_getter(); }
|
||||
char* node_info_get_io(void) { return stub_getter(); }
|
||||
|
||||
/* Linker stub for controller_connector.c's real implementation -- only
|
||||
* referenced by resource_sync_thread() (the background polling loop),
|
||||
* never invoked by this test (which calls collect_load_indices()
|
||||
* directly). */
|
||||
bool xcecd_send_load_indices(xce_resval_t** vals, int count)
|
||||
{
|
||||
(void)vals;
|
||||
(void)count;
|
||||
return true;
|
||||
}
|
||||
|
||||
#include "../src/resource_sync.c"
|
||||
|
||||
void setUp(void) { return; }
|
||||
void tearDown(void) { return; }
|
||||
|
||||
static void
|
||||
test_collect_load_indices_tags_host_with_virtual_name_not_gethostname(void)
|
||||
{
|
||||
xce_resval_t* vals;
|
||||
int count = 0;
|
||||
int i;
|
||||
|
||||
memset(&xcecd_ctx, 0, sizeof(xcecd_ctx));
|
||||
xcecd_ctx.virtual_name = (char*)"pc13v";
|
||||
|
||||
vals = collect_load_indices(&count);
|
||||
|
||||
TEST_ASSERT_NOT_NULL(vals);
|
||||
TEST_ASSERT_TRUE(count > 0);
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
TEST_ASSERT_NOT_NULL(vals[i].host);
|
||||
TEST_ASSERT_EQUAL_STRING("pc13v", vals[i].host);
|
||||
}
|
||||
|
||||
free_resvals(vals, count);
|
||||
|
||||
printf("test_collect_load_indices_tags_host_with_virtual_name_not_"
|
||||
"gethostname: PASS\n");
|
||||
}
|
||||
|
||||
static void
|
||||
test_collect_load_indices_falls_back_to_gethostname_when_virtual_name_unset(
|
||||
void)
|
||||
{
|
||||
xce_resval_t* vals;
|
||||
int count = 0;
|
||||
char expected[256];
|
||||
|
||||
memset(&xcecd_ctx, 0, sizeof(xcecd_ctx));
|
||||
xcecd_ctx.virtual_name = NULL;
|
||||
|
||||
TEST_ASSERT_EQUAL_INT(0, gethostname(expected, sizeof(expected)));
|
||||
|
||||
vals = collect_load_indices(&count);
|
||||
|
||||
TEST_ASSERT_NOT_NULL(vals);
|
||||
TEST_ASSERT_TRUE(count > 0);
|
||||
TEST_ASSERT_EQUAL_STRING(expected, vals[0].host);
|
||||
|
||||
free_resvals(vals, count);
|
||||
|
||||
printf("test_collect_load_indices_falls_back_to_gethostname_when_"
|
||||
"virtual_name_unset: PASS\n");
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
UNITY_BEGIN();
|
||||
RUN_TEST(test_collect_load_indices_tags_host_with_virtual_name_not_gethostname);
|
||||
RUN_TEST(test_collect_load_indices_falls_back_to_gethostname_when_virtual_name_unset);
|
||||
return UNITY_END();
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue