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:
@@ -16,6 +16,7 @@
|
||||
#include "vmsig.h"
|
||||
#include "vmsig_socket.h" /* vmsig_wire, vmsig_socket_attach */
|
||||
#include "core_internal.h" /* core_emit_up (synthetic lifecycle injection) */
|
||||
#include "memctx.h" /* vmsig_memctx_cfg (infra ro_fd ownership test) */
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
@@ -328,12 +329,77 @@ static void test_socket(void) {
|
||||
vmsig_ctx_free(ctx);
|
||||
}
|
||||
|
||||
/* ---- 6. ro_fd ownership: an infra-supplied RO-fd is closed by the adapter --- *
|
||||
* Regression for the latent leak: cfg.ro_fd ownership transfers to the adapter at
|
||||
* open(); mc_close() must close it, so a re-grant (detach + re-attach with a fresh
|
||||
* infra ro_fd) does not leak the prior one. Only DUPS leave outward (one per share),
|
||||
* so the original stays open across the run and is reaped at adapter close. */
|
||||
#ifndef MFD_CLOEXEC
|
||||
#include <sys/syscall.h>
|
||||
#include <linux/memfd.h>
|
||||
static int memfd_create(const char* name, unsigned int flags) {
|
||||
return (int)syscall(SYS_memfd_create, name, flags);
|
||||
}
|
||||
#endif
|
||||
#ifndef MFD_ALLOW_SEALING
|
||||
#define MFD_ALLOW_SEALING 0x0002U
|
||||
#endif
|
||||
#ifndef F_ADD_SEALS
|
||||
#define F_ADD_SEALS (1024 + 9)
|
||||
#define F_SEAL_SHRINK 0x0002
|
||||
#define F_SEAL_GROW 0x0004
|
||||
#endif
|
||||
#ifndef F_SEAL_FUTURE_WRITE
|
||||
#define F_SEAL_FUTURE_WRITE 0x0010
|
||||
#endif
|
||||
|
||||
static int make_ro_backing(uint32_t size) {
|
||||
int fd = memfd_create("vmsig_test_ro", MFD_CLOEXEC | MFD_ALLOW_SEALING);
|
||||
if (fd < 0) fd = memfd_create("vmsig_test_ro", MFD_CLOEXEC);
|
||||
if (fd < 0) return -1;
|
||||
if (ftruncate(fd, (off_t)size) != 0) { close(fd); return -1; }
|
||||
(void)fcntl(fd, F_ADD_SEALS, F_SEAL_SHRINK | F_SEAL_GROW | F_SEAL_FUTURE_WRITE);
|
||||
return fd;
|
||||
}
|
||||
|
||||
static void test_ro_fd_ownership(void) {
|
||||
printf("test_ro_fd_ownership\n");
|
||||
int ro = make_ro_backing(0x10000u); /* >= the stub low so the holder can mmap */
|
||||
CHECK(ro >= 0, "created an RO backing fd");
|
||||
if (ro < 0) return;
|
||||
|
||||
vmsig_ctx* ctx = vmsig_ctx_new();
|
||||
vmsig_core* core = vmsig_core_new(ctx);
|
||||
|
||||
holder h; memset(&h, 0, sizeof h);
|
||||
h.core = core; h.is_driver = 1; h.expect_ep = 0; h.stop_epoch = -1;
|
||||
add_holder(core, &h, VMSIG_CAP_MEMCTX, 0xFFFFFFFFu, 1ull << 0);
|
||||
|
||||
/* stub kcr3 (no VM) but a REAL infra ro_fd handed in for the RO share path. */
|
||||
vmsig_memctx_cfg mc; memset(&mc, 0, sizeof mc);
|
||||
mc.stub = 1; mc.ram_path = NULL; mc.low = 0; mc.ro_fd = ro;
|
||||
CHECK(vmsig_core_add_adapter(core, vmsig_memctx_ops(), &mc, 0) >= 0, "add memctx (infra ro_fd)");
|
||||
|
||||
vmsig_core_run(core);
|
||||
|
||||
CHECK(h.memctx >= 1, "holder received MEMCTX over the infra ro_fd");
|
||||
CHECK(h.ro_ok, "infra ro_fd re-shared and mmaps PROT_READ");
|
||||
CHECK(fcntl(ro, F_GETFD) >= 0, "infra ro_fd still open before close (no premature close)");
|
||||
|
||||
vmsig_core_free(core); /* mc_close closes the owned cfg_ro_fd */
|
||||
vmsig_ctx_free(ctx);
|
||||
|
||||
CHECK(fcntl(ro, F_GETFD) == -1, "infra ro_fd closed by mc_close after free (no leak)");
|
||||
if (fcntl(ro, F_GETFD) >= 0) close(ro); /* belt-and-braces if the assert failed */
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
test_multicast();
|
||||
test_epoch();
|
||||
test_retain();
|
||||
test_multivm();
|
||||
test_socket();
|
||||
test_ro_fd_ownership();
|
||||
printf("memctx tests: %s\n", g_fail ? "FAIL" : "PASS");
|
||||
return g_fail ? 1 : 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user