From nobody Wed May 14 05:48:35 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) client-ip=209.132.183.28; envelope-from=libvir-list-bounces@redhat.com; helo=mx1.redhat.com; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 1525465432939630.2361819135363; Fri, 4 May 2018 13:23:52 -0700 (PDT) Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id F37A73002475; Fri, 4 May 2018 20:23:51 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.21]) by smtp.corp.redhat.com (Postfix) with ESMTPS id C2EA060F9B; Fri, 4 May 2018 20:23:51 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id 7CD284CAAF; Fri, 4 May 2018 20:23:51 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id w44KLtHk013750 for ; Fri, 4 May 2018 16:21:55 -0400 Received: by smtp.corp.redhat.com (Postfix) id 5211A17F3F; Fri, 4 May 2018 20:21:55 +0000 (UTC) Received: from mx1.redhat.com (ext-mx16.extmail.prod.ext.phx2.redhat.com [10.5.110.45]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 47BED60930 for ; Fri, 4 May 2018 20:21:52 +0000 (UTC) Received: from mx0a-001b2d01.pphosted.com (mx0b-001b2d01.pphosted.com [148.163.158.5]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 4179C30016FB for ; Fri, 4 May 2018 20:21:50 +0000 (UTC) Received: from pps.filterd (m0098421.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.16.0.22/8.16.0.22) with SMTP id w44KFkur056230 for ; Fri, 4 May 2018 16:21:49 -0400 Received: from e38.co.us.ibm.com (e38.co.us.ibm.com [32.97.110.159]) by mx0a-001b2d01.pphosted.com with ESMTP id 2hrwnx9qf6-1 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=NOT) for ; Fri, 04 May 2018 16:21:49 -0400 Received: from localhost by e38.co.us.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Fri, 4 May 2018 14:21:48 -0600 Received: from b03cxnp08027.gho.boulder.ibm.com (9.17.130.19) by e38.co.us.ibm.com (192.168.1.138) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; Fri, 4 May 2018 14:21:46 -0600 Received: from b03ledav002.gho.boulder.ibm.com (b03ledav002.gho.boulder.ibm.com [9.17.130.233]) by b03cxnp08027.gho.boulder.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id w44KLkfH10944850; Fri, 4 May 2018 13:21:46 -0700 Received: from b03ledav002.gho.boulder.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 5EE42136048; Fri, 4 May 2018 14:21:46 -0600 (MDT) Received: from sbct-3.watson.ibm.com (unknown [9.47.158.153]) by b03ledav002.gho.boulder.ibm.com (Postfix) with ESMTP id 07500136043; Fri, 4 May 2018 14:21:45 -0600 (MDT) From: Stefan Berger To: libvir-list@redhat.com Date: Fri, 4 May 2018 16:21:20 -0400 In-Reply-To: <1525465285-14102-1-git-send-email-stefanb@linux.vnet.ibm.com> References: <1525465285-14102-1-git-send-email-stefanb@linux.vnet.ibm.com> X-TM-AS-GCONF: 00 x-cbid: 18050420-0028-0000-0000-0000098D2E55 X-IBM-SpamModules-Scores: X-IBM-SpamModules-Versions: BY=3.00008970; HX=3.00000241; KW=3.00000007; PH=3.00000004; SC=3.00000258; SDB=6.01027521; UDB=6.00524878; IPR=6.00806655; MB=3.00020932; MTD=3.00000008; XFM=3.00000015; UTC=2018-05-04 20:21:47 X-IBM-AV-DETECTION: SAVI=unused REMOTE=unused XFE=unused x-cbparentid: 18050420-0029-0000-0000-00003AA9743A Message-Id: <1525465285-14102-10-git-send-email-stefanb@linux.vnet.ibm.com> X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:, , definitions=2018-05-04_08:, , signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 priorityscore=1501 malwarescore=0 suspectscore=4 phishscore=0 bulkscore=0 spamscore=0 clxscore=1015 lowpriorityscore=0 impostorscore=0 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1709140000 definitions=main-1805040185 X-Greylist: Sender passed SPF test, Sender IP whitelisted by DNSRBL, ACL 207 matched, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.45]); Fri, 04 May 2018 20:21:50 +0000 (UTC) X-Greylist: inspected by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.45]); Fri, 04 May 2018 20:21:50 +0000 (UTC) for IP:'148.163.158.5' DOMAIN:'mx0b-001b2d01.pphosted.com' HELO:'mx0a-001b2d01.pphosted.com' FROM:'stefanb@linux.vnet.ibm.com' RCPT:'' X-RedHat-Spam-Score: -0.7 (RCVD_IN_DNSWL_LOW) 148.163.158.5 mx0b-001b2d01.pphosted.com 148.163.158.5 mx0b-001b2d01.pphosted.com X-Scanned-By: MIMEDefang 2.84 on 10.5.110.45 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 X-loop: libvir-list@redhat.com Subject: [libvirt] [PATCH v3 09/14] qemu: Implement a layer for external devices like tpm-emulator X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.48]); Fri, 04 May 2018 20:23:52 +0000 (UTC) X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" Implement a layer for starting and stopping of external devices. The tpm-emulator is the only user of this layer. Signed-off-by: Stefan Berger --- src/qemu/Makefile.inc.am | 2 + src/qemu/qemu_extdevice.c | 300 ++++++++++++++++++++++++++++++++++++++++++= ++++ src/qemu/qemu_extdevice.h | 43 +++++++ src/qemu/qemu_process.c | 13 ++ 4 files changed, 358 insertions(+) create mode 100644 src/qemu/qemu_extdevice.c create mode 100644 src/qemu/qemu_extdevice.h diff --git a/src/qemu/Makefile.inc.am b/src/qemu/Makefile.inc.am index 63e7c87..d16e880 100644 --- a/src/qemu/Makefile.inc.am +++ b/src/qemu/Makefile.inc.am @@ -19,6 +19,8 @@ QEMU_DRIVER_SOURCES =3D \ qemu/qemu_domain_address.h \ qemu/qemu_cgroup.c \ qemu/qemu_cgroup.h \ + qemu/qemu_extdevice.c \ + qemu/qemu_extdevice.h \ qemu/qemu_hostdev.c \ qemu/qemu_hostdev.h \ qemu/qemu_hotplug.c \ diff --git a/src/qemu/qemu_extdevice.c b/src/qemu/qemu_extdevice.c new file mode 100644 index 0000000..f3f337d --- /dev/null +++ b/src/qemu/qemu_extdevice.c @@ -0,0 +1,300 @@ +/* + * qemu_extdevice.c: QEMU external devices support + * + * Copyright (C) 2014, 2018 IBM Corporation + * + * 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 + * . + * + * Author: Stefan Berger + */ + +#include + +#include "qemu_extdevice.h" +#include "qemu_domain.h" + +#include "viralloc.h" +#include "virlog.h" +#include "virstring.h" +#include "virtime.h" +#include "virtpm.h" + +#define VIR_FROM_THIS VIR_FROM_QEMU + +VIR_LOG_INIT("qemu.qemu_extdevice") + +static int +qemuExtDeviceLogCommand(qemuDomainLogContextPtr logCtxt, + virCommandPtr cmd, + const char *info) +{ + int ret =3D -1; + char *timestamp =3D NULL; + char *logline =3D NULL; + int logFD; + + logFD =3D qemuDomainLogContextGetWriteFD(logCtxt); + + if ((timestamp =3D virTimeStringNow()) =3D=3D NULL) + goto cleanup; + + if (virAsprintf(&logline, "%s: Starting external device: %s\n", + timestamp, info) < 0) + goto cleanup; + + if (safewrite(logFD, logline, strlen(logline)) < 0) + goto cleanup; + + virCommandWriteArgLog(cmd, logFD); + + ret =3D 0; + + cleanup: + VIR_FREE(timestamp); + VIR_FREE(logline); + + return ret; +} + + +static int +qemuExtTPMInitPaths(virQEMUDriverPtr driver, + virDomainDefPtr def) +{ + virQEMUDriverConfigPtr cfg =3D virQEMUDriverGetConfig(driver); + int ret =3D 0; + + switch (def->tpm->type) { + case VIR_DOMAIN_TPM_TYPE_EMULATOR: + ret =3D virTPMEmulatorInitPaths(def->tpm, cfg->swtpmStorageDir, + def->uuid); + break; + case VIR_DOMAIN_TPM_TYPE_PASSTHROUGH: + case VIR_DOMAIN_TPM_TYPE_LAST: + break; + } + + virObjectUnref(cfg); + + return ret; +} + + +static int +qemuExtTPMPrepareHost(virQEMUDriverPtr driver, + virDomainDefPtr def) +{ + virQEMUDriverConfigPtr cfg =3D virQEMUDriverGetConfig(driver); + int ret =3D 0; + char *shortName =3D NULL; + + switch (def->tpm->type) { + case VIR_DOMAIN_TPM_TYPE_EMULATOR: + shortName =3D virDomainDefGetShortName(def); + if (!shortName) + goto cleanup; + + ret =3D virTPMEmulatorPrepareHost(def->tpm, cfg->swtpmLogDir, + def->name, cfg->swtpm_user, + cfg->swtpm_group, + cfg->swtpmStateDir, cfg->user, + shortName); + break; + case VIR_DOMAIN_TPM_TYPE_PASSTHROUGH: + case VIR_DOMAIN_TPM_TYPE_LAST: + break; + } + +cleanup: + VIR_FREE(shortName); + virObjectUnref(cfg); + + return ret; +} + + +/* + * qemuExtTPMStartEmulator: + * + * @driver: QEMU driver + * @def: domain definition + * @logCtxt: log context + * + * Start the external TPM Emulator: + * - have the command line built + * - start the external TPM Emulator and sync with it before QEMU start + */ +static int +qemuExtTPMStartEmulator(virQEMUDriverPtr driver, + virDomainDefPtr def, + qemuDomainLogContextPtr logCtxt) +{ + int ret =3D -1; + virCommandPtr cmd =3D NULL; + int exitstatus; + char *errbuf =3D NULL; + virQEMUDriverConfigPtr cfg =3D virQEMUDriverGetConfig(driver); + virDomainTPMDefPtr tpm =3D def->tpm; + char *shortName =3D virDomainDefGetShortName(def); + + if (!shortName) + return -1; + + /* stop any left-over TPM emulator for this VM */ + virTPMEmulatorStop(cfg->swtpmStateDir, shortName); + + if (!(cmd =3D virTPMEmulatorBuildCommand(tpm, def->name, def->uuid, + driver->privileged, + cfg->swtpm_user, + cfg->swtpm_group))) + goto cleanup; + + if (qemuExtDeviceLogCommand(logCtxt, cmd, "TPM Emulator") < 0) + goto cleanup; + + virCommandSetErrorBuffer(cmd, &errbuf); + + if (virCommandRun(cmd, &exitstatus) < 0 || exitstatus !=3D 0) { + VIR_ERROR("Could not start 'swtpm'. exitstatus: %d\n" + "stderr: %s\n", exitstatus, errbuf); + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Could not start 'swtpm'. exitstatus: %d, " + "error: %s"), exitstatus, errbuf); + goto error; + } + + ret =3D 0; + + cleanup: + VIR_FREE(shortName); + VIR_FREE(errbuf); + virCommandFree(cmd); + + virObjectUnref(cfg); + + return ret; + + error: + VIR_FREE(tpm->data.emulator.source.data.nix.path); + + goto cleanup; +} + +static int +qemuExtTPMStart(virQEMUDriverPtr driver, + virDomainDefPtr def, + qemuDomainLogContextPtr logCtxt) +{ + int ret =3D 0; + virDomainTPMDefPtr tpm =3D def->tpm; + + switch (tpm->type) { + case VIR_DOMAIN_TPM_TYPE_EMULATOR: + ret =3D qemuExtTPMStartEmulator(driver, def, logCtxt); + break; + case VIR_DOMAIN_TPM_TYPE_PASSTHROUGH: + case VIR_DOMAIN_TPM_TYPE_LAST: + break; + } + + return ret; +} + +static void +qemuExtTPMStop(virQEMUDriverPtr driver, virDomainDefPtr def) +{ + virQEMUDriverConfigPtr cfg =3D virQEMUDriverGetConfig(driver); + char *shortName =3D NULL; + + switch (def->tpm->type) { + case VIR_DOMAIN_TPM_TYPE_EMULATOR: + shortName =3D virDomainDefGetShortName(def); + if (!shortName) + goto cleanup; + + virTPMEmulatorStop(cfg->swtpmStateDir, shortName); + break; + case VIR_DOMAIN_TPM_TYPE_PASSTHROUGH: + case VIR_DOMAIN_TPM_TYPE_LAST: + break; + } + +cleanup: + VIR_FREE(shortName); + virObjectUnref(cfg); +} + +/* + * qemuExtDevicesInitPaths: + * + * @driver: QEMU driver + * @def: domain definition + * + * Initialize paths of external devices so that it is known where state is + * stored and we can remove directories and files in case of domain XML + * changes. + */ +int +qemuExtDevicesInitPaths(virQEMUDriverPtr driver, + virDomainDefPtr def) +{ + int ret =3D 0; + + if (def->tpm) + ret =3D qemuExtTPMInitPaths(driver, def); + + return ret; +} + +/* + * qemuExtDevicesPrepareHost: + * + * @driver: QEMU driver + * @def: domain definition + * + * Prepare host storage paths for external devices. + */ +int +qemuExtDevicesPrepareHost(virQEMUDriverPtr driver, + virDomainDefPtr def) +{ + int ret =3D 0; + + if (def->tpm) + ret =3D qemuExtTPMPrepareHost(driver, def); + + return ret; +} + +int +qemuExtDevicesStart(virQEMUDriverPtr driver, + virDomainDefPtr def, + qemuDomainLogContextPtr logCtxt) +{ + int ret =3D 0; + + if (def->tpm) + ret =3D qemuExtTPMStart(driver, def, logCtxt); + + return ret; +} + +void +qemuExtDevicesStop(virQEMUDriverPtr driver, + virDomainDefPtr def) +{ + if (def->tpm) + qemuExtTPMStop(driver, def); +} diff --git a/src/qemu/qemu_extdevice.h b/src/qemu/qemu_extdevice.h new file mode 100644 index 0000000..fd6b630 --- /dev/null +++ b/src/qemu/qemu_extdevice.h @@ -0,0 +1,43 @@ +/* + * qemu_extdevice.h: QEMU external devices support + * + * Copyright (C) 2014, 2018 IBM Corporation + * + * 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 + * . + * + * Author: Stefan Berger + */ +#ifndef __QEMU_EXTDEVICE_H__ +# define __QEMU_EXTDEVICE_H__ + +# include "qemu_conf.h" +# include "qemu_domain.h" + +int qemuExtDevicesInitPaths(virQEMUDriverPtr driver, + virDomainDefPtr def) + ATTRIBUTE_RETURN_CHECK; + +int qemuExtDevicesPrepareHost(virQEMUDriverPtr driver, + virDomainDefPtr def) + ATTRIBUTE_RETURN_CHECK; + +int qemuExtDevicesStart(virQEMUDriverPtr driver, + virDomainDefPtr def, + qemuDomainLogContextPtr logCtxt) + ATTRIBUTE_RETURN_CHECK; + +void qemuExtDevicesStop(virQEMUDriverPtr driver, virDomainDefPtr def); + +#endif /* __QEMU_EXTDEVICE_H__ */ diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index 9233d26..2b07530 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -48,6 +48,7 @@ #include "qemu_migration_params.h" #include "qemu_interface.h" #include "qemu_security.h" +#include "qemu_extdevice.h" =20 #include "cpu/cpu.h" #include "datatypes.h" @@ -5872,6 +5873,10 @@ qemuProcessPrepareHost(virQEMUDriverPtr driver, if (qemuProcessPrepareHostStorage(driver, vm, flags) < 0) goto cleanup; =20 + VIR_DEBUG("Preparing external devices"); + if (qemuExtDevicesPrepareHost(driver, vm->def) < 0) + goto cleanup; + ret =3D 0; cleanup: virObjectUnref(cfg); @@ -5955,6 +5960,10 @@ qemuProcessLaunch(virConnectPtr conn, goto cleanup; logfile =3D qemuDomainLogContextGetWriteFD(logCtxt); =20 + if (qemuExtDevicesInitPaths(driver, vm->def) < 0 || + qemuExtDevicesStart(driver, vm->def, logCtxt) < 0) + goto cleanup; + VIR_DEBUG("Building emulator command line"); if (!(cmd =3D qemuBuildCommandLine(driver, qemuDomainLogContextGetManager(logCtx= t), @@ -6194,6 +6203,8 @@ qemuProcessLaunch(virConnectPtr conn, ret =3D 0; =20 cleanup: + if (ret) + qemuExtDevicesStop(driver, vm->def); qemuDomainSecretDestroy(vm); virCommandFree(cmd); virObjectUnref(logCtxt); @@ -6614,6 +6625,8 @@ void qemuProcessStop(virQEMUDriverPtr driver, =20 qemuDomainCleanupRun(driver, vm); =20 + qemuExtDevicesStop(driver, vm->def); + /* Stop autodestroy in case guest is restarted */ qemuProcessAutoDestroyRemove(driver, vm); =20 --=20 2.5.5 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list