Re: [RFC v2 10/16] qemu: add vhost-user-gpu helper unit

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Tue, Aug 28, 2018 at 11:39:28PM +0200, marcandre.lureau@xxxxxxxxxx wrote:
From: Marc-André Lureau <marcandre.lureau@xxxxxxxxxx>

Similar to the qemu_tpm.c, add a unit with a few functions to
start/stop and setup the cgroup of the external vhost-user-gpu
process. See function documentation.

Signed-off-by: Marc-André Lureau <marcandre.lureau@xxxxxxxxxx>
---
src/conf/device_conf.h         |   1 +
src/qemu/Makefile.inc.am       |   2 +
src/qemu/qemu_vhost_user_gpu.c | 318 +++++++++++++++++++++++++++++++++
src/qemu/qemu_vhost_user_gpu.h |  48 +++++
4 files changed, 369 insertions(+)
create mode 100644 src/qemu/qemu_vhost_user_gpu.c
create mode 100644 src/qemu/qemu_vhost_user_gpu.h

diff --git a/src/conf/device_conf.h b/src/conf/device_conf.h
index ff7d6c9d5f..79a7ea9fe2 100644
--- a/src/conf/device_conf.h
+++ b/src/conf/device_conf.h
@@ -175,6 +175,7 @@ struct _virDomainDeviceInfo {
     * cases we might want to prevent that from happening by
     * locking the isolation group */
    bool isolationGroupLocked;
+    int vhost_user_fd;
};

int virDomainDeviceInfoCopy(virDomainDeviceInfoPtr dst,
diff --git a/src/qemu/Makefile.inc.am b/src/qemu/Makefile.inc.am
index 2afa67f195..28daf9d426 100644
--- a/src/qemu/Makefile.inc.am
+++ b/src/qemu/Makefile.inc.am
@@ -56,6 +56,8 @@ QEMU_DRIVER_SOURCES = \
	qemu/qemu_qapi.h \
	qemu/qemu_tpm.c \
	qemu/qemu_tpm.h \
+	qemu/qemu_vhost_user_gpu.c \
+	qemu/qemu_vhost_user_gpu.h \
	$(NULL)


diff --git a/src/qemu/qemu_vhost_user_gpu.c b/src/qemu/qemu_vhost_user_gpu.c
new file mode 100644
index 0000000000..9007614020
--- /dev/null
+++ b/src/qemu/qemu_vhost_user_gpu.c
@@ -0,0 +1,318 @@
+/*
+ * qemu_vhost_user_gpu.c: QEMU vhost-user GPU support
+ *
+ * Copyright (C) 2018 Red Hat, Inc.
+ *
+ * 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/>.
+ *
+ * Author: Marc-André Lureau <marcandre.lureau@xxxxxxxxxx>
+ */
+
+#include <config.h>
+
+#include "qemu_extdevice.h"
+#include "qemu_domain.h"
+#include "qemu_security.h"
+
+#include "conf/domain_conf.h"
+#include "vircommand.h"
+#include "viralloc.h"
+#include "virlog.h"
+#include "virutil.h"
+#include "virfile.h"
+#include "virstring.h"
+#include "virtime.h"
+#include "virpidfile.h"
+#include "qemu_vhost_user_gpu.h"
+
+#define VIR_FROM_THIS VIR_FROM_NONE
+
+VIR_LOG_INIT("qemu.vhost-user-gpu")
+
+/*
+ * Look up the vhost-user-gpu executable; to be found on the host
+ */
+static char *vhost_user_gpu_path;
+
+static int
+qemuVhostUserGPUInit(void)
+{
+    if (!vhost_user_gpu_path) {
+        vhost_user_gpu_path = virFindFileInPath("vhost-user-gpu");
+        if (!vhost_user_gpu_path) {
+            virReportSystemError(ENOENT, "%s",
+                                 _("Unable to find 'vhost-user-gpu' binary in $PATH"));
+            return -1;
+        }
+        if (!virFileIsExecutable(vhost_user_gpu_path)) {
+            virReportError(VIR_ERR_INTERNAL_ERROR,
+                           _("vhost-user-gpu %s is not an executable"),
+                           vhost_user_gpu_path);
+            VIR_FREE(vhost_user_gpu_path);
+            return -1;
+        }
+    }
+
+    return 0;
+}
+
+
+static char *
+qemuVhostUserGPUCreatePidFilename(const char *stateDir,
+                                  const char *shortName,
+                                  const char *alias)
+{
+    char *pidfile = NULL;
+    char *devicename = NULL;
+
+    if (virAsprintf(&devicename, "%s-%s-vhost-user-gpu", shortName, alias) < 0)
+        return NULL;
+
+    pidfile = virPidFileBuildPath(stateDir, devicename);
+
+    VIR_FREE(devicename);
+
+    return pidfile;
+}
+
+
+/*
+ * qemuVhostUserGPUGetPid
+ *
+ * @stateDir: the directory where vhost-user-gpu writes the pidfile into
+ * @shortName: short name of the domain
+ * @alias: video device alias
+ * @pid: pointer to pid
+ *
+ * Return -errno upon error, or zero on successful reading of the pidfile.
+ * If the PID was not still alive, zero will be returned, and @pid will be
+ * set to -1;
+ */
+static int
+qemuVhostUserGPUGetPid(const char *stateDir,
+                       const char *shortName,
+                       const char *alias,
+                       pid_t *pid)
+{
+    int ret;
+    char *pidfile = qemuVhostUserGPUCreatePidFilename(stateDir, shortName, alias);
+    if (!pidfile)
+        return -ENOMEM;
+
+    ret = virPidFileReadPathIfAlive(pidfile, pid, vhost_user_gpu_path);
+
+    VIR_FREE(pidfile);
+
+    return ret;
+}
+
+
+/*
+ * qemuExtVhostUserGPUStart:
+ *
+ * @driver: QEMU driver
+ * @def: domain definition
+ * @video: the video device
+ * @logCtxt: log context
+ *
+ * Start the external vhost-user-gpu process:
+ * - open a socketpair for vhost-user communication
+ * - have the command line built
+ * - start the external process and sync with it before QEMU start
+ */
+int qemuExtVhostUserGPUStart(virQEMUDriverPtr driver,
+                             virDomainDefPtr def,
+                             virDomainVideoDefPtr video,
+                             qemuDomainLogContextPtr logCtxt)
+{
+    int ret = -1;
+    virCommandPtr cmd = NULL;
+    int exitstatus = 0;
+    char *errbuf = NULL;
+    virQEMUDriverConfigPtr cfg;
+    char *pidfile, *shortName = virDomainDefGetShortName(def);
+    virTimeBackOffVar timebackoff;
+    const unsigned long long timeout = 500000; /* ms */

500 * 1000 /* ms */ is easier to read

+    int cmdret = 0, rc;
+    int pair[2] = { -1, -1 };
+
+    pid_t pid;
+
+    if (!shortName)
+        return -1;
+
+    cfg = virQEMUDriverGetConfig(driver);
+
+    /* stop any left-over for this VM */
+    qemuExtVhostUserGPUStop(driver, def, video);
+
+    if (!(pidfile = qemuVhostUserGPUCreatePidFilename(
+              cfg->stateDir, shortName, video->info.alias)))
+        goto error;
+
+    if (socketpair(AF_UNIX, SOCK_STREAM, 0, pair) < 0) {
+        virReportSystemError(errno, "%s", _("failed to create socket"));
+        goto error;
+    }

This socket will inherit the label from libvirtd and it cannot be changed
afterwards, see:
https://bugzilla.redhat.com/show_bug.cgi?id=999926

We have SecuritySetSocketLabel and SecurityClearSocketLabel that change
the context temporarily.
Having them on-disk would let us change the label afterwards, but for
FD passing, they should be labeled before the fork (unlike all the other
paths which we label after forking)

Jano

Attachment: signature.asc
Description: PGP signature

--
libvir-list mailing list
libvir-list@xxxxxxxxxx
https://www.redhat.com/mailman/listinfo/libvir-list

[Index of Archives]     [Virt Tools]     [Libvirt Users]     [Lib OS Info]     [Fedora Users]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [KDE Users]     [Fedora Tools]

  Powered by Linux