diff --git a/debian/patches/bitmap-mirror/0001-drive-mirror-add-support-for-sync-bitmap-mode-never.patch b/debian/patches/bitmap-mirror/0001-drive-mirror-add-support-for-sync-bitmap-mode-never.patch index c9c63b5..bed733d 100644 --- a/debian/patches/bitmap-mirror/0001-drive-mirror-add-support-for-sync-bitmap-mode-never.patch +++ b/debian/patches/bitmap-mirror/0001-drive-mirror-add-support-for-sync-bitmap-mode-never.patch @@ -27,18 +27,18 @@ Signed-off-by: Ma Haocong Signed-off-by: John Snow Signed-off-by: Fabian Grünbichler Signed-off-by: Thomas Lamprecht -[FE: rebased for 8.1.1] +[FE: rebased for 8.2.2] Signed-off-by: Fiona Ebner --- - block/mirror.c | 98 +++++++++++++++++++++----- + block/mirror.c | 99 ++++++++++++++++++++------ blockdev.c | 38 +++++++++- include/block/block_int-global-state.h | 4 +- qapi/block-core.json | 25 ++++++- tests/unit/test-block-iothread.c | 4 +- - 5 files changed, 142 insertions(+), 27 deletions(-) + 5 files changed, 142 insertions(+), 28 deletions(-) diff --git a/block/mirror.c b/block/mirror.c -index d3cacd1708..1ff42c8af1 100644 +index abbddb39e4..ed14c8b498 100644 --- a/block/mirror.c +++ b/block/mirror.c @@ -51,7 +51,7 @@ typedef struct MirrorBlockJob { @@ -50,7 +50,7 @@ index d3cacd1708..1ff42c8af1 100644 BlockMirrorBackingMode backing_mode; /* Whether the target image requires explicit zero-initialization */ bool zero_target; -@@ -65,6 +65,8 @@ typedef struct MirrorBlockJob { +@@ -73,6 +73,8 @@ typedef struct MirrorBlockJob { size_t buf_size; int64_t bdev_length; unsigned long *cow_bitmap; @@ -59,9 +59,9 @@ index d3cacd1708..1ff42c8af1 100644 BdrvDirtyBitmap *dirty_bitmap; BdrvDirtyBitmapIter *dbi; uint8_t *buf; -@@ -705,7 +707,8 @@ static int mirror_exit_common(Job *job) - bdrv_child_refresh_perms(mirror_top_bs, mirror_top_bs->backing, +@@ -724,7 +726,8 @@ static int mirror_exit_common(Job *job) &error_abort); + if (!abort && s->backing_mode == MIRROR_SOURCE_BACKING_CHAIN) { - BlockDriverState *backing = s->is_none_mode ? src : s->base; + BlockDriverState *backing; @@ -69,7 +69,7 @@ index d3cacd1708..1ff42c8af1 100644 BlockDriverState *unfiltered_target = bdrv_skip_filters(target_bs); if (bdrv_cow_bs(unfiltered_target) != backing) { -@@ -809,6 +812,16 @@ static void mirror_abort(Job *job) +@@ -831,6 +834,16 @@ static void mirror_abort(Job *job) assert(ret == 0); } @@ -86,7 +86,7 @@ index d3cacd1708..1ff42c8af1 100644 static void coroutine_fn mirror_throttle(MirrorBlockJob *s) { int64_t now = qemu_clock_get_ns(QEMU_CLOCK_REALTIME); -@@ -997,7 +1010,8 @@ static int coroutine_fn mirror_run(Job *job, Error **errp) +@@ -1027,7 +1040,8 @@ static int coroutine_fn mirror_run(Job *job, Error **errp) mirror_free_init(s); s->last_pause_ns = qemu_clock_get_ns(QEMU_CLOCK_REALTIME); @@ -96,7 +96,7 @@ index d3cacd1708..1ff42c8af1 100644 ret = mirror_dirty_init(s); if (ret < 0 || job_is_cancelled(&s->common.job)) { goto immediate_exit; -@@ -1251,6 +1265,7 @@ static const BlockJobDriver mirror_job_driver = { +@@ -1323,6 +1337,7 @@ static const BlockJobDriver mirror_job_driver = { .run = mirror_run, .prepare = mirror_prepare, .abort = mirror_abort, @@ -104,7 +104,7 @@ index d3cacd1708..1ff42c8af1 100644 .pause = mirror_pause, .complete = mirror_complete, .cancel = mirror_cancel, -@@ -1267,6 +1282,7 @@ static const BlockJobDriver commit_active_job_driver = { +@@ -1341,6 +1356,7 @@ static const BlockJobDriver commit_active_job_driver = { .run = mirror_run, .prepare = mirror_prepare, .abort = mirror_abort, @@ -112,7 +112,7 @@ index d3cacd1708..1ff42c8af1 100644 .pause = mirror_pause, .complete = mirror_complete, .cancel = commit_active_cancel, -@@ -1658,7 +1674,10 @@ static BlockJob *mirror_start_job( +@@ -1733,7 +1749,10 @@ static BlockJob *mirror_start_job( BlockCompletionFunc *cb, void *opaque, const BlockJobDriver *driver, @@ -124,9 +124,9 @@ index d3cacd1708..1ff42c8af1 100644 bool auto_complete, const char *filter_node_name, bool is_mirror, MirrorCopyMode copy_mode, Error **errp) -@@ -1670,10 +1689,39 @@ static BlockJob *mirror_start_job( - uint64_t target_perms, target_shared_perms; - int ret; +@@ -1747,10 +1766,39 @@ static BlockJob *mirror_start_job( + + GLOBAL_STATE_CODE(); - if (granularity == 0) { - granularity = bdrv_get_default_bitmap_granularity(target); @@ -166,7 +166,7 @@ index d3cacd1708..1ff42c8af1 100644 assert(is_power_of_2(granularity)); if (buf_size < 0) { -@@ -1804,7 +1852,9 @@ static BlockJob *mirror_start_job( +@@ -1890,7 +1938,9 @@ static BlockJob *mirror_start_job( s->replaces = g_strdup(replaces); s->on_source_error = on_source_error; s->on_target_error = on_target_error; @@ -176,10 +176,10 @@ index d3cacd1708..1ff42c8af1 100644 + s->bitmap_mode = bitmap_mode; s->backing_mode = backing_mode; s->zero_target = zero_target; - s->copy_mode = copy_mode; -@@ -1825,6 +1875,18 @@ static BlockJob *mirror_start_job( - bdrv_disable_dirty_bitmap(s->dirty_bitmap); - } + qatomic_set(&s->copy_mode, copy_mode); +@@ -1916,6 +1966,18 @@ static BlockJob *mirror_start_job( + */ + bdrv_disable_dirty_bitmap(s->dirty_bitmap); + if (s->sync_bitmap) { + bdrv_dirty_bitmap_set_busy(s->sync_bitmap, true); @@ -193,10 +193,10 @@ index d3cacd1708..1ff42c8af1 100644 + } + } + + bdrv_graph_wrlock(bs); ret = block_job_add_bdrv(&s->common, "source", bs, 0, BLK_PERM_WRITE_UNCHANGED | BLK_PERM_WRITE | - BLK_PERM_CONSISTENT_READ, -@@ -1902,6 +1964,9 @@ fail: +@@ -1998,6 +2060,9 @@ fail: if (s->dirty_bitmap) { bdrv_release_dirty_bitmap(s->dirty_bitmap); } @@ -206,7 +206,7 @@ index d3cacd1708..1ff42c8af1 100644 job_early_fail(&s->common.job); } -@@ -1919,31 +1984,25 @@ void mirror_start(const char *job_id, BlockDriverState *bs, +@@ -2020,35 +2085,28 @@ void mirror_start(const char *job_id, BlockDriverState *bs, BlockDriverState *target, const char *replaces, int creation_flags, int64_t speed, uint32_t granularity, int64_t buf_size, @@ -231,8 +231,12 @@ index d3cacd1708..1ff42c8af1 100644 - MirrorSyncMode_str(mode)); - return; - } +- + bdrv_graph_rdlock_main_loop(); - is_none_mode = mode == MIRROR_SYNC_MODE_NONE; base = mode == MIRROR_SYNC_MODE_TOP ? bdrv_backing_chain_next(bs) : NULL; + bdrv_graph_rdunlock_main_loop(); + mirror_start_job(job_id, bs, creation_flags, target, replaces, speed, granularity, buf_size, backing_mode, zero_target, on_source_error, on_target_error, unmap, NULL, NULL, @@ -243,7 +247,7 @@ index d3cacd1708..1ff42c8af1 100644 } BlockJob *commit_active_start(const char *job_id, BlockDriverState *bs, -@@ -1970,7 +2029,8 @@ BlockJob *commit_active_start(const char *job_id, BlockDriverState *bs, +@@ -2075,7 +2133,8 @@ BlockJob *commit_active_start(const char *job_id, BlockDriverState *bs, job_id, bs, creation_flags, base, NULL, speed, 0, 0, MIRROR_LEAVE_BACKING_CHAIN, false, on_error, on_error, true, cb, opaque, @@ -254,10 +258,10 @@ index d3cacd1708..1ff42c8af1 100644 errp); if (!job) { diff --git a/blockdev.c b/blockdev.c -index c28462a633..a402fa4bf7 100644 +index c91f49e7b6..8c8e8b604a 100644 --- a/blockdev.c +++ b/blockdev.c -@@ -2849,6 +2849,9 @@ static void blockdev_mirror_common(const char *job_id, BlockDriverState *bs, +@@ -2903,6 +2903,9 @@ static void blockdev_mirror_common(const char *job_id, BlockDriverState *bs, BlockDriverState *target, const char *replaces, enum MirrorSyncMode sync, @@ -267,7 +271,7 @@ index c28462a633..a402fa4bf7 100644 BlockMirrorBackingMode backing_mode, bool zero_target, bool has_speed, int64_t speed, -@@ -2867,6 +2870,7 @@ static void blockdev_mirror_common(const char *job_id, BlockDriverState *bs, +@@ -2921,6 +2924,7 @@ static void blockdev_mirror_common(const char *job_id, BlockDriverState *bs, { BlockDriverState *unfiltered_bs; int job_flags = JOB_DEFAULT; @@ -275,7 +279,7 @@ index c28462a633..a402fa4bf7 100644 GLOBAL_STATE_CODE(); GRAPH_RDLOCK_GUARD_MAINLOOP(); -@@ -2921,6 +2925,29 @@ static void blockdev_mirror_common(const char *job_id, BlockDriverState *bs, +@@ -2975,6 +2979,29 @@ static void blockdev_mirror_common(const char *job_id, BlockDriverState *bs, sync = MIRROR_SYNC_MODE_FULL; } @@ -305,7 +309,7 @@ index c28462a633..a402fa4bf7 100644 if (!replaces) { /* We want to mirror from @bs, but keep implicit filters on top */ unfiltered_bs = bdrv_skip_implicit_filters(bs); -@@ -2966,8 +2993,8 @@ static void blockdev_mirror_common(const char *job_id, BlockDriverState *bs, +@@ -3030,8 +3057,8 @@ static void blockdev_mirror_common(const char *job_id, BlockDriverState *bs, * and will allow to check whether the node still exist at mirror completion */ mirror_start(job_id, bs, target, @@ -316,7 +320,7 @@ index c28462a633..a402fa4bf7 100644 on_source_error, on_target_error, unmap, filter_node_name, copy_mode, errp); } -@@ -3115,6 +3142,8 @@ void qmp_drive_mirror(DriveMirror *arg, Error **errp) +@@ -3189,6 +3216,8 @@ void qmp_drive_mirror(DriveMirror *arg, Error **errp) blockdev_mirror_common(arg->job_id, bs, target_bs, arg->replaces, arg->sync, @@ -325,7 +329,7 @@ index c28462a633..a402fa4bf7 100644 backing_mode, zero_target, arg->has_speed, arg->speed, arg->has_granularity, arg->granularity, -@@ -3136,6 +3165,8 @@ void qmp_blockdev_mirror(const char *job_id, +@@ -3210,6 +3239,8 @@ void qmp_blockdev_mirror(const char *job_id, const char *device, const char *target, const char *replaces, MirrorSyncMode sync, @@ -334,7 +338,7 @@ index c28462a633..a402fa4bf7 100644 bool has_speed, int64_t speed, bool has_granularity, uint32_t granularity, bool has_buf_size, int64_t buf_size, -@@ -3184,7 +3215,8 @@ void qmp_blockdev_mirror(const char *job_id, +@@ -3258,7 +3289,8 @@ void qmp_blockdev_mirror(const char *job_id, } blockdev_mirror_common(job_id, bs, target_bs, @@ -345,7 +349,7 @@ index c28462a633..a402fa4bf7 100644 has_granularity, granularity, has_buf_size, buf_size, diff --git a/include/block/block_int-global-state.h b/include/block/block_int-global-state.h -index da5fb31089..32f0f9858a 100644 +index ef31c58bb3..57265a617a 100644 --- a/include/block/block_int-global-state.h +++ b/include/block/block_int-global-state.h @@ -152,7 +152,9 @@ void mirror_start(const char *job_id, BlockDriverState *bs, @@ -360,10 +364,10 @@ index da5fb31089..32f0f9858a 100644 BlockdevOnError on_source_error, BlockdevOnError on_target_error, diff --git a/qapi/block-core.json b/qapi/block-core.json -index bca1a0c372..a5cea82139 100644 +index ca390c5700..8db0986e9e 100644 --- a/qapi/block-core.json +++ b/qapi/block-core.json -@@ -2145,6 +2145,15 @@ +@@ -2163,6 +2163,15 @@ # destination (all the disk, only the sectors allocated in the # topmost image, or only new I/O). # @@ -379,7 +383,7 @@ index bca1a0c372..a5cea82139 100644 # @granularity: granularity of the dirty bitmap, default is 64K if the # image format doesn't have clusters, 4K if the clusters are # smaller than that, else the cluster size. Must be a power of 2 -@@ -2187,7 +2196,9 @@ +@@ -2205,7 +2214,9 @@ { 'struct': 'DriveMirror', 'data': { '*job-id': 'str', 'device': 'str', 'target': 'str', '*format': 'str', '*node-name': 'str', '*replaces': 'str', @@ -390,7 +394,7 @@ index bca1a0c372..a5cea82139 100644 '*speed': 'int', '*granularity': 'uint32', '*buf-size': 'int', '*on-source-error': 'BlockdevOnError', '*on-target-error': 'BlockdevOnError', -@@ -2471,6 +2482,15 @@ +@@ -2489,6 +2500,15 @@ # destination (all the disk, only the sectors allocated in the # topmost image, or only new I/O). # @@ -406,7 +410,7 @@ index bca1a0c372..a5cea82139 100644 # @granularity: granularity of the dirty bitmap, default is 64K if the # image format doesn't have clusters, 4K if the clusters are # smaller than that, else the cluster size. Must be a power of 2 -@@ -2521,7 +2541,8 @@ +@@ -2539,7 +2559,8 @@ { 'command': 'blockdev-mirror', 'data': { '*job-id': 'str', 'device': 'str', 'target': 'str', '*replaces': 'str', @@ -417,12 +421,12 @@ index bca1a0c372..a5cea82139 100644 '*buf-size': 'int', '*on-source-error': 'BlockdevOnError', '*on-target-error': 'BlockdevOnError', diff --git a/tests/unit/test-block-iothread.c b/tests/unit/test-block-iothread.c -index d727a5fee8..8a34aa2328 100644 +index 9b15d2768c..54acd47188 100644 --- a/tests/unit/test-block-iothread.c +++ b/tests/unit/test-block-iothread.c -@@ -757,8 +757,8 @@ static void test_propagate_mirror(void) - +@@ -766,8 +766,8 @@ static void test_propagate_mirror(void) /* Start a mirror job */ + aio_context_acquire(main_ctx); mirror_start("job0", src, target, NULL, JOB_DEFAULT, 0, 0, 0, - MIRROR_SYNC_MODE_NONE, MIRROR_OPEN_BACKING_CHAIN, false, - BLOCKDEV_ON_ERROR_REPORT, BLOCKDEV_ON_ERROR_REPORT, @@ -430,4 +434,4 @@ index d727a5fee8..8a34aa2328 100644 + false, BLOCKDEV_ON_ERROR_REPORT, BLOCKDEV_ON_ERROR_REPORT, false, "filter_node", MIRROR_COPY_MODE_BACKGROUND, &error_abort); - WITH_JOB_LOCK_GUARD() { + aio_context_release(main_ctx); diff --git a/debian/patches/bitmap-mirror/0002-drive-mirror-add-support-for-conditional-and-always-.patch b/debian/patches/bitmap-mirror/0002-drive-mirror-add-support-for-conditional-and-always-.patch index a4a5a0b..8ff09e2 100644 --- a/debian/patches/bitmap-mirror/0002-drive-mirror-add-support-for-conditional-and-always-.patch +++ b/debian/patches/bitmap-mirror/0002-drive-mirror-add-support-for-conditional-and-always-.patch @@ -24,10 +24,10 @@ Signed-off-by: Thomas Lamprecht 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/block/mirror.c b/block/mirror.c -index 1ff42c8af1..11b8a8e959 100644 +index ed14c8b498..beb98f2e07 100644 --- a/block/mirror.c +++ b/block/mirror.c -@@ -682,8 +682,6 @@ static int mirror_exit_common(Job *job) +@@ -695,8 +695,6 @@ static int mirror_exit_common(Job *job) bdrv_unfreeze_backing_chain(mirror_top_bs, target_bs); } @@ -36,9 +36,9 @@ index 1ff42c8af1..11b8a8e959 100644 /* Make sure that the source BDS doesn't go away during bdrv_replace_node, * before we can call bdrv_drained_end */ bdrv_ref(src); -@@ -788,6 +786,18 @@ static int mirror_exit_common(Job *job) - block_job_remove_all_bdrv(bjob); - bdrv_replace_node(mirror_top_bs, mirror_top_bs->backing->bs, &error_abort); +@@ -810,6 +808,18 @@ static int mirror_exit_common(Job *job) + bdrv_drained_end(target_bs); + bdrv_unref(target_bs); + if (s->sync_bitmap) { + if (s->bitmap_mode == BITMAP_SYNC_MODE_ALWAYS || @@ -55,7 +55,7 @@ index 1ff42c8af1..11b8a8e959 100644 bs_opaque->job = NULL; bdrv_drained_end(src); -@@ -1699,10 +1709,6 @@ static BlockJob *mirror_start_job( +@@ -1776,10 +1786,6 @@ static BlockJob *mirror_start_job( " sync mode", MirrorSyncMode_str(sync_mode)); return NULL; @@ -66,7 +66,7 @@ index 1ff42c8af1..11b8a8e959 100644 } } else if (bitmap) { error_setg(errp, -@@ -1719,6 +1725,12 @@ static BlockJob *mirror_start_job( +@@ -1796,6 +1802,12 @@ static BlockJob *mirror_start_job( return NULL; } granularity = bdrv_dirty_bitmap_granularity(bitmap); diff --git a/debian/patches/bitmap-mirror/0003-mirror-add-check-for-bitmap-mode-without-bitmap.patch b/debian/patches/bitmap-mirror/0003-mirror-add-check-for-bitmap-mode-without-bitmap.patch index 3bf9797..1acf777 100644 --- a/debian/patches/bitmap-mirror/0003-mirror-add-check-for-bitmap-mode-without-bitmap.patch +++ b/debian/patches/bitmap-mirror/0003-mirror-add-check-for-bitmap-mode-without-bitmap.patch @@ -16,10 +16,10 @@ Signed-off-by: Thomas Lamprecht 1 file changed, 3 insertions(+) diff --git a/blockdev.c b/blockdev.c -index a402fa4bf7..01b0ab0549 100644 +index 8c8e8b604a..cdfe7b33b1 100644 --- a/blockdev.c +++ b/blockdev.c -@@ -2946,6 +2946,9 @@ static void blockdev_mirror_common(const char *job_id, BlockDriverState *bs, +@@ -3000,6 +3000,9 @@ static void blockdev_mirror_common(const char *job_id, BlockDriverState *bs, if (bdrv_dirty_bitmap_check(bitmap, BDRV_BITMAP_ALLOW_RO, errp)) { return; } diff --git a/debian/patches/bitmap-mirror/0004-mirror-switch-to-bdrv_dirty_bitmap_merge_internal.patch b/debian/patches/bitmap-mirror/0004-mirror-switch-to-bdrv_dirty_bitmap_merge_internal.patch index 93a1524..5a637c4 100644 --- a/debian/patches/bitmap-mirror/0004-mirror-switch-to-bdrv_dirty_bitmap_merge_internal.patch +++ b/debian/patches/bitmap-mirror/0004-mirror-switch-to-bdrv_dirty_bitmap_merge_internal.patch @@ -16,10 +16,10 @@ Signed-off-by: Thomas Lamprecht 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/block/mirror.c b/block/mirror.c -index 11b8a8e959..00f2665ca4 100644 +index beb98f2e07..1aa75e7384 100644 --- a/block/mirror.c +++ b/block/mirror.c -@@ -792,8 +792,8 @@ static int mirror_exit_common(Job *job) +@@ -814,8 +814,8 @@ static int mirror_exit_common(Job *job) job->ret == 0 && ret == 0)) { /* Success; synchronize copy back to sync. */ bdrv_clear_dirty_bitmap(s->sync_bitmap, NULL); @@ -30,7 +30,7 @@ index 11b8a8e959..00f2665ca4 100644 } } bdrv_release_dirty_bitmap(s->dirty_bitmap); -@@ -1892,11 +1892,8 @@ static BlockJob *mirror_start_job( +@@ -1983,11 +1983,8 @@ static BlockJob *mirror_start_job( } if (s->sync_mode == MIRROR_SYNC_MODE_BITMAP) { @@ -43,4 +43,4 @@ index 11b8a8e959..00f2665ca4 100644 + NULL, true); } - ret = block_job_add_bdrv(&s->common, "source", bs, 0, + bdrv_graph_wrlock(bs); diff --git a/debian/patches/bitmap-mirror/0006-mirror-move-some-checks-to-qmp.patch b/debian/patches/bitmap-mirror/0006-mirror-move-some-checks-to-qmp.patch index f9a6e20..719eb8c 100644 --- a/debian/patches/bitmap-mirror/0006-mirror-move-some-checks-to-qmp.patch +++ b/debian/patches/bitmap-mirror/0006-mirror-move-some-checks-to-qmp.patch @@ -12,7 +12,7 @@ uniform w.r.t. backup block jobs. Signed-off-by: Fabian Grünbichler Signed-off-by: Thomas Lamprecht -[FE: rebase for 8.0] +[FE: rebase for 8.2.2] Signed-off-by: Fiona Ebner --- block/mirror.c | 28 +++------------ @@ -21,12 +21,12 @@ Signed-off-by: Fiona Ebner 3 files changed, 70 insertions(+), 59 deletions(-) diff --git a/block/mirror.c b/block/mirror.c -index 00f2665ca4..60cf574de5 100644 +index 1aa75e7384..a02efbfbbd 100644 --- a/block/mirror.c +++ b/block/mirror.c -@@ -1699,31 +1699,13 @@ static BlockJob *mirror_start_job( - uint64_t target_perms, target_shared_perms; - int ret; +@@ -1776,31 +1776,13 @@ static BlockJob *mirror_start_job( + + GLOBAL_STATE_CODE(); - if (sync_mode == MIRROR_SYNC_MODE_INCREMENTAL) { - error_setg(errp, "Sync mode '%s' not supported", @@ -62,10 +62,10 @@ index 00f2665ca4..60cf574de5 100644 if (bitmap_mode != BITMAP_SYNC_MODE_NEVER) { diff --git a/blockdev.c b/blockdev.c -index 01b0ab0549..cd5f205ad1 100644 +index cdfe7b33b1..38a40e3e32 100644 --- a/blockdev.c +++ b/blockdev.c -@@ -2925,7 +2925,36 @@ static void blockdev_mirror_common(const char *job_id, BlockDriverState *bs, +@@ -2979,7 +2979,36 @@ static void blockdev_mirror_common(const char *job_id, BlockDriverState *bs, sync = MIRROR_SYNC_MODE_FULL; } diff --git a/debian/patches/extra/0001-monitor-qmp-fix-race-with-clients-disconnecting-earl.patch b/debian/patches/extra/0001-monitor-qmp-fix-race-with-clients-disconnecting-earl.patch index cd9797a..45e7f87 100644 --- a/debian/patches/extra/0001-monitor-qmp-fix-race-with-clients-disconnecting-earl.patch +++ b/debian/patches/extra/0001-monitor-qmp-fix-race-with-clients-disconnecting-earl.patch @@ -78,7 +78,7 @@ index 252de85681..8db28f9272 100644 /** diff --git a/monitor/monitor.c b/monitor/monitor.c -index dc352f9e9d..56e1307014 100644 +index 01ede1babd..5681bca346 100644 --- a/monitor/monitor.c +++ b/monitor/monitor.c @@ -117,6 +117,21 @@ bool monitor_cur_is_qmp(void) diff --git a/debian/patches/extra/0003-ide-avoid-potential-deadlock-when-draining-during-tr.patch b/debian/patches/extra/0003-ide-avoid-potential-deadlock-when-draining-during-tr.patch index 7705d72..72c50fe 100644 --- a/debian/patches/extra/0003-ide-avoid-potential-deadlock-when-draining-during-tr.patch +++ b/debian/patches/extra/0003-ide-avoid-potential-deadlock-when-draining-during-tr.patch @@ -55,10 +55,10 @@ Signed-off-by: Fiona Ebner 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/hw/ide/core.c b/hw/ide/core.c -index c3508acbb1..289347af58 100644 +index 8a0579bff4..254255f8dc 100644 --- a/hw/ide/core.c +++ b/hw/ide/core.c -@@ -444,7 +444,7 @@ static void ide_trim_bh_cb(void *opaque) +@@ -456,7 +456,7 @@ static void ide_trim_bh_cb(void *opaque) iocb->bh = NULL; qemu_aio_unref(iocb); @@ -67,7 +67,7 @@ index c3508acbb1..289347af58 100644 blk_dec_in_flight(blk); } -@@ -504,6 +504,8 @@ static void ide_issue_trim_cb(void *opaque, int ret) +@@ -516,6 +516,8 @@ static void ide_issue_trim_cb(void *opaque, int ret) done: iocb->aiocb = NULL; if (iocb->bh) { @@ -76,7 +76,7 @@ index c3508acbb1..289347af58 100644 replay_bh_schedule_event(iocb->bh); } } -@@ -516,9 +518,6 @@ BlockAIOCB *ide_issue_trim( +@@ -528,9 +530,6 @@ BlockAIOCB *ide_issue_trim( IDEDevice *dev = s->unit ? s->bus->slave : s->bus->master; TrimAIOCB *iocb; @@ -86,7 +86,7 @@ index c3508acbb1..289347af58 100644 iocb = blk_aio_get(&trim_aiocb_info, s->blk, cb, cb_opaque); iocb->s = s; iocb->bh = qemu_bh_new_guarded(ide_trim_bh_cb, iocb, -@@ -742,8 +741,9 @@ void ide_cancel_dma_sync(IDEState *s) +@@ -754,8 +753,9 @@ void ide_cancel_dma_sync(IDEState *s) */ if (s->bus->dma->aiocb) { trace_ide_cancel_dma_sync_remaining(); diff --git a/debian/patches/extra/0004-migration-block-dirty-bitmap-fix-loading-bitmap-when.patch b/debian/patches/extra/0004-migration-block-dirty-bitmap-fix-loading-bitmap-when.patch index 4dae6ca..948ea38 100644 --- a/debian/patches/extra/0004-migration-block-dirty-bitmap-fix-loading-bitmap-when.patch +++ b/debian/patches/extra/0004-migration-block-dirty-bitmap-fix-loading-bitmap-when.patch @@ -20,10 +20,10 @@ Signed-off-by: Fiona Ebner 1 file changed, 6 insertions(+) diff --git a/migration/block-dirty-bitmap.c b/migration/block-dirty-bitmap.c -index 032fc5f405..e1ae3b7316 100644 +index 24347ab0f7..0070b13b6f 100644 --- a/migration/block-dirty-bitmap.c +++ b/migration/block-dirty-bitmap.c -@@ -805,8 +805,11 @@ static int dirty_bitmap_load_start(QEMUFile *f, DBMLoadState *s) +@@ -809,8 +809,11 @@ static int dirty_bitmap_load_start(QEMUFile *f, DBMLoadState *s) "destination", bdrv_dirty_bitmap_name(s->bitmap)); return -EINVAL; } else { @@ -35,7 +35,7 @@ index 032fc5f405..e1ae3b7316 100644 if (!s->bitmap) { error_report_err(local_err); return -EINVAL; -@@ -833,7 +836,10 @@ static int dirty_bitmap_load_start(QEMUFile *f, DBMLoadState *s) +@@ -837,7 +840,10 @@ static int dirty_bitmap_load_start(QEMUFile *f, DBMLoadState *s) bdrv_disable_dirty_bitmap(s->bitmap); if (flags & DIRTY_BITMAP_MIG_START_FLAG_ENABLED) { diff --git a/debian/patches/extra/0005-Revert-Revert-graph-lock-Disable-locking-for-now.patch b/debian/patches/extra/0005-Revert-Revert-graph-lock-Disable-locking-for-now.patch deleted file mode 100644 index f0648d2..0000000 --- a/debian/patches/extra/0005-Revert-Revert-graph-lock-Disable-locking-for-now.patch +++ /dev/null @@ -1,140 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Fiona Ebner -Date: Thu, 28 Sep 2023 10:07:03 +0200 -Subject: [PATCH] Revert "Revert "graph-lock: Disable locking for now"" - -This reverts commit 3cce22defb4b0e47cf135444e30cc673cff5ebad. - -There are still some issues with graph locking, e.g. deadlocks during -backup canceling [0]. Because the AioContext locks still exist, it -should be safe to disable locking again. - -From the original 80fc5d2600 ("graph-lock: Disable locking for now"): - -> We don't currently rely on graph locking yet. It is supposed to replace -> the AioContext lock eventually to enable multiqueue support, but as long -> as we still have the AioContext lock, it is sufficient without the graph -> lock. Once the AioContext lock goes away, the deadlock doesn't exist any -> more either and this commit can be reverted. (Of course, it can also be -> reverted while the AioContext lock still exists if the callers have been -> fixed.) - -[0]: https://lists.nongnu.org/archive/html/qemu-devel/2023-09/msg00729.html - -Signed-off-by: Fiona Ebner ---- - block/graph-lock.c | 24 ++++++++++++++++++++++++ - 1 file changed, 24 insertions(+) - -diff --git a/block/graph-lock.c b/block/graph-lock.c -index 5e66f01ae8..5c2873262a 100644 ---- a/block/graph-lock.c -+++ b/block/graph-lock.c -@@ -30,8 +30,10 @@ BdrvGraphLock graph_lock; - /* Protects the list of aiocontext and orphaned_reader_count */ - static QemuMutex aio_context_list_lock; - -+#if 0 - /* Written and read with atomic operations. */ - static int has_writer; -+#endif - - /* - * A reader coroutine could move from an AioContext to another. -@@ -88,6 +90,7 @@ void unregister_aiocontext(AioContext *ctx) - g_free(ctx->bdrv_graph); - } - -+#if 0 - static uint32_t reader_count(void) - { - BdrvGraphRWlock *brdv_graph; -@@ -105,12 +108,19 @@ static uint32_t reader_count(void) - assert((int32_t)rd >= 0); - return rd; - } -+#endif - - void bdrv_graph_wrlock(BlockDriverState *bs) - { -+#if 0 - AioContext *ctx = NULL; - - GLOBAL_STATE_CODE(); -+ /* -+ * TODO Some callers hold an AioContext lock when this is called, which -+ * causes deadlocks. Reenable once the AioContext locking is cleaned up (or -+ * AioContext locks are gone). -+ */ - assert(!qatomic_read(&has_writer)); - - /* -@@ -158,11 +168,13 @@ void bdrv_graph_wrlock(BlockDriverState *bs) - if (ctx) { - aio_context_acquire(bdrv_get_aio_context(bs)); - } -+#endif - } - - void bdrv_graph_wrunlock(void) - { - GLOBAL_STATE_CODE(); -+#if 0 - QEMU_LOCK_GUARD(&aio_context_list_lock); - assert(qatomic_read(&has_writer)); - -@@ -174,10 +186,13 @@ void bdrv_graph_wrunlock(void) - - /* Wake up all coroutine that are waiting to read the graph */ - qemu_co_enter_all(&reader_queue, &aio_context_list_lock); -+#endif - } - - void coroutine_fn bdrv_graph_co_rdlock(void) - { -+ /* TODO Reenable when wrlock is reenabled */ -+#if 0 - BdrvGraphRWlock *bdrv_graph; - bdrv_graph = qemu_get_current_aio_context()->bdrv_graph; - -@@ -237,10 +252,12 @@ void coroutine_fn bdrv_graph_co_rdlock(void) - qemu_co_queue_wait(&reader_queue, &aio_context_list_lock); - } - } -+#endif - } - - void coroutine_fn bdrv_graph_co_rdunlock(void) - { -+#if 0 - BdrvGraphRWlock *bdrv_graph; - bdrv_graph = qemu_get_current_aio_context()->bdrv_graph; - -@@ -258,6 +275,7 @@ void coroutine_fn bdrv_graph_co_rdunlock(void) - if (qatomic_read(&has_writer)) { - aio_wait_kick(); - } -+#endif - } - - void bdrv_graph_rdlock_main_loop(void) -@@ -275,13 +293,19 @@ void bdrv_graph_rdunlock_main_loop(void) - void assert_bdrv_graph_readable(void) - { - /* reader_count() is slow due to aio_context_list_lock lock contention */ -+ /* TODO Reenable when wrlock is reenabled */ -+#if 0 - #ifdef CONFIG_DEBUG_GRAPH_LOCK - assert(qemu_in_main_thread() || reader_count()); - #endif -+#endif - } - - void assert_bdrv_graph_writable(void) - { - assert(qemu_in_main_thread()); -+ /* TODO Reenable when wrlock is reenabled */ -+#if 0 - assert(qatomic_read(&has_writer)); -+#endif - } diff --git a/debian/patches/extra/0007-Revert-x86-acpi-workaround-Windows-not-handling-name.patch b/debian/patches/extra/0005-Revert-x86-acpi-workaround-Windows-not-handling-name.patch similarity index 95% rename from debian/patches/extra/0007-Revert-x86-acpi-workaround-Windows-not-handling-name.patch rename to debian/patches/extra/0005-Revert-x86-acpi-workaround-Windows-not-handling-name.patch index 02d9b6b..0bdf9d9 100644 --- a/debian/patches/extra/0007-Revert-x86-acpi-workaround-Windows-not-handling-name.patch +++ b/debian/patches/extra/0005-Revert-x86-acpi-workaround-Windows-not-handling-name.patch @@ -24,10 +24,10 @@ Signed-off-by: Fiona Ebner 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c -index bb12b0ad43..de14d3c3da 100644 +index 1e178341de..d8694b338e 100644 --- a/hw/i386/acpi-build.c +++ b/hw/i386/acpi-build.c -@@ -362,13 +362,9 @@ Aml *aml_pci_device_dsm(void) +@@ -357,13 +357,9 @@ Aml *aml_pci_device_dsm(void) { Aml *params = aml_local(0); Aml *pkg = aml_package(2); diff --git a/debian/patches/extra/0006-migration-states-workaround-snapshot-performance-reg.patch b/debian/patches/extra/0006-migration-states-workaround-snapshot-performance-reg.patch deleted file mode 100644 index 8031837..0000000 --- a/debian/patches/extra/0006-migration-states-workaround-snapshot-performance-reg.patch +++ /dev/null @@ -1,57 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Fiona Ebner -Date: Thu, 28 Sep 2023 11:19:14 +0200 -Subject: [PATCH] migration states: workaround snapshot performance regression - -Commit 813cd616 ("migration: Use migration_transferred_bytes() to -calculate rate_limit") introduced a prohibitive performance regression -when taking a snapshot [0]. The reason turns out to be the flushing -done by migration_transferred_bytes() - -Just use a _noflush version of the relevant function as a workaround -until upstream fixes the issue. This is inspired by a not-applied -upstream series [1], but doing the very minimum to avoid the -regression. - -[0]: https://gitlab.com/qemu-project/qemu/-/issues/1821 -[1]: https://lists.nongnu.org/archive/html/qemu-devel/2023-05/msg07708.html - -Signed-off-by: Fiona Ebner ---- - migration/migration-stats.c | 16 +++++++++++++++- - 1 file changed, 15 insertions(+), 1 deletion(-) - -diff --git a/migration/migration-stats.c b/migration/migration-stats.c -index 095d6d75bb..8073c8ebaa 100644 ---- a/migration/migration-stats.c -+++ b/migration/migration-stats.c -@@ -18,6 +18,20 @@ - - MigrationAtomicStats mig_stats; - -+/* -+ * Same as migration_transferred_bytes below, but using the _noflush -+ * variant of qemu_file_transferred() to avoid a performance -+ * regression in migration_rate_exceeded(). -+ */ -+static uint64_t migration_transferred_bytes_noflush(QEMUFile *f) -+{ -+ uint64_t multifd = stat64_get(&mig_stats.multifd_bytes); -+ uint64_t qemu_file = qemu_file_transferred_noflush(f); -+ -+ trace_migration_transferred_bytes(qemu_file, multifd); -+ return qemu_file + multifd; -+} -+ - bool migration_rate_exceeded(QEMUFile *f) - { - if (qemu_file_get_error(f)) { -@@ -25,7 +39,7 @@ bool migration_rate_exceeded(QEMUFile *f) - } - - uint64_t rate_limit_start = stat64_get(&mig_stats.rate_limit_start); -- uint64_t rate_limit_current = migration_transferred_bytes(f); -+ uint64_t rate_limit_current = migration_transferred_bytes_noflush(f); - uint64_t rate_limit_used = rate_limit_current - rate_limit_start; - uint64_t rate_limit_max = stat64_get(&mig_stats.rate_limit_max); - diff --git a/debian/patches/extra/0012-qemu_init-increase-NOFILE-soft-limit-on-POSIX.patch b/debian/patches/extra/0006-qemu_init-increase-NOFILE-soft-limit-on-POSIX.patch similarity index 83% rename from debian/patches/extra/0012-qemu_init-increase-NOFILE-soft-limit-on-POSIX.patch rename to debian/patches/extra/0006-qemu_init-increase-NOFILE-soft-limit-on-POSIX.patch index cdc1e06..5a032cc 100644 --- a/debian/patches/extra/0012-qemu_init-increase-NOFILE-soft-limit-on-POSIX.patch +++ b/debian/patches/extra/0006-qemu_init-increase-NOFILE-soft-limit-on-POSIX.patch @@ -33,26 +33,26 @@ Reviewed-by: Daniel P. Berrangé include/sysemu/os-posix.h | 1 + include/sysemu/os-win32.h | 5 +++++ os-posix.c | 22 ++++++++++++++++++++++ - softmmu/vl.c | 2 ++ + system/vl.c | 2 ++ 4 files changed, 30 insertions(+) diff --git a/include/sysemu/os-posix.h b/include/sysemu/os-posix.h -index 1030d39904..edc415aff5 100644 +index dff32ae185..b881ac6c6f 100644 --- a/include/sysemu/os-posix.h +++ b/include/sysemu/os-posix.h -@@ -48,6 +48,7 @@ void os_setup_early_signal_handling(void); - void os_set_proc_name(const char *s); - void os_setup_signal_handling(void); +@@ -51,6 +51,7 @@ bool is_daemonized(void); void os_daemonize(void); + bool os_set_runas(const char *user_id); + void os_set_chroot(const char *path); +void os_setup_limits(void); void os_setup_post(void); int os_mlock(void); diff --git a/include/sysemu/os-win32.h b/include/sysemu/os-win32.h -index 91aa0d7ec0..f6e23fe01e 100644 +index 1047d260cb..106f155037 100644 --- a/include/sysemu/os-win32.h +++ b/include/sysemu/os-win32.h -@@ -129,6 +129,11 @@ static inline int os_mlock(void) +@@ -128,6 +128,11 @@ static inline int os_mlock(void) return -ENOSYS; } @@ -65,7 +65,7 @@ index 91aa0d7ec0..f6e23fe01e 100644 #if !defined(lseek) diff --git a/os-posix.c b/os-posix.c -index cfcb96533c..0cc1d991b1 100644 +index 52ef6990ff..a4284e2c07 100644 --- a/os-posix.c +++ b/os-posix.c @@ -24,6 +24,7 @@ @@ -76,7 +76,7 @@ index cfcb96533c..0cc1d991b1 100644 #include #include #include -@@ -286,6 +287,27 @@ void os_daemonize(void) +@@ -256,6 +257,27 @@ void os_daemonize(void) } } @@ -104,11 +104,11 @@ index cfcb96533c..0cc1d991b1 100644 void os_setup_post(void) { int fd = 0; -diff --git a/softmmu/vl.c b/softmmu/vl.c -index c9e9ede237..ba6ad8a8df 100644 ---- a/softmmu/vl.c -+++ b/softmmu/vl.c -@@ -2713,6 +2713,8 @@ void qemu_init(int argc, char **argv) +diff --git a/system/vl.c b/system/vl.c +index e18fa3ce46..d2a3b3f457 100644 +--- a/system/vl.c ++++ b/system/vl.c +@@ -2782,6 +2782,8 @@ void qemu_init(int argc, char **argv) error_init(argv[0]); qemu_init_exec_dir(argv[0]); diff --git a/debian/patches/extra/0007-mirror-Don-t-call-job_pause_point-under-graph-lock.patch b/debian/patches/extra/0007-mirror-Don-t-call-job_pause_point-under-graph-lock.patch new file mode 100644 index 0000000..5d4197c --- /dev/null +++ b/debian/patches/extra/0007-mirror-Don-t-call-job_pause_point-under-graph-lock.patch @@ -0,0 +1,79 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Kevin Wolf +Date: Wed, 13 Mar 2024 16:30:00 +0100 +Subject: [PATCH] mirror: Don't call job_pause_point() under graph lock + +Calling job_pause_point() while holding the graph reader lock +potentially results in a deadlock: bdrv_graph_wrlock() first drains +everything, including the mirror job, which pauses it. The job is only +unpaused at the end of the drain section, which is when the graph writer +lock has been successfully taken. However, if the job happens to be +paused at a pause point where it still holds the reader lock, the writer +lock can't be taken as long as the job is still paused. + +Mark job_pause_point() as GRAPH_UNLOCKED and fix mirror accordingly. + +Cc: qemu-stable@nongnu.org +Buglink: https://issues.redhat.com/browse/RHEL-28125 +Fixes: 004915a96a7a ("block: Protect bs->backing with graph_lock") +Signed-off-by: Kevin Wolf +Message-ID: <20240313153000.33121-1-kwolf@redhat.com> +Reviewed-by: Eric Blake +Signed-off-by: Kevin Wolf +(cherry picked from commit ae5a40e8581185654a667fbbf7e4adbc2a2a3e45) +Signed-off-by: Fiona Ebner +--- + block/mirror.c | 10 ++++++---- + include/qemu/job.h | 2 +- + 2 files changed, 7 insertions(+), 5 deletions(-) + +diff --git a/block/mirror.c b/block/mirror.c +index cd9d3ad4a8..abbddb39e4 100644 +--- a/block/mirror.c ++++ b/block/mirror.c +@@ -479,9 +479,9 @@ static unsigned mirror_perform(MirrorBlockJob *s, int64_t offset, + return bytes_handled; + } + +-static void coroutine_fn GRAPH_RDLOCK mirror_iteration(MirrorBlockJob *s) ++static void coroutine_fn GRAPH_UNLOCKED mirror_iteration(MirrorBlockJob *s) + { +- BlockDriverState *source = s->mirror_top_bs->backing->bs; ++ BlockDriverState *source; + MirrorOp *pseudo_op; + int64_t offset; + /* At least the first dirty chunk is mirrored in one iteration. */ +@@ -489,6 +489,10 @@ static void coroutine_fn GRAPH_RDLOCK mirror_iteration(MirrorBlockJob *s) + bool write_zeroes_ok = bdrv_can_write_zeroes_with_unmap(blk_bs(s->target)); + int max_io_bytes = MAX(s->buf_size / MAX_IN_FLIGHT, MAX_IO_BYTES); + ++ bdrv_graph_co_rdlock(); ++ source = s->mirror_top_bs->backing->bs; ++ bdrv_graph_co_rdunlock(); ++ + bdrv_dirty_bitmap_lock(s->dirty_bitmap); + offset = bdrv_dirty_iter_next(s->dbi); + if (offset < 0) { +@@ -1078,9 +1082,7 @@ static int coroutine_fn mirror_run(Job *job, Error **errp) + mirror_wait_for_free_in_flight_slot(s); + continue; + } else if (cnt != 0) { +- bdrv_graph_co_rdlock(); + mirror_iteration(s); +- bdrv_graph_co_rdunlock(); + } + } + +diff --git a/include/qemu/job.h b/include/qemu/job.h +index e502787dd8..b4bc2e174b 100644 +--- a/include/qemu/job.h ++++ b/include/qemu/job.h +@@ -503,7 +503,7 @@ void job_enter(Job *job); + * + * Called with job_mutex *not* held. + */ +-void coroutine_fn job_pause_point(Job *job); ++void coroutine_fn GRAPH_UNLOCKED job_pause_point(Job *job); + + /** + * @job: The job that calls the function. diff --git a/debian/patches/extra/0008-target-i386-the-sgx_epc_get_section-stub-is-reachabl.patch b/debian/patches/extra/0008-target-i386-the-sgx_epc_get_section-stub-is-reachabl.patch deleted file mode 100644 index 194635f..0000000 --- a/debian/patches/extra/0008-target-i386-the-sgx_epc_get_section-stub-is-reachabl.patch +++ /dev/null @@ -1,34 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Paolo Bonzini -Date: Tue, 1 Feb 2022 20:09:41 +0100 -Subject: [PATCH] target/i386: the sgx_epc_get_section stub is reachable -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -The sgx_epc_get_section stub is reachable from cpu_x86_cpuid. It -should not assert, instead it should just return true just like -the "real" sgx_epc_get_section does when SGX is disabled. - -Reported-by: Vladimír Beneš -Cc: qemu-stable@nongnu.org -Signed-off-by: Paolo Bonzini -Message-ID: <20220201190941.106001-1-pbonzini@redhat.com> -Signed-off-by: Paolo Bonzini -(cherry-picked from commit 219615740425d9683588207b40a365e6741691a6) -Signed-off-by: Fiona Ebner ---- - hw/i386/sgx-stub.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/hw/i386/sgx-stub.c b/hw/i386/sgx-stub.c -index 26833eb233..16b1dfd90b 100644 ---- a/hw/i386/sgx-stub.c -+++ b/hw/i386/sgx-stub.c -@@ -34,5 +34,5 @@ void pc_machine_init_sgx_epc(PCMachineState *pcms) - - bool sgx_epc_get_section(int section_nr, uint64_t *addr, uint64_t *size) - { -- g_assert_not_reached(); -+ return true; - } diff --git a/debian/patches/extra/0009-ui-clipboard-mark-type-as-not-available-when-there-i.patch b/debian/patches/extra/0009-ui-clipboard-mark-type-as-not-available-when-there-i.patch deleted file mode 100644 index 4b09063..0000000 --- a/debian/patches/extra/0009-ui-clipboard-mark-type-as-not-available-when-there-i.patch +++ /dev/null @@ -1,86 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Fiona Ebner -Date: Wed, 24 Jan 2024 11:57:48 +0100 -Subject: [PATCH] ui/clipboard: mark type as not available when there is no - data -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -With VNC, a client can send a non-extended VNC_MSG_CLIENT_CUT_TEXT -message with len=0. In qemu_clipboard_set_data(), the clipboard info -will be updated setting data to NULL (because g_memdup(data, size) -returns NULL when size is 0). If the client does not set the -VNC_ENCODING_CLIPBOARD_EXT feature when setting up the encodings, then -the 'request' callback for the clipboard peer is not initialized. -Later, because data is NULL, qemu_clipboard_request() can be reached -via vdagent_chr_write() and vdagent_clipboard_recv_request() and -there, the clipboard owner's 'request' callback will be attempted to -be called, but that is a NULL pointer. - -In particular, this can happen when using the KRDC (22.12.3) VNC -client. - -Another scenario leading to the same issue is with two clients (say -noVNC and KRDC): - -The noVNC client sets the extension VNC_FEATURE_CLIPBOARD_EXT and -initializes its cbpeer. - -The KRDC client does not, but triggers a vnc_client_cut_text() (note -it's not the _ext variant)). There, a new clipboard info with it as -the 'owner' is created and via qemu_clipboard_set_data() is called, -which in turn calls qemu_clipboard_update() with that info. - -In qemu_clipboard_update(), the notifier for the noVNC client will be -called, i.e. vnc_clipboard_notify() and also set vs->cbinfo for the -noVNC client. The 'owner' in that clipboard info is the clipboard peer -for the KRDC client, which did not initialize the 'request' function. -That sounds correct to me, it is the owner of that clipboard info. - -Then when noVNC sends a VNC_MSG_CLIENT_CUT_TEXT message (it did set -the VNC_FEATURE_CLIPBOARD_EXT feature correctly, so a check for it -passes), that clipboard info is passed to qemu_clipboard_request() and -the original segfault still happens. - -Fix the issue by handling updates with size 0 differently. In -particular, mark in the clipboard info that the type is not available. - -While at it, switch to g_memdup2(), because g_memdup() is deprecated. - -Cc: qemu-stable@nongnu.org -Fixes: CVE-2023-6683 -Reported-by: Markus Frank -Suggested-by: Marc-André Lureau -Signed-off-by: Fiona Ebner -Reviewed-by: Marc-André Lureau -Tested-by: Markus Frank -(picked from https://lists.nongnu.org/archive/html/qemu-stable/2024-01/msg00228.html) -Signed-off-by: Fiona Ebner ---- - ui/clipboard.c | 12 +++++++++--- - 1 file changed, 9 insertions(+), 3 deletions(-) - -diff --git a/ui/clipboard.c b/ui/clipboard.c -index 3d14bffaf8..b3f6fa3c9e 100644 ---- a/ui/clipboard.c -+++ b/ui/clipboard.c -@@ -163,9 +163,15 @@ void qemu_clipboard_set_data(QemuClipboardPeer *peer, - } - - g_free(info->types[type].data); -- info->types[type].data = g_memdup(data, size); -- info->types[type].size = size; -- info->types[type].available = true; -+ if (size) { -+ info->types[type].data = g_memdup2(data, size); -+ info->types[type].size = size; -+ info->types[type].available = true; -+ } else { -+ info->types[type].data = NULL; -+ info->types[type].size = 0; -+ info->types[type].available = false; -+ } - - if (update) { - qemu_clipboard_update(info); diff --git a/debian/patches/extra/0010-virtio-scsi-Attach-event-vq-notifier-with-no_poll.patch b/debian/patches/extra/0010-virtio-scsi-Attach-event-vq-notifier-with-no_poll.patch deleted file mode 100644 index 85d80e8..0000000 --- a/debian/patches/extra/0010-virtio-scsi-Attach-event-vq-notifier-with-no_poll.patch +++ /dev/null @@ -1,65 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Hanna Czenczek -Date: Fri, 2 Feb 2024 16:31:56 +0100 -Subject: [PATCH] virtio-scsi: Attach event vq notifier with no_poll - -As of commit 38738f7dbbda90fbc161757b7f4be35b52205552 ("virtio-scsi: -don't waste CPU polling the event virtqueue"), we only attach an io_read -notifier for the virtio-scsi event virtqueue instead, and no polling -notifiers. During operation, the event virtqueue is typically -non-empty, but none of the buffers are intended to be used immediately. -Instead, they only get used when certain events occur. Therefore, it -makes no sense to continuously poll it when non-empty, because it is -supposed to be and stay non-empty. - -We do this by using virtio_queue_aio_attach_host_notifier_no_poll() -instead of virtio_queue_aio_attach_host_notifier() for the event -virtqueue. - -Commit 766aa2de0f29b657148e04599320d771c36fd126 ("virtio-scsi: implement -BlockDevOps->drained_begin()") however has virtio_scsi_drained_end() use -virtio_queue_aio_attach_host_notifier() for all virtqueues, including -the event virtqueue. This can lead to it being polled again, undoing -the benefit of commit 38738f7dbbda90fbc161757b7f4be35b52205552. - -Fix it by using virtio_queue_aio_attach_host_notifier_no_poll() for the -event virtqueue. - - ("virtio-scsi: implement BlockDevOps->drained_begin()") - -Reported-by: Fiona Ebner -Fixes: 766aa2de0f29b657148e04599320d771c36fd126 -Reviewed-by: Stefan Hajnoczi -Tested-by: Fiona Ebner -Reviewed-by: Fiona Ebner -Signed-off-by: Hanna Czenczek -Signed-off-by: Thomas Lamprecht ---- - hw/scsi/virtio-scsi.c | 7 ++++++- - 1 file changed, 6 insertions(+), 1 deletion(-) - -diff --git a/hw/scsi/virtio-scsi.c b/hw/scsi/virtio-scsi.c -index 45b95ea070..ad24a882fd 100644 ---- a/hw/scsi/virtio-scsi.c -+++ b/hw/scsi/virtio-scsi.c -@@ -1148,6 +1148,7 @@ static void virtio_scsi_drained_begin(SCSIBus *bus) - static void virtio_scsi_drained_end(SCSIBus *bus) - { - VirtIOSCSI *s = container_of(bus, VirtIOSCSI, bus); -+ VirtIOSCSICommon *vs = VIRTIO_SCSI_COMMON(s); - VirtIODevice *vdev = VIRTIO_DEVICE(s); - uint32_t total_queues = VIRTIO_SCSI_VQ_NUM_FIXED + - s->parent_obj.conf.num_queues; -@@ -1165,7 +1166,11 @@ static void virtio_scsi_drained_end(SCSIBus *bus) - - for (uint32_t i = 0; i < total_queues; i++) { - VirtQueue *vq = virtio_get_queue(vdev, i); -- virtio_queue_aio_attach_host_notifier(vq, s->ctx); -+ if (vq == vs->event_vq) { -+ virtio_queue_aio_attach_host_notifier_no_poll(vq, s->ctx); -+ } else { -+ virtio_queue_aio_attach_host_notifier(vq, s->ctx); -+ } - } - } - diff --git a/debian/patches/extra/0011-virtio-Re-enable-notifications-after-drain.patch b/debian/patches/extra/0011-virtio-Re-enable-notifications-after-drain.patch deleted file mode 100644 index 618ccb2..0000000 --- a/debian/patches/extra/0011-virtio-Re-enable-notifications-after-drain.patch +++ /dev/null @@ -1,125 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Hanna Czenczek -Date: Fri, 2 Feb 2024 16:31:57 +0100 -Subject: [PATCH] virtio: Re-enable notifications after drain - -During drain, we do not care about virtqueue notifications, which is why -we remove the handlers on it. When removing those handlers, whether vq -notifications are enabled or not depends on whether we were in polling -mode or not; if not, they are enabled (by default); if so, they have -been disabled by the io_poll_start callback. - -Because we do not care about those notifications after removing the -handlers, this is fine. However, we have to explicitly ensure they are -enabled when re-attaching the handlers, so we will resume receiving -notifications. We do this in virtio_queue_aio_attach_host_notifier*(). -If such a function is called while we are in a polling section, -attaching the notifiers will then invoke the io_poll_start callback, -re-disabling notifications. - -Because we will always miss virtqueue updates in the drained section, we -also need to poll the virtqueue once after attaching the notifiers. - -Buglink: https://issues.redhat.com/browse/RHEL-3934 -Signed-off-by: Hanna Czenczek -Signed-off-by: Thomas Lamprecht ---- - hw/virtio/virtio.c | 42 ++++++++++++++++++++++++++++++++++++++++++ - include/block/aio.h | 7 ++++++- - 2 files changed, 48 insertions(+), 1 deletion(-) - -diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c -index 969c25f4cf..02cce83111 100644 ---- a/hw/virtio/virtio.c -+++ b/hw/virtio/virtio.c -@@ -3526,6 +3526,17 @@ static void virtio_queue_host_notifier_aio_poll_end(EventNotifier *n) - - void virtio_queue_aio_attach_host_notifier(VirtQueue *vq, AioContext *ctx) - { -+ /* -+ * virtio_queue_aio_detach_host_notifier() can leave notifications disabled. -+ * Re-enable them. (And if detach has not been used before, notifications -+ * being enabled is still the default state while a notifier is attached; -+ * see virtio_queue_host_notifier_aio_poll_end(), which will always leave -+ * notifications enabled once the polling section is left.) -+ */ -+ if (!virtio_queue_get_notification(vq)) { -+ virtio_queue_set_notification(vq, 1); -+ } -+ - aio_set_event_notifier(ctx, &vq->host_notifier, - virtio_queue_host_notifier_read, - virtio_queue_host_notifier_aio_poll, -@@ -3533,6 +3544,13 @@ void virtio_queue_aio_attach_host_notifier(VirtQueue *vq, AioContext *ctx) - aio_set_event_notifier_poll(ctx, &vq->host_notifier, - virtio_queue_host_notifier_aio_poll_begin, - virtio_queue_host_notifier_aio_poll_end); -+ -+ /* -+ * We will have ignored notifications about new requests from the guest -+ * while no notifiers were attached, so "kick" the virt queue to process -+ * those requests now. -+ */ -+ event_notifier_set(&vq->host_notifier); - } - - /* -@@ -3543,14 +3561,38 @@ void virtio_queue_aio_attach_host_notifier(VirtQueue *vq, AioContext *ctx) - */ - void virtio_queue_aio_attach_host_notifier_no_poll(VirtQueue *vq, AioContext *ctx) - { -+ /* See virtio_queue_aio_attach_host_notifier() */ -+ if (!virtio_queue_get_notification(vq)) { -+ virtio_queue_set_notification(vq, 1); -+ } -+ - aio_set_event_notifier(ctx, &vq->host_notifier, - virtio_queue_host_notifier_read, - NULL, NULL); -+ -+ /* -+ * See virtio_queue_aio_attach_host_notifier(). -+ * Note that this may be unnecessary for the type of virtqueues this -+ * function is used for. Still, it will not hurt to have a quick look into -+ * whether we can/should process any of the virtqueue elements. -+ */ -+ event_notifier_set(&vq->host_notifier); - } - - void virtio_queue_aio_detach_host_notifier(VirtQueue *vq, AioContext *ctx) - { - aio_set_event_notifier(ctx, &vq->host_notifier, NULL, NULL, NULL); -+ -+ /* -+ * aio_set_event_notifier_poll() does not guarantee whether io_poll_end() -+ * will run after io_poll_begin(), so by removing the notifier, we do not -+ * know whether virtio_queue_host_notifier_aio_poll_end() has run after a -+ * previous virtio_queue_host_notifier_aio_poll_begin(), i.e. whether -+ * notifications are enabled or disabled. It does not really matter anyway; -+ * we just removed the notifier, so we do not care about notifications until -+ * we potentially re-attach it. The attach_host_notifier functions will -+ * ensure that notifications are enabled again when they are needed. -+ */ - } - - void virtio_queue_host_notifier_read(EventNotifier *n) -diff --git a/include/block/aio.h b/include/block/aio.h -index 32042e8905..79efadfa48 100644 ---- a/include/block/aio.h -+++ b/include/block/aio.h -@@ -498,9 +498,14 @@ void aio_set_event_notifier(AioContext *ctx, - AioPollFn *io_poll, - EventNotifierHandler *io_poll_ready); - --/* Set polling begin/end callbacks for an event notifier that has already been -+/* -+ * Set polling begin/end callbacks for an event notifier that has already been - * registered with aio_set_event_notifier. Do nothing if the event notifier is - * not registered. -+ * -+ * Note that if the io_poll_end() callback (or the entire notifier) is removed -+ * during polling, it will not be called, so an io_poll_begin() is not -+ * necessarily always followed by an io_poll_end(). - */ - void aio_set_event_notifier_poll(AioContext *ctx, - EventNotifier *notifier, diff --git a/debian/patches/extra/0013-virtio-blk-avoid-using-ioeventfd-state-in-irqfd-cond.patch b/debian/patches/extra/0013-virtio-blk-avoid-using-ioeventfd-state-in-irqfd-cond.patch deleted file mode 100644 index 8109e7d..0000000 --- a/debian/patches/extra/0013-virtio-blk-avoid-using-ioeventfd-state-in-irqfd-cond.patch +++ /dev/null @@ -1,61 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Stefan Hajnoczi -Date: Mon, 22 Jan 2024 12:26:25 -0500 -Subject: [PATCH] virtio-blk: avoid using ioeventfd state in irqfd conditional - -Requests that complete in an IOThread use irqfd to notify the guest -while requests that complete in the main loop thread use the traditional -qdev irq code path. The reason for this conditional is that the irq code -path requires the BQL: - - if (s->ioeventfd_started && !s->ioeventfd_disabled) { - virtio_notify_irqfd(vdev, req->vq); - } else { - virtio_notify(vdev, req->vq); - } - -There is a corner case where the conditional invokes the irq code path -instead of the irqfd code path: - - static void virtio_blk_stop_ioeventfd(VirtIODevice *vdev) - { - ... - /* - * Set ->ioeventfd_started to false before draining so that host notifiers - * are not detached/attached anymore. - */ - s->ioeventfd_started = false; - - /* Wait for virtio_blk_dma_restart_bh() and in flight I/O to complete */ - blk_drain(s->conf.conf.blk); - -During blk_drain() the conditional produces the wrong result because -ioeventfd_started is false. - -Use qemu_in_iothread() instead of checking the ioeventfd state. - -Cc: qemu-stable@nongnu.org -Buglink: https://issues.redhat.com/browse/RHEL-15394 -Signed-off-by: Stefan Hajnoczi -Message-ID: <20240122172625.415386-1-stefanha@redhat.com> -Reviewed-by: Kevin Wolf -Signed-off-by: Kevin Wolf -[FE: backport: dataplane -> ioeventfd rework didn't happen yet] -Signed-off-by: Fiona Ebner ---- - hw/block/virtio-blk.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c -index 39e7f23fab..61bd1f6859 100644 ---- a/hw/block/virtio-blk.c -+++ b/hw/block/virtio-blk.c -@@ -64,7 +64,7 @@ static void virtio_blk_req_complete(VirtIOBlockReq *req, unsigned char status) - iov_discard_undo(&req->inhdr_undo); - iov_discard_undo(&req->outhdr_undo); - virtqueue_push(req->vq, &req->elem, req->in_len); -- if (s->dataplane_started && !s->dataplane_disabled) { -+ if (qemu_in_iothread()) { - virtio_blk_data_plane_notify(s->dataplane, req->vq); - } else { - virtio_notify(vdev, req->vq); diff --git a/debian/patches/pve/0001-PVE-Config-block-file-change-locking-default-to-off.patch b/debian/patches/pve/0001-PVE-Config-block-file-change-locking-default-to-off.patch index 30dd2d4..338a6bc 100644 --- a/debian/patches/pve/0001-PVE-Config-block-file-change-locking-default-to-off.patch +++ b/debian/patches/pve/0001-PVE-Config-block-file-change-locking-default-to-off.patch @@ -14,7 +14,7 @@ Signed-off-by: Thomas Lamprecht 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/block/file-posix.c b/block/file-posix.c -index 7f540b03ed..ca551baa42 100644 +index b862406c71..bc09aefe3b 100644 --- a/block/file-posix.c +++ b/block/file-posix.c @@ -563,7 +563,7 @@ static QemuOptsList raw_runtime_opts = { diff --git a/debian/patches/pve/0002-PVE-Config-Adjust-network-script-path-to-etc-kvm.patch b/debian/patches/pve/0002-PVE-Config-Adjust-network-script-path-to-etc-kvm.patch index f7c9754..2c285e1 100644 --- a/debian/patches/pve/0002-PVE-Config-Adjust-network-script-path-to-etc-kvm.patch +++ b/debian/patches/pve/0002-PVE-Config-Adjust-network-script-path-to-etc-kvm.patch @@ -9,10 +9,10 @@ Signed-off-by: Thomas Lamprecht 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/net/net.h b/include/net/net.h -index 685ec58318..22edf4ee96 100644 +index ffbd2c8d56..e857c75f4c 100644 --- a/include/net/net.h +++ b/include/net/net.h -@@ -260,8 +260,8 @@ void netdev_add(QemuOpts *opts, Error **errp); +@@ -263,8 +263,8 @@ void netdev_add(QemuOpts *opts, Error **errp); int net_hub_id_for_client(NetClientState *nc, int *id); NetClientState *net_hub_port_find(int hub_id); diff --git a/debian/patches/pve/0003-PVE-Config-set-the-CPU-model-to-kvm64-32-instead-of-.patch b/debian/patches/pve/0003-PVE-Config-set-the-CPU-model-to-kvm64-32-instead-of-.patch index 4955ba3..595073d 100644 --- a/debian/patches/pve/0003-PVE-Config-set-the-CPU-model-to-kvm64-32-instead-of-.patch +++ b/debian/patches/pve/0003-PVE-Config-set-the-CPU-model-to-kvm64-32-instead-of-.patch @@ -10,10 +10,10 @@ Signed-off-by: Thomas Lamprecht 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/target/i386/cpu.h b/target/i386/cpu.h -index 0893b794e9..6d650a58b9 100644 +index 705d925e6c..ba269e5f1e 100644 --- a/target/i386/cpu.h +++ b/target/i386/cpu.h -@@ -2243,9 +2243,9 @@ uint64_t cpu_get_tsc(CPUX86State *env); +@@ -2281,9 +2281,9 @@ uint64_t cpu_get_tsc(CPUX86State *env); #define CPU_RESOLVING_TYPE TYPE_X86_CPU #ifdef TARGET_X86_64 diff --git a/debian/patches/pve/0004-PVE-Config-ui-spice-default-to-pve-certificates.patch b/debian/patches/pve/0004-PVE-Config-ui-spice-default-to-pve-certificates.patch index 6405a25..566ab43 100644 --- a/debian/patches/pve/0004-PVE-Config-ui-spice-default-to-pve-certificates.patch +++ b/debian/patches/pve/0004-PVE-Config-ui-spice-default-to-pve-certificates.patch @@ -9,7 +9,7 @@ Signed-off-by: Thomas Lamprecht 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/ui/spice-core.c b/ui/spice-core.c -index 52a59386d7..b20c25aee0 100644 +index db21db2c94..0eb138cf43 100644 --- a/ui/spice-core.c +++ b/ui/spice-core.c @@ -691,32 +691,35 @@ static void qemu_spice_init(void) diff --git a/debian/patches/pve/0005-PVE-Config-glusterfs-no-default-logfile-if-daemonize.patch b/debian/patches/pve/0005-PVE-Config-glusterfs-no-default-logfile-if-daemonize.patch index 947fc90..cb94976 100644 --- a/debian/patches/pve/0005-PVE-Config-glusterfs-no-default-logfile-if-daemonize.patch +++ b/debian/patches/pve/0005-PVE-Config-glusterfs-no-default-logfile-if-daemonize.patch @@ -9,7 +9,7 @@ Signed-off-by: Thomas Lamprecht 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/block/gluster.c b/block/gluster.c -index ad5fadbe79..d0011085c4 100644 +index cc74af06dc..3ba9bbfa5e 100644 --- a/block/gluster.c +++ b/block/gluster.c @@ -43,7 +43,7 @@ diff --git a/debian/patches/pve/0006-PVE-Config-rbd-block-rbd-disable-rbd_cache_writethro.patch b/debian/patches/pve/0006-PVE-Config-rbd-block-rbd-disable-rbd_cache_writethro.patch index 4bdb7b5..8881ab8 100644 --- a/debian/patches/pve/0006-PVE-Config-rbd-block-rbd-disable-rbd_cache_writethro.patch +++ b/debian/patches/pve/0006-PVE-Config-rbd-block-rbd-disable-rbd_cache_writethro.patch @@ -18,7 +18,7 @@ Signed-off-by: Thomas Lamprecht 1 file changed, 2 insertions(+) diff --git a/block/rbd.c b/block/rbd.c -index 978671411e..a4749f3b1b 100644 +index 84bb2fa5d7..63f60d41be 100644 --- a/block/rbd.c +++ b/block/rbd.c @@ -963,6 +963,8 @@ static int qemu_rbd_connect(rados_t *cluster, rados_ioctx_t *io_ctx, diff --git a/debian/patches/pve/0007-PVE-Up-glusterfs-allow-partial-reads.patch b/debian/patches/pve/0007-PVE-Up-glusterfs-allow-partial-reads.patch index c4e6729..56f56f6 100644 --- a/debian/patches/pve/0007-PVE-Up-glusterfs-allow-partial-reads.patch +++ b/debian/patches/pve/0007-PVE-Up-glusterfs-allow-partial-reads.patch @@ -16,7 +16,7 @@ Signed-off-by: Thomas Lamprecht 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/block/gluster.c b/block/gluster.c -index d0011085c4..2df3d6e35d 100644 +index 3ba9bbfa5e..34936eb855 100644 --- a/block/gluster.c +++ b/block/gluster.c @@ -58,6 +58,7 @@ typedef struct GlusterAIOCB { @@ -39,7 +39,7 @@ index d0011085c4..2df3d6e35d 100644 } aio_co_schedule(acb->aio_context, acb->coroutine); -@@ -1021,6 +1024,7 @@ static coroutine_fn int qemu_gluster_co_pwrite_zeroes(BlockDriverState *bs, +@@ -1023,6 +1026,7 @@ static coroutine_fn int qemu_gluster_co_pwrite_zeroes(BlockDriverState *bs, acb.ret = 0; acb.coroutine = qemu_coroutine_self(); acb.aio_context = bdrv_get_aio_context(bs); @@ -47,7 +47,7 @@ index d0011085c4..2df3d6e35d 100644 ret = glfs_zerofill_async(s->fd, offset, bytes, gluster_finish_aiocb, &acb); if (ret < 0) { -@@ -1201,9 +1205,11 @@ static coroutine_fn int qemu_gluster_co_rw(BlockDriverState *bs, +@@ -1203,9 +1207,11 @@ static coroutine_fn int qemu_gluster_co_rw(BlockDriverState *bs, acb.aio_context = bdrv_get_aio_context(bs); if (write) { @@ -59,7 +59,7 @@ index d0011085c4..2df3d6e35d 100644 ret = glfs_preadv_async(s->fd, qiov->iov, qiov->niov, offset, 0, gluster_finish_aiocb, &acb); } -@@ -1266,6 +1272,7 @@ static coroutine_fn int qemu_gluster_co_flush_to_disk(BlockDriverState *bs) +@@ -1268,6 +1274,7 @@ static coroutine_fn int qemu_gluster_co_flush_to_disk(BlockDriverState *bs) acb.ret = 0; acb.coroutine = qemu_coroutine_self(); acb.aio_context = bdrv_get_aio_context(bs); @@ -67,7 +67,7 @@ index d0011085c4..2df3d6e35d 100644 ret = glfs_fsync_async(s->fd, gluster_finish_aiocb, &acb); if (ret < 0) { -@@ -1314,6 +1321,7 @@ static coroutine_fn int qemu_gluster_co_pdiscard(BlockDriverState *bs, +@@ -1316,6 +1323,7 @@ static coroutine_fn int qemu_gluster_co_pdiscard(BlockDriverState *bs, acb.ret = 0; acb.coroutine = qemu_coroutine_self(); acb.aio_context = bdrv_get_aio_context(bs); diff --git a/debian/patches/pve/0008-PVE-Up-qemu-img-return-success-on-info-without-snaps.patch b/debian/patches/pve/0008-PVE-Up-qemu-img-return-success-on-info-without-snaps.patch index 3bdb7ee..6d5a5c1 100644 --- a/debian/patches/pve/0008-PVE-Up-qemu-img-return-success-on-info-without-snaps.patch +++ b/debian/patches/pve/0008-PVE-Up-qemu-img-return-success-on-info-without-snaps.patch @@ -9,10 +9,10 @@ Signed-off-by: Thomas Lamprecht 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/qemu-img.c b/qemu-img.c -index 78433f3746..25d427edd1 100644 +index 5a77f67719..de51233825 100644 --- a/qemu-img.c +++ b/qemu-img.c -@@ -3062,7 +3062,8 @@ static int img_info(int argc, char **argv) +@@ -3079,7 +3079,8 @@ static int img_info(int argc, char **argv) list = collect_image_info_list(image_opts, filename, fmt, chain, force_share); if (!list) { diff --git a/debian/patches/pve/0009-PVE-Up-qemu-img-dd-add-osize-and-read-from-to-stdin-.patch b/debian/patches/pve/0009-PVE-Up-qemu-img-dd-add-osize-and-read-from-to-stdin-.patch index 5255268..7a78820 100644 --- a/debian/patches/pve/0009-PVE-Up-qemu-img-dd-add-osize-and-read-from-to-stdin-.patch +++ b/debian/patches/pve/0009-PVE-Up-qemu-img-dd-add-osize-and-read-from-to-stdin-.patch @@ -38,7 +38,7 @@ Signed-off-by: Fiona Ebner 2 files changed, 133 insertions(+), 73 deletions(-) diff --git a/qemu-img-cmds.hx b/qemu-img-cmds.hx -index 1b1dab5b17..d1616c045a 100644 +index 068692d13e..73e0bb1d2c 100644 --- a/qemu-img-cmds.hx +++ b/qemu-img-cmds.hx @@ -58,9 +58,9 @@ SRST @@ -54,10 +54,10 @@ index 1b1dab5b17..d1616c045a 100644 DEF("info", img_info, diff --git a/qemu-img.c b/qemu-img.c -index 25d427edd1..220e6ec577 100644 +index de51233825..ad770f6570 100644 --- a/qemu-img.c +++ b/qemu-img.c -@@ -4899,10 +4899,12 @@ static int img_bitmap(int argc, char **argv) +@@ -4997,10 +4997,12 @@ static int img_bitmap(int argc, char **argv) #define C_IF 04 #define C_OF 010 #define C_SKIP 020 @@ -70,7 +70,7 @@ index 25d427edd1..220e6ec577 100644 }; struct DdIo { -@@ -4978,6 +4980,19 @@ static int img_dd_skip(const char *arg, +@@ -5076,6 +5078,19 @@ static int img_dd_skip(const char *arg, return 0; } @@ -90,7 +90,7 @@ index 25d427edd1..220e6ec577 100644 static int img_dd(int argc, char **argv) { int ret = 0; -@@ -5018,6 +5033,7 @@ static int img_dd(int argc, char **argv) +@@ -5116,6 +5131,7 @@ static int img_dd(int argc, char **argv) { "if", img_dd_if, C_IF }, { "of", img_dd_of, C_OF }, { "skip", img_dd_skip, C_SKIP }, @@ -98,7 +98,7 @@ index 25d427edd1..220e6ec577 100644 { NULL, NULL, 0 } }; const struct option long_options[] = { -@@ -5093,91 +5109,112 @@ static int img_dd(int argc, char **argv) +@@ -5191,91 +5207,112 @@ static int img_dd(int argc, char **argv) arg = NULL; } @@ -275,7 +275,7 @@ index 25d427edd1..220e6ec577 100644 } if (dd.flags & C_SKIP && (in.offset > INT64_MAX / in.bsz || -@@ -5194,20 +5231,43 @@ static int img_dd(int argc, char **argv) +@@ -5292,20 +5329,43 @@ static int img_dd(int argc, char **argv) in.buf = g_new(uint8_t, in.bsz); for (out_pos = 0; in_pos < size; ) { diff --git a/debian/patches/pve/0010-PVE-Up-qemu-img-dd-add-isize-parameter.patch b/debian/patches/pve/0010-PVE-Up-qemu-img-dd-add-isize-parameter.patch index d68e2aa..ea2031e 100644 --- a/debian/patches/pve/0010-PVE-Up-qemu-img-dd-add-isize-parameter.patch +++ b/debian/patches/pve/0010-PVE-Up-qemu-img-dd-add-isize-parameter.patch @@ -16,10 +16,10 @@ Signed-off-by: Fiona Ebner 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/qemu-img.c b/qemu-img.c -index 220e6ec577..58bf9b43d1 100644 +index ad770f6570..b0839a5d18 100644 --- a/qemu-img.c +++ b/qemu-img.c -@@ -4900,11 +4900,13 @@ static int img_bitmap(int argc, char **argv) +@@ -4998,11 +4998,13 @@ static int img_bitmap(int argc, char **argv) #define C_OF 010 #define C_SKIP 020 #define C_OSIZE 040 @@ -33,7 +33,7 @@ index 220e6ec577..58bf9b43d1 100644 }; struct DdIo { -@@ -4993,6 +4995,19 @@ static int img_dd_osize(const char *arg, +@@ -5091,6 +5093,19 @@ static int img_dd_osize(const char *arg, return 0; } @@ -53,7 +53,7 @@ index 220e6ec577..58bf9b43d1 100644 static int img_dd(int argc, char **argv) { int ret = 0; -@@ -5007,12 +5022,14 @@ static int img_dd(int argc, char **argv) +@@ -5105,12 +5120,14 @@ static int img_dd(int argc, char **argv) int c, i; const char *out_fmt = "raw"; const char *fmt = NULL; @@ -69,7 +69,7 @@ index 220e6ec577..58bf9b43d1 100644 }; struct DdIo in = { .bsz = 512, /* Block size is by default 512 bytes */ -@@ -5034,6 +5051,7 @@ static int img_dd(int argc, char **argv) +@@ -5132,6 +5149,7 @@ static int img_dd(int argc, char **argv) { "of", img_dd_of, C_OF }, { "skip", img_dd_skip, C_SKIP }, { "osize", img_dd_osize, C_OSIZE }, @@ -77,7 +77,7 @@ index 220e6ec577..58bf9b43d1 100644 { NULL, NULL, 0 } }; const struct option long_options[] = { -@@ -5230,9 +5248,10 @@ static int img_dd(int argc, char **argv) +@@ -5328,9 +5346,10 @@ static int img_dd(int argc, char **argv) in.buf = g_new(uint8_t, in.bsz); @@ -90,7 +90,7 @@ index 220e6ec577..58bf9b43d1 100644 if (blk1) { in_ret = blk_pread(blk1, in_pos, bytes, in.buf, 0); if (in_ret == 0) { -@@ -5241,6 +5260,9 @@ static int img_dd(int argc, char **argv) +@@ -5339,6 +5358,9 @@ static int img_dd(int argc, char **argv) } else { in_ret = read(STDIN_FILENO, in.buf, bytes); if (in_ret == 0) { diff --git a/debian/patches/pve/0011-PVE-Up-qemu-img-dd-add-n-skip_create.patch b/debian/patches/pve/0011-PVE-Up-qemu-img-dd-add-n-skip_create.patch index 5131d98..0c2cb38 100644 --- a/debian/patches/pve/0011-PVE-Up-qemu-img-dd-add-n-skip_create.patch +++ b/debian/patches/pve/0011-PVE-Up-qemu-img-dd-add-n-skip_create.patch @@ -13,10 +13,10 @@ Signed-off-by: Fiona Ebner 3 files changed, 26 insertions(+), 12 deletions(-) diff --git a/docs/tools/qemu-img.rst b/docs/tools/qemu-img.rst -index 15aeddc6d8..5e713e231d 100644 +index 4459c065f1..c6bc902182 100644 --- a/docs/tools/qemu-img.rst +++ b/docs/tools/qemu-img.rst -@@ -208,6 +208,10 @@ Parameters to convert subcommand: +@@ -212,6 +212,10 @@ Parameters to convert subcommand: Parameters to dd subcommand: @@ -27,7 +27,7 @@ index 15aeddc6d8..5e713e231d 100644 .. program:: qemu-img-dd .. option:: bs=BLOCK_SIZE -@@ -488,7 +492,7 @@ Command description: +@@ -492,7 +496,7 @@ Command description: it doesn't need to be specified separately in this case. @@ -36,7 +36,7 @@ index 15aeddc6d8..5e713e231d 100644 dd copies from *INPUT* file to *OUTPUT* file converting it from *FMT* format to *OUTPUT_FMT* format. -@@ -499,6 +503,11 @@ Command description: +@@ -503,6 +507,11 @@ Command description: The size syntax is similar to :manpage:`dd(1)`'s size syntax. @@ -49,7 +49,7 @@ index 15aeddc6d8..5e713e231d 100644 Give information about the disk image *FILENAME*. Use it in diff --git a/qemu-img-cmds.hx b/qemu-img-cmds.hx -index d1616c045a..b5b0bb4467 100644 +index 73e0bb1d2c..32749b416e 100644 --- a/qemu-img-cmds.hx +++ b/qemu-img-cmds.hx @@ -58,9 +58,9 @@ SRST @@ -65,10 +65,10 @@ index d1616c045a..b5b0bb4467 100644 DEF("info", img_info, diff --git a/qemu-img.c b/qemu-img.c -index 58bf9b43d1..9d414d639b 100644 +index b0839a5d18..4acdf75879 100644 --- a/qemu-img.c +++ b/qemu-img.c -@@ -5024,7 +5024,7 @@ static int img_dd(int argc, char **argv) +@@ -5122,7 +5122,7 @@ static int img_dd(int argc, char **argv) const char *fmt = NULL; int64_t size = 0, readsize = 0; int64_t out_pos, in_pos; @@ -77,7 +77,7 @@ index 58bf9b43d1..9d414d639b 100644 struct DdInfo dd = { .flags = 0, .count = 0, -@@ -5062,7 +5062,7 @@ static int img_dd(int argc, char **argv) +@@ -5160,7 +5160,7 @@ static int img_dd(int argc, char **argv) { 0, 0, 0, 0 } }; @@ -86,7 +86,7 @@ index 58bf9b43d1..9d414d639b 100644 if (c == EOF) { break; } -@@ -5082,6 +5082,9 @@ static int img_dd(int argc, char **argv) +@@ -5180,6 +5180,9 @@ static int img_dd(int argc, char **argv) case 'h': help(); break; @@ -96,7 +96,7 @@ index 58bf9b43d1..9d414d639b 100644 case 'U': force_share = true; break; -@@ -5212,13 +5215,15 @@ static int img_dd(int argc, char **argv) +@@ -5310,13 +5313,15 @@ static int img_dd(int argc, char **argv) size - in.bsz * in.offset, &error_abort); } diff --git a/debian/patches/pve/0012-qemu-img-dd-add-l-option-for-loading-a-snapshot.patch b/debian/patches/pve/0012-qemu-img-dd-add-l-option-for-loading-a-snapshot.patch index a956795..2c8f56e 100644 --- a/debian/patches/pve/0012-qemu-img-dd-add-l-option-for-loading-a-snapshot.patch +++ b/debian/patches/pve/0012-qemu-img-dd-add-l-option-for-loading-a-snapshot.patch @@ -12,10 +12,10 @@ Signed-off-by: Thomas Lamprecht 3 files changed, 36 insertions(+), 7 deletions(-) diff --git a/docs/tools/qemu-img.rst b/docs/tools/qemu-img.rst -index 5e713e231d..9390d5e5cf 100644 +index c6bc902182..fe2241856e 100644 --- a/docs/tools/qemu-img.rst +++ b/docs/tools/qemu-img.rst -@@ -492,10 +492,10 @@ Command description: +@@ -496,10 +496,10 @@ Command description: it doesn't need to be specified separately in this case. @@ -30,7 +30,7 @@ index 5e713e231d..9390d5e5cf 100644 The data is by default read and written using blocks of 512 bytes but can be modified by specifying *BLOCK_SIZE*. If count=\ *BLOCKS* is specified diff --git a/qemu-img-cmds.hx b/qemu-img-cmds.hx -index b5b0bb4467..36f97e1f19 100644 +index 32749b416e..40ee9c0ed8 100644 --- a/qemu-img-cmds.hx +++ b/qemu-img-cmds.hx @@ -58,9 +58,9 @@ SRST @@ -46,10 +46,10 @@ index b5b0bb4467..36f97e1f19 100644 DEF("info", img_info, diff --git a/qemu-img.c b/qemu-img.c -index 9d414d639b..e13a12137b 100644 +index 4acdf75879..a9632b5951 100644 --- a/qemu-img.c +++ b/qemu-img.c -@@ -5016,6 +5016,7 @@ static int img_dd(int argc, char **argv) +@@ -5114,6 +5114,7 @@ static int img_dd(int argc, char **argv) BlockDriver *drv = NULL, *proto_drv = NULL; BlockBackend *blk1 = NULL, *blk2 = NULL; QemuOpts *opts = NULL; @@ -57,7 +57,7 @@ index 9d414d639b..e13a12137b 100644 QemuOptsList *create_opts = NULL; Error *local_err = NULL; bool image_opts = false; -@@ -5025,6 +5026,7 @@ static int img_dd(int argc, char **argv) +@@ -5123,6 +5124,7 @@ static int img_dd(int argc, char **argv) int64_t size = 0, readsize = 0; int64_t out_pos, in_pos; bool force_share = false, skip_create = false; @@ -65,7 +65,7 @@ index 9d414d639b..e13a12137b 100644 struct DdInfo dd = { .flags = 0, .count = 0, -@@ -5062,7 +5064,7 @@ static int img_dd(int argc, char **argv) +@@ -5160,7 +5162,7 @@ static int img_dd(int argc, char **argv) { 0, 0, 0, 0 } }; @@ -74,7 +74,7 @@ index 9d414d639b..e13a12137b 100644 if (c == EOF) { break; } -@@ -5085,6 +5087,19 @@ static int img_dd(int argc, char **argv) +@@ -5183,6 +5185,19 @@ static int img_dd(int argc, char **argv) case 'n': skip_create = true; break; @@ -94,7 +94,7 @@ index 9d414d639b..e13a12137b 100644 case 'U': force_share = true; break; -@@ -5144,11 +5159,24 @@ static int img_dd(int argc, char **argv) +@@ -5242,11 +5257,24 @@ static int img_dd(int argc, char **argv) if (dd.flags & C_IF) { blk1 = img_open(image_opts, in.filename, fmt, 0, false, false, force_share); @@ -120,7 +120,7 @@ index 9d414d639b..e13a12137b 100644 } if (dd.flags & C_OSIZE) { -@@ -5303,6 +5331,7 @@ static int img_dd(int argc, char **argv) +@@ -5401,6 +5429,7 @@ static int img_dd(int argc, char **argv) out: g_free(arg); qemu_opts_del(opts); diff --git a/debian/patches/pve/0013-PVE-virtio-balloon-improve-query-balloon.patch b/debian/patches/pve/0013-PVE-virtio-balloon-improve-query-balloon.patch index 2c1524f..6b9cb0f 100644 --- a/debian/patches/pve/0013-PVE-virtio-balloon-improve-query-balloon.patch +++ b/debian/patches/pve/0013-PVE-virtio-balloon-improve-query-balloon.patch @@ -18,10 +18,10 @@ Signed-off-by: Fiona Ebner 4 files changed, 82 insertions(+), 4 deletions(-) diff --git a/hw/core/machine-hmp-cmds.c b/hw/core/machine-hmp-cmds.c -index c3e55ef9e9..0e32e6201f 100644 +index a6ff6a4875..e7f74d1c63 100644 --- a/hw/core/machine-hmp-cmds.c +++ b/hw/core/machine-hmp-cmds.c -@@ -169,7 +169,35 @@ void hmp_info_balloon(Monitor *mon, const QDict *qdict) +@@ -175,7 +175,35 @@ void hmp_info_balloon(Monitor *mon, const QDict *qdict) return; } @@ -103,10 +103,10 @@ index d004cf29d2..2660ed520b 100644 static void virtio_balloon_to_target(void *opaque, ram_addr_t target) diff --git a/qapi/machine.json b/qapi/machine.json -index a08b6576ca..5c9a4d55f4 100644 +index b6d634b30d..03a72efc11 100644 --- a/qapi/machine.json +++ b/qapi/machine.json -@@ -1063,9 +1063,29 @@ +@@ -1087,9 +1087,29 @@ # @actual: the logical size of the VM in bytes Formula used: # logical_vm_size = vm_ram_size - balloon_size # @@ -138,7 +138,7 @@ index a08b6576ca..5c9a4d55f4 100644 ## # @query-balloon: diff --git a/qapi/pragma.json b/qapi/pragma.json -index 7f810b0e97..325e684411 100644 +index 0aa4eeddd3..eae9f54700 100644 --- a/qapi/pragma.json +++ b/qapi/pragma.json @@ -35,6 +35,7 @@ diff --git a/debian/patches/pve/0014-PVE-qapi-modify-query-machines.patch b/debian/patches/pve/0014-PVE-qapi-modify-query-machines.patch index ab331f3..1fd44dc 100644 --- a/debian/patches/pve/0014-PVE-qapi-modify-query-machines.patch +++ b/debian/patches/pve/0014-PVE-qapi-modify-query-machines.patch @@ -30,10 +30,10 @@ index 3860a50c3b..40821e2317 100644 info->default_cpu_type = g_strdup(mc->default_cpu_type); } diff --git a/qapi/machine.json b/qapi/machine.json -index 5c9a4d55f4..fbb61f18e4 100644 +index 03a72efc11..297ad0e0e5 100644 --- a/qapi/machine.json +++ b/qapi/machine.json -@@ -139,6 +139,8 @@ +@@ -146,6 +146,8 @@ # # @is-default: whether the machine is default # @@ -42,7 +42,7 @@ index 5c9a4d55f4..fbb61f18e4 100644 # @cpu-max: maximum number of CPUs supported by the machine type # (since 1.5) # -@@ -163,7 +165,7 @@ +@@ -170,7 +172,7 @@ ## { 'struct': 'MachineInfo', 'data': { 'name': 'str', '*alias': 'str', diff --git a/debian/patches/pve/0015-PVE-qapi-modify-spice-query.patch b/debian/patches/pve/0015-PVE-qapi-modify-spice-query.patch index 26c6840..4f9533d 100644 --- a/debian/patches/pve/0015-PVE-qapi-modify-spice-query.patch +++ b/debian/patches/pve/0015-PVE-qapi-modify-spice-query.patch @@ -14,10 +14,10 @@ Signed-off-by: Fiona Ebner 2 files changed, 7 insertions(+) diff --git a/qapi/ui.json b/qapi/ui.json -index 006616aa77..dfd1d3e36b 100644 +index a0158baf23..20d8994f49 100644 --- a/qapi/ui.json +++ b/qapi/ui.json -@@ -317,11 +317,14 @@ +@@ -318,11 +318,14 @@ # # @channels: a list of @SpiceChannel for each active spice channel # @@ -33,7 +33,7 @@ index 006616aa77..dfd1d3e36b 100644 'if': 'CONFIG_SPICE' } diff --git a/ui/spice-core.c b/ui/spice-core.c -index b20c25aee0..26baeb7846 100644 +index 0eb138cf43..56d677efe1 100644 --- a/ui/spice-core.c +++ b/ui/spice-core.c @@ -548,6 +548,10 @@ static SpiceInfo *qmp_query_spice_real(Error **errp) diff --git a/debian/patches/pve/0016-PVE-add-IOChannel-implementation-for-savevm-async.patch b/debian/patches/pve/0016-PVE-add-IOChannel-implementation-for-savevm-async.patch index df086e3..b24cdff 100644 --- a/debian/patches/pve/0016-PVE-add-IOChannel-implementation-for-savevm-async.patch +++ b/debian/patches/pve/0016-PVE-add-IOChannel-implementation-for-savevm-async.patch @@ -16,19 +16,19 @@ Additionally, allows tracking the current position from the outside Signed-off-by: Fiona Ebner Signed-off-by: Thomas Lamprecht --- - migration/channel-savevm-async.c | 183 +++++++++++++++++++++++++++++++ + migration/channel-savevm-async.c | 184 +++++++++++++++++++++++++++++++ migration/channel-savevm-async.h | 51 +++++++++ migration/meson.build | 1 + - 3 files changed, 235 insertions(+) + 3 files changed, 236 insertions(+) create mode 100644 migration/channel-savevm-async.c create mode 100644 migration/channel-savevm-async.h diff --git a/migration/channel-savevm-async.c b/migration/channel-savevm-async.c new file mode 100644 -index 0000000000..aab081ce07 +index 0000000000..081a192f49 --- /dev/null +++ b/migration/channel-savevm-async.c -@@ -0,0 +1,183 @@ +@@ -0,0 +1,184 @@ +/* + * QIO Channel implementation to be used by savevm-async QMP calls + */ @@ -175,8 +175,9 @@ index 0000000000..aab081ce07 + +static void +qio_channel_savevm_async_set_aio_fd_handler(QIOChannel *ioc, -+ AioContext *ctx, ++ AioContext *read_ctx, + IOHandler *io_read, ++ AioContext *write_ctx, + IOHandler *io_write, + void *opaque) +{ @@ -270,7 +271,7 @@ index 0000000000..17ae2cb261 + +#endif /* QIO_CHANNEL_SAVEVM_ASYNC_H */ diff --git a/migration/meson.build b/migration/meson.build -index 1ae28523a1..37ddcb5d60 100644 +index 92b1cc4297..0e689eac09 100644 --- a/migration/meson.build +++ b/migration/meson.build @@ -13,6 +13,7 @@ system_ss.add(files( diff --git a/debian/patches/pve/0017-PVE-add-savevm-async-for-background-state-snapshots.patch b/debian/patches/pve/0017-PVE-add-savevm-async-for-background-state-snapshots.patch index df12d85..bd8837d 100644 --- a/debian/patches/pve/0017-PVE-add-savevm-async-for-background-state-snapshots.patch +++ b/debian/patches/pve/0017-PVE-add-savevm-async-for-background-state-snapshots.patch @@ -27,7 +27,7 @@ Signed-off-by: Stefan Reiter [FE: further improve aborting adapt to removal of QEMUFileOps improve condition for entering final stage - adapt to QAPI and other changes for 8.0] + adapt to QAPI and other changes for 8.2] Signed-off-by: Fiona Ebner --- hmp-commands-info.hx | 13 + @@ -35,13 +35,13 @@ Signed-off-by: Fiona Ebner include/migration/snapshot.h | 2 + include/monitor/hmp.h | 3 + migration/meson.build | 1 + - migration/savevm-async.c | 531 +++++++++++++++++++++++++++++++++++ + migration/savevm-async.c | 534 +++++++++++++++++++++++++++++++++++ monitor/hmp-cmds.c | 38 +++ qapi/migration.json | 34 +++ qapi/misc.json | 16 ++ qemu-options.hx | 12 + - softmmu/vl.c | 10 + - 11 files changed, 677 insertions(+) + system/vl.c | 10 + + 11 files changed, 680 insertions(+) create mode 100644 migration/savevm-async.c diff --git a/hmp-commands-info.hx b/hmp-commands-info.hx @@ -69,10 +69,10 @@ index f5b37eb74a..10fdd822e0 100644 .name = "balloon", .args_type = "", diff --git a/hmp-commands.hx b/hmp-commands.hx -index 2cbd0f77a0..e352f86872 100644 +index 765349ed14..893c3bd240 100644 --- a/hmp-commands.hx +++ b/hmp-commands.hx -@@ -1865,3 +1865,20 @@ SRST +@@ -1875,3 +1875,20 @@ SRST List event channels in the guest ERST #endif @@ -126,10 +126,10 @@ index 13f9a2dedb..7a7def7530 100644 void coroutine_fn hmp_screendump(Monitor *mon, const QDict *qdict); void hmp_chardev_add(Monitor *mon, const QDict *qdict); diff --git a/migration/meson.build b/migration/meson.build -index 37ddcb5d60..07f6057acc 100644 +index 0e689eac09..8f9d122187 100644 --- a/migration/meson.build +++ b/migration/meson.build -@@ -26,6 +26,7 @@ system_ss.add(files( +@@ -27,6 +27,7 @@ system_ss.add(files( 'options.c', 'postcopy-ram.c', 'savevm.c', @@ -139,10 +139,10 @@ index 37ddcb5d60..07f6057acc 100644 'threadinfo.c', diff --git a/migration/savevm-async.c b/migration/savevm-async.c new file mode 100644 -index 0000000000..e9fc18fb10 +index 0000000000..8f63c4c637 --- /dev/null +++ b/migration/savevm-async.c -@@ -0,0 +1,531 @@ +@@ -0,0 +1,534 @@ +#include "qemu/osdep.h" +#include "migration/channel-savevm-async.h" +#include "migration/migration.h" @@ -441,21 +441,25 @@ index 0000000000..e9fc18fb10 + * so move there now and after every flush. + */ + aio_co_reschedule_self(qemu_get_aio_context()); -+ for (bs = bdrv_first(&it); bs; bs = bdrv_next(&it)) { ++ bdrv_graph_co_rdlock(); ++ bs = bdrv_first(&it); ++ bdrv_graph_co_rdunlock(); ++ while (bs) { + /* target has BDRV_O_NO_FLUSH, no sense calling bdrv_flush on it */ -+ if (bs == blk_bs(snap_state.target)) { -+ continue; -+ } -+ -+ AioContext *bs_ctx = bdrv_get_aio_context(bs); -+ if (bs_ctx != qemu_get_aio_context()) { -+ DPRINTF("savevm: async flushing drive %s\n", bs->filename); -+ aio_co_reschedule_self(bs_ctx); -+ bdrv_graph_co_rdlock(); -+ bdrv_flush(bs); -+ bdrv_graph_co_rdunlock(); -+ aio_co_reschedule_self(qemu_get_aio_context()); ++ if (bs != blk_bs(snap_state.target)) { ++ AioContext *bs_ctx = bdrv_get_aio_context(bs); ++ if (bs_ctx != qemu_get_aio_context()) { ++ DPRINTF("savevm: async flushing drive %s\n", bs->filename); ++ aio_co_reschedule_self(bs_ctx); ++ bdrv_graph_co_rdlock(); ++ bdrv_flush(bs); ++ bdrv_graph_co_rdunlock(); ++ aio_co_reschedule_self(qemu_get_aio_context()); ++ } + } ++ bdrv_graph_co_rdlock(); ++ bs = bdrv_next(&it); ++ bdrv_graph_co_rdunlock(); + } + + DPRINTF("timing: async flushing took %ld ms\n", @@ -535,9 +539,10 @@ index 0000000000..e9fc18fb10 + * State is cleared in process_savevm_co, but has to be initialized + * here (blocking main thread, from QMP) to avoid race conditions. + */ -+ migrate_init(ms); ++ if (migrate_init(ms, errp)) { ++ return; ++ } + memset(&mig_stats, 0, sizeof(mig_stats)); -+ memset(&compression_counters, 0, sizeof(compression_counters)); + ms->to_dst_file = snap_state.file; + + error_setg(&snap_state.blocker, "block device is in use by savevm"); @@ -546,10 +551,8 @@ index 0000000000..e9fc18fb10 + snap_state.state = SAVE_STATE_ACTIVE; + snap_state.finalize_bh = qemu_bh_new(process_savevm_finalize, &snap_state); + snap_state.co = qemu_coroutine_create(&process_savevm_co, NULL); -+ qemu_mutex_unlock_iothread(); + qemu_savevm_state_header(snap_state.file); + qemu_savevm_state_setup(snap_state.file); -+ qemu_mutex_lock_iothread(); + + /* Async processing from here on out happens in iohandler context, so let + * the target bdrv have its home there. @@ -675,7 +678,7 @@ index 0000000000..e9fc18fb10 + return ret; +} diff --git a/monitor/hmp-cmds.c b/monitor/hmp-cmds.c -index 6c559b48c8..91be698308 100644 +index 871898ac46..ef4634e5c1 100644 --- a/monitor/hmp-cmds.c +++ b/monitor/hmp-cmds.c @@ -22,6 +22,7 @@ @@ -685,7 +688,7 @@ index 6c559b48c8..91be698308 100644 +#include "qapi/qapi-commands-migration.h" #include "qapi/qapi-commands-misc.h" #include "qapi/qmp/qdict.h" - #include "qapi/qmp/qerror.h" + #include "qemu/cutils.h" @@ -443,3 +444,40 @@ void hmp_info_mtree(Monitor *mon, const QDict *qdict) mtree_info(flatview, dispatch_tree, owner, disabled); @@ -728,10 +731,10 @@ index 6c559b48c8..91be698308 100644 + } +} diff --git a/qapi/migration.json b/qapi/migration.json -index 8843e74b59..aca0ca1ac1 100644 +index 197d3faa43..b41465fbe9 100644 --- a/qapi/migration.json +++ b/qapi/migration.json -@@ -291,6 +291,40 @@ +@@ -298,6 +298,40 @@ '*dirty-limit-throttle-time-per-round': 'uint64', '*dirty-limit-ring-full-time': 'uint64'} } @@ -800,10 +803,10 @@ index cda2effa81..94a58bb0bf 100644 # @CommandLineParameterType: # diff --git a/qemu-options.hx b/qemu-options.hx -index 8073f5edf5..dc1ececc9c 100644 +index b6b4ad9e67..881b0b3c43 100644 --- a/qemu-options.hx +++ b/qemu-options.hx -@@ -4483,6 +4483,18 @@ SRST +@@ -4590,6 +4590,18 @@ SRST Start right away with a saved state (``loadvm`` in monitor) ERST @@ -822,11 +825,11 @@ index 8073f5edf5..dc1ececc9c 100644 #ifndef _WIN32 DEF("daemonize", 0, QEMU_OPTION_daemonize, \ "-daemonize daemonize QEMU after initializing\n", QEMU_ARCH_ALL) -diff --git a/softmmu/vl.c b/softmmu/vl.c -index ba6ad8a8df..ddeace306e 100644 ---- a/softmmu/vl.c -+++ b/softmmu/vl.c -@@ -164,6 +164,7 @@ static const char *accelerators; +diff --git a/system/vl.c b/system/vl.c +index d2a3b3f457..57f7ba0525 100644 +--- a/system/vl.c ++++ b/system/vl.c +@@ -163,6 +163,7 @@ static const char *accelerators; static bool have_custom_ram_size; static const char *ram_memdev_id; static QDict *machine_opts_dict; @@ -834,7 +837,7 @@ index ba6ad8a8df..ddeace306e 100644 static QTAILQ_HEAD(, ObjectOption) object_opts = QTAILQ_HEAD_INITIALIZER(object_opts); static QTAILQ_HEAD(, DeviceOption) device_opts = QTAILQ_HEAD_INITIALIZER(device_opts); static int display_remote; -@@ -2647,6 +2648,12 @@ void qmp_x_exit_preconfig(Error **errp) +@@ -2715,6 +2716,12 @@ void qmp_x_exit_preconfig(Error **errp) if (loadvm) { load_snapshot(loadvm, NULL, false, NULL, &error_fatal); @@ -847,7 +850,7 @@ index ba6ad8a8df..ddeace306e 100644 } if (replay_mode != REPLAY_MODE_NONE) { replay_vmstate_init(); -@@ -3196,6 +3203,9 @@ void qemu_init(int argc, char **argv) +@@ -3265,6 +3272,9 @@ void qemu_init(int argc, char **argv) case QEMU_OPTION_loadvm: loadvm = optarg; break; diff --git a/debian/patches/pve/0018-PVE-add-optional-buffer-size-to-QEMUFile.patch b/debian/patches/pve/0018-PVE-add-optional-buffer-size-to-QEMUFile.patch index c946137..a4d925c 100644 --- a/debian/patches/pve/0018-PVE-add-optional-buffer-size-to-QEMUFile.patch +++ b/debian/patches/pve/0018-PVE-add-optional-buffer-size-to-QEMUFile.patch @@ -13,18 +13,18 @@ Signed-off-by: Thomas Lamprecht [FE: adapt to removal of QEMUFileOps] Signed-off-by: Fiona Ebner --- - migration/qemu-file.c | 49 +++++++++++++++++++++++++++------------- + migration/qemu-file.c | 50 +++++++++++++++++++++++++++------------- migration/qemu-file.h | 2 ++ migration/savevm-async.c | 5 ++-- - 3 files changed, 38 insertions(+), 18 deletions(-) + 3 files changed, 39 insertions(+), 18 deletions(-) diff --git a/migration/qemu-file.c b/migration/qemu-file.c -index 19c33c9985..e9ffff0f0a 100644 +index 94231ff295..afda98292f 100644 --- a/migration/qemu-file.c +++ b/migration/qemu-file.c -@@ -33,8 +33,8 @@ - #include "options.h" +@@ -34,8 +34,8 @@ #include "qapi/error.h" + #include "rdma.h" -#define IO_BUF_SIZE 32768 -#define MAX_IOV_SIZE MIN_CONST(IOV_MAX, 64) @@ -32,8 +32,8 @@ index 19c33c9985..e9ffff0f0a 100644 +#define MAX_IOV_SIZE MIN_CONST(IOV_MAX, 256) struct QEMUFile { - const QEMUFileHooks *hooks; -@@ -46,7 +46,8 @@ struct QEMUFile { + QIOChannel *ioc; +@@ -43,7 +43,8 @@ struct QEMUFile { int buf_index; int buf_size; /* 0 when writing */ @@ -43,7 +43,7 @@ index 19c33c9985..e9ffff0f0a 100644 DECLARE_BITMAP(may_free, MAX_IOV_SIZE); struct iovec iov[MAX_IOV_SIZE]; -@@ -100,7 +101,9 @@ int qemu_file_shutdown(QEMUFile *f) +@@ -97,7 +98,9 @@ int qemu_file_shutdown(QEMUFile *f) return 0; } @@ -54,7 +54,7 @@ index 19c33c9985..e9ffff0f0a 100644 { QEMUFile *f; -@@ -109,6 +112,8 @@ static QEMUFile *qemu_file_new_impl(QIOChannel *ioc, bool is_writable) +@@ -106,6 +109,8 @@ static QEMUFile *qemu_file_new_impl(QIOChannel *ioc, bool is_writable) object_ref(ioc); f->ioc = ioc; f->is_writable = is_writable; @@ -63,7 +63,7 @@ index 19c33c9985..e9ffff0f0a 100644 return f; } -@@ -119,17 +124,27 @@ static QEMUFile *qemu_file_new_impl(QIOChannel *ioc, bool is_writable) +@@ -116,17 +121,27 @@ static QEMUFile *qemu_file_new_impl(QIOChannel *ioc, bool is_writable) */ QEMUFile *qemu_file_get_return_path(QEMUFile *f) { @@ -93,8 +93,8 @@ index 19c33c9985..e9ffff0f0a 100644 + return qemu_file_new_impl(ioc, false, buffer_size); } - void qemu_file_set_hooks(QEMUFile *f, const QEMUFileHooks *hooks) -@@ -375,7 +390,7 @@ static ssize_t coroutine_mixed_fn qemu_fill_buffer(QEMUFile *f) + /* +@@ -320,7 +335,7 @@ static ssize_t coroutine_mixed_fn qemu_fill_buffer(QEMUFile *f) do { len = qio_channel_read(f->ioc, (char *)f->buf + pending, @@ -103,16 +103,17 @@ index 19c33c9985..e9ffff0f0a 100644 &local_error); if (len == QIO_CHANNEL_ERR_BLOCK) { if (qemu_in_coroutine()) { -@@ -425,6 +440,8 @@ int qemu_fclose(QEMUFile *f) +@@ -360,6 +375,9 @@ int qemu_fclose(QEMUFile *f) + ret = ret2; } g_clear_pointer(&f->ioc, object_unref); - ++ + free(f->buf); + - /* If any error was spotted before closing, we should report it - * instead of the close() return value. - */ -@@ -479,7 +496,7 @@ static void add_buf_to_iovec(QEMUFile *f, size_t len) + error_free(f->last_error_obj); + g_free(f); + trace_qemu_file_fclose(); +@@ -408,7 +426,7 @@ static void add_buf_to_iovec(QEMUFile *f, size_t len) { if (!add_to_iovec(f, f->buf + f->buf_index, len, false)) { f->buf_index += len; @@ -121,7 +122,7 @@ index 19c33c9985..e9ffff0f0a 100644 qemu_fflush(f); } } -@@ -504,7 +521,7 @@ void qemu_put_buffer(QEMUFile *f, const uint8_t *buf, size_t size) +@@ -433,7 +451,7 @@ void qemu_put_buffer(QEMUFile *f, const uint8_t *buf, size_t size) } while (size > 0) { @@ -130,7 +131,7 @@ index 19c33c9985..e9ffff0f0a 100644 if (l > size) { l = size; } -@@ -549,8 +566,8 @@ size_t coroutine_mixed_fn qemu_peek_buffer(QEMUFile *f, uint8_t **buf, size_t si +@@ -478,8 +496,8 @@ size_t coroutine_mixed_fn qemu_peek_buffer(QEMUFile *f, uint8_t **buf, size_t si size_t index; assert(!qemu_file_is_writable(f)); @@ -141,7 +142,7 @@ index 19c33c9985..e9ffff0f0a 100644 /* The 1st byte to read from */ index = f->buf_index + offset; -@@ -600,7 +617,7 @@ size_t coroutine_mixed_fn qemu_get_buffer(QEMUFile *f, uint8_t *buf, size_t size +@@ -529,7 +547,7 @@ size_t coroutine_mixed_fn qemu_get_buffer(QEMUFile *f, uint8_t *buf, size_t size size_t res; uint8_t *src; @@ -150,7 +151,7 @@ index 19c33c9985..e9ffff0f0a 100644 if (res == 0) { return done; } -@@ -634,7 +651,7 @@ size_t coroutine_mixed_fn qemu_get_buffer(QEMUFile *f, uint8_t *buf, size_t size +@@ -563,7 +581,7 @@ size_t coroutine_mixed_fn qemu_get_buffer(QEMUFile *f, uint8_t *buf, size_t size */ size_t coroutine_mixed_fn qemu_get_buffer_in_place(QEMUFile *f, uint8_t **buf, size_t size) { @@ -159,7 +160,7 @@ index 19c33c9985..e9ffff0f0a 100644 size_t res; uint8_t *src = NULL; -@@ -659,7 +676,7 @@ int coroutine_mixed_fn qemu_peek_byte(QEMUFile *f, int offset) +@@ -588,7 +606,7 @@ int coroutine_mixed_fn qemu_peek_byte(QEMUFile *f, int offset) int index = f->buf_index + offset; assert(!qemu_file_is_writable(f)); @@ -168,7 +169,7 @@ index 19c33c9985..e9ffff0f0a 100644 if (index >= f->buf_size) { qemu_fill_buffer(f); -@@ -777,7 +794,7 @@ static int qemu_compress_data(z_stream *stream, uint8_t *dest, size_t dest_len, +@@ -702,7 +720,7 @@ static int qemu_compress_data(z_stream *stream, uint8_t *dest, size_t dest_len, ssize_t qemu_put_compression_data(QEMUFile *f, z_stream *stream, const uint8_t *p, size_t size) { @@ -178,24 +179,24 @@ index 19c33c9985..e9ffff0f0a 100644 if (blen < compressBound(size)) { return -1; diff --git a/migration/qemu-file.h b/migration/qemu-file.h -index 47015f5201..1312b7c903 100644 +index 8aec9fabf7..5d0b18c51c 100644 --- a/migration/qemu-file.h +++ b/migration/qemu-file.h -@@ -63,7 +63,9 @@ typedef struct QEMUFileHooks { - } QEMUFileHooks; +@@ -30,7 +30,9 @@ + #include "io/channel.h" QEMUFile *qemu_file_new_input(QIOChannel *ioc); +QEMUFile *qemu_file_new_input_sized(QIOChannel *ioc, size_t buffer_size); QEMUFile *qemu_file_new_output(QIOChannel *ioc); +QEMUFile *qemu_file_new_output_sized(QIOChannel *ioc, size_t buffer_size); - void qemu_file_set_hooks(QEMUFile *f, const QEMUFileHooks *hooks); int qemu_fclose(QEMUFile *f); + /* diff --git a/migration/savevm-async.c b/migration/savevm-async.c -index e9fc18fb10..80624fada8 100644 +index 8f63c4c637..f8d1c2f2b1 100644 --- a/migration/savevm-async.c +++ b/migration/savevm-async.c -@@ -378,7 +378,7 @@ void qmp_savevm_start(const char *statefile, Error **errp) +@@ -382,7 +382,7 @@ void qmp_savevm_start(const char *statefile, Error **errp) QIOChannel *ioc = QIO_CHANNEL(qio_channel_savevm_async_new(snap_state.target, &snap_state.bs_pos)); @@ -204,7 +205,7 @@ index e9fc18fb10..80624fada8 100644 if (!snap_state.file) { error_set(errp, ERROR_CLASS_GENERIC_ERROR, "failed to open '%s'", statefile); -@@ -496,7 +496,8 @@ int load_snapshot_from_blockdev(const char *filename, Error **errp) +@@ -499,7 +499,8 @@ int load_snapshot_from_blockdev(const char *filename, Error **errp) blk_op_block_all(be, blocker); /* restore the VM state */ diff --git a/debian/patches/pve/0019-PVE-block-add-the-zeroinit-block-driver-filter.patch b/debian/patches/pve/0019-PVE-block-add-the-zeroinit-block-driver-filter.patch index 1cb8166..4d20cab 100644 --- a/debian/patches/pve/0019-PVE-block-add-the-zeroinit-block-driver-filter.patch +++ b/debian/patches/pve/0019-PVE-block-add-the-zeroinit-block-driver-filter.patch @@ -4,21 +4,22 @@ Date: Mon, 6 Apr 2020 12:16:47 +0200 Subject: [PATCH] PVE: block: add the zeroinit block driver filter Signed-off-by: Thomas Lamprecht -[FE: adapt to changed function signatures] +[FE: adapt to changed function signatures + adhere to block graph lock requirements] Signed-off-by: Fiona Ebner --- block/meson.build | 1 + - block/zeroinit.c | 200 ++++++++++++++++++++++++++++++++++++++++++++++ - 2 files changed, 201 insertions(+) + block/zeroinit.c | 214 ++++++++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 215 insertions(+) create mode 100644 block/zeroinit.c diff --git a/block/meson.build b/block/meson.build -index 529fc172c6..1833c71ce9 100644 +index 59ff6d380c..8ded0dc18b 100644 --- a/block/meson.build +++ b/block/meson.build -@@ -40,6 +40,7 @@ block_ss.add(files( - 'throttle-groups.c', +@@ -39,6 +39,7 @@ block_ss.add(files( 'throttle.c', + 'throttle-groups.c', 'write-threshold.c', + 'zeroinit.c', ), zstd, zlib, gnutls) @@ -26,10 +27,10 @@ index 529fc172c6..1833c71ce9 100644 system_ss.add(when: 'CONFIG_TCG', if_true: files('blkreplay.c')) diff --git a/block/zeroinit.c b/block/zeroinit.c new file mode 100644 -index 0000000000..1257342724 +index 0000000000..1f2032bf99 --- /dev/null +++ b/block/zeroinit.c -@@ -0,0 +1,200 @@ +@@ -0,0 +1,214 @@ +/* + * Filter to fake a zero-initialized block device. + * @@ -44,6 +45,7 @@ index 0000000000..1257342724 +#include "qapi/error.h" +#include "block/block_int.h" +#include "block/block-io.h" ++#include "block/graph-lock.h" +#include "qapi/qmp/qdict.h" +#include "qapi/qmp/qstring.h" +#include "qemu/cutils.h" @@ -94,6 +96,7 @@ index 0000000000..1257342724 + Error **errp) +{ + BDRVZeroinitState *s = bs->opaque; ++ BdrvChild *file = NULL; + QemuOpts *opts; + Error *local_err = NULL; + int ret; @@ -109,10 +112,13 @@ index 0000000000..1257342724 + } + + /* Open the raw file */ -+ bs->file = bdrv_open_child(qemu_opt_get(opts, "x-next"), options, "next", -+ bs, &child_of_bds, -+ BDRV_CHILD_FILTERED | BDRV_CHILD_PRIMARY, -+ false, &local_err); ++ file = bdrv_open_child(qemu_opt_get(opts, "x-next"), options, "next", bs, ++ &child_of_bds, ++ BDRV_CHILD_FILTERED | BDRV_CHILD_PRIMARY, false, ++ &local_err); ++ bdrv_graph_wrlock(bs); ++ bs->file = file; ++ bdrv_graph_wrunlock(bs); + if (local_err) { + ret = -EINVAL; + error_propagate(errp, local_err); @@ -125,7 +131,9 @@ index 0000000000..1257342724 + ret = 0; +fail: + if (ret < 0) { ++ bdrv_graph_wrlock(bs); + bdrv_unref_child(bs, bs->file); ++ bdrv_graph_wrunlock(bs); + } + qemu_opts_del(opts); + return ret; @@ -137,19 +145,22 @@ index 0000000000..1257342724 + (void)s; +} + -+static coroutine_fn int64_t zeroinit_co_getlength(BlockDriverState *bs) ++static coroutine_fn int64_t GRAPH_RDLOCK ++zeroinit_co_getlength(BlockDriverState *bs) +{ + return bdrv_co_getlength(bs->file->bs); +} + -+static int coroutine_fn zeroinit_co_preadv(BlockDriverState *bs, -+ int64_t offset, int64_t bytes, QEMUIOVector *qiov, BdrvRequestFlags flags) ++static int coroutine_fn GRAPH_RDLOCK ++zeroinit_co_preadv(BlockDriverState *bs, int64_t offset, int64_t bytes, ++ QEMUIOVector *qiov, BdrvRequestFlags flags) +{ + return bdrv_co_preadv(bs->file, offset, bytes, qiov, flags); +} + -+static int coroutine_fn zeroinit_co_pwrite_zeroes(BlockDriverState *bs, int64_t offset, -+ int64_t bytes, BdrvRequestFlags flags) ++static int coroutine_fn GRAPH_RDLOCK ++zeroinit_co_pwrite_zeroes(BlockDriverState *bs, int64_t offset, int64_t bytes, ++ BdrvRequestFlags flags) +{ + BDRVZeroinitState *s = bs->opaque; + if (offset >= s->extents) @@ -157,8 +168,9 @@ index 0000000000..1257342724 + return bdrv_pwrite_zeroes(bs->file, offset, bytes, flags); +} + -+static int coroutine_fn zeroinit_co_pwritev(BlockDriverState *bs, -+ int64_t offset, int64_t bytes, QEMUIOVector *qiov, BdrvRequestFlags flags) ++static int coroutine_fn GRAPH_RDLOCK ++zeroinit_co_pwritev(BlockDriverState *bs, int64_t offset, int64_t bytes, ++ QEMUIOVector *qiov, BdrvRequestFlags flags) +{ + BDRVZeroinitState *s = bs->opaque; + int64_t extents = offset + bytes; @@ -167,32 +179,35 @@ index 0000000000..1257342724 + return bdrv_co_pwritev(bs->file, offset, bytes, qiov, flags); +} + -+static coroutine_fn int zeroinit_co_flush(BlockDriverState *bs) ++static coroutine_fn int GRAPH_RDLOCK ++zeroinit_co_flush(BlockDriverState *bs) +{ + return bdrv_co_flush(bs->file->bs); +} + -+static int zeroinit_has_zero_init(BlockDriverState *bs) ++static int GRAPH_RDLOCK ++zeroinit_has_zero_init(BlockDriverState *bs) +{ + BDRVZeroinitState *s = bs->opaque; + return s->has_zero_init; +} + -+static int coroutine_fn zeroinit_co_pdiscard(BlockDriverState *bs, -+ int64_t offset, int64_t bytes) ++static int coroutine_fn GRAPH_RDLOCK ++zeroinit_co_pdiscard(BlockDriverState *bs, int64_t offset, int64_t bytes) +{ + return bdrv_co_pdiscard(bs->file, offset, bytes); +} + -+static int zeroinit_co_truncate(BlockDriverState *bs, int64_t offset, -+ _Bool exact, PreallocMode prealloc, -+ BdrvRequestFlags req_flags, Error **errp) ++static int GRAPH_RDLOCK ++zeroinit_co_truncate(BlockDriverState *bs, int64_t offset, _Bool exact, ++ PreallocMode prealloc, BdrvRequestFlags req_flags, ++ Error **errp) +{ + return bdrv_co_truncate(bs->file, offset, exact, prealloc, req_flags, errp); +} + -+static coroutine_fn int zeroinit_co_get_info(BlockDriverState *bs, -+ BlockDriverInfo *bdi) ++static coroutine_fn int GRAPH_RDLOCK ++zeroinit_co_get_info(BlockDriverState *bs, BlockDriverInfo *bdi) +{ + return bdrv_co_get_info(bs->file->bs, bdi); +} diff --git a/debian/patches/pve/0020-PVE-Add-dummy-id-command-line-parameter.patch b/debian/patches/pve/0020-PVE-Add-dummy-id-command-line-parameter.patch index 17f5de1..783d454 100644 --- a/debian/patches/pve/0020-PVE-Add-dummy-id-command-line-parameter.patch +++ b/debian/patches/pve/0020-PVE-Add-dummy-id-command-line-parameter.patch @@ -10,14 +10,14 @@ Signed-off-by: Wolfgang Bumiller Signed-off-by: Thomas Lamprecht --- qemu-options.hx | 3 +++ - softmmu/vl.c | 8 ++++++++ + system/vl.c | 8 ++++++++ 2 files changed, 11 insertions(+) diff --git a/qemu-options.hx b/qemu-options.hx -index dc1ececc9c..848d2dfdd1 100644 +index 881b0b3c43..c17374916c 100644 --- a/qemu-options.hx +++ b/qemu-options.hx -@@ -1197,6 +1197,9 @@ legacy PC, they are not recommended for modern configurations. +@@ -1218,6 +1218,9 @@ legacy PC, they are not recommended for modern configurations. ERST @@ -27,11 +27,11 @@ index dc1ececc9c..848d2dfdd1 100644 DEF("fda", HAS_ARG, QEMU_OPTION_fda, "-fda/-fdb file use 'file' as floppy disk 0/1 image\n", QEMU_ARCH_ALL) DEF("fdb", HAS_ARG, QEMU_OPTION_fdb, "", QEMU_ARCH_ALL) -diff --git a/softmmu/vl.c b/softmmu/vl.c -index ddeace306e..3ee90b3b94 100644 ---- a/softmmu/vl.c -+++ b/softmmu/vl.c -@@ -2683,6 +2683,7 @@ void qemu_init(int argc, char **argv) +diff --git a/system/vl.c b/system/vl.c +index 57f7ba0525..56d715c818 100644 +--- a/system/vl.c ++++ b/system/vl.c +@@ -2751,6 +2751,7 @@ void qemu_init(int argc, char **argv) MachineClass *machine_class; bool userconfig = true; FILE *vmstate_dump_file = NULL; @@ -39,7 +39,7 @@ index ddeace306e..3ee90b3b94 100644 qemu_add_opts(&qemu_drive_opts); qemu_add_drive_opts(&qemu_legacy_drive_opts); -@@ -3308,6 +3309,13 @@ void qemu_init(int argc, char **argv) +@@ -3377,6 +3378,13 @@ void qemu_init(int argc, char **argv) machine_parse_property_opt(qemu_find_opts("smp-opts"), "smp", optarg); break; @@ -50,6 +50,6 @@ index ddeace306e..3ee90b3b94 100644 + exit(1); + } + break; + #ifdef CONFIG_VNC case QEMU_OPTION_vnc: vnc_parse(optarg); - break; diff --git a/debian/patches/pve/0021-PVE-Config-Revert-target-i386-disable-LINT0-after-re.patch b/debian/patches/pve/0021-PVE-Config-Revert-target-i386-disable-LINT0-after-re.patch index 3c28401..ec4c417 100644 --- a/debian/patches/pve/0021-PVE-Config-Revert-target-i386-disable-LINT0-after-re.patch +++ b/debian/patches/pve/0021-PVE-Config-Revert-target-i386-disable-LINT0-after-re.patch @@ -11,10 +11,10 @@ Signed-off-by: Thomas Lamprecht 1 file changed, 9 insertions(+) diff --git a/hw/intc/apic_common.c b/hw/intc/apic_common.c -index 4a34f03047..59b917e50c 100644 +index bccb4241c2..bd0db7567a 100644 --- a/hw/intc/apic_common.c +++ b/hw/intc/apic_common.c -@@ -252,6 +252,15 @@ static void apic_reset_common(DeviceState *dev) +@@ -251,6 +251,15 @@ static void apic_reset_common(DeviceState *dev) info->vapic_base_update(s); apic_init_reset(dev); diff --git a/debian/patches/pve/0022-PVE-Up-Config-file-posix-make-locking-optiono-on-cre.patch b/debian/patches/pve/0022-PVE-Up-Config-file-posix-make-locking-optiono-on-cre.patch index f48fe4f..9d4b196 100644 --- a/debian/patches/pve/0022-PVE-Up-Config-file-posix-make-locking-optiono-on-cre.patch +++ b/debian/patches/pve/0022-PVE-Up-Config-file-posix-make-locking-optiono-on-cre.patch @@ -13,7 +13,7 @@ Signed-off-by: Thomas Lamprecht 2 files changed, 42 insertions(+), 20 deletions(-) diff --git a/block/file-posix.c b/block/file-posix.c -index ca551baa42..8b3b83e9d4 100644 +index bc09aefe3b..36a53d8682 100644 --- a/block/file-posix.c +++ b/block/file-posix.c @@ -2873,6 +2873,7 @@ raw_co_create(BlockdevCreateOptions *options, Error **errp) @@ -119,10 +119,10 @@ index ca551baa42..8b3b83e9d4 100644 }; return raw_co_create(&options, errp); diff --git a/qapi/block-core.json b/qapi/block-core.json -index a5cea82139..bb471c078d 100644 +index 8db0986e9e..299e3fc350 100644 --- a/qapi/block-core.json +++ b/qapi/block-core.json -@@ -4880,7 +4880,8 @@ +@@ -4935,7 +4935,8 @@ 'size': 'size', '*preallocation': 'PreallocMode', '*nocow': 'bool', diff --git a/debian/patches/pve/0024-PVE-Compat-4.0-used-balloon-qemu-4-0-config-size-fal.patch b/debian/patches/pve/0024-PVE-Compat-4.0-used-balloon-qemu-4-0-config-size-fal.patch index 277fa3f..5f26e20 100644 --- a/debian/patches/pve/0024-PVE-Compat-4.0-used-balloon-qemu-4-0-config-size-fal.patch +++ b/debian/patches/pve/0024-PVE-Compat-4.0-used-balloon-qemu-4-0-config-size-fal.patch @@ -26,10 +26,10 @@ Signed-off-by: Thomas Lamprecht 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/hw/core/machine.c b/hw/core/machine.c -index f0d35c6401..1427983543 100644 +index 0c17398141..36621d58a7 100644 --- a/hw/core/machine.c +++ b/hw/core/machine.c -@@ -148,7 +148,8 @@ GlobalProperty hw_compat_4_0[] = { +@@ -152,7 +152,8 @@ GlobalProperty hw_compat_4_0[] = { { "virtio-vga", "edid", "false" }, { "virtio-gpu-device", "edid", "false" }, { "virtio-device", "use-started", "false" }, diff --git a/debian/patches/pve/0025-PVE-Allow-version-code-in-machine-type.patch b/debian/patches/pve/0025-PVE-Allow-version-code-in-machine-type.patch index 507a5e3..5a5586a 100644 --- a/debian/patches/pve/0025-PVE-Allow-version-code-in-machine-type.patch +++ b/debian/patches/pve/0025-PVE-Allow-version-code-in-machine-type.patch @@ -17,7 +17,7 @@ Signed-off-by: Fiona Ebner hw/core/machine-qmp-cmds.c | 5 +++++ include/hw/boards.h | 2 ++ qapi/machine.json | 4 +++- - softmmu/vl.c | 25 +++++++++++++++++++++++++ + system/vl.c | 25 +++++++++++++++++++++++++ 4 files changed, 35 insertions(+), 1 deletion(-) diff --git a/hw/core/machine-qmp-cmds.c b/hw/core/machine-qmp-cmds.c @@ -37,10 +37,10 @@ index 40821e2317..ee93ddd69a 100644 if (mc->default_cpu_type) { diff --git a/include/hw/boards.h b/include/hw/boards.h -index ed83360198..f8b88cd86a 100644 +index da85f86efb..1aa0987020 100644 --- a/include/hw/boards.h +++ b/include/hw/boards.h -@@ -235,6 +235,8 @@ struct MachineClass { +@@ -240,6 +240,8 @@ struct MachineClass { const char *desc; const char *deprecation_reason; @@ -50,10 +50,10 @@ index ed83360198..f8b88cd86a 100644 void (*reset)(MachineState *state, ShutdownCause reason); void (*wakeup)(MachineState *state); diff --git a/qapi/machine.json b/qapi/machine.json -index fbb61f18e4..7da3c519ba 100644 +index 297ad0e0e5..a9fd40d844 100644 --- a/qapi/machine.json +++ b/qapi/machine.json -@@ -161,6 +161,8 @@ +@@ -168,6 +168,8 @@ # # @acpi: machine type supports ACPI (since 8.0) # @@ -62,7 +62,7 @@ index fbb61f18e4..7da3c519ba 100644 # Since: 1.2 ## { 'struct': 'MachineInfo', -@@ -168,7 +170,7 @@ +@@ -175,7 +177,7 @@ '*is-default': 'bool', '*is-current': 'bool', 'cpu-max': 'int', 'hotpluggable-cpus': 'bool', 'numa-mem-supported': 'bool', 'deprecated': 'bool', '*default-cpu-type': 'str', @@ -71,19 +71,19 @@ index fbb61f18e4..7da3c519ba 100644 ## # @query-machines: -diff --git a/softmmu/vl.c b/softmmu/vl.c -index 3ee90b3b94..4b6d0b82fd 100644 ---- a/softmmu/vl.c -+++ b/softmmu/vl.c -@@ -1597,6 +1597,7 @@ static const QEMUOption *lookup_opt(int argc, char **argv, +diff --git a/system/vl.c b/system/vl.c +index 56d715c818..87f03e61a1 100644 +--- a/system/vl.c ++++ b/system/vl.c +@@ -1660,6 +1660,7 @@ static const QEMUOption *lookup_opt(int argc, char **argv, static MachineClass *select_machine(QDict *qdict, Error **errp) { - const char *optarg = qdict_get_try_str(qdict, "type"); + const char *machine_type = qdict_get_try_str(qdict, "type"); + const char *pvever = qdict_get_try_str(qdict, "pvever"); GSList *machines = object_class_get_list(TYPE_MACHINE, false); MachineClass *machine_class; Error *local_err = NULL; -@@ -1614,6 +1615,11 @@ static MachineClass *select_machine(QDict *qdict, Error **errp) +@@ -1677,6 +1678,11 @@ static MachineClass *select_machine(QDict *qdict, Error **errp) } } @@ -95,7 +95,7 @@ index 3ee90b3b94..4b6d0b82fd 100644 g_slist_free(machines); if (local_err) { error_append_hint(&local_err, "Use -machine help to list supported machines\n"); -@@ -3250,12 +3256,31 @@ void qemu_init(int argc, char **argv) +@@ -3319,12 +3325,31 @@ void qemu_init(int argc, char **argv) case QEMU_OPTION_machine: { bool help; diff --git a/debian/patches/pve/0026-block-backup-move-bcs-bitmap-initialization-to-job-c.patch b/debian/patches/pve/0026-block-backup-move-bcs-bitmap-initialization-to-job-c.patch index ef3fb89..8767415 100644 --- a/debian/patches/pve/0026-block-backup-move-bcs-bitmap-initialization-to-job-c.patch +++ b/debian/patches/pve/0026-block-backup-move-bcs-bitmap-initialization-to-job-c.patch @@ -25,7 +25,7 @@ Signed-off-by: Thomas Lamprecht 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/block/backup.c b/block/backup.c -index db3791f4d1..39410dcf8d 100644 +index 8aae5836d7..2516eac5a7 100644 --- a/block/backup.c +++ b/block/backup.c @@ -237,8 +237,8 @@ static void backup_init_bcs_bitmap(BackupBlockJob *job) @@ -48,9 +48,9 @@ index db3791f4d1..39410dcf8d 100644 if (s->sync_mode == MIRROR_SYNC_MODE_TOP) { int64_t offset = 0; int64_t count; -@@ -495,6 +493,8 @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs, - block_job_add_bdrv(&job->common, "target", target, 0, BLK_PERM_ALL, +@@ -501,6 +499,8 @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs, &error_abort); + bdrv_graph_wrunlock(target); + backup_init_bcs_bitmap(job); + diff --git a/debian/patches/pve/0027-PVE-Backup-add-vma-backup-format-code.patch b/debian/patches/pve/0027-PVE-Backup-add-vma-backup-format-code.patch index 1620a56..c912b84 100644 --- a/debian/patches/pve/0027-PVE-Backup-add-vma-backup-format-code.patch +++ b/debian/patches/pve/0027-PVE-Backup-add-vma-backup-format-code.patch @@ -15,21 +15,21 @@ Signed-off-by: Fiona Ebner --- block/meson.build | 2 + meson.build | 5 + - vma-reader.c | 867 ++++++++++++++++++++++++++++++++++++++++++++ + vma-reader.c | 870 ++++++++++++++++++++++++++++++++++++++++++++ vma-writer.c | 818 +++++++++++++++++++++++++++++++++++++++++ - vma.c | 900 ++++++++++++++++++++++++++++++++++++++++++++++ + vma.c | 901 ++++++++++++++++++++++++++++++++++++++++++++++ vma.h | 150 ++++++++ - 6 files changed, 2742 insertions(+) + 6 files changed, 2746 insertions(+) create mode 100644 vma-reader.c create mode 100644 vma-writer.c create mode 100644 vma.c create mode 100644 vma.h diff --git a/block/meson.build b/block/meson.build -index 1833c71ce9..59b71ba9f3 100644 +index 8ded0dc18b..e709b67d37 100644 --- a/block/meson.build +++ b/block/meson.build -@@ -43,6 +43,8 @@ block_ss.add(files( +@@ -42,6 +42,8 @@ block_ss.add(files( 'zeroinit.c', ), zstd, zlib, gnutls) @@ -39,10 +39,10 @@ index 1833c71ce9..59b71ba9f3 100644 system_ss.add(files('block-ram-registrar.c')) diff --git a/meson.build b/meson.build -index a9c4f28247..cd95530d3b 100644 +index 6c77d9687d..8cb1ccd5e1 100644 --- a/meson.build +++ b/meson.build -@@ -1778,6 +1778,8 @@ endif +@@ -1802,6 +1802,8 @@ endif has_gettid = cc.has_function('gettid') @@ -51,7 +51,7 @@ index a9c4f28247..cd95530d3b 100644 # libselinux selinux = dependency('libselinux', required: get_option('selinux'), -@@ -3908,6 +3910,9 @@ if have_tools +@@ -3975,6 +3977,9 @@ if have_tools dependencies: [blockdev, qemuutil, gnutls, selinux], install: true) @@ -63,10 +63,10 @@ index a9c4f28247..cd95530d3b 100644 subdir('contrib/elf2dmp') diff --git a/vma-reader.c b/vma-reader.c new file mode 100644 -index 0000000000..81a891c6b1 +index 0000000000..d0b6721812 --- /dev/null +++ b/vma-reader.c -@@ -0,0 +1,867 @@ +@@ -0,0 +1,870 @@ +/* + * VMA: Virtual Machine Archive + * @@ -88,6 +88,7 @@ index 0000000000..81a891c6b1 +#include "qemu/ratelimit.h" +#include "vma.h" +#include "block/block.h" ++#include "block/graph-lock.h" +#include "sysemu/block-backend.h" + +static unsigned char zero_vma_block[VMA_BLOCK_SIZE]; @@ -600,8 +601,10 @@ index 0000000000..81a891c6b1 + } else { + int res = blk_pwrite(target, sector_num * BDRV_SECTOR_SIZE, nb_sectors * BDRV_SECTOR_SIZE, buf, 0); + if (res < 0) { ++ bdrv_graph_rdlock_main_loop(); + error_setg(errp, "blk_pwrite to %s failed (%d)", + bdrv_get_device_name(blk_bs(target)), res); ++ bdrv_graph_rdunlock_main_loop(); + return -1; + } + } @@ -1760,10 +1763,10 @@ index 0000000000..126b296647 +} diff --git a/vma.c b/vma.c new file mode 100644 -index 0000000000..347f6283ca +index 0000000000..bb715e9061 --- /dev/null +++ b/vma.c -@@ -0,0 +1,900 @@ +@@ -0,0 +1,901 @@ +/* + * VMA: Virtual Machine Archive + * @@ -2076,17 +2079,17 @@ index 0000000000..347f6283ca + inbuf); + } + -+ RestoreMap *map = g_new0(RestoreMap, 1); -+ map->devname = g_strdup(devname); -+ map->path = g_strdup(path); -+ map->format = format; -+ map->throttling_bps = bps_value; -+ map->throttling_group = group; -+ map->cache = cache; -+ map->write_zero = write_zero; -+ map->skip = skip; ++ RestoreMap *restore_map = g_new0(RestoreMap, 1); ++ restore_map->devname = g_strdup(devname); ++ restore_map->path = g_strdup(path); ++ restore_map->format = format; ++ restore_map->throttling_bps = bps_value; ++ restore_map->throttling_group = group; ++ restore_map->cache = cache; ++ restore_map->write_zero = write_zero; ++ restore_map->skip = skip; + -+ g_hash_table_insert(devmap, map->devname, map); ++ g_hash_table_insert(devmap, restore_map->devname, restore_map); + + }; + } @@ -2385,7 +2388,7 @@ index 0000000000..347f6283ca + +static int create_archive(int argc, char **argv) +{ -+ int i, c; ++ int c; + int verbose = 0; + const char *archivename; + GList *backup_coroutines = NULL; @@ -2543,6 +2546,7 @@ index 0000000000..347f6283ca + vma_writer_get_status(vmaw, &vmastat); + + if (verbose) { ++ int i; + for (i = 0; i < 256; i++) { + VmaStreamInfo *si = &vmastat.stream_info[i]; + if (si->size) { diff --git a/debian/patches/pve/0028-PVE-Backup-add-backup-dump-block-driver.patch b/debian/patches/pve/0028-PVE-Backup-add-backup-dump-block-driver.patch index 1adb45d..f8e45c8 100644 --- a/debian/patches/pve/0028-PVE-Backup-add-backup-dump-block-driver.patch +++ b/debian/patches/pve/0028-PVE-Backup-add-backup-dump-block-driver.patch @@ -199,7 +199,7 @@ index 0000000000..e46abf1070 + return bs; +} diff --git a/block/backup.c b/block/backup.c -index 39410dcf8d..af87fa6aa9 100644 +index 2516eac5a7..aec140e0c8 100644 --- a/block/backup.c +++ b/block/backup.c @@ -29,28 +29,6 @@ @@ -231,7 +231,7 @@ index 39410dcf8d..af87fa6aa9 100644 static const BlockJobDriver backup_job_driver; static void backup_cleanup_sync_bitmap(BackupBlockJob *job, int ret) -@@ -457,6 +435,14 @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs, +@@ -461,6 +439,14 @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs, } cluster_size = block_copy_cluster_size(bcs); @@ -247,7 +247,7 @@ index 39410dcf8d..af87fa6aa9 100644 if (perf->max_chunk && perf->max_chunk < cluster_size) { error_setg(errp, "Required max-chunk (%" PRIi64 ") is less than backup " diff --git a/block/meson.build b/block/meson.build -index 59b71ba9f3..6fde9f7dcd 100644 +index e709b67d37..f7d1b7ac42 100644 --- a/block/meson.build +++ b/block/meson.build @@ -4,6 +4,7 @@ block_ss.add(files( @@ -255,11 +255,11 @@ index 59b71ba9f3..6fde9f7dcd 100644 'amend.c', 'backup.c', + 'backup-dump.c', - 'copy-before-write.c', 'blkdebug.c', 'blklogwrites.c', + 'blkverify.c', diff --git a/include/block/block_int-common.h b/include/block/block_int-common.h -index 74195c3004..0a0339eee4 100644 +index 4e31d161c5..2fc6c37bc9 100644 --- a/include/block/block_int-common.h +++ b/include/block/block_int-common.h @@ -26,6 +26,7 @@ @@ -312,10 +312,10 @@ index 74195c3004..0a0339eee4 100644 BDRV_TRACKED_READ, BDRV_TRACKED_WRITE, diff --git a/job.c b/job.c -index 72d57f0934..93e22d180b 100644 +index 99a2e54b54..d7a18b8e6a 100644 --- a/job.c +++ b/job.c -@@ -330,7 +330,8 @@ static bool job_started_locked(Job *job) +@@ -331,7 +331,8 @@ static bool job_started_locked(Job *job) } /* Called with job_mutex held. */ diff --git a/debian/patches/pve/0029-PVE-Add-sequential-job-transaction-support.patch b/debian/patches/pve/0029-PVE-Add-sequential-job-transaction-support.patch index fbf610e..3d08d8c 100644 --- a/debian/patches/pve/0029-PVE-Add-sequential-job-transaction-support.patch +++ b/debian/patches/pve/0029-PVE-Add-sequential-job-transaction-support.patch @@ -11,7 +11,7 @@ Signed-off-by: Thomas Lamprecht 2 files changed, 46 insertions(+) diff --git a/include/qemu/job.h b/include/qemu/job.h -index e502787dd8..963cf2bef5 100644 +index b4bc2e174b..4586dc2d3c 100644 --- a/include/qemu/job.h +++ b/include/qemu/job.h @@ -381,6 +381,18 @@ void job_unlock(void); @@ -34,10 +34,10 @@ index e502787dd8..963cf2bef5 100644 * Release a reference that was previously acquired with job_txn_add_job or * job_txn_new. If it's the last reference to the object, it will be freed. diff --git a/job.c b/job.c -index 93e22d180b..2b31f1e14f 100644 +index d7a18b8e6a..868df1b4ce 100644 --- a/job.c +++ b/job.c -@@ -93,6 +93,8 @@ struct JobTxn { +@@ -94,6 +94,8 @@ struct JobTxn { /* Reference count */ int refcnt; @@ -46,7 +46,7 @@ index 93e22d180b..2b31f1e14f 100644 }; void job_lock(void) -@@ -118,6 +120,25 @@ JobTxn *job_txn_new(void) +@@ -119,6 +121,25 @@ JobTxn *job_txn_new(void) return txn; } @@ -72,7 +72,7 @@ index 93e22d180b..2b31f1e14f 100644 /* Called with job_mutex held. */ static void job_txn_ref_locked(JobTxn *txn) { -@@ -1057,6 +1078,12 @@ static void job_completed_txn_success_locked(Job *job) +@@ -1058,6 +1079,12 @@ static void job_completed_txn_success_locked(Job *job) */ QLIST_FOREACH(other_job, &txn->jobs, txn_list) { if (!job_is_completed_locked(other_job)) { @@ -85,7 +85,7 @@ index 93e22d180b..2b31f1e14f 100644 return; } assert(other_job->ret == 0); -@@ -1268,6 +1295,13 @@ int job_finish_sync_locked(Job *job, +@@ -1269,6 +1296,13 @@ int job_finish_sync_locked(Job *job, return -EBUSY; } diff --git a/debian/patches/pve/0030-PVE-Backup-Proxmox-backup-patches-for-QEMU.patch b/debian/patches/pve/0030-PVE-Backup-Proxmox-backup-patches-for-QEMU.patch index 8bc528e..5a09ba9 100644 --- a/debian/patches/pve/0030-PVE-Backup-Proxmox-backup-patches-for-QEMU.patch +++ b/debian/patches/pve/0030-PVE-Backup-Proxmox-backup-patches-for-QEMU.patch @@ -94,20 +94,20 @@ Signed-off-by: Fiona Ebner monitor/hmp-cmds.c | 72 +++ proxmox-backup-client.c | 146 +++++ proxmox-backup-client.h | 60 ++ - pve-backup.c | 1089 ++++++++++++++++++++++++++++++++ + pve-backup.c | 1103 ++++++++++++++++++++++++++++++++ qapi/block-core.json | 229 +++++++ qapi/common.json | 14 + qapi/machine.json | 16 +- - 14 files changed, 1704 insertions(+), 14 deletions(-) + 14 files changed, 1718 insertions(+), 14 deletions(-) create mode 100644 proxmox-backup-client.c create mode 100644 proxmox-backup-client.h create mode 100644 pve-backup.c diff --git a/block/meson.build b/block/meson.build -index 6fde9f7dcd..6d468f89e5 100644 +index f7d1b7ac42..9df99aceb5 100644 --- a/block/meson.build +++ b/block/meson.build -@@ -45,6 +45,11 @@ block_ss.add(files( +@@ -44,6 +44,11 @@ block_ss.add(files( ), zstd, zlib, gnutls) block_ss.add(files('../vma-writer.c'), libuuid) @@ -120,10 +120,10 @@ index 6fde9f7dcd..6d468f89e5 100644 system_ss.add(when: 'CONFIG_TCG', if_true: files('blkreplay.c')) system_ss.add(files('block-ram-registrar.c')) diff --git a/block/monitor/block-hmp-cmds.c b/block/monitor/block-hmp-cmds.c -index ca2599de44..6efe28cef5 100644 +index c729cbf1eb..1656859e03 100644 --- a/block/monitor/block-hmp-cmds.c +++ b/block/monitor/block-hmp-cmds.c -@@ -1029,3 +1029,42 @@ void hmp_change_medium(Monitor *mon, const char *device, const char *target, +@@ -1037,3 +1037,42 @@ void hmp_change_medium(Monitor *mon, const char *device, const char *target, qmp_blockdev_change_medium(device, NULL, target, arg, true, force, !!read_only, read_only_mode, errp); } @@ -167,7 +167,7 @@ index ca2599de44..6efe28cef5 100644 + hmp_handle_error(mon, error); +} diff --git a/blockdev.c b/blockdev.c -index cd5f205ad1..7793143d76 100644 +index 38a40e3e32..3049811be8 100644 --- a/blockdev.c +++ b/blockdev.c @@ -37,6 +37,7 @@ @@ -204,7 +204,7 @@ index 10fdd822e0..15937793c1 100644 { .name = "usernet", diff --git a/hmp-commands.hx b/hmp-commands.hx -index e352f86872..0c8b6725fb 100644 +index 893c3bd240..5c1ffbc602 100644 --- a/hmp-commands.hx +++ b/hmp-commands.hx @@ -101,6 +101,35 @@ ERST @@ -265,10 +265,10 @@ index 7a7def7530..cba7afe70c 100644 void hmp_device_add(Monitor *mon, const QDict *qdict); void hmp_device_del(Monitor *mon, const QDict *qdict); diff --git a/meson.build b/meson.build -index cd95530d3b..d53976d621 100644 +index 8cb1ccd5e1..955f579308 100644 --- a/meson.build +++ b/meson.build -@@ -1779,6 +1779,7 @@ endif +@@ -1803,6 +1803,7 @@ endif has_gettid = cc.has_function('gettid') libuuid = cc.find_library('uuid', required: true) @@ -277,7 +277,7 @@ index cd95530d3b..d53976d621 100644 # libselinux selinux = dependency('libselinux', diff --git a/monitor/hmp-cmds.c b/monitor/hmp-cmds.c -index 91be698308..5b9c231a4c 100644 +index ef4634e5c1..6e25279f42 100644 --- a/monitor/hmp-cmds.c +++ b/monitor/hmp-cmds.c @@ -21,6 +21,7 @@ @@ -586,10 +586,10 @@ index 0000000000..8cbf645b2c +#endif /* PROXMOX_BACKUP_CLIENT_H */ diff --git a/pve-backup.c b/pve-backup.c new file mode 100644 -index 0000000000..ae3d137e12 +index 0000000000..903afcd7e9 --- /dev/null +++ b/pve-backup.c -@@ -0,0 +1,1089 @@ +@@ -0,0 +1,1103 @@ +#include "proxmox-backup-client.h" +#include "vma.h" + @@ -600,6 +600,7 @@ index 0000000000..ae3d137e12 +#include "block/block_int-global-state.h" +#include "block/blockjob.h" +#include "block/dirty-bitmap.h" ++#include "block/graph-lock.h" +#include "qapi/qapi-commands-block.h" +#include "qapi/qmp/qerror.h" +#include "qemu/cutils.h" @@ -928,13 +929,6 @@ index 0000000000..ae3d137e12 + } + } + -+ if (di->job) { -+ WITH_JOB_LOCK_GUARD() { -+ job_unref_locked(&di->job->job); -+ di->job = NULL; -+ } -+ } -+ + // remove self from job list + backup_state.di_list = g_list_remove(backup_state.di_list, di); + @@ -954,6 +948,16 @@ index 0000000000..ae3d137e12 + di->completed_ret = ret; + + /* ++ * Needs to happen outside of coroutine, because it takes the graph write lock. ++ */ ++ if (di->job) { ++ WITH_JOB_LOCK_GUARD() { ++ job_unref_locked(&di->job->job); ++ di->job = NULL; ++ } ++ } ++ ++ /* + * Schedule stream cleanup in async coroutine. close_image and finish might + * take a while, so we can't block on them here. This way it also doesn't + * matter if we're already running in a coroutine or not. @@ -1178,7 +1182,7 @@ index 0000000000..ae3d137e12 + * case of an error, errp will be set, but the returned value might still be a + * list. + */ -+static GList coroutine_fn *get_device_info( ++static GList coroutine_fn GRAPH_RDLOCK *get_device_info( + const char *devlist, + Error **errp) +{ @@ -1279,7 +1283,9 @@ index 0000000000..ae3d137e12 + /* Todo: try to auto-detect format based on file name */ + format = has_format ? format : BACKUP_FORMAT_VMA; + ++ bdrv_graph_co_rdlock(); + di_list = get_device_info(devlist, &local_err); ++ bdrv_graph_co_rdunlock(); + if (local_err) { + error_propagate(errp, local_err); + goto err; @@ -1292,7 +1298,11 @@ index 0000000000..ae3d137e12 + while (l) { + PVEBackupDevInfo *di = (PVEBackupDevInfo *)l->data; + l = g_list_next(l); -+ if (bdrv_op_is_blocked(di->bs, BLOCK_OP_TYPE_BACKUP_SOURCE, errp)) { ++ ++ bdrv_graph_co_rdlock(); ++ bool blocked = bdrv_op_is_blocked(di->bs, BLOCK_OP_TYPE_BACKUP_SOURCE, errp); ++ bdrv_graph_co_rdunlock(); ++ if (blocked) { + goto err; + } + @@ -1376,7 +1386,9 @@ index 0000000000..ae3d137e12 + + di->block_size = dump_cb_block_size; + ++ bdrv_graph_co_rdlock(); + const char *devname = bdrv_get_device_name(di->bs); ++ bdrv_graph_co_rdunlock(); + PBSBitmapAction action = PBS_BITMAP_ACTION_NOT_USED; + size_t dirty = di->size; + @@ -1452,7 +1464,9 @@ index 0000000000..ae3d137e12 + goto err_mutex; + } + ++ bdrv_graph_co_rdlock(); + const char *devname = bdrv_get_device_name(di->bs); ++ bdrv_graph_co_rdunlock(); + di->dev_id = vma_writer_register_stream(vmaw, devname, di->size); + if (di->dev_id <= 0) { + error_set(errp, ERROR_CLASS_GENERIC_ERROR, @@ -1680,10 +1694,10 @@ index 0000000000..ae3d137e12 + return ret; +} diff --git a/qapi/block-core.json b/qapi/block-core.json -index bb471c078d..1b8462a51b 100644 +index 299e3fc350..c155d74230 100644 --- a/qapi/block-core.json +++ b/qapi/block-core.json -@@ -839,6 +839,235 @@ +@@ -841,6 +841,235 @@ { 'command': 'query-block', 'returns': ['BlockInfo'], 'allow-preconfig': true } @@ -1942,7 +1956,7 @@ index 6fed9cde1a..630a2a8f9a 100644 +## +{ 'struct': 'UuidInfo', 'data': {'UUID': 'str'} } diff --git a/qapi/machine.json b/qapi/machine.json -index 7da3c519ba..888457f810 100644 +index a9fd40d844..d97f024173 100644 --- a/qapi/machine.json +++ b/qapi/machine.json @@ -4,6 +4,8 @@ @@ -1954,7 +1968,7 @@ index 7da3c519ba..888457f810 100644 ## # = Machines ## -@@ -230,20 +232,6 @@ +@@ -237,20 +239,6 @@ ## { 'command': 'query-target', 'returns': 'TargetInfo' } diff --git a/debian/patches/pve/0031-PVE-Backup-pbs-restore-new-command-to-restore-from-p.patch b/debian/patches/pve/0031-PVE-Backup-pbs-restore-new-command-to-restore-from-p.patch index 2d35795..ded8ff2 100644 --- a/debian/patches/pve/0031-PVE-Backup-pbs-restore-new-command-to-restore-from-p.patch +++ b/debian/patches/pve/0031-PVE-Backup-pbs-restore-new-command-to-restore-from-p.patch @@ -14,10 +14,10 @@ Signed-off-by: Wolfgang Bumiller create mode 100644 pbs-restore.c diff --git a/meson.build b/meson.build -index d53976d621..c3330310d9 100644 +index 955f579308..c70f2a4937 100644 --- a/meson.build +++ b/meson.build -@@ -3914,6 +3914,10 @@ if have_tools +@@ -3981,6 +3981,10 @@ if have_tools vma = executable('vma', files('vma.c', 'vma-reader.c') + genh, dependencies: [authz, block, crypto, io, qom], install: true) diff --git a/debian/patches/pve/0032-PVE-Add-PBS-block-driver-to-map-backup-archives-into.patch b/debian/patches/pve/0032-PVE-Add-PBS-block-driver-to-map-backup-archives-into.patch index 0927c4d..78d0343 100644 --- a/debian/patches/pve/0032-PVE-Add-PBS-block-driver-to-map-backup-archives-into.patch +++ b/debian/patches/pve/0032-PVE-Add-PBS-block-driver-to-map-backup-archives-into.patch @@ -14,35 +14,33 @@ Signed-off-by: Wolfgang Bumiller getlength is now a coroutine function] Signed-off-by: Fiona Ebner --- - block/meson.build | 3 + - block/pbs.c | 305 +++++++++++++++++++++++++++++++++++++++++++ - configure | 9 ++ + block/meson.build | 2 + + block/pbs.c | 307 +++++++++++++++++++++++++++++++++++++++++++ meson.build | 2 +- qapi/block-core.json | 13 ++ qapi/pragma.json | 1 + - 6 files changed, 332 insertions(+), 1 deletion(-) + 5 files changed, 324 insertions(+), 1 deletion(-) create mode 100644 block/pbs.c diff --git a/block/meson.build b/block/meson.build -index 6d468f89e5..becc99ac4e 100644 +index 9df99aceb5..549c0c7103 100644 --- a/block/meson.build +++ b/block/meson.build -@@ -50,6 +50,9 @@ block_ss.add(files( +@@ -49,6 +49,8 @@ block_ss.add(files( '../pve-backup.c', ), libproxmox_backup_qemu) -+block_ss.add(when: 'CONFIG_PBS_BDRV', if_true: files('pbs.c')) -+block_ss.add(when: 'CONFIG_PBS_BDRV', if_true: libproxmox_backup_qemu) ++block_ss.add(files('pbs.c'), libproxmox_backup_qemu) + system_ss.add(when: 'CONFIG_TCG', if_true: files('blkreplay.c')) system_ss.add(files('block-ram-registrar.c')) diff --git a/block/pbs.c b/block/pbs.c new file mode 100644 -index 0000000000..a2211e0f3b +index 0000000000..dd72356bd3 --- /dev/null +++ b/block/pbs.c -@@ -0,0 +1,305 @@ +@@ -0,0 +1,307 @@ +/* + * Proxmox Backup Server read-only block driver + */ @@ -234,7 +232,8 @@ index 0000000000..a2211e0f3b + proxmox_restore_disconnect(s->conn); +} + -+static coroutine_fn int64_t pbs_co_getlength(BlockDriverState *bs) ++static coroutine_fn int64_t GRAPH_RDLOCK ++pbs_co_getlength(BlockDriverState *bs) +{ + BDRVPBSState *s = bs->opaque; + return s->length; @@ -251,9 +250,9 @@ index 0000000000..a2211e0f3b + aio_co_schedule(rcb->ctx, rcb->co); +} + -+static coroutine_fn int pbs_co_preadv(BlockDriverState *bs, -+ int64_t offset, int64_t bytes, -+ QEMUIOVector *qiov, BdrvRequestFlags flags) ++static coroutine_fn int GRAPH_RDLOCK ++pbs_co_preadv(BlockDriverState *bs, int64_t offset, int64_t bytes, ++ QEMUIOVector *qiov, BdrvRequestFlags flags) +{ + BDRVPBSState *s = bs->opaque; + int ret; @@ -298,16 +297,17 @@ index 0000000000..a2211e0f3b + return 0; +} + -+static coroutine_fn int pbs_co_pwritev(BlockDriverState *bs, -+ int64_t offset, int64_t bytes, -+ QEMUIOVector *qiov, BdrvRequestFlags flags) ++static coroutine_fn int GRAPH_RDLOCK ++pbs_co_pwritev(BlockDriverState *bs, int64_t offset, int64_t bytes, ++ QEMUIOVector *qiov, BdrvRequestFlags flags) +{ + fprintf(stderr, "pbs-bdrv: cannot write to backup file, make sure " + "any attached disk devices are set to read-only!\n"); + return -EPERM; +} + -+static void pbs_refresh_filename(BlockDriverState *bs) ++static void GRAPH_RDLOCK ++pbs_refresh_filename(BlockDriverState *bs) +{ + BDRVPBSState *s = bs->opaque; + if (s->namespace) { @@ -348,52 +348,11 @@ index 0000000000..a2211e0f3b +} + +block_init(bdrv_pbs_init); -diff --git a/configure b/configure -index 133f4e3235..f5a830c1f3 100755 ---- a/configure -+++ b/configure -@@ -256,6 +256,7 @@ qemu_suffix="qemu" - softmmu="yes" - linux_user="" - bsd_user="" -+pbs_bdrv="yes" - plugins="$default_feature" - ninja="" - python= -@@ -809,6 +810,10 @@ for opt do - ;; - --enable-download) download="enabled"; git_submodules_action=update; - ;; -+ --disable-pbs-bdrv) pbs_bdrv="no" -+ ;; -+ --enable-pbs-bdrv) pbs_bdrv="yes" -+ ;; - --enable-plugins) if test "$mingw32" = "yes"; then - error_exit "TCG plugins not currently supported on Windows platforms" - else -@@ -959,6 +964,7 @@ cat << EOF - bsd-user all BSD usermode emulation targets - pie Position Independent Executables - debug-tcg TCG debugging (default is disabled) -+ pbs-bdrv Proxmox backup server read-only block driver support - - NOTE: The object files are built at the place where configure is launched - EOF -@@ -1744,6 +1750,9 @@ if test "$solaris" = "yes" ; then - fi - echo "SRC_PATH=$source_path" >> $config_host_mak - echo "TARGET_DIRS=$target_list" >> $config_host_mak -+if test "$pbs_bdrv" = "yes" ; then -+ echo "CONFIG_PBS_BDRV=y" >> $config_host_mak -+fi - - # XXX: suppress that - if [ "$bsd" = "yes" ] ; then diff --git a/meson.build b/meson.build -index c3330310d9..cbfc9a43fb 100644 +index c70f2a4937..18c3a312eb 100644 --- a/meson.build +++ b/meson.build -@@ -4319,7 +4319,7 @@ summary_info += {'bzip2 support': libbzip2} +@@ -4390,7 +4390,7 @@ summary_info += {'bzip2 support': libbzip2} summary_info += {'lzfse support': liblzfse} summary_info += {'zstd support': zstd} summary_info += {'NUMA host support': numa} @@ -403,10 +362,10 @@ index c3330310d9..cbfc9a43fb 100644 summary_info += {'libdaxctl support': libdaxctl} summary_info += {'libudev': libudev} diff --git a/qapi/block-core.json b/qapi/block-core.json -index 1b8462a51b..d67a6d448a 100644 +index c155d74230..a4050268ca 100644 --- a/qapi/block-core.json +++ b/qapi/block-core.json -@@ -3396,6 +3396,7 @@ +@@ -3451,6 +3451,7 @@ 'parallels', 'preallocate', 'qcow', 'qcow2', 'qed', 'quorum', 'raw', 'rbd', { 'name': 'replication', 'if': 'CONFIG_REPLICATION' }, @@ -414,7 +373,7 @@ index 1b8462a51b..d67a6d448a 100644 'ssh', 'throttle', 'vdi', 'vhdx', { 'name': 'virtio-blk-vfio-pci', 'if': 'CONFIG_BLKIO' }, { 'name': 'virtio-blk-vhost-user', 'if': 'CONFIG_BLKIO' }, -@@ -3482,6 +3483,17 @@ +@@ -3537,6 +3538,17 @@ { 'struct': 'BlockdevOptionsNull', 'data': { '*size': 'int', '*latency-ns': 'uint64', '*read-zeroes': 'bool' } } @@ -432,7 +391,7 @@ index 1b8462a51b..d67a6d448a 100644 ## # @BlockdevOptionsNVMe: # -@@ -4890,6 +4902,7 @@ +@@ -4945,6 +4957,7 @@ 'nfs': 'BlockdevOptionsNfs', 'null-aio': 'BlockdevOptionsNull', 'null-co': 'BlockdevOptionsNull', @@ -441,7 +400,7 @@ index 1b8462a51b..d67a6d448a 100644 'nvme-io_uring': { 'type': 'BlockdevOptionsNvmeIoUring', 'if': 'CONFIG_BLKIO' }, diff --git a/qapi/pragma.json b/qapi/pragma.json -index 325e684411..b6079f6a0e 100644 +index eae9f54700..03467983b3 100644 --- a/qapi/pragma.json +++ b/qapi/pragma.json @@ -45,6 +45,7 @@ diff --git a/debian/patches/pve/0033-PVE-redirect-stderr-to-journal-when-daemonized.patch b/debian/patches/pve/0033-PVE-redirect-stderr-to-journal-when-daemonized.patch index 24ec761..475c49e 100644 --- a/debian/patches/pve/0033-PVE-redirect-stderr-to-journal-when-daemonized.patch +++ b/debian/patches/pve/0033-PVE-redirect-stderr-to-journal-when-daemonized.patch @@ -14,10 +14,10 @@ Signed-off-by: Thomas Lamprecht 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/meson.build b/meson.build -index cbfc9a43fb..8206270272 100644 +index 18c3a312eb..b598a0450b 100644 --- a/meson.build +++ b/meson.build -@@ -1779,6 +1779,7 @@ endif +@@ -1803,6 +1803,7 @@ endif has_gettid = cc.has_function('gettid') libuuid = cc.find_library('uuid', required: true) @@ -25,7 +25,7 @@ index cbfc9a43fb..8206270272 100644 libproxmox_backup_qemu = cc.find_library('proxmox_backup_qemu', required: true) # libselinux -@@ -3406,6 +3407,7 @@ if have_block +@@ -3468,6 +3469,7 @@ if have_block # os-posix.c contains POSIX-specific functions used by qemu-storage-daemon, # os-win32.c does not blockdev_ss.add(when: 'CONFIG_POSIX', if_true: files('os-posix.c')) @@ -34,7 +34,7 @@ index cbfc9a43fb..8206270272 100644 endif diff --git a/os-posix.c b/os-posix.c -index 0cc1d991b1..f33d9901cf 100644 +index a4284e2c07..197a2120fd 100644 --- a/os-posix.c +++ b/os-posix.c @@ -29,6 +29,8 @@ @@ -44,9 +44,9 @@ index 0cc1d991b1..f33d9901cf 100644 +#include +#include - /* Needed early for CONFIG_BSD etc. */ - #include "net/slirp.h" -@@ -332,9 +334,10 @@ void os_setup_post(void) + #include "qemu/error-report.h" + #include "qemu/log.h" +@@ -302,9 +304,10 @@ void os_setup_post(void) dup2(fd, 0); dup2(fd, 1); diff --git a/debian/patches/pve/0034-PVE-Migrate-dirty-bitmap-state-via-savevm.patch b/debian/patches/pve/0034-PVE-Migrate-dirty-bitmap-state-via-savevm.patch index 1015db3..f61465b 100644 --- a/debian/patches/pve/0034-PVE-Migrate-dirty-bitmap-state-via-savevm.patch +++ b/debian/patches/pve/0034-PVE-Migrate-dirty-bitmap-state-via-savevm.patch @@ -26,10 +26,10 @@ Signed-off-by: Fiona Ebner create mode 100644 migration/pbs-state.c diff --git a/include/migration/misc.h b/include/migration/misc.h -index 7dcc0b5c2c..4c940b2475 100644 +index 1bc8902e6d..43eb0e46d6 100644 --- a/include/migration/misc.h +++ b/include/migration/misc.h -@@ -77,4 +77,7 @@ bool migration_in_bg_snapshot(void); +@@ -80,4 +80,7 @@ bool migration_in_bg_snapshot(void); /* migration/block-dirty-bitmap.c */ void dirty_bitmap_mig_init(void); @@ -38,7 +38,7 @@ index 7dcc0b5c2c..4c940b2475 100644 + #endif diff --git a/migration/meson.build b/migration/meson.build -index 07f6057acc..343994d891 100644 +index 8f9d122187..2b9d2cc881 100644 --- a/migration/meson.build +++ b/migration/meson.build @@ -7,7 +7,9 @@ migration_files = files( @@ -52,10 +52,10 @@ index 07f6057acc..343994d891 100644 system_ss.add(files( 'block-dirty-bitmap.c', diff --git a/migration/migration.c b/migration/migration.c -index 7a4c8beb5d..0a955a2a18 100644 +index 982ab85f04..b84924442d 100644 --- a/migration/migration.c +++ b/migration/migration.c -@@ -162,6 +162,7 @@ void migration_object_init(void) +@@ -202,6 +202,7 @@ void migration_object_init(void) blk_mig_init(); ram_mig_init(); dirty_bitmap_mig_init(); @@ -174,10 +174,10 @@ index 0000000000..887e998b9e + NULL); +} diff --git a/pve-backup.c b/pve-backup.c -index ae3d137e12..e6b17b797e 100644 +index 903afcd7e9..777db7938e 100644 --- a/pve-backup.c +++ b/pve-backup.c -@@ -1082,6 +1082,7 @@ ProxmoxSupportStatus *qmp_query_proxmox_support(Error **errp) +@@ -1096,6 +1096,7 @@ ProxmoxSupportStatus *qmp_query_proxmox_support(Error **errp) ret->pbs_library_version = g_strdup(proxmox_backup_qemu_version()); ret->pbs_dirty_bitmap = true; ret->pbs_dirty_bitmap_savevm = true; @@ -186,10 +186,10 @@ index ae3d137e12..e6b17b797e 100644 ret->pbs_masterkey = true; ret->backup_max_workers = true; diff --git a/qapi/block-core.json b/qapi/block-core.json -index d67a6d448a..09de550c95 100644 +index a4050268ca..7b977459fa 100644 --- a/qapi/block-core.json +++ b/qapi/block-core.json -@@ -991,6 +991,11 @@ +@@ -993,6 +993,11 @@ # @pbs-dirty-bitmap-savevm: True if 'dirty-bitmaps' migration capability can # safely be set for savevm-async. # @@ -201,7 +201,7 @@ index d67a6d448a..09de550c95 100644 # @pbs-masterkey: True if the QMP backup call supports the 'master_keyfile' # parameter. # -@@ -1001,6 +1006,7 @@ +@@ -1003,6 +1008,7 @@ 'data': { 'pbs-dirty-bitmap': 'bool', 'query-bitmap-info': 'bool', 'pbs-dirty-bitmap-savevm': 'bool', diff --git a/debian/patches/pve/0035-migration-block-dirty-bitmap-migrate-other-bitmaps-e.patch b/debian/patches/pve/0035-migration-block-dirty-bitmap-migrate-other-bitmaps-e.patch index 75f5c28..8f98d6d 100644 --- a/debian/patches/pve/0035-migration-block-dirty-bitmap-migrate-other-bitmaps-e.patch +++ b/debian/patches/pve/0035-migration-block-dirty-bitmap-migrate-other-bitmaps-e.patch @@ -19,7 +19,7 @@ Signed-off-by: Thomas Lamprecht 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/migration/block-dirty-bitmap.c b/migration/block-dirty-bitmap.c -index e1ae3b7316..285dd1d148 100644 +index 0070b13b6f..954be621ba 100644 --- a/migration/block-dirty-bitmap.c +++ b/migration/block-dirty-bitmap.c @@ -540,7 +540,7 @@ static int add_bitmaps_to_list(DBMSaveState *s, BlockDriverState *bs, diff --git a/debian/patches/pve/0036-PVE-fall-back-to-open-iscsi-initiatorname.patch b/debian/patches/pve/0036-PVE-fall-back-to-open-iscsi-initiatorname.patch index f9fee14..c78bc03 100644 --- a/debian/patches/pve/0036-PVE-fall-back-to-open-iscsi-initiatorname.patch +++ b/debian/patches/pve/0036-PVE-fall-back-to-open-iscsi-initiatorname.patch @@ -21,10 +21,10 @@ Signed-off-by: Thomas Lamprecht 1 file changed, 30 insertions(+) diff --git a/block/iscsi.c b/block/iscsi.c -index 34f97ab646..398782963d 100644 +index 2ff14b7472..46f275fbf7 100644 --- a/block/iscsi.c +++ b/block/iscsi.c -@@ -1391,12 +1391,42 @@ static char *get_initiator_name(QemuOpts *opts) +@@ -1392,12 +1392,42 @@ static char *get_initiator_name(QemuOpts *opts) const char *name; char *iscsi_name; UuidInfo *uuid_info; diff --git a/debian/patches/pve/0037-PVE-block-stream-increase-chunk-size.patch b/debian/patches/pve/0037-PVE-block-stream-increase-chunk-size.patch index 28dd8d1..38807f8 100644 --- a/debian/patches/pve/0037-PVE-block-stream-increase-chunk-size.patch +++ b/debian/patches/pve/0037-PVE-block-stream-increase-chunk-size.patch @@ -11,7 +11,7 @@ Signed-off-by: Thomas Lamprecht 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/block/stream.c b/block/stream.c -index e522bbdec5..afed72db55 100644 +index 01fe7c0f16..87a97cb8a2 100644 --- a/block/stream.c +++ b/block/stream.c @@ -27,7 +27,7 @@ enum { diff --git a/debian/patches/pve/0038-block-io-accept-NULL-qiov-in-bdrv_pad_request.patch b/debian/patches/pve/0038-block-io-accept-NULL-qiov-in-bdrv_pad_request.patch index bb9b72c..611a444 100644 --- a/debian/patches/pve/0038-block-io-accept-NULL-qiov-in-bdrv_pad_request.patch +++ b/debian/patches/pve/0038-block-io-accept-NULL-qiov-in-bdrv_pad_request.patch @@ -20,10 +20,10 @@ Signed-off-by: Fiona Ebner 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/block/io.c b/block/io.c -index 83d1b1dfdc..e927881e40 100644 +index d202987770..d42c811bd7 100644 --- a/block/io.c +++ b/block/io.c -@@ -1723,22 +1723,25 @@ static int bdrv_pad_request(BlockDriverState *bs, +@@ -1756,22 +1756,25 @@ static int bdrv_pad_request(BlockDriverState *bs, return 0; } diff --git a/debian/patches/pve/0039-block-add-alloc-track-driver.patch b/debian/patches/pve/0039-block-add-alloc-track-driver.patch index ea5f105..d8dac88 100644 --- a/debian/patches/pve/0039-block-add-alloc-track-driver.patch +++ b/debian/patches/pve/0039-block-add-alloc-track-driver.patch @@ -19,27 +19,33 @@ well. This only worked if the target supports backing images, so up until now only for qcow2, with alloc-track any driver for the target can be used. -If 'auto-remove' is set, alloc-track will automatically detach itself -once the backing image is removed. It will be replaced by 'file'. +Replacing the node cannot be done in the +track_co_change_backing_file() callback, because replacing a node +cannot happen in a coroutine and requires the block graph lock +exclusively. Could either become a special option for the stream job, +or maybe the upcoming blockdev-replace QMP command can be used in the +future. Signed-off-by: Stefan Reiter Signed-off-by: Thomas Lamprecht [FE: adapt to changed function signatures make error return value consistent with QEMU - avoid premature break during read] + avoid premature break during read + adhere to block graph lock requirements] Signed-off-by: Fiona Ebner --- - block/alloc-track.c | 352 ++++++++++++++++++++++++++++++++++++++++++++ + block/alloc-track.c | 366 ++++++++++++++++++++++++++++++++++++++++++++ block/meson.build | 1 + - 2 files changed, 353 insertions(+) + block/stream.c | 34 ++++ + 3 files changed, 401 insertions(+) create mode 100644 block/alloc-track.c diff --git a/block/alloc-track.c b/block/alloc-track.c new file mode 100644 -index 0000000000..b75d7c6460 +index 0000000000..14698c362e --- /dev/null +++ b/block/alloc-track.c -@@ -0,0 +1,352 @@ +@@ -0,0 +1,366 @@ +/* + * Node to allow backing images to be applied to any node. Assumes a blank + * image to begin with, only new writes are tracked as allocated, thus this @@ -56,9 +62,11 @@ index 0000000000..b75d7c6460 +#include "qapi/error.h" +#include "block/block_int.h" +#include "block/dirty-bitmap.h" ++#include "block/graph-lock.h" +#include "qapi/qmp/qdict.h" +#include "qapi/qmp/qstring.h" +#include "qemu/cutils.h" ++#include "qemu/error-report.h" +#include "qemu/option.h" +#include "qemu/module.h" +#include "sysemu/block-backend.h" @@ -67,12 +75,12 @@ index 0000000000..b75d7c6460 + +typedef enum DropState { + DropNone, -+ DropRequested, + DropInProgress, +} DropState; + +typedef struct { + BdrvDirtyBitmap *bitmap; ++ uint64_t granularity; + DropState drop_state; + bool auto_remove; +} BDRVAllocTrackState; @@ -91,26 +99,29 @@ index 0000000000..b75d7c6460 + }, +}; + -+static void track_refresh_limits(BlockDriverState *bs, Error **errp) ++static void GRAPH_RDLOCK ++track_refresh_limits(BlockDriverState *bs, Error **errp) +{ -+ BlockDriverInfo bdi; ++ BDRVAllocTrackState *s = bs->opaque; + + if (!bs->file) { + return; + } + -+ /* always use alignment from underlying write device so RMW cycle for -+ * bdrv_pwritev reads data from our backing via track_co_preadv (no partial -+ * cluster allocation in 'file') */ -+ bdrv_get_info(bs->file->bs, &bdi); ++ /* ++ * Always use alignment from underlying write device so RMW cycle for ++ * bdrv_pwritev reads data from our backing via track_co_preadv. Also use at ++ * least the bitmap granularity. ++ */ + bs->bl.request_alignment = MAX(bs->file->bs->bl.request_alignment, -+ MAX(bdi.cluster_size, BDRV_SECTOR_SIZE)); ++ s->granularity); +} + +static int track_open(BlockDriverState *bs, QDict *options, int flags, + Error **errp) +{ + BDRVAllocTrackState *s = bs->opaque; ++ BdrvChild *file = NULL; + QemuOpts *opts; + Error *local_err = NULL; + int ret = 0; @@ -126,18 +137,45 @@ index 0000000000..b75d7c6460 + s->auto_remove = qemu_opt_get_bool(opts, TRACK_OPT_AUTO_REMOVE, false); + + /* open the target (write) node, backing will be attached by block layer */ -+ bs->file = bdrv_open_child(NULL, options, "file", bs, &child_of_bds, -+ BDRV_CHILD_DATA | BDRV_CHILD_METADATA, false, -+ &local_err); ++ file = bdrv_open_child(NULL, options, "file", bs, &child_of_bds, ++ BDRV_CHILD_DATA | BDRV_CHILD_METADATA, false, ++ &local_err); ++ bdrv_graph_wrlock(bs); ++ bs->file = file; ++ bdrv_graph_wrunlock(bs); + if (local_err) { + ret = -EINVAL; + error_propagate(errp, local_err); + goto fail; + } + ++ bdrv_graph_rdlock_main_loop(); ++ BlockDriverInfo bdi = {0}; ++ ret = bdrv_get_info(bs->file->bs, &bdi); ++ if (ret < 0) { ++ /* ++ * Not a hard failure. Worst that can happen is partial cluster ++ * allocation in the write target. However, the driver here returns its ++ * allocation status based on the dirty bitmap, so any other data that ++ * maps to such a cluster will still be copied later by a stream job (or ++ * during writes to that cluster). ++ */ ++ warn_report("alloc-track: unable to query cluster size for write target: %s", ++ strerror(ret)); ++ } ++ ret = 0; ++ /* ++ * Always consider alignment from underlying write device so RMW cycle for ++ * bdrv_pwritev reads data from our backing via track_co_preadv. Also try to ++ * avoid partial cluster allocation in the write target by considering the ++ * cluster size. ++ */ ++ s->granularity = MAX(bs->file->bs->bl.request_alignment, ++ MAX(bdi.cluster_size, BDRV_SECTOR_SIZE)); + track_refresh_limits(bs, errp); -+ uint64_t gran = bs->bl.request_alignment; -+ s->bitmap = bdrv_create_dirty_bitmap(bs->file->bs, gran, NULL, &local_err); ++ s->bitmap = bdrv_create_dirty_bitmap(bs->file->bs, s->granularity, NULL, ++ &local_err); ++ bdrv_graph_rdunlock_main_loop(); + if (local_err) { + ret = -EIO; + error_propagate(errp, local_err); @@ -148,7 +186,9 @@ index 0000000000..b75d7c6460 + +fail: + if (ret < 0) { ++ bdrv_graph_wrlock(bs); + bdrv_unref_child(bs, bs->file); ++ bdrv_graph_wrunlock(bs); + if (s->bitmap) { + bdrv_release_dirty_bitmap(s->bitmap); + } @@ -165,13 +205,15 @@ index 0000000000..b75d7c6460 + } +} + -+static coroutine_fn int64_t track_co_getlength(BlockDriverState *bs) ++static coroutine_fn int64_t GRAPH_RDLOCK ++track_co_getlength(BlockDriverState *bs) +{ + return bdrv_co_getlength(bs->file->bs); +} + -+static int coroutine_fn track_co_preadv(BlockDriverState *bs, -+ int64_t offset, int64_t bytes, QEMUIOVector *qiov, BdrvRequestFlags flags) ++static int coroutine_fn GRAPH_RDLOCK ++track_co_preadv(BlockDriverState *bs, int64_t offset, int64_t bytes, ++ QEMUIOVector *qiov, BdrvRequestFlags flags) +{ + BDRVAllocTrackState *s = bs->opaque; + QEMUIOVector local_qiov; @@ -229,36 +271,39 @@ index 0000000000..b75d7c6460 + return ret; +} + -+static int coroutine_fn track_co_pwritev(BlockDriverState *bs, -+ int64_t offset, int64_t bytes, QEMUIOVector *qiov, BdrvRequestFlags flags) ++static int coroutine_fn GRAPH_RDLOCK ++track_co_pwritev(BlockDriverState *bs, int64_t offset, int64_t bytes, ++ QEMUIOVector *qiov, BdrvRequestFlags flags) +{ + return bdrv_co_pwritev(bs->file, offset, bytes, qiov, flags); +} + -+static int coroutine_fn track_co_pwrite_zeroes(BlockDriverState *bs, -+ int64_t offset, int64_t bytes, BdrvRequestFlags flags) ++static int coroutine_fn GRAPH_RDLOCK ++track_co_pwrite_zeroes(BlockDriverState *bs, int64_t offset, int64_t bytes, ++ BdrvRequestFlags flags) +{ + return bdrv_co_pwrite_zeroes(bs->file, offset, bytes, flags); +} + -+static int coroutine_fn track_co_pdiscard(BlockDriverState *bs, -+ int64_t offset, int64_t bytes) ++static int coroutine_fn GRAPH_RDLOCK ++track_co_pdiscard(BlockDriverState *bs, int64_t offset, int64_t bytes) +{ + return bdrv_co_pdiscard(bs->file, offset, bytes); +} + -+static coroutine_fn int track_co_flush(BlockDriverState *bs) ++static coroutine_fn int GRAPH_RDLOCK ++track_co_flush(BlockDriverState *bs) +{ + return bdrv_co_flush(bs->file->bs); +} + -+static int coroutine_fn track_co_block_status(BlockDriverState *bs, -+ bool want_zero, -+ int64_t offset, -+ int64_t bytes, -+ int64_t *pnum, -+ int64_t *map, -+ BlockDriverState **file) ++static int coroutine_fn GRAPH_RDLOCK ++track_co_block_status(BlockDriverState *bs, bool want_zero, ++ int64_t offset, ++ int64_t bytes, ++ int64_t *pnum, ++ int64_t *map, ++ BlockDriverState **file) +{ + BDRVAllocTrackState *s = bs->opaque; + @@ -284,10 +329,10 @@ index 0000000000..b75d7c6460 + return 0; +} + -+static void track_child_perm(BlockDriverState *bs, BdrvChild *c, -+ BdrvChildRole role, BlockReopenQueue *reopen_queue, -+ uint64_t perm, uint64_t shared, -+ uint64_t *nperm, uint64_t *nshared) ++static void GRAPH_RDLOCK ++track_child_perm(BlockDriverState *bs, BdrvChild *c, BdrvChildRole role, ++ BlockReopenQueue *reopen_queue, uint64_t perm, uint64_t shared, ++ uint64_t *nperm, uint64_t *nshared) +{ + BDRVAllocTrackState *s = bs->opaque; + @@ -310,53 +355,28 @@ index 0000000000..b75d7c6460 + } +} + -+static void track_drop(void *opaque) ++static int coroutine_fn GRAPH_RDLOCK ++track_co_change_backing_file(BlockDriverState *bs, const char *backing_file, ++ const char *backing_fmt) +{ -+ BlockDriverState *bs = (BlockDriverState*)opaque; -+ BlockDriverState *file = bs->file->bs; -+ BDRVAllocTrackState *s = bs->opaque; -+ -+ assert(file); -+ -+ /* we rely on the fact that we're not used anywhere else, so let's wait -+ * until we're only used once - in the drive connected to the guest (and one -+ * ref is held by bdrv_ref in track_change_backing_file) */ -+ if (bs->refcnt > 2) { -+ aio_bh_schedule_oneshot(qemu_get_aio_context(), track_drop, opaque); -+ return; -+ } -+ AioContext *aio_context = bdrv_get_aio_context(bs); -+ aio_context_acquire(aio_context); -+ -+ bdrv_drained_begin(bs); -+ -+ /* now that we're drained, we can safely set 'DropInProgress' */ -+ s->drop_state = DropInProgress; -+ bdrv_child_refresh_perms(bs, bs->file, &error_abort); -+ -+ bdrv_replace_node(bs, file, &error_abort); -+ bdrv_set_backing_hd(bs, NULL, &error_abort); -+ bdrv_drained_end(bs); -+ bdrv_unref(bs); -+ aio_context_release(aio_context); -+} -+ -+static int track_change_backing_file(BlockDriverState *bs, -+ const char *backing_file, -+ const char *backing_fmt) -+{ -+ BDRVAllocTrackState *s = bs->opaque; -+ if (s->auto_remove && s->drop_state == DropNone && -+ backing_file == NULL && backing_fmt == NULL) -+ { -+ /* backing file has been disconnected, there's no longer any use for -+ * this node, so let's remove ourselves from the block graph - we need -+ * to schedule this for later however, since when this function is -+ * called, the blockjob modifying us is probably not done yet and has a -+ * blocker on 'bs' */ -+ s->drop_state = DropRequested; -+ bdrv_ref(bs); -+ aio_bh_schedule_oneshot(qemu_get_aio_context(), track_drop, (void*)bs); ++ /* ++ * Note that the actual backing file graph change is already done in the ++ * stream job itself with bdrv_set_backing_hd_drained(), so no need to ++ * actually do anything here. But still needs to be implemented, to make ++ * our caller (i.e. bdrv_co_change_backing_file() do the right thing). ++ * ++ * FIXME ++ * We'd like to auto-remove ourselves from the block graph, but it cannot ++ * be done from a coroutine. Currently done in the stream job, where it ++ * kinda fits better, but in the long-term, a special parameter would be ++ * nice (or done via qemu-server via upcoming blockdev-replace QMP command). ++ */ ++ if (backing_file == NULL) { ++ BDRVAllocTrackState *s = bs->opaque; ++ bdrv_drained_begin(bs); ++ s->drop_state = DropInProgress; ++ bdrv_child_refresh_perms(bs, bs->file, &error_abort); ++ bdrv_drained_end(bs); + } + + return 0; @@ -383,7 +403,7 @@ index 0000000000..b75d7c6460 + .supports_backing = true, + + .bdrv_co_block_status = track_co_block_status, -+ .bdrv_change_backing_file = track_change_backing_file, ++ .bdrv_co_change_backing_file = track_co_change_backing_file, +}; + +static void bdrv_alloc_track_init(void) @@ -393,7 +413,7 @@ index 0000000000..b75d7c6460 + +block_init(bdrv_alloc_track_init); diff --git a/block/meson.build b/block/meson.build -index becc99ac4e..0a69836593 100644 +index 549c0c7103..73777a1620 100644 --- a/block/meson.build +++ b/block/meson.build @@ -2,6 +2,7 @@ block_ss.add(genh) @@ -404,3 +424,48 @@ index becc99ac4e..0a69836593 100644 'amend.c', 'backup.c', 'backup-dump.c', +diff --git a/block/stream.c b/block/stream.c +index 87a97cb8a2..3a04e95ee2 100644 +--- a/block/stream.c ++++ b/block/stream.c +@@ -114,6 +114,40 @@ static int stream_prepare(Job *job) + ret = -EPERM; + goto out; + } ++ ++ /* ++ * This cannot be done in the co_change_backing_file callback, because ++ * bdrv_replace_node() cannot be done in a coroutine. The latter also ++ * requires the graph lock exclusively. Only required for the ++ * alloc-track driver. ++ * ++ * The long-term plan is to either have an explicit parameter for the ++ * stream job or use the upcoming blockdev-replace QMP command. ++ */ ++ if (base_id == NULL && strcmp(unfiltered_bs->drv->format_name, "alloc-track") == 0) { ++ BlockDriverState *file_bs; ++ ++ bdrv_graph_rdlock_main_loop(); ++ file_bs = unfiltered_bs->file->bs; ++ bdrv_graph_rdunlock_main_loop(); ++ ++ bdrv_ref(unfiltered_bs); // unrefed by bdrv_replace_node() ++ bdrv_drained_begin(file_bs); ++ bdrv_graph_wrlock(s->target_bs); ++ ++ bdrv_replace_node(unfiltered_bs, file_bs, &local_err); ++ ++ bdrv_graph_wrunlock(s->target_bs); ++ bdrv_drained_end(file_bs); ++ bdrv_unref(unfiltered_bs); ++ ++ if (local_err) { ++ error_prepend(&local_err, "failed to replace alloc-track node: "); ++ error_report_err(local_err); ++ ret = -EPERM; ++ goto out; ++ } ++ } + } + + out: diff --git a/debian/patches/pve/0040-Revert-block-rbd-workaround-for-ceph-issue-53784.patch b/debian/patches/pve/0040-Revert-block-rbd-workaround-for-ceph-issue-53784.patch index 094f353..f99f717 100644 --- a/debian/patches/pve/0040-Revert-block-rbd-workaround-for-ceph-issue-53784.patch +++ b/debian/patches/pve/0040-Revert-block-rbd-workaround-for-ceph-issue-53784.patch @@ -13,10 +13,10 @@ Signed-off-by: Thomas Lamprecht 1 file changed, 2 insertions(+), 40 deletions(-) diff --git a/block/rbd.c b/block/rbd.c -index a4749f3b1b..53e0396b51 100644 +index 63f60d41be..367db42dce 100644 --- a/block/rbd.c +++ b/block/rbd.c -@@ -1511,7 +1511,6 @@ static int coroutine_fn qemu_rbd_co_block_status(BlockDriverState *bs, +@@ -1515,7 +1515,6 @@ static int coroutine_fn qemu_rbd_co_block_status(BlockDriverState *bs, int status, r; RBDDiffIterateReq req = { .offs = offset }; uint64_t features, flags; @@ -24,7 +24,7 @@ index a4749f3b1b..53e0396b51 100644 assert(offset + bytes <= s->image_size); -@@ -1539,43 +1538,7 @@ static int coroutine_fn qemu_rbd_co_block_status(BlockDriverState *bs, +@@ -1543,43 +1542,7 @@ static int coroutine_fn qemu_rbd_co_block_status(BlockDriverState *bs, return status; } @@ -69,7 +69,7 @@ index a4749f3b1b..53e0396b51 100644 qemu_rbd_diff_iterate_cb, &req); if (r < 0 && r != QEMU_RBD_EXIT_DIFF_ITERATE2) { return status; -@@ -1594,8 +1557,7 @@ static int coroutine_fn qemu_rbd_co_block_status(BlockDriverState *bs, +@@ -1598,8 +1561,7 @@ static int coroutine_fn qemu_rbd_co_block_status(BlockDriverState *bs, status = BDRV_BLOCK_ZERO | BDRV_BLOCK_OFFSET_VALID; } diff --git a/debian/patches/pve/0041-Revert-block-rbd-fix-handling-of-holes-in-.bdrv_co_b.patch b/debian/patches/pve/0041-Revert-block-rbd-fix-handling-of-holes-in-.bdrv_co_b.patch index e4aca73..5ae0bff 100644 --- a/debian/patches/pve/0041-Revert-block-rbd-fix-handling-of-holes-in-.bdrv_co_b.patch +++ b/debian/patches/pve/0041-Revert-block-rbd-fix-handling-of-holes-in-.bdrv_co_b.patch @@ -14,10 +14,10 @@ Signed-off-by: Thomas Lamprecht 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/block/rbd.c b/block/rbd.c -index 53e0396b51..0913a0af39 100644 +index 367db42dce..347b121626 100644 --- a/block/rbd.c +++ b/block/rbd.c -@@ -1470,11 +1470,11 @@ static int qemu_rbd_diff_iterate_cb(uint64_t offs, size_t len, +@@ -1474,11 +1474,11 @@ static int qemu_rbd_diff_iterate_cb(uint64_t offs, size_t len, RBDDiffIterateReq *req = opaque; assert(req->offs + req->bytes <= offs); diff --git a/debian/patches/pve/0042-Revert-block-rbd-implement-bdrv_co_block_status.patch b/debian/patches/pve/0042-Revert-block-rbd-implement-bdrv_co_block_status.patch index 9e9a385..38966fe 100644 --- a/debian/patches/pve/0042-Revert-block-rbd-implement-bdrv_co_block_status.patch +++ b/debian/patches/pve/0042-Revert-block-rbd-implement-bdrv_co_block_status.patch @@ -24,7 +24,7 @@ Signed-off-by: Thomas Lamprecht 1 file changed, 112 deletions(-) diff --git a/block/rbd.c b/block/rbd.c -index 0913a0af39..1dab254517 100644 +index 347b121626..e61b359b97 100644 --- a/block/rbd.c +++ b/block/rbd.c @@ -108,12 +108,6 @@ typedef struct RBDTask { @@ -40,7 +40,7 @@ index 0913a0af39..1dab254517 100644 static int qemu_rbd_connect(rados_t *cluster, rados_ioctx_t *io_ctx, BlockdevOptionsRbd *opts, bool cache, const char *keypairs, const char *secretid, -@@ -1456,111 +1450,6 @@ static ImageInfoSpecific *qemu_rbd_get_specific_info(BlockDriverState *bs, +@@ -1460,111 +1454,6 @@ static ImageInfoSpecific *qemu_rbd_get_specific_info(BlockDriverState *bs, return spec_info; } @@ -152,7 +152,7 @@ index 0913a0af39..1dab254517 100644 static int64_t coroutine_fn qemu_rbd_co_getlength(BlockDriverState *bs) { BDRVRBDState *s = bs->opaque; -@@ -1796,7 +1685,6 @@ static BlockDriver bdrv_rbd = { +@@ -1800,7 +1689,6 @@ static BlockDriver bdrv_rbd = { #ifdef LIBRBD_SUPPORTS_WRITE_ZEROES .bdrv_co_pwrite_zeroes = qemu_rbd_co_pwrite_zeroes, #endif diff --git a/debian/patches/pve/0043-alloc-track-error-out-when-auto-remove-is-not-set.patch b/debian/patches/pve/0043-alloc-track-error-out-when-auto-remove-is-not-set.patch new file mode 100644 index 0000000..571c242 --- /dev/null +++ b/debian/patches/pve/0043-alloc-track-error-out-when-auto-remove-is-not-set.patch @@ -0,0 +1,43 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Fiona Ebner +Date: Tue, 26 Mar 2024 14:57:51 +0100 +Subject: [PATCH] alloc-track: error out when auto-remove is not set + +Since replacing the node now happens in the stream job, where the +option cannot be read from (it's internal to the driver), it will +always be treated as on. + +qemu-server will always set it, make sure to have other users notice +the change (should they even exist). The option can be fully dropped +in the future while adding a version guard in qemu-server. + +Signed-off-by: Fiona Ebner +--- + block/alloc-track.c | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +diff --git a/block/alloc-track.c b/block/alloc-track.c +index 14698c362e..dad8fe6375 100644 +--- a/block/alloc-track.c ++++ b/block/alloc-track.c +@@ -34,7 +34,6 @@ typedef struct { + BdrvDirtyBitmap *bitmap; + uint64_t granularity; + DropState drop_state; +- bool auto_remove; + } BDRVAllocTrackState; + + static QemuOptsList runtime_opts = { +@@ -86,7 +85,11 @@ static int track_open(BlockDriverState *bs, QDict *options, int flags, + goto fail; + } + +- s->auto_remove = qemu_opt_get_bool(opts, TRACK_OPT_AUTO_REMOVE, false); ++ if (!qemu_opt_get_bool(opts, TRACK_OPT_AUTO_REMOVE, false)) { ++ error_setg(errp, "alloc-track: requires auto-remove option to be set to on"); ++ ret = -EINVAL; ++ goto fail; ++ } + + /* open the target (write) node, backing will be attached by block layer */ + file = bdrv_open_child(NULL, options, "file", bs, &child_of_bds, diff --git a/debian/patches/pve/0043-alloc-track-fix-deadlock-during-drop.patch b/debian/patches/pve/0043-alloc-track-fix-deadlock-during-drop.patch deleted file mode 100644 index 153b8ef..0000000 --- a/debian/patches/pve/0043-alloc-track-fix-deadlock-during-drop.patch +++ /dev/null @@ -1,154 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Fiona Ebner -Date: Thu, 6 Apr 2023 14:59:31 +0200 -Subject: [PATCH] alloc-track: fix deadlock during drop - -by replacing the block node directly after changing the backing file -instead of rescheduling it. - -With changes in QEMU 8.0, calling bdrv_get_info (and bdrv_unref) -during drop can lead to a deadlock when using iothread (only triggered -with multiple disks, except during debugging where it also triggered -with one disk sometimes): -1. job_unref_locked acquires the AioContext and calls job->driver->free -2. track_drop gets scheduled -3. bdrv_graph_wrlock is called and polls which leads to track_drop being - called -4. track_drop acquires the AioContext recursively -5. bdrv_get_info is a wrapped coroutine (since 8.0) and thus polls for - bdrv_co_get_info. This releases the AioContext, but only once! The - documentation for the AIO_WAIT_WHILE macro states that the - AioContext lock needs to be acquired exactly once, but there does - not seem to be a way for track_drop to know if it acquired the lock - recursively or not (without adding further hacks). -6. Because the AioContext is still held by the main thread once, it can't - be acquired before entering bdrv_co_get_info in co_schedule_bh_cb - which happens in the iothread - -When doing the operation in change_backing_file, the AioContext has -already been acquired by the caller, so the issue with the recursive -lock goes away. - -The comment explaining why delaying the replace is necessary is -> we need to schedule this for later however, since when this function -> is called, the blockjob modifying us is probably not done yet and -> has a blocker on 'bs' - -However, there is no check for blockers in bdrv_replace_node. It would -need to be done by us, the caller, with check_to_replace_node. -Furthermore, the mirror job also does its call to bdrv_replace_node -while there is an active blocker (inserted by mirror itself) and they -use a specialized version to check for blockers instead of -check_to_replace_node there. Alloc-track could also do something -similar to check for other blockers, but it should be fine to rely on -Proxmox VE that no other operation with the blockdev is going on. - -Mirror also drains the target before replacing the node, but the -target can have other users. In case of alloc-track the file child -should not be accessible by anybody else and so there can't be an -in-flight operation for the file child when alloc-track is drained. - -The rescheduling based on refcounting is a hack and it doesn't seem to -be necessary anymore. It's not clear what the original issue from the -comment was. Testing with older builds with track_drop done directly -without rescheduling also didn't lead to any noticable issue for me. - -One issue it might have been is the one fixed by b1e1af394d -("block/stream: Drain subtree around graph change"), where -block-stream had a use-after-free if the base node changed at an -inconvenient time (which alloc-track's auto-drop does). - -It's also not possible to just not auto-replace the alloc-track. Not -replacing it at all leads to other operations like block resize -hanging, and there is no good way to replace it manually via QMP -(there is x-blockdev-change, but it is experimental and doesn't -implement the required operation yet). Also, it's just cleaner in -general to not leave unnecessary block nodes lying around. - -Suggested-by: Wolfgang Bumiller -Signed-off-by: Fiona Ebner -Signed-off-by: Thomas Lamprecht ---- - block/alloc-track.c | 54 ++++++++++++++------------------------------- - 1 file changed, 16 insertions(+), 38 deletions(-) - -diff --git a/block/alloc-track.c b/block/alloc-track.c -index b75d7c6460..76da140a68 100644 ---- a/block/alloc-track.c -+++ b/block/alloc-track.c -@@ -25,7 +25,6 @@ - - typedef enum DropState { - DropNone, -- DropRequested, - DropInProgress, - } DropState; - -@@ -268,37 +267,6 @@ static void track_child_perm(BlockDriverState *bs, BdrvChild *c, - } - } - --static void track_drop(void *opaque) --{ -- BlockDriverState *bs = (BlockDriverState*)opaque; -- BlockDriverState *file = bs->file->bs; -- BDRVAllocTrackState *s = bs->opaque; -- -- assert(file); -- -- /* we rely on the fact that we're not used anywhere else, so let's wait -- * until we're only used once - in the drive connected to the guest (and one -- * ref is held by bdrv_ref in track_change_backing_file) */ -- if (bs->refcnt > 2) { -- aio_bh_schedule_oneshot(qemu_get_aio_context(), track_drop, opaque); -- return; -- } -- AioContext *aio_context = bdrv_get_aio_context(bs); -- aio_context_acquire(aio_context); -- -- bdrv_drained_begin(bs); -- -- /* now that we're drained, we can safely set 'DropInProgress' */ -- s->drop_state = DropInProgress; -- bdrv_child_refresh_perms(bs, bs->file, &error_abort); -- -- bdrv_replace_node(bs, file, &error_abort); -- bdrv_set_backing_hd(bs, NULL, &error_abort); -- bdrv_drained_end(bs); -- bdrv_unref(bs); -- aio_context_release(aio_context); --} -- - static int track_change_backing_file(BlockDriverState *bs, - const char *backing_file, - const char *backing_fmt) -@@ -308,13 +276,23 @@ static int track_change_backing_file(BlockDriverState *bs, - backing_file == NULL && backing_fmt == NULL) - { - /* backing file has been disconnected, there's no longer any use for -- * this node, so let's remove ourselves from the block graph - we need -- * to schedule this for later however, since when this function is -- * called, the blockjob modifying us is probably not done yet and has a -- * blocker on 'bs' */ -- s->drop_state = DropRequested; -+ * this node, so let's remove ourselves from the block graph */ -+ BlockDriverState *file = bs->file->bs; -+ -+ /* Just to be sure, because bdrv_replace_node unrefs it */ - bdrv_ref(bs); -- aio_bh_schedule_oneshot(qemu_get_aio_context(), track_drop, (void*)bs); -+ bdrv_drained_begin(bs); -+ -+ /* now that we're drained, we can safely set 'DropInProgress' */ -+ s->drop_state = DropInProgress; -+ -+ bdrv_child_refresh_perms(bs, bs->file, &error_abort); -+ -+ bdrv_replace_node(bs, file, &error_abort); -+ bdrv_set_backing_hd(bs, NULL, &error_abort); -+ -+ bdrv_drained_end(bs); -+ bdrv_unref(bs); - } - - return 0; diff --git a/debian/patches/pve/0044-alloc-track-avoid-seemingly-superfluous-child-permis.patch b/debian/patches/pve/0044-alloc-track-avoid-seemingly-superfluous-child-permis.patch new file mode 100644 index 0000000..e4cc947 --- /dev/null +++ b/debian/patches/pve/0044-alloc-track-avoid-seemingly-superfluous-child-permis.patch @@ -0,0 +1,84 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Fiona Ebner +Date: Wed, 27 Mar 2024 11:15:39 +0100 +Subject: [PATCH] alloc-track: avoid seemingly superfluous child permission + update + +Doesn't seem necessary nowadays (maybe after commit "alloc-track: fix +deadlock during drop" where the dropping is not rescheduled and delayed +anymore or some upstream change). Should there really be some issue, +instead of having a drop state, this could also be just based off the +fact whether there is still a backing child. + +Dumping the cumulative (shared) permissions for the BDS with a debug +print yields the same values after this patch and with QEMU 8.1, +namely 3 and 5. + +Signed-off-by: Fiona Ebner +--- + block/alloc-track.c | 26 -------------------------- + 1 file changed, 26 deletions(-) + +diff --git a/block/alloc-track.c b/block/alloc-track.c +index dad8fe6375..7aff9763ad 100644 +--- a/block/alloc-track.c ++++ b/block/alloc-track.c +@@ -25,15 +25,9 @@ + + #define TRACK_OPT_AUTO_REMOVE "auto-remove" + +-typedef enum DropState { +- DropNone, +- DropInProgress, +-} DropState; +- + typedef struct { + BdrvDirtyBitmap *bitmap; + uint64_t granularity; +- DropState drop_state; + } BDRVAllocTrackState; + + static QemuOptsList runtime_opts = { +@@ -137,8 +131,6 @@ static int track_open(BlockDriverState *bs, QDict *options, int flags, + goto fail; + } + +- s->drop_state = DropNone; +- + fail: + if (ret < 0) { + bdrv_graph_wrlock(bs); +@@ -289,18 +281,8 @@ track_child_perm(BlockDriverState *bs, BdrvChild *c, BdrvChildRole role, + BlockReopenQueue *reopen_queue, uint64_t perm, uint64_t shared, + uint64_t *nperm, uint64_t *nshared) + { +- BDRVAllocTrackState *s = bs->opaque; +- + *nshared = BLK_PERM_ALL; + +- /* in case we're currently dropping ourselves, claim to not use any +- * permissions at all - which is fine, since from this point on we will +- * never issue a read or write anymore */ +- if (s->drop_state == DropInProgress) { +- *nperm = 0; +- return; +- } +- + if (role & BDRV_CHILD_DATA) { + *nperm = perm & DEFAULT_PERM_PASSTHROUGH; + } else { +@@ -326,14 +308,6 @@ track_co_change_backing_file(BlockDriverState *bs, const char *backing_file, + * kinda fits better, but in the long-term, a special parameter would be + * nice (or done via qemu-server via upcoming blockdev-replace QMP command). + */ +- if (backing_file == NULL) { +- BDRVAllocTrackState *s = bs->opaque; +- bdrv_drained_begin(bs); +- s->drop_state = DropInProgress; +- bdrv_child_refresh_perms(bs, bs->file, &error_abort); +- bdrv_drained_end(bs); +- } +- + return 0; + } + diff --git a/debian/patches/pve/0044-migration-for-snapshots-hold-the-BQL-during-setup-ca.patch b/debian/patches/pve/0044-migration-for-snapshots-hold-the-BQL-during-setup-ca.patch deleted file mode 100644 index 635f64a..0000000 --- a/debian/patches/pve/0044-migration-for-snapshots-hold-the-BQL-during-setup-ca.patch +++ /dev/null @@ -1,191 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Fiona Ebner -Date: Fri, 5 May 2023 13:39:53 +0200 -Subject: [PATCH] migration: for snapshots, hold the BQL during setup callbacks - -In spirit, this is a partial revert of commit 9b09503752 ("migration: -run setup callbacks out of big lock"), but only for the snapshot case. - -For snapshots, the bdrv_writev_vmstate() function is used during setup -(in QIOChannelBlock backing the QEMUFile), but not holding the BQL -while calling it could lead to an assertion failure. To understand -how, first note the following: - -1. Generated coroutine wrappers for block layer functions spawn the -coroutine and use AIO_WAIT_WHILE()/aio_poll() to wait for it. -2. If the host OS switches threads at an inconvenient time, it can -happen that a bottom half scheduled for the main thread's AioContext -is executed as part of a vCPU thread's aio_poll(). - -An example leading to the assertion failure is as follows: - -main thread: -1. A snapshot-save QMP command gets issued. -2. snapshot_save_job_bh() is scheduled. - -vCPU thread: -3. aio_poll() for the main thread's AioContext is called (e.g. when -the guest writes to a pflash device, as part of blk_pwrite which is a -generated coroutine wrapper). -4. snapshot_save_job_bh() is executed as part of aio_poll(). -3. qemu_savevm_state() is called. -4. qemu_mutex_unlock_iothread() is called. Now -qemu_get_current_aio_context() returns 0x0. -5. bdrv_writev_vmstate() is executed during the usual savevm setup. -But this function is a generated coroutine wrapper, so it uses -AIO_WAIT_WHILE. There, the assertion -assert(qemu_get_current_aio_context() == qemu_get_aio_context()); -will fail. - -To fix it, ensure that the BQL is held during setup. To avoid changing -the behavior for migration too, introduce conditionals for the setup -callbacks that need the BQL and only take the lock if it's not already -held. - -Signed-off-by: Fiona Ebner -Signed-off-by: Thomas Lamprecht ---- - include/migration/register.h | 2 +- - migration/block-dirty-bitmap.c | 15 ++++++++++++--- - migration/block.c | 15 ++++++++++++--- - migration/ram.c | 16 +++++++++++++--- - migration/savevm.c | 2 -- - 5 files changed, 38 insertions(+), 12 deletions(-) - -diff --git a/include/migration/register.h b/include/migration/register.h -index 90914f32f5..c728fd9120 100644 ---- a/include/migration/register.h -+++ b/include/migration/register.h -@@ -43,9 +43,9 @@ typedef struct SaveVMHandlers { - * by other locks. - */ - int (*save_live_iterate)(QEMUFile *f, void *opaque); -+ int (*save_setup)(QEMUFile *f, void *opaque); - - /* This runs outside the iothread lock! */ -- int (*save_setup)(QEMUFile *f, void *opaque); - /* Note for save_live_pending: - * must_precopy: - * - must be migrated in precopy or in stopped state -diff --git a/migration/block-dirty-bitmap.c b/migration/block-dirty-bitmap.c -index 285dd1d148..f7ee5a74d9 100644 ---- a/migration/block-dirty-bitmap.c -+++ b/migration/block-dirty-bitmap.c -@@ -1219,10 +1219,17 @@ static int dirty_bitmap_save_setup(QEMUFile *f, void *opaque) - { - DBMSaveState *s = &((DBMState *)opaque)->save; - SaveBitmapState *dbms = NULL; -+ bool release_lock = false; - -- qemu_mutex_lock_iothread(); -+ /* For snapshots, the BQL is held during setup. */ -+ if (!qemu_mutex_iothread_locked()) { -+ qemu_mutex_lock_iothread(); -+ release_lock = true; -+ } - if (init_dirty_bitmap_migration(s) < 0) { -- qemu_mutex_unlock_iothread(); -+ if (release_lock) { -+ qemu_mutex_unlock_iothread(); -+ } - return -1; - } - -@@ -1230,7 +1237,9 @@ static int dirty_bitmap_save_setup(QEMUFile *f, void *opaque) - send_bitmap_start(f, s, dbms); - } - qemu_put_bitmap_flags(f, DIRTY_BITMAP_MIG_FLAG_EOS); -- qemu_mutex_unlock_iothread(); -+ if (release_lock) { -+ qemu_mutex_unlock_iothread(); -+ } - return 0; - } - -diff --git a/migration/block.c b/migration/block.c -index 86c2256a2b..8423e0c9f9 100644 ---- a/migration/block.c -+++ b/migration/block.c -@@ -725,21 +725,30 @@ static void block_migration_cleanup(void *opaque) - static int block_save_setup(QEMUFile *f, void *opaque) - { - int ret; -+ bool release_lock = false; - - trace_migration_block_save("setup", block_mig_state.submitted, - block_mig_state.transferred); - -- qemu_mutex_lock_iothread(); -+ /* For snapshots, the BQL is held during setup. */ -+ if (!qemu_mutex_iothread_locked()) { -+ qemu_mutex_lock_iothread(); -+ release_lock = true; -+ } - ret = init_blk_migration(f); - if (ret < 0) { -- qemu_mutex_unlock_iothread(); -+ if (release_lock) { -+ qemu_mutex_unlock_iothread(); -+ } - return ret; - } - - /* start track dirty blocks */ - ret = set_dirty_tracking(); - -- qemu_mutex_unlock_iothread(); -+ if (release_lock) { -+ qemu_mutex_unlock_iothread(); -+ } - - if (ret) { - return ret; -diff --git a/migration/ram.c b/migration/ram.c -index 6e1514f69f..6a1aec7031 100644 ---- a/migration/ram.c -+++ b/migration/ram.c -@@ -2896,8 +2896,16 @@ static void migration_bitmap_clear_discarded_pages(RAMState *rs) - - static void ram_init_bitmaps(RAMState *rs) - { -- /* For memory_global_dirty_log_start below. */ -- qemu_mutex_lock_iothread(); -+ bool release_lock = false; -+ -+ /* -+ * For memory_global_dirty_log_start below. -+ * For snapshots, the BQL is held during setup. -+ */ -+ if (!qemu_mutex_iothread_locked()) { -+ qemu_mutex_lock_iothread(); -+ release_lock = true; -+ } - qemu_mutex_lock_ramlist(); - - WITH_RCU_READ_LOCK_GUARD() { -@@ -2909,7 +2917,9 @@ static void ram_init_bitmaps(RAMState *rs) - } - } - qemu_mutex_unlock_ramlist(); -- qemu_mutex_unlock_iothread(); -+ if (release_lock) { -+ qemu_mutex_unlock_iothread(); -+ } - - /* - * After an eventual first bitmap sync, fixup the initial bitmap -diff --git a/migration/savevm.c b/migration/savevm.c -index d60c4f487a..3c015722f7 100644 ---- a/migration/savevm.c -+++ b/migration/savevm.c -@@ -1625,10 +1625,8 @@ static int qemu_savevm_state(QEMUFile *f, Error **errp) - reset_vfio_bytes_transferred(); - ms->to_dst_file = f; - -- qemu_mutex_unlock_iothread(); - qemu_savevm_state_header(f); - qemu_savevm_state_setup(f); -- qemu_mutex_lock_iothread(); - - while (qemu_file_get_error(f) == 0) { - if (qemu_savevm_state_iterate(f, false) > 0) { diff --git a/debian/patches/pve/0046-block-copy-before-write-fix-permission.patch b/debian/patches/pve/0045-block-copy-before-write-fix-permission.patch similarity index 94% rename from debian/patches/pve/0046-block-copy-before-write-fix-permission.patch rename to debian/patches/pve/0045-block-copy-before-write-fix-permission.patch index 1c2e5bd..4bd5d48 100644 --- a/debian/patches/pve/0046-block-copy-before-write-fix-permission.patch +++ b/debian/patches/pve/0045-block-copy-before-write-fix-permission.patch @@ -33,10 +33,10 @@ Signed-off-by: Thomas Lamprecht 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/block/copy-before-write.c b/block/copy-before-write.c -index b866e42271..a2dddf6f57 100644 +index 13972879b1..dbdbbca44e 100644 --- a/block/copy-before-write.c +++ b/block/copy-before-write.c -@@ -364,9 +364,13 @@ static void cbw_child_perm(BlockDriverState *bs, BdrvChild *c, +@@ -364,9 +364,13 @@ cbw_child_perm(BlockDriverState *bs, BdrvChild *c, BdrvChildRole role, perm, shared, nperm, nshared); if (!QLIST_EMPTY(&bs->parents)) { diff --git a/debian/patches/pve/0045-savevm-async-don-t-hold-BQL-during-setup.patch b/debian/patches/pve/0045-savevm-async-don-t-hold-BQL-during-setup.patch deleted file mode 100644 index ac00f1a..0000000 --- a/debian/patches/pve/0045-savevm-async-don-t-hold-BQL-during-setup.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Fiona Ebner -Date: Fri, 5 May 2023 15:30:16 +0200 -Subject: [PATCH] savevm-async: don't hold BQL during setup - -See commit "migration: for snapshots, hold the BQL during setup -callbacks" for why. This is separate, because a version of that one -will hopefully land upstream. - -Signed-off-by: Fiona Ebner -Signed-off-by: Thomas Lamprecht ---- - migration/savevm-async.c | 2 -- - 1 file changed, 2 deletions(-) - -diff --git a/migration/savevm-async.c b/migration/savevm-async.c -index 80624fada8..b1d85a4b41 100644 ---- a/migration/savevm-async.c -+++ b/migration/savevm-async.c -@@ -401,10 +401,8 @@ void qmp_savevm_start(const char *statefile, Error **errp) - snap_state.state = SAVE_STATE_ACTIVE; - snap_state.finalize_bh = qemu_bh_new(process_savevm_finalize, &snap_state); - snap_state.co = qemu_coroutine_create(&process_savevm_co, NULL); -- qemu_mutex_unlock_iothread(); - qemu_savevm_state_header(snap_state.file); - qemu_savevm_state_setup(snap_state.file); -- qemu_mutex_lock_iothread(); - - /* Async processing from here on out happens in iohandler context, so let - * the target bdrv have its home there. diff --git a/debian/patches/pve/0047-block-copy-before-write-support-unligned-snapshot-di.patch b/debian/patches/pve/0046-block-copy-before-write-support-unligned-snapshot-di.patch similarity index 94% rename from debian/patches/pve/0047-block-copy-before-write-support-unligned-snapshot-di.patch rename to debian/patches/pve/0046-block-copy-before-write-support-unligned-snapshot-di.patch index 4656750..b7f0aff 100644 --- a/debian/patches/pve/0047-block-copy-before-write-support-unligned-snapshot-di.patch +++ b/debian/patches/pve/0046-block-copy-before-write-support-unligned-snapshot-di.patch @@ -15,7 +15,7 @@ Signed-off-by: Thomas Lamprecht 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/block/copy-before-write.c b/block/copy-before-write.c -index a2dddf6f57..0a219c2b75 100644 +index dbdbbca44e..2cbf6f9346 100644 --- a/block/copy-before-write.c +++ b/block/copy-before-write.c @@ -325,14 +325,24 @@ static int coroutine_fn GRAPH_RDLOCK @@ -45,4 +45,4 @@ index a2dddf6f57..0a219c2b75 100644 + return bdrv_co_pdiscard(s->target, aligned_offset, aligned_bytes); } - static void cbw_refresh_filename(BlockDriverState *bs) + static void GRAPH_RDLOCK cbw_refresh_filename(BlockDriverState *bs) diff --git a/debian/patches/pve/0048-block-copy-before-write-create-block_copy-bitmap-in-.patch b/debian/patches/pve/0047-block-copy-before-write-create-block_copy-bitmap-in-.patch similarity index 97% rename from debian/patches/pve/0048-block-copy-before-write-create-block_copy-bitmap-in-.patch rename to debian/patches/pve/0047-block-copy-before-write-create-block_copy-bitmap-in-.patch index ab7c0bf..12014ed 100644 --- a/debian/patches/pve/0048-block-copy-before-write-create-block_copy-bitmap-in-.patch +++ b/debian/patches/pve/0047-block-copy-before-write-create-block_copy-bitmap-in-.patch @@ -28,10 +28,10 @@ Signed-off-by: Thomas Lamprecht 4 files changed, 60 insertions(+), 58 deletions(-) diff --git a/block/block-copy.c b/block/block-copy.c -index e13d7bc6b6..b61685f1a2 100644 +index 9ee3dd7ef5..8fca2c3698 100644 --- a/block/block-copy.c +++ b/block/block-copy.c -@@ -346,6 +346,7 @@ static int64_t block_copy_calculate_cluster_size(BlockDriverState *target, +@@ -351,6 +351,7 @@ static int64_t block_copy_calculate_cluster_size(BlockDriverState *target, } BlockCopyState *block_copy_state_new(BdrvChild *source, BdrvChild *target, @@ -39,7 +39,7 @@ index e13d7bc6b6..b61685f1a2 100644 const BdrvDirtyBitmap *bitmap, Error **errp) { -@@ -360,7 +361,7 @@ BlockCopyState *block_copy_state_new(BdrvChild *source, BdrvChild *target, +@@ -367,7 +368,7 @@ BlockCopyState *block_copy_state_new(BdrvChild *source, BdrvChild *target, return NULL; } @@ -49,10 +49,10 @@ index e13d7bc6b6..b61685f1a2 100644 if (!copy_bitmap) { return NULL; diff --git a/block/copy-before-write.c b/block/copy-before-write.c -index 0a219c2b75..d3b95bd600 100644 +index 2cbf6f9346..afa5f473d2 100644 --- a/block/copy-before-write.c +++ b/block/copy-before-write.c -@@ -470,7 +470,7 @@ static int cbw_open(BlockDriverState *bs, QDict *options, int flags, +@@ -472,7 +472,7 @@ static int cbw_open(BlockDriverState *bs, QDict *options, int flags, ((BDRV_REQ_FUA | BDRV_REQ_MAY_UNMAP | BDRV_REQ_NO_FALLBACK) & bs->file->bs->supported_zero_flags); diff --git a/debian/patches/pve/0049-qapi-blockdev-backup-add-discard-source-parameter.patch b/debian/patches/pve/0048-qapi-blockdev-backup-add-discard-source-parameter.patch similarity index 89% rename from debian/patches/pve/0049-qapi-blockdev-backup-add-discard-source-parameter.patch rename to debian/patches/pve/0048-qapi-blockdev-backup-add-discard-source-parameter.patch index b6eee3e..a5cdb7d 100644 --- a/debian/patches/pve/0049-qapi-blockdev-backup-add-discard-source-parameter.patch +++ b/debian/patches/pve/0048-qapi-blockdev-backup-add-discard-source-parameter.patch @@ -45,7 +45,7 @@ Signed-off-by: Thomas Lamprecht 10 files changed, 37 insertions(+), 8 deletions(-) diff --git a/block/backup.c b/block/backup.c -index af87fa6aa9..3dc955f625 100644 +index aec140e0c8..f19b751fe6 100644 --- a/block/backup.c +++ b/block/backup.c @@ -332,7 +332,7 @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs, @@ -57,7 +57,7 @@ index af87fa6aa9..3dc955f625 100644 const char *filter_node_name, BackupPerf *perf, BlockdevOnError on_source_error, -@@ -429,7 +429,8 @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs, +@@ -433,7 +433,8 @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs, goto error; } @@ -68,7 +68,7 @@ index af87fa6aa9..3dc955f625 100644 goto error; } diff --git a/block/block-copy.c b/block/block-copy.c -index b61685f1a2..3c61e52bae 100644 +index 8fca2c3698..7e3b378528 100644 --- a/block/block-copy.c +++ b/block/block-copy.c @@ -137,6 +137,7 @@ typedef struct BlockCopyState { @@ -79,7 +79,7 @@ index b61685f1a2..3c61e52bae 100644 BlockReqList reqs; QLIST_HEAD(, BlockCopyCallState) calls; /* -@@ -348,6 +349,7 @@ static int64_t block_copy_calculate_cluster_size(BlockDriverState *target, +@@ -353,6 +354,7 @@ static int64_t block_copy_calculate_cluster_size(BlockDriverState *target, BlockCopyState *block_copy_state_new(BdrvChild *source, BdrvChild *target, BlockDriverState *copy_bitmap_bs, const BdrvDirtyBitmap *bitmap, @@ -87,7 +87,7 @@ index b61685f1a2..3c61e52bae 100644 Error **errp) { ERRP_GUARD(); -@@ -409,6 +411,7 @@ BlockCopyState *block_copy_state_new(BdrvChild *source, BdrvChild *target, +@@ -418,6 +420,7 @@ BlockCopyState *block_copy_state_new(BdrvChild *source, BdrvChild *target, cluster_size), }; @@ -95,7 +95,7 @@ index b61685f1a2..3c61e52bae 100644 block_copy_set_copy_opts(s, false, false); ratelimit_init(&s->rate_limit); -@@ -580,6 +583,12 @@ static coroutine_fn int block_copy_task_entry(AioTask *task) +@@ -589,6 +592,12 @@ static coroutine_fn int block_copy_task_entry(AioTask *task) co_put_to_shres(s->mem, t->req.bytes); block_copy_task_end(t, ret); @@ -109,7 +109,7 @@ index b61685f1a2..3c61e52bae 100644 } diff --git a/block/copy-before-write.c b/block/copy-before-write.c -index d3b95bd600..3503702d71 100644 +index afa5f473d2..5506f66857 100644 --- a/block/copy-before-write.c +++ b/block/copy-before-write.c @@ -44,6 +44,7 @@ typedef struct BDRVCopyBeforeWriteState { @@ -120,16 +120,16 @@ index d3b95bd600..3503702d71 100644 /* * @lock: protects access to @access_bitmap, @done_bitmap and -@@ -357,6 +358,8 @@ static void cbw_child_perm(BlockDriverState *bs, BdrvChild *c, - uint64_t perm, uint64_t shared, - uint64_t *nperm, uint64_t *nshared) +@@ -357,6 +358,8 @@ cbw_child_perm(BlockDriverState *bs, BdrvChild *c, BdrvChildRole role, + uint64_t perm, uint64_t shared, + uint64_t *nperm, uint64_t *nshared) { + BDRVCopyBeforeWriteState *s = bs->opaque; + if (!(role & BDRV_CHILD_FILTERED)) { /* * Target child -@@ -381,6 +384,10 @@ static void cbw_child_perm(BlockDriverState *bs, BdrvChild *c, +@@ -381,6 +384,10 @@ cbw_child_perm(BlockDriverState *bs, BdrvChild *c, BdrvChildRole role, * start */ *nperm = *nperm | BLK_PERM_CONSISTENT_READ; @@ -140,7 +140,7 @@ index d3b95bd600..3503702d71 100644 *nshared &= ~(BLK_PERM_WRITE | BLK_PERM_RESIZE); } } -@@ -470,7 +477,9 @@ static int cbw_open(BlockDriverState *bs, QDict *options, int flags, +@@ -472,7 +479,9 @@ static int cbw_open(BlockDriverState *bs, QDict *options, int flags, ((BDRV_REQ_FUA | BDRV_REQ_MAY_UNMAP | BDRV_REQ_NO_FALLBACK) & bs->file->bs->supported_zero_flags); @@ -151,7 +151,7 @@ index d3b95bd600..3503702d71 100644 if (!s->bcs) { error_prepend(errp, "Cannot create block-copy-state: "); ret = -EINVAL; -@@ -544,12 +553,14 @@ BlockDriver bdrv_cbw_filter = { +@@ -546,12 +555,14 @@ static BlockDriver bdrv_cbw_filter = { BlockDriverState *bdrv_cbw_append(BlockDriverState *source, BlockDriverState *target, const char *filter_node_name, @@ -166,7 +166,7 @@ index d3b95bd600..3503702d71 100644 assert(source->total_sectors == target->total_sectors); GLOBAL_STATE_CODE(); -@@ -562,7 +573,7 @@ BlockDriverState *bdrv_cbw_append(BlockDriverState *source, +@@ -564,7 +575,7 @@ BlockDriverState *bdrv_cbw_append(BlockDriverState *source, qdict_put_str(opts, "file", bdrv_get_node_name(source)); qdict_put_str(opts, "target", bdrv_get_node_name(target)); @@ -188,10 +188,10 @@ index 6e72bb25e9..01af0cd3c4 100644 Error **errp); void bdrv_cbw_drop(BlockDriverState *bs); diff --git a/block/replication.c b/block/replication.c -index ea4bf1aa80..39ad78cf98 100644 +index 5ded5f1ca9..bd75a6aee3 100644 --- a/block/replication.c +++ b/block/replication.c -@@ -579,8 +579,8 @@ static void replication_start(ReplicationState *rs, ReplicationMode mode, +@@ -604,8 +604,8 @@ static void replication_start(ReplicationState *rs, ReplicationMode mode, s->backup_job = backup_job_create( NULL, s->secondary_disk->bs, s->hidden_disk->bs, @@ -203,10 +203,10 @@ index ea4bf1aa80..39ad78cf98 100644 BLOCKDEV_ON_ERROR_REPORT, JOB_INTERNAL, backup_job_completed, bs, NULL, &local_err); diff --git a/blockdev.c b/blockdev.c -index 7793143d76..ce3fef924c 100644 +index 3049811be8..e167ad1e54 100644 --- a/blockdev.c +++ b/blockdev.c -@@ -2802,7 +2802,7 @@ static BlockJob *do_backup_common(BackupCommon *backup, +@@ -2854,7 +2854,7 @@ static BlockJob *do_backup_common(BackupCommon *backup, job = backup_job_create(backup->job_id, bs, target_bs, backup->speed, backup->sync, bmap, backup->bitmap_mode, @@ -216,10 +216,10 @@ index 7793143d76..ce3fef924c 100644 &perf, backup->on_source_error, diff --git a/include/block/block-common.h b/include/block/block-common.h -index e15395f2cb..913a8b259c 100644 +index d7599564db..7f56364e73 100644 --- a/include/block/block-common.h +++ b/include/block/block-common.h -@@ -234,6 +234,8 @@ typedef enum { +@@ -246,6 +246,8 @@ typedef enum { read-write fails */ #define BDRV_O_IO_URING 0x40000 /* use io_uring instead of the thread pool */ @@ -241,7 +241,7 @@ index 8b41643bfa..bdc703bacd 100644 /* Function should be called prior any actual copy request */ diff --git a/include/block/block_int-global-state.h b/include/block/block_int-global-state.h -index 32f0f9858a..546f2b5532 100644 +index 57265a617a..df731688b4 100644 --- a/include/block/block_int-global-state.h +++ b/include/block/block_int-global-state.h @@ -189,7 +189,7 @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs, @@ -254,10 +254,10 @@ index 32f0f9858a..546f2b5532 100644 BackupPerf *perf, BlockdevOnError on_source_error, diff --git a/qapi/block-core.json b/qapi/block-core.json -index 09de550c95..4297e5beda 100644 +index 7b977459fa..82960797dc 100644 --- a/qapi/block-core.json +++ b/qapi/block-core.json -@@ -1816,6 +1816,9 @@ +@@ -1834,6 +1834,9 @@ # node specified by @drive. If this option is not given, a node # name is autogenerated. (Since: 4.2) # @@ -267,7 +267,7 @@ index 09de550c95..4297e5beda 100644 # @x-perf: Performance options. (Since 6.0) # # Features: -@@ -1837,6 +1840,7 @@ +@@ -1855,6 +1858,7 @@ '*on-target-error': 'BlockdevOnError', '*auto-finalize': 'bool', '*auto-dismiss': 'bool', '*filter-node-name': 'str', diff --git a/debian/patches/pve/0050-copy-before-write-allow-specifying-minimum-cluster-s.patch b/debian/patches/pve/0049-copy-before-write-allow-specifying-minimum-cluster-s.patch similarity index 92% rename from debian/patches/pve/0050-copy-before-write-allow-specifying-minimum-cluster-s.patch rename to debian/patches/pve/0049-copy-before-write-allow-specifying-minimum-cluster-s.patch index 17949f4..71d6c14 100644 --- a/debian/patches/pve/0050-copy-before-write-allow-specifying-minimum-cluster-s.patch +++ b/debian/patches/pve/0049-copy-before-write-allow-specifying-minimum-cluster-s.patch @@ -25,7 +25,7 @@ Signed-off-by: Thomas Lamprecht 4 files changed, 23 insertions(+), 6 deletions(-) diff --git a/block/block-copy.c b/block/block-copy.c -index 3c61e52bae..c9a722a5a6 100644 +index 7e3b378528..adb1cbb440 100644 --- a/block/block-copy.c +++ b/block/block-copy.c @@ -310,6 +310,7 @@ void block_copy_set_copy_opts(BlockCopyState *s, bool use_copy_range, @@ -36,7 +36,7 @@ index 3c61e52bae..c9a722a5a6 100644 Error **errp) { int ret; -@@ -330,7 +331,7 @@ static int64_t block_copy_calculate_cluster_size(BlockDriverState *target, +@@ -335,7 +336,7 @@ static int64_t block_copy_calculate_cluster_size(BlockDriverState *target, "used. If the actual block size of the target exceeds " "this default, the backup may be unusable", BLOCK_COPY_CLUSTER_SIZE_DEFAULT); @@ -45,7 +45,7 @@ index 3c61e52bae..c9a722a5a6 100644 } else if (ret < 0 && !target_does_cow) { error_setg_errno(errp, -ret, "Couldn't determine the cluster size of the target image, " -@@ -340,16 +341,18 @@ static int64_t block_copy_calculate_cluster_size(BlockDriverState *target, +@@ -345,16 +346,18 @@ static int64_t block_copy_calculate_cluster_size(BlockDriverState *target, return ret; } else if (ret < 0 && target_does_cow) { /* Not fatal; just trudge on ahead. */ @@ -66,9 +66,9 @@ index 3c61e52bae..c9a722a5a6 100644 Error **errp) { ERRP_GUARD(); -@@ -358,7 +361,13 @@ BlockCopyState *block_copy_state_new(BdrvChild *source, BdrvChild *target, - BdrvDirtyBitmap *copy_bitmap; - bool is_fleecing; +@@ -365,7 +368,13 @@ BlockCopyState *block_copy_state_new(BdrvChild *source, BdrvChild *target, + + GLOBAL_STATE_CODE(); - cluster_size = block_copy_calculate_cluster_size(target->bs, errp); + if (min_cluster_size && !is_power_of_2(min_cluster_size)) { @@ -82,10 +82,10 @@ index 3c61e52bae..c9a722a5a6 100644 return NULL; } diff --git a/block/copy-before-write.c b/block/copy-before-write.c -index 3503702d71..4a8c5bdb62 100644 +index 5506f66857..fbc5aeb9eb 100644 --- a/block/copy-before-write.c +++ b/block/copy-before-write.c -@@ -479,7 +479,8 @@ static int cbw_open(BlockDriverState *bs, QDict *options, int flags, +@@ -481,7 +481,8 @@ static int cbw_open(BlockDriverState *bs, QDict *options, int flags, s->discard_source = flags & BDRV_O_CBW_DISCARD_SOURCE; s->bcs = block_copy_state_new(bs->file, s->target, bs, bitmap, @@ -108,10 +108,10 @@ index bdc703bacd..77857c6c68 100644 /* Function should be called prior any actual copy request */ diff --git a/qapi/block-core.json b/qapi/block-core.json -index 4297e5beda..33e7e3c090 100644 +index 82960797dc..f2fec625cc 100644 --- a/qapi/block-core.json +++ b/qapi/block-core.json -@@ -4825,12 +4825,18 @@ +@@ -4880,12 +4880,18 @@ # @on-cbw-error parameter will decide how this failure is handled. # Default 0. (Since 7.1) # diff --git a/debian/patches/pve/0051-backup-add-minimum-cluster-size-to-performance-optio.patch b/debian/patches/pve/0050-backup-add-minimum-cluster-size-to-performance-optio.patch similarity index 90% rename from debian/patches/pve/0051-backup-add-minimum-cluster-size-to-performance-optio.patch rename to debian/patches/pve/0050-backup-add-minimum-cluster-size-to-performance-optio.patch index d760e45..da2d2db 100644 --- a/debian/patches/pve/0051-backup-add-minimum-cluster-size-to-performance-optio.patch +++ b/debian/patches/pve/0050-backup-add-minimum-cluster-size-to-performance-optio.patch @@ -23,10 +23,10 @@ Signed-off-by: Thomas Lamprecht 5 files changed, 14 insertions(+), 3 deletions(-) diff --git a/block/backup.c b/block/backup.c -index 3dc955f625..ac5bd81338 100644 +index f19b751fe6..4367278d68 100644 --- a/block/backup.c +++ b/block/backup.c -@@ -430,7 +430,7 @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs, +@@ -434,7 +434,7 @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs, } cbw = bdrv_cbw_append(bs, target, filter_node_name, discard_source, @@ -36,10 +36,10 @@ index 3dc955f625..ac5bd81338 100644 goto error; } diff --git a/block/copy-before-write.c b/block/copy-before-write.c -index 4a8c5bdb62..9ca5ec5e5c 100644 +index fbc5aeb9eb..3d5523992c 100644 --- a/block/copy-before-write.c +++ b/block/copy-before-write.c -@@ -555,6 +555,7 @@ BlockDriverState *bdrv_cbw_append(BlockDriverState *source, +@@ -557,6 +557,7 @@ BlockDriverState *bdrv_cbw_append(BlockDriverState *source, BlockDriverState *target, const char *filter_node_name, bool discard_source, @@ -47,7 +47,7 @@ index 4a8c5bdb62..9ca5ec5e5c 100644 BlockCopyState **bcs, Error **errp) { -@@ -573,6 +574,7 @@ BlockDriverState *bdrv_cbw_append(BlockDriverState *source, +@@ -575,6 +576,7 @@ BlockDriverState *bdrv_cbw_append(BlockDriverState *source, } qdict_put_str(opts, "file", bdrv_get_node_name(source)); qdict_put_str(opts, "target", bdrv_get_node_name(target)); @@ -68,10 +68,10 @@ index 01af0cd3c4..dc6cafe7fa 100644 Error **errp); void bdrv_cbw_drop(BlockDriverState *bs); diff --git a/blockdev.c b/blockdev.c -index ce3fef924c..5ae1dde73c 100644 +index e167ad1e54..35ec5d8f0b 100644 --- a/blockdev.c +++ b/blockdev.c -@@ -2729,6 +2729,9 @@ static BlockJob *do_backup_common(BackupCommon *backup, +@@ -2781,6 +2781,9 @@ static BlockJob *do_backup_common(BackupCommon *backup, if (backup->x_perf->has_max_chunk) { perf.max_chunk = backup->x_perf->max_chunk; } @@ -82,10 +82,10 @@ index ce3fef924c..5ae1dde73c 100644 if ((backup->sync == MIRROR_SYNC_MODE_BITMAP) || diff --git a/qapi/block-core.json b/qapi/block-core.json -index 33e7e3c090..58fd637e86 100644 +index f2fec625cc..48eec4ef29 100644 --- a/qapi/block-core.json +++ b/qapi/block-core.json -@@ -1757,11 +1757,16 @@ +@@ -1775,11 +1775,16 @@ # it should not be less than job cluster size which is calculated # as maximum of target image cluster size and 64k. Default 0. # diff --git a/debian/patches/pve/0052-PVE-backup-add-fleecing-option.patch b/debian/patches/pve/0051-PVE-backup-add-fleecing-option.patch similarity index 91% rename from debian/patches/pve/0052-PVE-backup-add-fleecing-option.patch rename to debian/patches/pve/0051-PVE-backup-add-fleecing-option.patch index a4d78cd..53b6ab3 100644 --- a/debian/patches/pve/0052-PVE-backup-add-fleecing-option.patch +++ b/debian/patches/pve/0051-PVE-backup-add-fleecing-option.patch @@ -63,15 +63,15 @@ Signed-off-by: Fiona Ebner Signed-off-by: Thomas Lamprecht --- block/monitor/block-hmp-cmds.c | 1 + - pve-backup.c | 143 ++++++++++++++++++++++++++++++++- + pve-backup.c | 145 ++++++++++++++++++++++++++++++++- qapi/block-core.json | 8 +- - 3 files changed, 148 insertions(+), 4 deletions(-) + 3 files changed, 150 insertions(+), 4 deletions(-) diff --git a/block/monitor/block-hmp-cmds.c b/block/monitor/block-hmp-cmds.c -index 6efe28cef5..ca29cc4281 100644 +index 1656859e03..f6cc9e5cf7 100644 --- a/block/monitor/block-hmp-cmds.c +++ b/block/monitor/block-hmp-cmds.c -@@ -1064,6 +1064,7 @@ void coroutine_fn hmp_backup(Monitor *mon, const QDict *qdict) +@@ -1072,6 +1072,7 @@ void coroutine_fn hmp_backup(Monitor *mon, const QDict *qdict) NULL, NULL, devlist, qdict_haskey(qdict, "speed"), speed, false, 0, // BackupPerf max-workers @@ -80,21 +80,22 @@ index 6efe28cef5..ca29cc4281 100644 hmp_handle_error(mon, error); diff --git a/pve-backup.c b/pve-backup.c -index e6b17b797e..00aaff6509 100644 +index 777db7938e..4c728951ac 100644 --- a/pve-backup.c +++ b/pve-backup.c -@@ -7,8 +7,10 @@ +@@ -7,9 +7,11 @@ #include "sysemu/blockdev.h" #include "block/block_int-global-state.h" #include "block/blockjob.h" +#include "block/copy-before-write.h" #include "block/dirty-bitmap.h" + #include "block/graph-lock.h" #include "qapi/qapi-commands-block.h" +#include "qapi/qmp/qdict.h" #include "qapi/qmp/qerror.h" #include "qemu/cutils.h" -@@ -80,8 +82,15 @@ static void pvebackup_init(void) +@@ -81,8 +83,15 @@ static void pvebackup_init(void) // initialize PVEBackupState at startup opts_init(pvebackup_init); @@ -110,7 +111,7 @@ index e6b17b797e..00aaff6509 100644 size_t size; uint64_t block_size; uint8_t dev_id; -@@ -361,6 +370,25 @@ static void pvebackup_complete_cb(void *opaque, int ret) +@@ -355,6 +364,25 @@ static void pvebackup_complete_cb(void *opaque, int ret) PVEBackupDevInfo *di = opaque; di->completed_ret = ret; @@ -134,9 +135,9 @@ index e6b17b797e..00aaff6509 100644 + } + /* - * Schedule stream cleanup in async coroutine. close_image and finish might - * take a while, so we can't block on them here. This way it also doesn't -@@ -521,9 +549,82 @@ static void create_backup_jobs_bh(void *opaque) { + * Needs to happen outside of coroutine, because it takes the graph write lock. + */ +@@ -525,9 +553,84 @@ static void create_backup_jobs_bh(void *opaque) { bdrv_drained_begin(di->bs); @@ -144,7 +145,9 @@ index e6b17b797e..00aaff6509 100644 + + BlockDriverState *source_bs = di->bs; + bool discard_source = false; ++ bdrv_graph_co_rdlock(); + const char *job_id = bdrv_get_device_name(di->bs); ++ bdrv_graph_co_rdunlock(); + if (di->fleecing.bs) { + QDict *cbw_opts = qdict_new(); + qdict_put_str(cbw_opts, "driver", "copy-before-write"); @@ -221,7 +224,7 @@ index e6b17b797e..00aaff6509 100644 BLOCKDEV_ON_ERROR_REPORT, JOB_DEFAULT, pvebackup_complete_cb, di, backup_state.txn, &local_err); -@@ -581,6 +682,14 @@ static void create_backup_jobs_bh(void *opaque) { +@@ -585,6 +688,14 @@ static void create_backup_jobs_bh(void *opaque) { aio_co_enter(data->ctx, data->co); } @@ -236,15 +239,15 @@ index e6b17b797e..00aaff6509 100644 /* * Returns a list of device infos, which needs to be freed by the caller. In * case of an error, errp will be set, but the returned value might still be a -@@ -588,6 +697,7 @@ static void create_backup_jobs_bh(void *opaque) { +@@ -592,6 +703,7 @@ static void create_backup_jobs_bh(void *opaque) { */ - static GList coroutine_fn *get_device_info( + static GList coroutine_fn GRAPH_RDLOCK *get_device_info( const char *devlist, + bool fleecing, Error **errp) { gchar **devs = NULL; -@@ -611,6 +721,31 @@ static GList coroutine_fn *get_device_info( +@@ -615,6 +727,31 @@ static GList coroutine_fn GRAPH_RDLOCK *get_device_info( } PVEBackupDevInfo *di = g_new0(PVEBackupDevInfo, 1); di->bs = bs; @@ -276,7 +279,7 @@ index e6b17b797e..00aaff6509 100644 di_list = g_list_append(di_list, di); d++; } -@@ -660,6 +795,7 @@ UuidInfo coroutine_fn *qmp_backup( +@@ -664,6 +801,7 @@ UuidInfo coroutine_fn *qmp_backup( const char *devlist, bool has_speed, int64_t speed, bool has_max_workers, int64_t max_workers, @@ -284,16 +287,16 @@ index e6b17b797e..00aaff6509 100644 Error **errp) { assert(qemu_in_coroutine()); -@@ -687,7 +823,7 @@ UuidInfo coroutine_fn *qmp_backup( - /* Todo: try to auto-detect format based on file name */ +@@ -692,7 +830,7 @@ UuidInfo coroutine_fn *qmp_backup( format = has_format ? format : BACKUP_FORMAT_VMA; + bdrv_graph_co_rdlock(); - di_list = get_device_info(devlist, &local_err); + di_list = get_device_info(devlist, has_fleecing && fleecing, &local_err); + bdrv_graph_co_rdunlock(); if (local_err) { error_propagate(errp, local_err); - goto err; -@@ -1086,5 +1222,6 @@ ProxmoxSupportStatus *qmp_query_proxmox_support(Error **errp) +@@ -1100,5 +1238,6 @@ ProxmoxSupportStatus *qmp_query_proxmox_support(Error **errp) ret->query_bitmap_info = true; ret->pbs_masterkey = true; ret->backup_max_workers = true; @@ -301,10 +304,10 @@ index e6b17b797e..00aaff6509 100644 return ret; } diff --git a/qapi/block-core.json b/qapi/block-core.json -index 58fd637e86..0bc5f42677 100644 +index 48eec4ef29..1c036e488e 100644 --- a/qapi/block-core.json +++ b/qapi/block-core.json -@@ -933,6 +933,10 @@ +@@ -935,6 +935,10 @@ # # @max-workers: see @BackupPerf for details. Default 16. # @@ -315,7 +318,7 @@ index 58fd637e86..0bc5f42677 100644 # Returns: the uuid of the backup job # ## -@@ -953,7 +957,8 @@ +@@ -955,7 +959,8 @@ '*firewall-file': 'str', '*devlist': 'str', '*speed': 'int', @@ -325,7 +328,7 @@ index 58fd637e86..0bc5f42677 100644 'returns': 'UuidInfo', 'coroutine': true } ## -@@ -1009,6 +1014,7 @@ +@@ -1011,6 +1016,7 @@ 'pbs-dirty-bitmap-migration': 'bool', 'pbs-masterkey': 'bool', 'pbs-library-version': 'str', diff --git a/debian/patches/series b/debian/patches/series index 1680bca..0d87249 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -2,15 +2,9 @@ extra/0001-monitor-qmp-fix-race-with-clients-disconnecting-earl.patch extra/0002-scsi-megasas-Internal-cdbs-have-16-byte-length.patch extra/0003-ide-avoid-potential-deadlock-when-draining-during-tr.patch extra/0004-migration-block-dirty-bitmap-fix-loading-bitmap-when.patch -extra/0005-Revert-Revert-graph-lock-Disable-locking-for-now.patch -extra/0006-migration-states-workaround-snapshot-performance-reg.patch -extra/0007-Revert-x86-acpi-workaround-Windows-not-handling-name.patch -extra/0008-target-i386-the-sgx_epc_get_section-stub-is-reachabl.patch -extra/0009-ui-clipboard-mark-type-as-not-available-when-there-i.patch -extra/0010-virtio-scsi-Attach-event-vq-notifier-with-no_poll.patch -extra/0011-virtio-Re-enable-notifications-after-drain.patch -extra/0012-qemu_init-increase-NOFILE-soft-limit-on-POSIX.patch -extra/0013-virtio-blk-avoid-using-ioeventfd-state-in-irqfd-cond.patch +extra/0005-Revert-x86-acpi-workaround-Windows-not-handling-name.patch +extra/0006-qemu_init-increase-NOFILE-soft-limit-on-POSIX.patch +extra/0007-mirror-Don-t-call-job_pause_point-under-graph-lock.patch bitmap-mirror/0001-drive-mirror-add-support-for-sync-bitmap-mode-never.patch bitmap-mirror/0002-drive-mirror-add-support-for-conditional-and-always-.patch bitmap-mirror/0003-mirror-add-check-for-bitmap-mode-without-bitmap.patch @@ -59,13 +53,12 @@ pve/0039-block-add-alloc-track-driver.patch pve/0040-Revert-block-rbd-workaround-for-ceph-issue-53784.patch pve/0041-Revert-block-rbd-fix-handling-of-holes-in-.bdrv_co_b.patch pve/0042-Revert-block-rbd-implement-bdrv_co_block_status.patch -pve/0043-alloc-track-fix-deadlock-during-drop.patch -pve/0044-migration-for-snapshots-hold-the-BQL-during-setup-ca.patch -pve/0045-savevm-async-don-t-hold-BQL-during-setup.patch -pve/0046-block-copy-before-write-fix-permission.patch -pve/0047-block-copy-before-write-support-unligned-snapshot-di.patch -pve/0048-block-copy-before-write-create-block_copy-bitmap-in-.patch -pve/0049-qapi-blockdev-backup-add-discard-source-parameter.patch -pve/0050-copy-before-write-allow-specifying-minimum-cluster-s.patch -pve/0051-backup-add-minimum-cluster-size-to-performance-optio.patch -pve/0052-PVE-backup-add-fleecing-option.patch +pve/0043-alloc-track-error-out-when-auto-remove-is-not-set.patch +pve/0044-alloc-track-avoid-seemingly-superfluous-child-permis.patch +pve/0045-block-copy-before-write-fix-permission.patch +pve/0046-block-copy-before-write-support-unligned-snapshot-di.patch +pve/0047-block-copy-before-write-create-block_copy-bitmap-in-.patch +pve/0048-qapi-blockdev-backup-add-discard-source-parameter.patch +pve/0049-copy-before-write-allow-specifying-minimum-cluster-s.patch +pve/0050-backup-add-minimum-cluster-size-to-performance-optio.patch +pve/0051-PVE-backup-add-fleecing-option.patch diff --git a/qemu b/qemu index 20a1b34..11aa0b1 160000 --- a/qemu +++ b/qemu @@ -1 +1 @@ -Subproject commit 20a1b341a0af1fef84cec9e521d33da0e8d9ecf3 +Subproject commit 11aa0b1ff115b86160c4d37e7c37e6a6b13b77ea