mirror of
https://dev.lirent.ru/Vatrog/vm-automation-signaling.git
synced 2026-06-26 04:36:37 +03:00
vmsig: management daemon, runtime endpoint lifecycle, roster, discovery, in-tree drivers, packaging
- core: runtime attach/detach of a per-endpoint adapter trio (runtime-safe add_adapter + vmsig_core_detach_endpoint, deferred reap) - roster: VMSIG_EV_ROSTER + CAP_ROSTER, retained per-endpoint and replayed to late subscribers - discovery: inotify trigger dir, vmid/endpoint slot allocator, host probe; vmsigd daemon with config + per-uid admission - input driver and vgpu perception built in-tree; vgpu perception as a separate library - memctx: own the supplied ro_fd (closed at detach) - deb packaging: install rules, systemd unit, tmpfiles, default config
This commit is contained in:
@@ -0,0 +1,91 @@
|
||||
/* slot.c — vmid <-> endpoint allocator (see slot.h). Pure logic + a tiny pointer-free
|
||||
* on-disk format; no core dependency. */
|
||||
#define _GNU_SOURCE
|
||||
#include "slot.h"
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
void slot_init(slot_table* t) {
|
||||
memset(t, 0, sizeof *t);
|
||||
}
|
||||
|
||||
int slot_lookup(const slot_table* t, uint32_t vmid) {
|
||||
if (!vmid) return -1;
|
||||
for (int e = 0; e < VMSIG_SLOT_COUNT; e++)
|
||||
if (t->ent[e].vmid == vmid) return e;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int slot_alloc(slot_table* t, uint32_t vmid) {
|
||||
if (!vmid) return -1;
|
||||
int e = slot_lookup(t, vmid);
|
||||
if (e >= 0) return e; /* idempotent pin */
|
||||
/* lowest free bit: ffsll of the complement (1-based; 0 => none free) */
|
||||
int b = __builtin_ffsll((long long)~t->used_mask);
|
||||
if (b == 0) return -1; /* table full (64-VM ceiling) */
|
||||
e = b - 1;
|
||||
t->ent[e].vmid = vmid;
|
||||
t->used_mask |= (1ull << e);
|
||||
return e;
|
||||
}
|
||||
|
||||
void slot_free(slot_table* t, uint32_t vmid) {
|
||||
int e = slot_lookup(t, vmid);
|
||||
if (e < 0) return;
|
||||
t->ent[e].vmid = 0;
|
||||
t->used_mask &= ~(1ull << e);
|
||||
}
|
||||
|
||||
/* ---- persistence: magic + version + 64 * uint32 vmid (native byte order, tmpfs-local) ---- */
|
||||
#define SLOT_MAGIC 0x534C4F54u /* "SLOT" */
|
||||
#define SLOT_VERSION 1u
|
||||
|
||||
typedef struct {
|
||||
uint32_t magic;
|
||||
uint32_t version;
|
||||
uint32_t vmid[VMSIG_SLOT_COUNT];
|
||||
} slot_blob;
|
||||
|
||||
int slot_save(const slot_table* t, const char* path) {
|
||||
if (!path) return -1;
|
||||
slot_blob b;
|
||||
memset(&b, 0, sizeof b);
|
||||
b.magic = SLOT_MAGIC; b.version = SLOT_VERSION;
|
||||
for (int e = 0; e < VMSIG_SLOT_COUNT; e++) b.vmid[e] = t->ent[e].vmid;
|
||||
|
||||
char tmp[512];
|
||||
int n = snprintf(tmp, sizeof tmp, "%s.tmp", path);
|
||||
if (n < 0 || (size_t)n >= sizeof tmp) return -1;
|
||||
|
||||
int fd = open(tmp, O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC, 0600);
|
||||
if (fd < 0) return -1;
|
||||
ssize_t w = write(fd, &b, sizeof b);
|
||||
int rc = (w == (ssize_t)sizeof b) ? 0 : -1;
|
||||
if (close(fd) != 0) rc = -1;
|
||||
if (rc == 0 && rename(tmp, path) != 0) rc = -1;
|
||||
if (rc != 0) unlink(tmp);
|
||||
return rc;
|
||||
}
|
||||
|
||||
int slot_load(slot_table* t, const char* path) {
|
||||
slot_init(t);
|
||||
if (!path) return 0;
|
||||
int fd = open(path, O_RDONLY | O_CLOEXEC);
|
||||
if (fd < 0) return 0; /* no file => fresh start (valid) */
|
||||
slot_blob b;
|
||||
ssize_t r = read(fd, &b, sizeof b);
|
||||
close(fd);
|
||||
if (r != (ssize_t)sizeof b || b.magic != SLOT_MAGIC || b.version != SLOT_VERSION) {
|
||||
slot_init(t); /* corrupt/old => fresh start */
|
||||
return 0;
|
||||
}
|
||||
for (int e = 0; e < VMSIG_SLOT_COUNT; e++) {
|
||||
t->ent[e].vmid = b.vmid[e];
|
||||
if (b.vmid[e]) t->used_mask |= (1ull << e);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user