Enable qemu to be socket-activated based on a spice connection. Note that this depends on un-deprecating spice_server_set_listen_socket_fd, see https://gitlab.freedesktop.org/spice/spice/-/merge_requests/240
This partially addresses https://gitlab.com/qemu-project/qemu/-/issues/3011 Signed-off-by: Daniel Kahn Gillmor <d...@fifthhorseman.net> --- qemu-options.hx | 7 +++++-- ui/spice-core.c | 49 +++++++++++++++++++++++++++++++++++++------------ 2 files changed, 42 insertions(+), 14 deletions(-) diff --git a/qemu-options.hx b/qemu-options.hx index 1f862b19a6..d17c5bc5ff 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -2270,6 +2270,7 @@ DEF("spice", HAS_ARG, QEMU_OPTION_spice, " [,x509-cert-file=<file>][,x509-cacert-file=<file>]\n" " [,x509-dh-key-file=<file>][,addr=addr]\n" " [,ipv4=on|off][,ipv6=on|off][,unix=on|off]\n" + " [,socket-activated=<str>]\n" " [,tls-ciphers=<list>]\n" " [,tls-channel=[main|display|cursor|inputs|record|playback]]\n" " [,plaintext-channel=[main|display|cursor|inputs|record|playback]]\n" @@ -2297,8 +2298,10 @@ SRST Set the IP address spice is listening on. Default is any address. - ``ipv4=on|off``; \ ``ipv6=on|off``; \ ``unix=on|off`` - Force using the specified IP version. + ``ipv4=on|off``; \ ``ipv6=on|off``; \ ``unix=on|off`` ; \ ``socket-activated=<str>`` + Force using the specified IP version. Or, use a unix-domain socket. + Or, listen using the passed file descriptor from systemd-style socket + activation associated with FileDescriptorName ``str``. ``password-secret=<secret-id>`` Set the ID of the ``secret`` object containing the password diff --git a/ui/spice-core.c b/ui/spice-core.c index 0326c63bec..d74930db45 100644 --- a/ui/spice-core.c +++ b/ui/spice-core.c @@ -38,6 +38,7 @@ #include "migration/misc.h" #include "hw/pci/pci_bus.h" #include "ui/spice-display.h" +#include "qemu/systemd.h" /* core bits */ @@ -433,6 +434,9 @@ static QemuOptsList qemu_spice_opts = { },{ .name = "unix", .type = QEMU_OPT_BOOL, + },{ + .name = "socket-activated", + .type = QEMU_OPT_STRING, #endif },{ .name = "password-secret", @@ -736,18 +740,39 @@ static void qemu_spice_init(void) } spice_server = spice_server_new(); - spice_server_set_addr(spice_server, addr ? addr : "", addr_flags); - if (port) { - spice_server_set_port(spice_server, port); - } - if (tls_port) { - spice_server_set_tls(spice_server, tls_port, - x509_cacert_file, - x509_cert_file, - x509_key_file, - x509_key_password, - x509_dh_file, - tls_ciphers); + str = qemu_opt_get(opts, "socket-activated"); + if (str) { + int fd = socket_activated_fd_by_label(str); + if (fd == -1) { + error_report("socket-activated spice failed: " + "No FD found with label '%s'", + str); + exit(1); + } + + if (addr || addr_flags) { + error_report("When spice is socket-activated, do not set " + "addr or ipv4 or ipv6 or unix"); + exit(1); + } + if (spice_server_set_listen_socket_fd(spice_server, fd) == -1) { + error_report("spice_server_set_listen_socket_fd failed!"); + exit(1); + } + } else { + spice_server_set_addr(spice_server, addr ? addr : "", addr_flags); + if (port) { + spice_server_set_port(spice_server, port); + } + if (tls_port) { + spice_server_set_tls(spice_server, tls_port, + x509_cacert_file, + x509_cert_file, + x509_key_file, + x509_key_password, + x509_dh_file, + tls_ciphers); + } } if (password) { qemu_spice.set_passwd(password, false, false); -- 2.47.2