Skip to content

events: signature grammar, strict startup, info panda-events, owner names - #59

Merged
lacraig2 merged 3 commits into
mainfrom
events-e1-finish
Nov 13, 2026
Merged

lacraig2 merged 3 commits into
mainfrom
events-e1-finish

Conversation

@lacraig2

@lacraig2 lacraig2 commented Nov 3, 2026 •

Copy link
Copy Markdown
Member

Finishes the event registry from #58: the signature grammar, startup strictness, info panda-events, owner names, and a fix for RCU frees made before the machine is up.

Signature grammar (docs/design/event-signature-grammar.md)

  • ptr<T>, ptr<str> and ptr<u8[len]> hash their target; a bare ptr hashes as before.
  • bool is u8 for identity; the full signature keeps bool, so Python gets booleans.
  • type[N] declares a fixed array and hashes N.
  • No existing UUID changes. tests/static/event-uuid-vectors.tsv holds the vectors; events_registry.py checks them against events.c and Python's uuid5, and rust/panda-bindings/tests/event_uuid_vectors.rs derives them in Rust.

Startup check

  • A subscription still PENDING or MISMATCH once the machine is up fails startup. PANDA_EVENTS_STRICT=0 (or panda_events_set_strict(false)) makes it a warning. The report is one block, one line per subscription.
  • PANDA_SUB_OPTIONAL marks a conditional subscription: it is listed but never fails startup.
  • On the command line the check runs from a machine-init-done notifier and exits 1 on failure; it does nothing unless analysis is provisioned. Under pandare2, panda_init returns 1 and pandare2 raises EventsUnboundError with the report. panda_init also re-evaluates admission after qemu_init.

info panda-events (engine patch 0101): lists every event with its UUID, publisher, signature and namespace, and each subscription with its owner, state, kind, modes and reason. The handler is panda/src/events-hmp.c; the patch adds the command to hmp-commands-info.hx under CONFIG_PANDA. Records: ORIGINS, REUSE, features.toml (plugins), vanilla-gates.toml, base.json re-recorded.

Owner names: panda_events_set_owner_name(owner, name) names an owner that is not a plugin (pandare2's subscriptions).

RCU frees before the machine is up: pandare2 subscribes before panda_init, and QEMU's call_rcu thread takes the BQL, which isn't initialized yet. panda_events_call_rcu keeps those frees until the machine-init-done notifier.

Tests

  • nix build of the engine, .#python, the test plugins and every flake check: pass.
  • Guest (x86_64 Debian 13): guest, callbacks, api (now checks info panda-events), late, teardown, hookalias, calls: pass. calls hit its known intermittent hang once, then passed 3 of 3 reruns.
  • verify-series.sh: 101 patches apply with strict context; check-series.py, vanilla_inventory.py and tools/docs/gen.py --check pass.

After rebasing onto the renumbered series: info panda-events is patch 0101. The nix build of .#python, nix flake check, the smoke test and the guest tests above (api, callbacks, late, teardown, calls, guest, hookalias on x86_64 Debian 13) all pass. verify-series.sh: 101 patches apply with strict context.

…ames

Signature grammar (docs/design/event-signature-grammar.md):
- ptr<T>, ptr<str> and ptr<u8[len]> hash their target; a bare ptr hashes
  as before.
- bool is u8 for identity; the full signature keeps bool, so Python gets
  booleans.
- type[N] declares a fixed array and hashes N.
No existing UUID changes. events.c parses, canonicalizes (no whitespace, N
without leading zeros), lays out and diffs the new types. events.h adds
PANDA_EVENT_CTYPE_bool and the PANDA_EVENT_ARRAY, PTR, STR and BUF
field-list forms.

Startup check: a subscription still PENDING or MISMATCH once the machine
is up fails startup by default. PANDA_EVENTS_STRICT=0 (or
panda_events_set_strict(false)) makes it a warning. The report is one
block, a line per subscription (event, signature, owner, kind, state,
reason). PANDA_SUB_OPTIONAL marks a conditional subscription: it is listed
but never fails startup. After startup, a subscription that goes PENDING
is logged when it does.
- On the command line, a machine-init-done notifier added when the library
  loads runs the check after -plugin and the panda modules are in, and
  exits 1 on failure. It returns at once unless analysis is provisioned,
  and does not set the registry up if nothing used it.
- Under pandare2, panda_init defers the notifier, runs the check after
  after_machine_init, and returns 1 instead of exiting; pandare2 raises
  EventsUnboundError with panda_events_startup_report(). panda_init also
  re-evaluates admission after qemu_init, since a subscription made before
  QEMU chose KVM was decided with KVM off.

info panda-events: events-hmp.c prints panda_events_describe(false), and
engine patch 0101 adds the command to hmp-commands-info.hx under
CONFIG_PANDA.

panda_events_set_owner_name(owner, name) names an owner that is not a
plugin (pandare2's subscriptions), which otherwise shows as ?. NULL or ""
forgets it, and so does an unload.

tests/static/event-uuid-vectors.tsv holds (namespace, name, signature,
hashed part, UUID) rows, including bool/u8 and whitespace pairs that share
a UUID. events_registry.py checks them against events.c and Python's
uuid5, and rust/panda-bindings/tests/event_uuid_vectors.rs derives them in
Rust. events_registry.py also covers the grammar, strictness, the report,
the command-line notifier, panda_init's return under strict, optional
subscriptions and owner names.
pandare2 subscribes before panda_init. A publish or unsubscribe then
queued an RCU free, and QEMU's call_rcu thread takes the BQL to run
callbacks, which qemu_init has not initialized yet: the thread aborted
(qemu_mutex_lock_impl: mutex->initialized).

panda_events_call_rcu keeps such frees until the machine-init-done
notifier (panda_events_machine_up), then queues them. The registry's
snapshot and subscription frees and the core callback lists' retired
entries go through it.

Host test: the stub call_rcu asserts the machine is up, as QEMU's
thread would; events_registry.py has early cases (publish, instance
data and unsubscribe before the machine is up, directly and before
panda_init), and brings the machine up first otherwise.
@lacraig2
lacraig2 merged commit d399360 into main Nov 13, 2026
12 of 13 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant