diff --git a/pyplugins/apis/send_hypercall.py b/pyplugins/apis/send_hypercall.py index 9000e6cbc..df8850fed 100644 --- a/pyplugins/apis/send_hypercall.py +++ b/pyplugins/apis/send_hypercall.py @@ -71,6 +71,7 @@ def __init__(self) -> None: self.logger.setLevel("DEBUG") self.registered_events: Dict[str, Callable[..., Tuple[int, Union[str, bytes]]]] = {} + self._unhandled_warned: set = set() plugins.subscribe( plugins.Events, "igloo_send_hypercall", self.on_send_hypercall) @@ -157,7 +158,17 @@ def on_send_hypercall(self, cpu: Any, buf_addr: int, # Simulate command cb = self.registered_events.get(cmd) if cb is None: - self.logger.error(f"Unregistered send_hypercall command {cmd}") + # Guest-side init scripts fire some hypercalls (e.g. readiness, + # core_pattern_lock) best-effort: a config generated by an older + # penguin may not load the plugin that subscribes to them. That is + # benign, so warn once per command instead of erroring every boot. + if cmd not in self._unhandled_warned: + self._unhandled_warned.add(cmd) + self.logger.warning( + f"No subscriber for send_hypercall command {cmd!r}; " + f"if this project predates the plugin that handles it, " + f"add that plugin to the config or regenerate the config" + ) return cb_to_call = resolve_bound_method_from_class(cb) diff --git a/pyplugins/interventions/core_pattern_guard.py b/pyplugins/interventions/core_pattern_guard.py index 58c48fdbc..afc26a101 100644 --- a/pyplugins/interventions/core_pattern_guard.py +++ b/pyplugins/interventions/core_pattern_guard.py @@ -15,8 +15,11 @@ but never writes through to the original .data target, so the global keeps the value the init script put there. -No-op when core.shared_dir is unset -- there's nowhere to mirror dumps to, -and the init script's hypercall won't fire either. +Dormant when core.shared_dir is unset: the init script only fires the +hypercall when SHARED_DIR is in the guest env. We subscribe unconditionally +anyway so a stray core_pattern_lock (e.g. env.SHARED_DIR set by hand without +core.shared_dir) is honored instead of tripping send_hypercall's +"Unregistered send_hypercall command" error. """ from penguin import Plugin, plugins @@ -66,10 +69,6 @@ def proc_handler(self, ptregs, ctl, write, buffer, lenp, ppos_ptr): class CorePatternGuard(Plugin): def __init__(self): - conf = self.get_arg("conf") or {} - if not conf.get("core", {}).get("shared_dir"): - return - self._registered = False plugins.send_hypercall.subscribe("core_pattern_lock", self._on_lock) diff --git a/pyplugins/testing/verifier.py b/pyplugins/testing/verifier.py index dcc652fdb..6da63b3ac 100644 --- a/pyplugins/testing/verifier.py +++ b/pyplugins/testing/verifier.py @@ -215,7 +215,7 @@ def get_test_case_output(self, name, kind): def check_test_cases(self): results = {} test_cases = [] - for name in self.conditions: + for name in self.conditions or {}: test_type = self.conditions[name]["type"] test = getattr(self, f"test_{test_type}", None) if test is None: