From nobody Mon Feb 9 16:51:12 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of redhat.com designates 170.10.133.124 as permitted sender) client-ip=170.10.133.124; envelope-from=libvir-list-bounces@redhat.com; helo=us-smtp-delivery-124.mimecast.com; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of redhat.com designates 170.10.133.124 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=1689891656; cv=none; d=zohomail.com; s=zohoarc; b=gMYSdahaOW5jL3Z6enXI/cdyyFcwYRefOPBG9UR0w3/GsfNCLole/KT3iHVQHXQOdn2QATZzPX3G/nwADnoLPIJNSdjWneN721pQIIutfNqTY5/1cTZJlOtFQNFFRntBPIpnvChWBsPcqoeMur8ZXNI0f5jOzWpK7qetsc0jyI4= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1689891656; 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; bh=eEad6bBFDVkfr36w5Fr8oys7GudYGDIRZPa6kaina9U=; b=VlO3AERNwq9T24j71UwQXI3sjmZaGqBtxjUiBBmTcqo/qlNG8ZbUVvlMUWgF4/fb3OvRI7EWIwZq7Au4ANCB+mjlgHF1jDBC7gK2xc7osmzvfvk6kVqJofxSGnRqszs/8ugS80KjINOfjL8W0WdDPKq4XcppTY3mrDFZBsSs6yg= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of redhat.com designates 170.10.133.124 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by mx.zohomail.com with SMTPS id 1689891656055216.86508811789554; Thu, 20 Jul 2023 15:20:56 -0700 (PDT) Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-410-r5LrtSMVNa6B9h2UrjpXqw-1; Thu, 20 Jul 2023 18:20:44 -0400 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.rdu2.redhat.com [10.11.54.4]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 02BA1830DAC; Thu, 20 Jul 2023 22:20:32 +0000 (UTC) Received: from mm-prod-listman-01.mail-001.prod.us-east-1.aws.redhat.com (unknown [10.30.29.100]) by smtp.corp.redhat.com (Postfix) with ESMTP id DEC6B207B315; Thu, 20 Jul 2023 22:20:31 +0000 (UTC) Received: from mm-prod-listman-01.mail-001.prod.us-east-1.aws.redhat.com (localhost [IPv6:::1]) by mm-prod-listman-01.mail-001.prod.us-east-1.aws.redhat.com (Postfix) with ESMTP id 8B62C194F4AF; Thu, 20 Jul 2023 22:20:19 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.rdu2.redhat.com [10.11.54.1]) by mm-prod-listman-01.mail-001.prod.us-east-1.aws.redhat.com (Postfix) with ESMTP id A417C19452CC for ; Thu, 20 Jul 2023 22:20:14 +0000 (UTC) Received: by smtp.corp.redhat.com (Postfix) id 1286C40C2007; Thu, 20 Jul 2023 22:20:09 +0000 (UTC) Received: from himantopus.redhat.com (unknown [10.22.8.155]) by smtp.corp.redhat.com (Postfix) with ESMTPS id DBA1340C207D; Thu, 20 Jul 2023 22:20:08 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1689891655; h=from:from:sender:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references:list-id:list-help: list-unsubscribe:list-subscribe:list-post; bh=eEad6bBFDVkfr36w5Fr8oys7GudYGDIRZPa6kaina9U=; b=L0G2yM9op2yfOQHPYekAoAEcaxmbm5D1aQURobGC6AykZW8+sWcarghAwzCf9i7/qRptSW 4AC8ZVM4KjnUfUyv+1O0Ji8vLcuGjvEMuejhxSqfTOck1cQLwHu7ywnXb5OQ7wOfk3ciKI 5Xo76ylxFR1/clf7aqiqZfMX4s9zuGA= X-MC-Unique: r5LrtSMVNa6B9h2UrjpXqw-1 X-Original-To: libvir-list@listman.corp.redhat.com From: Jonathon Jongsma To: libvir-list@redhat.com Subject: [libvirt PATCH v6 18/36] qemu: include nbdkit state in private xml Date: Thu, 20 Jul 2023 17:19:45 -0500 Message-ID: <20230720222003.411549-19-jjongsma@redhat.com> In-Reply-To: <20230720222003.411549-1-jjongsma@redhat.com> References: <20230720222003.411549-1-jjongsma@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.1 on 10.11.54.1 X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.29 Precedence: list List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Peter Krempa Errors-To: libvir-list-bounces@redhat.com Sender: "libvir-list" X-Scanned-By: MIMEDefang 3.1 on 10.11.54.4 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @redhat.com) X-ZM-MESSAGEID: 1689891656443100009 Content-Type: text/plain; charset="utf-8"; x-default="true" Add xml to the private data for a disk source to represent the nbdkit process so that the state can be re-created if the libvirt daemon is restarted. Format: /path/to/nbdkit.pid /path/to/nbdkit.socket Signed-off-by: Jonathon Jongsma Reviewed-by: Peter Krempa --- src/qemu/qemu_domain.c | 52 +++++++++++++++++ src/qemu/qemu_nbdkit.c | 71 +++++++++++++++++++++++ src/qemu/qemu_nbdkit.h | 8 +++ src/qemu/qemu_process.c | 6 ++ tests/qemustatusxml2xmldata/modern-in.xml | 4 ++ 5 files changed, 141 insertions(+) diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index 1da33debda..d2db388622 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -1958,6 +1958,33 @@ qemuStorageSourcePrivateDataAssignSecinfo(qemuDomain= SecretInfo **secinfo, } =20 =20 +static int +qemuStorageSourcePrivateDataParseNbdkit(xmlNodePtr node, + xmlXPathContextPtr ctxt, + virStorageSource *src) +{ + g_autofree char *pidfile =3D NULL; + g_autofree char *socketfile =3D NULL; + VIR_XPATH_NODE_AUTORESTORE(ctxt); + + ctxt->node =3D node; + + if (!(pidfile =3D virXPathString("string(./pidfile)", ctxt))) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("missing nbdkit pid= file")); + return -1; + } + + if (!(socketfile =3D virXPathString("string(./socketfile)", ctxt))) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("missing nbdkit soc= ketfile")); + return -1; + } + + qemuNbdkitReconnectStorageSource(src, pidfile, socketfile); + + return 0; +} + + static int qemuStorageSourcePrivateDataParse(xmlXPathContextPtr ctxt, virStorageSource *src) @@ -1971,6 +1998,7 @@ qemuStorageSourcePrivateDataParse(xmlXPathContextPtr = ctxt, bool fdsetPresent =3D false; unsigned int fdSetID; int enccount; + xmlNodePtr nbdkitnode =3D NULL; =20 src->nodestorage =3D virXPathString("string(./nodenames/nodename[@type= =3D'storage']/@name)", ctxt); src->nodeformat =3D virXPathString("string(./nodenames/nodename[@type= =3D'format']/@name)", ctxt); @@ -2036,6 +2064,10 @@ qemuStorageSourcePrivateDataParse(xmlXPathContextPtr= ctxt, virTristateBoolTypeFromString(thresholdEventWithIndex) =3D=3D VIR_= TRISTATE_BOOL_YES) src->thresholdEventWithIndex =3D true; =20 + if ((nbdkitnode =3D virXPathNode("nbdkit", ctxt))) { + if (qemuStorageSourcePrivateDataParseNbdkit(nbdkitnode, ctxt, src)= < 0) + return -1; + } return 0; } =20 @@ -2053,6 +2085,23 @@ qemuStorageSourcePrivateDataFormatSecinfo(virBuffer = *buf, } =20 =20 +static void +qemuStorageSourcePrivateDataFormatNbdkit(qemuNbdkitProcess *nbdkit, + virBuffer *buf) +{ + g_auto(virBuffer) childBuf =3D VIR_BUFFER_INIT_CHILD(buf); + + if (!nbdkit) + return; + + virBufferEscapeString(&childBuf, "%s\n", + nbdkit->pidfile); + virBufferEscapeString(&childBuf, "%s\n", + nbdkit->socketfile); + virXMLFormatElement(buf, "nbdkit", NULL, &childBuf); +} + + static int qemuStorageSourcePrivateDataFormat(virStorageSource *src, virBuffer *buf) @@ -2102,6 +2151,9 @@ qemuStorageSourcePrivateDataFormat(virStorageSource *= src, if (src->thresholdEventWithIndex) virBufferAddLit(buf, "\n"); =20 + if (srcPriv) + qemuStorageSourcePrivateDataFormatNbdkit(srcPriv->nbdkitProcess, b= uf); + return 0; } =20 diff --git a/src/qemu/qemu_nbdkit.c b/src/qemu/qemu_nbdkit.c index a8988778ac..5539b54e8c 100644 --- a/src/qemu/qemu_nbdkit.c +++ b/src/qemu/qemu_nbdkit.c @@ -628,6 +628,77 @@ qemuNbdkitProcessNew(virStorageSource *source, return nbdkit; } =20 +/** + * qemuNbdkitReconnectStorageSource: + * @source: a storage source + * @pidfile: a pidfile for an nbdkit process + * @socketfile: the socket file associated with the nbdkit process + * + * This function constructs a new qemuNbdkitProcess object with the given = values for @pidfile and + * @socketfile and stores it in @source. This is intended to be called whe= n the libvirt daemon is + * restarted and tries to reconnect to all currently-running domains. Sinc= e this function is called + * from the code that parses the current daemon state, it should not perfo= rm any filesystem + * operations, or anything else that might fail. Additional initialization= will be done later by + * calling qemuNbdkitStorageSourceManageProcess(). + */ +void +qemuNbdkitReconnectStorageSource(virStorageSource *source, + const char *pidfile, + const char *socketfile) +{ + qemuDomainStorageSourcePrivate *srcpriv =3D qemuDomainStorageSourcePri= vateFetch(source); + + if (srcpriv->nbdkitProcess) { + VIR_WARN("source already has an nbdkit process"); + return; + } + + srcpriv->nbdkitProcess =3D qemuNbdkitProcessNew(source, pidfile, socke= tfile); +} + + +static void +qemuNbdkitStorageSourceManageProcessOne(virStorageSource *source) +{ + qemuDomainStorageSourcePrivate *srcpriv =3D QEMU_DOMAIN_STORAGE_SOURCE= _PRIVATE(source); + qemuNbdkitProcess *proc; + + if (!srcpriv) + return; + + proc =3D srcpriv->nbdkitProcess; + + if (!proc) + return; + + if (proc->pid <=3D 0) { + if (virPidFileReadPath(proc->pidfile, &proc->pid) < 0) { + VIR_WARN("Unable to read pidfile '%s'", proc->pidfile); + return; + } + } + + if (virProcessKill(proc->pid, 0) < 0) + VIR_WARN("nbdkit process %i is not alive", proc->pid); +} + +/** + * qemuNbdkitStorageSourceManageProcess: + * @source: a storage source + * @vm: the vm that owns this storage source + * + * This function re-enables monitoring of any nbdkit processes associated = with the backing chain of + * @source. It is intended to be called after libvirt restarts and has loa= ded its current state from + * disk and is attempting to re-connect to active domains. + */ +void +qemuNbdkitStorageSourceManageProcess(virStorageSource *source) +{ + virStorageSource *backing; + for (backing =3D source; backing !=3D NULL; backing =3D backing->backi= ngStore) + qemuNbdkitStorageSourceManageProcessOne(backing); +} + =20 bool qemuNbdkitInitStorageSource(qemuNbdkitCaps *caps, diff --git a/src/qemu/qemu_nbdkit.h b/src/qemu/qemu_nbdkit.h index ccd418b7d3..7e2aeed4eb 100644 --- a/src/qemu/qemu_nbdkit.h +++ b/src/qemu/qemu_nbdkit.h @@ -54,6 +54,14 @@ qemuNbdkitInitStorageSource(qemuNbdkitCaps *nbdkitCaps, uid_t user, gid_t group); =20 +void +qemuNbdkitReconnectStorageSource(virStorageSource *source, + const char *pidfile, + const char *socketfile); + +void +qemuNbdkitStorageSourceManageProcess(virStorageSource *src); + bool qemuNbdkitCapsGet(qemuNbdkitCaps *nbdkitCaps, qemuNbdkitCapsFlags flag); diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index 60a46b4b56..83bc8252fc 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -8989,6 +8989,12 @@ qemuProcessReconnect(void *opaque) } } =20 + for (i =3D 0; i < obj->def->ndisks; i++) + qemuNbdkitStorageSourceManageProcess(obj->def->disks[i]->src); + + if (obj->def->os.loader && obj->def->os.loader->nvram) + qemuNbdkitStorageSourceManageProcess(obj->def->os.loader->nvram); + /* update domain state XML with possibly updated state in virDomainObj= */ if (virDomainObjSave(obj, driver->xmlopt, cfg->stateDir) < 0) goto error; diff --git a/tests/qemustatusxml2xmldata/modern-in.xml b/tests/qemustatusxm= l2xmldata/modern-in.xml index 95fc569029..e139c8d38c 100644 --- a/tests/qemustatusxml2xmldata/modern-in.xml +++ b/tests/qemustatusxml2xmldata/modern-in.xml @@ -345,6 +345,10 @@ + + /path/to/nbdkit.pid + /path/to/nbdkit.socket + --=20 2.41.0