From nobody Thu Jan 23 05:40:12 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=none dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1737546814; cv=none; d=zohomail.com; s=zohoarc; b=J8TQGDlGrTJr/CIuQjC6miR7xW8HXqcxTY7H1fH3xopoISXG2zhU7GWu/LbAQ4yRzP8pKC4O4showES+CNZWTh59R2YBKBtNoiV1CmOV1sN8JaOUnG2WElkXoPdEvhQU1q8NuzvuzLJKXr02/dNHY+Z9bK2L+88Wl9aZzSqz7TY= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1737546814; 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=eclF9e9zIzUicX4hqn+OMI1DBWFsq28pajQTP44/ZJI=; b=fgRYyJkY+iDkL4mzYwFGLaC3kFDRkR9suew/Id7DsDlol0Jnoyai3kqW9eeHbCps2WbqlooVUfkENk8WBQxasJ/9fs4LqoCpwIEAaS3peKQy8TFwXyNAoTnIBWpFoM8OoRe0sZeKASpmEmGnavesE84+UzPM99WxX51CYgetksc= 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=none dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1737546814870502.14233834294294; Wed, 22 Jan 2025 03:53:34 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1taZGm-0002cy-Im; Wed, 22 Jan 2025 06:51:40 -0500 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 1taZGl-0002cS-Ao for qemu-devel@nongnu.org; Wed, 22 Jan 2025 06:51:39 -0500 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 1taZGj-0008Ap-L1 for qemu-devel@nongnu.org; Wed, 22 Jan 2025 06:51:39 -0500 Received: from mx-prod-mc-01.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-611-siAW2UWKOjqdTTn4fLMQ-w-1; Wed, 22 Jan 2025 06:51:33 -0500 Received: from mx-prod-int-04.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-04.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.40]) (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-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 655E519560B0; Wed, 22 Jan 2025 11:51:32 +0000 (UTC) Received: from merkur.fritz.box (unknown [10.39.193.195]) by mx-prod-int-04.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id BF3DB19560AA; Wed, 22 Jan 2025 11:51:30 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1737546697; 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=eclF9e9zIzUicX4hqn+OMI1DBWFsq28pajQTP44/ZJI=; b=XakxvKkTtO8muYu2OT8QoYHwbTGbp5LNHz2bm1c5csGMPWIEcxrQcXvrJlR7uhexDFWISX nHB8zgYMeox4F+5HPfEVs5p7eUfvP+2nH3WISYgzmnBAH1IbULIGDiPuIPKXiPGGTEWeu4 Z0vcZ5lFJK6gBm3tzVs20Bvhp7qL1WU= X-MC-Unique: siAW2UWKOjqdTTn4fLMQ-w-1 X-Mimecast-MFC-AGG-ID: siAW2UWKOjqdTTn4fLMQ-w From: Kevin Wolf To: qemu-block@nongnu.org Cc: kwolf@redhat.com, hreitz@redhat.com, pkrempa@redhat.com, peterx@redhat.com, qemu-devel@nongnu.org Subject: [PATCH 7/9] block: Add blockdev-set-active QMP command Date: Wed, 22 Jan 2025 12:50:44 +0100 Message-ID: <20250122115046.51216-8-kwolf@redhat.com> In-Reply-To: <20250122115046.51216-1-kwolf@redhat.com> References: <20250122115046.51216-1-kwolf@redhat.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 3.0 on 10.30.177.40 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=kwolf@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -50 X-Spam_score: -5.1 X-Spam_bar: ----- X-Spam_report: (-5.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-2.996, 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_H5=0.001, RCVD_IN_MSPIKE_WL=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, SPF_HELO_NONE=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: 1737546815811019000 Content-Type: text/plain; charset="utf-8" The system emulator tries to automatically activate and inactivate block nodes at the right point during migration. However, there are still cases where it's necessary that the user can do this manually. Images are only activated on the destination VM of a migration when the VM is actually resumed. If the VM was paused, this doesn't happen automatically. The user may want to perform some operation on a block device (e.g. taking a snapshot or starting a block job) without also resuming the VM yet. This is an example where a manual command is necessary. Another example is VM migration when the image files are opened by an external qemu-storage-daemon instance on each side. In this case, the process that needs to hand over the images isn't even part of the migration and can't know when the migration completes. Management tools need a way to explicitly inactivate images on the source and activate them on the destination. This adds a new blockdev-set-active QMP command that lets the user change the status of individual nodes (this is necessary in qemu-storage-daemon because it could be serving multiple VMs and only one of them migrates at a time). For convenience, operating on all devices (like QEMU does automatically during migration) is offered as an option, too, and can be used in the context of single VM. Signed-off-by: Kevin Wolf --- qapi/block-core.json | 32 ++++++++++++++++++++++++++++++ include/block/block-global-state.h | 3 +++ block.c | 21 ++++++++++++++++++++ blockdev.c | 32 ++++++++++++++++++++++++++++++ 4 files changed, 88 insertions(+) diff --git a/qapi/block-core.json b/qapi/block-core.json index 5bc164dbed..39c675a036 100644 --- a/qapi/block-core.json +++ b/qapi/block-core.json @@ -4941,6 +4941,38 @@ { 'command': 'blockdev-del', 'data': { 'node-name': 'str' }, 'allow-preconfig': true } =20 +## +# @blockdev-set-active: +# +# Activate or inactive a block device. Use this to manage the handover of = block +# devices on migration with qemu-storage-daemon. +# +# Activating a node automatically activates all of its child nodes first. +# Inactivating a node automatically inactivates any of its child nodes tha= t are +# not in use by a still active node. +# +# @node-name: Name of the graph node to activate or inactivate. By default= , all +# nodes are affected by the operation. +# +# @active: true if the nodes should be active when the command returns suc= cess, +# false if they should be inactive. +# +# Since: 10.0 +# +# .. qmp-example:: +# +# -> { "execute": "blockdev-set-active", +# "arguments": { +# "node-name": "node0", +# "active": false +# } +# } +# <- { "return": {} } +## +{ 'command': 'blockdev-set-active', + 'data': { '*node-name': 'str', 'active': 'bool' }, + 'allow-preconfig': true } + ## # @BlockdevCreateOptionsFile: # diff --git a/include/block/block-global-state.h b/include/block/block-globa= l-state.h index a826bf5f78..9be34b3c99 100644 --- a/include/block/block-global-state.h +++ b/include/block/block-global-state.h @@ -184,6 +184,9 @@ bdrv_activate(BlockDriverState *bs, Error **errp); int coroutine_fn no_co_wrapper_bdrv_rdlock bdrv_co_activate(BlockDriverState *bs, Error **errp); =20 +int no_coroutine_fn +bdrv_inactivate(BlockDriverState *bs, Error **errp); + void bdrv_activate_all(Error **errp); int bdrv_inactivate_all(void); =20 diff --git a/block.c b/block.c index 76cddd6757..ebb6a7baeb 100644 --- a/block.c +++ b/block.c @@ -7040,6 +7040,27 @@ bdrv_inactivate_recurse(BlockDriverState *bs, bool t= op_level) return 0; } =20 +int bdrv_inactivate(BlockDriverState *bs, Error **errp) +{ + int ret; + + GLOBAL_STATE_CODE(); + GRAPH_RDLOCK_GUARD_MAINLOOP(); + + if (bdrv_has_bds_parent(bs, true)) { + error_setg(errp, "Node has active parent node"); + return -EPERM; + } + + ret =3D bdrv_inactivate_recurse(bs, true); + if (ret < 0) { + error_setg_errno(errp, -ret, "Failed to inactivate node"); + return ret; + } + + return 0; +} + int bdrv_inactivate_all(void) { BlockDriverState *bs =3D NULL; diff --git a/blockdev.c b/blockdev.c index 218024497b..874cef0299 100644 --- a/blockdev.c +++ b/blockdev.c @@ -3455,6 +3455,38 @@ void qmp_blockdev_del(const char *node_name, Error *= *errp) bdrv_unref(bs); } =20 +void qmp_blockdev_set_active(const char *node_name, bool active, Error **e= rrp) +{ + int ret; + + GLOBAL_STATE_CODE(); + GRAPH_RDLOCK_GUARD_MAINLOOP(); + + if (!node_name) { + if (active) { + bdrv_activate_all(errp); + } else { + ret =3D bdrv_inactivate_all(); + if (ret < 0) { + error_setg_errno(errp, -ret, "Failed to inactivate all nod= es"); + } + } + } else { + BlockDriverState *bs =3D bdrv_find_node(node_name); + if (!bs) { + error_setg(errp, "Failed to find node with node-name=3D'%s'", + node_name); + return; + } + + if (active) { + bdrv_activate(bs, errp); + } else { + bdrv_inactivate(bs, errp); + } + } +} + static BdrvChild * GRAPH_RDLOCK bdrv_find_child(BlockDriverState *parent_bs, const char *child_name) { --=20 2.48.1