qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: John Snow <jsnow@redhat.com>
To: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>,
	"qemu-block@nongnu.org" <qemu-block@nongnu.org>
Cc: "fam@euphon.net" <fam@euphon.net>,
	"kwolf@redhat.com" <kwolf@redhat.com>,
	Denis Lunev <den@virtuozzo.com>,
	"qemu-devel@nongnu.org" <qemu-devel@nongnu.org>,
	"mreitz@redhat.com" <mreitz@redhat.com>
Subject: Re: [Qemu-devel] [PATCH v4 09/10] block/qcow2-bitmap: fix and improve qcow2_reopen_bitmaps_rw
Date: Fri, 27 Sep 2019 14:59:03 -0400	[thread overview]
Message-ID: <1c8f261a-bf38-ce70-fe0e-597ad9f7e66a@redhat.com> (raw)
In-Reply-To: <4fb89dc3-6eb6-bb86-2aaf-611881b82c39@virtuozzo.com>



On 9/27/19 3:52 AM, Vladimir Sementsov-Ogievskiy wrote:
> 27.09.2019 2:21, John Snow wrote:
>>
>>
>> On 8/7/19 10:12 AM, Vladimir Sementsov-Ogievskiy wrote:
>>> - Correct check for write access to file child, and in correct place
>>>    (only if we want to write).
>>> - Support reopen rw -> rw (which will be used in following commit),
>>>    for example, !bdrv_dirty_bitmap_readonly() is not a corruption if
>>>    bitmap is marked IN_USE in the image.
>>> - Consider unexpected bitmap as a corruption and check other
>>>    combinations of in-image and in-RAM bitmaps.
>>>
>>> Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
>>> ---
>>>   block/qcow2-bitmap.c | 56 +++++++++++++++++++++++++++++---------------
>>>   1 file changed, 37 insertions(+), 19 deletions(-)
>>>
>>> diff --git a/block/qcow2-bitmap.c b/block/qcow2-bitmap.c
>>> index a636dc50ca..e276a95154 100644
>>> --- a/block/qcow2-bitmap.c
>>> +++ b/block/qcow2-bitmap.c
>>> @@ -1108,18 +1108,14 @@ int qcow2_reopen_bitmaps_rw(BlockDriverState *bs, Error **errp)
>>>       Qcow2BitmapList *bm_list;
>>>       Qcow2Bitmap *bm;
>>>       GSList *ro_dirty_bitmaps = NULL;
>>> -    int ret = 0;
>>> +    int ret = -EINVAL;
>>> +    bool need_header_update = false;
>>>   
>>>       if (s->nb_bitmaps == 0) {
>>>           /* No bitmaps - nothing to do */
>>>           return 0;
>>>       }
>>>   
>>> -    if (!can_write(bs)) {
>>> -        error_setg(errp, "Can't write to the image on reopening bitmaps rw");
>>> -        return -EINVAL;
>>> -    }
>>> -
>>>       bm_list = bitmap_list_load(bs, s->bitmap_directory_offset,
>>>                                  s->bitmap_directory_size, errp);
>>>       if (bm_list == NULL) {
>>> @@ -1128,32 +1124,54 @@ int qcow2_reopen_bitmaps_rw(BlockDriverState *bs, Error **errp)
>>>   
>>>       QSIMPLEQ_FOREACH(bm, bm_list, entry) {
>>>           BdrvDirtyBitmap *bitmap = bdrv_find_dirty_bitmap(bs, bm->name);
>>> -        if (bitmap == NULL) {
>>> -            continue;
>>> -        }
>>>   
>>> -        if (!bdrv_dirty_bitmap_readonly(bitmap)) {
>>> -            error_setg(errp, "Bitmap %s was loaded prior to rw-reopen, but was "
>>> -                       "not marked as readonly. This is a bug, something went "
>>> -                       "wrong. All of the bitmaps may be corrupted", bm->name);
>>> -            ret = -EINVAL;
>>> +        if (!bitmap) {
>>> +            error_setg(errp, "Unexpected bitmap '%s' in the image '%s'",
>>> +                       bm->name, bs->filename);
>>>               goto out;
>>>           }
>>>   
>>
>> I think you can actually drop the definite article, because the image
>> name is the specifier.
>>
>> "Unexpected bitmap '%s' in image '%s'" is sufficient.
>>
>>> -        bm->flags |= BME_FLAG_IN_USE;
>>> -        ro_dirty_bitmaps = g_slist_append(ro_dirty_bitmaps, bitmap);
>>> +        if (!(bm->flags & BME_FLAG_IN_USE)) {
>>> +            if (!bdrv_dirty_bitmap_readonly(bitmap)) {
>>> +                error_setg(errp, "Corruption: bitmap '%s' is not marked IN_USE "
>>> +                           "in the image '%s' and not marked readonly in RAM",
>>> +                           bm->name, bs->filename);
>>> +                goto out;
>>> +            }
>>> +            if (bdrv_dirty_bitmap_inconsistent(bitmap)) {
>>> +                error_setg(errp, "Corruption: bitmap '%s' is inconsistent but "
>>> +                           "is not marked IN_USE in the image '%s'", bm->name,
>>> +                           bs->filename);
>>> +                goto out;
>>> +            }
>>
>> We support RW --> RW now, but what happens if something is marked IN_USE
>> on RO --> RW? It's not obvious from this function alone why that's safe
>> to ignore.
> 
> If bitmap is IN_USE in the image, it's always safe to ignore it, as it's marked as
> invalid anyway.
> 

Oh, okay -- we're relying on the initial open to have handled this for
us. I only asked because you're doing a lot of additional "sanity
checking" here and wondered.

(That's one drawback to doing sanity checking -- you give the impression
that we expect these combinations to be able to occur.)

> Consider RO->RW with IN_USE.
> 
> if corresponding BdrvDirtyBitmap is inconsistent, it's OK.
> 
> If not, how can that be? I can't imagine. But we have correct bitmap in RAM, should
> we mark it inconsistent, because of bitmap in image? I don't know.
> 

Yeah, I wouldn't know what to make of this occurrence either. I don't
expect it to be able to happen.

If it's +ro -inconsistent and +in_use, we absolutely have a bug
somewhere and we don't know what the right thing to do is because we're
outside of the expected state machine.

Hmm...

If it was RO, then we know we wouldn't be able to have any changes to
disk since we loaded the bitmap, and yet we have a clear state mismatch.

1) We loaded the bitmap incorrectly. Not very likely, but very severe if
true.
2) The disk changed without QEMU's consent.

It's probably the case that we shouldn't be working on this image
anymore -- this would be a very high-level corruption event; the
qcow2_signal_corruption kind.

AKA: "I have no idea what the hell happened, and since it's not possible
to know, please cease using this image immediately."

--js


  reply	other threads:[~2019-09-27 19:00 UTC|newest]

Thread overview: 34+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-08-07 14:12 [Qemu-devel] [PATCH v4 00/10] qcow2-bitmaps: rewrite reopening logic Vladimir Sementsov-Ogievskiy
2019-08-07 14:12 ` [Qemu-devel] [PATCH v4 01/10] block: switch reopen queue from QSIMPLEQ to QTAILQ Vladimir Sementsov-Ogievskiy
2019-09-24  9:50   ` Max Reitz
2019-08-07 14:12 ` [Qemu-devel] [PATCH v4 02/10] block: reverse order for reopen commits Vladimir Sementsov-Ogievskiy
2019-09-24 10:12   ` Max Reitz
2019-09-26 23:10     ` John Snow
2019-08-07 14:12 ` [Qemu-devel] [PATCH v4 03/10] iotests: add test-case to 165 to test reopening qcow2 bitmaps to RW Vladimir Sementsov-Ogievskiy
2019-09-26 22:57   ` John Snow
2019-09-27  7:28     ` Vladimir Sementsov-Ogievskiy
2019-09-27 10:22       ` Vladimir Sementsov-Ogievskiy
2019-09-27 10:29       ` Vladimir Sementsov-Ogievskiy
2019-09-27 18:30         ` John Snow
2019-09-27 19:54           ` Vladimir Sementsov-Ogievskiy
2019-08-07 14:12 ` [Qemu-devel] [PATCH v4 04/10] iotests.py: add event_wait_log and events_wait_log helpers Vladimir Sementsov-Ogievskiy
2019-09-26 23:05   ` John Snow
2019-09-27  7:31     ` Vladimir Sementsov-Ogievskiy
2019-09-27 10:38       ` Vladimir Sementsov-Ogievskiy
2019-08-07 14:12 ` [Qemu-devel] [PATCH v4 05/10] block/qcow2-bitmap: get rid of bdrv_has_changed_persistent_bitmaps Vladimir Sementsov-Ogievskiy
2019-08-07 14:12 ` [Qemu-devel] [PATCH v4 06/10] block/qcow2-bitmap: drop qcow2_reopen_bitmaps_rw_hint() Vladimir Sementsov-Ogievskiy
2019-08-07 14:12 ` [Qemu-devel] [PATCH v4 07/10] block/qcow2-bitmap: do not remove bitmaps on reopen-ro Vladimir Sementsov-Ogievskiy
2019-08-07 14:12 ` [Qemu-devel] [PATCH v4 08/10] iotests: add test 260 to check bitmap life after snapshot + commit Vladimir Sementsov-Ogievskiy
2019-09-26 23:09   ` John Snow
2019-08-07 14:12 ` [Qemu-devel] [PATCH v4 09/10] block/qcow2-bitmap: fix and improve qcow2_reopen_bitmaps_rw Vladimir Sementsov-Ogievskiy
2019-09-26 23:21   ` John Snow
2019-09-27  7:52     ` Vladimir Sementsov-Ogievskiy
2019-09-27 18:59       ` John Snow [this message]
2019-09-27 19:57         ` Vladimir Sementsov-Ogievskiy
2019-08-07 14:12 ` [Qemu-devel] [PATCH v4 10/10] qcow2-bitmap: move bitmap reopen-rw code to qcow2_reopen_commit Vladimir Sementsov-Ogievskiy
2019-09-26 23:24   ` John Snow
2019-09-27  9:13   ` Max Reitz
2019-09-05  9:54 ` [Qemu-devel] [PATCH v4 00/10] qcow2-bitmaps: rewrite reopening logic Vladimir Sementsov-Ogievskiy
2019-09-19 18:24   ` bugfix ping " Vladimir Sementsov-Ogievskiy
2019-09-26 23:25 ` [Qemu-devel] " John Snow
2019-09-27  7:53   ` Vladimir Sementsov-Ogievskiy

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=1c8f261a-bf38-ce70-fe0e-597ad9f7e66a@redhat.com \
    --to=jsnow@redhat.com \
    --cc=den@virtuozzo.com \
    --cc=fam@euphon.net \
    --cc=kwolf@redhat.com \
    --cc=mreitz@redhat.com \
    --cc=qemu-block@nongnu.org \
    --cc=qemu-devel@nongnu.org \
    --cc=vsementsov@virtuozzo.com \
    /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).