]> git.ipfire.org Git - thirdparty/systemd.git/commit
test: add reproducer for alias-corruption skip-desync regression 41957/head
authorLuca Boccassi <luca.boccassi@gmail.com>
Tue, 5 May 2026 22:20:09 +0000 (23:20 +0100)
committerLuca Boccassi <luca.boccassi@gmail.com>
Wed, 6 May 2026 12:02:38 +0000 (13:02 +0100)
commita1aed3eae2c4e23dc7e3e42aefeb6133491218d0
treefe126967ccd918798d5070dab41c03abcc57da86
parent4394046ee6f56092179631a3ba117e2a582490e9
test: add reproducer for alias-corruption skip-desync regression

The existing alias-corruption subtest only intermittently caught the
regression where unit_deserialize_state_skip() stopped at the first
empty line and thus failed to consume embedded "job" subsections
(written by job_serialize() when u->job or u->nop_job is non-NULL).
This same skip routine is also used by the pre-scan that builds the set
of serialized unit names (added in a77c7a8224 to detect stale alias
state). When skip terminates early at a job's end marker, the scan
desyncs and every subsequent unit name is dropped from the set,
silently bypassing the alias-corruption protection for those units.

Whether the bug fired depended on:
  1. Whether any unit happened to carry a pending job at the moment of
     reload/reexec (mostly chance, depends on timers, transient units,
     load, etc.).
  2. Hashmap iteration order during serialization (per-boot randomized
     siphash seed) determining if a job-bearing unit was written before
     a sus-NN.service alias.

To try and make the regression deterministic, add a "with_pending_jobs" mode
that creates 50 Type=oneshot services and starts them with
systemctl --no-block. Each remains in "activating" state with u->job
set forever, guaranteeing the serialized stream contains many embedded
job subsections regardless of hashmap order, and that at least one of
them precedes the sus units. Without the fix, the desync drops the
sus-NN entries from the set, the alias-corruption check
set_contains(serialized_units, u->id) returns false for every alias,
and legit.service's MainPID is overwritten on every run.

Co-developed-by: Claude Opus 4.7 <noreply@anthropic.com>
test/units/TEST-07-PID1.alias-corruption.sh