diff options
| author | Denis V. Lunev <den@openvz.org> | 2026-07-16 13:22:40 +0200 |
|---|---|---|
| committer | Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru> | 2026-08-17 18:32:44 +0300 |
| commit | 59ecd8a1ac3f05f572155a2d7a81fbeec397e2d3 (patch) | |
| tree | 3c194cbe2f62d5f4ae3a6b991f76811cda0593ec /block | |
| parent | 438ee08bc97af48ade6365133f2f5b43d4d788ae (diff) | |
| download | qemu-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.c | 15 |
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); |
