On 4/22/26 16:14, marcandre.lureau--- via Devel wrote:
From: Marc-André Lureau <marcandre.lureau@redhat.com>
Add helpers to manage the standalone qemu-vnc VNC server process. The qemu-vnc server connects to QEMU via the D-Bus display interface, providing VNC access decoupled from the QEMU process.
The helper handles process lifecycle (start/stop), D-Bus name watching, and provides D-Bus methods for password management, certificate reloading, and client connections.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com> --- po/POTFILES | 1 + src/qemu/meson.build | 1 + src/qemu/qemu_vnc.c | 407 +++++++++++++++++++++++++++++++++++++++++++ src/qemu/qemu_vnc.h | 41 +++++ 4 files changed, 450 insertions(+) create mode 100644 src/qemu/qemu_vnc.c create mode 100644 src/qemu/qemu_vnc.h
diff --git a/po/POTFILES b/po/POTFILES index a5f8705eb8..a4e3ed6f25 100644 --- a/po/POTFILES +++ b/po/POTFILES @@ -208,6 +208,7 @@ src/qemu/qemu_validate.c src/qemu/qemu_vhost_user.c src/qemu/qemu_vhost_user_gpu.c src/qemu/qemu_virtiofs.c +src/qemu/qemu_vnc.c src/remote/libvirtd.policy.in src/remote/remote_daemon.c src/remote/remote_daemon_config.c diff --git a/src/qemu/meson.build b/src/qemu/meson.build index b4fb62f14f..9737e50734 100644 --- a/src/qemu/meson.build +++ b/src/qemu/meson.build @@ -43,6 +43,7 @@ qemu_driver_sources = [ 'qemu_vhost_user.c', 'qemu_vhost_user_gpu.c', 'qemu_virtiofs.c', + 'qemu_vnc.c', ]
driver_source_files += files(qemu_driver_sources) diff --git a/src/qemu/qemu_vnc.c b/src/qemu/qemu_vnc.c new file mode 100644 index 0000000000..4afdf6aa79 --- /dev/null +++ b/src/qemu/qemu_vnc.c @@ -0,0 +1,407 @@ +/* + * SPDX-License-Identifier: LGPL-2.1-or-later + */ + +#include <config.h> + +#include <gio/gio.h> + +#include "qemu_dbus.h" +#include "qemu_extdevice.h" +#include "qemu_security.h" +#include "qemu_vnc.h" +#include "virerror.h" +#include "virlog.h" +#include "virpidfile.h" +#include "virgdbus.h" + +#define VIR_FROM_THIS VIR_FROM_NONE + +VIR_LOG_INIT("qemu.vnc"); + +#define ORG_QEMU_VNC "org.qemu.vnc" +#define ORG_QEMU_VNC_PATH "/org/qemu/Vnc1/Server" +#define ORG_QEMU_VNC_IFACE "org.qemu.Vnc1.Server" + + +void +qemuVncFree(qemuVnc *vnc) +{ + if (!vnc) + return; + + g_free(vnc); +} + + +qemuVnc * +qemuVncNew(void) +{ + g_autoptr(qemuVnc) vnc = g_new0(qemuVnc, 1); + + vnc->pid = -1; + + return g_steal_pointer(&vnc); +} + + +static char * +qemuVncCreatePidFilename(virDomainObj *vm) +{ + qemuDomainObjPrivate *priv = vm->privateData; + virQEMUDriver *driver = priv->driver; + g_autofree char *shortName = virDomainDefGetShortName(vm->def); + g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(driver); + g_autofree char *name = NULL; + + name = g_strdup_printf("%s-vnc", shortName); + + return virPidFileBuildPath(cfg->vncStateDir, name); +} + + +void +qemuVncStop(virDomainObj *vm, virDomainGraphicsDef *gfx)
Nitpick, for new code we can have one argument per line.
+{ + qemuDomainObjPrivate *priv = vm->privateData; + qemuDomainGraphicsPrivate *gfxpriv = QEMU_DOMAIN_GRAPHICS_PRIVATE(gfx); + qemuVnc *vnc = gfxpriv->vnc; + g_autofree char *pidfile = qemuVncCreatePidFilename(vm); + virErrorPtr orig_err; + + if (!vnc) + return; + + if (vnc->leaving_id) { + g_dbus_connection_signal_unsubscribe(priv->dbusConnection, vnc->leaving_id); + vnc->leaving_id = 0; + } + g_clear_handle_id(&vnc->name_watch, g_bus_unwatch_name); + + virErrorPreserveLast(&orig_err); + + if (virPidFileForceCleanupPath(pidfile) < 0) { + VIR_WARN("Unable to kill qemu-vnc process"); + } else { + vnc->pid = -1; + } + + virErrorRestore(&orig_err); +}
diff --git a/src/qemu/qemu_vnc.h b/src/qemu/qemu_vnc.h new file mode 100644 index 0000000000..6a0d2124c5 --- /dev/null +++ b/src/qemu/qemu_vnc.h @@ -0,0 +1,41 @@ +/* + * SPDX-License-Identifier: LGPL-2.1-or-later + */ + +#pragma once + +#include "qemu_conf.h" + +typedef struct _qemuVnc qemuVnc; +struct _qemuVnc { + pid_t pid; + guint name_watch; + bool name_appeared; + guint leaving_id; +}; + +bool qemuVncAvailable(const char *helper); + +qemuVnc *qemuVncNew(void); + +void qemuVncFree(qemuVnc *vnc); + +int qemuVncStart(virDomainObj *vm, + virDomainGraphicsDef *gfx); + +void qemuVncStop(virDomainObj *vm, + virDomainGraphicsDef *gfx); + +int qemuVncSetupCgroup(qemuVnc *vnc, + virCgroup *cgroup); + +int qemuVncSetPassword(virDomainObj *vm, + const char *password); + +int qemuVncReloadCertificates(virDomainObj *vm); + +int qemuVncAddClient(virDomainObj *vm, + int fd, + bool skipauth); + +G_DEFINE_AUTOPTR_CLEANUP_FUNC(qemuVnc, qemuVncFree);
And for new header files we tend to just copy-paste the header from .c file. No need to put function name onto the same line as return type. Michal