summaryrefslogtreecommitdiff
path: root/block
diff options
context:
space:
mode:
authorDenis V. Lunev <den@openvz.org>2026-07-16 13:22:40 +0200
committerVladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>2026-08-17 18:32:44 +0300
commit59ecd8a1ac3f05f572155a2d7a81fbeec397e2d3 (patch)
tree3c194cbe2f62d5f4ae3a6b991f76811cda0593ec /block
parent438ee08bc97af48ade6365133f2f5b43d4d788ae (diff)
downloadqemu-59ecd8a1ac3f05f572155a2d7a81fbeec397e2d3.tar.gz
qemu-59ecd8a1ac3f05f572155a2d7a81fbeec397e2d3.zip
block/monitor: reject persistent bitmap add on a read-only node
qmp_block_dirty_bitmap_add() marks a new bitmap persistent without checking write access to its node. bdrv_create_dirty_bitmap() always creates bitmaps writable, so a persistent bitmap added to an already read-only node stays writable in memory on a node that can never store it, and the next global inactivation fails: Lost persistent bitmaps during inactivation of node '<node>': No write access migration_block_inactivate: bdrv_inactivate_all() failed: -22 Forcing it read-only instead does not help: it was never stored, so it stays unpromotable on the next reopen to read-write and can trip bdrv_set_dirty()'s readonly assert on the first write. Reject the add instead, for both read-only and inactive nodes -- an already-inactive node skips qcow2_inactivate() on close, so a bitmap added during that window would never get stored either. Wrapped in a transaction, this denies the whole transaction, since qmp_transaction() is already all-or-none. Signed-off-by: Denis V. Lunev <den@openvz.org> CC: Eric Blake <eblake@redhat.com> CC: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru> CC: John Snow <jsnow@redhat.com> CC: Andrey Drobyshev <andrey.drobyshev@virtuozzo.com> Message-ID: <20260716112242.3000035-2-den@openvz.org> Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru> Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
Diffstat (limited to 'block')
-rw-r--r--block/monitor/bitmap-qmp-cmds.c15
1 files changed, 11 insertions, 4 deletions
diff --git a/block/monitor/bitmap-qmp-cmds.c b/block/monitor/bitmap-qmp-cmds.c
index a738e7bbf7..d87ca982aa 100644
--- a/block/monitor/bitmap-qmp-cmds.c
+++ b/block/monitor/bitmap-qmp-cmds.c
@@ -125,10 +125,17 @@ void qmp_block_dirty_bitmap_add(const char *node, const char *name,
disabled = false;
}
- if (persistent &&
- !bdrv_can_store_new_dirty_bitmap(bs, name, granularity, errp))
- {
- return;
+ if (persistent) {
+ if (!bdrv_is_writable(bs)) {
+ error_setg(errp, "Cannot add a persistent bitmap to "
+ "read-only or inactive node '%s'",
+ bdrv_get_node_name(bs));
+ return;
+ }
+
+ if (!bdrv_can_store_new_dirty_bitmap(bs, name, granularity, errp)) {
+ return;
+ }
}
bitmap = bdrv_create_dirty_bitmap(bs, granularity, name, errp);