update submodule and patches to QEMU 8.0.0
Many changes were necessary this time around: * QAPI was changed to avoid redundant has_* variables, see commit 44ea9d9be3 ("qapi: Start to elide redundant has_FOO in generated C") for details. This affected many QMP commands added by Proxmox too. * Pending querying for migration got split into two functions, one to estimate, one for exact value, see commit c8df4a7aef ("migration: Split save_live_pending() into state_pending_*") for details. Relevant for savevm-async and PBS dirty bitmap. * Some block (driver) functions got converted to coroutines, so the Proxmox block drivers needed to be adapted. * Alloc track auto-detaching during PBS live restore got broken by AioContext-related changes resulting in a deadlock. The current, hacky method was replaced by a simpler one. Stefan apparently ran into a problem with that when he wrote the driver, but there were improvements in the stream job code since then and I didn't manage to reproduce the issue. It's a separate patch "alloc-track: fix deadlock during drop" for now, you can find the details there. * Async snapshot-related changes: - The pending querying got adapted to the above-mentioned split and a patch is added to optimize it/make it more similar to what upstream code does. - Added initialization of the compression counters (for future-proofing). - It's necessary the hold the BQL (big QEMU lock = iothread mutex) during the setup phase, because block layer functions are used there and not doing so leads to racy, hard-to-debug crashes or hangs. It's necessary to change some upstream code too for this, a version of the patch "migration: for snapshots, hold the BQL during setup callbacks" is intended to be upstreamed. - Need to take the bdrv graph read lock before flushing. * hmp_info_balloon was moved to a different file. * Needed to include a new headers from time to time to still get the correct functions. Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
This commit is contained in:
parent
fb818ea5b9
commit
bf251437e9
@ -27,16 +27,18 @@ Signed-off-by: Ma Haocong <mahaocong@didichuxing.com>
|
||||
Signed-off-by: John Snow <jsnow@redhat.com>
|
||||
Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
|
||||
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
|
||||
[FE: rebased for 8.0]
|
||||
Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
|
||||
---
|
||||
block/mirror.c | 98 +++++++++++++++++++++-----
|
||||
blockdev.c | 39 +++++++++-
|
||||
blockdev.c | 38 +++++++++-
|
||||
include/block/block_int-global-state.h | 4 +-
|
||||
qapi/block-core.json | 29 ++++++--
|
||||
tests/unit/test-block-iothread.c | 4 +-
|
||||
5 files changed, 145 insertions(+), 29 deletions(-)
|
||||
5 files changed, 144 insertions(+), 29 deletions(-)
|
||||
|
||||
diff --git a/block/mirror.c b/block/mirror.c
|
||||
index 251adc5ae0..8ead5f77a0 100644
|
||||
index 663e2b7002..9099c75992 100644
|
||||
--- a/block/mirror.c
|
||||
+++ b/block/mirror.c
|
||||
@@ -51,7 +51,7 @@ typedef struct MirrorBlockJob {
|
||||
@ -57,7 +59,7 @@ index 251adc5ae0..8ead5f77a0 100644
|
||||
BdrvDirtyBitmap *dirty_bitmap;
|
||||
BdrvDirtyBitmapIter *dbi;
|
||||
uint8_t *buf;
|
||||
@@ -699,7 +701,8 @@ static int mirror_exit_common(Job *job)
|
||||
@@ -703,7 +705,8 @@ static int mirror_exit_common(Job *job)
|
||||
bdrv_child_refresh_perms(mirror_top_bs, mirror_top_bs->backing,
|
||||
&error_abort);
|
||||
if (!abort && s->backing_mode == MIRROR_SOURCE_BACKING_CHAIN) {
|
||||
@ -67,7 +69,7 @@ index 251adc5ae0..8ead5f77a0 100644
|
||||
BlockDriverState *unfiltered_target = bdrv_skip_filters(target_bs);
|
||||
|
||||
if (bdrv_cow_bs(unfiltered_target) != backing) {
|
||||
@@ -797,6 +800,16 @@ static void mirror_abort(Job *job)
|
||||
@@ -801,6 +804,16 @@ static void mirror_abort(Job *job)
|
||||
assert(ret == 0);
|
||||
}
|
||||
|
||||
@ -84,7 +86,7 @@ index 251adc5ae0..8ead5f77a0 100644
|
||||
static void coroutine_fn mirror_throttle(MirrorBlockJob *s)
|
||||
{
|
||||
int64_t now = qemu_clock_get_ns(QEMU_CLOCK_REALTIME);
|
||||
@@ -977,7 +990,8 @@ static int coroutine_fn mirror_run(Job *job, Error **errp)
|
||||
@@ -987,7 +1000,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);
|
||||
@ -94,7 +96,7 @@ index 251adc5ae0..8ead5f77a0 100644
|
||||
ret = mirror_dirty_init(s);
|
||||
if (ret < 0 || job_is_cancelled(&s->common.job)) {
|
||||
goto immediate_exit;
|
||||
@@ -1224,6 +1238,7 @@ static const BlockJobDriver mirror_job_driver = {
|
||||
@@ -1240,6 +1254,7 @@ static const BlockJobDriver mirror_job_driver = {
|
||||
.run = mirror_run,
|
||||
.prepare = mirror_prepare,
|
||||
.abort = mirror_abort,
|
||||
@ -102,7 +104,7 @@ index 251adc5ae0..8ead5f77a0 100644
|
||||
.pause = mirror_pause,
|
||||
.complete = mirror_complete,
|
||||
.cancel = mirror_cancel,
|
||||
@@ -1240,6 +1255,7 @@ static const BlockJobDriver commit_active_job_driver = {
|
||||
@@ -1256,6 +1271,7 @@ static const BlockJobDriver commit_active_job_driver = {
|
||||
.run = mirror_run,
|
||||
.prepare = mirror_prepare,
|
||||
.abort = mirror_abort,
|
||||
@ -110,7 +112,7 @@ index 251adc5ae0..8ead5f77a0 100644
|
||||
.pause = mirror_pause,
|
||||
.complete = mirror_complete,
|
||||
.cancel = commit_active_cancel,
|
||||
@@ -1627,7 +1643,10 @@ static BlockJob *mirror_start_job(
|
||||
@@ -1647,7 +1663,10 @@ static BlockJob *mirror_start_job(
|
||||
BlockCompletionFunc *cb,
|
||||
void *opaque,
|
||||
const BlockJobDriver *driver,
|
||||
@ -122,7 +124,7 @@ index 251adc5ae0..8ead5f77a0 100644
|
||||
bool auto_complete, const char *filter_node_name,
|
||||
bool is_mirror, MirrorCopyMode copy_mode,
|
||||
Error **errp)
|
||||
@@ -1639,10 +1658,39 @@ static BlockJob *mirror_start_job(
|
||||
@@ -1659,10 +1678,39 @@ static BlockJob *mirror_start_job(
|
||||
uint64_t target_perms, target_shared_perms;
|
||||
int ret;
|
||||
|
||||
@ -164,7 +166,7 @@ index 251adc5ae0..8ead5f77a0 100644
|
||||
assert(is_power_of_2(granularity));
|
||||
|
||||
if (buf_size < 0) {
|
||||
@@ -1774,7 +1822,9 @@ static BlockJob *mirror_start_job(
|
||||
@@ -1793,7 +1841,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;
|
||||
@ -175,7 +177,7 @@ index 251adc5ae0..8ead5f77a0 100644
|
||||
s->backing_mode = backing_mode;
|
||||
s->zero_target = zero_target;
|
||||
s->copy_mode = copy_mode;
|
||||
@@ -1795,6 +1845,18 @@ static BlockJob *mirror_start_job(
|
||||
@@ -1814,6 +1864,18 @@ static BlockJob *mirror_start_job(
|
||||
bdrv_disable_dirty_bitmap(s->dirty_bitmap);
|
||||
}
|
||||
|
||||
@ -194,7 +196,7 @@ index 251adc5ae0..8ead5f77a0 100644
|
||||
ret = block_job_add_bdrv(&s->common, "source", bs, 0,
|
||||
BLK_PERM_WRITE_UNCHANGED | BLK_PERM_WRITE |
|
||||
BLK_PERM_CONSISTENT_READ,
|
||||
@@ -1872,6 +1934,9 @@ fail:
|
||||
@@ -1891,6 +1953,9 @@ fail:
|
||||
if (s->dirty_bitmap) {
|
||||
bdrv_release_dirty_bitmap(s->dirty_bitmap);
|
||||
}
|
||||
@ -204,7 +206,7 @@ index 251adc5ae0..8ead5f77a0 100644
|
||||
job_early_fail(&s->common.job);
|
||||
}
|
||||
|
||||
@@ -1889,31 +1954,25 @@ void mirror_start(const char *job_id, BlockDriverState *bs,
|
||||
@@ -1908,31 +1973,25 @@ 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,
|
||||
@ -241,7 +243,7 @@ index 251adc5ae0..8ead5f77a0 100644
|
||||
}
|
||||
|
||||
BlockJob *commit_active_start(const char *job_id, BlockDriverState *bs,
|
||||
@@ -1940,7 +1999,8 @@ BlockJob *commit_active_start(const char *job_id, BlockDriverState *bs,
|
||||
@@ -1959,7 +2018,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,
|
||||
@ -252,21 +254,20 @@ index 251adc5ae0..8ead5f77a0 100644
|
||||
errp);
|
||||
if (!job) {
|
||||
diff --git a/blockdev.c b/blockdev.c
|
||||
index 3f1dec6242..2ee30323cb 100644
|
||||
index d7b5c18f0a..6c34d9bb3a 100644
|
||||
--- a/blockdev.c
|
||||
+++ b/blockdev.c
|
||||
@@ -2946,6 +2946,10 @@ static void blockdev_mirror_common(const char *job_id, BlockDriverState *bs,
|
||||
@@ -2932,6 +2932,9 @@ static void blockdev_mirror_common(const char *job_id, BlockDriverState *bs,
|
||||
BlockDriverState *target,
|
||||
bool has_replaces, const char *replaces,
|
||||
const char *replaces,
|
||||
enum MirrorSyncMode sync,
|
||||
+ bool has_bitmap,
|
||||
+ const char *bitmap_name,
|
||||
+ bool has_bitmap_mode,
|
||||
+ BitmapSyncMode bitmap_mode,
|
||||
BlockMirrorBackingMode backing_mode,
|
||||
bool zero_target,
|
||||
bool has_speed, int64_t speed,
|
||||
@@ -2965,6 +2969,7 @@ static void blockdev_mirror_common(const char *job_id, BlockDriverState *bs,
|
||||
@@ -2950,6 +2953,7 @@ static void blockdev_mirror_common(const char *job_id, BlockDriverState *bs,
|
||||
{
|
||||
BlockDriverState *unfiltered_bs;
|
||||
int job_flags = JOB_DEFAULT;
|
||||
@ -274,11 +275,11 @@ index 3f1dec6242..2ee30323cb 100644
|
||||
|
||||
if (!has_speed) {
|
||||
speed = 0;
|
||||
@@ -3019,6 +3024,29 @@ static void blockdev_mirror_common(const char *job_id, BlockDriverState *bs,
|
||||
@@ -3001,6 +3005,29 @@ static void blockdev_mirror_common(const char *job_id, BlockDriverState *bs,
|
||||
sync = MIRROR_SYNC_MODE_FULL;
|
||||
}
|
||||
|
||||
+ if (has_bitmap) {
|
||||
+ if (bitmap) {
|
||||
+ if (granularity) {
|
||||
+ error_setg(errp, "Granularity and bitmap cannot both be set");
|
||||
+ return;
|
||||
@ -301,53 +302,53 @@ index 3f1dec6242..2ee30323cb 100644
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
if (!has_replaces) {
|
||||
if (!replaces) {
|
||||
/* We want to mirror from @bs, but keep implicit filters on top */
|
||||
unfiltered_bs = bdrv_skip_implicit_filters(bs);
|
||||
@@ -3065,8 +3093,8 @@ static void blockdev_mirror_common(const char *job_id, BlockDriverState *bs,
|
||||
@@ -3046,8 +3073,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,
|
||||
- has_replaces ? replaces : NULL, job_flags,
|
||||
- replaces, job_flags,
|
||||
- speed, granularity, buf_size, sync, backing_mode, zero_target,
|
||||
+ has_replaces ? replaces : NULL, job_flags, speed, granularity,
|
||||
+ buf_size, sync, bitmap, bitmap_mode, backing_mode, zero_target,
|
||||
+ replaces, job_flags, speed, granularity, buf_size, sync,
|
||||
+ bitmap, bitmap_mode, backing_mode, zero_target,
|
||||
on_source_error, on_target_error, unmap, filter_node_name,
|
||||
copy_mode, errp);
|
||||
}
|
||||
@@ -3211,6 +3239,8 @@ void qmp_drive_mirror(DriveMirror *arg, Error **errp)
|
||||
@@ -3192,6 +3219,8 @@ void qmp_drive_mirror(DriveMirror *arg, Error **errp)
|
||||
|
||||
blockdev_mirror_common(arg->has_job_id ? arg->job_id : NULL, bs, target_bs,
|
||||
arg->has_replaces, arg->replaces, arg->sync,
|
||||
+ arg->has_bitmap, arg->bitmap,
|
||||
blockdev_mirror_common(arg->job_id, bs, target_bs,
|
||||
arg->replaces, arg->sync,
|
||||
+ arg->bitmap,
|
||||
+ arg->has_bitmap_mode, arg->bitmap_mode,
|
||||
backing_mode, zero_target,
|
||||
arg->has_speed, arg->speed,
|
||||
arg->has_granularity, arg->granularity,
|
||||
@@ -3232,6 +3262,8 @@ void qmp_blockdev_mirror(bool has_job_id, const char *job_id,
|
||||
@@ -3213,6 +3242,8 @@ void qmp_blockdev_mirror(const char *job_id,
|
||||
const char *device, const char *target,
|
||||
bool has_replaces, const char *replaces,
|
||||
const char *replaces,
|
||||
MirrorSyncMode sync,
|
||||
+ bool has_bitmap, const char *bitmap,
|
||||
+ const char *bitmap,
|
||||
+ bool has_bitmap_mode, BitmapSyncMode bitmap_mode,
|
||||
bool has_speed, int64_t speed,
|
||||
bool has_granularity, uint32_t granularity,
|
||||
bool has_buf_size, int64_t buf_size,
|
||||
@@ -3281,7 +3313,8 @@ void qmp_blockdev_mirror(bool has_job_id, const char *job_id,
|
||||
@@ -3261,7 +3292,8 @@ void qmp_blockdev_mirror(const char *job_id,
|
||||
}
|
||||
|
||||
blockdev_mirror_common(has_job_id ? job_id : NULL, bs, target_bs,
|
||||
- has_replaces, replaces, sync, backing_mode,
|
||||
+ has_replaces, replaces, sync, has_bitmap,
|
||||
blockdev_mirror_common(job_id, bs, target_bs,
|
||||
- replaces, sync, backing_mode,
|
||||
+ replaces, sync,
|
||||
+ bitmap, has_bitmap_mode, bitmap_mode, backing_mode,
|
||||
zero_target, has_speed, speed,
|
||||
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 b49f4eb35b..9d744db618 100644
|
||||
index 902406eb99..d559be928c 100644
|
||||
--- a/include/block/block_int-global-state.h
|
||||
+++ b/include/block/block_int-global-state.h
|
||||
@@ -149,7 +149,9 @@ void mirror_start(const char *job_id, BlockDriverState *bs,
|
||||
@@ -152,7 +152,9 @@ 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,
|
||||
@ -359,10 +360,10 @@ index b49f4eb35b..9d744db618 100644
|
||||
BlockdevOnError on_source_error,
|
||||
BlockdevOnError on_target_error,
|
||||
diff --git a/qapi/block-core.json b/qapi/block-core.json
|
||||
index 95ac4fa634..7daaf545be 100644
|
||||
index c05ad0c07e..3c945c1f93 100644
|
||||
--- a/qapi/block-core.json
|
||||
+++ b/qapi/block-core.json
|
||||
@@ -2000,10 +2000,19 @@
|
||||
@@ -2095,10 +2095,19 @@
|
||||
# (all the disk, only the sectors allocated in the topmost image, or
|
||||
# only new I/O).
|
||||
#
|
||||
@ -383,7 +384,7 @@ index 95ac4fa634..7daaf545be 100644
|
||||
#
|
||||
# @buf-size: maximum amount of data in flight from source to
|
||||
# target (since 1.4).
|
||||
@@ -2043,7 +2052,9 @@
|
||||
@@ -2138,7 +2147,9 @@
|
||||
{ 'struct': 'DriveMirror',
|
||||
'data': { '*job-id': 'str', 'device': 'str', 'target': 'str',
|
||||
'*format': 'str', '*node-name': 'str', '*replaces': 'str',
|
||||
@ -394,7 +395,7 @@ index 95ac4fa634..7daaf545be 100644
|
||||
'*speed': 'int', '*granularity': 'uint32',
|
||||
'*buf-size': 'int', '*on-source-error': 'BlockdevOnError',
|
||||
'*on-target-error': 'BlockdevOnError',
|
||||
@@ -2322,10 +2333,19 @@
|
||||
@@ -2417,10 +2428,19 @@
|
||||
# (all the disk, only the sectors allocated in the topmost image, or
|
||||
# only new I/O).
|
||||
#
|
||||
@ -415,7 +416,7 @@ index 95ac4fa634..7daaf545be 100644
|
||||
#
|
||||
# @buf-size: maximum amount of data in flight from source to
|
||||
# target
|
||||
@@ -2375,7 +2395,8 @@
|
||||
@@ -2470,7 +2490,8 @@
|
||||
{ 'command': 'blockdev-mirror',
|
||||
'data': { '*job-id': 'str', 'device': 'str', 'target': 'str',
|
||||
'*replaces': 'str',
|
||||
@ -426,10 +427,10 @@ index 95ac4fa634..7daaf545be 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 8ca5adec5e..dae80e5a5f 100644
|
||||
index 3a5e1eb2c4..c1ecc49073 100644
|
||||
--- a/tests/unit/test-block-iothread.c
|
||||
+++ b/tests/unit/test-block-iothread.c
|
||||
@@ -755,8 +755,8 @@ static void test_propagate_mirror(void)
|
||||
@@ -757,8 +757,8 @@ static void test_propagate_mirror(void)
|
||||
|
||||
/* Start a mirror job */
|
||||
mirror_start("job0", src, target, NULL, JOB_DEFAULT, 0, 0, 0,
|
||||
|
@ -24,10 +24,10 @@ Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
|
||||
1 file changed, 18 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/block/mirror.c b/block/mirror.c
|
||||
index 8ead5f77a0..35c1b8f25d 100644
|
||||
index 9099c75992..e2ff42067b 100644
|
||||
--- a/block/mirror.c
|
||||
+++ b/block/mirror.c
|
||||
@@ -676,8 +676,6 @@ static int mirror_exit_common(Job *job)
|
||||
@@ -680,8 +680,6 @@ static int mirror_exit_common(Job *job)
|
||||
bdrv_unfreeze_backing_chain(mirror_top_bs, target_bs);
|
||||
}
|
||||
|
||||
@ -36,7 +36,7 @@ index 8ead5f77a0..35c1b8f25d 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);
|
||||
@@ -778,6 +776,18 @@ static int mirror_exit_common(Job *job)
|
||||
@@ -782,6 +780,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);
|
||||
|
||||
@ -55,7 +55,7 @@ index 8ead5f77a0..35c1b8f25d 100644
|
||||
bs_opaque->job = NULL;
|
||||
|
||||
bdrv_drained_end(src);
|
||||
@@ -1668,10 +1678,6 @@ static BlockJob *mirror_start_job(
|
||||
@@ -1688,10 +1698,6 @@ static BlockJob *mirror_start_job(
|
||||
" sync mode",
|
||||
MirrorSyncMode_str(sync_mode));
|
||||
return NULL;
|
||||
@ -66,7 +66,7 @@ index 8ead5f77a0..35c1b8f25d 100644
|
||||
}
|
||||
} else if (bitmap) {
|
||||
error_setg(errp,
|
||||
@@ -1688,6 +1694,12 @@ static BlockJob *mirror_start_job(
|
||||
@@ -1708,6 +1714,12 @@ static BlockJob *mirror_start_job(
|
||||
return NULL;
|
||||
}
|
||||
granularity = bdrv_dirty_bitmap_granularity(bitmap);
|
||||
|
@ -16,10 +16,10 @@ Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
|
||||
1 file changed, 3 insertions(+)
|
||||
|
||||
diff --git a/blockdev.c b/blockdev.c
|
||||
index 2ee30323cb..dd1c2cdef7 100644
|
||||
index 6c34d9bb3a..24a76b451d 100644
|
||||
--- a/blockdev.c
|
||||
+++ b/blockdev.c
|
||||
@@ -3045,6 +3045,9 @@ static void blockdev_mirror_common(const char *job_id, BlockDriverState *bs,
|
||||
@@ -3026,6 +3026,9 @@ static void blockdev_mirror_common(const char *job_id, BlockDriverState *bs,
|
||||
if (bdrv_dirty_bitmap_check(bitmap, BDRV_BITMAP_ALLOW_RO, errp)) {
|
||||
return;
|
||||
}
|
||||
@ -28,4 +28,4 @@ index 2ee30323cb..dd1c2cdef7 100644
|
||||
+ return;
|
||||
}
|
||||
|
||||
if (!has_replaces) {
|
||||
if (!replaces) {
|
||||
|
@ -16,10 +16,10 @@ Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
|
||||
1 file changed, 4 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/block/mirror.c b/block/mirror.c
|
||||
index 35c1b8f25d..4969c6833c 100644
|
||||
index e2ff42067b..f42953837b 100644
|
||||
--- a/block/mirror.c
|
||||
+++ b/block/mirror.c
|
||||
@@ -782,8 +782,8 @@ static int mirror_exit_common(Job *job)
|
||||
@@ -786,8 +786,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 35c1b8f25d..4969c6833c 100644
|
||||
}
|
||||
}
|
||||
bdrv_release_dirty_bitmap(s->dirty_bitmap);
|
||||
@@ -1862,11 +1862,8 @@ static BlockJob *mirror_start_job(
|
||||
@@ -1881,11 +1881,8 @@ static BlockJob *mirror_start_job(
|
||||
}
|
||||
|
||||
if (s->sync_mode == MIRROR_SYNC_MODE_BITMAP) {
|
||||
|
@ -12,6 +12,8 @@ uniform w.r.t. backup block jobs.
|
||||
|
||||
Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
|
||||
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
|
||||
[FE: rebase for 8.0]
|
||||
Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
|
||||
---
|
||||
block/mirror.c | 28 +++------------
|
||||
blockdev.c | 29 +++++++++++++++
|
||||
@ -19,10 +21,10 @@ Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
|
||||
3 files changed, 70 insertions(+), 59 deletions(-)
|
||||
|
||||
diff --git a/block/mirror.c b/block/mirror.c
|
||||
index 4969c6833c..cf85ae1074 100644
|
||||
index f42953837b..8f79efaa87 100644
|
||||
--- a/block/mirror.c
|
||||
+++ b/block/mirror.c
|
||||
@@ -1668,31 +1668,13 @@ static BlockJob *mirror_start_job(
|
||||
@@ -1688,31 +1688,13 @@ static BlockJob *mirror_start_job(
|
||||
uint64_t target_perms, target_shared_perms;
|
||||
int ret;
|
||||
|
||||
@ -60,17 +62,17 @@ index 4969c6833c..cf85ae1074 100644
|
||||
|
||||
if (bitmap_mode != BITMAP_SYNC_MODE_NEVER) {
|
||||
diff --git a/blockdev.c b/blockdev.c
|
||||
index dd1c2cdef7..756e980889 100644
|
||||
index 24a76b451d..3917af7d02 100644
|
||||
--- a/blockdev.c
|
||||
+++ b/blockdev.c
|
||||
@@ -3024,7 +3024,36 @@ static void blockdev_mirror_common(const char *job_id, BlockDriverState *bs,
|
||||
@@ -3005,7 +3005,36 @@ static void blockdev_mirror_common(const char *job_id, BlockDriverState *bs,
|
||||
sync = MIRROR_SYNC_MODE_FULL;
|
||||
}
|
||||
|
||||
+ if ((sync == MIRROR_SYNC_MODE_BITMAP) ||
|
||||
+ (sync == MIRROR_SYNC_MODE_INCREMENTAL)) {
|
||||
+ /* done before desugaring 'incremental' to print the right message */
|
||||
+ if (!has_bitmap) {
|
||||
+ if (!bitmap) {
|
||||
+ error_setg(errp, "Must provide a valid bitmap name for "
|
||||
+ "'%s' sync mode", MirrorSyncMode_str(sync));
|
||||
+ return;
|
||||
@ -91,7 +93,7 @@ index dd1c2cdef7..756e980889 100644
|
||||
+ bitmap_mode = BITMAP_SYNC_MODE_ON_SUCCESS;
|
||||
+ }
|
||||
+
|
||||
if (has_bitmap) {
|
||||
if (bitmap) {
|
||||
+ if (sync != MIRROR_SYNC_MODE_BITMAP) {
|
||||
+ error_setg(errp, "Sync mode '%s' not supported with bitmap.",
|
||||
+ MirrorSyncMode_str(sync));
|
||||
|
@ -48,7 +48,7 @@ Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
|
||||
6 files changed, 59 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/include/monitor/monitor.h b/include/monitor/monitor.h
|
||||
index 737e750670..38804b8595 100644
|
||||
index 033390f699..ad35d4fea8 100644
|
||||
--- a/include/monitor/monitor.h
|
||||
+++ b/include/monitor/monitor.h
|
||||
@@ -16,6 +16,7 @@ extern QemuOptsList qemu_mon_opts;
|
||||
@ -60,7 +60,7 @@ index 737e750670..38804b8595 100644
|
||||
void monitor_init_globals(void);
|
||||
void monitor_init_globals_core(void);
|
||||
diff --git a/monitor/monitor-internal.h b/monitor/monitor-internal.h
|
||||
index a2cdbbf646..b531bd50e7 100644
|
||||
index 53e3808054..a19f8cbc2b 100644
|
||||
--- a/monitor/monitor-internal.h
|
||||
+++ b/monitor/monitor-internal.h
|
||||
@@ -152,6 +152,13 @@ typedef struct {
|
||||
@ -78,7 +78,7 @@ index a2cdbbf646..b531bd50e7 100644
|
||||
|
||||
/**
|
||||
diff --git a/monitor/monitor.c b/monitor/monitor.c
|
||||
index 86949024f6..c306cadcf4 100644
|
||||
index 8dc96f6af9..f3c38cb714 100644
|
||||
--- a/monitor/monitor.c
|
||||
+++ b/monitor/monitor.c
|
||||
@@ -135,6 +135,21 @@ bool monitor_cur_is_qmp(void)
|
||||
|
@ -1,42 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Fiona Ebner <f.ebner@proxmox.com>
|
||||
Date: Fri, 28 Oct 2022 10:09:46 +0200
|
||||
Subject: [PATCH] init: daemonize: defuse PID file resolve error
|
||||
|
||||
When proxmox-file-restore invokes QEMU, the PID file is a (temporary)
|
||||
file that's already unlinked, so resolving the absolute path here
|
||||
failed.
|
||||
|
||||
It should not be a critical error when the PID file unlink handler
|
||||
can't be registered, because the path can't be resolved for whatever
|
||||
reason. If the file is already gone from QEMU's perspective (i.e.
|
||||
errno is ENOENT), silently ignore the error. Otherwise, print a
|
||||
warning.
|
||||
|
||||
Reported-by: Dominik Csapak <d.csapak@proxmox.com>
|
||||
Suggested-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
|
||||
Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
|
||||
---
|
||||
softmmu/vl.c | 9 +++++----
|
||||
1 file changed, 5 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/softmmu/vl.c b/softmmu/vl.c
|
||||
index 5115221efe..5f7f6ca981 100644
|
||||
--- a/softmmu/vl.c
|
||||
+++ b/softmmu/vl.c
|
||||
@@ -2460,10 +2460,11 @@ static void qemu_maybe_daemonize(const char *pid_file)
|
||||
|
||||
pid_file_realpath = g_malloc0(PATH_MAX);
|
||||
if (!realpath(pid_file, pid_file_realpath)) {
|
||||
- error_report("cannot resolve PID file path: %s: %s",
|
||||
- pid_file, strerror(errno));
|
||||
- unlink(pid_file);
|
||||
- exit(1);
|
||||
+ if (errno != ENOENT) {
|
||||
+ warn_report("not removing PID file on exit: cannot resolve PID "
|
||||
+ "file path: %s: %s", pid_file, strerror(errno));
|
||||
+ }
|
||||
+ return;
|
||||
}
|
||||
|
||||
qemu_unlink_pidfile_notifier = (struct UnlinkPidfileNotifier) {
|
@ -38,7 +38,7 @@ Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
|
||||
3 files changed, 25 insertions(+)
|
||||
|
||||
diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h
|
||||
index 785dd5a56e..886f6bb79e 100644
|
||||
index bd50ad5ee1..7623703943 100644
|
||||
--- a/include/hw/qdev-core.h
|
||||
+++ b/include/hw/qdev-core.h
|
||||
@@ -162,6 +162,10 @@ struct NamedClockList {
|
||||
@ -63,7 +63,7 @@ index 785dd5a56e..886f6bb79e 100644
|
||||
|
||||
struct DeviceListener {
|
||||
diff --git a/softmmu/memory.c b/softmmu/memory.c
|
||||
index bc0be3f62c..7dcb3347aa 100644
|
||||
index b1a6cae6f5..e4d2268d32 100644
|
||||
--- a/softmmu/memory.c
|
||||
+++ b/softmmu/memory.c
|
||||
@@ -533,6 +533,7 @@ static MemTxResult access_with_adjusted_size(hwaddr addr,
|
@ -1,44 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Chenyi Qiang <chenyi.qiang@intel.com>
|
||||
Date: Fri, 16 Dec 2022 14:22:31 +0800
|
||||
Subject: [PATCH] virtio-mem: Fix the bitmap index of the section offset
|
||||
|
||||
vmem->bitmap indexes the memory region of the virtio-mem backend at a
|
||||
granularity of block_size. To calculate the index of target section offset,
|
||||
the block_size should be divided instead of the bitmap_size.
|
||||
|
||||
Fixes: 2044969f0b ("virtio-mem: Implement RamDiscardManager interface")
|
||||
Signed-off-by: Chenyi Qiang <chenyi.qiang@intel.com>
|
||||
Message-Id: <20221216062231.11181-1-chenyi.qiang@intel.com>
|
||||
Reviewed-by: David Hildenbrand <david@redhat.com>
|
||||
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
|
||||
Cc: qemu-stable@nongnu.org
|
||||
Signed-off-by: David Hildenbrand <david@redhat.com>
|
||||
(cherry-picked from commit b11cf32e07a2f7ff0d171b89497381a04c9d07e0)
|
||||
Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
|
||||
---
|
||||
hw/virtio/virtio-mem.c | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/hw/virtio/virtio-mem.c b/hw/virtio/virtio-mem.c
|
||||
index ed170def48..e19ee817fe 100644
|
||||
--- a/hw/virtio/virtio-mem.c
|
||||
+++ b/hw/virtio/virtio-mem.c
|
||||
@@ -235,7 +235,7 @@ static int virtio_mem_for_each_plugged_section(const VirtIOMEM *vmem,
|
||||
uint64_t offset, size;
|
||||
int ret = 0;
|
||||
|
||||
- first_bit = s->offset_within_region / vmem->bitmap_size;
|
||||
+ first_bit = s->offset_within_region / vmem->block_size;
|
||||
first_bit = find_next_bit(vmem->bitmap, vmem->bitmap_size, first_bit);
|
||||
while (first_bit < vmem->bitmap_size) {
|
||||
MemoryRegionSection tmp = *s;
|
||||
@@ -267,7 +267,7 @@ static int virtio_mem_for_each_unplugged_section(const VirtIOMEM *vmem,
|
||||
uint64_t offset, size;
|
||||
int ret = 0;
|
||||
|
||||
- first_bit = s->offset_within_region / vmem->bitmap_size;
|
||||
+ first_bit = s->offset_within_region / vmem->block_size;
|
||||
first_bit = find_next_zero_bit(vmem->bitmap, vmem->bitmap_size, first_bit);
|
||||
while (first_bit < vmem->bitmap_size) {
|
||||
MemoryRegionSection tmp = *s;
|
@ -55,10 +55,10 @@ Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
|
||||
1 file changed, 6 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/hw/ide/core.c b/hw/ide/core.c
|
||||
index 39afdc0006..b67c1885a8 100644
|
||||
index 45d14a25e9..08e1f0c3d7 100644
|
||||
--- a/hw/ide/core.c
|
||||
+++ b/hw/ide/core.c
|
||||
@@ -443,7 +443,7 @@ static void ide_trim_bh_cb(void *opaque)
|
||||
@@ -444,7 +444,7 @@ static void ide_trim_bh_cb(void *opaque)
|
||||
iocb->bh = NULL;
|
||||
qemu_aio_unref(iocb);
|
||||
|
||||
@ -67,7 +67,7 @@ index 39afdc0006..b67c1885a8 100644
|
||||
blk_dec_in_flight(blk);
|
||||
}
|
||||
|
||||
@@ -503,6 +503,8 @@ static void ide_issue_trim_cb(void *opaque, int ret)
|
||||
@@ -504,6 +504,8 @@ static void ide_issue_trim_cb(void *opaque, int ret)
|
||||
done:
|
||||
iocb->aiocb = NULL;
|
||||
if (iocb->bh) {
|
||||
@ -76,7 +76,7 @@ index 39afdc0006..b67c1885a8 100644
|
||||
replay_bh_schedule_event(iocb->bh);
|
||||
}
|
||||
}
|
||||
@@ -514,9 +516,6 @@ BlockAIOCB *ide_issue_trim(
|
||||
@@ -515,9 +517,6 @@ BlockAIOCB *ide_issue_trim(
|
||||
IDEState *s = opaque;
|
||||
TrimAIOCB *iocb;
|
||||
|
||||
@ -86,7 +86,7 @@ index 39afdc0006..b67c1885a8 100644
|
||||
iocb = blk_aio_get(&trim_aiocb_info, s->blk, cb, cb_opaque);
|
||||
iocb->s = s;
|
||||
iocb->bh = qemu_bh_new(ide_trim_bh_cb, iocb);
|
||||
@@ -739,8 +738,9 @@ void ide_cancel_dma_sync(IDEState *s)
|
||||
@@ -740,8 +739,9 @@ void ide_cancel_dma_sync(IDEState *s)
|
||||
*/
|
||||
if (s->bus->dma->aiocb) {
|
||||
trace_ide_cancel_dma_sync_remaining();
|
@ -1,36 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Chenyi Qiang <chenyi.qiang@intel.com>
|
||||
Date: Wed, 28 Dec 2022 17:03:12 +0800
|
||||
Subject: [PATCH] virtio-mem: Fix the iterator variable in a vmem->rdl_list
|
||||
loop
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
It should be the variable rdl2 to revert the already-notified listeners.
|
||||
|
||||
Fixes: 2044969f0b ("virtio-mem: Implement RamDiscardManager interface")
|
||||
Signed-off-by: Chenyi Qiang <chenyi.qiang@intel.com>
|
||||
Message-Id: <20221228090312.17276-1-chenyi.qiang@intel.com>
|
||||
Cc: qemu-stable@nongnu.org
|
||||
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
|
||||
Signed-off-by: David Hildenbrand <david@redhat.com>
|
||||
(cherry-picked from commit 29f1b328e3b767cba2661920a8470738469b9e36)
|
||||
Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
|
||||
---
|
||||
hw/virtio/virtio-mem.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/hw/virtio/virtio-mem.c b/hw/virtio/virtio-mem.c
|
||||
index e19ee817fe..56db586c89 100644
|
||||
--- a/hw/virtio/virtio-mem.c
|
||||
+++ b/hw/virtio/virtio-mem.c
|
||||
@@ -341,7 +341,7 @@ static int virtio_mem_notify_plug(VirtIOMEM *vmem, uint64_t offset,
|
||||
if (ret) {
|
||||
/* Notify all already-notified listeners. */
|
||||
QLIST_FOREACH(rdl2, &vmem->rdl_list, next) {
|
||||
- MemoryRegionSection tmp = *rdl->section;
|
||||
+ MemoryRegionSection tmp = *rdl2->section;
|
||||
|
||||
if (rdl2 == rdl) {
|
||||
break;
|
@ -10,10 +10,10 @@ Signed-off-by: Alexander Bulekov <alxndr@bu.edu>
|
||||
2 files changed, 4 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/include/exec/memory.h b/include/exec/memory.h
|
||||
index 91f8a2395a..d7268d9f39 100644
|
||||
index 15ade918ba..e6819e3c39 100644
|
||||
--- a/include/exec/memory.h
|
||||
+++ b/include/exec/memory.h
|
||||
@@ -765,6 +765,9 @@ struct MemoryRegion {
|
||||
@@ -791,6 +791,9 @@ struct MemoryRegion {
|
||||
unsigned ioeventfd_nb;
|
||||
MemoryRegionIoeventfd *ioeventfds;
|
||||
RamDiscardManager *rdm; /* Only for RAM */
|
||||
@ -24,7 +24,7 @@ index 91f8a2395a..d7268d9f39 100644
|
||||
|
||||
struct IOMMUMemoryRegion {
|
||||
diff --git a/softmmu/memory.c b/softmmu/memory.c
|
||||
index 7dcb3347aa..2b46714191 100644
|
||||
index e4d2268d32..d88acb204b 100644
|
||||
--- a/softmmu/memory.c
|
||||
+++ b/softmmu/memory.c
|
||||
@@ -544,7 +544,7 @@ static MemTxResult access_with_adjusted_size(hwaddr addr,
|
@ -1,141 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jason Wang <jasowang@redhat.com>
|
||||
Date: Fri, 16 Dec 2022 11:35:52 +0800
|
||||
Subject: [PATCH] vhost: fix vq dirty bitmap syncing when vIOMMU is enabled
|
||||
|
||||
When vIOMMU is enabled, the vq->used_phys is actually the IOVA not
|
||||
GPA. So we need to translate it to GPA before the syncing otherwise we
|
||||
may hit the following crash since IOVA could be out of the scope of
|
||||
the GPA log size. This could be noted when using virtio-IOMMU with
|
||||
vhost using 1G memory.
|
||||
|
||||
Fixes: c471ad0e9bd46 ("vhost_net: device IOTLB support")
|
||||
Cc: qemu-stable@nongnu.org
|
||||
Tested-by: Lei Yang <leiyang@redhat.com>
|
||||
Reported-by: Yalan Zhang <yalzhang@redhat.com>
|
||||
Signed-off-by: Jason Wang <jasowang@redhat.com>
|
||||
Message-Id: <20221216033552.77087-1-jasowang@redhat.com>
|
||||
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
|
||||
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
|
||||
(cherry-picked from commit 345cc1cbcbce2bab00abc2b88338d7d89c702d6b)
|
||||
Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
|
||||
---
|
||||
hw/virtio/vhost.c | 84 ++++++++++++++++++++++++++++++++++++-----------
|
||||
1 file changed, 64 insertions(+), 20 deletions(-)
|
||||
|
||||
diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c
|
||||
index 7fb008bc9e..fdcd1a8fdf 100644
|
||||
--- a/hw/virtio/vhost.c
|
||||
+++ b/hw/virtio/vhost.c
|
||||
@@ -20,6 +20,7 @@
|
||||
#include "qemu/range.h"
|
||||
#include "qemu/error-report.h"
|
||||
#include "qemu/memfd.h"
|
||||
+#include "qemu/log.h"
|
||||
#include "standard-headers/linux/vhost_types.h"
|
||||
#include "hw/virtio/virtio-bus.h"
|
||||
#include "hw/virtio/virtio-access.h"
|
||||
@@ -106,6 +107,24 @@ static void vhost_dev_sync_region(struct vhost_dev *dev,
|
||||
}
|
||||
}
|
||||
|
||||
+static bool vhost_dev_has_iommu(struct vhost_dev *dev)
|
||||
+{
|
||||
+ VirtIODevice *vdev = dev->vdev;
|
||||
+
|
||||
+ /*
|
||||
+ * For vhost, VIRTIO_F_IOMMU_PLATFORM means the backend support
|
||||
+ * incremental memory mapping API via IOTLB API. For platform that
|
||||
+ * does not have IOMMU, there's no need to enable this feature
|
||||
+ * which may cause unnecessary IOTLB miss/update transactions.
|
||||
+ */
|
||||
+ if (vdev) {
|
||||
+ return virtio_bus_device_iommu_enabled(vdev) &&
|
||||
+ virtio_host_has_feature(vdev, VIRTIO_F_IOMMU_PLATFORM);
|
||||
+ } else {
|
||||
+ return false;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
static int vhost_sync_dirty_bitmap(struct vhost_dev *dev,
|
||||
MemoryRegionSection *section,
|
||||
hwaddr first,
|
||||
@@ -137,8 +156,51 @@ static int vhost_sync_dirty_bitmap(struct vhost_dev *dev,
|
||||
continue;
|
||||
}
|
||||
|
||||
- vhost_dev_sync_region(dev, section, start_addr, end_addr, vq->used_phys,
|
||||
- range_get_last(vq->used_phys, vq->used_size));
|
||||
+ if (vhost_dev_has_iommu(dev)) {
|
||||
+ IOMMUTLBEntry iotlb;
|
||||
+ hwaddr used_phys = vq->used_phys, used_size = vq->used_size;
|
||||
+ hwaddr phys, s, offset;
|
||||
+
|
||||
+ while (used_size) {
|
||||
+ rcu_read_lock();
|
||||
+ iotlb = address_space_get_iotlb_entry(dev->vdev->dma_as,
|
||||
+ used_phys,
|
||||
+ true,
|
||||
+ MEMTXATTRS_UNSPECIFIED);
|
||||
+ rcu_read_unlock();
|
||||
+
|
||||
+ if (!iotlb.target_as) {
|
||||
+ qemu_log_mask(LOG_GUEST_ERROR, "translation "
|
||||
+ "failure for used_iova %"PRIx64"\n",
|
||||
+ used_phys);
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ offset = used_phys & iotlb.addr_mask;
|
||||
+ phys = iotlb.translated_addr + offset;
|
||||
+
|
||||
+ /*
|
||||
+ * Distance from start of used ring until last byte of
|
||||
+ * IOMMU page.
|
||||
+ */
|
||||
+ s = iotlb.addr_mask - offset;
|
||||
+ /*
|
||||
+ * Size of used ring, or of the part of it until end
|
||||
+ * of IOMMU page. To avoid zero result, do the adding
|
||||
+ * outside of MIN().
|
||||
+ */
|
||||
+ s = MIN(s, used_size - 1) + 1;
|
||||
+
|
||||
+ vhost_dev_sync_region(dev, section, start_addr, end_addr, phys,
|
||||
+ range_get_last(phys, s));
|
||||
+ used_size -= s;
|
||||
+ used_phys += s;
|
||||
+ }
|
||||
+ } else {
|
||||
+ vhost_dev_sync_region(dev, section, start_addr,
|
||||
+ end_addr, vq->used_phys,
|
||||
+ range_get_last(vq->used_phys, vq->used_size));
|
||||
+ }
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -306,24 +368,6 @@ static inline void vhost_dev_log_resize(struct vhost_dev *dev, uint64_t size)
|
||||
dev->log_size = size;
|
||||
}
|
||||
|
||||
-static bool vhost_dev_has_iommu(struct vhost_dev *dev)
|
||||
-{
|
||||
- VirtIODevice *vdev = dev->vdev;
|
||||
-
|
||||
- /*
|
||||
- * For vhost, VIRTIO_F_IOMMU_PLATFORM means the backend support
|
||||
- * incremental memory mapping API via IOTLB API. For platform that
|
||||
- * does not have IOMMU, there's no need to enable this feature
|
||||
- * which may cause unnecessary IOTLB miss/update transactions.
|
||||
- */
|
||||
- if (vdev) {
|
||||
- return virtio_bus_device_iommu_enabled(vdev) &&
|
||||
- virtio_host_has_feature(vdev, VIRTIO_F_IOMMU_PLATFORM);
|
||||
- } else {
|
||||
- return false;
|
||||
- }
|
||||
-}
|
||||
-
|
||||
static void *vhost_memory_map(struct vhost_dev *dev, hwaddr addr,
|
||||
hwaddr *plen, bool is_write)
|
||||
{
|
@ -15,7 +15,7 @@ Signed-off-by: Alexander Bulekov <alxndr@bu.edu>
|
||||
1 file changed, 6 insertions(+)
|
||||
|
||||
diff --git a/hw/scsi/lsi53c895a.c b/hw/scsi/lsi53c895a.c
|
||||
index 50979640c3..894b9311ac 100644
|
||||
index af93557a9a..db27872963 100644
|
||||
--- a/hw/scsi/lsi53c895a.c
|
||||
+++ b/hw/scsi/lsi53c895a.c
|
||||
@@ -2302,6 +2302,12 @@ static void lsi_scsi_realize(PCIDevice *dev, Error **errp)
|
@ -1,42 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
|
||||
Date: Mon, 9 Jan 2023 10:58:09 +0000
|
||||
Subject: [PATCH] virtio-rng-pci: fix migration compat for vectors
|
||||
|
||||
Fixup the migration compatibility for existing machine types
|
||||
so that they do not enable msi-x.
|
||||
|
||||
Symptom:
|
||||
|
||||
(qemu) qemu: get_pci_config_device: Bad config data: i=0x34 read: 84 device: 98 cmask: ff wmask: 0 w1cmask:0
|
||||
qemu: Failed to load PCIDevice:config
|
||||
qemu: Failed to load virtio-rng:virtio
|
||||
qemu: error while loading state for instance 0x0 of device '0000:00:03.0/virtio-rng'
|
||||
qemu: load of migration failed: Invalid argument
|
||||
|
||||
Note: This fix will break migration from 7.2->7.2-fixed with this patch
|
||||
|
||||
bz: https://bugzilla.redhat.com/show_bug.cgi?id=2155749
|
||||
Fixes: 9ea02e8f1 ("virtio-rng-pci: Allow setting nvectors, so we can use MSI-X")
|
||||
|
||||
Reviewed-by: Thomas Huth <thuth@redhat.com>
|
||||
Acked-by: David Daney <david.daney@fungible.com>
|
||||
Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
|
||||
(picked-up from https://lists.nongnu.org/archive/html/qemu-devel/2023-01/msg01319.html)
|
||||
Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
|
||||
---
|
||||
hw/core/machine.c | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/hw/core/machine.c b/hw/core/machine.c
|
||||
index 8d34caa31d..77a0a131d1 100644
|
||||
--- a/hw/core/machine.c
|
||||
+++ b/hw/core/machine.c
|
||||
@@ -42,6 +42,7 @@
|
||||
|
||||
GlobalProperty hw_compat_7_1[] = {
|
||||
{ "virtio-device", "queue_reset", "false" },
|
||||
+ { "virtio-rng-pci", "vectors", "0" },
|
||||
};
|
||||
const size_t hw_compat_7_1_len = G_N_ELEMENTS(hw_compat_7_1);
|
||||
|
@ -1,36 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Stefan Hajnoczi <stefanha@redhat.com>
|
||||
Date: Thu, 26 Jan 2023 15:13:58 -0500
|
||||
Subject: [PATCH] block: fix detect-zeroes= with BDRV_REQ_REGISTERED_BUF
|
||||
|
||||
When a write request is converted into a write zeroes request by the
|
||||
detect-zeroes= feature, it is no longer associated with an I/O buffer.
|
||||
The BDRV_REQ_REGISTERED_BUF flag doesn't make sense without an I/O
|
||||
buffer and must be cleared because bdrv_co_do_pwrite_zeroes() fails with
|
||||
-EINVAL when it's set.
|
||||
|
||||
Fiona Ebner <f.ebner@proxmox.com> bisected and diagnosed this QEMU 7.2
|
||||
regression where writes containing zeroes to a blockdev with
|
||||
discard=unmap,detect-zeroes=unmap fail.
|
||||
|
||||
Buglink: https://gitlab.com/qemu-project/qemu/-/issues/1404
|
||||
Fixes: e8b6535533be ("block: add BDRV_REQ_REGISTERED_BUF request flag")
|
||||
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
|
||||
---
|
||||
block/io.c | 3 +++
|
||||
1 file changed, 3 insertions(+)
|
||||
|
||||
diff --git a/block/io.c b/block/io.c
|
||||
index b9424024f9..bbaa0d1b2d 100644
|
||||
--- a/block/io.c
|
||||
+++ b/block/io.c
|
||||
@@ -2087,6 +2087,9 @@ static int coroutine_fn bdrv_aligned_pwritev(BdrvChild *child,
|
||||
if (bs->detect_zeroes == BLOCKDEV_DETECT_ZEROES_OPTIONS_UNMAP) {
|
||||
flags |= BDRV_REQ_MAY_UNMAP;
|
||||
}
|
||||
+
|
||||
+ /* Can't use optimization hint with bufferless zero write */
|
||||
+ flags &= ~BDRV_REQ_REGISTERED_BUF;
|
||||
}
|
||||
|
||||
if (ret < 0) {
|
@ -1,32 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Paolo Bonzini <pbonzini@redhat.com>
|
||||
Date: Tue, 10 Jan 2023 17:36:33 +0100
|
||||
Subject: [PATCH] block/iscsi: fix double-free on BUSY or similar statuses
|
||||
|
||||
Commit 8c460269aa77 ("iscsi: base all handling of check condition on
|
||||
scsi_sense_to_errno", 2019-07-15) removed a "goto out" so that the
|
||||
same coroutine is re-entered twice; once from iscsi_co_generic_cb,
|
||||
once from the timer callback iscsi_retry_timer_expired. This can
|
||||
cause a crash.
|
||||
|
||||
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1378
|
||||
Reported-by: Grzegorz Zdanowski <https://gitlab.com/kiler129>
|
||||
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
||||
(cherry-picked from commit 5080152e2ef6cde7aa692e29880c62bd54acb750)
|
||||
Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
|
||||
---
|
||||
block/iscsi.c | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/block/iscsi.c b/block/iscsi.c
|
||||
index 3ed4a50c0d..89cd032c3a 100644
|
||||
--- a/block/iscsi.c
|
||||
+++ b/block/iscsi.c
|
||||
@@ -268,6 +268,7 @@ iscsi_co_generic_cb(struct iscsi_context *iscsi, int status,
|
||||
timer_mod(&iTask->retry_timer,
|
||||
qemu_clock_get_ms(QEMU_CLOCK_REALTIME) + retry_time);
|
||||
iTask->do_retry = 1;
|
||||
+ return;
|
||||
} else if (status == SCSI_STATUS_CHECK_CONDITION) {
|
||||
int error = iscsi_translate_sense(&task->sense);
|
||||
if (error == EAGAIN) {
|
@ -1,67 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Klaus Jensen <k.jensen@samsung.com>
|
||||
Date: Wed, 8 Mar 2023 19:57:12 +0300
|
||||
Subject: [PATCH] hw/nvme: fix missing endian conversions for doorbell buffers
|
||||
|
||||
The eventidx and doorbell value are not handling endianness correctly.
|
||||
Fix this.
|
||||
|
||||
Fixes: 3f7fe8de3d49 ("hw/nvme: Implement shadow doorbell buffer support")
|
||||
Cc: qemu-stable@nongnu.org
|
||||
Reported-by: Guenter Roeck <linux@roeck-us.net>
|
||||
Reviewed-by: Keith Busch <kbusch@kernel.org>
|
||||
Signed-off-by: Klaus Jensen <k.jensen@samsung.com>
|
||||
(cherry picked from commit 2fda0726e5149e032acfa5fe442db56cd6433c4c)
|
||||
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
|
||||
Conflicts: hw/nvme/ctrl.c
|
||||
(picked up from qemu-stable mailing list)
|
||||
Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
|
||||
---
|
||||
hw/nvme/ctrl.c | 22 ++++++++++++++++------
|
||||
1 file changed, 16 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/hw/nvme/ctrl.c b/hw/nvme/ctrl.c
|
||||
index e54276dc1d..98d8e34109 100644
|
||||
--- a/hw/nvme/ctrl.c
|
||||
+++ b/hw/nvme/ctrl.c
|
||||
@@ -1333,8 +1333,12 @@ static inline void nvme_blk_write(BlockBackend *blk, int64_t offset,
|
||||
|
||||
static void nvme_update_cq_head(NvmeCQueue *cq)
|
||||
{
|
||||
- pci_dma_read(&cq->ctrl->parent_obj, cq->db_addr, &cq->head,
|
||||
- sizeof(cq->head));
|
||||
+ uint32_t v;
|
||||
+
|
||||
+ pci_dma_read(&cq->ctrl->parent_obj, cq->db_addr, &v, sizeof(v));
|
||||
+
|
||||
+ cq->head = le32_to_cpu(v);
|
||||
+
|
||||
trace_pci_nvme_shadow_doorbell_cq(cq->cqid, cq->head);
|
||||
}
|
||||
|
||||
@@ -6141,15 +6145,21 @@ static uint16_t nvme_admin_cmd(NvmeCtrl *n, NvmeRequest *req)
|
||||
|
||||
static void nvme_update_sq_eventidx(const NvmeSQueue *sq)
|
||||
{
|
||||
- pci_dma_write(&sq->ctrl->parent_obj, sq->ei_addr, &sq->tail,
|
||||
- sizeof(sq->tail));
|
||||
+ uint32_t v = cpu_to_le32(sq->tail);
|
||||
+
|
||||
+ pci_dma_write(&sq->ctrl->parent_obj, sq->ei_addr, &v, sizeof(v));
|
||||
+
|
||||
trace_pci_nvme_eventidx_sq(sq->sqid, sq->tail);
|
||||
}
|
||||
|
||||
static void nvme_update_sq_tail(NvmeSQueue *sq)
|
||||
{
|
||||
- pci_dma_read(&sq->ctrl->parent_obj, sq->db_addr, &sq->tail,
|
||||
- sizeof(sq->tail));
|
||||
+ uint32_t v;
|
||||
+
|
||||
+ pci_dma_read(&sq->ctrl->parent_obj, sq->db_addr, &v, sizeof(v));
|
||||
+
|
||||
+ sq->tail = le32_to_cpu(v);
|
||||
+
|
||||
trace_pci_nvme_shadow_doorbell_sq(sq->sqid, sq->tail);
|
||||
}
|
||||
|
@ -1,50 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Julia Suvorova <jusual@redhat.com>
|
||||
Date: Thu, 23 Feb 2023 13:57:47 +0100
|
||||
Subject: [PATCH] hw/smbios: fix field corruption in type 4 table
|
||||
|
||||
Since table type 4 of SMBIOS version 2.6 is shorter than 3.0, the
|
||||
strings which follow immediately after the struct fields have been
|
||||
overwritten by unconditional filling of later fields such as core_count2.
|
||||
Make these fields dependent on the SMBIOS version.
|
||||
|
||||
Fixes: 05e27d74c7 ("hw/smbios: add core_count2 to smbios table type 4")
|
||||
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2169904
|
||||
|
||||
Signed-off-by: Julia Suvorova <jusual@redhat.com>
|
||||
Message-Id: <20230223125747.254914-1-jusual@redhat.com>
|
||||
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
|
||||
Reviewed-by: Ani Sinha <ani@anisinha.ca>
|
||||
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
|
||||
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
|
||||
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
|
||||
(cherry-picked from commit 60d09b8dc7dd4256d664ad680795cb1327805b2b)
|
||||
Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
|
||||
---
|
||||
hw/smbios/smbios.c | 8 +++++---
|
||||
1 file changed, 5 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/hw/smbios/smbios.c b/hw/smbios/smbios.c
|
||||
index b4243de735..66a020999b 100644
|
||||
--- a/hw/smbios/smbios.c
|
||||
+++ b/hw/smbios/smbios.c
|
||||
@@ -749,14 +749,16 @@ static void smbios_build_type_4_table(MachineState *ms, unsigned instance)
|
||||
t->core_count = (ms->smp.cores > 255) ? 0xFF : ms->smp.cores;
|
||||
t->core_enabled = t->core_count;
|
||||
|
||||
- t->core_count2 = t->core_enabled2 = cpu_to_le16(ms->smp.cores);
|
||||
-
|
||||
t->thread_count = (ms->smp.threads > 255) ? 0xFF : ms->smp.threads;
|
||||
- t->thread_count2 = cpu_to_le16(ms->smp.threads);
|
||||
|
||||
t->processor_characteristics = cpu_to_le16(0x02); /* Unknown */
|
||||
t->processor_family2 = cpu_to_le16(0x01); /* Other */
|
||||
|
||||
+ if (tbl_len == SMBIOS_TYPE_4_LEN_V30) {
|
||||
+ t->core_count2 = t->core_enabled2 = cpu_to_le16(ms->smp.cores);
|
||||
+ t->thread_count2 = cpu_to_le16(ms->smp.threads);
|
||||
+ }
|
||||
+
|
||||
SMBIOS_BUILD_TABLE_POST;
|
||||
smbios_type4_count++;
|
||||
}
|
@ -1,35 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
|
||||
Date: Tue, 7 Feb 2023 17:49:44 +0000
|
||||
Subject: [PATCH] virtio-rng-pci: fix transitional migration compat for vectors
|
||||
|
||||
In bad9c5a516 ("virtio-rng-pci: fix migration compat for vectors") I
|
||||
fixed the virtio-rng-pci migration compatibility, but it was discovered
|
||||
that we also need to fix the other aliases of the device for the
|
||||
transitional cases.
|
||||
|
||||
Fixes: 9ea02e8f1 ('virtio-rng-pci: Allow setting nvectors, so we can use MSI-X')
|
||||
bz: https://bugzilla.redhat.com/show_bug.cgi?id=2162569
|
||||
Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
|
||||
Message-Id: <20230207174944.138255-1-dgilbert@redhat.com>
|
||||
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
|
||||
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
|
||||
(cherry-picked from commit 62bdb8871512076841f4464f7e26efdc7783f78d)
|
||||
Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
|
||||
---
|
||||
hw/core/machine.c | 2 ++
|
||||
1 file changed, 2 insertions(+)
|
||||
|
||||
diff --git a/hw/core/machine.c b/hw/core/machine.c
|
||||
index cd84579591..4297315984 100644
|
||||
--- a/hw/core/machine.c
|
||||
+++ b/hw/core/machine.c
|
||||
@@ -43,6 +43,8 @@
|
||||
GlobalProperty hw_compat_7_1[] = {
|
||||
{ "virtio-device", "queue_reset", "false" },
|
||||
{ "virtio-rng-pci", "vectors", "0" },
|
||||
+ { "virtio-rng-pci-transitional", "vectors", "0" },
|
||||
+ { "virtio-rng-pci-non-transitional", "vectors", "0" },
|
||||
};
|
||||
const size_t hw_compat_7_1_len = G_N_ELEMENTS(hw_compat_7_1);
|
||||
|
@ -1,80 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Akihiko Odaki <akihiko.odaki@daynix.com>
|
||||
Date: Tue, 31 Jan 2023 12:00:37 +0900
|
||||
Subject: [PATCH] hw/timer/hpet: Fix expiration time overflow
|
||||
|
||||
The expiration time provided for timer_mod() can overflow if a
|
||||
ridiculously large value is set to the comparator register. The
|
||||
resulting value can represent a past time after rounded, forcing the
|
||||
timer to fire immediately. If the timer is configured as periodic, it
|
||||
will rearm the timer again, and form an endless loop.
|
||||
|
||||
Check if the expiration value will overflow, and if it will, stop the
|
||||
timer instead of rearming the timer with the overflowed time.
|
||||
|
||||
This bug was found by Alexander Bulekov when fuzzing igb, a new
|
||||
network device emulation:
|
||||
https://patchew.org/QEMU/20230129053316.1071513-1-alxndr@bu.edu/
|
||||
|
||||
The fixed test case is:
|
||||
fuzz/crash_2d7036941dcda1ad4380bb8a9174ed0c949bcefd
|
||||
|
||||
Fixes: 16b29ae180 ("Add HPET emulation to qemu (Beth Kon)")
|
||||
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
|
||||
Acked-by: Michael S. Tsirkin <mst@redhat.com>
|
||||
Message-Id: <20230131030037.18856-1-akihiko.odaki@daynix.com>
|
||||
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
|
||||
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
|
||||
(cherry-picked from commit 37d2bcbc2a4e9c2e9061bec72a32c7e49b9f81ec)
|
||||
Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
|
||||
---
|
||||
hw/timer/hpet.c | 19 +++++++++++++------
|
||||
1 file changed, 13 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/hw/timer/hpet.c b/hw/timer/hpet.c
|
||||
index 9520471be2..5f88ffdef8 100644
|
||||
--- a/hw/timer/hpet.c
|
||||
+++ b/hw/timer/hpet.c
|
||||
@@ -352,6 +352,16 @@ static const VMStateDescription vmstate_hpet = {
|
||||
}
|
||||
};
|
||||
|
||||
+static void hpet_arm(HPETTimer *t, uint64_t ticks)
|
||||
+{
|
||||
+ if (ticks < ns_to_ticks(INT64_MAX / 2)) {
|
||||
+ timer_mod(t->qemu_timer,
|
||||
+ qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + ticks_to_ns(ticks));
|
||||
+ } else {
|
||||
+ timer_del(t->qemu_timer);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
/*
|
||||
* timer expiration callback
|
||||
*/
|
||||
@@ -374,13 +384,11 @@ static void hpet_timer(void *opaque)
|
||||
}
|
||||
}
|
||||
diff = hpet_calculate_diff(t, cur_tick);
|
||||
- timer_mod(t->qemu_timer,
|
||||
- qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + (int64_t)ticks_to_ns(diff));
|
||||
+ hpet_arm(t, diff);
|
||||
} else if (t->config & HPET_TN_32BIT && !timer_is_periodic(t)) {
|
||||
if (t->wrap_flag) {
|
||||
diff = hpet_calculate_diff(t, cur_tick);
|
||||
- timer_mod(t->qemu_timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
|
||||
- (int64_t)ticks_to_ns(diff));
|
||||
+ hpet_arm(t, diff);
|
||||
t->wrap_flag = 0;
|
||||
}
|
||||
}
|
||||
@@ -407,8 +415,7 @@ static void hpet_set_timer(HPETTimer *t)
|
||||
t->wrap_flag = 1;
|
||||
}
|
||||
}
|
||||
- timer_mod(t->qemu_timer,
|
||||
- qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + (int64_t)ticks_to_ns(diff));
|
||||
+ hpet_arm(t, diff);
|
||||
}
|
||||
|
||||
static void hpet_del_timer(HPETTimer *t)
|
@ -1,71 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= <eperezma@redhat.com>
|
||||
Date: Thu, 9 Feb 2023 18:00:04 +0100
|
||||
Subject: [PATCH] vdpa: stop all svq on device deletion
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Not stopping them leave the device in a bad state when virtio-net
|
||||
fronted device is unplugged with device_del monitor command.
|
||||
|
||||
This is not triggable in regular poweroff or qemu forces shutdown
|
||||
because cleanup is called right after vhost_vdpa_dev_start(false). But
|
||||
devices hot unplug does not call vdpa device cleanups. This lead to all
|
||||
the vhost_vdpa devices without stop the SVQ but the last.
|
||||
|
||||
Fix it and clean the code, making it symmetric with
|
||||
vhost_vdpa_svqs_start.
|
||||
|
||||
Fixes: dff4426fa656 ("vhost: Add Shadow VirtQueue kick forwarding capabilities")
|
||||
Reported-by: Lei Yang <leiyang@redhat.com>
|
||||
Signed-off-by: Eugenio Pérez <eperezma@redhat.com>
|
||||
Message-Id: <20230209170004.899472-1-eperezma@redhat.com>
|
||||
Tested-by: Laurent Vivier <lvivier@redhat.com>
|
||||
Acked-by: Jason Wang <jasowang@redhat.com>
|
||||
(cherry-picked from commit 2e1a9de96b487cf818a22d681cad8d3f5d18dcca)
|
||||
Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
|
||||
---
|
||||
hw/virtio/vhost-vdpa.c | 17 ++---------------
|
||||
1 file changed, 2 insertions(+), 15 deletions(-)
|
||||
|
||||
diff --git a/hw/virtio/vhost-vdpa.c b/hw/virtio/vhost-vdpa.c
|
||||
index 7468e44b87..03c78d25d8 100644
|
||||
--- a/hw/virtio/vhost-vdpa.c
|
||||
+++ b/hw/virtio/vhost-vdpa.c
|
||||
@@ -707,26 +707,11 @@ static int vhost_vdpa_get_device_id(struct vhost_dev *dev,
|
||||
return ret;
|
||||
}
|
||||
|
||||
-static void vhost_vdpa_reset_svq(struct vhost_vdpa *v)
|
||||
-{
|
||||
- if (!v->shadow_vqs_enabled) {
|
||||
- return;
|
||||
- }
|
||||
-
|
||||
- for (unsigned i = 0; i < v->shadow_vqs->len; ++i) {
|
||||
- VhostShadowVirtqueue *svq = g_ptr_array_index(v->shadow_vqs, i);
|
||||
- vhost_svq_stop(svq);
|
||||
- }
|
||||
-}
|
||||
-
|
||||
static int vhost_vdpa_reset_device(struct vhost_dev *dev)
|
||||
{
|
||||
- struct vhost_vdpa *v = dev->opaque;
|
||||
int ret;
|
||||
uint8_t status = 0;
|
||||
|
||||
- vhost_vdpa_reset_svq(v);
|
||||
-
|
||||
ret = vhost_vdpa_call(dev, VHOST_VDPA_SET_STATUS, &status);
|
||||
trace_vhost_vdpa_reset_device(dev, status);
|
||||
return ret;
|
||||
@@ -1088,6 +1073,8 @@ static void vhost_vdpa_svqs_stop(struct vhost_dev *dev)
|
||||
|
||||
for (unsigned i = 0; i < v->shadow_vqs->len; ++i) {
|
||||
VhostShadowVirtqueue *svq = g_ptr_array_index(v->shadow_vqs, i);
|
||||
+
|
||||
+ vhost_svq_stop(svq);
|
||||
vhost_vdpa_svq_unmap_rings(dev, svq);
|
||||
}
|
||||
}
|
@ -1,132 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Carlos=20L=C3=B3pez?= <clopez@suse.de>
|
||||
Date: Mon, 13 Feb 2023 09:57:47 +0100
|
||||
Subject: [PATCH] vhost: avoid a potential use of an uninitialized variable in
|
||||
vhost_svq_poll()
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
In vhost_svq_poll(), if vhost_svq_get_buf() fails due to a device
|
||||
providing invalid descriptors, len is left uninitialized and returned
|
||||
to the caller, potentally leaking stack data or causing undefined
|
||||
behavior.
|
||||
|
||||
Fix this by initializing len to 0.
|
||||
|
||||
Found with GCC 13 and -fanalyzer (abridged):
|
||||
|
||||
../hw/virtio/vhost-shadow-virtqueue.c: In function ‘vhost_svq_poll’:
|
||||
../hw/virtio/vhost-shadow-virtqueue.c:538:12: warning: use of uninitialized value ‘len’ [CWE-457] [-Wanalyzer-use-of-uninitialized-value]
|
||||
538 | return len;
|
||||
| ^~~
|
||||
‘vhost_svq_poll’: events 1-4
|
||||
|
|
||||
| 522 | size_t vhost_svq_poll(VhostShadowVirtqueue *svq)
|
||||
| | ^~~~~~~~~~~~~~
|
||||
| | |
|
||||
| | (1) entry to ‘vhost_svq_poll’
|
||||
|......
|
||||
| 525 | uint32_t len;
|
||||
| | ~~~
|
||||
| | |
|
||||
| | (2) region created on stack here
|
||||
| | (3) capacity: 4 bytes
|
||||
|......
|
||||
| 528 | if (vhost_svq_more_used(svq)) {
|
||||
| | ~
|
||||
| | |
|
||||
| | (4) inlined call to ‘vhost_svq_more_used’ from ‘vhost_svq_poll’
|
||||
|
||||
(...)
|
||||
|
||||
| 528 | if (vhost_svq_more_used(svq)) {
|
||||
| | ^~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
| | ||
|
||||
| | |(8) ...to here
|
||||
| | (7) following ‘true’ branch...
|
||||
|......
|
||||
| 537 | vhost_svq_get_buf(svq, &len);
|
||||
| | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
| | |
|
||||
| | (9) calling ‘vhost_svq_get_buf’ from ‘vhost_svq_poll’
|
||||
|
|
||||
+--> ‘vhost_svq_get_buf’: events 10-11
|
||||
|
|
||||
| 416 | static VirtQueueElement *vhost_svq_get_buf(VhostShadowVirtqueue *svq,
|
||||
| | ^~~~~~~~~~~~~~~~~
|
||||
| | |
|
||||
| | (10) entry to ‘vhost_svq_get_buf’
|
||||
|......
|
||||
| 423 | if (!vhost_svq_more_used(svq)) {
|
||||
| | ~
|
||||
| | |
|
||||
| | (11) inlined call to ‘vhost_svq_more_used’ from ‘vhost_svq_get_buf’
|
||||
|
|
||||
|
||||
(...)
|
||||
|
||||
|
|
||||
‘vhost_svq_get_buf’: event 14
|
||||
|
|
||||
| 423 | if (!vhost_svq_more_used(svq)) {
|
||||
| | ^
|
||||
| | |
|
||||
| | (14) following ‘false’ branch...
|
||||
|
|
||||
‘vhost_svq_get_buf’: event 15
|
||||
|
|
||||
|cc1:
|
||||
| (15): ...to here
|
||||
|
|
||||
<------+
|
||||
|
|
||||
‘vhost_svq_poll’: events 16-17
|
||||
|
|
||||
| 537 | vhost_svq_get_buf(svq, &len);
|
||||
| | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
| | |
|
||||
| | (16) returning to ‘vhost_svq_poll’ from ‘vhost_svq_get_buf’
|
||||
| 538 | return len;
|
||||
| | ~~~
|
||||
| | |
|
||||
| | (17) use of uninitialized value ‘len’ here
|
||||
|
||||
Note by Laurent Vivier <lvivier@redhat.com>:
|
||||
|
||||
The return value is only used to detect an error:
|
||||
|
||||
vhost_svq_poll
|
||||
vhost_vdpa_net_cvq_add
|
||||
vhost_vdpa_net_load_cmd
|
||||
vhost_vdpa_net_load_mac
|
||||
-> a negative return is only used to detect error
|
||||
vhost_vdpa_net_load_mq
|
||||
-> a negative return is only used to detect error
|
||||
vhost_vdpa_net_handle_ctrl_avail
|
||||
-> a negative return is only used to detect error
|
||||
|
||||
Fixes: d368c0b052ad ("vhost: Do not depend on !NULL VirtQueueElement on vhost_svq_flush")
|
||||
Signed-off-by: Carlos López <clopez@suse.de>
|
||||
Message-Id: <20230213085747.19956-1-clopez@suse.de>
|
||||
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
|
||||
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
|
||||
(cherry-picked from commit e4dd39c699b7d63a06f686ec06ded8adbee989c1)
|
||||
Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
|
||||
---
|
||||
hw/virtio/vhost-shadow-virtqueue.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/hw/virtio/vhost-shadow-virtqueue.c b/hw/virtio/vhost-shadow-virtqueue.c
|
||||
index 5bd14cad96..a723073747 100644
|
||||
--- a/hw/virtio/vhost-shadow-virtqueue.c
|
||||
+++ b/hw/virtio/vhost-shadow-virtqueue.c
|
||||
@@ -522,7 +522,7 @@ static void vhost_svq_flush(VhostShadowVirtqueue *svq,
|
||||
size_t vhost_svq_poll(VhostShadowVirtqueue *svq)
|
||||
{
|
||||
int64_t start_us = g_get_monotonic_time();
|
||||
- uint32_t len;
|
||||
+ uint32_t len = 0;
|
||||
|
||||
do {
|
||||
if (vhost_svq_more_used(svq)) {
|
@ -1,70 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Yajun Wu <yajunw@nvidia.com>
|
||||
Date: Tue, 14 Feb 2023 10:14:30 +0800
|
||||
Subject: [PATCH] chardev/char-socket: set s->listener = NULL in
|
||||
char_socket_finalize
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
After live migration with virtio block device, qemu crash at:
|
||||
|
||||
#0 0x000055914f46f795 in object_dynamic_cast_assert (obj=0x559151b7b090, typename=0x55914f80fbc4 "qio-channel", file=0x55914f80fb90 "/images/testvfe/sw/qemu.gerrit/include/io/channel.h", line=30, func=0x55914f80fcb8 <__func__.17257> "QIO_CHANNEL") at ../qom/object.c:872
|
||||
#1 0x000055914f480d68 in QIO_CHANNEL (obj=0x559151b7b090) at /images/testvfe/sw/qemu.gerrit/include/io/channel.h:29
|
||||
#2 0x000055914f4812f8 in qio_net_listener_set_client_func_full (listener=0x559151b7a720, func=0x55914f580b97 <tcp_chr_accept>, data=0x5591519f4ea0, notify=0x0, context=0x0) at ../io/net-listener.c:166
|
||||
#3 0x000055914f580059 in tcp_chr_update_read_handler (chr=0x5591519f4ea0) at ../chardev/char-socket.c:637
|
||||
#4 0x000055914f583dca in qemu_chr_be_update_read_handlers (s=0x5591519f4ea0, context=0x0) at ../chardev/char.c:226
|
||||
#5 0x000055914f57b7c9 in qemu_chr_fe_set_handlers_full (b=0x559152bf23a0, fd_can_read=0x0, fd_read=0x0, fd_event=0x0, be_change=0x0, opaque=0x0, context=0x0, set_open=false, sync_state=true) at ../chardev/char-fe.c:279
|
||||
#6 0x000055914f57b86d in qemu_chr_fe_set_handlers (b=0x559152bf23a0, fd_can_read=0x0, fd_read=0x0, fd_event=0x0, be_change=0x0, opaque=0x0, context=0x0, set_open=false) at ../chardev/char-fe.c:304
|
||||
#7 0x000055914f378caf in vhost_user_async_close (d=0x559152bf21a0, chardev=0x559152bf23a0, vhost=0x559152bf2420, cb=0x55914f2fb8c1 <vhost_user_blk_disconnect>) at ../hw/virtio/vhost-user.c:2725
|
||||
#8 0x000055914f2fba40 in vhost_user_blk_event (opaque=0x559152bf21a0, event=CHR_EVENT_CLOSED) at ../hw/block/vhost-user-blk.c:395
|
||||
#9 0x000055914f58388c in chr_be_event (s=0x5591519f4ea0, event=CHR_EVENT_CLOSED) at ../chardev/char.c:61
|
||||
#10 0x000055914f583905 in qemu_chr_be_event (s=0x5591519f4ea0, event=CHR_EVENT_CLOSED) at ../chardev/char.c:81
|
||||
#11 0x000055914f581275 in char_socket_finalize (obj=0x5591519f4ea0) at ../chardev/char-socket.c:1083
|
||||
#12 0x000055914f46f073 in object_deinit (obj=0x5591519f4ea0, type=0x5591519055c0) at ../qom/object.c:680
|
||||
#13 0x000055914f46f0e5 in object_finalize (data=0x5591519f4ea0) at ../qom/object.c:694
|
||||
#14 0x000055914f46ff06 in object_unref (objptr=0x5591519f4ea0) at ../qom/object.c:1202
|
||||
#15 0x000055914f4715a4 in object_finalize_child_property (obj=0x559151b76c50, name=0x559151b7b250 "char3", opaque=0x5591519f4ea0) at ../qom/object.c:1747
|
||||
#16 0x000055914f46ee86 in object_property_del_all (obj=0x559151b76c50) at ../qom/object.c:632
|
||||
#17 0x000055914f46f0d2 in object_finalize (data=0x559151b76c50) at ../qom/object.c:693
|
||||
#18 0x000055914f46ff06 in object_unref (objptr=0x559151b76c50) at ../qom/object.c:1202
|
||||
#19 0x000055914f4715a4 in object_finalize_child_property (obj=0x559151b6b560, name=0x559151b76630 "chardevs", opaque=0x559151b76c50) at ../qom/object.c:1747
|
||||
#20 0x000055914f46ef67 in object_property_del_child (obj=0x559151b6b560, child=0x559151b76c50) at ../qom/object.c:654
|
||||
#21 0x000055914f46f042 in object_unparent (obj=0x559151b76c50) at ../qom/object.c:673
|
||||
#22 0x000055914f58632a in qemu_chr_cleanup () at ../chardev/char.c:1189
|
||||
#23 0x000055914f16c66c in qemu_cleanup () at ../softmmu/runstate.c:830
|
||||
#24 0x000055914eee7b9e in qemu_default_main () at ../softmmu/main.c:38
|
||||
#25 0x000055914eee7bcc in main (argc=86, argv=0x7ffc97cb8d88) at ../softmmu/main.c:48
|
||||
|
||||
In char_socket_finalize after s->listener freed, event callback function
|
||||
vhost_user_blk_event will be called to handle CHR_EVENT_CLOSED.
|
||||
vhost_user_blk_event is calling qio_net_listener_set_client_func_full which
|
||||
is still using s->listener.
|
||||
|
||||
Setting s->listener = NULL after object_unref(OBJECT(s->listener)) can
|
||||
solve this issue.
|
||||
|
||||
Signed-off-by: Yajun Wu <yajunw@nvidia.com>
|
||||
Acked-by: Jiri Pirko <jiri@nvidia.com>
|
||||
Message-Id: <20230214021430.3638579-1-yajunw@nvidia.com>
|
||||
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
|
||||
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
|
||||
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
|
||||
(cherry-picked from commit b8a7f51f59e28d5a8e0c07ed3919cc9695560ed2)
|
||||
Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
|
||||
---
|
||||
chardev/char-socket.c | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/chardev/char-socket.c b/chardev/char-socket.c
|
||||
index 879564aa8a..b00efb1482 100644
|
||||
--- a/chardev/char-socket.c
|
||||
+++ b/chardev/char-socket.c
|
||||
@@ -1065,6 +1065,7 @@ static void char_socket_finalize(Object *obj)
|
||||
qio_net_listener_set_client_func_full(s->listener, NULL, NULL,
|
||||
NULL, chr->gcontext);
|
||||
object_unref(OBJECT(s->listener));
|
||||
+ s->listener = NULL;
|
||||
}
|
||||
if (s->tls_creds) {
|
||||
object_unref(OBJECT(s->tls_creds));
|
@ -1,41 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jason Wang <jasowang@redhat.com>
|
||||
Date: Thu, 23 Feb 2023 14:59:20 +0800
|
||||
Subject: [PATCH] intel-iommu: fail MAP notifier without caching mode
|
||||
|
||||
Without caching mode, MAP notifier won't work correctly since guest
|
||||
won't send IOTLB update event when it establishes new mappings in the
|
||||
I/O page tables. Let's fail the IOMMU notifiers early instead of
|
||||
misbehaving silently.
|
||||
|
||||
Reviewed-by: Eric Auger <eric.auger@redhat.com>
|
||||
Tested-by: Viktor Prutyanov <viktor@daynix.com>
|
||||
Signed-off-by: Jason Wang <jasowang@redhat.com>
|
||||
Message-Id: <20230223065924.42503-2-jasowang@redhat.com>
|
||||
Reviewed-by: Peter Xu <peterx@redhat.com>
|
||||
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
|
||||
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
|
||||
(cherry-picked from commit b8d78277c091f26fdd64f239bc8bb7e55d74cecf)
|
||||
Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
|
||||
---
|
||||
hw/i386/intel_iommu.c | 7 +++++++
|
||||
1 file changed, 7 insertions(+)
|
||||
|
||||
diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
|
||||
index a08ee85edf..9143376677 100644
|
||||
--- a/hw/i386/intel_iommu.c
|
||||
+++ b/hw/i386/intel_iommu.c
|
||||
@@ -3186,6 +3186,13 @@ static int vtd_iommu_notify_flag_changed(IOMMUMemoryRegion *iommu,
|
||||
"Snoop Control with vhost or VFIO is not supported");
|
||||
return -ENOTSUP;
|
||||
}
|
||||
+ if (!s->caching_mode && (new & IOMMU_NOTIFIER_MAP)) {
|
||||
+ error_setg_errno(errp, ENOTSUP,
|
||||
+ "device %02x.%02x.%x requires caching mode",
|
||||
+ pci_bus_num(vtd_as->bus), PCI_SLOT(vtd_as->devfn),
|
||||
+ PCI_FUNC(vtd_as->devfn));
|
||||
+ return -ENOTSUP;
|
||||
+ }
|
||||
|
||||
/* Update per-address-space notifier flags */
|
||||
vtd_as->notifier_flags = new;
|
@ -1,50 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jason Wang <jasowang@redhat.com>
|
||||
Date: Thu, 23 Feb 2023 14:59:21 +0800
|
||||
Subject: [PATCH] intel-iommu: fail DEVIOTLB_UNMAP without dt mode
|
||||
|
||||
Without dt mode, device IOTLB notifier won't work since guest won't
|
||||
send device IOTLB invalidation descriptor in this case. Let's fail
|
||||
early instead of misbehaving silently.
|
||||
|
||||
Reviewed-by: Laurent Vivier <lvivier@redhat.com>
|
||||
Tested-by: Laurent Vivier <lvivier@redhat.com>
|
||||
Tested-by: Viktor Prutyanov <viktor@daynix.com>
|
||||
Buglink: https://bugzilla.redhat.com/2156876
|
||||
Signed-off-by: Jason Wang <jasowang@redhat.com>
|
||||
Message-Id: <20230223065924.42503-3-jasowang@redhat.com>
|
||||
Reviewed-by: Peter Xu <peterx@redhat.com>
|
||||
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
|
||||
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
|
||||
(cherry-picked from commit 09adb0e021207b60a0c51a68939b4539d98d3ef3)
|
||||
Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
|
||||
---
|
||||
hw/i386/intel_iommu.c | 8 ++++++++
|
||||
1 file changed, 8 insertions(+)
|
||||
|
||||
diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
|
||||
index 9143376677..d025ef2873 100644
|
||||
--- a/hw/i386/intel_iommu.c
|
||||
+++ b/hw/i386/intel_iommu.c
|
||||
@@ -3179,6 +3179,7 @@ static int vtd_iommu_notify_flag_changed(IOMMUMemoryRegion *iommu,
|
||||
{
|
||||
VTDAddressSpace *vtd_as = container_of(iommu, VTDAddressSpace, iommu);
|
||||
IntelIOMMUState *s = vtd_as->iommu_state;
|
||||
+ X86IOMMUState *x86_iommu = X86_IOMMU_DEVICE(s);
|
||||
|
||||
/* TODO: add support for VFIO and vhost users */
|
||||
if (s->snoop_control) {
|
||||
@@ -3193,6 +3194,13 @@ static int vtd_iommu_notify_flag_changed(IOMMUMemoryRegion *iommu,
|
||||
PCI_FUNC(vtd_as->devfn));
|
||||
return -ENOTSUP;
|
||||
}
|
||||
+ if (!x86_iommu->dt_supported && (new & IOMMU_NOTIFIER_DEVIOTLB_UNMAP)) {
|
||||
+ error_setg_errno(errp, ENOTSUP,
|
||||
+ "device %02x.%02x.%x requires device IOTLB mode",
|
||||
+ pci_bus_num(vtd_as->bus), PCI_SLOT(vtd_as->devfn),
|
||||
+ PCI_FUNC(vtd_as->devfn));
|
||||
+ return -ENOTSUP;
|
||||
+ }
|
||||
|
||||
/* Update per-address-space notifier flags */
|
||||
vtd_as->notifier_flags = new;
|
@ -1,166 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Laszlo Ersek <lersek@redhat.com>
|
||||
Date: Thu, 5 Jan 2023 17:18:04 +0100
|
||||
Subject: [PATCH] acpi: cpuhp: fix guest-visible maximum access size to the
|
||||
legacy reg block
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
The modern ACPI CPU hotplug interface was introduced in the following
|
||||
series (aa1dd39ca307..679dd1a957df), released in v2.7.0:
|
||||
|
||||
1 abd49bc2ed2f docs: update ACPI CPU hotplug spec with new protocol
|
||||
2 16bcab97eb9f pc: piix4/ich9: add 'cpu-hotplug-legacy' property
|
||||
3 5e1b5d93887b acpi: cpuhp: add CPU devices AML with _STA method
|
||||
4 ac35f13ba8f8 pc: acpi: introduce AcpiDeviceIfClass.madt_cpu hook
|
||||
5 d2238cb6781d acpi: cpuhp: implement hot-add parts of CPU hotplug
|
||||
interface
|
||||
6 8872c25a26cc acpi: cpuhp: implement hot-remove parts of CPU hotplug
|
||||
interface
|
||||
7 76623d00ae57 acpi: cpuhp: add cpu._OST handling
|
||||
8 679dd1a957df pc: use new CPU hotplug interface since 2.7 machine type
|
||||
|
||||
Before patch#1, "docs/specs/acpi_cpu_hotplug.txt" only specified 1-byte
|
||||
accesses for the hotplug register block. Patch#1 preserved the same
|
||||
restriction for the legacy register block, but:
|
||||
|
||||
- it specified DWORD accesses for some of the modern registers,
|
||||
|
||||
- in particular, the switch from the legacy block to the modern block
|
||||
would require a DWORD write to the *legacy* block.
|
||||
|
||||
The latter functionality was then implemented in cpu_status_write()
|
||||
[hw/acpi/cpu_hotplug.c], in patch#8.
|
||||
|
||||
Unfortunately, all DWORD accesses depended on a dormant bug: the one
|
||||
introduced in earlier commit a014ed07bd5a ("memory: accept mismatching
|
||||
sizes in memory_region_access_valid", 2013-05-29); first released in
|
||||
v1.6.0. Due to commit a014ed07bd5a, the DWORD accesses to the *legacy*
|
||||
CPU hotplug register block would work in spite of the above series *not*
|
||||
relaxing "valid.max_access_size = 1" in "hw/acpi/cpu_hotplug.c":
|
||||
|
||||
> static const MemoryRegionOps AcpiCpuHotplug_ops = {
|
||||
> .read = cpu_status_read,
|
||||
> .write = cpu_status_write,
|
||||
> .endianness = DEVICE_LITTLE_ENDIAN,
|
||||
> .valid = {
|
||||
> .min_access_size = 1,
|
||||
> .max_access_size = 1,
|
||||
> },
|
||||
> };
|
||||
|
||||
Later, in commits e6d0c3ce6895 ("acpi: cpuhp: introduce 'Command data 2'
|
||||
field", 2020-01-22) and ae340aa3d256 ("acpi: cpuhp: spec: add typical
|
||||
usecases", 2020-01-22), first released in v5.0.0, the modern CPU hotplug
|
||||
interface (including the documentation) was extended with another DWORD
|
||||
*read* access, namely to the "Command data 2" register, which would be
|
||||
important for the guest to confirm whether it managed to switch the
|
||||
register block from legacy to modern.
|
||||
|
||||
This functionality too silently depended on the bug from commit
|
||||
a014ed07bd5a.
|
||||
|
||||
In commit 5d971f9e6725 ('memory: Revert "memory: accept mismatching sizes
|
||||
in memory_region_access_valid"', 2020-06-26), first released in v5.1.0,
|
||||
the bug from commit a014ed07bd5a was fixed (the commit was reverted).
|
||||
That swiftly exposed the bug in "AcpiCpuHotplug_ops", still present from
|
||||
the v2.7.0 series quoted at the top -- namely the fact that
|
||||
"valid.max_access_size = 1" didn't match what the guest was supposed to
|
||||
do, according to the spec ("docs/specs/acpi_cpu_hotplug.txt").
|
||||
|
||||
The symptom is that the "modern interface negotiation protocol"
|
||||
described in commit ae340aa3d256:
|
||||
|
||||
> + Use following steps to detect and enable modern CPU hotplug interface:
|
||||
> + 1. Store 0x0 to the 'CPU selector' register,
|
||||
> + attempting to switch to modern mode
|
||||
> + 2. Store 0x0 to the 'CPU selector' register,
|
||||
> + to ensure valid selector value
|
||||
> + 3. Store 0x0 to the 'Command field' register,
|
||||
> + 4. Read the 'Command data 2' register.
|
||||
> + If read value is 0x0, the modern interface is enabled.
|
||||
> + Otherwise legacy or no CPU hotplug interface available
|
||||
|
||||
falls apart for the guest: steps 1 and 2 are lost, because they are DWORD
|
||||
writes; so no switching happens. Step 3 (a single-byte write) is not
|
||||
lost, but it has no effect; see the condition in cpu_status_write() in
|
||||
patch#8. And step 4 *misleads* the guest into thinking that the switch
|
||||
worked: the DWORD read is lost again -- it returns zero to the guest
|
||||
without ever reaching the device model, so the guest never learns the
|
||||
switch didn't work.
|
||||
|
||||
This means that guest behavior centered on the "Command data 2" register
|
||||
worked *only* in the v5.0.0 release; it got effectively regressed in
|
||||
v5.1.0.
|
||||
|
||||
To make things *even more* complicated, the breakage was (and remains, as
|
||||
of today) visible with TCG acceleration only. Commit 5d971f9e6725 makes
|
||||
no difference with KVM acceleration -- the DWORD accesses still work,
|
||||
despite "valid.max_access_size = 1".
|
||||
|
||||
As commit 5d971f9e6725 suggests, fix the problem by raising
|
||||
"valid.max_access_size" to 4 -- the spec now clearly instructs the guest
|
||||
to perform DWORD accesses to the legacy register block too, for enabling
|
||||
(and verifying!) the modern block. In order to keep compatibility for the
|
||||
device model implementation though, set "impl.max_access_size = 1", so
|
||||
that wide accesses be split before they reach the legacy read/write
|
||||
handlers, like they always have been on KVM, and like they were on TCG
|
||||
before 5d971f9e6725 (v5.1.0).
|
||||
|
||||
Tested with:
|
||||
|
||||
- OVMF IA32 + qemu-system-i386, CPU hotplug/hot-unplug with SMM,
|
||||
intermixed with ACPI S3 suspend/resume, using KVM accel
|
||||
(regression-test);
|
||||
|
||||
- OVMF IA32X64 + qemu-system-x86_64, CPU hotplug/hot-unplug with SMM,
|
||||
intermixed with ACPI S3 suspend/resume, using KVM accel
|
||||
(regression-test);
|
||||
|
||||
- OVMF IA32 + qemu-system-i386, SMM enabled, using TCG accel; verified the
|
||||
register block switch and the present/possible CPU counting through the
|
||||
modern hotplug interface, during OVMF boot (bugfix test);
|
||||
|
||||
- I do not have any testcase (guest payload) for regression-testing CPU
|
||||
hotplug through the *legacy* CPU hotplug register block.
|
||||
|
||||
Cc: "Michael S. Tsirkin" <mst@redhat.com>
|
||||
Cc: Ani Sinha <ani@anisinha.ca>
|
||||
Cc: Ard Biesheuvel <ardb@kernel.org>
|
||||
Cc: Igor Mammedov <imammedo@redhat.com>
|
||||
Cc: Paolo Bonzini <pbonzini@redhat.com>
|
||||
Cc: Peter Maydell <peter.maydell@linaro.org>
|
||||
Cc: Philippe Mathieu-Daudé <philmd@linaro.org>
|
||||
Cc: qemu-stable@nongnu.org
|
||||
Ref: "IO port write width clamping differs between TCG and KVM"
|
||||
Link: http://mid.mail-archive.com/aaedee84-d3ed-a4f9-21e7-d221a28d1683@redhat.com
|
||||
Link: https://lists.gnu.org/archive/html/qemu-devel/2023-01/msg00199.html
|
||||
Reported-by: Ard Biesheuvel <ardb@kernel.org>
|
||||
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
|
||||
Tested-by: Ard Biesheuvel <ardb@kernel.org>
|
||||
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
|
||||
Tested-by: Igor Mammedov <imammedo@redhat.com>
|
||||
Message-Id: <20230105161804.82486-1-lersek@redhat.com>
|
||||
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
|
||||
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
|
||||
(cherry-picked from commit dab30fbef3896bb652a09d46c37d3f55657cbcbb)
|
||||
Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
|
||||
---
|
||||
hw/acpi/cpu_hotplug.c | 3 +++
|
||||
1 file changed, 3 insertions(+)
|
||||
|
||||
diff --git a/hw/acpi/cpu_hotplug.c b/hw/acpi/cpu_hotplug.c
|
||||
index 53654f8638..ff14c3f410 100644
|
||||
--- a/hw/acpi/cpu_hotplug.c
|
||||
+++ b/hw/acpi/cpu_hotplug.c
|
||||
@@ -52,6 +52,9 @@ static const MemoryRegionOps AcpiCpuHotplug_ops = {
|
||||
.endianness = DEVICE_LITTLE_ENDIAN,
|
||||
.valid = {
|
||||
.min_access_size = 1,
|
||||
+ .max_access_size = 4,
|
||||
+ },
|
||||
+ .impl = {
|
||||
.max_access_size = 1,
|
||||
},
|
||||
};
|
@ -1,286 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Richard Henderson <richard.henderson@linaro.org>
|
||||
Date: Sat, 14 Jan 2023 13:05:41 -1000
|
||||
Subject: [PATCH] tests/tcg/i386: Introduce and use reg_t consistently
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Define reg_t based on the actual register width.
|
||||
Define the inlines using that type. This will allow
|
||||
input registers to 32-bit insns to be set to 64-bit
|
||||
values on x86-64, which allows testing various edge cases.
|
||||
|
||||
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
|
||||
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
|
||||
Message-Id: <20230114230542.3116013-2-richard.henderson@linaro.org>
|
||||
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
||||
(cherry-picked from commit 5d62d6649cd367b5b4a3676e7514d2f9ca86cb03)
|
||||
Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
|
||||
---
|
||||
tests/tcg/i386/test-i386-bmi2.c | 182 ++++++++++++++++----------------
|
||||
1 file changed, 93 insertions(+), 89 deletions(-)
|
||||
|
||||
diff --git a/tests/tcg/i386/test-i386-bmi2.c b/tests/tcg/i386/test-i386-bmi2.c
|
||||
index 5fadf47510..3c3ef85513 100644
|
||||
--- a/tests/tcg/i386/test-i386-bmi2.c
|
||||
+++ b/tests/tcg/i386/test-i386-bmi2.c
|
||||
@@ -3,34 +3,40 @@
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
||||
+#ifdef __x86_64
|
||||
+typedef uint64_t reg_t;
|
||||
+#else
|
||||
+typedef uint32_t reg_t;
|
||||
+#endif
|
||||
+
|
||||
#define insn1q(name, arg0) \
|
||||
-static inline uint64_t name##q(uint64_t arg0) \
|
||||
+static inline reg_t name##q(reg_t arg0) \
|
||||
{ \
|
||||
- uint64_t result64; \
|
||||
+ reg_t result64; \
|
||||
asm volatile (#name "q %1, %0" : "=r"(result64) : "rm"(arg0)); \
|
||||
return result64; \
|
||||
}
|
||||
|
||||
#define insn1l(name, arg0) \
|
||||
-static inline uint32_t name##l(uint32_t arg0) \
|
||||
+static inline reg_t name##l(reg_t arg0) \
|
||||
{ \
|
||||
- uint32_t result32; \
|
||||
+ reg_t result32; \
|
||||
asm volatile (#name "l %k1, %k0" : "=r"(result32) : "rm"(arg0)); \
|
||||
return result32; \
|
||||
}
|
||||
|
||||
#define insn2q(name, arg0, c0, arg1, c1) \
|
||||
-static inline uint64_t name##q(uint64_t arg0, uint64_t arg1) \
|
||||
+static inline reg_t name##q(reg_t arg0, reg_t arg1) \
|
||||
{ \
|
||||
- uint64_t result64; \
|
||||
+ reg_t result64; \
|
||||
asm volatile (#name "q %2, %1, %0" : "=r"(result64) : c0(arg0), c1(arg1)); \
|
||||
return result64; \
|
||||
}
|
||||
|
||||
#define insn2l(name, arg0, c0, arg1, c1) \
|
||||
-static inline uint32_t name##l(uint32_t arg0, uint32_t arg1) \
|
||||
+static inline reg_t name##l(reg_t arg0, reg_t arg1) \
|
||||
{ \
|
||||
- uint32_t result32; \
|
||||
+ reg_t result32; \
|
||||
asm volatile (#name "l %k2, %k1, %k0" : "=r"(result32) : c0(arg0), c1(arg1)); \
|
||||
return result32; \
|
||||
}
|
||||
@@ -65,130 +71,128 @@ insn1l(blsr, src)
|
||||
int main(int argc, char *argv[]) {
|
||||
uint64_t ehlo = 0x202020204f4c4845ull;
|
||||
uint64_t mask = 0xa080800302020001ull;
|
||||
- uint32_t result32;
|
||||
+ reg_t result;
|
||||
|
||||
#ifdef __x86_64
|
||||
- uint64_t result64;
|
||||
-
|
||||
/* 64 bits */
|
||||
- result64 = andnq(mask, ehlo);
|
||||
- assert(result64 == 0x002020204d4c4844);
|
||||
+ result = andnq(mask, ehlo);
|
||||
+ assert(result == 0x002020204d4c4844);
|
||||
|
||||
- result64 = pextq(ehlo, mask);
|
||||
- assert(result64 == 133);
|
||||
+ result = pextq(ehlo, mask);
|
||||
+ assert(result == 133);
|
||||
|
||||
- result64 = pdepq(result64, mask);
|
||||
- assert(result64 == (ehlo & mask));
|
||||
+ result = pdepq(result, mask);
|
||||
+ assert(result == (ehlo & mask));
|
||||
|
||||
- result64 = pextq(-1ull, mask);
|
||||
- assert(result64 == 511); /* mask has 9 bits set */
|
||||
+ result = pextq(-1ull, mask);
|
||||
+ assert(result == 511); /* mask has 9 bits set */
|
||||
|
||||
- result64 = pdepq(-1ull, mask);
|
||||
- assert(result64 == mask);
|
||||
+ result = pdepq(-1ull, mask);
|
||||
+ assert(result == mask);
|
||||
|
||||
- result64 = bextrq(mask, 0x3f00);
|
||||
- assert(result64 == (mask & ~INT64_MIN));
|
||||
+ result = bextrq(mask, 0x3f00);
|
||||
+ assert(result == (mask & ~INT64_MIN));
|
||||
|
||||
- result64 = bextrq(mask, 0x1038);
|
||||
- assert(result64 == 0xa0);
|
||||
+ result = bextrq(mask, 0x1038);
|
||||
+ assert(result == 0xa0);
|
||||
|
||||
- result64 = bextrq(mask, 0x10f8);
|
||||
- assert(result64 == 0);
|
||||
+ result = bextrq(mask, 0x10f8);
|
||||
+ assert(result == 0);
|
||||
|
||||
- result64 = blsiq(0x30);
|
||||
- assert(result64 == 0x10);
|
||||
+ result = blsiq(0x30);
|
||||
+ assert(result == 0x10);
|
||||
|
||||
- result64 = blsiq(0x30ull << 32);
|
||||
- assert(result64 == 0x10ull << 32);
|
||||
+ result = blsiq(0x30ull << 32);
|
||||
+ assert(result == 0x10ull << 32);
|
||||
|
||||
- result64 = blsmskq(0x30);
|
||||
- assert(result64 == 0x1f);
|
||||
+ result = blsmskq(0x30);
|
||||
+ assert(result == 0x1f);
|
||||
|
||||
- result64 = blsrq(0x30);
|
||||
- assert(result64 == 0x20);
|
||||
+ result = blsrq(0x30);
|
||||
+ assert(result == 0x20);
|
||||
|
||||
- result64 = blsrq(0x30ull << 32);
|
||||
- assert(result64 == 0x20ull << 32);
|
||||
+ result = blsrq(0x30ull << 32);
|
||||
+ assert(result == 0x20ull << 32);
|
||||
|
||||
- result64 = bzhiq(mask, 0x3f);
|
||||
- assert(result64 == (mask & ~INT64_MIN));
|
||||
+ result = bzhiq(mask, 0x3f);
|
||||
+ assert(result == (mask & ~INT64_MIN));
|
||||
|
||||
- result64 = bzhiq(mask, 0x1f);
|
||||
- assert(result64 == (mask & ~(-1 << 30)));
|
||||
+ result = bzhiq(mask, 0x1f);
|
||||
+ assert(result == (mask & ~(-1 << 30)));
|
||||
|
||||
- result64 = rorxq(0x2132435465768798, 8);
|
||||
- assert(result64 == 0x9821324354657687);
|
||||
+ result = rorxq(0x2132435465768798, 8);
|
||||
+ assert(result == 0x9821324354657687);
|
||||
|
||||
- result64 = sarxq(0xffeeddccbbaa9988, 8);
|
||||
- assert(result64 == 0xffffeeddccbbaa99);
|
||||
+ result = sarxq(0xffeeddccbbaa9988, 8);
|
||||
+ assert(result == 0xffffeeddccbbaa99);
|
||||
|
||||
- result64 = sarxq(0x77eeddccbbaa9988, 8 | 64);
|
||||
- assert(result64 == 0x0077eeddccbbaa99);
|
||||
+ result = sarxq(0x77eeddccbbaa9988, 8 | 64);
|
||||
+ assert(result == 0x0077eeddccbbaa99);
|
||||
|
||||
- result64 = shrxq(0xffeeddccbbaa9988, 8);
|
||||
- assert(result64 == 0x00ffeeddccbbaa99);
|
||||
+ result = shrxq(0xffeeddccbbaa9988, 8);
|
||||
+ assert(result == 0x00ffeeddccbbaa99);
|
||||
|
||||
- result64 = shrxq(0x77eeddccbbaa9988, 8 | 192);
|
||||
- assert(result64 == 0x0077eeddccbbaa99);
|
||||
+ result = shrxq(0x77eeddccbbaa9988, 8 | 192);
|
||||
+ assert(result == 0x0077eeddccbbaa99);
|
||||
|
||||
- result64 = shlxq(0xffeeddccbbaa9988, 8);
|
||||
- assert(result64 == 0xeeddccbbaa998800);
|
||||
+ result = shlxq(0xffeeddccbbaa9988, 8);
|
||||
+ assert(result == 0xeeddccbbaa998800);
|
||||
#endif
|
||||
|
||||
/* 32 bits */
|
||||
- result32 = andnl(mask, ehlo);
|
||||
- assert(result32 == 0x04d4c4844);
|
||||
+ result = andnl(mask, ehlo);
|
||||
+ assert(result == 0x04d4c4844);
|
||||
|
||||
- result32 = pextl((uint32_t) ehlo, mask);
|
||||
- assert(result32 == 5);
|
||||
+ result = pextl((uint32_t) ehlo, mask);
|
||||
+ assert(result == 5);
|
||||
|
||||
- result32 = pdepl(result32, mask);
|
||||
- assert(result32 == (uint32_t)(ehlo & mask));
|
||||
+ result = pdepl(result, mask);
|
||||
+ assert(result == (uint32_t)(ehlo & mask));
|
||||
|
||||
- result32 = pextl(-1u, mask);
|
||||
- assert(result32 == 7); /* mask has 3 bits set */
|
||||
+ result = pextl(-1u, mask);
|
||||
+ assert(result == 7); /* mask has 3 bits set */
|
||||
|
||||
- result32 = pdepl(-1u, mask);
|
||||
- assert(result32 == (uint32_t)mask);
|
||||
+ result = pdepl(-1u, mask);
|
||||
+ assert(result == (uint32_t)mask);
|
||||
|
||||
- result32 = bextrl(mask, 0x1f00);
|
||||
- assert(result32 == (mask & ~INT32_MIN));
|
||||
+ result = bextrl(mask, 0x1f00);
|
||||
+ assert(result == (mask & ~INT32_MIN));
|
||||
|
||||
- result32 = bextrl(ehlo, 0x1018);
|
||||
- assert(result32 == 0x4f);
|
||||
+ result = bextrl(ehlo, 0x1018);
|
||||
+ assert(result == 0x4f);
|
||||
|
||||
- result32 = bextrl(mask, 0x1038);
|
||||
- assert(result32 == 0);
|
||||
+ result = bextrl(mask, 0x1038);
|
||||
+ assert(result == 0);
|
||||
|
||||
- result32 = blsil(0xffff);
|
||||
- assert(result32 == 1);
|
||||
+ result = blsil(0xffff);
|
||||
+ assert(result == 1);
|
||||
|
||||
- result32 = blsmskl(0x300);
|
||||
- assert(result32 == 0x1ff);
|
||||
+ result = blsmskl(0x300);
|
||||
+ assert(result == 0x1ff);
|
||||
|
||||
- result32 = blsrl(0xffc);
|
||||
- assert(result32 == 0xff8);
|
||||
+ result = blsrl(0xffc);
|
||||
+ assert(result == 0xff8);
|
||||
|
||||
- result32 = bzhil(mask, 0xf);
|
||||
- assert(result32 == 1);
|
||||
+ result = bzhil(mask, 0xf);
|
||||
+ assert(result == 1);
|
||||
|
||||
- result32 = rorxl(0x65768798, 8);
|
||||
- assert(result32 == 0x98657687);
|
||||
+ result = rorxl(0x65768798, 8);
|
||||
+ assert(result == 0x98657687);
|
||||
|
||||
- result32 = sarxl(0xffeeddcc, 8);
|
||||
- assert(result32 == 0xffffeedd);
|
||||
+ result = sarxl(0xffeeddcc, 8);
|
||||
+ assert(result == 0xffffeedd);
|
||||
|
||||
- result32 = sarxl(0x77eeddcc, 8 | 32);
|
||||
- assert(result32 == 0x0077eedd);
|
||||
+ result = sarxl(0x77eeddcc, 8 | 32);
|
||||
+ assert(result == 0x0077eedd);
|
||||
|
||||
- result32 = shrxl(0xffeeddcc, 8);
|
||||
- assert(result32 == 0x00ffeedd);
|
||||
+ result = shrxl(0xffeeddcc, 8);
|
||||
+ assert(result == 0x00ffeedd);
|
||||
|
||||
- result32 = shrxl(0x77eeddcc, 8 | 128);
|
||||
- assert(result32 == 0x0077eedd);
|
||||
+ result = shrxl(0x77eeddcc, 8 | 128);
|
||||
+ assert(result == 0x0077eedd);
|
||||
|
||||
- result32 = shlxl(0xffeeddcc, 8);
|
||||
- assert(result32 == 0xeeddcc00);
|
||||
+ result = shlxl(0xffeeddcc, 8);
|
||||
+ assert(result == 0xeeddcc00);
|
||||
|
||||
return 0;
|
||||
}
|
@ -1,97 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Richard Henderson <richard.henderson@linaro.org>
|
||||
Date: Sat, 14 Jan 2023 13:05:42 -1000
|
||||
Subject: [PATCH] target/i386: Fix BEXTR instruction
|
||||
|
||||
There were two problems here: not limiting the input to operand bits,
|
||||
and not correctly handling large extraction length.
|
||||
|
||||
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1372
|
||||
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
|
||||
Message-Id: <20230114230542.3116013-3-richard.henderson@linaro.org>
|
||||
Cc: qemu-stable@nongnu.org
|
||||
Fixes: 1d0b926150e5 ("target/i386: move scalar 0F 38 and 0F 3A instruction to new decoder", 2022-10-18)
|
||||
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
||||
(cherry-picked from commit b14c0098975264ed03144f145bca0179a6763a07)
|
||||
Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
|
||||
---
|
||||
target/i386/tcg/emit.c.inc | 22 +++++++++++-----------
|
||||
tests/tcg/i386/test-i386-bmi2.c | 12 ++++++++++++
|
||||
2 files changed, 23 insertions(+), 11 deletions(-)
|
||||
|
||||
diff --git a/target/i386/tcg/emit.c.inc b/target/i386/tcg/emit.c.inc
|
||||
index 7037ff91c6..99f6ba6e19 100644
|
||||
--- a/target/i386/tcg/emit.c.inc
|
||||
+++ b/target/i386/tcg/emit.c.inc
|
||||
@@ -1078,30 +1078,30 @@ static void gen_ANDN(DisasContext *s, CPUX86State *env, X86DecodedInsn *decode)
|
||||
static void gen_BEXTR(DisasContext *s, CPUX86State *env, X86DecodedInsn *decode)
|
||||
{
|
||||
MemOp ot = decode->op[0].ot;
|
||||
- TCGv bound, zero;
|
||||
+ TCGv bound = tcg_constant_tl(ot == MO_64 ? 63 : 31);
|
||||
+ TCGv zero = tcg_constant_tl(0);
|
||||
+ TCGv mone = tcg_constant_tl(-1);
|
||||
|
||||
/*
|
||||
* Extract START, and shift the operand.
|
||||
* Shifts larger than operand size get zeros.
|
||||
*/
|
||||
tcg_gen_ext8u_tl(s->A0, s->T1);
|
||||
+ if (TARGET_LONG_BITS == 64 && ot == MO_32) {
|
||||
+ tcg_gen_ext32u_tl(s->T0, s->T0);
|
||||
+ }
|
||||
tcg_gen_shr_tl(s->T0, s->T0, s->A0);
|
||||
|
||||
- bound = tcg_constant_tl(ot == MO_64 ? 63 : 31);
|
||||
- zero = tcg_constant_tl(0);
|
||||
tcg_gen_movcond_tl(TCG_COND_LEU, s->T0, s->A0, bound, s->T0, zero);
|
||||
|
||||
/*
|
||||
- * Extract the LEN into a mask. Lengths larger than
|
||||
- * operand size get all ones.
|
||||
+ * Extract the LEN into an inverse mask. Lengths larger than
|
||||
+ * operand size get all zeros, length 0 gets all ones.
|
||||
*/
|
||||
tcg_gen_extract_tl(s->A0, s->T1, 8, 8);
|
||||
- tcg_gen_movcond_tl(TCG_COND_LEU, s->A0, s->A0, bound, s->A0, bound);
|
||||
-
|
||||
- tcg_gen_movi_tl(s->T1, 1);
|
||||
- tcg_gen_shl_tl(s->T1, s->T1, s->A0);
|
||||
- tcg_gen_subi_tl(s->T1, s->T1, 1);
|
||||
- tcg_gen_and_tl(s->T0, s->T0, s->T1);
|
||||
+ tcg_gen_shl_tl(s->T1, mone, s->A0);
|
||||
+ tcg_gen_movcond_tl(TCG_COND_LEU, s->T1, s->A0, bound, s->T1, zero);
|
||||
+ tcg_gen_andc_tl(s->T0, s->T0, s->T1);
|
||||
|
||||
gen_op_update1_cc(s);
|
||||
set_cc_op(s, CC_OP_LOGICB + ot);
|
||||
diff --git a/tests/tcg/i386/test-i386-bmi2.c b/tests/tcg/i386/test-i386-bmi2.c
|
||||
index 3c3ef85513..982d4abda4 100644
|
||||
--- a/tests/tcg/i386/test-i386-bmi2.c
|
||||
+++ b/tests/tcg/i386/test-i386-bmi2.c
|
||||
@@ -99,6 +99,9 @@ int main(int argc, char *argv[]) {
|
||||
result = bextrq(mask, 0x10f8);
|
||||
assert(result == 0);
|
||||
|
||||
+ result = bextrq(0xfedcba9876543210ull, 0x7f00);
|
||||
+ assert(result == 0xfedcba9876543210ull);
|
||||
+
|
||||
result = blsiq(0x30);
|
||||
assert(result == 0x10);
|
||||
|
||||
@@ -164,6 +167,15 @@ int main(int argc, char *argv[]) {
|
||||
result = bextrl(mask, 0x1038);
|
||||
assert(result == 0);
|
||||
|
||||
+ result = bextrl((reg_t)0x8f635a775ad3b9b4ull, 0x3018);
|
||||
+ assert(result == 0x5a);
|
||||
+
|
||||
+ result = bextrl((reg_t)0xfedcba9876543210ull, 0x7f00);
|
||||
+ assert(result == 0x76543210u);
|
||||
+
|
||||
+ result = bextrl(-1, 0);
|
||||
+ assert(result == 0);
|
||||
+
|
||||
result = blsil(0xffff);
|
||||
assert(result == 1);
|
||||
|
@ -1,47 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Richard Henderson <richard.henderson@linaro.org>
|
||||
Date: Sat, 14 Jan 2023 08:06:01 -1000
|
||||
Subject: [PATCH] target/i386: Fix C flag for BLSI, BLSMSK, BLSR
|
||||
|
||||
We forgot to set cc_src, which is used for computing C.
|
||||
|
||||
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1370
|
||||
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
|
||||
Message-Id: <20230114180601.2993644-1-richard.henderson@linaro.org>
|
||||
Cc: qemu-stable@nongnu.org
|
||||
Fixes: 1d0b926150e5 ("target/i386: move scalar 0F 38 and 0F 3A instruction to new decoder", 2022-10-18)
|
||||
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
||||
(cherry-picked from commit 99282098dc74c2055bde5652bde6cf0067d0c370)
|
||||
Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
|
||||
---
|
||||
target/i386/tcg/emit.c.inc | 3 +++
|
||||
1 file changed, 3 insertions(+)
|
||||
|
||||
diff --git a/target/i386/tcg/emit.c.inc b/target/i386/tcg/emit.c.inc
|
||||
index 99f6ba6e19..4d7702c106 100644
|
||||
--- a/target/i386/tcg/emit.c.inc
|
||||
+++ b/target/i386/tcg/emit.c.inc
|
||||
@@ -1111,6 +1111,7 @@ static void gen_BLSI(DisasContext *s, CPUX86State *env, X86DecodedInsn *decode)
|
||||
{
|
||||
MemOp ot = decode->op[0].ot;
|
||||
|
||||
+ tcg_gen_mov_tl(cpu_cc_src, s->T0);
|
||||
tcg_gen_neg_tl(s->T1, s->T0);
|
||||
tcg_gen_and_tl(s->T0, s->T0, s->T1);
|
||||
tcg_gen_mov_tl(cpu_cc_dst, s->T0);
|
||||
@@ -1121,6 +1122,7 @@ static void gen_BLSMSK(DisasContext *s, CPUX86State *env, X86DecodedInsn *decode
|
||||
{
|
||||
MemOp ot = decode->op[0].ot;
|
||||
|
||||
+ tcg_gen_mov_tl(cpu_cc_src, s->T0);
|
||||
tcg_gen_subi_tl(s->T1, s->T0, 1);
|
||||
tcg_gen_xor_tl(s->T0, s->T0, s->T1);
|
||||
tcg_gen_mov_tl(cpu_cc_dst, s->T0);
|
||||
@@ -1131,6 +1133,7 @@ static void gen_BLSR(DisasContext *s, CPUX86State *env, X86DecodedInsn *decode)
|
||||
{
|
||||
MemOp ot = decode->op[0].ot;
|
||||
|
||||
+ tcg_gen_mov_tl(cpu_cc_src, s->T0);
|
||||
tcg_gen_subi_tl(s->T1, s->T0, 1);
|
||||
tcg_gen_and_tl(s->T0, s->T0, s->T1);
|
||||
tcg_gen_mov_tl(cpu_cc_dst, s->T0);
|
@ -1,192 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Paolo Bonzini <pbonzini@redhat.com>
|
||||
Date: Tue, 31 Jan 2023 09:48:03 +0100
|
||||
Subject: [PATCH] target/i386: fix ADOX followed by ADCX
|
||||
|
||||
When ADCX is followed by ADOX or vice versa, the second instruction's
|
||||
carry comes from EFLAGS and the condition codes use the CC_OP_ADCOX
|
||||
operation. Retrieving the carry from EFLAGS is handled by this bit
|
||||
of gen_ADCOX:
|
||||
|
||||
tcg_gen_extract_tl(carry_in, cpu_cc_src,
|
||||
ctz32(cc_op == CC_OP_ADCX ? CC_C : CC_O), 1);
|
||||
|
||||
Unfortunately, in this case cc_op has been overwritten by the previous
|
||||
"if" statement to CC_OP_ADCOX. This works by chance when the first
|
||||
instruction is ADCX; however, if the first instruction is ADOX,
|
||||
ADCX will incorrectly take its carry from OF instead of CF.
|
||||
|
||||
Fix by moving the computation of the new cc_op at the end of the function.
|
||||
The included exhaustive test case fails without this patch and passes
|
||||
afterwards.
|
||||
|
||||
Because ADCX/ADOX need not be invoked through the VEX prefix, this
|
||||
regression bisects to commit 16fc5726a6e2 ("target/i386: reimplement
|
||||
0x0f 0x38, add AVX", 2022-10-18). However, the mistake happened a
|
||||
little earlier, when BMI instructions were rewritten using the new
|
||||
decoder framework.
|
||||
|
||||
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1471
|
||||
Reported-by: Paul Jolly <https://gitlab.com/myitcv>
|
||||
Fixes: 1d0b926150e5 ("target/i386: move scalar 0F 38 and 0F 3A instruction to new decoder", 2022-10-18)
|
||||
Cc: qemu-stable@nongnu.org
|
||||
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
||||
(cherry-picked from commit 60c7dd22e1383754d5f150bc9f7c2785c662a7b6)
|
||||
Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
|
||||
---
|
||||
target/i386/tcg/emit.c.inc | 20 +++++----
|
||||
tests/tcg/i386/Makefile.target | 6 ++-
|
||||
tests/tcg/i386/test-i386-adcox.c | 75 ++++++++++++++++++++++++++++++++
|
||||
3 files changed, 91 insertions(+), 10 deletions(-)
|
||||
create mode 100644 tests/tcg/i386/test-i386-adcox.c
|
||||
|
||||
diff --git a/target/i386/tcg/emit.c.inc b/target/i386/tcg/emit.c.inc
|
||||
index 4d7702c106..0d7c6e80ae 100644
|
||||
--- a/target/i386/tcg/emit.c.inc
|
||||
+++ b/target/i386/tcg/emit.c.inc
|
||||
@@ -1015,6 +1015,7 @@ VSIB_AVX(VPGATHERQ, vpgatherq)
|
||||
|
||||
static void gen_ADCOX(DisasContext *s, CPUX86State *env, MemOp ot, int cc_op)
|
||||
{
|
||||
+ int opposite_cc_op;
|
||||
TCGv carry_in = NULL;
|
||||
TCGv carry_out = (cc_op == CC_OP_ADCX ? cpu_cc_dst : cpu_cc_src2);
|
||||
TCGv zero;
|
||||
@@ -1022,14 +1023,8 @@ static void gen_ADCOX(DisasContext *s, CPUX86State *env, MemOp ot, int cc_op)
|
||||
if (cc_op == s->cc_op || s->cc_op == CC_OP_ADCOX) {
|
||||
/* Re-use the carry-out from a previous round. */
|
||||
carry_in = carry_out;
|
||||
- cc_op = s->cc_op;
|
||||
- } else if (s->cc_op == CC_OP_ADCX || s->cc_op == CC_OP_ADOX) {
|
||||
- /* Merge with the carry-out from the opposite instruction. */
|
||||
- cc_op = CC_OP_ADCOX;
|
||||
- }
|
||||
-
|
||||
- /* If we don't have a carry-in, get it out of EFLAGS. */
|
||||
- if (!carry_in) {
|
||||
+ } else {
|
||||
+ /* We don't have a carry-in, get it out of EFLAGS. */
|
||||
if (s->cc_op != CC_OP_ADCX && s->cc_op != CC_OP_ADOX) {
|
||||
gen_compute_eflags(s);
|
||||
}
|
||||
@@ -1053,7 +1048,14 @@ static void gen_ADCOX(DisasContext *s, CPUX86State *env, MemOp ot, int cc_op)
|
||||
tcg_gen_add2_tl(s->T0, carry_out, s->T0, carry_out, s->T1, zero);
|
||||
break;
|
||||
}
|
||||
- set_cc_op(s, cc_op);
|
||||
+
|
||||
+ opposite_cc_op = cc_op == CC_OP_ADCX ? CC_OP_ADOX : CC_OP_ADCX;
|
||||
+ if (s->cc_op == CC_OP_ADCOX || s->cc_op == opposite_cc_op) {
|
||||
+ /* Merge with the carry-out from the opposite instruction. */
|
||||
+ set_cc_op(s, CC_OP_ADCOX);
|
||||
+ } else {
|
||||
+ set_cc_op(s, cc_op);
|
||||
+ }
|
||||
}
|
||||
|
||||
static void gen_ADCX(DisasContext *s, CPUX86State *env, X86DecodedInsn *decode)
|
||||
diff --git a/tests/tcg/i386/Makefile.target b/tests/tcg/i386/Makefile.target
|
||||
index 81831cafbc..bafd8c2180 100644
|
||||
--- a/tests/tcg/i386/Makefile.target
|
||||
+++ b/tests/tcg/i386/Makefile.target
|
||||
@@ -14,7 +14,7 @@ config-cc.mak: Makefile
|
||||
I386_SRCS=$(notdir $(wildcard $(I386_SRC)/*.c))
|
||||
ALL_X86_TESTS=$(I386_SRCS:.c=)
|
||||
SKIP_I386_TESTS=test-i386-ssse3 test-avx test-3dnow test-mmx
|
||||
-X86_64_TESTS:=$(filter test-i386-bmi2 $(SKIP_I386_TESTS), $(ALL_X86_TESTS))
|
||||
+X86_64_TESTS:=$(filter test-i386-adcox test-i386-bmi2 $(SKIP_I386_TESTS), $(ALL_X86_TESTS))
|
||||
|
||||
test-i386-sse-exceptions: CFLAGS += -msse4.1 -mfpmath=sse
|
||||
run-test-i386-sse-exceptions: QEMU_OPTS += -cpu max
|
||||
@@ -28,6 +28,10 @@ test-i386-bmi2: CFLAGS=-O2
|
||||
run-test-i386-bmi2: QEMU_OPTS += -cpu max
|
||||
run-plugin-test-i386-bmi2-%: QEMU_OPTS += -cpu max
|
||||
|
||||
+test-i386-adcox: CFLAGS=-O2
|
||||
+run-test-i386-adcox: QEMU_OPTS += -cpu max
|
||||
+run-plugin-test-i386-adcox-%: QEMU_OPTS += -cpu max
|
||||
+
|
||||
#
|
||||
# hello-i386 is a barebones app
|
||||
#
|
||||
diff --git a/tests/tcg/i386/test-i386-adcox.c b/tests/tcg/i386/test-i386-adcox.c
|
||||
new file mode 100644
|
||||
index 0000000000..16169efff8
|
||||
--- /dev/null
|
||||
+++ b/tests/tcg/i386/test-i386-adcox.c
|
||||
@@ -0,0 +1,75 @@
|
||||
+/* See if various BMI2 instructions give expected results */
|
||||
+#include <assert.h>
|
||||
+#include <stdint.h>
|
||||
+#include <stdio.h>
|
||||
+
|
||||
+#define CC_C 1
|
||||
+#define CC_O (1 << 11)
|
||||
+
|
||||
+#ifdef __x86_64__
|
||||
+#define REG uint64_t
|
||||
+#else
|
||||
+#define REG uint32_t
|
||||
+#endif
|
||||
+
|
||||
+void test_adox_adcx(uint32_t in_c, uint32_t in_o, REG adcx_operand, REG adox_operand)
|
||||
+{
|
||||
+ REG flags;
|
||||
+ REG out_adcx, out_adox;
|
||||
+
|
||||
+ asm("pushf; pop %0" : "=r"(flags));
|
||||
+ flags &= ~(CC_C | CC_O);
|
||||
+ flags |= (in_c ? CC_C : 0);
|
||||
+ flags |= (in_o ? CC_O : 0);
|
||||
+
|
||||
+ out_adcx = adcx_operand;
|
||||
+ out_adox = adox_operand;
|
||||
+ asm("push %0; popf;"
|
||||
+ "adox %3, %2;"
|
||||
+ "adcx %3, %1;"
|
||||
+ "pushf; pop %0"
|
||||
+ : "+r" (flags), "+r" (out_adcx), "+r" (out_adox)
|
||||
+ : "r" ((REG)-1), "0" (flags), "1" (out_adcx), "2" (out_adox));
|
||||
+
|
||||
+ assert(out_adcx == in_c + adcx_operand - 1);
|
||||
+ assert(out_adox == in_o + adox_operand - 1);
|
||||
+ assert(!!(flags & CC_C) == (in_c || adcx_operand));
|
||||
+ assert(!!(flags & CC_O) == (in_o || adox_operand));
|
||||
+}
|
||||
+
|
||||
+void test_adcx_adox(uint32_t in_c, uint32_t in_o, REG adcx_operand, REG adox_operand)
|
||||
+{
|
||||
+ REG flags;
|
||||
+ REG out_adcx, out_adox;
|
||||
+
|
||||
+ asm("pushf; pop %0" : "=r"(flags));
|
||||
+ flags &= ~(CC_C | CC_O);
|
||||
+ flags |= (in_c ? CC_C : 0);
|
||||
+ flags |= (in_o ? CC_O : 0);
|
||||
+
|
||||
+ out_adcx = adcx_operand;
|
||||
+ out_adox = adox_operand;
|
||||
+ asm("push %0; popf;"
|
||||
+ "adcx %3, %1;"
|
||||
+ "adox %3, %2;"
|
||||
+ "pushf; pop %0"
|
||||
+ : "+r" (flags), "+r" (out_adcx), "+r" (out_adox)
|
||||
+ : "r" ((REG)-1), "0" (flags), "1" (out_adcx), "2" (out_adox));
|
||||
+
|
||||
+ assert(out_adcx == in_c + adcx_operand - 1);
|
||||
+ assert(out_adox == in_o + adox_operand - 1);
|
||||
+ assert(!!(flags & CC_C) == (in_c || adcx_operand));
|
||||
+ assert(!!(flags & CC_O) == (in_o || adox_operand));
|
||||
+}
|
||||
+
|
||||
+int main(int argc, char *argv[]) {
|
||||
+ /* try all combinations of input CF, input OF, CF from op1+op2, OF from op2+op1 */
|
||||
+ int i;
|
||||
+ for (i = 0; i <= 15; i++) {
|
||||
+ printf("%d\n", i);
|
||||
+ test_adcx_adox(!!(i & 1), !!(i & 2), !!(i & 4), !!(i & 8));
|
||||
+ test_adox_adcx(!!(i & 1), !!(i & 2), !!(i & 4), !!(i & 8));
|
||||
+ }
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
@ -1,64 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Richard Henderson <richard.henderson@linaro.org>
|
||||
Date: Sat, 14 Jan 2023 13:32:06 -1000
|
||||
Subject: [PATCH] target/i386: Fix BZHI instruction
|
||||
|
||||
We did not correctly handle N >= operand size.
|
||||
|
||||
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1374
|
||||
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
|
||||
Message-Id: <20230114233206.3118472-1-richard.henderson@linaro.org>
|
||||
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
||||
(cherry-picked from commit 9ad2ba6e8e7fc195d0dd0b76ab38bd2fceb1bdd4)
|
||||
Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
|
||||
---
|
||||
target/i386/tcg/emit.c.inc | 14 +++++++-------
|
||||
tests/tcg/i386/test-i386-bmi2.c | 3 +++
|
||||
2 files changed, 10 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/target/i386/tcg/emit.c.inc b/target/i386/tcg/emit.c.inc
|
||||
index 0d7c6e80ae..7296f3952c 100644
|
||||
--- a/target/i386/tcg/emit.c.inc
|
||||
+++ b/target/i386/tcg/emit.c.inc
|
||||
@@ -1145,20 +1145,20 @@ static void gen_BLSR(DisasContext *s, CPUX86State *env, X86DecodedInsn *decode)
|
||||
static void gen_BZHI(DisasContext *s, CPUX86State *env, X86DecodedInsn *decode)
|
||||
{
|
||||
MemOp ot = decode->op[0].ot;
|
||||
- TCGv bound;
|
||||
+ TCGv bound = tcg_constant_tl(ot == MO_64 ? 63 : 31);
|
||||
+ TCGv zero = tcg_constant_tl(0);
|
||||
+ TCGv mone = tcg_constant_tl(-1);
|
||||
|
||||
- tcg_gen_ext8u_tl(s->T1, cpu_regs[s->vex_v]);
|
||||
- bound = tcg_constant_tl(ot == MO_64 ? 63 : 31);
|
||||
+ tcg_gen_ext8u_tl(s->T1, s->T1);
|
||||
|
||||
/*
|
||||
* Note that since we're using BMILG (in order to get O
|
||||
* cleared) we need to store the inverse into C.
|
||||
*/
|
||||
- tcg_gen_setcond_tl(TCG_COND_LT, cpu_cc_src, s->T1, bound);
|
||||
- tcg_gen_movcond_tl(TCG_COND_GT, s->T1, s->T1, bound, bound, s->T1);
|
||||
+ tcg_gen_setcond_tl(TCG_COND_LEU, cpu_cc_src, s->T1, bound);
|
||||
|
||||
- tcg_gen_movi_tl(s->A0, -1);
|
||||
- tcg_gen_shl_tl(s->A0, s->A0, s->T1);
|
||||
+ tcg_gen_shl_tl(s->A0, mone, s->T1);
|
||||
+ tcg_gen_movcond_tl(TCG_COND_LEU, s->A0, s->T1, bound, s->A0, zero);
|
||||
tcg_gen_andc_tl(s->T0, s->T0, s->A0);
|
||||
|
||||
gen_op_update1_cc(s);
|
||||
diff --git a/tests/tcg/i386/test-i386-bmi2.c b/tests/tcg/i386/test-i386-bmi2.c
|
||||
index 982d4abda4..0244df7987 100644
|
||||
--- a/tests/tcg/i386/test-i386-bmi2.c
|
||||
+++ b/tests/tcg/i386/test-i386-bmi2.c
|
||||
@@ -123,6 +123,9 @@ int main(int argc, char *argv[]) {
|
||||
result = bzhiq(mask, 0x1f);
|
||||
assert(result == (mask & ~(-1 << 30)));
|
||||
|
||||
+ result = bzhiq(mask, 0x40);
|
||||
+ assert(result == mask);
|
||||
+
|
||||
result = rorxq(0x2132435465768798, 8);
|
||||
assert(result == 0x9821324354657687);
|
||||
|
@ -14,10 +14,10 @@ Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/block/file-posix.c b/block/file-posix.c
|
||||
index b9647c5ffc..9a16d86344 100644
|
||||
index c2dee3f056..9681bd0434 100644
|
||||
--- a/block/file-posix.c
|
||||
+++ b/block/file-posix.c
|
||||
@@ -552,7 +552,7 @@ static QemuOptsList raw_runtime_opts = {
|
||||
@@ -553,7 +553,7 @@ static QemuOptsList raw_runtime_opts = {
|
||||
{
|
||||
.name = "locking",
|
||||
.type = QEMU_OPT_STRING,
|
||||
@ -26,7 +26,7 @@ index b9647c5ffc..9a16d86344 100644
|
||||
},
|
||||
{
|
||||
.name = "pr-manager",
|
||||
@@ -652,7 +652,7 @@ static int raw_open_common(BlockDriverState *bs, QDict *options,
|
||||
@@ -653,7 +653,7 @@ static int raw_open_common(BlockDriverState *bs, QDict *options,
|
||||
s->use_lock = false;
|
||||
break;
|
||||
case ON_OFF_AUTO_AUTO:
|
||||
|
@ -9,10 +9,10 @@ Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/include/net/net.h b/include/net/net.h
|
||||
index dc20b31e9f..5ae04a8693 100644
|
||||
index 1448d00afb..d1601d32c1 100644
|
||||
--- a/include/net/net.h
|
||||
+++ b/include/net/net.h
|
||||
@@ -236,8 +236,8 @@ void netdev_add(QemuOpts *opts, Error **errp);
|
||||
@@ -258,8 +258,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);
|
||||
|
||||
|
@ -10,10 +10,10 @@ Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/target/i386/cpu.h b/target/i386/cpu.h
|
||||
index d4bc19577a..be7da64f38 100644
|
||||
index d243e290d3..3489b05ec4 100644
|
||||
--- a/target/i386/cpu.h
|
||||
+++ b/target/i386/cpu.h
|
||||
@@ -2174,9 +2174,9 @@ uint64_t cpu_get_tsc(CPUX86State *env);
|
||||
@@ -2203,9 +2203,9 @@ uint64_t cpu_get_tsc(CPUX86State *env);
|
||||
#define CPU_RESOLVING_TYPE TYPE_X86_CPU
|
||||
|
||||
#ifdef TARGET_X86_64
|
||||
|
@ -9,10 +9,10 @@ Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
|
||||
1 file changed, 9 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/ui/spice-core.c b/ui/spice-core.c
|
||||
index c3ac20ad43..37774f1c0a 100644
|
||||
index 52a59386d7..b20c25aee0 100644
|
||||
--- a/ui/spice-core.c
|
||||
+++ b/ui/spice-core.c
|
||||
@@ -689,32 +689,35 @@ static void qemu_spice_init(void)
|
||||
@@ -691,32 +691,35 @@ static void qemu_spice_init(void)
|
||||
|
||||
if (tls_port) {
|
||||
x509_dir = qemu_opt_get(opts, "x509-dir");
|
||||
|
@ -9,10 +9,10 @@ Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
|
||||
1 file changed, 11 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/block/gluster.c b/block/gluster.c
|
||||
index 7c90f7ba4b..2e03102f00 100644
|
||||
index 185a83e5e5..f11a40aa9e 100644
|
||||
--- a/block/gluster.c
|
||||
+++ b/block/gluster.c
|
||||
@@ -42,7 +42,7 @@
|
||||
@@ -43,7 +43,7 @@
|
||||
#define GLUSTER_DEBUG_DEFAULT 4
|
||||
#define GLUSTER_DEBUG_MAX 9
|
||||
#define GLUSTER_OPT_LOGFILE "logfile"
|
||||
@ -21,7 +21,7 @@ index 7c90f7ba4b..2e03102f00 100644
|
||||
/*
|
||||
* Several versions of GlusterFS (3.12? -> 6.0.1) fail when the transfer size
|
||||
* is greater or equal to 1024 MiB, so we are limiting the transfer size to 512
|
||||
@@ -424,6 +424,7 @@ static struct glfs *qemu_gluster_glfs_init(BlockdevOptionsGluster *gconf,
|
||||
@@ -425,6 +425,7 @@ static struct glfs *qemu_gluster_glfs_init(BlockdevOptionsGluster *gconf,
|
||||
int old_errno;
|
||||
SocketAddressList *server;
|
||||
unsigned long long port;
|
||||
@ -29,7 +29,7 @@ index 7c90f7ba4b..2e03102f00 100644
|
||||
|
||||
glfs = glfs_find_preopened(gconf->volume);
|
||||
if (glfs) {
|
||||
@@ -466,9 +467,15 @@ static struct glfs *qemu_gluster_glfs_init(BlockdevOptionsGluster *gconf,
|
||||
@@ -467,9 +468,15 @@ static struct glfs *qemu_gluster_glfs_init(BlockdevOptionsGluster *gconf,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -18,10 +18,10 @@ Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
|
||||
1 file changed, 2 insertions(+)
|
||||
|
||||
diff --git a/block/rbd.c b/block/rbd.c
|
||||
index f826410f40..64a8d7d48b 100644
|
||||
index 978671411e..a4749f3b1b 100644
|
||||
--- a/block/rbd.c
|
||||
+++ b/block/rbd.c
|
||||
@@ -820,6 +820,8 @@ static int qemu_rbd_connect(rados_t *cluster, rados_ioctx_t *io_ctx,
|
||||
@@ -963,6 +963,8 @@ static int qemu_rbd_connect(rados_t *cluster, rados_ioctx_t *io_ctx,
|
||||
rados_conf_set(*cluster, "rbd_cache", "false");
|
||||
}
|
||||
|
||||
|
@ -13,11 +13,11 @@ Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
|
||||
3 files changed, 44 insertions(+)
|
||||
|
||||
diff --git a/net/net.c b/net/net.c
|
||||
index 840ad9dca5..28e97c5d85 100644
|
||||
index 6492ad530e..33e901cba8 100644
|
||||
--- a/net/net.c
|
||||
+++ b/net/net.c
|
||||
@@ -1372,6 +1372,33 @@ void hmp_info_network(Monitor *mon, const QDict *qdict)
|
||||
}
|
||||
@@ -1397,6 +1397,33 @@ RxFilterInfoList *qmp_query_rx_filter(const char *name, Error **errp)
|
||||
return filter_list;
|
||||
}
|
||||
|
||||
+int64_t qmp_get_link_status(const char *name, Error **errp)
|
||||
@ -51,7 +51,7 @@ index 840ad9dca5..28e97c5d85 100644
|
||||
{
|
||||
NetClientState *nc;
|
||||
diff --git a/qapi/net.json b/qapi/net.json
|
||||
index 522ac582ed..327d7c5a37 100644
|
||||
index d6eb30008b..4fe71b149d 100644
|
||||
--- a/qapi/net.json
|
||||
+++ b/qapi/net.json
|
||||
@@ -36,6 +36,21 @@
|
||||
|
@ -16,10 +16,10 @@ Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
|
||||
1 file changed, 9 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/block/gluster.c b/block/gluster.c
|
||||
index 2e03102f00..7886c5fe8c 100644
|
||||
index f11a40aa9e..6756e6b886 100644
|
||||
--- a/block/gluster.c
|
||||
+++ b/block/gluster.c
|
||||
@@ -57,6 +57,7 @@ typedef struct GlusterAIOCB {
|
||||
@@ -58,6 +58,7 @@ typedef struct GlusterAIOCB {
|
||||
int ret;
|
||||
Coroutine *coroutine;
|
||||
AioContext *aio_context;
|
||||
@ -27,7 +27,7 @@ index 2e03102f00..7886c5fe8c 100644
|
||||
} GlusterAIOCB;
|
||||
|
||||
typedef struct BDRVGlusterState {
|
||||
@@ -752,8 +753,10 @@ static void gluster_finish_aiocb(struct glfs_fd *fd, ssize_t ret,
|
||||
@@ -753,8 +754,10 @@ static void gluster_finish_aiocb(struct glfs_fd *fd, ssize_t ret,
|
||||
acb->ret = 0; /* Success */
|
||||
} else if (ret < 0) {
|
||||
acb->ret = -errno; /* Read/Write failed */
|
||||
@ -39,7 +39,7 @@ index 2e03102f00..7886c5fe8c 100644
|
||||
}
|
||||
|
||||
aio_co_schedule(acb->aio_context, acb->coroutine);
|
||||
@@ -1022,6 +1025,7 @@ static coroutine_fn int qemu_gluster_co_pwrite_zeroes(BlockDriverState *bs,
|
||||
@@ -1021,6 +1024,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 2e03102f00..7886c5fe8c 100644
|
||||
|
||||
ret = glfs_zerofill_async(s->fd, offset, bytes, gluster_finish_aiocb, &acb);
|
||||
if (ret < 0) {
|
||||
@@ -1203,9 +1207,11 @@ static coroutine_fn int qemu_gluster_co_rw(BlockDriverState *bs,
|
||||
@@ -1201,9 +1205,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 2e03102f00..7886c5fe8c 100644
|
||||
ret = glfs_preadv_async(s->fd, qiov->iov, qiov->niov, offset, 0,
|
||||
gluster_finish_aiocb, &acb);
|
||||
}
|
||||
@@ -1268,6 +1274,7 @@ static coroutine_fn int qemu_gluster_co_flush_to_disk(BlockDriverState *bs)
|
||||
@@ -1266,6 +1272,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 2e03102f00..7886c5fe8c 100644
|
||||
|
||||
ret = glfs_fsync_async(s->fd, gluster_finish_aiocb, &acb);
|
||||
if (ret < 0) {
|
||||
@@ -1316,6 +1323,7 @@ static coroutine_fn int qemu_gluster_co_pdiscard(BlockDriverState *bs,
|
||||
@@ -1314,6 +1321,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);
|
||||
|
@ -9,10 +9,10 @@ Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
|
||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/qemu-img.c b/qemu-img.c
|
||||
index a9b3a8103c..0bc9f1af59 100644
|
||||
index 9aeac69fa6..0919fac1f1 100644
|
||||
--- a/qemu-img.c
|
||||
+++ b/qemu-img.c
|
||||
@@ -3013,7 +3013,8 @@ static int img_info(int argc, char **argv)
|
||||
@@ -3059,7 +3059,8 @@ static int img_info(int argc, char **argv)
|
||||
list = collect_image_info_list(image_opts, filename, fmt, chain,
|
||||
force_share);
|
||||
if (!list) {
|
||||
|
@ -54,10 +54,10 @@ index 1b1dab5b17..d1616c045a 100644
|
||||
|
||||
DEF("info", img_info,
|
||||
diff --git a/qemu-img.c b/qemu-img.c
|
||||
index 0bc9f1af59..221b9d6a16 100644
|
||||
index 0919fac1f1..c584de648c 100644
|
||||
--- a/qemu-img.c
|
||||
+++ b/qemu-img.c
|
||||
@@ -4829,10 +4829,12 @@ static int img_bitmap(int argc, char **argv)
|
||||
@@ -4885,10 +4885,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 0bc9f1af59..221b9d6a16 100644
|
||||
};
|
||||
|
||||
struct DdIo {
|
||||
@@ -4908,6 +4910,19 @@ static int img_dd_skip(const char *arg,
|
||||
@@ -4964,6 +4966,19 @@ static int img_dd_skip(const char *arg,
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -90,7 +90,7 @@ index 0bc9f1af59..221b9d6a16 100644
|
||||
static int img_dd(int argc, char **argv)
|
||||
{
|
||||
int ret = 0;
|
||||
@@ -4948,6 +4963,7 @@ static int img_dd(int argc, char **argv)
|
||||
@@ -5004,6 +5019,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 0bc9f1af59..221b9d6a16 100644
|
||||
{ NULL, NULL, 0 }
|
||||
};
|
||||
const struct option long_options[] = {
|
||||
@@ -5023,91 +5039,112 @@ static int img_dd(int argc, char **argv)
|
||||
@@ -5079,91 +5095,112 @@ static int img_dd(int argc, char **argv)
|
||||
arg = NULL;
|
||||
}
|
||||
|
||||
@ -275,7 +275,7 @@ index 0bc9f1af59..221b9d6a16 100644
|
||||
}
|
||||
|
||||
if (dd.flags & C_SKIP && (in.offset > INT64_MAX / in.bsz ||
|
||||
@@ -5124,20 +5161,43 @@ static int img_dd(int argc, char **argv)
|
||||
@@ -5180,20 +5217,43 @@ static int img_dd(int argc, char **argv)
|
||||
in.buf = g_new(uint8_t, in.bsz);
|
||||
|
||||
for (out_pos = 0; in_pos < size; ) {
|
||||
|
@ -16,10 +16,10 @@ Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
|
||||
1 file changed, 25 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/qemu-img.c b/qemu-img.c
|
||||
index 221b9d6a16..c1306385a8 100644
|
||||
index c584de648c..a57ceeddfe 100644
|
||||
--- a/qemu-img.c
|
||||
+++ b/qemu-img.c
|
||||
@@ -4830,11 +4830,13 @@ static int img_bitmap(int argc, char **argv)
|
||||
@@ -4886,11 +4886,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 221b9d6a16..c1306385a8 100644
|
||||
};
|
||||
|
||||
struct DdIo {
|
||||
@@ -4923,6 +4925,19 @@ static int img_dd_osize(const char *arg,
|
||||
@@ -4979,6 +4981,19 @@ static int img_dd_osize(const char *arg,
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -53,7 +53,7 @@ index 221b9d6a16..c1306385a8 100644
|
||||
static int img_dd(int argc, char **argv)
|
||||
{
|
||||
int ret = 0;
|
||||
@@ -4937,12 +4952,14 @@ static int img_dd(int argc, char **argv)
|
||||
@@ -4993,12 +5008,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 221b9d6a16..c1306385a8 100644
|
||||
};
|
||||
struct DdIo in = {
|
||||
.bsz = 512, /* Block size is by default 512 bytes */
|
||||
@@ -4964,6 +4981,7 @@ static int img_dd(int argc, char **argv)
|
||||
@@ -5020,6 +5037,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 221b9d6a16..c1306385a8 100644
|
||||
{ NULL, NULL, 0 }
|
||||
};
|
||||
const struct option long_options[] = {
|
||||
@@ -5160,9 +5178,10 @@ static int img_dd(int argc, char **argv)
|
||||
@@ -5216,9 +5234,10 @@ static int img_dd(int argc, char **argv)
|
||||
|
||||
in.buf = g_new(uint8_t, in.bsz);
|
||||
|
||||
@ -90,7 +90,7 @@ index 221b9d6a16..c1306385a8 100644
|
||||
if (blk1) {
|
||||
in_ret = blk_pread(blk1, in_pos, bytes, in.buf, 0);
|
||||
if (in_ret == 0) {
|
||||
@@ -5171,6 +5190,9 @@ static int img_dd(int argc, char **argv)
|
||||
@@ -5227,6 +5246,9 @@ static int img_dd(int argc, char **argv)
|
||||
} else {
|
||||
in_ret = read(STDIN_FILENO, in.buf, bytes);
|
||||
if (in_ret == 0) {
|
||||
|
@ -65,10 +65,10 @@ index d1616c045a..b5b0bb4467 100644
|
||||
|
||||
DEF("info", img_info,
|
||||
diff --git a/qemu-img.c b/qemu-img.c
|
||||
index c1306385a8..59c403373b 100644
|
||||
index a57ceeddfe..06d814e39c 100644
|
||||
--- a/qemu-img.c
|
||||
+++ b/qemu-img.c
|
||||
@@ -4954,7 +4954,7 @@ static int img_dd(int argc, char **argv)
|
||||
@@ -5010,7 +5010,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 c1306385a8..59c403373b 100644
|
||||
struct DdInfo dd = {
|
||||
.flags = 0,
|
||||
.count = 0,
|
||||
@@ -4992,7 +4992,7 @@ static int img_dd(int argc, char **argv)
|
||||
@@ -5048,7 +5048,7 @@ static int img_dd(int argc, char **argv)
|
||||
{ 0, 0, 0, 0 }
|
||||
};
|
||||
|
||||
@ -86,7 +86,7 @@ index c1306385a8..59c403373b 100644
|
||||
if (c == EOF) {
|
||||
break;
|
||||
}
|
||||
@@ -5012,6 +5012,9 @@ static int img_dd(int argc, char **argv)
|
||||
@@ -5068,6 +5068,9 @@ static int img_dd(int argc, char **argv)
|
||||
case 'h':
|
||||
help();
|
||||
break;
|
||||
@ -96,7 +96,7 @@ index c1306385a8..59c403373b 100644
|
||||
case 'U':
|
||||
force_share = true;
|
||||
break;
|
||||
@@ -5142,13 +5145,15 @@ static int img_dd(int argc, char **argv)
|
||||
@@ -5198,13 +5201,15 @@ static int img_dd(int argc, char **argv)
|
||||
size - in.bsz * in.offset, &error_abort);
|
||||
}
|
||||
|
||||
|
@ -7,20 +7,62 @@ Actually provide memory information via the query-balloon
|
||||
command.
|
||||
|
||||
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
|
||||
[FE: add BalloonInfo to member name exceptions list]
|
||||
[FE: add BalloonInfo to member name exceptions list
|
||||
rebase for 8.0 - moved to hw/core/machine-hmp-cmds.c]
|
||||
Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
|
||||
---
|
||||
hw/core/machine-hmp-cmds.c | 30 +++++++++++++++++++++++++++++-
|
||||
hw/virtio/virtio-balloon.c | 33 +++++++++++++++++++++++++++++++--
|
||||
monitor/hmp-cmds.c | 30 +++++++++++++++++++++++++++++-
|
||||
qapi/machine.json | 22 +++++++++++++++++++++-
|
||||
qapi/pragma.json | 1 +
|
||||
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
|
||||
--- 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)
|
||||
return;
|
||||
}
|
||||
|
||||
- monitor_printf(mon, "balloon: actual=%" PRId64 "\n", info->actual >> 20);
|
||||
+ monitor_printf(mon, "balloon: actual=%" PRId64, info->actual >> 20);
|
||||
+ monitor_printf(mon, " max_mem=%" PRId64, info->max_mem >> 20);
|
||||
+ if (info->has_total_mem) {
|
||||
+ monitor_printf(mon, " total_mem=%" PRId64, info->total_mem >> 20);
|
||||
+ }
|
||||
+ if (info->has_free_mem) {
|
||||
+ monitor_printf(mon, " free_mem=%" PRId64, info->free_mem >> 20);
|
||||
+ }
|
||||
+
|
||||
+ if (info->has_mem_swapped_in) {
|
||||
+ monitor_printf(mon, " mem_swapped_in=%" PRId64, info->mem_swapped_in);
|
||||
+ }
|
||||
+ if (info->has_mem_swapped_out) {
|
||||
+ monitor_printf(mon, " mem_swapped_out=%" PRId64, info->mem_swapped_out);
|
||||
+ }
|
||||
+ if (info->has_major_page_faults) {
|
||||
+ monitor_printf(mon, " major_page_faults=%" PRId64,
|
||||
+ info->major_page_faults);
|
||||
+ }
|
||||
+ if (info->has_minor_page_faults) {
|
||||
+ monitor_printf(mon, " minor_page_faults=%" PRId64,
|
||||
+ info->minor_page_faults);
|
||||
+ }
|
||||
+ if (info->has_last_update) {
|
||||
+ monitor_printf(mon, " last_update=%" PRId64,
|
||||
+ info->last_update);
|
||||
+ }
|
||||
+
|
||||
+ monitor_printf(mon, "\n");
|
||||
|
||||
qapi_free_BalloonInfo(info);
|
||||
}
|
||||
diff --git a/hw/virtio/virtio-balloon.c b/hw/virtio/virtio-balloon.c
|
||||
index 73ac5eb675..bbfe7eca62 100644
|
||||
index 746f07c4d2..a41854b902 100644
|
||||
--- a/hw/virtio/virtio-balloon.c
|
||||
+++ b/hw/virtio/virtio-balloon.c
|
||||
@@ -806,8 +806,37 @@ static uint64_t virtio_balloon_get_features(VirtIODevice *vdev, uint64_t f,
|
||||
@@ -804,8 +804,37 @@ static uint64_t virtio_balloon_get_features(VirtIODevice *vdev, uint64_t f,
|
||||
static void virtio_balloon_stat(void *opaque, BalloonInfo *info)
|
||||
{
|
||||
VirtIOBalloon *dev = opaque;
|
||||
@ -60,52 +102,11 @@ index 73ac5eb675..bbfe7eca62 100644
|
||||
}
|
||||
|
||||
static void virtio_balloon_to_target(void *opaque, ram_addr_t target)
|
||||
diff --git a/monitor/hmp-cmds.c b/monitor/hmp-cmds.c
|
||||
index 01b789a79e..480b798963 100644
|
||||
--- a/monitor/hmp-cmds.c
|
||||
+++ b/monitor/hmp-cmds.c
|
||||
@@ -696,7 +696,35 @@ void hmp_info_balloon(Monitor *mon, const QDict *qdict)
|
||||
return;
|
||||
}
|
||||
|
||||
- monitor_printf(mon, "balloon: actual=%" PRId64 "\n", info->actual >> 20);
|
||||
+ monitor_printf(mon, "balloon: actual=%" PRId64, info->actual >> 20);
|
||||
+ monitor_printf(mon, " max_mem=%" PRId64, info->max_mem >> 20);
|
||||
+ if (info->has_total_mem) {
|
||||
+ monitor_printf(mon, " total_mem=%" PRId64, info->total_mem >> 20);
|
||||
+ }
|
||||
+ if (info->has_free_mem) {
|
||||
+ monitor_printf(mon, " free_mem=%" PRId64, info->free_mem >> 20);
|
||||
+ }
|
||||
+
|
||||
+ if (info->has_mem_swapped_in) {
|
||||
+ monitor_printf(mon, " mem_swapped_in=%" PRId64, info->mem_swapped_in);
|
||||
+ }
|
||||
+ if (info->has_mem_swapped_out) {
|
||||
+ monitor_printf(mon, " mem_swapped_out=%" PRId64, info->mem_swapped_out);
|
||||
+ }
|
||||
+ if (info->has_major_page_faults) {
|
||||
+ monitor_printf(mon, " major_page_faults=%" PRId64,
|
||||
+ info->major_page_faults);
|
||||
+ }
|
||||
+ if (info->has_minor_page_faults) {
|
||||
+ monitor_printf(mon, " minor_page_faults=%" PRId64,
|
||||
+ info->minor_page_faults);
|
||||
+ }
|
||||
+ if (info->has_last_update) {
|
||||
+ monitor_printf(mon, " last_update=%" PRId64,
|
||||
+ info->last_update);
|
||||
+ }
|
||||
+
|
||||
+ monitor_printf(mon, "\n");
|
||||
|
||||
qapi_free_BalloonInfo(info);
|
||||
}
|
||||
diff --git a/qapi/machine.json b/qapi/machine.json
|
||||
index b9228a5e46..10e77a9af3 100644
|
||||
index 604b686e59..15f5f86683 100644
|
||||
--- a/qapi/machine.json
|
||||
+++ b/qapi/machine.json
|
||||
@@ -1054,9 +1054,29 @@
|
||||
@@ -1056,9 +1056,29 @@
|
||||
# @actual: the logical size of the VM in bytes
|
||||
# Formula used: logical_vm_size = vm_ram_size - balloon_size
|
||||
#
|
||||
|
@ -13,13 +13,13 @@ Signed-off-by: Dietmar Maurer <dietmar@proxmox.com>
|
||||
2 files changed, 9 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/hw/core/machine-qmp-cmds.c b/hw/core/machine-qmp-cmds.c
|
||||
index 4f4ab30f8c..76fff60a6b 100644
|
||||
index b98ff15089..24595f618c 100644
|
||||
--- a/hw/core/machine-qmp-cmds.c
|
||||
+++ b/hw/core/machine-qmp-cmds.c
|
||||
@@ -99,6 +99,12 @@ MachineInfoList *qmp_query_machines(Error **errp)
|
||||
info->hotpluggable_cpus = mc->has_hotpluggable_cpus;
|
||||
@@ -103,6 +103,12 @@ MachineInfoList *qmp_query_machines(Error **errp)
|
||||
info->numa_mem_supported = mc->numa_mem_supported;
|
||||
info->deprecated = !!mc->deprecation_reason;
|
||||
info->acpi = !!object_class_property_find(OBJECT_CLASS(mc), "acpi");
|
||||
+
|
||||
+ if (strcmp(mc->name, MACHINE_GET_CLASS(current_machine)->name) == 0) {
|
||||
+ info->has_is_current = true;
|
||||
@ -28,9 +28,9 @@ index 4f4ab30f8c..76fff60a6b 100644
|
||||
+
|
||||
if (mc->default_cpu_type) {
|
||||
info->default_cpu_type = g_strdup(mc->default_cpu_type);
|
||||
info->has_default_cpu_type = true;
|
||||
}
|
||||
diff --git a/qapi/machine.json b/qapi/machine.json
|
||||
index 10e77a9af3..9156103c8f 100644
|
||||
index 15f5f86683..c904280085 100644
|
||||
--- a/qapi/machine.json
|
||||
+++ b/qapi/machine.json
|
||||
@@ -138,6 +138,8 @@
|
||||
@ -42,7 +42,7 @@ index 10e77a9af3..9156103c8f 100644
|
||||
# @cpu-max: maximum number of CPUs supported by the machine type
|
||||
# (since 1.5)
|
||||
#
|
||||
@@ -159,7 +161,7 @@
|
||||
@@ -161,7 +163,7 @@
|
||||
##
|
||||
{ 'struct': 'MachineInfo',
|
||||
'data': { 'name': 'str', '*alias': 'str',
|
||||
@ -50,4 +50,4 @@ index 10e77a9af3..9156103c8f 100644
|
||||
+ '*is-default': 'bool', '*is-current': 'bool', 'cpu-max': 'int',
|
||||
'hotpluggable-cpus': 'bool', 'numa-mem-supported': 'bool',
|
||||
'deprecated': 'bool', '*default-cpu-type': 'str',
|
||||
'*default-ram-id': 'str' } }
|
||||
'*default-ram-id': 'str', 'acpi': 'bool' } }
|
||||
|
@ -6,13 +6,15 @@ Subject: [PATCH] PVE: qapi: modify spice query
|
||||
Provide the last ticket in the SpiceInfo struct optionally.
|
||||
|
||||
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
|
||||
[FE: adapt to QAPI change]
|
||||
Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
|
||||
---
|
||||
qapi/ui.json | 3 +++
|
||||
ui/spice-core.c | 5 +++++
|
||||
2 files changed, 8 insertions(+)
|
||||
ui/spice-core.c | 4 ++++
|
||||
2 files changed, 7 insertions(+)
|
||||
|
||||
diff --git a/qapi/ui.json b/qapi/ui.json
|
||||
index 0abba3e930..bf8f441227 100644
|
||||
index 98322342f7..316d4dc933 100644
|
||||
--- a/qapi/ui.json
|
||||
+++ b/qapi/ui.json
|
||||
@@ -310,11 +310,14 @@
|
||||
@ -31,15 +33,14 @@ index 0abba3e930..bf8f441227 100644
|
||||
'if': 'CONFIG_SPICE' }
|
||||
|
||||
diff --git a/ui/spice-core.c b/ui/spice-core.c
|
||||
index 37774f1c0a..367f77f2b4 100644
|
||||
index b20c25aee0..26baeb7846 100644
|
||||
--- a/ui/spice-core.c
|
||||
+++ b/ui/spice-core.c
|
||||
@@ -534,6 +534,11 @@ static SpiceInfo *qmp_query_spice_real(Error **errp)
|
||||
@@ -548,6 +548,10 @@ static SpiceInfo *qmp_query_spice_real(Error **errp)
|
||||
micro = SPICE_SERVER_VERSION & 0xff;
|
||||
info->compiled_version = g_strdup_printf("%d.%d.%d", major, minor, micro);
|
||||
|
||||
+ if (auth_passwd) {
|
||||
+ info->has_ticket = true;
|
||||
+ info->ticket = g_strdup(auth_passwd);
|
||||
+ }
|
||||
+
|
||||
|
@ -15,19 +15,19 @@ Additionally, allows tracking the current position from the outside
|
||||
|
||||
Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
|
||||
---
|
||||
migration/channel-savevm-async.c | 182 +++++++++++++++++++++++++++++++
|
||||
migration/channel-savevm-async.c | 183 +++++++++++++++++++++++++++++++
|
||||
migration/channel-savevm-async.h | 51 +++++++++
|
||||
migration/meson.build | 1 +
|
||||
3 files changed, 234 insertions(+)
|
||||
3 files changed, 235 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..06d5484778
|
||||
index 0000000000..aab081ce07
|
||||
--- /dev/null
|
||||
+++ b/migration/channel-savevm-async.c
|
||||
@@ -0,0 +1,182 @@
|
||||
@@ -0,0 +1,183 @@
|
||||
+/*
|
||||
+ * QIO Channel implementation to be used by savevm-async QMP calls
|
||||
+ */
|
||||
@ -71,6 +71,7 @@ index 0000000000..06d5484778
|
||||
+ size_t niov,
|
||||
+ int **fds,
|
||||
+ size_t *nfds,
|
||||
+ int flags,
|
||||
+ Error **errp)
|
||||
+{
|
||||
+ QIOChannelSavevmAsync *saioc = QIO_CHANNEL_SAVEVM_ASYNC(ioc);
|
||||
@ -268,7 +269,7 @@ index 0000000000..17ae2cb261
|
||||
+
|
||||
+#endif /* QIO_CHANNEL_SAVEVM_ASYNC_H */
|
||||
diff --git a/migration/meson.build b/migration/meson.build
|
||||
index 690487cf1a..8cac83c06c 100644
|
||||
index 0d1bb9f96e..8a142fc7a9 100644
|
||||
--- a/migration/meson.build
|
||||
+++ b/migration/meson.build
|
||||
@@ -13,6 +13,7 @@ softmmu_ss.add(files(
|
||||
|
@ -25,7 +25,8 @@ Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
|
||||
Signed-off-by: Stefan Reiter <s.reiter@proxmox.com>
|
||||
[FE: further improve aborting
|
||||
adapt to removal of QEMUFileOps
|
||||
improve condition for entering final stage]
|
||||
improve condition for entering final stage
|
||||
adapt to QAPI and other changes for 8.0]
|
||||
Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
|
||||
---
|
||||
hmp-commands-info.hx | 13 +
|
||||
@ -33,17 +34,17 @@ Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
|
||||
include/migration/snapshot.h | 2 +
|
||||
include/monitor/hmp.h | 5 +
|
||||
migration/meson.build | 1 +
|
||||
migration/savevm-async.c | 538 +++++++++++++++++++++++++++++++++++
|
||||
monitor/hmp-cmds.c | 57 ++++
|
||||
migration/savevm-async.c | 535 +++++++++++++++++++++++++++++++++++
|
||||
monitor/hmp-cmds.c | 58 ++++
|
||||
qapi/migration.json | 34 +++
|
||||
qapi/misc.json | 32 +++
|
||||
qemu-options.hx | 12 +
|
||||
softmmu/vl.c | 10 +
|
||||
11 files changed, 737 insertions(+)
|
||||
11 files changed, 735 insertions(+)
|
||||
create mode 100644 migration/savevm-async.c
|
||||
|
||||
diff --git a/hmp-commands-info.hx b/hmp-commands-info.hx
|
||||
index 754b1e8408..489c524e9e 100644
|
||||
index 47d63d26db..a166bff3d5 100644
|
||||
--- a/hmp-commands-info.hx
|
||||
+++ b/hmp-commands-info.hx
|
||||
@@ -540,6 +540,19 @@ SRST
|
||||
@ -67,11 +68,11 @@ index 754b1e8408..489c524e9e 100644
|
||||
.name = "balloon",
|
||||
.args_type = "",
|
||||
diff --git a/hmp-commands.hx b/hmp-commands.hx
|
||||
index 673e39a697..039be0033d 100644
|
||||
index bb85ee1d26..b66d7fc4ab 100644
|
||||
--- a/hmp-commands.hx
|
||||
+++ b/hmp-commands.hx
|
||||
@@ -1815,3 +1815,36 @@ SRST
|
||||
Dump the FDT in dtb format to *filename*.
|
||||
@@ -1846,3 +1846,36 @@ SRST
|
||||
List event channels in the guest
|
||||
ERST
|
||||
#endif
|
||||
+
|
||||
@ -119,10 +120,10 @@ index e72083b117..c846d37806 100644
|
||||
+
|
||||
#endif
|
||||
diff --git a/include/monitor/hmp.h b/include/monitor/hmp.h
|
||||
index dfbc0c9a2f..440f86aba8 100644
|
||||
index fdb69b7f9c..c012bad741 100644
|
||||
--- a/include/monitor/hmp.h
|
||||
+++ b/include/monitor/hmp.h
|
||||
@@ -27,6 +27,7 @@ void hmp_info_status(Monitor *mon, const QDict *qdict);
|
||||
@@ -28,6 +28,7 @@ void hmp_info_status(Monitor *mon, const QDict *qdict);
|
||||
void hmp_info_uuid(Monitor *mon, const QDict *qdict);
|
||||
void hmp_info_chardev(Monitor *mon, const QDict *qdict);
|
||||
void hmp_info_mice(Monitor *mon, const QDict *qdict);
|
||||
@ -130,10 +131,10 @@ index dfbc0c9a2f..440f86aba8 100644
|
||||
void hmp_info_migrate(Monitor *mon, const QDict *qdict);
|
||||
void hmp_info_migrate_capabilities(Monitor *mon, const QDict *qdict);
|
||||
void hmp_info_migrate_parameters(Monitor *mon, const QDict *qdict);
|
||||
@@ -81,6 +82,10 @@ void hmp_netdev_add(Monitor *mon, const QDict *qdict);
|
||||
void hmp_netdev_del(Monitor *mon, const QDict *qdict);
|
||||
void hmp_getfd(Monitor *mon, const QDict *qdict);
|
||||
void hmp_closefd(Monitor *mon, const QDict *qdict);
|
||||
@@ -94,6 +95,10 @@ void hmp_closefd(Monitor *mon, const QDict *qdict);
|
||||
void hmp_mouse_move(Monitor *mon, const QDict *qdict);
|
||||
void hmp_mouse_button(Monitor *mon, const QDict *qdict);
|
||||
void hmp_mouse_set(Monitor *mon, const QDict *qdict);
|
||||
+void hmp_savevm_start(Monitor *mon, const QDict *qdict);
|
||||
+void hmp_snapshot_drive(Monitor *mon, const QDict *qdict);
|
||||
+void hmp_delete_drive_snapshot(Monitor *mon, const QDict *qdict);
|
||||
@ -142,23 +143,23 @@ index dfbc0c9a2f..440f86aba8 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 8cac83c06c..0842d00cd2 100644
|
||||
index 8a142fc7a9..a7824b5266 100644
|
||||
--- a/migration/meson.build
|
||||
+++ b/migration/meson.build
|
||||
@@ -24,6 +24,7 @@ softmmu_ss.add(files(
|
||||
@@ -25,6 +25,7 @@ softmmu_ss.add(files(
|
||||
'multifd-zlib.c',
|
||||
'postcopy-ram.c',
|
||||
'savevm.c',
|
||||
+ 'savevm-async.c',
|
||||
'socket.c',
|
||||
'tls.c',
|
||||
), gnutls)
|
||||
'threadinfo.c',
|
||||
diff --git a/migration/savevm-async.c b/migration/savevm-async.c
|
||||
new file mode 100644
|
||||
index 0000000000..dc30558713
|
||||
index 0000000000..24660af014
|
||||
--- /dev/null
|
||||
+++ b/migration/savevm-async.c
|
||||
@@ -0,0 +1,538 @@
|
||||
@@ -0,0 +1,535 @@
|
||||
+#include "qemu/osdep.h"
|
||||
+#include "migration/channel-savevm-async.h"
|
||||
+#include "migration/migration.h"
|
||||
@ -231,24 +232,20 @@ index 0000000000..dc30558713
|
||||
+ info->bytes = s->bs_pos;
|
||||
+ switch (s->state) {
|
||||
+ case SAVE_STATE_ERROR:
|
||||
+ info->has_status = true;
|
||||
+ info->status = g_strdup("failed");
|
||||
+ info->has_total_time = true;
|
||||
+ info->total_time = s->total_time;
|
||||
+ if (s->error) {
|
||||
+ info->has_error = true;
|
||||
+ info->error = g_strdup(error_get_pretty(s->error));
|
||||
+ }
|
||||
+ break;
|
||||
+ case SAVE_STATE_ACTIVE:
|
||||
+ info->has_status = true;
|
||||
+ info->status = g_strdup("active");
|
||||
+ info->has_total_time = true;
|
||||
+ info->total_time = qemu_clock_get_ms(QEMU_CLOCK_REALTIME)
|
||||
+ - s->total_time;
|
||||
+ break;
|
||||
+ case SAVE_STATE_COMPLETED:
|
||||
+ info->has_status = true;
|
||||
+ info->status = g_strdup("completed");
|
||||
+ info->has_total_time = true;
|
||||
+ info->total_time = s->total_time;
|
||||
@ -405,14 +402,14 @@ index 0000000000..dc30558713
|
||||
+ }
|
||||
+
|
||||
+ while (snap_state.state == SAVE_STATE_ACTIVE) {
|
||||
+ uint64_t pending_size, pend_precopy, pend_compatible, pend_postcopy;
|
||||
+ uint64_t pending_size, pend_precopy, pend_postcopy;
|
||||
+
|
||||
+ /* pending is expected to be called without iothread lock */
|
||||
+ qemu_mutex_unlock_iothread();
|
||||
+ qemu_savevm_state_pending(snap_state.file, 0, &pend_precopy, &pend_compatible, &pend_postcopy);
|
||||
+ qemu_savevm_state_pending_exact(&pend_precopy, &pend_postcopy);
|
||||
+ qemu_mutex_lock_iothread();
|
||||
+
|
||||
+ pending_size = pend_precopy + pend_compatible + pend_postcopy;
|
||||
+ pending_size = pend_precopy + pend_postcopy;
|
||||
+
|
||||
+ /*
|
||||
+ * A guest reaching this cutoff is dirtying lots of RAM. It should be
|
||||
@ -465,7 +462,9 @@ index 0000000000..dc30558713
|
||||
+ 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());
|
||||
+ }
|
||||
+ }
|
||||
@ -476,7 +475,7 @@ index 0000000000..dc30558713
|
||||
+ qemu_bh_schedule(snap_state.finalize_bh);
|
||||
+}
|
||||
+
|
||||
+void qmp_savevm_start(bool has_statefile, const char *statefile, Error **errp)
|
||||
+void qmp_savevm_start(const char *statefile, Error **errp)
|
||||
+{
|
||||
+ Error *local_err = NULL;
|
||||
+ MigrationState *ms = migrate_get_current();
|
||||
@ -513,7 +512,7 @@ index 0000000000..dc30558713
|
||||
+ snap_state.error = NULL;
|
||||
+ }
|
||||
+
|
||||
+ if (!has_statefile) {
|
||||
+ if (!statefile) {
|
||||
+ vm_stop(RUN_STATE_SAVE_VM);
|
||||
+ snap_state.state = SAVE_STATE_COMPLETED;
|
||||
+ return;
|
||||
@ -643,8 +642,7 @@ index 0000000000..dc30558713
|
||||
+ Error **errp)
|
||||
+{
|
||||
+ // Compatibility to older qemu-server.
|
||||
+ (void)qmp_blockdev_snapshot_delete_internal_sync(device, false, NULL,
|
||||
+ true, name, errp);
|
||||
+ (void)qmp_blockdev_snapshot_delete_internal_sync(device, NULL, name, errp);
|
||||
+}
|
||||
+
|
||||
+int load_snapshot_from_blockdev(const char *filename, Error **errp)
|
||||
@ -698,19 +696,28 @@ index 0000000000..dc30558713
|
||||
+ return ret;
|
||||
+}
|
||||
diff --git a/monitor/hmp-cmds.c b/monitor/hmp-cmds.c
|
||||
index 480b798963..cfebfd1db5 100644
|
||||
index 6c559b48c8..435f9334f9 100644
|
||||
--- a/monitor/hmp-cmds.c
|
||||
+++ b/monitor/hmp-cmds.c
|
||||
@@ -1906,6 +1906,63 @@ void hmp_info_memory_devices(Monitor *mon, const QDict *qdict)
|
||||
hmp_handle_error(mon, err);
|
||||
}
|
||||
@@ -22,6 +22,7 @@
|
||||
#include "monitor/monitor-internal.h"
|
||||
#include "qapi/error.h"
|
||||
#include "qapi/qapi-commands-control.h"
|
||||
+#include "qapi/qapi-commands-migration.h"
|
||||
#include "qapi/qapi-commands-misc.h"
|
||||
#include "qapi/qmp/qdict.h"
|
||||
#include "qapi/qmp/qerror.h"
|
||||
@@ -443,3 +444,60 @@ void hmp_info_mtree(Monitor *mon, const QDict *qdict)
|
||||
|
||||
mtree_info(flatview, dispatch_tree, owner, disabled);
|
||||
}
|
||||
+
|
||||
+void hmp_savevm_start(Monitor *mon, const QDict *qdict)
|
||||
+{
|
||||
+ Error *errp = NULL;
|
||||
+ const char *statefile = qdict_get_try_str(qdict, "statefile");
|
||||
+
|
||||
+ qmp_savevm_start(statefile != NULL, statefile, &errp);
|
||||
+ qmp_savevm_start(statefile, &errp);
|
||||
+ hmp_handle_error(mon, errp);
|
||||
+}
|
||||
+
|
||||
@ -747,7 +754,7 @@ index 480b798963..cfebfd1db5 100644
|
||||
+ SaveVMInfo *info;
|
||||
+ info = qmp_query_savevm(NULL);
|
||||
+
|
||||
+ if (info->has_status) {
|
||||
+ if (info->status) {
|
||||
+ monitor_printf(mon, "savevm status: %s\n", info->status);
|
||||
+ monitor_printf(mon, "total time: %" PRIu64 " milliseconds\n",
|
||||
+ info->total_time);
|
||||
@ -757,16 +764,12 @@ index 480b798963..cfebfd1db5 100644
|
||||
+ if (info->has_bytes) {
|
||||
+ monitor_printf(mon, "Bytes saved: %"PRIu64"\n", info->bytes);
|
||||
+ }
|
||||
+ if (info->has_error) {
|
||||
+ if (info->error) {
|
||||
+ monitor_printf(mon, "Error: %s\n", info->error);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
void hmp_info_iothreads(Monitor *mon, const QDict *qdict)
|
||||
{
|
||||
IOThreadInfoList *info_list = qmp_query_iothreads(NULL);
|
||||
diff --git a/qapi/migration.json b/qapi/migration.json
|
||||
index 88ecf86ac8..4435866379 100644
|
||||
index c84fa10e86..1702b92553 100644
|
||||
--- a/qapi/migration.json
|
||||
+++ b/qapi/migration.json
|
||||
@@ -261,6 +261,40 @@
|
||||
@ -811,10 +814,10 @@ index 88ecf86ac8..4435866379 100644
|
||||
# @query-migrate:
|
||||
#
|
||||
diff --git a/qapi/misc.json b/qapi/misc.json
|
||||
index 27ef5a2b20..b3ce75dcae 100644
|
||||
index 6ddd16ea28..098c9bbe93 100644
|
||||
--- a/qapi/misc.json
|
||||
+++ b/qapi/misc.json
|
||||
@@ -435,6 +435,38 @@
|
||||
@@ -469,6 +469,38 @@
|
||||
##
|
||||
{ 'command': 'query-fdsets', 'returns': ['FdsetInfo'] }
|
||||
|
||||
@ -854,10 +857,10 @@ index 27ef5a2b20..b3ce75dcae 100644
|
||||
# @CommandLineParameterType:
|
||||
#
|
||||
diff --git a/qemu-options.hx b/qemu-options.hx
|
||||
index 7f99d15b23..54efb127c4 100644
|
||||
index 59bdf67a2c..fc6cb23dd9 100644
|
||||
--- a/qemu-options.hx
|
||||
+++ b/qemu-options.hx
|
||||
@@ -4391,6 +4391,18 @@ SRST
|
||||
@@ -4378,6 +4378,18 @@ SRST
|
||||
Start right away with a saved state (``loadvm`` in monitor)
|
||||
ERST
|
||||
|
||||
@ -877,7 +880,7 @@ index 7f99d15b23..54efb127c4 100644
|
||||
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 5f7f6ca981..21f067d115 100644
|
||||
index ea20b23e4c..0eabc71b68 100644
|
||||
--- a/softmmu/vl.c
|
||||
+++ b/softmmu/vl.c
|
||||
@@ -164,6 +164,7 @@ static const char *accelerators;
|
||||
@ -888,7 +891,7 @@ index 5f7f6ca981..21f067d115 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;
|
||||
@@ -2607,6 +2608,12 @@ void qmp_x_exit_preconfig(Error **errp)
|
||||
@@ -2612,6 +2613,12 @@ void qmp_x_exit_preconfig(Error **errp)
|
||||
|
||||
if (loadvm) {
|
||||
load_snapshot(loadvm, NULL, false, NULL, &error_fatal);
|
||||
@ -901,7 +904,7 @@ index 5f7f6ca981..21f067d115 100644
|
||||
}
|
||||
if (replay_mode != REPLAY_MODE_NONE) {
|
||||
replay_vmstate_init();
|
||||
@@ -3151,6 +3158,9 @@ void qemu_init(int argc, char **argv)
|
||||
@@ -3159,6 +3166,9 @@ void qemu_init(int argc, char **argv)
|
||||
case QEMU_OPTION_loadvm:
|
||||
loadvm = optarg;
|
||||
break;
|
||||
|
@ -19,7 +19,7 @@ Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
|
||||
3 files changed, 38 insertions(+), 18 deletions(-)
|
||||
|
||||
diff --git a/migration/qemu-file.c b/migration/qemu-file.c
|
||||
index 2d5f74ffc2..9fd97e6fe1 100644
|
||||
index 102ab3b439..5ced17aba4 100644
|
||||
--- a/migration/qemu-file.c
|
||||
+++ b/migration/qemu-file.c
|
||||
@@ -31,8 +31,8 @@
|
||||
@ -178,7 +178,7 @@ index 2d5f74ffc2..9fd97e6fe1 100644
|
||||
if (blen < compressBound(size)) {
|
||||
return -1;
|
||||
diff --git a/migration/qemu-file.h b/migration/qemu-file.h
|
||||
index fa13d04d78..914f1a63a8 100644
|
||||
index 9d0155a2a1..cc06240e8d 100644
|
||||
--- a/migration/qemu-file.h
|
||||
+++ b/migration/qemu-file.h
|
||||
@@ -63,7 +63,9 @@ typedef struct QEMUFileHooks {
|
||||
@ -192,10 +192,10 @@ index fa13d04d78..914f1a63a8 100644
|
||||
int qemu_fclose(QEMUFile *f);
|
||||
|
||||
diff --git a/migration/savevm-async.c b/migration/savevm-async.c
|
||||
index dc30558713..a38e7351c1 100644
|
||||
index 24660af014..70273a2996 100644
|
||||
--- a/migration/savevm-async.c
|
||||
+++ b/migration/savevm-async.c
|
||||
@@ -374,7 +374,7 @@ void qmp_savevm_start(bool has_statefile, const char *statefile, Error **errp)
|
||||
@@ -372,7 +372,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 +204,7 @@ index dc30558713..a38e7351c1 100644
|
||||
|
||||
if (!snap_state.file) {
|
||||
error_set(errp, ERROR_CLASS_GENERIC_ERROR, "failed to open '%s'", statefile);
|
||||
@@ -507,7 +507,8 @@ int load_snapshot_from_blockdev(const char *filename, Error **errp)
|
||||
@@ -504,7 +504,8 @@ int load_snapshot_from_blockdev(const char *filename, Error **errp)
|
||||
blk_op_block_all(be, blocker);
|
||||
|
||||
/* restore the VM state */
|
||||
|
@ -4,19 +4,19 @@ Date: Mon, 6 Apr 2020 12:16:47 +0200
|
||||
Subject: [PATCH] PVE: block: add the zeroinit block driver filter
|
||||
|
||||
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
|
||||
[adapt to changed function signatures]
|
||||
Signed-off-by: Fabian Ebner <f.ebner@proxmox.com>
|
||||
[FE: adapt to changed function signatures]
|
||||
Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
|
||||
---
|
||||
block/meson.build | 1 +
|
||||
block/zeroinit.c | 198 ++++++++++++++++++++++++++++++++++++++++++++++
|
||||
2 files changed, 199 insertions(+)
|
||||
block/zeroinit.c | 200 ++++++++++++++++++++++++++++++++++++++++++++++
|
||||
2 files changed, 201 insertions(+)
|
||||
create mode 100644 block/zeroinit.c
|
||||
|
||||
diff --git a/block/meson.build b/block/meson.build
|
||||
index b7c68b83a3..020a89ae07 100644
|
||||
index 382bec0e7d..253fe49fa2 100644
|
||||
--- a/block/meson.build
|
||||
+++ b/block/meson.build
|
||||
@@ -43,6 +43,7 @@ block_ss.add(files(
|
||||
@@ -44,6 +44,7 @@ block_ss.add(files(
|
||||
'vmdk.c',
|
||||
'vpc.c',
|
||||
'write-threshold.c',
|
||||
@ -26,10 +26,10 @@ index b7c68b83a3..020a89ae07 100644
|
||||
softmmu_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..b60e1b84dc
|
||||
index 0000000000..1257342724
|
||||
--- /dev/null
|
||||
+++ b/block/zeroinit.c
|
||||
@@ -0,0 +1,198 @@
|
||||
@@ -0,0 +1,200 @@
|
||||
+/*
|
||||
+ * Filter to fake a zero-initialized block device.
|
||||
+ *
|
||||
@ -43,6 +43,7 @@ index 0000000000..b60e1b84dc
|
||||
+#include "qemu/osdep.h"
|
||||
+#include "qapi/error.h"
|
||||
+#include "block/block_int.h"
|
||||
+#include "block/block-io.h"
|
||||
+#include "qapi/qmp/qdict.h"
|
||||
+#include "qapi/qmp/qstring.h"
|
||||
+#include "qemu/cutils.h"
|
||||
@ -136,9 +137,9 @@ index 0000000000..b60e1b84dc
|
||||
+ (void)s;
|
||||
+}
|
||||
+
|
||||
+static int64_t zeroinit_getlength(BlockDriverState *bs)
|
||||
+static coroutine_fn int64_t zeroinit_co_getlength(BlockDriverState *bs)
|
||||
+{
|
||||
+ return bdrv_getlength(bs->file->bs);
|
||||
+ return bdrv_co_getlength(bs->file->bs);
|
||||
+}
|
||||
+
|
||||
+static int coroutine_fn zeroinit_co_preadv(BlockDriverState *bs,
|
||||
@ -190,9 +191,10 @@ index 0000000000..b60e1b84dc
|
||||
+ return bdrv_co_truncate(bs->file, offset, exact, prealloc, req_flags, errp);
|
||||
+}
|
||||
+
|
||||
+static int zeroinit_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
|
||||
+static coroutine_fn int zeroinit_co_get_info(BlockDriverState *bs,
|
||||
+ BlockDriverInfo *bdi)
|
||||
+{
|
||||
+ return bdrv_get_info(bs->file->bs, bdi);
|
||||
+ return bdrv_co_get_info(bs->file->bs, bdi);
|
||||
+}
|
||||
+
|
||||
+static BlockDriver bdrv_zeroinit = {
|
||||
@ -203,7 +205,7 @@ index 0000000000..b60e1b84dc
|
||||
+ .bdrv_parse_filename = zeroinit_parse_filename,
|
||||
+ .bdrv_file_open = zeroinit_open,
|
||||
+ .bdrv_close = zeroinit_close,
|
||||
+ .bdrv_getlength = zeroinit_getlength,
|
||||
+ .bdrv_co_getlength = zeroinit_co_getlength,
|
||||
+ .bdrv_child_perm = bdrv_default_perms,
|
||||
+ .bdrv_co_flush_to_disk = zeroinit_co_flush,
|
||||
+
|
||||
@ -219,7 +221,7 @@ index 0000000000..b60e1b84dc
|
||||
+ .bdrv_co_pdiscard = zeroinit_co_pdiscard,
|
||||
+
|
||||
+ .bdrv_co_truncate = zeroinit_co_truncate,
|
||||
+ .bdrv_get_info = zeroinit_get_info,
|
||||
+ .bdrv_co_get_info = zeroinit_co_get_info,
|
||||
+};
|
||||
+
|
||||
+static void bdrv_zeroinit_init(void)
|
||||
|
@ -14,10 +14,10 @@ Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
|
||||
2 files changed, 11 insertions(+)
|
||||
|
||||
diff --git a/qemu-options.hx b/qemu-options.hx
|
||||
index 54efb127c4..ef456d03ec 100644
|
||||
index fc6cb23dd9..3ccedf7c45 100644
|
||||
--- a/qemu-options.hx
|
||||
+++ b/qemu-options.hx
|
||||
@@ -1147,6 +1147,9 @@ backend describes how QEMU handles the data.
|
||||
@@ -1150,6 +1150,9 @@ backend describes how QEMU handles the data.
|
||||
|
||||
ERST
|
||||
|
||||
@ -28,10 +28,10 @@ index 54efb127c4..ef456d03ec 100644
|
||||
"-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 21f067d115..9d737e7914 100644
|
||||
index 0eabc71b68..323f6a23d4 100644
|
||||
--- a/softmmu/vl.c
|
||||
+++ b/softmmu/vl.c
|
||||
@@ -2643,6 +2643,7 @@ void qemu_init(int argc, char **argv)
|
||||
@@ -2648,6 +2648,7 @@ void qemu_init(int argc, char **argv)
|
||||
MachineClass *machine_class;
|
||||
bool userconfig = true;
|
||||
FILE *vmstate_dump_file = NULL;
|
||||
@ -39,7 +39,7 @@ index 21f067d115..9d737e7914 100644
|
||||
|
||||
qemu_add_opts(&qemu_drive_opts);
|
||||
qemu_add_drive_opts(&qemu_legacy_drive_opts);
|
||||
@@ -3263,6 +3264,13 @@ void qemu_init(int argc, char **argv)
|
||||
@@ -3271,6 +3272,13 @@ void qemu_init(int argc, char **argv)
|
||||
machine_parse_property_opt(qemu_find_opts("smp-opts"),
|
||||
"smp", optarg);
|
||||
break;
|
||||
|
@ -11,10 +11,10 @@ Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
|
||||
1 file changed, 9 insertions(+)
|
||||
|
||||
diff --git a/hw/intc/apic_common.c b/hw/intc/apic_common.c
|
||||
index 2a20982066..7968ad5a93 100644
|
||||
index 4a34f03047..59b917e50c 100644
|
||||
--- a/hw/intc/apic_common.c
|
||||
+++ b/hw/intc/apic_common.c
|
||||
@@ -278,6 +278,15 @@ static void apic_reset_common(DeviceState *dev)
|
||||
@@ -252,6 +252,15 @@ static void apic_reset_common(DeviceState *dev)
|
||||
info->vapic_base_update(s);
|
||||
|
||||
apic_init_reset(dev);
|
||||
|
@ -13,10 +13,10 @@ Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
|
||||
2 files changed, 42 insertions(+), 20 deletions(-)
|
||||
|
||||
diff --git a/block/file-posix.c b/block/file-posix.c
|
||||
index 9a16d86344..bd68df57ad 100644
|
||||
index 9681bd0434..044890822d 100644
|
||||
--- a/block/file-posix.c
|
||||
+++ b/block/file-posix.c
|
||||
@@ -2487,6 +2487,7 @@ raw_co_create(BlockdevCreateOptions *options, Error **errp)
|
||||
@@ -2483,6 +2483,7 @@ raw_co_create(BlockdevCreateOptions *options, Error **errp)
|
||||
int fd;
|
||||
uint64_t perm, shared;
|
||||
int result = 0;
|
||||
@ -24,7 +24,7 @@ index 9a16d86344..bd68df57ad 100644
|
||||
|
||||
/* Validate options and set default values */
|
||||
assert(options->driver == BLOCKDEV_DRIVER_FILE);
|
||||
@@ -2527,19 +2528,22 @@ raw_co_create(BlockdevCreateOptions *options, Error **errp)
|
||||
@@ -2523,19 +2524,22 @@ raw_co_create(BlockdevCreateOptions *options, Error **errp)
|
||||
perm = BLK_PERM_WRITE | BLK_PERM_RESIZE;
|
||||
shared = BLK_PERM_ALL & ~BLK_PERM_RESIZE;
|
||||
|
||||
@ -59,7 +59,7 @@ index 9a16d86344..bd68df57ad 100644
|
||||
}
|
||||
|
||||
/* Clear the file by truncating it to 0 */
|
||||
@@ -2593,13 +2597,15 @@ raw_co_create(BlockdevCreateOptions *options, Error **errp)
|
||||
@@ -2589,13 +2593,15 @@ raw_co_create(BlockdevCreateOptions *options, Error **errp)
|
||||
}
|
||||
|
||||
out_unlock:
|
||||
@ -82,7 +82,7 @@ index 9a16d86344..bd68df57ad 100644
|
||||
}
|
||||
|
||||
out_close:
|
||||
@@ -2624,6 +2630,7 @@ static int coroutine_fn raw_co_create_opts(BlockDriver *drv,
|
||||
@@ -2619,6 +2625,7 @@ raw_co_create_opts(BlockDriver *drv, const char *filename,
|
||||
PreallocMode prealloc;
|
||||
char *buf = NULL;
|
||||
Error *local_err = NULL;
|
||||
@ -90,7 +90,7 @@ index 9a16d86344..bd68df57ad 100644
|
||||
|
||||
/* Skip file: protocol prefix */
|
||||
strstart(filename, "file:", &filename);
|
||||
@@ -2646,6 +2653,18 @@ static int coroutine_fn raw_co_create_opts(BlockDriver *drv,
|
||||
@@ -2641,6 +2648,18 @@ raw_co_create_opts(BlockDriver *drv, const char *filename,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@ -109,7 +109,7 @@ index 9a16d86344..bd68df57ad 100644
|
||||
options = (BlockdevCreateOptions) {
|
||||
.driver = BLOCKDEV_DRIVER_FILE,
|
||||
.u.file = {
|
||||
@@ -2657,6 +2676,8 @@ static int coroutine_fn raw_co_create_opts(BlockDriver *drv,
|
||||
@@ -2652,6 +2671,8 @@ raw_co_create_opts(BlockDriver *drv, const char *filename,
|
||||
.nocow = nocow,
|
||||
.has_extent_size_hint = has_extent_size_hint,
|
||||
.extent_size_hint = extent_size_hint,
|
||||
@ -119,10 +119,10 @@ index 9a16d86344..bd68df57ad 100644
|
||||
};
|
||||
return raw_co_create(&options, errp);
|
||||
diff --git a/qapi/block-core.json b/qapi/block-core.json
|
||||
index 7daaf545be..9e902b96bb 100644
|
||||
index 3c945c1f93..542add004b 100644
|
||||
--- a/qapi/block-core.json
|
||||
+++ b/qapi/block-core.json
|
||||
@@ -4624,7 +4624,8 @@
|
||||
@@ -4740,7 +4740,8 @@
|
||||
'size': 'size',
|
||||
'*preallocation': 'PreallocMode',
|
||||
'*nocow': 'bool',
|
||||
|
@ -26,10 +26,10 @@ Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
|
||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/hw/core/machine.c b/hw/core/machine.c
|
||||
index 8d34caa31d..2df9037c4e 100644
|
||||
index cd13b8b0a3..cb1d334bcb 100644
|
||||
--- a/hw/core/machine.c
|
||||
+++ b/hw/core/machine.c
|
||||
@@ -132,7 +132,8 @@ GlobalProperty hw_compat_4_0[] = {
|
||||
@@ -141,7 +141,8 @@ GlobalProperty hw_compat_4_0[] = {
|
||||
{ "virtio-vga", "edid", "false" },
|
||||
{ "virtio-gpu-device", "edid", "false" },
|
||||
{ "virtio-device", "use-started", "false" },
|
||||
|
@ -11,35 +11,36 @@ and only if 'is-current').
|
||||
|
||||
Signed-off-by: Stefan Reiter <s.reiter@proxmox.com>
|
||||
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
|
||||
[FE: adapt to QAPI changes]
|
||||
Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
|
||||
---
|
||||
hw/core/machine-qmp-cmds.c | 6 ++++++
|
||||
hw/core/machine-qmp-cmds.c | 5 +++++
|
||||
include/hw/boards.h | 2 ++
|
||||
qapi/machine.json | 4 +++-
|
||||
softmmu/vl.c | 25 +++++++++++++++++++++++++
|
||||
4 files changed, 36 insertions(+), 1 deletion(-)
|
||||
4 files changed, 35 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/hw/core/machine-qmp-cmds.c b/hw/core/machine-qmp-cmds.c
|
||||
index 76fff60a6b..ec9201fb9a 100644
|
||||
index 24595f618c..ee9cb0cd04 100644
|
||||
--- a/hw/core/machine-qmp-cmds.c
|
||||
+++ b/hw/core/machine-qmp-cmds.c
|
||||
@@ -103,6 +103,12 @@ MachineInfoList *qmp_query_machines(Error **errp)
|
||||
@@ -107,6 +107,11 @@ MachineInfoList *qmp_query_machines(Error **errp)
|
||||
if (strcmp(mc->name, MACHINE_GET_CLASS(current_machine)->name) == 0) {
|
||||
info->has_is_current = true;
|
||||
info->is_current = true;
|
||||
+
|
||||
+ // PVE version string only exists for current machine
|
||||
+ if (mc->pve_version) {
|
||||
+ info->has_pve_version = true;
|
||||
+ info->pve_version = g_strdup(mc->pve_version);
|
||||
+ }
|
||||
}
|
||||
|
||||
if (mc->default_cpu_type) {
|
||||
diff --git a/include/hw/boards.h b/include/hw/boards.h
|
||||
index 90f1dd3aeb..14d60520d9 100644
|
||||
index 6fbbfd56c8..61a526e97d 100644
|
||||
--- a/include/hw/boards.h
|
||||
+++ b/include/hw/boards.h
|
||||
@@ -230,6 +230,8 @@ struct MachineClass {
|
||||
@@ -232,6 +232,8 @@ struct MachineClass {
|
||||
const char *desc;
|
||||
const char *deprecation_reason;
|
||||
|
||||
@ -49,29 +50,29 @@ index 90f1dd3aeb..14d60520d9 100644
|
||||
void (*reset)(MachineState *state, ShutdownCause reason);
|
||||
void (*wakeup)(MachineState *state);
|
||||
diff --git a/qapi/machine.json b/qapi/machine.json
|
||||
index 9156103c8f..f4fb1b2c9c 100644
|
||||
index c904280085..47f3facdb2 100644
|
||||
--- a/qapi/machine.json
|
||||
+++ b/qapi/machine.json
|
||||
@@ -157,6 +157,8 @@
|
||||
@@ -159,6 +159,8 @@
|
||||
#
|
||||
# @default-ram-id: the default ID of initial RAM memory backend (since 5.2)
|
||||
# @acpi: machine type supports ACPI (since 8.0)
|
||||
#
|
||||
+# @pve-version: custom PVE version suffix specified as 'machine+pveN'
|
||||
+#
|
||||
# Since: 1.2
|
||||
##
|
||||
{ 'struct': 'MachineInfo',
|
||||
@@ -164,7 +166,7 @@
|
||||
@@ -166,7 +168,7 @@
|
||||
'*is-default': 'bool', '*is-current': 'bool', 'cpu-max': 'int',
|
||||
'hotpluggable-cpus': 'bool', 'numa-mem-supported': 'bool',
|
||||
'deprecated': 'bool', '*default-cpu-type': 'str',
|
||||
- '*default-ram-id': 'str' } }
|
||||
+ '*default-ram-id': 'str', '*pve-version': 'str' } }
|
||||
- '*default-ram-id': 'str', 'acpi': 'bool' } }
|
||||
+ '*default-ram-id': 'str', 'acpi': 'bool', '*pve-version': 'str' } }
|
||||
|
||||
##
|
||||
# @query-machines:
|
||||
diff --git a/softmmu/vl.c b/softmmu/vl.c
|
||||
index 9d737e7914..a64eee2fad 100644
|
||||
index 323f6a23d4..25abdc9da7 100644
|
||||
--- a/softmmu/vl.c
|
||||
+++ b/softmmu/vl.c
|
||||
@@ -1578,6 +1578,7 @@ static const QEMUOption *lookup_opt(int argc, char **argv,
|
||||
@ -94,7 +95,7 @@ index 9d737e7914..a64eee2fad 100644
|
||||
g_slist_free(machines);
|
||||
if (local_err) {
|
||||
error_append_hint(&local_err, "Use -machine help to list supported machines\n");
|
||||
@@ -3205,12 +3211,31 @@ void qemu_init(int argc, char **argv)
|
||||
@@ -3213,12 +3219,31 @@ void qemu_init(int argc, char **argv)
|
||||
case QEMU_OPTION_machine:
|
||||
{
|
||||
bool help;
|
||||
|
@ -25,7 +25,7 @@ Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
|
||||
1 file changed, 4 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/block/backup.c b/block/backup.c
|
||||
index 6a9ad97a53..9b0151c5be 100644
|
||||
index db3791f4d1..39410dcf8d 100644
|
||||
--- a/block/backup.c
|
||||
+++ b/block/backup.c
|
||||
@@ -237,8 +237,8 @@ static void backup_init_bcs_bitmap(BackupBlockJob *job)
|
||||
@ -48,7 +48,7 @@ index 6a9ad97a53..9b0151c5be 100644
|
||||
if (s->sync_mode == MIRROR_SYNC_MODE_TOP) {
|
||||
int64_t offset = 0;
|
||||
int64_t count;
|
||||
@@ -492,6 +490,8 @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs,
|
||||
@@ -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,
|
||||
&error_abort);
|
||||
|
||||
|
@ -20,10 +20,10 @@ Signed-off-by: Fabian Ebner <f.ebner@proxmox.com>
|
||||
create mode 100644 vma.h
|
||||
|
||||
diff --git a/block/meson.build b/block/meson.build
|
||||
index 020a89ae07..4feae20e37 100644
|
||||
index 253fe49fa2..744b698a82 100644
|
||||
--- a/block/meson.build
|
||||
+++ b/block/meson.build
|
||||
@@ -46,6 +46,8 @@ block_ss.add(files(
|
||||
@@ -47,6 +47,8 @@ block_ss.add(files(
|
||||
'zeroinit.c',
|
||||
), zstd, zlib, gnutls)
|
||||
|
||||
@ -33,10 +33,10 @@ index 020a89ae07..4feae20e37 100644
|
||||
softmmu_ss.add(files('block-ram-registrar.c'))
|
||||
|
||||
diff --git a/meson.build b/meson.build
|
||||
index 5c6b5a1c75..e8cf7e3d78 100644
|
||||
index c44d05a13f..b9bc31b01c 100644
|
||||
--- a/meson.build
|
||||
+++ b/meson.build
|
||||
@@ -1525,6 +1525,8 @@ keyutils = dependency('libkeyutils', required: false,
|
||||
@@ -1527,6 +1527,8 @@ keyutils = dependency('libkeyutils', required: false,
|
||||
|
||||
has_gettid = cc.has_function('gettid')
|
||||
|
||||
@ -45,7 +45,7 @@ index 5c6b5a1c75..e8cf7e3d78 100644
|
||||
# libselinux
|
||||
selinux = dependency('libselinux',
|
||||
required: get_option('selinux'),
|
||||
@@ -3596,6 +3598,9 @@ if have_tools
|
||||
@@ -3645,6 +3647,9 @@ if have_tools
|
||||
dependencies: [blockdev, qemuutil, gnutls, selinux],
|
||||
install: true)
|
||||
|
||||
|
@ -9,21 +9,23 @@ Subject: [PATCH] PVE-Backup: add backup-dump block driver
|
||||
- job.c: make job_should_pause non-static
|
||||
|
||||
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
|
||||
[FE: adapt to coroutine changes]
|
||||
Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
|
||||
---
|
||||
block/backup-dump.c | 167 +++++++++++++++++++++++++++++++
|
||||
block/backup-dump.c | 168 +++++++++++++++++++++++++++++++
|
||||
block/backup.c | 30 ++----
|
||||
block/meson.build | 1 +
|
||||
include/block/block_int-common.h | 35 +++++++
|
||||
job.c | 3 +-
|
||||
5 files changed, 213 insertions(+), 23 deletions(-)
|
||||
5 files changed, 214 insertions(+), 23 deletions(-)
|
||||
create mode 100644 block/backup-dump.c
|
||||
|
||||
diff --git a/block/backup-dump.c b/block/backup-dump.c
|
||||
new file mode 100644
|
||||
index 0000000000..04718a94e2
|
||||
index 0000000000..232a094426
|
||||
--- /dev/null
|
||||
+++ b/block/backup-dump.c
|
||||
@@ -0,0 +1,167 @@
|
||||
@@ -0,0 +1,168 @@
|
||||
+/*
|
||||
+ * BlockDriver to send backup data stream to a callback function
|
||||
+ *
|
||||
@ -45,7 +47,8 @@ index 0000000000..04718a94e2
|
||||
+ void *dump_cb_data;
|
||||
+} BDRVBackupDumpState;
|
||||
+
|
||||
+static int qemu_backup_dump_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
|
||||
+static coroutine_fn int qemu_backup_dump_co_get_info(BlockDriverState *bs,
|
||||
+ BlockDriverInfo *bdi)
|
||||
+{
|
||||
+ BDRVBackupDumpState *s = bs->opaque;
|
||||
+
|
||||
@ -86,7 +89,7 @@ index 0000000000..04718a94e2
|
||||
+ /* Nothing to do. */
|
||||
+}
|
||||
+
|
||||
+static int64_t qemu_backup_dump_getlength(BlockDriverState *bs)
|
||||
+static coroutine_fn int64_t qemu_backup_dump_co_getlength(BlockDriverState *bs)
|
||||
+{
|
||||
+ BDRVBackupDumpState *s = bs->opaque;
|
||||
+
|
||||
@ -146,8 +149,8 @@ index 0000000000..04718a94e2
|
||||
+
|
||||
+ .bdrv_close = qemu_backup_dump_close,
|
||||
+ .bdrv_has_zero_init = bdrv_has_zero_init_1,
|
||||
+ .bdrv_getlength = qemu_backup_dump_getlength,
|
||||
+ .bdrv_get_info = qemu_backup_dump_get_info,
|
||||
+ .bdrv_co_getlength = qemu_backup_dump_co_getlength,
|
||||
+ .bdrv_co_get_info = qemu_backup_dump_co_get_info,
|
||||
+
|
||||
+ .bdrv_co_writev = qemu_backup_dump_co_writev,
|
||||
+
|
||||
@ -192,7 +195,7 @@ index 0000000000..04718a94e2
|
||||
+ return bs;
|
||||
+}
|
||||
diff --git a/block/backup.c b/block/backup.c
|
||||
index 9b0151c5be..6e8f6e67b3 100644
|
||||
index 39410dcf8d..af87fa6aa9 100644
|
||||
--- a/block/backup.c
|
||||
+++ b/block/backup.c
|
||||
@@ -29,28 +29,6 @@
|
||||
@ -224,7 +227,7 @@ index 9b0151c5be..6e8f6e67b3 100644
|
||||
static const BlockJobDriver backup_job_driver;
|
||||
|
||||
static void backup_cleanup_sync_bitmap(BackupBlockJob *job, int ret)
|
||||
@@ -454,6 +432,14 @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs,
|
||||
@@ -457,6 +435,14 @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs,
|
||||
}
|
||||
|
||||
cluster_size = block_copy_cluster_size(bcs);
|
||||
@ -240,7 +243,7 @@ index 9b0151c5be..6e8f6e67b3 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 4feae20e37..0d7023fc82 100644
|
||||
index 744b698a82..f580f95395 100644
|
||||
--- a/block/meson.build
|
||||
+++ b/block/meson.build
|
||||
@@ -4,6 +4,7 @@ block_ss.add(files(
|
||||
@ -252,18 +255,18 @@ index 4feae20e37..0d7023fc82 100644
|
||||
'blkdebug.c',
|
||||
'blklogwrites.c',
|
||||
diff --git a/include/block/block_int-common.h b/include/block/block_int-common.h
|
||||
index 31ae91e56e..37b64bcd93 100644
|
||||
index f01bb8b617..d7ffd1826e 100644
|
||||
--- a/include/block/block_int-common.h
|
||||
+++ b/include/block/block_int-common.h
|
||||
@@ -26,6 +26,7 @@
|
||||
|
||||
#include "block/accounting.h"
|
||||
#include "block/block.h"
|
||||
#include "block/aio.h"
|
||||
#include "block/block-common.h"
|
||||
+#include "block/block-copy.h"
|
||||
#include "block/aio-wait.h"
|
||||
#include "qemu/queue.h"
|
||||
#include "qemu/coroutine.h"
|
||||
@@ -64,6 +65,40 @@
|
||||
#include "block/block-global-state.h"
|
||||
#include "block/snapshot.h"
|
||||
#include "qemu/iov.h"
|
||||
@@ -60,6 +61,40 @@
|
||||
|
||||
#define BLOCK_PROBE_BUF_SIZE 512
|
||||
|
||||
|
@ -8,7 +8,8 @@ Signed-off-by: Dietmar Maurer <dietmar@proxmox.com>
|
||||
Signed-off-by: Stefan Reiter <s.reiter@proxmox.com>
|
||||
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
|
||||
[FE: add new force parameter to job_cancel_sync calls
|
||||
adapt for new job lock mechanism replacing AioContext locks]
|
||||
adapt for new job lock mechanism replacing AioContext locks
|
||||
adapt to QAPI changes]
|
||||
Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
|
||||
---
|
||||
block/meson.build | 5 +
|
||||
@ -18,23 +19,23 @@ Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
|
||||
hmp-commands.hx | 29 +
|
||||
include/monitor/hmp.h | 3 +
|
||||
meson.build | 1 +
|
||||
monitor/hmp-cmds.c | 44 ++
|
||||
proxmox-backup-client.c | 176 ++++++
|
||||
proxmox-backup-client.h | 59 ++
|
||||
pve-backup.c | 956 +++++++++++++++++++++++++++++++++
|
||||
monitor/hmp-cmds.c | 45 ++
|
||||
proxmox-backup-client.c | 176 +++++++
|
||||
proxmox-backup-client.h | 59 +++
|
||||
pve-backup.c | 938 +++++++++++++++++++++++++++++++++
|
||||
qapi/block-core.json | 109 ++++
|
||||
qapi/common.json | 13 +
|
||||
qapi/machine.json | 15 +-
|
||||
14 files changed, 1445 insertions(+), 13 deletions(-)
|
||||
14 files changed, 1428 insertions(+), 13 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 0d7023fc82..e995ae72b9 100644
|
||||
index f580f95395..5bcebb934b 100644
|
||||
--- a/block/meson.build
|
||||
+++ b/block/meson.build
|
||||
@@ -48,6 +48,11 @@ block_ss.add(files(
|
||||
@@ -49,6 +49,11 @@ block_ss.add(files(
|
||||
), zstd, zlib, gnutls)
|
||||
|
||||
block_ss.add(files('../vma-writer.c'), libuuid)
|
||||
@ -47,12 +48,12 @@ index 0d7023fc82..e995ae72b9 100644
|
||||
softmmu_ss.add(when: 'CONFIG_TCG', if_true: files('blkreplay.c'))
|
||||
softmmu_ss.add(files('block-ram-registrar.c'))
|
||||
diff --git a/block/monitor/block-hmp-cmds.c b/block/monitor/block-hmp-cmds.c
|
||||
index b6135e9bfe..477044c54a 100644
|
||||
index 2846083546..947d4f3df0 100644
|
||||
--- a/block/monitor/block-hmp-cmds.c
|
||||
+++ b/block/monitor/block-hmp-cmds.c
|
||||
@@ -1015,3 +1015,36 @@ void hmp_info_snapshots(Monitor *mon, const QDict *qdict)
|
||||
g_free(sn_tab);
|
||||
g_free(global_snapshots);
|
||||
@@ -1027,3 +1027,36 @@ 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);
|
||||
}
|
||||
+
|
||||
+void hmp_backup_cancel(Monitor *mon, const QDict *qdict)
|
||||
@ -75,32 +76,32 @@ index b6135e9bfe..477044c54a 100644
|
||||
+
|
||||
+ qmp_backup(
|
||||
+ backup_file,
|
||||
+ false, NULL, // PBS password
|
||||
+ false, NULL, // PBS keyfile
|
||||
+ false, NULL, // PBS key_password
|
||||
+ false, NULL, // PBS fingerprint
|
||||
+ false, NULL, // PBS backup-id
|
||||
+ NULL, // PBS password
|
||||
+ NULL, // PBS keyfile
|
||||
+ NULL, // PBS key_password
|
||||
+ NULL, // PBS fingerprint
|
||||
+ NULL, // PBS backup-id
|
||||
+ false, 0, // PBS backup-time
|
||||
+ true, dir ? BACKUP_FORMAT_DIR : BACKUP_FORMAT_VMA,
|
||||
+ false, NULL, false, NULL, !!devlist,
|
||||
+ NULL, NULL,
|
||||
+ devlist, qdict_haskey(qdict, "speed"), speed, &error);
|
||||
+
|
||||
+ hmp_handle_error(mon, error);
|
||||
+}
|
||||
diff --git a/blockdev.c b/blockdev.c
|
||||
index 756e980889..bc8d67b290 100644
|
||||
index 47c70eeb91..3b95f54b64 100644
|
||||
--- a/blockdev.c
|
||||
+++ b/blockdev.c
|
||||
@@ -36,6 +36,7 @@
|
||||
#include "hw/block/block.h"
|
||||
@@ -37,6 +37,7 @@
|
||||
#include "block/blockjob.h"
|
||||
#include "block/dirty-bitmap.h"
|
||||
#include "block/qdict.h"
|
||||
+#include "block/blockjob_int.h"
|
||||
#include "block/throttle-groups.h"
|
||||
#include "monitor/monitor.h"
|
||||
#include "qemu/error-report.h"
|
||||
diff --git a/hmp-commands-info.hx b/hmp-commands-info.hx
|
||||
index 489c524e9e..bc1d46d845 100644
|
||||
index a166bff3d5..4b75966c2e 100644
|
||||
--- a/hmp-commands-info.hx
|
||||
+++ b/hmp-commands-info.hx
|
||||
@@ -486,6 +486,20 @@ SRST
|
||||
@ -125,7 +126,7 @@ index 489c524e9e..bc1d46d845 100644
|
||||
{
|
||||
.name = "usernet",
|
||||
diff --git a/hmp-commands.hx b/hmp-commands.hx
|
||||
index 039be0033d..fcf9461295 100644
|
||||
index b66d7fc4ab..9b6b8e2e9c 100644
|
||||
--- a/hmp-commands.hx
|
||||
+++ b/hmp-commands.hx
|
||||
@@ -101,6 +101,35 @@ ERST
|
||||
@ -165,10 +166,10 @@ index 039be0033d..fcf9461295 100644
|
||||
|
||||
{
|
||||
diff --git a/include/monitor/hmp.h b/include/monitor/hmp.h
|
||||
index 440f86aba8..350527e599 100644
|
||||
index c012bad741..2e504db706 100644
|
||||
--- a/include/monitor/hmp.h
|
||||
+++ b/include/monitor/hmp.h
|
||||
@@ -31,6 +31,7 @@ void hmp_info_savevm(Monitor *mon, const QDict *qdict);
|
||||
@@ -32,6 +32,7 @@ void hmp_info_savevm(Monitor *mon, const QDict *qdict);
|
||||
void hmp_info_migrate(Monitor *mon, const QDict *qdict);
|
||||
void hmp_info_migrate_capabilities(Monitor *mon, const QDict *qdict);
|
||||
void hmp_info_migrate_parameters(Monitor *mon, const QDict *qdict);
|
||||
@ -176,20 +177,20 @@ index 440f86aba8..350527e599 100644
|
||||
void hmp_info_cpus(Monitor *mon, const QDict *qdict);
|
||||
void hmp_info_vnc(Monitor *mon, const QDict *qdict);
|
||||
void hmp_info_spice(Monitor *mon, const QDict *qdict);
|
||||
@@ -74,6 +75,8 @@ void hmp_x_colo_lost_heartbeat(Monitor *mon, const QDict *qdict);
|
||||
void hmp_set_password(Monitor *mon, const QDict *qdict);
|
||||
void hmp_expire_password(Monitor *mon, const QDict *qdict);
|
||||
void hmp_change(Monitor *mon, const QDict *qdict);
|
||||
@@ -84,6 +85,8 @@ void hmp_change_vnc(Monitor *mon, const char *device, const char *target,
|
||||
void hmp_change_medium(Monitor *mon, const char *device, const char *target,
|
||||
const char *arg, const char *read_only, bool force,
|
||||
Error **errp);
|
||||
+void hmp_backup(Monitor *mon, const QDict *qdict);
|
||||
+void hmp_backup_cancel(Monitor *mon, const QDict *qdict);
|
||||
void hmp_migrate(Monitor *mon, const QDict *qdict);
|
||||
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 e8cf7e3d78..782756162c 100644
|
||||
index b9bc31b01c..b12ef9f8d4 100644
|
||||
--- a/meson.build
|
||||
+++ b/meson.build
|
||||
@@ -1526,6 +1526,7 @@ keyutils = dependency('libkeyutils', required: false,
|
||||
@@ -1528,6 +1528,7 @@ keyutils = dependency('libkeyutils', required: false,
|
||||
has_gettid = cc.has_function('gettid')
|
||||
|
||||
libuuid = cc.find_library('uuid', required: true)
|
||||
@ -198,11 +199,19 @@ index e8cf7e3d78..782756162c 100644
|
||||
# libselinux
|
||||
selinux = dependency('libselinux',
|
||||
diff --git a/monitor/hmp-cmds.c b/monitor/hmp-cmds.c
|
||||
index cfebfd1db5..a40b25e906 100644
|
||||
index 435f9334f9..9e1bd57aeb 100644
|
||||
--- a/monitor/hmp-cmds.c
|
||||
+++ b/monitor/hmp-cmds.c
|
||||
@@ -199,6 +199,50 @@ void hmp_info_mice(Monitor *mon, const QDict *qdict)
|
||||
qapi_free_MouseInfoList(mice_list);
|
||||
@@ -21,6 +21,7 @@
|
||||
#include "qemu/help_option.h"
|
||||
#include "monitor/monitor-internal.h"
|
||||
#include "qapi/error.h"
|
||||
+#include "qapi/qapi-commands-block-core.h"
|
||||
#include "qapi/qapi-commands-control.h"
|
||||
#include "qapi/qapi-commands-migration.h"
|
||||
#include "qapi/qapi-commands-misc.h"
|
||||
@@ -144,6 +145,50 @@ void hmp_sync_profile(Monitor *mon, const QDict *qdict)
|
||||
}
|
||||
}
|
||||
|
||||
+void hmp_info_backup(Monitor *mon, const QDict *qdict)
|
||||
@ -216,8 +225,8 @@ index cfebfd1db5..a40b25e906 100644
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ if (info->has_status) {
|
||||
+ if (info->has_errmsg) {
|
||||
+ if (info->status) {
|
||||
+ if (info->errmsg) {
|
||||
+ monitor_printf(mon, "Backup status: %s - %s\n",
|
||||
+ info->status, info->errmsg);
|
||||
+ } else {
|
||||
@ -225,7 +234,7 @@ index cfebfd1db5..a40b25e906 100644
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (info->has_backup_file) {
|
||||
+ if (info->backup_file) {
|
||||
+ monitor_printf(mon, "Start time: %s", ctime(&info->start_time));
|
||||
+ if (info->end_time) {
|
||||
+ monitor_printf(mon, "End time: %s", ctime(&info->end_time));
|
||||
@ -249,9 +258,9 @@ index cfebfd1db5..a40b25e906 100644
|
||||
+ qapi_free_BackupStatus(info);
|
||||
+}
|
||||
+
|
||||
void hmp_info_migrate(Monitor *mon, const QDict *qdict)
|
||||
void hmp_exit_preconfig(Monitor *mon, const QDict *qdict)
|
||||
{
|
||||
MigrationInfo *info;
|
||||
Error *err = NULL;
|
||||
diff --git a/proxmox-backup-client.c b/proxmox-backup-client.c
|
||||
new file mode 100644
|
||||
index 0000000000..a8f6653a81
|
||||
@ -501,10 +510,10 @@ index 0000000000..1dda8b7d8f
|
||||
+#endif /* PROXMOX_BACKUP_CLIENT_H */
|
||||
diff --git a/pve-backup.c b/pve-backup.c
|
||||
new file mode 100644
|
||||
index 0000000000..6af212b9b4
|
||||
index 0000000000..bb51c030bd
|
||||
--- /dev/null
|
||||
+++ b/pve-backup.c
|
||||
@@ -0,0 +1,956 @@
|
||||
@@ -0,0 +1,938 @@
|
||||
+#include "proxmox-backup-client.h"
|
||||
+#include "vma.h"
|
||||
+
|
||||
@ -512,6 +521,7 @@ index 0000000000..6af212b9b4
|
||||
+#include "qemu/module.h"
|
||||
+#include "sysemu/block-backend.h"
|
||||
+#include "sysemu/blockdev.h"
|
||||
+#include "block/block_int-global-state.h"
|
||||
+#include "block/blockjob.h"
|
||||
+#include "qapi/qapi-commands-block.h"
|
||||
+#include "qapi/qmp/qerror.h"
|
||||
@ -1020,25 +1030,17 @@ index 0000000000..6af212b9b4
|
||||
+
|
||||
+typedef struct QmpBackupTask {
|
||||
+ const char *backup_file;
|
||||
+ bool has_password;
|
||||
+ const char *password;
|
||||
+ bool has_keyfile;
|
||||
+ const char *keyfile;
|
||||
+ bool has_key_password;
|
||||
+ const char *key_password;
|
||||
+ bool has_backup_id;
|
||||
+ const char *backup_id;
|
||||
+ bool has_backup_time;
|
||||
+ const char *fingerprint;
|
||||
+ bool has_fingerprint;
|
||||
+ int64_t backup_time;
|
||||
+ bool has_format;
|
||||
+ BackupFormat format;
|
||||
+ bool has_config_file;
|
||||
+ const char *config_file;
|
||||
+ bool has_firewall_file;
|
||||
+ const char *firewall_file;
|
||||
+ bool has_devlist;
|
||||
+ const char *devlist;
|
||||
+ bool has_speed;
|
||||
+ int64_t speed;
|
||||
@ -1079,7 +1081,7 @@ index 0000000000..6af212b9b4
|
||||
+ /* Todo: try to auto-detect format based on file name */
|
||||
+ BackupFormat format = task->has_format ? task->format : BACKUP_FORMAT_VMA;
|
||||
+
|
||||
+ if (task->has_devlist) {
|
||||
+ if (task->devlist) {
|
||||
+ devs = g_strsplit_set(task->devlist, ",;:", -1);
|
||||
+
|
||||
+ gchar **d = devs;
|
||||
@ -1144,11 +1146,11 @@ index 0000000000..6af212b9b4
|
||||
+ uuid_generate(uuid);
|
||||
+
|
||||
+ if (format == BACKUP_FORMAT_PBS) {
|
||||
+ if (!task->has_password) {
|
||||
+ if (!task->password) {
|
||||
+ error_set(task->errp, ERROR_CLASS_GENERIC_ERROR, "missing parameter 'password'");
|
||||
+ goto err;
|
||||
+ }
|
||||
+ if (!task->has_backup_id) {
|
||||
+ if (!task->backup_id) {
|
||||
+ error_set(task->errp, ERROR_CLASS_GENERIC_ERROR, "missing parameter 'backup-id'");
|
||||
+ goto err;
|
||||
+ }
|
||||
@ -1166,10 +1168,10 @@ index 0000000000..6af212b9b4
|
||||
+ task->backup_id,
|
||||
+ task->backup_time,
|
||||
+ dump_cb_block_size,
|
||||
+ task->has_password ? task->password : NULL,
|
||||
+ task->has_keyfile ? task->keyfile : NULL,
|
||||
+ task->has_key_password ? task->key_password : NULL,
|
||||
+ task->has_fingerprint ? task->fingerprint : NULL,
|
||||
+ task->password,
|
||||
+ task->keyfile,
|
||||
+ task->key_password,
|
||||
+ task->fingerprint,
|
||||
+ &pbs_err);
|
||||
+
|
||||
+ if (!pbs) {
|
||||
@ -1264,7 +1266,7 @@ index 0000000000..6af212b9b4
|
||||
+
|
||||
+
|
||||
+ /* add configuration file to archive */
|
||||
+ if (task->has_config_file) {
|
||||
+ if (task->config_file) {
|
||||
+ if (pvebackup_co_add_config(task->config_file, config_name, format, backup_dir,
|
||||
+ vmaw, pbs, task->errp) != 0) {
|
||||
+ goto err;
|
||||
@ -1272,7 +1274,7 @@ index 0000000000..6af212b9b4
|
||||
+ }
|
||||
+
|
||||
+ /* add firewall file to archive */
|
||||
+ if (task->has_firewall_file) {
|
||||
+ if (task->firewall_file) {
|
||||
+ if (pvebackup_co_add_config(task->firewall_file, firewall_name, format, backup_dir,
|
||||
+ vmaw, pbs, task->errp) != 0) {
|
||||
+ goto err;
|
||||
@ -1360,37 +1362,30 @@ index 0000000000..6af212b9b4
|
||||
+
|
||||
+UuidInfo *qmp_backup(
|
||||
+ const char *backup_file,
|
||||
+ bool has_password, const char *password,
|
||||
+ bool has_keyfile, const char *keyfile,
|
||||
+ bool has_key_password, const char *key_password,
|
||||
+ bool has_fingerprint, const char *fingerprint,
|
||||
+ bool has_backup_id, const char *backup_id,
|
||||
+ const char *password,
|
||||
+ const char *keyfile,
|
||||
+ const char *key_password,
|
||||
+ const char *fingerprint,
|
||||
+ const char *backup_id,
|
||||
+ bool has_backup_time, int64_t backup_time,
|
||||
+ bool has_format, BackupFormat format,
|
||||
+ bool has_config_file, const char *config_file,
|
||||
+ bool has_firewall_file, const char *firewall_file,
|
||||
+ bool has_devlist, const char *devlist,
|
||||
+ const char *config_file,
|
||||
+ const char *firewall_file,
|
||||
+ const char *devlist,
|
||||
+ bool has_speed, int64_t speed, Error **errp)
|
||||
+{
|
||||
+ QmpBackupTask task = {
|
||||
+ .backup_file = backup_file,
|
||||
+ .has_password = has_password,
|
||||
+ .password = password,
|
||||
+ .has_key_password = has_key_password,
|
||||
+ .key_password = key_password,
|
||||
+ .has_fingerprint = has_fingerprint,
|
||||
+ .fingerprint = fingerprint,
|
||||
+ .has_backup_id = has_backup_id,
|
||||
+ .backup_id = backup_id,
|
||||
+ .has_backup_time = has_backup_time,
|
||||
+ .backup_time = backup_time,
|
||||
+ .has_format = has_format,
|
||||
+ .format = format,
|
||||
+ .has_config_file = has_config_file,
|
||||
+ .config_file = config_file,
|
||||
+ .has_firewall_file = has_firewall_file,
|
||||
+ .firewall_file = firewall_file,
|
||||
+ .has_devlist = has_devlist,
|
||||
+ .devlist = devlist,
|
||||
+ .has_speed = has_speed,
|
||||
+ .speed = speed,
|
||||
@ -1424,22 +1419,18 @@ index 0000000000..6af212b9b4
|
||||
+ return info;
|
||||
+ }
|
||||
+
|
||||
+ info->has_status = true;
|
||||
+ info->has_start_time = true;
|
||||
+ info->start_time = backup_state.stat.start_time;
|
||||
+
|
||||
+ if (backup_state.stat.backup_file) {
|
||||
+ info->has_backup_file = true;
|
||||
+ info->backup_file = g_strdup(backup_state.stat.backup_file);
|
||||
+ }
|
||||
+
|
||||
+ info->has_uuid = true;
|
||||
+ info->uuid = g_strdup(backup_state.stat.uuid_str);
|
||||
+
|
||||
+ if (backup_state.stat.end_time) {
|
||||
+ if (backup_state.stat.error) {
|
||||
+ info->status = g_strdup("error");
|
||||
+ info->has_errmsg = true;
|
||||
+ info->errmsg = g_strdup(error_get_pretty(backup_state.stat.error));
|
||||
+ } else {
|
||||
+ info->status = g_strdup("done");
|
||||
@ -1462,10 +1453,10 @@ index 0000000000..6af212b9b4
|
||||
+ return info;
|
||||
+}
|
||||
diff --git a/qapi/block-core.json b/qapi/block-core.json
|
||||
index 9e902b96bb..c3b6b93472 100644
|
||||
index 542add004b..16fb4c5ea0 100644
|
||||
--- a/qapi/block-core.json
|
||||
+++ b/qapi/block-core.json
|
||||
@@ -740,6 +740,115 @@
|
||||
@@ -835,6 +835,115 @@
|
||||
{ 'command': 'query-block', 'returns': ['BlockInfo'],
|
||||
'allow-preconfig': true }
|
||||
|
||||
@ -1603,7 +1594,7 @@ index 356db3f670..aae8a3b682 100644
|
||||
+##
|
||||
+{ 'struct': 'UuidInfo', 'data': {'UUID': 'str'} }
|
||||
diff --git a/qapi/machine.json b/qapi/machine.json
|
||||
index f4fb1b2c9c..0d6ee836ed 100644
|
||||
index 47f3facdb2..46760978ae 100644
|
||||
--- a/qapi/machine.json
|
||||
+++ b/qapi/machine.json
|
||||
@@ -4,6 +4,8 @@
|
||||
@ -1615,7 +1606,7 @@ index f4fb1b2c9c..0d6ee836ed 100644
|
||||
##
|
||||
# = Machines
|
||||
##
|
||||
@@ -226,19 +228,6 @@
|
||||
@@ -228,19 +230,6 @@
|
||||
##
|
||||
{ 'command': 'query-target', 'returns': 'TargetInfo' }
|
||||
|
||||
|
@ -12,10 +12,10 @@ Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
|
||||
create mode 100644 pbs-restore.c
|
||||
|
||||
diff --git a/meson.build b/meson.build
|
||||
index 782756162c..63ea813a9a 100644
|
||||
index b12ef9f8d4..8ec21bba90 100644
|
||||
--- a/meson.build
|
||||
+++ b/meson.build
|
||||
@@ -3602,6 +3602,10 @@ if have_tools
|
||||
@@ -3651,6 +3651,10 @@ if have_tools
|
||||
vma = executable('vma', files('vma.c', 'vma-reader.c') + genh,
|
||||
dependencies: [authz, block, crypto, io, qom], install: true)
|
||||
|
||||
|
@ -24,27 +24,27 @@ Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
|
||||
monitor/hmp-cmds.c | 45 ++++++++++----
|
||||
proxmox-backup-client.c | 3 +-
|
||||
proxmox-backup-client.h | 1 +
|
||||
pve-backup.c | 103 ++++++++++++++++++++++++++++++---
|
||||
pve-backup.c | 104 ++++++++++++++++++++++++++++++---
|
||||
qapi/block-core.json | 12 +++-
|
||||
6 files changed, 142 insertions(+), 23 deletions(-)
|
||||
6 files changed, 143 insertions(+), 23 deletions(-)
|
||||
|
||||
diff --git a/block/monitor/block-hmp-cmds.c b/block/monitor/block-hmp-cmds.c
|
||||
index 477044c54a..556af25861 100644
|
||||
index 947d4f3df0..bcba630f12 100644
|
||||
--- a/block/monitor/block-hmp-cmds.c
|
||||
+++ b/block/monitor/block-hmp-cmds.c
|
||||
@@ -1042,6 +1042,7 @@ void hmp_backup(Monitor *mon, const QDict *qdict)
|
||||
false, NULL, // PBS fingerprint
|
||||
false, NULL, // PBS backup-id
|
||||
@@ -1054,6 +1054,7 @@ void hmp_backup(Monitor *mon, const QDict *qdict)
|
||||
NULL, // PBS fingerprint
|
||||
NULL, // PBS backup-id
|
||||
false, 0, // PBS backup-time
|
||||
+ false, false, // PBS incremental
|
||||
true, dir ? BACKUP_FORMAT_DIR : BACKUP_FORMAT_VMA,
|
||||
false, NULL, false, NULL, !!devlist,
|
||||
NULL, NULL,
|
||||
devlist, qdict_haskey(qdict, "speed"), speed, &error);
|
||||
diff --git a/monitor/hmp-cmds.c b/monitor/hmp-cmds.c
|
||||
index a40b25e906..670f783515 100644
|
||||
index 9e1bd57aeb..087161a967 100644
|
||||
--- a/monitor/hmp-cmds.c
|
||||
+++ b/monitor/hmp-cmds.c
|
||||
@@ -225,19 +225,42 @@ void hmp_info_backup(Monitor *mon, const QDict *qdict)
|
||||
@@ -171,19 +171,42 @@ void hmp_info_backup(Monitor *mon, const QDict *qdict)
|
||||
monitor_printf(mon, "End time: %s", ctime(&info->end_time));
|
||||
}
|
||||
|
||||
@ -132,10 +132,18 @@ index 1dda8b7d8f..8cbf645b2c 100644
|
||||
|
||||
|
||||
diff --git a/pve-backup.c b/pve-backup.c
|
||||
index 3d28975eaa..abd7062afe 100644
|
||||
index bb51c030bd..cfdeb50f23 100644
|
||||
--- a/pve-backup.c
|
||||
+++ b/pve-backup.c
|
||||
@@ -28,6 +28,8 @@
|
||||
@@ -7,6 +7,7 @@
|
||||
#include "sysemu/blockdev.h"
|
||||
#include "block/block_int-global-state.h"
|
||||
#include "block/blockjob.h"
|
||||
+#include "block/dirty-bitmap.h"
|
||||
#include "qapi/qapi-commands-block.h"
|
||||
#include "qapi/qmp/qerror.h"
|
||||
|
||||
@@ -29,6 +30,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
@ -144,7 +152,7 @@ index 3d28975eaa..abd7062afe 100644
|
||||
static struct PVEBackupState {
|
||||
struct {
|
||||
// Everithing accessed from qmp_backup_query command is protected using lock
|
||||
@@ -39,7 +41,9 @@ static struct PVEBackupState {
|
||||
@@ -40,7 +43,9 @@ static struct PVEBackupState {
|
||||
uuid_t uuid;
|
||||
char uuid_str[37];
|
||||
size_t total;
|
||||
@ -154,7 +162,7 @@ index 3d28975eaa..abd7062afe 100644
|
||||
size_t zero_bytes;
|
||||
} stat;
|
||||
int64_t speed;
|
||||
@@ -66,6 +70,7 @@ typedef struct PVEBackupDevInfo {
|
||||
@@ -67,6 +72,7 @@ typedef struct PVEBackupDevInfo {
|
||||
uint8_t dev_id;
|
||||
bool completed;
|
||||
char targetfile[PATH_MAX];
|
||||
@ -162,7 +170,7 @@ index 3d28975eaa..abd7062afe 100644
|
||||
BlockDriverState *target;
|
||||
} PVEBackupDevInfo;
|
||||
|
||||
@@ -107,11 +112,12 @@ static bool pvebackup_error_or_canceled(void)
|
||||
@@ -108,11 +114,12 @@ static bool pvebackup_error_or_canceled(void)
|
||||
return error_or_canceled;
|
||||
}
|
||||
|
||||
@ -176,7 +184,7 @@ index 3d28975eaa..abd7062afe 100644
|
||||
qemu_mutex_unlock(&backup_state.stat.lock);
|
||||
}
|
||||
|
||||
@@ -150,7 +156,8 @@ pvebackup_co_dump_pbs_cb(
|
||||
@@ -151,7 +158,8 @@ pvebackup_co_dump_pbs_cb(
|
||||
pvebackup_propagate_error(local_err);
|
||||
return pbs_res;
|
||||
} else {
|
||||
@ -186,7 +194,7 @@ index 3d28975eaa..abd7062afe 100644
|
||||
}
|
||||
|
||||
return size;
|
||||
@@ -210,11 +217,11 @@ pvebackup_co_dump_vma_cb(
|
||||
@@ -211,11 +219,11 @@ pvebackup_co_dump_vma_cb(
|
||||
} else {
|
||||
if (remaining >= VMA_CLUSTER_SIZE) {
|
||||
assert(ret == VMA_CLUSTER_SIZE);
|
||||
@ -200,7 +208,7 @@ index 3d28975eaa..abd7062afe 100644
|
||||
remaining = 0;
|
||||
}
|
||||
}
|
||||
@@ -250,6 +257,18 @@ static void coroutine_fn pvebackup_co_cleanup(void *unused)
|
||||
@@ -251,6 +259,18 @@ static void coroutine_fn pvebackup_co_cleanup(void *unused)
|
||||
if (local_err != NULL) {
|
||||
pvebackup_propagate_error(local_err);
|
||||
}
|
||||
@ -219,7 +227,7 @@ index 3d28975eaa..abd7062afe 100644
|
||||
}
|
||||
|
||||
proxmox_backup_disconnect(backup_state.pbs);
|
||||
@@ -305,6 +324,12 @@ static void pvebackup_complete_cb(void *opaque, int ret)
|
||||
@@ -306,6 +326,12 @@ static void pvebackup_complete_cb(void *opaque, int ret)
|
||||
// remove self from job queue
|
||||
backup_state.di_list = g_list_remove(backup_state.di_list, di);
|
||||
|
||||
@ -232,7 +240,7 @@ index 3d28975eaa..abd7062afe 100644
|
||||
g_free(di);
|
||||
|
||||
qemu_mutex_unlock(&backup_state.backup_mutex);
|
||||
@@ -469,12 +494,18 @@ static bool create_backup_jobs(void) {
|
||||
@@ -470,12 +496,18 @@ static bool create_backup_jobs(void) {
|
||||
|
||||
assert(di->target != NULL);
|
||||
|
||||
@ -253,16 +261,16 @@ index 3d28975eaa..abd7062afe 100644
|
||||
JOB_DEFAULT, pvebackup_complete_cb, di, NULL, &local_err);
|
||||
|
||||
aio_context_release(aio_context);
|
||||
@@ -525,6 +556,8 @@ typedef struct QmpBackupTask {
|
||||
@@ -521,6 +553,8 @@ typedef struct QmpBackupTask {
|
||||
bool has_backup_time;
|
||||
const char *fingerprint;
|
||||
bool has_fingerprint;
|
||||
int64_t backup_time;
|
||||
+ bool has_use_dirty_bitmap;
|
||||
+ bool use_dirty_bitmap;
|
||||
bool has_format;
|
||||
BackupFormat format;
|
||||
bool has_config_file;
|
||||
@@ -616,6 +649,7 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
|
||||
const char *config_file;
|
||||
@@ -609,6 +643,7 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
|
||||
}
|
||||
|
||||
size_t total = 0;
|
||||
@ -270,7 +278,7 @@ index 3d28975eaa..abd7062afe 100644
|
||||
|
||||
l = di_list;
|
||||
while (l) {
|
||||
@@ -653,6 +687,8 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
|
||||
@@ -646,6 +681,8 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
|
||||
int dump_cb_block_size = PROXMOX_BACKUP_DEFAULT_CHUNK_SIZE; // Hardcoded (4M)
|
||||
firewall_name = "fw.conf";
|
||||
|
||||
@ -279,7 +287,7 @@ index 3d28975eaa..abd7062afe 100644
|
||||
char *pbs_err = NULL;
|
||||
pbs = proxmox_backup_new(
|
||||
task->backup_file,
|
||||
@@ -672,7 +708,8 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
|
||||
@@ -665,7 +702,8 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
|
||||
goto err;
|
||||
}
|
||||
|
||||
@ -289,7 +297,7 @@ index 3d28975eaa..abd7062afe 100644
|
||||
goto err;
|
||||
|
||||
/* register all devices */
|
||||
@@ -683,9 +720,40 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
|
||||
@@ -676,9 +714,40 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
|
||||
|
||||
const char *devname = bdrv_get_device_name(di->bs);
|
||||
|
||||
@ -332,7 +340,7 @@ index 3d28975eaa..abd7062afe 100644
|
||||
|
||||
if (!(di->target = bdrv_backup_dump_create(dump_cb_block_size, di->size, pvebackup_co_dump_pbs_cb, di, task->errp))) {
|
||||
goto err;
|
||||
@@ -694,6 +762,8 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
|
||||
@@ -687,6 +756,8 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
|
||||
di->dev_id = dev_id;
|
||||
}
|
||||
} else if (format == BACKUP_FORMAT_VMA) {
|
||||
@ -341,7 +349,7 @@ index 3d28975eaa..abd7062afe 100644
|
||||
vmaw = vma_writer_create(task->backup_file, uuid, &local_err);
|
||||
if (!vmaw) {
|
||||
if (local_err) {
|
||||
@@ -721,6 +791,8 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
|
||||
@@ -714,6 +785,8 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
|
||||
}
|
||||
}
|
||||
} else if (format == BACKUP_FORMAT_DIR) {
|
||||
@ -350,7 +358,7 @@ index 3d28975eaa..abd7062afe 100644
|
||||
if (mkdir(task->backup_file, 0640) != 0) {
|
||||
error_setg_errno(task->errp, errno, "can't create directory '%s'\n",
|
||||
task->backup_file);
|
||||
@@ -793,8 +865,10 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
|
||||
@@ -786,8 +859,10 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
|
||||
char *uuid_str = g_strdup(backup_state.stat.uuid_str);
|
||||
|
||||
backup_state.stat.total = total;
|
||||
@ -361,7 +369,7 @@ index 3d28975eaa..abd7062afe 100644
|
||||
|
||||
qemu_mutex_unlock(&backup_state.stat.lock);
|
||||
|
||||
@@ -818,6 +892,10 @@ err:
|
||||
@@ -811,6 +886,10 @@ err:
|
||||
PVEBackupDevInfo *di = (PVEBackupDevInfo *)l->data;
|
||||
l = g_list_next(l);
|
||||
|
||||
@ -372,15 +380,15 @@ index 3d28975eaa..abd7062afe 100644
|
||||
if (di->target) {
|
||||
bdrv_unref(di->target);
|
||||
}
|
||||
@@ -859,6 +937,7 @@ UuidInfo *qmp_backup(
|
||||
bool has_fingerprint, const char *fingerprint,
|
||||
bool has_backup_id, const char *backup_id,
|
||||
@@ -852,6 +931,7 @@ UuidInfo *qmp_backup(
|
||||
const char *fingerprint,
|
||||
const char *backup_id,
|
||||
bool has_backup_time, int64_t backup_time,
|
||||
+ bool has_use_dirty_bitmap, bool use_dirty_bitmap,
|
||||
bool has_format, BackupFormat format,
|
||||
bool has_config_file, const char *config_file,
|
||||
bool has_firewall_file, const char *firewall_file,
|
||||
@@ -877,6 +956,8 @@ UuidInfo *qmp_backup(
|
||||
const char *config_file,
|
||||
const char *firewall_file,
|
||||
@@ -866,6 +946,8 @@ UuidInfo *qmp_backup(
|
||||
.backup_id = backup_id,
|
||||
.has_backup_time = has_backup_time,
|
||||
.backup_time = backup_time,
|
||||
@ -388,8 +396,8 @@ index 3d28975eaa..abd7062afe 100644
|
||||
+ .use_dirty_bitmap = use_dirty_bitmap,
|
||||
.has_format = has_format,
|
||||
.format = format,
|
||||
.has_config_file = has_config_file,
|
||||
@@ -945,10 +1026,14 @@ BackupStatus *qmp_query_backup(Error **errp)
|
||||
.config_file = config_file,
|
||||
@@ -927,10 +1009,14 @@ BackupStatus *qmp_query_backup(Error **errp)
|
||||
|
||||
info->has_total = true;
|
||||
info->total = backup_state.stat.total;
|
||||
@ -405,10 +413,10 @@ index 3d28975eaa..abd7062afe 100644
|
||||
qemu_mutex_unlock(&backup_state.stat.lock);
|
||||
|
||||
diff --git a/qapi/block-core.json b/qapi/block-core.json
|
||||
index c3b6b93472..992e6c1e3f 100644
|
||||
index 16fb4c5ea0..92f90a898a 100644
|
||||
--- a/qapi/block-core.json
|
||||
+++ b/qapi/block-core.json
|
||||
@@ -753,8 +753,13 @@
|
||||
@@ -848,8 +848,13 @@
|
||||
#
|
||||
# @total: total amount of bytes involved in the backup process
|
||||
#
|
||||
@ -422,7 +430,7 @@ index c3b6b93472..992e6c1e3f 100644
|
||||
# @zero-bytes: amount of 'zero' bytes detected.
|
||||
#
|
||||
# @start-time: time (epoch) when backup job started.
|
||||
@@ -767,8 +772,8 @@
|
||||
@@ -862,8 +867,8 @@
|
||||
#
|
||||
##
|
||||
{ 'struct': 'BackupStatus',
|
||||
@ -433,7 +441,7 @@ index c3b6b93472..992e6c1e3f 100644
|
||||
'*start-time': 'int', '*end-time': 'int',
|
||||
'*backup-file': 'str', '*uuid': 'str' } }
|
||||
|
||||
@@ -811,6 +816,8 @@
|
||||
@@ -906,6 +911,8 @@
|
||||
#
|
||||
# @backup-time: backup timestamp (Unix epoch, required for format 'pbs')
|
||||
#
|
||||
@ -442,7 +450,7 @@ index c3b6b93472..992e6c1e3f 100644
|
||||
# Returns: the uuid of the backup job
|
||||
#
|
||||
##
|
||||
@@ -821,6 +828,7 @@
|
||||
@@ -916,6 +923,7 @@
|
||||
'*fingerprint': 'str',
|
||||
'*backup-id': 'str',
|
||||
'*backup-time': 'int',
|
||||
|
@ -12,40 +12,42 @@ Signed-off-by: Stefan Reiter <s.reiter@proxmox.com>
|
||||
PVE: add zero block handling to PBS dump callback
|
||||
Signed-off-by: Stefan Reiter <s.reiter@proxmox.com>
|
||||
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
|
||||
[FE: adapt to QAPI change dropping redundant has_*]
|
||||
Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
|
||||
---
|
||||
block/monitor/block-hmp-cmds.c | 4 ++-
|
||||
pve-backup.c | 57 +++++++++++++++++++++++++++-------
|
||||
pve-backup.c | 54 +++++++++++++++++++++++++++-------
|
||||
qapi/block-core.json | 6 ++++
|
||||
3 files changed, 54 insertions(+), 13 deletions(-)
|
||||
3 files changed, 52 insertions(+), 12 deletions(-)
|
||||
|
||||
diff --git a/block/monitor/block-hmp-cmds.c b/block/monitor/block-hmp-cmds.c
|
||||
index 556af25861..a09f722fea 100644
|
||||
index bcba630f12..6a6ed6d0e7 100644
|
||||
--- a/block/monitor/block-hmp-cmds.c
|
||||
+++ b/block/monitor/block-hmp-cmds.c
|
||||
@@ -1042,7 +1042,9 @@ void hmp_backup(Monitor *mon, const QDict *qdict)
|
||||
false, NULL, // PBS fingerprint
|
||||
false, NULL, // PBS backup-id
|
||||
@@ -1054,7 +1054,9 @@ void hmp_backup(Monitor *mon, const QDict *qdict)
|
||||
NULL, // PBS fingerprint
|
||||
NULL, // PBS backup-id
|
||||
false, 0, // PBS backup-time
|
||||
- false, false, // PBS incremental
|
||||
+ false, false, // PBS use-dirty-bitmap
|
||||
+ false, false, // PBS compress
|
||||
+ false, false, // PBS encrypt
|
||||
true, dir ? BACKUP_FORMAT_DIR : BACKUP_FORMAT_VMA,
|
||||
false, NULL, false, NULL, !!devlist,
|
||||
NULL, NULL,
|
||||
devlist, qdict_haskey(qdict, "speed"), speed, &error);
|
||||
diff --git a/pve-backup.c b/pve-backup.c
|
||||
index abd7062afe..e113ab61b9 100644
|
||||
index cfdeb50f23..f1eacbcaf6 100644
|
||||
--- a/pve-backup.c
|
||||
+++ b/pve-backup.c
|
||||
@@ -8,6 +8,7 @@
|
||||
#include "block/blockjob.h"
|
||||
@@ -10,6 +10,7 @@
|
||||
#include "block/dirty-bitmap.h"
|
||||
#include "qapi/qapi-commands-block.h"
|
||||
#include "qapi/qmp/qerror.h"
|
||||
+#include "qemu/cutils.h"
|
||||
|
||||
/* PVE backup state and related function */
|
||||
|
||||
@@ -67,6 +68,7 @@ opts_init(pvebackup_init);
|
||||
@@ -69,6 +70,7 @@ opts_init(pvebackup_init);
|
||||
typedef struct PVEBackupDevInfo {
|
||||
BlockDriverState *bs;
|
||||
size_t size;
|
||||
@ -53,7 +55,7 @@ index abd7062afe..e113ab61b9 100644
|
||||
uint8_t dev_id;
|
||||
bool completed;
|
||||
char targetfile[PATH_MAX];
|
||||
@@ -137,10 +139,13 @@ pvebackup_co_dump_pbs_cb(
|
||||
@@ -139,10 +141,13 @@ pvebackup_co_dump_pbs_cb(
|
||||
PVEBackupDevInfo *di = opaque;
|
||||
|
||||
assert(backup_state.pbs);
|
||||
@ -67,7 +69,7 @@ index abd7062afe..e113ab61b9 100644
|
||||
qemu_co_mutex_lock(&backup_state.dump_callback_mutex);
|
||||
|
||||
// avoid deadlock if job is cancelled
|
||||
@@ -149,17 +154,29 @@ pvebackup_co_dump_pbs_cb(
|
||||
@@ -151,17 +156,29 @@ pvebackup_co_dump_pbs_cb(
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -105,7 +107,7 @@ index abd7062afe..e113ab61b9 100644
|
||||
return size;
|
||||
}
|
||||
|
||||
@@ -180,6 +197,7 @@ pvebackup_co_dump_vma_cb(
|
||||
@@ -182,6 +199,7 @@ pvebackup_co_dump_vma_cb(
|
||||
int ret = -1;
|
||||
|
||||
assert(backup_state.vmaw);
|
||||
@ -113,7 +115,7 @@ index abd7062afe..e113ab61b9 100644
|
||||
|
||||
uint64_t remaining = size;
|
||||
|
||||
@@ -206,9 +224,7 @@ pvebackup_co_dump_vma_cb(
|
||||
@@ -208,9 +226,7 @@ pvebackup_co_dump_vma_cb(
|
||||
qemu_co_mutex_unlock(&backup_state.dump_callback_mutex);
|
||||
|
||||
++cluster_num;
|
||||
@ -124,9 +126,9 @@ index abd7062afe..e113ab61b9 100644
|
||||
if (ret < 0) {
|
||||
Error *local_err = NULL;
|
||||
vma_writer_error_propagate(backup_state.vmaw, &local_err);
|
||||
@@ -566,6 +582,10 @@ typedef struct QmpBackupTask {
|
||||
@@ -560,6 +576,10 @@ typedef struct QmpBackupTask {
|
||||
const char *config_file;
|
||||
const char *firewall_file;
|
||||
bool has_devlist;
|
||||
const char *devlist;
|
||||
+ bool has_compress;
|
||||
+ bool compress;
|
||||
@ -135,7 +137,7 @@ index abd7062afe..e113ab61b9 100644
|
||||
bool has_speed;
|
||||
int64_t speed;
|
||||
Error **errp;
|
||||
@@ -689,6 +709,7 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
|
||||
@@ -683,6 +703,7 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
|
||||
|
||||
bool use_dirty_bitmap = task->has_use_dirty_bitmap && task->use_dirty_bitmap;
|
||||
|
||||
@ -143,19 +145,16 @@ index abd7062afe..e113ab61b9 100644
|
||||
char *pbs_err = NULL;
|
||||
pbs = proxmox_backup_new(
|
||||
task->backup_file,
|
||||
@@ -698,8 +719,10 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
|
||||
task->has_password ? task->password : NULL,
|
||||
task->has_keyfile ? task->keyfile : NULL,
|
||||
task->has_key_password ? task->key_password : NULL,
|
||||
@@ -692,6 +713,8 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
|
||||
task->password,
|
||||
task->keyfile,
|
||||
task->key_password,
|
||||
+ task->has_compress ? task->compress : true,
|
||||
+ task->has_encrypt ? task->encrypt : task->has_keyfile,
|
||||
task->has_fingerprint ? task->fingerprint : NULL,
|
||||
- &pbs_err);
|
||||
+ &pbs_err);
|
||||
+ task->has_encrypt ? task->encrypt : !!task->keyfile,
|
||||
task->fingerprint,
|
||||
&pbs_err);
|
||||
|
||||
if (!pbs) {
|
||||
error_set(task->errp, ERROR_CLASS_GENERIC_ERROR,
|
||||
@@ -718,6 +741,8 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
|
||||
@@ -712,6 +735,8 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
|
||||
PVEBackupDevInfo *di = (PVEBackupDevInfo *)l->data;
|
||||
l = g_list_next(l);
|
||||
|
||||
@ -164,25 +163,24 @@ index abd7062afe..e113ab61b9 100644
|
||||
const char *devname = bdrv_get_device_name(di->bs);
|
||||
|
||||
BdrvDirtyBitmap *bitmap = bdrv_find_dirty_bitmap(di->bs, PBS_BITMAP_NAME);
|
||||
@@ -938,6 +963,8 @@ UuidInfo *qmp_backup(
|
||||
bool has_backup_id, const char *backup_id,
|
||||
@@ -932,6 +957,8 @@ UuidInfo *qmp_backup(
|
||||
const char *backup_id,
|
||||
bool has_backup_time, int64_t backup_time,
|
||||
bool has_use_dirty_bitmap, bool use_dirty_bitmap,
|
||||
+ bool has_compress, bool compress,
|
||||
+ bool has_encrypt, bool encrypt,
|
||||
bool has_format, BackupFormat format,
|
||||
bool has_config_file, const char *config_file,
|
||||
bool has_firewall_file, const char *firewall_file,
|
||||
@@ -948,6 +975,8 @@ UuidInfo *qmp_backup(
|
||||
const char *config_file,
|
||||
const char *firewall_file,
|
||||
@@ -941,6 +968,7 @@ UuidInfo *qmp_backup(
|
||||
QmpBackupTask task = {
|
||||
.backup_file = backup_file,
|
||||
.has_password = has_password,
|
||||
.password = password,
|
||||
+ .has_keyfile = has_keyfile,
|
||||
+ .keyfile = keyfile,
|
||||
.has_key_password = has_key_password,
|
||||
.key_password = key_password,
|
||||
.has_fingerprint = has_fingerprint,
|
||||
@@ -958,6 +987,10 @@ UuidInfo *qmp_backup(
|
||||
.fingerprint = fingerprint,
|
||||
.backup_id = backup_id,
|
||||
@@ -948,6 +976,10 @@ UuidInfo *qmp_backup(
|
||||
.backup_time = backup_time,
|
||||
.has_use_dirty_bitmap = has_use_dirty_bitmap,
|
||||
.use_dirty_bitmap = use_dirty_bitmap,
|
||||
@ -192,12 +190,12 @@ index abd7062afe..e113ab61b9 100644
|
||||
+ .encrypt = encrypt,
|
||||
.has_format = has_format,
|
||||
.format = format,
|
||||
.has_config_file = has_config_file,
|
||||
.config_file = config_file,
|
||||
diff --git a/qapi/block-core.json b/qapi/block-core.json
|
||||
index 992e6c1e3f..5ac6276dc1 100644
|
||||
index 92f90a898a..864b8ce97c 100644
|
||||
--- a/qapi/block-core.json
|
||||
+++ b/qapi/block-core.json
|
||||
@@ -818,6 +818,10 @@
|
||||
@@ -913,6 +913,10 @@
|
||||
#
|
||||
# @use-dirty-bitmap: use dirty bitmap to detect incremental changes since last job (optional for format 'pbs')
|
||||
#
|
||||
@ -208,7 +206,7 @@ index 992e6c1e3f..5ac6276dc1 100644
|
||||
# Returns: the uuid of the backup job
|
||||
#
|
||||
##
|
||||
@@ -829,6 +833,8 @@
|
||||
@@ -924,6 +928,8 @@
|
||||
'*backup-id': 'str',
|
||||
'*backup-time': 'int',
|
||||
'*use-dirty-bitmap': 'bool',
|
||||
|
@ -8,23 +8,24 @@ Signed-off-by: Stefan Reiter <s.reiter@proxmox.com>
|
||||
Signed-off-by: Dietmar Maurer <dietmar@proxmox.com>
|
||||
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
|
||||
[FE: adapt to changed function signatures
|
||||
make pbs_co_preadv return values consistent with QEMU]
|
||||
make pbs_co_preadv return values consistent with QEMU
|
||||
getlength is now a coroutine function]
|
||||
Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
|
||||
---
|
||||
block/meson.build | 3 +
|
||||
block/pbs.c | 276 +++++++++++++++++++++++++++++++++++++++++++
|
||||
block/pbs.c | 277 +++++++++++++++++++++++++++++++++++++++++++
|
||||
configure | 9 ++
|
||||
meson.build | 2 +-
|
||||
qapi/block-core.json | 13 ++
|
||||
qapi/pragma.json | 1 +
|
||||
6 files changed, 303 insertions(+), 1 deletion(-)
|
||||
6 files changed, 304 insertions(+), 1 deletion(-)
|
||||
create mode 100644 block/pbs.c
|
||||
|
||||
diff --git a/block/meson.build b/block/meson.build
|
||||
index e995ae72b9..7ef2fa72d5 100644
|
||||
index 5bcebb934b..eece0d5743 100644
|
||||
--- a/block/meson.build
|
||||
+++ b/block/meson.build
|
||||
@@ -53,6 +53,9 @@ block_ss.add(files(
|
||||
@@ -54,6 +54,9 @@ block_ss.add(files(
|
||||
'../pve-backup.c',
|
||||
), libproxmox_backup_qemu)
|
||||
|
||||
@ -36,10 +37,10 @@ index e995ae72b9..7ef2fa72d5 100644
|
||||
softmmu_ss.add(files('block-ram-registrar.c'))
|
||||
diff --git a/block/pbs.c b/block/pbs.c
|
||||
new file mode 100644
|
||||
index 0000000000..9d1f1f39d4
|
||||
index 0000000000..43e69ada46
|
||||
--- /dev/null
|
||||
+++ b/block/pbs.c
|
||||
@@ -0,0 +1,276 @@
|
||||
@@ -0,0 +1,277 @@
|
||||
+/*
|
||||
+ * Proxmox Backup Server read-only block driver
|
||||
+ */
|
||||
@ -52,6 +53,7 @@ index 0000000000..9d1f1f39d4
|
||||
+#include "qemu/option.h"
|
||||
+#include "qemu/cutils.h"
|
||||
+#include "block/block_int.h"
|
||||
+#include "block/block-io.h"
|
||||
+
|
||||
+#include <proxmox-backup-qemu.h>
|
||||
+
|
||||
@ -218,7 +220,7 @@ index 0000000000..9d1f1f39d4
|
||||
+ proxmox_restore_disconnect(s->conn);
|
||||
+}
|
||||
+
|
||||
+static int64_t pbs_getlength(BlockDriverState *bs)
|
||||
+static coroutine_fn int64_t pbs_co_getlength(BlockDriverState *bs)
|
||||
+{
|
||||
+ BDRVPBSState *s = bs->opaque;
|
||||
+ return s->length;
|
||||
@ -301,7 +303,7 @@ index 0000000000..9d1f1f39d4
|
||||
+ .bdrv_file_open = pbs_file_open,
|
||||
+ .bdrv_open = pbs_open,
|
||||
+ .bdrv_close = pbs_close,
|
||||
+ .bdrv_getlength = pbs_getlength,
|
||||
+ .bdrv_co_getlength = pbs_co_getlength,
|
||||
+
|
||||
+ .bdrv_co_preadv = pbs_co_preadv,
|
||||
+ .bdrv_co_pwritev = pbs_co_pwritev,
|
||||
@ -317,10 +319,10 @@ index 0000000000..9d1f1f39d4
|
||||
+
|
||||
+block_init(bdrv_pbs_init);
|
||||
diff --git a/configure b/configure
|
||||
index 26c7bc5154..c587e986c7 100755
|
||||
index 800b5850f4..37e12a3dce 100755
|
||||
--- a/configure
|
||||
+++ b/configure
|
||||
@@ -285,6 +285,7 @@ linux_user=""
|
||||
@@ -288,6 +288,7 @@ linux_user=""
|
||||
bsd_user=""
|
||||
pie=""
|
||||
coroutine=""
|
||||
@ -328,9 +330,9 @@ index 26c7bc5154..c587e986c7 100755
|
||||
plugins="$default_feature"
|
||||
meson=""
|
||||
ninja=""
|
||||
@@ -864,6 +865,10 @@ for opt do
|
||||
--enable-uuid|--disable-uuid)
|
||||
echo "$0: $opt is obsolete, UUID support is always built" >&2
|
||||
@@ -872,6 +873,10 @@ for opt do
|
||||
;;
|
||||
--with-coroutine=*) coroutine="$optarg"
|
||||
;;
|
||||
+ --disable-pbs-bdrv) pbs_bdrv="no"
|
||||
+ ;;
|
||||
@ -339,15 +341,15 @@ index 26c7bc5154..c587e986c7 100755
|
||||
--with-git=*) git="$optarg"
|
||||
;;
|
||||
--with-git-submodules=*)
|
||||
@@ -1049,6 +1054,7 @@ cat << EOF
|
||||
@@ -1048,6 +1053,7 @@ cat << EOF
|
||||
debug-info debugging information
|
||||
safe-stack SafeStack Stack Smash Protection. Depends on
|
||||
clang/llvm >= 3.7 and requires coroutine backend ucontext.
|
||||
clang/llvm and requires coroutine backend ucontext.
|
||||
+ pbs-bdrv Proxmox backup server read-only block driver support
|
||||
|
||||
NOTE: The object files are built at the place where configure is launched
|
||||
EOF
|
||||
@@ -2372,6 +2378,9 @@ echo "TARGET_DIRS=$target_list" >> $config_host_mak
|
||||
@@ -2385,6 +2391,9 @@ echo "TARGET_DIRS=$target_list" >> $config_host_mak
|
||||
if test "$modules" = "yes"; then
|
||||
echo "CONFIG_MODULES=y" >> $config_host_mak
|
||||
fi
|
||||
@ -358,10 +360,10 @@ index 26c7bc5154..c587e986c7 100755
|
||||
# XXX: suppress that
|
||||
if [ "$bsd" = "yes" ] ; then
|
||||
diff --git a/meson.build b/meson.build
|
||||
index 63ea813a9a..f7f5b3f253 100644
|
||||
index 8ec21bba90..419bea5cf4 100644
|
||||
--- a/meson.build
|
||||
+++ b/meson.build
|
||||
@@ -3978,7 +3978,7 @@ summary_info += {'bzip2 support': libbzip2}
|
||||
@@ -4035,7 +4035,7 @@ summary_info += {'bzip2 support': libbzip2}
|
||||
summary_info += {'lzfse support': liblzfse}
|
||||
summary_info += {'zstd support': zstd}
|
||||
summary_info += {'NUMA host support': numa}
|
||||
@ -371,10 +373,10 @@ index 63ea813a9a..f7f5b3f253 100644
|
||||
summary_info += {'libdaxctl support': libdaxctl}
|
||||
summary_info += {'libudev': libudev}
|
||||
diff --git a/qapi/block-core.json b/qapi/block-core.json
|
||||
index 5ac6276dc1..45b63dfe26 100644
|
||||
index 864b8ce97c..705a65ab1a 100644
|
||||
--- a/qapi/block-core.json
|
||||
+++ b/qapi/block-core.json
|
||||
@@ -3103,6 +3103,7 @@
|
||||
@@ -3198,6 +3198,7 @@
|
||||
'parallels', 'preallocate', 'qcow', 'qcow2', 'qed', 'quorum',
|
||||
'raw', 'rbd',
|
||||
{ 'name': 'replication', 'if': 'CONFIG_REPLICATION' },
|
||||
@ -382,7 +384,7 @@ index 5ac6276dc1..45b63dfe26 100644
|
||||
'ssh', 'throttle', 'vdi', 'vhdx',
|
||||
{ 'name': 'virtio-blk-vfio-pci', 'if': 'CONFIG_BLKIO' },
|
||||
{ 'name': 'virtio-blk-vhost-user', 'if': 'CONFIG_BLKIO' },
|
||||
@@ -3179,6 +3180,17 @@
|
||||
@@ -3274,6 +3275,17 @@
|
||||
{ 'struct': 'BlockdevOptionsNull',
|
||||
'data': { '*size': 'int', '*latency-ns': 'uint64', '*read-zeroes': 'bool' } }
|
||||
|
||||
@ -400,7 +402,7 @@ index 5ac6276dc1..45b63dfe26 100644
|
||||
##
|
||||
# @BlockdevOptionsNVMe:
|
||||
#
|
||||
@@ -4531,6 +4543,7 @@
|
||||
@@ -4647,6 +4659,7 @@
|
||||
'nfs': 'BlockdevOptionsNfs',
|
||||
'null-aio': 'BlockdevOptionsNull',
|
||||
'null-co': 'BlockdevOptionsNull',
|
||||
|
@ -16,10 +16,10 @@ Signed-off-by: Stefan Reiter <s.reiter@proxmox.com>
|
||||
2 files changed, 38 insertions(+)
|
||||
|
||||
diff --git a/pve-backup.c b/pve-backup.c
|
||||
index e113ab61b9..9318ca4f0c 100644
|
||||
index f1eacbcaf6..c6fee40a67 100644
|
||||
--- a/pve-backup.c
|
||||
+++ b/pve-backup.c
|
||||
@@ -1072,3 +1072,12 @@ BackupStatus *qmp_query_backup(Error **errp)
|
||||
@@ -1054,3 +1054,12 @@ BackupStatus *qmp_query_backup(Error **errp)
|
||||
|
||||
return info;
|
||||
}
|
||||
@ -33,10 +33,10 @@ index e113ab61b9..9318ca4f0c 100644
|
||||
+ return ret;
|
||||
+}
|
||||
diff --git a/qapi/block-core.json b/qapi/block-core.json
|
||||
index 45b63dfe26..8b0e0d92de 100644
|
||||
index 705a65ab1a..1ac535fcf2 100644
|
||||
--- a/qapi/block-core.json
|
||||
+++ b/qapi/block-core.json
|
||||
@@ -863,6 +863,35 @@
|
||||
@@ -958,6 +958,35 @@
|
||||
##
|
||||
{ 'command': 'backup-cancel' }
|
||||
|
||||
|
@ -15,10 +15,10 @@ Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
|
||||
3 files changed, 159 insertions(+), 42 deletions(-)
|
||||
|
||||
diff --git a/monitor/hmp-cmds.c b/monitor/hmp-cmds.c
|
||||
index 670f783515..d819e5fc36 100644
|
||||
index 087161a967..9a67e544ce 100644
|
||||
--- a/monitor/hmp-cmds.c
|
||||
+++ b/monitor/hmp-cmds.c
|
||||
@@ -202,6 +202,7 @@ void hmp_info_mice(Monitor *mon, const QDict *qdict)
|
||||
@@ -148,6 +148,7 @@ void hmp_sync_profile(Monitor *mon, const QDict *qdict)
|
||||
void hmp_info_backup(Monitor *mon, const QDict *qdict)
|
||||
{
|
||||
BackupStatus *info;
|
||||
@ -26,7 +26,7 @@ index 670f783515..d819e5fc36 100644
|
||||
|
||||
info = qmp_query_backup(NULL);
|
||||
|
||||
@@ -232,26 +233,29 @@ void hmp_info_backup(Monitor *mon, const QDict *qdict)
|
||||
@@ -178,26 +179,29 @@ void hmp_info_backup(Monitor *mon, const QDict *qdict)
|
||||
// this should not happen normally
|
||||
monitor_printf(mon, "Total size: %d\n", 0);
|
||||
} else {
|
||||
@ -69,10 +69,10 @@ index 670f783515..d819e5fc36 100644
|
||||
info->zero_bytes, zero_per);
|
||||
|
||||
diff --git a/pve-backup.c b/pve-backup.c
|
||||
index 9318ca4f0c..c85b2ecd83 100644
|
||||
index c6fee40a67..d4abe6e703 100644
|
||||
--- a/pve-backup.c
|
||||
+++ b/pve-backup.c
|
||||
@@ -46,6 +46,7 @@ static struct PVEBackupState {
|
||||
@@ -48,6 +48,7 @@ static struct PVEBackupState {
|
||||
size_t transferred;
|
||||
size_t reused;
|
||||
size_t zero_bytes;
|
||||
@ -80,7 +80,7 @@ index 9318ca4f0c..c85b2ecd83 100644
|
||||
} stat;
|
||||
int64_t speed;
|
||||
VmaWriter *vmaw;
|
||||
@@ -669,7 +670,6 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
|
||||
@@ -663,7 +664,6 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
|
||||
}
|
||||
|
||||
size_t total = 0;
|
||||
@ -88,7 +88,7 @@ index 9318ca4f0c..c85b2ecd83 100644
|
||||
|
||||
l = di_list;
|
||||
while (l) {
|
||||
@@ -690,18 +690,33 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
|
||||
@@ -684,18 +684,33 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
|
||||
|
||||
uuid_generate(uuid);
|
||||
|
||||
@ -108,12 +108,12 @@ index 9318ca4f0c..c85b2ecd83 100644
|
||||
+ }
|
||||
+
|
||||
if (format == BACKUP_FORMAT_PBS) {
|
||||
if (!task->has_password) {
|
||||
if (!task->password) {
|
||||
error_set(task->errp, ERROR_CLASS_GENERIC_ERROR, "missing parameter 'password'");
|
||||
- goto err;
|
||||
+ goto err_mutex;
|
||||
}
|
||||
if (!task->has_backup_id) {
|
||||
if (!task->backup_id) {
|
||||
error_set(task->errp, ERROR_CLASS_GENERIC_ERROR, "missing parameter 'backup-id'");
|
||||
- goto err;
|
||||
+ goto err_mutex;
|
||||
@ -125,7 +125,7 @@ index 9318ca4f0c..c85b2ecd83 100644
|
||||
}
|
||||
|
||||
int dump_cb_block_size = PROXMOX_BACKUP_DEFAULT_CHUNK_SIZE; // Hardcoded (4M)
|
||||
@@ -728,12 +743,12 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
|
||||
@@ -722,12 +737,12 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
|
||||
error_set(task->errp, ERROR_CLASS_GENERIC_ERROR,
|
||||
"proxmox_backup_new failed: %s", pbs_err);
|
||||
proxmox_backup_free_error(pbs_err);
|
||||
@ -140,7 +140,7 @@ index 9318ca4f0c..c85b2ecd83 100644
|
||||
|
||||
/* register all devices */
|
||||
l = di_list;
|
||||
@@ -744,6 +759,8 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
|
||||
@@ -738,6 +753,8 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
|
||||
di->block_size = dump_cb_block_size;
|
||||
|
||||
const char *devname = bdrv_get_device_name(di->bs);
|
||||
@ -149,7 +149,7 @@ index 9318ca4f0c..c85b2ecd83 100644
|
||||
|
||||
BdrvDirtyBitmap *bitmap = bdrv_find_dirty_bitmap(di->bs, PBS_BITMAP_NAME);
|
||||
bool expect_only_dirty = false;
|
||||
@@ -752,49 +769,59 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
|
||||
@@ -746,49 +763,59 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
|
||||
if (bitmap == NULL) {
|
||||
bitmap = bdrv_create_dirty_bitmap(di->bs, dump_cb_block_size, PBS_BITMAP_NAME, task->errp);
|
||||
if (!bitmap) {
|
||||
@ -219,7 +219,7 @@ index 9318ca4f0c..c85b2ecd83 100644
|
||||
}
|
||||
|
||||
/* register all devices for vma writer */
|
||||
@@ -804,7 +831,7 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
|
||||
@@ -798,7 +825,7 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
|
||||
l = g_list_next(l);
|
||||
|
||||
if (!(di->target = bdrv_backup_dump_create(VMA_CLUSTER_SIZE, di->size, pvebackup_co_dump_vma_cb, di, task->errp))) {
|
||||
@ -228,7 +228,7 @@ index 9318ca4f0c..c85b2ecd83 100644
|
||||
}
|
||||
|
||||
const char *devname = bdrv_get_device_name(di->bs);
|
||||
@@ -812,16 +839,14 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
|
||||
@@ -806,16 +833,14 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
|
||||
if (di->dev_id <= 0) {
|
||||
error_set(task->errp, ERROR_CLASS_GENERIC_ERROR,
|
||||
"register_stream failed");
|
||||
@ -247,7 +247,7 @@ index 9318ca4f0c..c85b2ecd83 100644
|
||||
}
|
||||
backup_dir = task->backup_file;
|
||||
|
||||
@@ -838,18 +863,18 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
|
||||
@@ -832,18 +857,18 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
|
||||
di->size, flags, false, &local_err);
|
||||
if (local_err) {
|
||||
error_propagate(task->errp, local_err);
|
||||
@ -269,8 +269,8 @@ index 9318ca4f0c..c85b2ecd83 100644
|
||||
}
|
||||
|
||||
|
||||
@@ -857,7 +882,7 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
|
||||
if (task->has_config_file) {
|
||||
@@ -851,7 +876,7 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
|
||||
if (task->config_file) {
|
||||
if (pvebackup_co_add_config(task->config_file, config_name, format, backup_dir,
|
||||
vmaw, pbs, task->errp) != 0) {
|
||||
- goto err;
|
||||
@ -278,8 +278,8 @@ index 9318ca4f0c..c85b2ecd83 100644
|
||||
}
|
||||
}
|
||||
|
||||
@@ -865,12 +890,11 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
|
||||
if (task->has_firewall_file) {
|
||||
@@ -859,12 +884,11 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
|
||||
if (task->firewall_file) {
|
||||
if (pvebackup_co_add_config(task->firewall_file, firewall_name, format, backup_dir,
|
||||
vmaw, pbs, task->errp) != 0) {
|
||||
- goto err;
|
||||
@ -293,7 +293,7 @@ index 9318ca4f0c..c85b2ecd83 100644
|
||||
|
||||
if (backup_state.stat.error) {
|
||||
error_free(backup_state.stat.error);
|
||||
@@ -890,10 +914,9 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
|
||||
@@ -884,10 +908,9 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
|
||||
char *uuid_str = g_strdup(backup_state.stat.uuid_str);
|
||||
|
||||
backup_state.stat.total = total;
|
||||
@ -305,7 +305,7 @@ index 9318ca4f0c..c85b2ecd83 100644
|
||||
|
||||
qemu_mutex_unlock(&backup_state.stat.lock);
|
||||
|
||||
@@ -910,6 +933,9 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
|
||||
@@ -904,6 +927,9 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
|
||||
task->result = uuid_info;
|
||||
return;
|
||||
|
||||
@ -315,7 +315,7 @@ index 9318ca4f0c..c85b2ecd83 100644
|
||||
err:
|
||||
|
||||
l = di_list;
|
||||
@@ -1073,11 +1099,42 @@ BackupStatus *qmp_query_backup(Error **errp)
|
||||
@@ -1055,11 +1081,42 @@ BackupStatus *qmp_query_backup(Error **errp)
|
||||
return info;
|
||||
}
|
||||
|
||||
@ -359,10 +359,10 @@ index 9318ca4f0c..c85b2ecd83 100644
|
||||
return ret;
|
||||
}
|
||||
diff --git a/qapi/block-core.json b/qapi/block-core.json
|
||||
index 8b0e0d92de..7fde927621 100644
|
||||
index 1ac535fcf2..130d5f065f 100644
|
||||
--- a/qapi/block-core.json
|
||||
+++ b/qapi/block-core.json
|
||||
@@ -871,6 +871,8 @@
|
||||
@@ -966,6 +966,8 @@
|
||||
# @pbs-dirty-bitmap: True if dirty-bitmap-incremental backups to PBS are
|
||||
# supported.
|
||||
#
|
||||
@ -371,7 +371,7 @@ index 8b0e0d92de..7fde927621 100644
|
||||
# @pbs-dirty-bitmap-savevm: True if 'dirty-bitmaps' migration capability can
|
||||
# safely be set for savevm-async.
|
||||
#
|
||||
@@ -879,6 +881,7 @@
|
||||
@@ -974,6 +976,7 @@
|
||||
##
|
||||
{ 'struct': 'ProxmoxSupportStatus',
|
||||
'data': { 'pbs-dirty-bitmap': 'bool',
|
||||
@ -379,7 +379,7 @@ index 8b0e0d92de..7fde927621 100644
|
||||
'pbs-dirty-bitmap-savevm': 'bool',
|
||||
'pbs-library-version': 'str' } }
|
||||
|
||||
@@ -892,6 +895,59 @@
|
||||
@@ -987,6 +990,59 @@
|
||||
##
|
||||
{ 'command': 'query-proxmox-support', 'returns': 'ProxmoxSupportStatus' }
|
||||
|
||||
|
@ -14,10 +14,10 @@ Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
|
||||
2 files changed, 7 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/meson.build b/meson.build
|
||||
index f7f5b3f253..283b0e356e 100644
|
||||
index 419bea5cf4..c39c6054ee 100644
|
||||
--- a/meson.build
|
||||
+++ b/meson.build
|
||||
@@ -1526,6 +1526,7 @@ keyutils = dependency('libkeyutils', required: false,
|
||||
@@ -1528,6 +1528,7 @@ keyutils = dependency('libkeyutils', required: false,
|
||||
has_gettid = cc.has_function('gettid')
|
||||
|
||||
libuuid = cc.find_library('uuid', required: true)
|
||||
@ -25,7 +25,7 @@ index f7f5b3f253..283b0e356e 100644
|
||||
libproxmox_backup_qemu = cc.find_library('proxmox_backup_qemu', required: true)
|
||||
|
||||
# libselinux
|
||||
@@ -3096,6 +3097,7 @@ if have_block
|
||||
@@ -3143,6 +3144,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 f7f5b3f253..283b0e356e 100644
|
||||
endif
|
||||
|
||||
diff --git a/os-posix.c b/os-posix.c
|
||||
index 4858650c3e..c5cb12226a 100644
|
||||
index 5adc69f560..80c7777f10 100644
|
||||
--- a/os-posix.c
|
||||
+++ b/os-posix.c
|
||||
@@ -28,6 +28,8 @@
|
||||
|
@ -20,10 +20,10 @@ Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
|
||||
1 file changed, 50 insertions(+), 113 deletions(-)
|
||||
|
||||
diff --git a/pve-backup.c b/pve-backup.c
|
||||
index c85b2ecd83..b5fb844434 100644
|
||||
index d4abe6e703..214c839c0b 100644
|
||||
--- a/pve-backup.c
|
||||
+++ b/pve-backup.c
|
||||
@@ -52,6 +52,7 @@ static struct PVEBackupState {
|
||||
@@ -54,6 +54,7 @@ static struct PVEBackupState {
|
||||
VmaWriter *vmaw;
|
||||
ProxmoxBackupHandle *pbs;
|
||||
GList *di_list;
|
||||
@ -31,7 +31,7 @@ index c85b2ecd83..b5fb844434 100644
|
||||
QemuMutex backup_mutex;
|
||||
CoMutex dump_callback_mutex;
|
||||
} backup_state;
|
||||
@@ -71,34 +72,12 @@ typedef struct PVEBackupDevInfo {
|
||||
@@ -73,34 +74,12 @@ typedef struct PVEBackupDevInfo {
|
||||
size_t size;
|
||||
uint64_t block_size;
|
||||
uint8_t dev_id;
|
||||
@ -67,7 +67,7 @@ index c85b2ecd83..b5fb844434 100644
|
||||
static void pvebackup_propagate_error(Error *err)
|
||||
{
|
||||
qemu_mutex_lock(&backup_state.stat.lock);
|
||||
@@ -274,18 +253,6 @@ static void coroutine_fn pvebackup_co_cleanup(void *unused)
|
||||
@@ -276,18 +255,6 @@ static void coroutine_fn pvebackup_co_cleanup(void *unused)
|
||||
if (local_err != NULL) {
|
||||
pvebackup_propagate_error(local_err);
|
||||
}
|
||||
@ -86,7 +86,7 @@ index c85b2ecd83..b5fb844434 100644
|
||||
}
|
||||
|
||||
proxmox_backup_disconnect(backup_state.pbs);
|
||||
@@ -324,8 +291,6 @@ static void pvebackup_complete_cb(void *opaque, int ret)
|
||||
@@ -326,8 +293,6 @@ static void pvebackup_complete_cb(void *opaque, int ret)
|
||||
|
||||
qemu_mutex_lock(&backup_state.backup_mutex);
|
||||
|
||||
@ -95,7 +95,7 @@ index c85b2ecd83..b5fb844434 100644
|
||||
if (ret < 0) {
|
||||
Error *local_err = NULL;
|
||||
error_setg(&local_err, "job failed with err %d - %s", ret, strerror(-ret));
|
||||
@@ -338,20 +303,17 @@ static void pvebackup_complete_cb(void *opaque, int ret)
|
||||
@@ -340,20 +305,17 @@ static void pvebackup_complete_cb(void *opaque, int ret)
|
||||
|
||||
block_on_coroutine_fn(pvebackup_complete_stream, di);
|
||||
|
||||
@ -122,7 +122,7 @@ index c85b2ecd83..b5fb844434 100644
|
||||
}
|
||||
|
||||
static void pvebackup_cancel(void)
|
||||
@@ -373,32 +335,28 @@ static void pvebackup_cancel(void)
|
||||
@@ -375,32 +337,28 @@ static void pvebackup_cancel(void)
|
||||
proxmox_backup_abort(backup_state.pbs, "backup canceled");
|
||||
}
|
||||
|
||||
@ -173,7 +173,7 @@ index c85b2ecd83..b5fb844434 100644
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -458,49 +416,19 @@ static int coroutine_fn pvebackup_co_add_config(
|
||||
@@ -460,49 +418,19 @@ static int coroutine_fn pvebackup_co_add_config(
|
||||
goto out;
|
||||
}
|
||||
|
||||
@ -230,7 +230,7 @@ index c85b2ecd83..b5fb844434 100644
|
||||
BackupPerf perf = { .max_workers = 16 };
|
||||
|
||||
/* create and start all jobs (paused state) */
|
||||
@@ -523,7 +451,7 @@ static bool create_backup_jobs(void) {
|
||||
@@ -525,7 +453,7 @@ static bool create_backup_jobs(void) {
|
||||
BlockJob *job = backup_job_create(
|
||||
NULL, di->bs, di->target, backup_state.speed, sync_mode, di->bitmap,
|
||||
bitmap_mode, false, NULL, &perf, BLOCKDEV_ON_ERROR_REPORT, BLOCKDEV_ON_ERROR_REPORT,
|
||||
@ -239,7 +239,7 @@ index c85b2ecd83..b5fb844434 100644
|
||||
|
||||
aio_context_release(aio_context);
|
||||
|
||||
@@ -535,7 +463,8 @@ static bool create_backup_jobs(void) {
|
||||
@@ -537,7 +465,8 @@ static bool create_backup_jobs(void) {
|
||||
pvebackup_propagate_error(create_job_err);
|
||||
break;
|
||||
}
|
||||
@ -249,7 +249,7 @@ index c85b2ecd83..b5fb844434 100644
|
||||
|
||||
bdrv_unref(di->target);
|
||||
di->target = NULL;
|
||||
@@ -553,6 +482,12 @@ static bool create_backup_jobs(void) {
|
||||
@@ -555,6 +484,12 @@ static bool create_backup_jobs(void) {
|
||||
bdrv_unref(di->target);
|
||||
di->target = NULL;
|
||||
}
|
||||
@ -262,7 +262,7 @@ index c85b2ecd83..b5fb844434 100644
|
||||
}
|
||||
}
|
||||
|
||||
@@ -943,10 +878,6 @@ err:
|
||||
@@ -937,10 +872,6 @@ err:
|
||||
PVEBackupDevInfo *di = (PVEBackupDevInfo *)l->data;
|
||||
l = g_list_next(l);
|
||||
|
||||
@ -273,7 +273,7 @@ index c85b2ecd83..b5fb844434 100644
|
||||
if (di->target) {
|
||||
bdrv_unref(di->target);
|
||||
}
|
||||
@@ -1035,9 +966,15 @@ UuidInfo *qmp_backup(
|
||||
@@ -1021,9 +952,15 @@ UuidInfo *qmp_backup(
|
||||
block_on_coroutine_fn(pvebackup_co_prepare, &task);
|
||||
|
||||
if (*errp == NULL) {
|
||||
|
@ -57,10 +57,10 @@ Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
|
||||
2 files changed, 138 insertions(+), 79 deletions(-)
|
||||
|
||||
diff --git a/pve-backup.c b/pve-backup.c
|
||||
index b5fb844434..88268bb586 100644
|
||||
index 214c839c0b..1d233dac93 100644
|
||||
--- a/pve-backup.c
|
||||
+++ b/pve-backup.c
|
||||
@@ -33,7 +33,9 @@ const char *PBS_BITMAP_NAME = "pbs-incremental-dirty-bitmap";
|
||||
@@ -35,7 +35,9 @@ const char *PBS_BITMAP_NAME = "pbs-incremental-dirty-bitmap";
|
||||
|
||||
static struct PVEBackupState {
|
||||
struct {
|
||||
@ -71,7 +71,7 @@ index b5fb844434..88268bb586 100644
|
||||
QemuMutex lock;
|
||||
Error *error;
|
||||
time_t start_time;
|
||||
@@ -47,20 +49,22 @@ static struct PVEBackupState {
|
||||
@@ -49,20 +51,22 @@ static struct PVEBackupState {
|
||||
size_t reused;
|
||||
size_t zero_bytes;
|
||||
GList *bitmap_list;
|
||||
@ -96,7 +96,7 @@ index b5fb844434..88268bb586 100644
|
||||
qemu_co_mutex_init(&backup_state.dump_callback_mutex);
|
||||
}
|
||||
|
||||
@@ -72,6 +76,7 @@ typedef struct PVEBackupDevInfo {
|
||||
@@ -74,6 +78,7 @@ typedef struct PVEBackupDevInfo {
|
||||
size_t size;
|
||||
uint64_t block_size;
|
||||
uint8_t dev_id;
|
||||
@ -104,7 +104,7 @@ index b5fb844434..88268bb586 100644
|
||||
char targetfile[PATH_MAX];
|
||||
BdrvDirtyBitmap *bitmap;
|
||||
BlockDriverState *target;
|
||||
@@ -227,12 +232,12 @@ pvebackup_co_dump_vma_cb(
|
||||
@@ -229,12 +234,12 @@ pvebackup_co_dump_vma_cb(
|
||||
}
|
||||
|
||||
// assumes the caller holds backup_mutex
|
||||
@ -119,7 +119,7 @@ index b5fb844434..88268bb586 100644
|
||||
qemu_mutex_unlock(&backup_state.stat.lock);
|
||||
|
||||
if (backup_state.vmaw) {
|
||||
@@ -261,35 +266,29 @@ static void coroutine_fn pvebackup_co_cleanup(void *unused)
|
||||
@@ -263,35 +268,29 @@ static void coroutine_fn pvebackup_co_cleanup(void *unused)
|
||||
|
||||
g_list_free(backup_state.di_list);
|
||||
backup_state.di_list = NULL;
|
||||
@ -171,7 +171,7 @@ index b5fb844434..88268bb586 100644
|
||||
|
||||
if (ret < 0) {
|
||||
Error *local_err = NULL;
|
||||
@@ -301,7 +300,19 @@ static void pvebackup_complete_cb(void *opaque, int ret)
|
||||
@@ -303,7 +302,19 @@ static void pvebackup_complete_cb(void *opaque, int ret)
|
||||
|
||||
assert(di->target == NULL);
|
||||
|
||||
@ -192,7 +192,7 @@ index b5fb844434..88268bb586 100644
|
||||
|
||||
// remove self from job list
|
||||
backup_state.di_list = g_list_remove(backup_state.di_list, di);
|
||||
@@ -310,21 +321,46 @@ static void pvebackup_complete_cb(void *opaque, int ret)
|
||||
@@ -312,21 +323,46 @@ static void pvebackup_complete_cb(void *opaque, int ret)
|
||||
|
||||
/* call cleanup if we're the last job */
|
||||
if (!g_list_first(backup_state.di_list)) {
|
||||
@ -244,7 +244,7 @@ index b5fb844434..88268bb586 100644
|
||||
|
||||
if (backup_state.vmaw) {
|
||||
/* make sure vma writer does not block anymore */
|
||||
@@ -342,28 +378,22 @@ static void pvebackup_cancel(void)
|
||||
@@ -344,28 +380,22 @@ static void pvebackup_cancel(void)
|
||||
((PVEBackupDevInfo *)bdi->data)->job :
|
||||
NULL;
|
||||
|
||||
@ -282,7 +282,7 @@ index b5fb844434..88268bb586 100644
|
||||
}
|
||||
|
||||
// assumes the caller holds backup_mutex
|
||||
@@ -416,10 +446,18 @@ static int coroutine_fn pvebackup_co_add_config(
|
||||
@@ -418,10 +448,18 @@ static int coroutine_fn pvebackup_co_add_config(
|
||||
goto out;
|
||||
}
|
||||
|
||||
@ -302,7 +302,7 @@ index b5fb844434..88268bb586 100644
|
||||
Error *local_err = NULL;
|
||||
|
||||
/* create job transaction to synchronize bitmap commit and cancel all
|
||||
@@ -455,24 +493,19 @@ static bool create_backup_jobs(void) {
|
||||
@@ -457,24 +495,19 @@ static bool create_backup_jobs(void) {
|
||||
|
||||
aio_context_release(aio_context);
|
||||
|
||||
@ -332,7 +332,7 @@ index b5fb844434..88268bb586 100644
|
||||
l = backup_state.di_list;
|
||||
while (l) {
|
||||
PVEBackupDevInfo *di = (PVEBackupDevInfo *)l->data;
|
||||
@@ -485,13 +518,15 @@ static bool create_backup_jobs(void) {
|
||||
@@ -487,13 +520,15 @@ static bool create_backup_jobs(void) {
|
||||
|
||||
if (di->job) {
|
||||
WITH_JOB_LOCK_GUARD() {
|
||||
@ -349,7 +349,7 @@ index b5fb844434..88268bb586 100644
|
||||
}
|
||||
|
||||
typedef struct QmpBackupTask {
|
||||
@@ -528,11 +563,12 @@ typedef struct QmpBackupTask {
|
||||
@@ -522,11 +557,12 @@ typedef struct QmpBackupTask {
|
||||
UuidInfo *result;
|
||||
} QmpBackupTask;
|
||||
|
||||
@ -363,7 +363,7 @@ index b5fb844434..88268bb586 100644
|
||||
QmpBackupTask *task = opaque;
|
||||
|
||||
task->result = NULL; // just to be sure
|
||||
@@ -553,8 +589,9 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
|
||||
@@ -547,8 +583,9 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
|
||||
const char *firewall_name = "qemu-server.fw";
|
||||
|
||||
if (backup_state.di_list) {
|
||||
@ -374,7 +374,7 @@ index b5fb844434..88268bb586 100644
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -621,6 +658,8 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
|
||||
@@ -615,6 +652,8 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
|
||||
}
|
||||
di->size = size;
|
||||
total += size;
|
||||
@ -383,7 +383,7 @@ index b5fb844434..88268bb586 100644
|
||||
}
|
||||
|
||||
uuid_generate(uuid);
|
||||
@@ -852,6 +891,8 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
|
||||
@@ -846,6 +885,8 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
|
||||
backup_state.stat.dirty = total - backup_state.stat.reused;
|
||||
backup_state.stat.transferred = 0;
|
||||
backup_state.stat.zero_bytes = 0;
|
||||
@ -392,7 +392,7 @@ index b5fb844434..88268bb586 100644
|
||||
|
||||
qemu_mutex_unlock(&backup_state.stat.lock);
|
||||
|
||||
@@ -866,6 +907,33 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
|
||||
@@ -860,6 +901,33 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
|
||||
uuid_info->UUID = uuid_str;
|
||||
|
||||
task->result = uuid_info;
|
||||
@ -426,7 +426,7 @@ index b5fb844434..88268bb586 100644
|
||||
return;
|
||||
|
||||
err_mutex:
|
||||
@@ -888,6 +956,7 @@ err:
|
||||
@@ -882,6 +950,7 @@ err:
|
||||
g_free(di);
|
||||
}
|
||||
g_list_free(di_list);
|
||||
@ -434,7 +434,7 @@ index b5fb844434..88268bb586 100644
|
||||
|
||||
if (devs) {
|
||||
g_strfreev(devs);
|
||||
@@ -908,6 +977,8 @@ err:
|
||||
@@ -902,6 +971,8 @@ err:
|
||||
}
|
||||
|
||||
task->result = NULL;
|
||||
@ -443,7 +443,7 @@ index b5fb844434..88268bb586 100644
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -961,24 +1032,8 @@ UuidInfo *qmp_backup(
|
||||
@@ -947,24 +1018,8 @@ UuidInfo *qmp_backup(
|
||||
.errp = errp,
|
||||
};
|
||||
|
||||
@ -468,7 +468,7 @@ index b5fb844434..88268bb586 100644
|
||||
return task.result;
|
||||
}
|
||||
|
||||
@@ -1030,6 +1085,7 @@ BackupStatus *qmp_query_backup(Error **errp)
|
||||
@@ -1012,6 +1067,7 @@ BackupStatus *qmp_query_backup(Error **errp)
|
||||
info->transferred = backup_state.stat.transferred;
|
||||
info->has_reused = true;
|
||||
info->reused = backup_state.stat.reused;
|
||||
@ -477,10 +477,10 @@ index b5fb844434..88268bb586 100644
|
||||
qemu_mutex_unlock(&backup_state.stat.lock);
|
||||
|
||||
diff --git a/qapi/block-core.json b/qapi/block-core.json
|
||||
index 7fde927621..bf559c6d52 100644
|
||||
index 130d5f065f..43838212e3 100644
|
||||
--- a/qapi/block-core.json
|
||||
+++ b/qapi/block-core.json
|
||||
@@ -770,12 +770,15 @@
|
||||
@@ -865,12 +865,15 @@
|
||||
#
|
||||
# @uuid: uuid for this backup job
|
||||
#
|
||||
|
@ -13,21 +13,23 @@ safe migration is possible and makes sense.
|
||||
|
||||
Signed-off-by: Stefan Reiter <s.reiter@proxmox.com>
|
||||
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
|
||||
[FE: split up state_pending for 8.0]
|
||||
Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
|
||||
---
|
||||
include/migration/misc.h | 3 ++
|
||||
migration/meson.build | 2 +
|
||||
migration/migration.c | 1 +
|
||||
migration/pbs-state.c | 106 +++++++++++++++++++++++++++++++++++++++
|
||||
migration/pbs-state.c | 104 +++++++++++++++++++++++++++++++++++++++
|
||||
pve-backup.c | 1 +
|
||||
qapi/block-core.json | 6 +++
|
||||
6 files changed, 119 insertions(+)
|
||||
6 files changed, 117 insertions(+)
|
||||
create mode 100644 migration/pbs-state.c
|
||||
|
||||
diff --git a/include/migration/misc.h b/include/migration/misc.h
|
||||
index 465906710d..4f0aeceb6f 100644
|
||||
index 8b49841016..78f63ca400 100644
|
||||
--- a/include/migration/misc.h
|
||||
+++ b/include/migration/misc.h
|
||||
@@ -75,4 +75,7 @@ bool migration_in_bg_snapshot(void);
|
||||
@@ -77,4 +77,7 @@ bool migration_in_bg_snapshot(void);
|
||||
/* migration/block-dirty-bitmap.c */
|
||||
void dirty_bitmap_mig_init(void);
|
||||
|
||||
@ -36,7 +38,7 @@ index 465906710d..4f0aeceb6f 100644
|
||||
+
|
||||
#endif
|
||||
diff --git a/migration/meson.build b/migration/meson.build
|
||||
index 0842d00cd2..d012f4d8d3 100644
|
||||
index a7824b5266..de6a271b58 100644
|
||||
--- a/migration/meson.build
|
||||
+++ b/migration/meson.build
|
||||
@@ -6,8 +6,10 @@ migration_files = files(
|
||||
@ -51,10 +53,10 @@ index 0842d00cd2..d012f4d8d3 100644
|
||||
softmmu_ss.add(files(
|
||||
'block-dirty-bitmap.c',
|
||||
diff --git a/migration/migration.c b/migration/migration.c
|
||||
index f485eea5fb..89b287180f 100644
|
||||
index bda4789193..c8318aa258 100644
|
||||
--- a/migration/migration.c
|
||||
+++ b/migration/migration.c
|
||||
@@ -229,6 +229,7 @@ void migration_object_init(void)
|
||||
@@ -245,6 +245,7 @@ void migration_object_init(void)
|
||||
blk_mig_init();
|
||||
ram_mig_init();
|
||||
dirty_bitmap_mig_init();
|
||||
@ -64,10 +66,10 @@ index f485eea5fb..89b287180f 100644
|
||||
void migration_cancel(const Error *error)
|
||||
diff --git a/migration/pbs-state.c b/migration/pbs-state.c
|
||||
new file mode 100644
|
||||
index 0000000000..29f2b3860d
|
||||
index 0000000000..887e998b9e
|
||||
--- /dev/null
|
||||
+++ b/migration/pbs-state.c
|
||||
@@ -0,0 +1,106 @@
|
||||
@@ -0,0 +1,104 @@
|
||||
+/*
|
||||
+ * PBS (dirty-bitmap) state migration
|
||||
+ */
|
||||
@ -86,11 +88,8 @@ index 0000000000..29f2b3860d
|
||||
+/* state is accessed via this static variable directly, 'opaque' is NULL */
|
||||
+static PBSState pbs_state;
|
||||
+
|
||||
+static void pbs_state_save_pending(QEMUFile *f, void *opaque,
|
||||
+ uint64_t max_size,
|
||||
+ uint64_t *res_precopy_only,
|
||||
+ uint64_t *res_compatible,
|
||||
+ uint64_t *res_postcopy_only)
|
||||
+static void pbs_state_pending(void *opaque, uint64_t *must_precopy,
|
||||
+ uint64_t *can_postcopy)
|
||||
+{
|
||||
+ /* we send everything in save_setup, so nothing is ever pending */
|
||||
+}
|
||||
@ -160,7 +159,8 @@ index 0000000000..29f2b3860d
|
||||
+static SaveVMHandlers savevm_pbs_state_handlers = {
|
||||
+ .save_setup = pbs_state_save_setup,
|
||||
+ .has_postcopy = pbs_state_has_postcopy,
|
||||
+ .save_live_pending = pbs_state_save_pending,
|
||||
+ .state_pending_exact = pbs_state_pending,
|
||||
+ .state_pending_estimate = pbs_state_pending,
|
||||
+ .is_active_iterate = pbs_state_is_active_iterate,
|
||||
+ .load_state = pbs_state_load,
|
||||
+ .is_active = pbs_state_is_active,
|
||||
@ -175,10 +175,10 @@ index 0000000000..29f2b3860d
|
||||
+ NULL);
|
||||
+}
|
||||
diff --git a/pve-backup.c b/pve-backup.c
|
||||
index 88268bb586..fa9c6c4493 100644
|
||||
index 1d233dac93..5c9c153e31 100644
|
||||
--- a/pve-backup.c
|
||||
+++ b/pve-backup.c
|
||||
@@ -1128,6 +1128,7 @@ ProxmoxSupportStatus *qmp_query_proxmox_support(Error **errp)
|
||||
@@ -1110,6 +1110,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;
|
||||
@ -187,10 +187,10 @@ index 88268bb586..fa9c6c4493 100644
|
||||
return ret;
|
||||
}
|
||||
diff --git a/qapi/block-core.json b/qapi/block-core.json
|
||||
index bf559c6d52..24f30260c8 100644
|
||||
index 43838212e3..e7412f6322 100644
|
||||
--- a/qapi/block-core.json
|
||||
+++ b/qapi/block-core.json
|
||||
@@ -879,6 +879,11 @@
|
||||
@@ -974,6 +974,11 @@
|
||||
# @pbs-dirty-bitmap-savevm: True if 'dirty-bitmaps' migration capability can
|
||||
# safely be set for savevm-async.
|
||||
#
|
||||
@ -202,7 +202,7 @@ index bf559c6d52..24f30260c8 100644
|
||||
# @pbs-library-version: Running version of libproxmox-backup-qemu0 library.
|
||||
#
|
||||
##
|
||||
@@ -886,6 +891,7 @@
|
||||
@@ -981,6 +986,7 @@
|
||||
'data': { 'pbs-dirty-bitmap': 'bool',
|
||||
'query-bitmap-info': 'bool',
|
||||
'pbs-dirty-bitmap-savevm': 'bool',
|
||||
|
@ -19,10 +19,10 @@ Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/migration/block-dirty-bitmap.c b/migration/block-dirty-bitmap.c
|
||||
index 9aba7d9c22..f4ecf9c9f9 100644
|
||||
index fe73aa94b1..a6440929fa 100644
|
||||
--- a/migration/block-dirty-bitmap.c
|
||||
+++ b/migration/block-dirty-bitmap.c
|
||||
@@ -538,7 +538,7 @@ static int add_bitmaps_to_list(DBMSaveState *s, BlockDriverState *bs,
|
||||
@@ -539,7 +539,7 @@ static int add_bitmaps_to_list(DBMSaveState *s, BlockDriverState *bs,
|
||||
|
||||
if (bdrv_dirty_bitmap_check(bitmap, BDRV_BITMAP_DEFAULT, &local_err)) {
|
||||
error_report_err(local_err);
|
||||
|
@ -21,10 +21,10 @@ Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
|
||||
1 file changed, 30 insertions(+)
|
||||
|
||||
diff --git a/block/iscsi.c b/block/iscsi.c
|
||||
index a316d46d96..3ed4a50c0d 100644
|
||||
index 9fc0bed90b..1d40933165 100644
|
||||
--- a/block/iscsi.c
|
||||
+++ b/block/iscsi.c
|
||||
@@ -1387,12 +1387,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;
|
||||
|
@ -23,20 +23,23 @@ way instead)
|
||||
|
||||
Signed-off-by: Stefan Reiter <s.reiter@proxmox.com>
|
||||
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
|
||||
[FE: adapt to QAPI changes
|
||||
call coroutine version of is_inserted()]
|
||||
Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
|
||||
---
|
||||
block/monitor/block-hmp-cmds.c | 4 +-
|
||||
hmp-commands.hx | 2 +
|
||||
proxmox-backup-client.c | 31 -----
|
||||
pve-backup.c | 232 ++++++++++-----------------------
|
||||
pve-backup.c | 220 +++++++++++----------------------
|
||||
qapi/block-core.json | 4 +-
|
||||
5 files changed, 77 insertions(+), 196 deletions(-)
|
||||
5 files changed, 79 insertions(+), 182 deletions(-)
|
||||
|
||||
diff --git a/block/monitor/block-hmp-cmds.c b/block/monitor/block-hmp-cmds.c
|
||||
index a09f722fea..71ed202491 100644
|
||||
index 6a6ed6d0e7..bcf5849196 100644
|
||||
--- a/block/monitor/block-hmp-cmds.c
|
||||
+++ b/block/monitor/block-hmp-cmds.c
|
||||
@@ -1016,7 +1016,7 @@ void hmp_info_snapshots(Monitor *mon, const QDict *qdict)
|
||||
g_free(global_snapshots);
|
||||
@@ -1028,7 +1028,7 @@ void hmp_change_medium(Monitor *mon, const char *device, const char *target,
|
||||
!!read_only, read_only_mode, errp);
|
||||
}
|
||||
|
||||
-void hmp_backup_cancel(Monitor *mon, const QDict *qdict)
|
||||
@ -44,7 +47,7 @@ index a09f722fea..71ed202491 100644
|
||||
{
|
||||
Error *error = NULL;
|
||||
|
||||
@@ -1025,7 +1025,7 @@ void hmp_backup_cancel(Monitor *mon, const QDict *qdict)
|
||||
@@ -1037,7 +1037,7 @@ void hmp_backup_cancel(Monitor *mon, const QDict *qdict)
|
||||
hmp_handle_error(mon, error);
|
||||
}
|
||||
|
||||
@ -54,7 +57,7 @@ index a09f722fea..71ed202491 100644
|
||||
Error *error = NULL;
|
||||
|
||||
diff --git a/hmp-commands.hx b/hmp-commands.hx
|
||||
index fcf9461295..5fdb198ca4 100644
|
||||
index 9b6b8e2e9c..896430dae8 100644
|
||||
--- a/hmp-commands.hx
|
||||
+++ b/hmp-commands.hx
|
||||
@@ -111,6 +111,7 @@ ERST
|
||||
@ -116,10 +119,10 @@ index 4ce7bc0b5e..0923037dec 100644
|
||||
static void proxmox_backup_schedule_wake(void *data) {
|
||||
CoCtxData *waker = (CoCtxData *)data;
|
||||
diff --git a/pve-backup.c b/pve-backup.c
|
||||
index 5662f48b72..e4fe1b601d 100644
|
||||
index 5c9c153e31..378e4a9a63 100644
|
||||
--- a/pve-backup.c
|
||||
+++ b/pve-backup.c
|
||||
@@ -354,7 +354,7 @@ static void job_cancel_bh(void *opaque) {
|
||||
@@ -356,7 +356,7 @@ static void job_cancel_bh(void *opaque) {
|
||||
aio_co_enter(data->ctx, data->co);
|
||||
}
|
||||
|
||||
@ -128,7 +131,7 @@ index 5662f48b72..e4fe1b601d 100644
|
||||
{
|
||||
Error *cancel_err = NULL;
|
||||
error_setg(&cancel_err, "backup canceled");
|
||||
@@ -391,11 +391,6 @@ static void coroutine_fn pvebackup_co_cancel(void *opaque)
|
||||
@@ -393,11 +393,6 @@ static void coroutine_fn pvebackup_co_cancel(void *opaque)
|
||||
qemu_co_mutex_unlock(&backup_state.backup_mutex);
|
||||
}
|
||||
|
||||
@ -140,33 +143,25 @@ index 5662f48b72..e4fe1b601d 100644
|
||||
// assumes the caller holds backup_mutex
|
||||
static int coroutine_fn pvebackup_co_add_config(
|
||||
const char *file,
|
||||
@@ -529,50 +524,27 @@ static void create_backup_jobs_bh(void *opaque) {
|
||||
@@ -531,42 +526,27 @@ static void create_backup_jobs_bh(void *opaque) {
|
||||
aio_co_enter(data->ctx, data->co);
|
||||
}
|
||||
|
||||
-typedef struct QmpBackupTask {
|
||||
- const char *backup_file;
|
||||
- bool has_password;
|
||||
- const char *password;
|
||||
- bool has_keyfile;
|
||||
- const char *keyfile;
|
||||
- bool has_key_password;
|
||||
- const char *key_password;
|
||||
- bool has_backup_id;
|
||||
- const char *backup_id;
|
||||
- bool has_backup_time;
|
||||
- const char *fingerprint;
|
||||
- bool has_fingerprint;
|
||||
- int64_t backup_time;
|
||||
- bool has_use_dirty_bitmap;
|
||||
- bool use_dirty_bitmap;
|
||||
- bool has_format;
|
||||
- BackupFormat format;
|
||||
- bool has_config_file;
|
||||
- const char *config_file;
|
||||
- bool has_firewall_file;
|
||||
- const char *firewall_file;
|
||||
- bool has_devlist;
|
||||
- const char *devlist;
|
||||
- bool has_compress;
|
||||
- bool compress;
|
||||
@ -181,19 +176,19 @@ index 5662f48b72..e4fe1b601d 100644
|
||||
-static void coroutine_fn pvebackup_co_prepare(void *opaque)
|
||||
+UuidInfo coroutine_fn *qmp_backup(
|
||||
+ const char *backup_file,
|
||||
+ bool has_password, const char *password,
|
||||
+ bool has_keyfile, const char *keyfile,
|
||||
+ bool has_key_password, const char *key_password,
|
||||
+ bool has_fingerprint, const char *fingerprint,
|
||||
+ bool has_backup_id, const char *backup_id,
|
||||
+ const char *password,
|
||||
+ const char *keyfile,
|
||||
+ const char *key_password,
|
||||
+ const char *fingerprint,
|
||||
+ const char *backup_id,
|
||||
+ bool has_backup_time, int64_t backup_time,
|
||||
+ bool has_use_dirty_bitmap, bool use_dirty_bitmap,
|
||||
+ bool has_compress, bool compress,
|
||||
+ bool has_encrypt, bool encrypt,
|
||||
+ bool has_format, BackupFormat format,
|
||||
+ bool has_config_file, const char *config_file,
|
||||
+ bool has_firewall_file, const char *firewall_file,
|
||||
+ bool has_devlist, const char *devlist,
|
||||
+ const char *config_file,
|
||||
+ const char *firewall_file,
|
||||
+ const char *devlist,
|
||||
+ bool has_speed, int64_t speed, Error **errp)
|
||||
{
|
||||
assert(qemu_in_coroutine());
|
||||
@ -207,7 +202,7 @@ index 5662f48b72..e4fe1b601d 100644
|
||||
BlockBackend *blk;
|
||||
BlockDriverState *bs = NULL;
|
||||
const char *backup_dir = NULL;
|
||||
@@ -589,17 +561,17 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
|
||||
@@ -583,32 +563,32 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
|
||||
const char *firewall_name = "qemu-server.fw";
|
||||
|
||||
if (backup_state.di_list) {
|
||||
@ -223,18 +218,19 @@ index 5662f48b72..e4fe1b601d 100644
|
||||
- BackupFormat format = task->has_format ? task->format : BACKUP_FORMAT_VMA;
|
||||
+ format = has_format ? format : BACKUP_FORMAT_VMA;
|
||||
|
||||
- if (task->has_devlist) {
|
||||
- if (task->devlist) {
|
||||
- devs = g_strsplit_set(task->devlist, ",;:", -1);
|
||||
+ if (has_devlist) {
|
||||
+ if (devlist) {
|
||||
+ devs = g_strsplit_set(devlist, ",;:", -1);
|
||||
|
||||
gchar **d = devs;
|
||||
while (d && *d) {
|
||||
@@ -607,14 +579,14 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
|
||||
blk = blk_by_name(*d);
|
||||
if (blk) {
|
||||
bs = blk_bs(blk);
|
||||
if (!bdrv_is_inserted(bs)) {
|
||||
- if (!bdrv_is_inserted(bs)) {
|
||||
- error_setg(task->errp, QERR_DEVICE_HAS_NO_MEDIUM, *d);
|
||||
+ if (!bdrv_co_is_inserted(bs)) {
|
||||
+ error_setg(errp, QERR_DEVICE_HAS_NO_MEDIUM, *d);
|
||||
goto err;
|
||||
}
|
||||
@ -247,7 +243,16 @@ index 5662f48b72..e4fe1b601d 100644
|
||||
"Device '%s' not found", *d);
|
||||
goto err;
|
||||
}
|
||||
@@ -637,7 +609,7 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
|
||||
@@ -620,7 +600,7 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
|
||||
|
||||
bs = NULL;
|
||||
for (bs = bdrv_first(&it); bs; bs = bdrv_next(&it)) {
|
||||
- if (!bdrv_is_inserted(bs) || bdrv_is_read_only(bs)) {
|
||||
+ if (!bdrv_co_is_inserted(bs) || bdrv_is_read_only(bs)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -631,7 +611,7 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
|
||||
}
|
||||
|
||||
if (!di_list) {
|
||||
@ -256,7 +261,7 @@ index 5662f48b72..e4fe1b601d 100644
|
||||
goto err;
|
||||
}
|
||||
|
||||
@@ -647,13 +619,13 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
|
||||
@@ -641,13 +621,13 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
|
||||
while (l) {
|
||||
PVEBackupDevInfo *di = (PVEBackupDevInfo *)l->data;
|
||||
l = g_list_next(l);
|
||||
@ -272,19 +277,19 @@ index 5662f48b72..e4fe1b601d 100644
|
||||
goto err;
|
||||
}
|
||||
di->size = size;
|
||||
@@ -680,47 +652,44 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
|
||||
@@ -674,47 +654,44 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
|
||||
}
|
||||
|
||||
if (format == BACKUP_FORMAT_PBS) {
|
||||
- if (!task->has_password) {
|
||||
- if (!task->password) {
|
||||
- error_set(task->errp, ERROR_CLASS_GENERIC_ERROR, "missing parameter 'password'");
|
||||
+ if (!has_password) {
|
||||
+ if (!password) {
|
||||
+ error_set(errp, ERROR_CLASS_GENERIC_ERROR, "missing parameter 'password'");
|
||||
goto err_mutex;
|
||||
}
|
||||
- if (!task->has_backup_id) {
|
||||
- if (!task->backup_id) {
|
||||
- error_set(task->errp, ERROR_CLASS_GENERIC_ERROR, "missing parameter 'backup-id'");
|
||||
+ if (!has_backup_id) {
|
||||
+ if (!backup_id) {
|
||||
+ error_set(errp, ERROR_CLASS_GENERIC_ERROR, "missing parameter 'backup-id'");
|
||||
goto err_mutex;
|
||||
}
|
||||
@ -310,19 +315,19 @@ index 5662f48b72..e4fe1b601d 100644
|
||||
+ backup_id,
|
||||
+ backup_time,
|
||||
dump_cb_block_size,
|
||||
- task->has_password ? task->password : NULL,
|
||||
- task->has_keyfile ? task->keyfile : NULL,
|
||||
- task->has_key_password ? task->key_password : NULL,
|
||||
- task->password,
|
||||
- task->keyfile,
|
||||
- task->key_password,
|
||||
- task->has_compress ? task->compress : true,
|
||||
- task->has_encrypt ? task->encrypt : task->has_keyfile,
|
||||
- task->has_fingerprint ? task->fingerprint : NULL,
|
||||
+ has_password ? password : NULL,
|
||||
+ has_keyfile ? keyfile : NULL,
|
||||
+ has_key_password ? key_password : NULL,
|
||||
- task->has_encrypt ? task->encrypt : !!task->keyfile,
|
||||
- task->fingerprint,
|
||||
+ password,
|
||||
+ keyfile,
|
||||
+ key_password,
|
||||
+ has_compress ? compress : true,
|
||||
+ has_encrypt ? encrypt : has_keyfile,
|
||||
+ has_fingerprint ? fingerprint : NULL,
|
||||
&pbs_err);
|
||||
+ has_encrypt ? encrypt : !!keyfile,
|
||||
+ fingerprint,
|
||||
&pbs_err);
|
||||
|
||||
if (!pbs) {
|
||||
- error_set(task->errp, ERROR_CLASS_GENERIC_ERROR,
|
||||
@ -337,7 +342,7 @@ index 5662f48b72..e4fe1b601d 100644
|
||||
if (connect_result < 0)
|
||||
goto err_mutex;
|
||||
|
||||
@@ -739,9 +708,9 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
|
||||
@@ -733,9 +710,9 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
|
||||
BdrvDirtyBitmap *bitmap = bdrv_find_dirty_bitmap(di->bs, PBS_BITMAP_NAME);
|
||||
bool expect_only_dirty = false;
|
||||
|
||||
@ -349,7 +354,7 @@ index 5662f48b72..e4fe1b601d 100644
|
||||
if (!bitmap) {
|
||||
goto err_mutex;
|
||||
}
|
||||
@@ -771,12 +740,12 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
|
||||
@@ -765,12 +742,12 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
|
||||
}
|
||||
}
|
||||
|
||||
@ -364,7 +369,7 @@ index 5662f48b72..e4fe1b601d 100644
|
||||
goto err_mutex;
|
||||
}
|
||||
|
||||
@@ -790,10 +759,10 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
|
||||
@@ -784,10 +761,10 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
|
||||
backup_state.stat.bitmap_list = g_list_append(backup_state.stat.bitmap_list, info);
|
||||
}
|
||||
} else if (format == BACKUP_FORMAT_VMA) {
|
||||
@ -377,7 +382,7 @@ index 5662f48b72..e4fe1b601d 100644
|
||||
}
|
||||
goto err_mutex;
|
||||
}
|
||||
@@ -804,25 +773,25 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
|
||||
@@ -798,25 +775,25 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
|
||||
PVEBackupDevInfo *di = (PVEBackupDevInfo *)l->data;
|
||||
l = g_list_next(l);
|
||||
|
||||
@ -409,7 +414,7 @@ index 5662f48b72..e4fe1b601d 100644
|
||||
|
||||
l = di_list;
|
||||
while (l) {
|
||||
@@ -836,34 +805,34 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
|
||||
@@ -830,34 +807,34 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
|
||||
bdrv_img_create(di->targetfile, "raw", NULL, NULL, NULL,
|
||||
di->size, flags, false, &local_err);
|
||||
if (local_err) {
|
||||
@ -433,10 +438,10 @@ index 5662f48b72..e4fe1b601d 100644
|
||||
|
||||
|
||||
/* add configuration file to archive */
|
||||
- if (task->has_config_file) {
|
||||
- if (task->config_file) {
|
||||
- if (pvebackup_co_add_config(task->config_file, config_name, format, backup_dir,
|
||||
- vmaw, pbs, task->errp) != 0) {
|
||||
+ if (has_config_file) {
|
||||
+ if (config_file) {
|
||||
+ if (pvebackup_co_add_config(config_file, config_name, format, backup_dir,
|
||||
+ vmaw, pbs, errp) != 0) {
|
||||
goto err_mutex;
|
||||
@ -444,16 +449,16 @@ index 5662f48b72..e4fe1b601d 100644
|
||||
}
|
||||
|
||||
/* add firewall file to archive */
|
||||
- if (task->has_firewall_file) {
|
||||
- if (task->firewall_file) {
|
||||
- if (pvebackup_co_add_config(task->firewall_file, firewall_name, format, backup_dir,
|
||||
- vmaw, pbs, task->errp) != 0) {
|
||||
+ if (has_firewall_file) {
|
||||
+ if (firewall_file) {
|
||||
+ if (pvebackup_co_add_config(firewall_file, firewall_name, format, backup_dir,
|
||||
+ vmaw, pbs, errp) != 0) {
|
||||
goto err_mutex;
|
||||
}
|
||||
}
|
||||
@@ -881,7 +850,7 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
|
||||
@@ -875,7 +852,7 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
|
||||
if (backup_state.stat.backup_file) {
|
||||
g_free(backup_state.stat.backup_file);
|
||||
}
|
||||
@ -462,7 +467,7 @@ index 5662f48b72..e4fe1b601d 100644
|
||||
|
||||
uuid_copy(backup_state.stat.uuid, uuid);
|
||||
uuid_unparse_lower(uuid, backup_state.stat.uuid_str);
|
||||
@@ -896,7 +865,7 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
|
||||
@@ -890,7 +867,7 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
|
||||
|
||||
qemu_mutex_unlock(&backup_state.stat.lock);
|
||||
|
||||
@ -471,7 +476,7 @@ index 5662f48b72..e4fe1b601d 100644
|
||||
|
||||
backup_state.vmaw = vmaw;
|
||||
backup_state.pbs = pbs;
|
||||
@@ -906,8 +875,6 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
|
||||
@@ -900,8 +877,6 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
|
||||
uuid_info = g_malloc0(sizeof(*uuid_info));
|
||||
uuid_info->UUID = uuid_str;
|
||||
|
||||
@ -480,7 +485,7 @@ index 5662f48b72..e4fe1b601d 100644
|
||||
/* Run create_backup_jobs_bh outside of coroutine (in BH) but keep
|
||||
* backup_mutex locked. This is fine, a CoMutex can be held across yield
|
||||
* points, and we'll release it as soon as the BH reschedules us.
|
||||
@@ -921,7 +888,7 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
|
||||
@@ -915,7 +890,7 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
|
||||
qemu_coroutine_yield();
|
||||
|
||||
if (local_err) {
|
||||
@ -489,7 +494,7 @@ index 5662f48b72..e4fe1b601d 100644
|
||||
goto err;
|
||||
}
|
||||
|
||||
@@ -934,7 +901,7 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
|
||||
@@ -928,7 +903,7 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
|
||||
/* start the first job in the transaction */
|
||||
job_txn_start_seq(backup_state.txn);
|
||||
|
||||
@ -498,7 +503,7 @@ index 5662f48b72..e4fe1b601d 100644
|
||||
|
||||
err_mutex:
|
||||
qemu_mutex_unlock(&backup_state.stat.lock);
|
||||
@@ -965,7 +932,7 @@ err:
|
||||
@@ -959,7 +934,7 @@ err:
|
||||
if (vmaw) {
|
||||
Error *err = NULL;
|
||||
vma_writer_close(vmaw, &err);
|
||||
@ -507,7 +512,7 @@ index 5662f48b72..e4fe1b601d 100644
|
||||
}
|
||||
|
||||
if (pbs) {
|
||||
@@ -976,65 +943,8 @@ err:
|
||||
@@ -970,57 +945,8 @@ err:
|
||||
rmdir(backup_dir);
|
||||
}
|
||||
|
||||
@ -519,32 +524,27 @@ index 5662f48b72..e4fe1b601d 100644
|
||||
-
|
||||
-UuidInfo *qmp_backup(
|
||||
- const char *backup_file,
|
||||
- bool has_password, const char *password,
|
||||
- bool has_keyfile, const char *keyfile,
|
||||
- bool has_key_password, const char *key_password,
|
||||
- bool has_fingerprint, const char *fingerprint,
|
||||
- bool has_backup_id, const char *backup_id,
|
||||
- const char *password,
|
||||
- const char *keyfile,
|
||||
- const char *key_password,
|
||||
- const char *fingerprint,
|
||||
- const char *backup_id,
|
||||
- bool has_backup_time, int64_t backup_time,
|
||||
- bool has_use_dirty_bitmap, bool use_dirty_bitmap,
|
||||
- bool has_compress, bool compress,
|
||||
- bool has_encrypt, bool encrypt,
|
||||
- bool has_format, BackupFormat format,
|
||||
- bool has_config_file, const char *config_file,
|
||||
- bool has_firewall_file, const char *firewall_file,
|
||||
- bool has_devlist, const char *devlist,
|
||||
- const char *config_file,
|
||||
- const char *firewall_file,
|
||||
- const char *devlist,
|
||||
- bool has_speed, int64_t speed, Error **errp)
|
||||
-{
|
||||
- QmpBackupTask task = {
|
||||
- .backup_file = backup_file,
|
||||
- .has_password = has_password,
|
||||
- .password = password,
|
||||
- .has_keyfile = has_keyfile,
|
||||
- .keyfile = keyfile,
|
||||
- .has_key_password = has_key_password,
|
||||
- .key_password = key_password,
|
||||
- .has_fingerprint = has_fingerprint,
|
||||
- .fingerprint = fingerprint,
|
||||
- .has_backup_id = has_backup_id,
|
||||
- .backup_id = backup_id,
|
||||
- .has_backup_time = has_backup_time,
|
||||
- .backup_time = backup_time,
|
||||
@ -556,11 +556,8 @@ index 5662f48b72..e4fe1b601d 100644
|
||||
- .encrypt = encrypt,
|
||||
- .has_format = has_format,
|
||||
- .format = format,
|
||||
- .has_config_file = has_config_file,
|
||||
- .config_file = config_file,
|
||||
- .has_firewall_file = has_firewall_file,
|
||||
- .firewall_file = firewall_file,
|
||||
- .has_devlist = has_devlist,
|
||||
- .devlist = devlist,
|
||||
- .has_speed = has_speed,
|
||||
- .speed = speed,
|
||||
@ -575,10 +572,10 @@ index 5662f48b72..e4fe1b601d 100644
|
||||
|
||||
BackupStatus *qmp_query_backup(Error **errp)
|
||||
diff --git a/qapi/block-core.json b/qapi/block-core.json
|
||||
index 24f30260c8..4e8c35a3a2 100644
|
||||
index e7412f6322..93d924ef79 100644
|
||||
--- a/qapi/block-core.json
|
||||
+++ b/qapi/block-core.json
|
||||
@@ -842,7 +842,7 @@
|
||||
@@ -937,7 +937,7 @@
|
||||
'*config-file': 'str',
|
||||
'*firewall-file': 'str',
|
||||
'*devlist': 'str', '*speed': 'int' },
|
||||
@ -587,7 +584,7 @@ index 24f30260c8..4e8c35a3a2 100644
|
||||
|
||||
##
|
||||
# @query-backup:
|
||||
@@ -864,7 +864,7 @@
|
||||
@@ -959,7 +959,7 @@
|
||||
# Notes: This command succeeds even if there is no backup process running.
|
||||
#
|
||||
##
|
||||
|
@ -12,6 +12,8 @@ from the PVE side to avoid QMP calls with unsupported parameters.
|
||||
Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
|
||||
Signed-off-by: Stefan Reiter <s.reiter@proxmox.com>
|
||||
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
|
||||
[FE: adapt to QAPI change dropping redundant has_*]
|
||||
Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
|
||||
---
|
||||
block/monitor/block-hmp-cmds.c | 1 +
|
||||
pve-backup.c | 3 +++
|
||||
@ -19,38 +21,38 @@ Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
|
||||
3 files changed, 11 insertions(+)
|
||||
|
||||
diff --git a/block/monitor/block-hmp-cmds.c b/block/monitor/block-hmp-cmds.c
|
||||
index 71ed202491..c7468e5d3b 100644
|
||||
index bcf5849196..fb881056e9 100644
|
||||
--- a/block/monitor/block-hmp-cmds.c
|
||||
+++ b/block/monitor/block-hmp-cmds.c
|
||||
@@ -1039,6 +1039,7 @@ void coroutine_fn hmp_backup(Monitor *mon, const QDict *qdict)
|
||||
false, NULL, // PBS password
|
||||
false, NULL, // PBS keyfile
|
||||
false, NULL, // PBS key_password
|
||||
+ false, NULL, // PBS master_keyfile
|
||||
false, NULL, // PBS fingerprint
|
||||
false, NULL, // PBS backup-id
|
||||
@@ -1051,6 +1051,7 @@ void coroutine_fn hmp_backup(Monitor *mon, const QDict *qdict)
|
||||
NULL, // PBS password
|
||||
NULL, // PBS keyfile
|
||||
NULL, // PBS key_password
|
||||
+ NULL, // PBS master_keyfile
|
||||
NULL, // PBS fingerprint
|
||||
NULL, // PBS backup-id
|
||||
false, 0, // PBS backup-time
|
||||
diff --git a/pve-backup.c b/pve-backup.c
|
||||
index 109498eaf9..4b5134ed27 100644
|
||||
index 378e4a9a63..504c11657a 100644
|
||||
--- a/pve-backup.c
|
||||
+++ b/pve-backup.c
|
||||
@@ -529,6 +529,7 @@ UuidInfo coroutine_fn *qmp_backup(
|
||||
bool has_password, const char *password,
|
||||
bool has_keyfile, const char *keyfile,
|
||||
bool has_key_password, const char *key_password,
|
||||
+ bool has_master_keyfile, const char *master_keyfile,
|
||||
bool has_fingerprint, const char *fingerprint,
|
||||
bool has_backup_id, const char *backup_id,
|
||||
@@ -531,6 +531,7 @@ UuidInfo coroutine_fn *qmp_backup(
|
||||
const char *password,
|
||||
const char *keyfile,
|
||||
const char *key_password,
|
||||
+ const char *master_keyfile,
|
||||
const char *fingerprint,
|
||||
const char *backup_id,
|
||||
bool has_backup_time, int64_t backup_time,
|
||||
@@ -677,6 +678,7 @@ UuidInfo coroutine_fn *qmp_backup(
|
||||
has_password ? password : NULL,
|
||||
has_keyfile ? keyfile : NULL,
|
||||
has_key_password ? key_password : NULL,
|
||||
+ has_master_keyfile ? master_keyfile : NULL,
|
||||
@@ -679,6 +680,7 @@ UuidInfo coroutine_fn *qmp_backup(
|
||||
password,
|
||||
keyfile,
|
||||
key_password,
|
||||
+ master_keyfile,
|
||||
has_compress ? compress : true,
|
||||
has_encrypt ? encrypt : has_keyfile,
|
||||
has_fingerprint ? fingerprint : NULL,
|
||||
@@ -1040,5 +1042,6 @@ ProxmoxSupportStatus *qmp_query_proxmox_support(Error **errp)
|
||||
has_encrypt ? encrypt : !!keyfile,
|
||||
fingerprint,
|
||||
@@ -1038,5 +1040,6 @@ ProxmoxSupportStatus *qmp_query_proxmox_support(Error **errp)
|
||||
ret->pbs_dirty_bitmap_savevm = true;
|
||||
ret->pbs_dirty_bitmap_migration = true;
|
||||
ret->query_bitmap_info = true;
|
||||
@ -58,10 +60,10 @@ index 109498eaf9..4b5134ed27 100644
|
||||
return ret;
|
||||
}
|
||||
diff --git a/qapi/block-core.json b/qapi/block-core.json
|
||||
index 4e8c35a3a2..d8c7331090 100644
|
||||
index 93d924ef79..568feb63ad 100644
|
||||
--- a/qapi/block-core.json
|
||||
+++ b/qapi/block-core.json
|
||||
@@ -813,6 +813,8 @@
|
||||
@@ -908,6 +908,8 @@
|
||||
#
|
||||
# @key-password: password for keyfile (optional for format 'pbs')
|
||||
#
|
||||
@ -70,7 +72,7 @@ index 4e8c35a3a2..d8c7331090 100644
|
||||
# @fingerprint: server cert fingerprint (optional for format 'pbs')
|
||||
#
|
||||
# @backup-id: backup ID (required for format 'pbs')
|
||||
@@ -832,6 +834,7 @@
|
||||
@@ -927,6 +929,7 @@
|
||||
'*password': 'str',
|
||||
'*keyfile': 'str',
|
||||
'*key-password': 'str',
|
||||
@ -78,7 +80,7 @@ index 4e8c35a3a2..d8c7331090 100644
|
||||
'*fingerprint': 'str',
|
||||
'*backup-id': 'str',
|
||||
'*backup-time': 'int',
|
||||
@@ -884,6 +887,9 @@
|
||||
@@ -979,6 +982,9 @@
|
||||
# migration cap if this is false/unset may lead
|
||||
# to crashes on migration!
|
||||
#
|
||||
@ -88,7 +90,7 @@ index 4e8c35a3a2..d8c7331090 100644
|
||||
# @pbs-library-version: Running version of libproxmox-backup-qemu0 library.
|
||||
#
|
||||
##
|
||||
@@ -892,6 +898,7 @@
|
||||
@@ -987,6 +993,7 @@
|
||||
'query-bitmap-info': 'bool',
|
||||
'pbs-dirty-bitmap-savevm': 'bool',
|
||||
'pbs-dirty-bitmap-migration': 'bool',
|
||||
|
@ -17,10 +17,10 @@ Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
|
||||
1 file changed, 14 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/block/pbs.c b/block/pbs.c
|
||||
index 9d1f1f39d4..ce9a870885 100644
|
||||
index 43e69ada46..5d20789084 100644
|
||||
--- a/block/pbs.c
|
||||
+++ b/block/pbs.c
|
||||
@@ -200,7 +200,16 @@ static coroutine_fn int pbs_co_preadv(BlockDriverState *bs,
|
||||
@@ -201,7 +201,16 @@ static coroutine_fn int pbs_co_preadv(BlockDriverState *bs,
|
||||
BDRVPBSState *s = bs->opaque;
|
||||
int ret;
|
||||
char *pbs_error = NULL;
|
||||
@ -38,7 +38,7 @@ index 9d1f1f39d4..ce9a870885 100644
|
||||
|
||||
if (offset < 0 || bytes < 0) {
|
||||
fprintf(stderr, "unexpected negative 'offset' or 'bytes' value!\n");
|
||||
@@ -223,8 +232,10 @@ static coroutine_fn int pbs_co_preadv(BlockDriverState *bs,
|
||||
@@ -224,8 +233,10 @@ static coroutine_fn int pbs_co_preadv(BlockDriverState *bs,
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
|
@ -11,10 +11,10 @@ Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/block/stream.c b/block/stream.c
|
||||
index 694709bd25..e09bd5c4ef 100644
|
||||
index 7f9e1ecdbb..6a29d80398 100644
|
||||
--- a/block/stream.c
|
||||
+++ b/block/stream.c
|
||||
@@ -28,7 +28,7 @@ enum {
|
||||
@@ -27,7 +27,7 @@ enum {
|
||||
* large enough to process multiple clusters in a single call, so
|
||||
* that populating contiguous regions of the image is efficient.
|
||||
*/
|
||||
|
@ -17,10 +17,10 @@ Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
|
||||
1 file changed, 4 insertions(+)
|
||||
|
||||
diff --git a/block/io.c b/block/io.c
|
||||
index b9424024f9..01f50d28c8 100644
|
||||
index 2e267a85ab..449a44bf20 100644
|
||||
--- a/block/io.c
|
||||
+++ b/block/io.c
|
||||
@@ -1730,6 +1730,10 @@ static int bdrv_pad_request(BlockDriverState *bs,
|
||||
@@ -1576,6 +1576,10 @@ static int bdrv_pad_request(BlockDriverState *bs,
|
||||
{
|
||||
int ret;
|
||||
|
||||
|
@ -28,17 +28,17 @@ Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
|
||||
make error return value consistent with QEMU]
|
||||
Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
|
||||
---
|
||||
block/alloc-track.c | 350 ++++++++++++++++++++++++++++++++++++++++++++
|
||||
block/alloc-track.c | 351 ++++++++++++++++++++++++++++++++++++++++++++
|
||||
block/meson.build | 1 +
|
||||
2 files changed, 351 insertions(+)
|
||||
2 files changed, 352 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..43d40d11af
|
||||
index 0000000000..113bbd7058
|
||||
--- /dev/null
|
||||
+++ b/block/alloc-track.c
|
||||
@@ -0,0 +1,350 @@
|
||||
@@ -0,0 +1,351 @@
|
||||
+/*
|
||||
+ * 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
|
||||
@ -54,6 +54,7 @@ index 0000000000..43d40d11af
|
||||
+#include "qemu/osdep.h"
|
||||
+#include "qapi/error.h"
|
||||
+#include "block/block_int.h"
|
||||
+#include "block/dirty-bitmap.h"
|
||||
+#include "qapi/qmp/qdict.h"
|
||||
+#include "qapi/qmp/qstring.h"
|
||||
+#include "qemu/cutils.h"
|
||||
@ -163,9 +164,9 @@ index 0000000000..43d40d11af
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static int64_t track_getlength(BlockDriverState *bs)
|
||||
+static coroutine_fn int64_t track_co_getlength(BlockDriverState *bs)
|
||||
+{
|
||||
+ return bdrv_getlength(bs->file->bs);
|
||||
+ return bdrv_co_getlength(bs->file->bs);
|
||||
+}
|
||||
+
|
||||
+static int coroutine_fn track_co_preadv(BlockDriverState *bs,
|
||||
@ -365,7 +366,7 @@ index 0000000000..43d40d11af
|
||||
+
|
||||
+ .bdrv_file_open = track_open,
|
||||
+ .bdrv_close = track_close,
|
||||
+ .bdrv_getlength = track_getlength,
|
||||
+ .bdrv_co_getlength = track_co_getlength,
|
||||
+ .bdrv_child_perm = track_child_perm,
|
||||
+ .bdrv_refresh_limits = track_refresh_limits,
|
||||
+
|
||||
@ -390,7 +391,7 @@ index 0000000000..43d40d11af
|
||||
+
|
||||
+block_init(bdrv_alloc_track_init);
|
||||
diff --git a/block/meson.build b/block/meson.build
|
||||
index 7ef2fa72d5..15352f579f 100644
|
||||
index eece0d5743..8a68162cc0 100644
|
||||
--- a/block/meson.build
|
||||
+++ b/block/meson.build
|
||||
@@ -2,6 +2,7 @@ block_ss.add(genh)
|
||||
|
@ -11,7 +11,7 @@ Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
|
||||
1 file changed, 5 insertions(+)
|
||||
|
||||
diff --git a/migration/savevm-async.c b/migration/savevm-async.c
|
||||
index a38e7351c1..0b1b60c6ae 100644
|
||||
index 70273a2996..fab1dc32d2 100644
|
||||
--- a/migration/savevm-async.c
|
||||
+++ b/migration/savevm-async.c
|
||||
@@ -20,6 +20,7 @@
|
||||
@ -22,7 +22,7 @@ index a38e7351c1..0b1b60c6ae 100644
|
||||
|
||||
/* #define DEBUG_SAVEVM_STATE */
|
||||
|
||||
@@ -521,6 +522,10 @@ int load_snapshot_from_blockdev(const char *filename, Error **errp)
|
||||
@@ -518,6 +519,10 @@ int load_snapshot_from_blockdev(const char *filename, Error **errp)
|
||||
dirty_bitmap_mig_before_vm_start();
|
||||
|
||||
qemu_fclose(f);
|
||||
|
@ -46,10 +46,10 @@ index b5b0bb4467..36f97e1f19 100644
|
||||
|
||||
DEF("info", img_info,
|
||||
diff --git a/qemu-img.c b/qemu-img.c
|
||||
index 59c403373b..065a54cc42 100644
|
||||
index 06d814e39c..e2c06c496d 100644
|
||||
--- a/qemu-img.c
|
||||
+++ b/qemu-img.c
|
||||
@@ -4946,6 +4946,7 @@ static int img_dd(int argc, char **argv)
|
||||
@@ -5002,6 +5002,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 59c403373b..065a54cc42 100644
|
||||
QemuOptsList *create_opts = NULL;
|
||||
Error *local_err = NULL;
|
||||
bool image_opts = false;
|
||||
@@ -4955,6 +4956,7 @@ static int img_dd(int argc, char **argv)
|
||||
@@ -5011,6 +5012,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 59c403373b..065a54cc42 100644
|
||||
struct DdInfo dd = {
|
||||
.flags = 0,
|
||||
.count = 0,
|
||||
@@ -4992,7 +4994,7 @@ static int img_dd(int argc, char **argv)
|
||||
@@ -5048,7 +5050,7 @@ static int img_dd(int argc, char **argv)
|
||||
{ 0, 0, 0, 0 }
|
||||
};
|
||||
|
||||
@ -74,7 +74,7 @@ index 59c403373b..065a54cc42 100644
|
||||
if (c == EOF) {
|
||||
break;
|
||||
}
|
||||
@@ -5015,6 +5017,19 @@ static int img_dd(int argc, char **argv)
|
||||
@@ -5071,6 +5073,19 @@ static int img_dd(int argc, char **argv)
|
||||
case 'n':
|
||||
skip_create = true;
|
||||
break;
|
||||
@ -94,7 +94,7 @@ index 59c403373b..065a54cc42 100644
|
||||
case 'U':
|
||||
force_share = true;
|
||||
break;
|
||||
@@ -5074,11 +5089,24 @@ static int img_dd(int argc, char **argv)
|
||||
@@ -5130,11 +5145,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 59c403373b..065a54cc42 100644
|
||||
}
|
||||
|
||||
if (dd.flags & C_OSIZE) {
|
||||
@@ -5233,6 +5261,7 @@ static int img_dd(int argc, char **argv)
|
||||
@@ -5289,6 +5317,7 @@ static int img_dd(int argc, char **argv)
|
||||
out:
|
||||
g_free(arg);
|
||||
qemu_opts_del(opts);
|
||||
|
@ -4,6 +4,8 @@ Date: Tue, 26 Apr 2022 16:06:28 +0200
|
||||
Subject: [PATCH] pbs: namespace support
|
||||
|
||||
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
|
||||
[FE: adapt to QAPI change dropping redundant has_*]
|
||||
Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
|
||||
---
|
||||
block/monitor/block-hmp-cmds.c | 1 +
|
||||
block/pbs.c | 25 +++++++++++++++++++++----
|
||||
@ -13,22 +15,22 @@ Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
|
||||
5 files changed, 47 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/block/monitor/block-hmp-cmds.c b/block/monitor/block-hmp-cmds.c
|
||||
index c7468e5d3b..57b2457f1e 100644
|
||||
index fb881056e9..25ac598980 100644
|
||||
--- a/block/monitor/block-hmp-cmds.c
|
||||
+++ b/block/monitor/block-hmp-cmds.c
|
||||
@@ -1041,6 +1041,7 @@ void coroutine_fn hmp_backup(Monitor *mon, const QDict *qdict)
|
||||
false, NULL, // PBS key_password
|
||||
false, NULL, // PBS master_keyfile
|
||||
false, NULL, // PBS fingerprint
|
||||
+ false, NULL, // PBS backup-ns
|
||||
false, NULL, // PBS backup-id
|
||||
@@ -1053,6 +1053,7 @@ void coroutine_fn hmp_backup(Monitor *mon, const QDict *qdict)
|
||||
NULL, // PBS key_password
|
||||
NULL, // PBS master_keyfile
|
||||
NULL, // PBS fingerprint
|
||||
+ NULL, // PBS backup-ns
|
||||
NULL, // PBS backup-id
|
||||
false, 0, // PBS backup-time
|
||||
false, false, // PBS use-dirty-bitmap
|
||||
diff --git a/block/pbs.c b/block/pbs.c
|
||||
index ce9a870885..9192f3e41b 100644
|
||||
index 5d20789084..a2211e0f3b 100644
|
||||
--- a/block/pbs.c
|
||||
+++ b/block/pbs.c
|
||||
@@ -14,6 +14,7 @@
|
||||
@@ -15,6 +15,7 @@
|
||||
#include <proxmox-backup-qemu.h>
|
||||
|
||||
#define PBS_OPT_REPOSITORY "repository"
|
||||
@ -36,7 +38,7 @@ index ce9a870885..9192f3e41b 100644
|
||||
#define PBS_OPT_SNAPSHOT "snapshot"
|
||||
#define PBS_OPT_ARCHIVE "archive"
|
||||
#define PBS_OPT_KEYFILE "keyfile"
|
||||
@@ -27,6 +28,7 @@ typedef struct {
|
||||
@@ -28,6 +29,7 @@ typedef struct {
|
||||
int64_t length;
|
||||
|
||||
char *repository;
|
||||
@ -44,7 +46,7 @@ index ce9a870885..9192f3e41b 100644
|
||||
char *snapshot;
|
||||
char *archive;
|
||||
} BDRVPBSState;
|
||||
@@ -40,6 +42,11 @@ static QemuOptsList runtime_opts = {
|
||||
@@ -41,6 +43,11 @@ static QemuOptsList runtime_opts = {
|
||||
.type = QEMU_OPT_STRING,
|
||||
.help = "The server address and repository to connect to.",
|
||||
},
|
||||
@ -56,7 +58,7 @@ index ce9a870885..9192f3e41b 100644
|
||||
{
|
||||
.name = PBS_OPT_SNAPSHOT,
|
||||
.type = QEMU_OPT_STRING,
|
||||
@@ -76,7 +83,7 @@ static QemuOptsList runtime_opts = {
|
||||
@@ -77,7 +84,7 @@ static QemuOptsList runtime_opts = {
|
||||
|
||||
|
||||
// filename format:
|
||||
@ -65,7 +67,7 @@ index ce9a870885..9192f3e41b 100644
|
||||
static void pbs_parse_filename(const char *filename, QDict *options,
|
||||
Error **errp)
|
||||
{
|
||||
@@ -112,6 +119,7 @@ static int pbs_open(BlockDriverState *bs, QDict *options, int flags,
|
||||
@@ -113,6 +120,7 @@ static int pbs_open(BlockDriverState *bs, QDict *options, int flags,
|
||||
s->archive = g_strdup(qemu_opt_get(opts, PBS_OPT_ARCHIVE));
|
||||
const char *keyfile = qemu_opt_get(opts, PBS_OPT_KEYFILE);
|
||||
const char *password = qemu_opt_get(opts, PBS_OPT_PASSWORD);
|
||||
@ -73,7 +75,7 @@ index ce9a870885..9192f3e41b 100644
|
||||
const char *fingerprint = qemu_opt_get(opts, PBS_OPT_FINGERPRINT);
|
||||
const char *key_password = qemu_opt_get(opts, PBS_OPT_ENCRYPTION_PASSWORD);
|
||||
|
||||
@@ -124,9 +132,12 @@ static int pbs_open(BlockDriverState *bs, QDict *options, int flags,
|
||||
@@ -125,9 +133,12 @@ static int pbs_open(BlockDriverState *bs, QDict *options, int flags,
|
||||
if (!key_password) {
|
||||
key_password = getenv("PBS_ENCRYPTION_PASSWORD");
|
||||
}
|
||||
@ -87,7 +89,7 @@ index ce9a870885..9192f3e41b 100644
|
||||
keyfile, key_password, fingerprint, &pbs_error);
|
||||
|
||||
/* invalidates qemu_opt_get char pointers from above */
|
||||
@@ -171,6 +182,7 @@ static int pbs_file_open(BlockDriverState *bs, QDict *options, int flags,
|
||||
@@ -172,6 +183,7 @@ static int pbs_file_open(BlockDriverState *bs, QDict *options, int flags,
|
||||
static void pbs_close(BlockDriverState *bs) {
|
||||
BDRVPBSState *s = bs->opaque;
|
||||
g_free(s->repository);
|
||||
@ -95,7 +97,7 @@ index ce9a870885..9192f3e41b 100644
|
||||
g_free(s->snapshot);
|
||||
g_free(s->archive);
|
||||
proxmox_restore_disconnect(s->conn);
|
||||
@@ -252,8 +264,13 @@ static coroutine_fn int pbs_co_pwritev(BlockDriverState *bs,
|
||||
@@ -253,8 +265,13 @@ static coroutine_fn int pbs_co_pwritev(BlockDriverState *bs,
|
||||
static void pbs_refresh_filename(BlockDriverState *bs)
|
||||
{
|
||||
BDRVPBSState *s = bs->opaque;
|
||||
@ -170,10 +172,10 @@ index 2f834cf42e..f03d9bab8d 100644
|
||||
fprintf(stderr, "restore failed: %s\n", pbs_error);
|
||||
return -1;
|
||||
diff --git a/pve-backup.c b/pve-backup.c
|
||||
index 4b5134ed27..262e7d3894 100644
|
||||
index 504c11657a..809ff6d134 100644
|
||||
--- a/pve-backup.c
|
||||
+++ b/pve-backup.c
|
||||
@@ -10,6 +10,8 @@
|
||||
@@ -12,6 +12,8 @@
|
||||
#include "qapi/qmp/qerror.h"
|
||||
#include "qemu/cutils.h"
|
||||
|
||||
@ -182,30 +184,30 @@ index 4b5134ed27..262e7d3894 100644
|
||||
/* PVE backup state and related function */
|
||||
|
||||
/*
|
||||
@@ -531,6 +533,7 @@ UuidInfo coroutine_fn *qmp_backup(
|
||||
bool has_key_password, const char *key_password,
|
||||
bool has_master_keyfile, const char *master_keyfile,
|
||||
bool has_fingerprint, const char *fingerprint,
|
||||
+ bool has_backup_ns, const char *backup_ns,
|
||||
bool has_backup_id, const char *backup_id,
|
||||
@@ -533,6 +535,7 @@ UuidInfo coroutine_fn *qmp_backup(
|
||||
const char *key_password,
|
||||
const char *master_keyfile,
|
||||
const char *fingerprint,
|
||||
+ const char *backup_ns,
|
||||
const char *backup_id,
|
||||
bool has_backup_time, int64_t backup_time,
|
||||
bool has_use_dirty_bitmap, bool use_dirty_bitmap,
|
||||
@@ -670,8 +673,9 @@ UuidInfo coroutine_fn *qmp_backup(
|
||||
@@ -672,8 +675,9 @@ UuidInfo coroutine_fn *qmp_backup(
|
||||
firewall_name = "fw.conf";
|
||||
|
||||
char *pbs_err = NULL;
|
||||
- pbs = proxmox_backup_new(
|
||||
+ pbs = proxmox_backup_new_ns(
|
||||
backup_file,
|
||||
+ has_backup_ns ? backup_ns : NULL,
|
||||
+ backup_ns,
|
||||
backup_id,
|
||||
backup_time,
|
||||
dump_cb_block_size,
|
||||
diff --git a/qapi/block-core.json b/qapi/block-core.json
|
||||
index d8c7331090..889726fc26 100644
|
||||
index 568feb63ad..9edeb33d82 100644
|
||||
--- a/qapi/block-core.json
|
||||
+++ b/qapi/block-core.json
|
||||
@@ -817,6 +817,8 @@
|
||||
@@ -912,6 +912,8 @@
|
||||
#
|
||||
# @fingerprint: server cert fingerprint (optional for format 'pbs')
|
||||
#
|
||||
@ -214,7 +216,7 @@ index d8c7331090..889726fc26 100644
|
||||
# @backup-id: backup ID (required for format 'pbs')
|
||||
#
|
||||
# @backup-time: backup timestamp (Unix epoch, required for format 'pbs')
|
||||
@@ -836,6 +838,7 @@
|
||||
@@ -931,6 +933,7 @@
|
||||
'*key-password': 'str',
|
||||
'*master-keyfile': 'str',
|
||||
'*fingerprint': 'str',
|
||||
@ -222,7 +224,7 @@ index d8c7331090..889726fc26 100644
|
||||
'*backup-id': 'str',
|
||||
'*backup-time': 'int',
|
||||
'*use-dirty-bitmap': 'bool',
|
||||
@@ -3290,7 +3293,7 @@
|
||||
@@ -3385,7 +3388,7 @@
|
||||
{ 'struct': 'BlockdevOptionsPbs',
|
||||
'data': { 'repository': 'str', 'snapshot': 'str', 'archive': 'str',
|
||||
'*keyfile': 'str', '*password': 'str', '*fingerprint': 'str',
|
||||
|
@ -12,10 +12,10 @@ Signed-off-by: Fabian Ebner <f.ebner@proxmox.com>
|
||||
1 file changed, 2 insertions(+), 40 deletions(-)
|
||||
|
||||
diff --git a/block/rbd.c b/block/rbd.c
|
||||
index 64a8d7d48b..9fc6dcb957 100644
|
||||
index a4749f3b1b..53e0396b51 100644
|
||||
--- a/block/rbd.c
|
||||
+++ b/block/rbd.c
|
||||
@@ -1348,7 +1348,6 @@ static int coroutine_fn qemu_rbd_co_block_status(BlockDriverState *bs,
|
||||
@@ -1511,7 +1511,6 @@ static int coroutine_fn qemu_rbd_co_block_status(BlockDriverState *bs,
|
||||
int status, r;
|
||||
RBDDiffIterateReq req = { .offs = offset };
|
||||
uint64_t features, flags;
|
||||
@ -23,7 +23,7 @@ index 64a8d7d48b..9fc6dcb957 100644
|
||||
|
||||
assert(offset + bytes <= s->image_size);
|
||||
|
||||
@@ -1376,43 +1375,7 @@ static int coroutine_fn qemu_rbd_co_block_status(BlockDriverState *bs,
|
||||
@@ -1539,43 +1538,7 @@ static int coroutine_fn qemu_rbd_co_block_status(BlockDriverState *bs,
|
||||
return status;
|
||||
}
|
||||
|
||||
@ -68,7 +68,7 @@ index 64a8d7d48b..9fc6dcb957 100644
|
||||
qemu_rbd_diff_iterate_cb, &req);
|
||||
if (r < 0 && r != QEMU_RBD_EXIT_DIFF_ITERATE2) {
|
||||
return status;
|
||||
@@ -1431,8 +1394,7 @@ static int coroutine_fn qemu_rbd_co_block_status(BlockDriverState *bs,
|
||||
@@ -1594,8 +1557,7 @@ static int coroutine_fn qemu_rbd_co_block_status(BlockDriverState *bs,
|
||||
status = BDRV_BLOCK_ZERO | BDRV_BLOCK_OFFSET_VALID;
|
||||
}
|
||||
|
||||
|
@ -13,10 +13,10 @@ Signed-off-by: Fabian Ebner <f.ebner@proxmox.com>
|
||||
1 file changed, 5 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/block/rbd.c b/block/rbd.c
|
||||
index 9fc6dcb957..98f4ba2620 100644
|
||||
index 53e0396b51..0913a0af39 100644
|
||||
--- a/block/rbd.c
|
||||
+++ b/block/rbd.c
|
||||
@@ -1307,11 +1307,11 @@ static int qemu_rbd_diff_iterate_cb(uint64_t offs, size_t len,
|
||||
@@ -1470,11 +1470,11 @@ static int qemu_rbd_diff_iterate_cb(uint64_t offs, size_t len,
|
||||
RBDDiffIterateReq *req = opaque;
|
||||
|
||||
assert(req->offs + req->bytes <= offs);
|
||||
|
@ -23,10 +23,10 @@ Signed-off-by: Fabian Ebner <f.ebner@proxmox.com>
|
||||
1 file changed, 112 deletions(-)
|
||||
|
||||
diff --git a/block/rbd.c b/block/rbd.c
|
||||
index 98f4ba2620..efcbbe5949 100644
|
||||
index 0913a0af39..1dab254517 100644
|
||||
--- a/block/rbd.c
|
||||
+++ b/block/rbd.c
|
||||
@@ -97,12 +97,6 @@ typedef struct RBDTask {
|
||||
@@ -108,12 +108,6 @@ typedef struct RBDTask {
|
||||
int64_t ret;
|
||||
} RBDTask;
|
||||
|
||||
@ -39,7 +39,7 @@ index 98f4ba2620..efcbbe5949 100644
|
||||
static int qemu_rbd_connect(rados_t *cluster, rados_ioctx_t *io_ctx,
|
||||
BlockdevOptionsRbd *opts, bool cache,
|
||||
const char *keypairs, const char *secretid,
|
||||
@@ -1293,111 +1287,6 @@ static ImageInfoSpecific *qemu_rbd_get_specific_info(BlockDriverState *bs,
|
||||
@@ -1456,111 +1450,6 @@ static ImageInfoSpecific *qemu_rbd_get_specific_info(BlockDriverState *bs,
|
||||
return spec_info;
|
||||
}
|
||||
|
||||
@ -148,10 +148,10 @@ index 98f4ba2620..efcbbe5949 100644
|
||||
- return status;
|
||||
-}
|
||||
-
|
||||
static int64_t qemu_rbd_getlength(BlockDriverState *bs)
|
||||
static int64_t coroutine_fn qemu_rbd_co_getlength(BlockDriverState *bs)
|
||||
{
|
||||
BDRVRBDState *s = bs->opaque;
|
||||
@@ -1633,7 +1522,6 @@ static BlockDriver bdrv_rbd = {
|
||||
@@ -1796,7 +1685,6 @@ static BlockDriver bdrv_rbd = {
|
||||
#ifdef LIBRBD_SUPPORTS_WRITE_ZEROES
|
||||
.bdrv_co_pwrite_zeroes = qemu_rbd_co_pwrite_zeroes,
|
||||
#endif
|
||||
|
@ -21,10 +21,10 @@ Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
|
||||
1 file changed, 8 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/pve-backup.c b/pve-backup.c
|
||||
index 262e7d3894..fde3554133 100644
|
||||
index 809ff6d134..221e45ed0e 100644
|
||||
--- a/pve-backup.c
|
||||
+++ b/pve-backup.c
|
||||
@@ -503,6 +503,11 @@ static void create_backup_jobs_bh(void *opaque) {
|
||||
@@ -505,6 +505,11 @@ static void create_backup_jobs_bh(void *opaque) {
|
||||
}
|
||||
|
||||
if (*errp) {
|
||||
@ -36,7 +36,7 @@ index 262e7d3894..fde3554133 100644
|
||||
l = backup_state.di_list;
|
||||
while (l) {
|
||||
PVEBackupDevInfo *di = (PVEBackupDevInfo *)l->data;
|
||||
@@ -513,11 +518,11 @@ static void create_backup_jobs_bh(void *opaque) {
|
||||
@@ -515,11 +520,11 @@ static void create_backup_jobs_bh(void *opaque) {
|
||||
di->target = NULL;
|
||||
}
|
||||
|
||||
@ -50,7 +50,7 @@ index 262e7d3894..fde3554133 100644
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -943,6 +948,7 @@ err:
|
||||
@@ -945,6 +950,7 @@ err:
|
||||
|
||||
if (pbs) {
|
||||
proxmox_backup_disconnect(pbs);
|
||||
|
@ -23,10 +23,10 @@ Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
|
||||
1 file changed, 19 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/pve-backup.c b/pve-backup.c
|
||||
index fde3554133..0cf30e1ced 100644
|
||||
index 221e45ed0e..a20fa38ee8 100644
|
||||
--- a/pve-backup.c
|
||||
+++ b/pve-backup.c
|
||||
@@ -316,6 +316,13 @@ static void coroutine_fn pvebackup_co_complete_stream(void *opaque)
|
||||
@@ -318,6 +318,13 @@ static void coroutine_fn pvebackup_co_complete_stream(void *opaque)
|
||||
}
|
||||
}
|
||||
|
||||
@ -40,7 +40,7 @@ index fde3554133..0cf30e1ced 100644
|
||||
// remove self from job list
|
||||
backup_state.di_list = g_list_remove(backup_state.di_list, di);
|
||||
|
||||
@@ -491,6 +498,11 @@ static void create_backup_jobs_bh(void *opaque) {
|
||||
@@ -493,6 +500,11 @@ static void create_backup_jobs_bh(void *opaque) {
|
||||
aio_context_release(aio_context);
|
||||
|
||||
di->job = job;
|
||||
@ -52,7 +52,7 @@ index fde3554133..0cf30e1ced 100644
|
||||
|
||||
if (!job || local_err) {
|
||||
error_setg(errp, "backup_job_create failed: %s",
|
||||
@@ -518,11 +530,15 @@ static void create_backup_jobs_bh(void *opaque) {
|
||||
@@ -520,11 +532,15 @@ static void create_backup_jobs_bh(void *opaque) {
|
||||
di->target = NULL;
|
||||
}
|
||||
|
||||
|
@ -39,10 +39,10 @@ Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
|
||||
1 file changed, 38 insertions(+), 19 deletions(-)
|
||||
|
||||
diff --git a/pve-backup.c b/pve-backup.c
|
||||
index 0cf30e1ced..4067018dbe 100644
|
||||
index a20fa38ee8..3509f46ed8 100644
|
||||
--- a/pve-backup.c
|
||||
+++ b/pve-backup.c
|
||||
@@ -354,12 +354,41 @@ static void pvebackup_complete_cb(void *opaque, int ret)
|
||||
@@ -356,12 +356,41 @@ static void pvebackup_complete_cb(void *opaque, int ret)
|
||||
|
||||
/*
|
||||
* job_cancel(_sync) does not like to be called from coroutines, so defer to
|
||||
@ -87,7 +87,7 @@ index 0cf30e1ced..4067018dbe 100644
|
||||
aio_co_enter(data->ctx, data->co);
|
||||
}
|
||||
|
||||
@@ -380,22 +409,12 @@ void coroutine_fn qmp_backup_cancel(Error **errp)
|
||||
@@ -382,22 +411,12 @@ void coroutine_fn qmp_backup_cancel(Error **errp)
|
||||
proxmox_backup_abort(backup_state.pbs, "backup canceled");
|
||||
}
|
||||
|
||||
|
@ -21,10 +21,10 @@ Signed-off-by: Fabian Ebner <f.ebner@proxmox.com>
|
||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/block/alloc-track.c b/block/alloc-track.c
|
||||
index 43d40d11af..95c9c67cd8 100644
|
||||
index 113bbd7058..b75d7c6460 100644
|
||||
--- a/block/alloc-track.c
|
||||
+++ b/block/alloc-track.c
|
||||
@@ -174,7 +174,8 @@ static int coroutine_fn track_co_preadv(BlockDriverState *bs,
|
||||
@@ -175,7 +175,8 @@ static int coroutine_fn track_co_preadv(BlockDriverState *bs,
|
||||
ret = bdrv_co_preadv(bs->backing, local_offset, local_bytes,
|
||||
&local_qiov, flags);
|
||||
} else {
|
||||
|
@ -31,13 +31,13 @@ Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
|
||||
3 files changed, 23 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/block/monitor/block-hmp-cmds.c b/block/monitor/block-hmp-cmds.c
|
||||
index 57b2457f1e..ab0c988ae9 100644
|
||||
index 25ac598980..74e43a757f 100644
|
||||
--- a/block/monitor/block-hmp-cmds.c
|
||||
+++ b/block/monitor/block-hmp-cmds.c
|
||||
@@ -1049,7 +1049,9 @@ void coroutine_fn hmp_backup(Monitor *mon, const QDict *qdict)
|
||||
@@ -1061,7 +1061,9 @@ void coroutine_fn hmp_backup(Monitor *mon, const QDict *qdict)
|
||||
false, false, // PBS encrypt
|
||||
true, dir ? BACKUP_FORMAT_DIR : BACKUP_FORMAT_VMA,
|
||||
false, NULL, false, NULL, !!devlist,
|
||||
NULL, NULL,
|
||||
- devlist, qdict_haskey(qdict, "speed"), speed, &error);
|
||||
+ devlist, qdict_haskey(qdict, "speed"), speed,
|
||||
+ false, 0, // BackupPerf max-workers
|
||||
@ -46,10 +46,10 @@ index 57b2457f1e..ab0c988ae9 100644
|
||||
hmp_handle_error(mon, error);
|
||||
}
|
||||
diff --git a/pve-backup.c b/pve-backup.c
|
||||
index 4067018dbe..3ca4f74cb8 100644
|
||||
index 3509f46ed8..a343d63586 100644
|
||||
--- a/pve-backup.c
|
||||
+++ b/pve-backup.c
|
||||
@@ -55,6 +55,7 @@ static struct PVEBackupState {
|
||||
@@ -57,6 +57,7 @@ static struct PVEBackupState {
|
||||
bool starting;
|
||||
} stat;
|
||||
int64_t speed;
|
||||
@ -57,7 +57,7 @@ index 4067018dbe..3ca4f74cb8 100644
|
||||
VmaWriter *vmaw;
|
||||
ProxmoxBackupHandle *pbs;
|
||||
GList *di_list;
|
||||
@@ -490,8 +491,6 @@ static void create_backup_jobs_bh(void *opaque) {
|
||||
@@ -492,8 +493,6 @@ static void create_backup_jobs_bh(void *opaque) {
|
||||
}
|
||||
backup_state.txn = job_txn_new_seq();
|
||||
|
||||
@ -66,7 +66,7 @@ index 4067018dbe..3ca4f74cb8 100644
|
||||
/* create and start all jobs (paused state) */
|
||||
GList *l = backup_state.di_list;
|
||||
while (l) {
|
||||
@@ -511,8 +510,9 @@ static void create_backup_jobs_bh(void *opaque) {
|
||||
@@ -513,8 +512,9 @@ static void create_backup_jobs_bh(void *opaque) {
|
||||
|
||||
BlockJob *job = backup_job_create(
|
||||
NULL, di->bs, di->target, backup_state.speed, sync_mode, di->bitmap,
|
||||
@ -78,10 +78,10 @@ index 4067018dbe..3ca4f74cb8 100644
|
||||
|
||||
aio_context_release(aio_context);
|
||||
|
||||
@@ -583,7 +583,9 @@ UuidInfo coroutine_fn *qmp_backup(
|
||||
bool has_config_file, const char *config_file,
|
||||
bool has_firewall_file, const char *firewall_file,
|
||||
bool has_devlist, const char *devlist,
|
||||
@@ -585,7 +585,9 @@ UuidInfo coroutine_fn *qmp_backup(
|
||||
const char *config_file,
|
||||
const char *firewall_file,
|
||||
const char *devlist,
|
||||
- bool has_speed, int64_t speed, Error **errp)
|
||||
+ bool has_speed, int64_t speed,
|
||||
+ bool has_max_workers, int64_t max_workers,
|
||||
@ -89,7 +89,7 @@ index 4067018dbe..3ca4f74cb8 100644
|
||||
{
|
||||
assert(qemu_in_coroutine());
|
||||
|
||||
@@ -913,6 +915,11 @@ UuidInfo coroutine_fn *qmp_backup(
|
||||
@@ -915,6 +917,11 @@ UuidInfo coroutine_fn *qmp_backup(
|
||||
|
||||
backup_state.speed = (has_speed && speed > 0) ? speed : 0;
|
||||
|
||||
@ -101,7 +101,7 @@ index 4067018dbe..3ca4f74cb8 100644
|
||||
backup_state.vmaw = vmaw;
|
||||
backup_state.pbs = pbs;
|
||||
|
||||
@@ -1088,5 +1095,6 @@ ProxmoxSupportStatus *qmp_query_proxmox_support(Error **errp)
|
||||
@@ -1086,5 +1093,6 @@ ProxmoxSupportStatus *qmp_query_proxmox_support(Error **errp)
|
||||
ret->pbs_dirty_bitmap_migration = true;
|
||||
ret->query_bitmap_info = true;
|
||||
ret->pbs_masterkey = true;
|
||||
@ -109,10 +109,10 @@ index 4067018dbe..3ca4f74cb8 100644
|
||||
return ret;
|
||||
}
|
||||
diff --git a/qapi/block-core.json b/qapi/block-core.json
|
||||
index 889726fc26..65795b7204 100644
|
||||
index 9edeb33d82..809f3c61bc 100644
|
||||
--- a/qapi/block-core.json
|
||||
+++ b/qapi/block-core.json
|
||||
@@ -829,6 +829,8 @@
|
||||
@@ -924,6 +924,8 @@
|
||||
#
|
||||
# @encrypt: use encryption ((optional for format 'pbs', defaults to true if there is a keyfile)
|
||||
#
|
||||
@ -121,7 +121,7 @@ index 889726fc26..65795b7204 100644
|
||||
# Returns: the uuid of the backup job
|
||||
#
|
||||
##
|
||||
@@ -847,7 +849,9 @@
|
||||
@@ -942,7 +944,9 @@
|
||||
'*format': 'BackupFormat',
|
||||
'*config-file': 'str',
|
||||
'*firewall-file': 'str',
|
||||
@ -132,7 +132,7 @@ index 889726fc26..65795b7204 100644
|
||||
'returns': 'UuidInfo', 'coroutine': true }
|
||||
|
||||
##
|
||||
@@ -902,7 +906,8 @@
|
||||
@@ -997,7 +1001,8 @@
|
||||
'pbs-dirty-bitmap-savevm': 'bool',
|
||||
'pbs-dirty-bitmap-migration': 'bool',
|
||||
'pbs-masterkey': 'bool',
|
||||
|
153
debian/patches/pve/0063-alloc-track-fix-deadlock-during-drop.patch
vendored
Normal file
153
debian/patches/pve/0063-alloc-track-fix-deadlock-during-drop.patch
vendored
Normal file
@ -0,0 +1,153 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Fiona Ebner <f.ebner@proxmox.com>
|
||||
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 <w.bumiller@proxmox.com>
|
||||
Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
|
||||
---
|
||||
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;
|
49
debian/patches/pve/0064-savevm-async-optimize-querying-pending.patch
vendored
Normal file
49
debian/patches/pve/0064-savevm-async-optimize-querying-pending.patch
vendored
Normal file
@ -0,0 +1,49 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Fiona Ebner <f.ebner@proxmox.com>
|
||||
Date: Fri, 31 Mar 2023 14:13:01 +0200
|
||||
Subject: [PATCH] savevm-async: optimize querying pending
|
||||
|
||||
by using the estimate variant until the precopy estimate is below the
|
||||
threshold. This is similar to what is done in migration.c
|
||||
|
||||
Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
|
||||
---
|
||||
migration/savevm-async.c | 15 +++++++++++----
|
||||
1 file changed, 11 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/migration/savevm-async.c b/migration/savevm-async.c
|
||||
index fab1dc32d2..de91506821 100644
|
||||
--- a/migration/savevm-async.c
|
||||
+++ b/migration/savevm-async.c
|
||||
@@ -242,12 +242,19 @@ static void coroutine_fn process_savevm_co(void *opaque)
|
||||
|
||||
while (snap_state.state == SAVE_STATE_ACTIVE) {
|
||||
uint64_t pending_size, pend_precopy, pend_postcopy;
|
||||
+ uint64_t threshold = 400 * 1000;
|
||||
|
||||
- /* pending is expected to be called without iothread lock */
|
||||
+ /*
|
||||
+ * pending_{estimate,exact} are expected to be called without iothread
|
||||
+ * lock. Similar to what is done in migration.c, call the exact variant
|
||||
+ * only once pend_precopy in the estimate is below the threshold.
|
||||
+ */
|
||||
qemu_mutex_unlock_iothread();
|
||||
- qemu_savevm_state_pending_exact(&pend_precopy, &pend_postcopy);
|
||||
+ qemu_savevm_state_pending_estimate(&pend_precopy, &pend_postcopy);
|
||||
+ if (pend_precopy <= threshold) {
|
||||
+ qemu_savevm_state_pending_exact(&pend_precopy, &pend_postcopy);
|
||||
+ }
|
||||
qemu_mutex_lock_iothread();
|
||||
-
|
||||
pending_size = pend_precopy + pend_postcopy;
|
||||
|
||||
/*
|
||||
@@ -259,7 +266,7 @@ static void coroutine_fn process_savevm_co(void *opaque)
|
||||
maxlen = blk_getlength(snap_state.target) - 100*1024*1024;
|
||||
|
||||
/* Note that there is no progress for pend_postcopy when iterating */
|
||||
- if (pending_size - pend_postcopy > 400000 && snap_state.bs_pos + pending_size < maxlen) {
|
||||
+ if (pend_precopy > threshold && snap_state.bs_pos + pending_size < maxlen) {
|
||||
ret = qemu_savevm_state_iterate(snap_state.file, false);
|
||||
if (ret < 0) {
|
||||
save_snapshot_error("qemu_savevm_state_iterate error %d", ret);
|
26
debian/patches/pve/0065-savevm-async-also-initialize-compression-counters.patch
vendored
Normal file
26
debian/patches/pve/0065-savevm-async-also-initialize-compression-counters.patch
vendored
Normal file
@ -0,0 +1,26 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Fiona Ebner <f.ebner@proxmox.com>
|
||||
Date: Thu, 27 Apr 2023 10:28:08 +0200
|
||||
Subject: [PATCH] savevm-async: also initialize compression counters
|
||||
|
||||
Like is done in the migration code. While the compression migration
|
||||
capability is not used by Proxmox VE currently, it's still worth to
|
||||
be prepared for the future.
|
||||
|
||||
Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
|
||||
---
|
||||
migration/savevm-async.c | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/migration/savevm-async.c b/migration/savevm-async.c
|
||||
index de91506821..effe6d1e0d 100644
|
||||
--- a/migration/savevm-async.c
|
||||
+++ b/migration/savevm-async.c
|
||||
@@ -394,6 +394,7 @@ void qmp_savevm_start(const char *statefile, Error **errp)
|
||||
*/
|
||||
migrate_init(ms);
|
||||
memset(&ram_counters, 0, sizeof(ram_counters));
|
||||
+ 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");
|
190
debian/patches/pve/0066-migration-for-snapshots-hold-the-BQL-during-setup-ca.patch
vendored
Normal file
190
debian/patches/pve/0066-migration-for-snapshots-hold-the-BQL-during-setup-ca.patch
vendored
Normal file
@ -0,0 +1,190 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Fiona Ebner <f.ebner@proxmox.com>
|
||||
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 <f.ebner@proxmox.com>
|
||||
---
|
||||
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 a8dfd8fefd..fa9b0b0f10 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 a6440929fa..69fab3275c 100644
|
||||
--- a/migration/block-dirty-bitmap.c
|
||||
+++ b/migration/block-dirty-bitmap.c
|
||||
@@ -1214,10 +1214,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;
|
||||
}
|
||||
|
||||
@@ -1225,7 +1232,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 b2497bbd32..c9d55be642 100644
|
||||
--- a/migration/block.c
|
||||
+++ b/migration/block.c
|
||||
@@ -716,21 +716,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 79d881f735..0ecbbc3202 100644
|
||||
--- a/migration/ram.c
|
||||
+++ b/migration/ram.c
|
||||
@@ -3117,8 +3117,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() {
|
||||
@@ -3130,7 +3138,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 aa54a67fda..fc6a82a555 100644
|
||||
--- a/migration/savevm.c
|
||||
+++ b/migration/savevm.c
|
||||
@@ -1621,10 +1621,8 @@ static int qemu_savevm_state(QEMUFile *f, Error **errp)
|
||||
memset(&compression_counters, 0, sizeof(compression_counters));
|
||||
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) {
|
29
debian/patches/pve/0067-savevm-async-don-t-hold-BQL-during-setup.patch
vendored
Normal file
29
debian/patches/pve/0067-savevm-async-don-t-hold-BQL-during-setup.patch
vendored
Normal file
@ -0,0 +1,29 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Fiona Ebner <f.ebner@proxmox.com>
|
||||
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 <f.ebner@proxmox.com>
|
||||
---
|
||||
migration/savevm-async.c | 2 --
|
||||
1 file changed, 2 deletions(-)
|
||||
|
||||
diff --git a/migration/savevm-async.c b/migration/savevm-async.c
|
||||
index effe6d1e0d..f006a8e4d4 100644
|
||||
--- a/migration/savevm-async.c
|
||||
+++ b/migration/savevm-async.c
|
||||
@@ -403,10 +403,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.
|
37
debian/patches/series
vendored
37
debian/patches/series
vendored
@ -1,31 +1,9 @@
|
||||
extra/0001-monitor-qmp-fix-race-with-clients-disconnecting-earl.patch
|
||||
extra/0002-init-daemonize-defuse-PID-file-resolve-error.patch
|
||||
extra/0003-virtio-mem-Fix-the-bitmap-index-of-the-section-offse.patch
|
||||
extra/0004-virtio-mem-Fix-the-iterator-variable-in-a-vmem-rdl_l.patch
|
||||
extra/0005-vhost-fix-vq-dirty-bitmap-syncing-when-vIOMMU-is-ena.patch
|
||||
extra/0006-virtio-rng-pci-fix-migration-compat-for-vectors.patch
|
||||
extra/0007-block-fix-detect-zeroes-with-BDRV_REQ_REGISTERED_BUF.patch
|
||||
extra/0008-memory-prevent-dma-reentracy-issues.patch
|
||||
extra/0009-block-iscsi-fix-double-free-on-BUSY-or-similar-statu.patch
|
||||
extra/0010-scsi-megasas-Internal-cdbs-have-16-byte-length.patch
|
||||
extra/0011-ide-avoid-potential-deadlock-when-draining-during-tr.patch
|
||||
extra/0012-hw-nvme-fix-missing-endian-conversions-for-doorbell-.patch
|
||||
extra/0013-hw-smbios-fix-field-corruption-in-type-4-table.patch
|
||||
extra/0014-virtio-rng-pci-fix-transitional-migration-compat-for.patch
|
||||
extra/0015-hw-timer-hpet-Fix-expiration-time-overflow.patch
|
||||
extra/0016-vdpa-stop-all-svq-on-device-deletion.patch
|
||||
extra/0017-vhost-avoid-a-potential-use-of-an-uninitialized-vari.patch
|
||||
extra/0018-chardev-char-socket-set-s-listener-NULL-in-char_sock.patch
|
||||
extra/0019-intel-iommu-fail-MAP-notifier-without-caching-mode.patch
|
||||
extra/0020-intel-iommu-fail-DEVIOTLB_UNMAP-without-dt-mode.patch
|
||||
extra/0021-memory-Allow-disabling-re-entrancy-checking-per-MR.patch
|
||||
extra/0022-lsi53c895a-disable-reentrancy-detection-for-script-R.patch
|
||||
extra/0023-acpi-cpuhp-fix-guest-visible-maximum-access-size-to-.patch
|
||||
extra/0024-tests-tcg-i386-Introduce-and-use-reg_t-consistently.patch
|
||||
extra/0025-target-i386-Fix-BEXTR-instruction.patch
|
||||
extra/0026-target-i386-Fix-C-flag-for-BLSI-BLSMSK-BLSR.patch
|
||||
extra/0027-target-i386-fix-ADOX-followed-by-ADCX.patch
|
||||
extra/0028-target-i386-Fix-BZHI-instruction.patch
|
||||
extra/0002-memory-prevent-dma-reentracy-issues.patch
|
||||
extra/0003-scsi-megasas-Internal-cdbs-have-16-byte-length.patch
|
||||
extra/0004-ide-avoid-potential-deadlock-when-draining-during-tr.patch
|
||||
extra/0005-memory-Allow-disabling-re-entrancy-checking-per-MR.patch
|
||||
extra/0006-lsi53c895a-disable-reentrancy-detection-for-script-R.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
|
||||
@ -94,3 +72,8 @@ pve/0059-vma-create-support-64KiB-unaligned-input-images.patch
|
||||
pve/0060-vma-create-avoid-triggering-assertion-in-error-case.patch
|
||||
pve/0061-block-alloc-track-avoid-premature-break.patch
|
||||
pve/0062-PVE-Backup-allow-passing-max-workers-performance-set.patch
|
||||
pve/0063-alloc-track-fix-deadlock-during-drop.patch
|
||||
pve/0064-savevm-async-optimize-querying-pending.patch
|
||||
pve/0065-savevm-async-also-initialize-compression-counters.patch
|
||||
pve/0066-migration-for-snapshots-hold-the-BQL-during-setup-ca.patch
|
||||
pve/0067-savevm-async-don-t-hold-BQL-during-setup.patch
|
||||
|
2
qemu
2
qemu
@ -1 +1 @@
|
||||
Subproject commit b67b00e6b4c7831a3f5bc684bc0df7a9bfd1bd56
|
||||
Subproject commit c1eb2ddf0f8075faddc5f7c3d39feae3e8e9d6b4
|
Loading…
Reference in New Issue
Block a user