From nobody Sun May 5 08:28:25 2024 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 1513788486775247.57414825833962; Wed, 20 Dec 2017 08:48:06 -0800 (PST) Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 7E7387EAA5; Wed, 20 Dec 2017 16:48:04 +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 31F0F18E40; Wed, 20 Dec 2017 16:48:04 +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 DC8634A467; Wed, 20 Dec 2017 16:48:02 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id vBKGm13K008428 for ; Wed, 20 Dec 2017 11:48:01 -0500 Received: by smtp.corp.redhat.com (Postfix) id 59A0C18E33; Wed, 20 Dec 2017 16:48:01 +0000 (UTC) Received: from localhost.localdomain.com (unknown [10.42.22.189]) by smtp.corp.redhat.com (Postfix) with ESMTP id A5B1A60C20; Wed, 20 Dec 2017 16:47:59 +0000 (UTC) From: "Daniel P. Berrange" To: libvir-list@redhat.com Date: Wed, 20 Dec 2017 16:47:46 +0000 Message-Id: <20171220164750.26419-2-berrange@redhat.com> In-Reply-To: <20171220164750.26419-1-berrange@redhat.com> References: <20171220164750.26419-1-berrange@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.14 X-loop: libvir-list@redhat.com Cc: Martin Kletzander , David Vossel , Fabian Deutsch Subject: [libvirt] [PATCH 1/5] conf: allow different resource registration modes 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.14 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.28]); Wed, 20 Dec 2017 16:48:05 +0000 (UTC) X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" Currently the QEMU driver has three ways of setting up cgroups. It either skips them entirely (if non-root), or uses systemd-machined, or uses cgroups directly. It is further possible to register directly with systemd and bypass machined. We don't support this by systemd-nsspawn does and we ought to. This change adds ability to configure the mechanism for registering resources between all these options explicitly. via Signed-off-by: Daniel P. Berrange --- src/conf/domain_conf.c | 42 ++++++++++++++++++++++------- src/conf/domain_conf.h | 12 +++++++++ src/libvirt_private.syms | 2 ++ src/lxc/lxc_cgroup.c | 34 ++++++++++++++++++++++++ src/lxc/lxc_cgroup.h | 3 +++ src/lxc/lxc_process.c | 11 ++++---- src/qemu/qemu_cgroup.c | 69 +++++++++++++++++++++++++++++++++++++++++---= ---- src/util/vircgroup.c | 55 ++++++++++++++++++++++++-------------- src/util/vircgroup.h | 10 ++++++- 9 files changed, 194 insertions(+), 44 deletions(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 9a62bc472c..fb8e7a0ec7 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -910,6 +910,14 @@ VIR_ENUM_IMPL(virDomainHPTResizing, "required", ); =20 +VIR_ENUM_IMPL(virDomainResourceRegister, + VIR_DOMAIN_RESOURCE_REGISTER_LAST, + "default", + "none", + "cgroup", + "machined", + "systemd"); + /* Internal mapping: subset of block job types that can be present in * XML (remaining types are not two-phase). */ VIR_ENUM_DECL(virDomainBlockJob) @@ -17698,16 +17706,20 @@ virDomainResourceDefParse(xmlNodePtr node, { virDomainResourceDefPtr def =3D NULL; xmlNodePtr tmp =3D ctxt->node; + char *reg; =20 ctxt->node =3D node; =20 if (VIR_ALLOC(def) < 0) goto error; =20 - /* Find out what type of virtualization to use */ - if (!(def->partition =3D virXPathString("string(./partition)", ctxt)))= { - virReportError(VIR_ERR_INTERNAL_ERROR, - "%s", _("missing resource partition attribute")); + def->partition =3D virXPathString("string(./partition)", ctxt); + + reg =3D virXMLPropString(node, "register"); + if (reg !=3D NULL && + (def->reg =3D virDomainResourceRegisterTypeFromString(reg)) <=3D 0= ) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + "%s", _("Invalid register attribute")); goto error; } =20 @@ -25568,11 +25580,23 @@ static void virDomainResourceDefFormat(virBufferPtr buf, virDomainResourceDefPtr def) { - virBufferAddLit(buf, "\n"); - virBufferAdjustIndent(buf, 2); - virBufferEscapeString(buf, "%s\n", def->partiti= on); - virBufferAdjustIndent(buf, -2); - virBufferAddLit(buf, "\n"); + if (def->reg =3D=3D VIR_DOMAIN_RESOURCE_REGISTER_DEFAULT && + def->partition =3D=3D NULL) + return; + + virBufferAddLit(buf, "reg !=3D VIR_DOMAIN_RESOURCE_REGISTER_DEFAULT) + virBufferAsprintf(buf, " register=3D'%s'", virDomainResourceRegist= erTypeToString(def->reg)); + + if (def->partition) { + virBufferAddLit(buf, ">\n"); + virBufferAdjustIndent(buf, 2); + virBufferEscapeString(buf, "%s\n", def->par= tition); + virBufferAdjustIndent(buf, -2); + virBufferAddLit(buf, "\n"); + } else { + virBufferAddLit(buf, "/>\n"); + } } =20 =20 diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 6f7f96b3dd..a7a6628a36 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -2145,9 +2145,20 @@ struct _virDomainPanicDef { void virBlkioDeviceArrayClear(virBlkioDevicePtr deviceWeights, int ndevices); =20 +typedef enum { + VIR_DOMAIN_RESOURCE_REGISTER_DEFAULT, + VIR_DOMAIN_RESOURCE_REGISTER_NONE, + VIR_DOMAIN_RESOURCE_REGISTER_CGROUP, + VIR_DOMAIN_RESOURCE_REGISTER_MACHINED, + VIR_DOMAIN_RESOURCE_REGISTER_SYSTEMD, + + VIR_DOMAIN_RESOURCE_REGISTER_LAST, +} virDomainResourceRegister; + typedef struct _virDomainResourceDef virDomainResourceDef; typedef virDomainResourceDef *virDomainResourceDefPtr; struct _virDomainResourceDef { + int reg; /* enum virDomainResourceRegister */ char *partition; }; =20 @@ -3325,6 +3336,7 @@ VIR_ENUM_DECL(virDomainMemorySource) VIR_ENUM_DECL(virDomainMemoryAllocation) VIR_ENUM_DECL(virDomainIOMMUModel) VIR_ENUM_DECL(virDomainShmemModel) +VIR_ENUM_DECL(virDomainResourceRegister) /* from libvirt.h */ VIR_ENUM_DECL(virDomainState) VIR_ENUM_DECL(virDomainNostateReason) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index d5c3b9abb5..a0fde65dba 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -489,6 +489,8 @@ virDomainRedirdevBusTypeToString; virDomainRedirdevDefFind; virDomainRedirdevDefFree; virDomainRedirdevDefRemove; +virDomainResourceRegisterTypeFromString; +virDomainResourceRegisterTypeToString; virDomainRNGBackendTypeToString; virDomainRNGDefFree; virDomainRNGFind; diff --git a/src/lxc/lxc_cgroup.c b/src/lxc/lxc_cgroup.c index 3369801870..7bd479df1b 100644 --- a/src/lxc/lxc_cgroup.c +++ b/src/lxc/lxc_cgroup.c @@ -478,6 +478,35 @@ static int virLXCCgroupSetupDeviceACL(virDomainDefPtr = def, return ret; } =20 +int virLXCCgroupMode(virDomainResourceRegister reg, + virCgroupRegister *cgreg) +{ + switch (reg) { + case VIR_DOMAIN_RESOURCE_REGISTER_NONE: + goto unsupported; + case VIR_DOMAIN_RESOURCE_REGISTER_DEFAULT: + *cgreg =3D VIR_CGROUP_REGISTER_DEFAULT; + break; + case VIR_DOMAIN_RESOURCE_REGISTER_MACHINED: + *cgreg =3D VIR_CGROUP_REGISTER_MACHINED; + break; + case VIR_DOMAIN_RESOURCE_REGISTER_CGROUP: + *cgreg =3D VIR_CGROUP_REGISTER_DIRECT; + break; + case VIR_DOMAIN_RESOURCE_REGISTER_SYSTEMD: + default: + goto unsupported; + } + + return 0; + + unsupported: + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("Resource register '%s' not available"), + virDomainResourceRegisterTypeToString(reg)); + return -1; +} + =20 virCgroupPtr virLXCCgroupCreate(virDomainDefPtr def, pid_t initpid, @@ -485,11 +514,15 @@ virCgroupPtr virLXCCgroupCreate(virDomainDefPtr def, int *nicindexes) { virCgroupPtr cgroup =3D NULL; + virCgroupRegister reg; char *machineName =3D virLXCDomainGetMachineName(def, 0); =20 if (!machineName) goto cleanup; =20 + if (virLXCCgroupMode(def->resource->reg, ®) < 0) + goto cleanup; + if (def->resource->partition[0] !=3D '/') { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("Resource partition '%s' must start with '/'"), @@ -504,6 +537,7 @@ virCgroupPtr virLXCCgroupCreate(virDomainDefPtr def, initpid, true, nnicindexes, nicindexes, + ®, def->resource->partition, -1, &cgroup) < 0) diff --git a/src/lxc/lxc_cgroup.h b/src/lxc/lxc_cgroup.h index e85f21c47d..979d6a154b 100644 --- a/src/lxc/lxc_cgroup.h +++ b/src/lxc/lxc_cgroup.h @@ -27,6 +27,9 @@ # include "lxc_fuse.h" # include "virusb.h" =20 +int virLXCCgroupMode(virDomainResourceRegister reg, + virCgroupRegister *cgreg); + virCgroupPtr virLXCCgroupCreate(virDomainDefPtr def, pid_t initpid, size_t nnicindexes, diff --git a/src/lxc/lxc_process.c b/src/lxc/lxc_process.c index efd8a69000..24aa0cb0bf 100644 --- a/src/lxc/lxc_process.c +++ b/src/lxc/lxc_process.c @@ -1166,6 +1166,7 @@ virLXCProcessEnsureRootFS(virDomainObjPtr vm) return -1; } =20 + /** * virLXCProcessStart: * @conn: pointer to connection @@ -1260,13 +1261,13 @@ int virLXCProcessStart(virConnectPtr conn, if (VIR_ALLOC(res) < 0) goto cleanup; =20 - if (VIR_STRDUP(res->partition, "/machine") < 0) { - VIR_FREE(res); - goto cleanup; - } - vm->def->resource =3D res; } + if (vm->def->resource->reg !=3D VIR_DOMAIN_RESOURCE_REGISTER_NONE && + !vm->def->resource->partition) { + if (VIR_STRDUP(vm->def->resource->partition, "/machine") < 0) + goto cleanup; + } =20 if (virAsprintf(&logfile, "%s/%s.log", cfg->logDir, vm->def->name) < 0) diff --git a/src/qemu/qemu_cgroup.c b/src/qemu/qemu_cgroup.c index 19252ea239..5167d7fee1 100644 --- a/src/qemu/qemu_cgroup.c +++ b/src/qemu/qemu_cgroup.c @@ -834,6 +834,46 @@ qemuSetupCpuCgroup(virDomainObjPtr vm) } =20 =20 +static int qemuGetCgroupMode(virDomainObjPtr vm, + virDomainResourceRegister reg, + virCgroupRegister *cgreg) +{ + qemuDomainObjPrivatePtr priv =3D vm->privateData; + bool avail =3D virQEMUDriverIsPrivileged(priv->driver) && + virCgroupAvailable(); + + switch (reg) { + case VIR_DOMAIN_RESOURCE_REGISTER_NONE: + return 0; + case VIR_DOMAIN_RESOURCE_REGISTER_DEFAULT: + if (!avail) + return 0; + *cgreg =3D VIR_CGROUP_REGISTER_DEFAULT; + break; + case VIR_DOMAIN_RESOURCE_REGISTER_MACHINED: + if (!avail) + goto unsupported; + *cgreg =3D VIR_CGROUP_REGISTER_MACHINED; + break; + case VIR_DOMAIN_RESOURCE_REGISTER_CGROUP: + if (!avail) + goto unsupported; + *cgreg =3D VIR_CGROUP_REGISTER_DIRECT; + break; + case VIR_DOMAIN_RESOURCE_REGISTER_SYSTEMD: + default: + goto unsupported; + } + + return 1; + + unsupported: + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("Resource register '%s' not available"), + virDomainResourceRegisterTypeToString(reg)); + return -1; +} + static int qemuInitCgroup(virDomainObjPtr vm, size_t nnicindexes, @@ -842,11 +882,17 @@ qemuInitCgroup(virDomainObjPtr vm, int ret =3D -1; qemuDomainObjPrivatePtr priv =3D vm->privateData; virQEMUDriverConfigPtr cfg =3D virQEMUDriverGetConfig(priv->driver); + virCgroupRegister reg; + int rv; =20 - if (!virQEMUDriverIsPrivileged(priv->driver)) - goto done; - - if (!virCgroupAvailable()) + rv =3D qemuGetCgroupMode(vm, + vm->def->resource ? + vm->def->resource->reg : + VIR_DOMAIN_RESOURCE_REGISTER_DEFAULT, + ®); + if (rv < 0) + goto cleanup; + if (rv =3D=3D 0) goto done; =20 virCgroupFree(&priv->cgroup); @@ -857,13 +903,12 @@ qemuInitCgroup(virDomainObjPtr vm, if (VIR_ALLOC(res) < 0) goto cleanup; =20 - if (VIR_STRDUP(res->partition, "/machine") < 0) { - VIR_FREE(res); - goto cleanup; - } - vm->def->resource =3D res; } + if (!vm->def->resource->partition) { + if (VIR_STRDUP(vm->def->resource->partition, "/machine") < 0) + goto cleanup; + } =20 if (vm->def->resource->partition[0] !=3D '/') { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, @@ -879,6 +924,7 @@ qemuInitCgroup(virDomainObjPtr vm, vm->pid, false, nnicindexes, nicindexes, + ®, vm->def->resource->partition, cfg->cgroupControllers, &priv->cgroup) < 0) { @@ -980,6 +1026,11 @@ qemuConnectCgroup(virDomainObjPtr vm) virQEMUDriverConfigPtr cfg =3D virQEMUDriverGetConfig(priv->driver); int ret =3D -1; =20 + if (vm->def->resource && + vm->def->resource->reg =3D=3D VIR_DOMAIN_RESOURCE_REGISTER_NONE) { + goto done; + } + if (!virQEMUDriverIsPrivileged(priv->driver)) goto done; =20 diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c index 0a31947b0d..07ffb78c78 100644 --- a/src/util/vircgroup.c +++ b/src/util/vircgroup.c @@ -1733,6 +1733,7 @@ virCgroupNewMachine(const char *name, bool isContainer, size_t nnicindexes, int *nicindexes, + virCgroupRegister *reg, const char *partition, int controllers, virCgroupPtr *group) @@ -1741,28 +1742,42 @@ virCgroupNewMachine(const char *name, =20 *group =3D NULL; =20 - if ((rv =3D virCgroupNewMachineSystemd(name, - drivername, - uuid, - rootdir, - pidleader, - isContainer, - nnicindexes, - nicindexes, - partition, - controllers, - group)) =3D=3D 0) - return 0; + if (*reg =3D=3D VIR_CGROUP_REGISTER_DEFAULT || + *reg =3D=3D VIR_CGROUP_REGISTER_MACHINED) { + if ((rv =3D virCgroupNewMachineSystemd(name, + drivername, + uuid, + rootdir, + pidleader, + isContainer, + nnicindexes, + nicindexes, + partition, + controllers, + group)) =3D=3D 0) { + *reg =3D VIR_CGROUP_REGISTER_MACHINED; + return 0; + } =20 - if (rv =3D=3D -1) - return -1; + if (rv =3D=3D -1) + return -1; + + if (*reg =3D=3D VIR_CGROUP_REGISTER_MACHINED) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + "%s", _("Systemd machined requested, but not av= ailable")); + return -1; + } + } =20 - return virCgroupNewMachineManual(name, - drivername, - pidleader, - partition, - controllers, - group); + rv =3D virCgroupNewMachineManual(name, + drivername, + pidleader, + partition, + controllers, + group); + if (rv =3D=3D 0) + *reg =3D VIR_CGROUP_REGISTER_DIRECT; + return rv; } =20 =20 diff --git a/src/util/vircgroup.h b/src/util/vircgroup.h index d833927678..63ee1aba5c 100644 --- a/src/util/vircgroup.h +++ b/src/util/vircgroup.h @@ -46,7 +46,8 @@ enum { VIR_CGROUP_CONTROLLER_LAST }; =20 -VIR_ENUM_DECL(virCgroupController); +VIR_ENUM_DECL(virCgroupController) + /* Items of this enum are used later in virCgroupNew to create * bit array stored in int. Like this: * 1 << VIR_CGROUP_CONTROLLER_CPU @@ -103,6 +104,12 @@ virCgroupNewDetectMachine(const char *name, virCgroupPtr *group) ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2); =20 +typedef enum { + VIR_CGROUP_REGISTER_DEFAULT, + VIR_CGROUP_REGISTER_DIRECT, + VIR_CGROUP_REGISTER_MACHINED, +} virCgroupRegister; + int virCgroupNewMachine(const char *name, const char *drivername, const unsigned char *uuid, @@ -111,6 +118,7 @@ int virCgroupNewMachine(const char *name, bool isContainer, size_t nnicindexes, int *nicindexes, + virCgroupRegister *reg, const char *partition, int controllers, virCgroupPtr *group) --=20 2.14.3 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list From nobody Sun May 5 08:28:25 2024 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 1513788486647429.8702190726058; Wed, 20 Dec 2017 08:48:06 -0800 (PST) Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 995C96016A; Wed, 20 Dec 2017 16:48:04 +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 784D1600D4; Wed, 20 Dec 2017 16:48:04 +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 40B054A469; Wed, 20 Dec 2017 16:48:04 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id vBKGm3Bq008436 for ; Wed, 20 Dec 2017 11:48:03 -0500 Received: by smtp.corp.redhat.com (Postfix) id 0823F18E4C; Wed, 20 Dec 2017 16:48:03 +0000 (UTC) Received: from localhost.localdomain.com (unknown [10.42.22.189]) by smtp.corp.redhat.com (Postfix) with ESMTP id BF2C060C20; Wed, 20 Dec 2017 16:48:01 +0000 (UTC) From: "Daniel P. Berrange" To: libvir-list@redhat.com Date: Wed, 20 Dec 2017 16:47:47 +0000 Message-Id: <20171220164750.26419-3-berrange@redhat.com> In-Reply-To: <20171220164750.26419-1-berrange@redhat.com> References: <20171220164750.26419-1-berrange@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.14 X-loop: libvir-list@redhat.com Cc: Martin Kletzander , David Vossel , Fabian Deutsch Subject: [libvirt] [PATCH 2/5] conf: expose APIs to let drivers load individual config / status files 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.11 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.25]); Wed, 20 Dec 2017 16:48:05 +0000 (UTC) X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" Currently drivers can only do a bulk load of config / status files for their guests. This exposes some helper methods to allow individual guests to be loaded. Signed-off-by: Daniel P. Berrange --- src/conf/virdomainobjlist.c | 98 ++++++++++++++++++++++++++++++++---------= ---- src/conf/virdomainobjlist.h | 17 ++++++++ src/libvirt_private.syms | 2 + 3 files changed, 89 insertions(+), 28 deletions(-) diff --git a/src/conf/virdomainobjlist.c b/src/conf/virdomainobjlist.c index 87a742b1ea..37f795fe6d 100644 --- a/src/conf/virdomainobjlist.c +++ b/src/conf/virdomainobjlist.c @@ -443,16 +443,15 @@ void virDomainObjListRemoveLocked(virDomainObjListPtr= doms, virObjectUnlock(dom); } =20 - static virDomainObjPtr -virDomainObjListLoadConfig(virDomainObjListPtr doms, - virCapsPtr caps, - virDomainXMLOptionPtr xmlopt, - const char *configDir, - const char *autostartDir, - const char *name, - virDomainLoadConfigNotify notify, - void *opaque) +virDomainObjListLoadConfigLocked(virDomainObjListPtr doms, + virCapsPtr caps, + virDomainXMLOptionPtr xmlopt, + const char *configDir, + const char *autostartDir, + const char *name, + virDomainLoadConfigNotify notify, + void *opaque) { char *configFile =3D NULL, *autostartLink =3D NULL; virDomainDefPtr def =3D NULL; @@ -496,14 +495,36 @@ virDomainObjListLoadConfig(virDomainObjListPtr doms, } =20 =20 -static virDomainObjPtr -virDomainObjListLoadStatus(virDomainObjListPtr doms, - const char *statusDir, - const char *name, +virDomainObjPtr +virDomainObjListLoadConfig(virDomainObjListPtr doms, virCapsPtr caps, virDomainXMLOptionPtr xmlopt, + const char *configDir, + const char *autostartDir, + const char *name, virDomainLoadConfigNotify notify, void *opaque) +{ + virDomainObjPtr vm =3D NULL; + virObjectRWLockWrite(doms); + + vm =3D virDomainObjListLoadConfigLocked(doms, caps, xmlopt, configDir, + autostartDir, name, notify, opaq= ue); + virObjectRef(vm); + + virObjectRWUnlock(doms); + return vm; +} + + +static virDomainObjPtr +virDomainObjListLoadStatusLocked(virDomainObjListPtr doms, + const char *statusDir, + const char *name, + virCapsPtr caps, + virDomainXMLOptionPtr xmlopt, + virDomainLoadConfigNotify notify, + void *opaque) { char *statusFile =3D NULL; virDomainObjPtr obj =3D NULL; @@ -555,6 +576,27 @@ virDomainObjListLoadStatus(virDomainObjListPtr doms, } =20 =20 +virDomainObjPtr +virDomainObjListLoadStatus(virDomainObjListPtr doms, + const char *statusDir, + const char *name, + virCapsPtr caps, + virDomainXMLOptionPtr xmlopt, + virDomainLoadConfigNotify notify, + void *opaque) +{ + virDomainObjPtr vm =3D NULL; + virObjectRWLockWrite(doms); + + vm =3D virDomainObjListLoadStatusLocked(doms, statusDir, name, caps, x= mlopt, + notify, opaque); + virObjectRef(vm); + + virObjectRWUnlock(doms); + return vm; +} + + int virDomainObjListLoadAllConfigs(virDomainObjListPtr doms, const char *configDir, @@ -587,22 +629,22 @@ virDomainObjListLoadAllConfigs(virDomainObjListPtr do= ms, kill the whole process */ VIR_INFO("Loading config file '%s.xml'", entry->d_name); if (liveStatus) - dom =3D virDomainObjListLoadStatus(doms, - configDir, - entry->d_name, - caps, - xmlopt, - notify, - opaque); + dom =3D virDomainObjListLoadStatusLocked(doms, + configDir, + entry->d_name, + caps, + xmlopt, + notify, + opaque); else - dom =3D virDomainObjListLoadConfig(doms, - caps, - xmlopt, - configDir, - autostartDir, - entry->d_name, - notify, - opaque); + dom =3D virDomainObjListLoadConfigLocked(doms, + caps, + xmlopt, + configDir, + autostartDir, + entry->d_name, + notify, + opaque); if (dom) { if (!liveStatus) dom->persistent =3D 1; diff --git a/src/conf/virdomainobjlist.h b/src/conf/virdomainobjlist.h index bb186bde30..4aee8fae13 100644 --- a/src/conf/virdomainobjlist.h +++ b/src/conf/virdomainobjlist.h @@ -77,6 +77,23 @@ int virDomainObjListLoadAllConfigs(virDomainObjListPtr d= oms, virDomainXMLOptionPtr xmlopt, virDomainLoadConfigNotify notify, void *opaque); +virDomainObjPtr +virDomainObjListLoadConfig(virDomainObjListPtr doms, + virCapsPtr caps, + virDomainXMLOptionPtr xmlopt, + const char *configDir, + const char *autostartDir, + const char *name, + virDomainLoadConfigNotify notify, + void *opaque); +virDomainObjPtr +virDomainObjListLoadStatus(virDomainObjListPtr doms, + const char *statusDir, + const char *name, + virCapsPtr caps, + virDomainXMLOptionPtr xmlopt, + virDomainLoadConfigNotify notify, + void *opaque); =20 int virDomainObjListNumOfDomains(virDomainObjListPtr doms, bool active, diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index a0fde65dba..be631e3dd7 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -938,6 +938,8 @@ virDomainObjListForEach; virDomainObjListGetActiveIDs; virDomainObjListGetInactiveNames; virDomainObjListLoadAllConfigs; +virDomainObjListLoadConfig; +virDomainObjListLoadStatus; virDomainObjListNew; virDomainObjListNumOfDomains; virDomainObjListRemove; --=20 2.14.3 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list From nobody Sun May 5 08:28:25 2024 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 1513788499187819.4654701374592; Wed, 20 Dec 2017 08:48:19 -0800 (PST) Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id A74DC7EAB0; Wed, 20 Dec 2017 16:48:17 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.20]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 813755C549; Wed, 20 Dec 2017 16:48:17 +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 479471808873; Wed, 20 Dec 2017 16:48:17 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id vBKGm5a4008458 for ; Wed, 20 Dec 2017 11:48:05 -0500 Received: by smtp.corp.redhat.com (Postfix) id 50DAD18E33; Wed, 20 Dec 2017 16:48:05 +0000 (UTC) Received: from localhost.localdomain.com (unknown [10.42.22.189]) by smtp.corp.redhat.com (Postfix) with ESMTP id DFBC360C31; Wed, 20 Dec 2017 16:48:03 +0000 (UTC) From: "Daniel P. Berrange" To: libvir-list@redhat.com Date: Wed, 20 Dec 2017 16:47:48 +0000 Message-Id: <20171220164750.26419-4-berrange@redhat.com> In-Reply-To: <20171220164750.26419-1-berrange@redhat.com> References: <20171220164750.26419-1-berrange@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.14 X-loop: libvir-list@redhat.com Cc: Martin Kletzander , David Vossel , Fabian Deutsch Subject: [libvirt] [PATCH 3/5] qemu: add a public API to trigger QEMU driver to connect to running guest 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.16 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.28]); Wed, 20 Dec 2017 16:48:18 +0000 (UTC) X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" Currently the QEMU driver will reconnect to running guests during libvirtd startup. To support the ability to launch a fully supported guest externally to the main libvirtd daemon, this adds a QEMU specific public API virDomainQemuReconnect(conn, name, flags); This accepts a domain name, and simply runs the normal reconnect logic that the QEMU driver would do at startup. Signed-off-by: Daniel P. Berrange --- include/libvirt/libvirt-qemu.h | 4 ++++ src/driver-hypervisor.h | 5 +++++ src/libvirt-qemu.c | 48 ++++++++++++++++++++++++++++++++++++++= ++++ src/libvirt_qemu.syms | 5 +++++ src/remote/qemu_protocol.x | 18 +++++++++++++++- src/remote/remote_driver.c | 1 + 6 files changed, 80 insertions(+), 1 deletion(-) diff --git a/include/libvirt/libvirt-qemu.h b/include/libvirt/libvirt-qemu.h index 2bb8ee8685..0d38d2f9f8 100644 --- a/include/libvirt/libvirt-qemu.h +++ b/include/libvirt/libvirt-qemu.h @@ -44,6 +44,10 @@ virDomainPtr virDomainQemuAttach(virConnectPtr domain, unsigned int pid_value, unsigned int flags); =20 +virDomainPtr virDomainQemuReconnect(virConnectPtr domain, + const char *name, + unsigned int flags); + typedef enum { VIR_DOMAIN_QEMU_AGENT_COMMAND_MIN =3D -2, VIR_DOMAIN_QEMU_AGENT_COMMAND_BLOCK =3D -2, diff --git a/src/driver-hypervisor.h b/src/driver-hypervisor.h index ce0e2b2525..2e923e730f 100644 --- a/src/driver-hypervisor.h +++ b/src/driver-hypervisor.h @@ -848,6 +848,10 @@ typedef virDomainPtr (*virDrvDomainQemuAttach)(virConnectPtr conn, unsigned int pid_value, unsigned int flags); +typedef virDomainPtr +(*virDrvDomainQemuReconnect)(virConnectPtr conn, + const char *name, + unsigned int flags); =20 typedef int (*virDrvConnectDomainQemuMonitorEventRegister)(virConnectPtr conn, @@ -1463,6 +1467,7 @@ struct _virHypervisorDriver { virDrvDomainSnapshotDelete domainSnapshotDelete; virDrvDomainQemuMonitorCommand domainQemuMonitorCommand; virDrvDomainQemuAttach domainQemuAttach; + virDrvDomainQemuReconnect domainQemuReconnect; virDrvDomainQemuAgentCommand domainQemuAgentCommand; virDrvConnectDomainQemuMonitorEventRegister connectDomainQemuMonitorEv= entRegister; virDrvConnectDomainQemuMonitorEventDeregister connectDomainQemuMonitor= EventDeregister; diff --git a/src/libvirt-qemu.c b/src/libvirt-qemu.c index 43f63839eb..c5859cf312 100644 --- a/src/libvirt-qemu.c +++ b/src/libvirt-qemu.c @@ -164,6 +164,54 @@ virDomainQemuAttach(virConnectPtr conn, return NULL; } =20 +/** + * virDomainQemuReconnect: + * @conn: pointer to a hypervisor connection + * @name: the libvirt guest name + * @flags: optional flags, currently unused + * + * This API is QEMU specific, so it will only work with hypervisor + * connections to the QEMU driver. + * + * This API will attach to an QEMU process that a separate libvirt + * helper has launched. The external QEMU must fully follow the + * normal libvirt QEMU configuration. + * + * If successful, then the guest will appear in the list of running + * domains for this connection, and other APIs should operate + * normally (provided the above requirements were honored). + * + * Returns a new domain object on success, NULL otherwise + */ +virDomainPtr +virDomainQemuReconnect(virConnectPtr conn, + const char *name, + unsigned int flags) +{ + VIR_DEBUG("conn=3D%p, name=3D%s, flags=3D0x%x", conn, name, flags); + + virResetLastError(); + + virCheckConnectReturn(conn, NULL); + virCheckNonNullArgGoto(name, error); + + virCheckReadOnlyGoto(conn->flags, error); + + if (conn->driver->domainQemuReconnect) { + virDomainPtr ret; + ret =3D conn->driver->domainQemuReconnect(conn, name, flags); + if (!ret) + goto error; + return ret; + } + + virReportUnsupportedError(); + + error: + virDispatchError(conn); + return NULL; +} + =20 /** * virDomainQemuAgentCommand: diff --git a/src/libvirt_qemu.syms b/src/libvirt_qemu.syms index 3a297e3a2b..a109fcc0d0 100644 --- a/src/libvirt_qemu.syms +++ b/src/libvirt_qemu.syms @@ -30,3 +30,8 @@ LIBVIRT_QEMU_1.2.3 { virConnectDomainQemuMonitorEventDeregister; virConnectDomainQemuMonitorEventRegister; } LIBVIRT_QEMU_0.10.0; + +LIBVIRT_QEMU_4.1.0 { + global: + virDomainQemuReconnect; +} LIBVIRT_QEMU_1.2.3; diff --git a/src/remote/qemu_protocol.x b/src/remote/qemu_protocol.x index f6b88a984c..b5307bf9dd 100644 --- a/src/remote/qemu_protocol.x +++ b/src/remote/qemu_protocol.x @@ -82,6 +82,15 @@ struct qemu_domain_monitor_event_msg { remote_string details; }; =20 +struct qemu_domain_reconnect_args { + remote_nonnull_string name; + unsigned int flags; +}; + +struct qemu_domain_reconnect_ret { + remote_nonnull_domain dom; +}; + /* Define the program number, protocol version and procedure numbers here.= */ const QEMU_PROGRAM =3D 0x20008087; const QEMU_PROTOCOL_VERSION =3D 1; @@ -154,5 +163,12 @@ enum qemu_procedure { * @generate: both * @acl: none */ - QEMU_PROC_DOMAIN_MONITOR_EVENT =3D 6 + QEMU_PROC_DOMAIN_MONITOR_EVENT =3D 6, + + /** + * @generate: both + * @acl: domain:start + * @acl: domain:write + */ + QEMU_PROC_DOMAIN_RECONNECT =3D 7 }; diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c index f8fa64af99..b76242fe2e 100644 --- a/src/remote/remote_driver.c +++ b/src/remote/remote_driver.c @@ -8431,6 +8431,7 @@ static virHypervisorDriver hypervisor_driver =3D { .domainSnapshotDelete =3D remoteDomainSnapshotDelete, /* 0.8.0 */ .domainQemuMonitorCommand =3D remoteDomainQemuMonitorCommand, /* 0.8.3= */ .domainQemuAttach =3D remoteDomainQemuAttach, /* 0.9.4 */ + .domainQemuReconnect =3D remoteDomainQemuReconnect, /* 4.1.0 */ .domainQemuAgentCommand =3D remoteDomainQemuAgentCommand, /* 0.10.0 */ .connectDomainQemuMonitorEventRegister =3D remoteConnectDomainQemuMoni= torEventRegister, /* 1.2.3 */ .connectDomainQemuMonitorEventDeregister =3D remoteConnectDomainQemuMo= nitorEventDeregister, /* 1.2.3 */ --=20 2.14.3 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list From nobody Sun May 5 08:28:25 2024 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 1513788500919964.3653052119421; Wed, 20 Dec 2017 08:48:20 -0800 (PST) Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id CEE564903B; Wed, 20 Dec 2017 16:48:18 +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 A9EF818E40; Wed, 20 Dec 2017 16:48:18 +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 75C653FCF9; Wed, 20 Dec 2017 16:48:18 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id vBKGm9Hf008478 for ; Wed, 20 Dec 2017 11:48:09 -0500 Received: by smtp.corp.redhat.com (Postfix) id 4A24960C29; Wed, 20 Dec 2017 16:48:09 +0000 (UTC) Received: from localhost.localdomain.com (unknown [10.42.22.189]) by smtp.corp.redhat.com (Postfix) with ESMTP id 9510C18E54; Wed, 20 Dec 2017 16:48:05 +0000 (UTC) From: "Daniel P. Berrange" To: libvir-list@redhat.com Date: Wed, 20 Dec 2017 16:47:49 +0000 Message-Id: <20171220164750.26419-5-berrange@redhat.com> In-Reply-To: <20171220164750.26419-1-berrange@redhat.com> References: <20171220164750.26419-1-berrange@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.14 X-loop: libvir-list@redhat.com Cc: Martin Kletzander , David Vossel , Fabian Deutsch Subject: [libvirt] [PATCH 4/5] qemu: implement the new virDomainQemuReconnect method 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.14 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.38]); Wed, 20 Dec 2017 16:48:19 +0000 (UTC) X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" Signed-off-by: Daniel P. Berrange --- src/qemu/qemu_driver.c | 57 +++++++++++++++++++++++++++++++++++++++++++++= ++++ src/qemu/qemu_process.c | 31 ++++++++++++++++++--------- src/qemu/qemu_process.h | 1 + 3 files changed, 79 insertions(+), 10 deletions(-) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 97b194b057..fea1f24250 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -16300,6 +16300,62 @@ static virDomainPtr qemuDomainQemuAttach(virConnec= tPtr conn, } =20 =20 +static virDomainPtr qemuDomainQemuReconnect(virConnectPtr conn, + const char *name, + unsigned int flags) +{ + virQEMUDriverPtr driver =3D conn->privateData; + virDomainObjPtr vm =3D NULL; + virDomainPtr dom =3D NULL; + virCapsPtr caps =3D NULL; + virQEMUDriverConfigPtr cfg; + + virCheckFlags(0, NULL); + + cfg =3D virQEMUDriverGetConfig(driver); + + if (strchr(name, '/')) { + virReportError(VIR_ERR_XML_ERROR, + _("name %s cannot contain '/'"), name); + goto cleanup; + } + + vm =3D virDomainObjListFindByName(driver->domains, name); + if (vm) { + virReportError(VIR_ERR_OPERATION_INVALID, + _("Domain '%s' already exists"), name); + goto cleanup; + } + + if (!(caps =3D virQEMUDriverGetCapabilities(driver, false))) + goto cleanup; + + if (!(vm =3D virDomainObjListLoadStatus(driver->domains, + cfg->stateDir, + name, + caps, + driver->xmlopt, + NULL, NULL))) { + goto cleanup; + } + + if (virDomainQemuReconnectEnsureACL(conn, vm->def) < 0) { + qemuDomainRemoveInactive(driver, vm); + goto cleanup; + } + + dom =3D virGetDomain(conn, vm->def->name, vm->def->uuid, vm->def->id); + + qemuDomainObjEndJob(driver, vm); + + cleanup: + virDomainObjEndAPI(&vm); + virObjectUnref(caps); + virObjectUnref(cfg); + return dom; +} + + static int qemuDomainOpenConsole(virDomainPtr dom, const char *dev_name, @@ -21262,6 +21318,7 @@ static virHypervisorDriver qemuHypervisorDriver =3D= { .domainSnapshotDelete =3D qemuDomainSnapshotDelete, /* 0.8.0 */ .domainQemuMonitorCommand =3D qemuDomainQemuMonitorCommand, /* 0.8.3 */ .domainQemuAttach =3D qemuDomainQemuAttach, /* 0.9.4 */ + .domainQemuReconnect =3D qemuDomainQemuReconnect, /* 4.1.0 */ .domainQemuAgentCommand =3D qemuDomainQemuAgentCommand, /* 0.10.0 */ .connectDomainQemuMonitorEventRegister =3D qemuConnectDomainQemuMonito= rEventRegister, /* 1.2.3 */ .connectDomainQemuMonitorEventDeregister =3D qemuConnectDomainQemuMoni= torEventDeregister, /* 1.2.3 */ diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index a0f430f89f..ea924cf9b6 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -7088,14 +7088,10 @@ struct qemuProcessReconnectData { * We can't do normal MonitorEnter & MonitorExit because these two lock the * monitor lock, which does not exists in this early phase. */ -static void -qemuProcessReconnect(void *opaque) +int +qemuProcessReconnect(virQEMUDriverPtr driver, virDomainObjPtr obj, virConn= ectPtr conn) { - struct qemuProcessReconnectData *data =3D opaque; - virQEMUDriverPtr driver =3D data->driver; - virDomainObjPtr obj =3D data->obj; qemuDomainObjPrivatePtr priv; - virConnectPtr conn =3D data->conn; struct qemuDomainJobObj oldjob; int state; int reason; @@ -7104,8 +7100,7 @@ qemuProcessReconnect(void *opaque) unsigned int stopFlags =3D 0; bool jobStarted =3D false; virCapsPtr caps =3D NULL; - - VIR_FREE(data); + int ret =3D -1; =20 qemuDomainObjRestoreJob(obj, &oldjob); if (oldjob.asyncJob =3D=3D QEMU_ASYNC_JOB_MIGRATION_IN) @@ -7297,6 +7292,7 @@ qemuProcessReconnect(void *opaque) if (virAtomicIntInc(&driver->nactive) =3D=3D 1 && driver->inhibitCallb= ack) driver->inhibitCallback(true, driver->inhibitOpaque); =20 + ret =3D 0; cleanup: if (jobStarted) { if (!virDomainObjIsActive(obj)) @@ -7311,7 +7307,7 @@ qemuProcessReconnect(void *opaque) virObjectUnref(cfg); virObjectUnref(caps); virNWFilterUnlockFilterUpdates(); - return; + return ret; =20 error: if (virDomainObjIsActive(obj)) { @@ -7338,6 +7334,21 @@ qemuProcessReconnect(void *opaque) goto cleanup; } =20 + +static void +qemuProcessReconnectThread(void *opaque) +{ + struct qemuProcessReconnectData *data =3D opaque; + virQEMUDriverPtr driver =3D data->driver; + virDomainObjPtr obj =3D data->obj; + virConnectPtr conn =3D data->conn; + + qemuProcessReconnect(driver, obj, conn); + + VIR_FREE(data); +} + + static int qemuProcessReconnectHelper(virDomainObjPtr obj, void *opaque) @@ -7369,7 +7380,7 @@ qemuProcessReconnectHelper(virDomainObjPtr obj, */ virObjectRef(data->conn); =20 - if (virThreadCreate(&thread, false, qemuProcessReconnect, data) < 0) { + if (virThreadCreate(&thread, false, qemuProcessReconnectThread, data) = < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Could not create thread. QEMU initialization " "might be incomplete")); diff --git a/src/qemu/qemu_process.h b/src/qemu/qemu_process.h index cd9a720313..846577d341 100644 --- a/src/qemu/qemu_process.h +++ b/src/qemu/qemu_process.h @@ -45,6 +45,7 @@ int qemuProcessBuildDestroyMemoryPaths(virQEMUDriverPtr d= river, =20 void qemuProcessAutostartAll(virQEMUDriverPtr driver); void qemuProcessReconnectAll(virConnectPtr conn, virQEMUDriverPtr driver); +int qemuProcessReconnect(virQEMUDriverPtr driver, virDomainObjPtr obj, vir= ConnectPtr conn); =20 typedef struct _qemuProcessIncomingDef qemuProcessIncomingDef; typedef qemuProcessIncomingDef *qemuProcessIncomingDefPtr; --=20 2.14.3 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list From nobody Sun May 5 08:28:25 2024 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 1513788502965993.3614881791664; Wed, 20 Dec 2017 08:48:22 -0800 (PST) Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id BE34F2C977D; Wed, 20 Dec 2017 16:48:20 +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 8D2FE1755C; Wed, 20 Dec 2017 16:48:20 +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 5A6213FA5B; Wed, 20 Dec 2017 16:48:20 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id vBKGmBap008493 for ; Wed, 20 Dec 2017 11:48:11 -0500 Received: by smtp.corp.redhat.com (Postfix) id DF17A18EC1; Wed, 20 Dec 2017 16:48:11 +0000 (UTC) Received: from localhost.localdomain.com (unknown [10.42.22.189]) by smtp.corp.redhat.com (Postfix) with ESMTP id 9377E60C29; Wed, 20 Dec 2017 16:48:09 +0000 (UTC) From: "Daniel P. Berrange" To: libvir-list@redhat.com Date: Wed, 20 Dec 2017 16:47:50 +0000 Message-Id: <20171220164750.26419-6-berrange@redhat.com> In-Reply-To: <20171220164750.26419-1-berrange@redhat.com> References: <20171220164750.26419-1-berrange@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.14 X-loop: libvir-list@redhat.com Cc: Martin Kletzander , David Vossel , Fabian Deutsch Subject: [libvirt] [PATCH 5/5] qemu: implement the 'libvirt_qemu' shim for launching guests externally 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.16 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.29]); Wed, 20 Dec 2017 16:48:21 +0000 (UTC) X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" This introduces a new binary 'libvirt_qemu' which can be used to launch guests externally from libvirtd. eg libvirt_qemu -c qemu:///system /path/to/xml/file This will launch a guest from the requested XML file and then connect to qemu:///system to register it with libvirtd. At this point all normal libvirtd operations should generally work. NB, this impl has many flaws: - We don't generate a unique 'id', so all guests will get id=3D=3D1. Surprisingly this doesn't break the world. - Tracking of unique name + UUIDs is *not* race free. - No tracking/allocation of shared resource state (PCI devices, etc) Most other functionality works, but might have expected results. In terms of namespace support there's some restrictions - The mount namespace must share certain dirs /etc/libvirt /var/run/libvirt /var/lib/libvirt /var/cache/libvirt between the libvirtd and libvirt_qemu processes - The PID namespace must match libvirtd & libvirt_qemu though this will be addressed in another patch to come - The network namespace can be different - Hotplug/unplug will likely break if separate namespaces are used - The libvirt_qemu will exit if startup fails, however, it won't exit when QEMU later shuts down - you must listen for libvirtd events to detect that right now. We'll fix that - Killing the libvirt_qemu shim will not kill the QEMU process. You must kill via the libvirt API as normal. This won't change, because we need to be able to ultimately restart the libvirt_qemu shim in order to apply software updates to running instance. We might wire up a special signal though to let you kill libvirt_qemu & take out QEMU at same time eg SIGQUIT or something like that perhaps. Signed-off-by: Daniel P. Berrange --- po/POTFILES.in | 1 + src/Makefile.am | 49 ++++ src/qemu/qemu_conf.h | 2 +- src/qemu/qemu_controller.c | 551 +++++++++++++++++++++++++++++++++++++++++= ++++ src/qemu/qemu_domain.c | 2 +- src/qemu/qemu_driver.c | 2 +- 6 files changed, 604 insertions(+), 3 deletions(-) create mode 100644 src/qemu/qemu_controller.c diff --git a/po/POTFILES.in b/po/POTFILES.in index c1fa23427e..d97175b6d5 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -133,6 +133,7 @@ src/qemu/qemu_block.c src/qemu/qemu_capabilities.c src/qemu/qemu_cgroup.c src/qemu/qemu_command.c +src/qemu/qemu_controller.c src/qemu/qemu_conf.c src/qemu/qemu_domain.c src/qemu/qemu_domain_address.c diff --git a/src/Makefile.am b/src/Makefile.am index 4c022d1e44..7ca5ad4d3c 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -922,6 +922,9 @@ QEMU_DRIVER_SOURCES =3D \ qemu/qemu_capspriv.h \ qemu/qemu_security.c qemu/qemu_security.h =20 +QEMU_CONTROLLER_SOURCES =3D \ + qemu/qemu_controller.c + XENAPI_DRIVER_SOURCES =3D \ xenapi/xenapi_driver.c xenapi/xenapi_driver.h \ xenapi/xenapi_driver_private.h \ @@ -3115,6 +3118,52 @@ endif WITH_LIBVIRTD endif WITH_LXC EXTRA_DIST +=3D $(LXC_CONTROLLER_SOURCES) =20 +if WITH_QEMU +if WITH_LIBVIRTD +libexec_PROGRAMS +=3D libvirt_qemu + +libvirt_qemu_SOURCES =3D \ + $(QEMU_CONTROLLER_SOURCES) \ + $(DATATYPES_SOURCES) +libvirt_qemu_LDFLAGS =3D \ + $(AM_LDFLAGS) \ + $(PIE_LDFLAGS) \ + $(NULL) +libvirt_qemu_LDADD =3D \ + libvirt.la \ + libvirt-qemu.la \ + libvirt_driver_qemu_impl.la +if WITH_NETWORK +libvirt_qemu_LDADD +=3D libvirt_driver_network_impl.la +endif WITH_NETWORK +if WITH_STORAGE +libvirt_qemu_LDADD +=3D libvirt_driver_storage_impl.la +endif WITH_STORAGE +libvirt_qemu_LDADD +=3D ../gnulib/lib/libgnu.la $(LIBSOCKET) +if WITH_DTRACE_PROBES +libvirt_qemu_LDADD +=3D libvirt_probes.lo libvirt_qemu_probes.lo +endif WITH_DTRACE_PROBES +libvirt_qemu_LDADD +=3D $(SECDRIVER_LIBS) +libvirt_qemu_CFLAGS =3D \ + -I$(srcdir)/access \ + -I$(srcdir)/conf \ + -I$(srcdir)/secret \ + $(AM_CFLAGS) \ + $(PIE_CFLAGS) \ + $(LIBNL_CFLAGS) \ + $(FUSE_CFLAGS) \ + $(DBUS_CFLAGS) \ + $(XDR_CFLAGS) \ + $(NULL) +if WITH_BLKID +libvirt_qemu_CFLAGS +=3D $(BLKID_CFLAGS) +libvirt_qemu_LDADD +=3D $(BLKID_LIBS) +endif WITH_BLKID +libvirt_qemu_CFLAGS +=3D $(SECDRIVER_CFLAGS) +endif WITH_LIBVIRTD +endif WITH_QEMU +EXTRA_DIST +=3D $(QEMU_CONTROLLER_SOURCES) + if WITH_SECDRIVER_APPARMOR if WITH_LIBVIRTD libexec_PROGRAMS +=3D virt-aa-helper diff --git a/src/qemu/qemu_conf.h b/src/qemu/qemu_conf.h index a553e30e2e..a19b199147 100644 --- a/src/qemu/qemu_conf.h +++ b/src/qemu/qemu_conf.h @@ -296,7 +296,7 @@ struct _qemuDomainCmdlineDef { char **env_value; }; =20 - +int qemuSecurityInit(virQEMUDriverPtr driver); =20 void qemuDomainCmdlineDefFree(qemuDomainCmdlineDefPtr def); =20 diff --git a/src/qemu/qemu_controller.c b/src/qemu/qemu_controller.c new file mode 100644 index 0000000000..320d9a99b6 --- /dev/null +++ b/src/qemu/qemu_controller.c @@ -0,0 +1,551 @@ +/* + * qemu_controller.c: QEMU process controller + * + * Copyright (C) 2006-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 + * . + * + */ + +#include + +#include +#include +#include +#include + +#include "virgettext.h" +#include "virthread.h" +#include "virlog.h" +#include "virfile.h" +#include "viralloc.h" +#include "virstring.h" +#include "dirname.h" +#include "driver.h" + +#include "qemu/qemu_conf.h" +#include "qemu/qemu_process.h" +#include "qemu/qemu_driver.h" +#include "libvirt_internal.h" + +static const char *argv0; + +#define VIR_FROM_THIS VIR_FROM_QEMU + +VIR_LOG_INIT("qemu.qemu_controller"); + +typedef struct virQEMUController virQEMUController; +typedef virQEMUController *virQEMUControllerPtr; +struct virQEMUController { + const char *uri; + bool privileged; + const char *xml; + virQEMUDriverPtr driver; + virConnectPtr conn; + virDomainObjPtr vm; +}; + +static void +virQEMUControllerDriverFree(virQEMUDriverPtr driver) +{ + if (!driver) + return; + + virObjectUnref(driver->config); + virObjectUnref(driver->hostdevMgr); + virHashFree(driver->sharedDevices); + virObjectUnref(driver->caps); + virObjectUnref(driver->qemuCapsCache); + + virObjectUnref(driver->domains); + virObjectUnref(driver->remotePorts); + virObjectUnref(driver->webSocketPorts); + virObjectUnref(driver->migrationPorts); + virObjectUnref(driver->migrationErrors); + + virObjectUnref(driver->xmlopt); + + virSysinfoDefFree(driver->hostsysinfo); + + virObjectUnref(driver->closeCallbacks); + + VIR_FREE(driver->qemuImgBinary); + + virObjectUnref(driver->securityManager); + + ebtablesContextFree(driver->ebtables); + + virLockManagerPluginUnref(driver->lockManager); + + virMutexDestroy(&driver->lock); + VIR_FREE(driver); +} + +static virQEMUDriverPtr virQEMUControllerNewDriver(bool privileged) +{ + virQEMUDriverPtr driver =3D NULL; + char *driverConf =3D NULL; + virConnectPtr conn =3D NULL; + virQEMUDriverConfigPtr cfg; + uid_t run_uid =3D -1; + gid_t run_gid =3D -1; + char *hugepagePath =3D NULL; + char *memoryBackingPath =3D NULL; + size_t i; + + if (VIR_ALLOC(driver) < 0) + return NULL; + + if (virMutexInit(&driver->lock) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("cannot initialize mutex")); + VIR_FREE(driver); + return NULL; + } + + driver->privileged =3D privileged; + + /* read the host sysinfo */ + if (privileged) + driver->hostsysinfo =3D virSysinfoRead(); + + if (!(driver->config =3D cfg =3D virQEMUDriverConfigNew(privileged))) + goto error; + + if (virAsprintf(&driverConf, "%s/qemu.conf", cfg->configBaseDir) < 0) + goto error; + + if (virQEMUDriverConfigLoadFile(cfg, driverConf, privileged) < 0) + goto error; + VIR_FREE(driverConf); + + if (virQEMUDriverConfigValidate(cfg) < 0) + goto error; + + if (virFileMakePath(cfg->stateDir) < 0) { + virReportSystemError(errno, _("Failed to create state dir %s"), + cfg->stateDir); + goto error; + } + if (virFileMakePath(cfg->libDir) < 0) { + virReportSystemError(errno, _("Failed to create lib dir %s"), + cfg->libDir); + goto error; + } + if (virFileMakePath(cfg->cacheDir) < 0) { + virReportSystemError(errno, _("Failed to create cache dir %s"), + cfg->cacheDir); + goto error; + } + if (virFileMakePath(cfg->saveDir) < 0) { + virReportSystemError(errno, _("Failed to create save dir %s"), + cfg->saveDir); + goto error; + } + if (virFileMakePath(cfg->snapshotDir) < 0) { + virReportSystemError(errno, _("Failed to create save dir %s"), + cfg->snapshotDir); + goto error; + } + if (virFileMakePath(cfg->autoDumpPath) < 0) { + virReportSystemError(errno, _("Failed to create dump dir %s"), + cfg->autoDumpPath); + goto error; + } + if (virFileMakePath(cfg->channelTargetDir) < 0) { + virReportSystemError(errno, _("Failed to create channel target dir= %s"), + cfg->channelTargetDir); + goto error; + } + if (virFileMakePath(cfg->nvramDir) < 0) { + virReportSystemError(errno, _("Failed to create nvram dir %s"), + cfg->nvramDir); + goto error; + } + if (virFileMakePath(cfg->memoryBackingDir) < 0) { + virReportSystemError(errno, _("Failed to create memory backing dir= %s"), + cfg->memoryBackingDir); + goto error; + } + + driver->qemuImgBinary =3D virFindFileInPath("qemu-img"); + + if (!(driver->lockManager =3D + virLockManagerPluginNew(cfg->lockManagerName ? + cfg->lockManagerName : "nop", + "qemu", + cfg->configBaseDir, + 0))) + goto error; + + if (cfg->macFilter) { + if (!(driver->ebtables =3D ebtablesContextNew("qemu"))) { + virReportSystemError(errno, + _("failed to enable mac filter in '%s'"), + __FILE__); + goto error; + } + + if (ebtablesAddForwardPolicyReject(driver->ebtables) < 0) + goto error; + } + + /* Allocate bitmap for remote display port reservations. We cannot + * do this before the config is loaded properly, since the port + * numbers are configurable now */ + if ((driver->remotePorts =3D + virPortAllocatorNew(_("display"), + cfg->remotePortMin, + cfg->remotePortMax, + 0)) =3D=3D NULL) + goto error; + + if ((driver->webSocketPorts =3D + virPortAllocatorNew(_("webSocket"), + cfg->webSocketPortMin, + cfg->webSocketPortMax, + 0)) =3D=3D NULL) + goto error; + + if ((driver->migrationPorts =3D + virPortAllocatorNew(_("migration"), + cfg->migrationPortMin, + cfg->migrationPortMax, + 0)) =3D=3D NULL) + goto error; + + if (qemuSecurityInit(driver) < 0) + goto error; + + if (!(driver->hostdevMgr =3D virHostdevManagerGetDefault())) + goto error; + + if (!(driver->sharedDevices =3D virHashCreate(30, qemuSharedDeviceEntr= yFree))) + goto error; + + if (privileged) { + char *channeldir; + + if (chown(cfg->libDir, cfg->user, cfg->group) < 0) { + virReportSystemError(errno, + _("unable to set ownership of '%s' to use= r %d:%d"), + cfg->libDir, (int) cfg->user, + (int) cfg->group); + goto error; + } + if (chown(cfg->cacheDir, cfg->user, cfg->group) < 0) { + virReportSystemError(errno, + _("unable to set ownership of '%s' to %d:= %d"), + cfg->cacheDir, (int) cfg->user, + (int) cfg->group); + goto error; + } + if (chown(cfg->saveDir, cfg->user, cfg->group) < 0) { + virReportSystemError(errno, + _("unable to set ownership of '%s' to %d:= %d"), + cfg->saveDir, (int) cfg->user, + (int) cfg->group); + goto error; + } + if (chown(cfg->snapshotDir, cfg->user, cfg->group) < 0) { + virReportSystemError(errno, + _("unable to set ownership of '%s' to %d:= %d"), + cfg->snapshotDir, (int) cfg->user, + (int) cfg->group); + goto error; + } + if (chown(cfg->autoDumpPath, cfg->user, cfg->group) < 0) { + virReportSystemError(errno, + _("unable to set ownership of '%s' to %d:= %d"), + cfg->autoDumpPath, (int) cfg->user, + (int) cfg->group); + goto error; + } + if (!(channeldir =3D mdir_name(cfg->channelTargetDir))) { + virReportOOMError(); + goto error; + } + if (chown(channeldir, cfg->user, cfg->group) < 0) { + virReportSystemError(errno, + _("unable to set ownership of '%s' to %d:= %d"), + channeldir, (int) cfg->user, + (int) cfg->group); + VIR_FREE(channeldir); + goto error; + } + VIR_FREE(channeldir); + if (chown(cfg->channelTargetDir, cfg->user, cfg->group) < 0) { + virReportSystemError(errno, + _("unable to set ownership of '%s' to %d:= %d"), + cfg->channelTargetDir, (int) cfg->user, + (int) cfg->group); + goto error; + } + if (chown(cfg->nvramDir, cfg->user, cfg->group) < 0) { + virReportSystemError(errno, + _("unable to set ownership of '%s' to %d:= %d"), + cfg->nvramDir, (int) cfg->user, + (int) cfg->group); + goto error; + } + if (chown(cfg->memoryBackingDir, cfg->user, cfg->group) < 0) { + virReportSystemError(errno, + _("unable to set ownership of '%s' to %d:= %d"), + cfg->memoryBackingDir, (int) cfg->user, + (int) cfg->group); + goto error; + } + + run_uid =3D cfg->user; + run_gid =3D cfg->group; + } + + driver->qemuCapsCache =3D virQEMUCapsCacheNew(cfg->libDir, + cfg->cacheDir, + run_uid, + run_gid); + if (!driver->qemuCapsCache) + goto error; + + if ((driver->caps =3D virQEMUDriverCreateCapabilities(driver)) =3D=3D = NULL) + goto error; + + if (!(driver->xmlopt =3D virQEMUDriverCreateXMLConf(driver))) + goto error; + + /* If hugetlbfs is present, then we need to create a sub-directory wit= hin + * it, since we can't assume the root mount point has permissions that + * will let our spawned QEMU instances use it. */ + for (i =3D 0; i < cfg->nhugetlbfs; i++) { + hugepagePath =3D qemuGetBaseHugepagePath(&cfg->hugetlbfs[i]); + + if (!hugepagePath) + goto error; + + if (virFileMakePath(hugepagePath) < 0) { + virReportSystemError(errno, + _("unable to create hugepage path %s"), + hugepagePath); + goto error; + } + if (privileged && + virFileUpdatePerm(cfg->hugetlbfs[i].mnt_dir, + 0, S_IXGRP | S_IXOTH) < 0) + goto error; + VIR_FREE(hugepagePath); + } + + if (qemuGetMemoryBackingBasePath(cfg, &memoryBackingPath) < 0) + goto error; + + if (virFileMakePath(memoryBackingPath) < 0) { + virReportSystemError(errno, + _("unable to create memory backing path %s"), + memoryBackingPath); + goto error; + } + + if (privileged && + virFileUpdatePerm(memoryBackingPath, + 0, S_IXGRP | S_IXOTH) < 0) + goto error; + VIR_FREE(memoryBackingPath); + + if (!(driver->closeCallbacks =3D virCloseCallbacksNew())) + goto error; + + return driver; + + error: + virObjectUnref(conn); + VIR_FREE(driverConf); + VIR_FREE(hugepagePath); + VIR_FREE(memoryBackingPath); + virQEMUControllerDriverFree(driver); + return NULL; +} + +static void show_help(FILE *io) +{ + fprintf(io, "\n"); + fprintf(io, "syntax: %s [OPTIONS] PATH-TO-XML\n", argv0); + fprintf(io, "\n"); + fprintf(io, "Options\n"); + fprintf(io, "\n"); + fprintf(io, " -c URI, --connect URI\n"); + fprintf(io, " -h, --help\n"); + fprintf(io, "\n"); +} + +static void +virQEMUControllerMain(void *opaque) +{ + int ret =3D -1; + virQEMUControllerPtr ctrl =3D opaque; + virQEMUDriverConfigPtr cfg; + virDomainChrSourceDef monitor_chr =3D { 0 }; + qemuDomainObjPrivatePtr priv; + virDomainPtr dom; + + if (!(ctrl->conn =3D virConnectOpen(ctrl->uri))) { + fprintf(stderr, "Unable to connect to %s: %s", + ctrl->uri, virGetLastErrorMessage()); + goto cleanup; + } + + if (!(ctrl->driver =3D virQEMUControllerNewDriver(ctrl->privileged))) { + fprintf(stderr, "Unable to initialize driver: %s", + virGetLastErrorMessage()); + goto cleanup; + } + + cfg =3D virObjectRef(ctrl->driver->config); + + if (qemuProcessPrepareMonitorChr(&monitor_chr, cfg->libDir) < 0) { + fprintf(stderr, "Unable to prepare QEMU monitor: %s\n", + virGetLastErrorMessage()); + goto cleanup; + } + + if (!(ctrl->vm =3D virDomainObjNew(ctrl->driver->xmlopt))) { + fprintf(stderr, "Unable to allocate domain object: %s\n", + virGetLastErrorMessage()); + goto cleanup; + } + + if (!(ctrl->vm->def =3D virDomainDefParseFile(ctrl->xml, + ctrl->driver->caps, ctrl->= driver->xmlopt, + NULL, VIR_DOMAIN_DEF_PARSE= _INACTIVE))) { + fprintf(stderr, "Unable to parse domain config %s\n", + virGetLastErrorMessage()); + goto cleanup; + } + + if (qemuProcessStart(NULL, ctrl->driver, ctrl->vm, NULL, 0, NULL, -1, = NULL, NULL, 0, 0) < 0) { + fprintf(stderr, "Unable to start QEMU: %s\n", + virGetLastErrorMessage()); + goto cleanup; + } + + priv =3D ctrl->vm->privateData; + + /* Release the monitor & agent sockets, so main libvirtd can take over= */ + qemuMonitorClose(priv->mon); + if (priv->agent) + qemuAgentClose(priv->agent); + + dom =3D virDomainQemuReconnect(ctrl->conn, ctrl->vm->def->name, 0); + if (!dom) { + qemuProcessStop(ctrl->driver, ctrl->vm, 0, 0, 0); + fprintf(stderr, "Unable to reconnect with libvirtd: %s\n", + virGetLastErrorMessage()); + goto cleanup; + } + + virObjectUnref(dom); + + fprintf(stderr, "QEMU running and connected\n"); + ret =3D 0; + cleanup: + virConnectClose(ctrl->conn); + if (ret < 0) + exit(EXIT_FAILURE); +} + +int main(int argc, char **argv) +{ + int rc =3D 1; + virThread thr; + virQEMUControllerPtr ctrl; + const struct option options[] =3D { + { "connect", 1, NULL, 'c' }, + { "help", 0, NULL, 'h' }, + { 0, 0, 0, 0 }, + }; + + argv0 =3D argv[0]; + + if (virGettextInitialize() < 0 || + virThreadInitialize() < 0 || + virErrorInitialize() < 0) { + fprintf(stderr, _("%s: initialization failed\n"), argv0); + exit(EXIT_FAILURE); + } + + /* Initialize logging */ + virLogSetFromEnv(); + + virUpdateSelfLastChanged(argv[0]); + + virFileActivateDirOverride(argv[0]); + + if (VIR_ALLOC(ctrl) < 0) + goto cleanup; + + ctrl->privileged =3D geteuid() =3D=3D 0; + ctrl->uri =3D ctrl->privileged ? "qemu:///system" : "qemu:///session"; + + while (1) { + int c; + + c =3D getopt_long(argc, argv, "c:h", + options, NULL); + + if (c =3D=3D -1) + break; + + switch (c) { + case 'c': + ctrl->uri =3D optarg; + break; + + case 'h': + case '?': + show_help(stdout); + rc =3D 0; + goto cleanup; + } + } + + ctrl->xml =3D argv[optind]; + + if (ctrl->xml =3D=3D NULL) { + fprintf(stderr, "Missing XML file path\n"); + show_help(stderr); + goto cleanup; + } + + if (virEventRegisterDefaultImpl() < 0) { + fprintf(stderr, "Unable to initialize events: %s", + virGetLastErrorMessage()); + goto cleanup; + } + + if (virThreadCreate(&thr, false, virQEMUControllerMain, ctrl) < 0) + goto cleanup; + + for (;;) + virEventRunDefaultImpl(); + + rc =3D 0; + + cleanup: + virStateCleanup(); + if (ctrl->conn) + virConnectClose(ctrl->conn); + virObjectUnref(ctrl->vm); + VIR_FREE(ctrl); + return rc; +} diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index 74b82450b4..8c8e9891c8 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -262,7 +262,7 @@ qemuDomainDisableNamespace(virDomainObjPtr vm, void qemuDomainEventQueue(virQEMUDriverPtr driver, virObjectEventPtr event) { - if (event) + if (event && driver->domainEventState) virObjectEventStateQueue(driver->domainEventState, event); } =20 diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index fea1f24250..a7252ea913 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -371,7 +371,7 @@ qemuSecurityChownCallback(const virStorageSource *src, } =20 =20 -static int +int qemuSecurityInit(virQEMUDriverPtr driver) { char **names; --=20 2.14.3 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list