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