On Wed, Jan 29, 2025 at 05:40:39PM +0400, marcandre.lureau(a)redhat.com wrote:
From: Marc-André Lureau <marcandre.lureau(a)redhat.com>
Helpers to start the qemu-rdp server and set it up.
Signed-off-by: Marc-André Lureau <marcandre.lureau(a)redhat.com>
---
po/POTFILES | 1 +
src/qemu/meson.build | 1 +
src/qemu/qemu_domain.c | 1 +
src/qemu/qemu_domain.h | 2 +
src/qemu/qemu_rdp.c | 427 +++++++++++++++++++++++++++++++++++++++++
src/qemu/qemu_rdp.h | 71 +++++++
6 files changed, 503 insertions(+)
create mode 100644 src/qemu/qemu_rdp.c
create mode 100644 src/qemu/qemu_rdp.h
snip
+ logpath = qemuRdpCreateLogFilename(cfg, vm->def);
+
+ if (cfg->stdioLogD) {
+ g_autoptr(virLogManager) logManager = virLogManagerNew(driver->privileged);
+
+ if (!logManager)
+ goto error;
+
+ if ((logfd = virLogManagerDomainOpenLogFile(logManager,
+ "qemu",
+ vm->def->uuid,
+ vm->def->name,
+ logpath,
+ 0,
+ NULL, NULL)) < 0)
+ goto error;
+ } else {
+ if ((logfd = open(logpath, O_WRONLY | O_CREAT | O_APPEND, S_IRUSR | S_IWUSR))
< 0) {
+ virReportSystemError(errno, _("failed to create logfile %1$s"),
+ logpath);
+ goto error;
+ }
+ if (virSetCloseExec(logfd) < 0) {
+ virReportSystemError(errno, _("failed to set close-on-exec flag on
%1$s"),
+ logpath);
+ goto error;
+ }
+ }
These 30 lines are repeated in the dbus helper, and likewise the
virtiofs helper. This ought to be spun out to a helper API we
can call like:
if (!(logfd = qemuHelperOpenLogFile(driver, vm, "rdp"))
goto error
+
+ cmd = virCommandNew(cfg->qemuRdpName);
+ virCommandClearCaps(cmd);
+ virCommandSetPidFile(cmd, pidfile);
+ virCommandSetOutputFD(cmd, &logfd);
+ virCommandSetErrorFD(cmd, &logfd);
+ virCommandDaemonize(cmd);
+ if (dbus_addr) {
If 'dbus_addr' is NULL, AFAICT an error has been reported and we should
be propagating that as a fatal error scenario.
+ if (!qemuRdpHasFeature(rdp, QEMU_RDP_FEATURE_DBUS_ADDRESS))
{
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("qemu-rdp doesn't support custom D-Bus
address"));
Missing 'return -1', but...
+ }
...this ought be checked when we're probing capabilities for RDP
support probably.
+ virCommandAddArgPair(cmd, "--dbus-address",
dbus_addr);
+ }
+ virCommandAddArg(cmd, "serve");
+
+ virCommandAddArg(cmd, "--bind-address");
+ virCommandAddArgBuffer(cmd, &bind_addr);
+
+ certpath = g_build_filename(cfg->rdpTLSx509certdir, "server-cert.pem",
NULL);
+ keypath = g_build_filename(cfg->rdpTLSx509certdir, "server-key.pem",
NULL);
+ virCommandAddArgPair(cmd, "--cert", certpath);
+ virCommandAddArgPair(cmd, "--key", keypath);
+
+ if (qemuExtDeviceLogCommand(driver, vm, cmd, "qemu-rdp") < 0)
+ return -1;
+
+ rdp->name_watch = g_bus_watch_name_on_connection(priv->dbusConnection,
+ ORG_QEMUDISPLAY_RDP,
+ G_BUS_NAME_WATCHER_FLAGS_NONE,
+ name_appeared_cb,
+ name_vanished_cb,
+ rdp,
+ NULL);
+
+ if (qemuSecurityCommandRun(driver, vm, cmd, -1, -1, false, NULL) < 0)
+ goto error;
+
+ if (virPidFileReadPath(pidfile, &pid) < 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("Unable to read qemu-rdp pidfile '%1$s'"),
+ pidfile);
+ goto error;
+ }
+
+ if (virProcessKill(pid, 0) != 0) {
+ virReportSystemError(errno, "%s",
+ _("qemu-rdp died unexpectedly"));
+ goto error;
+ }
+
+ rdp->pid = pid;
+
+ return 0;
+
+ error:
+ g_clear_handle_id(&rdp->name_watch, g_bus_unwatch_name);
+ qemuRdpStop(vm, gfx);
+ return -1;
+}
+
+
+int
+qemuRdpSetCredentials(virDomainObj *vm,
+ const char *username,
+ const char *password,
+ const char *domain)
+{
+ qemuDomainObjPrivate *priv = vm->privateData;
+ g_autoptr(GVariant) args = NULL;
+
+ args = g_variant_new("(sss)", username, password, domain);
+
+ return virGDBusCallMethod(priv->dbusConnection,
+ NULL,
+ G_VARIANT_TYPE("()"),
+ NULL,
+ ORG_QEMUDISPLAY_RDP,
+ ORG_QEMUDISPLAY_RDP_PATH,
+ ORG_QEMUDISPLAY_RDP_IFACE,
+ "SetCredentials",
+ args);
+}
diff --git a/src/qemu/qemu_rdp.h b/src/qemu/qemu_rdp.h
new file mode 100644
index 0000000000..6af90b06d2
--- /dev/null
+++ b/src/qemu/qemu_rdp.h
@@ -0,0 +1,71 @@
+/*
+ * qemu_rdp.h: QEMU RDP support
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see
+ * <
http://www.gnu.org/licenses/>.
+ */
+
+#pragma once
+
+#include "qemu_conf.h"
+#include "virbitmap.h"
+#include "virenum.h"
+
+typedef enum {
+ QEMU_RDP_FEATURE_NONE = 0,
+
+ QEMU_RDP_FEATURE_DBUS_ADDRESS,
+ QEMU_RDP_FEATURE_REMOTEFX,
+ QEMU_RDP_FEATURE_LAST,
+} qemuRdpFeature;
+
+VIR_ENUM_DECL(qemuRdpFeature);
+
+typedef struct _qemuRdp qemuRdp;
+struct _qemuRdp {
+ int fd[2];
+ virBitmap *features;
+ pid_t pid;
+ guint name_watch;
+ bool name_appeared;
+ guint leaving_id;
+};
+
+qemuRdp *qemuRdpNew(void);
+
+qemuRdp *qemuRdpNewForHelper(const char *helper);
+
+void qemuRdpFree(qemuRdp *rdp);
+
+void qemuRdpSetFeature(qemuRdp *rdp,
+ qemuRdpFeature feature);
+
+bool qemuRdpHasFeature(const qemuRdp *rdp,
+ qemuRdpFeature feature);
+
+int qemuRdpStart(virDomainObj *vm,
+ virDomainGraphicsDef *gfx);
+
+void qemuRdpStop(virDomainObj *vm,
+ virDomainGraphicsDef *gfx);
+
+int qemuRdpSetupCgroup(qemuRdp *rdp,
+ virCgroup *cgroup);
+
+int qemuRdpSetCredentials(virDomainObj *vm,
+ const char *username,
+ const char *password,
+ const char *domain);
+
+G_DEFINE_AUTOPTR_CLEANUP_FUNC(qemuRdp, qemuRdpFree);
--
2.47.0
With regards,
Daniel
--
|:
https://berrange.com -o-
https://www.flickr.com/photos/dberrange :|
|:
https://libvirt.org -o-
https://fstop138.berrange.com :|
|:
https://entangle-photo.org -o-
https://www.instagram.com/dberrange :|