#ifndef VMSIG_HOST_PROBE_H #define VMSIG_HOST_PROBE_H #include /* host_probe.h — the platform-coupled discovery seam (private to the discovery module). * * This is the ONLY surface that knows the host's config convention (/etc/pve/qemu-server), * the QMP socket path convention, and the `info mtree` text. It produces a NEUTRAL facts * struct; discovery.c consumes ONLY that and never names a path convention. A non-Proxmox * host (or a unit test) injects its own vmsig_host_probe with the same two-stage contract. */ #define VMSIG_HF_NAME_MAX 32 #define VMSIG_HF_PATH_MAX 128 typedef struct { uint32_t vmid; char name[VMSIG_HF_NAME_MAX]; /* host VM name (truncated) */ char ram_path[VMSIG_HF_PATH_MAX]; /* guest-RAM backing file (the trigger) */ char qmp_path[VMSIG_HF_PATH_MAX]; /* QMP socket ('@' prefix => abstract) */ uint64_t cfg_ram_bytes; /* RAM size from host config (sanity) */ uint64_t low; /* below-4G split (memctx locator); 0=unknown */ int vm_state; /* VMSIG_VM_* from the liveness oracle */ int share_on; /* memory-backend share=on verified */ int ok; /* 1 => all fail-closed gates passed (attach) */ int retry; /* 1 => transient (QMP not up yet) — back off */ } vmsig_host_facts; /* Two-stage probe. Stage 1 reads host config (cheap, local). Stage 2 corroborates liveness * and derives `low` (QMP round-trip, bounded). Splitting them lets the state machine treat * "config error" (permanent, drop) apart from "QMP not up yet" (transient, retry). */ typedef struct vmsig_host_probe { /* Populate paths + name + cfg_ram_bytes + share_on from host config; stat the RAM file. * Sets out->ok=0 on any permanent gate failure (no share=on, missing/oversized file). * Returns 0 when `out` was populated, -1 on a usage error. */ int (*config)(const struct vmsig_host_probe* p, uint32_t vmid, vmsig_host_facts* out); /* Corroborate liveness + derive `low` via QMP. Mutates `io`: sets vm_state, low, ok; or * retry=1 (QMP not reachable yet) / ok=0 (stale: file present but VM dead / unparsable). */ int (*live)(const struct vmsig_host_probe* p, vmsig_host_facts* io); void* ud; /* implementation-private */ } vmsig_host_probe; /* The default Proxmox probe over (watch_dir, pve_conf). `qmp_dir` is the QMP socket dir * (Proxmox: /var/run/qemu-server, socket "/.qmp"). The returned struct * references the path strings by pointer — the caller keeps them alive. */ vmsig_host_probe host_probe_proxmox(const char* watch_dir, const char* pve_conf, const char* qmp_dir); #endif /* VMSIG_HOST_PROBE_H */