From nobody Fri May 10 21:30:07 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=fail; 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 ARC-Seal: i=1; a=rsa-sha256; t=1610715941; cv=none; d=zohomail.com; s=zohoarc; b=OVhhBTkC8TzKxbFT8Ydg/icKkC7xj4vyzx8WRnPIYedKIwTw1flr7xIW2W30gJzH7fSKUYELZoy0tYNK+ADCDc0MfMpMV0OKvc7RBNB+3JuFhqiodL3UH3w/f/nTv38tsfLi82yYbFObvpc1J/8fSpmNjnss8p+3JC3OXT4R2Y0= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1610715941; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=f8QA3U6Gnw8hWYP3Fzo72aiMuFKL6DyIS/zDdgwS/E4=; b=c0RzVZyKkKGfbcDyBe2xRS2LZTzmOeRFS1EJkwZcTWrTBPfBiP3NoxuSpMYfq9UrYX8CUwnGM0HtvaSN13OPeDFgKidviBYhx0vPoMOEYCVZI5xayVVv0fAh4yahXnjR1eSHZInqyJ42pQ3rYAyjPldOBt4OPSQmQmwac5zCMEs= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=fail; 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 Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1610715940852329.8283043083775; Fri, 15 Jan 2021 05:05:40 -0800 (PST) Received: from localhost ([::1]:44328 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1l0OnL-0003KD-K0 for importer@patchew.org; Fri, 15 Jan 2021 08:05:39 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:35730) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1l0Ol8-00022m-Q7; Fri, 15 Jan 2021 08:03:22 -0500 Received: from fanzine.igalia.com ([178.60.130.6]:44635) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1l0Ol3-0003wA-Sr; Fri, 15 Jan 2021 08:03:22 -0500 Received: from [213.94.31.64] (helo=perseus.local) by fanzine.igalia.com with esmtpsa (Cipher TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim) id 1l0Okg-0007Wc-NT; Fri, 15 Jan 2021 14:02:54 +0100 Received: from berto by perseus.local with local (Exim 4.92) (envelope-from ) id 1l0OkT-0003fm-RU; Fri, 15 Jan 2021 14:02:41 +0100 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=igalia.com; s=20170329; h=Content-Transfer-Encoding:MIME-Version:References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From; bh=f8QA3U6Gnw8hWYP3Fzo72aiMuFKL6DyIS/zDdgwS/E4=; b=AHPkMLkh5C7zLTGl323vm92LMfDZW+mwkoJyYQfYPk0qbhbs/MvpMjUGN7tKDyhw/0a2oqYmtpX1S8lpo7c8nG06S4TTO0l6ctfViV972TT3ErxsFslQtWggxDwumzDOYHO4QT/9S8JbOx4EHrzRK03jl2HFoSFnELH9VtYl9dNibfZgRBkki1evSdPNn1g9xdlBq/NZ1WAaUFq4V1SC1kESfNTr6rqv3qKaj0Jf4L3KIeMxERJg0zIvh1fTkqFNzZ7s8RVDW8aBX9YxbVMetmP6TisGcfXf57bSn0sJQaLMg28MEm/7e4F51wMJTAbeC+7af0luW2qwTR+WH0Hq3g==; From: Alberto Garcia To: qemu-devel@nongnu.org Subject: [RFC PATCH 1/2] block: Allow changing bs->file on reopen Date: Fri, 15 Jan 2021 14:02:37 +0100 Message-Id: <1a9b457d93c0732e8e4785a0cc4b5f3b935f2cf6.1610715661.git.berto@igalia.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable 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=178.60.130.6; envelope-from=berto@igalia.com; helo=fanzine.igalia.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, 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.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , Vladimir Sementsov-Ogievskiy , Alberto Garcia , qemu-block@nongnu.org, Kashyap Chamarthy , Max Reitz Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) Content-Type: text/plain; charset="utf-8" When the x-blockdev-reopen was added it allowed reconfiguring the graph by replacing backing files, but changing the 'file' option was forbidden. Because of this restriction some operations are not possible, notably inserting and removing block filters. This patch adds support for replacing the 'file' option. This is similar to replacing the backing file and the user is likewise responsible for the correctness of the resulting graph, otherwise this can lead to data corruption. Signed-off-by: Alberto Garcia --- include/block/block.h | 1 + block.c | 61 ++++++++++++++++++++++++++++++++++++++++++ tests/qemu-iotests/245 | 7 ++--- 3 files changed, 66 insertions(+), 3 deletions(-) diff --git a/include/block/block.h b/include/block/block.h index 82271d9ccd..6dd687a69e 100644 --- a/include/block/block.h +++ b/include/block/block.h @@ -196,6 +196,7 @@ typedef struct BDRVReopenState { bool backing_missing; bool replace_backing_bs; /* new_backing_bs is ignored if this is fals= e */ BlockDriverState *old_backing_bs; /* keep pointer for permissions upda= te */ + BlockDriverState *old_file_bs; /* keep pointer for permissions upda= te */ uint64_t perm, shared_perm; QDict *options; QDict *explicit_options; diff --git a/block.c b/block.c index 576b145cbf..114788e58e 100644 --- a/block.c +++ b/block.c @@ -3978,6 +3978,10 @@ int bdrv_reopen_multiple(BlockReopenQueue *bs_queue,= Error **errp) refresh_list =3D bdrv_topological_dfs(refresh_list, found, state->old_backing_bs); } + if (state->old_file_bs) { + refresh_list =3D bdrv_topological_dfs(refresh_list, found, + state->old_file_bs); + } } =20 ret =3D bdrv_list_refresh_perms(refresh_list, bs_queue, &tran, errp); @@ -4196,6 +4200,57 @@ static int bdrv_reopen_parse_backing(BDRVReopenState= *reopen_state, return 0; } =20 +static int bdrv_reopen_parse_file(BDRVReopenState *reopen_state, + GSList **tran, + Error **errp) +{ + BlockDriverState *bs =3D reopen_state->bs; + BlockDriverState *new_file_bs; + QObject *value; + const char *str; + + value =3D qdict_get(reopen_state->options, "file"); + if (value =3D=3D NULL) { + return 0; + } + + /* The 'file' option only allows strings */ + assert(qobject_type(value) =3D=3D QTYPE_QSTRING); + + str =3D qobject_get_try_str(value); + new_file_bs =3D bdrv_lookup_bs(NULL, str, errp); + if (new_file_bs =3D=3D NULL) { + return -EINVAL; + } else if (bdrv_recurse_has_child(new_file_bs, bs)) { + error_setg(errp, "Making '%s' a file of '%s' " + "would create a cycle", str, bs->node_name); + return -EINVAL; + } + + assert(bs->file && bs->file->bs); + + /* If 'file' points to the current child then there's nothing to do */ + if (bs->file->bs =3D=3D new_file_bs) { + return 0; + } + + /* Check AioContext compatibility */ + if (!bdrv_reopen_can_attach(bs, bs->file, new_file_bs, errp)) { + return -EINVAL; + } + + /* At the moment only backing links are frozen */ + assert(!bs->file->frozen); + + /* Store the old file bs because we'll need to refresh its permissions= */ + reopen_state->old_file_bs =3D bs->file->bs; + + /* And finally replace the child */ + bdrv_replace_child(bs->file, new_file_bs, tran); + + return 0; +} + /* * Prepares a BlockDriverState for reopen. All changes are staged in the * 'opaque' field of the BDRVReopenState, which is used and allocated by @@ -4347,6 +4402,12 @@ static int bdrv_reopen_prepare(BDRVReopenState *reop= en_state, } qdict_del(reopen_state->options, "backing"); =20 + ret =3D bdrv_reopen_parse_file(reopen_state, set_backings_tran, errp); + if (ret < 0) { + goto error; + } + qdict_del(reopen_state->options, "file"); + /* Options that are not handled are only okay if they are unchanged * compared to the old state. It is expected that some options are only * used for the initial open, but not reopen (e.g. filename) */ diff --git a/tests/qemu-iotests/245 b/tests/qemu-iotests/245 index e60c8326d3..f9d68b3958 100755 --- a/tests/qemu-iotests/245 +++ b/tests/qemu-iotests/245 @@ -145,8 +145,8 @@ class TestBlockdevReopen(iotests.QMPTestCase): self.reopen(opts, {'driver': 'raw'}, "Cannot change the option 'dr= iver'") self.reopen(opts, {'driver': ''}, "Invalid parameter ''") self.reopen(opts, {'driver': None}, "Invalid parameter type for 'd= river', expected: string") - self.reopen(opts, {'file': 'not-found'}, "Cannot change the option= 'file'") - self.reopen(opts, {'file': ''}, "Cannot change the option 'file'") + self.reopen(opts, {'file': 'not-found'}, "Cannot find device=3D no= r node_name=3Dnot-found") + self.reopen(opts, {'file': ''}, "Cannot find device=3D nor node_na= me=3D") self.reopen(opts, {'file': None}, "Invalid parameter type for 'fil= e', expected: BlockdevRef") self.reopen(opts, {'file.node-name': 'newname'}, "Cannot change th= e option 'node-name'") self.reopen(opts, {'file.driver': 'host_device'}, "Cannot change t= he option 'driver'") @@ -454,7 +454,8 @@ class TestBlockdevReopen(iotests.QMPTestCase): # More illegal operations self.reopen(opts[2], {'backing': 'hd1'}, "Making 'hd1' a backing file of 'hd2' would create a c= ycle") - self.reopen(opts[2], {'file': 'hd0-file'}, "Cannot change the opti= on 'file'") + self.reopen(opts[2], {'file': 'hd0-file'}, + "Conflicts with use by hd2 as 'file', which does not a= llow 'write, resize' on hd0-file") =20 result =3D self.vm.qmp('blockdev-del', conv_keys =3D True, node_na= me =3D 'hd2') self.assert_qmp(result, 'error/class', 'GenericError') --=20 2.20.1 From nobody Fri May 10 21:30:07 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=fail; 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 ARC-Seal: i=1; a=rsa-sha256; t=1610715964; cv=none; d=zohomail.com; s=zohoarc; b=eTLJnOON2WoiyfOmUdzt6OWb/gV9IulyDsnFakHyo3zEgX+YyLlmapvUkgQPCaoFMfofV5yMa6LRQlluzmjPvqD08YFDVV/VoFvrlUZPcDi8lpGghrF6S3JIQ0GIk76zkX2GUtIE5NCdZC6VOBcvd9EOghvoUVC2uFGh6M5XQYI= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1610715964; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=D/3jKyHLwJmlaYsfs930G7WJY9pPcoP2AfxzDeDVO/w=; b=l9Zqsy6vedbvyqtcxXRdEvs6LiGsdkjXWextTvnHoFhOKUU1QyfiQK5rQJtyAFIMZQIluWupbs9mST1AQVR8cfGVg+gTv/q7ADwu+iI0RZnXWy5+4jDPTZJZUHjTdlBnCbiG8iCA86LfJLjC3LBBPZnnV1SR1bTFCeI7X8yohsQ= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=fail; 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 Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 161071596431781.6354892797774; Fri, 15 Jan 2021 05:06:04 -0800 (PST) Received: from localhost ([::1]:44790 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1l0Onj-0003Wl-3F for importer@patchew.org; Fri, 15 Jan 2021 08:06:03 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:35728) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1l0Ol7-00022R-LQ; Fri, 15 Jan 2021 08:03:21 -0500 Received: from fanzine.igalia.com ([178.60.130.6]:44638) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1l0Ol3-0003wC-Tc; Fri, 15 Jan 2021 08:03:21 -0500 Received: from [213.94.31.64] (helo=perseus.local) by fanzine.igalia.com with esmtpsa (Cipher TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim) id 1l0Okg-0007We-L2; Fri, 15 Jan 2021 14:02:54 +0100 Received: from berto by perseus.local with local (Exim 4.92) (envelope-from ) id 1l0OkT-0003fo-SQ; Fri, 15 Jan 2021 14:02:41 +0100 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=igalia.com; s=20170329; h=Content-Transfer-Encoding:MIME-Version:References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From; bh=D/3jKyHLwJmlaYsfs930G7WJY9pPcoP2AfxzDeDVO/w=; b=L7H/StLd5EoKlwtpxjTQrsKr9KOeYGE1/EdS28fyefLG24hx0Q7qSqEKsc4aRGwWrt+sDOEkEOj8h4DrGvcVJOclI9MAwQrpR6rmtK37Uuc1g3Psu49b+CcmcWfWGM69/gMWuQnoNHYjjG7fqcoLni3kcbblduVlu+oLfWCyRHCvz4YxfuYJ+Ib6UT4T+XHGtImeh5rffDjJjHb0SgawZ9//EfmVwUJeQVXPaDX8QdZrNxEJI7lSLNxT8eOYQ0MKxG8vohhszgT9sc0L+nC6K9UNoIvFXNz/XywCtlzxzFoc2rQNUeVa5Z9w3bcZZcka9zr/Q18kblBPduiBgmGACg==; From: Alberto Garcia To: qemu-devel@nongnu.org Subject: [RFC PATCH 2/2] iotests: Update 245 to support replacing files with x-blockdev-reopen Date: Fri, 15 Jan 2021 14:02:38 +0100 Message-Id: X-Mailer: git-send-email 2.20.1 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable 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=178.60.130.6; envelope-from=berto@igalia.com; helo=fanzine.igalia.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, 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.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , Vladimir Sementsov-Ogievskiy , Alberto Garcia , qemu-block@nongnu.org, Kashyap Chamarthy , Max Reitz Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) Content-Type: text/plain; charset="utf-8" Signed-off-by: Alberto Garcia --- tests/qemu-iotests/245 | 54 +++++++++++++++++++++++++++++++++++++- tests/qemu-iotests/245.out | 4 +-- 2 files changed, 55 insertions(+), 3 deletions(-) diff --git a/tests/qemu-iotests/245 b/tests/qemu-iotests/245 index f9d68b3958..bad6911f0c 100755 --- a/tests/qemu-iotests/245 +++ b/tests/qemu-iotests/245 @@ -78,7 +78,7 @@ class TestBlockdevReopen(iotests.QMPTestCase): for line in log.split("\n"): if line.startswith("Pattern verification failed"): raise Exception("%s (command #%d)" % (line, found)) - if re.match("read .*/.* bytes at offset", line): + if re.match("(read|wrote) .*/.* bytes at offset", line): found +=3D 1 self.assertEqual(found, self.total_io_cmds, "Expected output of %d qemu-io commands, found %d= " % @@ -536,6 +536,58 @@ class TestBlockdevReopen(iotests.QMPTestCase): result =3D self.vm.qmp('blockdev-del', conv_keys =3D True, node_na= me =3D 'bv') self.assert_qmp(result, 'return', {}) =20 + def test_replace_file(self): + qemu_img('create', '-f', 'raw', hd_path[0], '10k') + qemu_img('create', '-f', 'raw', hd_path[1], '10k') + + hd0_opts =3D {'driver': 'file', + 'node-name': 'hd0-file', + 'filename': hd_path[0] } + hd1_opts =3D {'driver': 'file', + 'node-name': 'hd1-file', + 'filename': hd_path[1] } + + opts =3D {'driver': 'raw', 'node-name': 'hd', 'file': 'hd0-file'} + + result =3D self.vm.qmp('blockdev-add', conv_keys =3D False, **hd0_= opts) + self.assert_qmp(result, 'return', {}) + result =3D self.vm.qmp('blockdev-add', conv_keys =3D False, **hd1_= opts) + self.assert_qmp(result, 'return', {}) + result =3D self.vm.qmp('blockdev-add', conv_keys =3D False, **opts) + self.assert_qmp(result, 'return', {}) + + self.run_qemu_io("hd", "read -P 0 0 10k") + self.run_qemu_io("hd", "write -P 0xa0 0 10k") + + self.reopen(opts, {'file': 'hd1-file'}) + self.run_qemu_io("hd", "read -P 0 0 10k") + self.run_qemu_io("hd", "write -P 0xa1 0 10k") + + self.reopen(opts, {'file': 'hd0-file'}) + self.run_qemu_io("hd", "read -P 0xa0 0 10k") + + self.reopen(opts, {'file': 'hd1-file'}) + self.run_qemu_io("hd", "read -P 0xa1 0 10k") + + def test_insert_throttle_filter(self): + hd0_opts =3D hd_opts(0) + result =3D self.vm.qmp('blockdev-add', conv_keys =3D False, **hd0_= opts) + self.assert_qmp(result, 'return', {}) + + opts =3D { 'qom-type': 'throttle-group', 'id': 'group0', + 'props': { 'limits': { 'iops-total': 1000 } } } + result =3D self.vm.qmp('object-add', conv_keys =3D False, **opts) + self.assert_qmp(result, 'return', {}) + + opts =3D { 'driver': 'throttle', 'node-name': 'throttle0', + 'throttle-group': 'group0', 'file': 'hd0-file' } + result =3D self.vm.qmp('blockdev-add', conv_keys =3D False, **opts) + self.assert_qmp(result, 'return', {}) + + self.reopen(hd0_opts, {'file': 'throttle0'}) + + self.reopen(hd0_opts, {'file': 'hd0-file'}) + # Misc reopen tests with different block drivers @iotests.skip_if_unsupported(['quorum', 'throttle']) def test_misc_drivers(self): diff --git a/tests/qemu-iotests/245.out b/tests/qemu-iotests/245.out index 4b33dcaf5c..537a2b5b63 100644 --- a/tests/qemu-iotests/245.out +++ b/tests/qemu-iotests/245.out @@ -10,8 +10,8 @@ {"return": {}} {"data": {"id": "stream0", "type": "stream"}, "event": "BLOCK_JOB_PENDING"= , "timestamp": {"microseconds": "USECS", "seconds": "SECS"}} {"data": {"device": "stream0", "len": 3145728, "offset": 3145728, "speed":= 0, "type": "stream"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"micro= seconds": "USECS", "seconds": "SECS"}} -..................... +....................... ---------------------------------------------------------------------- -Ran 21 tests +Ran 23 tests =20 OK --=20 2.20.1