From: Max Reitz <mreitz@redhat.com>
To: qemu-block@nongnu.org
Cc: Kevin Wolf <kwolf@redhat.com>,
qemu-devel@nongnu.org, Max Reitz <mreitz@redhat.com>
Subject: [Qemu-devel] [PATCH v3 7/8] block: Ignore loosening perm restrictions failures
Date: Wed, 22 May 2019 19:03:51 +0200 [thread overview]
Message-ID: <20190522170352.12020-8-mreitz@redhat.com> (raw)
In-Reply-To: <20190522170352.12020-1-mreitz@redhat.com>
We generally assume that loosening permission restrictions can never
fail. We have seen in the past that this assumption is wrong. This has
led to crashes because we generally pass &error_abort when loosening
permissions.
However, a failure in such a case should actually be handled in quite
the opposite way: It is very much not fatal, so qemu may report it, but
still consider the operation successful. The only realistic problem is
that qemu may then retain permissions and thus locks on images it
actually does not require. But again, that is not fatal.
To implement this behavior, we make all functions that change
permissions and that pass &error_abort to the initiating function
(bdrv_check_perm() or bdrv_child_check_perm()) evaluate the
@loosen_restrictions value introduced in the previous patch. If it is
true and an error did occur, we abort the permission update, discard the
error, and instead report success to the caller.
bdrv_child_try_set_perm() itself does not pass &error_abort, but it is
the only public function to change permissions. As such, callers may
pass &error_abort to it, expecting dropping permission restrictions to
never fail.
Signed-off-by: Max Reitz <mreitz@redhat.com>
---
block.c | 44 ++++++++++++++++++++++++++++++++++++++------
1 file changed, 38 insertions(+), 6 deletions(-)
diff --git a/block.c b/block.c
index f5d7f4d971..58e1e3ce14 100644
--- a/block.c
+++ b/block.c
@@ -2121,11 +2121,26 @@ static void bdrv_child_abort_perm_update(BdrvChild *c)
int bdrv_child_try_set_perm(BdrvChild *c, uint64_t perm, uint64_t shared,
Error **errp)
{
+ Error *local_err = NULL;
int ret;
+ bool tighten_restrictions;
- ret = bdrv_child_check_perm(c, NULL, perm, shared, NULL, NULL, errp);
+ ret = bdrv_child_check_perm(c, NULL, perm, shared, NULL,
+ &tighten_restrictions, &local_err);
if (ret < 0) {
bdrv_child_abort_perm_update(c);
+ if (tighten_restrictions) {
+ error_propagate(errp, local_err);
+ } else {
+ /*
+ * Our caller may intend to only loosen restrictions and
+ * does not expect this function to fail. Errors are not
+ * fatal in such a case, so we can just hide them from our
+ * caller.
+ */
+ error_free(local_err);
+ ret = 0;
+ }
return ret;
}
@@ -2308,10 +2323,19 @@ static void bdrv_replace_child(BdrvChild *child, BlockDriverState *new_bs)
/* Update permissions for old node. This is guaranteed to succeed
* because we're just taking a parent away, so we're loosening
* restrictions. */
+ bool tighten_restrictions;
+ int ret;
+
bdrv_get_cumulative_perm(old_bs, &perm, &shared_perm);
- bdrv_check_perm(old_bs, NULL, perm, shared_perm, NULL,
- NULL, &error_abort);
- bdrv_set_perm(old_bs, perm, shared_perm);
+ ret = bdrv_check_perm(old_bs, NULL, perm, shared_perm, NULL,
+ &tighten_restrictions, NULL);
+ assert(tighten_restrictions == false);
+ if (ret < 0) {
+ /* We only tried to loosen restrictions, so errors are not fatal */
+ bdrv_abort_perm_update(old_bs);
+ } else {
+ bdrv_set_perm(old_bs, perm, shared_perm);
+ }
}
}
@@ -5352,6 +5376,7 @@ static bool bdrv_has_bds_parent(BlockDriverState *bs, bool only_active)
static int bdrv_inactivate_recurse(BlockDriverState *bs)
{
BdrvChild *child, *parent;
+ bool tighten_restrictions;
uint64_t perm, shared_perm;
int ret;
@@ -5388,8 +5413,15 @@ static int bdrv_inactivate_recurse(BlockDriverState *bs)
/* Update permissions, they may differ for inactive nodes */
bdrv_get_cumulative_perm(bs, &perm, &shared_perm);
- bdrv_check_perm(bs, NULL, perm, shared_perm, NULL, NULL, &error_abort);
- bdrv_set_perm(bs, perm, shared_perm);
+ ret = bdrv_check_perm(bs, NULL, perm, shared_perm, NULL,
+ &tighten_restrictions, NULL);
+ assert(tighten_restrictions == false);
+ if (ret < 0) {
+ /* We only tried to loosen restrictions, so errors are not fatal */
+ bdrv_abort_perm_update(bs);
+ } else {
+ bdrv_set_perm(bs, perm, shared_perm);
+ }
/* Recursively inactivate children */
--
2.21.0
next prev parent reply other threads:[~2019-05-22 17:11 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-05-22 17:03 [Qemu-devel] [PATCH v3 0/8] block: Ignore loosening perm restrictions failures Max Reitz
2019-05-22 17:03 ` [Qemu-devel] [PATCH v3 1/8] file-posix: Update open_flags in raw_set_perm() Max Reitz
2019-05-22 17:03 ` [Qemu-devel] [PATCH v3 2/8] block: Add bdrv_child_refresh_perms() Max Reitz
2019-05-22 17:03 ` [Qemu-devel] [PATCH v3 3/8] block/mirror: Fix child permissions Max Reitz
2019-05-22 17:03 ` [Qemu-devel] [PATCH v3 4/8] block/commit: Drop bdrv_child_try_set_perm() Max Reitz
2019-05-22 17:03 ` [Qemu-devel] [PATCH v3 5/8] block: Fix order in bdrv_replace_child() Max Reitz
2019-05-22 17:03 ` [Qemu-devel] [PATCH v3 6/8] block: Add *tighten_restrictions to *check*_perm() Max Reitz
2019-05-22 17:03 ` Max Reitz [this message]
2019-05-22 17:03 ` [Qemu-devel] [PATCH v3 8/8] iotests: Test failure to loosen restrictions Max Reitz
2019-05-22 18:24 ` [Qemu-devel] [PATCH v3 0/8] block: Ignore loosening perm restrictions failures Eric Blake
2019-05-22 18:37 ` Max Reitz
2019-05-22 19:31 ` Eric Blake
2019-06-13 19:44 ` Max Reitz
2019-06-14 14:02 ` Kevin Wolf
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20190522170352.12020-8-mreitz@redhat.com \
--to=mreitz@redhat.com \
--cc=kwolf@redhat.com \
--cc=qemu-block@nongnu.org \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).