update submodule and patches to 7.1.0
Notable changes: * The only big change is the switch to using a custom QIOChannel for savevm-async, because the previously used QEMUFileOps was dropped. Changes to the current implementation: * Switch to vector based methods as required for an IO channel. For short reads the passed-in IO vector is stuffed with zeroes at the end, just to be sure. * For reading: The documentation in include/io/channel.h states that at least one byte should be read, so also error out when whe are at the very end instead of returning 0. * For reading: Fix off-by-one error when request goes beyond end. The wrong code piece was: if ((pos + size) > maxlen) { size = maxlen - pos - 1; } Previously, the last byte would not be read. It's actually possible to get a snapshot .raw file that has content all the way up the final 512 byte (= BDRV_SECTOR_SIZE) boundary without any trailing zero bytes (I wrote a script to do it). Luckily, it didn't cause a real issue, because qemu_loadvm_state() is not interested in the final (i.e. QEMU_VM_VMDESCRIPTION) section. The buffer for reading it is simply freed up afterwards and the function will assume that it read the whole section, even if that's not the case. * For writing: Make use of the generated blk_pwritev() wrapper instead of manually wrapping the coroutine to simplify and save a few lines. * Adapt to changed interfaces for blk_{pread,pwrite}: * a9262f551e ("block: Change blk_{pread,pwrite}() param order") * 3b35d4542c ("block: Add a 'flags' param to blk_pread()") * bf5b16fa40 ("block: Make blk_{pread,pwrite}() return 0 on success") Those changes especially affected the qemu-img dd patches, because the context also changed, but also some of our block drivers used the functions. * Drop qemu-common.h include: it got renamed after essentially everything was moved to other headers. The only remaining user I could find for things dropped from the header between 7.0 and 7.1 was qemu_get_vm_name() in the iscsi-initiatorname patch, but it already includes the header to which the function was moved. Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
This commit is contained in:
parent
2775b2e378
commit
5b15e2ecaf
@ -36,7 +36,7 @@ Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
|
|||||||
5 files changed, 145 insertions(+), 29 deletions(-)
|
5 files changed, 145 insertions(+), 29 deletions(-)
|
||||||
|
|
||||||
diff --git a/block/mirror.c b/block/mirror.c
|
diff --git a/block/mirror.c b/block/mirror.c
|
||||||
index d8ecb9efa2..d95a7d7940 100644
|
index 3c4ab1159d..f2eca983f1 100644
|
||||||
--- a/block/mirror.c
|
--- a/block/mirror.c
|
||||||
+++ b/block/mirror.c
|
+++ b/block/mirror.c
|
||||||
@@ -51,7 +51,7 @@ typedef struct MirrorBlockJob {
|
@@ -51,7 +51,7 @@ typedef struct MirrorBlockJob {
|
||||||
@ -252,7 +252,7 @@ index d8ecb9efa2..d95a7d7940 100644
|
|||||||
errp);
|
errp);
|
||||||
if (!job) {
|
if (!job) {
|
||||||
diff --git a/blockdev.c b/blockdev.c
|
diff --git a/blockdev.c b/blockdev.c
|
||||||
index e46e831212..fa601838a3 100644
|
index 9230888e34..9a1a3118ed 100644
|
||||||
--- a/blockdev.c
|
--- a/blockdev.c
|
||||||
+++ b/blockdev.c
|
+++ b/blockdev.c
|
||||||
@@ -2951,6 +2951,10 @@ static void blockdev_mirror_common(const char *job_id, BlockDriverState *bs,
|
@@ -2951,6 +2951,10 @@ static void blockdev_mirror_common(const char *job_id, BlockDriverState *bs,
|
||||||
@ -344,10 +344,10 @@ index e46e831212..fa601838a3 100644
|
|||||||
has_granularity, granularity,
|
has_granularity, granularity,
|
||||||
has_buf_size, buf_size,
|
has_buf_size, buf_size,
|
||||||
diff --git a/include/block/block_int-global-state.h b/include/block/block_int-global-state.h
|
diff --git a/include/block/block_int-global-state.h b/include/block/block_int-global-state.h
|
||||||
index 0f21b0570b..e7f901d048 100644
|
index b49f4eb35b..9d744db618 100644
|
||||||
--- a/include/block/block_int-global-state.h
|
--- a/include/block/block_int-global-state.h
|
||||||
+++ b/include/block/block_int-global-state.h
|
+++ b/include/block/block_int-global-state.h
|
||||||
@@ -148,7 +148,9 @@ void mirror_start(const char *job_id, BlockDriverState *bs,
|
@@ -149,7 +149,9 @@ void mirror_start(const char *job_id, BlockDriverState *bs,
|
||||||
BlockDriverState *target, const char *replaces,
|
BlockDriverState *target, const char *replaces,
|
||||||
int creation_flags, int64_t speed,
|
int creation_flags, int64_t speed,
|
||||||
uint32_t granularity, int64_t buf_size,
|
uint32_t granularity, int64_t buf_size,
|
||||||
@ -359,10 +359,10 @@ index 0f21b0570b..e7f901d048 100644
|
|||||||
BlockdevOnError on_source_error,
|
BlockdevOnError on_source_error,
|
||||||
BlockdevOnError on_target_error,
|
BlockdevOnError on_target_error,
|
||||||
diff --git a/qapi/block-core.json b/qapi/block-core.json
|
diff --git a/qapi/block-core.json b/qapi/block-core.json
|
||||||
index beeb91952a..fb25c2b245 100644
|
index 2173e7734a..e1857e7094 100644
|
||||||
--- a/qapi/block-core.json
|
--- a/qapi/block-core.json
|
||||||
+++ b/qapi/block-core.json
|
+++ b/qapi/block-core.json
|
||||||
@@ -1993,10 +1993,19 @@
|
@@ -2000,10 +2000,19 @@
|
||||||
# (all the disk, only the sectors allocated in the topmost image, or
|
# (all the disk, only the sectors allocated in the topmost image, or
|
||||||
# only new I/O).
|
# only new I/O).
|
||||||
#
|
#
|
||||||
@ -383,7 +383,7 @@ index beeb91952a..fb25c2b245 100644
|
|||||||
#
|
#
|
||||||
# @buf-size: maximum amount of data in flight from source to
|
# @buf-size: maximum amount of data in flight from source to
|
||||||
# target (since 1.4).
|
# target (since 1.4).
|
||||||
@@ -2034,7 +2043,9 @@
|
@@ -2043,7 +2052,9 @@
|
||||||
{ 'struct': 'DriveMirror',
|
{ 'struct': 'DriveMirror',
|
||||||
'data': { '*job-id': 'str', 'device': 'str', 'target': 'str',
|
'data': { '*job-id': 'str', 'device': 'str', 'target': 'str',
|
||||||
'*format': 'str', '*node-name': 'str', '*replaces': 'str',
|
'*format': 'str', '*node-name': 'str', '*replaces': 'str',
|
||||||
@ -394,7 +394,7 @@ index beeb91952a..fb25c2b245 100644
|
|||||||
'*speed': 'int', '*granularity': 'uint32',
|
'*speed': 'int', '*granularity': 'uint32',
|
||||||
'*buf-size': 'int', '*on-source-error': 'BlockdevOnError',
|
'*buf-size': 'int', '*on-source-error': 'BlockdevOnError',
|
||||||
'*on-target-error': 'BlockdevOnError',
|
'*on-target-error': 'BlockdevOnError',
|
||||||
@@ -2306,10 +2317,19 @@
|
@@ -2322,10 +2333,19 @@
|
||||||
# (all the disk, only the sectors allocated in the topmost image, or
|
# (all the disk, only the sectors allocated in the topmost image, or
|
||||||
# only new I/O).
|
# only new I/O).
|
||||||
#
|
#
|
||||||
@ -415,7 +415,7 @@ index beeb91952a..fb25c2b245 100644
|
|||||||
#
|
#
|
||||||
# @buf-size: maximum amount of data in flight from source to
|
# @buf-size: maximum amount of data in flight from source to
|
||||||
# target
|
# target
|
||||||
@@ -2358,7 +2378,8 @@
|
@@ -2375,7 +2395,8 @@
|
||||||
{ 'command': 'blockdev-mirror',
|
{ 'command': 'blockdev-mirror',
|
||||||
'data': { '*job-id': 'str', 'device': 'str', 'target': 'str',
|
'data': { '*job-id': 'str', 'device': 'str', 'target': 'str',
|
||||||
'*replaces': 'str',
|
'*replaces': 'str',
|
||||||
@ -426,10 +426,10 @@ index beeb91952a..fb25c2b245 100644
|
|||||||
'*buf-size': 'int', '*on-source-error': 'BlockdevOnError',
|
'*buf-size': 'int', '*on-source-error': 'BlockdevOnError',
|
||||||
'*on-target-error': 'BlockdevOnError',
|
'*on-target-error': 'BlockdevOnError',
|
||||||
diff --git a/tests/unit/test-block-iothread.c b/tests/unit/test-block-iothread.c
|
diff --git a/tests/unit/test-block-iothread.c b/tests/unit/test-block-iothread.c
|
||||||
index 94718c9319..7977ac14f4 100644
|
index 8b55eccc89..f4650be8e5 100644
|
||||||
--- a/tests/unit/test-block-iothread.c
|
--- a/tests/unit/test-block-iothread.c
|
||||||
+++ b/tests/unit/test-block-iothread.c
|
+++ b/tests/unit/test-block-iothread.c
|
||||||
@@ -626,8 +626,8 @@ static void test_propagate_mirror(void)
|
@@ -753,8 +753,8 @@ static void test_propagate_mirror(void)
|
||||||
|
|
||||||
/* Start a mirror job */
|
/* Start a mirror job */
|
||||||
mirror_start("job0", src, target, NULL, JOB_DEFAULT, 0, 0, 0,
|
mirror_start("job0", src, target, NULL, JOB_DEFAULT, 0, 0, 0,
|
||||||
|
@ -24,7 +24,7 @@ Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
|
|||||||
1 file changed, 18 insertions(+), 6 deletions(-)
|
1 file changed, 18 insertions(+), 6 deletions(-)
|
||||||
|
|
||||||
diff --git a/block/mirror.c b/block/mirror.c
|
diff --git a/block/mirror.c b/block/mirror.c
|
||||||
index d95a7d7940..2c79ee41af 100644
|
index f2eca983f1..b6475d50ad 100644
|
||||||
--- a/block/mirror.c
|
--- a/block/mirror.c
|
||||||
+++ b/block/mirror.c
|
+++ b/block/mirror.c
|
||||||
@@ -673,8 +673,6 @@ static int mirror_exit_common(Job *job)
|
@@ -673,8 +673,6 @@ static int mirror_exit_common(Job *job)
|
||||||
|
@ -16,7 +16,7 @@ Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
|
|||||||
1 file changed, 3 insertions(+)
|
1 file changed, 3 insertions(+)
|
||||||
|
|
||||||
diff --git a/blockdev.c b/blockdev.c
|
diff --git a/blockdev.c b/blockdev.c
|
||||||
index fa601838a3..93fd0a61a4 100644
|
index 9a1a3118ed..a57b0af2e7 100644
|
||||||
--- a/blockdev.c
|
--- a/blockdev.c
|
||||||
+++ b/blockdev.c
|
+++ b/blockdev.c
|
||||||
@@ -3050,6 +3050,9 @@ static void blockdev_mirror_common(const char *job_id, BlockDriverState *bs,
|
@@ -3050,6 +3050,9 @@ static void blockdev_mirror_common(const char *job_id, BlockDriverState *bs,
|
||||||
|
@ -16,7 +16,7 @@ Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
|
|||||||
1 file changed, 4 insertions(+), 7 deletions(-)
|
1 file changed, 4 insertions(+), 7 deletions(-)
|
||||||
|
|
||||||
diff --git a/block/mirror.c b/block/mirror.c
|
diff --git a/block/mirror.c b/block/mirror.c
|
||||||
index 2c79ee41af..e04a3ea6f4 100644
|
index b6475d50ad..8b3342f9ec 100644
|
||||||
--- a/block/mirror.c
|
--- a/block/mirror.c
|
||||||
+++ b/block/mirror.c
|
+++ b/block/mirror.c
|
||||||
@@ -779,8 +779,8 @@ static int mirror_exit_common(Job *job)
|
@@ -779,8 +779,8 @@ static int mirror_exit_common(Job *job)
|
||||||
|
@ -19,7 +19,7 @@ Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
|
|||||||
3 files changed, 70 insertions(+), 59 deletions(-)
|
3 files changed, 70 insertions(+), 59 deletions(-)
|
||||||
|
|
||||||
diff --git a/block/mirror.c b/block/mirror.c
|
diff --git a/block/mirror.c b/block/mirror.c
|
||||||
index e04a3ea6f4..4feec2a002 100644
|
index 8b3342f9ec..1d4ff0efad 100644
|
||||||
--- a/block/mirror.c
|
--- a/block/mirror.c
|
||||||
+++ b/block/mirror.c
|
+++ b/block/mirror.c
|
||||||
@@ -1634,31 +1634,13 @@ static BlockJob *mirror_start_job(
|
@@ -1634,31 +1634,13 @@ static BlockJob *mirror_start_job(
|
||||||
@ -60,7 +60,7 @@ index e04a3ea6f4..4feec2a002 100644
|
|||||||
|
|
||||||
if (bitmap_mode != BITMAP_SYNC_MODE_NEVER) {
|
if (bitmap_mode != BITMAP_SYNC_MODE_NEVER) {
|
||||||
diff --git a/blockdev.c b/blockdev.c
|
diff --git a/blockdev.c b/blockdev.c
|
||||||
index 93fd0a61a4..1af5a1fcb2 100644
|
index a57b0af2e7..ce62a9b439 100644
|
||||||
--- a/blockdev.c
|
--- a/blockdev.c
|
||||||
+++ b/blockdev.c
|
+++ b/blockdev.c
|
||||||
@@ -3029,7 +3029,36 @@ static void blockdev_mirror_common(const char *job_id, BlockDriverState *bs,
|
@@ -3029,7 +3029,36 @@ static void blockdev_mirror_common(const char *job_id, BlockDriverState *bs,
|
||||||
|
@ -48,7 +48,7 @@ Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
|
|||||||
6 files changed, 59 insertions(+), 5 deletions(-)
|
6 files changed, 59 insertions(+), 5 deletions(-)
|
||||||
|
|
||||||
diff --git a/include/monitor/monitor.h b/include/monitor/monitor.h
|
diff --git a/include/monitor/monitor.h b/include/monitor/monitor.h
|
||||||
index cc4cc6c6ad..82f649d9ab 100644
|
index a4b40e8391..d64ae8f34e 100644
|
||||||
--- a/include/monitor/monitor.h
|
--- a/include/monitor/monitor.h
|
||||||
+++ b/include/monitor/monitor.h
|
+++ b/include/monitor/monitor.h
|
||||||
@@ -16,6 +16,7 @@ extern QemuOptsList qemu_mon_opts;
|
@@ -16,6 +16,7 @@ extern QemuOptsList qemu_mon_opts;
|
||||||
@ -78,7 +78,7 @@ index caa2e90ef2..e1596f79ab 100644
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
diff --git a/monitor/monitor.c b/monitor/monitor.c
|
diff --git a/monitor/monitor.c b/monitor/monitor.c
|
||||||
index 21c7a68758..ad9813567a 100644
|
index 86949024f6..c306cadcf4 100644
|
||||||
--- a/monitor/monitor.c
|
--- a/monitor/monitor.c
|
||||||
+++ b/monitor/monitor.c
|
+++ b/monitor/monitor.c
|
||||||
@@ -135,6 +135,21 @@ bool monitor_cur_is_qmp(void)
|
@@ -135,6 +135,21 @@ bool monitor_cur_is_qmp(void)
|
||||||
@ -189,10 +189,10 @@ index 0990873ec8..e605003771 100644
|
|||||||
aio_bh_schedule_oneshot(qemu_get_aio_context(), do_qmp_dispatch_bh,
|
aio_bh_schedule_oneshot(qemu_get_aio_context(), do_qmp_dispatch_bh,
|
||||||
&data);
|
&data);
|
||||||
diff --git a/stubs/monitor-core.c b/stubs/monitor-core.c
|
diff --git a/stubs/monitor-core.c b/stubs/monitor-core.c
|
||||||
index d058a2a00d..3290b58120 100644
|
index afa477aae6..d3ff124bf3 100644
|
||||||
--- a/stubs/monitor-core.c
|
--- a/stubs/monitor-core.c
|
||||||
+++ b/stubs/monitor-core.c
|
+++ b/stubs/monitor-core.c
|
||||||
@@ -13,6 +13,11 @@ Monitor *monitor_set_cur(Coroutine *co, Monitor *mon)
|
@@ -12,6 +12,11 @@ Monitor *monitor_set_cur(Coroutine *co, Monitor *mon)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,47 +0,0 @@
|
|||||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Fabian Ebner <f.ebner@proxmox.com>
|
|
||||||
Date: Fri, 20 May 2022 09:59:22 +0200
|
|
||||||
Subject: [PATCH] block/gluster: correctly set max_pdiscard
|
|
||||||
|
|
||||||
On 64-bit platforms, assigning SIZE_MAX to the int64_t max_pdiscard
|
|
||||||
results in a negative value, and the following assertion would trigger
|
|
||||||
down the line (it's not the same max_pdiscard, but computed from the
|
|
||||||
other one):
|
|
||||||
qemu-system-x86_64: ../block/io.c:3166: bdrv_co_pdiscard: Assertion
|
|
||||||
`max_pdiscard >= bs->bl.request_alignment' failed.
|
|
||||||
|
|
||||||
On 32-bit platforms, it's fine to keep using SIZE_MAX.
|
|
||||||
|
|
||||||
The assertion in qemu_gluster_co_pdiscard() is checking that the value
|
|
||||||
of 'bytes' can safely be passed to glfs_discard_async(), which takes a
|
|
||||||
size_t for the argument in question, so it is kept as is. And since
|
|
||||||
max_pdiscard is still <= SIZE_MAX, relying on max_pdiscard is still
|
|
||||||
fine.
|
|
||||||
|
|
||||||
Fixes: 0c8022876f ("block: use int64_t instead of int in driver discard handlers")
|
|
||||||
Cc: qemu-stable@nongnu.org
|
|
||||||
Signed-off-by: Fabian Ebner <f.ebner@proxmox.com>
|
|
||||||
Message-Id: <20220520075922.43972-1-f.ebner@proxmox.com>
|
|
||||||
Reviewed-by: Eric Blake <eblake@redhat.com>
|
|
||||||
Reviewed-by: Stefano Garzarella <sgarzare@redhat.com>
|
|
||||||
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
|
|
||||||
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
|
||||||
(cherry-picked from commit 9b38fc56c054c7de65fa3bf7cdd82b32654f6b7d)
|
|
||||||
Signed-off-by: Fabian Ebner <f.ebner@proxmox.com>
|
|
||||||
---
|
|
||||||
block/gluster.c | 2 +-
|
|
||||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/block/gluster.c b/block/gluster.c
|
|
||||||
index 80b75cb96c..1079b6186b 100644
|
|
||||||
--- a/block/gluster.c
|
|
||||||
+++ b/block/gluster.c
|
|
||||||
@@ -901,7 +901,7 @@ out:
|
|
||||||
static void qemu_gluster_refresh_limits(BlockDriverState *bs, Error **errp)
|
|
||||||
{
|
|
||||||
bs->bl.max_transfer = GLUSTER_MAX_TRANSFER;
|
|
||||||
- bs->bl.max_pdiscard = SIZE_MAX;
|
|
||||||
+ bs->bl.max_pdiscard = MIN(SIZE_MAX, INT64_MAX);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int qemu_gluster_reopen_prepare(BDRVReopenState *state,
|
|
@ -1,129 +0,0 @@
|
|||||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Hanna Reitz <hreitz@redhat.com>
|
|
||||||
Date: Mon, 14 Mar 2022 17:27:18 +0100
|
|
||||||
Subject: [PATCH] block/vmdk: Fix reopening bs->file
|
|
||||||
|
|
||||||
VMDK disk data is stored in extents, which may or may not be separate
|
|
||||||
from bs->file. VmdkExtent.file points to where they are stored. Each
|
|
||||||
that is stored in bs->file will simply reuse the exact pointer value of
|
|
||||||
bs->file.
|
|
||||||
|
|
||||||
(That is why vmdk_free_extents() will unref VmdkExtent.file (e->file)
|
|
||||||
only if e->file != bs->file.)
|
|
||||||
|
|
||||||
Reopen operations can change bs->file (they will replace the whole
|
|
||||||
BdrvChild object, not just the BDS stored in that BdrvChild), and then
|
|
||||||
we will need to change all .file pointers of all such VmdkExtents to
|
|
||||||
point to the new BdrvChild.
|
|
||||||
|
|
||||||
In vmdk_reopen_prepare(), we have to check which VmdkExtents are
|
|
||||||
affected, and in vmdk_reopen_commit(), we can modify them. We have to
|
|
||||||
split this because:
|
|
||||||
- The new BdrvChild is created only after prepare, so we can change
|
|
||||||
VmdkExtent.file only in commit
|
|
||||||
- In commit, there no longer is any (valid) reference to the old
|
|
||||||
BdrvChild object, so there would be nothing to compare VmdkExtent.file
|
|
||||||
against to see whether it was equal to bs->file before reopening
|
|
||||||
(There is BDRVReopenState.old_file_bs, but the old bs->file
|
|
||||||
BdrvChild's .bs pointer will be NULL-ed when the new BdrvChild is
|
|
||||||
created, and so we cannot compare VmdkExtent.file->bs against
|
|
||||||
BDRVReopenState.old_file_bs)
|
|
||||||
|
|
||||||
Signed-off-by: Hanna Reitz <hreitz@redhat.com>
|
|
||||||
Message-Id: <20220314162719.65384-2-hreitz@redhat.com>
|
|
||||||
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
|
||||||
(cherry-picked from commit 6d17e2879854d7d0e623c06a9286085e97bf3545)
|
|
||||||
Signed-off-by: Fabian Ebner <f.ebner@proxmox.com>
|
|
||||||
---
|
|
||||||
block/vmdk.c | 56 +++++++++++++++++++++++++++++++++++++++++++++++++++-
|
|
||||||
1 file changed, 55 insertions(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/block/vmdk.c b/block/vmdk.c
|
|
||||||
index 37c0946066..38e5ab3806 100644
|
|
||||||
--- a/block/vmdk.c
|
|
||||||
+++ b/block/vmdk.c
|
|
||||||
@@ -178,6 +178,10 @@ typedef struct BDRVVmdkState {
|
|
||||||
char *create_type;
|
|
||||||
} BDRVVmdkState;
|
|
||||||
|
|
||||||
+typedef struct BDRVVmdkReopenState {
|
|
||||||
+ bool *extents_using_bs_file;
|
|
||||||
+} BDRVVmdkReopenState;
|
|
||||||
+
|
|
||||||
typedef struct VmdkMetaData {
|
|
||||||
unsigned int l1_index;
|
|
||||||
unsigned int l2_index;
|
|
||||||
@@ -400,15 +404,63 @@ static int vmdk_is_cid_valid(BlockDriverState *bs)
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
-/* We have nothing to do for VMDK reopen, stubs just return success */
|
|
||||||
static int vmdk_reopen_prepare(BDRVReopenState *state,
|
|
||||||
BlockReopenQueue *queue, Error **errp)
|
|
||||||
{
|
|
||||||
+ BDRVVmdkState *s;
|
|
||||||
+ BDRVVmdkReopenState *rs;
|
|
||||||
+ int i;
|
|
||||||
+
|
|
||||||
assert(state != NULL);
|
|
||||||
assert(state->bs != NULL);
|
|
||||||
+ assert(state->opaque == NULL);
|
|
||||||
+
|
|
||||||
+ s = state->bs->opaque;
|
|
||||||
+
|
|
||||||
+ rs = g_new0(BDRVVmdkReopenState, 1);
|
|
||||||
+ state->opaque = rs;
|
|
||||||
+
|
|
||||||
+ /*
|
|
||||||
+ * Check whether there are any extents stored in bs->file; if bs->file
|
|
||||||
+ * changes, we will need to update their .file pointers to follow suit
|
|
||||||
+ */
|
|
||||||
+ rs->extents_using_bs_file = g_new(bool, s->num_extents);
|
|
||||||
+ for (i = 0; i < s->num_extents; i++) {
|
|
||||||
+ rs->extents_using_bs_file[i] = s->extents[i].file == state->bs->file;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
+static void vmdk_reopen_clean(BDRVReopenState *state)
|
|
||||||
+{
|
|
||||||
+ BDRVVmdkReopenState *rs = state->opaque;
|
|
||||||
+
|
|
||||||
+ g_free(rs->extents_using_bs_file);
|
|
||||||
+ g_free(rs);
|
|
||||||
+ state->opaque = NULL;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static void vmdk_reopen_commit(BDRVReopenState *state)
|
|
||||||
+{
|
|
||||||
+ BDRVVmdkState *s = state->bs->opaque;
|
|
||||||
+ BDRVVmdkReopenState *rs = state->opaque;
|
|
||||||
+ int i;
|
|
||||||
+
|
|
||||||
+ for (i = 0; i < s->num_extents; i++) {
|
|
||||||
+ if (rs->extents_using_bs_file[i]) {
|
|
||||||
+ s->extents[i].file = state->bs->file;
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ vmdk_reopen_clean(state);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static void vmdk_reopen_abort(BDRVReopenState *state)
|
|
||||||
+{
|
|
||||||
+ vmdk_reopen_clean(state);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
static int vmdk_parent_open(BlockDriverState *bs)
|
|
||||||
{
|
|
||||||
char *p_name;
|
|
||||||
@@ -3072,6 +3124,8 @@ static BlockDriver bdrv_vmdk = {
|
|
||||||
.bdrv_open = vmdk_open,
|
|
||||||
.bdrv_co_check = vmdk_co_check,
|
|
||||||
.bdrv_reopen_prepare = vmdk_reopen_prepare,
|
|
||||||
+ .bdrv_reopen_commit = vmdk_reopen_commit,
|
|
||||||
+ .bdrv_reopen_abort = vmdk_reopen_abort,
|
|
||||||
.bdrv_child_perm = bdrv_default_perms,
|
|
||||||
.bdrv_co_preadv = vmdk_co_preadv,
|
|
||||||
.bdrv_co_pwritev = vmdk_co_pwritev,
|
|
@ -1,44 +0,0 @@
|
|||||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Stefan Hajnoczi <stefanha@redhat.com>
|
|
||||||
Date: Thu, 9 Jun 2022 17:47:11 +0100
|
|
||||||
Subject: [PATCH] linux-aio: fix unbalanced plugged counter in laio_io_unplug()
|
|
||||||
|
|
||||||
Every laio_io_plug() call has a matching laio_io_unplug() call. There is
|
|
||||||
a plugged counter that tracks the number of levels of plugging and
|
|
||||||
allows for nesting.
|
|
||||||
|
|
||||||
The plugged counter must reflect the balance between laio_io_plug() and
|
|
||||||
laio_io_unplug() calls accurately. Otherwise I/O stalls occur since
|
|
||||||
io_submit(2) calls are skipped while plugged.
|
|
||||||
|
|
||||||
Reported-by: Nikolay Tenev <nt@storpool.com>
|
|
||||||
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
|
|
||||||
Reviewed-by: Stefano Garzarella <sgarzare@redhat.com>
|
|
||||||
Message-id: 20220609164712.1539045-2-stefanha@redhat.com
|
|
||||||
Cc: Stefano Garzarella <sgarzare@redhat.com>
|
|
||||||
Fixes: 68d7946648 ("linux-aio: add `dev_max_batch` parameter to laio_io_unplug()")
|
|
||||||
[Stefano Garzarella suggested adding a Fixes tag.
|
|
||||||
--Stefan]
|
|
||||||
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
|
|
||||||
(cherry-picked from commit f387cac5af030a58ac5a0dacf64cab5e5a4fe5c7)
|
|
||||||
Signed-off-by: Fabian Ebner <f.ebner@proxmox.com>
|
|
||||||
---
|
|
||||||
block/linux-aio.c | 4 +++-
|
|
||||||
1 file changed, 3 insertions(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/block/linux-aio.c b/block/linux-aio.c
|
|
||||||
index 4c423fcccf..6078da7e42 100644
|
|
||||||
--- a/block/linux-aio.c
|
|
||||||
+++ b/block/linux-aio.c
|
|
||||||
@@ -363,8 +363,10 @@ void laio_io_unplug(BlockDriverState *bs, LinuxAioState *s,
|
|
||||||
uint64_t dev_max_batch)
|
|
||||||
{
|
|
||||||
assert(s->io_q.plugged);
|
|
||||||
+ s->io_q.plugged--;
|
|
||||||
+
|
|
||||||
if (s->io_q.in_queue >= laio_max_batch(s, dev_max_batch) ||
|
|
||||||
- (--s->io_q.plugged == 0 &&
|
|
||||||
+ (!s->io_q.plugged &&
|
|
||||||
!s->io_q.blocked && !QSIMPLEQ_EMPTY(&s->io_q.pending))) {
|
|
||||||
ioq_submit(s);
|
|
||||||
}
|
|
@ -1,100 +0,0 @@
|
|||||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Claudio Fontana <cfontana@suse.de>
|
|
||||||
Date: Tue, 31 May 2022 13:47:07 +0200
|
|
||||||
Subject: [PATCH] pci: fix overflow in snprintf string formatting
|
|
||||||
MIME-Version: 1.0
|
|
||||||
Content-Type: text/plain; charset=UTF-8
|
|
||||||
Content-Transfer-Encoding: 8bit
|
|
||||||
|
|
||||||
the code in pcibus_get_fw_dev_path contained the potential for a
|
|
||||||
stack buffer overflow of 1 byte, potentially writing to the stack an
|
|
||||||
extra NUL byte.
|
|
||||||
|
|
||||||
This overflow could happen if the PCI slot is >= 0x10000000,
|
|
||||||
and the PCI function is >= 0x10000000, due to the size parameter
|
|
||||||
of snprintf being incorrectly calculated in the call:
|
|
||||||
|
|
||||||
if (PCI_FUNC(d->devfn))
|
|
||||||
snprintf(path + off, sizeof(path) + off, ",%x", PCI_FUNC(d->devfn));
|
|
||||||
|
|
||||||
since the off obtained from a previous call to snprintf is added
|
|
||||||
instead of subtracted from the total available size of the buffer.
|
|
||||||
|
|
||||||
Without the accurate size guard from snprintf, we end up writing in the
|
|
||||||
worst case:
|
|
||||||
|
|
||||||
name (32) + "@" (1) + SLOT (8) + "," (1) + FUNC (8) + term NUL (1) = 51 bytes
|
|
||||||
|
|
||||||
In order to provide something more robust, replace all of the code in
|
|
||||||
pcibus_get_fw_dev_path with a single call to g_strdup_printf,
|
|
||||||
so there is no need to rely on manual calculations.
|
|
||||||
|
|
||||||
Found by compiling QEMU with FORTIFY_SOURCE=3 as the error:
|
|
||||||
|
|
||||||
*** buffer overflow detected ***: terminated
|
|
||||||
|
|
||||||
Thread 1 "qemu-system-x86" received signal SIGABRT, Aborted.
|
|
||||||
[Switching to Thread 0x7ffff642c380 (LWP 121307)]
|
|
||||||
0x00007ffff71ff55c in __pthread_kill_implementation () from /lib64/libc.so.6
|
|
||||||
(gdb) bt
|
|
||||||
#0 0x00007ffff71ff55c in __pthread_kill_implementation () at /lib64/libc.so.6
|
|
||||||
#1 0x00007ffff71ac6f6 in raise () at /lib64/libc.so.6
|
|
||||||
#2 0x00007ffff7195814 in abort () at /lib64/libc.so.6
|
|
||||||
#3 0x00007ffff71f279e in __libc_message () at /lib64/libc.so.6
|
|
||||||
#4 0x00007ffff729767a in __fortify_fail () at /lib64/libc.so.6
|
|
||||||
#5 0x00007ffff7295c36 in () at /lib64/libc.so.6
|
|
||||||
#6 0x00007ffff72957f5 in __snprintf_chk () at /lib64/libc.so.6
|
|
||||||
#7 0x0000555555b1c1fd in pcibus_get_fw_dev_path ()
|
|
||||||
#8 0x0000555555f2bde4 in qdev_get_fw_dev_path_helper.constprop ()
|
|
||||||
#9 0x0000555555f2bd86 in qdev_get_fw_dev_path_helper.constprop ()
|
|
||||||
#10 0x00005555559a6e5d in get_boot_device_path ()
|
|
||||||
#11 0x00005555559a712c in get_boot_devices_list ()
|
|
||||||
#12 0x0000555555b1a3d0 in fw_cfg_machine_reset ()
|
|
||||||
#13 0x0000555555bf4c2d in pc_machine_reset ()
|
|
||||||
#14 0x0000555555c66988 in qemu_system_reset ()
|
|
||||||
#15 0x0000555555a6dff6 in qdev_machine_creation_done ()
|
|
||||||
#16 0x0000555555c79186 in qmp_x_exit_preconfig.part ()
|
|
||||||
#17 0x0000555555c7b459 in qemu_init ()
|
|
||||||
#18 0x0000555555960a29 in main ()
|
|
||||||
|
|
||||||
Found-by: Dario Faggioli <Dario Faggioli <dfaggioli@suse.com>
|
|
||||||
Found-by: Martin Liška <martin.liska@suse.com>
|
|
||||||
Cc: qemu-stable@nongnu.org
|
|
||||||
Signed-off-by: Claudio Fontana <cfontana@suse.de>
|
|
||||||
Message-Id: <20220531114707.18830-1-cfontana@suse.de>
|
|
||||||
Reviewed-by: Ani Sinha <ani@anisinha.ca>
|
|
||||||
(cherry-picked from commit 36f18c6989a3d1ff1d7a0e50b0868ef3958299b4)
|
|
||||||
Signed-off-by: Fabian Ebner <f.ebner@proxmox.com>
|
|
||||||
---
|
|
||||||
hw/pci/pci.c | 18 +++++++++---------
|
|
||||||
1 file changed, 9 insertions(+), 9 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/hw/pci/pci.c b/hw/pci/pci.c
|
|
||||||
index dae9119bfe..c69b412434 100644
|
|
||||||
--- a/hw/pci/pci.c
|
|
||||||
+++ b/hw/pci/pci.c
|
|
||||||
@@ -2625,15 +2625,15 @@ static char *pci_dev_fw_name(DeviceState *dev, char *buf, int len)
|
|
||||||
static char *pcibus_get_fw_dev_path(DeviceState *dev)
|
|
||||||
{
|
|
||||||
PCIDevice *d = (PCIDevice *)dev;
|
|
||||||
- char path[50], name[33];
|
|
||||||
- int off;
|
|
||||||
-
|
|
||||||
- off = snprintf(path, sizeof(path), "%s@%x",
|
|
||||||
- pci_dev_fw_name(dev, name, sizeof name),
|
|
||||||
- PCI_SLOT(d->devfn));
|
|
||||||
- if (PCI_FUNC(d->devfn))
|
|
||||||
- snprintf(path + off, sizeof(path) + off, ",%x", PCI_FUNC(d->devfn));
|
|
||||||
- return g_strdup(path);
|
|
||||||
+ char name[33];
|
|
||||||
+ int has_func = !!PCI_FUNC(d->devfn);
|
|
||||||
+
|
|
||||||
+ return g_strdup_printf("%s@%x%s%.*x",
|
|
||||||
+ pci_dev_fw_name(dev, name, sizeof(name)),
|
|
||||||
+ PCI_SLOT(d->devfn),
|
|
||||||
+ has_func ? "," : "",
|
|
||||||
+ has_func,
|
|
||||||
+ PCI_FUNC(d->devfn));
|
|
||||||
}
|
|
||||||
|
|
||||||
static char *pcibus_get_dev_path(DeviceState *dev)
|
|
@ -1,48 +0,0 @@
|
|||||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
||||||
From: "Maciej S. Szmigiero" <maciej.szmigiero@oracle.com>
|
|
||||||
Date: Mon, 23 May 2022 18:26:58 +0200
|
|
||||||
Subject: [PATCH] target/i386/kvm: Fix disabling MPX on "-cpu host" with
|
|
||||||
MPX-capable host
|
|
||||||
|
|
||||||
Since KVM commit 5f76f6f5ff96 ("KVM: nVMX: Do not expose MPX VMX controls when guest MPX disabled")
|
|
||||||
it is not possible to disable MPX on a "-cpu host" just by adding "-mpx"
|
|
||||||
there if the host CPU does indeed support MPX.
|
|
||||||
QEMU will fail to set MSR_IA32_VMX_TRUE_{EXIT,ENTRY}_CTLS MSRs in this case
|
|
||||||
and so trigger an assertion failure.
|
|
||||||
|
|
||||||
Instead, besides "-mpx" one has to explicitly add also
|
|
||||||
"-vmx-exit-clear-bndcfgs" and "-vmx-entry-load-bndcfgs" to QEMU command
|
|
||||||
line to make it work, which is a bit convoluted.
|
|
||||||
|
|
||||||
Make the MPX-related bits in FEAT_VMX_{EXIT,ENTRY}_CTLS dependent on MPX
|
|
||||||
being actually enabled so such workarounds are no longer necessary.
|
|
||||||
|
|
||||||
Signed-off-by: Maciej S. Szmigiero <maciej.szmigiero@oracle.com>
|
|
||||||
Message-Id: <51aa2125c76363204cc23c27165e778097c33f0b.1653323077.git.maciej.szmigiero@oracle.com>
|
|
||||||
Cc: qemu-stable@nongnu.org
|
|
||||||
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
|
||||||
(cherry-picked from commit 267b5e7e378afd260004cb37a66a6fcd641e3b53)
|
|
||||||
Signed-off-by: Fabian Ebner <f.ebner@proxmox.com>
|
|
||||||
---
|
|
||||||
target/i386/cpu.c | 8 ++++++++
|
|
||||||
1 file changed, 8 insertions(+)
|
|
||||||
|
|
||||||
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
|
|
||||||
index cb6b5467d0..6e6945139b 100644
|
|
||||||
--- a/target/i386/cpu.c
|
|
||||||
+++ b/target/i386/cpu.c
|
|
||||||
@@ -1327,6 +1327,14 @@ static FeatureDep feature_dependencies[] = {
|
|
||||||
.from = { FEAT_7_0_EBX, CPUID_7_0_EBX_INVPCID },
|
|
||||||
.to = { FEAT_VMX_SECONDARY_CTLS, VMX_SECONDARY_EXEC_ENABLE_INVPCID },
|
|
||||||
},
|
|
||||||
+ {
|
|
||||||
+ .from = { FEAT_7_0_EBX, CPUID_7_0_EBX_MPX },
|
|
||||||
+ .to = { FEAT_VMX_EXIT_CTLS, VMX_VM_EXIT_CLEAR_BNDCFGS },
|
|
||||||
+ },
|
|
||||||
+ {
|
|
||||||
+ .from = { FEAT_7_0_EBX, CPUID_7_0_EBX_MPX },
|
|
||||||
+ .to = { FEAT_VMX_ENTRY_CTLS, VMX_VM_ENTRY_LOAD_BNDCFGS },
|
|
||||||
+ },
|
|
||||||
{
|
|
||||||
.from = { FEAT_7_0_EBX, CPUID_7_0_EBX_RDSEED },
|
|
||||||
.to = { FEAT_VMX_SECONDARY_CTLS, VMX_SECONDARY_EXEC_RDSEED_EXITING },
|
|
@ -1,121 +0,0 @@
|
|||||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Stefan Hajnoczi <stefanha@redhat.com>
|
|
||||||
Date: Mon, 7 Mar 2022 15:38:51 +0000
|
|
||||||
Subject: [PATCH] coroutine-ucontext: use QEMU_DEFINE_STATIC_CO_TLS()
|
|
||||||
MIME-Version: 1.0
|
|
||||||
Content-Type: text/plain; charset=UTF-8
|
|
||||||
Content-Transfer-Encoding: 8bit
|
|
||||||
|
|
||||||
Thread-Local Storage variables cannot be used directly from coroutine
|
|
||||||
code because the compiler may optimize TLS variable accesses across
|
|
||||||
qemu_coroutine_yield() calls. When the coroutine is re-entered from
|
|
||||||
another thread the TLS variables from the old thread must no longer be
|
|
||||||
used.
|
|
||||||
|
|
||||||
Use QEMU_DEFINE_STATIC_CO_TLS() for the current and leader variables.
|
|
||||||
|
|
||||||
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
|
|
||||||
Message-Id: <20220307153853.602859-2-stefanha@redhat.com>
|
|
||||||
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
|
|
||||||
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
|
||||||
(cherry-picked from commit 34145a307d849d0b6734d0222a7aa0bb9eef7407)
|
|
||||||
Signed-off-by: Fabian Ebner <f.ebner@proxmox.com>
|
|
||||||
---
|
|
||||||
util/coroutine-ucontext.c | 38 ++++++++++++++++++++++++--------------
|
|
||||||
1 file changed, 24 insertions(+), 14 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/util/coroutine-ucontext.c b/util/coroutine-ucontext.c
|
|
||||||
index 904b375192..127d5a13c8 100644
|
|
||||||
--- a/util/coroutine-ucontext.c
|
|
||||||
+++ b/util/coroutine-ucontext.c
|
|
||||||
@@ -25,6 +25,7 @@
|
|
||||||
#include "qemu/osdep.h"
|
|
||||||
#include <ucontext.h>
|
|
||||||
#include "qemu/coroutine_int.h"
|
|
||||||
+#include "qemu/coroutine-tls.h"
|
|
||||||
|
|
||||||
#ifdef CONFIG_VALGRIND_H
|
|
||||||
#include <valgrind/valgrind.h>
|
|
||||||
@@ -66,8 +67,8 @@ typedef struct {
|
|
||||||
/**
|
|
||||||
* Per-thread coroutine bookkeeping
|
|
||||||
*/
|
|
||||||
-static __thread CoroutineUContext leader;
|
|
||||||
-static __thread Coroutine *current;
|
|
||||||
+QEMU_DEFINE_STATIC_CO_TLS(Coroutine *, current);
|
|
||||||
+QEMU_DEFINE_STATIC_CO_TLS(CoroutineUContext, leader);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* va_args to makecontext() must be type 'int', so passing
|
|
||||||
@@ -97,14 +98,15 @@ static inline __attribute__((always_inline))
|
|
||||||
void finish_switch_fiber(void *fake_stack_save)
|
|
||||||
{
|
|
||||||
#ifdef CONFIG_ASAN
|
|
||||||
+ CoroutineUContext *leaderp = get_ptr_leader();
|
|
||||||
const void *bottom_old;
|
|
||||||
size_t size_old;
|
|
||||||
|
|
||||||
__sanitizer_finish_switch_fiber(fake_stack_save, &bottom_old, &size_old);
|
|
||||||
|
|
||||||
- if (!leader.stack) {
|
|
||||||
- leader.stack = (void *)bottom_old;
|
|
||||||
- leader.stack_size = size_old;
|
|
||||||
+ if (!leaderp->stack) {
|
|
||||||
+ leaderp->stack = (void *)bottom_old;
|
|
||||||
+ leaderp->stack_size = size_old;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#ifdef CONFIG_TSAN
|
|
||||||
@@ -161,8 +163,10 @@ static void coroutine_trampoline(int i0, int i1)
|
|
||||||
|
|
||||||
/* Initialize longjmp environment and switch back the caller */
|
|
||||||
if (!sigsetjmp(self->env, 0)) {
|
|
||||||
- start_switch_fiber_asan(COROUTINE_YIELD, &fake_stack_save, leader.stack,
|
|
||||||
- leader.stack_size);
|
|
||||||
+ CoroutineUContext *leaderp = get_ptr_leader();
|
|
||||||
+
|
|
||||||
+ start_switch_fiber_asan(COROUTINE_YIELD, &fake_stack_save,
|
|
||||||
+ leaderp->stack, leaderp->stack_size);
|
|
||||||
start_switch_fiber_tsan(&fake_stack_save, self, true); /* true=caller */
|
|
||||||
siglongjmp(*(sigjmp_buf *)co->entry_arg, 1);
|
|
||||||
}
|
|
||||||
@@ -297,7 +301,7 @@ qemu_coroutine_switch(Coroutine *from_, Coroutine *to_,
|
|
||||||
int ret;
|
|
||||||
void *fake_stack_save = NULL;
|
|
||||||
|
|
||||||
- current = to_;
|
|
||||||
+ set_current(to_);
|
|
||||||
|
|
||||||
ret = sigsetjmp(from->env, 0);
|
|
||||||
if (ret == 0) {
|
|
||||||
@@ -315,18 +319,24 @@ qemu_coroutine_switch(Coroutine *from_, Coroutine *to_,
|
|
||||||
|
|
||||||
Coroutine *qemu_coroutine_self(void)
|
|
||||||
{
|
|
||||||
- if (!current) {
|
|
||||||
- current = &leader.base;
|
|
||||||
+ Coroutine *self = get_current();
|
|
||||||
+ CoroutineUContext *leaderp = get_ptr_leader();
|
|
||||||
+
|
|
||||||
+ if (!self) {
|
|
||||||
+ self = &leaderp->base;
|
|
||||||
+ set_current(self);
|
|
||||||
}
|
|
||||||
#ifdef CONFIG_TSAN
|
|
||||||
- if (!leader.tsan_co_fiber) {
|
|
||||||
- leader.tsan_co_fiber = __tsan_get_current_fiber();
|
|
||||||
+ if (!leaderp->tsan_co_fiber) {
|
|
||||||
+ leaderp->tsan_co_fiber = __tsan_get_current_fiber();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
- return current;
|
|
||||||
+ return self;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool qemu_in_coroutine(void)
|
|
||||||
{
|
|
||||||
- return current && current->caller;
|
|
||||||
+ Coroutine *self = get_current();
|
|
||||||
+
|
|
||||||
+ return self && self->caller;
|
|
||||||
}
|
|
@ -1,123 +0,0 @@
|
|||||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Stefan Hajnoczi <stefanha@redhat.com>
|
|
||||||
Date: Mon, 7 Mar 2022 15:38:52 +0000
|
|
||||||
Subject: [PATCH] coroutine: use QEMU_DEFINE_STATIC_CO_TLS()
|
|
||||||
MIME-Version: 1.0
|
|
||||||
Content-Type: text/plain; charset=UTF-8
|
|
||||||
Content-Transfer-Encoding: 8bit
|
|
||||||
|
|
||||||
Thread-Local Storage variables cannot be used directly from coroutine
|
|
||||||
code because the compiler may optimize TLS variable accesses across
|
|
||||||
qemu_coroutine_yield() calls. When the coroutine is re-entered from
|
|
||||||
another thread the TLS variables from the old thread must no longer be
|
|
||||||
used.
|
|
||||||
|
|
||||||
Use QEMU_DEFINE_STATIC_CO_TLS() for the current and leader variables.
|
|
||||||
The alloc_pool QSLIST needs a typedef so the return value of
|
|
||||||
get_ptr_alloc_pool() can be stored in a local variable.
|
|
||||||
|
|
||||||
One example of why this code is necessary: a coroutine that yields
|
|
||||||
before calling qemu_coroutine_create() to create another coroutine is
|
|
||||||
affected by the TLS issue.
|
|
||||||
|
|
||||||
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
|
|
||||||
Message-Id: <20220307153853.602859-3-stefanha@redhat.com>
|
|
||||||
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
|
|
||||||
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
|
||||||
(cherry-picked from commit ac387a08a9c9f6b36757da912f0339c25f421f90)
|
|
||||||
Signed-off-by: Fabian Ebner <f.ebner@proxmox.com>
|
|
||||||
---
|
|
||||||
util/qemu-coroutine.c | 41 ++++++++++++++++++++++++-----------------
|
|
||||||
1 file changed, 24 insertions(+), 17 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/util/qemu-coroutine.c b/util/qemu-coroutine.c
|
|
||||||
index c03b2422ff..f3e8300c8d 100644
|
|
||||||
--- a/util/qemu-coroutine.c
|
|
||||||
+++ b/util/qemu-coroutine.c
|
|
||||||
@@ -18,6 +18,7 @@
|
|
||||||
#include "qemu/atomic.h"
|
|
||||||
#include "qemu/coroutine.h"
|
|
||||||
#include "qemu/coroutine_int.h"
|
|
||||||
+#include "qemu/coroutine-tls.h"
|
|
||||||
#include "block/aio.h"
|
|
||||||
|
|
||||||
/** Initial batch size is 64, and is increased on demand */
|
|
||||||
@@ -29,17 +30,20 @@ enum {
|
|
||||||
static QSLIST_HEAD(, Coroutine) release_pool = QSLIST_HEAD_INITIALIZER(pool);
|
|
||||||
static unsigned int pool_batch_size = POOL_INITIAL_BATCH_SIZE;
|
|
||||||
static unsigned int release_pool_size;
|
|
||||||
-static __thread QSLIST_HEAD(, Coroutine) alloc_pool = QSLIST_HEAD_INITIALIZER(pool);
|
|
||||||
-static __thread unsigned int alloc_pool_size;
|
|
||||||
-static __thread Notifier coroutine_pool_cleanup_notifier;
|
|
||||||
+
|
|
||||||
+typedef QSLIST_HEAD(, Coroutine) CoroutineQSList;
|
|
||||||
+QEMU_DEFINE_STATIC_CO_TLS(CoroutineQSList, alloc_pool);
|
|
||||||
+QEMU_DEFINE_STATIC_CO_TLS(unsigned int, alloc_pool_size);
|
|
||||||
+QEMU_DEFINE_STATIC_CO_TLS(Notifier, coroutine_pool_cleanup_notifier);
|
|
||||||
|
|
||||||
static void coroutine_pool_cleanup(Notifier *n, void *value)
|
|
||||||
{
|
|
||||||
Coroutine *co;
|
|
||||||
Coroutine *tmp;
|
|
||||||
+ CoroutineQSList *alloc_pool = get_ptr_alloc_pool();
|
|
||||||
|
|
||||||
- QSLIST_FOREACH_SAFE(co, &alloc_pool, pool_next, tmp) {
|
|
||||||
- QSLIST_REMOVE_HEAD(&alloc_pool, pool_next);
|
|
||||||
+ QSLIST_FOREACH_SAFE(co, alloc_pool, pool_next, tmp) {
|
|
||||||
+ QSLIST_REMOVE_HEAD(alloc_pool, pool_next);
|
|
||||||
qemu_coroutine_delete(co);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -49,27 +53,30 @@ Coroutine *qemu_coroutine_create(CoroutineEntry *entry, void *opaque)
|
|
||||||
Coroutine *co = NULL;
|
|
||||||
|
|
||||||
if (CONFIG_COROUTINE_POOL) {
|
|
||||||
- co = QSLIST_FIRST(&alloc_pool);
|
|
||||||
+ CoroutineQSList *alloc_pool = get_ptr_alloc_pool();
|
|
||||||
+
|
|
||||||
+ co = QSLIST_FIRST(alloc_pool);
|
|
||||||
if (!co) {
|
|
||||||
if (release_pool_size > qatomic_read(&pool_batch_size)) {
|
|
||||||
/* Slow path; a good place to register the destructor, too. */
|
|
||||||
- if (!coroutine_pool_cleanup_notifier.notify) {
|
|
||||||
- coroutine_pool_cleanup_notifier.notify = coroutine_pool_cleanup;
|
|
||||||
- qemu_thread_atexit_add(&coroutine_pool_cleanup_notifier);
|
|
||||||
+ Notifier *notifier = get_ptr_coroutine_pool_cleanup_notifier();
|
|
||||||
+ if (!notifier->notify) {
|
|
||||||
+ notifier->notify = coroutine_pool_cleanup;
|
|
||||||
+ qemu_thread_atexit_add(notifier);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* This is not exact; there could be a little skew between
|
|
||||||
* release_pool_size and the actual size of release_pool. But
|
|
||||||
* it is just a heuristic, it does not need to be perfect.
|
|
||||||
*/
|
|
||||||
- alloc_pool_size = qatomic_xchg(&release_pool_size, 0);
|
|
||||||
- QSLIST_MOVE_ATOMIC(&alloc_pool, &release_pool);
|
|
||||||
- co = QSLIST_FIRST(&alloc_pool);
|
|
||||||
+ set_alloc_pool_size(qatomic_xchg(&release_pool_size, 0));
|
|
||||||
+ QSLIST_MOVE_ATOMIC(alloc_pool, &release_pool);
|
|
||||||
+ co = QSLIST_FIRST(alloc_pool);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (co) {
|
|
||||||
- QSLIST_REMOVE_HEAD(&alloc_pool, pool_next);
|
|
||||||
- alloc_pool_size--;
|
|
||||||
+ QSLIST_REMOVE_HEAD(alloc_pool, pool_next);
|
|
||||||
+ set_alloc_pool_size(get_alloc_pool_size() - 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -93,9 +100,9 @@ static void coroutine_delete(Coroutine *co)
|
|
||||||
qatomic_inc(&release_pool_size);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
- if (alloc_pool_size < qatomic_read(&pool_batch_size)) {
|
|
||||||
- QSLIST_INSERT_HEAD(&alloc_pool, co, pool_next);
|
|
||||||
- alloc_pool_size++;
|
|
||||||
+ if (get_alloc_pool_size() < qatomic_read(&pool_batch_size)) {
|
|
||||||
+ QSLIST_INSERT_HEAD(get_ptr_alloc_pool(), co, pool_next);
|
|
||||||
+ set_alloc_pool_size(get_alloc_pool_size() + 1);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,90 +0,0 @@
|
|||||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Kevin Wolf <kwolf@redhat.com>
|
|
||||||
Date: Tue, 10 May 2022 17:10:19 +0200
|
|
||||||
Subject: [PATCH] coroutine: Rename qemu_coroutine_inc/dec_pool_size()
|
|
||||||
|
|
||||||
It's true that these functions currently affect the batch size in which
|
|
||||||
coroutines are reused (i.e. moved from the global release pool to the
|
|
||||||
allocation pool of a specific thread), but this is a bug and will be
|
|
||||||
fixed in a separate patch.
|
|
||||||
|
|
||||||
In fact, the comment in the header file already just promises that it
|
|
||||||
influences the pool size, so reflect this in the name of the functions.
|
|
||||||
As a nice side effect, the shorter function name makes some line
|
|
||||||
wrapping unnecessary.
|
|
||||||
|
|
||||||
Cc: qemu-stable@nongnu.org
|
|
||||||
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
|
||||||
Message-Id: <20220510151020.105528-2-kwolf@redhat.com>
|
|
||||||
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
|
||||||
(cherry-picked from commit 98e3ab35054b946f7c2aba5408822532b0920b53)
|
|
||||||
Signed-off-by: Fabian Ebner <f.ebner@proxmox.com>
|
|
||||||
---
|
|
||||||
hw/block/virtio-blk.c | 6 ++----
|
|
||||||
include/qemu/coroutine.h | 6 +++---
|
|
||||||
util/qemu-coroutine.c | 4 ++--
|
|
||||||
3 files changed, 7 insertions(+), 9 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c
|
|
||||||
index 540c38f829..6a1cc41877 100644
|
|
||||||
--- a/hw/block/virtio-blk.c
|
|
||||||
+++ b/hw/block/virtio-blk.c
|
|
||||||
@@ -1215,8 +1215,7 @@ static void virtio_blk_device_realize(DeviceState *dev, Error **errp)
|
|
||||||
for (i = 0; i < conf->num_queues; i++) {
|
|
||||||
virtio_add_queue(vdev, conf->queue_size, virtio_blk_handle_output);
|
|
||||||
}
|
|
||||||
- qemu_coroutine_increase_pool_batch_size(conf->num_queues * conf->queue_size
|
|
||||||
- / 2);
|
|
||||||
+ qemu_coroutine_inc_pool_size(conf->num_queues * conf->queue_size / 2);
|
|
||||||
virtio_blk_data_plane_create(vdev, conf, &s->dataplane, &err);
|
|
||||||
if (err != NULL) {
|
|
||||||
error_propagate(errp, err);
|
|
||||||
@@ -1253,8 +1252,7 @@ static void virtio_blk_device_unrealize(DeviceState *dev)
|
|
||||||
for (i = 0; i < conf->num_queues; i++) {
|
|
||||||
virtio_del_queue(vdev, i);
|
|
||||||
}
|
|
||||||
- qemu_coroutine_decrease_pool_batch_size(conf->num_queues * conf->queue_size
|
|
||||||
- / 2);
|
|
||||||
+ qemu_coroutine_dec_pool_size(conf->num_queues * conf->queue_size / 2);
|
|
||||||
qemu_del_vm_change_state_handler(s->change);
|
|
||||||
blockdev_mark_auto_del(s->blk);
|
|
||||||
virtio_cleanup(vdev);
|
|
||||||
diff --git a/include/qemu/coroutine.h b/include/qemu/coroutine.h
|
|
||||||
index c828a95ee0..5b621d1295 100644
|
|
||||||
--- a/include/qemu/coroutine.h
|
|
||||||
+++ b/include/qemu/coroutine.h
|
|
||||||
@@ -334,12 +334,12 @@ void coroutine_fn yield_until_fd_readable(int fd);
|
|
||||||
/**
|
|
||||||
* Increase coroutine pool size
|
|
||||||
*/
|
|
||||||
-void qemu_coroutine_increase_pool_batch_size(unsigned int additional_pool_size);
|
|
||||||
+void qemu_coroutine_inc_pool_size(unsigned int additional_pool_size);
|
|
||||||
|
|
||||||
/**
|
|
||||||
- * Devcrease coroutine pool size
|
|
||||||
+ * Decrease coroutine pool size
|
|
||||||
*/
|
|
||||||
-void qemu_coroutine_decrease_pool_batch_size(unsigned int additional_pool_size);
|
|
||||||
+void qemu_coroutine_dec_pool_size(unsigned int additional_pool_size);
|
|
||||||
|
|
||||||
#include "qemu/lockable.h"
|
|
||||||
|
|
||||||
diff --git a/util/qemu-coroutine.c b/util/qemu-coroutine.c
|
|
||||||
index f3e8300c8d..ea23929a74 100644
|
|
||||||
--- a/util/qemu-coroutine.c
|
|
||||||
+++ b/util/qemu-coroutine.c
|
|
||||||
@@ -212,12 +212,12 @@ AioContext *coroutine_fn qemu_coroutine_get_aio_context(Coroutine *co)
|
|
||||||
return co->ctx;
|
|
||||||
}
|
|
||||||
|
|
||||||
-void qemu_coroutine_increase_pool_batch_size(unsigned int additional_pool_size)
|
|
||||||
+void qemu_coroutine_inc_pool_size(unsigned int additional_pool_size)
|
|
||||||
{
|
|
||||||
qatomic_add(&pool_batch_size, additional_pool_size);
|
|
||||||
}
|
|
||||||
|
|
||||||
-void qemu_coroutine_decrease_pool_batch_size(unsigned int removing_pool_size)
|
|
||||||
+void qemu_coroutine_dec_pool_size(unsigned int removing_pool_size)
|
|
||||||
{
|
|
||||||
qatomic_sub(&pool_batch_size, removing_pool_size);
|
|
||||||
}
|
|
@ -1,121 +0,0 @@
|
|||||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Kevin Wolf <kwolf@redhat.com>
|
|
||||||
Date: Tue, 10 May 2022 17:10:20 +0200
|
|
||||||
Subject: [PATCH] coroutine: Revert to constant batch size
|
|
||||||
|
|
||||||
Commit 4c41c69e changed the way the coroutine pool is sized because for
|
|
||||||
virtio-blk devices with a large queue size and heavy I/O, it was just
|
|
||||||
too small and caused coroutines to be deleted and reallocated soon
|
|
||||||
afterwards. The change made the size dynamic based on the number of
|
|
||||||
queues and the queue size of virtio-blk devices.
|
|
||||||
|
|
||||||
There are two important numbers here: Slightly simplified, when a
|
|
||||||
coroutine terminates, it is generally stored in the global release pool
|
|
||||||
up to a certain pool size, and if the pool is full, it is freed.
|
|
||||||
Conversely, when allocating a new coroutine, the coroutines in the
|
|
||||||
release pool are reused if the pool already has reached a certain
|
|
||||||
minimum size (the batch size), otherwise we allocate new coroutines.
|
|
||||||
|
|
||||||
The problem after commit 4c41c69e is that it not only increases the
|
|
||||||
maximum pool size (which is the intended effect), but also the batch
|
|
||||||
size for reusing coroutines (which is a bug). It means that in cases
|
|
||||||
with many devices and/or a large queue size (which defaults to the
|
|
||||||
number of vcpus for virtio-blk-pci), many thousand coroutines could be
|
|
||||||
sitting in the release pool without being reused.
|
|
||||||
|
|
||||||
This is not only a waste of memory and allocations, but it actually
|
|
||||||
makes the QEMU process likely to hit the vm.max_map_count limit on Linux
|
|
||||||
because each coroutine requires two mappings (its stack and the guard
|
|
||||||
page for the stack), causing it to abort() in qemu_alloc_stack() because
|
|
||||||
when the limit is hit, mprotect() starts to fail with ENOMEM.
|
|
||||||
|
|
||||||
In order to fix the problem, change the batch size back to 64 to avoid
|
|
||||||
uselessly accumulating coroutines in the release pool, but keep the
|
|
||||||
dynamic maximum pool size so that coroutines aren't freed too early
|
|
||||||
in heavy I/O scenarios.
|
|
||||||
|
|
||||||
Note that this fix doesn't strictly make it impossible to hit the limit,
|
|
||||||
but this would only happen if most of the coroutines are actually in use
|
|
||||||
at the same time, not just sitting in a pool. This is the same behaviour
|
|
||||||
as we already had before commit 4c41c69e. Fully preventing this would
|
|
||||||
require allowing qemu_coroutine_create() to return an error, but it
|
|
||||||
doesn't seem to be a scenario that people hit in practice.
|
|
||||||
|
|
||||||
Cc: qemu-stable@nongnu.org
|
|
||||||
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2079938
|
|
||||||
Fixes: 4c41c69e05fe28c0f95f8abd2ebf407e95a4f04b
|
|
||||||
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
|
||||||
Message-Id: <20220510151020.105528-3-kwolf@redhat.com>
|
|
||||||
Tested-by: Hiroki Narukawa <hnarukaw@yahoo-corp.jp>
|
|
||||||
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
|
||||||
(cherry-picked from commit 9ec7a59b5aad4b736871c378d30f5ef5ec51cb52)
|
|
||||||
Signed-off-by: Fabian Ebner <f.ebner@proxmox.com>
|
|
||||||
---
|
|
||||||
util/qemu-coroutine.c | 22 ++++++++++++++--------
|
|
||||||
1 file changed, 14 insertions(+), 8 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/util/qemu-coroutine.c b/util/qemu-coroutine.c
|
|
||||||
index ea23929a74..4a8bd63ef0 100644
|
|
||||||
--- a/util/qemu-coroutine.c
|
|
||||||
+++ b/util/qemu-coroutine.c
|
|
||||||
@@ -21,14 +21,20 @@
|
|
||||||
#include "qemu/coroutine-tls.h"
|
|
||||||
#include "block/aio.h"
|
|
||||||
|
|
||||||
-/** Initial batch size is 64, and is increased on demand */
|
|
||||||
+/**
|
|
||||||
+ * The minimal batch size is always 64, coroutines from the release_pool are
|
|
||||||
+ * reused as soon as there are 64 coroutines in it. The maximum pool size starts
|
|
||||||
+ * with 64 and is increased on demand so that coroutines are not deleted even if
|
|
||||||
+ * they are not immediately reused.
|
|
||||||
+ */
|
|
||||||
enum {
|
|
||||||
- POOL_INITIAL_BATCH_SIZE = 64,
|
|
||||||
+ POOL_MIN_BATCH_SIZE = 64,
|
|
||||||
+ POOL_INITIAL_MAX_SIZE = 64,
|
|
||||||
};
|
|
||||||
|
|
||||||
/** Free list to speed up creation */
|
|
||||||
static QSLIST_HEAD(, Coroutine) release_pool = QSLIST_HEAD_INITIALIZER(pool);
|
|
||||||
-static unsigned int pool_batch_size = POOL_INITIAL_BATCH_SIZE;
|
|
||||||
+static unsigned int pool_max_size = POOL_INITIAL_MAX_SIZE;
|
|
||||||
static unsigned int release_pool_size;
|
|
||||||
|
|
||||||
typedef QSLIST_HEAD(, Coroutine) CoroutineQSList;
|
|
||||||
@@ -57,7 +63,7 @@ Coroutine *qemu_coroutine_create(CoroutineEntry *entry, void *opaque)
|
|
||||||
|
|
||||||
co = QSLIST_FIRST(alloc_pool);
|
|
||||||
if (!co) {
|
|
||||||
- if (release_pool_size > qatomic_read(&pool_batch_size)) {
|
|
||||||
+ if (release_pool_size > POOL_MIN_BATCH_SIZE) {
|
|
||||||
/* Slow path; a good place to register the destructor, too. */
|
|
||||||
Notifier *notifier = get_ptr_coroutine_pool_cleanup_notifier();
|
|
||||||
if (!notifier->notify) {
|
|
||||||
@@ -95,12 +101,12 @@ static void coroutine_delete(Coroutine *co)
|
|
||||||
co->caller = NULL;
|
|
||||||
|
|
||||||
if (CONFIG_COROUTINE_POOL) {
|
|
||||||
- if (release_pool_size < qatomic_read(&pool_batch_size) * 2) {
|
|
||||||
+ if (release_pool_size < qatomic_read(&pool_max_size) * 2) {
|
|
||||||
QSLIST_INSERT_HEAD_ATOMIC(&release_pool, co, pool_next);
|
|
||||||
qatomic_inc(&release_pool_size);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
- if (get_alloc_pool_size() < qatomic_read(&pool_batch_size)) {
|
|
||||||
+ if (get_alloc_pool_size() < qatomic_read(&pool_max_size)) {
|
|
||||||
QSLIST_INSERT_HEAD(get_ptr_alloc_pool(), co, pool_next);
|
|
||||||
set_alloc_pool_size(get_alloc_pool_size() + 1);
|
|
||||||
return;
|
|
||||||
@@ -214,10 +220,10 @@ AioContext *coroutine_fn qemu_coroutine_get_aio_context(Coroutine *co)
|
|
||||||
|
|
||||||
void qemu_coroutine_inc_pool_size(unsigned int additional_pool_size)
|
|
||||||
{
|
|
||||||
- qatomic_add(&pool_batch_size, additional_pool_size);
|
|
||||||
+ qatomic_add(&pool_max_size, additional_pool_size);
|
|
||||||
}
|
|
||||||
|
|
||||||
void qemu_coroutine_dec_pool_size(unsigned int removing_pool_size)
|
|
||||||
{
|
|
||||||
- qatomic_sub(&pool_batch_size, removing_pool_size);
|
|
||||||
+ qatomic_sub(&pool_max_size, removing_pool_size);
|
|
||||||
}
|
|
@ -1,117 +0,0 @@
|
|||||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Paolo Bonzini <pbonzini@redhat.com>
|
|
||||||
Date: Fri, 29 Apr 2022 21:16:28 +0200
|
|
||||||
Subject: [PATCH] target/i386: do not consult nonexistent host leaves
|
|
||||||
|
|
||||||
When cache_info_passthrough is requested, QEMU passes the host values
|
|
||||||
of the cache information CPUID leaves down to the guest. However,
|
|
||||||
it blindly assumes that the CPUID leaf exists on the host, and this
|
|
||||||
cannot be guaranteed: for example, KVM has recently started to
|
|
||||||
synthesize AMD leaves up to 0x80000021 in order to provide accurate
|
|
||||||
CPU bug information to guests.
|
|
||||||
|
|
||||||
Querying a nonexistent host leaf fills the output arguments of
|
|
||||||
host_cpuid with data that (albeit deterministic) is nonsensical
|
|
||||||
as cache information, namely the data in the highest Intel CPUID
|
|
||||||
leaf. If said highest leaf is not ECX-dependent, this can even
|
|
||||||
cause an infinite loop when kvm_arch_init_vcpu prepares the input
|
|
||||||
to KVM_SET_CPUID2. The infinite loop is only terminated by an
|
|
||||||
abort() when the array gets full.
|
|
||||||
|
|
||||||
Reported-by: Maxim Levitsky <mlevitsk@redhat.com>
|
|
||||||
Reviewed-by: Maxim Levitsky <mlevitsk@redhat.com>
|
|
||||||
Cc: qemu-stable@nongnu.org
|
|
||||||
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
|
||||||
(cherry-picked from commit 798d8ec0dacd4cc0034298d94f430c14f23e2919)
|
|
||||||
Signed-off-by: Fabian Ebner <f.ebner@proxmox.com>
|
|
||||||
---
|
|
||||||
target/i386/cpu.c | 41 ++++++++++++++++++++++++++++++++++++-----
|
|
||||||
1 file changed, 36 insertions(+), 5 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
|
|
||||||
index 6e6945139b..c79e151887 100644
|
|
||||||
--- a/target/i386/cpu.c
|
|
||||||
+++ b/target/i386/cpu.c
|
|
||||||
@@ -5030,6 +5030,37 @@ uint64_t x86_cpu_get_supported_feature_word(FeatureWord w,
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
+static void x86_cpu_get_cache_cpuid(uint32_t func, uint32_t index,
|
|
||||||
+ uint32_t *eax, uint32_t *ebx,
|
|
||||||
+ uint32_t *ecx, uint32_t *edx)
|
|
||||||
+{
|
|
||||||
+ uint32_t level, unused;
|
|
||||||
+
|
|
||||||
+ /* Only return valid host leaves. */
|
|
||||||
+ switch (func) {
|
|
||||||
+ case 2:
|
|
||||||
+ case 4:
|
|
||||||
+ host_cpuid(0, 0, &level, &unused, &unused, &unused);
|
|
||||||
+ break;
|
|
||||||
+ case 0x80000005:
|
|
||||||
+ case 0x80000006:
|
|
||||||
+ case 0x8000001d:
|
|
||||||
+ host_cpuid(0x80000000, 0, &level, &unused, &unused, &unused);
|
|
||||||
+ break;
|
|
||||||
+ default:
|
|
||||||
+ return;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ if (func > level) {
|
|
||||||
+ *eax = 0;
|
|
||||||
+ *ebx = 0;
|
|
||||||
+ *ecx = 0;
|
|
||||||
+ *edx = 0;
|
|
||||||
+ } else {
|
|
||||||
+ host_cpuid(func, index, eax, ebx, ecx, edx);
|
|
||||||
+ }
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
/*
|
|
||||||
* Only for builtin_x86_defs models initialized with x86_register_cpudef_types.
|
|
||||||
*/
|
|
||||||
@@ -5288,7 +5319,7 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
|
|
||||||
case 2:
|
|
||||||
/* cache info: needed for Pentium Pro compatibility */
|
|
||||||
if (cpu->cache_info_passthrough) {
|
|
||||||
- host_cpuid(index, 0, eax, ebx, ecx, edx);
|
|
||||||
+ x86_cpu_get_cache_cpuid(index, 0, eax, ebx, ecx, edx);
|
|
||||||
break;
|
|
||||||
} else if (cpu->vendor_cpuid_only && IS_AMD_CPU(env)) {
|
|
||||||
*eax = *ebx = *ecx = *edx = 0;
|
|
||||||
@@ -5308,7 +5339,7 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
|
|
||||||
case 4:
|
|
||||||
/* cache info: needed for Core compatibility */
|
|
||||||
if (cpu->cache_info_passthrough) {
|
|
||||||
- host_cpuid(index, count, eax, ebx, ecx, edx);
|
|
||||||
+ x86_cpu_get_cache_cpuid(index, count, eax, ebx, ecx, edx);
|
|
||||||
/* QEMU gives out its own APIC IDs, never pass down bits 31..26. */
|
|
||||||
*eax &= ~0xFC000000;
|
|
||||||
if ((*eax & 31) && cs->nr_cores > 1) {
|
|
||||||
@@ -5710,7 +5741,7 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
|
|
||||||
case 0x80000005:
|
|
||||||
/* cache info (L1 cache) */
|
|
||||||
if (cpu->cache_info_passthrough) {
|
|
||||||
- host_cpuid(index, 0, eax, ebx, ecx, edx);
|
|
||||||
+ x86_cpu_get_cache_cpuid(index, 0, eax, ebx, ecx, edx);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
*eax = (L1_DTLB_2M_ASSOC << 24) | (L1_DTLB_2M_ENTRIES << 16) |
|
|
||||||
@@ -5723,7 +5754,7 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
|
|
||||||
case 0x80000006:
|
|
||||||
/* cache info (L2 cache) */
|
|
||||||
if (cpu->cache_info_passthrough) {
|
|
||||||
- host_cpuid(index, 0, eax, ebx, ecx, edx);
|
|
||||||
+ x86_cpu_get_cache_cpuid(index, 0, eax, ebx, ecx, edx);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
*eax = (AMD_ENC_ASSOC(L2_DTLB_2M_ASSOC) << 28) |
|
|
||||||
@@ -5783,7 +5814,7 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
|
|
||||||
case 0x8000001D:
|
|
||||||
*eax = 0;
|
|
||||||
if (cpu->cache_info_passthrough) {
|
|
||||||
- host_cpuid(index, count, eax, ebx, ecx, edx);
|
|
||||||
+ x86_cpu_get_cache_cpuid(index, count, eax, ebx, ecx, edx);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
switch (count) {
|
|
@ -1,108 +0,0 @@
|
|||||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Stefan Hajnoczi <stefanha@redhat.com>
|
|
||||||
Date: Wed, 27 Apr 2022 15:35:36 +0100
|
|
||||||
Subject: [PATCH] virtio-scsi: fix ctrl and event handler functions in
|
|
||||||
dataplane mode
|
|
||||||
|
|
||||||
Commit f34e8d8b8d48d73f36a67b6d5e492ef9784b5012 ("virtio-scsi: prepare
|
|
||||||
virtio_scsi_handle_cmd for dataplane") prepared the virtio-scsi cmd
|
|
||||||
virtqueue handler function to be used in both the dataplane and
|
|
||||||
non-datpalane code paths.
|
|
||||||
|
|
||||||
It failed to convert the ctrl and event virtqueue handler functions,
|
|
||||||
which are not designed to be called from the dataplane code path but
|
|
||||||
will be since the ioeventfd is set up for those virtqueues when
|
|
||||||
dataplane starts.
|
|
||||||
|
|
||||||
Convert the ctrl and event virtqueue handler functions now so they
|
|
||||||
operate correctly when called from the dataplane code path. Avoid code
|
|
||||||
duplication by extracting this code into a helper function.
|
|
||||||
|
|
||||||
Fixes: f34e8d8b8d48d73f36a67b6d5e492ef9784b5012 ("virtio-scsi: prepare virtio_scsi_handle_cmd for dataplane")
|
|
||||||
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
|
|
||||||
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
|
|
||||||
Message-id: 20220427143541.119567-2-stefanha@redhat.com
|
|
||||||
[Fixed s/by used/be used/ typo pointed out by Michael Tokarev
|
|
||||||
<mjt@tls.msk.ru>.
|
|
||||||
--Stefan]
|
|
||||||
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
|
|
||||||
(cherry-picked from commit 2f743ef6366c2df4ef51ef3ae318138cdc0125ab)
|
|
||||||
Signed-off-by: Fabian Ebner <f.ebner@proxmox.com>
|
|
||||||
---
|
|
||||||
hw/scsi/virtio-scsi.c | 42 +++++++++++++++++++++++++++---------------
|
|
||||||
1 file changed, 27 insertions(+), 15 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/hw/scsi/virtio-scsi.c b/hw/scsi/virtio-scsi.c
|
|
||||||
index 34a968ecfb..417fbc71d6 100644
|
|
||||||
--- a/hw/scsi/virtio-scsi.c
|
|
||||||
+++ b/hw/scsi/virtio-scsi.c
|
|
||||||
@@ -472,16 +472,32 @@ bool virtio_scsi_handle_ctrl_vq(VirtIOSCSI *s, VirtQueue *vq)
|
|
||||||
return progress;
|
|
||||||
}
|
|
||||||
|
|
||||||
+/*
|
|
||||||
+ * If dataplane is configured but not yet started, do so now and return true on
|
|
||||||
+ * success.
|
|
||||||
+ *
|
|
||||||
+ * Dataplane is started by the core virtio code but virtqueue handler functions
|
|
||||||
+ * can also be invoked when a guest kicks before DRIVER_OK, so this helper
|
|
||||||
+ * function helps us deal with manually starting ioeventfd in that case.
|
|
||||||
+ */
|
|
||||||
+static bool virtio_scsi_defer_to_dataplane(VirtIOSCSI *s)
|
|
||||||
+{
|
|
||||||
+ if (!s->ctx || s->dataplane_started) {
|
|
||||||
+ return false;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ virtio_device_start_ioeventfd(&s->parent_obj.parent_obj);
|
|
||||||
+ return !s->dataplane_fenced;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
static void virtio_scsi_handle_ctrl(VirtIODevice *vdev, VirtQueue *vq)
|
|
||||||
{
|
|
||||||
VirtIOSCSI *s = (VirtIOSCSI *)vdev;
|
|
||||||
|
|
||||||
- if (s->ctx) {
|
|
||||||
- virtio_device_start_ioeventfd(vdev);
|
|
||||||
- if (!s->dataplane_fenced) {
|
|
||||||
- return;
|
|
||||||
- }
|
|
||||||
+ if (virtio_scsi_defer_to_dataplane(s)) {
|
|
||||||
+ return;
|
|
||||||
}
|
|
||||||
+
|
|
||||||
virtio_scsi_acquire(s);
|
|
||||||
virtio_scsi_handle_ctrl_vq(s, vq);
|
|
||||||
virtio_scsi_release(s);
|
|
||||||
@@ -720,12 +736,10 @@ static void virtio_scsi_handle_cmd(VirtIODevice *vdev, VirtQueue *vq)
|
|
||||||
/* use non-QOM casts in the data path */
|
|
||||||
VirtIOSCSI *s = (VirtIOSCSI *)vdev;
|
|
||||||
|
|
||||||
- if (s->ctx && !s->dataplane_started) {
|
|
||||||
- virtio_device_start_ioeventfd(vdev);
|
|
||||||
- if (!s->dataplane_fenced) {
|
|
||||||
- return;
|
|
||||||
- }
|
|
||||||
+ if (virtio_scsi_defer_to_dataplane(s)) {
|
|
||||||
+ return;
|
|
||||||
}
|
|
||||||
+
|
|
||||||
virtio_scsi_acquire(s);
|
|
||||||
virtio_scsi_handle_cmd_vq(s, vq);
|
|
||||||
virtio_scsi_release(s);
|
|
||||||
@@ -855,12 +869,10 @@ static void virtio_scsi_handle_event(VirtIODevice *vdev, VirtQueue *vq)
|
|
||||||
{
|
|
||||||
VirtIOSCSI *s = VIRTIO_SCSI(vdev);
|
|
||||||
|
|
||||||
- if (s->ctx) {
|
|
||||||
- virtio_device_start_ioeventfd(vdev);
|
|
||||||
- if (!s->dataplane_fenced) {
|
|
||||||
- return;
|
|
||||||
- }
|
|
||||||
+ if (virtio_scsi_defer_to_dataplane(s)) {
|
|
||||||
+ return;
|
|
||||||
}
|
|
||||||
+
|
|
||||||
virtio_scsi_acquire(s);
|
|
||||||
virtio_scsi_handle_event_vq(s, vq);
|
|
||||||
virtio_scsi_release(s);
|
|
@ -1,91 +0,0 @@
|
|||||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Stefan Hajnoczi <stefanha@redhat.com>
|
|
||||||
Date: Wed, 27 Apr 2022 15:35:37 +0100
|
|
||||||
Subject: [PATCH] virtio-scsi: don't waste CPU polling the event virtqueue
|
|
||||||
|
|
||||||
The virtio-scsi event virtqueue is not emptied by its handler function.
|
|
||||||
This is typical for rx virtqueues where the device uses buffers when
|
|
||||||
some event occurs (e.g. a packet is received, an error condition
|
|
||||||
happens, etc).
|
|
||||||
|
|
||||||
Polling non-empty virtqueues wastes CPU cycles. We are not waiting for
|
|
||||||
new buffers to become available, we are waiting for an event to occur,
|
|
||||||
so it's a misuse of CPU resources to poll for buffers.
|
|
||||||
|
|
||||||
Introduce the new virtio_queue_aio_attach_host_notifier_no_poll() API,
|
|
||||||
which is identical to virtio_queue_aio_attach_host_notifier() except
|
|
||||||
that it does not poll the virtqueue.
|
|
||||||
|
|
||||||
Before this patch the following command-line consumed 100% CPU in the
|
|
||||||
IOThread polling and calling virtio_scsi_handle_event():
|
|
||||||
|
|
||||||
$ qemu-system-x86_64 -M accel=kvm -m 1G -cpu host \
|
|
||||||
--object iothread,id=iothread0 \
|
|
||||||
--device virtio-scsi-pci,iothread=iothread0 \
|
|
||||||
--blockdev file,filename=test.img,aio=native,cache.direct=on,node-name=drive0 \
|
|
||||||
--device scsi-hd,drive=drive0
|
|
||||||
|
|
||||||
After this patch CPU is no longer wasted.
|
|
||||||
|
|
||||||
Reported-by: Nir Soffer <nsoffer@redhat.com>
|
|
||||||
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
|
|
||||||
Tested-by: Nir Soffer <nsoffer@redhat.com>
|
|
||||||
Message-id: 20220427143541.119567-3-stefanha@redhat.com
|
|
||||||
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
|
|
||||||
(cherry-picked from commit 38738f7dbbda90fbc161757b7f4be35b52205552)
|
|
||||||
Signed-off-by: Fabian Ebner <f.ebner@proxmox.com>
|
|
||||||
---
|
|
||||||
hw/scsi/virtio-scsi-dataplane.c | 2 +-
|
|
||||||
hw/virtio/virtio.c | 13 +++++++++++++
|
|
||||||
include/hw/virtio/virtio.h | 1 +
|
|
||||||
3 files changed, 15 insertions(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/hw/scsi/virtio-scsi-dataplane.c b/hw/scsi/virtio-scsi-dataplane.c
|
|
||||||
index 29575cbaf6..8bb6e6acfc 100644
|
|
||||||
--- a/hw/scsi/virtio-scsi-dataplane.c
|
|
||||||
+++ b/hw/scsi/virtio-scsi-dataplane.c
|
|
||||||
@@ -138,7 +138,7 @@ int virtio_scsi_dataplane_start(VirtIODevice *vdev)
|
|
||||||
|
|
||||||
aio_context_acquire(s->ctx);
|
|
||||||
virtio_queue_aio_attach_host_notifier(vs->ctrl_vq, s->ctx);
|
|
||||||
- virtio_queue_aio_attach_host_notifier(vs->event_vq, s->ctx);
|
|
||||||
+ virtio_queue_aio_attach_host_notifier_no_poll(vs->event_vq, s->ctx);
|
|
||||||
|
|
||||||
for (i = 0; i < vs->conf.num_queues; i++) {
|
|
||||||
virtio_queue_aio_attach_host_notifier(vs->cmd_vqs[i], s->ctx);
|
|
||||||
diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
|
|
||||||
index 9d637e043e..67a873f54a 100644
|
|
||||||
--- a/hw/virtio/virtio.c
|
|
||||||
+++ b/hw/virtio/virtio.c
|
|
||||||
@@ -3534,6 +3534,19 @@ void virtio_queue_aio_attach_host_notifier(VirtQueue *vq, AioContext *ctx)
|
|
||||||
virtio_queue_host_notifier_aio_poll_end);
|
|
||||||
}
|
|
||||||
|
|
||||||
+/*
|
|
||||||
+ * Same as virtio_queue_aio_attach_host_notifier() but without polling. Use
|
|
||||||
+ * this for rx virtqueues and similar cases where the virtqueue handler
|
|
||||||
+ * function does not pop all elements. When the virtqueue is left non-empty
|
|
||||||
+ * polling consumes CPU cycles and should not be used.
|
|
||||||
+ */
|
|
||||||
+void virtio_queue_aio_attach_host_notifier_no_poll(VirtQueue *vq, AioContext *ctx)
|
|
||||||
+{
|
|
||||||
+ aio_set_event_notifier(ctx, &vq->host_notifier, true,
|
|
||||||
+ virtio_queue_host_notifier_read,
|
|
||||||
+ NULL, NULL);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
void virtio_queue_aio_detach_host_notifier(VirtQueue *vq, AioContext *ctx)
|
|
||||||
{
|
|
||||||
aio_set_event_notifier(ctx, &vq->host_notifier, true, NULL, NULL, NULL);
|
|
||||||
diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h
|
|
||||||
index b31c4507f5..b62a35fdca 100644
|
|
||||||
--- a/include/hw/virtio/virtio.h
|
|
||||||
+++ b/include/hw/virtio/virtio.h
|
|
||||||
@@ -317,6 +317,7 @@ EventNotifier *virtio_queue_get_host_notifier(VirtQueue *vq);
|
|
||||||
void virtio_queue_set_host_notifier_enabled(VirtQueue *vq, bool enabled);
|
|
||||||
void virtio_queue_host_notifier_read(EventNotifier *n);
|
|
||||||
void virtio_queue_aio_attach_host_notifier(VirtQueue *vq, AioContext *ctx);
|
|
||||||
+void virtio_queue_aio_attach_host_notifier_no_poll(VirtQueue *vq, AioContext *ctx);
|
|
||||||
void virtio_queue_aio_detach_host_notifier(VirtQueue *vq, AioContext *ctx);
|
|
||||||
VirtQueue *virtio_vector_first_queue(VirtIODevice *vdev, uint16_t vector);
|
|
||||||
VirtQueue *virtio_vector_next_queue(VirtQueue *vq);
|
|
@ -1,102 +0,0 @@
|
|||||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
||||||
From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= <eperezma@redhat.com>
|
|
||||||
Date: Thu, 12 May 2022 19:57:42 +0200
|
|
||||||
Subject: [PATCH] vhost: Track descriptor chain in private at SVQ
|
|
||||||
MIME-Version: 1.0
|
|
||||||
Content-Type: text/plain; charset=UTF-8
|
|
||||||
Content-Transfer-Encoding: 8bit
|
|
||||||
|
|
||||||
The device could have access to modify them, and it definitely have
|
|
||||||
access when we implement packed vq. Harden SVQ maintaining a private
|
|
||||||
copy of the descriptor chain. Other fields like buffer addresses are
|
|
||||||
already maintained sepparatedly.
|
|
||||||
|
|
||||||
Signed-off-by: Eugenio Pérez <eperezma@redhat.com>
|
|
||||||
Message-Id: <20220512175747.142058-2-eperezma@redhat.com>
|
|
||||||
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
|
|
||||||
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
|
|
||||||
(cherry-picked from commit 495fe3a78749c39c0e772c4e1a55d6cb8a7e5292)
|
|
||||||
Signed-off-by: Fabian Ebner <f.ebner@proxmox.com>
|
|
||||||
---
|
|
||||||
hw/virtio/vhost-shadow-virtqueue.c | 12 +++++++-----
|
|
||||||
hw/virtio/vhost-shadow-virtqueue.h | 6 ++++++
|
|
||||||
2 files changed, 13 insertions(+), 5 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/hw/virtio/vhost-shadow-virtqueue.c b/hw/virtio/vhost-shadow-virtqueue.c
|
|
||||||
index b232803d1b..3155801f50 100644
|
|
||||||
--- a/hw/virtio/vhost-shadow-virtqueue.c
|
|
||||||
+++ b/hw/virtio/vhost-shadow-virtqueue.c
|
|
||||||
@@ -138,6 +138,7 @@ static void vhost_vring_write_descs(VhostShadowVirtqueue *svq, hwaddr *sg,
|
|
||||||
for (n = 0; n < num; n++) {
|
|
||||||
if (more_descs || (n + 1 < num)) {
|
|
||||||
descs[i].flags = flags | cpu_to_le16(VRING_DESC_F_NEXT);
|
|
||||||
+ descs[i].next = cpu_to_le16(svq->desc_next[i]);
|
|
||||||
} else {
|
|
||||||
descs[i].flags = flags;
|
|
||||||
}
|
|
||||||
@@ -145,10 +146,10 @@ static void vhost_vring_write_descs(VhostShadowVirtqueue *svq, hwaddr *sg,
|
|
||||||
descs[i].len = cpu_to_le32(iovec[n].iov_len);
|
|
||||||
|
|
||||||
last = i;
|
|
||||||
- i = cpu_to_le16(descs[i].next);
|
|
||||||
+ i = cpu_to_le16(svq->desc_next[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
- svq->free_head = le16_to_cpu(descs[last].next);
|
|
||||||
+ svq->free_head = le16_to_cpu(svq->desc_next[last]);
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool vhost_svq_add_split(VhostShadowVirtqueue *svq,
|
|
||||||
@@ -336,7 +337,6 @@ static void vhost_svq_disable_notification(VhostShadowVirtqueue *svq)
|
|
||||||
static VirtQueueElement *vhost_svq_get_buf(VhostShadowVirtqueue *svq,
|
|
||||||
uint32_t *len)
|
|
||||||
{
|
|
||||||
- vring_desc_t *descs = svq->vring.desc;
|
|
||||||
const vring_used_t *used = svq->vring.used;
|
|
||||||
vring_used_elem_t used_elem;
|
|
||||||
uint16_t last_used;
|
|
||||||
@@ -365,7 +365,7 @@ static VirtQueueElement *vhost_svq_get_buf(VhostShadowVirtqueue *svq,
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
- descs[used_elem.id].next = svq->free_head;
|
|
||||||
+ svq->desc_next[used_elem.id] = svq->free_head;
|
|
||||||
svq->free_head = used_elem.id;
|
|
||||||
|
|
||||||
*len = used_elem.len;
|
|
||||||
@@ -540,8 +540,9 @@ void vhost_svq_start(VhostShadowVirtqueue *svq, VirtIODevice *vdev,
|
|
||||||
svq->vring.used = qemu_memalign(qemu_real_host_page_size, device_size);
|
|
||||||
memset(svq->vring.used, 0, device_size);
|
|
||||||
svq->ring_id_maps = g_new0(VirtQueueElement *, svq->vring.num);
|
|
||||||
+ svq->desc_next = g_new0(uint16_t, svq->vring.num);
|
|
||||||
for (unsigned i = 0; i < svq->vring.num - 1; i++) {
|
|
||||||
- svq->vring.desc[i].next = cpu_to_le16(i + 1);
|
|
||||||
+ svq->desc_next[i] = cpu_to_le16(i + 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -574,6 +575,7 @@ void vhost_svq_stop(VhostShadowVirtqueue *svq)
|
|
||||||
virtqueue_detach_element(svq->vq, next_avail_elem, 0);
|
|
||||||
}
|
|
||||||
svq->vq = NULL;
|
|
||||||
+ g_free(svq->desc_next);
|
|
||||||
g_free(svq->ring_id_maps);
|
|
||||||
qemu_vfree(svq->vring.desc);
|
|
||||||
qemu_vfree(svq->vring.used);
|
|
||||||
diff --git a/hw/virtio/vhost-shadow-virtqueue.h b/hw/virtio/vhost-shadow-virtqueue.h
|
|
||||||
index e5e24c536d..c132c994e9 100644
|
|
||||||
--- a/hw/virtio/vhost-shadow-virtqueue.h
|
|
||||||
+++ b/hw/virtio/vhost-shadow-virtqueue.h
|
|
||||||
@@ -53,6 +53,12 @@ typedef struct VhostShadowVirtqueue {
|
|
||||||
/* Next VirtQueue element that guest made available */
|
|
||||||
VirtQueueElement *next_guest_avail_elem;
|
|
||||||
|
|
||||||
+ /*
|
|
||||||
+ * Backup next field for each descriptor so we can recover securely, not
|
|
||||||
+ * needing to trust the device access.
|
|
||||||
+ */
|
|
||||||
+ uint16_t *desc_next;
|
|
||||||
+
|
|
||||||
/* Next head to expose to the device */
|
|
||||||
uint16_t shadow_avail_idx;
|
|
||||||
|
|
@ -1,62 +0,0 @@
|
|||||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
||||||
From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= <eperezma@redhat.com>
|
|
||||||
Date: Thu, 12 May 2022 19:57:43 +0200
|
|
||||||
Subject: [PATCH] vhost: Fix device's used descriptor dequeue
|
|
||||||
MIME-Version: 1.0
|
|
||||||
Content-Type: text/plain; charset=UTF-8
|
|
||||||
Content-Transfer-Encoding: 8bit
|
|
||||||
|
|
||||||
Only the first one of them were properly enqueued back.
|
|
||||||
|
|
||||||
Fixes: 100890f7ca ("vhost: Shadow virtqueue buffers forwarding")
|
|
||||||
|
|
||||||
Signed-off-by: Eugenio Pérez <eperezma@redhat.com>
|
|
||||||
Message-Id: <20220512175747.142058-3-eperezma@redhat.com>
|
|
||||||
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
|
|
||||||
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
|
|
||||||
(cherry-picked from commit 81abfa5724c9a6502d7a1d3a67c55f2a303a1170)
|
|
||||||
Signed-off-by: Fabian Ebner <f.ebner@proxmox.com>
|
|
||||||
---
|
|
||||||
hw/virtio/vhost-shadow-virtqueue.c | 17 +++++++++++++++--
|
|
||||||
1 file changed, 15 insertions(+), 2 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/hw/virtio/vhost-shadow-virtqueue.c b/hw/virtio/vhost-shadow-virtqueue.c
|
|
||||||
index 3155801f50..31fc50907d 100644
|
|
||||||
--- a/hw/virtio/vhost-shadow-virtqueue.c
|
|
||||||
+++ b/hw/virtio/vhost-shadow-virtqueue.c
|
|
||||||
@@ -334,12 +334,22 @@ static void vhost_svq_disable_notification(VhostShadowVirtqueue *svq)
|
|
||||||
svq->vring.avail->flags |= cpu_to_le16(VRING_AVAIL_F_NO_INTERRUPT);
|
|
||||||
}
|
|
||||||
|
|
||||||
+static uint16_t vhost_svq_last_desc_of_chain(const VhostShadowVirtqueue *svq,
|
|
||||||
+ uint16_t num, uint16_t i)
|
|
||||||
+{
|
|
||||||
+ for (uint16_t j = 0; j < (num - 1); ++j) {
|
|
||||||
+ i = le16_to_cpu(svq->desc_next[i]);
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ return i;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
static VirtQueueElement *vhost_svq_get_buf(VhostShadowVirtqueue *svq,
|
|
||||||
uint32_t *len)
|
|
||||||
{
|
|
||||||
const vring_used_t *used = svq->vring.used;
|
|
||||||
vring_used_elem_t used_elem;
|
|
||||||
- uint16_t last_used;
|
|
||||||
+ uint16_t last_used, last_used_chain, num;
|
|
||||||
|
|
||||||
if (!vhost_svq_more_used(svq)) {
|
|
||||||
return NULL;
|
|
||||||
@@ -365,7 +375,10 @@ static VirtQueueElement *vhost_svq_get_buf(VhostShadowVirtqueue *svq,
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
- svq->desc_next[used_elem.id] = svq->free_head;
|
|
||||||
+ num = svq->ring_id_maps[used_elem.id]->in_num +
|
|
||||||
+ svq->ring_id_maps[used_elem.id]->out_num;
|
|
||||||
+ last_used_chain = vhost_svq_last_desc_of_chain(svq, num, used_elem.id);
|
|
||||||
+ svq->desc_next[last_used_chain] = svq->free_head;
|
|
||||||
svq->free_head = used_elem.id;
|
|
||||||
|
|
||||||
*len = used_elem.len;
|
|
@ -1,39 +0,0 @@
|
|||||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
||||||
From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= <eperezma@redhat.com>
|
|
||||||
Date: Thu, 12 May 2022 19:57:44 +0200
|
|
||||||
Subject: [PATCH] vdpa: Fix bad index calculus at vhost_vdpa_get_vring_base
|
|
||||||
MIME-Version: 1.0
|
|
||||||
Content-Type: text/plain; charset=UTF-8
|
|
||||||
Content-Transfer-Encoding: 8bit
|
|
||||||
|
|
||||||
Fixes: 6d0b222666 ("vdpa: Adapt vhost_vdpa_get_vring_base to SVQ")
|
|
||||||
|
|
||||||
Acked-by: Jason Wang <jasowang@redhat.com>
|
|
||||||
Signed-off-by: Eugenio Pérez <eperezma@redhat.com>
|
|
||||||
Message-Id: <20220512175747.142058-4-eperezma@redhat.com>
|
|
||||||
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
|
|
||||||
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
|
|
||||||
(cherry-picked from commit 639036477ef890958415967e753ca2cbb348c16c)
|
|
||||||
Signed-off-by: Fabian Ebner <f.ebner@proxmox.com>
|
|
||||||
---
|
|
||||||
hw/virtio/vhost-vdpa.c | 4 ++--
|
|
||||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/hw/virtio/vhost-vdpa.c b/hw/virtio/vhost-vdpa.c
|
|
||||||
index 8adf7c0b92..8555a84f87 100644
|
|
||||||
--- a/hw/virtio/vhost-vdpa.c
|
|
||||||
+++ b/hw/virtio/vhost-vdpa.c
|
|
||||||
@@ -1170,11 +1170,11 @@ static int vhost_vdpa_get_vring_base(struct vhost_dev *dev,
|
|
||||||
struct vhost_vring_state *ring)
|
|
||||||
{
|
|
||||||
struct vhost_vdpa *v = dev->opaque;
|
|
||||||
+ int vdpa_idx = ring->index - dev->vq_index;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
if (v->shadow_vqs_enabled) {
|
|
||||||
- VhostShadowVirtqueue *svq = g_ptr_array_index(v->shadow_vqs,
|
|
||||||
- ring->index);
|
|
||||||
+ VhostShadowVirtqueue *svq = g_ptr_array_index(v->shadow_vqs, vdpa_idx);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Setting base as last used idx, so destination will see as available
|
|
@ -1,35 +0,0 @@
|
|||||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
||||||
From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= <eperezma@redhat.com>
|
|
||||||
Date: Thu, 12 May 2022 19:57:45 +0200
|
|
||||||
Subject: [PATCH] vdpa: Fix index calculus at vhost_vdpa_svqs_start
|
|
||||||
MIME-Version: 1.0
|
|
||||||
Content-Type: text/plain; charset=UTF-8
|
|
||||||
Content-Transfer-Encoding: 8bit
|
|
||||||
|
|
||||||
With the introduction of MQ the index of the vq needs to be calculated
|
|
||||||
with the device model vq_index.
|
|
||||||
|
|
||||||
Signed-off-by: Eugenio Pérez <eperezma@redhat.com>
|
|
||||||
Acked-by: Jason Wang <jasowang@redhat.com>
|
|
||||||
Message-Id: <20220512175747.142058-5-eperezma@redhat.com>
|
|
||||||
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
|
|
||||||
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
|
|
||||||
(cherry-picked from commit 1c82fdfef8a227518ffecae9d419bcada995c202)
|
|
||||||
Signed-off-by: Fabian Ebner <f.ebner@proxmox.com>
|
|
||||||
---
|
|
||||||
hw/virtio/vhost-vdpa.c | 2 +-
|
|
||||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/hw/virtio/vhost-vdpa.c b/hw/virtio/vhost-vdpa.c
|
|
||||||
index 8555a84f87..aa43cfa7d9 100644
|
|
||||||
--- a/hw/virtio/vhost-vdpa.c
|
|
||||||
+++ b/hw/virtio/vhost-vdpa.c
|
|
||||||
@@ -1016,7 +1016,7 @@ static bool vhost_vdpa_svqs_start(struct vhost_dev *dev)
|
|
||||||
VirtQueue *vq = virtio_get_queue(dev->vdev, dev->vq_index + i);
|
|
||||||
VhostShadowVirtqueue *svq = g_ptr_array_index(v->shadow_vqs, i);
|
|
||||||
struct vhost_vring_addr addr = {
|
|
||||||
- .index = i,
|
|
||||||
+ .index = dev->vq_index + i,
|
|
||||||
};
|
|
||||||
int r;
|
|
||||||
bool ok = vhost_vdpa_svq_setup(dev, svq, i, &err);
|
|
@ -1,74 +0,0 @@
|
|||||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
||||||
From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= <philmd@redhat.com>
|
|
||||||
Date: Thu, 12 May 2022 19:57:46 +0200
|
|
||||||
Subject: [PATCH] hw/virtio: Replace g_memdup() by g_memdup2()
|
|
||||||
MIME-Version: 1.0
|
|
||||||
Content-Type: text/plain; charset=UTF-8
|
|
||||||
Content-Transfer-Encoding: 8bit
|
|
||||||
|
|
||||||
Per https://discourse.gnome.org/t/port-your-module-from-g-memdup-to-g-memdup2-now/5538
|
|
||||||
|
|
||||||
The old API took the size of the memory to duplicate as a guint,
|
|
||||||
whereas most memory functions take memory sizes as a gsize. This
|
|
||||||
made it easy to accidentally pass a gsize to g_memdup(). For large
|
|
||||||
values, that would lead to a silent truncation of the size from 64
|
|
||||||
to 32 bits, and result in a heap area being returned which is
|
|
||||||
significantly smaller than what the caller expects. This can likely
|
|
||||||
be exploited in various modules to cause a heap buffer overflow.
|
|
||||||
|
|
||||||
Replace g_memdup() by the safer g_memdup2() wrapper.
|
|
||||||
|
|
||||||
Acked-by: Jason Wang <jasowang@redhat.com>
|
|
||||||
Acked-by: Eugenio Pérez <eperezma@redhat.com>
|
|
||||||
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
|
|
||||||
Message-Id: <20220512175747.142058-6-eperezma@redhat.com>
|
|
||||||
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
|
|
||||||
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
|
|
||||||
(cherry-picked from commit d792199de55ca5cb5334016884039c740290b5c7)
|
|
||||||
Signed-off-by: Fabian Ebner <f.ebner@proxmox.com>
|
|
||||||
---
|
|
||||||
hw/net/virtio-net.c | 3 ++-
|
|
||||||
hw/virtio/virtio-crypto.c | 6 +++---
|
|
||||||
2 files changed, 5 insertions(+), 4 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
|
|
||||||
index 1067e72b39..e4748a7e6c 100644
|
|
||||||
--- a/hw/net/virtio-net.c
|
|
||||||
+++ b/hw/net/virtio-net.c
|
|
||||||
@@ -1443,7 +1443,8 @@ static void virtio_net_handle_ctrl(VirtIODevice *vdev, VirtQueue *vq)
|
|
||||||
}
|
|
||||||
|
|
||||||
iov_cnt = elem->out_num;
|
|
||||||
- iov2 = iov = g_memdup(elem->out_sg, sizeof(struct iovec) * elem->out_num);
|
|
||||||
+ iov2 = iov = g_memdup2(elem->out_sg,
|
|
||||||
+ sizeof(struct iovec) * elem->out_num);
|
|
||||||
s = iov_to_buf(iov, iov_cnt, 0, &ctrl, sizeof(ctrl));
|
|
||||||
iov_discard_front(&iov, &iov_cnt, sizeof(ctrl));
|
|
||||||
if (s != sizeof(ctrl)) {
|
|
||||||
diff --git a/hw/virtio/virtio-crypto.c b/hw/virtio/virtio-crypto.c
|
|
||||||
index dcd80b904d..0e31e3cc04 100644
|
|
||||||
--- a/hw/virtio/virtio-crypto.c
|
|
||||||
+++ b/hw/virtio/virtio-crypto.c
|
|
||||||
@@ -242,7 +242,7 @@ static void virtio_crypto_handle_ctrl(VirtIODevice *vdev, VirtQueue *vq)
|
|
||||||
}
|
|
||||||
|
|
||||||
out_num = elem->out_num;
|
|
||||||
- out_iov_copy = g_memdup(elem->out_sg, sizeof(out_iov[0]) * out_num);
|
|
||||||
+ out_iov_copy = g_memdup2(elem->out_sg, sizeof(out_iov[0]) * out_num);
|
|
||||||
out_iov = out_iov_copy;
|
|
||||||
|
|
||||||
in_num = elem->in_num;
|
|
||||||
@@ -605,11 +605,11 @@ virtio_crypto_handle_request(VirtIOCryptoReq *request)
|
|
||||||
}
|
|
||||||
|
|
||||||
out_num = elem->out_num;
|
|
||||||
- out_iov_copy = g_memdup(elem->out_sg, sizeof(out_iov[0]) * out_num);
|
|
||||||
+ out_iov_copy = g_memdup2(elem->out_sg, sizeof(out_iov[0]) * out_num);
|
|
||||||
out_iov = out_iov_copy;
|
|
||||||
|
|
||||||
in_num = elem->in_num;
|
|
||||||
- in_iov_copy = g_memdup(elem->in_sg, sizeof(in_iov[0]) * in_num);
|
|
||||||
+ in_iov_copy = g_memdup2(elem->in_sg, sizeof(in_iov[0]) * in_num);
|
|
||||||
in_iov = in_iov_copy;
|
|
||||||
|
|
||||||
if (unlikely(iov_to_buf(out_iov, out_num, 0, &req, sizeof(req))
|
|
@ -1,47 +0,0 @@
|
|||||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
||||||
From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= <eperezma@redhat.com>
|
|
||||||
Date: Thu, 12 May 2022 19:57:47 +0200
|
|
||||||
Subject: [PATCH] vhost: Fix element in vhost_svq_add failure
|
|
||||||
MIME-Version: 1.0
|
|
||||||
Content-Type: text/plain; charset=UTF-8
|
|
||||||
Content-Transfer-Encoding: 8bit
|
|
||||||
|
|
||||||
Coverity rightly reports that is not free in that case.
|
|
||||||
|
|
||||||
Fixes: Coverity CID 1487559
|
|
||||||
Fixes: 100890f7ca ("vhost: Shadow virtqueue buffers forwarding")
|
|
||||||
|
|
||||||
Signed-off-by: Eugenio Pérez <eperezma@redhat.com>
|
|
||||||
Message-Id: <20220512175747.142058-7-eperezma@redhat.com>
|
|
||||||
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
|
|
||||||
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
|
|
||||||
(cherry-picked from commit 5181db132b587754dda3a520eec923b87a65bbb7)
|
|
||||||
Signed-off-by: Fabian Ebner <f.ebner@proxmox.com>
|
|
||||||
---
|
|
||||||
hw/virtio/vhost-shadow-virtqueue.c | 8 ++++++++
|
|
||||||
1 file changed, 8 insertions(+)
|
|
||||||
|
|
||||||
diff --git a/hw/virtio/vhost-shadow-virtqueue.c b/hw/virtio/vhost-shadow-virtqueue.c
|
|
||||||
index 31fc50907d..06d0bb39d9 100644
|
|
||||||
--- a/hw/virtio/vhost-shadow-virtqueue.c
|
|
||||||
+++ b/hw/virtio/vhost-shadow-virtqueue.c
|
|
||||||
@@ -199,11 +199,19 @@ static bool vhost_svq_add_split(VhostShadowVirtqueue *svq,
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
+/**
|
|
||||||
+ * Add an element to a SVQ.
|
|
||||||
+ *
|
|
||||||
+ * The caller must check that there is enough slots for the new element. It
|
|
||||||
+ * takes ownership of the element: In case of failure, it is free and the SVQ
|
|
||||||
+ * is considered broken.
|
|
||||||
+ */
|
|
||||||
static bool vhost_svq_add(VhostShadowVirtqueue *svq, VirtQueueElement *elem)
|
|
||||||
{
|
|
||||||
unsigned qemu_head;
|
|
||||||
bool ok = vhost_svq_add_split(svq, elem, &qemu_head);
|
|
||||||
if (unlikely(!ok)) {
|
|
||||||
+ g_free(elem);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
@ -1,49 +0,0 @@
|
|||||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Dominique Martinet <dominique.martinet@atmark-techno.com>
|
|
||||||
Date: Thu, 30 Jun 2022 10:01:37 +0900
|
|
||||||
Subject: [PATCH] io_uring: fix short read slow path
|
|
||||||
|
|
||||||
sqeq.off here is the offset to read within the disk image, so obviously
|
|
||||||
not 'nread' (the amount we just read), but as the author meant to write
|
|
||||||
its current value incremented by the amount we just read.
|
|
||||||
|
|
||||||
Normally recent versions of linux will not issue short reads,
|
|
||||||
but it can happen so we should fix this.
|
|
||||||
|
|
||||||
This lead to weird image corruptions when short read happened
|
|
||||||
|
|
||||||
Fixes: 6663a0a33764 ("block/io_uring: implements interfaces for io_uring")
|
|
||||||
Link: https://lkml.kernel.org/r/YrrFGO4A1jS0GI0G@atmark-techno.com
|
|
||||||
Signed-off-by: Dominique Martinet <dominique.martinet@atmark-techno.com>
|
|
||||||
Message-Id: <20220630010137.2518851-1-dominique.martinet@atmark-techno.com>
|
|
||||||
Reviewed-by: Hanna Reitz <hreitz@redhat.com>
|
|
||||||
Reviewed-by: Stefano Garzarella <sgarzare@redhat.com>
|
|
||||||
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
|
|
||||||
(cherry-picked from commit c06fc7ce147e57ab493bad9263f1601b8298484b)
|
|
||||||
Signed-off-by: Fabian Ebner <f.ebner@proxmox.com>
|
|
||||||
---
|
|
||||||
block/io_uring.c | 4 ++--
|
|
||||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/block/io_uring.c b/block/io_uring.c
|
|
||||||
index 782afdb433..e451e55de0 100644
|
|
||||||
--- a/block/io_uring.c
|
|
||||||
+++ b/block/io_uring.c
|
|
||||||
@@ -89,7 +89,7 @@ static void luring_resubmit_short_read(LuringState *s, LuringAIOCB *luringcb,
|
|
||||||
trace_luring_resubmit_short_read(s, luringcb, nread);
|
|
||||||
|
|
||||||
/* Update read position */
|
|
||||||
- luringcb->total_read = nread;
|
|
||||||
+ luringcb->total_read += nread;
|
|
||||||
remaining = luringcb->qiov->size - luringcb->total_read;
|
|
||||||
|
|
||||||
/* Shorten qiov */
|
|
||||||
@@ -103,7 +103,7 @@ static void luring_resubmit_short_read(LuringState *s, LuringAIOCB *luringcb,
|
|
||||||
remaining);
|
|
||||||
|
|
||||||
/* Update sqe */
|
|
||||||
- luringcb->sqeq.off = nread;
|
|
||||||
+ luringcb->sqeq.off += nread;
|
|
||||||
luringcb->sqeq.addr = (__u64)(uintptr_t)luringcb->resubmit_qiov.iov;
|
|
||||||
luringcb->sqeq.len = luringcb->resubmit_qiov.niov;
|
|
||||||
|
|
@ -1,82 +0,0 @@
|
|||||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Ding Hui <dinghui@sangfor.com.cn>
|
|
||||||
Date: Wed, 29 Jun 2022 17:40:26 +0800
|
|
||||||
Subject: [PATCH] e1000: set RX descriptor status in a separate operation
|
|
||||||
|
|
||||||
The code of setting RX descriptor status field maybe work fine in
|
|
||||||
previously, however with the update of glibc version, it shows two
|
|
||||||
issues when guest using dpdk receive packets:
|
|
||||||
|
|
||||||
1. The dpdk has a certain probability getting wrong buffer_addr
|
|
||||||
|
|
||||||
this impact may be not obvious, such as lost a packet once in
|
|
||||||
a while
|
|
||||||
|
|
||||||
2. The dpdk may consume a packet twice when scan the RX desc queue
|
|
||||||
over again
|
|
||||||
|
|
||||||
this impact will lead a infinite wait in Qemu, since the RDT
|
|
||||||
(tail pointer) be inscreased to equal to RDH by unexpected,
|
|
||||||
which regard as the RX desc queue is full
|
|
||||||
|
|
||||||
Write a whole of RX desc with DD flag on is not quite correct, because
|
|
||||||
when the underlying implementation of memcpy using XMM registers to
|
|
||||||
copy e1000_rx_desc (when AVX or something else CPU feature is usable),
|
|
||||||
the bytes order of desc writing to memory is indeterminacy
|
|
||||||
|
|
||||||
We can use full-scale test case to reproduce the issue-2 by
|
|
||||||
https://github.com/BASM/qemu_dpdk_e1000_test (thanks to Leonid Myravjev)
|
|
||||||
|
|
||||||
I also write a POC test case at https://github.com/cdkey/e1000_poc
|
|
||||||
which can reproduce both of them, and easy to verify the patch effect.
|
|
||||||
|
|
||||||
The hw watchpoint also shows that, when Qemu using XMM related instructions
|
|
||||||
writing 16 bytes e1000_rx_desc, concurrent with DPDK using movb
|
|
||||||
writing 1 byte status, the final result of writing to memory will be one
|
|
||||||
of them, if it made by Qemu which DD flag is on, DPDK will consume it
|
|
||||||
again.
|
|
||||||
|
|
||||||
Setting DD status in a separate operation, can prevent the impact of
|
|
||||||
disorder memory writing by memcpy, also avoid unexpected data when
|
|
||||||
concurrent writing status by qemu and guest dpdk.
|
|
||||||
|
|
||||||
Links: https://lore.kernel.org/qemu-devel/20200102110504.GG121208@stefanha-x1.localdomain/T/
|
|
||||||
|
|
||||||
Reported-by: Leonid Myravjev <asm@asm.pp.ru>
|
|
||||||
Cc: Stefan Hajnoczi <stefanha@gmail.com>
|
|
||||||
Cc: Paolo Bonzini <pbonzini@redhat.com>
|
|
||||||
Cc: Michael S. Tsirkin <mst@redhat.com>
|
|
||||||
Cc: qemu-stable@nongnu.org
|
|
||||||
Tested-by: Jing Zhang <zhangjing@sangfor.com.cn>
|
|
||||||
Reviewed-by: Frank Lee <lifan38153@sangfor.com.cn>
|
|
||||||
Signed-off-by: Ding Hui <dinghui@sangfor.com.cn>
|
|
||||||
Signed-off-by: Jason Wang <jasowang@redhat.com>
|
|
||||||
(cherry-picked from commit 034d00d4858161e1d4cff82d8d230bce874a04d3)
|
|
||||||
Signed-off-by: Fabian Ebner <f.ebner@proxmox.com>
|
|
||||||
---
|
|
||||||
hw/net/e1000.c | 5 ++++-
|
|
||||||
1 file changed, 4 insertions(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/hw/net/e1000.c b/hw/net/e1000.c
|
|
||||||
index f5bc81296d..e26e0a64c1 100644
|
|
||||||
--- a/hw/net/e1000.c
|
|
||||||
+++ b/hw/net/e1000.c
|
|
||||||
@@ -979,7 +979,7 @@ e1000_receive_iov(NetClientState *nc, const struct iovec *iov, int iovcnt)
|
|
||||||
base = rx_desc_base(s) + sizeof(desc) * s->mac_reg[RDH];
|
|
||||||
pci_dma_read(d, base, &desc, sizeof(desc));
|
|
||||||
desc.special = vlan_special;
|
|
||||||
- desc.status |= (vlan_status | E1000_RXD_STAT_DD);
|
|
||||||
+ desc.status &= ~E1000_RXD_STAT_DD;
|
|
||||||
if (desc.buffer_addr) {
|
|
||||||
if (desc_offset < size) {
|
|
||||||
size_t iov_copy;
|
|
||||||
@@ -1013,6 +1013,9 @@ e1000_receive_iov(NetClientState *nc, const struct iovec *iov, int iovcnt)
|
|
||||||
DBGOUT(RX, "Null RX descriptor!!\n");
|
|
||||||
}
|
|
||||||
pci_dma_write(d, base, &desc, sizeof(desc));
|
|
||||||
+ desc.status |= (vlan_status | E1000_RXD_STAT_DD);
|
|
||||||
+ pci_dma_write(d, base + offsetof(struct e1000_rx_desc, status),
|
|
||||||
+ &desc.status, sizeof(desc.status));
|
|
||||||
|
|
||||||
if (++s->mac_reg[RDH] * sizeof(desc) >= s->mac_reg[RDLEN])
|
|
||||||
s->mac_reg[RDH] = 0;
|
|
@ -14,10 +14,10 @@ Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
|
|||||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
diff --git a/block/file-posix.c b/block/file-posix.c
|
diff --git a/block/file-posix.c b/block/file-posix.c
|
||||||
index 39a3d6dbe6..e5bf5d59bf 100644
|
index 48cd096624..3d60b80286 100644
|
||||||
--- a/block/file-posix.c
|
--- a/block/file-posix.c
|
||||||
+++ b/block/file-posix.c
|
+++ b/block/file-posix.c
|
||||||
@@ -554,7 +554,7 @@ static QemuOptsList raw_runtime_opts = {
|
@@ -553,7 +553,7 @@ static QemuOptsList raw_runtime_opts = {
|
||||||
{
|
{
|
||||||
.name = "locking",
|
.name = "locking",
|
||||||
.type = QEMU_OPT_STRING,
|
.type = QEMU_OPT_STRING,
|
||||||
@ -26,7 +26,7 @@ index 39a3d6dbe6..e5bf5d59bf 100644
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
.name = "pr-manager",
|
.name = "pr-manager",
|
||||||
@@ -654,7 +654,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;
|
s->use_lock = false;
|
||||||
break;
|
break;
|
||||||
case ON_OFF_AUTO_AUTO:
|
case ON_OFF_AUTO_AUTO:
|
||||||
|
@ -10,10 +10,10 @@ Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
|
|||||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
diff --git a/target/i386/cpu.h b/target/i386/cpu.h
|
diff --git a/target/i386/cpu.h b/target/i386/cpu.h
|
||||||
index 982c532353..5395e7e471 100644
|
index 82004b65b9..4868db8f94 100644
|
||||||
--- a/target/i386/cpu.h
|
--- a/target/i386/cpu.h
|
||||||
+++ b/target/i386/cpu.h
|
+++ b/target/i386/cpu.h
|
||||||
@@ -2087,9 +2087,9 @@ uint64_t cpu_get_tsc(CPUX86State *env);
|
@@ -2133,9 +2133,9 @@ uint64_t cpu_get_tsc(CPUX86State *env);
|
||||||
#define CPU_RESOLVING_TYPE TYPE_X86_CPU
|
#define CPU_RESOLVING_TYPE TYPE_X86_CPU
|
||||||
|
|
||||||
#ifdef TARGET_X86_64
|
#ifdef TARGET_X86_64
|
||||||
|
@ -9,7 +9,7 @@ Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
|
|||||||
1 file changed, 11 insertions(+), 4 deletions(-)
|
1 file changed, 11 insertions(+), 4 deletions(-)
|
||||||
|
|
||||||
diff --git a/block/gluster.c b/block/gluster.c
|
diff --git a/block/gluster.c b/block/gluster.c
|
||||||
index 592e71b22a..aebfece6eb 100644
|
index b60213ab80..93da76bc31 100644
|
||||||
--- a/block/gluster.c
|
--- a/block/gluster.c
|
||||||
+++ b/block/gluster.c
|
+++ b/block/gluster.c
|
||||||
@@ -42,7 +42,7 @@
|
@@ -42,7 +42,7 @@
|
||||||
|
@ -18,7 +18,7 @@ Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
|
|||||||
1 file changed, 2 insertions(+)
|
1 file changed, 2 insertions(+)
|
||||||
|
|
||||||
diff --git a/block/rbd.c b/block/rbd.c
|
diff --git a/block/rbd.c b/block/rbd.c
|
||||||
index 6caf35cbba..0cec24c86d 100644
|
index f826410f40..64a8d7d48b 100644
|
||||||
--- a/block/rbd.c
|
--- a/block/rbd.c
|
||||||
+++ b/block/rbd.c
|
+++ b/block/rbd.c
|
||||||
@@ -820,6 +820,8 @@ static int qemu_rbd_connect(rados_t *cluster, rados_ioctx_t *io_ctx,
|
@@ -820,6 +820,8 @@ static int qemu_rbd_connect(rados_t *cluster, rados_ioctx_t *io_ctx,
|
||||||
|
@ -11,10 +11,10 @@ Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
|
|||||||
3 files changed, 43 insertions(+)
|
3 files changed, 43 insertions(+)
|
||||||
|
|
||||||
diff --git a/net/net.c b/net/net.c
|
diff --git a/net/net.c b/net/net.c
|
||||||
index f0d14dbfc1..6d476c47ef 100644
|
index 2db160e063..8329347891 100644
|
||||||
--- a/net/net.c
|
--- a/net/net.c
|
||||||
+++ b/net/net.c
|
+++ b/net/net.c
|
||||||
@@ -1334,6 +1334,33 @@ void hmp_info_network(Monitor *mon, const QDict *qdict)
|
@@ -1343,6 +1343,33 @@ void hmp_info_network(Monitor *mon, const QDict *qdict)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -49,7 +49,7 @@ index f0d14dbfc1..6d476c47ef 100644
|
|||||||
{
|
{
|
||||||
NetClientState *nc;
|
NetClientState *nc;
|
||||||
diff --git a/qapi/net.json b/qapi/net.json
|
diff --git a/qapi/net.json b/qapi/net.json
|
||||||
index b92f3f5fb4..52c7e1f82b 100644
|
index 75ba2cb989..a3c93ab88f 100644
|
||||||
--- a/qapi/net.json
|
--- a/qapi/net.json
|
||||||
+++ b/qapi/net.json
|
+++ b/qapi/net.json
|
||||||
@@ -35,6 +35,21 @@
|
@@ -35,6 +35,21 @@
|
||||||
@ -75,12 +75,12 @@ index b92f3f5fb4..52c7e1f82b 100644
|
|||||||
# @netdev_add:
|
# @netdev_add:
|
||||||
#
|
#
|
||||||
diff --git a/qapi/pragma.json b/qapi/pragma.json
|
diff --git a/qapi/pragma.json b/qapi/pragma.json
|
||||||
index e6a021c19c..41139d8645 100644
|
index 7f810b0e97..a2358e303a 100644
|
||||||
--- a/qapi/pragma.json
|
--- a/qapi/pragma.json
|
||||||
+++ b/qapi/pragma.json
|
+++ b/qapi/pragma.json
|
||||||
@@ -25,6 +25,7 @@
|
@@ -26,6 +26,7 @@
|
||||||
'system_reset',
|
|
||||||
'system_wakeup' ],
|
'system_wakeup' ],
|
||||||
|
# Commands allowed to return a non-dictionary
|
||||||
'command-returns-exceptions': [
|
'command-returns-exceptions': [
|
||||||
+ 'get_link_status',
|
+ 'get_link_status',
|
||||||
'human-monitor-command',
|
'human-monitor-command',
|
||||||
|
@ -16,7 +16,7 @@ Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
|
|||||||
1 file changed, 9 insertions(+), 1 deletion(-)
|
1 file changed, 9 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
diff --git a/block/gluster.c b/block/gluster.c
|
diff --git a/block/gluster.c b/block/gluster.c
|
||||||
index aebfece6eb..3b7ee2f649 100644
|
index 93da76bc31..1079b6186b 100644
|
||||||
--- a/block/gluster.c
|
--- a/block/gluster.c
|
||||||
+++ b/block/gluster.c
|
+++ b/block/gluster.c
|
||||||
@@ -57,6 +57,7 @@ typedef struct GlusterAIOCB {
|
@@ -57,6 +57,7 @@ typedef struct GlusterAIOCB {
|
||||||
|
@ -9,10 +9,10 @@ Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
|
|||||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
diff --git a/qemu-img.c b/qemu-img.c
|
diff --git a/qemu-img.c b/qemu-img.c
|
||||||
index 1caddfb23a..2782e181c0 100644
|
index 7d4b33b3da..bb36f42dd2 100644
|
||||||
--- a/qemu-img.c
|
--- a/qemu-img.c
|
||||||
+++ b/qemu-img.c
|
+++ b/qemu-img.c
|
||||||
@@ -3005,7 +3005,8 @@ static int img_info(int argc, char **argv)
|
@@ -3010,7 +3010,8 @@ static int img_info(int argc, char **argv)
|
||||||
list = collect_image_info_list(image_opts, filename, fmt, chain,
|
list = collect_image_info_list(image_opts, filename, fmt, chain,
|
||||||
force_share);
|
force_share);
|
||||||
if (!list) {
|
if (!list) {
|
||||||
|
@ -31,10 +31,11 @@ override the output file's size.
|
|||||||
|
|
||||||
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
|
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
|
||||||
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
|
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
|
||||||
|
Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
|
||||||
---
|
---
|
||||||
qemu-img-cmds.hx | 4 +-
|
qemu-img-cmds.hx | 4 +-
|
||||||
qemu-img.c | 187 +++++++++++++++++++++++++++++------------------
|
qemu-img.c | 202 ++++++++++++++++++++++++++++++-----------------
|
||||||
2 files changed, 119 insertions(+), 72 deletions(-)
|
2 files changed, 133 insertions(+), 73 deletions(-)
|
||||||
|
|
||||||
diff --git a/qemu-img-cmds.hx b/qemu-img-cmds.hx
|
diff --git a/qemu-img-cmds.hx b/qemu-img-cmds.hx
|
||||||
index 1b1dab5b17..d1616c045a 100644
|
index 1b1dab5b17..d1616c045a 100644
|
||||||
@ -53,10 +54,10 @@ index 1b1dab5b17..d1616c045a 100644
|
|||||||
|
|
||||||
DEF("info", img_info,
|
DEF("info", img_info,
|
||||||
diff --git a/qemu-img.c b/qemu-img.c
|
diff --git a/qemu-img.c b/qemu-img.c
|
||||||
index 2782e181c0..8cd43b3601 100644
|
index bb36f42dd2..74afcb79ef 100644
|
||||||
--- a/qemu-img.c
|
--- a/qemu-img.c
|
||||||
+++ b/qemu-img.c
|
+++ b/qemu-img.c
|
||||||
@@ -4821,10 +4821,12 @@ static int img_bitmap(int argc, char **argv)
|
@@ -4826,10 +4826,12 @@ static int img_bitmap(int argc, char **argv)
|
||||||
#define C_IF 04
|
#define C_IF 04
|
||||||
#define C_OF 010
|
#define C_OF 010
|
||||||
#define C_SKIP 020
|
#define C_SKIP 020
|
||||||
@ -69,7 +70,7 @@ index 2782e181c0..8cd43b3601 100644
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct DdIo {
|
struct DdIo {
|
||||||
@@ -4900,6 +4902,19 @@ static int img_dd_skip(const char *arg,
|
@@ -4905,6 +4907,19 @@ static int img_dd_skip(const char *arg,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -89,7 +90,7 @@ index 2782e181c0..8cd43b3601 100644
|
|||||||
static int img_dd(int argc, char **argv)
|
static int img_dd(int argc, char **argv)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
@@ -4940,6 +4955,7 @@ static int img_dd(int argc, char **argv)
|
@@ -4945,6 +4960,7 @@ static int img_dd(int argc, char **argv)
|
||||||
{ "if", img_dd_if, C_IF },
|
{ "if", img_dd_if, C_IF },
|
||||||
{ "of", img_dd_of, C_OF },
|
{ "of", img_dd_of, C_OF },
|
||||||
{ "skip", img_dd_skip, C_SKIP },
|
{ "skip", img_dd_skip, C_SKIP },
|
||||||
@ -97,7 +98,7 @@ index 2782e181c0..8cd43b3601 100644
|
|||||||
{ NULL, NULL, 0 }
|
{ NULL, NULL, 0 }
|
||||||
};
|
};
|
||||||
const struct option long_options[] = {
|
const struct option long_options[] = {
|
||||||
@@ -5015,91 +5031,112 @@ static int img_dd(int argc, char **argv)
|
@@ -5020,91 +5036,112 @@ static int img_dd(int argc, char **argv)
|
||||||
arg = NULL;
|
arg = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -153,9 +154,9 @@ index 2782e181c0..8cd43b3601 100644
|
|||||||
}
|
}
|
||||||
- create_opts = qemu_opts_append(create_opts, drv->create_opts);
|
- create_opts = qemu_opts_append(create_opts, drv->create_opts);
|
||||||
- create_opts = qemu_opts_append(create_opts, proto_drv->create_opts);
|
- create_opts = qemu_opts_append(create_opts, proto_drv->create_opts);
|
||||||
|
|
||||||
- opts = qemu_opts_create(create_opts, NULL, 0, &error_abort);
|
|
||||||
-
|
-
|
||||||
|
- opts = qemu_opts_create(create_opts, NULL, 0, &error_abort);
|
||||||
|
|
||||||
- size = blk_getlength(blk1);
|
- size = blk_getlength(blk1);
|
||||||
- if (size < 0) {
|
- if (size < 0) {
|
||||||
- error_report("Failed to get size for '%s'", in.filename);
|
- error_report("Failed to get size for '%s'", in.filename);
|
||||||
@ -274,41 +275,54 @@ index 2782e181c0..8cd43b3601 100644
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (dd.flags & C_SKIP && (in.offset > INT64_MAX / in.bsz ||
|
if (dd.flags & C_SKIP && (in.offset > INT64_MAX / in.bsz ||
|
||||||
@@ -5117,11 +5154,17 @@ static int img_dd(int argc, char **argv)
|
@@ -5121,20 +5158,43 @@ static int img_dd(int argc, char **argv)
|
||||||
|
in.buf = g_new(uint8_t, in.bsz);
|
||||||
|
|
||||||
for (out_pos = 0; in_pos < size; block_count++) {
|
for (out_pos = 0; in_pos < size; block_count++) {
|
||||||
int in_ret, out_ret;
|
+ int in_ret, out_ret;
|
||||||
|
int bytes = (in_pos + in.bsz > size) ? size - in_pos : in.bsz;
|
||||||
-
|
-
|
||||||
- if (in_pos + in.bsz > size) {
|
- ret = blk_pread(blk1, in_pos, bytes, in.buf, 0);
|
||||||
- in_ret = blk_pread(blk1, in_pos, in.buf, size - in_pos);
|
- if (ret < 0) {
|
||||||
+ size_t in_bsz = in_pos + in.bsz > size ? size - in_pos : in.bsz;
|
|
||||||
+ if (blk1) {
|
+ if (blk1) {
|
||||||
+ in_ret = blk_pread(blk1, in_pos, in.buf, in_bsz);
|
+ in_ret = blk_pread(blk1, in_pos, bytes, in.buf, 0);
|
||||||
} else {
|
+ if (in_ret == 0) {
|
||||||
- in_ret = blk_pread(blk1, in_pos, in.buf, in.bsz);
|
+ in_ret = bytes;
|
||||||
+ in_ret = read(STDIN_FILENO, in.buf, in_bsz);
|
+ }
|
||||||
|
+ } else {
|
||||||
|
+ in_ret = read(STDIN_FILENO, in.buf, bytes);
|
||||||
+ if (in_ret == 0) {
|
+ if (in_ret == 0) {
|
||||||
+ /* early EOF is considered an error */
|
+ /* early EOF is considered an error */
|
||||||
+ error_report("Input ended unexpectedly");
|
+ error_report("Input ended unexpectedly");
|
||||||
+ ret = -1;
|
+ ret = -1;
|
||||||
+ goto out;
|
+ goto out;
|
||||||
+ }
|
+ }
|
||||||
}
|
+ }
|
||||||
if (in_ret < 0) {
|
+ if (in_ret < 0) {
|
||||||
error_report("error while reading from input image file: %s",
|
error_report("error while reading from input image file: %s",
|
||||||
@@ -5131,9 +5174,13 @@ static int img_dd(int argc, char **argv)
|
- strerror(-ret));
|
||||||
|
+ strerror(-in_ret));
|
||||||
|
+ ret = -1;
|
||||||
|
goto out;
|
||||||
}
|
}
|
||||||
in_pos += in_ret;
|
in_pos += bytes;
|
||||||
|
|
||||||
- out_ret = blk_pwrite(blk2, out_pos, in.buf, in_ret, 0);
|
- ret = blk_pwrite(blk2, out_pos, bytes, in.buf, 0);
|
||||||
|
- if (ret < 0) {
|
||||||
+ if (blk2) {
|
+ if (blk2) {
|
||||||
+ out_ret = blk_pwrite(blk2, out_pos, in.buf, in_ret, 0);
|
+ out_ret = blk_pwrite(blk2, out_pos, in_ret, in.buf, 0);
|
||||||
|
+ if (out_ret == 0) {
|
||||||
|
+ out_ret = in_ret;
|
||||||
|
+ }
|
||||||
+ } else {
|
+ } else {
|
||||||
+ out_ret = write(STDOUT_FILENO, in.buf, in_ret);
|
+ out_ret = write(STDOUT_FILENO, in.buf, in_ret);
|
||||||
+ }
|
+ }
|
||||||
|
+
|
||||||
- if (out_ret < 0) {
|
|
||||||
+ if (out_ret != in_ret) {
|
+ if (out_ret != in_ret) {
|
||||||
error_report("error while writing to output image file: %s",
|
error_report("error while writing to output image file: %s",
|
||||||
strerror(-out_ret));
|
- strerror(-ret));
|
||||||
ret = -1;
|
+ strerror(-out_ret));
|
||||||
|
+ ret = -1;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
out_pos += bytes;
|
||||||
|
@ -10,15 +10,16 @@ an expected end of input.
|
|||||||
|
|
||||||
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
|
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
|
||||||
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
|
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
|
||||||
|
Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
|
||||||
---
|
---
|
||||||
qemu-img.c | 28 +++++++++++++++++++++++++---
|
qemu-img.c | 28 +++++++++++++++++++++++++---
|
||||||
1 file changed, 25 insertions(+), 3 deletions(-)
|
1 file changed, 25 insertions(+), 3 deletions(-)
|
||||||
|
|
||||||
diff --git a/qemu-img.c b/qemu-img.c
|
diff --git a/qemu-img.c b/qemu-img.c
|
||||||
index 8cd43b3601..67033b2d2c 100644
|
index 74afcb79ef..14594d44b6 100644
|
||||||
--- a/qemu-img.c
|
--- a/qemu-img.c
|
||||||
+++ b/qemu-img.c
|
+++ b/qemu-img.c
|
||||||
@@ -4822,11 +4822,13 @@ static int img_bitmap(int argc, char **argv)
|
@@ -4827,11 +4827,13 @@ static int img_bitmap(int argc, char **argv)
|
||||||
#define C_OF 010
|
#define C_OF 010
|
||||||
#define C_SKIP 020
|
#define C_SKIP 020
|
||||||
#define C_OSIZE 040
|
#define C_OSIZE 040
|
||||||
@ -32,7 +33,7 @@ index 8cd43b3601..67033b2d2c 100644
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct DdIo {
|
struct DdIo {
|
||||||
@@ -4915,6 +4917,19 @@ static int img_dd_osize(const char *arg,
|
@@ -4920,6 +4922,19 @@ static int img_dd_osize(const char *arg,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -52,7 +53,7 @@ index 8cd43b3601..67033b2d2c 100644
|
|||||||
static int img_dd(int argc, char **argv)
|
static int img_dd(int argc, char **argv)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
@@ -4929,12 +4944,14 @@ static int img_dd(int argc, char **argv)
|
@@ -4934,12 +4949,14 @@ static int img_dd(int argc, char **argv)
|
||||||
int c, i;
|
int c, i;
|
||||||
const char *out_fmt = "raw";
|
const char *out_fmt = "raw";
|
||||||
const char *fmt = NULL;
|
const char *fmt = NULL;
|
||||||
@ -68,7 +69,7 @@ index 8cd43b3601..67033b2d2c 100644
|
|||||||
};
|
};
|
||||||
struct DdIo in = {
|
struct DdIo in = {
|
||||||
.bsz = 512, /* Block size is by default 512 bytes */
|
.bsz = 512, /* Block size is by default 512 bytes */
|
||||||
@@ -4956,6 +4973,7 @@ static int img_dd(int argc, char **argv)
|
@@ -4961,6 +4978,7 @@ static int img_dd(int argc, char **argv)
|
||||||
{ "of", img_dd_of, C_OF },
|
{ "of", img_dd_of, C_OF },
|
||||||
{ "skip", img_dd_skip, C_SKIP },
|
{ "skip", img_dd_skip, C_SKIP },
|
||||||
{ "osize", img_dd_osize, C_OSIZE },
|
{ "osize", img_dd_osize, C_OSIZE },
|
||||||
@ -76,7 +77,7 @@ index 8cd43b3601..67033b2d2c 100644
|
|||||||
{ NULL, NULL, 0 }
|
{ NULL, NULL, 0 }
|
||||||
};
|
};
|
||||||
const struct option long_options[] = {
|
const struct option long_options[] = {
|
||||||
@@ -5152,14 +5170,18 @@ static int img_dd(int argc, char **argv)
|
@@ -5157,9 +5175,10 @@ static int img_dd(int argc, char **argv)
|
||||||
|
|
||||||
in.buf = g_new(uint8_t, in.bsz);
|
in.buf = g_new(uint8_t, in.bsz);
|
||||||
|
|
||||||
@ -84,12 +85,14 @@ index 8cd43b3601..67033b2d2c 100644
|
|||||||
+ readsize = (dd.isize > 0) ? dd.isize : size;
|
+ readsize = (dd.isize > 0) ? dd.isize : size;
|
||||||
+ for (out_pos = 0; in_pos < readsize; block_count++) {
|
+ for (out_pos = 0; in_pos < readsize; block_count++) {
|
||||||
int in_ret, out_ret;
|
int in_ret, out_ret;
|
||||||
- size_t in_bsz = in_pos + in.bsz > size ? size - in_pos : in.bsz;
|
- int bytes = (in_pos + in.bsz > size) ? size - in_pos : in.bsz;
|
||||||
+ size_t in_bsz = in_pos + in.bsz > readsize ? readsize - in_pos : in.bsz;
|
+ int bytes = (in_pos + in.bsz > readsize) ? readsize - in_pos : in.bsz;
|
||||||
if (blk1) {
|
if (blk1) {
|
||||||
in_ret = blk_pread(blk1, in_pos, in.buf, in_bsz);
|
in_ret = blk_pread(blk1, in_pos, bytes, in.buf, 0);
|
||||||
|
if (in_ret == 0) {
|
||||||
|
@@ -5168,6 +5187,9 @@ static int img_dd(int argc, char **argv)
|
||||||
} else {
|
} else {
|
||||||
in_ret = read(STDIN_FILENO, in.buf, in_bsz);
|
in_ret = read(STDIN_FILENO, in.buf, bytes);
|
||||||
if (in_ret == 0) {
|
if (in_ret == 0) {
|
||||||
+ if (dd.isize == 0) {
|
+ if (dd.isize == 0) {
|
||||||
+ goto out;
|
+ goto out;
|
||||||
|
@ -13,7 +13,7 @@ Signed-off-by: Fabian Ebner <f.ebner@proxmox.com>
|
|||||||
3 files changed, 26 insertions(+), 12 deletions(-)
|
3 files changed, 26 insertions(+), 12 deletions(-)
|
||||||
|
|
||||||
diff --git a/docs/tools/qemu-img.rst b/docs/tools/qemu-img.rst
|
diff --git a/docs/tools/qemu-img.rst b/docs/tools/qemu-img.rst
|
||||||
index 8885ea11cf..33979b7430 100644
|
index 85a6e05b35..699229eef6 100644
|
||||||
--- a/docs/tools/qemu-img.rst
|
--- a/docs/tools/qemu-img.rst
|
||||||
+++ b/docs/tools/qemu-img.rst
|
+++ b/docs/tools/qemu-img.rst
|
||||||
@@ -208,6 +208,10 @@ Parameters to convert subcommand:
|
@@ -208,6 +208,10 @@ Parameters to convert subcommand:
|
||||||
@ -65,10 +65,10 @@ index d1616c045a..b5b0bb4467 100644
|
|||||||
|
|
||||||
DEF("info", img_info,
|
DEF("info", img_info,
|
||||||
diff --git a/qemu-img.c b/qemu-img.c
|
diff --git a/qemu-img.c b/qemu-img.c
|
||||||
index 67033b2d2c..35c2bdc95c 100644
|
index 14594d44b6..c6b4a5567d 100644
|
||||||
--- a/qemu-img.c
|
--- a/qemu-img.c
|
||||||
+++ b/qemu-img.c
|
+++ b/qemu-img.c
|
||||||
@@ -4946,7 +4946,7 @@ static int img_dd(int argc, char **argv)
|
@@ -4951,7 +4951,7 @@ static int img_dd(int argc, char **argv)
|
||||||
const char *fmt = NULL;
|
const char *fmt = NULL;
|
||||||
int64_t size = 0, readsize = 0;
|
int64_t size = 0, readsize = 0;
|
||||||
int64_t block_count = 0, out_pos, in_pos;
|
int64_t block_count = 0, out_pos, in_pos;
|
||||||
@ -77,7 +77,7 @@ index 67033b2d2c..35c2bdc95c 100644
|
|||||||
struct DdInfo dd = {
|
struct DdInfo dd = {
|
||||||
.flags = 0,
|
.flags = 0,
|
||||||
.count = 0,
|
.count = 0,
|
||||||
@@ -4984,7 +4984,7 @@ static int img_dd(int argc, char **argv)
|
@@ -4989,7 +4989,7 @@ static int img_dd(int argc, char **argv)
|
||||||
{ 0, 0, 0, 0 }
|
{ 0, 0, 0, 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -86,7 +86,7 @@ index 67033b2d2c..35c2bdc95c 100644
|
|||||||
if (c == EOF) {
|
if (c == EOF) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -5004,6 +5004,9 @@ static int img_dd(int argc, char **argv)
|
@@ -5009,6 +5009,9 @@ static int img_dd(int argc, char **argv)
|
||||||
case 'h':
|
case 'h':
|
||||||
help();
|
help();
|
||||||
break;
|
break;
|
||||||
@ -96,7 +96,7 @@ index 67033b2d2c..35c2bdc95c 100644
|
|||||||
case 'U':
|
case 'U':
|
||||||
force_share = true;
|
force_share = true;
|
||||||
break;
|
break;
|
||||||
@@ -5134,13 +5137,15 @@ static int img_dd(int argc, char **argv)
|
@@ -5139,13 +5142,15 @@ static int img_dd(int argc, char **argv)
|
||||||
size - in.bsz * in.offset, &error_abort);
|
size - in.bsz * in.offset, &error_abort);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,10 +14,10 @@ Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
|
|||||||
3 files changed, 81 insertions(+), 4 deletions(-)
|
3 files changed, 81 insertions(+), 4 deletions(-)
|
||||||
|
|
||||||
diff --git a/hw/virtio/virtio-balloon.c b/hw/virtio/virtio-balloon.c
|
diff --git a/hw/virtio/virtio-balloon.c b/hw/virtio/virtio-balloon.c
|
||||||
index 163d244eb4..389907f1f8 100644
|
index 73ac5eb675..bbfe7eca62 100644
|
||||||
--- a/hw/virtio/virtio-balloon.c
|
--- a/hw/virtio/virtio-balloon.c
|
||||||
+++ b/hw/virtio/virtio-balloon.c
|
+++ b/hw/virtio/virtio-balloon.c
|
||||||
@@ -813,8 +813,37 @@ static uint64_t virtio_balloon_get_features(VirtIODevice *vdev, uint64_t f,
|
@@ -806,8 +806,37 @@ static uint64_t virtio_balloon_get_features(VirtIODevice *vdev, uint64_t f,
|
||||||
static void virtio_balloon_stat(void *opaque, BalloonInfo *info)
|
static void virtio_balloon_stat(void *opaque, BalloonInfo *info)
|
||||||
{
|
{
|
||||||
VirtIOBalloon *dev = opaque;
|
VirtIOBalloon *dev = opaque;
|
||||||
@ -58,10 +58,10 @@ index 163d244eb4..389907f1f8 100644
|
|||||||
|
|
||||||
static void virtio_balloon_to_target(void *opaque, ram_addr_t target)
|
static void virtio_balloon_to_target(void *opaque, ram_addr_t target)
|
||||||
diff --git a/monitor/hmp-cmds.c b/monitor/hmp-cmds.c
|
diff --git a/monitor/hmp-cmds.c b/monitor/hmp-cmds.c
|
||||||
index 634968498b..5482dd0569 100644
|
index c6cd6f91dd..15572befb1 100644
|
||||||
--- a/monitor/hmp-cmds.c
|
--- a/monitor/hmp-cmds.c
|
||||||
+++ b/monitor/hmp-cmds.c
|
+++ b/monitor/hmp-cmds.c
|
||||||
@@ -708,7 +708,35 @@ void hmp_info_balloon(Monitor *mon, const QDict *qdict)
|
@@ -715,7 +715,35 @@ void hmp_info_balloon(Monitor *mon, const QDict *qdict)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -99,10 +99,10 @@ index 634968498b..5482dd0569 100644
|
|||||||
qapi_free_BalloonInfo(info);
|
qapi_free_BalloonInfo(info);
|
||||||
}
|
}
|
||||||
diff --git a/qapi/machine.json b/qapi/machine.json
|
diff --git a/qapi/machine.json b/qapi/machine.json
|
||||||
index d25a481ce4..3627172aed 100644
|
index 6afd1936b0..8b4be9b718 100644
|
||||||
--- a/qapi/machine.json
|
--- a/qapi/machine.json
|
||||||
+++ b/qapi/machine.json
|
+++ b/qapi/machine.json
|
||||||
@@ -1018,10 +1018,30 @@
|
@@ -1054,9 +1054,29 @@
|
||||||
# @actual: the logical size of the VM in bytes
|
# @actual: the logical size of the VM in bytes
|
||||||
# Formula used: logical_vm_size = vm_ram_size - balloon_size
|
# Formula used: logical_vm_size = vm_ram_size - balloon_size
|
||||||
#
|
#
|
||||||
@ -123,7 +123,6 @@ index d25a481ce4..3627172aed 100644
|
|||||||
+# @max_mem: amount of memory (in bytes) assigned to the guest
|
+# @max_mem: amount of memory (in bytes) assigned to the guest
|
||||||
+#
|
+#
|
||||||
# Since: 0.14
|
# Since: 0.14
|
||||||
#
|
|
||||||
##
|
##
|
||||||
-{ 'struct': 'BalloonInfo', 'data': {'actual': 'int' } }
|
-{ 'struct': 'BalloonInfo', 'data': {'actual': 'int' } }
|
||||||
+{ 'struct': 'BalloonInfo',
|
+{ 'struct': 'BalloonInfo',
|
||||||
|
@ -30,10 +30,10 @@ index 4f4ab30f8c..76fff60a6b 100644
|
|||||||
info->default_cpu_type = g_strdup(mc->default_cpu_type);
|
info->default_cpu_type = g_strdup(mc->default_cpu_type);
|
||||||
info->has_default_cpu_type = true;
|
info->has_default_cpu_type = true;
|
||||||
diff --git a/qapi/machine.json b/qapi/machine.json
|
diff --git a/qapi/machine.json b/qapi/machine.json
|
||||||
index 3627172aed..ca133e68ce 100644
|
index 8b4be9b718..555458f785 100644
|
||||||
--- a/qapi/machine.json
|
--- a/qapi/machine.json
|
||||||
+++ b/qapi/machine.json
|
+++ b/qapi/machine.json
|
||||||
@@ -139,6 +139,8 @@
|
@@ -138,6 +138,8 @@
|
||||||
#
|
#
|
||||||
# @is-default: whether the machine is default
|
# @is-default: whether the machine is default
|
||||||
#
|
#
|
||||||
@ -42,7 +42,7 @@ index 3627172aed..ca133e68ce 100644
|
|||||||
# @cpu-max: maximum number of CPUs supported by the machine type
|
# @cpu-max: maximum number of CPUs supported by the machine type
|
||||||
# (since 1.5)
|
# (since 1.5)
|
||||||
#
|
#
|
||||||
@@ -160,7 +162,7 @@
|
@@ -159,7 +161,7 @@
|
||||||
##
|
##
|
||||||
{ 'struct': 'MachineInfo',
|
{ 'struct': 'MachineInfo',
|
||||||
'data': { 'name': 'str', '*alias': 'str',
|
'data': { 'name': 'str', '*alias': 'str',
|
||||||
|
@ -12,10 +12,10 @@ Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
|
|||||||
2 files changed, 8 insertions(+)
|
2 files changed, 8 insertions(+)
|
||||||
|
|
||||||
diff --git a/qapi/ui.json b/qapi/ui.json
|
diff --git a/qapi/ui.json b/qapi/ui.json
|
||||||
index 13a8bb82aa..4c34436ba7 100644
|
index cf58ab4283..0be2388941 100644
|
||||||
--- a/qapi/ui.json
|
--- a/qapi/ui.json
|
||||||
+++ b/qapi/ui.json
|
+++ b/qapi/ui.json
|
||||||
@@ -300,11 +300,14 @@
|
@@ -310,11 +310,14 @@
|
||||||
#
|
#
|
||||||
# @channels: a list of @SpiceChannel for each active spice channel
|
# @channels: a list of @SpiceChannel for each active spice channel
|
||||||
#
|
#
|
||||||
|
280
debian/patches/pve/0016-PVE-add-IOChannel-implementation-for-savevm-async.patch
vendored
Normal file
280
debian/patches/pve/0016-PVE-add-IOChannel-implementation-for-savevm-async.patch
vendored
Normal file
@ -0,0 +1,280 @@
|
|||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Fiona Ebner <f.ebner@proxmox.com>
|
||||||
|
Date: Thu, 13 Oct 2022 11:33:50 +0200
|
||||||
|
Subject: [PATCH] PVE: add IOChannel implementation for savevm-async
|
||||||
|
|
||||||
|
based on migration/channel-block.c and the implementation that was
|
||||||
|
present in migration/savevm-async.c before QEMU 7.1.
|
||||||
|
|
||||||
|
Passes along read/write requests to the given BlockBackend, while
|
||||||
|
ensuring that a read request going beyond the end results in a
|
||||||
|
graceful short read.
|
||||||
|
|
||||||
|
Additionally, allows tracking the current position from the outside
|
||||||
|
(intended to be used for progress tracking).
|
||||||
|
|
||||||
|
Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
|
||||||
|
---
|
||||||
|
migration/channel-savevm-async.c | 181 +++++++++++++++++++++++++++++++
|
||||||
|
migration/channel-savevm-async.h | 51 +++++++++
|
||||||
|
migration/meson.build | 1 +
|
||||||
|
3 files changed, 233 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..efea3842cf
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/migration/channel-savevm-async.c
|
||||||
|
@@ -0,0 +1,181 @@
|
||||||
|
+/*
|
||||||
|
+ * QIO Channel implementation to be used by savevm-async QMP calls
|
||||||
|
+ */
|
||||||
|
+#include "qemu/osdep.h"
|
||||||
|
+#include "migration/channel-savevm-async.h"
|
||||||
|
+#include "qapi/error.h"
|
||||||
|
+#include "sysemu/block-backend.h"
|
||||||
|
+#include "trace.h"
|
||||||
|
+
|
||||||
|
+QIOChannelSavevmAsync *
|
||||||
|
+qio_channel_savevm_async_new(BlockBackend *be, size_t *bs_pos)
|
||||||
|
+{
|
||||||
|
+ QIOChannelSavevmAsync *ioc;
|
||||||
|
+
|
||||||
|
+ ioc = QIO_CHANNEL_SAVEVM_ASYNC(object_new(TYPE_QIO_CHANNEL_SAVEVM_ASYNC));
|
||||||
|
+
|
||||||
|
+ bdrv_ref(blk_bs(be));
|
||||||
|
+ ioc->be = be;
|
||||||
|
+ ioc->bs_pos = bs_pos;
|
||||||
|
+
|
||||||
|
+ return ioc;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+static void
|
||||||
|
+qio_channel_savevm_async_finalize(Object *obj)
|
||||||
|
+{
|
||||||
|
+ QIOChannelSavevmAsync *ioc = QIO_CHANNEL_SAVEVM_ASYNC(obj);
|
||||||
|
+
|
||||||
|
+ if (ioc->be) {
|
||||||
|
+ bdrv_unref(blk_bs(ioc->be));
|
||||||
|
+ ioc->be = NULL;
|
||||||
|
+ }
|
||||||
|
+ ioc->bs_pos = NULL;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+static ssize_t
|
||||||
|
+qio_channel_savevm_async_readv(QIOChannel *ioc,
|
||||||
|
+ const struct iovec *iov,
|
||||||
|
+ size_t niov,
|
||||||
|
+ int **fds,
|
||||||
|
+ size_t *nfds,
|
||||||
|
+ Error **errp)
|
||||||
|
+{
|
||||||
|
+ QIOChannelSavevmAsync *saioc = QIO_CHANNEL_SAVEVM_ASYNC(ioc);
|
||||||
|
+ BlockBackend *be = saioc->be;
|
||||||
|
+ int64_t maxlen = blk_getlength(be);
|
||||||
|
+ QEMUIOVector qiov;
|
||||||
|
+ size_t size;
|
||||||
|
+ int ret;
|
||||||
|
+
|
||||||
|
+ qemu_iovec_init_external(&qiov, (struct iovec *)iov, niov);
|
||||||
|
+
|
||||||
|
+ if (*saioc->bs_pos >= maxlen) {
|
||||||
|
+ error_setg(errp, "cannot read beyond maxlen");
|
||||||
|
+ return -1;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (maxlen - *saioc->bs_pos < qiov.size) {
|
||||||
|
+ size = maxlen - *saioc->bs_pos;
|
||||||
|
+ } else {
|
||||||
|
+ size = qiov.size;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ // returns 0 on success
|
||||||
|
+ ret = blk_preadv(be, *saioc->bs_pos, size, &qiov, 0);
|
||||||
|
+ if (ret < 0) {
|
||||||
|
+ error_setg(errp, "blk_preadv returned %d", ret);
|
||||||
|
+ return -1;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ *saioc->bs_pos += size;
|
||||||
|
+ return size;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+static ssize_t
|
||||||
|
+qio_channel_savevm_async_writev(QIOChannel *ioc,
|
||||||
|
+ const struct iovec *iov,
|
||||||
|
+ size_t niov,
|
||||||
|
+ int *fds,
|
||||||
|
+ size_t nfds,
|
||||||
|
+ int flags,
|
||||||
|
+ Error **errp)
|
||||||
|
+{
|
||||||
|
+ QIOChannelSavevmAsync *saioc = QIO_CHANNEL_SAVEVM_ASYNC(ioc);
|
||||||
|
+ BlockBackend *be = saioc->be;
|
||||||
|
+ QEMUIOVector qiov;
|
||||||
|
+ int ret;
|
||||||
|
+
|
||||||
|
+ qemu_iovec_init_external(&qiov, (struct iovec *)iov, niov);
|
||||||
|
+
|
||||||
|
+ if (qemu_in_coroutine()) {
|
||||||
|
+ ret = blk_co_pwritev(be, *saioc->bs_pos, qiov.size, &qiov, 0);
|
||||||
|
+ aio_wait_kick();
|
||||||
|
+ } else {
|
||||||
|
+ ret = blk_pwritev(be, *saioc->bs_pos, qiov.size, &qiov, 0);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (ret < 0) {
|
||||||
|
+ return ret;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ *saioc->bs_pos += qiov.size;
|
||||||
|
+ return qiov.size;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+static int
|
||||||
|
+qio_channel_savevm_async_set_blocking(QIOChannel *ioc,
|
||||||
|
+ bool enabled,
|
||||||
|
+ Error **errp)
|
||||||
|
+{
|
||||||
|
+ if (!enabled) {
|
||||||
|
+ error_setg(errp, "Non-blocking mode not supported for savevm-async");
|
||||||
|
+ return -1;
|
||||||
|
+ }
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+static int
|
||||||
|
+qio_channel_savevm_async_close(QIOChannel *ioc,
|
||||||
|
+ Error **errp)
|
||||||
|
+{
|
||||||
|
+ QIOChannelSavevmAsync *saioc = QIO_CHANNEL_SAVEVM_ASYNC(ioc);
|
||||||
|
+ int rv = bdrv_flush(blk_bs(saioc->be));
|
||||||
|
+
|
||||||
|
+ if (rv < 0) {
|
||||||
|
+ error_setg_errno(errp, -rv, "Unable to flush VMState");
|
||||||
|
+ return -1;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ bdrv_unref(blk_bs(saioc->be));
|
||||||
|
+ saioc->be = NULL;
|
||||||
|
+ saioc->bs_pos = NULL;
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+static void
|
||||||
|
+qio_channel_savevm_async_set_aio_fd_handler(QIOChannel *ioc,
|
||||||
|
+ AioContext *ctx,
|
||||||
|
+ IOHandler *io_read,
|
||||||
|
+ IOHandler *io_write,
|
||||||
|
+ void *opaque)
|
||||||
|
+{
|
||||||
|
+ // if channel-block starts doing something, check if this needs adaptation
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+static void
|
||||||
|
+qio_channel_savevm_async_class_init(ObjectClass *klass,
|
||||||
|
+ void *class_data G_GNUC_UNUSED)
|
||||||
|
+{
|
||||||
|
+ QIOChannelClass *ioc_klass = QIO_CHANNEL_CLASS(klass);
|
||||||
|
+
|
||||||
|
+ ioc_klass->io_writev = qio_channel_savevm_async_writev;
|
||||||
|
+ ioc_klass->io_readv = qio_channel_savevm_async_readv;
|
||||||
|
+ ioc_klass->io_set_blocking = qio_channel_savevm_async_set_blocking;
|
||||||
|
+ ioc_klass->io_close = qio_channel_savevm_async_close;
|
||||||
|
+ ioc_klass->io_set_aio_fd_handler = qio_channel_savevm_async_set_aio_fd_handler;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static const TypeInfo qio_channel_savevm_async_info = {
|
||||||
|
+ .parent = TYPE_QIO_CHANNEL,
|
||||||
|
+ .name = TYPE_QIO_CHANNEL_SAVEVM_ASYNC,
|
||||||
|
+ .instance_size = sizeof(QIOChannelSavevmAsync),
|
||||||
|
+ .instance_finalize = qio_channel_savevm_async_finalize,
|
||||||
|
+ .class_init = qio_channel_savevm_async_class_init,
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+static void
|
||||||
|
+qio_channel_savevm_async_register_types(void)
|
||||||
|
+{
|
||||||
|
+ type_register_static(&qio_channel_savevm_async_info);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+type_init(qio_channel_savevm_async_register_types);
|
||||||
|
diff --git a/migration/channel-savevm-async.h b/migration/channel-savevm-async.h
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000..17ae2cb261
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/migration/channel-savevm-async.h
|
||||||
|
@@ -0,0 +1,51 @@
|
||||||
|
+/*
|
||||||
|
+ * QEMU I/O channels driver for savevm-async.c
|
||||||
|
+ *
|
||||||
|
+ * Copyright (c) 2022 Proxmox Server Solutions
|
||||||
|
+ *
|
||||||
|
+ * Authors:
|
||||||
|
+ * Fiona Ebner (f.ebner@proxmox.com)
|
||||||
|
+ *
|
||||||
|
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
|
||||||
|
+ * See the COPYING file in the top-level directory.
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+#ifndef QIO_CHANNEL_SAVEVM_ASYNC_H
|
||||||
|
+#define QIO_CHANNEL_SAVEVM_ASYNC_H
|
||||||
|
+
|
||||||
|
+#include "io/channel.h"
|
||||||
|
+#include "qom/object.h"
|
||||||
|
+
|
||||||
|
+#define TYPE_QIO_CHANNEL_SAVEVM_ASYNC "qio-channel-savevm-async"
|
||||||
|
+OBJECT_DECLARE_SIMPLE_TYPE(QIOChannelSavevmAsync, QIO_CHANNEL_SAVEVM_ASYNC)
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+/**
|
||||||
|
+ * QIOChannelSavevmAsync:
|
||||||
|
+ *
|
||||||
|
+ * The QIOChannelBlock object provides a channel implementation that is able to
|
||||||
|
+ * perform I/O on any BlockBackend whose BlockDriverState directly contains a
|
||||||
|
+ * VMState (as opposed to indirectly, like qcow2). It allows tracking the
|
||||||
|
+ * current position from the outside.
|
||||||
|
+ */
|
||||||
|
+struct QIOChannelSavevmAsync {
|
||||||
|
+ QIOChannel parent;
|
||||||
|
+ BlockBackend *be;
|
||||||
|
+ size_t *bs_pos;
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+/**
|
||||||
|
+ * qio_channel_savevm_async_new:
|
||||||
|
+ * @be: the block backend
|
||||||
|
+ * @bs_pos: used to keep track of the IOChannels current position
|
||||||
|
+ *
|
||||||
|
+ * Create a new IO channel object that can perform I/O on a BlockBackend object
|
||||||
|
+ * whose BlockDriverState directly contains a VMState.
|
||||||
|
+ *
|
||||||
|
+ * Returns: the new channel object
|
||||||
|
+ */
|
||||||
|
+QIOChannelSavevmAsync *
|
||||||
|
+qio_channel_savevm_async_new(BlockBackend *be, size_t *bs_pos);
|
||||||
|
+
|
||||||
|
+#endif /* QIO_CHANNEL_SAVEVM_ASYNC_H */
|
||||||
|
diff --git a/migration/meson.build b/migration/meson.build
|
||||||
|
index 690487cf1a..8cac83c06c 100644
|
||||||
|
--- a/migration/meson.build
|
||||||
|
+++ b/migration/meson.build
|
||||||
|
@@ -13,6 +13,7 @@ softmmu_ss.add(files(
|
||||||
|
'block-dirty-bitmap.c',
|
||||||
|
'channel.c',
|
||||||
|
'channel-block.c',
|
||||||
|
+ 'channel-savevm-async.c',
|
||||||
|
'colo-failover.c',
|
||||||
|
'colo.c',
|
||||||
|
'exec.c',
|
@ -23,25 +23,26 @@ Signed-off-by: Dietmar Maurer <dietmar@proxmox.com>
|
|||||||
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
|
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
|
||||||
[improve aborting]
|
[improve aborting]
|
||||||
Signed-off-by: Stefan Reiter <s.reiter@proxmox.com>
|
Signed-off-by: Stefan Reiter <s.reiter@proxmox.com>
|
||||||
[FE: further improve aborting]
|
[FE: further improve aborting
|
||||||
|
adapt to removal of QEMUFileOps]
|
||||||
Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
|
Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
|
||||||
---
|
---
|
||||||
hmp-commands-info.hx | 13 +
|
hmp-commands-info.hx | 13 +
|
||||||
hmp-commands.hx | 33 ++
|
hmp-commands.hx | 33 +++
|
||||||
include/migration/snapshot.h | 2 +
|
include/migration/snapshot.h | 2 +
|
||||||
include/monitor/hmp.h | 5 +
|
include/monitor/hmp.h | 5 +
|
||||||
migration/meson.build | 1 +
|
migration/meson.build | 1 +
|
||||||
migration/savevm-async.c | 604 +++++++++++++++++++++++++++++++++++
|
migration/savevm-async.c | 531 +++++++++++++++++++++++++++++++++++
|
||||||
monitor/hmp-cmds.c | 57 ++++
|
monitor/hmp-cmds.c | 57 ++++
|
||||||
qapi/migration.json | 34 ++
|
qapi/migration.json | 34 +++
|
||||||
qapi/misc.json | 32 ++
|
qapi/misc.json | 32 +++
|
||||||
qemu-options.hx | 12 +
|
qemu-options.hx | 12 +
|
||||||
softmmu/vl.c | 10 +
|
softmmu/vl.c | 10 +
|
||||||
11 files changed, 803 insertions(+)
|
11 files changed, 730 insertions(+)
|
||||||
create mode 100644 migration/savevm-async.c
|
create mode 100644 migration/savevm-async.c
|
||||||
|
|
||||||
diff --git a/hmp-commands-info.hx b/hmp-commands-info.hx
|
diff --git a/hmp-commands-info.hx b/hmp-commands-info.hx
|
||||||
index adfa085a9b..925e680e5a 100644
|
index 188d9ece3b..97b88eaaad 100644
|
||||||
--- a/hmp-commands-info.hx
|
--- a/hmp-commands-info.hx
|
||||||
+++ b/hmp-commands-info.hx
|
+++ b/hmp-commands-info.hx
|
||||||
@@ -538,6 +538,19 @@ SRST
|
@@ -538,6 +538,19 @@ SRST
|
||||||
@ -65,12 +66,12 @@ index adfa085a9b..925e680e5a 100644
|
|||||||
.name = "balloon",
|
.name = "balloon",
|
||||||
.args_type = "",
|
.args_type = "",
|
||||||
diff --git a/hmp-commands.hx b/hmp-commands.hx
|
diff --git a/hmp-commands.hx b/hmp-commands.hx
|
||||||
index 8476277aa9..7f0ac498c4 100644
|
index 182e639d14..bbcc73e942 100644
|
||||||
--- a/hmp-commands.hx
|
--- a/hmp-commands.hx
|
||||||
+++ b/hmp-commands.hx
|
+++ b/hmp-commands.hx
|
||||||
@@ -1746,3 +1746,36 @@ ERST
|
@@ -1800,3 +1800,36 @@ ERST
|
||||||
"\n\t\t\t -b to specify dirty bitmap as method of calculation)",
|
"\n\t\t\t\t\t limit on a specified virtual cpu",
|
||||||
.cmd = hmp_calc_dirty_rate,
|
.cmd = hmp_cancel_vcpu_dirty_limit,
|
||||||
},
|
},
|
||||||
+
|
+
|
||||||
+ {
|
+ {
|
||||||
@ -117,7 +118,7 @@ index e72083b117..c846d37806 100644
|
|||||||
+
|
+
|
||||||
#endif
|
#endif
|
||||||
diff --git a/include/monitor/hmp.h b/include/monitor/hmp.h
|
diff --git a/include/monitor/hmp.h b/include/monitor/hmp.h
|
||||||
index 96d014826a..3a39ba41b5 100644
|
index a618eb1e4e..55067beff1 100644
|
||||||
--- a/include/monitor/hmp.h
|
--- a/include/monitor/hmp.h
|
||||||
+++ b/include/monitor/hmp.h
|
+++ b/include/monitor/hmp.h
|
||||||
@@ -26,6 +26,7 @@ void hmp_info_status(Monitor *mon, const QDict *qdict);
|
@@ -26,6 +26,7 @@ void hmp_info_status(Monitor *mon, const QDict *qdict);
|
||||||
@ -140,10 +141,10 @@ index 96d014826a..3a39ba41b5 100644
|
|||||||
void hmp_screendump(Monitor *mon, const QDict *qdict);
|
void hmp_screendump(Monitor *mon, const QDict *qdict);
|
||||||
void hmp_chardev_add(Monitor *mon, const QDict *qdict);
|
void hmp_chardev_add(Monitor *mon, const QDict *qdict);
|
||||||
diff --git a/migration/meson.build b/migration/meson.build
|
diff --git a/migration/meson.build b/migration/meson.build
|
||||||
index 8b5ca5c047..1e2aec8486 100644
|
index 8cac83c06c..0842d00cd2 100644
|
||||||
--- a/migration/meson.build
|
--- a/migration/meson.build
|
||||||
+++ b/migration/meson.build
|
+++ b/migration/meson.build
|
||||||
@@ -23,6 +23,7 @@ softmmu_ss.add(files(
|
@@ -24,6 +24,7 @@ softmmu_ss.add(files(
|
||||||
'multifd-zlib.c',
|
'multifd-zlib.c',
|
||||||
'postcopy-ram.c',
|
'postcopy-ram.c',
|
||||||
'savevm.c',
|
'savevm.c',
|
||||||
@ -153,11 +154,12 @@ index 8b5ca5c047..1e2aec8486 100644
|
|||||||
), gnutls)
|
), gnutls)
|
||||||
diff --git a/migration/savevm-async.c b/migration/savevm-async.c
|
diff --git a/migration/savevm-async.c b/migration/savevm-async.c
|
||||||
new file mode 100644
|
new file mode 100644
|
||||||
index 0000000000..b9a43c56bc
|
index 0000000000..b3692739a0
|
||||||
--- /dev/null
|
--- /dev/null
|
||||||
+++ b/migration/savevm-async.c
|
+++ b/migration/savevm-async.c
|
||||||
@@ -0,0 +1,604 @@
|
@@ -0,0 +1,531 @@
|
||||||
+#include "qemu/osdep.h"
|
+#include "qemu/osdep.h"
|
||||||
|
+#include "migration/channel-savevm-async.h"
|
||||||
+#include "migration/migration.h"
|
+#include "migration/migration.h"
|
||||||
+#include "migration/savevm.h"
|
+#include "migration/savevm.h"
|
||||||
+#include "migration/snapshot.h"
|
+#include "migration/snapshot.h"
|
||||||
@ -181,9 +183,6 @@ index 0000000000..b9a43c56bc
|
|||||||
+
|
+
|
||||||
+/* #define DEBUG_SAVEVM_STATE */
|
+/* #define DEBUG_SAVEVM_STATE */
|
||||||
+
|
+
|
||||||
+/* used while emulated sync operation in progress */
|
|
||||||
+#define NOT_DONE -EINPROGRESS
|
|
||||||
+
|
|
||||||
+#ifdef DEBUG_SAVEVM_STATE
|
+#ifdef DEBUG_SAVEVM_STATE
|
||||||
+#define DPRINTF(fmt, ...) \
|
+#define DPRINTF(fmt, ...) \
|
||||||
+ do { printf("savevm-async: " fmt, ## __VA_ARGS__); } while (0)
|
+ do { printf("savevm-async: " fmt, ## __VA_ARGS__); } while (0)
|
||||||
@ -270,6 +269,7 @@ index 0000000000..b9a43c56bc
|
|||||||
+
|
+
|
||||||
+ if (snap_state.file) {
|
+ if (snap_state.file) {
|
||||||
+ ret = qemu_fclose(snap_state.file);
|
+ ret = qemu_fclose(snap_state.file);
|
||||||
|
+ snap_state.file = NULL;
|
||||||
+ }
|
+ }
|
||||||
+
|
+
|
||||||
+ if (snap_state.target) {
|
+ if (snap_state.target) {
|
||||||
@ -313,60 +313,6 @@ index 0000000000..b9a43c56bc
|
|||||||
+ snap_state.state = SAVE_STATE_ERROR;
|
+ snap_state.state = SAVE_STATE_ERROR;
|
||||||
+}
|
+}
|
||||||
+
|
+
|
||||||
+static int block_state_close(void *opaque, Error **errp)
|
|
||||||
+{
|
|
||||||
+ snap_state.file = NULL;
|
|
||||||
+ return blk_flush(snap_state.target);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+typedef struct BlkRwCo {
|
|
||||||
+ int64_t offset;
|
|
||||||
+ QEMUIOVector *qiov;
|
|
||||||
+ ssize_t ret;
|
|
||||||
+} BlkRwCo;
|
|
||||||
+
|
|
||||||
+static void coroutine_fn block_state_write_entry(void *opaque) {
|
|
||||||
+ BlkRwCo *rwco = opaque;
|
|
||||||
+ rwco->ret = blk_co_pwritev(snap_state.target, rwco->offset, rwco->qiov->size,
|
|
||||||
+ rwco->qiov, 0);
|
|
||||||
+ aio_wait_kick();
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static ssize_t block_state_writev_buffer(void *opaque, struct iovec *iov,
|
|
||||||
+ int iovcnt, int64_t pos, Error **errp)
|
|
||||||
+{
|
|
||||||
+ QEMUIOVector qiov;
|
|
||||||
+ BlkRwCo rwco;
|
|
||||||
+
|
|
||||||
+ assert(pos == snap_state.bs_pos);
|
|
||||||
+ rwco = (BlkRwCo) {
|
|
||||||
+ .offset = pos,
|
|
||||||
+ .qiov = &qiov,
|
|
||||||
+ .ret = NOT_DONE,
|
|
||||||
+ };
|
|
||||||
+
|
|
||||||
+ qemu_iovec_init_external(&qiov, iov, iovcnt);
|
|
||||||
+
|
|
||||||
+ if (qemu_in_coroutine()) {
|
|
||||||
+ block_state_write_entry(&rwco);
|
|
||||||
+ } else {
|
|
||||||
+ Coroutine *co = qemu_coroutine_create(&block_state_write_entry, &rwco);
|
|
||||||
+ bdrv_coroutine_enter(blk_bs(snap_state.target), co);
|
|
||||||
+ BDRV_POLL_WHILE(blk_bs(snap_state.target), rwco.ret == NOT_DONE);
|
|
||||||
+ }
|
|
||||||
+ if (rwco.ret < 0) {
|
|
||||||
+ return rwco.ret;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ snap_state.bs_pos += qiov.size;
|
|
||||||
+ return qiov.size;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static const QEMUFileOps block_file_ops = {
|
|
||||||
+ .writev_buffer = block_state_writev_buffer,
|
|
||||||
+ .close = block_state_close,
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
+static void process_savevm_finalize(void *opaque)
|
+static void process_savevm_finalize(void *opaque)
|
||||||
+{
|
+{
|
||||||
+ int ret;
|
+ int ret;
|
||||||
@ -579,7 +525,9 @@ index 0000000000..b9a43c56bc
|
|||||||
+ goto restart;
|
+ goto restart;
|
||||||
+ }
|
+ }
|
||||||
+
|
+
|
||||||
+ snap_state.file = qemu_fopen_ops(&snap_state, &block_file_ops);
|
+ QIOChannel *ioc = QIO_CHANNEL(qio_channel_savevm_async_new(snap_state.target,
|
||||||
|
+ &snap_state.bs_pos));
|
||||||
|
+ snap_state.file = qemu_file_new_output(ioc);
|
||||||
+
|
+
|
||||||
+ if (!snap_state.file) {
|
+ if (!snap_state.file) {
|
||||||
+ error_set(errp, ERROR_CLASS_GENERIC_ERROR, "failed to open '%s'", statefile);
|
+ error_set(errp, ERROR_CLASS_GENERIC_ERROR, "failed to open '%s'", statefile);
|
||||||
@ -691,27 +639,6 @@ index 0000000000..b9a43c56bc
|
|||||||
+ true, name, errp);
|
+ true, name, errp);
|
||||||
+}
|
+}
|
||||||
+
|
+
|
||||||
+static ssize_t loadstate_get_buffer(void *opaque, uint8_t *buf, int64_t pos,
|
|
||||||
+ size_t size, Error **errp)
|
|
||||||
+{
|
|
||||||
+ BlockBackend *be = opaque;
|
|
||||||
+ int64_t maxlen = blk_getlength(be);
|
|
||||||
+ if (pos > maxlen) {
|
|
||||||
+ return -EIO;
|
|
||||||
+ }
|
|
||||||
+ if ((pos + size) > maxlen) {
|
|
||||||
+ size = maxlen - pos - 1;
|
|
||||||
+ }
|
|
||||||
+ if (size == 0) {
|
|
||||||
+ return 0;
|
|
||||||
+ }
|
|
||||||
+ return blk_pread(be, pos, buf, size);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static const QEMUFileOps loadstate_file_ops = {
|
|
||||||
+ .get_buffer = loadstate_get_buffer,
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
+int load_snapshot_from_blockdev(const char *filename, Error **errp)
|
+int load_snapshot_from_blockdev(const char *filename, Error **errp)
|
||||||
+{
|
+{
|
||||||
+ BlockBackend *be;
|
+ BlockBackend *be;
|
||||||
@ -719,6 +646,7 @@ index 0000000000..b9a43c56bc
|
|||||||
+ Error *blocker = NULL;
|
+ Error *blocker = NULL;
|
||||||
+
|
+
|
||||||
+ QEMUFile *f;
|
+ QEMUFile *f;
|
||||||
|
+ size_t bs_pos = 0;
|
||||||
+ int ret = -EINVAL;
|
+ int ret = -EINVAL;
|
||||||
+
|
+
|
||||||
+ be = blk_new_open(filename, NULL, NULL, 0, &local_err);
|
+ be = blk_new_open(filename, NULL, NULL, 0, &local_err);
|
||||||
@ -732,7 +660,7 @@ index 0000000000..b9a43c56bc
|
|||||||
+ blk_op_block_all(be, blocker);
|
+ blk_op_block_all(be, blocker);
|
||||||
+
|
+
|
||||||
+ /* restore the VM state */
|
+ /* restore the VM state */
|
||||||
+ f = qemu_fopen_ops(be, &loadstate_file_ops);
|
+ f = qemu_file_new_input(QIO_CHANNEL(qio_channel_savevm_async_new(be, &bs_pos)));
|
||||||
+ if (!f) {
|
+ if (!f) {
|
||||||
+ error_setg(errp, "Could not open VM state file");
|
+ error_setg(errp, "Could not open VM state file");
|
||||||
+ goto the_end;
|
+ goto the_end;
|
||||||
@ -762,10 +690,10 @@ index 0000000000..b9a43c56bc
|
|||||||
+ return ret;
|
+ return ret;
|
||||||
+}
|
+}
|
||||||
diff --git a/monitor/hmp-cmds.c b/monitor/hmp-cmds.c
|
diff --git a/monitor/hmp-cmds.c b/monitor/hmp-cmds.c
|
||||||
index 5482dd0569..c64b959738 100644
|
index 15572befb1..1507180990 100644
|
||||||
--- a/monitor/hmp-cmds.c
|
--- a/monitor/hmp-cmds.c
|
||||||
+++ b/monitor/hmp-cmds.c
|
+++ b/monitor/hmp-cmds.c
|
||||||
@@ -1906,6 +1906,63 @@ void hmp_info_memory_devices(Monitor *mon, const QDict *qdict)
|
@@ -1925,6 +1925,63 @@ void hmp_info_memory_devices(Monitor *mon, const QDict *qdict)
|
||||||
hmp_handle_error(mon, err);
|
hmp_handle_error(mon, err);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -830,10 +758,10 @@ index 5482dd0569..c64b959738 100644
|
|||||||
{
|
{
|
||||||
IOThreadInfoList *info_list = qmp_query_iothreads(NULL);
|
IOThreadInfoList *info_list = qmp_query_iothreads(NULL);
|
||||||
diff --git a/qapi/migration.json b/qapi/migration.json
|
diff --git a/qapi/migration.json b/qapi/migration.json
|
||||||
index 27d7b28158..31d6cc902e 100644
|
index 81185d4311..3129f71fa8 100644
|
||||||
--- a/qapi/migration.json
|
--- a/qapi/migration.json
|
||||||
+++ b/qapi/migration.json
|
+++ b/qapi/migration.json
|
||||||
@@ -258,6 +258,40 @@
|
@@ -261,6 +261,40 @@
|
||||||
'*compression': 'CompressionStats',
|
'*compression': 'CompressionStats',
|
||||||
'*socket-address': ['SocketAddress'] } }
|
'*socket-address': ['SocketAddress'] } }
|
||||||
|
|
||||||
@ -875,7 +803,7 @@ index 27d7b28158..31d6cc902e 100644
|
|||||||
# @query-migrate:
|
# @query-migrate:
|
||||||
#
|
#
|
||||||
diff --git a/qapi/misc.json b/qapi/misc.json
|
diff --git a/qapi/misc.json b/qapi/misc.json
|
||||||
index b83cc39029..1e5dd7db29 100644
|
index 27ef5a2b20..b3ce75dcae 100644
|
||||||
--- a/qapi/misc.json
|
--- a/qapi/misc.json
|
||||||
+++ b/qapi/misc.json
|
+++ b/qapi/misc.json
|
||||||
@@ -435,6 +435,38 @@
|
@@ -435,6 +435,38 @@
|
||||||
@ -918,10 +846,10 @@ index b83cc39029..1e5dd7db29 100644
|
|||||||
# @CommandLineParameterType:
|
# @CommandLineParameterType:
|
||||||
#
|
#
|
||||||
diff --git a/qemu-options.hx b/qemu-options.hx
|
diff --git a/qemu-options.hx b/qemu-options.hx
|
||||||
index 34e9b32a5c..aeade4ef80 100644
|
index 31c04f7eea..c2ca6e91b5 100644
|
||||||
--- a/qemu-options.hx
|
--- a/qemu-options.hx
|
||||||
+++ b/qemu-options.hx
|
+++ b/qemu-options.hx
|
||||||
@@ -4254,6 +4254,18 @@ SRST
|
@@ -4341,6 +4341,18 @@ SRST
|
||||||
Start right away with a saved state (``loadvm`` in monitor)
|
Start right away with a saved state (``loadvm`` in monitor)
|
||||||
ERST
|
ERST
|
||||||
|
|
||||||
@ -941,18 +869,18 @@ index 34e9b32a5c..aeade4ef80 100644
|
|||||||
DEF("daemonize", 0, QEMU_OPTION_daemonize, \
|
DEF("daemonize", 0, QEMU_OPTION_daemonize, \
|
||||||
"-daemonize daemonize QEMU after initializing\n", QEMU_ARCH_ALL)
|
"-daemonize daemonize QEMU after initializing\n", QEMU_ARCH_ALL)
|
||||||
diff --git a/softmmu/vl.c b/softmmu/vl.c
|
diff --git a/softmmu/vl.c b/softmmu/vl.c
|
||||||
index 6f646531a0..a3f2a3818c 100644
|
index 706bd7cff7..b8637c4262 100644
|
||||||
--- a/softmmu/vl.c
|
--- a/softmmu/vl.c
|
||||||
+++ b/softmmu/vl.c
|
+++ b/softmmu/vl.c
|
||||||
@@ -157,6 +157,7 @@ static const char *incoming;
|
@@ -165,6 +165,7 @@ static const char *accelerators;
|
||||||
static const char *loadvm;
|
static bool have_custom_ram_size;
|
||||||
static const char *accelerators;
|
static const char *ram_memdev_id;
|
||||||
static QDict *machine_opts_dict;
|
static QDict *machine_opts_dict;
|
||||||
+static const char *loadstate;
|
+static const char *loadstate;
|
||||||
static QTAILQ_HEAD(, ObjectOption) object_opts = QTAILQ_HEAD_INITIALIZER(object_opts);
|
static QTAILQ_HEAD(, ObjectOption) object_opts = QTAILQ_HEAD_INITIALIZER(object_opts);
|
||||||
static QTAILQ_HEAD(, DeviceOption) device_opts = QTAILQ_HEAD_INITIALIZER(device_opts);
|
static QTAILQ_HEAD(, DeviceOption) device_opts = QTAILQ_HEAD_INITIALIZER(device_opts);
|
||||||
static ram_addr_t maxram_size;
|
static int display_remote;
|
||||||
@@ -2749,6 +2750,12 @@ void qmp_x_exit_preconfig(Error **errp)
|
@@ -2584,6 +2585,12 @@ void qmp_x_exit_preconfig(Error **errp)
|
||||||
|
|
||||||
if (loadvm) {
|
if (loadvm) {
|
||||||
load_snapshot(loadvm, NULL, false, NULL, &error_fatal);
|
load_snapshot(loadvm, NULL, false, NULL, &error_fatal);
|
||||||
@ -965,7 +893,7 @@ index 6f646531a0..a3f2a3818c 100644
|
|||||||
}
|
}
|
||||||
if (replay_mode != REPLAY_MODE_NONE) {
|
if (replay_mode != REPLAY_MODE_NONE) {
|
||||||
replay_vmstate_init();
|
replay_vmstate_init();
|
||||||
@@ -3289,6 +3296,9 @@ void qemu_init(int argc, char **argv, char **envp)
|
@@ -3133,6 +3140,9 @@ void qemu_init(int argc, char **argv, char **envp)
|
||||||
case QEMU_OPTION_loadvm:
|
case QEMU_OPTION_loadvm:
|
||||||
loadvm = optarg;
|
loadvm = optarg;
|
||||||
break;
|
break;
|
@ -10,14 +10,16 @@ Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
|
|||||||
[increase max IOV count in QEMUFile to actually write more data]
|
[increase max IOV count in QEMUFile to actually write more data]
|
||||||
Signed-off-by: Stefan Reiter <s.reiter@proxmox.com>
|
Signed-off-by: Stefan Reiter <s.reiter@proxmox.com>
|
||||||
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
|
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
|
||||||
|
[FE: adapt to removal of QEMUFileOps]
|
||||||
|
Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
|
||||||
---
|
---
|
||||||
migration/qemu-file.c | 38 +++++++++++++++++++++++++-------------
|
migration/qemu-file.c | 49 +++++++++++++++++++++++++++-------------
|
||||||
migration/qemu-file.h | 1 +
|
migration/qemu-file.h | 2 ++
|
||||||
migration/savevm-async.c | 4 ++--
|
migration/savevm-async.c | 5 ++--
|
||||||
3 files changed, 28 insertions(+), 15 deletions(-)
|
3 files changed, 38 insertions(+), 18 deletions(-)
|
||||||
|
|
||||||
diff --git a/migration/qemu-file.c b/migration/qemu-file.c
|
diff --git a/migration/qemu-file.c b/migration/qemu-file.c
|
||||||
index 1479cddad9..21a3355ae2 100644
|
index 4f400c2e52..21e8998867 100644
|
||||||
--- a/migration/qemu-file.c
|
--- a/migration/qemu-file.c
|
||||||
+++ b/migration/qemu-file.c
|
+++ b/migration/qemu-file.c
|
||||||
@@ -31,8 +31,8 @@
|
@@ -31,8 +31,8 @@
|
||||||
@ -30,9 +32,9 @@ index 1479cddad9..21a3355ae2 100644
|
|||||||
+#define MAX_IOV_SIZE MIN_CONST(IOV_MAX, 256)
|
+#define MAX_IOV_SIZE MIN_CONST(IOV_MAX, 256)
|
||||||
|
|
||||||
struct QEMUFile {
|
struct QEMUFile {
|
||||||
const QEMUFileOps *ops;
|
const QEMUFileHooks *hooks;
|
||||||
@@ -46,7 +46,8 @@ struct QEMUFile {
|
@@ -55,7 +55,8 @@ struct QEMUFile {
|
||||||
when reading */
|
|
||||||
int buf_index;
|
int buf_index;
|
||||||
int buf_size; /* 0 when writing */
|
int buf_size; /* 0 when writing */
|
||||||
- uint8_t buf[IO_BUF_SIZE];
|
- uint8_t buf[IO_BUF_SIZE];
|
||||||
@ -41,53 +43,76 @@ index 1479cddad9..21a3355ae2 100644
|
|||||||
|
|
||||||
DECLARE_BITMAP(may_free, MAX_IOV_SIZE);
|
DECLARE_BITMAP(may_free, MAX_IOV_SIZE);
|
||||||
struct iovec iov[MAX_IOV_SIZE];
|
struct iovec iov[MAX_IOV_SIZE];
|
||||||
@@ -104,7 +105,7 @@ bool qemu_file_mode_is_not_valid(const char *mode)
|
@@ -106,7 +107,9 @@ bool qemu_file_mode_is_not_valid(const char *mode)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
-QEMUFile *qemu_fopen_ops(void *opaque, const QEMUFileOps *ops, bool has_ioc)
|
-static QEMUFile *qemu_file_new_impl(QIOChannel *ioc, bool is_writable)
|
||||||
+QEMUFile *qemu_fopen_ops_sized(void *opaque, const QEMUFileOps *ops, bool has_ioc, size_t buffer_size)
|
+static QEMUFile *qemu_file_new_impl(QIOChannel *ioc,
|
||||||
|
+ bool is_writable,
|
||||||
|
+ size_t buffer_size)
|
||||||
{
|
{
|
||||||
QEMUFile *f;
|
QEMUFile *f;
|
||||||
|
|
||||||
@@ -113,9 +114,17 @@ QEMUFile *qemu_fopen_ops(void *opaque, const QEMUFileOps *ops, bool has_ioc)
|
@@ -115,6 +118,8 @@ static QEMUFile *qemu_file_new_impl(QIOChannel *ioc, bool is_writable)
|
||||||
f->opaque = opaque;
|
object_ref(ioc);
|
||||||
f->ops = ops;
|
f->ioc = ioc;
|
||||||
f->has_ioc = has_ioc;
|
f->is_writable = is_writable;
|
||||||
+ f->buf_allocated_size = buffer_size;
|
+ f->buf_allocated_size = buffer_size;
|
||||||
+ f->buf = malloc(buffer_size);
|
+ f->buf = malloc(buffer_size);
|
||||||
+
|
|
||||||
return f;
|
return f;
|
||||||
}
|
}
|
||||||
|
@@ -125,17 +130,27 @@ static QEMUFile *qemu_file_new_impl(QIOChannel *ioc, bool is_writable)
|
||||||
|
*/
|
||||||
|
QEMUFile *qemu_file_get_return_path(QEMUFile *f)
|
||||||
|
{
|
||||||
|
- return qemu_file_new_impl(f->ioc, !f->is_writable);
|
||||||
|
+ return qemu_file_new_impl(f->ioc, !f->is_writable, DEFAULT_IO_BUF_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
+QEMUFile *qemu_fopen_ops(void *opaque, const QEMUFileOps *ops, bool has_ioc)
|
QEMUFile *qemu_file_new_output(QIOChannel *ioc)
|
||||||
+{
|
{
|
||||||
+ return qemu_fopen_ops_sized(opaque, ops, has_ioc, DEFAULT_IO_BUF_SIZE);
|
- return qemu_file_new_impl(ioc, true);
|
||||||
|
+ return qemu_file_new_impl(ioc, true, DEFAULT_IO_BUF_SIZE);
|
||||||
+}
|
+}
|
||||||
+
|
+
|
||||||
|
+QEMUFile *qemu_file_new_output_sized(QIOChannel *ioc, size_t buffer_size)
|
||||||
|
+{
|
||||||
|
+ return qemu_file_new_impl(ioc, true, buffer_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
QEMUFile *qemu_file_new_input(QIOChannel *ioc)
|
||||||
|
{
|
||||||
|
- return qemu_file_new_impl(ioc, false);
|
||||||
|
+ return qemu_file_new_impl(ioc, false, DEFAULT_IO_BUF_SIZE);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+QEMUFile *qemu_file_new_input_sized(QIOChannel *ioc, size_t buffer_size)
|
||||||
|
+{
|
||||||
|
+ return qemu_file_new_impl(ioc, false, buffer_size);
|
||||||
|
}
|
||||||
|
|
||||||
void qemu_file_set_hooks(QEMUFile *f, const QEMUFileHooks *hooks)
|
void qemu_file_set_hooks(QEMUFile *f, const QEMUFileHooks *hooks)
|
||||||
{
|
@@ -393,7 +408,7 @@ static ssize_t qemu_fill_buffer(QEMUFile *f)
|
||||||
@@ -350,7 +359,7 @@ static ssize_t qemu_fill_buffer(QEMUFile *f)
|
do {
|
||||||
|
len = qio_channel_read(f->ioc,
|
||||||
|
(char *)f->buf + pending,
|
||||||
|
- IO_BUF_SIZE - pending,
|
||||||
|
+ f->buf_allocated_size - pending,
|
||||||
|
&local_error);
|
||||||
|
if (len == QIO_CHANNEL_ERR_BLOCK) {
|
||||||
|
if (qemu_in_coroutine()) {
|
||||||
|
@@ -443,6 +458,8 @@ int qemu_fclose(QEMUFile *f)
|
||||||
}
|
}
|
||||||
|
g_clear_pointer(&f->ioc, object_unref);
|
||||||
|
|
||||||
len = f->ops->get_buffer(f->opaque, f->buf + pending, f->pos,
|
|
||||||
- IO_BUF_SIZE - pending, &local_error);
|
|
||||||
+ f->buf_allocated_size - pending, &local_error);
|
|
||||||
if (len > 0) {
|
|
||||||
f->buf_size += len;
|
|
||||||
f->pos += len;
|
|
||||||
@@ -390,6 +399,9 @@ int qemu_fclose(QEMUFile *f)
|
|
||||||
ret = ret2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+
|
|
||||||
+ free(f->buf);
|
+ free(f->buf);
|
||||||
+
|
+
|
||||||
/* If any error was spotted before closing, we should report it
|
/* If any error was spotted before closing, we should report it
|
||||||
* instead of the close() return value.
|
* instead of the close() return value.
|
||||||
*/
|
*/
|
||||||
@@ -444,7 +456,7 @@ static void add_buf_to_iovec(QEMUFile *f, size_t len)
|
@@ -497,7 +514,7 @@ static void add_buf_to_iovec(QEMUFile *f, size_t len)
|
||||||
{
|
{
|
||||||
if (!add_to_iovec(f, f->buf + f->buf_index, len, false)) {
|
if (!add_to_iovec(f, f->buf + f->buf_index, len, false)) {
|
||||||
f->buf_index += len;
|
f->buf_index += len;
|
||||||
@ -96,7 +121,7 @@ index 1479cddad9..21a3355ae2 100644
|
|||||||
qemu_fflush(f);
|
qemu_fflush(f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -470,7 +482,7 @@ void qemu_put_buffer(QEMUFile *f, const uint8_t *buf, size_t size)
|
@@ -523,7 +540,7 @@ void qemu_put_buffer(QEMUFile *f, const uint8_t *buf, size_t size)
|
||||||
}
|
}
|
||||||
|
|
||||||
while (size > 0) {
|
while (size > 0) {
|
||||||
@ -105,7 +130,7 @@ index 1479cddad9..21a3355ae2 100644
|
|||||||
if (l > size) {
|
if (l > size) {
|
||||||
l = size;
|
l = size;
|
||||||
}
|
}
|
||||||
@@ -517,8 +529,8 @@ size_t qemu_peek_buffer(QEMUFile *f, uint8_t **buf, size_t size, size_t offset)
|
@@ -570,8 +587,8 @@ size_t qemu_peek_buffer(QEMUFile *f, uint8_t **buf, size_t size, size_t offset)
|
||||||
size_t index;
|
size_t index;
|
||||||
|
|
||||||
assert(!qemu_file_is_writable(f));
|
assert(!qemu_file_is_writable(f));
|
||||||
@ -116,7 +141,7 @@ index 1479cddad9..21a3355ae2 100644
|
|||||||
|
|
||||||
/* The 1st byte to read from */
|
/* The 1st byte to read from */
|
||||||
index = f->buf_index + offset;
|
index = f->buf_index + offset;
|
||||||
@@ -568,7 +580,7 @@ size_t qemu_get_buffer(QEMUFile *f, uint8_t *buf, size_t size)
|
@@ -621,7 +638,7 @@ size_t qemu_get_buffer(QEMUFile *f, uint8_t *buf, size_t size)
|
||||||
size_t res;
|
size_t res;
|
||||||
uint8_t *src;
|
uint8_t *src;
|
||||||
|
|
||||||
@ -125,7 +150,7 @@ index 1479cddad9..21a3355ae2 100644
|
|||||||
if (res == 0) {
|
if (res == 0) {
|
||||||
return done;
|
return done;
|
||||||
}
|
}
|
||||||
@@ -602,7 +614,7 @@ size_t qemu_get_buffer(QEMUFile *f, uint8_t *buf, size_t size)
|
@@ -655,7 +672,7 @@ size_t qemu_get_buffer(QEMUFile *f, uint8_t *buf, size_t size)
|
||||||
*/
|
*/
|
||||||
size_t qemu_get_buffer_in_place(QEMUFile *f, uint8_t **buf, size_t size)
|
size_t qemu_get_buffer_in_place(QEMUFile *f, uint8_t **buf, size_t size)
|
||||||
{
|
{
|
||||||
@ -134,7 +159,7 @@ index 1479cddad9..21a3355ae2 100644
|
|||||||
size_t res;
|
size_t res;
|
||||||
uint8_t *src = NULL;
|
uint8_t *src = NULL;
|
||||||
|
|
||||||
@@ -627,7 +639,7 @@ int qemu_peek_byte(QEMUFile *f, int offset)
|
@@ -680,7 +697,7 @@ int qemu_peek_byte(QEMUFile *f, int offset)
|
||||||
int index = f->buf_index + offset;
|
int index = f->buf_index + offset;
|
||||||
|
|
||||||
assert(!qemu_file_is_writable(f));
|
assert(!qemu_file_is_writable(f));
|
||||||
@ -143,7 +168,7 @@ index 1479cddad9..21a3355ae2 100644
|
|||||||
|
|
||||||
if (index >= f->buf_size) {
|
if (index >= f->buf_size) {
|
||||||
qemu_fill_buffer(f);
|
qemu_fill_buffer(f);
|
||||||
@@ -779,7 +791,7 @@ static int qemu_compress_data(z_stream *stream, uint8_t *dest, size_t dest_len,
|
@@ -832,7 +849,7 @@ static int qemu_compress_data(z_stream *stream, uint8_t *dest, size_t dest_len,
|
||||||
ssize_t qemu_put_compression_data(QEMUFile *f, z_stream *stream,
|
ssize_t qemu_put_compression_data(QEMUFile *f, z_stream *stream,
|
||||||
const uint8_t *p, size_t size)
|
const uint8_t *p, size_t size)
|
||||||
{
|
{
|
||||||
@ -153,36 +178,39 @@ index 1479cddad9..21a3355ae2 100644
|
|||||||
if (blen < compressBound(size)) {
|
if (blen < compressBound(size)) {
|
||||||
return -1;
|
return -1;
|
||||||
diff --git a/migration/qemu-file.h b/migration/qemu-file.h
|
diff --git a/migration/qemu-file.h b/migration/qemu-file.h
|
||||||
index 3f36d4dc8c..67501fd9cf 100644
|
index fa13d04d78..914f1a63a8 100644
|
||||||
--- a/migration/qemu-file.h
|
--- a/migration/qemu-file.h
|
||||||
+++ b/migration/qemu-file.h
|
+++ b/migration/qemu-file.h
|
||||||
@@ -121,6 +121,7 @@ typedef struct QEMUFileHooks {
|
@@ -63,7 +63,9 @@ typedef struct QEMUFileHooks {
|
||||||
} QEMUFileHooks;
|
} QEMUFileHooks;
|
||||||
|
|
||||||
QEMUFile *qemu_fopen_ops(void *opaque, const QEMUFileOps *ops, bool has_ioc);
|
QEMUFile *qemu_file_new_input(QIOChannel *ioc);
|
||||||
+QEMUFile *qemu_fopen_ops_sized(void *opaque, const QEMUFileOps *ops, bool has_ioc, size_t buffer_size);
|
+QEMUFile *qemu_file_new_input_sized(QIOChannel *ioc, size_t buffer_size);
|
||||||
|
QEMUFile *qemu_file_new_output(QIOChannel *ioc);
|
||||||
|
+QEMUFile *qemu_file_new_output_sized(QIOChannel *ioc, size_t buffer_size);
|
||||||
void qemu_file_set_hooks(QEMUFile *f, const QEMUFileHooks *hooks);
|
void qemu_file_set_hooks(QEMUFile *f, const QEMUFileHooks *hooks);
|
||||||
int qemu_get_fd(QEMUFile *f);
|
|
||||||
int qemu_fclose(QEMUFile *f);
|
int qemu_fclose(QEMUFile *f);
|
||||||
|
|
||||||
diff --git a/migration/savevm-async.c b/migration/savevm-async.c
|
diff --git a/migration/savevm-async.c b/migration/savevm-async.c
|
||||||
index b9a43c56bc..0bc5799cf8 100644
|
index b3692739a0..e65a5e3482 100644
|
||||||
--- a/migration/savevm-async.c
|
--- a/migration/savevm-async.c
|
||||||
+++ b/migration/savevm-async.c
|
+++ b/migration/savevm-async.c
|
||||||
@@ -420,7 +420,7 @@ void qmp_savevm_start(bool has_statefile, const char *statefile, Error **errp)
|
@@ -367,7 +367,7 @@ void qmp_savevm_start(bool has_statefile, const char *statefile, Error **errp)
|
||||||
goto restart;
|
|
||||||
}
|
|
||||||
|
|
||||||
- snap_state.file = qemu_fopen_ops(&snap_state, &block_file_ops);
|
QIOChannel *ioc = QIO_CHANNEL(qio_channel_savevm_async_new(snap_state.target,
|
||||||
+ snap_state.file = qemu_fopen_ops_sized(&snap_state, &block_file_ops, false, 4 * 1024 * 1024);
|
&snap_state.bs_pos));
|
||||||
|
- snap_state.file = qemu_file_new_output(ioc);
|
||||||
|
+ snap_state.file = qemu_file_new_output_sized(ioc, 4 * 1024 * 1024);
|
||||||
|
|
||||||
if (!snap_state.file) {
|
if (!snap_state.file) {
|
||||||
error_set(errp, ERROR_CLASS_GENERIC_ERROR, "failed to open '%s'", statefile);
|
error_set(errp, ERROR_CLASS_GENERIC_ERROR, "failed to open '%s'", statefile);
|
||||||
@@ -573,7 +573,7 @@ int load_snapshot_from_blockdev(const char *filename, Error **errp)
|
@@ -500,7 +500,8 @@ int load_snapshot_from_blockdev(const char *filename, Error **errp)
|
||||||
blk_op_block_all(be, blocker);
|
blk_op_block_all(be, blocker);
|
||||||
|
|
||||||
/* restore the VM state */
|
/* restore the VM state */
|
||||||
- f = qemu_fopen_ops(be, &loadstate_file_ops);
|
- f = qemu_file_new_input(QIO_CHANNEL(qio_channel_savevm_async_new(be, &bs_pos)));
|
||||||
+ f = qemu_fopen_ops_sized(be, &loadstate_file_ops, false, 4 * 1024 * 1024);
|
+ f = qemu_file_new_input_sized(QIO_CHANNEL(qio_channel_savevm_async_new(be, &bs_pos)),
|
||||||
|
+ 4 * 1024 * 1024);
|
||||||
if (!f) {
|
if (!f) {
|
||||||
error_setg(errp, "Could not open VM state file");
|
error_setg(errp, "Could not open VM state file");
|
||||||
goto the_end;
|
goto the_end;
|
@ -13,7 +13,7 @@ Signed-off-by: Fabian Ebner <f.ebner@proxmox.com>
|
|||||||
create mode 100644 block/zeroinit.c
|
create mode 100644 block/zeroinit.c
|
||||||
|
|
||||||
diff --git a/block/meson.build b/block/meson.build
|
diff --git a/block/meson.build b/block/meson.build
|
||||||
index 0b2a60c99b..9451fc3ccd 100644
|
index 60bc305597..ad40c10b6a 100644
|
||||||
--- a/block/meson.build
|
--- a/block/meson.build
|
||||||
+++ b/block/meson.build
|
+++ b/block/meson.build
|
||||||
@@ -43,6 +43,7 @@ block_ss.add(files(
|
@@ -43,6 +43,7 @@ block_ss.add(files(
|
@ -14,12 +14,12 @@ Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
|
|||||||
2 files changed, 11 insertions(+)
|
2 files changed, 11 insertions(+)
|
||||||
|
|
||||||
diff --git a/qemu-options.hx b/qemu-options.hx
|
diff --git a/qemu-options.hx b/qemu-options.hx
|
||||||
index aeade4ef80..a26f0b0400 100644
|
index c2ca6e91b5..ab4734ef32 100644
|
||||||
--- a/qemu-options.hx
|
--- a/qemu-options.hx
|
||||||
+++ b/qemu-options.hx
|
+++ b/qemu-options.hx
|
||||||
@@ -1075,6 +1075,9 @@ DEFHEADING()
|
@@ -1118,6 +1118,9 @@ backend describes how QEMU handles the data.
|
||||||
|
|
||||||
DEFHEADING(Block device options:)
|
ERST
|
||||||
|
|
||||||
+DEF("id", HAS_ARG, QEMU_OPTION_id,
|
+DEF("id", HAS_ARG, QEMU_OPTION_id,
|
||||||
+ "-id n set the VMID", QEMU_ARCH_ALL)
|
+ "-id n set the VMID", QEMU_ARCH_ALL)
|
||||||
@ -28,10 +28,10 @@ index aeade4ef80..a26f0b0400 100644
|
|||||||
"-fda/-fdb file use 'file' as floppy disk 0/1 image\n", QEMU_ARCH_ALL)
|
"-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)
|
DEF("fdb", HAS_ARG, QEMU_OPTION_fdb, "", QEMU_ARCH_ALL)
|
||||||
diff --git a/softmmu/vl.c b/softmmu/vl.c
|
diff --git a/softmmu/vl.c b/softmmu/vl.c
|
||||||
index a3f2a3818c..4208142685 100644
|
index b8637c4262..39f149924e 100644
|
||||||
--- a/softmmu/vl.c
|
--- a/softmmu/vl.c
|
||||||
+++ b/softmmu/vl.c
|
+++ b/softmmu/vl.c
|
||||||
@@ -2785,6 +2785,7 @@ void qemu_init(int argc, char **argv, char **envp)
|
@@ -2620,6 +2620,7 @@ void qemu_init(int argc, char **argv, char **envp)
|
||||||
MachineClass *machine_class;
|
MachineClass *machine_class;
|
||||||
bool userconfig = true;
|
bool userconfig = true;
|
||||||
FILE *vmstate_dump_file = NULL;
|
FILE *vmstate_dump_file = NULL;
|
||||||
@ -39,7 +39,7 @@ index a3f2a3818c..4208142685 100644
|
|||||||
|
|
||||||
qemu_add_opts(&qemu_drive_opts);
|
qemu_add_opts(&qemu_drive_opts);
|
||||||
qemu_add_drive_opts(&qemu_legacy_drive_opts);
|
qemu_add_drive_opts(&qemu_legacy_drive_opts);
|
||||||
@@ -3420,6 +3421,13 @@ void qemu_init(int argc, char **argv, char **envp)
|
@@ -3245,6 +3246,13 @@ void qemu_init(int argc, char **argv, char **envp)
|
||||||
machine_parse_property_opt(qemu_find_opts("smp-opts"),
|
machine_parse_property_opt(qemu_find_opts("smp-opts"),
|
||||||
"smp", optarg);
|
"smp", optarg);
|
||||||
break;
|
break;
|
@ -13,10 +13,10 @@ Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
|
|||||||
2 files changed, 42 insertions(+), 20 deletions(-)
|
2 files changed, 42 insertions(+), 20 deletions(-)
|
||||||
|
|
||||||
diff --git a/block/file-posix.c b/block/file-posix.c
|
diff --git a/block/file-posix.c b/block/file-posix.c
|
||||||
index e5bf5d59bf..b013668dce 100644
|
index 3d60b80286..49ee1db5f9 100644
|
||||||
--- a/block/file-posix.c
|
--- a/block/file-posix.c
|
||||||
+++ b/block/file-posix.c
|
+++ b/block/file-posix.c
|
||||||
@@ -2461,6 +2461,7 @@ raw_co_create(BlockdevCreateOptions *options, Error **errp)
|
@@ -2475,6 +2475,7 @@ raw_co_create(BlockdevCreateOptions *options, Error **errp)
|
||||||
int fd;
|
int fd;
|
||||||
uint64_t perm, shared;
|
uint64_t perm, shared;
|
||||||
int result = 0;
|
int result = 0;
|
||||||
@ -24,7 +24,7 @@ index e5bf5d59bf..b013668dce 100644
|
|||||||
|
|
||||||
/* Validate options and set default values */
|
/* Validate options and set default values */
|
||||||
assert(options->driver == BLOCKDEV_DRIVER_FILE);
|
assert(options->driver == BLOCKDEV_DRIVER_FILE);
|
||||||
@@ -2501,19 +2502,22 @@ raw_co_create(BlockdevCreateOptions *options, Error **errp)
|
@@ -2515,19 +2516,22 @@ raw_co_create(BlockdevCreateOptions *options, Error **errp)
|
||||||
perm = BLK_PERM_WRITE | BLK_PERM_RESIZE;
|
perm = BLK_PERM_WRITE | BLK_PERM_RESIZE;
|
||||||
shared = BLK_PERM_ALL & ~BLK_PERM_RESIZE;
|
shared = BLK_PERM_ALL & ~BLK_PERM_RESIZE;
|
||||||
|
|
||||||
@ -59,7 +59,7 @@ index e5bf5d59bf..b013668dce 100644
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Clear the file by truncating it to 0 */
|
/* Clear the file by truncating it to 0 */
|
||||||
@@ -2567,13 +2571,15 @@ raw_co_create(BlockdevCreateOptions *options, Error **errp)
|
@@ -2581,13 +2585,15 @@ raw_co_create(BlockdevCreateOptions *options, Error **errp)
|
||||||
}
|
}
|
||||||
|
|
||||||
out_unlock:
|
out_unlock:
|
||||||
@ -82,7 +82,7 @@ index e5bf5d59bf..b013668dce 100644
|
|||||||
}
|
}
|
||||||
|
|
||||||
out_close:
|
out_close:
|
||||||
@@ -2598,6 +2604,7 @@ static int coroutine_fn raw_co_create_opts(BlockDriver *drv,
|
@@ -2612,6 +2618,7 @@ static int coroutine_fn raw_co_create_opts(BlockDriver *drv,
|
||||||
PreallocMode prealloc;
|
PreallocMode prealloc;
|
||||||
char *buf = NULL;
|
char *buf = NULL;
|
||||||
Error *local_err = NULL;
|
Error *local_err = NULL;
|
||||||
@ -90,7 +90,7 @@ index e5bf5d59bf..b013668dce 100644
|
|||||||
|
|
||||||
/* Skip file: protocol prefix */
|
/* Skip file: protocol prefix */
|
||||||
strstart(filename, "file:", &filename);
|
strstart(filename, "file:", &filename);
|
||||||
@@ -2620,6 +2627,18 @@ static int coroutine_fn raw_co_create_opts(BlockDriver *drv,
|
@@ -2634,6 +2641,18 @@ static int coroutine_fn raw_co_create_opts(BlockDriver *drv,
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -109,7 +109,7 @@ index e5bf5d59bf..b013668dce 100644
|
|||||||
options = (BlockdevCreateOptions) {
|
options = (BlockdevCreateOptions) {
|
||||||
.driver = BLOCKDEV_DRIVER_FILE,
|
.driver = BLOCKDEV_DRIVER_FILE,
|
||||||
.u.file = {
|
.u.file = {
|
||||||
@@ -2631,6 +2650,8 @@ static int coroutine_fn raw_co_create_opts(BlockDriver *drv,
|
@@ -2645,6 +2664,8 @@ static int coroutine_fn raw_co_create_opts(BlockDriver *drv,
|
||||||
.nocow = nocow,
|
.nocow = nocow,
|
||||||
.has_extent_size_hint = has_extent_size_hint,
|
.has_extent_size_hint = has_extent_size_hint,
|
||||||
.extent_size_hint = extent_size_hint,
|
.extent_size_hint = extent_size_hint,
|
||||||
@ -119,10 +119,10 @@ index e5bf5d59bf..b013668dce 100644
|
|||||||
};
|
};
|
||||||
return raw_co_create(&options, errp);
|
return raw_co_create(&options, errp);
|
||||||
diff --git a/qapi/block-core.json b/qapi/block-core.json
|
diff --git a/qapi/block-core.json b/qapi/block-core.json
|
||||||
index fb25c2b245..564b6b43f7 100644
|
index e1857e7094..ddac91e8f6 100644
|
||||||
--- a/qapi/block-core.json
|
--- a/qapi/block-core.json
|
||||||
+++ b/qapi/block-core.json
|
+++ b/qapi/block-core.json
|
||||||
@@ -4484,7 +4484,8 @@
|
@@ -4537,7 +4537,8 @@
|
||||||
'size': 'size',
|
'size': 'size',
|
||||||
'*preallocation': 'PreallocMode',
|
'*preallocation': 'PreallocMode',
|
||||||
'*nocow': 'bool',
|
'*nocow': 'bool',
|
@ -26,10 +26,10 @@ Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
|
|||||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
diff --git a/hw/core/machine.c b/hw/core/machine.c
|
diff --git a/hw/core/machine.c b/hw/core/machine.c
|
||||||
index 1e23fdc14b..8a50445ee8 100644
|
index a673302cce..fa424440bd 100644
|
||||||
--- a/hw/core/machine.c
|
--- a/hw/core/machine.c
|
||||||
+++ b/hw/core/machine.c
|
+++ b/hw/core/machine.c
|
||||||
@@ -118,7 +118,8 @@ GlobalProperty hw_compat_4_0[] = {
|
@@ -127,7 +127,8 @@ GlobalProperty hw_compat_4_0[] = {
|
||||||
{ "virtio-vga", "edid", "false" },
|
{ "virtio-vga", "edid", "false" },
|
||||||
{ "virtio-gpu-device", "edid", "false" },
|
{ "virtio-gpu-device", "edid", "false" },
|
||||||
{ "virtio-device", "use-started", "false" },
|
{ "virtio-device", "use-started", "false" },
|
@ -36,7 +36,7 @@ index 76fff60a6b..ec9201fb9a 100644
|
|||||||
|
|
||||||
if (mc->default_cpu_type) {
|
if (mc->default_cpu_type) {
|
||||||
diff --git a/include/hw/boards.h b/include/hw/boards.h
|
diff --git a/include/hw/boards.h b/include/hw/boards.h
|
||||||
index c92ac8815c..572d911ed4 100644
|
index 7b416c9787..8ae15c51aa 100644
|
||||||
--- a/include/hw/boards.h
|
--- a/include/hw/boards.h
|
||||||
+++ b/include/hw/boards.h
|
+++ b/include/hw/boards.h
|
||||||
@@ -230,6 +230,8 @@ struct MachineClass {
|
@@ -230,6 +230,8 @@ struct MachineClass {
|
||||||
@ -49,10 +49,10 @@ index c92ac8815c..572d911ed4 100644
|
|||||||
void (*reset)(MachineState *state);
|
void (*reset)(MachineState *state);
|
||||||
void (*wakeup)(MachineState *state);
|
void (*wakeup)(MachineState *state);
|
||||||
diff --git a/qapi/machine.json b/qapi/machine.json
|
diff --git a/qapi/machine.json b/qapi/machine.json
|
||||||
index ca133e68ce..39ba204b52 100644
|
index 555458f785..d868e4d31d 100644
|
||||||
--- a/qapi/machine.json
|
--- a/qapi/machine.json
|
||||||
+++ b/qapi/machine.json
|
+++ b/qapi/machine.json
|
||||||
@@ -158,6 +158,8 @@
|
@@ -157,6 +157,8 @@
|
||||||
#
|
#
|
||||||
# @default-ram-id: the default ID of initial RAM memory backend (since 5.2)
|
# @default-ram-id: the default ID of initial RAM memory backend (since 5.2)
|
||||||
#
|
#
|
||||||
@ -61,7 +61,7 @@ index ca133e68ce..39ba204b52 100644
|
|||||||
# Since: 1.2
|
# Since: 1.2
|
||||||
##
|
##
|
||||||
{ 'struct': 'MachineInfo',
|
{ 'struct': 'MachineInfo',
|
||||||
@@ -165,7 +167,7 @@
|
@@ -164,7 +166,7 @@
|
||||||
'*is-default': 'bool', '*is-current': 'bool', 'cpu-max': 'int',
|
'*is-default': 'bool', '*is-current': 'bool', 'cpu-max': 'int',
|
||||||
'hotpluggable-cpus': 'bool', 'numa-mem-supported': 'bool',
|
'hotpluggable-cpus': 'bool', 'numa-mem-supported': 'bool',
|
||||||
'deprecated': 'bool', '*default-cpu-type': 'str',
|
'deprecated': 'bool', '*default-cpu-type': 'str',
|
||||||
@ -71,10 +71,10 @@ index ca133e68ce..39ba204b52 100644
|
|||||||
##
|
##
|
||||||
# @query-machines:
|
# @query-machines:
|
||||||
diff --git a/softmmu/vl.c b/softmmu/vl.c
|
diff --git a/softmmu/vl.c b/softmmu/vl.c
|
||||||
index 4208142685..37d85f1b96 100644
|
index 39f149924e..0d233d55f3 100644
|
||||||
--- a/softmmu/vl.c
|
--- a/softmmu/vl.c
|
||||||
+++ b/softmmu/vl.c
|
+++ b/softmmu/vl.c
|
||||||
@@ -1659,6 +1659,7 @@ static const QEMUOption *lookup_opt(int argc, char **argv,
|
@@ -1580,6 +1580,7 @@ static const QEMUOption *lookup_opt(int argc, char **argv,
|
||||||
static MachineClass *select_machine(QDict *qdict, Error **errp)
|
static MachineClass *select_machine(QDict *qdict, Error **errp)
|
||||||
{
|
{
|
||||||
const char *optarg = qdict_get_try_str(qdict, "type");
|
const char *optarg = qdict_get_try_str(qdict, "type");
|
||||||
@ -82,7 +82,7 @@ index 4208142685..37d85f1b96 100644
|
|||||||
GSList *machines = object_class_get_list(TYPE_MACHINE, false);
|
GSList *machines = object_class_get_list(TYPE_MACHINE, false);
|
||||||
MachineClass *machine_class;
|
MachineClass *machine_class;
|
||||||
Error *local_err = NULL;
|
Error *local_err = NULL;
|
||||||
@@ -1676,6 +1677,11 @@ static MachineClass *select_machine(QDict *qdict, Error **errp)
|
@@ -1597,6 +1598,11 @@ static MachineClass *select_machine(QDict *qdict, Error **errp)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -94,7 +94,7 @@ index 4208142685..37d85f1b96 100644
|
|||||||
g_slist_free(machines);
|
g_slist_free(machines);
|
||||||
if (local_err) {
|
if (local_err) {
|
||||||
error_append_hint(&local_err, "Use -machine help to list supported machines\n");
|
error_append_hint(&local_err, "Use -machine help to list supported machines\n");
|
||||||
@@ -3362,12 +3368,31 @@ void qemu_init(int argc, char **argv, char **envp)
|
@@ -3187,12 +3193,31 @@ void qemu_init(int argc, char **argv, char **envp)
|
||||||
case QEMU_OPTION_machine:
|
case QEMU_OPTION_machine:
|
||||||
{
|
{
|
||||||
bool help;
|
bool help;
|
@ -25,11 +25,11 @@ Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
|
|||||||
1 file changed, 4 insertions(+), 4 deletions(-)
|
1 file changed, 4 insertions(+), 4 deletions(-)
|
||||||
|
|
||||||
diff --git a/block/backup.c b/block/backup.c
|
diff --git a/block/backup.c b/block/backup.c
|
||||||
index 5cfd0b999c..07b899035c 100644
|
index b2b649e305..b6fa9e8a69 100644
|
||||||
--- a/block/backup.c
|
--- a/block/backup.c
|
||||||
+++ b/block/backup.c
|
+++ b/block/backup.c
|
||||||
@@ -239,8 +239,8 @@ static void backup_init_bcs_bitmap(BackupBlockJob *job)
|
@@ -237,8 +237,8 @@ static void backup_init_bcs_bitmap(BackupBlockJob *job)
|
||||||
assert(ret);
|
true);
|
||||||
} else if (job->sync_mode == MIRROR_SYNC_MODE_TOP) {
|
} else if (job->sync_mode == MIRROR_SYNC_MODE_TOP) {
|
||||||
/*
|
/*
|
||||||
- * We can't hog the coroutine to initialize this thoroughly.
|
- * We can't hog the coroutine to initialize this thoroughly.
|
||||||
@ -39,7 +39,7 @@ index 5cfd0b999c..07b899035c 100644
|
|||||||
*/
|
*/
|
||||||
block_copy_set_skip_unallocated(job->bcs, true);
|
block_copy_set_skip_unallocated(job->bcs, true);
|
||||||
}
|
}
|
||||||
@@ -254,8 +254,6 @@ static int coroutine_fn backup_run(Job *job, Error **errp)
|
@@ -252,8 +252,6 @@ static int coroutine_fn backup_run(Job *job, Error **errp)
|
||||||
BackupBlockJob *s = container_of(job, BackupBlockJob, common.job);
|
BackupBlockJob *s = container_of(job, BackupBlockJob, common.job);
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
@ -48,7 +48,7 @@ index 5cfd0b999c..07b899035c 100644
|
|||||||
if (s->sync_mode == MIRROR_SYNC_MODE_TOP) {
|
if (s->sync_mode == MIRROR_SYNC_MODE_TOP) {
|
||||||
int64_t offset = 0;
|
int64_t offset = 0;
|
||||||
int64_t count;
|
int64_t count;
|
||||||
@@ -494,6 +492,8 @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs,
|
@@ -492,6 +490,8 @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs,
|
||||||
block_job_add_bdrv(&job->common, "target", target, 0, BLK_PERM_ALL,
|
block_job_add_bdrv(&job->common, "target", target, 0, BLK_PERM_ALL,
|
||||||
&error_abort);
|
&error_abort);
|
||||||
|
|
@ -9,18 +9,18 @@ Signed-off-by: Fabian Ebner <f.ebner@proxmox.com>
|
|||||||
---
|
---
|
||||||
block/meson.build | 2 +
|
block/meson.build | 2 +
|
||||||
meson.build | 5 +
|
meson.build | 5 +
|
||||||
vma-reader.c | 860 ++++++++++++++++++++++++++++++++++++++++++++++
|
vma-reader.c | 859 ++++++++++++++++++++++++++++++++++++++++++++++
|
||||||
vma-writer.c | 791 ++++++++++++++++++++++++++++++++++++++++++
|
vma-writer.c | 791 ++++++++++++++++++++++++++++++++++++++++++
|
||||||
vma.c | 850 +++++++++++++++++++++++++++++++++++++++++++++
|
vma.c | 849 +++++++++++++++++++++++++++++++++++++++++++++
|
||||||
vma.h | 150 ++++++++
|
vma.h | 150 ++++++++
|
||||||
6 files changed, 2658 insertions(+)
|
6 files changed, 2656 insertions(+)
|
||||||
create mode 100644 vma-reader.c
|
create mode 100644 vma-reader.c
|
||||||
create mode 100644 vma-writer.c
|
create mode 100644 vma-writer.c
|
||||||
create mode 100644 vma.c
|
create mode 100644 vma.c
|
||||||
create mode 100644 vma.h
|
create mode 100644 vma.h
|
||||||
|
|
||||||
diff --git a/block/meson.build b/block/meson.build
|
diff --git a/block/meson.build b/block/meson.build
|
||||||
index 9451fc3ccd..819eb80951 100644
|
index ad40c10b6a..3a0b84bc11 100644
|
||||||
--- a/block/meson.build
|
--- a/block/meson.build
|
||||||
+++ b/block/meson.build
|
+++ b/block/meson.build
|
||||||
@@ -46,6 +46,8 @@ block_ss.add(files(
|
@@ -46,6 +46,8 @@ block_ss.add(files(
|
||||||
@ -33,10 +33,10 @@ index 9451fc3ccd..819eb80951 100644
|
|||||||
|
|
||||||
if get_option('qcow1').allowed()
|
if get_option('qcow1').allowed()
|
||||||
diff --git a/meson.build b/meson.build
|
diff --git a/meson.build b/meson.build
|
||||||
index 861de93c4f..96a91b95e4 100644
|
index d5230eadd6..ffff66c0cc 100644
|
||||||
--- a/meson.build
|
--- a/meson.build
|
||||||
+++ b/meson.build
|
+++ b/meson.build
|
||||||
@@ -1267,6 +1267,8 @@ keyutils = dependency('libkeyutils', required: false,
|
@@ -1462,6 +1462,8 @@ keyutils = dependency('libkeyutils', required: false,
|
||||||
|
|
||||||
has_gettid = cc.has_function('gettid')
|
has_gettid = cc.has_function('gettid')
|
||||||
|
|
||||||
@ -45,7 +45,7 @@ index 861de93c4f..96a91b95e4 100644
|
|||||||
# libselinux
|
# libselinux
|
||||||
selinux = dependency('libselinux',
|
selinux = dependency('libselinux',
|
||||||
required: get_option('selinux'),
|
required: get_option('selinux'),
|
||||||
@@ -3359,6 +3361,9 @@ if have_tools
|
@@ -3607,6 +3609,9 @@ if have_tools
|
||||||
dependencies: [blockdev, qemuutil, gnutls, selinux],
|
dependencies: [blockdev, qemuutil, gnutls, selinux],
|
||||||
install: true)
|
install: true)
|
||||||
|
|
||||||
@ -57,10 +57,10 @@ index 861de93c4f..96a91b95e4 100644
|
|||||||
subdir('contrib/elf2dmp')
|
subdir('contrib/elf2dmp')
|
||||||
diff --git a/vma-reader.c b/vma-reader.c
|
diff --git a/vma-reader.c b/vma-reader.c
|
||||||
new file mode 100644
|
new file mode 100644
|
||||||
index 0000000000..4f4ee2b47b
|
index 0000000000..e65f1e8415
|
||||||
--- /dev/null
|
--- /dev/null
|
||||||
+++ b/vma-reader.c
|
+++ b/vma-reader.c
|
||||||
@@ -0,0 +1,860 @@
|
@@ -0,0 +1,859 @@
|
||||||
+/*
|
+/*
|
||||||
+ * VMA: Virtual Machine Archive
|
+ * VMA: Virtual Machine Archive
|
||||||
+ *
|
+ *
|
||||||
@ -78,7 +78,6 @@ index 0000000000..4f4ee2b47b
|
|||||||
+#include <glib.h>
|
+#include <glib.h>
|
||||||
+#include <uuid/uuid.h>
|
+#include <uuid/uuid.h>
|
||||||
+
|
+
|
||||||
+#include "qemu-common.h"
|
|
||||||
+#include "qemu/timer.h"
|
+#include "qemu/timer.h"
|
||||||
+#include "qemu/ratelimit.h"
|
+#include "qemu/ratelimit.h"
|
||||||
+#include "vma.h"
|
+#include "vma.h"
|
||||||
@ -589,7 +588,7 @@ index 0000000000..4f4ee2b47b
|
|||||||
+ }
|
+ }
|
||||||
+ }
|
+ }
|
||||||
+ } else {
|
+ } else {
|
||||||
+ int res = blk_pwrite(target, sector_num * BDRV_SECTOR_SIZE, buf, nb_sectors * BDRV_SECTOR_SIZE, 0);
|
+ int res = blk_pwrite(target, sector_num * BDRV_SECTOR_SIZE, nb_sectors * BDRV_SECTOR_SIZE, buf, 0);
|
||||||
+ if (res < 0) {
|
+ if (res < 0) {
|
||||||
+ error_setg(errp, "blk_pwrite to %s failed (%d)",
|
+ error_setg(errp, "blk_pwrite to %s failed (%d)",
|
||||||
+ bdrv_get_device_name(blk_bs(target)), res);
|
+ bdrv_get_device_name(blk_bs(target)), res);
|
||||||
@ -1720,10 +1719,10 @@ index 0000000000..df4b20793d
|
|||||||
+}
|
+}
|
||||||
diff --git a/vma.c b/vma.c
|
diff --git a/vma.c b/vma.c
|
||||||
new file mode 100644
|
new file mode 100644
|
||||||
index 0000000000..91612d50a2
|
index 0000000000..e8dffb43e0
|
||||||
--- /dev/null
|
--- /dev/null
|
||||||
+++ b/vma.c
|
+++ b/vma.c
|
||||||
@@ -0,0 +1,850 @@
|
@@ -0,0 +1,849 @@
|
||||||
+/*
|
+/*
|
||||||
+ * VMA: Virtual Machine Archive
|
+ * VMA: Virtual Machine Archive
|
||||||
+ *
|
+ *
|
||||||
@ -1741,7 +1740,6 @@ index 0000000000..91612d50a2
|
|||||||
+#include <glib.h>
|
+#include <glib.h>
|
||||||
+
|
+
|
||||||
+#include "vma.h"
|
+#include "vma.h"
|
||||||
+#include "qemu-common.h"
|
|
||||||
+#include "qemu/module.h"
|
+#include "qemu/module.h"
|
||||||
+#include "qemu/error-report.h"
|
+#include "qemu/error-report.h"
|
||||||
+#include "qemu/main-loop.h"
|
+#include "qemu/main-loop.h"
|
@ -10,20 +10,20 @@ Subject: [PATCH] PVE-Backup: add backup-dump block driver
|
|||||||
|
|
||||||
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
|
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
|
||||||
---
|
---
|
||||||
block/backup-dump.c | 168 +++++++++++++++++++++++++++++++
|
block/backup-dump.c | 167 +++++++++++++++++++++++++++++++
|
||||||
block/backup.c | 30 ++----
|
block/backup.c | 30 ++----
|
||||||
block/meson.build | 1 +
|
block/meson.build | 1 +
|
||||||
include/block/block_int-common.h | 35 +++++++
|
include/block/block_int-common.h | 35 +++++++
|
||||||
job.c | 3 +-
|
job.c | 3 +-
|
||||||
5 files changed, 214 insertions(+), 23 deletions(-)
|
5 files changed, 213 insertions(+), 23 deletions(-)
|
||||||
create mode 100644 block/backup-dump.c
|
create mode 100644 block/backup-dump.c
|
||||||
|
|
||||||
diff --git a/block/backup-dump.c b/block/backup-dump.c
|
diff --git a/block/backup-dump.c b/block/backup-dump.c
|
||||||
new file mode 100644
|
new file mode 100644
|
||||||
index 0000000000..93d7f46950
|
index 0000000000..04718a94e2
|
||||||
--- /dev/null
|
--- /dev/null
|
||||||
+++ b/block/backup-dump.c
|
+++ b/block/backup-dump.c
|
||||||
@@ -0,0 +1,168 @@
|
@@ -0,0 +1,167 @@
|
||||||
+/*
|
+/*
|
||||||
+ * BlockDriver to send backup data stream to a callback function
|
+ * BlockDriver to send backup data stream to a callback function
|
||||||
+ *
|
+ *
|
||||||
@ -35,7 +35,6 @@ index 0000000000..93d7f46950
|
|||||||
+ */
|
+ */
|
||||||
+
|
+
|
||||||
+#include "qemu/osdep.h"
|
+#include "qemu/osdep.h"
|
||||||
+#include "qemu-common.h"
|
|
||||||
+#include "qom/object_interfaces.h"
|
+#include "qom/object_interfaces.h"
|
||||||
+#include "block/block_int.h"
|
+#include "block/block_int.h"
|
||||||
+
|
+
|
||||||
@ -193,7 +192,7 @@ index 0000000000..93d7f46950
|
|||||||
+ return bs;
|
+ return bs;
|
||||||
+}
|
+}
|
||||||
diff --git a/block/backup.c b/block/backup.c
|
diff --git a/block/backup.c b/block/backup.c
|
||||||
index 07b899035c..7b5d02f580 100644
|
index b6fa9e8a69..789f8b7799 100644
|
||||||
--- a/block/backup.c
|
--- a/block/backup.c
|
||||||
+++ b/block/backup.c
|
+++ b/block/backup.c
|
||||||
@@ -29,28 +29,6 @@
|
@@ -29,28 +29,6 @@
|
||||||
@ -225,7 +224,7 @@ index 07b899035c..7b5d02f580 100644
|
|||||||
static const BlockJobDriver backup_job_driver;
|
static const BlockJobDriver backup_job_driver;
|
||||||
|
|
||||||
static void backup_cleanup_sync_bitmap(BackupBlockJob *job, int ret)
|
static void backup_cleanup_sync_bitmap(BackupBlockJob *job, int ret)
|
||||||
@@ -456,6 +434,14 @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs,
|
@@ -454,6 +432,14 @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs,
|
||||||
}
|
}
|
||||||
|
|
||||||
cluster_size = block_copy_cluster_size(bcs);
|
cluster_size = block_copy_cluster_size(bcs);
|
||||||
@ -241,7 +240,7 @@ index 07b899035c..7b5d02f580 100644
|
|||||||
if (perf->max_chunk && perf->max_chunk < cluster_size) {
|
if (perf->max_chunk && perf->max_chunk < cluster_size) {
|
||||||
error_setg(errp, "Required max-chunk (%" PRIi64 ") is less than backup "
|
error_setg(errp, "Required max-chunk (%" PRIi64 ") is less than backup "
|
||||||
diff --git a/block/meson.build b/block/meson.build
|
diff --git a/block/meson.build b/block/meson.build
|
||||||
index 819eb80951..067708b7c0 100644
|
index 3a0b84bc11..7f22e7f177 100644
|
||||||
--- a/block/meson.build
|
--- a/block/meson.build
|
||||||
+++ b/block/meson.build
|
+++ b/block/meson.build
|
||||||
@@ -4,6 +4,7 @@ block_ss.add(files(
|
@@ -4,6 +4,7 @@ block_ss.add(files(
|
@ -30,7 +30,7 @@ Signed-off-by: Fabian Ebner <f.ebner@proxmox.com>
|
|||||||
create mode 100644 pve-backup.c
|
create mode 100644 pve-backup.c
|
||||||
|
|
||||||
diff --git a/block/meson.build b/block/meson.build
|
diff --git a/block/meson.build b/block/meson.build
|
||||||
index 067708b7c0..42aac96dbb 100644
|
index 7f22e7f177..2783b77e9c 100644
|
||||||
--- a/block/meson.build
|
--- a/block/meson.build
|
||||||
+++ b/block/meson.build
|
+++ b/block/meson.build
|
||||||
@@ -48,6 +48,11 @@ block_ss.add(files(
|
@@ -48,6 +48,11 @@ block_ss.add(files(
|
||||||
@ -87,7 +87,7 @@ index bfb3c043a0..89ca64444d 100644
|
|||||||
+ hmp_handle_error(mon, error);
|
+ hmp_handle_error(mon, error);
|
||||||
+}
|
+}
|
||||||
diff --git a/blockdev.c b/blockdev.c
|
diff --git a/blockdev.c b/blockdev.c
|
||||||
index 1af5a1fcb2..9916a72334 100644
|
index ce62a9b439..1600b24eab 100644
|
||||||
--- a/blockdev.c
|
--- a/blockdev.c
|
||||||
+++ b/blockdev.c
|
+++ b/blockdev.c
|
||||||
@@ -36,6 +36,7 @@
|
@@ -36,6 +36,7 @@
|
||||||
@ -99,7 +99,7 @@ index 1af5a1fcb2..9916a72334 100644
|
|||||||
#include "monitor/monitor.h"
|
#include "monitor/monitor.h"
|
||||||
#include "qemu/error-report.h"
|
#include "qemu/error-report.h"
|
||||||
diff --git a/hmp-commands-info.hx b/hmp-commands-info.hx
|
diff --git a/hmp-commands-info.hx b/hmp-commands-info.hx
|
||||||
index 925e680e5a..d9b787d2c6 100644
|
index 97b88eaaad..92a8867afb 100644
|
||||||
--- a/hmp-commands-info.hx
|
--- a/hmp-commands-info.hx
|
||||||
+++ b/hmp-commands-info.hx
|
+++ b/hmp-commands-info.hx
|
||||||
@@ -484,6 +484,20 @@ SRST
|
@@ -484,6 +484,20 @@ SRST
|
||||||
@ -124,10 +124,10 @@ index 925e680e5a..d9b787d2c6 100644
|
|||||||
{
|
{
|
||||||
.name = "usernet",
|
.name = "usernet",
|
||||||
diff --git a/hmp-commands.hx b/hmp-commands.hx
|
diff --git a/hmp-commands.hx b/hmp-commands.hx
|
||||||
index 7f0ac498c4..994445f301 100644
|
index bbcc73e942..97f24942b3 100644
|
||||||
--- a/hmp-commands.hx
|
--- a/hmp-commands.hx
|
||||||
+++ b/hmp-commands.hx
|
+++ b/hmp-commands.hx
|
||||||
@@ -99,6 +99,35 @@ ERST
|
@@ -101,6 +101,35 @@ ERST
|
||||||
SRST
|
SRST
|
||||||
``block_stream``
|
``block_stream``
|
||||||
Copy data from a backing file into a block device.
|
Copy data from a backing file into a block device.
|
||||||
@ -164,7 +164,7 @@ index 7f0ac498c4..994445f301 100644
|
|||||||
|
|
||||||
{
|
{
|
||||||
diff --git a/include/monitor/hmp.h b/include/monitor/hmp.h
|
diff --git a/include/monitor/hmp.h b/include/monitor/hmp.h
|
||||||
index 3a39ba41b5..d269b4c99c 100644
|
index 55067beff1..5a98d2d927 100644
|
||||||
--- a/include/monitor/hmp.h
|
--- a/include/monitor/hmp.h
|
||||||
+++ b/include/monitor/hmp.h
|
+++ b/include/monitor/hmp.h
|
||||||
@@ -30,6 +30,7 @@ void hmp_info_savevm(Monitor *mon, const QDict *qdict);
|
@@ -30,6 +30,7 @@ void hmp_info_savevm(Monitor *mon, const QDict *qdict);
|
||||||
@ -185,10 +185,10 @@ index 3a39ba41b5..d269b4c99c 100644
|
|||||||
void hmp_device_add(Monitor *mon, const QDict *qdict);
|
void hmp_device_add(Monitor *mon, const QDict *qdict);
|
||||||
void hmp_device_del(Monitor *mon, const QDict *qdict);
|
void hmp_device_del(Monitor *mon, const QDict *qdict);
|
||||||
diff --git a/meson.build b/meson.build
|
diff --git a/meson.build b/meson.build
|
||||||
index 96a91b95e4..76fcb23299 100644
|
index ffff66c0cc..0bc2fb5b10 100644
|
||||||
--- a/meson.build
|
--- a/meson.build
|
||||||
+++ b/meson.build
|
+++ b/meson.build
|
||||||
@@ -1268,6 +1268,7 @@ keyutils = dependency('libkeyutils', required: false,
|
@@ -1463,6 +1463,7 @@ keyutils = dependency('libkeyutils', required: false,
|
||||||
has_gettid = cc.has_function('gettid')
|
has_gettid = cc.has_function('gettid')
|
||||||
|
|
||||||
libuuid = cc.find_library('uuid', required: true)
|
libuuid = cc.find_library('uuid', required: true)
|
||||||
@ -197,10 +197,10 @@ index 96a91b95e4..76fcb23299 100644
|
|||||||
# libselinux
|
# libselinux
|
||||||
selinux = dependency('libselinux',
|
selinux = dependency('libselinux',
|
||||||
diff --git a/monitor/hmp-cmds.c b/monitor/hmp-cmds.c
|
diff --git a/monitor/hmp-cmds.c b/monitor/hmp-cmds.c
|
||||||
index c64b959738..ef654221c4 100644
|
index 1507180990..1168773da7 100644
|
||||||
--- a/monitor/hmp-cmds.c
|
--- a/monitor/hmp-cmds.c
|
||||||
+++ b/monitor/hmp-cmds.c
|
+++ b/monitor/hmp-cmds.c
|
||||||
@@ -195,6 +195,50 @@ void hmp_info_mice(Monitor *mon, const QDict *qdict)
|
@@ -197,6 +197,50 @@ void hmp_info_mice(Monitor *mon, const QDict *qdict)
|
||||||
qapi_free_MouseInfoList(mice_list);
|
qapi_free_MouseInfoList(mice_list);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1464,12 +1464,12 @@ index 0000000000..88f5ee133f
|
|||||||
+ return info;
|
+ return info;
|
||||||
+}
|
+}
|
||||||
diff --git a/qapi/block-core.json b/qapi/block-core.json
|
diff --git a/qapi/block-core.json b/qapi/block-core.json
|
||||||
index 564b6b43f7..ffcc25367b 100644
|
index ddac91e8f6..90ad07b7ee 100644
|
||||||
--- a/qapi/block-core.json
|
--- a/qapi/block-core.json
|
||||||
+++ b/qapi/block-core.json
|
+++ b/qapi/block-core.json
|
||||||
@@ -744,6 +744,115 @@
|
@@ -740,6 +740,115 @@
|
||||||
{ 'command': 'query-block', 'returns': ['BlockInfo'] }
|
{ 'command': 'query-block', 'returns': ['BlockInfo'],
|
||||||
|
'allow-preconfig': true }
|
||||||
|
|
||||||
+##
|
+##
|
||||||
+# @BackupStatus:
|
+# @BackupStatus:
|
||||||
@ -1584,10 +1584,10 @@ index 564b6b43f7..ffcc25367b 100644
|
|||||||
# @BlockDeviceTimedStats:
|
# @BlockDeviceTimedStats:
|
||||||
#
|
#
|
||||||
diff --git a/qapi/common.json b/qapi/common.json
|
diff --git a/qapi/common.json b/qapi/common.json
|
||||||
index 412cc4f5ae..3e7a77ea66 100644
|
index 356db3f670..aae8a3b682 100644
|
||||||
--- a/qapi/common.json
|
--- a/qapi/common.json
|
||||||
+++ b/qapi/common.json
|
+++ b/qapi/common.json
|
||||||
@@ -208,3 +208,16 @@
|
@@ -206,3 +206,16 @@
|
||||||
##
|
##
|
||||||
{ 'struct': 'HumanReadableText',
|
{ 'struct': 'HumanReadableText',
|
||||||
'data': { 'human-readable-text': 'str' } }
|
'data': { 'human-readable-text': 'str' } }
|
||||||
@ -1605,7 +1605,7 @@ index 412cc4f5ae..3e7a77ea66 100644
|
|||||||
+##
|
+##
|
||||||
+{ 'struct': 'UuidInfo', 'data': {'UUID': 'str'} }
|
+{ 'struct': 'UuidInfo', 'data': {'UUID': 'str'} }
|
||||||
diff --git a/qapi/machine.json b/qapi/machine.json
|
diff --git a/qapi/machine.json b/qapi/machine.json
|
||||||
index 39ba204b52..091aafeff7 100644
|
index d868e4d31d..a63d9a078d 100644
|
||||||
--- a/qapi/machine.json
|
--- a/qapi/machine.json
|
||||||
+++ b/qapi/machine.json
|
+++ b/qapi/machine.json
|
||||||
@@ -4,6 +4,8 @@
|
@@ -4,6 +4,8 @@
|
||||||
@ -1617,7 +1617,7 @@ index 39ba204b52..091aafeff7 100644
|
|||||||
##
|
##
|
||||||
# = Machines
|
# = Machines
|
||||||
##
|
##
|
||||||
@@ -227,19 +229,6 @@
|
@@ -226,19 +228,6 @@
|
||||||
##
|
##
|
||||||
{ 'command': 'query-target', 'returns': 'TargetInfo' }
|
{ 'command': 'query-target', 'returns': 'TargetInfo' }
|
||||||
|
|
@ -7,15 +7,15 @@ Subject: [PATCH] PVE-Backup: pbs-restore - new command to restore from proxmox
|
|||||||
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
|
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
|
||||||
---
|
---
|
||||||
meson.build | 4 +
|
meson.build | 4 +
|
||||||
pbs-restore.c | 224 ++++++++++++++++++++++++++++++++++++++++++++++++++
|
pbs-restore.c | 223 ++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||||
2 files changed, 228 insertions(+)
|
2 files changed, 227 insertions(+)
|
||||||
create mode 100644 pbs-restore.c
|
create mode 100644 pbs-restore.c
|
||||||
|
|
||||||
diff --git a/meson.build b/meson.build
|
diff --git a/meson.build b/meson.build
|
||||||
index 76fcb23299..9476ccbe07 100644
|
index 0bc2fb5b10..f48d2e0457 100644
|
||||||
--- a/meson.build
|
--- a/meson.build
|
||||||
+++ b/meson.build
|
+++ b/meson.build
|
||||||
@@ -3365,6 +3365,10 @@ if have_tools
|
@@ -3613,6 +3613,10 @@ if have_tools
|
||||||
vma = executable('vma', files('vma.c', 'vma-reader.c') + genh,
|
vma = executable('vma', files('vma.c', 'vma-reader.c') + genh,
|
||||||
dependencies: [authz, block, crypto, io, qom], install: true)
|
dependencies: [authz, block, crypto, io, qom], install: true)
|
||||||
|
|
||||||
@ -28,10 +28,10 @@ index 76fcb23299..9476ccbe07 100644
|
|||||||
subdir('contrib/elf2dmp')
|
subdir('contrib/elf2dmp')
|
||||||
diff --git a/pbs-restore.c b/pbs-restore.c
|
diff --git a/pbs-restore.c b/pbs-restore.c
|
||||||
new file mode 100644
|
new file mode 100644
|
||||||
index 0000000000..4d3f925a1b
|
index 0000000000..2f834cf42e
|
||||||
--- /dev/null
|
--- /dev/null
|
||||||
+++ b/pbs-restore.c
|
+++ b/pbs-restore.c
|
||||||
@@ -0,0 +1,224 @@
|
@@ -0,0 +1,223 @@
|
||||||
+/*
|
+/*
|
||||||
+ * Qemu image restore helper for Proxmox Backup
|
+ * Qemu image restore helper for Proxmox Backup
|
||||||
+ *
|
+ *
|
||||||
@ -50,7 +50,6 @@ index 0000000000..4d3f925a1b
|
|||||||
+#include <getopt.h>
|
+#include <getopt.h>
|
||||||
+#include <string.h>
|
+#include <string.h>
|
||||||
+
|
+
|
||||||
+#include "qemu-common.h"
|
|
||||||
+#include "qemu/module.h"
|
+#include "qemu/module.h"
|
||||||
+#include "qemu/error-report.h"
|
+#include "qemu/error-report.h"
|
||||||
+#include "qemu/main-loop.h"
|
+#include "qemu/main-loop.h"
|
||||||
@ -96,7 +95,7 @@ index 0000000000..4d3f925a1b
|
|||||||
+ }
|
+ }
|
||||||
+ res = blk_pwrite_zeroes(callback_data->target, offset, data_len, 0);
|
+ res = blk_pwrite_zeroes(callback_data->target, offset, data_len, 0);
|
||||||
+ } else {
|
+ } else {
|
||||||
+ res = blk_pwrite(callback_data->target, offset, data, data_len, 0);
|
+ res = blk_pwrite(callback_data->target, offset, data_len, data, 0);
|
||||||
+ }
|
+ }
|
||||||
+
|
+
|
||||||
+ if (res < 0) {
|
+ if (res < 0) {
|
@ -41,10 +41,10 @@ index 89ca64444d..45da74d7a0 100644
|
|||||||
false, NULL, false, NULL, !!devlist,
|
false, NULL, false, NULL, !!devlist,
|
||||||
devlist, qdict_haskey(qdict, "speed"), speed, &error);
|
devlist, qdict_haskey(qdict, "speed"), speed, &error);
|
||||||
diff --git a/monitor/hmp-cmds.c b/monitor/hmp-cmds.c
|
diff --git a/monitor/hmp-cmds.c b/monitor/hmp-cmds.c
|
||||||
index ef654221c4..c5c74ac1dc 100644
|
index 1168773da7..4c1671e289 100644
|
||||||
--- a/monitor/hmp-cmds.c
|
--- a/monitor/hmp-cmds.c
|
||||||
+++ b/monitor/hmp-cmds.c
|
+++ b/monitor/hmp-cmds.c
|
||||||
@@ -221,19 +221,42 @@ void hmp_info_backup(Monitor *mon, const QDict *qdict)
|
@@ -223,19 +223,42 @@ void hmp_info_backup(Monitor *mon, const QDict *qdict)
|
||||||
monitor_printf(mon, "End time: %s", ctime(&info->end_time));
|
monitor_printf(mon, "End time: %s", ctime(&info->end_time));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -405,10 +405,10 @@ index 88f5ee133f..1c49cd178d 100644
|
|||||||
qemu_mutex_unlock(&backup_state.stat.lock);
|
qemu_mutex_unlock(&backup_state.stat.lock);
|
||||||
|
|
||||||
diff --git a/qapi/block-core.json b/qapi/block-core.json
|
diff --git a/qapi/block-core.json b/qapi/block-core.json
|
||||||
index ffcc25367b..b332d8a8da 100644
|
index 90ad07b7ee..3ad9eb5d1a 100644
|
||||||
--- a/qapi/block-core.json
|
--- a/qapi/block-core.json
|
||||||
+++ b/qapi/block-core.json
|
+++ b/qapi/block-core.json
|
||||||
@@ -757,8 +757,13 @@
|
@@ -753,8 +753,13 @@
|
||||||
#
|
#
|
||||||
# @total: total amount of bytes involved in the backup process
|
# @total: total amount of bytes involved in the backup process
|
||||||
#
|
#
|
||||||
@ -422,7 +422,7 @@ index ffcc25367b..b332d8a8da 100644
|
|||||||
# @zero-bytes: amount of 'zero' bytes detected.
|
# @zero-bytes: amount of 'zero' bytes detected.
|
||||||
#
|
#
|
||||||
# @start-time: time (epoch) when backup job started.
|
# @start-time: time (epoch) when backup job started.
|
||||||
@@ -771,8 +776,8 @@
|
@@ -767,8 +772,8 @@
|
||||||
#
|
#
|
||||||
##
|
##
|
||||||
{ 'struct': 'BackupStatus',
|
{ 'struct': 'BackupStatus',
|
||||||
@ -433,7 +433,7 @@ index ffcc25367b..b332d8a8da 100644
|
|||||||
'*start-time': 'int', '*end-time': 'int',
|
'*start-time': 'int', '*end-time': 'int',
|
||||||
'*backup-file': 'str', '*uuid': 'str' } }
|
'*backup-file': 'str', '*uuid': 'str' } }
|
||||||
|
|
||||||
@@ -815,6 +820,8 @@
|
@@ -811,6 +816,8 @@
|
||||||
#
|
#
|
||||||
# @backup-time: backup timestamp (Unix epoch, required for format 'pbs')
|
# @backup-time: backup timestamp (Unix epoch, required for format 'pbs')
|
||||||
#
|
#
|
||||||
@ -442,7 +442,7 @@ index ffcc25367b..b332d8a8da 100644
|
|||||||
# Returns: the uuid of the backup job
|
# Returns: the uuid of the backup job
|
||||||
#
|
#
|
||||||
##
|
##
|
||||||
@@ -825,6 +832,7 @@
|
@@ -821,6 +828,7 @@
|
||||||
'*fingerprint': 'str',
|
'*fingerprint': 'str',
|
||||||
'*backup-id': 'str',
|
'*backup-id': 'str',
|
||||||
'*backup-time': 'int',
|
'*backup-time': 'int',
|
@ -194,10 +194,10 @@ index 1c49cd178d..c15abefdda 100644
|
|||||||
.format = format,
|
.format = format,
|
||||||
.has_config_file = has_config_file,
|
.has_config_file = has_config_file,
|
||||||
diff --git a/qapi/block-core.json b/qapi/block-core.json
|
diff --git a/qapi/block-core.json b/qapi/block-core.json
|
||||||
index b332d8a8da..abef91062a 100644
|
index 3ad9eb5d1a..4120052690 100644
|
||||||
--- a/qapi/block-core.json
|
--- a/qapi/block-core.json
|
||||||
+++ b/qapi/block-core.json
|
+++ b/qapi/block-core.json
|
||||||
@@ -822,6 +822,10 @@
|
@@ -818,6 +818,10 @@
|
||||||
#
|
#
|
||||||
# @use-dirty-bitmap: use dirty bitmap to detect incremental changes since last job (optional for format 'pbs')
|
# @use-dirty-bitmap: use dirty bitmap to detect incremental changes since last job (optional for format 'pbs')
|
||||||
#
|
#
|
||||||
@ -208,7 +208,7 @@ index b332d8a8da..abef91062a 100644
|
|||||||
# Returns: the uuid of the backup job
|
# Returns: the uuid of the backup job
|
||||||
#
|
#
|
||||||
##
|
##
|
||||||
@@ -833,6 +837,8 @@
|
@@ -829,6 +833,8 @@
|
||||||
'*backup-id': 'str',
|
'*backup-id': 'str',
|
||||||
'*backup-time': 'int',
|
'*backup-time': 'int',
|
||||||
'*use-dirty-bitmap': 'bool',
|
'*use-dirty-bitmap': 'bool',
|
@ -13,13 +13,13 @@ Signed-off-by: Fabian Ebner <f.ebner@proxmox.com>
|
|||||||
block/meson.build | 3 +
|
block/meson.build | 3 +
|
||||||
block/pbs.c | 276 +++++++++++++++++++++++++++++++++++++++++++
|
block/pbs.c | 276 +++++++++++++++++++++++++++++++++++++++++++
|
||||||
configure | 9 ++
|
configure | 9 ++
|
||||||
meson.build | 1 +
|
meson.build | 2 +-
|
||||||
qapi/block-core.json | 13 ++
|
qapi/block-core.json | 13 ++
|
||||||
5 files changed, 302 insertions(+)
|
5 files changed, 302 insertions(+), 1 deletion(-)
|
||||||
create mode 100644 block/pbs.c
|
create mode 100644 block/pbs.c
|
||||||
|
|
||||||
diff --git a/block/meson.build b/block/meson.build
|
diff --git a/block/meson.build b/block/meson.build
|
||||||
index 42aac96dbb..f94cc0cd25 100644
|
index 2783b77e9c..a26a69434e 100644
|
||||||
--- a/block/meson.build
|
--- a/block/meson.build
|
||||||
+++ b/block/meson.build
|
+++ b/block/meson.build
|
||||||
@@ -53,6 +53,9 @@ block_ss.add(files(
|
@@ -53,6 +53,9 @@ block_ss.add(files(
|
||||||
@ -315,63 +315,64 @@ index 0000000000..0b05ea9080
|
|||||||
+
|
+
|
||||||
+block_init(bdrv_pbs_init);
|
+block_init(bdrv_pbs_init);
|
||||||
diff --git a/configure b/configure
|
diff --git a/configure b/configure
|
||||||
index 7c08c18358..08d164b4f5 100755
|
index 72ab03f11a..7203c270ec 100755
|
||||||
--- a/configure
|
--- a/configure
|
||||||
+++ b/configure
|
+++ b/configure
|
||||||
@@ -325,6 +325,7 @@ trace_file="trace"
|
@@ -309,6 +309,7 @@ linux_user=""
|
||||||
opengl="$default_feature"
|
bsd_user=""
|
||||||
|
pie=""
|
||||||
coroutine=""
|
coroutine=""
|
||||||
tls_priority="NORMAL"
|
|
||||||
+pbs_bdrv="yes"
|
+pbs_bdrv="yes"
|
||||||
plugins="$default_feature"
|
plugins="$default_feature"
|
||||||
secret_keyring="$default_feature"
|
|
||||||
meson=""
|
meson=""
|
||||||
@@ -991,6 +992,10 @@ for opt do
|
meson_args=""
|
||||||
;;
|
@@ -902,6 +903,10 @@ for opt do
|
||||||
--disable-pvrdma) pvrdma="no"
|
--enable-uuid|--disable-uuid)
|
||||||
|
echo "$0: $opt is obsolete, UUID support is always built" >&2
|
||||||
;;
|
;;
|
||||||
+ --disable-pbs-bdrv) pbs_bdrv="no"
|
+ --disable-pbs-bdrv) pbs_bdrv="no"
|
||||||
+ ;;
|
+ ;;
|
||||||
+ --enable-pbs-bdrv) pbs_bdrv="yes"
|
+ --enable-pbs-bdrv) pbs_bdrv="yes"
|
||||||
+ ;;
|
+ ;;
|
||||||
--disable-vhost-user) vhost_user="no"
|
--with-git=*) git="$optarg"
|
||||||
;;
|
;;
|
||||||
--enable-vhost-user) vhost_user="yes"
|
--with-git-submodules=*)
|
||||||
@@ -1265,6 +1270,7 @@ cat << EOF
|
@@ -1087,6 +1092,7 @@ cat << EOF
|
||||||
vhost-user vhost-user backend support
|
debug-info debugging information
|
||||||
vhost-vdpa vhost-vdpa kernel backend support
|
safe-stack SafeStack Stack Smash Protection. Depends on
|
||||||
opengl opengl support
|
clang/llvm >= 3.7 and requires coroutine backend ucontext.
|
||||||
+ pbs-bdrv Proxmox backup server read-only block driver support
|
+ pbs-bdrv Proxmox backup server read-only block driver support
|
||||||
gio libgio support
|
|
||||||
|
|
||||||
NOTE: The object files are built at the place where configure is launched
|
NOTE: The object files are built at the place where configure is launched
|
||||||
@@ -2848,6 +2854,9 @@ if test "$xen" = "enabled" ; then
|
EOF
|
||||||
echo "XEN_CFLAGS=$xen_cflags" >> $config_host_mak
|
@@ -2463,6 +2469,9 @@ echo "TARGET_DIRS=$target_list" >> $config_host_mak
|
||||||
echo "XEN_LIBS=$xen_libs" >> $config_host_mak
|
if test "$modules" = "yes"; then
|
||||||
|
echo "CONFIG_MODULES=y" >> $config_host_mak
|
||||||
fi
|
fi
|
||||||
+if test "$pbs_bdrv" = "yes" ; then
|
+if test "$pbs_bdrv" = "yes" ; then
|
||||||
+ echo "CONFIG_PBS_BDRV=y" >> $config_host_mak
|
+ echo "CONFIG_PBS_BDRV=y" >> $config_host_mak
|
||||||
+fi
|
+fi
|
||||||
if test "$vhost_scsi" = "yes" ; then
|
|
||||||
echo "CONFIG_VHOST_SCSI=y" >> $config_host_mak
|
# XXX: suppress that
|
||||||
fi
|
if [ "$bsd" = "yes" ] ; then
|
||||||
diff --git a/meson.build b/meson.build
|
diff --git a/meson.build b/meson.build
|
||||||
index 9476ccbe07..d3783a83e4 100644
|
index f48d2e0457..be4785e2f6 100644
|
||||||
--- a/meson.build
|
--- a/meson.build
|
||||||
+++ b/meson.build
|
+++ b/meson.build
|
||||||
@@ -3743,6 +3743,7 @@ summary_info += {'bzip2 support': libbzip2}
|
@@ -3986,7 +3986,7 @@ summary_info += {'bzip2 support': libbzip2}
|
||||||
summary_info += {'lzfse support': liblzfse}
|
summary_info += {'lzfse support': liblzfse}
|
||||||
summary_info += {'zstd support': zstd}
|
summary_info += {'zstd support': zstd}
|
||||||
summary_info += {'NUMA host support': numa}
|
summary_info += {'NUMA host support': numa}
|
||||||
|
-summary_info += {'capstone': capstone}
|
||||||
+summary_info += {'PBS bdrv support': config_host.has_key('CONFIG_PBS_BDRV')}
|
+summary_info += {'PBS bdrv support': config_host.has_key('CONFIG_PBS_BDRV')}
|
||||||
summary_info += {'capstone': capstone_opt == 'internal' ? capstone_opt : capstone}
|
|
||||||
summary_info += {'libpmem support': libpmem}
|
summary_info += {'libpmem support': libpmem}
|
||||||
summary_info += {'libdaxctl support': libdaxctl}
|
summary_info += {'libdaxctl support': libdaxctl}
|
||||||
|
summary_info += {'libudev': libudev}
|
||||||
diff --git a/qapi/block-core.json b/qapi/block-core.json
|
diff --git a/qapi/block-core.json b/qapi/block-core.json
|
||||||
index abef91062a..68591cb343 100644
|
index 4120052690..96bc696aaa 100644
|
||||||
--- a/qapi/block-core.json
|
--- a/qapi/block-core.json
|
||||||
+++ b/qapi/block-core.json
|
+++ b/qapi/block-core.json
|
||||||
@@ -3073,6 +3073,7 @@
|
@@ -3099,6 +3099,7 @@
|
||||||
'luks', 'nbd', 'nfs', 'null-aio', 'null-co', 'nvme', 'parallels',
|
'luks', 'nbd', 'nfs', 'null-aio', 'null-co', 'nvme', 'parallels',
|
||||||
'preallocate', 'qcow', 'qcow2', 'qed', 'quorum', 'raw', 'rbd',
|
'preallocate', 'qcow', 'qcow2', 'qed', 'quorum', 'raw', 'rbd',
|
||||||
{ 'name': 'replication', 'if': 'CONFIG_REPLICATION' },
|
{ 'name': 'replication', 'if': 'CONFIG_REPLICATION' },
|
||||||
@ -379,7 +380,7 @@ index abef91062a..68591cb343 100644
|
|||||||
'ssh', 'throttle', 'vdi', 'vhdx', 'vmdk', 'vpc', 'vvfat' ] }
|
'ssh', 'throttle', 'vdi', 'vhdx', 'vmdk', 'vpc', 'vvfat' ] }
|
||||||
|
|
||||||
##
|
##
|
||||||
@@ -3145,6 +3146,17 @@
|
@@ -3171,6 +3172,17 @@
|
||||||
{ 'struct': 'BlockdevOptionsNull',
|
{ 'struct': 'BlockdevOptionsNull',
|
||||||
'data': { '*size': 'int', '*latency-ns': 'uint64', '*read-zeroes': 'bool' } }
|
'data': { '*size': 'int', '*latency-ns': 'uint64', '*read-zeroes': 'bool' } }
|
||||||
|
|
||||||
@ -397,7 +398,7 @@ index abef91062a..68591cb343 100644
|
|||||||
##
|
##
|
||||||
# @BlockdevOptionsNVMe:
|
# @BlockdevOptionsNVMe:
|
||||||
#
|
#
|
||||||
@@ -4405,6 +4417,7 @@
|
@@ -4455,6 +4467,7 @@
|
||||||
'nfs': 'BlockdevOptionsNfs',
|
'nfs': 'BlockdevOptionsNfs',
|
||||||
'null-aio': 'BlockdevOptionsNull',
|
'null-aio': 'BlockdevOptionsNull',
|
||||||
'null-co': 'BlockdevOptionsNull',
|
'null-co': 'BlockdevOptionsNull',
|
@ -33,10 +33,10 @@ index c15abefdda..4684789813 100644
|
|||||||
+ return ret;
|
+ return ret;
|
||||||
+}
|
+}
|
||||||
diff --git a/qapi/block-core.json b/qapi/block-core.json
|
diff --git a/qapi/block-core.json b/qapi/block-core.json
|
||||||
index 68591cb343..7d25aa4fa1 100644
|
index 96bc696aaa..0b453c61d4 100644
|
||||||
--- a/qapi/block-core.json
|
--- a/qapi/block-core.json
|
||||||
+++ b/qapi/block-core.json
|
+++ b/qapi/block-core.json
|
||||||
@@ -867,6 +867,35 @@
|
@@ -863,6 +863,35 @@
|
||||||
##
|
##
|
||||||
{ 'command': 'backup-cancel' }
|
{ 'command': 'backup-cancel' }
|
||||||
|
|
@ -15,10 +15,10 @@ Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
|
|||||||
3 files changed, 159 insertions(+), 42 deletions(-)
|
3 files changed, 159 insertions(+), 42 deletions(-)
|
||||||
|
|
||||||
diff --git a/monitor/hmp-cmds.c b/monitor/hmp-cmds.c
|
diff --git a/monitor/hmp-cmds.c b/monitor/hmp-cmds.c
|
||||||
index c5c74ac1dc..df273f41fb 100644
|
index 4c1671e289..c1152f55a7 100644
|
||||||
--- a/monitor/hmp-cmds.c
|
--- a/monitor/hmp-cmds.c
|
||||||
+++ b/monitor/hmp-cmds.c
|
+++ b/monitor/hmp-cmds.c
|
||||||
@@ -198,6 +198,7 @@ void hmp_info_mice(Monitor *mon, const QDict *qdict)
|
@@ -200,6 +200,7 @@ void hmp_info_mice(Monitor *mon, const QDict *qdict)
|
||||||
void hmp_info_backup(Monitor *mon, const QDict *qdict)
|
void hmp_info_backup(Monitor *mon, const QDict *qdict)
|
||||||
{
|
{
|
||||||
BackupStatus *info;
|
BackupStatus *info;
|
||||||
@ -26,7 +26,7 @@ index c5c74ac1dc..df273f41fb 100644
|
|||||||
|
|
||||||
info = qmp_query_backup(NULL);
|
info = qmp_query_backup(NULL);
|
||||||
|
|
||||||
@@ -228,26 +229,29 @@ void hmp_info_backup(Monitor *mon, const QDict *qdict)
|
@@ -230,26 +231,29 @@ void hmp_info_backup(Monitor *mon, const QDict *qdict)
|
||||||
// this should not happen normally
|
// this should not happen normally
|
||||||
monitor_printf(mon, "Total size: %d\n", 0);
|
monitor_printf(mon, "Total size: %d\n", 0);
|
||||||
} else {
|
} else {
|
||||||
@ -359,10 +359,10 @@ index 4684789813..f90abaa50a 100644
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
diff --git a/qapi/block-core.json b/qapi/block-core.json
|
diff --git a/qapi/block-core.json b/qapi/block-core.json
|
||||||
index 7d25aa4fa1..69571d86eb 100644
|
index 0b453c61d4..16e184dd28 100644
|
||||||
--- a/qapi/block-core.json
|
--- a/qapi/block-core.json
|
||||||
+++ b/qapi/block-core.json
|
+++ b/qapi/block-core.json
|
||||||
@@ -875,6 +875,8 @@
|
@@ -871,6 +871,8 @@
|
||||||
# @pbs-dirty-bitmap: True if dirty-bitmap-incremental backups to PBS are
|
# @pbs-dirty-bitmap: True if dirty-bitmap-incremental backups to PBS are
|
||||||
# supported.
|
# supported.
|
||||||
#
|
#
|
||||||
@ -371,7 +371,7 @@ index 7d25aa4fa1..69571d86eb 100644
|
|||||||
# @pbs-dirty-bitmap-savevm: True if 'dirty-bitmaps' migration capability can
|
# @pbs-dirty-bitmap-savevm: True if 'dirty-bitmaps' migration capability can
|
||||||
# safely be set for savevm-async.
|
# safely be set for savevm-async.
|
||||||
#
|
#
|
||||||
@@ -883,6 +885,7 @@
|
@@ -879,6 +881,7 @@
|
||||||
##
|
##
|
||||||
{ 'struct': 'ProxmoxSupportStatus',
|
{ 'struct': 'ProxmoxSupportStatus',
|
||||||
'data': { 'pbs-dirty-bitmap': 'bool',
|
'data': { 'pbs-dirty-bitmap': 'bool',
|
||||||
@ -379,7 +379,7 @@ index 7d25aa4fa1..69571d86eb 100644
|
|||||||
'pbs-dirty-bitmap-savevm': 'bool',
|
'pbs-dirty-bitmap-savevm': 'bool',
|
||||||
'pbs-library-version': 'str' } }
|
'pbs-library-version': 'str' } }
|
||||||
|
|
||||||
@@ -896,6 +899,59 @@
|
@@ -892,6 +895,59 @@
|
||||||
##
|
##
|
||||||
{ 'command': 'query-proxmox-support', 'returns': 'ProxmoxSupportStatus' }
|
{ '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(-)
|
2 files changed, 7 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
diff --git a/meson.build b/meson.build
|
diff --git a/meson.build b/meson.build
|
||||||
index d3783a83e4..715245ba20 100644
|
index be4785e2f6..3fc7c8d435 100644
|
||||||
--- a/meson.build
|
--- a/meson.build
|
||||||
+++ b/meson.build
|
+++ b/meson.build
|
||||||
@@ -1268,6 +1268,7 @@ keyutils = dependency('libkeyutils', required: false,
|
@@ -1463,6 +1463,7 @@ keyutils = dependency('libkeyutils', required: false,
|
||||||
has_gettid = cc.has_function('gettid')
|
has_gettid = cc.has_function('gettid')
|
||||||
|
|
||||||
libuuid = cc.find_library('uuid', required: true)
|
libuuid = cc.find_library('uuid', required: true)
|
||||||
@ -25,7 +25,7 @@ index d3783a83e4..715245ba20 100644
|
|||||||
libproxmox_backup_qemu = cc.find_library('proxmox_backup_qemu', required: true)
|
libproxmox_backup_qemu = cc.find_library('proxmox_backup_qemu', required: true)
|
||||||
|
|
||||||
# libselinux
|
# libselinux
|
||||||
@@ -2861,6 +2862,7 @@ if have_block
|
@@ -3105,6 +3106,7 @@ if have_block
|
||||||
# os-posix.c contains POSIX-specific functions used by qemu-storage-daemon,
|
# os-posix.c contains POSIX-specific functions used by qemu-storage-daemon,
|
||||||
# os-win32.c does not
|
# os-win32.c does not
|
||||||
blockdev_ss.add(when: 'CONFIG_POSIX', if_true: files('os-posix.c'))
|
blockdev_ss.add(when: 'CONFIG_POSIX', if_true: files('os-posix.c'))
|
||||||
@ -34,7 +34,7 @@ index d3783a83e4..715245ba20 100644
|
|||||||
endif
|
endif
|
||||||
|
|
||||||
diff --git a/os-posix.c b/os-posix.c
|
diff --git a/os-posix.c b/os-posix.c
|
||||||
index 24692c8593..d1bc5ac12d 100644
|
index 321fc4bd13..b1870d2690 100644
|
||||||
--- a/os-posix.c
|
--- a/os-posix.c
|
||||||
+++ b/os-posix.c
|
+++ b/os-posix.c
|
||||||
@@ -28,6 +28,8 @@
|
@@ -28,6 +28,8 @@
|
||||||
@ -44,15 +44,15 @@ index 24692c8593..d1bc5ac12d 100644
|
|||||||
+#include <systemd/sd-journal.h>
|
+#include <systemd/sd-journal.h>
|
||||||
+#include <syslog.h>
|
+#include <syslog.h>
|
||||||
|
|
||||||
#include "qemu-common.h"
|
|
||||||
/* Needed early for CONFIG_BSD etc. */
|
/* Needed early for CONFIG_BSD etc. */
|
||||||
@@ -291,9 +293,10 @@ void os_setup_post(void)
|
#include "net/slirp.h"
|
||||||
|
@@ -281,9 +283,10 @@ void os_setup_post(void)
|
||||||
|
|
||||||
dup2(fd, 0);
|
dup2(fd, 0);
|
||||||
dup2(fd, 1);
|
dup2(fd, 1);
|
||||||
- /* In case -D is given do not redirect stderr to /dev/null */
|
- /* In case -D is given do not redirect stderr to /dev/null */
|
||||||
+ /* In case -D is given do not redirect stderr to journal */
|
+ /* In case -D is given do not redirect stderr to journal */
|
||||||
if (!qemu_logfile) {
|
if (!qemu_log_enabled()) {
|
||||||
- dup2(fd, 2);
|
- dup2(fd, 2);
|
||||||
+ int journal_fd = sd_journal_stream_fd("QEMU", LOG_ERR, 0);
|
+ int journal_fd = sd_journal_stream_fd("QEMU", LOG_ERR, 0);
|
||||||
+ dup2(journal_fd, 2);
|
+ dup2(journal_fd, 2);
|
@ -481,10 +481,10 @@ index 63c686463f..6f05796fad 100644
|
|||||||
qemu_mutex_unlock(&backup_state.stat.lock);
|
qemu_mutex_unlock(&backup_state.stat.lock);
|
||||||
|
|
||||||
diff --git a/qapi/block-core.json b/qapi/block-core.json
|
diff --git a/qapi/block-core.json b/qapi/block-core.json
|
||||||
index 69571d86eb..e6c3687bea 100644
|
index 16e184dd28..cb17d00fe0 100644
|
||||||
--- a/qapi/block-core.json
|
--- a/qapi/block-core.json
|
||||||
+++ b/qapi/block-core.json
|
+++ b/qapi/block-core.json
|
||||||
@@ -774,12 +774,15 @@
|
@@ -770,12 +770,15 @@
|
||||||
#
|
#
|
||||||
# @uuid: uuid for this backup job
|
# @uuid: uuid for this backup job
|
||||||
#
|
#
|
@ -36,11 +36,11 @@ index 465906710d..4f0aeceb6f 100644
|
|||||||
+
|
+
|
||||||
#endif
|
#endif
|
||||||
diff --git a/migration/meson.build b/migration/meson.build
|
diff --git a/migration/meson.build b/migration/meson.build
|
||||||
index 1e2aec8486..259e863a43 100644
|
index 0842d00cd2..d012f4d8d3 100644
|
||||||
--- a/migration/meson.build
|
--- a/migration/meson.build
|
||||||
+++ b/migration/meson.build
|
+++ b/migration/meson.build
|
||||||
@@ -7,8 +7,10 @@ migration_files = files(
|
@@ -6,8 +6,10 @@ migration_files = files(
|
||||||
'qemu-file-channel.c',
|
'vmstate.c',
|
||||||
'qemu-file.c',
|
'qemu-file.c',
|
||||||
'yank_functions.c',
|
'yank_functions.c',
|
||||||
+ 'pbs-state.c',
|
+ 'pbs-state.c',
|
||||||
@ -51,10 +51,10 @@ index 1e2aec8486..259e863a43 100644
|
|||||||
softmmu_ss.add(files(
|
softmmu_ss.add(files(
|
||||||
'block-dirty-bitmap.c',
|
'block-dirty-bitmap.c',
|
||||||
diff --git a/migration/migration.c b/migration/migration.c
|
diff --git a/migration/migration.c b/migration/migration.c
|
||||||
index 695f0f2900..6e17f8e91c 100644
|
index bb8bbddfe4..8109e468eb 100644
|
||||||
--- a/migration/migration.c
|
--- a/migration/migration.c
|
||||||
+++ b/migration/migration.c
|
+++ b/migration/migration.c
|
||||||
@@ -214,6 +214,7 @@ void migration_object_init(void)
|
@@ -229,6 +229,7 @@ void migration_object_init(void)
|
||||||
blk_mig_init();
|
blk_mig_init();
|
||||||
ram_mig_init();
|
ram_mig_init();
|
||||||
dirty_bitmap_mig_init();
|
dirty_bitmap_mig_init();
|
||||||
@ -187,10 +187,10 @@ index 6f05796fad..5fa3cc1352 100644
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
diff --git a/qapi/block-core.json b/qapi/block-core.json
|
diff --git a/qapi/block-core.json b/qapi/block-core.json
|
||||||
index e6c3687bea..05382a1069 100644
|
index cb17d00fe0..bd978ea562 100644
|
||||||
--- a/qapi/block-core.json
|
--- a/qapi/block-core.json
|
||||||
+++ b/qapi/block-core.json
|
+++ b/qapi/block-core.json
|
||||||
@@ -883,6 +883,11 @@
|
@@ -879,6 +879,11 @@
|
||||||
# @pbs-dirty-bitmap-savevm: True if 'dirty-bitmaps' migration capability can
|
# @pbs-dirty-bitmap-savevm: True if 'dirty-bitmaps' migration capability can
|
||||||
# safely be set for savevm-async.
|
# safely be set for savevm-async.
|
||||||
#
|
#
|
||||||
@ -202,7 +202,7 @@ index e6c3687bea..05382a1069 100644
|
|||||||
# @pbs-library-version: Running version of libproxmox-backup-qemu0 library.
|
# @pbs-library-version: Running version of libproxmox-backup-qemu0 library.
|
||||||
#
|
#
|
||||||
##
|
##
|
||||||
@@ -890,6 +895,7 @@
|
@@ -886,6 +891,7 @@
|
||||||
'data': { 'pbs-dirty-bitmap': 'bool',
|
'data': { 'pbs-dirty-bitmap': 'bool',
|
||||||
'query-bitmap-info': 'bool',
|
'query-bitmap-info': 'bool',
|
||||||
'pbs-dirty-bitmap-savevm': 'bool',
|
'pbs-dirty-bitmap-savevm': 'bool',
|
@ -21,7 +21,7 @@ Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
|
|||||||
1 file changed, 30 insertions(+)
|
1 file changed, 30 insertions(+)
|
||||||
|
|
||||||
diff --git a/block/iscsi.c b/block/iscsi.c
|
diff --git a/block/iscsi.c b/block/iscsi.c
|
||||||
index 51f2a5eeaa..f11591ac94 100644
|
index d707d0b354..da6ed52323 100644
|
||||||
--- a/block/iscsi.c
|
--- a/block/iscsi.c
|
||||||
+++ b/block/iscsi.c
|
+++ b/block/iscsi.c
|
||||||
@@ -1386,12 +1386,42 @@ static char *get_initiator_name(QemuOpts *opts)
|
@@ -1386,12 +1386,42 @@ static char *get_initiator_name(QemuOpts *opts)
|
@ -54,10 +54,10 @@ index ea7b665aa2..ef45552e3b 100644
|
|||||||
Error *error = NULL;
|
Error *error = NULL;
|
||||||
|
|
||||||
diff --git a/hmp-commands.hx b/hmp-commands.hx
|
diff --git a/hmp-commands.hx b/hmp-commands.hx
|
||||||
index 994445f301..aaea875970 100644
|
index 97f24942b3..7a2be816da 100644
|
||||||
--- a/hmp-commands.hx
|
--- a/hmp-commands.hx
|
||||||
+++ b/hmp-commands.hx
|
+++ b/hmp-commands.hx
|
||||||
@@ -109,6 +109,7 @@ ERST
|
@@ -111,6 +111,7 @@ ERST
|
||||||
"\n\t\t\t Use -d to dump data into a directory instead"
|
"\n\t\t\t Use -d to dump data into a directory instead"
|
||||||
"\n\t\t\t of using VMA format.",
|
"\n\t\t\t of using VMA format.",
|
||||||
.cmd = hmp_backup,
|
.cmd = hmp_backup,
|
||||||
@ -65,7 +65,7 @@ index 994445f301..aaea875970 100644
|
|||||||
},
|
},
|
||||||
|
|
||||||
SRST
|
SRST
|
||||||
@@ -122,6 +123,7 @@ ERST
|
@@ -124,6 +125,7 @@ ERST
|
||||||
.params = "",
|
.params = "",
|
||||||
.help = "cancel the current VM backup",
|
.help = "cancel the current VM backup",
|
||||||
.cmd = hmp_backup_cancel,
|
.cmd = hmp_backup_cancel,
|
||||||
@ -575,10 +575,10 @@ index 5fa3cc1352..323014744c 100644
|
|||||||
|
|
||||||
BackupStatus *qmp_query_backup(Error **errp)
|
BackupStatus *qmp_query_backup(Error **errp)
|
||||||
diff --git a/qapi/block-core.json b/qapi/block-core.json
|
diff --git a/qapi/block-core.json b/qapi/block-core.json
|
||||||
index 05382a1069..f0399bf249 100644
|
index bd978ea562..ca1966f54b 100644
|
||||||
--- a/qapi/block-core.json
|
--- a/qapi/block-core.json
|
||||||
+++ b/qapi/block-core.json
|
+++ b/qapi/block-core.json
|
||||||
@@ -846,7 +846,7 @@
|
@@ -842,7 +842,7 @@
|
||||||
'*config-file': 'str',
|
'*config-file': 'str',
|
||||||
'*firewall-file': 'str',
|
'*firewall-file': 'str',
|
||||||
'*devlist': 'str', '*speed': 'int' },
|
'*devlist': 'str', '*speed': 'int' },
|
||||||
@ -587,7 +587,7 @@ index 05382a1069..f0399bf249 100644
|
|||||||
|
|
||||||
##
|
##
|
||||||
# @query-backup:
|
# @query-backup:
|
||||||
@@ -868,7 +868,7 @@
|
@@ -864,7 +864,7 @@
|
||||||
# Notes: This command succeeds even if there is no backup process running.
|
# Notes: This command succeeds even if there is no backup process running.
|
||||||
#
|
#
|
||||||
##
|
##
|
@ -58,10 +58,10 @@ index 323014744c..9f6c04a512 100644
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
diff --git a/qapi/block-core.json b/qapi/block-core.json
|
diff --git a/qapi/block-core.json b/qapi/block-core.json
|
||||||
index f0399bf249..13e03ca154 100644
|
index ca1966f54b..fc8a125451 100644
|
||||||
--- a/qapi/block-core.json
|
--- a/qapi/block-core.json
|
||||||
+++ b/qapi/block-core.json
|
+++ b/qapi/block-core.json
|
||||||
@@ -817,6 +817,8 @@
|
@@ -813,6 +813,8 @@
|
||||||
#
|
#
|
||||||
# @key-password: password for keyfile (optional for format 'pbs')
|
# @key-password: password for keyfile (optional for format 'pbs')
|
||||||
#
|
#
|
||||||
@ -70,7 +70,7 @@ index f0399bf249..13e03ca154 100644
|
|||||||
# @fingerprint: server cert fingerprint (optional for format 'pbs')
|
# @fingerprint: server cert fingerprint (optional for format 'pbs')
|
||||||
#
|
#
|
||||||
# @backup-id: backup ID (required for format 'pbs')
|
# @backup-id: backup ID (required for format 'pbs')
|
||||||
@@ -836,6 +838,7 @@
|
@@ -832,6 +834,7 @@
|
||||||
'*password': 'str',
|
'*password': 'str',
|
||||||
'*keyfile': 'str',
|
'*keyfile': 'str',
|
||||||
'*key-password': 'str',
|
'*key-password': 'str',
|
||||||
@ -78,7 +78,7 @@ index f0399bf249..13e03ca154 100644
|
|||||||
'*fingerprint': 'str',
|
'*fingerprint': 'str',
|
||||||
'*backup-id': 'str',
|
'*backup-id': 'str',
|
||||||
'*backup-time': 'int',
|
'*backup-time': 'int',
|
||||||
@@ -888,6 +891,9 @@
|
@@ -884,6 +887,9 @@
|
||||||
# migration cap if this is false/unset may lead
|
# migration cap if this is false/unset may lead
|
||||||
# to crashes on migration!
|
# to crashes on migration!
|
||||||
#
|
#
|
||||||
@ -88,7 +88,7 @@ index f0399bf249..13e03ca154 100644
|
|||||||
# @pbs-library-version: Running version of libproxmox-backup-qemu0 library.
|
# @pbs-library-version: Running version of libproxmox-backup-qemu0 library.
|
||||||
#
|
#
|
||||||
##
|
##
|
||||||
@@ -896,6 +902,7 @@
|
@@ -892,6 +898,7 @@
|
||||||
'query-bitmap-info': 'bool',
|
'query-bitmap-info': 'bool',
|
||||||
'pbs-dirty-bitmap-savevm': 'bool',
|
'pbs-dirty-bitmap-savevm': 'bool',
|
||||||
'pbs-dirty-bitmap-migration': 'bool',
|
'pbs-dirty-bitmap-migration': 'bool',
|
@ -17,10 +17,10 @@ Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
|
|||||||
1 file changed, 4 insertions(+)
|
1 file changed, 4 insertions(+)
|
||||||
|
|
||||||
diff --git a/block/io.c b/block/io.c
|
diff --git a/block/io.c b/block/io.c
|
||||||
index 3280144a17..cd7ba08768 100644
|
index 0a8cbefe86..531b3b7a2d 100644
|
||||||
--- a/block/io.c
|
--- a/block/io.c
|
||||||
+++ b/block/io.c
|
+++ b/block/io.c
|
||||||
@@ -1794,6 +1794,10 @@ static int bdrv_pad_request(BlockDriverState *bs,
|
@@ -1734,6 +1734,10 @@ static int bdrv_pad_request(BlockDriverState *bs,
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
@ -389,7 +389,7 @@ index 0000000000..6b50fbe537
|
|||||||
+
|
+
|
||||||
+block_init(bdrv_alloc_track_init);
|
+block_init(bdrv_alloc_track_init);
|
||||||
diff --git a/block/meson.build b/block/meson.build
|
diff --git a/block/meson.build b/block/meson.build
|
||||||
index f94cc0cd25..1716febb1d 100644
|
index a26a69434e..74e5f49758 100644
|
||||||
--- a/block/meson.build
|
--- a/block/meson.build
|
||||||
+++ b/block/meson.build
|
+++ b/block/meson.build
|
||||||
@@ -2,6 +2,7 @@ block_ss.add(genh)
|
@@ -2,6 +2,7 @@ block_ss.add(genh)
|
@ -10,7 +10,7 @@ Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
|
|||||||
1 file changed, 4 insertions(+), 1 deletion(-)
|
1 file changed, 4 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
diff --git a/qapi/pragma.json b/qapi/pragma.json
|
diff --git a/qapi/pragma.json b/qapi/pragma.json
|
||||||
index 41139d8645..a581acf7d4 100644
|
index a2358e303a..9ff5c84ffd 100644
|
||||||
--- a/qapi/pragma.json
|
--- a/qapi/pragma.json
|
||||||
+++ b/qapi/pragma.json
|
+++ b/qapi/pragma.json
|
||||||
@@ -15,6 +15,7 @@
|
@@ -15,6 +15,7 @@
|
||||||
@ -21,7 +21,7 @@ index 41139d8645..a581acf7d4 100644
|
|||||||
'migrate_cancel',
|
'migrate_cancel',
|
||||||
'netdev_add',
|
'netdev_add',
|
||||||
'netdev_del',
|
'netdev_del',
|
||||||
@@ -63,6 +64,8 @@
|
@@ -64,6 +65,8 @@
|
||||||
'SysEmuTarget', # query-cpu-fast, query-target
|
'SysEmuTarget', # query-cpu-fast, query-target
|
||||||
'UuidInfo', # query-uuid
|
'UuidInfo', # query-uuid
|
||||||
'VncClientInfo', # query-vnc, query-vnc-servers, ...
|
'VncClientInfo', # query-vnc, query-vnc-servers, ...
|
@ -11,10 +11,10 @@ Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
|
|||||||
1 file changed, 5 insertions(+)
|
1 file changed, 5 insertions(+)
|
||||||
|
|
||||||
diff --git a/migration/savevm-async.c b/migration/savevm-async.c
|
diff --git a/migration/savevm-async.c b/migration/savevm-async.c
|
||||||
index 0bc5799cf8..10ebefef06 100644
|
index e65a5e3482..2ed2536816 100644
|
||||||
--- a/migration/savevm-async.c
|
--- a/migration/savevm-async.c
|
||||||
+++ b/migration/savevm-async.c
|
+++ b/migration/savevm-async.c
|
||||||
@@ -19,6 +19,7 @@
|
@@ -20,6 +20,7 @@
|
||||||
#include "qemu/timer.h"
|
#include "qemu/timer.h"
|
||||||
#include "qemu/main-loop.h"
|
#include "qemu/main-loop.h"
|
||||||
#include "qemu/rcu.h"
|
#include "qemu/rcu.h"
|
||||||
@ -22,7 +22,7 @@ index 0bc5799cf8..10ebefef06 100644
|
|||||||
|
|
||||||
/* #define DEBUG_SAVEVM_STATE */
|
/* #define DEBUG_SAVEVM_STATE */
|
||||||
|
|
||||||
@@ -586,6 +587,10 @@ int load_snapshot_from_blockdev(const char *filename, Error **errp)
|
@@ -514,6 +515,10 @@ int load_snapshot_from_blockdev(const char *filename, Error **errp)
|
||||||
dirty_bitmap_mig_before_vm_start();
|
dirty_bitmap_mig_before_vm_start();
|
||||||
|
|
||||||
qemu_fclose(f);
|
qemu_fclose(f);
|
@ -12,7 +12,7 @@ Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
|
|||||||
3 files changed, 36 insertions(+), 7 deletions(-)
|
3 files changed, 36 insertions(+), 7 deletions(-)
|
||||||
|
|
||||||
diff --git a/docs/tools/qemu-img.rst b/docs/tools/qemu-img.rst
|
diff --git a/docs/tools/qemu-img.rst b/docs/tools/qemu-img.rst
|
||||||
index 33979b7430..68e9c80788 100644
|
index 699229eef6..4189ced8bc 100644
|
||||||
--- a/docs/tools/qemu-img.rst
|
--- a/docs/tools/qemu-img.rst
|
||||||
+++ b/docs/tools/qemu-img.rst
|
+++ b/docs/tools/qemu-img.rst
|
||||||
@@ -492,10 +492,10 @@ Command description:
|
@@ -492,10 +492,10 @@ Command description:
|
||||||
@ -46,10 +46,10 @@ index b5b0bb4467..36f97e1f19 100644
|
|||||||
|
|
||||||
DEF("info", img_info,
|
DEF("info", img_info,
|
||||||
diff --git a/qemu-img.c b/qemu-img.c
|
diff --git a/qemu-img.c b/qemu-img.c
|
||||||
index 35c2bdc95c..6e93bbd425 100644
|
index c6b4a5567d..041c203fc3 100644
|
||||||
--- a/qemu-img.c
|
--- a/qemu-img.c
|
||||||
+++ b/qemu-img.c
|
+++ b/qemu-img.c
|
||||||
@@ -4938,6 +4938,7 @@ static int img_dd(int argc, char **argv)
|
@@ -4943,6 +4943,7 @@ static int img_dd(int argc, char **argv)
|
||||||
BlockDriver *drv = NULL, *proto_drv = NULL;
|
BlockDriver *drv = NULL, *proto_drv = NULL;
|
||||||
BlockBackend *blk1 = NULL, *blk2 = NULL;
|
BlockBackend *blk1 = NULL, *blk2 = NULL;
|
||||||
QemuOpts *opts = NULL;
|
QemuOpts *opts = NULL;
|
||||||
@ -57,7 +57,7 @@ index 35c2bdc95c..6e93bbd425 100644
|
|||||||
QemuOptsList *create_opts = NULL;
|
QemuOptsList *create_opts = NULL;
|
||||||
Error *local_err = NULL;
|
Error *local_err = NULL;
|
||||||
bool image_opts = false;
|
bool image_opts = false;
|
||||||
@@ -4947,6 +4948,7 @@ static int img_dd(int argc, char **argv)
|
@@ -4952,6 +4953,7 @@ static int img_dd(int argc, char **argv)
|
||||||
int64_t size = 0, readsize = 0;
|
int64_t size = 0, readsize = 0;
|
||||||
int64_t block_count = 0, out_pos, in_pos;
|
int64_t block_count = 0, out_pos, in_pos;
|
||||||
bool force_share = false, skip_create = false;
|
bool force_share = false, skip_create = false;
|
||||||
@ -65,7 +65,7 @@ index 35c2bdc95c..6e93bbd425 100644
|
|||||||
struct DdInfo dd = {
|
struct DdInfo dd = {
|
||||||
.flags = 0,
|
.flags = 0,
|
||||||
.count = 0,
|
.count = 0,
|
||||||
@@ -4984,7 +4986,7 @@ static int img_dd(int argc, char **argv)
|
@@ -4989,7 +4991,7 @@ static int img_dd(int argc, char **argv)
|
||||||
{ 0, 0, 0, 0 }
|
{ 0, 0, 0, 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -74,7 +74,7 @@ index 35c2bdc95c..6e93bbd425 100644
|
|||||||
if (c == EOF) {
|
if (c == EOF) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -5007,6 +5009,19 @@ static int img_dd(int argc, char **argv)
|
@@ -5012,6 +5014,19 @@ static int img_dd(int argc, char **argv)
|
||||||
case 'n':
|
case 'n':
|
||||||
skip_create = true;
|
skip_create = true;
|
||||||
break;
|
break;
|
||||||
@ -94,7 +94,7 @@ index 35c2bdc95c..6e93bbd425 100644
|
|||||||
case 'U':
|
case 'U':
|
||||||
force_share = true;
|
force_share = true;
|
||||||
break;
|
break;
|
||||||
@@ -5066,11 +5081,24 @@ static int img_dd(int argc, char **argv)
|
@@ -5071,11 +5086,24 @@ static int img_dd(int argc, char **argv)
|
||||||
if (dd.flags & C_IF) {
|
if (dd.flags & C_IF) {
|
||||||
blk1 = img_open(image_opts, in.filename, fmt, 0, false, false,
|
blk1 = img_open(image_opts, in.filename, fmt, 0, false, false,
|
||||||
force_share);
|
force_share);
|
||||||
@ -120,7 +120,7 @@ index 35c2bdc95c..6e93bbd425 100644
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (dd.flags & C_OSIZE) {
|
if (dd.flags & C_OSIZE) {
|
||||||
@@ -5219,6 +5247,7 @@ static int img_dd(int argc, char **argv)
|
@@ -5230,6 +5258,7 @@ static int img_dd(int argc, char **argv)
|
||||||
out:
|
out:
|
||||||
g_free(arg);
|
g_free(arg);
|
||||||
qemu_opts_del(opts);
|
qemu_opts_del(opts);
|
@ -24,10 +24,10 @@ Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
|
|||||||
3 files changed, 126 insertions(+), 97 deletions(-)
|
3 files changed, 126 insertions(+), 97 deletions(-)
|
||||||
|
|
||||||
diff --git a/vma-reader.c b/vma-reader.c
|
diff --git a/vma-reader.c b/vma-reader.c
|
||||||
index 4f4ee2b47b..844d95a5ba 100644
|
index e65f1e8415..81a891c6b1 100644
|
||||||
--- a/vma-reader.c
|
--- a/vma-reader.c
|
||||||
+++ b/vma-reader.c
|
+++ b/vma-reader.c
|
||||||
@@ -29,6 +29,7 @@ typedef struct VmaRestoreState {
|
@@ -28,6 +28,7 @@ typedef struct VmaRestoreState {
|
||||||
bool write_zeroes;
|
bool write_zeroes;
|
||||||
unsigned long *bitmap;
|
unsigned long *bitmap;
|
||||||
int bitmap_size;
|
int bitmap_size;
|
||||||
@ -35,7 +35,7 @@ index 4f4ee2b47b..844d95a5ba 100644
|
|||||||
} VmaRestoreState;
|
} VmaRestoreState;
|
||||||
|
|
||||||
struct VmaReader {
|
struct VmaReader {
|
||||||
@@ -426,13 +427,14 @@ VmaDeviceInfo *vma_reader_get_device_info(VmaReader *vmar, guint8 dev_id)
|
@@ -425,13 +426,14 @@ VmaDeviceInfo *vma_reader_get_device_info(VmaReader *vmar, guint8 dev_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void allocate_rstate(VmaReader *vmar, guint8 dev_id,
|
static void allocate_rstate(VmaReader *vmar, guint8 dev_id,
|
||||||
@ -51,7 +51,7 @@ index 4f4ee2b47b..844d95a5ba 100644
|
|||||||
|
|
||||||
int64_t size = vmar->devinfo[dev_id].size;
|
int64_t size = vmar->devinfo[dev_id].size;
|
||||||
|
|
||||||
@@ -447,28 +449,30 @@ static void allocate_rstate(VmaReader *vmar, guint8 dev_id,
|
@@ -446,28 +448,30 @@ static void allocate_rstate(VmaReader *vmar, guint8 dev_id,
|
||||||
}
|
}
|
||||||
|
|
||||||
int vma_reader_register_bs(VmaReader *vmar, guint8 dev_id, BlockBackend *target,
|
int vma_reader_register_bs(VmaReader *vmar, guint8 dev_id, BlockBackend *target,
|
||||||
@ -99,7 +99,7 @@ index 4f4ee2b47b..844d95a5ba 100644
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -561,19 +565,23 @@ static int restore_extent(VmaReader *vmar, unsigned char *buf,
|
@@ -560,19 +564,23 @@ static int restore_extent(VmaReader *vmar, unsigned char *buf,
|
||||||
VmaRestoreState *rstate = &vmar->rstate[dev_id];
|
VmaRestoreState *rstate = &vmar->rstate[dev_id];
|
||||||
BlockBackend *target = NULL;
|
BlockBackend *target = NULL;
|
||||||
|
|
||||||
@ -129,7 +129,7 @@ index 4f4ee2b47b..844d95a5ba 100644
|
|||||||
|
|
||||||
max_sector = vmar->devinfo[dev_id].size/BDRV_SECTOR_SIZE;
|
max_sector = vmar->devinfo[dev_id].size/BDRV_SECTOR_SIZE;
|
||||||
} else {
|
} else {
|
||||||
@@ -619,7 +627,7 @@ static int restore_extent(VmaReader *vmar, unsigned char *buf,
|
@@ -618,7 +626,7 @@ static int restore_extent(VmaReader *vmar, unsigned char *buf,
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -138,7 +138,7 @@ index 4f4ee2b47b..844d95a5ba 100644
|
|||||||
int nb_sectors = end_sector - sector_num;
|
int nb_sectors = end_sector - sector_num;
|
||||||
if (restore_write_data(vmar, dev_id, target, vmstate_fd,
|
if (restore_write_data(vmar, dev_id, target, vmstate_fd,
|
||||||
buf + start, sector_num, nb_sectors,
|
buf + start, sector_num, nb_sectors,
|
||||||
@@ -655,7 +663,7 @@ static int restore_extent(VmaReader *vmar, unsigned char *buf,
|
@@ -654,7 +662,7 @@ static int restore_extent(VmaReader *vmar, unsigned char *buf,
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -147,7 +147,7 @@ index 4f4ee2b47b..844d95a5ba 100644
|
|||||||
int nb_sectors = end_sector - sector_num;
|
int nb_sectors = end_sector - sector_num;
|
||||||
if (restore_write_data(vmar, dev_id, target, vmstate_fd,
|
if (restore_write_data(vmar, dev_id, target, vmstate_fd,
|
||||||
buf + start, sector_num,
|
buf + start, sector_num,
|
||||||
@@ -680,7 +688,7 @@ static int restore_extent(VmaReader *vmar, unsigned char *buf,
|
@@ -679,7 +687,7 @@ static int restore_extent(VmaReader *vmar, unsigned char *buf,
|
||||||
vmar->partial_zero_cluster_data += zero_size;
|
vmar->partial_zero_cluster_data += zero_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -156,7 +156,7 @@ index 4f4ee2b47b..844d95a5ba 100644
|
|||||||
if (restore_write_data(vmar, dev_id, target, vmstate_fd,
|
if (restore_write_data(vmar, dev_id, target, vmstate_fd,
|
||||||
zero_vma_block, sector_num,
|
zero_vma_block, sector_num,
|
||||||
nb_sectors, errp) < 0) {
|
nb_sectors, errp) < 0) {
|
||||||
@@ -851,7 +859,7 @@ int vma_reader_verify(VmaReader *vmar, bool verbose, Error **errp)
|
@@ -850,7 +858,7 @@ int vma_reader_verify(VmaReader *vmar, bool verbose, Error **errp)
|
||||||
|
|
||||||
for (dev_id = 1; dev_id < 255; dev_id++) {
|
for (dev_id = 1; dev_id < 255; dev_id++) {
|
||||||
if (vma_reader_get_device_info(vmar, dev_id)) {
|
if (vma_reader_get_device_info(vmar, dev_id)) {
|
||||||
@ -166,10 +166,10 @@ index 4f4ee2b47b..844d95a5ba 100644
|
|||||||
}
|
}
|
||||||
|
|
||||||
diff --git a/vma.c b/vma.c
|
diff --git a/vma.c b/vma.c
|
||||||
index 91612d50a2..e1a750ff50 100644
|
index e8dffb43e0..e6e9ffc7fe 100644
|
||||||
--- a/vma.c
|
--- a/vma.c
|
||||||
+++ b/vma.c
|
+++ b/vma.c
|
||||||
@@ -139,6 +139,7 @@ typedef struct RestoreMap {
|
@@ -138,6 +138,7 @@ typedef struct RestoreMap {
|
||||||
char *throttling_group;
|
char *throttling_group;
|
||||||
char *cache;
|
char *cache;
|
||||||
bool write_zero;
|
bool write_zero;
|
||||||
@ -177,7 +177,7 @@ index 91612d50a2..e1a750ff50 100644
|
|||||||
} RestoreMap;
|
} RestoreMap;
|
||||||
|
|
||||||
static bool try_parse_option(char **line, const char *optname, char **out, const char *inbuf) {
|
static bool try_parse_option(char **line, const char *optname, char **out, const char *inbuf) {
|
||||||
@@ -246,47 +247,61 @@ static int extract_content(int argc, char **argv)
|
@@ -245,47 +246,61 @@ static int extract_content(int argc, char **argv)
|
||||||
char *bps = NULL;
|
char *bps = NULL;
|
||||||
char *group = NULL;
|
char *group = NULL;
|
||||||
char *cache = NULL;
|
char *cache = NULL;
|
||||||
@ -265,7 +265,7 @@ index 91612d50a2..e1a750ff50 100644
|
|||||||
if (!devname) {
|
if (!devname) {
|
||||||
g_error("read map failed - no dev name specified ('%s')",
|
g_error("read map failed - no dev name specified ('%s')",
|
||||||
inbuf);
|
inbuf);
|
||||||
@@ -300,6 +315,7 @@ static int extract_content(int argc, char **argv)
|
@@ -299,6 +314,7 @@ static int extract_content(int argc, char **argv)
|
||||||
map->throttling_group = group;
|
map->throttling_group = group;
|
||||||
map->cache = cache;
|
map->cache = cache;
|
||||||
map->write_zero = write_zero;
|
map->write_zero = write_zero;
|
||||||
@ -273,7 +273,7 @@ index 91612d50a2..e1a750ff50 100644
|
|||||||
|
|
||||||
g_hash_table_insert(devmap, map->devname, map);
|
g_hash_table_insert(devmap, map->devname, map);
|
||||||
|
|
||||||
@@ -329,6 +345,7 @@ static int extract_content(int argc, char **argv)
|
@@ -328,6 +344,7 @@ static int extract_content(int argc, char **argv)
|
||||||
const char *cache = NULL;
|
const char *cache = NULL;
|
||||||
int flags = BDRV_O_RDWR;
|
int flags = BDRV_O_RDWR;
|
||||||
bool write_zero = true;
|
bool write_zero = true;
|
||||||
@ -281,7 +281,7 @@ index 91612d50a2..e1a750ff50 100644
|
|||||||
|
|
||||||
BlockBackend *blk = NULL;
|
BlockBackend *blk = NULL;
|
||||||
|
|
||||||
@@ -344,6 +361,7 @@ static int extract_content(int argc, char **argv)
|
@@ -343,6 +360,7 @@ static int extract_content(int argc, char **argv)
|
||||||
throttling_group = map->throttling_group;
|
throttling_group = map->throttling_group;
|
||||||
cache = map->cache;
|
cache = map->cache;
|
||||||
write_zero = map->write_zero;
|
write_zero = map->write_zero;
|
||||||
@ -289,7 +289,7 @@ index 91612d50a2..e1a750ff50 100644
|
|||||||
} else {
|
} else {
|
||||||
devfn = g_strdup_printf("%s/tmp-disk-%s.raw",
|
devfn = g_strdup_printf("%s/tmp-disk-%s.raw",
|
||||||
dirname, di->devname);
|
dirname, di->devname);
|
||||||
@@ -362,57 +380,60 @@ static int extract_content(int argc, char **argv)
|
@@ -361,57 +379,60 @@ static int extract_content(int argc, char **argv)
|
||||||
write_zero = false;
|
write_zero = false;
|
||||||
}
|
}
|
||||||
|
|
@ -112,10 +112,10 @@ index c5eb4d5bad..7471e2ef9d 100644
|
|||||||
|
|
||||||
static const char *const pbs_strong_runtime_opts[] = {
|
static const char *const pbs_strong_runtime_opts[] = {
|
||||||
diff --git a/pbs-restore.c b/pbs-restore.c
|
diff --git a/pbs-restore.c b/pbs-restore.c
|
||||||
index 4d3f925a1b..62042bdd93 100644
|
index 2f834cf42e..f03d9bab8d 100644
|
||||||
--- a/pbs-restore.c
|
--- a/pbs-restore.c
|
||||||
+++ b/pbs-restore.c
|
+++ b/pbs-restore.c
|
||||||
@@ -30,7 +30,7 @@
|
@@ -29,7 +29,7 @@
|
||||||
static void help(void)
|
static void help(void)
|
||||||
{
|
{
|
||||||
const char *help_msg =
|
const char *help_msg =
|
||||||
@ -124,7 +124,7 @@ index 4d3f925a1b..62042bdd93 100644
|
|||||||
;
|
;
|
||||||
|
|
||||||
printf("%s", help_msg);
|
printf("%s", help_msg);
|
||||||
@@ -78,6 +78,7 @@ int main(int argc, char **argv)
|
@@ -77,6 +77,7 @@ int main(int argc, char **argv)
|
||||||
Error *main_loop_err = NULL;
|
Error *main_loop_err = NULL;
|
||||||
const char *format = "raw";
|
const char *format = "raw";
|
||||||
const char *repository = NULL;
|
const char *repository = NULL;
|
||||||
@ -132,7 +132,7 @@ index 4d3f925a1b..62042bdd93 100644
|
|||||||
const char *keyfile = NULL;
|
const char *keyfile = NULL;
|
||||||
int verbose = false;
|
int verbose = false;
|
||||||
bool skip_zero = false;
|
bool skip_zero = false;
|
||||||
@@ -91,6 +92,7 @@ int main(int argc, char **argv)
|
@@ -90,6 +91,7 @@ int main(int argc, char **argv)
|
||||||
{"verbose", no_argument, 0, 'v'},
|
{"verbose", no_argument, 0, 'v'},
|
||||||
{"format", required_argument, 0, 'f'},
|
{"format", required_argument, 0, 'f'},
|
||||||
{"repository", required_argument, 0, 'r'},
|
{"repository", required_argument, 0, 'r'},
|
||||||
@ -140,7 +140,7 @@ index 4d3f925a1b..62042bdd93 100644
|
|||||||
{"keyfile", required_argument, 0, 'k'},
|
{"keyfile", required_argument, 0, 'k'},
|
||||||
{0, 0, 0, 0}
|
{0, 0, 0, 0}
|
||||||
};
|
};
|
||||||
@@ -111,6 +113,9 @@ int main(int argc, char **argv)
|
@@ -110,6 +112,9 @@ int main(int argc, char **argv)
|
||||||
case 'r':
|
case 'r':
|
||||||
repository = g_strdup(argv[optind - 1]);
|
repository = g_strdup(argv[optind - 1]);
|
||||||
break;
|
break;
|
||||||
@ -150,7 +150,7 @@ index 4d3f925a1b..62042bdd93 100644
|
|||||||
case 'k':
|
case 'k':
|
||||||
keyfile = g_strdup(argv[optind - 1]);
|
keyfile = g_strdup(argv[optind - 1]);
|
||||||
break;
|
break;
|
||||||
@@ -161,8 +166,16 @@ int main(int argc, char **argv)
|
@@ -160,8 +165,16 @@ int main(int argc, char **argv)
|
||||||
fprintf(stderr, "connecting to repository '%s'\n", repository);
|
fprintf(stderr, "connecting to repository '%s'\n", repository);
|
||||||
}
|
}
|
||||||
char *pbs_error = NULL;
|
char *pbs_error = NULL;
|
||||||
@ -202,10 +202,10 @@ index 9f6c04a512..f6a5f8c785 100644
|
|||||||
backup_time,
|
backup_time,
|
||||||
dump_cb_block_size,
|
dump_cb_block_size,
|
||||||
diff --git a/qapi/block-core.json b/qapi/block-core.json
|
diff --git a/qapi/block-core.json b/qapi/block-core.json
|
||||||
index 13e03ca154..89875f309c 100644
|
index fc8a125451..cc2ead0b75 100644
|
||||||
--- a/qapi/block-core.json
|
--- a/qapi/block-core.json
|
||||||
+++ b/qapi/block-core.json
|
+++ b/qapi/block-core.json
|
||||||
@@ -821,6 +821,8 @@
|
@@ -817,6 +817,8 @@
|
||||||
#
|
#
|
||||||
# @fingerprint: server cert fingerprint (optional for format 'pbs')
|
# @fingerprint: server cert fingerprint (optional for format 'pbs')
|
||||||
#
|
#
|
||||||
@ -214,7 +214,7 @@ index 13e03ca154..89875f309c 100644
|
|||||||
# @backup-id: backup ID (required for format 'pbs')
|
# @backup-id: backup ID (required for format 'pbs')
|
||||||
#
|
#
|
||||||
# @backup-time: backup timestamp (Unix epoch, required for format 'pbs')
|
# @backup-time: backup timestamp (Unix epoch, required for format 'pbs')
|
||||||
@@ -840,6 +842,7 @@
|
@@ -836,6 +838,7 @@
|
||||||
'*key-password': 'str',
|
'*key-password': 'str',
|
||||||
'*master-keyfile': 'str',
|
'*master-keyfile': 'str',
|
||||||
'*fingerprint': 'str',
|
'*fingerprint': 'str',
|
||||||
@ -222,7 +222,7 @@ index 13e03ca154..89875f309c 100644
|
|||||||
'*backup-id': 'str',
|
'*backup-id': 'str',
|
||||||
'*backup-time': 'int',
|
'*backup-time': 'int',
|
||||||
'*use-dirty-bitmap': 'bool',
|
'*use-dirty-bitmap': 'bool',
|
||||||
@@ -3256,7 +3259,7 @@
|
@@ -3282,7 +3285,7 @@
|
||||||
{ 'struct': 'BlockdevOptionsPbs',
|
{ 'struct': 'BlockdevOptionsPbs',
|
||||||
'data': { 'repository': 'str', 'snapshot': 'str', 'archive': 'str',
|
'data': { 'repository': 'str', 'snapshot': 'str', 'archive': 'str',
|
||||||
'*keyfile': 'str', '*password': 'str', '*fingerprint': '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(-)
|
1 file changed, 2 insertions(+), 40 deletions(-)
|
||||||
|
|
||||||
diff --git a/block/rbd.c b/block/rbd.c
|
diff --git a/block/rbd.c b/block/rbd.c
|
||||||
index 0cec24c86d..0a9b97aa5e 100644
|
index 64a8d7d48b..9fc6dcb957 100644
|
||||||
--- a/block/rbd.c
|
--- a/block/rbd.c
|
||||||
+++ b/block/rbd.c
|
+++ b/block/rbd.c
|
||||||
@@ -1324,7 +1324,6 @@ static int coroutine_fn qemu_rbd_co_block_status(BlockDriverState *bs,
|
@@ -1348,7 +1348,6 @@ static int coroutine_fn qemu_rbd_co_block_status(BlockDriverState *bs,
|
||||||
int status, r;
|
int status, r;
|
||||||
RBDDiffIterateReq req = { .offs = offset };
|
RBDDiffIterateReq req = { .offs = offset };
|
||||||
uint64_t features, flags;
|
uint64_t features, flags;
|
||||||
@ -23,7 +23,7 @@ index 0cec24c86d..0a9b97aa5e 100644
|
|||||||
|
|
||||||
assert(offset + bytes <= s->image_size);
|
assert(offset + bytes <= s->image_size);
|
||||||
|
|
||||||
@@ -1352,43 +1351,7 @@ static int coroutine_fn qemu_rbd_co_block_status(BlockDriverState *bs,
|
@@ -1376,43 +1375,7 @@ static int coroutine_fn qemu_rbd_co_block_status(BlockDriverState *bs,
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -68,7 +68,7 @@ index 0cec24c86d..0a9b97aa5e 100644
|
|||||||
qemu_rbd_diff_iterate_cb, &req);
|
qemu_rbd_diff_iterate_cb, &req);
|
||||||
if (r < 0 && r != QEMU_RBD_EXIT_DIFF_ITERATE2) {
|
if (r < 0 && r != QEMU_RBD_EXIT_DIFF_ITERATE2) {
|
||||||
return status;
|
return status;
|
||||||
@@ -1407,8 +1370,7 @@ static int coroutine_fn qemu_rbd_co_block_status(BlockDriverState *bs,
|
@@ -1431,8 +1394,7 @@ static int coroutine_fn qemu_rbd_co_block_status(BlockDriverState *bs,
|
||||||
status = BDRV_BLOCK_ZERO | BDRV_BLOCK_OFFSET_VALID;
|
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(-)
|
1 file changed, 5 insertions(+), 5 deletions(-)
|
||||||
|
|
||||||
diff --git a/block/rbd.c b/block/rbd.c
|
diff --git a/block/rbd.c b/block/rbd.c
|
||||||
index 0a9b97aa5e..1c585d23e9 100644
|
index 9fc6dcb957..98f4ba2620 100644
|
||||||
--- a/block/rbd.c
|
--- a/block/rbd.c
|
||||||
+++ b/block/rbd.c
|
+++ b/block/rbd.c
|
||||||
@@ -1283,11 +1283,11 @@ static int qemu_rbd_diff_iterate_cb(uint64_t offs, size_t len,
|
@@ -1307,11 +1307,11 @@ static int qemu_rbd_diff_iterate_cb(uint64_t offs, size_t len,
|
||||||
RBDDiffIterateReq *req = opaque;
|
RBDDiffIterateReq *req = opaque;
|
||||||
|
|
||||||
assert(req->offs + req->bytes <= offs);
|
assert(req->offs + req->bytes <= offs);
|
@ -23,7 +23,7 @@ Signed-off-by: Fabian Ebner <f.ebner@proxmox.com>
|
|||||||
1 file changed, 112 deletions(-)
|
1 file changed, 112 deletions(-)
|
||||||
|
|
||||||
diff --git a/block/rbd.c b/block/rbd.c
|
diff --git a/block/rbd.c b/block/rbd.c
|
||||||
index 1c585d23e9..1704767041 100644
|
index 98f4ba2620..efcbbe5949 100644
|
||||||
--- a/block/rbd.c
|
--- a/block/rbd.c
|
||||||
+++ b/block/rbd.c
|
+++ b/block/rbd.c
|
||||||
@@ -97,12 +97,6 @@ typedef struct RBDTask {
|
@@ -97,12 +97,6 @@ typedef struct RBDTask {
|
||||||
@ -39,7 +39,7 @@ index 1c585d23e9..1704767041 100644
|
|||||||
static int qemu_rbd_connect(rados_t *cluster, rados_ioctx_t *io_ctx,
|
static int qemu_rbd_connect(rados_t *cluster, rados_ioctx_t *io_ctx,
|
||||||
BlockdevOptionsRbd *opts, bool cache,
|
BlockdevOptionsRbd *opts, bool cache,
|
||||||
const char *keypairs, const char *secretid,
|
const char *keypairs, const char *secretid,
|
||||||
@@ -1269,111 +1263,6 @@ static ImageInfoSpecific *qemu_rbd_get_specific_info(BlockDriverState *bs,
|
@@ -1293,111 +1287,6 @@ static ImageInfoSpecific *qemu_rbd_get_specific_info(BlockDriverState *bs,
|
||||||
return spec_info;
|
return spec_info;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -151,7 +151,7 @@ index 1c585d23e9..1704767041 100644
|
|||||||
static int64_t qemu_rbd_getlength(BlockDriverState *bs)
|
static int64_t qemu_rbd_getlength(BlockDriverState *bs)
|
||||||
{
|
{
|
||||||
BDRVRBDState *s = bs->opaque;
|
BDRVRBDState *s = bs->opaque;
|
||||||
@@ -1609,7 +1498,6 @@ static BlockDriver bdrv_rbd = {
|
@@ -1633,7 +1522,6 @@ static BlockDriver bdrv_rbd = {
|
||||||
#ifdef LIBRBD_SUPPORTS_WRITE_ZEROES
|
#ifdef LIBRBD_SUPPORTS_WRITE_ZEROES
|
||||||
.bdrv_co_pwrite_zeroes = qemu_rbd_co_pwrite_zeroes,
|
.bdrv_co_pwrite_zeroes = qemu_rbd_co_pwrite_zeroes,
|
||||||
#endif
|
#endif
|
@ -25,10 +25,10 @@ Signed-off-by: Fabian Ebner <f.ebner@proxmox.com>
|
|||||||
1 file changed, 10 insertions(+), 2 deletions(-)
|
1 file changed, 10 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
diff --git a/vma.c b/vma.c
|
diff --git a/vma.c b/vma.c
|
||||||
index e1a750ff50..b1137e27a7 100644
|
index e6e9ffc7fe..304f02bc84 100644
|
||||||
--- a/vma.c
|
--- a/vma.c
|
||||||
+++ b/vma.c
|
+++ b/vma.c
|
||||||
@@ -549,7 +549,7 @@ static void coroutine_fn backup_run(void *opaque)
|
@@ -548,7 +548,7 @@ static void coroutine_fn backup_run(void *opaque)
|
||||||
struct iovec iov;
|
struct iovec iov;
|
||||||
QEMUIOVector qiov;
|
QEMUIOVector qiov;
|
||||||
|
|
||||||
@ -37,7 +37,7 @@ index e1a750ff50..b1137e27a7 100644
|
|||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
unsigned char *buf = blk_blockalign(job->target, VMA_CLUSTER_SIZE);
|
unsigned char *buf = blk_blockalign(job->target, VMA_CLUSTER_SIZE);
|
||||||
@@ -563,8 +563,16 @@ static void coroutine_fn backup_run(void *opaque)
|
@@ -562,8 +562,16 @@ static void coroutine_fn backup_run(void *opaque)
|
||||||
iov.iov_len = VMA_CLUSTER_SIZE;
|
iov.iov_len = VMA_CLUSTER_SIZE;
|
||||||
qemu_iovec_init_external(&qiov, &iov, 1);
|
qemu_iovec_init_external(&qiov, &iov, 1);
|
||||||
|
|
@ -109,10 +109,10 @@ index 2e22030eec..e9aa7e0f49 100644
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
diff --git a/qapi/block-core.json b/qapi/block-core.json
|
diff --git a/qapi/block-core.json b/qapi/block-core.json
|
||||||
index 89875f309c..43281aca79 100644
|
index cc2ead0b75..e3f62faa81 100644
|
||||||
--- a/qapi/block-core.json
|
--- a/qapi/block-core.json
|
||||||
+++ b/qapi/block-core.json
|
+++ b/qapi/block-core.json
|
||||||
@@ -833,6 +833,8 @@
|
@@ -829,6 +829,8 @@
|
||||||
#
|
#
|
||||||
# @encrypt: use encryption ((optional for format 'pbs', defaults to true if there is a keyfile)
|
# @encrypt: use encryption ((optional for format 'pbs', defaults to true if there is a keyfile)
|
||||||
#
|
#
|
||||||
@ -121,7 +121,7 @@ index 89875f309c..43281aca79 100644
|
|||||||
# Returns: the uuid of the backup job
|
# Returns: the uuid of the backup job
|
||||||
#
|
#
|
||||||
##
|
##
|
||||||
@@ -851,7 +853,9 @@
|
@@ -847,7 +849,9 @@
|
||||||
'*format': 'BackupFormat',
|
'*format': 'BackupFormat',
|
||||||
'*config-file': 'str',
|
'*config-file': 'str',
|
||||||
'*firewall-file': 'str',
|
'*firewall-file': 'str',
|
||||||
@ -132,7 +132,7 @@ index 89875f309c..43281aca79 100644
|
|||||||
'returns': 'UuidInfo', 'coroutine': true }
|
'returns': 'UuidInfo', 'coroutine': true }
|
||||||
|
|
||||||
##
|
##
|
||||||
@@ -906,7 +910,8 @@
|
@@ -902,7 +906,8 @@
|
||||||
'pbs-dirty-bitmap-savevm': 'bool',
|
'pbs-dirty-bitmap-savevm': 'bool',
|
||||||
'pbs-dirty-bitmap-migration': 'bool',
|
'pbs-dirty-bitmap-migration': 'bool',
|
||||||
'pbs-masterkey': 'bool',
|
'pbs-masterkey': 'bool',
|
115
debian/patches/series
vendored
115
debian/patches/series
vendored
@ -1,24 +1,4 @@
|
|||||||
extra/0001-monitor-qmp-fix-race-with-clients-disconnecting-earl.patch
|
extra/0001-monitor-qmp-fix-race-with-clients-disconnecting-earl.patch
|
||||||
extra/0002-block-gluster-correctly-set-max_pdiscard.patch
|
|
||||||
extra/0003-block-vmdk-Fix-reopening-bs-file.patch
|
|
||||||
extra/0004-linux-aio-fix-unbalanced-plugged-counter-in-laio_io_.patch
|
|
||||||
extra/0005-pci-fix-overflow-in-snprintf-string-formatting.patch
|
|
||||||
extra/0006-target-i386-kvm-Fix-disabling-MPX-on-cpu-host-with-M.patch
|
|
||||||
extra/0007-coroutine-ucontext-use-QEMU_DEFINE_STATIC_CO_TLS.patch
|
|
||||||
extra/0008-coroutine-use-QEMU_DEFINE_STATIC_CO_TLS.patch
|
|
||||||
extra/0009-coroutine-Rename-qemu_coroutine_inc-dec_pool_size.patch
|
|
||||||
extra/0010-coroutine-Revert-to-constant-batch-size.patch
|
|
||||||
extra/0011-target-i386-do-not-consult-nonexistent-host-leaves.patch
|
|
||||||
extra/0012-virtio-scsi-fix-ctrl-and-event-handler-functions-in-.patch
|
|
||||||
extra/0013-virtio-scsi-don-t-waste-CPU-polling-the-event-virtqu.patch
|
|
||||||
extra/0014-vhost-Track-descriptor-chain-in-private-at-SVQ.patch
|
|
||||||
extra/0015-vhost-Fix-device-s-used-descriptor-dequeue.patch
|
|
||||||
extra/0016-vdpa-Fix-bad-index-calculus-at-vhost_vdpa_get_vring_.patch
|
|
||||||
extra/0017-vdpa-Fix-index-calculus-at-vhost_vdpa_svqs_start.patch
|
|
||||||
extra/0018-hw-virtio-Replace-g_memdup-by-g_memdup2.patch
|
|
||||||
extra/0019-vhost-Fix-element-in-vhost_svq_add-failure.patch
|
|
||||||
extra/0020-io_uring-fix-short-read-slow-path.patch
|
|
||||||
extra/0021-e1000-set-RX-descriptor-status-in-a-separate-operati.patch
|
|
||||||
bitmap-mirror/0001-drive-mirror-add-support-for-sync-bitmap-mode-never.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/0002-drive-mirror-add-support-for-conditional-and-always-.patch
|
||||||
bitmap-mirror/0003-mirror-add-check-for-bitmap-mode-without-bitmap.patch
|
bitmap-mirror/0003-mirror-add-check-for-bitmap-mode-without-bitmap.patch
|
||||||
@ -40,50 +20,51 @@ pve/0012-PVE-Up-qemu-img-dd-add-n-skip_create.patch
|
|||||||
pve/0013-PVE-virtio-balloon-improve-query-balloon.patch
|
pve/0013-PVE-virtio-balloon-improve-query-balloon.patch
|
||||||
pve/0014-PVE-qapi-modify-query-machines.patch
|
pve/0014-PVE-qapi-modify-query-machines.patch
|
||||||
pve/0015-PVE-qapi-modify-spice-query.patch
|
pve/0015-PVE-qapi-modify-spice-query.patch
|
||||||
pve/0016-PVE-add-savevm-async-for-background-state-snapshots.patch
|
pve/0016-PVE-add-IOChannel-implementation-for-savevm-async.patch
|
||||||
pve/0017-PVE-add-optional-buffer-size-to-QEMUFile.patch
|
pve/0017-PVE-add-savevm-async-for-background-state-snapshots.patch
|
||||||
pve/0018-PVE-block-add-the-zeroinit-block-driver-filter.patch
|
pve/0018-PVE-add-optional-buffer-size-to-QEMUFile.patch
|
||||||
pve/0019-PVE-Add-dummy-id-command-line-parameter.patch
|
pve/0019-PVE-block-add-the-zeroinit-block-driver-filter.patch
|
||||||
pve/0020-PVE-Config-Revert-target-i386-disable-LINT0-after-re.patch
|
pve/0020-PVE-Add-dummy-id-command-line-parameter.patch
|
||||||
pve/0021-PVE-Up-Config-file-posix-make-locking-optiono-on-cre.patch
|
pve/0021-PVE-Config-Revert-target-i386-disable-LINT0-after-re.patch
|
||||||
pve/0022-PVE-monitor-disable-oob-capability.patch
|
pve/0022-PVE-Up-Config-file-posix-make-locking-optiono-on-cre.patch
|
||||||
pve/0023-PVE-Compat-4.0-used-balloon-qemu-4-0-config-size-fal.patch
|
pve/0023-PVE-monitor-disable-oob-capability.patch
|
||||||
pve/0024-PVE-Allow-version-code-in-machine-type.patch
|
pve/0024-PVE-Compat-4.0-used-balloon-qemu-4-0-config-size-fal.patch
|
||||||
pve/0025-block-backup-move-bcs-bitmap-initialization-to-job-c.patch
|
pve/0025-PVE-Allow-version-code-in-machine-type.patch
|
||||||
pve/0026-PVE-Backup-add-vma-backup-format-code.patch
|
pve/0026-block-backup-move-bcs-bitmap-initialization-to-job-c.patch
|
||||||
pve/0027-PVE-Backup-add-backup-dump-block-driver.patch
|
pve/0027-PVE-Backup-add-vma-backup-format-code.patch
|
||||||
pve/0028-PVE-Backup-proxmox-backup-patches-for-qemu.patch
|
pve/0028-PVE-Backup-add-backup-dump-block-driver.patch
|
||||||
pve/0029-PVE-Backup-pbs-restore-new-command-to-restore-from-p.patch
|
pve/0029-PVE-Backup-proxmox-backup-patches-for-qemu.patch
|
||||||
pve/0030-PVE-Backup-Add-dirty-bitmap-tracking-for-incremental.patch
|
pve/0030-PVE-Backup-pbs-restore-new-command-to-restore-from-p.patch
|
||||||
pve/0031-PVE-various-PBS-fixes.patch
|
pve/0031-PVE-Backup-Add-dirty-bitmap-tracking-for-incremental.patch
|
||||||
pve/0032-PVE-Add-PBS-block-driver-to-map-backup-archives-into.patch
|
pve/0032-PVE-various-PBS-fixes.patch
|
||||||
pve/0033-PVE-add-query_proxmox_support-QMP-command.patch
|
pve/0033-PVE-Add-PBS-block-driver-to-map-backup-archives-into.patch
|
||||||
pve/0034-PVE-add-query-pbs-bitmap-info-QMP-call.patch
|
pve/0034-PVE-add-query_proxmox_support-QMP-command.patch
|
||||||
pve/0035-PVE-redirect-stderr-to-journal-when-daemonized.patch
|
pve/0035-PVE-add-query-pbs-bitmap-info-QMP-call.patch
|
||||||
pve/0036-PVE-Add-sequential-job-transaction-support.patch
|
pve/0036-PVE-redirect-stderr-to-journal-when-daemonized.patch
|
||||||
pve/0037-PVE-Backup-Use-a-transaction-to-synchronize-job-stat.patch
|
pve/0037-PVE-Add-sequential-job-transaction-support.patch
|
||||||
pve/0038-PVE-Backup-Don-t-block-on-finishing-and-cleanup-crea.patch
|
pve/0038-PVE-Backup-Use-a-transaction-to-synchronize-job-stat.patch
|
||||||
pve/0039-PVE-Migrate-dirty-bitmap-state-via-savevm.patch
|
pve/0039-PVE-Backup-Don-t-block-on-finishing-and-cleanup-crea.patch
|
||||||
pve/0040-migration-block-dirty-bitmap-migrate-other-bitmaps-e.patch
|
pve/0040-PVE-Migrate-dirty-bitmap-state-via-savevm.patch
|
||||||
pve/0041-PVE-fall-back-to-open-iscsi-initiatorname.patch
|
pve/0041-migration-block-dirty-bitmap-migrate-other-bitmaps-e.patch
|
||||||
pve/0042-PVE-Use-coroutine-QMP-for-backup-cancel_backup.patch
|
pve/0042-PVE-fall-back-to-open-iscsi-initiatorname.patch
|
||||||
pve/0043-PBS-add-master-key-support.patch
|
pve/0043-PVE-Use-coroutine-QMP-for-backup-cancel_backup.patch
|
||||||
pve/0044-PVE-block-pbs-fast-path-reads-without-allocation-if-.patch
|
pve/0044-PBS-add-master-key-support.patch
|
||||||
pve/0045-PVE-block-stream-increase-chunk-size.patch
|
pve/0045-PVE-block-pbs-fast-path-reads-without-allocation-if-.patch
|
||||||
pve/0046-block-io-accept-NULL-qiov-in-bdrv_pad_request.patch
|
pve/0046-PVE-block-stream-increase-chunk-size.patch
|
||||||
pve/0047-block-add-alloc-track-driver.patch
|
pve/0047-block-io-accept-NULL-qiov-in-bdrv_pad_request.patch
|
||||||
pve/0048-PVE-whitelist-invalid-QAPI-names-for-backwards-compa.patch
|
pve/0048-block-add-alloc-track-driver.patch
|
||||||
pve/0049-PVE-savevm-async-register-yank-before-migration_inco.patch
|
pve/0049-PVE-whitelist-invalid-QAPI-names-for-backwards-compa.patch
|
||||||
pve/0050-qemu-img-dd-add-l-option-for-loading-a-snapshot.patch
|
pve/0050-PVE-savevm-async-register-yank-before-migration_inco.patch
|
||||||
pve/0051-vma-allow-partial-restore.patch
|
pve/0051-qemu-img-dd-add-l-option-for-loading-a-snapshot.patch
|
||||||
pve/0052-pbs-namespace-support.patch
|
pve/0052-vma-allow-partial-restore.patch
|
||||||
pve/0053-Revert-block-rbd-workaround-for-ceph-issue-53784.patch
|
pve/0053-pbs-namespace-support.patch
|
||||||
pve/0054-Revert-block-rbd-fix-handling-of-holes-in-.bdrv_co_b.patch
|
pve/0054-Revert-block-rbd-workaround-for-ceph-issue-53784.patch
|
||||||
pve/0055-Revert-block-rbd-implement-bdrv_co_block_status.patch
|
pve/0055-Revert-block-rbd-fix-handling-of-holes-in-.bdrv_co_b.patch
|
||||||
pve/0056-PVE-Backup-create-jobs-correctly-cancel-in-error-sce.patch
|
pve/0056-Revert-block-rbd-implement-bdrv_co_block_status.patch
|
||||||
pve/0057-PVE-Backup-ensure-jobs-in-di_list-are-referenced.patch
|
pve/0057-PVE-Backup-create-jobs-correctly-cancel-in-error-sce.patch
|
||||||
pve/0058-PVE-Backup-avoid-segfault-issues-upon-backup-cancel.patch
|
pve/0058-PVE-Backup-ensure-jobs-in-di_list-are-referenced.patch
|
||||||
pve/0059-vma-create-support-64KiB-unaligned-input-images.patch
|
pve/0059-PVE-Backup-avoid-segfault-issues-upon-backup-cancel.patch
|
||||||
pve/0060-vma-create-avoid-triggering-assertion-in-error-case.patch
|
pve/0060-vma-create-support-64KiB-unaligned-input-images.patch
|
||||||
pve/0061-block-alloc-track-avoid-premature-break.patch
|
pve/0061-vma-create-avoid-triggering-assertion-in-error-case.patch
|
||||||
pve/0062-PVE-Backup-allow-passing-max-workers-performance-set.patch
|
pve/0062-block-alloc-track-avoid-premature-break.patch
|
||||||
|
pve/0063-PVE-Backup-allow-passing-max-workers-performance-set.patch
|
||||||
|
2
qemu
2
qemu
@ -1 +1 @@
|
|||||||
Subproject commit 823a3f11fb8f04c3c3cc0f95f968fef1bfc6534f
|
Subproject commit 621da7789083b80d6f1ff1c0fb499334007b4f51
|
Loading…
Reference in New Issue
Block a user