From nobody Wed Nov 5 07:39:42 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.gnu.org (208.118.235.17 [208.118.235.17]) by mx.zohomail.com with SMTPS id 1533918541958500.6644119127794; Fri, 10 Aug 2018 09:29:01 -0700 (PDT) Received: from localhost ([::1]:57206 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1foAHW-0000JN-2F for importer@patchew.org; Fri, 10 Aug 2018 12:28:54 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:48294) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1foAFu-0007eH-TL for qemu-devel@nongnu.org; Fri, 10 Aug 2018 12:27:16 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1foAFt-0004wi-Sr for qemu-devel@nongnu.org; Fri, 10 Aug 2018 12:27:14 -0400 Received: from mx3-rdu2.redhat.com ([66.187.233.73]:48522 helo=mx1.redhat.com) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1foAFn-0004j3-I8; Fri, 10 Aug 2018 12:27:07 -0400 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.rdu2.redhat.com [10.11.54.5]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 27A9A819703B; Fri, 10 Aug 2018 16:27:07 +0000 (UTC) Received: from localhost.localdomain.com (ovpn-117-117.ams2.redhat.com [10.36.117.117]) by smtp.corp.redhat.com (Postfix) with ESMTP id DD88C7C54; Fri, 10 Aug 2018 16:27:05 +0000 (UTC) From: Kevin Wolf To: qemu-block@nongnu.org Date: Fri, 10 Aug 2018 18:26:57 +0200 Message-Id: <20180810162658.6562-2-kwolf@redhat.com> In-Reply-To: <20180810162658.6562-1-kwolf@redhat.com> References: <20180810162658.6562-1-kwolf@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.11.54.5 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.8]); Fri, 10 Aug 2018 16:27:07 +0000 (UTC) X-Greylist: inspected by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.8]); Fri, 10 Aug 2018 16:27:07 +0000 (UTC) for IP:'10.11.54.5' DOMAIN:'int-mx05.intmail.prod.int.rdu2.redhat.com' HELO:'smtp.corp.redhat.com' FROM:'kwolf@redhat.com' RCPT:'' X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 66.187.233.73 Subject: [Qemu-devel] [PATCH 1/2] commit: Add top-node/base-node options X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: kwolf@redhat.com, pkrempa@redhat.com, qemu-devel@nongnu.org, mreitz@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RDMRC_1 RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" The block-commit QMP command required specifying the top and base nodes of the commit jobs using the file name of that node. While this works in simple cases (local files with absolute paths), the file names generated for more complicated setups can be hard to predict. This adds two new options top-node and base-node to the command, which allow specifying node names instead. They are mutually exclusive with the old options. Signed-off-by: Kevin Wolf --- qapi/block-core.json | 24 ++++++++++++++++++------ blockdev.c | 32 ++++++++++++++++++++++++++++++-- 2 files changed, 48 insertions(+), 8 deletions(-) diff --git a/qapi/block-core.json b/qapi/block-core.json index 5b9084a394..91dd075c84 100644 --- a/qapi/block-core.json +++ b/qapi/block-core.json @@ -1455,12 +1455,23 @@ # # @device: the device name or node-name of a root node # -# @base: The file name of the backing image to write data into. -# If not specified, this is the deepest backing image. +# @base-node: The node name of the backing image to write data into. +# If not specified, this is the deepest backing image. +# (since: 2.10) # -# @top: The file name of the backing image within the image chain, -# which contains the topmost data to be committed down.= If -# not specified, this is the active layer. +# @base: Same as @base-node, except that it is a file name rather than a n= ode +# name. This must be the exact filename string that was used to ope= n the +# node; other strings, even if addressing the same file, are not +# accepted (deprecated, use @base-node instead) +# +# @top-node: The node name of the backing image within the image chain +# which contains the topmost data to be committed down. If +# not specified, this is the active layer. (since: 2.10) +# +# @top: Same as @top-node, except that it is a file name rather than a node +# name. This must be the exact filename string that was used to open= the +# node; other strings, even if addressing the same file, are not +# accepted (deprecated, use @base-node instead) # # @backing-file: The backing file string to write into the overlay # image of 'top'. If 'top' is the active layer, @@ -1516,7 +1527,8 @@ # ## { 'command': 'block-commit', - 'data': { '*job-id': 'str', 'device': 'str', '*base': 'str', '*top': 'st= r', + 'data': { '*job-id': 'str', 'device': 'str', '*base-node': 'str', + '*base': 'str', '*top-node': 'str', '*top': 'str', '*backing-file': 'str', '*speed': 'int', '*filter-node-name': 'str' } } =20 diff --git a/blockdev.c b/blockdev.c index dcf8c8d2ab..064c8fb3f5 100644 --- a/blockdev.c +++ b/blockdev.c @@ -3308,7 +3308,9 @@ out: } =20 void qmp_block_commit(bool has_job_id, const char *job_id, const char *dev= ice, + bool has_base_node, const char *base_node, bool has_base, const char *base, + bool has_top_node, const char *top_node, bool has_top, const char *top, bool has_backing_file, const char *backing_file, bool has_speed, int64_t speed, @@ -3360,7 +3362,20 @@ void qmp_block_commit(bool has_job_id, const char *j= ob_id, const char *device, /* default top_bs is the active layer */ top_bs =3D bs; =20 - if (has_top && top) { + if (has_top_node && has_top) { + error_setg(errp, "'top-node' and 'top' are mutually exclusive"); + goto out; + } else if (has_top_node) { + top_bs =3D bdrv_lookup_bs(NULL, top_node, errp); + if (top_bs =3D=3D NULL) { + goto out; + } + if (!bdrv_chain_contains(bs, top_bs)) { + error_setg(errp, "'%s' is not in this backing file chain", + top_node); + goto out; + } + } else if (has_top && top) { if (strcmp(bs->filename, top) !=3D 0) { top_bs =3D bdrv_find_backing_image(bs, top); } @@ -3373,7 +3388,20 @@ void qmp_block_commit(bool has_job_id, const char *j= ob_id, const char *device, =20 assert(bdrv_get_aio_context(top_bs) =3D=3D aio_context); =20 - if (has_base && base) { + if (has_base_node && has_base) { + error_setg(errp, "'base-node' and 'base' are mutually exclusive"); + goto out; + } else if (has_base_node) { + base_bs =3D bdrv_lookup_bs(NULL, base_node, errp); + if (base_bs =3D=3D NULL) { + goto out; + } + if (!bdrv_chain_contains(top_bs, base_bs)) { + error_setg(errp, "'%s' is not in this backing file chain", + base_node); + goto out; + } + } else if (has_base && base) { base_bs =3D bdrv_find_backing_image(top_bs, base); } else { base_bs =3D bdrv_find_base(top_bs); --=20 2.13.6 From nobody Wed Nov 5 07:39:42 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1533918540507128.57910827398655; Fri, 10 Aug 2018 09:29:00 -0700 (PDT) Received: from localhost ([::1]:57207 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1foAHX-0000KT-7T for importer@patchew.org; Fri, 10 Aug 2018 12:28:55 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:48300) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1foAFv-0007eh-6I for qemu-devel@nongnu.org; Fri, 10 Aug 2018 12:27:16 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1foAFu-0004wv-0t for qemu-devel@nongnu.org; Fri, 10 Aug 2018 12:27:15 -0400 Received: from mx3-rdu2.redhat.com ([66.187.233.73]:52736 helo=mx1.redhat.com) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1foAFp-0004nq-4d; Fri, 10 Aug 2018 12:27:09 -0400 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.rdu2.redhat.com [10.11.54.5]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id AABA540200AC; Fri, 10 Aug 2018 16:27:08 +0000 (UTC) Received: from localhost.localdomain.com (ovpn-117-117.ams2.redhat.com [10.36.117.117]) by smtp.corp.redhat.com (Postfix) with ESMTP id 6E81B2315B; Fri, 10 Aug 2018 16:27:07 +0000 (UTC) From: Kevin Wolf To: qemu-block@nongnu.org Date: Fri, 10 Aug 2018 18:26:58 +0200 Message-Id: <20180810162658.6562-3-kwolf@redhat.com> In-Reply-To: <20180810162658.6562-1-kwolf@redhat.com> References: <20180810162658.6562-1-kwolf@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.11.54.5 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.6]); Fri, 10 Aug 2018 16:27:08 +0000 (UTC) X-Greylist: inspected by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.6]); Fri, 10 Aug 2018 16:27:08 +0000 (UTC) for IP:'10.11.54.5' DOMAIN:'int-mx05.intmail.prod.int.rdu2.redhat.com' HELO:'smtp.corp.redhat.com' FROM:'kwolf@redhat.com' RCPT:'' X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 66.187.233.73 Subject: [Qemu-devel] [PATCH 2/2] qemu-iotests: Test commit with top-node/base-node X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: kwolf@redhat.com, pkrempa@redhat.com, qemu-devel@nongnu.org, mreitz@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RDMRC_1 RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" This adds some tests for block-commit with the new options top-node and base-node (taking node names) instead of top and base (taking file names). Signed-off-by: Kevin Wolf --- tests/qemu-iotests/040 | 52 ++++++++++++++++++++++++++++++++++++++++++= ++-- tests/qemu-iotests/040.out | 4 ++-- 2 files changed, 52 insertions(+), 4 deletions(-) diff --git a/tests/qemu-iotests/040 b/tests/qemu-iotests/040 index 1beb5e6dab..1cb1ceeb33 100755 --- a/tests/qemu-iotests/040 +++ b/tests/qemu-iotests/040 @@ -57,9 +57,12 @@ class ImageCommitTestCase(iotests.QMPTestCase): self.assert_no_active_block_jobs() self.vm.shutdown() =20 - def run_commit_test(self, top, base, need_ready=3DFalse): + def run_commit_test(self, top, base, need_ready=3DFalse, node_names=3D= False): self.assert_no_active_block_jobs() - result =3D self.vm.qmp('block-commit', device=3D'drive0', top=3Dto= p, base=3Dbase) + if node_names: + result =3D self.vm.qmp('block-commit', device=3D'drive0', top_= node=3Dtop, base_node=3Dbase) + else: + result =3D self.vm.qmp('block-commit', device=3D'drive0', top= =3Dtop, base=3Dbase) self.assert_qmp(result, 'return', {}) self.wait_for_complete(need_ready) =20 @@ -101,6 +104,11 @@ class TestSingleDrive(ImageCommitTestCase): self.assertEqual(-1, qemu_io('-f', 'raw', '-c', 'read -P 0xab 0 52= 4288', backing_img).find("verification failed")) self.assertEqual(-1, qemu_io('-f', 'raw', '-c', 'read -P 0xef 5242= 88 524288', backing_img).find("verification failed")) =20 + def test_commit_node(self): + self.run_commit_test("mid", "base", node_names=3DTrue) + self.assertEqual(-1, qemu_io('-f', 'raw', '-c', 'read -P 0xab 0 52= 4288', backing_img).find("verification failed")) + self.assertEqual(-1, qemu_io('-f', 'raw', '-c', 'read -P 0xef 5242= 88 524288', backing_img).find("verification failed")) + def test_device_not_found(self): result =3D self.vm.qmp('block-commit', device=3D'nonexistent', top= =3D'%s' % mid_img) self.assert_qmp(result, 'error/class', 'DeviceNotFound') @@ -123,6 +131,30 @@ class TestSingleDrive(ImageCommitTestCase): self.assert_qmp(result, 'error/class', 'GenericError') self.assert_qmp(result, 'error/desc', 'Base \'badfile\' not found') =20 + def test_top_node_invalid(self): + self.assert_no_active_block_jobs() + result =3D self.vm.qmp('block-commit', device=3D'drive0', top_node= =3D'badfile', base_node=3D'base') + self.assert_qmp(result, 'error/class', 'GenericError') + self.assert_qmp(result, 'error/desc', "Cannot find device=3D nor n= ode_name=3Dbadfile") + + def test_base_node_invalid(self): + self.assert_no_active_block_jobs() + result =3D self.vm.qmp('block-commit', device=3D'drive0', top_node= =3D'mid', base_node=3D'badfile') + self.assert_qmp(result, 'error/class', 'GenericError') + self.assert_qmp(result, 'error/desc', "Cannot find device=3D nor n= ode_name=3Dbadfile") + + def test_top_path_and_node(self): + self.assert_no_active_block_jobs() + result =3D self.vm.qmp('block-commit', device=3D'drive0', top_node= =3D'mid', base_node=3D'base', top=3D'%s' % mid_img) + self.assert_qmp(result, 'error/class', 'GenericError') + self.assert_qmp(result, 'error/desc', "'top-node' and 'top' are mu= tually exclusive") + + def test_base_path_and_node(self): + self.assert_no_active_block_jobs() + result =3D self.vm.qmp('block-commit', device=3D'drive0', top_node= =3D'mid', base_node=3D'base', base=3D'%s' % backing_img) + self.assert_qmp(result, 'error/class', 'GenericError') + self.assert_qmp(result, 'error/desc', "'base-node' and 'base' are = mutually exclusive") + def test_top_is_active(self): self.run_commit_test(test_img, backing_img, need_ready=3DTrue) self.assertEqual(-1, qemu_io('-f', 'raw', '-c', 'read -P 0xab 0 52= 4288', backing_img).find("verification failed")) @@ -139,6 +171,22 @@ class TestSingleDrive(ImageCommitTestCase): self.assert_qmp(result, 'error/class', 'GenericError') self.assert_qmp(result, 'error/desc', 'Base \'%s\' not found' % mi= d_img) =20 + def test_top_and_base_node_reversed(self): + self.assert_no_active_block_jobs() + result =3D self.vm.qmp('block-commit', device=3D'drive0', top_node= =3D'base', base_node=3D'top') + self.assert_qmp(result, 'error/class', 'GenericError') + self.assert_qmp(result, 'error/desc', "'top' is not in this backin= g file chain") + + def test_top_node_in_wrong_chain(self): + self.assert_no_active_block_jobs() + + result =3D self.vm.qmp('blockdev-add', driver=3D'null-co', node_na= me=3D'null') + self.assert_qmp(result, 'return', {}) + + result =3D self.vm.qmp('block-commit', device=3D'drive0', top_node= =3D'null', base_node=3D'base') + self.assert_qmp(result, 'error/class', 'GenericError') + self.assert_qmp(result, 'error/desc', "'null' is not in this backi= ng file chain") + # When the job is running on a BB that is automatically deleted on hot # unplug, the job is cancelled when the device disappears def test_hot_unplug(self): diff --git a/tests/qemu-iotests/040.out b/tests/qemu-iotests/040.out index e20a75ce4f..802ffaa0c0 100644 --- a/tests/qemu-iotests/040.out +++ b/tests/qemu-iotests/040.out @@ -1,5 +1,5 @@ -............................. +........................................... ---------------------------------------------------------------------- -Ran 29 tests +Ran 43 tests =20 OK --=20 2.13.6