From nobody Tue Feb 10 11:55:40 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of redhat.com designates 170.10.129.124 as permitted sender) client-ip=170.10.129.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.129.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=1674252284; cv=none; d=zohomail.com; s=zohoarc; b=CMt4j/mcwkqYldlaQ3h/rLcm69nWDJEMMkYF/vpvVSa9FGdhA3XOm/TQN6YT099+fiQTV9H7fjbJfSJ66H/hpGu1FLTT6ERR44FMoqKT5v8vkJd/R/vGDtjpJRlxBpQZ8Z5Da1V4TQk0SoK2lQ8d8c63AN9AHL/2w+IghHqtCbQ= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1674252284; h=Content-Type:Content-Transfer-Encoding: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=Gire2gEybJL7fm7wOIJodipCyzwlDP2f9F4j/DpqdVU=; b=iDS9xGuPCPmjZUIGC7fQhrXMs1GdGaWKfGId7+qcqbRzbQcFurnnToAj468XgH3LiXFMnv7mpD4MAWAqI/rmmkLC8Ywn+Pf9vododga1xzNhX2072u/L1xzwEv/xUrvSMSdsYEYpSerPT6s87G16g48e02XUwG9YJKtJPbxuZzQ= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of redhat.com designates 170.10.129.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.129.124]) by mx.zohomail.com with SMTPS id 1674252283888339.6333698446816; Fri, 20 Jan 2023 14:04:43 -0800 (PST) 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-241-KkAx2G9EOZCLx6kJIwRSrA-1; Fri, 20 Jan 2023 17:04:40 -0500 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.rdu2.redhat.com [10.11.54.1]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id C7BC281B551; Fri, 20 Jan 2023 22:03: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 B065440AE1EF; Fri, 20 Jan 2023 22:03:32 +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 7F3131946A76; Fri, 20 Jan 2023 22:03:32 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.rdu2.redhat.com [10.11.54.7]) by mm-prod-listman-01.mail-001.prod.us-east-1.aws.redhat.com (Postfix) with ESMTP id 1D02E1946A6D for ; Fri, 20 Jan 2023 22:03:30 +0000 (UTC) Received: by smtp.corp.redhat.com (Postfix) id 0074914171C8; Fri, 20 Jan 2023 22:03:30 +0000 (UTC) Received: from himantopus.redhat.com (unknown [10.22.18.185]) by smtp.corp.redhat.com (Postfix) with ESMTPS id D1AEF140EBF6 for ; Fri, 20 Jan 2023 22:03:29 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1674252282; h=from:from:sender:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to: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=Gire2gEybJL7fm7wOIJodipCyzwlDP2f9F4j/DpqdVU=; b=ZxjYS6aRQ5ORHJQo9nfT+n0RoRrnqUcq96rYPlzIXTEQGu+LmvO4TyErE/U4Zf/CollcyO av+YHDnyt/RgYr9B/UaE+GZDSEJBFBtYlNTyEzP+22GVsM5EYVZqv4jpdSYAw28R0tVPTi Z7HsqO57SfP7SfWGoIqRCTdg42Aa1CY= X-MC-Unique: KkAx2G9EOZCLx6kJIwRSrA-1 X-Original-To: libvir-list@listman.corp.redhat.com From: Jonathon Jongsma To: libvir-list@redhat.com Subject: [libvirt PATCH v4 18/31] qemu: include nbdkit state in private xml Date: Fri, 20 Jan 2023 16:03:12 -0600 Message-Id: <20230120220325.1015090-19-jjongsma@redhat.com> In-Reply-To: <20230120220325.1015090-1-jjongsma@redhat.com> References: <20230120220325.1015090-1-jjongsma@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.1 on 10.11.54.7 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: , Errors-To: libvir-list-bounces@redhat.com Sender: "libvir-list" X-Scanned-By: MIMEDefang 3.1 on 10.11.54.1 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: 1674252286040100001 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 --- src/qemu/qemu_domain.c | 48 ++++++++++++++ src/qemu/qemu_nbdkit.c | 77 +++++++++++++++++++++++ src/qemu/qemu_nbdkit.h | 8 +++ src/qemu/qemu_process.c | 11 ++++ tests/qemustatusxml2xmldata/modern-in.xml | 4 ++ 5 files changed, 148 insertions(+) diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index 0e3eaf49f8..28d4bddf14 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -1911,6 +1911,29 @@ 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))) + return -1; + + if (!(socketfile =3D virXPathString("string(./socketfile)", ctxt))) + return -1; + + qemuNbdkitReconnectStorageSource(src, pidfile, socketfile); + + return 0; +} + + static int qemuStorageSourcePrivateDataParse(xmlXPathContextPtr ctxt, virStorageSource *src) @@ -1921,6 +1944,7 @@ qemuStorageSourcePrivateDataParse(xmlXPathContextPtr = ctxt, g_autofree char *httpcookiealias =3D NULL; g_autofree char *tlskeyalias =3D NULL; g_autofree char *thresholdEventWithIndex =3D NULL; + 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); @@ -1964,6 +1988,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 @@ -1981,6 +2009,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) @@ -2019,6 +2064,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 00ca945904..2b26e9bc08 100644 --- a/src/qemu/qemu_nbdkit.c +++ b/src/qemu/qemu_nbdkit.c @@ -627,6 +627,83 @@ 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 int +qemuNbdkitStorageSourceManageProcessOne(virStorageSource *source) +{ + qemuDomainStorageSourcePrivate *srcpriv =3D QEMU_DOMAIN_STORAGE_SOURCE= _PRIVATE(source); + qemuNbdkitProcess *proc; + + if (!srcpriv) + return 0; + + proc =3D srcpriv->nbdkitProcess; + + if (proc) { + if (proc->pid <=3D 0) { + if (virPidFileReadPath(proc->pidfile, &proc->pid) < 0) + return -1; + } + + if (virProcessKill(proc->pid, 0) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("nbdkit process %i is not alive"), proc->pid); + return -1; + } + } + + return 0; +} + +/** + * 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. + */ +int +qemuNbdkitStorageSourceManageProcess(virStorageSource *source) +{ + virStorageSource *backing; + for (backing =3D source->backingStore; backing !=3D NULL; backing =3D = backing->backingStore) { + if (qemuNbdkitStorageSourceManageProcessOne(backing) < 0) + return -1; + } + + return qemuNbdkitStorageSourceManageProcessOne(source); +} + =20 bool qemuNbdkitInitStorageSource(qemuNbdkitCaps *caps, diff --git a/src/qemu/qemu_nbdkit.h b/src/qemu/qemu_nbdkit.h index ccd418b7d3..2be46b6002 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); + +int +qemuNbdkitStorageSourceManageProcess(virStorageSource *src); + bool qemuNbdkitCapsGet(qemuNbdkitCaps *nbdkitCaps, qemuNbdkitCapsFlags flag); diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index 6d1751b5d7..7ec31ef6ac 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -9047,6 +9047,17 @@ qemuProcessReconnect(void *opaque) } } =20 + for (i =3D 0; i < obj->def->ndisks; i++) { + virDomainDiskDef *disk =3D obj->def->disks[i]; + if (qemuNbdkitStorageSourceManageProcess(disk->src) < 0) + goto error; + } + + if (obj->def->os.loader && obj->def->os.loader->nvram) { + if (qemuNbdkitStorageSourceManageProcess(obj->def->os.loader->nvra= m) < 0) + goto error; + } + /* 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 7759034f7a..71b3eb4736 100644 --- a/tests/qemustatusxml2xmldata/modern-in.xml +++ b/tests/qemustatusxml2xmldata/modern-in.xml @@ -342,6 +342,10 @@ + + /path/to/nbdkit.pid + /path/to/nbdkit.socket + --=20 2.39.0