all lists on lists.proxmox.com
 help / color / mirror / Atom feed
From: Fiona Ebner <f.ebner@proxmox.com>
To: pve-devel@lists.proxmox.com
Subject: [pve-devel] [PATCH qemu 03/13] block/io: clear BDRV_BLOCK_RECURSE flag after recursing in bdrv_co_block_status
Date: Thu, 25 Jan 2024 15:41:39 +0100	[thread overview]
Message-ID: <20240125144149.216064-4-f.ebner@proxmox.com> (raw)
In-Reply-To: <20240125144149.216064-1-f.ebner@proxmox.com>

Using fleecing backup like in [0] on a qcow2 image (with metadata
preallocation) can lead to the following assertion failure:

> bdrv_co_do_block_status: Assertion `!(ret & BDRV_BLOCK_ZERO)' failed.

In the reproducer [0], it happens because the BDRV_BLOCK_RECURSE flag
will be set by the qcow2 driver, so the caller will recursively check
the file child. Then the BDRV_BLOCK_ZERO set too. Later up the call
chain, in bdrv_co_do_block_status() for the snapshot-access driver,
the assertion failure will happen, because both flags are set.

To fix it, clear the recurse flag after the recursive check was done.

In detail:

> #0  qcow2_co_block_status

Returns 0x45 = BDRV_BLOCK_RECURSE | BDRV_BLOCK_DATA |
BDRV_BLOCK_OFFSET_VALID.

> #1  bdrv_co_do_block_status

Because of the data flag, bdrv_co_do_block_status() will now also set
BDRV_BLOCK_ALLOCATED. Because of the recurse flag,
bdrv_co_do_block_status() for the bdrv_file child will be called,
which returns 0x16 = BDRV_BLOCK_ALLOCATED | BDRV_BLOCK_OFFSET_VALID |
BDRV_BLOCK_ZERO. Now the return value inherits the zero flag.

Returns 0x57 = BDRV_BLOCK_RECURSE | BDRV_BLOCK_DATA |
BDRV_BLOCK_OFFSET_VALID | BDRV_BLOCK_ALLOCATED | BDRV_BLOCK_ZERO.

> #2  bdrv_co_common_block_status_above
> #3  bdrv_co_block_status_above
> #4  bdrv_co_block_status
> #5  cbw_co_snapshot_block_status
> #6  bdrv_co_snapshot_block_status
> #7  snapshot_access_co_block_status
> #8  bdrv_co_do_block_status

Return value is propagated all the way up to here, where the assertion
failure happens, because BDRV_BLOCK_RECURSE and BDRV_BLOCK_ZERO are
both set.

> #9  bdrv_co_common_block_status_above
> #10 bdrv_co_block_status_above
> #11 block_copy_block_status
> #12 block_copy_dirty_clusters
> #13 block_copy_common
> #14 block_copy_async_co_entry
> #15 coroutine_trampoline

[0]:

> #!/bin/bash
> rm /tmp/disk.qcow2
> ./qemu-img create /tmp/disk.qcow2 -o preallocation=metadata -f qcow2 1G
> ./qemu-img create /tmp/fleecing.qcow2 -f qcow2 1G
> ./qemu-img create /tmp/backup.qcow2 -f qcow2 1G
> ./qemu-system-x86_64 --qmp stdio \
> --blockdev qcow2,node-name=node0,file.driver=file,file.filename=/tmp/disk.qcow2 \
> --blockdev qcow2,node-name=node1,file.driver=file,file.filename=/tmp/fleecing.qcow2 \
> --blockdev qcow2,node-name=node2,file.driver=file,file.filename=/tmp/backup.qcow2 \
> <<EOF
> {"execute": "qmp_capabilities"}
> {"execute": "blockdev-add", "arguments": { "driver": "copy-before-write", "file": "node0", "target": "node1", "node-name": "node3" } }
> {"execute": "blockdev-add", "arguments": { "driver": "snapshot-access", "file": "node3", "node-name": "snap0" } }
> {"execute": "blockdev-backup", "arguments": { "device": "snap0", "target": "node1", "sync": "full", "job-id": "backup0" } }
> EOF

Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
---

Can be added as an extra/ patch.

 block/io.c | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/block/io.c b/block/io.c
index 63f7b3ad3e..24a3c84c93 100644
--- a/block/io.c
+++ b/block/io.c
@@ -2589,6 +2589,16 @@ bdrv_co_block_status(BlockDriverState *bs, bool want_zero,
                 ret |= (ret2 & BDRV_BLOCK_ZERO);
             }
         }
+
+        /*
+         * Now that the recursive search was done, clear the flag. Otherwise,
+         * with more complicated block graphs like snapshot-access ->
+         * copy-before-write -> qcow2, where the return value will be propagated
+         * further up to a parent bdrv_co_do_block_status() call, both the
+         * BDRV_BLOCK_RECURSE and BDRV_BLOCK_ZERO flags would be set, which is
+         * not allowed.
+         */
+        ret &= ~BDRV_BLOCK_RECURSE;
     }
 
 out:
-- 
2.39.2





  parent reply	other threads:[~2024-01-25 14:41 UTC|newest]

Thread overview: 31+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-01-25 14:41 [pve-devel] [RFC qemu/guest-common/manager/qemu-server/docs 00/13] fix #4136: implement backup fleecing Fiona Ebner
2024-01-25 14:41 ` [pve-devel] [PATCH qemu 01/13] backup: factor out gathering device info into helper Fiona Ebner
2024-01-25 14:41 ` [pve-devel] [PATCH qemu 02/13] backup: get device info: code cleanup Fiona Ebner
2024-01-25 14:41 ` Fiona Ebner [this message]
2024-01-25 14:41 ` [pve-devel] [RFC qemu 04/13] block/copy-before-write: create block_copy bitmap in filter node Fiona Ebner
2024-01-25 14:41 ` [pve-devel] [RFC qemu 05/13] qapi: blockdev-backup: add discard-source parameter Fiona Ebner
2024-01-25 14:41 ` [pve-devel] [HACK qemu 06/13] block/{copy-before-write, snapshot-access}: implement bdrv_co_get_info driver callback Fiona Ebner
2024-01-29 14:35   ` Fiona Ebner
2024-01-25 14:41 ` [pve-devel] [HACK qemu 07/13] block/block-copy: always consider source cluster size too Fiona Ebner
2024-01-25 14:41 ` [pve-devel] [RFC qemu 08/13] PVE backup: add fleecing option Fiona Ebner
2024-01-25 14:41 ` [pve-devel] [RFC guest-common 09/13] vzdump: schema: add fleecing property string Fiona Ebner
2024-01-29 15:41   ` Fiona Ebner
2024-01-30 14:03     ` DERUMIER, Alexandre
2024-02-01  8:28       ` Fiona Ebner
2024-02-01 12:39     ` DERUMIER, Alexandre
2024-02-01 13:11       ` Fiona Ebner
2024-02-01 13:20         ` DERUMIER, Alexandre
2024-02-01 13:27           ` Fiona Ebner
2024-02-01 21:33             ` DERUMIER, Alexandre
2024-02-02  8:30               ` Fiona Ebner
2024-02-01 13:30           ` Fiona Ebner
2024-01-25 14:41 ` [pve-devel] [RFC manager 10/13] vzdump: handle new 'fleecing' " Fiona Ebner
2024-01-25 14:41 ` [pve-devel] [RFC qemu-server 11/13] backup: disk info: also keep track of size Fiona Ebner
2024-01-25 14:41 ` [pve-devel] [RFC qemu-server 12/13] backup: implement fleecing option Fiona Ebner
2024-01-29 15:28   ` Fiona Ebner
2024-01-25 14:41 ` [pve-devel] [RFC docs 13/13] vzdump: add section about backup fleecing Fiona Ebner
2024-01-25 16:13   ` Dietmar Maurer
2024-01-25 16:41     ` DERUMIER, Alexandre
2024-01-25 18:18       ` Dietmar Maurer
2024-01-26  8:39         ` Fiona Ebner
2024-01-25 16:02 ` [pve-devel] [RFC qemu/guest-common/manager/qemu-server/docs 00/13] fix #4136: implement " DERUMIER, Alexandre

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=20240125144149.216064-4-f.ebner@proxmox.com \
    --to=f.ebner@proxmox.com \
    --cc=pve-devel@lists.proxmox.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.
Service provided by Proxmox Server Solutions GmbH | Privacy | Legal