From nobody Sun Sep 28 16:28:08 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=1758645541; cv=none; d=zohomail.com; s=zohoarc; b=VV9PKp7mb+JE4NkZonoARKz8PtfbbPDUdeu5mdhnb7NgBU8ee3KXI5njVe97CdsZjaqtOUh4soLZCG890/uP5oY5SYgcOikyT957fZf72UI4xu4UZzrKWzLnSqltw9gAcU+Vs5Zw3x4ItUiFKMd2UdorT8LbUgoCa8gX+GV0qP0= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1758645541; 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=Y+ywBNmpuSKsYD4JIXq1tBOOTOsTd7MaPXqk8fbBL9s=; b=iUrOfoUOSB5WGunTyv5GIwdRlPa8kXnu3ecT43ZXblFb3ylwFeEJr0nN63/UVRarm7DHMzXVsFcr6fJpZwGOIaIbF7ff6aeg97ZGBBvsTT1K00aLWCXwor7l63hoPizNMPwo9FE96hfKAwh4FxOwIRaWEjywlEZ+0i9twheQUT8= 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 1758645541487251.39683710490795; Tue, 23 Sep 2025 09:39:01 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1v161Y-00066K-C3; Tue, 23 Sep 2025 12:37:52 -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 1v161W-00065D-Ic for qemu-devel@nongnu.org; Tue, 23 Sep 2025 12:37:50 -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 1v161T-0007bQ-Gh for qemu-devel@nongnu.org; Tue, 23 Sep 2025 12:37:50 -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-119-69obEIOUOKigr1z_WGSTkQ-1; Tue, 23 Sep 2025 12:37:44 -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 25B86195608B; Tue, 23 Sep 2025 16:37:43 +0000 (UTC) Received: from merkur.redhat.com (unknown [10.45.224.18]) by mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 261523000198; Tue, 23 Sep 2025 16:37:40 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1758645465; 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=Y+ywBNmpuSKsYD4JIXq1tBOOTOsTd7MaPXqk8fbBL9s=; b=JMMAj2hW763Znd02eMRTKIrwD++TfvcGKCFlyU05swGIRecY6jJbRA7MR+RJ6NXCP3fBsu SRw90WeLxkPBiHXHGPZ/UXnuWmcdndvStkeDpjAZNsCFcbO6s4OJwaJweWhfq9+UdPfCUj WaFeK2yj+R87PXP1H//BtFwfvoI1yus= X-MC-Unique: 69obEIOUOKigr1z_WGSTkQ-1 X-Mimecast-MFC-AGG-ID: 69obEIOUOKigr1z_WGSTkQ_1758645463 From: Kevin Wolf To: qemu-block@nongnu.org Cc: kwolf@redhat.com, hreitz@redhat.com, eblake@redhat.com, qemu-devel@nongnu.org Subject: [PATCH 1/2] block: Expose block limits for images in QMP Date: Tue, 23 Sep 2025 18:37:34 +0200 Message-ID: <20250923163735.378254-2-kwolf@redhat.com> In-Reply-To: <20250923163735.378254-1-kwolf@redhat.com> References: <20250923163735.378254-1-kwolf@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.129.124; envelope-from=kwolf@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.442, 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_H4=0.001, RCVD_IN_MSPIKE_WL=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_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: 1758645542904154100 Content-Type: text/plain; charset="utf-8" This information can be useful both for debugging and for management tools trying to configure guest devices with the optimal limits (possibly across multiple hosts). There is no reason not to make it available, so just add it to BlockNodeInfo. Signed-off-by: Kevin Wolf Reviewed-by: Eric Blake --- qapi/block-core.json | 59 ++++++++++++++++++++++++++++++++ block/qapi.c | 34 ++++++++++++++++-- tests/qemu-iotests/184 | 3 +- tests/qemu-iotests/184.out | 8 ----- tests/qemu-iotests/common.filter | 3 +- 5 files changed, 94 insertions(+), 13 deletions(-) diff --git a/qapi/block-core.json b/qapi/block-core.json index dc6eb4ae23..eda041ac1c 100644 --- a/qapi/block-core.json +++ b/qapi/block-core.json @@ -275,6 +275,62 @@ 'file': 'ImageInfoSpecificFileWrapper' } } =20 +## +# @BlockLimitsInfo: +# +# @request-alignment: Alignment requirement, in bytes, for offset/length o= f I/O +# requests. +# +# @max-discard: Maximum number of bytes that can be discarded at once. If = not +# present, there is no specific maximum. +# +# @discard-alignment: Optimal alignment for discard requests in bytes. A p= ower +# of 2 is best, but not mandatory. If not present, discards don't have= a +# alignment requirement different from @request-alignment. +# +# @max-write-zeroes: Maximum number of bytes that can be zeroed out at onc= e. If +# not present, there is no specific maximum. +# +# @write-zeroes-alignment: Optimal alignment for write_zeroes requests in +# bytes. A power of 2 is best, but not mandatory. If not present, +# write_zeroes doesn't have a alignment requirement different from +# @request-alignment. +# +# @opt-transfer: Optimal transfer length in bytes. If not present, there i= s no +# preferred size. +# +# @max-transfer: Maximal transfer length in bytes. If not present, there i= s no +# specific maximum. +# +# @max-hw-transfer: Maximal hardware transfer length in bytes. Applies +# whenever transfers to the device bypass the kernel I/O scheduler, for +# example with SG_IO. If not present, there is no specific maximum. +# +# @max-iov: Maximum number of scatter/gather elements +# +# @max-hw-iov: Maximal number of scatter/gather elements allowed by the ha= rdware. +# Applies whenever transfers to the device bypass the kernel I/O sched= uler, +# for example with SG_IO. If not present, the hardware limits is unkno= wn +# and @max-iov is always used. +# +# @min-mem-alignment: memory alignment in bytes so that no bounce buffer i= s needed +# +# @opt-mem-alignment: memory alignment in bytes that is used for bounce bu= ffers +## +{ 'struct': 'BlockLimitsInfo', + 'data': { 'request-alignment': 'uint32', + '*max-discard': 'uint64', + '*discard-alignment': 'uint32', + '*max-write-zeroes': 'uint64', + '*write-zeroes-alignment': 'uint32', + '*opt-transfer': 'uint32', + '*max-transfer': 'uint32', + '*max-hw-transfer': 'uint32', + 'max-iov': 'int', + '*max-hw-iov': 'int', + 'min-mem-alignment': 'size', + 'opt-mem-alignment': 'size' } } + ## # @BlockNodeInfo: # @@ -304,6 +360,8 @@ # # @snapshots: list of VM snapshots # +# @limits: block limits that are used for I/O on the node (Since 10.2) +# # @format-specific: structure supplying additional format-specific # information (since 1.7) # @@ -315,6 +373,7 @@ '*cluster-size': 'int', '*encrypted': 'bool', '*compressed': 'b= ool', '*backing-filename': 'str', '*full-backing-filename': 'str', '*backing-filename-format': 'str', '*snapshots': ['SnapshotInfo= '], + '*limits': 'BlockLimitsInfo', '*format-specific': 'ImageInfoSpecific' } } =20 ## diff --git a/block/qapi.c b/block/qapi.c index 12fbf8d1b7..54521d0a68 100644 --- a/block/qapi.c +++ b/block/qapi.c @@ -235,7 +235,8 @@ int bdrv_query_snapshot_info_list(BlockDriverState *bs, * in @info, setting @errp on error. */ static void GRAPH_RDLOCK -bdrv_do_query_node_info(BlockDriverState *bs, BlockNodeInfo *info, Error *= *errp) +bdrv_do_query_node_info(BlockDriverState *bs, BlockNodeInfo *info, bool li= mits, + Error **errp) { int64_t size; const char *backing_filename; @@ -269,6 +270,33 @@ bdrv_do_query_node_info(BlockDriverState *bs, BlockNod= eInfo *info, Error **errp) info->dirty_flag =3D bdi.is_dirty; info->has_dirty_flag =3D true; } + + if (limits) { + info->limits =3D g_new(BlockLimitsInfo, 1); + *info->limits =3D (BlockLimitsInfo) { + .request_alignment =3D bs->bl.request_alignment, + .has_max_discard =3D bs->bl.max_pdiscard !=3D 0, + .max_discard =3D bs->bl.max_pdiscard, + .has_discard_alignment =3D bs->bl.pdiscard_alignment !=3D= 0, + .discard_alignment =3D bs->bl.pdiscard_alignment, + .has_max_write_zeroes =3D bs->bl.max_pwrite_zeroes !=3D = 0, + .max_write_zeroes =3D bs->bl.max_pwrite_zeroes, + .has_write_zeroes_alignment =3D bs->bl.pwrite_zeroes_alignment= !=3D 0, + .write_zeroes_alignment =3D bs->bl.pwrite_zeroes_alignment, + .has_opt_transfer =3D bs->bl.opt_transfer !=3D 0, + .opt_transfer =3D bs->bl.opt_transfer, + .has_max_transfer =3D bs->bl.max_transfer !=3D 0, + .max_transfer =3D bs->bl.max_transfer, + .has_max_hw_transfer =3D bs->bl.max_hw_transfer !=3D 0, + .max_hw_transfer =3D bs->bl.max_hw_transfer, + .max_iov =3D bs->bl.max_iov, + .has_max_hw_iov =3D bs->bl.max_hw_iov !=3D 0, + .max_hw_iov =3D bs->bl.max_hw_iov, + .min_mem_alignment =3D bs->bl.min_mem_alignment, + .opt_mem_alignment =3D bs->bl.opt_mem_alignment, + }; + } + info->format_specific =3D bdrv_get_specific_info(bs, &err); if (err) { error_propagate(errp, err); @@ -343,7 +371,7 @@ void bdrv_query_image_info(BlockDriverState *bs, ImageInfo *info; =20 info =3D g_new0(ImageInfo, 1); - bdrv_do_query_node_info(bs, qapi_ImageInfo_base(info), errp); + bdrv_do_query_node_info(bs, qapi_ImageInfo_base(info), true, errp); if (*errp) { goto fail; } @@ -397,7 +425,7 @@ void bdrv_query_block_graph_info(BlockDriverState *bs, BdrvChild *c; =20 info =3D g_new0(BlockGraphInfo, 1); - bdrv_do_query_node_info(bs, qapi_BlockGraphInfo_base(info), errp); + bdrv_do_query_node_info(bs, qapi_BlockGraphInfo_base(info), false, err= p); if (*errp) { goto fail; } diff --git a/tests/qemu-iotests/184 b/tests/qemu-iotests/184 index e4cbcd8634..6d44bad59f 100755 --- a/tests/qemu-iotests/184 +++ b/tests/qemu-iotests/184 @@ -46,7 +46,8 @@ do_run_qemu() run_qemu() { do_run_qemu "$@" 2>&1 | _filter_testdir | _filter_qemu | _filter_qmp\ - | _filter_qemu_io | _filter_generated_node_ids + | _filter_qemu_io | _filter_generated_node_ids \ + | _filter_img_info } =20 test_throttle=3D$($QEMU_IMG --help|grep throttle) diff --git a/tests/qemu-iotests/184.out b/tests/qemu-iotests/184.out index ef99bb2e9a..52692b6b3b 100644 --- a/tests/qemu-iotests/184.out +++ b/tests/qemu-iotests/184.out @@ -41,12 +41,6 @@ Testing: }, "iops_wr": 0, "ro": false, - "children": [ - { - "node-name": "disk0", - "child": "file" - } - ], "node-name": "throttle0", "backing_file_depth": 1, "drv": "throttle", @@ -75,8 +69,6 @@ Testing: }, "iops_wr": 0, "ro": false, - "children": [ - ], "node-name": "disk0", "backing_file_depth": 0, "drv": "null-co", diff --git a/tests/qemu-iotests/common.filter b/tests/qemu-iotests/common.f= ilter index 511a55b1e8..26e6b45b04 100644 --- a/tests/qemu-iotests/common.filter +++ b/tests/qemu-iotests/common.filter @@ -229,6 +229,7 @@ _filter_img_info() discard=3D0 regex_json_spec_start=3D'^ *"format-specific": \{' regex_json_child_start=3D'^ *"children": \[' + regex_json_limit_start=3D'^ *"limits": \{' gsed -e "s#$REMOTE_TEST_DIR#TEST_DIR#g" \ -e "s#$IMGPROTO:$TEST_DIR#TEST_DIR#g" \ -e "s#$TEST_DIR#TEST_DIR#g" \ @@ -261,7 +262,7 @@ _filter_img_info() discard=3D1 elif [[ $line =3D~ "Child node '/" ]]; then discard=3D1 - elif [[ $line =3D~ $regex_json_spec_start ]]; then + elif [[ $line =3D~ $regex_json_spec_start || $line =3D~ $regex= _json_limit_start ]]; then discard=3D2 regex_json_end=3D"^${line%%[^ ]*}\\},? *$" elif [[ $line =3D~ $regex_json_child_start ]]; then --=20 2.51.0 From nobody Sun Sep 28 16:28:08 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=1758645515; cv=none; d=zohomail.com; s=zohoarc; b=VZBl4YFt4SOXnu3Y1/XQkjYAG7NmwlHclxaxRA6DSWN6NwzrOMba7AIJ+bxupEuRNu2h5GZqsOR4KjfmVaIhfKJH5utXZcVQ/0rf4uDtnoI8bVEPxGpNqOWZCodIzgfqXkH7BaWS2UHkCBDhnn0Y6ghKQ6KkT/YKt2ZsxYx6SnA= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1758645515; 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=nUIsHhG8I2IxSrJHkmZVdDZYaN0KdI35c/W+eoN1P10=; b=gaP8V0uw7qDm7bnhvlItulnPe2/yGKAj0WLnENtU0ft4+Di8cgkyfYEbatCm6hW22pOz4rwUChdfWX2FEDEAfCvVcMi80Y6JQl9K5XiPe9POJkbj1s9QbRU5LzkaQihebA1vmJYAChXDyvwtOzs+r/bwKo9vbX09AuHkpDvNdKM= 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 1758645515819712.2924703681524; Tue, 23 Sep 2025 09:38:35 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1v161b-00067D-P1; Tue, 23 Sep 2025 12:37:55 -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 1v161Y-00066P-NT for qemu-devel@nongnu.org; Tue, 23 Sep 2025 12:37:52 -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 1v161W-0007c4-JC for qemu-devel@nongnu.org; Tue, 23 Sep 2025 12:37:52 -0400 Received: from mx-prod-mc-02.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-669-YDd-o6OUOymVzek4PilBNQ-1; Tue, 23 Sep 2025 12:37:46 -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-02.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 496571956087; Tue, 23 Sep 2025 16:37:45 +0000 (UTC) Received: from merkur.redhat.com (unknown [10.45.224.18]) by mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 802D4300018D; Tue, 23 Sep 2025 16:37:43 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1758645469; 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=nUIsHhG8I2IxSrJHkmZVdDZYaN0KdI35c/W+eoN1P10=; b=UkHsOXXeftlWmnDGIDWVpR7GqCgygyksEASu+1E4VajsSlEKKrgk0fJfvpfX5aqH799dqr DyLg8+ROnmUv4pubRCg4NkNJt3eLhOYJ/awgyiWwQ16riy91fLuiSjCChpro6LC2guf3JA 9htAu0mbxJcd4NcSSbt6uYLX/37bY9k= X-MC-Unique: YDd-o6OUOymVzek4PilBNQ-1 X-Mimecast-MFC-AGG-ID: YDd-o6OUOymVzek4PilBNQ_1758645465 From: Kevin Wolf To: qemu-block@nongnu.org Cc: kwolf@redhat.com, hreitz@redhat.com, eblake@redhat.com, qemu-devel@nongnu.org Subject: [PATCH 2/2] qemu-img info: Optionally show block limits Date: Tue, 23 Sep 2025 18:37:35 +0200 Message-ID: <20250923163735.378254-3-kwolf@redhat.com> In-Reply-To: <20250923163735.378254-1-kwolf@redhat.com> References: <20250923163735.378254-1-kwolf@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.129.124; envelope-from=kwolf@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.442, 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_H4=0.001, RCVD_IN_MSPIKE_WL=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_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: 1758645518511154100 Content-Type: text/plain; charset="utf-8" Add a new --limits option to 'qemu-img info' that displays the block limits for the image and all of its children, making the information more accessible for human users than in QMP. This option is not enabled by default because it can be a lot of output that isn't usually relevant if you're not specifically trying to diagnose some I/O problem. This makes the same information automatically also available in HMP 'info block -v'. Signed-off-by: Kevin Wolf Reviewed-by: Eric Blake --- docs/tools/qemu-img.rst | 6 +++++- include/block/qapi.h | 2 +- block/qapi.c | 34 ++++++++++++++++++++++++++++++++-- qemu-img.c | 15 ++++++++++++--- qemu-img-cmds.hx | 4 ++-- 5 files changed, 52 insertions(+), 9 deletions(-) diff --git a/docs/tools/qemu-img.rst b/docs/tools/qemu-img.rst index 5e7b85079d..fdc9ea9cf2 100644 --- a/docs/tools/qemu-img.rst +++ b/docs/tools/qemu-img.rst @@ -503,7 +503,7 @@ Command description: =20 The size syntax is similar to :manpage:`dd(1)`'s size syntax. =20 -.. option:: info [--object OBJECTDEF] [--image-opts] [-f FMT] [--output=3D= OFMT] [--backing-chain] [-U] FILENAME +.. option:: info [--object OBJECTDEF] [--image-opts] [-f FMT] [--output=3D= OFMT] [--backing-chain] [--limits] [-U] FILENAME =20 Give information about the disk image *FILENAME*. Use it in particular to know the size reserved on disk which can be different @@ -571,6 +571,10 @@ Command description: ``ImageInfoSpecific*`` QAPI object (e.g. ``ImageInfoSpecificQCow2`` for qcow2 images). =20 + *Block limits* + The block limits for I/O that QEMU detected for the image. + This information is only shown if the ``--limits`` option was specifie= d. + .. option:: map [--object OBJECTDEF] [--image-opts] [-f FMT] [--start-offs= et=3DOFFSET] [--max-length=3DLEN] [--output=3DOFMT] [-U] FILENAME =20 Dump the metadata of image *FILENAME* and its backing file chain. diff --git a/include/block/qapi.h b/include/block/qapi.h index 54c48de26a..be554e53dc 100644 --- a/include/block/qapi.h +++ b/include/block/qapi.h @@ -42,7 +42,7 @@ bdrv_query_image_info(BlockDriverState *bs, ImageInfo **p= _info, bool flat, bool skip_implicit_filters, Error **errp); void GRAPH_RDLOCK bdrv_query_block_graph_info(BlockDriverState *bs, BlockGraphInfo **p_info, - Error **errp); + bool limits, Error **errp); =20 void bdrv_snapshot_dump(QEMUSnapshotInfo *sn); void bdrv_image_info_specific_dump(ImageInfoSpecific *info_spec, diff --git a/block/qapi.c b/block/qapi.c index 54521d0a68..9f5771e019 100644 --- a/block/qapi.c +++ b/block/qapi.c @@ -417,6 +417,7 @@ fail: */ void bdrv_query_block_graph_info(BlockDriverState *bs, BlockGraphInfo **p_info, + bool limits, Error **errp) { ERRP_GUARD(); @@ -425,7 +426,7 @@ void bdrv_query_block_graph_info(BlockDriverState *bs, BdrvChild *c; =20 info =3D g_new0(BlockGraphInfo, 1); - bdrv_do_query_node_info(bs, qapi_BlockGraphInfo_base(info), false, err= p); + bdrv_do_query_node_info(bs, qapi_BlockGraphInfo_base(info), limits, er= rp); if (*errp) { goto fail; } @@ -439,7 +440,7 @@ void bdrv_query_block_graph_info(BlockDriverState *bs, QAPI_LIST_APPEND(children_list_tail, c_info); =20 c_info->name =3D g_strdup(c->name); - bdrv_query_block_graph_info(c->bs, &c_info->info, errp); + bdrv_query_block_graph_info(c->bs, &c_info->info, limits, errp); if (*errp) { goto fail; } @@ -936,6 +937,29 @@ void bdrv_image_info_specific_dump(ImageInfoSpecific *= info_spec, visit_free(v); } =20 +/** + * Dumps the given BlockLimitsInfo object in a human-readable form, + * prepending an optional prefix if the dump is not empty. + */ +static void bdrv_image_info_limits_dump(BlockLimitsInfo *limits, + const char *prefix, + int indentation) +{ + QObject *obj; + Visitor *v =3D qobject_output_visitor_new(&obj); + + visit_type_BlockLimitsInfo(v, NULL, &limits, &error_abort); + visit_complete(v, &obj); + if (!qobject_is_empty_dump(obj)) { + if (prefix) { + qemu_printf("%*s%s", indentation * 4, "", prefix); + } + dump_qobject(indentation + 1, obj); + } + qobject_unref(obj); + visit_free(v); +} + /** * Print the given @info object in human-readable form. Every field is in= dented * using the given @indentation (four spaces per indentation level). @@ -1011,6 +1035,12 @@ void bdrv_node_info_dump(BlockNodeInfo *info, int in= dentation, bool protocol) } } =20 + if (info->limits) { + bdrv_image_info_limits_dump(info->limits, + "Block limits:\n", + indentation); + } + if (info->has_snapshots) { SnapshotInfoList *elem; =20 diff --git a/qemu-img.c b/qemu-img.c index 7a162fdc08..5cdbeda969 100644 --- a/qemu-img.c +++ b/qemu-img.c @@ -86,6 +86,7 @@ enum { OPTION_BITMAPS =3D 275, OPTION_FORCE =3D 276, OPTION_SKIP_BROKEN =3D 277, + OPTION_LIMITS =3D 278, }; =20 typedef enum OutputFormat { @@ -3002,7 +3003,8 @@ static gboolean str_equal_func(gconstpointer a, gcons= tpointer b) static BlockGraphInfoList *collect_image_info_list(bool image_opts, const char *filename, const char *fmt, - bool chain, bool force_= share) + bool chain, bool limits, + bool force_share) { BlockGraphInfoList *head =3D NULL; BlockGraphInfoList **tail =3D &head; @@ -3039,7 +3041,7 @@ static BlockGraphInfoList *collect_image_info_list(bo= ol image_opts, * the chain manually here. */ bdrv_graph_rdlock_main_loop(); - bdrv_query_block_graph_info(bs, &info, &err); + bdrv_query_block_graph_info(bs, &info, limits, &err); bdrv_graph_rdunlock_main_loop(); =20 if (err) { @@ -3088,6 +3090,7 @@ static int img_info(const img_cmd_t *ccmd, int argc, = char **argv) BlockGraphInfoList *list; bool image_opts =3D false; bool force_share =3D false; + bool limits =3D false; =20 fmt =3D NULL; for(;;) { @@ -3097,6 +3100,7 @@ static int img_info(const img_cmd_t *ccmd, int argc, = char **argv) {"image-opts", no_argument, 0, OPTION_IMAGE_OPTS}, {"backing-chain", no_argument, 0, OPTION_BACKING_CHAIN}, {"force-share", no_argument, 0, 'U'}, + {"limits", no_argument, 0, OPTION_LIMITS}, {"output", required_argument, 0, OPTION_OUTPUT}, {"object", required_argument, 0, OPTION_OBJECT}, {0, 0, 0, 0} @@ -3119,6 +3123,8 @@ static int img_info(const img_cmd_t *ccmd, int argc, = char **argv) " display information about the backing chain for copy-on-write overla= ys\n" " -U, --force-share\n" " open image in shared mode for concurrent access\n" +" --limits\n" +" show detected block limits (may depend on options, e.g. cache mode)\= n" " --output human|json\n" " specify output format (default: human)\n" " --object OBJDEF\n" @@ -3140,6 +3146,9 @@ static int img_info(const img_cmd_t *ccmd, int argc, = char **argv) case 'U': force_share =3D true; break; + case OPTION_LIMITS: + limits =3D true; + break; case OPTION_OUTPUT: output_format =3D parse_output_format(argv[0], optarg); break; @@ -3156,7 +3165,7 @@ static int img_info(const img_cmd_t *ccmd, int argc, = char **argv) filename =3D argv[optind++]; =20 list =3D collect_image_info_list(image_opts, filename, fmt, chain, - force_share); + limits, force_share); if (!list) { return 1; } diff --git a/qemu-img-cmds.hx b/qemu-img-cmds.hx index 2c5a8a28f9..74b66f9d42 100644 --- a/qemu-img-cmds.hx +++ b/qemu-img-cmds.hx @@ -66,9 +66,9 @@ SRST ERST =20 DEF("info", img_info, - "info [--object objectdef] [--image-opts] [-f fmt] [--output=3Dofmt] [= --backing-chain] [-U] filename") + "info [--object objectdef] [--image-opts] [-f fmt] [--output=3Dofmt] [= --backing-chain] [--limits] [-U] filename") SRST -.. option:: info [--object OBJECTDEF] [--image-opts] [-f FMT] [--output=3D= OFMT] [--backing-chain] [-U] FILENAME +.. option:: info [--object OBJECTDEF] [--image-opts] [-f FMT] [--output=3D= OFMT] [--backing-chain] [--limits] [-U] FILENAME ERST =20 DEF("map", img_map, --=20 2.51.0