From nobody Mon Feb 9 00:56:15 2026 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; dmarc=pass(p=none dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1562947659; cv=none; d=zoho.com; s=zohoarc; b=N0D6DqTJC1oj4FDDD1a5s8z9TBZuHVf47ep3Qtm5MciqmwbNT5gf9P6g/ZBPdMP/wxvNg7Mhe/JrOylcPGIQFtE9mxIjja8m3Mq0L6BhVBrarwJ4q70q9T1zCub7CRuq4kRCTFrEmbZo0b8r/xtrhzAP04alcAZnXu2xcPntVp0= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1562947659; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To:ARC-Authentication-Results; bh=iXhU7wm70Yj+oXo8W6L4CU3b9PQGPXem0IqUunGQ3L4=; b=CNbGYtOPu0sj2p8uLhUHaTg8mngKwx48Y5cxA9rBBIBXtrIAfZinF9T290hoJn/itD48I1baeqOfjRaa0WY5o9EHliDjImrVzO13Uaa3rBGpaz0I0MeHfaCzTxczuMDzMHeq2Q9n7+zrcSEa7tB6+hL5qsu1TAJgdRKHpMXQpE8= ARC-Authentication-Results: i=1; mx.zoho.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass header.from= (p=none dis=none) header.from= Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 1562947659583560.0772143787682; Fri, 12 Jul 2019 09:07:39 -0700 (PDT) Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id DA2DE3082E56; Fri, 12 Jul 2019 16:07:37 +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 B81265D756; Fri, 12 Jul 2019 16:07:37 +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 47ACD1833002; Fri, 12 Jul 2019 16:07:37 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id x6CG7Wvk017464 for ; Fri, 12 Jul 2019 12:07:33 -0400 Received: by smtp.corp.redhat.com (Postfix) id EFAD660F9B; Fri, 12 Jul 2019 16:07:32 +0000 (UTC) Received: from angien.brq.redhat.com (unknown [10.43.2.229]) by smtp.corp.redhat.com (Postfix) with ESMTP id 42C0C60C73; Fri, 12 Jul 2019 16:07:32 +0000 (UTC) From: Peter Krempa To: libvir-list@redhat.com Date: Fri, 12 Jul 2019 18:06:03 +0200 Message-Id: <7c6a00c7cb9a3a68a6dd529ace9bf87cb8cbdf3e.1562947284.git.pkrempa@redhat.com> In-Reply-To: References: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 X-loop: libvir-list@redhat.com Cc: Peter Krempa Subject: [libvirt] [PATCH 22/25] qemu: blockjob: Track orphaned backing chains in blockjob status XML 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: , 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.15 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.46]); Fri, 12 Jul 2019 16:07:38 +0000 (UTC) Content-Type: text/plain; charset="utf-8" When the guest unplugs the disk frontend libvirt is responsible for deleting the backend. Since a blockjob may still have a reference to the backing chain when it is running we'll have to store the metadata for the unplugged disk for future reference. This patch adds 'chain' and 'mirrorChain' fields to 'qemuBlockJobData' to keep them around with the job along with status XML machinery and tests. Later patches will then add code to change the ownership of the chain when unplugging the disk backend. Signed-off-by: Peter Krempa Reviewed-by: J=C3=A1n Tomko --- src/qemu/qemu_blockjob.c | 5 + src/qemu/qemu_blockjob.h | 2 + src/qemu/qemu_domain.c | 124 ++++++++++++++++-- .../blockjob-blockdev-in.xml | 37 ++++++ 4 files changed, 160 insertions(+), 8 deletions(-) diff --git a/src/qemu/qemu_blockjob.c b/src/qemu/qemu_blockjob.c index 360fc40e61..70b223b29d 100644 --- a/src/qemu/qemu_blockjob.c +++ b/src/qemu/qemu_blockjob.c @@ -61,6 +61,9 @@ qemuBlockJobDataDispose(void *obj) { qemuBlockJobDataPtr job =3D obj; + virObjectUnref(job->chain); + virObjectUnref(job->mirrorChain); + VIR_FREE(job->name); VIR_FREE(job->errmsg); } @@ -116,6 +119,8 @@ qemuBlockJobRegister(qemuBlockJobDataPtr job, if (disk) { job->disk =3D disk; + job->chain =3D virObjectRef(disk->src); + job->mirrorChain =3D virObjectRef(disk->mirror); QEMU_DOMAIN_DISK_PRIVATE(disk)->blockjob =3D virObjectRef(job); } diff --git a/src/qemu/qemu_blockjob.h b/src/qemu/qemu_blockjob.h index 2d8ecdd4c3..d07ab75c8b 100644 --- a/src/qemu/qemu_blockjob.h +++ b/src/qemu/qemu_blockjob.h @@ -75,6 +75,8 @@ struct _qemuBlockJobData { char *name; virDomainDiskDefPtr disk; /* may be NULL, if blockjob does not corresp= ond to any disk */ + virStorageSourcePtr chain; /* Reference to the chain the job operates = on. */ + virStorageSourcePtr mirrorChain; /* reference to 'mirror' part of the = job */ int type; /* qemuBlockJobType */ int state; /* qemuBlockjobState */ diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index 13a90ab60b..48b99e5511 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -2313,22 +2313,59 @@ qemuDomainObjPrivateXMLFormatAutomaticPlacement(vir= BufferPtr buf, } +typedef struct qemuDomainPrivateBlockJobFormatData { + virDomainXMLOptionPtr xmlopt; + virBufferPtr buf; +} qemuDomainPrivateBlockJobFormatData; + + +static int +qemuDomainObjPrivateXMLFormatBlockjobFormatChain(virBufferPtr buf, + const char *chainname, + virStorageSourcePtr src, + virDomainXMLOptionPtr xml= opt) +{ + VIR_AUTOCLEAN(virBuffer) attrBuf =3D VIR_BUFFER_INITIALIZER; + VIR_AUTOCLEAN(virBuffer) childBuf =3D VIR_BUFFER_INITIALIZER; + unsigned int xmlflags =3D VIR_DOMAIN_DEF_FORMAT_STATUS; + + virBufferSetChildIndent(&childBuf, buf); + + virBufferAsprintf(&attrBuf, " type=3D'%s' format=3D'%s'", + virStorageTypeToString(src->type), + virStorageFileFormatTypeToString(src->format)); + + if (virDomainDiskSourceFormat(&childBuf, src, "source", 0, true, xmlfl= ags, xmlopt) < 0) + return -1; + + if (virDomainDiskBackingStoreFormat(&childBuf, src, xmlopt, xmlflags) = < 0) + return -1; + + if (virXMLFormatElement(buf, chainname, &attrBuf, &childBuf) < 0) + return -1; + + return 0; +} + + static int qemuDomainObjPrivateXMLFormatBlockjobIterator(void *payload, const void *name ATTRIBUTE_U= NUSED, - void *data) + void *opaque) { VIR_AUTOCLEAN(virBuffer) attrBuf =3D VIR_BUFFER_INITIALIZER; VIR_AUTOCLEAN(virBuffer) childBuf =3D VIR_BUFFER_INITIALIZER; + VIR_AUTOCLEAN(virBuffer) chainsBuf =3D VIR_BUFFER_INITIALIZER; qemuBlockJobDataPtr job =3D payload; - virBufferPtr buf =3D data; const char *state =3D qemuBlockjobStateTypeToString(job->state); const char *newstate =3D NULL; + struct qemuDomainPrivateBlockJobFormatData *data =3D opaque; if (job->newstate !=3D -1) newstate =3D qemuBlockjobStateTypeToString(job->newstate); - virBufferSetChildIndent(&childBuf, buf); + virBufferSetChildIndent(&childBuf, data->buf); + virBufferSetChildIndent(&chainsBuf, &childBuf); virBufferEscapeString(&attrBuf, " name=3D'%s'", job->name); virBufferEscapeString(&attrBuf, " type=3D'%s'", qemuBlockjobTypeToStri= ng(job->type)); @@ -2336,10 +2373,28 @@ qemuDomainObjPrivateXMLFormatBlockjobIterator(void = *payload, virBufferEscapeString(&attrBuf, " newstate=3D'%s'", newstate); virBufferEscapeString(&childBuf, "%s", job->errmsg); - if (job->disk) + if (job->disk) { virBufferEscapeString(&childBuf, "\n", job->disk= ->dst); + } else { + if (job->chain && + qemuDomainObjPrivateXMLFormatBlockjobFormatChain(&chainsBuf, + "disk", + job->chain, + data->xmlopt)= < 0) + return -1; + + if (job->mirrorChain && + qemuDomainObjPrivateXMLFormatBlockjobFormatChain(&chainsBuf, + "mirror", + job->mirrorCh= ain, + data->xmlopt)= < 0) + return -1; + + if (virXMLFormatElement(&childBuf, "chains", NULL, &chainsBuf) < 0) + return -1; + } - return virXMLFormatElement(buf, "blockjob", &attrBuf, &childBuf); + return virXMLFormatElement(data->buf, "blockjob", &attrBuf, &childBuf); } @@ -2351,6 +2406,8 @@ qemuDomainObjPrivateXMLFormatBlockjobs(virBufferPtr b= uf, VIR_AUTOCLEAN(virBuffer) attrBuf =3D VIR_BUFFER_INITIALIZER; VIR_AUTOCLEAN(virBuffer) childBuf =3D VIR_BUFFER_INITIALIZER; bool bj =3D qemuDomainHasBlockjob(vm, false); + struct qemuDomainPrivateBlockJobFormatData iterdata =3D { priv->driver= ->xmlopt, + &childBuf }; virBufferAsprintf(&attrBuf, " active=3D'%s'", virTristateBoolTypeToString(virTristateBoolFromBool(= bj))); @@ -2360,7 +2417,7 @@ qemuDomainObjPrivateXMLFormatBlockjobs(virBufferPtr b= uf, if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_BLOCKDEV) && virHashForEach(priv->blockjobs, qemuDomainObjPrivateXMLFormatBlockjobIterator, - &childBuf) < 0) + &iterdata) < 0) return -1; return virXMLFormatElement(buf, "blockjobs", &attrBuf, &childBuf); @@ -2702,10 +2759,49 @@ qemuDomainObjPrivateXMLParseAutomaticPlacement(xmlX= PathContextPtr ctxt, } +static virStorageSourcePtr +qemuDomainObjPrivateXMLParseBlockjobChain(xmlNodePtr node, + xmlXPathContextPtr ctxt, + virDomainXMLOptionPtr xmlopt) + +{ + VIR_XPATH_NODE_AUTORESTORE(ctxt); + VIR_AUTOFREE(char *) format =3D NULL; + VIR_AUTOFREE(char *) type =3D NULL; + VIR_AUTOFREE(char *) index =3D NULL; + VIR_AUTOUNREF(virStorageSourcePtr) src =3D NULL; + xmlNodePtr sourceNode; + unsigned int xmlflags =3D VIR_DOMAIN_DEF_PARSE_STATUS; + + ctxt->node =3D node; + + if (!(type =3D virXMLPropString(ctxt->node, "type")) || + !(format =3D virXMLPropString(ctxt->node, "format")) || + !(index =3D virXPathString("string(./source/@index)", ctxt)) || + !(sourceNode =3D virXPathNode("./source", ctxt))) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("missing job chain data")); + return NULL; + } + + if (!(src =3D virDomainStorageSourceParseBase(type, format, index))) + return NULL; + + if (virDomainStorageSourceParse(sourceNode, ctxt, src, xmlflags, xmlop= t) < 0) + return NULL; + + if (virDomainDiskBackingStoreParse(ctxt, src, xmlflags, xmlopt) < 0) + return NULL; + + VIR_RETURN_PTR(src); +} + + static int qemuDomainObjPrivateXMLParseBlockjobData(virDomainObjPtr vm, xmlNodePtr node, - xmlXPathContextPtr ctxt) + xmlXPathContextPtr ctxt, + virDomainXMLOptionPtr xmlopt) { VIR_XPATH_NODE_AUTORESTORE(ctxt); virDomainDiskDefPtr disk =3D NULL; @@ -2719,6 +2815,7 @@ qemuDomainObjPrivateXMLParseBlockjobData(virDomainObj= Ptr vm, VIR_AUTOFREE(char *) newstatestr =3D NULL; int newstate =3D -1; bool invalidData =3D false; + xmlNodePtr tmp; ctxt->node =3D node; @@ -2750,6 +2847,16 @@ qemuDomainObjPrivateXMLParseBlockjobData(virDomainOb= jPtr vm, !(disk =3D virDomainDiskByName(vm->def, diskdst, false))) invalidData =3D true; + if (!disk && !invalidData) { + if ((tmp =3D virXPathNode("./chains/disk", ctxt)) && + !(job->chain =3D qemuDomainObjPrivateXMLParseBlockjobChain(tmp= , ctxt, xmlopt))) + invalidData =3D true; + + if ((tmp =3D virXPathNode("./chains/mirror", ctxt)) && + !(job->mirrorChain =3D qemuDomainObjPrivateXMLParseBlockjobCha= in(tmp, ctxt, xmlopt))) + invalidData =3D true; + } + job->state =3D state; job->newstate =3D newstate; job->errmsg =3D virXPathString("string(./errmsg)", ctxt); @@ -2782,7 +2889,8 @@ qemuDomainObjPrivateXMLParseBlockjobs(virDomainObjPtr= vm, return -1; for (i =3D 0; i < nnodes; i++) { - if (qemuDomainObjPrivateXMLParseBlockjobData(vm, nodes[i], ctx= t) < 0) + if (qemuDomainObjPrivateXMLParseBlockjobData(vm, nodes[i], ctx= t, + priv->driver->xml= opt) < 0) return -1; } } diff --git a/tests/qemustatusxml2xmldata/blockjob-blockdev-in.xml b/tests/q= emustatusxml2xmldata/blockjob-blockdev-in.xml index 115eaa4887..538385000c 100644 --- a/tests/qemustatusxml2xmldata/blockjob-blockdev-in.xml +++ b/tests/qemustatusxml2xmldata/blockjob-blockdev-in.xml @@ -239,6 +239,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + copy --=20 2.21.0 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list