myxce/.wolf/bugs/bug-1933.md

5.2 KiB

id status status_updated status_note component severity timestamp last_seen occurrences files tags related fix_commits gitea_issue gitea_synced_status gitea_synced_hash
bug-1933 fixed 2026-10-10 scheduler wrong-result 2026-10-10T03:36:53Z 2026-10-10T03:36:53Z 1
src/scheduler/src/plugins/limit.c
src/lib/xcelimit.c
scheduler
limit
project
hostgroup
bug-1785
6ecd418d
358 fixed 0d19e8b066b2

bug-1933: xce_scheduler limit plugin resolves hosts: scopes against project groups (host-group limits ignored)

Description

Observed: The scheduler's limit plugin built every limit with the host-group and project-group managers swapped. A limit scoped to a host group never matched that group's hosts; a limit scoped to projects resolved its member names against the host groups. The new regression test, before the fix:

../scheduler/testsuite/test_limit_plugin.c:491:test_limit_scopes_resolve_against_own_group_kind:FAIL: Expected 1 Was 0

(host group hg1 = {hostA}; a limit with hosts: [hg1] did not match host hostA.)

Expected: a limit's hosts: members resolve against the host groups (hosts: [hg1] matches every host in hg1), and its projects: members resolve against the project groups (a project name never matches a host group). Impact: wrong result, silent. Every host limit that names a host group applies to no host (only to a host literally named like the group), so the limit is never enforced. A project limit whose member name equals a host group's name matches the projects named like that group's hosts instead of the project itself. Limits naming plain host or project names, and limits without host/project scopes, are unaffected. In addition, the groups a limit builds for its own scopes were registered in the wrong manager (<limit>-pg-group in the host groups, <limit>-hg-group in the project groups). Found by: review, during /kiro-spec-requirements project-config (2026-10-10, codebase survey of project-scoped limits).

Environment

  • OS: no /etc/os-release; Docker container; NixOS kernel; kernel Linux 6.18.33 x86_64
  • libc: glibc 2.42-47 (interpreter /nix/store/wb6rhpznjfczwlwx23zmdrrw74bayxw4-glibc-2.42-47/lib/ld-linux-x86-64.so.2)
  • Toolchain: gcc (GCC) 15.2.0, meson 1.9.1
  • Build: asan (xce.build), ASAN_OPTIONS=detect_leaks=0
  • Code: scheduler-framework @ 25cdbc79-dirty
  • Deployment: n/a (unit test of the scheduler limit plugin); the defect is in code shared by the live scheduler and xce_scheduler --sim.

Reproduction

  1. cd src && nix develop . --command meson compile -C xce.build sched_limit_plugin_test
  2. ASAN_OPTIONS=detect_leaks=0 ./xce.build/scheduler/testsuite/sched_limit_plugin_test
  3. Test test_limit_scopes_resolve_against_own_group_kind (src/scheduler/testsuite/test_limit_plugin.c): loads host group hg1 = {hostA}, configures limit host_scoped with hosts: [hg1] and limit project_scoped with projects: [hg1], then checks match_limit() for host hostA/hostB and project hostA/hg1.
  • Frequency: deterministic
  • Evidence: the test above; no logs kept.

Root cause

build_limit() (src/lib/xcelimit.c:292) takes its group managers as (ugmgr, qgmgr, hgmgr, pgmgr), but limit_seed_config_impl() (src/scheduler/src/plugins/limit.c:77) passed (core->ugmgr, core->qgmgr, core->pgmgr, core->hgmgr). build_consumer() therefore built the HOST consumer with the project-group manager and the PROJECT consumer with the host-group manager. make_g_member() (src/lib/group.c) treats a member name as a nested group only if the manager it is given knows that group, so hg1 became a literal host name (the project-group manager is empty) and a project member named like a host group became that host group. Since ecf1916d (2026-01-12, "support limit"), the first version of the plugin call; carried through 7c229284 and 487e7b94. Scope: limit.c:77 is the only production caller of build_limit() (checked with grep -rn "build_limit("); the lib tests (src/lib/testsuite/test_limit.c) pass the managers in the right order.

Fix

src/scheduler/src/plugins/limit.c: pass (core->hgmgr), (core->pgmgr) in the order build_limit() declares, so each scope resolves against its own kind of group. No wire, WAL, snapshot or config change. The project-group manager is still never loaded from config (projects have no config yet); that is project-config scope (Requirement 6.7). src/scheduler/testsuite/test_limit_plugin.c: new regression test; main() now initializes the interned-string table (xstring_table_init()), which group names need and which no earlier test in this binary exercised.

Verification

  • Test: test_limit_scopes_resolve_against_own_group_kind (src/scheduler/testsuite/test_limit_plugin.c): RED before the fix (Expected 1 Was 0 at line 491, hosts: [hg1] not matching hostA), GREEN after (6/6 in sched_limit_plugin_test).
  • Suites: scheduler suite 119/119 OK, libxce tests 2/2 OK, asan (xce.build), 2026-10-10.
  • Live: n/a: the change is one argument order in config-time limit construction, fully covered by the unit test; no live limit run.

References

  • Found during: .kiro/specs/project-config/requirements.md (Requirement 6.7)
  • Introduced: ecf1916d