From nobody Fri Nov 14 22:14:41 2025 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=quarantine dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1759862206; cv=none; d=zohomail.com; s=zohoarc; b=KWZbUSAEUVLtBgulCqxADFirSEb/8OhEEIKdjrapDBtvRp0jO2wsH/IacsbiaTZwmlRIi1YlWWoT+TTO0Pw0WHYIU5iNx5im8G6Dk/xZzZYpT+FrBBHOOcxCr8gSxGLd1K2KSM0mz++B4WZYLdy43NC932NwRu7GG6w65ObL7jU= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1759862206; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=S5jrEUwy0EJFOIS/WkiXiOdV2GbJ0vVIS71974BPMO4=; b=nTxNdDFkfxIbmRVnCtWLOpilR9oCYhsZXfte5no6igGGXpkveMoRFosf9u32t6hPCNQu4f4S6U5sx5EzrWVZB+/3awGNr7a/aVvkTg88M5nlyrdDj2uhVfTJGkQ1d/cmFbZmPNZxmp00QC+flsjrO33XPibARTXEOp103fyF5eU= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1759862206918548.9607318059794; Tue, 7 Oct 2025 11:36:46 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1v6CXH-0005yA-DI; Tue, 07 Oct 2025 14:35:43 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1v6CWc-0005i4-U0 for qemu-devel@nongnu.org; Tue, 07 Oct 2025 14:35:04 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1v6CWZ-0002dn-8f for qemu-devel@nongnu.org; Tue, 07 Oct 2025 14:35:02 -0400 Received: from mx-prod-mc-04.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-488-cGa3z8MZMO6wSBDr6FUhlQ-1; Tue, 07 Oct 2025 14:34:54 -0400 Received: from mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.93]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-04.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 38A3E19560AF; Tue, 7 Oct 2025 18:34:53 +0000 (UTC) Received: from localhost (unknown [10.2.16.87]) by mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 93D811800446; Tue, 7 Oct 2025 18:34:52 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1759862097; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=S5jrEUwy0EJFOIS/WkiXiOdV2GbJ0vVIS71974BPMO4=; b=OQKDe+fES4ETQtfvfQjOJ37t3Isc5KPcqtGVwPlYla9COYFXWFWpzeZho7x5qtzvpDNA9O 0Gagq8Nkzxzs+tU5v0K2rstTMSzayQdqn1RQpT2Wyo4VX1Jn8ONljBoeExV9XJcHIf3F+C Odm9OKC9grPmC1l+FEyMW01BLZ++QEk= X-MC-Unique: cGa3z8MZMO6wSBDr6FUhlQ-1 X-Mimecast-MFC-AGG-ID: cGa3z8MZMO6wSBDr6FUhlQ_1759862093 From: Stefan Hajnoczi To: qemu-devel@nongnu.org Cc: Kevin Wolf , Eric Blake , qemu-block@nongnu.org, Hanna Reitz , Stefan Hajnoczi Subject: [PATCH v2 1/5] block: add BdrvChildClass->propagate_attach/detach() callbacks Date: Tue, 7 Oct 2025 14:34:43 -0400 Message-ID: <20251007183447.93120-2-stefanha@redhat.com> In-Reply-To: <20251007183447.93120-1-stefanha@redhat.com> References: <20251007183447.93120-1-stefanha@redhat.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.93 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=170.10.133.124; envelope-from=stefanha@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -24 X-Spam_score: -2.5 X-Spam_bar: -- X-Spam_report: (-2.5 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.422, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H3=0.001, RCVD_IN_MSPIKE_WL=0.001, RCVD_IN_VALIDITY_CERTIFIED_BLOCKED=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=unavailable autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @redhat.com) X-ZM-MESSAGEID: 1759862211207116600 Content-Type: text/plain; charset="utf-8" bdrv_replace_child_noperm() is the heart of block graph changes. It is called when a node is inserted, removed, or replaced. These changes happen without notifying parents in the graph, so it is currently not possible to monitor changes. Add BdrvChildClass callbacks to propagate attach/detach operations to the roots of the graph. The next commit will introduce a BlockBackend API for monitoring changes using this mechanism. Signed-off-by: Stefan Hajnoczi Reviewed-by: Eric Blake --- include/block/block_int-common.h | 11 +++++++ block.c | 56 +++++++++++++++++++++++++------- 2 files changed, 56 insertions(+), 11 deletions(-) diff --git a/include/block/block_int-common.h b/include/block/block_int-com= mon.h index 034c0634c8..0368a3191c 100644 --- a/include/block/block_int-common.h +++ b/include/block/block_int-common.h @@ -963,6 +963,17 @@ struct BdrvChildClass { void GRAPH_RDLOCK_PTR (*activate)(BdrvChild *child, Error **errp); int GRAPH_RDLOCK_PTR (*inactivate)(BdrvChild *child); =20 + /* + * Optional callbacks when a descendant (child, grandchild, etc) attac= hes + * or detaches a BlockDriverState. Allows monitoring changes to the gr= aph. + * + * Called after ->attach() and before ->detach(). + */ + void GRAPH_WRLOCK_PTR (*propagate_attach)(BdrvChild *self, + BdrvChild *descendant); + void GRAPH_WRLOCK_PTR (*propagate_detach)(BdrvChild *self, + BdrvChild *descendant); + void GRAPH_WRLOCK_PTR (*attach)(BdrvChild *child); void GRAPH_WRLOCK_PTR (*detach)(BdrvChild *child); =20 diff --git a/block.c b/block.c index 8848e9a7ed..e1480dda04 100644 --- a/block.c +++ b/block.c @@ -1497,6 +1497,32 @@ static void GRAPH_WRLOCK bdrv_child_cb_detach(BdrvCh= ild *child) } } =20 +static void GRAPH_WRLOCK +bdrv_child_cb_propagate_attach(BdrvChild *self, BdrvChild *descendant) +{ + BlockDriverState *bs =3D self->opaque; + BdrvChild *c; + + QLIST_FOREACH(c, &bs->parents, next_parent) { + if (c->klass->propagate_attach) { + c->klass->propagate_attach(c, descendant); + } + } +} + +static void GRAPH_WRLOCK +bdrv_child_cb_propagate_detach(BdrvChild *self, BdrvChild *descendant) +{ + BlockDriverState *bs =3D self->opaque; + BdrvChild *c; + + QLIST_FOREACH(c, &bs->parents, next_parent) { + if (c->klass->propagate_detach) { + c->klass->propagate_detach(c, descendant); + } + } +} + static int bdrv_child_cb_update_filename(BdrvChild *c, BlockDriverState *b= ase, const char *filename, bool backing_mask_protocol, @@ -1519,17 +1545,19 @@ AioContext *child_of_bds_get_parent_aio_context(Bdr= vChild *c) } =20 const BdrvChildClass child_of_bds =3D { - .parent_is_bds =3D true, - .get_parent_desc =3D bdrv_child_get_parent_desc, - .inherit_options =3D bdrv_inherited_options, - .drained_begin =3D bdrv_child_cb_drained_begin, - .drained_poll =3D bdrv_child_cb_drained_poll, - .drained_end =3D bdrv_child_cb_drained_end, - .attach =3D bdrv_child_cb_attach, - .detach =3D bdrv_child_cb_detach, - .inactivate =3D bdrv_child_cb_inactivate, - .change_aio_ctx =3D bdrv_child_cb_change_aio_ctx, - .update_filename =3D bdrv_child_cb_update_filename, + .parent_is_bds =3D true, + .get_parent_desc =3D bdrv_child_get_parent_desc, + .inherit_options =3D bdrv_inherited_options, + .drained_begin =3D bdrv_child_cb_drained_begin, + .drained_poll =3D bdrv_child_cb_drained_poll, + .drained_end =3D bdrv_child_cb_drained_end, + .attach =3D bdrv_child_cb_attach, + .detach =3D bdrv_child_cb_detach, + .propagate_attach =3D bdrv_child_cb_propagate_attach, + .propagate_detach =3D bdrv_child_cb_propagate_detach, + .inactivate =3D bdrv_child_cb_inactivate, + .change_aio_ctx =3D bdrv_child_cb_change_aio_ctx, + .update_filename =3D bdrv_child_cb_update_filename, .get_parent_aio_context =3D child_of_bds_get_parent_aio_context, }; =20 @@ -2967,6 +2995,9 @@ bdrv_replace_child_noperm(BdrvChild *child, BlockDriv= erState *new_bs) } =20 if (old_bs) { + if (child->klass->propagate_detach) { + child->klass->propagate_detach(child, child); + } if (child->klass->detach) { child->klass->detach(child); } @@ -2980,6 +3011,9 @@ bdrv_replace_child_noperm(BdrvChild *child, BlockDriv= erState *new_bs) if (child->klass->attach) { child->klass->attach(child); } + if (child->klass->propagate_attach) { + child->klass->propagate_attach(child, child); + } } =20 /* --=20 2.51.0 From nobody Fri Nov 14 22:14:41 2025 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=quarantine dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1759862157; cv=none; d=zohomail.com; s=zohoarc; b=lpSgiXPQwx5TwgydCWo8Eq2VLJflDNsUpQ8V8hmbzhqzLSBBozeit74xfqyChj+wGMlFbTYcHSIh8qMYUwkezUOIuNQP+t0/T1eFxWyFw6olsP9SH8STnjtG2enN2SAgiPBtTyDvVBtwDmb6DvYpYLXijwqdJhUH85TB+J9pe7I= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1759862157; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=4+d+ZZynQwMoVubA0KaHn38NBhgbFi2k8bySMKvDrIg=; b=Bmj0UhvzA7Ii81TGECjWwzLEBs/5f710N3kus/YAjFNVMDFXslXNfQgJ2lEz3L5+h9RGQzKmq7s1Qm9sNXIgTnxkUqsWZxd2XufZf11Jp6CHqEdmfpBqx0uvM0EtjH7fn68na7heVkuLwQFWd6f5DJMg/gDLCGUeyESo7OT1vLA= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1759862157638669.8236692968211; Tue, 7 Oct 2025 11:35:57 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1v6CXB-0005tJ-27; Tue, 07 Oct 2025 14:35:38 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1v6CWd-0005i8-CU for qemu-devel@nongnu.org; Tue, 07 Oct 2025 14:35:04 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.129.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1v6CWZ-0002dp-0b for qemu-devel@nongnu.org; Tue, 07 Oct 2025 14:35:03 -0400 Received: from mx-prod-mc-04.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-599-YCDhIJxDNJ-U6gnWaJRqZA-1; Tue, 07 Oct 2025 14:34:56 -0400 Received: from mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.17]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-04.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 773741955F29; Tue, 7 Oct 2025 18:34:55 +0000 (UTC) Received: from localhost (unknown [10.2.16.87]) by mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id E1BB11956056; Tue, 7 Oct 2025 18:34:54 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1759862098; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=4+d+ZZynQwMoVubA0KaHn38NBhgbFi2k8bySMKvDrIg=; b=fAducl7Xd7vVSP256zBBix/YesJJMjD38IVJ6+HtM6hXXjUbg8qbvE3bAjYLgWI/gg+BbY QU+/7ysMrlbtqTMEY90Ze4cwCI2jMJA3WPgVe2P6mNHj+ovar6/TsPyFt9p4526VYmyTVd HN1fjQFyBXJ1ZvuwhCEb97aqgA3M/sE= X-MC-Unique: YCDhIJxDNJ-U6gnWaJRqZA-1 X-Mimecast-MFC-AGG-ID: YCDhIJxDNJ-U6gnWaJRqZA_1759862095 From: Stefan Hajnoczi To: qemu-devel@nongnu.org Cc: Kevin Wolf , Eric Blake , qemu-block@nongnu.org, Hanna Reitz , Stefan Hajnoczi Subject: [PATCH v2 2/5] block: add blk_add_attach/detach_notifier() APIs Date: Tue, 7 Oct 2025 14:34:44 -0400 Message-ID: <20251007183447.93120-3-stefanha@redhat.com> In-Reply-To: <20251007183447.93120-1-stefanha@redhat.com> References: <20251007183447.93120-1-stefanha@redhat.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 3.0 on 10.30.177.17 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=170.10.129.124; envelope-from=stefanha@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -24 X-Spam_score: -2.5 X-Spam_bar: -- X-Spam_report: (-2.5 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.422, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H3=0.001, RCVD_IN_MSPIKE_WL=0.001, RCVD_IN_VALIDITY_CERTIFIED_BLOCKED=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @redhat.com) X-ZM-MESSAGEID: 1759862161197154100 Content-Type: text/plain; charset="utf-8" Add an API to receive a callback when a BlockDriverState is attached or detached from the block graph. This allows callers to track insert, remove, and replace operations. Note that this API might be able to replace the blk_add_remove_bs_notifier() API if the callback checks that the root BDS is being removed and ignores all other calls. I think this is a bit messy though, so I kept blk_add_remove_bs_notifier(). Signed-off-by: Stefan Hajnoczi Reviewed-by: Eric Blake --- include/system/block-backend-global-state.h | 9 ++ block/block-backend.c | 44 ++++++ tests/unit/test-block-backend.c | 164 ++++++++++++++++++++ 3 files changed, 217 insertions(+) diff --git a/include/system/block-backend-global-state.h b/include/system/b= lock-backend-global-state.h index c3849640df..e828f271ee 100644 --- a/include/system/block-backend-global-state.h +++ b/include/system/block-backend-global-state.h @@ -97,6 +97,15 @@ void blk_remove_aio_context_notifier(BlockBackend *blk, void (*detach_aio_context)(void *), void *opaque); void blk_add_remove_bs_notifier(BlockBackend *blk, Notifier *notify); + +typedef struct { + BlockBackend *blk; + BlockDriverState *bs; +} BlockBackendAttachDetachArgs; + +void blk_add_attach_notifier(BlockBackend *blk, Notifier *notify); +void blk_add_detach_notifier(BlockBackend *blk, Notifier *notify); + BlockBackendRootState *blk_get_root_state(BlockBackend *blk); void blk_update_root_state(BlockBackend *blk); bool blk_get_detect_zeroes_from_root_state(BlockBackend *blk); diff --git a/block/block-backend.c b/block/block-backend.c index f8d6ba65c1..45e31f0079 100644 --- a/block/block-backend.c +++ b/block/block-backend.c @@ -76,6 +76,7 @@ struct BlockBackend { =20 /* Protected by BQL */ NotifierList remove_bs_notifiers, insert_bs_notifiers; + NotifierList attach_notifiers, detach_notifiers; QLIST_HEAD(, BlockBackendAioNotifier) aio_notifiers; =20 int quiesce_counter; /* atomic: written under BQL, read by other threa= ds */ @@ -280,6 +281,30 @@ static int GRAPH_RDLOCK blk_root_inactivate(BdrvChild = *child) return 0; } =20 +static void GRAPH_WRLOCK +blk_root_propagate_attach(BdrvChild *self, BdrvChild *descendant) +{ + BlockBackend *blk =3D self->opaque; + BlockBackendAttachDetachArgs args =3D { + .blk =3D blk, + .bs =3D descendant->bs, + }; + + notifier_list_notify(&blk->attach_notifiers, &args); +} + +static void GRAPH_WRLOCK +blk_root_propagate_detach(BdrvChild *self, BdrvChild *descendant) +{ + BlockBackend *blk =3D self->opaque; + BlockBackendAttachDetachArgs args =3D { + .blk =3D blk, + .bs =3D descendant->bs, + }; + + notifier_list_notify(&blk->detach_notifiers, &args); +} + static void blk_root_attach(BdrvChild *child) { BlockBackend *blk =3D child->opaque; @@ -333,6 +358,9 @@ static const BdrvChildClass child_root =3D { .activate =3D blk_root_activate, .inactivate =3D blk_root_inactivate, =20 + .propagate_attach =3D blk_root_propagate_attach, + .propagate_detach =3D blk_root_propagate_detach, + .attach =3D blk_root_attach, .detach =3D blk_root_detach, =20 @@ -374,6 +402,8 @@ BlockBackend *blk_new(AioContext *ctx, uint64_t perm, u= int64_t shared_perm) qemu_co_queue_init(&blk->queued_requests); notifier_list_init(&blk->remove_bs_notifiers); notifier_list_init(&blk->insert_bs_notifiers); + notifier_list_init(&blk->attach_notifiers); + notifier_list_init(&blk->detach_notifiers); QLIST_INIT(&blk->aio_notifiers); =20 QTAILQ_INSERT_TAIL(&block_backends, blk, link); @@ -492,6 +522,8 @@ static void blk_delete(BlockBackend *blk) } assert(QLIST_EMPTY(&blk->remove_bs_notifiers.notifiers)); assert(QLIST_EMPTY(&blk->insert_bs_notifiers.notifiers)); + assert(QLIST_EMPTY(&blk->attach_notifiers.notifiers)); + assert(QLIST_EMPTY(&blk->detach_notifiers.notifiers)); assert(QLIST_EMPTY(&blk->aio_notifiers)); assert(qemu_co_queue_empty(&blk->queued_requests)); qemu_mutex_destroy(&blk->queued_requests_lock); @@ -2512,6 +2544,18 @@ void blk_add_remove_bs_notifier(BlockBackend *blk, N= otifier *notify) notifier_list_add(&blk->remove_bs_notifiers, notify); } =20 +void blk_add_attach_notifier(BlockBackend *blk, Notifier *notify) +{ + GLOBAL_STATE_CODE(); + notifier_list_add(&blk->attach_notifiers, notify); +} + +void blk_add_detach_notifier(BlockBackend *blk, Notifier *notify) +{ + GLOBAL_STATE_CODE(); + notifier_list_add(&blk->detach_notifiers, notify); +} + BlockAcctStats *blk_get_stats(BlockBackend *blk) { IO_CODE(); diff --git a/tests/unit/test-block-backend.c b/tests/unit/test-block-backen= d.c index 4257b3f815..693383f029 100644 --- a/tests/unit/test-block-backend.c +++ b/tests/unit/test-block-backend.c @@ -24,6 +24,7 @@ =20 #include "qemu/osdep.h" #include "block/block.h" +#include "block/block_int.h" #include "system/block-backend.h" #include "qapi/error.h" #include "qemu/main-loop.h" @@ -70,6 +71,167 @@ static void test_drain_all_aio_error(void) blk_unref(blk); } =20 +static int bdrv_test_co_change_backing_file(BlockDriverState *bs, + const char *backing_file, + const char *backing_fmt) +{ + return 0; /* just return success so bdrv_set_backing_hd() works */ +} + +static BlockDriver bdrv_test =3D { + .format_name =3D "test", + .supports_backing =3D true, + .bdrv_child_perm =3D bdrv_default_perms, + .bdrv_co_change_backing_file =3D bdrv_test_co_change_backing_file, +}; + +typedef struct { + Notifier attach_notifier; + Notifier detach_notifier; + GArray *notifications; +} AttachDetach; + +typedef enum { + NOTIFY_END =3D 0, + NOTIFY_ATTACH, + NOTIFY_DETACH, +} NotificationType; + +typedef struct { + NotificationType type; + BlockDriverState *bs; +} Notification; + +static void attach_detach_append(AttachDetach *ad, NotificationType type, + BlockBackendAttachDetachArgs *args) +{ + Notification n =3D { + .type =3D type, + .bs =3D args->bs, + }; + + g_array_append_vals(ad->notifications, &n, 1); +} + +static void attach_notify(Notifier *notifier, void *data) +{ + AttachDetach *ad =3D container_of(notifier, AttachDetach, attach_notif= ier); + attach_detach_append(ad, NOTIFY_ATTACH, data); +} + +static void detach_notify(Notifier *notifier, void *data) +{ + AttachDetach *ad =3D container_of(notifier, AttachDetach, attach_notif= ier); + attach_detach_append(ad, NOTIFY_DETACH, data); +} + +static void attach_detach_init(AttachDetach *ad, BlockBackend *blk) +{ + ad->attach_notifier.notify =3D attach_notify; + ad->detach_notifier.notify =3D detach_notify; + ad->notifications =3D g_array_new(true, true, sizeof(Notification)); + + blk_add_attach_notifier(blk, &ad->attach_notifier); + blk_add_detach_notifier(blk, &ad->detach_notifier); +} + +static void attach_detach_cleanup(AttachDetach *ad) +{ + g_array_free(ad->notifications, true); + notifier_remove(&ad->detach_notifier); + notifier_remove(&ad->attach_notifier); +} + +/* + * Check that the expected notifications occurred. @expected is terminated= by a + * NOTIFY_END element. + */ +static void attach_detach_expect(AttachDetach *ad, const Notification *exp= ected) +{ + GArray *array =3D ad->notifications; + + /* The array is zero terminated so there is at least one element */ + Notification *actual =3D (Notification *)array->data; + + while (expected->type !=3D NOTIFY_END) { + g_assert_cmpint(actual->type, =3D=3D, expected->type); + g_assert(actual->bs =3D=3D expected->bs); + expected++; + actual++; + } + + g_assert_cmpint(actual->type, =3D=3D, NOTIFY_END); + + g_array_remove_range(array, 0, array->len); +} + +static void test_attach_detach_notifier(void) +{ + AttachDetach ad; + BlockDriverState *format; + BlockDriverState *file; + BlockDriverState *file2; + BlockBackend *blk =3D blk_new(qemu_get_aio_context(), + BLK_PERM_ALL, BLK_PERM_ALL); + + attach_detach_init(&ad, blk); + + format =3D bdrv_new_open_driver(&bdrv_test, "format", BDRV_O_RDWR, + &error_abort); + file =3D bdrv_new_open_driver(&bdrv_test, "file", BDRV_O_RDWR, &error_= abort); + file2 =3D bdrv_new_open_driver(&bdrv_test, "file2", BDRV_O_RDWR, + &error_abort); + + bdrv_graph_wrlock_drained(); + bdrv_attach_child(format, file, "file", &child_of_bds, + BDRV_CHILD_PRIMARY | BDRV_CHILD_DATA, &error_abort); + bdrv_graph_wrunlock(); + + /* Insert format -> file */ + blk_insert_bs(blk, format, &error_abort); + attach_detach_expect(&ad, (Notification[]){ + (Notification){NOTIFY_ATTACH, format}, + {}, + }); + + /* Replace format -> file with file2 */ + blk_replace_bs(blk, file2, &error_abort); + attach_detach_expect(&ad, (Notification[]){ + (Notification){NOTIFY_DETACH, format}, + (Notification){NOTIFY_ATTACH, file2}, + {}, + }); + + /* Remove file2 */ + blk_remove_bs(blk); + attach_detach_expect(&ad, (Notification[]){ + (Notification){NOTIFY_DETACH, file2}, + {}, + }); + + /* These BDSes were unrefed so we need new instances */ + file =3D bdrv_new_open_driver(&bdrv_test, "file", BDRV_O_RDWR, &error_= abort); + file2 =3D bdrv_new_open_driver(&bdrv_test, "file2", BDRV_O_RDWR, + &error_abort); + + /* Replace a non-root node */ + bdrv_graph_wrlock_drained(); + bdrv_attach_child(format, file, "file", &child_of_bds, + BDRV_CHILD_PRIMARY | BDRV_CHILD_DATA, &error_abort); + bdrv_replace_node(file, file2, &error_abort); + bdrv_graph_wrunlock(); + attach_detach_expect(&ad, (Notification[]){ + (Notification){NOTIFY_ATTACH, file}, + (Notification){NOTIFY_DETACH, file}, + (Notification){NOTIFY_ATTACH, file2}, + {}, + }); + + attach_detach_cleanup(&ad); + blk_unref(blk); + bdrv_unref(format); +} + int main(int argc, char **argv) { bdrv_init(); @@ -80,6 +242,8 @@ int main(int argc, char **argv) g_test_add_func("/block-backend/drain_aio_error", test_drain_aio_error= ); g_test_add_func("/block-backend/drain_all_aio_error", test_drain_all_aio_error); + g_test_add_func("/block-backend/attach_detach_notifier", + test_attach_detach_notifier); =20 return g_test_run(); } --=20 2.51.0 From nobody Fri Nov 14 22:14:41 2025 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=quarantine dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1759862191; cv=none; d=zohomail.com; s=zohoarc; b=MvwAUCOOZgVZF82oQ7mLqccj+XD18VDo85zJRhIumH4GifSoekg6/yzpqTqZiteSDW3WDvPbr97vQy9OyZ/awlU2o2CY+NiYcHZTq0PbmbWm8osR3rK86ZqzFG6j3bmvAsp51QdjRgagSmiK4lKIPzJbgdcMz8lWDs6zPccTiLc= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1759862191; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=pJXNRnHEOV8SoZ+YBFNRT9lJhGALX9mzhYDz9HUAN9I=; b=QRpEWq8U8ZEn5GviJPjE5ikxVtqid3a7r6tu2HTEwCZFqPO9zD8r1Davn89eH/oG/A2epTAgq5aKHzl0yuLJubI8xSvbr6DvHfeVwbrm75yLHv/a458OIaP2JWna2AIjixV7Si2EDkXv+h5+JufQhoWJUPx1zlc6WD0qsiAUPNs= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1759862191656360.1748253737919; Tue, 7 Oct 2025 11:36:31 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1v6CXJ-000631-Ib; Tue, 07 Oct 2025 14:35:45 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1v6CWe-0005ie-7Q for qemu-devel@nongnu.org; Tue, 07 Oct 2025 14:35:04 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1v6CWb-0002e0-R7 for qemu-devel@nongnu.org; Tue, 07 Oct 2025 14:35:03 -0400 Received: from mx-prod-mc-06.mail-002.prod.us-west-2.aws.redhat.com (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-280-yurKvxbuPCmU1ftsN_1JHA-1; Tue, 07 Oct 2025 14:34:58 -0400 Received: from mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.111]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-06.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 82A711800366; Tue, 7 Oct 2025 18:34:57 +0000 (UTC) Received: from localhost (unknown [10.2.16.87]) by mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id F3BD818004D8; Tue, 7 Oct 2025 18:34:56 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1759862100; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=pJXNRnHEOV8SoZ+YBFNRT9lJhGALX9mzhYDz9HUAN9I=; b=g2LIpOlsCGD6MmJN8H3b80di3BCvFshdEvZ9z9YEymQV4JOMMOFeps+bmpOPyeQU2T/jkT NcWnNXpmFxfyaZTQVgFJWb1U+Itoz1g6BXXPUpn4zpbFrEHOD+LX6XSYhTQHomegxuka14 aRRnhutbbV4EXw2CqCTKvOe8BnNHS5E= X-MC-Unique: yurKvxbuPCmU1ftsN_1JHA-1 X-Mimecast-MFC-AGG-ID: yurKvxbuPCmU1ftsN_1JHA_1759862097 From: Stefan Hajnoczi To: qemu-devel@nongnu.org Cc: Kevin Wolf , Eric Blake , qemu-block@nongnu.org, Hanna Reitz , Stefan Hajnoczi Subject: [PATCH v2 3/5] block: rename RAMBlockRegistrar->notifier field Date: Tue, 7 Oct 2025 14:34:45 -0400 Message-ID: <20251007183447.93120-4-stefanha@redhat.com> In-Reply-To: <20251007183447.93120-1-stefanha@redhat.com> References: <20251007183447.93120-1-stefanha@redhat.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.111 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=170.10.133.124; envelope-from=stefanha@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -24 X-Spam_score: -2.5 X-Spam_bar: -- X-Spam_report: (-2.5 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.422, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H3=0.001, RCVD_IN_MSPIKE_WL=0.001, RCVD_IN_VALIDITY_CERTIFIED_BLOCKED=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @redhat.com) X-ZM-MESSAGEID: 1759862203627116600 Content-Type: text/plain; charset="utf-8" The 'notifier' field name will be confusing when the BlockBackend attach and detach notifiers are added in the next commit. Rename the field so it's clear that this is the RAMBlock notifier. Signed-off-by: Stefan Hajnoczi Reviewed-by: Eric Blake --- include/system/block-ram-registrar.h | 2 +- block/block-ram-registrar.c | 14 ++++++++------ 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/include/system/block-ram-registrar.h b/include/system/block-ra= m-registrar.h index d8b2f7942b..76c157bd54 100644 --- a/include/system/block-ram-registrar.h +++ b/include/system/block-ram-registrar.h @@ -21,7 +21,7 @@ */ typedef struct { BlockBackend *blk; - RAMBlockNotifier notifier; + RAMBlockNotifier ram_block_notifier; bool ok; } BlockRAMRegistrar; =20 diff --git a/block/block-ram-registrar.c b/block/block-ram-registrar.c index fcda2b86af..d5b84667a1 100644 --- a/block/block-ram-registrar.c +++ b/block/block-ram-registrar.c @@ -12,7 +12,8 @@ static void ram_block_added(RAMBlockNotifier *n, void *host, size_t size, size_t max_size) { - BlockRAMRegistrar *r =3D container_of(n, BlockRAMRegistrar, notifier); + BlockRAMRegistrar *r =3D + container_of(n, BlockRAMRegistrar, ram_block_notifier); Error *err =3D NULL; =20 if (!r->ok) { @@ -21,7 +22,7 @@ static void ram_block_added(RAMBlockNotifier *n, void *ho= st, size_t size, =20 if (!blk_register_buf(r->blk, host, max_size, &err)) { error_report_err(err); - ram_block_notifier_remove(&r->notifier); + ram_block_notifier_remove(n); r->ok =3D false; } } @@ -29,14 +30,15 @@ static void ram_block_added(RAMBlockNotifier *n, void *= host, size_t size, static void ram_block_removed(RAMBlockNotifier *n, void *host, size_t size, size_t max_size) { - BlockRAMRegistrar *r =3D container_of(n, BlockRAMRegistrar, notifier); + BlockRAMRegistrar *r =3D + container_of(n, BlockRAMRegistrar, ram_block_notifier); blk_unregister_buf(r->blk, host, max_size); } =20 void blk_ram_registrar_init(BlockRAMRegistrar *r, BlockBackend *blk) { r->blk =3D blk; - r->notifier =3D (RAMBlockNotifier){ + r->ram_block_notifier =3D (RAMBlockNotifier){ .ram_block_added =3D ram_block_added, .ram_block_removed =3D ram_block_removed, =20 @@ -47,12 +49,12 @@ void blk_ram_registrar_init(BlockRAMRegistrar *r, Block= Backend *blk) }; r->ok =3D true; =20 - ram_block_notifier_add(&r->notifier); + ram_block_notifier_add(&r->ram_block_notifier); } =20 void blk_ram_registrar_destroy(BlockRAMRegistrar *r) { if (r->ok) { - ram_block_notifier_remove(&r->notifier); + ram_block_notifier_remove(&r->ram_block_notifier); } } --=20 2.51.0 From nobody Fri Nov 14 22:14:41 2025 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=quarantine dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1759862204; cv=none; d=zohomail.com; s=zohoarc; b=KMA+LNmzbvWCit1Q49ALhp/WH8Ri+wBfING7HDQRCXnIhgie+EaJ4Ts34CGrOCIuwcn0GdKLqEep32680CmeAYzcGK2rNKmrJqPIsrww5PpfWYN1ovAVg8Y6/Ue2zZyW85Av9EreduMiW+scDMIiz2mBBI7sRD0KrspUVG1QBow= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1759862204; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=oT0Pgap99n2+YSNINo4XgcnXxn2KZv6jwWIxQ2bC8+o=; b=aCJjXTBQpVddpn2hfVCuRlnDFUreYVOqcu9ClXTIGFJVSNAuBlX/Kg32E2zYL27pID73OSLW3l8v7cJpLEOk9dGUkJEKV4+TfssQdPRQn24b60sBlgIOa2m5nSWoKT3bTf5sl0KzkE7XoIULEDTJBsOVLxTag1gW0U0wATtRIXE= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1759862204089265.57423672675486; Tue, 7 Oct 2025 11:36:44 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1v6CXK-000664-Qk; Tue, 07 Oct 2025 14:35:46 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1v6CWn-0005oV-Ax for qemu-devel@nongnu.org; Tue, 07 Oct 2025 14:35:16 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1v6CWf-0002pz-3Z for qemu-devel@nongnu.org; Tue, 07 Oct 2025 14:35:11 -0400 Received: from mx-prod-mc-05.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-304-o-r2Azk3MUSfXtCvf58x8Q-1; Tue, 07 Oct 2025 14:35:00 -0400 Received: from mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.4]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id C070F19560BA; Tue, 7 Oct 2025 18:34:59 +0000 (UTC) Received: from localhost (unknown [10.2.16.87]) by mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 242CF30002C6; Tue, 7 Oct 2025 18:34:58 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1759862103; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=oT0Pgap99n2+YSNINo4XgcnXxn2KZv6jwWIxQ2bC8+o=; b=apbbXmHGW8c/6qDeMEeO8T4NVAvbjV4CbIuG8YZzRZJYzhhsfdJ8ayUhCaDv5xCbgCSxVu 59Pi5C35qO1JiMtY2K15Y2sZv6zaw4k08Tjcfmsb3sGTFTTImOzoSi7b6KGMxTKURx0R1r NSm6vjp+cjCI3pLyPGgwmirxBPGv3mA= X-MC-Unique: o-r2Azk3MUSfXtCvf58x8Q-1 X-Mimecast-MFC-AGG-ID: o-r2Azk3MUSfXtCvf58x8Q_1759862099 From: Stefan Hajnoczi To: qemu-devel@nongnu.org Cc: Kevin Wolf , Eric Blake , qemu-block@nongnu.org, Hanna Reitz , Stefan Hajnoczi , Yingshun Cui Subject: [PATCH v2 4/5] block: update inserted/removed nodes from BlockRAMRegistrar Date: Tue, 7 Oct 2025 14:34:46 -0400 Message-ID: <20251007183447.93120-5-stefanha@redhat.com> In-Reply-To: <20251007183447.93120-1-stefanha@redhat.com> References: <20251007183447.93120-1-stefanha@redhat.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.4 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=170.10.133.124; envelope-from=stefanha@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -24 X-Spam_score: -2.5 X-Spam_bar: -- X-Spam_report: (-2.5 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.422, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H3=0.001, RCVD_IN_MSPIKE_WL=0.001, RCVD_IN_VALIDITY_CERTIFIED_BLOCKED=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=unavailable autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @redhat.com) X-ZM-MESSAGEID: 1759862228092116600 Content-Type: text/plain; charset="utf-8" BlockRAMRegistrar ensures that RAMBlocks are registered with BlockDriverStates. This is essential for vdpa-blk because they need to know the memory mappings of I/O buffers. However, BlockRAMRegistrar is currently unaware of changes to the block graph and newly inserted nodes have no RAMBlocks registered. Use the new blk_add_attach_notifier() and blk_add_detach_notifier() APIs to bring nodes up to speed when the graph changes. This fixes vdpa-blk across mirror and other operations that modify the block graph. Previously I/O would not succeed after a new node was inserted due to missing memory mappings. Buglink: https://issues.redhat.com/browse/RHEL-88175 Reported-by: Yingshun Cui Signed-off-by: Stefan Hajnoczi Reviewed-by: Eric Blake --- include/system/block-ram-registrar.h | 2 + block/block-ram-registrar.c | 61 +++++++++++++++++++++++++++- 2 files changed, 61 insertions(+), 2 deletions(-) diff --git a/include/system/block-ram-registrar.h b/include/system/block-ra= m-registrar.h index 76c157bd54..292c197d1c 100644 --- a/include/system/block-ram-registrar.h +++ b/include/system/block-ram-registrar.h @@ -22,6 +22,8 @@ typedef struct { BlockBackend *blk; RAMBlockNotifier ram_block_notifier; + Notifier blk_attach_notifier; + Notifier blk_detach_notifier; bool ok; } BlockRAMRegistrar; =20 diff --git a/block/block-ram-registrar.c b/block/block-ram-registrar.c index d5b84667a1..2d334c5655 100644 --- a/block/block-ram-registrar.c +++ b/block/block-ram-registrar.c @@ -7,7 +7,9 @@ #include "qemu/osdep.h" #include "system/block-backend.h" #include "system/block-ram-registrar.h" +#include "system/ramblock.h" #include "qapi/error.h" +#include "trace.h" =20 static void ram_block_added(RAMBlockNotifier *n, void *host, size_t size, size_t max_size) @@ -22,8 +24,8 @@ static void ram_block_added(RAMBlockNotifier *n, void *ho= st, size_t size, =20 if (!blk_register_buf(r->blk, host, max_size, &err)) { error_report_err(err); - ram_block_notifier_remove(n); - r->ok =3D false; + blk_ram_registrar_destroy(r); + return; } } =20 @@ -35,6 +37,50 @@ static void ram_block_removed(RAMBlockNotifier *n, void = *host, size_t size, blk_unregister_buf(r->blk, host, max_size); } =20 +static void blk_attached(Notifier *n, void *data) +{ + BlockRAMRegistrar *r =3D + container_of(n, BlockRAMRegistrar, blk_attach_notifier); + BlockBackendAttachDetachArgs *args =3D data; + BlockDriverState *bs =3D args->bs; + Error *err =3D NULL; + + WITH_RCU_READ_LOCK_GUARD() { + RAMBlock *rb; + + RAMBLOCK_FOREACH(rb) { + ram_addr_t max_size =3D qemu_ram_get_max_length(rb); + void *host =3D qemu_ram_get_host_addr(rb); + + if (!bdrv_register_buf(bs, host, max_size, &err)) { + goto err; + } + } + } + + return; + +err: + error_report_err(err); + blk_ram_registrar_destroy(r); +} + +static void blk_detached(Notifier *n, void *data) +{ + BlockBackendAttachDetachArgs *args =3D data; + BlockDriverState *bs =3D args->bs; + RAMBlock *rb; + + RCU_READ_LOCK_GUARD(); + + RAMBLOCK_FOREACH(rb) { + ram_addr_t max_size =3D qemu_ram_get_max_length(rb); + void *host =3D qemu_ram_get_host_addr(rb); + + bdrv_unregister_buf(bs, host, max_size); + } +} + void blk_ram_registrar_init(BlockRAMRegistrar *r, BlockBackend *blk) { r->blk =3D blk; @@ -47,14 +93,25 @@ void blk_ram_registrar_init(BlockRAMRegistrar *r, Block= Backend *blk) * value that does not change across resize. */ }; + r->blk_attach_notifier =3D (Notifier){ + .notify =3D blk_attached, + }; + r->blk_detach_notifier =3D (Notifier){ + .notify =3D blk_detached, + }; r->ok =3D true; =20 ram_block_notifier_add(&r->ram_block_notifier); + blk_add_attach_notifier(blk, &r->blk_attach_notifier); + blk_add_detach_notifier(blk, &r->blk_detach_notifier); } =20 void blk_ram_registrar_destroy(BlockRAMRegistrar *r) { if (r->ok) { + notifier_remove(&r->blk_detach_notifier); + notifier_remove(&r->blk_attach_notifier); ram_block_notifier_remove(&r->ram_block_notifier); + r->ok =3D false; } } --=20 2.51.0 From nobody Fri Nov 14 22:14:41 2025 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=quarantine dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1759862186; cv=none; d=zohomail.com; s=zohoarc; b=beL+XcLeot00N3XoHurlwKESsnK7wQkg+kAF989vX3CeAmVD6ckW3XHXaiLx0fSBNogRScdFCxgbDqgNgrkT+TsXAs+qRnXZ/Iz2dn5D/Azx62U3ALkqKd7gnwvw1dvLK9s5CTqz5McByyHZL2e9YgVahdGEZMINBgbnbQhd2ic= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1759862186; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=05ZWYAXl5ZwTZ0FtrkUAUoGr1gQfXaB5RyM4Ta7fz84=; b=UZ+DzLZiH78olfN0Tgt2AfW8wEI9E84tVSgF81iAQlppPI06/OiZhNe0IN51Ff9AuPmPsiOzarJV3OWZVo8D3LyI9Lrj73Tiu8N3EfS//0ZBhKbx/szTsy423KKWGo1XqXjVXdDHOUyK5Qy2/7FALqjl41fslBccRrH2rf3spL0= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1759862186122903.435561281206; Tue, 7 Oct 2025 11:36:26 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1v6CXH-0005yn-Oe; Tue, 07 Oct 2025 14:35:43 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1v6CWi-0005oB-GG for qemu-devel@nongnu.org; Tue, 07 Oct 2025 14:35:09 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1v6CWf-0002qF-GI for qemu-devel@nongnu.org; Tue, 07 Oct 2025 14:35:08 -0400 Received: from mx-prod-mc-05.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-68-kldb1I1zN8SxpSlsCacXHg-1; Tue, 07 Oct 2025 14:35:02 -0400 Received: from mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.17]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id B346F1956096; Tue, 7 Oct 2025 18:35:01 +0000 (UTC) Received: from localhost (unknown [10.2.16.87]) by mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 3E3F31956056; Tue, 7 Oct 2025 18:35:01 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1759862104; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=05ZWYAXl5ZwTZ0FtrkUAUoGr1gQfXaB5RyM4Ta7fz84=; b=Y5OGIG9GaQDiTbl4mWkNRIxsCCGID95264lBD8+yXg8B2su2Grrqi9yI1CoTRKTzRWs0Cu pQNYiZL731PhPzMyjNSprHU/gf8pBKEPqLtGN0CeCZ6A8ejSOQkM9HbI7YMzXVArc55BU0 wNSIE3aJwlW0GxbkyOIaks3Toy+5uzI= X-MC-Unique: kldb1I1zN8SxpSlsCacXHg-1 X-Mimecast-MFC-AGG-ID: kldb1I1zN8SxpSlsCacXHg_1759862101 From: Stefan Hajnoczi To: qemu-devel@nongnu.org Cc: Kevin Wolf , Eric Blake , qemu-block@nongnu.org, Hanna Reitz , Stefan Hajnoczi Subject: [PATCH v2 5/5] tests/functional: add vdpa-blk blockdev-mirror test Date: Tue, 7 Oct 2025 14:34:47 -0400 Message-ID: <20251007183447.93120-6-stefanha@redhat.com> In-Reply-To: <20251007183447.93120-1-stefanha@redhat.com> References: <20251007183447.93120-1-stefanha@redhat.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 3.0 on 10.30.177.17 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=170.10.133.124; envelope-from=stefanha@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -24 X-Spam_score: -2.5 X-Spam_bar: -- X-Spam_report: (-2.5 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.422, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H3=0.001, RCVD_IN_MSPIKE_WL=0.001, RCVD_IN_VALIDITY_CERTIFIED_BLOCKED=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @redhat.com) X-ZM-MESSAGEID: 1759862189160154100 Content-Type: text/plain; charset="utf-8" Add a test case that reproduces https://issues.redhat.com/browse/RHEL-88175. When the mirror blockjob completes, it replaces the original vdpa-blk blockdev node with a new vdpa-blk blockdev. This will only work if the BlockRAMRegistrar populates memory mappings (see the previous commit). Signed-off-by: Stefan Hajnoczi Tested-by: Eric Blake --- tests/functional/x86_64/meson.build | 1 + .../functional/x86_64/test_vdpa_blk_mirror.py | 118 ++++++++++++++++++ 2 files changed, 119 insertions(+) create mode 100755 tests/functional/x86_64/test_vdpa_blk_mirror.py diff --git a/tests/functional/x86_64/meson.build b/tests/functional/x86_64/= meson.build index f78eec5e6c..dfe0e00190 100644 --- a/tests/functional/x86_64/meson.build +++ b/tests/functional/x86_64/meson.build @@ -33,6 +33,7 @@ tests_x86_64_system_thorough =3D [ 'replay', 'reverse_debug', 'tuxrun', + 'vdpa_blk_mirror', 'vfio_user_client', 'virtio_balloon', 'virtio_gpu', diff --git a/tests/functional/x86_64/test_vdpa_blk_mirror.py b/tests/functi= onal/x86_64/test_vdpa_blk_mirror.py new file mode 100755 index 0000000000..7d52836920 --- /dev/null +++ b/tests/functional/x86_64/test_vdpa_blk_mirror.py @@ -0,0 +1,118 @@ +#!/usr/bin/env python3 +# +# SPDX-License-Identifier: GPL-2.0-or-later +# +# Copyright Red Hat, Inc. +# +# vdpa-blk mirror blockjob tests + + +import glob +import os +import subprocess +from qemu_test import LinuxKernelTest, Asset +from qemu_test import exec_command_and_wait_for_pattern + + +def run(cmd: str) -> None: + ''' + Run a shell command without capturing stdout/stderr and raise + subprocess.CalledProcessError on failure. + ''' + subprocess.check_call(cmd, shell=3DTrue, + stdout=3Dsubprocess.DEVNULL, + stderr=3Dsubprocess.DEVNULL) + + +class VdpaBlk(LinuxKernelTest): + + KERNEL_COMMAND_LINE =3D 'printk.time=3D0 console=3DttyS0 rd.rescue' + ASSET_KERNEL =3D Asset( + ('https://archives.fedoraproject.org/pub/archive/fedora/linux/rele= ases' + '/31/Server/x86_64/os/images/pxeboot/vmlinuz'), + 'd4738d03dbbe083ca610d0821d0a8f1488bebbdccef54ce33e3adb35fda00129') + ASSET_INITRD =3D Asset( + ('https://archives.fedoraproject.org/pub/archive/fedora/linux/rele= ases' + '/31/Server/x86_64/os/images/pxeboot/initrd.img'), + '277cd6c7adf77c7e63d73bbb2cded8ef9e2d3a2f100000e92ff1f8396513cd8b') + VDPA_DEV_1 =3D f'vdpa-{os.getpid()}-1' + VDPA_DEV_2 =3D f'vdpa-{os.getpid()}-2' + + def setUp(self) -> None: + def create_vdpa_dev(name): + ''' + Create a new vdpasim_blk device and return its vhost_vdpa devi= ce + path. + ''' + run(f'sudo -n vdpa dev add mgmtdev vdpasim_blk name {name}') + sysfs_vhost_vdpa_dev_dir =3D \ + glob.glob(f'/sys/bus/vdpa/devices/{name}/vhost-vdpa-*')[0] + vhost_dev_basename =3D os.path.basename(sysfs_vhost_vdpa_dev_d= ir) + vhost_dev_path =3D f'/dev/{vhost_dev_basename}' + run(f'sudo -n chown {os.getuid()}:{os.getgid()} {vhost_dev_pat= h}') + return vhost_dev_path + + try: + run('sudo -n modprobe vhost_vdpa') + run('sudo -n modprobe vdpa_sim_blk') + + self.vhost_dev_1_path =3D create_vdpa_dev(self.VDPA_DEV_1) + self.vhost_dev_2_path =3D create_vdpa_dev(self.VDPA_DEV_2) + except subprocess.CalledProcessError: + self.skipTest('Failed to set up vdpa_blk device') + + super().setUp() + + def tearDown(self) -> None: + super().tearDown() + + try: + run(f'sudo -n vdpa dev del {self.VDPA_DEV_2}') + run(f'sudo -n vdpa dev del {self.VDPA_DEV_1}') + run('sudo -n modprobe --remove vdpa_sim_blk') + run('sudo -n modprobe --remove vhost_vdpa') + except subprocess.CalledProcessError: + pass # ignore failures + + def test_mirror(self) -> None: + ''' + Check that I/O works after a mirror blockjob pivots. See + https://issues.redhat.com/browse/RHEL-88175. + ''' + kernel_path =3D self.ASSET_KERNEL.fetch() + initrd_path =3D self.ASSET_INITRD.fetch() + + self.vm.add_args('-m', '1G') + self.vm.add_args('-object', 'memory-backend-memfd,id=3Dmem,size=3D= 1G') + self.vm.add_args('-machine', 'pc,accel=3Dkvm:tcg,memory-backend=3D= mem') + self.vm.add_args('-append', self.KERNEL_COMMAND_LINE) + self.vm.add_args('-blockdev', + 'virtio-blk-vhost-vdpa,node-name=3Dvdpa-blk-0,' + + f'path=3D{self.vhost_dev_1_path},cache.direct=3Don') + self.vm.add_args('-device', 'virtio-blk-pci,drive=3Dvdpa-blk-0') + + self.launch_kernel(kernel_path, initrd_path, + wait_for=3D'# ') + + self.vm.cmd('blockdev-add', + driver=3D'virtio-blk-vhost-vdpa', + node_name=3D'vdpa-blk-1', + path=3Dself.vhost_dev_2_path, + cache=3D{'direct': True}) + self.vm.cmd('blockdev-mirror', + device=3D'vdpa-blk-0', + job_id=3D'mirror0', + target=3D'vdpa-blk-1', + sync=3D'full', + target_is_zero=3DTrue) + self.vm.event_wait('BLOCK_JOB_READY') + self.vm.cmd('block-job-complete', + device=3D'mirror0') + + exec_command_and_wait_for_pattern(self, + 'dd if=3D/dev/vda of=3D/dev/null iflag=3Ddirect bs=3D4k count= =3D1', + '4096 bytes (4.1 kB, 4.0 KiB) copied') + + +if __name__ =3D=3D '__main__': + LinuxKernelTest.main() --=20 2.51.0