bump version to 3.0.1-1
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
This commit is contained in:
parent
4ba321f213
commit
0775f12b63
4
Makefile
4
Makefile
@ -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
40
debian/changelog
vendored
@ -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
|
||||
|
||||
|
36
debian/patches/extra/0001-monitor-guard-iothread-access-by-mon-use_io_thread.patch
vendored
Normal file
36
debian/patches/extra/0001-monitor-guard-iothread-access-by-mon-use_io_thread.patch
vendored
Normal 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
|
||||
|
@ -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
|
||||
|
114
debian/patches/extra/0002-monitor-delay-monitor-iothread-creation.patch
vendored
Normal file
114
debian/patches/extra/0002-monitor-delay-monitor-iothread-creation.patch
vendored
Normal 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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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;
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
28
debian/patches/series
vendored
@ -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
2
qemu
@ -1 +1 @@
|
||||
Subproject commit 38441756b70eec5807b5f60dad11a93a91199866
|
||||
Subproject commit 1dfcf652e6ae5eb6b98d2c55a509e8eb054a2fab
|
Loading…
Reference in New Issue
Block a user