public inbox for pve-devel@lists.proxmox.com
 help / color / mirror / Atom feed
From: Alexandre Derumier <alexandre.derumier@groupe-cyllene.com>
To: pve-devel@lists.proxmox.com
Subject: [RFC qemu-server 02/13] add D-Bus display support
Date: Tue, 25 Aug 2026 13:34:27 +0200	[thread overview]
Message-ID: <20260825113442.947620-3-alexandre.derumier@groupe-cyllene.com> (raw)
In-Reply-To: <20260825113442.947620-1-alexandre.derumier@groupe-cyllene.com>

Add a private D-Bus daemon per VM for QEMU's -display dbus.

Signed-off-by: Alexandre Derumier <alexandre.derumier@groupe-cyllene.com>
---
 src/PVE/QemuServer/DBusDisplay.pm | 100 ++++++++++++++++++++++++++++++
 src/PVE/QemuServer/Helpers.pm     |   6 ++
 2 files changed, 106 insertions(+)
 create mode 100644 src/PVE/QemuServer/DBusDisplay.pm

diff --git a/src/PVE/QemuServer/DBusDisplay.pm b/src/PVE/QemuServer/DBusDisplay.pm
new file mode 100644
index 0000000..b8684be
--- /dev/null
+++ b/src/PVE/QemuServer/DBusDisplay.pm
@@ -0,0 +1,100 @@
+package PVE::QemuServer::DBusDisplay;
+
+# A private D-Bus bus per VM for QEMU's -display dbus. QEMU connects to the
+# address rather than creating it, and every QEMU wants to own org.qemu, so the
+# session bus would cap a node at one VM. libvirt does the same.
+
+use strict;
+use warnings;
+
+use Time::HiRes qw(usleep);
+
+use PVE::ProcFSTools;
+use PVE::Tools qw(file_set_contents);
+use PVE::QemuServer::Helpers;
+
+sub config_file {
+    my ($vmid) = @_;
+    return "$PVE::QemuServer::Helpers::var_run_tmpdir/$vmid.dbusdisplay.conf";
+}
+
+sub pidfile {
+    my ($vmid) = @_;
+    return "$PVE::QemuServer::Helpers::var_run_tmpdir/$vmid.dbusdisplay.pid";
+}
+
+sub write_config {
+    my ($vmid) = @_;
+
+    my $socket = PVE::QemuServer::Helpers::dbus_socket($vmid);
+    my $pidfile = pidfile($vmid);
+
+    my $conf = <<"EOF";
+<!DOCTYPE busconfig PUBLIC "-//freedesktop//DTD D-Bus Bus Configuration 1.0//EN"
+ "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
+<busconfig>
+  <type>org.qemu</type>
+  <listen>unix:path=$socket</listen>
+  <pidfile>$pidfile</pidfile>
+  <auth>EXTERNAL</auth>
+  <policy context="default">
+    <allow send_destination="*" eavesdrop="true"/>
+    <allow eavesdrop="true"/>
+    <allow own="*"/>
+  </policy>
+</busconfig>
+EOF
+
+    my $path = config_file($vmid);
+    file_set_contents($path, $conf, 0600);
+
+    return $path;
+}
+
+# Called inside the VM's systemd scope, so it dies with the VM, as swtpm does.
+sub start {
+    my ($vmid) = @_;
+
+    stop($vmid); # a survivor from an unclean stop still holds the socket
+
+    my $config = write_config($vmid);
+    unlink PVE::QemuServer::Helpers::dbus_socket($vmid);
+
+    PVE::Tools::run_command(
+        ['dbus-daemon', "--config-file=$config", '--fork'],
+        errmsg => "failed to start D-Bus daemon for VM $vmid",
+    );
+
+    return;
+}
+
+sub stop {
+    my ($vmid) = @_;
+
+    my $pidfile = pidfile($vmid);
+    if (my $pid = eval { PVE::Tools::file_read_firstline($pidfile) }) {
+        if ($pid =~ m/^(\d+)$/) {
+            $pid = $1;
+            kill('TERM', $pid);
+
+            # Waited for: a dying daemon unlinks the new socket and holds the VM's scope
+            # cgroup open, which blocks the next start.
+            for (my $waited = 0; $waited < 5; $waited += 0.05) {
+                last if !PVE::ProcFSTools::check_process_running($pid);
+                usleep(50_000);
+            }
+            if (PVE::ProcFSTools::check_process_running($pid)) {
+                warn "D-Bus daemon for VM $vmid did not exit, killing it\n";
+                kill('KILL', $pid);
+            }
+        }
+    }
+
+    unlink $pidfile;
+    unlink config_file($vmid);
+    unlink PVE::QemuServer::Helpers::dbus_socket($vmid);
+
+    return;
+}
+
+1;
diff --git a/src/PVE/QemuServer/Helpers.pm b/src/PVE/QemuServer/Helpers.pm
index dd17eef..816f7aa 100644
--- a/src/PVE/QemuServer/Helpers.pm
+++ b/src/PVE/QemuServer/Helpers.pm
@@ -140,6 +140,12 @@ sub vnc_socket {
     return "${var_run_tmpdir}/$vmid.vnc";
 }
 
+sub dbus_socket {
+    my ($vmid) = @_;
+    # dbusdisplay, not dbus: keep it apart from the dbus-vmstate helper's files.
+    return "${var_run_tmpdir}/$vmid.dbusdisplay";
+}
+
 # Parse the cmdline of a running kvm/qemu-* process and return arguments as hash
 sub parse_cmdline {
     my ($pid) = @_;
-- 
2.55.0




  parent reply	other threads:[~2026-08-25 11:35 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-08-25 11:34 [RFC pve-http-server/qemu-server/pve-manager/pve-{qemu-kyber,kyberproxy, kyber-web,qemu-rdp,rdpproxy,rdp-web} 00/13] add rdp && kyber consoles for qemu over D-Bus display Alexandre Derumier
2026-08-25 11:34 ` [RFC pve-http-server 01/13] anyevent : proxy a path prefix to a local http proxy Alexandre Derumier
2026-08-25 11:34 ` Alexandre Derumier [this message]
2026-08-25 11:34 ` [RFC qemu-server 03/13] add kyber display Alexandre Derumier
2026-08-25 11:34 ` [RFC qemu-server 04/13] add rdp display Alexandre Derumier
2026-08-25 11:34 ` [RFC qemu-server 05/13] add experimental kyber-gl display Alexandre Derumier
2026-08-25 11:34 ` [RFC pve-manager 06/13] ui: add kyber console Alexandre Derumier
2026-08-25 11:34 ` [RFC pve-manager 07/13] ui: add rdp console Alexandre Derumier
2026-08-25 11:34 ` [RFC pve-kyber-web 10/13] add pve-kyber-web: console's webassembly client Alexandre Derumier
2026-08-25 11:34 ` [RFC pve-qemu-rdp 11/13] Add pve-qemu-rdp: an RDP server for the console Alexandre Derumier
2026-08-25 11:34 ` [RFC pve-rdpproxy 12/13] Add pve-rdpproxy Alexandre Derumier

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260825113442.947620-3-alexandre.derumier@groupe-cyllene.com \
    --to=alexandre.derumier@groupe-cyllene.com \
    --cc=pve-devel@lists.proxmox.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
Service provided by Proxmox Server Solutions GmbH | Privacy | Legal