bump version to 3.0.1-1

Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
master
Wolfgang Bumiller 2019-04-19 09:53:37 +02:00
parent 4ba321f213
commit 0775f12b63
32 changed files with 451 additions and 956 deletions

View File

@ -1,6 +1,6 @@
# also update debian/changelog
KVMVER=3.0.0
KVMPKGREL=1~pvetest2
KVMVER=3.0.1
KVMPKGREL=1
KVMPACKAGE = pve-qemu-kvm
KVMSRC = qemu

40
debian/changelog vendored
View File

@ -1,8 +1,42 @@
pve-qemu-kvm (3.0.0-1~pvetest2) unstable; urgency=medium
pve-qemu-kvm (3.0.1-1) unstable; urgency=medium
* update to 3.0.0
* update to 3.0.1
-- Proxmox Support Team <support@proxmox.com> Thu, 30 Aug 2018 14:59:49 +0200
-- Proxmox Support Team <support@proxmox.com> Fri, 19 Apr 2019 09:51:15 +0200
pve-qemu-kvm (2.12.1-3) stable; urgency=medium
* fix an error handling issue with live snapshots where if a storage runs
full the process would ignore the error
-- Proxmox Support Team <support@proxmox.com> Mon, 18 Mar 2019 11:34:08 +0100
pve-qemu-kvm (2.12.1-2) stable; urgency=medium
* fix CVE-2019-3812: Out-of-bounds read in hw/i2c/i2c-ddc.c allows for memory
disclosure
* fix CVE-2018-18849: lsi53c895a: OOB msg buffer access leads to DoS
* fix CVE-2018-20124: rdma: OOB access when building scatter-gather array
* fix CVE-2019-6778: slirp: heap buffer overflow in tcp_emu()
-- Proxmox Support Team <support@proxmox.com> Tue, 19 Feb 2019 09:28:42 +0100
pve-qemu-kvm (2.12.1-1) stable; urgency=medium
* update to 2.12.1 with some additional CVE fixes included
* fix CVE-2018-10839: ne2000: integer overflow leads to buffer overflow issue
* fix CVE-2018-17958: rtl8139: integer overflow leads to buffer overflow
* fix CVE-2018-17962: pcnet: integer overflow leads to buffer overflow
* fix CVE-2018-17963: net: ignore packets with large size
-- Proxmox Support Team <support@proxmox.com> Tue, 16 Oct 2018 14:22:11 +0200
pve-qemu-kvm (2.11.2-1) stable; urgency=medium

View File

@ -0,0 +1,36 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Wolfgang Bumiller <w.bumiller@proxmox.com>
Date: Tue, 25 Sep 2018 10:15:06 +0200
Subject: [PATCH] monitor: guard iothread access by mon->use_io_thread
monitor_resume() and monitor_suspend() both want to
"kick" the I/O thread if it is there, but in
monitor_suspend() lacked the use_io_thread flag condition.
This is required when we later only spawn the thread on
first use.
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Peter Xu <peterx@redhat.com>
Message-Id: <20180925081507.11873-2-w.bumiller@proxmox.com>
Signed-off-by: Markus Armbruster <armbru@redhat.com>
---
monitor.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/monitor.c b/monitor.c
index a1999e396c..836c0bbdaa 100644
--- a/monitor.c
+++ b/monitor.c
@@ -4376,7 +4376,7 @@ int monitor_suspend(Monitor *mon)
atomic_inc(&mon->suspend_cnt);
- if (monitor_is_qmp(mon)) {
+ if (monitor_is_qmp(mon) && mon->use_io_thread) {
/*
* Kick I/O thread to make sure this takes effect. It'll be
* evaluated again in prepare() of the watch object.
--
2.11.0

View File

@ -1,47 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= <marcandre.lureau@redhat.com>
Date: Wed, 22 Aug 2018 19:02:47 +0200
Subject: [PATCH] seccomp: use SIGSYS signal instead of killing the thread
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
The seccomp action SCMP_ACT_KILL results in immediate termination of
the thread that made the bad system call. However, qemu being
multi-threaded, it keeps running. There is no easy way for parent
process / management layer (libvirt) to know about that situation.
Instead, the default SIGSYS handler when invoked with SCMP_ACT_TRAP
will terminate the program and core dump.
This may not be the most secure solution, but probably better than
just killing the offending thread. SCMP_ACT_KILL_PROCESS has been
added in Linux 4.14 to improve the situation, which I propose to use
by default if available in the next patch.
Related to:
https://bugzilla.redhat.com/show_bug.cgi?id=1594456
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Acked-by: Eduardo Otubo <otubo@redhat.com>
---
qemu-seccomp.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/qemu-seccomp.c b/qemu-seccomp.c
index 9cd8eb9499..b117a92559 100644
--- a/qemu-seccomp.c
+++ b/qemu-seccomp.c
@@ -125,7 +125,7 @@ static int seccomp_start(uint32_t seccomp_opts)
continue;
}
- rc = seccomp_rule_add_array(ctx, SCMP_ACT_KILL, blacklist[i].num,
+ rc = seccomp_rule_add_array(ctx, SCMP_ACT_TRAP, blacklist[i].num,
blacklist[i].narg, blacklist[i].arg_cmp);
if (rc < 0) {
goto seccomp_return;
--
2.11.0

View File

@ -0,0 +1,114 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Wolfgang Bumiller <w.bumiller@proxmox.com>
Date: Tue, 25 Sep 2018 10:15:07 +0200
Subject: [PATCH] monitor: delay monitor iothread creation
Commit d32749deb615 moved the call to monitor_init_globals()
to before os_daemonize(), making it an unsuitable place to
spawn the monitor iothread as it won't be inherited over the
fork() in os_daemonize().
We now spawn the thread the first time we instantiate a
monitor which actually has use_io_thread == true.
Instantiation of monitors happens only after os_daemonize().
We still need to create the qmp_dispatcher_bh when not using
iothreads, so this now still happens in
monitor_init_globals().
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
Fixes: d32749deb615 ("monitor: move init global earlier")
Message-Id: <20180925081507.11873-3-w.bumiller@proxmox.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Peter Xu <peterx@redhat.com>
Tested-by: Peter Xu <peterx@redhat.com>
[This fixes a crash on shutdown with --daemonize]
Signed-off-by: Markus Armbruster <armbru@redhat.com>
---
monitor.c | 36 ++++++++++++++++++++++--------------
1 file changed, 22 insertions(+), 14 deletions(-)
diff --git a/monitor.c b/monitor.c
index 836c0bbdaa..c7eae64fd9 100644
--- a/monitor.c
+++ b/monitor.c
@@ -807,9 +807,14 @@ static void monitor_qapi_event_init(void)
static void handle_hmp_command(Monitor *mon, const char *cmdline);
+static void monitor_iothread_init(void);
+
static void monitor_data_init(Monitor *mon, bool skip_flush,
bool use_io_thread)
{
+ if (use_io_thread && !mon_iothread) {
+ monitor_iothread_init();
+ }
memset(mon, 0, sizeof(Monitor));
qemu_mutex_init(&mon->mon_lock);
qemu_mutex_init(&mon->qmp.qmp_queue_lock);
@@ -4544,6 +4549,15 @@ static AioContext *monitor_get_aio_context(void)
static void monitor_iothread_init(void)
{
mon_iothread = iothread_create("mon_iothread", &error_abort);
+}
+
+void monitor_init_globals(void)
+{
+ monitor_init_qmp_commands();
+ monitor_qapi_event_init();
+ sortcmdlist();
+ qemu_mutex_init(&monitor_lock);
+ qemu_mutex_init(&mon_fdsets_lock);
/*
* The dispatcher BH must run in the main loop thread, since we
@@ -4559,21 +4573,11 @@ static void monitor_iothread_init(void)
* monitors that are using the I/O thread have their output
* written by the I/O thread.
*/
- qmp_respond_bh = aio_bh_new(monitor_get_aio_context(),
+ qmp_respond_bh = aio_bh_new(iohandler_get_aio_context(),
monitor_qmp_bh_responder,
NULL);
}
-void monitor_init_globals(void)
-{
- monitor_init_qmp_commands();
- monitor_qapi_event_init();
- sortcmdlist();
- qemu_mutex_init(&monitor_lock);
- qemu_mutex_init(&mon_fdsets_lock);
- monitor_iothread_init();
-}
-
/* These functions just adapt the readline interface in a typesafe way. We
* could cast function pointers but that discards compiler checks.
*/
@@ -4711,7 +4715,9 @@ void monitor_cleanup(void)
* we need to unregister from chardev below in
* monitor_data_destroy(), and chardev is not thread-safe yet
*/
- iothread_stop(mon_iothread);
+ if (mon_iothread) {
+ iothread_stop(mon_iothread);
+ }
/*
* Flush all response queues. Note that even after this flush,
@@ -4735,8 +4741,10 @@ void monitor_cleanup(void)
qemu_bh_delete(qmp_respond_bh);
qmp_respond_bh = NULL;
- iothread_destroy(mon_iothread);
- mon_iothread = NULL;
+ if (mon_iothread) {
+ iothread_destroy(mon_iothread);
+ mon_iothread = NULL;
+ }
}
QemuOptsList qemu_mon_opts = {
--
2.11.0

View File

@ -1,90 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= <marcandre.lureau@redhat.com>
Date: Wed, 22 Aug 2018 19:02:48 +0200
Subject: [PATCH] seccomp: prefer SCMP_ACT_KILL_PROCESS if available
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
The upcoming libseccomp release should have SCMP_ACT_KILL_PROCESS
action (https://github.com/seccomp/libseccomp/issues/96).
SCMP_ACT_KILL_PROCESS is preferable to immediately terminate the
offending process, rather than having the SIGSYS handler running.
Use SECCOMP_GET_ACTION_AVAIL to check availability of kernel support,
as libseccomp will fallback on SCMP_ACT_KILL otherwise, and we still
prefer SCMP_ACT_TRAP.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Acked-by: Eduardo Otubo <otubo@redhat.com>
---
qemu-seccomp.c | 31 ++++++++++++++++++++++++++++++-
1 file changed, 30 insertions(+), 1 deletion(-)
diff --git a/qemu-seccomp.c b/qemu-seccomp.c
index b117a92559..f0c833f3ca 100644
--- a/qemu-seccomp.c
+++ b/qemu-seccomp.c
@@ -20,6 +20,7 @@
#include <sys/prctl.h>
#include <seccomp.h>
#include "sysemu/seccomp.h"
+#include <linux/seccomp.h>
/* For some architectures (notably ARM) cacheflush is not supported until
* libseccomp 2.2.3, but configure enforces that we are using a more recent
@@ -107,12 +108,40 @@ static const struct QemuSeccompSyscall blacklist[] = {
{ SCMP_SYS(sched_get_priority_min), QEMU_SECCOMP_SET_RESOURCECTL },
};
+static inline __attribute__((unused)) int
+qemu_seccomp(unsigned int operation, unsigned int flags, void *args)
+{
+#ifdef __NR_seccomp
+ return syscall(__NR_seccomp, operation, flags, args);
+#else
+ errno = ENOSYS;
+ return -1;
+#endif
+}
+
+static uint32_t qemu_seccomp_get_kill_action(void)
+{
+#if defined(SECCOMP_GET_ACTION_AVAIL) && defined(SCMP_ACT_KILL_PROCESS) && \
+ defined(SECCOMP_RET_KILL_PROCESS)
+ {
+ uint32_t action = SECCOMP_RET_KILL_PROCESS;
+
+ if (qemu_seccomp(SECCOMP_GET_ACTION_AVAIL, 0, &action) == 0) {
+ return SCMP_ACT_KILL_PROCESS;
+ }
+ }
+#endif
+
+ return SCMP_ACT_TRAP;
+}
+
static int seccomp_start(uint32_t seccomp_opts)
{
int rc = 0;
unsigned int i = 0;
scmp_filter_ctx ctx;
+ uint32_t action = qemu_seccomp_get_kill_action();
ctx = seccomp_init(SCMP_ACT_ALLOW);
if (ctx == NULL) {
@@ -125,7 +154,7 @@ static int seccomp_start(uint32_t seccomp_opts)
continue;
}
- rc = seccomp_rule_add_array(ctx, SCMP_ACT_TRAP, blacklist[i].num,
+ rc = seccomp_rule_add_array(ctx, action, blacklist[i].num,
blacklist[i].narg, blacklist[i].arg_cmp);
if (rc < 0) {
goto seccomp_return;
--
2.11.0

View File

@ -1,53 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= <marcandre.lureau@redhat.com>
Date: Wed, 22 Aug 2018 19:02:49 +0200
Subject: [PATCH] configure: require libseccomp 2.2.0
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
The following patch is going to require TSYNC, which is only available
since libseccomp 2.2.0.
libseccomp 2.2.0 was released February 12, 2015.
According to repology, libseccomp version in different distros:
RHEL-7: 2.3.1
Debian (Stretch): 2.3.1
OpenSUSE Leap 15: 2.3.2
Ubuntu (Xenial): 2.3.1
This will drop support for -sandbox on:
Debian (Jessie): 2.1.1 (but 2.2.3 in backports)
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Acked-by: Eduardo Otubo <otubo@redhat.com>
---
configure | 7 ++-----
1 file changed, 2 insertions(+), 5 deletions(-)
diff --git a/configure b/configure
index 601c1f44f9..d2cc11cdbb 100755
--- a/configure
+++ b/configure
@@ -2222,13 +2222,10 @@ fi
##########################################
# libseccomp check
+libseccomp_minver="2.2.0"
if test "$seccomp" != "no" ; then
case "$cpu" in
- i386|x86_64)
- libseccomp_minver="2.1.0"
- ;;
- mips)
- libseccomp_minver="2.2.0"
+ i386|x86_64|mips)
;;
arm|aarch64)
libseccomp_minver="2.2.3"
--
2.11.0

View File

@ -1,57 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= <marcandre.lureau@redhat.com>
Date: Wed, 22 Aug 2018 19:02:50 +0200
Subject: [PATCH] seccomp: set the seccomp filter to all threads
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
When using "-seccomp on", the seccomp policy is only applied to the
main thread, the vcpu worker thread and other worker threads created
after seccomp policy is applied; the seccomp policy is not applied to
e.g. the RCU thread because it is created before the seccomp policy is
applied and SECCOMP_FILTER_FLAG_TSYNC isn't used.
This can be verified with
for task in /proc/`pidof qemu`/task/*; do cat $task/status | grep Secc ; done
Seccomp: 2
Seccomp: 0
Seccomp: 0
Seccomp: 2
Seccomp: 2
Seccomp: 2
Starting with libseccomp 2.2.0 and kernel >= 3.17, we can use
seccomp_attr_set(ctx, > SCMP_FLTATR_CTL_TSYNC, 1) to update the policy
on all threads.
libseccomp requirement was bumped to 2.2.0 in previous patch.
libseccomp should fail to set the filter if it can't honour
SCMP_FLTATR_CTL_TSYNC (untested), and thus -sandbox will now fail on
kernel < 3.17.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Acked-by: Eduardo Otubo <otubo@redhat.com>
---
qemu-seccomp.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/qemu-seccomp.c b/qemu-seccomp.c
index f0c833f3ca..4729eb107f 100644
--- a/qemu-seccomp.c
+++ b/qemu-seccomp.c
@@ -149,6 +149,11 @@ static int seccomp_start(uint32_t seccomp_opts)
goto seccomp_return;
}
+ rc = seccomp_attr_set(ctx, SCMP_FLTATR_CTL_TSYNC, 1);
+ if (rc != 0) {
+ goto seccomp_return;
+ }
+
for (i = 0; i < ARRAY_SIZE(blacklist); i++) {
if (!(seccomp_opts & blacklist[i].set)) {
continue;
--
2.11.0

View File

@ -1,73 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Wolfgang Bumiller <w.bumiller@proxmox.com>
Date: Fri, 7 Sep 2018 14:45:51 +0200
Subject: [PATCH] monitor: create iothread after daemonizing
Commit d32749deb615 moved the call to monitor_init_globals()
to before os_daemonize() in order to initialize locks used
when parsing arguments and instantiating monitors.
This function also creates an iothread which is now lost
when fork()ing in os_daemonize(), causing its final join to
fail.
Fix this by exposing monitor_iothread_init() to be used in
vl.c after the os_daemonize() call.
FIXME: verify nothing between the new init() place and
iothread spawning actually already depends on the iothread.
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
Fixes: d32749deb615 ("monitor: move init global earlier")
---
include/monitor/monitor.h | 1 +
monitor.c | 3 +--
vl.c | 1 +
3 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/include/monitor/monitor.h b/include/monitor/monitor.h
index 2ef5e04b37..119c4a393e 100644
--- a/include/monitor/monitor.h
+++ b/include/monitor/monitor.h
@@ -18,6 +18,7 @@ extern __thread Monitor *cur_mon;
bool monitor_cur_is_qmp(void);
void monitor_init_globals(void);
+void monitor_iothread_init(void);
void monitor_init(Chardev *chr, int flags);
void monitor_cleanup(void);
diff --git a/monitor.c b/monitor.c
index 77861e96af..24bfa0266b 100644
--- a/monitor.c
+++ b/monitor.c
@@ -4539,7 +4539,7 @@ static AioContext *monitor_get_aio_context(void)
return iothread_get_aio_context(mon_iothread);
}
-static void monitor_iothread_init(void)
+void monitor_iothread_init(void)
{
mon_iothread = iothread_create("mon_iothread", &error_abort);
@@ -4569,7 +4569,6 @@ void monitor_init_globals(void)
sortcmdlist();
qemu_mutex_init(&monitor_lock);
qemu_mutex_init(&mon_fdsets_lock);
- monitor_iothread_init();
}
/* These functions just adapt the readline interface in a typesafe way. We
diff --git a/vl.c b/vl.c
index a03e4c2867..d96f4d0d2a 100644
--- a/vl.c
+++ b/vl.c
@@ -4008,6 +4008,7 @@ int main(int argc, char **argv, char **envp)
os_daemonize();
rcu_disable_atfork();
+ monitor_iothread_init();
if (pid_file && qemu_create_pidfile(pid_file) != 0) {
error_report("could not acquire pid file: %s", strerror(errno));
--
2.11.0

View File

@ -8,10 +8,10 @@ Subject: [PATCH] PVE: [Config] Adjust network script path to /etc/kvm/
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/include/net/net.h b/include/net/net.h
index 1425960f76..fdf0957642 100644
index 3e4638b8c6..e4dfe43f75 100644
--- a/include/net/net.h
+++ b/include/net/net.h
@@ -216,8 +216,9 @@ void qmp_netdev_add(QDict *qdict, QObject **ret, Error **errp);
@@ -210,8 +210,9 @@ void qmp_netdev_add(QDict *qdict, QObject **ret, Error **errp);
int net_hub_id_for_client(NetClientState *nc, int *id);
NetClientState *net_hub_port_find(int hub_id);

View File

@ -17,7 +17,7 @@ Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
1 file changed, 2 insertions(+)
diff --git a/block/rbd.c b/block/rbd.c
index ca8e5bbace..34ae730711 100644
index 014c68d629..53293845f6 100644
--- a/block/rbd.c
+++ b/block/rbd.c
@@ -634,6 +634,8 @@ static int qemu_rbd_connect(rados_t *cluster, rados_ioctx_t *io_ctx,

View File

@ -10,10 +10,10 @@ Subject: [PATCH] PVE: [Up] qmp: add get_link_status
3 files changed, 43 insertions(+)
diff --git a/net/net.c b/net/net.c
index 2a3133990c..cd9178d6c9 100644
index f8275843fb..8c8e100afa 100644
--- a/net/net.c
+++ b/net/net.c
@@ -1331,6 +1331,33 @@ void hmp_info_network(Monitor *mon, const QDict *qdict)
@@ -1342,6 +1342,33 @@ void hmp_info_network(Monitor *mon, const QDict *qdict)
}
}

View File

@ -8,10 +8,10 @@ Subject: [PATCH] PVE: [Up] qemu-img: return success on info without snapshots
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/qemu-img.c b/qemu-img.c
index 1acddf693c..4438e0c2c9 100644
index 4799e097dc..789217cd35 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -2720,7 +2720,8 @@ static int img_info(int argc, char **argv)
@@ -2719,7 +2719,8 @@ static int img_info(int argc, char **argv)
list = collect_image_info_list(image_opts, filename, fmt, chain,
force_share);
if (!list) {

View File

@ -52,10 +52,10 @@ index 1526f327a5..0ea4b6ffb2 100644
DEF("info", img_info,
diff --git a/qemu-img.c b/qemu-img.c
index 4438e0c2c9..f46eefce4f 100644
index 789217cd35..f459dd8345 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -4302,10 +4302,12 @@ out:
@@ -4301,10 +4301,12 @@ out:
#define C_IF 04
#define C_OF 010
#define C_SKIP 020
@ -68,7 +68,7 @@ index 4438e0c2c9..f46eefce4f 100644
};
struct DdIo {
@@ -4384,6 +4386,20 @@ static int img_dd_skip(const char *arg,
@@ -4383,6 +4385,20 @@ static int img_dd_skip(const char *arg,
return 0;
}
@ -89,7 +89,7 @@ index 4438e0c2c9..f46eefce4f 100644
static int img_dd(int argc, char **argv)
{
int ret = 0;
@@ -4424,6 +4440,7 @@ static int img_dd(int argc, char **argv)
@@ -4423,6 +4439,7 @@ static int img_dd(int argc, char **argv)
{ "if", img_dd_if, C_IF },
{ "of", img_dd_of, C_OF },
{ "skip", img_dd_skip, C_SKIP },
@ -97,7 +97,7 @@ index 4438e0c2c9..f46eefce4f 100644
{ NULL, NULL, 0 }
};
const struct option long_options[] = {
@@ -4502,8 +4519,13 @@ static int img_dd(int argc, char **argv)
@@ -4501,8 +4518,13 @@ static int img_dd(int argc, char **argv)
arg = NULL;
}
@ -113,7 +113,7 @@ index 4438e0c2c9..f46eefce4f 100644
ret = -1;
goto out;
}
@@ -4515,85 +4537,101 @@ static int img_dd(int argc, char **argv)
@@ -4514,85 +4536,101 @@ static int img_dd(int argc, char **argv)
goto out;
}
@ -279,7 +279,7 @@ index 4438e0c2c9..f46eefce4f 100644
}
if (dd.flags & C_SKIP && (in.offset > INT64_MAX / in.bsz ||
@@ -4611,11 +4649,17 @@ static int img_dd(int argc, char **argv)
@@ -4610,11 +4648,17 @@ static int img_dd(int argc, char **argv)
for (out_pos = 0; in_pos < size; block_count++) {
int in_ret, out_ret;
@ -301,7 +301,7 @@ index 4438e0c2c9..f46eefce4f 100644
}
if (in_ret < 0) {
error_report("error while reading from input image file: %s",
@@ -4625,9 +4669,13 @@ static int img_dd(int argc, char **argv)
@@ -4624,9 +4668,13 @@ static int img_dd(int argc, char **argv)
}
in_pos += in_ret;

View File

@ -14,10 +14,10 @@ Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
1 file changed, 26 insertions(+), 3 deletions(-)
diff --git a/qemu-img.c b/qemu-img.c
index f46eefce4f..ec546846c6 100644
index f459dd8345..1f623f5bba 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -4303,11 +4303,13 @@ out:
@@ -4302,11 +4302,13 @@ out:
#define C_OF 010
#define C_SKIP 020
#define C_OSIZE 040
@ -31,7 +31,7 @@ index f46eefce4f..ec546846c6 100644
};
struct DdIo {
@@ -4400,6 +4402,20 @@ static int img_dd_osize(const char *arg,
@@ -4399,6 +4401,20 @@ static int img_dd_osize(const char *arg,
return 0;
}
@ -52,7 +52,7 @@ index f46eefce4f..ec546846c6 100644
static int img_dd(int argc, char **argv)
{
int ret = 0;
@@ -4414,12 +4430,14 @@ static int img_dd(int argc, char **argv)
@@ -4413,12 +4429,14 @@ static int img_dd(int argc, char **argv)
int c, i;
const char *out_fmt = "raw";
const char *fmt = NULL;
@ -68,7 +68,7 @@ index f46eefce4f..ec546846c6 100644
};
struct DdIo in = {
.bsz = 512, /* Block size is by default 512 bytes */
@@ -4441,6 +4459,7 @@ static int img_dd(int argc, char **argv)
@@ -4440,6 +4458,7 @@ static int img_dd(int argc, char **argv)
{ "of", img_dd_of, C_OF },
{ "skip", img_dd_skip, C_SKIP },
{ "osize", img_dd_osize, C_OSIZE },
@ -76,7 +76,7 @@ index f46eefce4f..ec546846c6 100644
{ NULL, NULL, 0 }
};
const struct option long_options[] = {
@@ -4647,14 +4666,18 @@ static int img_dd(int argc, char **argv)
@@ -4646,14 +4665,18 @@ static int img_dd(int argc, char **argv)
in.buf = g_new(uint8_t, in.bsz);

View File

@ -8,10 +8,10 @@ Subject: [PATCH] PVE: [Up] qemu-img dd : add -n skip_create
1 file changed, 14 insertions(+), 9 deletions(-)
diff --git a/qemu-img.c b/qemu-img.c
index ec546846c6..afa6e26ccf 100644
index 1f623f5bba..5d9322db33 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -4432,7 +4432,7 @@ static int img_dd(int argc, char **argv)
@@ -4431,7 +4431,7 @@ static int img_dd(int argc, char **argv)
const char *fmt = NULL;
int64_t size = 0, readsize = 0;
int64_t block_count = 0, out_pos, in_pos;
@ -20,7 +20,7 @@ index ec546846c6..afa6e26ccf 100644
struct DdInfo dd = {
.flags = 0,
.count = 0,
@@ -4470,7 +4470,7 @@ static int img_dd(int argc, char **argv)
@@ -4469,7 +4469,7 @@ static int img_dd(int argc, char **argv)
{ 0, 0, 0, 0 }
};
@ -29,7 +29,7 @@ index ec546846c6..afa6e26ccf 100644
if (c == EOF) {
break;
}
@@ -4490,6 +4490,9 @@ static int img_dd(int argc, char **argv)
@@ -4489,6 +4489,9 @@ static int img_dd(int argc, char **argv)
case 'h':
help();
break;
@ -39,7 +39,7 @@ index ec546846c6..afa6e26ccf 100644
case 'U':
force_share = true;
break;
@@ -4630,13 +4633,15 @@ static int img_dd(int argc, char **argv)
@@ -4629,13 +4632,15 @@ static int img_dd(int argc, char **argv)
size - in.bsz * in.offset, &error_abort);
}

View File

@ -32,7 +32,7 @@ index a7d890c076..4e8ebf9adc 100644
##
diff --git a/vl.c b/vl.c
index 16b913f9d5..c750b7c18e 100644
index 12d27fa028..9c3a41bfe2 100644
--- a/vl.c
+++ b/vl.c
@@ -1455,6 +1455,11 @@ MachineInfoList *qmp_query_machines(Error **errp)

View File

@ -7,15 +7,15 @@ Subject: [PATCH] PVE: internal snapshot async
Makefile.objs | 1 +
hmp-commands-info.hx | 13 ++
hmp-commands.hx | 32 +++
hmp.c | 57 +++++
hmp.c | 57 ++++++
hmp.h | 5 +
include/migration/snapshot.h | 1 +
qapi/migration.json | 34 +++
qapi/migration.json | 34 ++++
qapi/misc.json | 32 +++
qemu-options.hx | 13 ++
savevm-async.c | 528 +++++++++++++++++++++++++++++++++++++++++++
savevm-async.c | 460 +++++++++++++++++++++++++++++++++++++++++++
vl.c | 10 +
11 files changed, 726 insertions(+)
11 files changed, 658 insertions(+)
create mode 100644 savevm-async.c
diff --git a/Makefile.objs b/Makefile.objs
@ -310,10 +310,10 @@ index b1bf0f485f..31329e26e2 100644
"-daemonize daemonize QEMU after initializing\n", QEMU_ARCH_ALL)
diff --git a/savevm-async.c b/savevm-async.c
new file mode 100644
index 0000000000..0bf830c906
index 0000000000..73b7fe75ed
--- /dev/null
+++ b/savevm-async.c
@@ -0,0 +1,528 @@
@@ -0,0 +1,460 @@
+#include "qemu/osdep.h"
+#include "migration/migration.h"
+#include "migration/savevm.h"
@ -321,9 +321,7 @@ index 0000000000..0bf830c906
+#include "migration/global_state.h"
+#include "migration/ram.h"
+#include "migration/qemu-file.h"
+#include "qapi/qmp/qerror.h"
+#include "sysemu/sysemu.h"
+#include "qmp-commands.h"
+#include "block/block.h"
+#include "sysemu/block-backend.h"
+#include "qapi/error.h"
@ -331,11 +329,13 @@ index 0000000000..0bf830c906
+#include "qapi/qmp/qdict.h"
+#include "qapi/qapi-commands-migration.h"
+#include "qapi/qapi-commands-misc.h"
+#include "qapi/qapi-commands-block.h"
+#include "qemu/cutils.h"
+
+/* #define DEBUG_SAVEVM_STATE */
+
+#define NOT_DONE 0x7fffffff /* used while emulated sync operation in progress */
+/* used while emulated sync operation in progress */
+#define NOT_DONE -EINPROGRESS
+
+#ifdef DEBUG_SAVEVM_STATE
+#define DPRINTF(fmt, ...) \
@ -363,6 +363,8 @@ index 0000000000..0bf830c906
+ int saved_vm_running;
+ QEMUFile *file;
+ int64_t total_time;
+ QEMUBH *cleanup_bh;
+ QemuThread thread;
+} snap_state;
+
+SaveVMInfo *qmp_query_savevm(Error **errp)
@ -450,19 +452,6 @@ index 0000000000..0bf830c906
+ g_free (msg);
+
+ snap_state.state = SAVE_STATE_ERROR;
+
+ save_snapshot_cleanup();
+}
+
+static void save_snapshot_completed(void)
+{
+ DPRINTF("save_snapshot_completed\n");
+
+ if (save_snapshot_cleanup() < 0) {
+ snap_state.state = SAVE_STATE_ERROR;
+ } else {
+ snap_state.state = SAVE_STATE_COMPLETED;
+ }
+}
+
+static int block_state_close(void *opaque)
@ -471,67 +460,123 @@ index 0000000000..0bf830c906
+ 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);
+}
+
+static ssize_t block_state_writev_buffer(void *opaque, struct iovec *iov,
+ int iovcnt, int64_t pos)
+{
+ int ret;
+ 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);
+ ret = blk_co_pwritev(snap_state.target, pos, qiov.size, &qiov, 0);
+ if (ret < 0) {
+ return ret;
+
+ 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 int store_and_stop(void) {
+ if (global_state_store()) {
+ save_snapshot_error("Error saving global state");
+ return 1;
+static const QEMUFileOps block_file_ops = {
+ .writev_buffer = block_state_writev_buffer,
+ .close = block_state_close,
+};
+
+static void process_savevm_cleanup(void *opaque)
+{
+ int ret;
+ qemu_bh_delete(snap_state.cleanup_bh);
+ snap_state.cleanup_bh = NULL;
+ qemu_mutex_unlock_iothread();
+ qemu_thread_join(&snap_state.thread);
+ qemu_mutex_lock_iothread();
+ ret = save_snapshot_cleanup();
+ if (ret < 0) {
+ save_snapshot_error("save_snapshot_cleanup error %d", ret);
+ } else if (snap_state.state == SAVE_STATE_ACTIVE) {
+ snap_state.state = SAVE_STATE_COMPLETED;
+ } else {
+ save_snapshot_error("process_savevm_cleanup: invalid state: %d",
+ snap_state.state);
+ }
+ if (runstate_is_running()) {
+ vm_stop(RUN_STATE_SAVE_VM);
+ if (snap_state.saved_vm_running) {
+ vm_start();
+ snap_state.saved_vm_running = false;
+ }
+ return 0;
+}
+
+static void process_savevm_co(void *opaque)
+static void *process_savevm_thread(void *opaque)
+{
+ int ret;
+ int64_t maxlen;
+
+ snap_state.state = SAVE_STATE_ACTIVE;
+ rcu_register_thread();
+
+ qemu_mutex_unlock_iothread();
+ qemu_savevm_state_header(snap_state.file);
+ qemu_savevm_state_setup(snap_state.file);
+ ret = qemu_file_get_error(snap_state.file);
+ qemu_mutex_lock_iothread();
+
+ if (ret < 0) {
+ save_snapshot_error("qemu_savevm_state_setup failed");
+ return;
+ rcu_unregister_thread();
+ return NULL;
+ }
+
+ while (snap_state.state == SAVE_STATE_ACTIVE) {
+ uint64_t pending_size, pend_post, pend_nonpost;
+ uint64_t pending_size, pend_precopy, pend_compatible, pend_postcopy;
+
+ qemu_savevm_state_pending(snap_state.file, 0, &pend_nonpost, &pend_post);
+ pending_size = pend_post + pend_nonpost;
+ qemu_savevm_state_pending(snap_state.file, 0, &pend_precopy, &pend_compatible, &pend_postcopy);
+ pending_size = pend_precopy + pend_compatible + pend_postcopy;
+
+ if (pending_size) {
+ ret = qemu_savevm_state_iterate(snap_state.file, false);
+ if (ret < 0) {
+ save_snapshot_error("qemu_savevm_state_iterate error %d", ret);
+ break;
+ }
+ DPRINTF("savevm inerate pending size %lu ret %d\n", pending_size, ret);
+ } else {
+ DPRINTF("done iterating\n");
+ if (store_and_stop())
+ maxlen = blk_getlength(snap_state.target) - 30*1024*1024;
+
+ if (pending_size > 400000 && snap_state.bs_pos + pending_size < maxlen) {
+ qemu_mutex_lock_iothread();
+ ret = qemu_savevm_state_iterate(snap_state.file, false);
+ if (ret < 0) {
+ save_snapshot_error("qemu_savevm_state_iterate error %d", ret);
+ break;
+ }
+ qemu_mutex_unlock_iothread();
+ DPRINTF("savevm inerate pending size %lu ret %d\n", pending_size, ret);
+ } else {
+ qemu_mutex_lock_iothread();
+ qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER);
+ ret = global_state_store();
+ if (ret) {
+ save_snapshot_error("global_state_store error %d", ret);
+ break;
+ }
+ ret = vm_stop_force_state(RUN_STATE_FINISH_MIGRATE);
+ if (ret < 0) {
+ save_snapshot_error("vm_stop_force_state error %d", ret);
+ break;
+ }
+ DPRINTF("savevm inerate finished\n");
+ /* upstream made the return value here inconsistent
+ * (-1 instead of 'ret' in one case and 0 after flush which can
@ -543,36 +588,19 @@ index 0000000000..0bf830c906
+ save_snapshot_error("qemu_savevm_state_iterate error %d", ret);
+ break;
+ }
+ qemu_savevm_state_cleanup();
+ DPRINTF("save complete\n");
+ save_snapshot_completed();
+ break;
+ }
+
+ /* stop the VM if we get to the end of available space,
+ * or if pending_size is just a few MB
+ */
+ maxlen = blk_getlength(snap_state.target) - 30*1024*1024;
+ if ((pending_size < 100000) ||
+ ((snap_state.bs_pos + pending_size) >= maxlen)) {
+ if (store_and_stop())
+ break;
+ }
+ }
+
+ if(snap_state.state == SAVE_STATE_CANCELLED) {
+ save_snapshot_completed();
+ Error *errp = NULL;
+ qmp_savevm_end(&errp);
+ }
+ qemu_bh_schedule(snap_state.cleanup_bh);
+ qemu_mutex_unlock_iothread();
+
+ rcu_unregister_thread();
+ return NULL;
+}
+
+static const QEMUFileOps block_file_ops = {
+ .writev_buffer = block_state_writev_buffer,
+ .close = block_state_close,
+};
+
+
+void qmp_savevm_start(bool has_statefile, const char *statefile, Error **errp)
+{
+ Error *local_err = NULL;
@ -627,8 +655,10 @@ index 0000000000..0bf830c906
+ error_setg(&snap_state.blocker, "block device is in use by savevm");
+ blk_op_block_all(snap_state.target, snap_state.blocker);
+
+ Coroutine *co = qemu_coroutine_create(process_savevm_co, NULL);
+ qemu_coroutine_enter(co);
+ snap_state.state = SAVE_STATE_ACTIVE;
+ snap_state.cleanup_bh = qemu_bh_new(process_savevm_cleanup, &snap_state);
+ qemu_thread_create(&snap_state.thread, "savevm-async", process_savevm_thread,
+ NULL, QEMU_THREAD_JOINABLE);
+
+ return;
+
@ -661,118 +691,20 @@ index 0000000000..0bf830c906
+ snap_state.state = SAVE_STATE_DONE;
+}
+
+// FIXME: Deprecated
+void qmp_snapshot_drive(const char *device, const char *name, Error **errp)
+{
+ BlockBackend *blk;
+ BlockDriverState *bs;
+ QEMUSnapshotInfo sn1, *sn = &sn1;
+ int ret;
+#ifdef _WIN32
+ struct _timeb tb;
+#else
+ struct timeval tv;
+#endif
+
+ if (snap_state.state != SAVE_STATE_COMPLETED) {
+ error_set(errp, ERROR_CLASS_GENERIC_ERROR,
+ "VM snapshot not ready/started\n");
+ return;
+ }
+
+ blk = blk_by_name(device);
+ if (!blk) {
+ error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND,
+ "Device '%s' not found", device);
+ return;
+ }
+
+ bs = blk_bs(blk);
+ if (!bdrv_is_inserted(bs)) {
+ error_setg(errp, QERR_DEVICE_HAS_NO_MEDIUM, device);
+ return;
+ }
+
+ if (bdrv_is_read_only(bs)) {
+ error_setg(errp, "Node '%s' is read only", device);
+ return;
+ }
+
+ if (!bdrv_can_snapshot(bs)) {
+ error_setg(errp, QERR_UNSUPPORTED);
+ return;
+ }
+
+ if (bdrv_snapshot_find(bs, sn, name) >= 0) {
+ error_set(errp, ERROR_CLASS_GENERIC_ERROR,
+ "snapshot '%s' already exists", name);
+ return;
+ }
+
+ sn = &sn1;
+ memset(sn, 0, sizeof(*sn));
+
+#ifdef _WIN32
+ _ftime(&tb);
+ sn->date_sec = tb.time;
+ sn->date_nsec = tb.millitm * 1000000;
+#else
+ gettimeofday(&tv, NULL);
+ sn->date_sec = tv.tv_sec;
+ sn->date_nsec = tv.tv_usec * 1000;
+#endif
+ sn->vm_clock_nsec = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
+
+ pstrcpy(sn->name, sizeof(sn->name), name);
+
+ sn->vm_state_size = 0; /* do not save state */
+
+ ret = bdrv_snapshot_create(bs, sn);
+ if (ret < 0) {
+ error_set(errp, ERROR_CLASS_GENERIC_ERROR,
+ "Error while creating snapshot on '%s'\n", device);
+ return;
+ }
+ // Compatibility to older qemu-server.
+ qmp_blockdev_snapshot_internal_sync(device, name, errp);
+}
+
+// FIXME: Deprecated
+void qmp_delete_drive_snapshot(const char *device, const char *name,
+ Error **errp)
+{
+ BlockBackend *blk;
+ BlockDriverState *bs;
+ QEMUSnapshotInfo sn1, *sn = &sn1;
+ Error *local_err = NULL;
+
+ int ret;
+
+ blk = blk_by_name(device);
+ if (!blk) {
+ error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND,
+ "Device '%s' not found", device);
+ return;
+ }
+
+ bs = blk_bs(blk);
+ if (bdrv_is_read_only(bs)) {
+ error_setg(errp, "Node '%s' is read only", device);
+ return;
+ }
+
+ if (!bdrv_can_snapshot(bs)) {
+ error_setg(errp, QERR_UNSUPPORTED);
+ return;
+ }
+
+ if (bdrv_snapshot_find(bs, sn, name) < 0) {
+ /* return success if snapshot does not exists */
+ return;
+ }
+
+ ret = bdrv_snapshot_delete(bs, NULL, name, &local_err);
+ if (ret < 0) {
+ error_set(errp, ERROR_CLASS_GENERIC_ERROR,
+ "Error while deleting snapshot on '%s'\n", device);
+ return;
+ }
+ // Compatibility to older qemu-server.
+ (void)qmp_blockdev_snapshot_delete_internal_sync(device, false, NULL,
+ true, name, errp);
+}
+
+static ssize_t loadstate_get_buffer(void *opaque, uint8_t *buf, int64_t pos,
@ -843,7 +775,7 @@ index 0000000000..0bf830c906
+ return ret;
+}
diff --git a/vl.c b/vl.c
index c750b7c18e..b2e3e23724 100644
index 9c3a41bfe2..63107d82a3 100644
--- a/vl.c
+++ b/vl.c
@@ -2927,6 +2927,7 @@ int main(int argc, char **argv, char **envp)
@ -854,7 +786,7 @@ index c750b7c18e..b2e3e23724 100644
MachineClass *machine_class;
const char *cpu_model;
const char *vga_model = NULL;
@@ -3528,6 +3529,9 @@ int main(int argc, char **argv, char **envp)
@@ -3529,6 +3530,9 @@ int main(int argc, char **argv, char **envp)
case QEMU_OPTION_loadvm:
loadvm = optarg;
break;
@ -864,7 +796,7 @@ index c750b7c18e..b2e3e23724 100644
case QEMU_OPTION_full_screen:
dpy.has_full_screen = true;
dpy.full_screen = true;
@@ -4623,6 +4627,12 @@ int main(int argc, char **argv, char **envp)
@@ -4624,6 +4628,12 @@ int main(int argc, char **argv, char **envp)
error_report_err(local_err);
autostart = 0;
}

View File

@ -1,249 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Wolfgang Bumiller <w.bumiller@proxmox.com>
Date: Tue, 8 Nov 2016 11:13:06 +0100
Subject: [PATCH] PVE: convert savevm-async to threads
---
savevm-async.c | 151 ++++++++++++++++++++++++++++++++++-----------------------
1 file changed, 90 insertions(+), 61 deletions(-)
diff --git a/savevm-async.c b/savevm-async.c
index 0bf830c906..157eb7a50d 100644
--- a/savevm-async.c
+++ b/savevm-async.c
@@ -5,9 +5,7 @@
#include "migration/global_state.h"
#include "migration/ram.h"
#include "migration/qemu-file.h"
-#include "qapi/qmp/qerror.h"
#include "sysemu/sysemu.h"
-#include "qmp-commands.h"
#include "block/block.h"
#include "sysemu/block-backend.h"
#include "qapi/error.h"
@@ -47,6 +45,8 @@ static struct SnapshotState {
int saved_vm_running;
QEMUFile *file;
int64_t total_time;
+ QEMUBH *cleanup_bh;
+ QemuThread thread;
} snap_state;
SaveVMInfo *qmp_query_savevm(Error **errp)
@@ -134,19 +134,6 @@ static void save_snapshot_error(const char *fmt, ...)
g_free (msg);
snap_state.state = SAVE_STATE_ERROR;
-
- save_snapshot_cleanup();
-}
-
-static void save_snapshot_completed(void)
-{
- DPRINTF("save_snapshot_completed\n");
-
- if (save_snapshot_cleanup() < 0) {
- snap_state.state = SAVE_STATE_ERROR;
- } else {
- snap_state.state = SAVE_STATE_COMPLETED;
- }
}
static int block_state_close(void *opaque)
@@ -155,67 +142,118 @@ static int block_state_close(void *opaque)
return blk_flush(snap_state.target);
}
+typedef struct BlkRwCo {
+ int64_t offset;
+ QEMUIOVector *qiov;
+ int ret;
+} BlkRwCo;
+
+static void 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);
+}
+
static ssize_t block_state_writev_buffer(void *opaque, struct iovec *iov,
int iovcnt, int64_t pos)
{
- int ret;
QEMUIOVector qiov;
+ AioContext *aio_context;
+ Coroutine *co;
+ BlkRwCo rwco;
+
+ assert(pos == snap_state.bs_pos);
+ rwco = (BlkRwCo) {
+ .offset = pos,
+ .qiov = &qiov,
+ .ret = NOT_DONE,
+ };
qemu_iovec_init_external(&qiov, iov, iovcnt);
- ret = blk_co_pwritev(snap_state.target, pos, qiov.size, &qiov, 0);
- if (ret < 0) {
- return ret;
+
+ aio_context = blk_get_aio_context(snap_state.target);
+ aio_context_acquire(aio_context);
+ co = qemu_coroutine_create(&block_state_write_entry, &rwco);
+ qemu_coroutine_enter(co);
+ while (rwco.ret == NOT_DONE) {
+ aio_poll(aio_context, true);
}
+ aio_context_release(aio_context);
+
snap_state.bs_pos += qiov.size;
return qiov.size;
}
-static int store_and_stop(void) {
- if (global_state_store()) {
- save_snapshot_error("Error saving global state");
- return 1;
+static void process_savevm_cleanup(void *opaque)
+{
+ int ret;
+ qemu_bh_delete(snap_state.cleanup_bh);
+ snap_state.cleanup_bh = NULL;
+ qemu_mutex_unlock_iothread();
+ qemu_thread_join(&snap_state.thread);
+ qemu_mutex_lock_iothread();
+ ret = save_snapshot_cleanup();
+ if (ret < 0) {
+ save_snapshot_error("save_snapshot_cleanup error %d", ret);
+ } else if (snap_state.state == SAVE_STATE_ACTIVE) {
+ snap_state.state = SAVE_STATE_COMPLETED;
+ } else {
+ save_snapshot_error("process_savevm_cleanup: invalid state: %d",
+ snap_state.state);
}
- if (runstate_is_running()) {
- vm_stop(RUN_STATE_SAVE_VM);
+ if (snap_state.saved_vm_running) {
+ vm_start();
+ snap_state.saved_vm_running = false;
}
- return 0;
}
-static void process_savevm_co(void *opaque)
+static void *process_savevm_thread(void *opaque)
{
int ret;
int64_t maxlen;
- snap_state.state = SAVE_STATE_ACTIVE;
+ rcu_register_thread();
- qemu_mutex_unlock_iothread();
qemu_savevm_state_header(snap_state.file);
qemu_savevm_state_setup(snap_state.file);
ret = qemu_file_get_error(snap_state.file);
- qemu_mutex_lock_iothread();
if (ret < 0) {
save_snapshot_error("qemu_savevm_state_setup failed");
- return;
+ rcu_unregister_thread();
+ return NULL;
}
while (snap_state.state == SAVE_STATE_ACTIVE) {
- uint64_t pending_size, pend_post, pend_nonpost;
+ uint64_t pending_size, pend_precopy, pend_compatible, pend_postcopy;
- qemu_savevm_state_pending(snap_state.file, 0, &pend_nonpost, &pend_post);
- pending_size = pend_post + pend_nonpost;
+ qemu_savevm_state_pending(snap_state.file, 0, &pend_precopy, &pend_compatible, &pend_postcopy);
+ pending_size = pend_precopy + pend_compatible + pend_postcopy;
- if (pending_size) {
- ret = qemu_savevm_state_iterate(snap_state.file, false);
- if (ret < 0) {
- save_snapshot_error("qemu_savevm_state_iterate error %d", ret);
- break;
- }
- DPRINTF("savevm inerate pending size %lu ret %d\n", pending_size, ret);
+ maxlen = blk_getlength(snap_state.target) - 30*1024*1024;
+
+ if (pending_size > 400000 && snap_state.bs_pos + pending_size < maxlen) {
+ qemu_mutex_lock_iothread();
+ ret = qemu_savevm_state_iterate(snap_state.file, false);
+ if (ret < 0) {
+ save_snapshot_error("qemu_savevm_state_iterate error %d", ret);
+ break;
+ }
+ qemu_mutex_unlock_iothread();
+ DPRINTF("savevm inerate pending size %lu ret %d\n", pending_size, ret);
} else {
- DPRINTF("done iterating\n");
- if (store_and_stop())
+ qemu_mutex_lock_iothread();
+ qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER);
+ ret = global_state_store();
+ if (ret) {
+ save_snapshot_error("global_state_store error %d", ret);
break;
+ }
+ ret = vm_stop_force_state(RUN_STATE_FINISH_MIGRATE);
+ if (ret < 0) {
+ save_snapshot_error("vm_stop_force_state error %d", ret);
+ break;
+ }
DPRINTF("savevm inerate finished\n");
/* upstream made the return value here inconsistent
* (-1 instead of 'ret' in one case and 0 after flush which can
@@ -227,28 +265,17 @@ static void process_savevm_co(void *opaque)
save_snapshot_error("qemu_savevm_state_iterate error %d", ret);
break;
}
+ qemu_savevm_state_cleanup();
DPRINTF("save complete\n");
- save_snapshot_completed();
break;
}
-
- /* stop the VM if we get to the end of available space,
- * or if pending_size is just a few MB
- */
- maxlen = blk_getlength(snap_state.target) - 30*1024*1024;
- if ((pending_size < 100000) ||
- ((snap_state.bs_pos + pending_size) >= maxlen)) {
- if (store_and_stop())
- break;
- }
}
- if(snap_state.state == SAVE_STATE_CANCELLED) {
- save_snapshot_completed();
- Error *errp = NULL;
- qmp_savevm_end(&errp);
- }
+ qemu_bh_schedule(snap_state.cleanup_bh);
+ qemu_mutex_unlock_iothread();
+ rcu_unregister_thread();
+ return NULL;
}
static const QEMUFileOps block_file_ops = {
@@ -311,8 +338,10 @@ void qmp_savevm_start(bool has_statefile, const char *statefile, Error **errp)
error_setg(&snap_state.blocker, "block device is in use by savevm");
blk_op_block_all(snap_state.target, snap_state.blocker);
- Coroutine *co = qemu_coroutine_create(process_savevm_co, NULL);
- qemu_coroutine_enter(co);
+ snap_state.state = SAVE_STATE_ACTIVE;
+ snap_state.cleanup_bh = qemu_bh_new(process_savevm_cleanup, &snap_state);
+ qemu_thread_create(&snap_state.thread, "savevm-async", process_savevm_thread,
+ NULL, QEMU_THREAD_JOINABLE);
return;
--
2.11.0

View File

@ -16,7 +16,7 @@ having been started at the same point in time.
5 files changed, 7 insertions(+), 4 deletions(-)
diff --git a/block/backup.c b/block/backup.c
index 8630d32926..7f970842d7 100644
index 8630d32926..3aaa75892a 100644
--- a/block/backup.c
+++ b/block/backup.c
@@ -613,6 +613,7 @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs,
@ -31,7 +31,7 @@ index 8630d32926..7f970842d7 100644
block_job_add_bdrv(&job->common, "target", target, 0, BLK_PERM_ALL,
&error_abort);
job->len = len;
+ job->common.job.pause_count = pause_count;
+ job->common.job.pause_count += pause_count;
return &job->common;
@ -83,10 +83,10 @@ index 903b9c1034..0b2516c3cf 100644
void hmp_drive_add_node(Monitor *mon, const char *optstr);
diff --git a/job.c b/job.c
index fa671b431a..72c50ee18e 100644
index a3bec7fb22..950924ebad 100644
--- a/job.c
+++ b/job.c
@@ -557,7 +557,7 @@ void job_start(Job *job)
@@ -549,7 +549,7 @@ void job_start(Job *job)
job->co = qemu_coroutine_create(job_co_entry, job);
job->pause_count--;
job->busy = true;

View File

@ -1,65 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Alexandre Derumier <aderumier@odiso.com>
Date: Tue, 13 Sep 2016 01:57:56 +0200
Subject: [PATCH] PVE: block: snapshot: qmp_snapshot_drive: add aiocontext
Signed-off-by: Alexandre Derumier <aderumier@odiso.com>
---
savevm-async.c | 15 +++++++++++----
1 file changed, 11 insertions(+), 4 deletions(-)
diff --git a/savevm-async.c b/savevm-async.c
index 157eb7a50d..87d5460a26 100644
--- a/savevm-async.c
+++ b/savevm-async.c
@@ -379,6 +379,7 @@ void qmp_snapshot_drive(const char *device, const char *name, Error **errp)
BlockBackend *blk;
BlockDriverState *bs;
QEMUSnapshotInfo sn1, *sn = &sn1;
+ AioContext *aio_context;
int ret;
#ifdef _WIN32
struct _timeb tb;
@@ -405,20 +406,23 @@ void qmp_snapshot_drive(const char *device, const char *name, Error **errp)
return;
}
+ aio_context = bdrv_get_aio_context(bs);
+ aio_context_acquire(aio_context);
+
if (bdrv_is_read_only(bs)) {
error_setg(errp, "Node '%s' is read only", device);
- return;
+ goto out;
}
if (!bdrv_can_snapshot(bs)) {
error_setg(errp, QERR_UNSUPPORTED);
- return;
+ goto out;
}
if (bdrv_snapshot_find(bs, sn, name) >= 0) {
error_set(errp, ERROR_CLASS_GENERIC_ERROR,
"snapshot '%s' already exists", name);
- return;
+ goto out;
}
sn = &sn1;
@@ -443,8 +447,11 @@ void qmp_snapshot_drive(const char *device, const char *name, Error **errp)
if (ret < 0) {
error_set(errp, ERROR_CLASS_GENERIC_ERROR,
"Error while creating snapshot on '%s'\n", device);
- return;
+ goto out;
}
+
+out:
+ aio_context_release(aio_context);
}
void qmp_delete_drive_snapshot(const char *device, const char *name,
--
2.11.0

View File

@ -7,7 +7,7 @@ TODO: Move to a libvma block backend.
---
MAINTAINERS | 6 +
block/Makefile.objs | 3 +
block/vma.c | 424 ++++++++++++++++++++++++++++++++++++++++
block/vma.c | 503 +++++++++++++++++++++++++++++++++++++++++++++++
blockdev.c | 536 +++++++++++++++++++++++++++++++++++++++++++++++++++
configure | 29 +++
hmp-commands-info.hx | 13 ++
@ -17,7 +17,7 @@ TODO: Move to a libvma block backend.
qapi/block-core.json | 109 ++++++++++-
qapi/common.json | 13 ++
qapi/misc.json | 13 --
12 files changed, 1229 insertions(+), 14 deletions(-)
12 files changed, 1308 insertions(+), 14 deletions(-)
create mode 100644 block/vma.c
diff --git a/MAINTAINERS b/MAINTAINERS
@ -57,10 +57,10 @@ index c00f0b32d6..abfd0f69d7 100644
+vma.o-libs := $(VMA_LIBS)
diff --git a/block/vma.c b/block/vma.c
new file mode 100644
index 0000000000..7151514f94
index 0000000000..b911b198dc
--- /dev/null
+++ b/block/vma.c
@@ -0,0 +1,424 @@
@@ -0,0 +1,503 @@
+/*
+ * VMA archive backend for QEMU, container object
+ *
@ -74,10 +74,12 @@ index 0000000000..7151514f94
+
+#include "qemu/osdep.h"
+#include "qemu/uuid.h"
+#include "qemu/option.h"
+#include "qemu-common.h"
+#include "qapi/error.h"
+#include "qapi/qmp/qerror.h"
+#include "qapi/qmp/qstring.h"
+#include "qapi/qmp/qdict.h"
+#include "qom/object.h"
+#include "qom/object_interfaces.h"
+#include "block/block_int.h"
@ -132,9 +134,9 @@ index 0000000000..7151514f94
+ return;
+ }
+
+ rc = VMAWriter_fopen(vo->filename, &vo->vma);
+ if (rc < 0) {
+ error_setg_errno(errp, -rc, "failed to create VMA archive");
+ vo->vma = VMAWriter_fopen(vo->filename);
+ if (!vo->vma) {
+ error_setg_errno(errp, errno, "failed to create VMA archive");
+ return;
+ }
+
@ -147,7 +149,7 @@ index 0000000000..7151514f94
+ qemu_mutex_init(&vo->mutex);
+}
+
+static bool vma_object_can_be_deleted(UserCreatable *uc, Error **errp)
+static bool vma_object_can_be_deleted(UserCreatable *uc)
+{
+ //VMAObjectState *vo = VMA_OBJECT(uc);
+ //if (!vo->vma) {
@ -300,13 +302,17 @@ index 0000000000..7151514f94
+{
+ char *sep;
+
+ if (strncmp(filename, "vma:", sizeof("vma:")-1) == 0) {
+ filename += sizeof("vma:")-1;
+ }
+
+ sep = strchr(filename, '/');
+ if (!sep || sep == filename) {
+ error_setg(errp, "VMA filename should be <vma-object>/<device-name>");
+ error_setg(errp, "VMA file should be <vma-obj>/<name>/<size>");
+ return;
+ }
+
+ qdict_put(options, "vma", qstring_from_substr(filename, 0, sep-filename-1));
+ qdict_put(options, "vma", qstring_from_substr(filename, 0, sep-filename));
+
+ while (*sep && *sep == '/')
+ ++sep;
@ -315,7 +321,24 @@ index 0000000000..7151514f94
+ return;
+ }
+
+ qdict_put(options, "name", qstring_from_str(sep));
+ filename = sep;
+ sep = strchr(filename, '/');
+ if (!sep || sep == filename) {
+ error_setg(errp, "VMA file should be <vma-obj>/<name>/<size>");
+ return;
+ }
+
+ qdict_put(options, "name", qstring_from_substr(filename, 0, sep-filename));
+
+ while (*sep && *sep == '/')
+ ++sep;
+ if (!*sep) {
+ error_setg(errp, "missing device size\n");
+ return;
+ }
+
+ filename = sep;
+ qdict_put_str(options, "size", filename);
+}
+
+static QemuOptsList runtime_opts = {
@ -363,7 +386,18 @@ index 0000000000..7151514f94
+ BDRV_SECTOR_SIZE);
+
+ vma_id = qemu_opt_get(opts, "vma");
+ if (!vma_id) {
+ ret = -EINVAL;
+ error_setg(errp, "missing 'vma' property");
+ goto failed_opts;
+ }
+
+ device_name = qemu_opt_get(opts, "name");
+ if (!device_name) {
+ ret = -EINVAL;
+ error_setg(errp, "missing 'name' property");
+ goto failed_opts;
+ }
+
+ VMAObjectState *vma = vma_by_id(vma_id);
+ if (!vma) {
@ -419,13 +453,16 @@ index 0000000000..7151514f94
+static coroutine_fn int qemu_vma_co_writev(BlockDriverState *bs,
+ int64_t sector_num,
+ int nb_sectors,
+ QEMUIOVector *qiov)
+ QEMUIOVector *qiov,
+ int flags)
+{
+ size_t i;
+ ssize_t rc;
+ BDRVVMAState *s = bs->opaque;
+ VMAObjectState *vo = s->vma_obj;
+ off_t offset = sector_num * BDRV_SECTOR_SIZE;
+ /* flags can be only values we set in supported_write_flags */
+ assert(flags == 0);
+
+ qemu_mutex_lock(&vo->mutex);
+ if (vo->blocked) {
@ -455,12 +492,47 @@ index 0000000000..7151514f94
+{
+ bdi->cluster_size = VMA_CLUSTER_SIZE;
+ bdi->unallocated_blocks_are_zero = true;
+ bdi->can_write_zeroes_with_unmap = false;
+ return 0;
+}
+
+static int qemu_vma_check_perm(BlockDriverState *bs,
+ uint64_t perm,
+ uint64_t shared,
+ Error **errp)
+{
+ /* Nothing to do. */
+ return 0;
+}
+
+static void qemu_vma_set_perm(BlockDriverState *bs,
+ uint64_t perm,
+ uint64_t shared)
+{
+ /* Nothing to do. */
+}
+
+static void qemu_vma_abort_perm_update(BlockDriverState *bs)
+{
+ /* Nothing to do. */
+}
+
+static void qemu_vma_refresh_limits(BlockDriverState *bs, Error **errp)
+{
+ bs->bl.request_alignment = BDRV_SECTOR_SIZE; /* No sub-sector I/O */
+}
+static void qemu_vma_child_perm(BlockDriverState *bs, BdrvChild *c,
+ const BdrvChildRole *role,
+ BlockReopenQueue *reopen_queue,
+ uint64_t perm, uint64_t shared,
+ uint64_t *nperm, uint64_t *nshared)
+{
+ *nperm = BLK_PERM_ALL;
+ *nshared = BLK_PERM_ALL;
+}
+
+static BlockDriver bdrv_vma_drive = {
+ .format_name = "vma-drive",
+ .protocol_name = "vma",
+ .instance_size = sizeof(BDRVVMAState),
+
+#if 0
@ -476,7 +548,14 @@ index 0000000000..7151514f94
+ .bdrv_getlength = qemu_vma_getlength,
+ .bdrv_get_info = qemu_vma_get_info,
+
+ //.bdrv_co_preadv = qemu_vma_co_preadv,
+ .bdrv_co_writev = qemu_vma_co_writev,
+
+ .bdrv_refresh_limits = qemu_vma_refresh_limits,
+ .bdrv_check_perm = qemu_vma_check_perm,
+ .bdrv_set_perm = qemu_vma_set_perm,
+ .bdrv_abort_perm_update = qemu_vma_abort_perm_update,
+ .bdrv_child_perm = qemu_vma_child_perm,
+};
+
+static void bdrv_vma_init(void)
@ -1052,7 +1131,7 @@ index d5eb6b62ca..4f18d3c3d7 100644
bool has_base, const char *base,
bool has_base_node, const char *base_node,
diff --git a/configure b/configure
index 2a7796ea80..601c1f44f9 100755
index 7b3f80a49c..d2cc11cdbb 100755
--- a/configure
+++ b/configure
@@ -475,6 +475,7 @@ vxhs=""
@ -1082,7 +1161,7 @@ index 2a7796ea80..601c1f44f9 100755
NOTE: The object files are built at the place where configure is launched
EOF
@@ -4124,6 +4130,22 @@ EOF
@@ -4121,6 +4127,22 @@ EOF
fi
##########################################
@ -1105,7 +1184,7 @@ index 2a7796ea80..601c1f44f9 100755
# signalfd probe
signalfd="no"
cat > $TMPC << EOF
@@ -6010,6 +6032,7 @@ echo "replication support $replication"
@@ -6007,6 +6029,7 @@ echo "replication support $replication"
echo "VxHS block device $vxhs"
echo "capstone $capstone"
echo "docker $docker"
@ -1113,7 +1192,7 @@ index 2a7796ea80..601c1f44f9 100755
if test "$sdl_too_old" = "yes"; then
echo "-> Your SDL version is too old - please upgrade to have SDL support"
@@ -6496,6 +6519,12 @@ if test "$usb_redir" = "yes" ; then
@@ -6493,6 +6516,12 @@ if test "$usb_redir" = "yes" ; then
echo "USB_REDIR_LIBS=$usb_redir_libs" >> $config_host_mak
fi

View File

@ -1,60 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Alexandre Derumier <aderumier@odiso.com>
Date: Mon, 7 Nov 2016 11:47:50 +0100
Subject: [PATCH] PVE: block: snapshot: qmp_delete_drive_snapshot : add
aiocontext
this fix snapshot delete of qcow2 with iothread enabled
Signed-off-by: Alexandre Derumier <aderumier@odiso.com>
---
savevm-async.c | 13 ++++++++++---
1 file changed, 10 insertions(+), 3 deletions(-)
diff --git a/savevm-async.c b/savevm-async.c
index 87d5460a26..aa578c4a49 100644
--- a/savevm-async.c
+++ b/savevm-async.c
@@ -461,6 +461,7 @@ void qmp_delete_drive_snapshot(const char *device, const char *name,
BlockDriverState *bs;
QEMUSnapshotInfo sn1, *sn = &sn1;
Error *local_err = NULL;
+ AioContext *aio_context;
int ret;
@@ -477,22 +478,28 @@ void qmp_delete_drive_snapshot(const char *device, const char *name,
return;
}
+ aio_context = bdrv_get_aio_context(bs);
+ aio_context_acquire(aio_context);
+
if (!bdrv_can_snapshot(bs)) {
error_setg(errp, QERR_UNSUPPORTED);
- return;
+ goto out;
}
if (bdrv_snapshot_find(bs, sn, name) < 0) {
/* return success if snapshot does not exists */
- return;
+ goto out;
}
ret = bdrv_snapshot_delete(bs, NULL, name, &local_err);
if (ret < 0) {
error_set(errp, ERROR_CLASS_GENERIC_ERROR,
"Error while deleting snapshot on '%s'\n", device);
- return;
+ goto out;
}
+
+out:
+ aio_context_release(aio_context);
}
static ssize_t loadstate_get_buffer(void *opaque, uint8_t *buf, int64_t pos,
--
2.11.0

View File

@ -56,7 +56,7 @@ index a836ee87d7..92c7886dee 100644
block-obj-m = block/
diff --git a/block/backup.c b/block/backup.c
index 7f970842d7..5f53163a77 100644
index 3aaa75892a..2410cca257 100644
--- a/block/backup.c
+++ b/block/backup.c
@@ -34,6 +34,7 @@ typedef struct BackupBlockJob {
@ -265,7 +265,7 @@ index 7f970842d7..5f53163a77 100644
+ &error_abort);
+ }
job->len = len;
job->common.job.pause_count = pause_count;
job->common.job.pause_count += pause_count;
diff --git a/block/replication.c b/block/replication.c
index 84e07cc4d4..04fa448a5b 100644
@ -280,7 +280,7 @@ index 84e07cc4d4..04fa448a5b 100644
if (local_err) {
error_propagate(errp, local_err);
diff --git a/blockdev.c b/blockdev.c
index 4f18d3c3d7..d5458f044e 100644
index 4f18d3c3d7..86508066cc 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -31,7 +31,6 @@
@ -649,7 +649,7 @@ index 4f18d3c3d7..d5458f044e 100644
- di->target = NULL;
- }
+ pvebackup_dump_cb, pvebackup_complete_cb, di,
+ 2, NULL, &local_err);
+ 1, NULL, &local_err);
if (!job || local_err != NULL) {
error_setg(&backup_state.error, "backup_job_create failed");
pvebackup_cancel(NULL);
@ -718,10 +718,10 @@ index 0b2516c3cf..ecd6243440 100644
int pause_count,
JobTxn *txn, Error **errp);
diff --git a/job.c b/job.c
index 72c50ee18e..1b3bda275d 100644
index 950924ebad..b4eaf57e64 100644
--- a/job.c
+++ b/job.c
@@ -256,7 +256,8 @@ static bool job_started(Job *job)
@@ -248,7 +248,8 @@ static bool job_started(Job *job)
return job->co;
}

View File

@ -27,7 +27,7 @@ index 31329e26e2..15df7e4fab 100644
"-fda/-fdb file use 'file' as floppy disk 0/1 image\n", QEMU_ARCH_ALL)
DEF("fdb", HAS_ARG, QEMU_OPTION_fdb, "", QEMU_ARCH_ALL)
diff --git a/vl.c b/vl.c
index b2e3e23724..a03e4c2867 100644
index 63107d82a3..e349797245 100644
--- a/vl.c
+++ b/vl.c
@@ -2915,6 +2915,7 @@ static void register_global_properties(MachineState *ms)
@ -38,7 +38,7 @@ index b2e3e23724..a03e4c2867 100644
int snapshot, linux_boot;
const char *initrd_filename;
const char *kernel_filename, *kernel_cmdline;
@@ -3659,6 +3660,13 @@ int main(int argc, char **argv, char **envp)
@@ -3660,6 +3661,13 @@ int main(int argc, char **argv, char **envp)
exit(1);
}
break;

28
debian/patches/series vendored
View File

@ -16,20 +16,14 @@ pve/0015-PVE-virtio-balloon-improve-query-balloon.patch
pve/0016-PVE-qapi-modify-query-machines.patch
pve/0017-PVE-qapi-modify-spice-query.patch
pve/0018-PVE-internal-snapshot-async.patch
pve/0019-PVE-convert-savevm-async-to-threads.patch
pve/0020-PVE-block-snapshot-qmp_snapshot_drive-add-aiocontext.patch
pve/0021-PVE-block-snapshot-qmp_delete_drive_snapshot-add-aio.patch
pve/0022-PVE-block-add-the-zeroinit-block-driver-filter.patch
pve/0023-PVE-backup-modify-job-api.patch
pve/0024-PVE-backup-introduce-vma-archive-format.patch
pve/0025-PVE-Deprecated-adding-old-vma-files.patch
pve/0026-PVE-vma-add-throttling-options-to-drive-mapping-fifo.patch
pve/0027-PVE-vma-add-cache-option-to-device-map.patch
pve/0028-PVE-vma-remove-forced-NO_FLUSH-option.patch
pve/0029-PVE-Add-dummy-id-command-line-parameter.patch
pve/0030-PVE-Config-Revert-target-i386-disable-LINT0-after-re.patch
extra/0001-seccomp-use-SIGSYS-signal-instead-of-killing-the-thr.patch
extra/0002-seccomp-prefer-SCMP_ACT_KILL_PROCESS-if-available.patch
extra/0003-configure-require-libseccomp-2.2.0.patch
extra/0004-seccomp-set-the-seccomp-filter-to-all-threads.patch
extra/0005-monitor-create-iothread-after-daemonizing.patch
pve/0019-PVE-block-add-the-zeroinit-block-driver-filter.patch
pve/0020-PVE-backup-modify-job-api.patch
pve/0021-PVE-backup-introduce-vma-archive-format.patch
pve/0022-PVE-Deprecated-adding-old-vma-files.patch
pve/0023-PVE-vma-add-throttling-options-to-drive-mapping-fifo.patch
pve/0024-PVE-vma-add-cache-option-to-device-map.patch
pve/0025-PVE-vma-remove-forced-NO_FLUSH-option.patch
pve/0026-PVE-Add-dummy-id-command-line-parameter.patch
pve/0027-PVE-Config-Revert-target-i386-disable-LINT0-after-re.patch
extra/0001-monitor-guard-iothread-access-by-mon-use_io_thread.patch
extra/0002-monitor-delay-monitor-iothread-creation.patch

2
qemu

@ -1 +1 @@
Subproject commit 38441756b70eec5807b5f60dad11a93a91199866
Subproject commit 1dfcf652e6ae5eb6b98d2c55a509e8eb054a2fab