#ifndef VMSIG_DISCOVERY_H #define VMSIG_DISCOVERY_H #include "vmsig_core.h" #include "host_probe.h" /* discovery.h — runtime VM discovery (private to the discovery module). * * Watches a tmpfs trigger dir for "vm--ram" files, corroborates each candidate via the * host-probe seam, assigns a stable endpoint slot, hot-plugs the VM (sink), and publishes the * roster. The state machine + slot allocation are decoupled from actuation by a sink seam, so * the orchestration is unit-testable without armed adapters. */ typedef struct vmsig_discovery vmsig_discovery; /* Actuation seam: bring a discovered VM up / tear it down. Default (NULL) wires the core * adapter trio (memctx+vmhost+input via vmsig_core_add_adapter) and detach_endpoint. A test * injects a recording sink to verify the state machine without real adapters. Roster publish * is owned by discovery (not the sink): ATTACH after a successful attach, DETACH before tear-down. */ typedef struct { int (*attach)(void* ud, vmsig_core* core, uint32_t vmid, uint32_t endpoint, const vmsig_host_facts* f); /* 0 = up, -1 = failed (slot freed) */ void (*detach)(void* ud, vmsig_core* core, uint32_t vmid, uint32_t endpoint); void* ud; } vmsig_discovery_sink; /* Create discovery over `core`. `watch_dir` (e.g. /dev/shm/vmsig) is scanned once and * inotify-watched. `probe` NULL => default Proxmox probe over (watch_dir, pve_conf, qmp_dir); * `sink` NULL => default core trio; `slots_path` NULL => no persistence. Registers the inotify * + retry-timer loop sources and runs a bootstrap scan. The core owns the lifetime (freed at * vmsig_core_free via the source on_free). NULL on error. */ vmsig_discovery* vmsig_discovery_new(vmsig_core* core, const char* watch_dir, const char* pve_conf, const char* qmp_dir, const char* slots_path, const vmsig_host_probe* probe, const vmsig_discovery_sink* sink); /* Resolve vmid -> endpoint for the admission policy (WS4); -1 if not currently attached. */ int vmsig_discovery_slot_of_vmid(vmsig_discovery* d, uint32_t vmid); /* TEST-ONLY: drive a file appear(present=1)/gone(present=0) directly, bypassing inotify; and * force a re-probe of every probing candidate, bypassing the retry timer. Lets the state * machine be unit-tested deterministically without threads/timers. */ void vmsig_discovery_feed(vmsig_discovery* d, uint32_t vmid, int present); void vmsig_discovery_tick(vmsig_discovery* d); #endif /* VMSIG_DISCOVERY_H */