mirror of
https://dev.lirent.ru/Vatrog/vm-automation-signaling.git
synced 2026-06-20 19:06:37 +03:00
709f4b586a
An epoll-driven, neutral transfer-event bus that connects sensors and input actuators to one or more controls, bidirectionally. It owns the transfer context and events — delivery order, priority, protocol-level timing, and an interrupt-driven event model over fd sources (eventfd/timerfd/sockets) — and stays agnostic to both the sensor/input drivers and the control. What lives here: - memctx: a coherent address-space context per endpoint — the guest address-space root paired with a pre-opened read-only RAM-region fd, with per-endpoint epoch invalidation and retained replay to late subscribers. Perception lives in out-of-tree sensor libraries that consume this datum read-only. - exclusive-ownership leases for destructive resource classes (input, power, memory-write). - write-signaled memory writes (MEMWRITE): an atomic write to guest memory routed through the seam under an exclusive lease, never a writable mapping. - a host-management seam for VM lifecycle/status and a neutral input-injection command path. - multi-VM endpoints; capability-gated, audited control authorization over an in-process or unix-socket transport. Builds against headers only by default (a stub mode that exercises the seam without a VM); armed builds link the real sensor/input libraries behind flags. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
82 lines
4.4 KiB
C
82 lines
4.4 KiB
C
#ifndef VMSIG_ADAPTER_H
|
|
#define VMSIG_ADAPTER_H
|
|
#include "vmsig_event.h"
|
|
#include "vmsig_memctx.h" /* vmsig_memctx_reg — address-space context registration seam */
|
|
|
|
/* vmsig_adapter.h — unified SI adapter interface. One vtable, three readiness
|
|
* shapes behind it. The adapter is the ONLY place that includes neighbor headers
|
|
* (memmodel.h/win32.h/vgpu_stream.h/vmctl.h). It registers 0..N fds with the core;
|
|
* the core does not know whether it is a socket, eventfd or timerfd. SI specifics
|
|
* never leave these functions. */
|
|
|
|
typedef struct vmsig_adapter vmsig_adapter; /* opaque adapter instance */
|
|
|
|
/* How the adapter expresses readiness. The core treats all three as ordinary
|
|
* epoll fds; the enum is documentation + the choice of default epoll flags. */
|
|
typedef enum {
|
|
VMSIG_RDY_FD = 0, /* native pollable fd (socket) */
|
|
VMSIG_RDY_TIMERFD = 1, /* timerfd; adapter samples shared memory */
|
|
VMSIG_RDY_EVENTFD = 2 /* worker thread bridges a blocking API -> eventfd */
|
|
} vmsig_readiness;
|
|
|
|
/* Sink handed by the core to the adapter for emitting UP events without knowing
|
|
* the internals of the context. emit() is thread-safe (also called from worker
|
|
* threads); register_memctx/unregister_memctx are called ONLY on the loop thread.
|
|
* The registration hooks may be NULL (adapters/tests need not call them). */
|
|
typedef struct {
|
|
int (*emit)(void* token, vmsig_event* ev); /* UP (thread-safe) */
|
|
int (*register_memctx)(void* token, const vmsig_memctx_reg* reg); /* loop thread: AS context; 0/-1 */
|
|
void (*unregister_memctx)(void* token, uint32_t endpoint); /* loop thread: context gone */
|
|
void* token;
|
|
} vmsig_emit;
|
|
|
|
/* One fd contributed by the adapter, with epoll flags and a cookie for demux. */
|
|
typedef struct {
|
|
int fd;
|
|
uint32_t epoll_events; /* EPOLLIN / EPOLLOUT / ... */
|
|
vmsig_readiness shape;
|
|
uint32_t cookie; /* adapter-private fd discriminator */
|
|
} vmsig_fd_reg;
|
|
|
|
/* Adapter vtable. Each SI adapter implements this; SI specifics do not leak. */
|
|
typedef struct vmsig_adapter_ops {
|
|
const char* name; /* "memctx"/"input"/"vmhost" — diagnostics */
|
|
vmsig_source source; /* neutral seam role */
|
|
uint32_t codec; /* vmsig_codec owned by the adapter */
|
|
|
|
/* Create an instance from opaque cfg (adapter parses it; core passes as-is).
|
|
* Returns an instance or NULL. `endpoint` is the id of the VM it binds to. */
|
|
vmsig_adapter* (*open)(const void* cfg, uint32_t endpoint);
|
|
|
|
/* Attach: open the SI contract, bring up workers, hand fds into reg[]
|
|
* (<=cap), store `emit` for UP. Returns the number of registered fds (>=0) / -1. */
|
|
int (*attach)(vmsig_adapter* a, const vmsig_emit* emit,
|
|
vmsig_fd_reg* reg, int cap);
|
|
|
|
/* Readiness of one of the adapter's fds: `cookie` identifies the fd, `events`
|
|
* are the epoll flags. The adapter does NON-blocking work (reads the socket /
|
|
* drains the eventfd / reads the timerfd + samples counters) and calls emit on
|
|
* each UP. 0 — ok, -1 — fatal (the core detaches the adapter). */
|
|
int (*on_readiness)(vmsig_adapter* a, uint32_t cookie, uint32_t events);
|
|
|
|
/* Consume a DOWN event (a control decision): encode it into the contract
|
|
* (vmctl_batch / vmctl power; write the vgpu control block; read request to vmie).
|
|
* For blocking sinks it hands the work to a worker and returns immediately;
|
|
* completion arrives later as an UP VMSIG_EV_ACT_ACK (keyed by ev->corr).
|
|
* 0 — accepted, 1 — rejected (not for this seam), -1 — error. */
|
|
int (*submit)(vmsig_adapter* a, const vmsig_event* ev);
|
|
|
|
/* Detach + free: stop workers, close SI handles and fds. */
|
|
void (*close)(vmsig_adapter* a);
|
|
} vmsig_adapter_ops;
|
|
|
|
/* Factories (defined in each adapter's TU — the only symbol the build/cli layer
|
|
* needs; keeps neighbor headers out of the core's include-path). */
|
|
const vmsig_adapter_ops* vmsig_memctx_ops(void); /* vmie: address-space context (kcr3+locator) */
|
|
const vmsig_adapter_ops* vmsig_input_ops(void); /* vmctl */
|
|
const vmsig_adapter_ops* vmsig_vmhost_ops(void); /* QEMU/QMP (its own signaling) */
|
|
/* (vgpu frame sensor is no longer a signaling adapter: vgpu perception lives in an
|
|
* out-of-repo S-lib that consumes memctx; see vgpu-perception-handoff.) */
|
|
|
|
#endif /* VMSIG_ADAPTER_H */
|