Compare commits

..

8 Commits

Author SHA1 Message Date
Cole Robinson 54d3da1da5 CVE-2017-1000256: libvirt: TLS certificate verification disabled for clients (bz #1503687) 2017-12-04 12:16:49 -05:00
Cole Robinson faf5df2081 Fix TPM2 passthrough (bz #1486240)
Fix spice GL qemu:///system rendernode permissions (bz #1460804)
Fix on_reboot=destroy setting (bz #1476866)
Fix disk images in /dev/shm (bz #1482146)
2017-09-15 19:04:20 -04:00
Cole Robinson e5075407b1 Enable ZFS storage driver (bz #1471912)
Don't use cgroup mount points from /proc/mounts that are hidden (bz #1470593)
disk driver name=... should be optional (bz #1473091)
2017-08-04 16:11:19 -04:00
Cole Robinson 8c3f1e830e Fix resuming qemu VMs suspended before libvirt 3.2.0
Fix issues with AMD CPU models, and some others
2017-07-12 16:26:46 -04:00
Cole Robinson 58083f4418 Remove wireshark workaround 2017-06-14 10:47:37 -04:00
Cole Robinson 55a13fd521 Tweak condition for not starting in live environment (bz #1146232) 2017-05-31 17:28:27 -04:00
Cole Robinson 262bbf08f2 Fix aarch64 gic default for non-kvm VMs (bz #1449837)
Don't run libvirtd in live environment, to avoid network collision (bz #1146232)
2017-05-30 18:57:48 -04:00
Cole Robinson 0fe69a9b44 Rebased to version 3.2.1 2017-05-10 20:26:58 -04:00
36 changed files with 4027 additions and 1993 deletions
-31
View File
@@ -1,31 +0,0 @@
[suppress_function]
symbol_version_regexp = LIBVIRT_PRIVATE.*
soname_regexp = libvirt\\.so.*
[suppress_function]
symbol_version_regexp = LIBVIRT_ADMIN_PRIVATE.*
soname_regexp = libvirt-admin\\.so.*
[suppress_variable]
symbol_version_regexp = LIBVIRT_PRIVATE.*
soname_regexp = libvirt\\.so.*
[suppress_variable]
symbol_version_regexp = LIBVIRT_ADMIN_PRIVATE.*
soname_regexp = libvirt-admin\\.so.*
[suppress_function]
symbol_version_regexp = .*
soname_regexp = libvirt_storage_.*\\.so.*
[suppress_variable]
symbol_version_regexp = .*
soname_regexp = libvirt_storage_.*\\.so.*
[suppress_function]
symbol_version_regexp = .*
soname_regexp = libvirt_driver_.*\\.so.*
[suppress_variable]
symbol_version_regexp = .*
soname_regexp = libvirt_driver_.*\\.so.*
@@ -1,40 +0,0 @@
From 76cdc7adf55723ff8da146bd3c15c64d0afd5d93 Mon Sep 17 00:00:00 2001
From: Martin Kletzander <mkletzan@redhat.com>
Date: Tue, 27 Feb 2024 16:20:12 +0100
Subject: [PATCH] Fix off-by-one error in udevListInterfacesByStatus
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Ever since this function was introduced in 2012 it could've tried
filling in an extra interface name. That was made worse in 2019 when
the caller functions started accepting NULL arrays of size 0.
This is assigned CVE-2024-1441.
Signed-off-by: Martin Kletzander <mkletzan@redhat.com>
Reported-by: Alexander Kuznetsov <kuznetsovam@altlinux.org>
Fixes: 5a33366f5c0b18c93d161bd144f9f079de4ac8ca
Fixes: d6064e2759a24e0802f363e3a810dc5a7d7ebb15
Reviewed-by: Ján Tomko <jtomko@redhat.com>
(cherry picked from commit c664015fe3a7bf59db26686e9ed69af011c6ebb8)
---
src/interface/interface_backend_udev.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/interface/interface_backend_udev.c b/src/interface/interface_backend_udev.c
index fb6799ed94..4091483060 100644
--- a/src/interface/interface_backend_udev.c
+++ b/src/interface/interface_backend_udev.c
@@ -222,7 +222,7 @@ udevListInterfacesByStatus(virConnectPtr conn,
g_autoptr(virInterfaceDef) def = NULL;
/* Ensure we won't exceed the size of our array */
- if (count > names_len)
+ if (count >= names_len)
break;
path = udev_list_entry_get_name(dev_entry);
--
2.43.0
@@ -1,41 +0,0 @@
From 3499354e12a1c1832bf4030693a64e03ceb79d05 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= <berrange@redhat.com>
Date: Wed, 5 Jun 2024 11:16:21 +0100
Subject: [PATCH] interface: fix udev reference leak with invalid flags
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
The udevInterfaceGetXMLDesc method takes a reference on the udev
driver as its first action. If the virCheckFlags() condition
fails, however, this reference is never released.
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
---
src/interface/interface_backend_udev.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/src/interface/interface_backend_udev.c b/src/interface/interface_backend_udev.c
index fdf11a8318..e1a50389c9 100644
--- a/src/interface/interface_backend_udev.c
+++ b/src/interface/interface_backend_udev.c
@@ -1027,12 +1027,14 @@ static char *
udevInterfaceGetXMLDesc(virInterfacePtr ifinfo,
unsigned int flags)
{
- struct udev *udev = udev_ref(driver->udev);
+ struct udev *udev = NULL;
g_autoptr(virInterfaceDef) ifacedef = NULL;
char *xmlstr = NULL;
virCheckFlags(VIR_INTERFACE_XML_INACTIVE, NULL);
+ udev = udev_ref(driver->udev);
+
/* Recursively build up the interface XML based on the requested
* interface name
*/
--
2.45.1
@@ -1,90 +0,0 @@
From c120b31f826cd51127d28f8beaa61ac0d5f03048 Mon Sep 17 00:00:00 2001
From: Dmitry Frolov <frolov@swemel.ru>
Date: Tue, 12 Sep 2023 15:56:47 +0300
Subject: [PATCH] interface: fix udev_device_get_sysattr_value return value
check
Reviewing the code I found that return value of function
udev_device_get_sysattr_value() is dereferenced without a check.
udev_device_get_sysattr_value() may return NULL by number of reasons.
v2: VIR_DEBUG added, replaced STREQ(NULLSTR()) with STREQ_NULLABLE()
v3: More checks added, to skip earlier. More verbose VIR_DEBUG.
Signed-off-by: Dmitry Frolov <frolov@swemel.ru>
Reviewed-by: Martin Kletzander <mkletzan@redhat.com>
(cherry picked from commit 2ca94317ac642a70921947150ced8acc674ccdc8)
---
src/interface/interface_backend_udev.c | 26 +++++++++++++++++++-------
1 file changed, 19 insertions(+), 7 deletions(-)
diff --git a/src/interface/interface_backend_udev.c b/src/interface/interface_backend_udev.c
index a0485ddd21..fb6799ed94 100644
--- a/src/interface/interface_backend_udev.c
+++ b/src/interface/interface_backend_udev.c
@@ -23,6 +23,7 @@
#include <dirent.h>
#include <libudev.h>
+#include "virlog.h"
#include "virerror.h"
#include "virfile.h"
#include "datatypes.h"
@@ -40,6 +41,8 @@
#define VIR_FROM_THIS VIR_FROM_INTERFACE
+VIR_LOG_INIT("interface.interface_backend_udev");
+
struct udev_iface_driver {
struct udev *udev;
/* pid file FD, ensures two copies of the driver can't use the same root */
@@ -354,11 +357,20 @@ udevConnectListAllInterfaces(virConnectPtr conn,
const char *macaddr;
g_autoptr(virInterfaceDef) def = NULL;
- path = udev_list_entry_get_name(dev_entry);
- dev = udev_device_new_from_syspath(udev, path);
- name = udev_device_get_sysname(dev);
+ if (!(path = udev_list_entry_get_name(dev_entry))) {
+ VIR_DEBUG("Skipping interface, path == NULL");
+ continue;
+ }
+ if (!(dev = udev_device_new_from_syspath(udev, path))) {
+ VIR_DEBUG("Skipping interface '%s', dev == NULL", path);
+ continue;
+ }
+ if (!(name = udev_device_get_sysname(dev))) {
+ VIR_DEBUG("Skipping interface '%s', name == NULL", path);
+ continue;
+ }
macaddr = udev_device_get_sysattr_value(dev, "address");
- status = STREQ(udev_device_get_sysattr_value(dev, "operstate"), "up");
+ status = STREQ_NULLABLE(udev_device_get_sysattr_value(dev, "operstate"), "up");
def = udevGetMinimalDefForDevice(dev);
if (!virConnectListAllInterfacesCheckACL(conn, def)) {
@@ -964,9 +976,9 @@ udevGetIfaceDef(struct udev *udev, const char *name)
/* MTU */
mtu_str = udev_device_get_sysattr_value(dev, "mtu");
- if (virStrToLong_ui(mtu_str, NULL, 10, &mtu) < 0) {
+ if (!mtu_str || virStrToLong_ui(mtu_str, NULL, 10, &mtu) < 0) {
virReportError(VIR_ERR_INTERNAL_ERROR,
- _("Could not parse MTU value '%1$s'"), mtu_str);
+ _("Could not parse MTU value '%1$s'"), NULLSTR(mtu_str));
goto error;
}
ifacedef->mtu = mtu;
@@ -1089,7 +1101,7 @@ udevInterfaceIsActive(virInterfacePtr ifinfo)
goto cleanup;
/* Check if it's active or not */
- status = STREQ(udev_device_get_sysattr_value(dev, "operstate"), "up");
+ status = STREQ_NULLABLE(udev_device_get_sysattr_value(dev, "operstate"), "up");
udev_device_unref(dev);
--
2.43.0
@@ -1,49 +0,0 @@
From 98f1cf88fa7e0f992d93f376418fbfb3996a9690 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= <berrange@redhat.com>
Date: Fri, 17 May 2024 14:55:24 +0100
Subject: [PATCH] rpc: avoid leak of GSource in use for interrupting main loop
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
We never release the reference on the GSource created for
interrupting the main loop, nor do we remove it from the
main context if our thread is woken up prior to the wakeup
callback firing.
This can result in a leak of GSource objects, along with an
ever growing list of GSources attached to the main context,
which will gradually slow down execution of the loop, as
several operations are O(N) for the number of attached GSource
objects.
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
---
src/rpc/virnetclient.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/src/rpc/virnetclient.c b/src/rpc/virnetclient.c
index 147b0d661a..6d424eb599 100644
--- a/src/rpc/virnetclient.c
+++ b/src/rpc/virnetclient.c
@@ -1946,7 +1946,7 @@ static int virNetClientIO(virNetClient *client,
/* Check to see if another thread is dispatching */
if (client->haveTheBuck) {
/* Force other thread to wakeup from poll */
- GSource *wakeup = g_idle_source_new();
+ g_autoptr(GSource) wakeup = g_idle_source_new();
g_source_set_callback(wakeup, virNetClientIOWakeup, client->eventLoop, NULL);
g_source_attach(wakeup, client->eventCtx);
@@ -1968,6 +1968,7 @@ static int virNetClientIO(virNetClient *client,
return -1;
}
+ g_source_destroy(wakeup);
VIR_DEBUG("Woken up from sleep head=%p call=%p",
client->waitDispatch, thiscall);
/* Three reasons we can be woken up
--
2.45.1
@@ -1,99 +0,0 @@
From 8074d64dc2eca846d6a61efe1a9b7428a0ce1dd1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= <berrange@redhat.com>
Date: Tue, 30 Apr 2024 11:51:15 +0100
Subject: [PATCH] rpc: ensure temporary GSource is removed from client event
loop
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Users are seeing periodic segfaults from libvirt client apps,
especially thread heavy ones like virt-manager. A typical
stack trace would end up in the virNetClientIOEventFD method,
with illegal access to stale stack data. eg
==238721==ERROR: AddressSanitizer: stack-use-after-return on address 0x75cd18709788 at pc 0x75cd3111f907 bp 0x75cd181ff550 sp 0x75cd181ff548
WRITE of size 4 at 0x75cd18709788 thread T11
#0 0x75cd3111f906 in virNetClientIOEventFD /usr/src/debug/libvirt/libvirt-10.2.0/build/../src/rpc/virnetclient.c:1634:15
#1 0x75cd3210d198 (/usr/lib/libglib-2.0.so.0+0x5a198) (BuildId: 0a2311dfbbc6c215dc36f4b6bdd2b4b6fbae55a2)
#2 0x75cd3216c3be (/usr/lib/libglib-2.0.so.0+0xb93be) (BuildId: 0a2311dfbbc6c215dc36f4b6bdd2b4b6fbae55a2)
#3 0x75cd3210ddc6 in g_main_loop_run (/usr/lib/libglib-2.0.so.0+0x5adc6) (BuildId: 0a2311dfbbc6c215dc36f4b6bdd2b4b6fbae55a2)
#4 0x75cd3111a47c in virNetClientIOEventLoop /usr/src/debug/libvirt/libvirt-10.2.0/build/../src/rpc/virnetclient.c:1722:9
#5 0x75cd3111a47c in virNetClientIO /usr/src/debug/libvirt/libvirt-10.2.0/build/../src/rpc/virnetclient.c:2002:10
#6 0x75cd3111a47c in virNetClientSendInternal /usr/src/debug/libvirt/libvirt-10.2.0/build/../src/rpc/virnetclient.c:2170:11
#7 0x75cd311198a8 in virNetClientSendWithReply /usr/src/debug/libvirt/libvirt-10.2.0/build/../src/rpc/virnetclient.c:2198:11
#8 0x75cd31111653 in virNetClientProgramCall /usr/src/debug/libvirt/libvirt-10.2.0/build/../src/rpc/virnetclientprogram.c:318:9
#9 0x75cd31241c8f in callFull /usr/src/debug/libvirt/libvirt-10.2.0/build/../src/remote/remote_driver.c:6054:10
#10 0x75cd31241c8f in call /usr/src/debug/libvirt/libvirt-10.2.0/build/../src/remote/remote_driver.c:6076:12
#11 0x75cd31241c8f in remoteNetworkGetXMLDesc /usr/src/debug/libvirt/libvirt-10.2.0/build/src/remote/remote_client_bodies.h:5959:9
#12 0x75cd31410ff7 in virNetworkGetXMLDesc /usr/src/debug/libvirt/libvirt-10.2.0/build/../src/libvirt-network.c:952:15
The root cause is a bad assumption in the virNetClientIOEventLoop
method. This method is run by whichever thread currently owns the
buck, and is responsible for handling I/O. Inside a for(;;) loop,
this method creates a temporary GSource, adds it to the event loop
and runs g_main_loop_run(). When I/O is ready, the GSource callback
(virNetClientIOEventFD) will fire and call g_main_loop_quit(), and
return G_SOURCE_REMOVE which results in the temporary GSource being
destroyed. A g_autoptr() will then remove the last reference.
What was overlooked, is that a second thread can come along and
while it can't enter virNetClientIOEventLoop, it will register an
idle source that uses virNetClientIOWakeup to interrupt the
original thread's 'g_main_loop_run' call. When this happens the
virNetClientIOEventFD callback never runs, and so the temporary
GSource is not destroyed. The g_autoptr() will remove a reference,
but by virtue of still being attached to the event context, there
is an extra reference held causing GSource to be leaked. The
next time 'g_main_loop_run' is called, the original GSource will
trigger its callback, and access data that was allocated on the
stack by the previous thread, and likely SEGV.
To solve this, the thread calling 'g_main_loop_run' must call
g_source_destroy, immediately upon return, to guarantee that
the temporary GSource is removed.
CVE-2024-4418
Reviewed-by: Ján Tomko <jtomko@redhat.com>
Reported-by: Martin Shirokov <shirokovmartin@gmail.com>
Tested-by: Martin Shirokov <shirokovmartin@gmail.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
---
src/rpc/virnetclient.c | 14 +++++++++++++-
1 file changed, 13 insertions(+), 1 deletion(-)
diff --git a/src/rpc/virnetclient.c b/src/rpc/virnetclient.c
index 68098b1c8d..147b0d661a 100644
--- a/src/rpc/virnetclient.c
+++ b/src/rpc/virnetclient.c
@@ -1657,7 +1657,7 @@ static int virNetClientIOEventLoop(virNetClient *client,
#endif /* !WIN32 */
int timeout = -1;
virNetMessage *msg = NULL;
- g_autoptr(GSource) G_GNUC_UNUSED source = NULL;
+ g_autoptr(GSource) source = NULL;
GIOCondition ev = 0;
struct virNetClientIOEventData data = {
.client = client,
@@ -1721,6 +1721,18 @@ static int virNetClientIOEventLoop(virNetClient *client,
g_main_loop_run(client->eventLoop);
+ /*
+ * If virNetClientIOEventFD ran, this GSource will already be
+ * destroyed due to G_SOURCE_REMOVE. It is harmless to re-destroy
+ * it, since we still own a reference.
+ *
+ * If virNetClientIOWakeup ran, it will have interrupted the
+ * g_main_loop_run call, before virNetClientIOEventFD could
+ * run, and thus the GSource is still registered, and we need
+ * to destroy it since it is referencing stack memory for 'data'
+ */
+ g_source_destroy(source);
+
#ifndef WIN32
ignore_value(pthread_sigmask(SIG_SETMASK, &oldmask, NULL));
#endif /* !WIN32 */
--
2.45.1
@@ -1,76 +0,0 @@
From 7cb03e6a28e465c49f0cabe8fe2e7d21edb5aadf Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= <berrange@redhat.com>
Date: Mon, 18 Dec 2023 12:17:18 +0000
Subject: [PATCH] rpc: fix race in waking up client event loop
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
The first thread to issue a client RPC request will own the event
loop execution, sitting in the virNetClientIOEventLoop function.
It releases the client lock while running:
virNetClientUnlock()
g_main_loop_run()
virNetClientLock()
If a second thread arrives with an RPC request, it will queue it
for the first thread to process. To inform the first thread that
there's a new request it calls g_main_loop_quit() to break it out
of the main loop.
This works if the first thread is in g_main_loop_run() at that
time. There is a small window of opportunity, however, where
the first thread has released the client lock, but not yet got
into g_main_loop_run(). If that happens, the wakeup from the
second thread is lost.
This patch deals with that by changing the way the wakeup is
performed. Instead of directly calling g_main_loop_quit(), the
second thread creates an idle source to run the quit function
from within the first thread. This guarantees that the first
thread will see the wakeup.
Tested by: Fima Shevrin <efim.shevrin@virtuozzo.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Denis V. Lunev <den@openvz.org>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
---
src/rpc/virnetclient.c | 13 ++++++++++++-
1 file changed, 12 insertions(+), 1 deletion(-)
diff --git a/src/rpc/virnetclient.c b/src/rpc/virnetclient.c
index 4ab8af68c5..68098b1c8d 100644
--- a/src/rpc/virnetclient.c
+++ b/src/rpc/virnetclient.c
@@ -1848,6 +1848,15 @@ static void virNetClientIOUpdateCallback(virNetClient *client,
}
+static gboolean virNetClientIOWakeup(gpointer opaque)
+{
+ GMainLoop *loop = opaque;
+
+ g_main_loop_quit(loop);
+
+ return G_SOURCE_REMOVE;
+}
+
/*
* This function sends a message to remote server and awaits a reply
*
@@ -1925,7 +1934,9 @@ static int virNetClientIO(virNetClient *client,
/* Check to see if another thread is dispatching */
if (client->haveTheBuck) {
/* Force other thread to wakeup from poll */
- g_main_loop_quit(client->eventLoop);
+ GSource *wakeup = g_idle_source_new();
+ g_source_set_callback(wakeup, virNetClientIOWakeup, client->eventLoop, NULL);
+ g_source_attach(wakeup, client->eventCtx);
/* If we are non-blocking, detach the thread and keep the call in the
* queue. */
--
2.43.0
@@ -0,0 +1,122 @@
From: Andrea Bolognani <abologna@redhat.com>
Date: Fri, 12 May 2017 14:05:55 +0200
Subject: [PATCH] tests: Check default GIC version for aarch64/virt TCG guests
Signed-off-by: Andrea Bolognani <abologna@redhat.com>
(cherry picked from commit b24eaf6210ebaf5dc8d29621063873c8419c517e)
---
.../qemuxml2argv-aarch64-gic-none-tcg.args | 19 ++++++++++++++++
.../qemuxml2argv-aarch64-gic-none-tcg.xml | 17 +++++++++++++++
tests/qemuxml2argvtest.c | 3 +++
.../qemuxml2xmlout-aarch64-gic-none-tcg.xml | 25 ++++++++++++++++++++++
tests/qemuxml2xmltest.c | 1 +
5 files changed, 65 insertions(+)
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-aarch64-gic-none-tcg.args
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-aarch64-gic-none-tcg.xml
create mode 100644 tests/qemuxml2xmloutdata/qemuxml2xmlout-aarch64-gic-none-tcg.xml
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-aarch64-gic-none-tcg.args b/tests/qemuxml2argvdata/qemuxml2argv-aarch64-gic-none-tcg.args
new file mode 100644
index 000000000..975a01481
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-aarch64-gic-none-tcg.args
@@ -0,0 +1,19 @@
+LC_ALL=C \
+PATH=/bin \
+HOME=/home/test \
+USER=test \
+LOGNAME=test \
+QEMU_AUDIO_DRV=none \
+/usr/bin/qemu-system-aarch64 \
+-name guest \
+-S \
+-machine virt,accel=tcg,gic-version=3 \
+-cpu cortex-a57 \
+-m 1024 \
+-smp 1,sockets=1,cores=1,threads=1 \
+-uuid 6ba410c5-1e5c-4d57-bee7-2228e7ffa32f \
+-nographic \
+-nodefaults \
+-monitor unix:/tmp/lib/domain--1-guest/monitor.sock,server,nowait \
+-no-acpi \
+-boot c
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-aarch64-gic-none-tcg.xml b/tests/qemuxml2argvdata/qemuxml2argv-aarch64-gic-none-tcg.xml
new file mode 100644
index 000000000..0aa33dbec
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-aarch64-gic-none-tcg.xml
@@ -0,0 +1,17 @@
+<domain type='qemu'>
+ <name>guest</name>
+ <uuid>6ba410c5-1e5c-4d57-bee7-2228e7ffa32f</uuid>
+ <memory unit='KiB'>1048576</memory>
+ <vcpu placement='static'>1</vcpu>
+ <os>
+ <type arch='aarch64' machine='virt'>hvm</type>
+ <boot dev='hd'/>
+ </os>
+ <cpu mode='custom'>
+ <model>cortex-a57</model>
+ </cpu>
+ <devices>
+ <emulator>/usr/bin/qemu-system-aarch64</emulator>
+ <memballoon model='none'/>
+ </devices>
+</domain>
diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c
index cc4fb91cd..362b140ac 100644
--- a/tests/qemuxml2argvtest.c
+++ b/tests/qemuxml2argvtest.c
@@ -2250,6 +2250,9 @@ mymain(void)
DO_TEST_GIC("aarch64-gic-none-both", GIC_BOTH,
QEMU_CAPS_KVM, QEMU_CAPS_MACHINE_OPT,
QEMU_CAPS_MACH_VIRT_GIC_VERSION);
+ DO_TEST_GIC("aarch64-gic-none-tcg", GIC_BOTH,
+ QEMU_CAPS_MACHINE_OPT,
+ QEMU_CAPS_MACH_VIRT_GIC_VERSION);
DO_TEST_GIC("aarch64-gic-default", GIC_NONE,
QEMU_CAPS_KVM, QEMU_CAPS_MACHINE_OPT);
DO_TEST_GIC("aarch64-gic-default", GIC_NONE,
diff --git a/tests/qemuxml2xmloutdata/qemuxml2xmlout-aarch64-gic-none-tcg.xml b/tests/qemuxml2xmloutdata/qemuxml2xmlout-aarch64-gic-none-tcg.xml
new file mode 100644
index 000000000..69510e281
--- /dev/null
+++ b/tests/qemuxml2xmloutdata/qemuxml2xmlout-aarch64-gic-none-tcg.xml
@@ -0,0 +1,25 @@
+<domain type='qemu'>
+ <name>guest</name>
+ <uuid>6ba410c5-1e5c-4d57-bee7-2228e7ffa32f</uuid>
+ <memory unit='KiB'>1048576</memory>
+ <currentMemory unit='KiB'>1048576</currentMemory>
+ <vcpu placement='static'>1</vcpu>
+ <os>
+ <type arch='aarch64' machine='virt'>hvm</type>
+ <boot dev='hd'/>
+ </os>
+ <features>
+ <gic version='3'/>
+ </features>
+ <cpu mode='custom' match='exact' check='none'>
+ <model fallback='allow'>cortex-a57</model>
+ </cpu>
+ <clock offset='utc'/>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>restart</on_reboot>
+ <on_crash>destroy</on_crash>
+ <devices>
+ <emulator>/usr/bin/qemu-system-aarch64</emulator>
+ <memballoon model='none'/>
+ </devices>
+</domain>
diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c
index eae999dd6..aae632afe 100644
--- a/tests/qemuxml2xmltest.c
+++ b/tests/qemuxml2xmltest.c
@@ -1073,6 +1073,7 @@ mymain(void)
DO_TEST_FULL("aarch64-gic-none-v2", WHEN_BOTH, GIC_V2, NONE);
DO_TEST_FULL("aarch64-gic-none-v3", WHEN_BOTH, GIC_V3, NONE);
DO_TEST_FULL("aarch64-gic-none-both", WHEN_BOTH, GIC_BOTH, NONE);
+ DO_TEST_FULL("aarch64-gic-none-tcg", WHEN_BOTH, GIC_BOTH, NONE);
DO_TEST_FULL("aarch64-gic-default", WHEN_BOTH, GIC_NONE, NONE);
DO_TEST_FULL("aarch64-gic-default", WHEN_BOTH, GIC_V2, NONE);
DO_TEST_FULL("aarch64-gic-default", WHEN_BOTH, GIC_V3, NONE);
@@ -0,0 +1,85 @@
From: Andrea Bolognani <abologna@redhat.com>
Date: Fri, 12 May 2017 13:29:57 +0200
Subject: [PATCH] qemu: Use GICv2 for aarch64/virt TCG guests
There are currently some limitations in the emulated GICv3
that make it unsuitable as a default. Use GICv2 instead.
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1450433
Signed-off-by: Andrea Bolognani <abologna@redhat.com>
(cherry picked from commit bc07101a7c2cd2ce07ad1ca28c47e0a7cde5625d)
---
src/qemu/qemu_domain.c | 23 +++++++++++++++++++++-
.../qemuxml2argv-aarch64-gic-none-tcg.args | 2 +-
.../qemuxml2xmlout-aarch64-gic-none-tcg.xml | 2 +-
3 files changed, 24 insertions(+), 3 deletions(-)
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index 589eb1889..891f8258a 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -2527,6 +2527,24 @@ qemuDomainDefEnableDefaultFeatures(virDomainDefPtr def,
for (version = VIR_GIC_VERSION_LAST - 1;
version > VIR_GIC_VERSION_NONE;
version--) {
+
+ /* We want to use the highest available GIC version for guests;
+ * however, the emulated GICv3 is currently lacking a MSI controller,
+ * making it unsuitable for the pure PCIe topology we aim for.
+ *
+ * For that reason, we skip this step entirely for TCG guests,
+ * and rely on the code below to pick the default version, GICv2,
+ * which supports all the features we need.
+ *
+ * We'll want to revisit this once MSI support for GICv3 has been
+ * implemented in QEMU.
+ *
+ * See https://bugzilla.redhat.com/show_bug.cgi?id=1414081 */
+ if (version == VIR_GIC_VERSION_3 &&
+ def->virtType == VIR_DOMAIN_VIRT_QEMU) {
+ continue;
+ }
+
if (virQEMUCapsSupportsGICVersion(qemuCaps,
def->virtType,
version)) {
@@ -2544,8 +2562,11 @@ qemuDomainDefEnableDefaultFeatures(virDomainDefPtr def,
/* Use the default GIC version if no version was specified */
if (def->features[VIR_DOMAIN_FEATURE_GIC] == VIR_TRISTATE_SWITCH_ON &&
- def->gic_version == VIR_GIC_VERSION_NONE)
+ def->gic_version == VIR_GIC_VERSION_NONE) {
+ VIR_DEBUG("Using GIC version %s (default)",
+ virGICVersionTypeToString(VIR_GIC_VERSION_DEFAULT));
def->gic_version = VIR_GIC_VERSION_DEFAULT;
+ }
}
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-aarch64-gic-none-tcg.args b/tests/qemuxml2argvdata/qemuxml2argv-aarch64-gic-none-tcg.args
index 975a01481..52b699696 100644
--- a/tests/qemuxml2argvdata/qemuxml2argv-aarch64-gic-none-tcg.args
+++ b/tests/qemuxml2argvdata/qemuxml2argv-aarch64-gic-none-tcg.args
@@ -7,7 +7,7 @@ QEMU_AUDIO_DRV=none \
/usr/bin/qemu-system-aarch64 \
-name guest \
-S \
--machine virt,accel=tcg,gic-version=3 \
+-machine virt,accel=tcg \
-cpu cortex-a57 \
-m 1024 \
-smp 1,sockets=1,cores=1,threads=1 \
diff --git a/tests/qemuxml2xmloutdata/qemuxml2xmlout-aarch64-gic-none-tcg.xml b/tests/qemuxml2xmloutdata/qemuxml2xmlout-aarch64-gic-none-tcg.xml
index 69510e281..a0cd0b768 100644
--- a/tests/qemuxml2xmloutdata/qemuxml2xmlout-aarch64-gic-none-tcg.xml
+++ b/tests/qemuxml2xmloutdata/qemuxml2xmlout-aarch64-gic-none-tcg.xml
@@ -9,7 +9,7 @@
<boot dev='hd'/>
</os>
<features>
- <gic version='3'/>
+ <gic version='2'/>
</features>
<cpu mode='custom' match='exact' check='none'>
<model fallback='allow'>cortex-a57</model>
@@ -0,0 +1,67 @@
From: Andrea Bolognani <abologna@redhat.com>
Date: Fri, 12 May 2017 14:38:08 +0200
Subject: [PATCH] gic: Remove VIR_GIC_VERSION_DEFAULT
The QEMU default is GICv2, and some of the code in libvirt
relies on the exact value. Stop pretending that's not the
case and use GICv2 explicitly where needed.
Signed-off-by: Andrea Bolognani <abologna@redhat.com>
(cherry picked from commit 5645badd1fe04fee7237c2f95e7710e978e40770)
---
src/qemu/qemu_command.c | 6 +++---
src/qemu/qemu_domain.c | 7 +++----
src/util/virgic.h | 3 ---
3 files changed, 6 insertions(+), 10 deletions(-)
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 2d1328cf9..5feddc523 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -7321,9 +7321,9 @@ qemuBuildMachineCommandLine(virCommandPtr cmd,
goto cleanup;
}
- /* The default GIC version should not be specified on the
- * QEMU commandline for backwards compatibility reasons */
- if (def->gic_version != VIR_GIC_VERSION_DEFAULT) {
+ /* The default GIC version (GICv2) should not be specified on
+ * the QEMU commandline for backwards compatibility reasons */
+ if (def->gic_version != VIR_GIC_VERSION_2) {
if (!virQEMUCapsGet(qemuCaps,
QEMU_CAPS_MACH_VIRT_GIC_VERSION)) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index 891f8258a..4a127cedf 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -2560,12 +2560,11 @@ qemuDomainDefEnableDefaultFeatures(virDomainDefPtr def,
def->features[VIR_DOMAIN_FEATURE_GIC] = VIR_TRISTATE_SWITCH_ON;
}
- /* Use the default GIC version if no version was specified */
+ /* Use the default GIC version (GICv2) if no version was specified */
if (def->features[VIR_DOMAIN_FEATURE_GIC] == VIR_TRISTATE_SWITCH_ON &&
def->gic_version == VIR_GIC_VERSION_NONE) {
- VIR_DEBUG("Using GIC version %s (default)",
- virGICVersionTypeToString(VIR_GIC_VERSION_DEFAULT));
- def->gic_version = VIR_GIC_VERSION_DEFAULT;
+ VIR_DEBUG("Using GIC version 2 (default)");
+ def->gic_version = VIR_GIC_VERSION_2;
}
}
diff --git a/src/util/virgic.h b/src/util/virgic.h
index 1c9efd60f..2d77fdd45 100644
--- a/src/util/virgic.h
+++ b/src/util/virgic.h
@@ -35,9 +35,6 @@ typedef enum {
VIR_ENUM_DECL(virGICVersion);
-/* Consider GIC v2 the default */
-# define VIR_GIC_VERSION_DEFAULT VIR_GIC_VERSION_2
-
typedef enum {
VIR_GIC_IMPLEMENTATION_NONE = 0,
VIR_GIC_IMPLEMENTATION_KERNEL = (1 << 1),
@@ -0,0 +1,198 @@
From: Laine Stump <laine@laine.org>
Date: Thu, 18 May 2017 14:16:27 -0400
Subject: [PATCH] Revert "qemu: propagate bridge MTU into qemu "host_mtu"
option"
This reverts commit 2841e675.
It turns out that adding the host_mtu field to the PCI capabilities in
the guest bumps the length of PCI capabilities beyond the 32 byte
boundary, so the virtio-net device gets 64 bytes of ioport space
instead of 32, which offsets the address of all the other following
devices. Migration doesn't work very well when the location and length
of PCI capabilities of devices is changed between source and
destination.
This means that we need to make sure that the absence/presence of
host_mtu on the qemu commandline always matches between source and
destination, which means that we need to make setting of host_mtu an
opt-in thing (it can't happen automatically when the bridge being used
has a non-default MTU, which is what commit 2841e675 implemented).
I do want to re-implement this feature with an <mtu auto='on'/>
setting, but probably won't backport that to any stable branches, so
I'm first reverting the original commit, and that revert can be pushed
to the few releases that have been made since the original (3.1.0 -
3.3.0)
Resolves: https://bugzilla.redhat.com/1449346
(cherry picked from commit 77780a29edace958a1f931d3281b962be4f5290e)
(cherry picked from commit a2f5e87dceb1725c16cd4df17a4b7381ecf65901)
---
src/qemu/qemu_command.c | 32 ++++++++++----------------------
src/qemu/qemu_command.h | 3 +--
src/qemu/qemu_hotplug.c | 5 ++---
src/qemu/qemu_interface.c | 5 ++---
src/qemu/qemu_interface.h | 3 +--
5 files changed, 16 insertions(+), 32 deletions(-)
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 5feddc523..3abfe7b55 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -3629,8 +3629,7 @@ qemuBuildNicDevStr(virDomainDefPtr def,
int vlan,
unsigned int bootindex,
size_t vhostfdSize,
- virQEMUCapsPtr qemuCaps,
- unsigned int mtu)
+ virQEMUCapsPtr qemuCaps)
{
virBuffer buf = VIR_BUFFER_INITIALIZER;
const char *nic = net->model;
@@ -3754,23 +3753,13 @@ qemuBuildNicDevStr(virDomainDefPtr def,
virBufferAsprintf(&buf, ",rx_queue_size=%u", net->driver.virtio.rx_queue_size);
}
- if (usingVirtio && mtu) {
- if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_VIRTIO_NET_HOST_MTU)) {
-
- virBufferAsprintf(&buf, ",host_mtu=%u", mtu);
-
- } else {
- /* log an error if mtu was requested specifically for this
- * interface, otherwise, if it's just what was reported by
- * the attached network, ignore it.
- */
- if (net->mtu) {
- virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
- _("setting MTU is not supported with "
- "this QEMU binary"));
- goto error;
- }
+ if (usingVirtio && net->mtu) {
+ if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_VIRTIO_NET_HOST_MTU)) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("setting MTU is not supported with this QEMU binary"));
+ goto error;
}
+ virBufferAsprintf(&buf, ",host_mtu=%u", net->mtu);
}
if (vlan == -1)
@@ -8213,7 +8202,7 @@ qemuBuildVhostuserCommandLine(virQEMUDriverPtr driver,
VIR_FREE(netdev);
if (!(nic = qemuBuildNicDevStr(def, net, -1, bootindex,
- queues, qemuCaps, net->mtu))) {
+ queues, qemuCaps))) {
virReportError(VIR_ERR_INTERNAL_ERROR,
"%s", _("Error generating NIC -device string"));
goto error;
@@ -8259,7 +8248,6 @@ qemuBuildInterfaceCommandLine(virQEMUDriverPtr driver,
virDomainNetType actualType = virDomainNetGetActualType(net);
virNetDevBandwidthPtr actualBandwidth;
size_t i;
- unsigned int mtu = net->mtu;
if (!bootindex)
@@ -8314,7 +8302,7 @@ qemuBuildInterfaceCommandLine(virQEMUDriverPtr driver,
memset(tapfd, -1, tapfdSize * sizeof(tapfd[0]));
if (qemuInterfaceBridgeConnect(def, driver, net,
- tapfd, &tapfdSize, &mtu) < 0)
+ tapfd, &tapfdSize) < 0)
goto cleanup;
break;
@@ -8494,7 +8482,7 @@ qemuBuildInterfaceCommandLine(virQEMUDriverPtr driver,
}
if (qemuDomainSupportsNicdev(def, net)) {
if (!(nic = qemuBuildNicDevStr(def, net, vlan, bootindex,
- vhostfdSize, qemuCaps, mtu)))
+ vhostfdSize, qemuCaps)))
goto cleanup;
virCommandAddArgList(cmd, "-device", nic, NULL);
} else {
diff --git a/src/qemu/qemu_command.h b/src/qemu/qemu_command.h
index 7da92c8c9..09cb00ee9 100644
--- a/src/qemu/qemu_command.h
+++ b/src/qemu/qemu_command.h
@@ -101,8 +101,7 @@ char *qemuBuildNicDevStr(virDomainDefPtr def,
int vlan,
unsigned int bootindex,
size_t vhostfdSize,
- virQEMUCapsPtr qemuCaps,
- unsigned int mtu);
+ virQEMUCapsPtr qemuCaps);
char *qemuDeviceDriveHostAlias(virDomainDiskDefPtr disk);
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index f133d04a8..2a4159560 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -968,7 +968,6 @@ qemuDomainAttachNetDevice(virQEMUDriverPtr driver,
bool charDevPlugged = false;
bool netdevPlugged = false;
bool hostPlugged = false;
- unsigned int mtu = net->mtu;
/* preallocate new slot for device */
if (VIR_REALLOC_N(vm->def->nets, vm->def->nnets + 1) < 0)
@@ -1025,7 +1024,7 @@ qemuDomainAttachNetDevice(virQEMUDriverPtr driver,
goto cleanup;
memset(vhostfd, -1, sizeof(*vhostfd) * vhostfdSize);
if (qemuInterfaceBridgeConnect(vm->def, driver, net,
- tapfd, &tapfdSize, &mtu) < 0)
+ tapfd, &tapfdSize) < 0)
goto cleanup;
iface_connected = true;
if (qemuInterfaceOpenVhostNet(vm->def, net, priv->qemuCaps,
@@ -1239,7 +1238,7 @@ qemuDomainAttachNetDevice(virQEMUDriverPtr driver,
VIR_FORCE_CLOSE(vhostfd[i]);
if (!(nicstr = qemuBuildNicDevStr(vm->def, net, vlan, 0,
- queueSize, priv->qemuCaps, mtu)))
+ queueSize, priv->qemuCaps)))
goto try_remove;
qemuDomainObjEnterMonitor(driver, vm);
diff --git a/src/qemu/qemu_interface.c b/src/qemu/qemu_interface.c
index c5dca60f1..ce448d243 100644
--- a/src/qemu/qemu_interface.c
+++ b/src/qemu/qemu_interface.c
@@ -503,8 +503,7 @@ qemuInterfaceBridgeConnect(virDomainDefPtr def,
virQEMUDriverPtr driver,
virDomainNetDefPtr net,
int *tapfd,
- size_t *tapfdSize,
- unsigned int *mtu)
+ size_t *tapfdSize)
{
const char *brname;
int ret = -1;
@@ -545,7 +544,7 @@ qemuInterfaceBridgeConnect(virDomainDefPtr def,
def->uuid, tunpath, tapfd, *tapfdSize,
virDomainNetGetActualVirtPortProfile(net),
virDomainNetGetActualVlan(net),
- net->mtu, mtu,
+ 0, NULL,
tap_create_flags) < 0) {
virDomainAuditNetDevice(def, net, tunpath, false);
goto cleanup;
diff --git a/src/qemu/qemu_interface.h b/src/qemu/qemu_interface.h
index ba74ac2cf..a7faa0b3d 100644
--- a/src/qemu/qemu_interface.h
+++ b/src/qemu/qemu_interface.h
@@ -51,8 +51,7 @@ int qemuInterfaceBridgeConnect(virDomainDefPtr def,
virQEMUDriverPtr driver,
virDomainNetDefPtr net,
int *tapfd,
- size_t *tapfdSize,
- unsigned int *mtu)
+ size_t *tapfdSize)
ATTRIBUTE_NONNULL(2);
int qemuInterfaceOpenVhostNet(virDomainDefPtr def,
@@ -0,0 +1,145 @@
From: Jiri Denemark <jdenemar@redhat.com>
Date: Wed, 29 Mar 2017 14:45:44 +0200
Subject: [PATCH] cpu: Introduce virCPUCopyMigratable
This new internal API makes a copy of virCPUDef while removing all
features which would block migration. It uses cpu_map.xml as a database
of such features, which should only be used as a fallback when we cannot
get the data from a hypervisor. The main goal of this API is to decouple
this filtering from virCPUUpdate so that the hypervisor driver can
filter the features according to the hypervisor.
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
(cherry picked from commit 05e91c79f19e0be96526098d58a3498dac3f8529)
---
src/cpu/cpu.c | 31 +++++++++++++++++++++++++++++++
src/cpu/cpu.h | 8 ++++++++
src/cpu/cpu_x86.c | 25 +++++++++++++++++++++++++
src/libvirt_private.syms | 1 +
4 files changed, 65 insertions(+)
diff --git a/src/cpu/cpu.c b/src/cpu/cpu.c
index 93647a2ed..8a407ac18 100644
--- a/src/cpu/cpu.c
+++ b/src/cpu/cpu.c
@@ -1130,3 +1130,34 @@ virCPUExpandFeatures(virArch arch,
VIR_DEBUG("nfeatures=%zu", cpu->nfeatures);
return 0;
}
+
+
+/**
+ * virCPUCopyMigratable:
+ *
+ * @arch: CPU architecture
+ * @cpu: CPU definition to be copied
+ *
+ * Makes a copy of @cpu with all features which would block migration removed.
+ * If this doesn't make sense for a given architecture, the function returns a
+ * plain copy of @cpu (i.e., a copy with no features removed).
+ *
+ * Returns the copy of the CPU or NULL on error.
+ */
+virCPUDefPtr
+virCPUCopyMigratable(virArch arch,
+ virCPUDefPtr cpu)
+{
+ struct cpuArchDriver *driver;
+
+ VIR_DEBUG("arch=%s, cpu=%p, model=%s",
+ virArchToString(arch), cpu, NULLSTR(cpu->model));
+
+ if (!(driver = cpuGetSubDriver(arch)))
+ return NULL;
+
+ if (driver->copyMigratable)
+ return driver->copyMigratable(cpu);
+ else
+ return virCPUDefCopy(cpu);
+}
diff --git a/src/cpu/cpu.h b/src/cpu/cpu.h
index 8c238ad55..352445c40 100644
--- a/src/cpu/cpu.h
+++ b/src/cpu/cpu.h
@@ -118,6 +118,9 @@ typedef int
typedef int
(*virCPUArchExpandFeatures)(virCPUDefPtr cpu);
+typedef virCPUDefPtr
+(*virCPUArchCopyMigratable)(virCPUDefPtr cpu);
+
struct cpuArchDriver {
const char *name;
const virArch *arch;
@@ -138,6 +141,7 @@ struct cpuArchDriver {
virCPUArchTranslate translate;
virCPUArchConvertLegacy convertLegacy;
virCPUArchExpandFeatures expandFeatures;
+ virCPUArchCopyMigratable copyMigratable;
};
@@ -254,6 +258,10 @@ int
virCPUExpandFeatures(virArch arch,
virCPUDefPtr cpu);
+virCPUDefPtr
+virCPUCopyMigratable(virArch arch,
+ virCPUDefPtr cpu);
+
/* virCPUDataFormat and virCPUDataParse are implemented for unit tests only and
* have no real-life usage
*/
diff --git a/src/cpu/cpu_x86.c b/src/cpu/cpu_x86.c
index 48648a7f4..a771b251e 100644
--- a/src/cpu/cpu_x86.c
+++ b/src/cpu/cpu_x86.c
@@ -2903,6 +2903,30 @@ virCPUx86ExpandFeatures(virCPUDefPtr cpu)
}
+static virCPUDefPtr
+virCPUx86CopyMigratable(virCPUDefPtr cpu)
+{
+ virCPUDefPtr copy;
+ virCPUx86MapPtr map;
+
+ if (!(map = virCPUx86GetMap()))
+ return NULL;
+
+ if (!(copy = virCPUDefCopyWithoutModel(cpu)))
+ return NULL;
+
+ if (virCPUDefCopyModelFilter(copy, cpu, false,
+ x86FeatureIsMigratable, map) < 0)
+ goto error;
+
+ return copy;
+
+ error:
+ virCPUDefFree(copy);
+ return NULL;
+}
+
+
int
virCPUx86DataAddCPUID(virCPUDataPtr cpuData,
const virCPUx86CPUID *cpuid)
@@ -2978,4 +3002,5 @@ struct cpuArchDriver cpuDriverX86 = {
.getModels = virCPUx86GetModels,
.translate = virCPUx86Translate,
.expandFeatures = virCPUx86ExpandFeatures,
+ .copyMigratable = virCPUx86CopyMigratable,
};
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index b551cb86a..dc6db3b28 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -1016,6 +1016,7 @@ virCPUCheckFeature;
virCPUCompare;
virCPUCompareXML;
virCPUConvertLegacy;
+virCPUCopyMigratable;
virCPUDataCheckFeature;
virCPUDataFormat;
virCPUDataFree;
@@ -0,0 +1,78 @@
From: Jiri Denemark <jdenemar@redhat.com>
Date: Thu, 30 Mar 2017 13:50:44 +0200
Subject: [PATCH] qemu: Move common code in virQEMUCapsInitCPUModel one layer
up
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
(cherry picked from commit d84b93fad51b190238e18b1daac82ea6e28869e9)
---
src/qemu/qemu_capabilities.c | 25 ++++++++++---------------
1 file changed, 10 insertions(+), 15 deletions(-)
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index b1245ad5d..1a15750a3 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -3111,17 +3111,11 @@ virQEMUCapsCPUFilterFeatures(const char *name,
*/
static int
virQEMUCapsInitCPUModelS390(virQEMUCapsPtr qemuCaps,
- virDomainVirtType type,
+ qemuMonitorCPUModelInfoPtr modelInfo,
virCPUDefPtr cpu)
{
- qemuMonitorCPUModelInfoPtr modelInfo;
size_t i;
- if (type == VIR_DOMAIN_VIRT_KVM)
- modelInfo = qemuCaps->kvmCPUModelInfo;
- else
- modelInfo = qemuCaps->tcgCPUModelInfo;
-
if (!modelInfo) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("missing host CPU model info from QEMU capabilities "
@@ -3163,9 +3157,9 @@ virQEMUCapsInitCPUModelS390(virQEMUCapsPtr qemuCaps,
static int
virQEMUCapsInitCPUModelX86(virQEMUCapsPtr qemuCaps,
virDomainVirtType type,
+ qemuMonitorCPUModelInfoPtr model,
virCPUDefPtr cpu)
{
- qemuMonitorCPUModelInfoPtr model;
virCPUDataPtr data = NULL;
unsigned long long sigFamily = 0;
unsigned long long sigModel = 0;
@@ -3174,11 +3168,6 @@ virQEMUCapsInitCPUModelX86(virQEMUCapsPtr qemuCaps,
int ret = -1;
size_t i;
- if (type == VIR_DOMAIN_VIRT_KVM)
- model = qemuCaps->kvmCPUModelInfo;
- else
- model = qemuCaps->tcgCPUModelInfo;
-
if (!model)
return 1;
@@ -3239,12 +3228,18 @@ virQEMUCapsInitCPUModel(virQEMUCapsPtr qemuCaps,
virDomainVirtType type,
virCPUDefPtr cpu)
{
+ qemuMonitorCPUModelInfoPtr model;
int ret = 1;
+ if (type == VIR_DOMAIN_VIRT_KVM)
+ model = qemuCaps->kvmCPUModelInfo;
+ else
+ model = qemuCaps->tcgCPUModelInfo;
+
if (ARCH_IS_S390(qemuCaps->arch))
- ret = virQEMUCapsInitCPUModelS390(qemuCaps, type, cpu);
+ ret = virQEMUCapsInitCPUModelS390(qemuCaps, model, cpu);
else if (ARCH_IS_X86(qemuCaps->arch))
- ret = virQEMUCapsInitCPUModelX86(qemuCaps, type, cpu);
+ ret = virQEMUCapsInitCPUModelX86(qemuCaps, type, model, cpu);
if (ret == 0)
cpu->fallback = VIR_CPU_FALLBACK_FORBID;
@@ -0,0 +1,139 @@
From: Jiri Denemark <jdenemar@redhat.com>
Date: Wed, 29 Mar 2017 13:33:50 +0200
Subject: [PATCH] qemu: Add migratable parameter to virQEMUCapsInitCPUModel
The caller can ask for a migratable CPU model by passing true for the
new parameter.
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
(cherry picked from commit 00e0cbcb567a57c7b5a145d7fd3fb662779f6bec)
---
src/qemu/qemu_capabilities.c | 36 +++++++++++++++++++++++++-----------
src/qemu/qemu_capspriv.h | 3 ++-
tests/cputest.c | 2 +-
3 files changed, 28 insertions(+), 13 deletions(-)
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index 1a15750a3..b8e4e47b6 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -3112,7 +3112,8 @@ virQEMUCapsCPUFilterFeatures(const char *name,
static int
virQEMUCapsInitCPUModelS390(virQEMUCapsPtr qemuCaps,
qemuMonitorCPUModelInfoPtr modelInfo,
- virCPUDefPtr cpu)
+ virCPUDefPtr cpu,
+ bool migratable)
{
size_t i;
@@ -3140,8 +3141,12 @@ virQEMUCapsInitCPUModelS390(virQEMUCapsPtr qemuCaps,
if (VIR_STRDUP(feature->name, prop->name) < 0)
return -1;
- feature->policy = prop->value.boolean ? VIR_CPU_FEATURE_REQUIRE
- : VIR_CPU_FEATURE_DISABLE;
+
+ if (!prop->value.boolean ||
+ (migratable && prop->migratable == VIR_TRISTATE_BOOL_NO))
+ feature->policy = VIR_CPU_FEATURE_DISABLE;
+ else
+ feature->policy = VIR_CPU_FEATURE_REQUIRE;
cpu->nfeatures++;
}
@@ -3158,7 +3163,8 @@ static int
virQEMUCapsInitCPUModelX86(virQEMUCapsPtr qemuCaps,
virDomainVirtType type,
qemuMonitorCPUModelInfoPtr model,
- virCPUDefPtr cpu)
+ virCPUDefPtr cpu,
+ bool migratable)
{
virCPUDataPtr data = NULL;
unsigned long long sigFamily = 0;
@@ -3179,9 +3185,13 @@ virQEMUCapsInitCPUModelX86(virQEMUCapsPtr qemuCaps,
switch (prop->type) {
case QEMU_MONITOR_CPU_PROPERTY_BOOLEAN:
- if (prop->value.boolean &&
- virCPUx86DataAddFeature(data, prop->name) < 0)
+ if (!prop->value.boolean ||
+ (migratable && prop->migratable == VIR_TRISTATE_BOOL_NO))
+ continue;
+
+ if (virCPUx86DataAddFeature(data, prop->name) < 0)
goto cleanup;
+
break;
case QEMU_MONITOR_CPU_PROPERTY_STRING:
@@ -3220,13 +3230,14 @@ virQEMUCapsInitCPUModelX86(virQEMUCapsPtr qemuCaps,
/**
* Returns 0 when host CPU model provided by QEMU was filled in qemuCaps,
- * 1 when the caller should fall back to using virCapsPtr->host.cpu,
+ * 1 when the caller should fall back to other methods
* -1 on error.
*/
int
virQEMUCapsInitCPUModel(virQEMUCapsPtr qemuCaps,
virDomainVirtType type,
- virCPUDefPtr cpu)
+ virCPUDefPtr cpu,
+ bool migratable)
{
qemuMonitorCPUModelInfoPtr model;
int ret = 1;
@@ -3236,10 +3247,13 @@ virQEMUCapsInitCPUModel(virQEMUCapsPtr qemuCaps,
else
model = qemuCaps->tcgCPUModelInfo;
+ if (migratable && model && !model->migratability)
+ return 1;
+
if (ARCH_IS_S390(qemuCaps->arch))
- ret = virQEMUCapsInitCPUModelS390(qemuCaps, model, cpu);
+ ret = virQEMUCapsInitCPUModelS390(qemuCaps, model, cpu, migratable);
else if (ARCH_IS_X86(qemuCaps->arch))
- ret = virQEMUCapsInitCPUModelX86(qemuCaps, type, model, cpu);
+ ret = virQEMUCapsInitCPUModelX86(qemuCaps, type, model, cpu, migratable);
if (ret == 0)
cpu->fallback = VIR_CPU_FALLBACK_FORBID;
@@ -3268,7 +3282,7 @@ virQEMUCapsInitHostCPUModel(virQEMUCapsPtr qemuCaps,
cpu->match = VIR_CPU_MATCH_EXACT;
cpu->fallback = VIR_CPU_FALLBACK_ALLOW;
- if ((rc = virQEMUCapsInitCPUModel(qemuCaps, type, cpu)) < 0) {
+ if ((rc = virQEMUCapsInitCPUModel(qemuCaps, type, cpu, false)) < 0) {
goto error;
} else if (rc == 1) {
VIR_DEBUG("No host CPU model info from QEMU; probing host CPU directly");
diff --git a/src/qemu/qemu_capspriv.h b/src/qemu/qemu_capspriv.h
index 61ccd4517..1baaaf334 100644
--- a/src/qemu/qemu_capspriv.h
+++ b/src/qemu/qemu_capspriv.h
@@ -81,7 +81,8 @@ virQEMUCapsInitHostCPUModel(virQEMUCapsPtr qemuCaps,
int
virQEMUCapsInitCPUModel(virQEMUCapsPtr qemuCaps,
virDomainVirtType type,
- virCPUDefPtr cpu);
+ virCPUDefPtr cpu,
+ bool migratable);
void
virQEMUCapsSetCPUModelInfo(virQEMUCapsPtr qemuCaps,
diff --git a/tests/cputest.c b/tests/cputest.c
index 3d3e43f16..8c07cf4f6 100644
--- a/tests/cputest.c
+++ b/tests/cputest.c
@@ -709,7 +709,7 @@ cpuTestJSONCPUID(const void *arg)
cpu->match = VIR_CPU_MATCH_EXACT;
cpu->fallback = VIR_CPU_FALLBACK_FORBID;
- if (virQEMUCapsInitCPUModel(qemuCaps, VIR_DOMAIN_VIRT_KVM, cpu) != 0)
+ if (virQEMUCapsInitCPUModel(qemuCaps, VIR_DOMAIN_VIRT_KVM, cpu, false) != 0)
goto cleanup;
ret = cpuTestCompareXML(data->arch, cpu, result, false);
@@ -0,0 +1,47 @@
From: Jiri Denemark <jdenemar@redhat.com>
Date: Fri, 7 Apr 2017 17:03:38 +0200
Subject: [PATCH] qemu: Introduce virQEMUCapsSetHostModel
A simple helper as a complement to virQEMUCapsGetHostModel.
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
(cherry picked from commit bffc3b9fe501ff122ad81ddf42ecdb69f70ff70a)
---
src/qemu/qemu_capabilities.c | 17 +++++++++++++----
1 file changed, 13 insertions(+), 4 deletions(-)
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index b8e4e47b6..f6020b86d 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -2419,6 +2419,18 @@ virQEMUCapsGetHostModel(virQEMUCapsPtr qemuCaps,
}
+static void
+virQEMUCapsSetHostModel(virQEMUCapsPtr qemuCaps,
+ virDomainVirtType type,
+ virCPUDefPtr cpu)
+{
+ if (type == VIR_DOMAIN_VIRT_KVM)
+ qemuCaps->kvmCPUModel = cpu;
+ else
+ qemuCaps->tcgCPUModel = cpu;
+}
+
+
bool
virQEMUCapsIsCPUModeSupported(virQEMUCapsPtr qemuCaps,
virCapsPtr caps,
@@ -3295,10 +3307,7 @@ virQEMUCapsInitHostCPUModel(virQEMUCapsPtr qemuCaps,
goto error;
}
- if (type == VIR_DOMAIN_VIRT_KVM)
- qemuCaps->kvmCPUModel = cpu;
- else
- qemuCaps->tcgCPUModel = cpu;
+ virQEMUCapsSetHostModel(qemuCaps, type, cpu);
cleanup:
virCPUDefFree(hostCPU);
@@ -0,0 +1,70 @@
From: Jiri Denemark <jdenemar@redhat.com>
Date: Fri, 7 Apr 2017 17:40:31 +0200
Subject: [PATCH] qemu: Move qemuCaps CPU data copying into a separate function
This introduces virQEMUCapsHostCPUDataCopy which will later be
refactored a bit and called twice from virQEMUCapsNewCopy.
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
(cherry picked from commit 8be4346ca5ae4b568b3e8ce3de9cf46f2e94b416)
---
src/qemu/qemu_capabilities.c | 39 +++++++++++++++++++++++++--------------
1 file changed, 25 insertions(+), 14 deletions(-)
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index f6020b86d..d17e0e8b8 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -2082,6 +2082,30 @@ virQEMUCapsNew(void)
}
+static int
+virQEMUCapsHostCPUDataCopy(virQEMUCapsPtr dst,
+ virQEMUCapsPtr src)
+{
+ if (src->kvmCPUModel &&
+ !(dst->kvmCPUModel = virCPUDefCopy(src->kvmCPUModel)))
+ return -1;
+
+ if (src->tcgCPUModel &&
+ !(dst->tcgCPUModel = virCPUDefCopy(src->tcgCPUModel)))
+ return -1;
+
+ if (src->kvmCPUModelInfo &&
+ !(dst->kvmCPUModelInfo = qemuMonitorCPUModelInfoCopy(src->kvmCPUModelInfo)))
+ return -1;
+
+ if (src->tcgCPUModelInfo &&
+ !(dst->tcgCPUModelInfo = qemuMonitorCPUModelInfoCopy(src->tcgCPUModelInfo)))
+ return -1;
+
+ return 0;
+}
+
+
virQEMUCapsPtr virQEMUCapsNewCopy(virQEMUCapsPtr qemuCaps)
{
virQEMUCapsPtr ret = virQEMUCapsNew();
@@ -2119,20 +2143,7 @@ virQEMUCapsPtr virQEMUCapsNewCopy(virQEMUCapsPtr qemuCaps)
goto error;
}
- if (qemuCaps->kvmCPUModel &&
- !(ret->kvmCPUModel = virCPUDefCopy(qemuCaps->kvmCPUModel)))
- goto error;
-
- if (qemuCaps->tcgCPUModel &&
- !(ret->tcgCPUModel = virCPUDefCopy(qemuCaps->tcgCPUModel)))
- goto error;
-
- if (qemuCaps->kvmCPUModelInfo &&
- !(ret->kvmCPUModelInfo = qemuMonitorCPUModelInfoCopy(qemuCaps->kvmCPUModelInfo)))
- goto error;
-
- if (qemuCaps->tcgCPUModelInfo &&
- !(ret->tcgCPUModelInfo = qemuMonitorCPUModelInfoCopy(qemuCaps->tcgCPUModelInfo)))
+ if (virQEMUCapsHostCPUDataCopy(ret, qemuCaps) < 0)
goto error;
if (VIR_ALLOC_N(ret->machineTypes, qemuCaps->nmachineTypes) < 0)
@@ -0,0 +1,67 @@
From: Jiri Denemark <jdenemar@redhat.com>
Date: Fri, 7 Apr 2017 17:43:59 +0200
Subject: [PATCH] qemu: Introduce virQEMUCapsHostCPUDataClear
To keep freeing of host CPU data in one place.
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
(cherry picked from commit b0605e848724c5dc478382398b734398abff674c)
---
src/qemu/qemu_capabilities.c | 30 +++++++++++++++++-------------
1 file changed, 17 insertions(+), 13 deletions(-)
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index d17e0e8b8..2da53a60b 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -2106,6 +2106,21 @@ virQEMUCapsHostCPUDataCopy(virQEMUCapsPtr dst,
}
+static void
+virQEMUCapsHostCPUDataClear(virQEMUCapsPtr qemuCaps)
+{
+ qemuMonitorCPUModelInfoFree(qemuCaps->kvmCPUModelInfo);
+ qemuMonitorCPUModelInfoFree(qemuCaps->tcgCPUModelInfo);
+ qemuCaps->kvmCPUModelInfo = NULL;
+ qemuCaps->tcgCPUModelInfo = NULL;
+
+ virCPUDefFree(qemuCaps->kvmCPUModel);
+ virCPUDefFree(qemuCaps->tcgCPUModel);
+ qemuCaps->kvmCPUModel = NULL;
+ qemuCaps->tcgCPUModel = NULL;
+}
+
+
virQEMUCapsPtr virQEMUCapsNewCopy(virQEMUCapsPtr qemuCaps)
{
virQEMUCapsPtr ret = virQEMUCapsNew();
@@ -2192,10 +2207,7 @@ void virQEMUCapsDispose(void *obj)
VIR_FREE(qemuCaps->gicCapabilities);
- qemuMonitorCPUModelInfoFree(qemuCaps->kvmCPUModelInfo);
- qemuMonitorCPUModelInfoFree(qemuCaps->tcgCPUModelInfo);
- virCPUDefFree(qemuCaps->kvmCPUModel);
- virCPUDefFree(qemuCaps->tcgCPUModel);
+ virQEMUCapsHostCPUDataClear(qemuCaps);
}
void
@@ -4068,15 +4080,7 @@ virQEMUCapsReset(virQEMUCapsPtr qemuCaps)
VIR_FREE(qemuCaps->gicCapabilities);
qemuCaps->ngicCapabilities = 0;
- qemuMonitorCPUModelInfoFree(qemuCaps->kvmCPUModelInfo);
- qemuMonitorCPUModelInfoFree(qemuCaps->tcgCPUModelInfo);
- qemuCaps->kvmCPUModelInfo = NULL;
- qemuCaps->tcgCPUModelInfo = NULL;
-
- virCPUDefFree(qemuCaps->kvmCPUModel);
- virCPUDefFree(qemuCaps->tcgCPUModel);
- qemuCaps->kvmCPUModel = NULL;
- qemuCaps->tcgCPUModel = NULL;
+ virQEMUCapsHostCPUDataClear(qemuCaps);
}
@@ -0,0 +1,342 @@
From: Jiri Denemark <jdenemar@redhat.com>
Date: Fri, 7 Apr 2017 18:15:26 +0200
Subject: [PATCH] qemu: Move qemuCaps host CPU data in a struct
We need to store several CPU related data structure for both KVM and
TCG. So instead of keeping two different copies of everything let's
make a virQEMUCapsHostCPUData struct and use it twice.
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
(cherry picked from commit b0a84ffb7f38f990120c231cfb74956a0ed10d95)
---
src/qemu/qemu_capabilities.c | 168 +++++++++++++++++++++----------------------
1 file changed, 82 insertions(+), 86 deletions(-)
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index 2da53a60b..bbb234538 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -373,6 +373,19 @@ struct virQEMUCapsMachineType {
unsigned int maxCpus;
bool hotplugCpus;
};
+
+typedef struct _virQEMUCapsHostCPUData virQEMUCapsHostCPUData;
+typedef virQEMUCapsHostCPUData *virQEMUCapsHostCPUDataPtr;
+struct _virQEMUCapsHostCPUData {
+ /* Only the "info" part is stored in the capabilities cache, the rest is
+ * re-computed from other fields and external data sources everytime we
+ * probe QEMU or load the cache.
+ */
+ qemuMonitorCPUModelInfoPtr info;
+ /* Host CPU definition reported in domain capabilities. */
+ virCPUDefPtr reported;
+};
+
/*
* Update the XML parser/formatter when adding more
* information to this struct so that it gets cached
@@ -407,15 +420,8 @@ struct _virQEMUCaps {
size_t ngicCapabilities;
virGICCapability *gicCapabilities;
- qemuMonitorCPUModelInfoPtr kvmCPUModelInfo;
- qemuMonitorCPUModelInfoPtr tcgCPUModelInfo;
-
- /* Anything below is not stored in the cache since the values are
- * re-computed from the other fields or external data sources every
- * time we probe QEMU or load the results from the cache.
- */
- virCPUDefPtr kvmCPUModel;
- virCPUDefPtr tcgCPUModel;
+ virQEMUCapsHostCPUData kvmCPU;
+ virQEMUCapsHostCPUData tcgCPU;
};
struct virQEMUCapsSearchData {
@@ -2083,23 +2089,15 @@ virQEMUCapsNew(void)
static int
-virQEMUCapsHostCPUDataCopy(virQEMUCapsPtr dst,
- virQEMUCapsPtr src)
+virQEMUCapsHostCPUDataCopy(virQEMUCapsHostCPUDataPtr dst,
+ virQEMUCapsHostCPUDataPtr src)
{
- if (src->kvmCPUModel &&
- !(dst->kvmCPUModel = virCPUDefCopy(src->kvmCPUModel)))
+ if (src->info &&
+ !(dst->info = qemuMonitorCPUModelInfoCopy(src->info)))
return -1;
- if (src->tcgCPUModel &&
- !(dst->tcgCPUModel = virCPUDefCopy(src->tcgCPUModel)))
- return -1;
-
- if (src->kvmCPUModelInfo &&
- !(dst->kvmCPUModelInfo = qemuMonitorCPUModelInfoCopy(src->kvmCPUModelInfo)))
- return -1;
-
- if (src->tcgCPUModelInfo &&
- !(dst->tcgCPUModelInfo = qemuMonitorCPUModelInfoCopy(src->tcgCPUModelInfo)))
+ if (src->reported &&
+ !(dst->reported = virCPUDefCopy(src->reported)))
return -1;
return 0;
@@ -2107,17 +2105,12 @@ virQEMUCapsHostCPUDataCopy(virQEMUCapsPtr dst,
static void
-virQEMUCapsHostCPUDataClear(virQEMUCapsPtr qemuCaps)
+virQEMUCapsHostCPUDataClear(virQEMUCapsHostCPUDataPtr cpuData)
{
- qemuMonitorCPUModelInfoFree(qemuCaps->kvmCPUModelInfo);
- qemuMonitorCPUModelInfoFree(qemuCaps->tcgCPUModelInfo);
- qemuCaps->kvmCPUModelInfo = NULL;
- qemuCaps->tcgCPUModelInfo = NULL;
-
- virCPUDefFree(qemuCaps->kvmCPUModel);
- virCPUDefFree(qemuCaps->tcgCPUModel);
- qemuCaps->kvmCPUModel = NULL;
- qemuCaps->tcgCPUModel = NULL;
+ qemuMonitorCPUModelInfoFree(cpuData->info);
+ virCPUDefFree(cpuData->reported);
+
+ memset(cpuData, 0, sizeof(*cpuData));
}
@@ -2158,7 +2151,8 @@ virQEMUCapsPtr virQEMUCapsNewCopy(virQEMUCapsPtr qemuCaps)
goto error;
}
- if (virQEMUCapsHostCPUDataCopy(ret, qemuCaps) < 0)
+ if (virQEMUCapsHostCPUDataCopy(&ret->kvmCPU, &qemuCaps->kvmCPU) < 0 ||
+ virQEMUCapsHostCPUDataCopy(&ret->tcgCPU, &qemuCaps->tcgCPU) < 0)
goto error;
if (VIR_ALLOC_N(ret->machineTypes, qemuCaps->nmachineTypes) < 0)
@@ -2207,7 +2201,8 @@ void virQEMUCapsDispose(void *obj)
VIR_FREE(qemuCaps->gicCapabilities);
- virQEMUCapsHostCPUDataClear(qemuCaps);
+ virQEMUCapsHostCPUDataClear(&qemuCaps->kvmCPU);
+ virQEMUCapsHostCPUDataClear(&qemuCaps->tcgCPU);
}
void
@@ -2431,14 +2426,24 @@ virQEMUCapsGetCPUDefinitions(virQEMUCapsPtr qemuCaps,
}
+static virQEMUCapsHostCPUDataPtr
+virQEMUCapsGetHostCPUData(virQEMUCapsPtr qemuCaps,
+ virDomainVirtType type)
+{
+ if (type == VIR_DOMAIN_VIRT_KVM)
+ return &qemuCaps->kvmCPU;
+ else
+ return &qemuCaps->tcgCPU;
+}
+
+
virCPUDefPtr
virQEMUCapsGetHostModel(virQEMUCapsPtr qemuCaps,
virDomainVirtType type)
{
- if (type == VIR_DOMAIN_VIRT_KVM)
- return qemuCaps->kvmCPUModel;
- else
- return qemuCaps->tcgCPUModel;
+ virQEMUCapsHostCPUDataPtr cpuData = virQEMUCapsGetHostCPUData(qemuCaps, type);
+
+ return cpuData->reported;
}
@@ -2447,10 +2452,9 @@ virQEMUCapsSetHostModel(virQEMUCapsPtr qemuCaps,
virDomainVirtType type,
virCPUDefPtr cpu)
{
- if (type == VIR_DOMAIN_VIRT_KVM)
- qemuCaps->kvmCPUModel = cpu;
- else
- qemuCaps->tcgCPUModel = cpu;
+ virQEMUCapsHostCPUDataPtr cpuData = virQEMUCapsGetHostCPUData(qemuCaps, type);
+
+ cpuData->reported = cpu;
}
@@ -2841,24 +2845,28 @@ virQEMUCapsProbeQMPHostCPU(virQEMUCapsPtr qemuCaps,
qemuMonitorPtr mon,
bool tcg)
{
- qemuMonitorCPUModelInfoPtr *modelInfo;
+ qemuMonitorCPUModelInfoPtr modelInfo = NULL;
qemuMonitorCPUModelInfoPtr nonMigratable = NULL;
virHashTablePtr hash = NULL;
const char *model;
qemuMonitorCPUModelExpansionType type;
+ virDomainVirtType virtType;
+ virQEMUCapsHostCPUDataPtr cpuData;
int ret = -1;
if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_QUERY_CPU_MODEL_EXPANSION))
return 0;
if (tcg || !virQEMUCapsGet(qemuCaps, QEMU_CAPS_KVM)) {
- modelInfo = &qemuCaps->tcgCPUModelInfo;
+ virtType = VIR_DOMAIN_VIRT_QEMU;
model = "max";
} else {
- modelInfo = &qemuCaps->kvmCPUModelInfo;
+ virtType = VIR_DOMAIN_VIRT_KVM;
model = "host";
}
+ cpuData = virQEMUCapsGetHostCPUData(qemuCaps, virtType);
+
/* Some x86_64 features defined in cpu_map.xml use spelling which differ
* from the one preferred by QEMU. Static expansion would give us only the
* preferred spelling, thus we need to do a full expansion on the result of
@@ -2869,14 +2877,14 @@ virQEMUCapsProbeQMPHostCPU(virQEMUCapsPtr qemuCaps,
else
type = QEMU_MONITOR_CPU_MODEL_EXPANSION_STATIC;
- if (qemuMonitorGetCPUModelExpansion(mon, type, model, true, modelInfo) < 0)
- return -1;
+ if (qemuMonitorGetCPUModelExpansion(mon, type, model, true, &modelInfo) < 0)
+ goto cleanup;
/* Try to check migratability of each feature. */
- if (*modelInfo &&
+ if (modelInfo &&
qemuMonitorGetCPUModelExpansion(mon, type, model, false,
&nonMigratable) < 0)
- goto error;
+ goto cleanup;
if (nonMigratable) {
qemuMonitorCPUPropertyPtr prop;
@@ -2884,12 +2892,12 @@ virQEMUCapsProbeQMPHostCPU(virQEMUCapsPtr qemuCaps,
size_t i;
if (!(hash = virHashCreate(0, NULL)))
- goto error;
+ goto cleanup;
- for (i = 0; i < (*modelInfo)->nprops; i++) {
- prop = (*modelInfo)->props + i;
+ for (i = 0; i < modelInfo->nprops; i++) {
+ prop = modelInfo->props + i;
if (virHashAddEntry(hash, prop->name, prop) < 0)
- goto error;
+ goto cleanup;
}
for (i = 0; i < nonMigratable->nprops; i++) {
@@ -2907,21 +2915,18 @@ virQEMUCapsProbeQMPHostCPU(virQEMUCapsPtr qemuCaps,
}
}
- (*modelInfo)->migratability = true;
+ modelInfo->migratability = true;
}
+ VIR_STEAL_PTR(cpuData->info, modelInfo);
ret = 0;
cleanup:
virHashFree(hash);
qemuMonitorCPUModelInfoFree(nonMigratable);
+ qemuMonitorCPUModelInfoFree(modelInfo);
return ret;
-
- error:
- qemuMonitorCPUModelInfoFree(*modelInfo);
- *modelInfo = NULL;
- goto cleanup;
}
struct tpmTypeToCaps {
@@ -3274,21 +3279,19 @@ virQEMUCapsInitCPUModel(virQEMUCapsPtr qemuCaps,
virCPUDefPtr cpu,
bool migratable)
{
- qemuMonitorCPUModelInfoPtr model;
+ virQEMUCapsHostCPUDataPtr cpuData = virQEMUCapsGetHostCPUData(qemuCaps, type);
int ret = 1;
- if (type == VIR_DOMAIN_VIRT_KVM)
- model = qemuCaps->kvmCPUModelInfo;
- else
- model = qemuCaps->tcgCPUModelInfo;
-
- if (migratable && model && !model->migratability)
+ if (migratable && cpuData->info && !cpuData->info->migratability)
return 1;
- if (ARCH_IS_S390(qemuCaps->arch))
- ret = virQEMUCapsInitCPUModelS390(qemuCaps, model, cpu, migratable);
- else if (ARCH_IS_X86(qemuCaps->arch))
- ret = virQEMUCapsInitCPUModelX86(qemuCaps, type, model, cpu, migratable);
+ if (ARCH_IS_S390(qemuCaps->arch)) {
+ ret = virQEMUCapsInitCPUModelS390(qemuCaps, cpuData->info,
+ cpu, migratable);
+ } else if (ARCH_IS_X86(qemuCaps->arch)) {
+ ret = virQEMUCapsInitCPUModelX86(qemuCaps, type, cpuData->info,
+ cpu, migratable);
+ }
if (ret == 0)
cpu->fallback = VIR_CPU_FALLBACK_FORBID;
@@ -3348,10 +3351,9 @@ virQEMUCapsSetCPUModelInfo(virQEMUCapsPtr qemuCaps,
virDomainVirtType type,
qemuMonitorCPUModelInfoPtr modelInfo)
{
- if (type == VIR_DOMAIN_VIRT_KVM)
- qemuCaps->kvmCPUModelInfo = modelInfo;
- else
- qemuCaps->tcgCPUModelInfo = modelInfo;
+ virQEMUCapsHostCPUDataPtr cpuData = virQEMUCapsGetHostCPUData(qemuCaps, type);
+
+ cpuData->info = modelInfo;
}
@@ -3810,18 +3812,11 @@ virQEMUCapsFormatHostCPUModelInfo(virQEMUCapsPtr qemuCaps,
virBufferPtr buf,
virDomainVirtType type)
{
- qemuMonitorCPUModelInfoPtr model;
- const char *typeStr;
+ virQEMUCapsHostCPUDataPtr cpuData = virQEMUCapsGetHostCPUData(qemuCaps, type);
+ qemuMonitorCPUModelInfoPtr model = cpuData->info;
+ const char *typeStr = type == VIR_DOMAIN_VIRT_KVM ? "kvm" : "tcg";
size_t i;
- if (type == VIR_DOMAIN_VIRT_KVM) {
- typeStr = "kvm";
- model = qemuCaps->kvmCPUModelInfo;
- } else {
- typeStr = "tcg";
- model = qemuCaps->tcgCPUModelInfo;
- }
-
if (!model)
return;
@@ -4080,7 +4075,8 @@ virQEMUCapsReset(virQEMUCapsPtr qemuCaps)
VIR_FREE(qemuCaps->gicCapabilities);
qemuCaps->ngicCapabilities = 0;
- virQEMUCapsHostCPUDataClear(qemuCaps);
+ virQEMUCapsHostCPUDataClear(&qemuCaps->kvmCPU);
+ virQEMUCapsHostCPUDataClear(&qemuCaps->tcgCPU);
}
@@ -0,0 +1,119 @@
From: Jiri Denemark <jdenemar@redhat.com>
Date: Tue, 11 Apr 2017 11:14:30 +0200
Subject: [PATCH] qemu: Prepare qemuCaps for multiple host CPU defs
Soon we will need to store multiple host CPU definitions in
virQEMUCapsHostCPUData and qemuCaps users will want to request the one
they need. This patch introduces virQEMUCapsHostCPUType enum which will
be used for specifying the requested CPU definition.
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
(cherry picked from commit 1fe517c68df92eb7f379fa87cb0d29d566aad6f4)
---
src/qemu/qemu_capabilities.c | 16 ++++++++++++----
src/qemu/qemu_capabilities.h | 10 +++++++++-
src/qemu/qemu_command.c | 3 ++-
src/qemu/qemu_process.c | 6 ++++--
4 files changed, 27 insertions(+), 8 deletions(-)
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index bbb234538..a6324a398 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -2439,11 +2439,17 @@ virQEMUCapsGetHostCPUData(virQEMUCapsPtr qemuCaps,
virCPUDefPtr
virQEMUCapsGetHostModel(virQEMUCapsPtr qemuCaps,
- virDomainVirtType type)
+ virDomainVirtType type,
+ virQEMUCapsHostCPUType cpuType)
{
virQEMUCapsHostCPUDataPtr cpuData = virQEMUCapsGetHostCPUData(qemuCaps, type);
- return cpuData->reported;
+ switch (cpuType) {
+ case VIR_QEMU_CAPS_HOST_CPU_REPORTED:
+ return cpuData->reported;
+ }
+
+ return NULL;
}
@@ -2472,7 +2478,8 @@ virQEMUCapsIsCPUModeSupported(virQEMUCapsPtr qemuCaps,
virQEMUCapsGuestIsNative(caps->host.arch, qemuCaps->arch);
case VIR_CPU_MODE_HOST_MODEL:
- return !!virQEMUCapsGetHostModel(qemuCaps, type);
+ return !!virQEMUCapsGetHostModel(qemuCaps, type,
+ VIR_QEMU_CAPS_HOST_CPU_REPORTED);
case VIR_CPU_MODE_CUSTOM:
if (type == VIR_DOMAIN_VIRT_KVM)
@@ -5456,7 +5463,8 @@ virQEMUCapsFillDomainCPUCaps(virCapsPtr caps,
if (virQEMUCapsIsCPUModeSupported(qemuCaps, caps, domCaps->virttype,
VIR_CPU_MODE_HOST_MODEL)) {
- virCPUDefPtr cpu = virQEMUCapsGetHostModel(qemuCaps, domCaps->virttype);
+ virCPUDefPtr cpu = virQEMUCapsGetHostModel(qemuCaps, domCaps->virttype,
+ VIR_QEMU_CAPS_HOST_CPU_REPORTED);
domCaps->cpu.hostModel = virCPUDefCopy(cpu);
}
diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h
index d44682f2a..88e27855b 100644
--- a/src/qemu/qemu_capabilities.h
+++ b/src/qemu/qemu_capabilities.h
@@ -449,8 +449,16 @@ int virQEMUCapsGetCPUDefinitions(virQEMUCapsPtr qemuCaps,
virDomainVirtType type,
char ***names,
size_t *count);
+
+typedef enum {
+ /* Host CPU definition reported in domain capabilities. */
+ VIR_QEMU_CAPS_HOST_CPU_REPORTED,
+} virQEMUCapsHostCPUType;
+
virCPUDefPtr virQEMUCapsGetHostModel(virQEMUCapsPtr qemuCaps,
- virDomainVirtType type);
+ virDomainVirtType type,
+ virQEMUCapsHostCPUType cpuType);
+
bool virQEMUCapsIsCPUModeSupported(virQEMUCapsPtr qemuCaps,
virCapsPtr caps,
virDomainVirtType type,
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 3abfe7b55..311edd13e 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -6879,7 +6879,8 @@ qemuBuildCpuCommandLine(virCommandPtr cmd,
if (def->cpu->mode == VIR_CPU_MODE_CUSTOM)
cpuDef = def->cpu;
else if (def->cpu->mode == VIR_CPU_MODE_HOST_PASSTHROUGH)
- cpuDef = virQEMUCapsGetHostModel(qemuCaps, def->virtType);
+ cpuDef = virQEMUCapsGetHostModel(qemuCaps, def->virtType,
+ VIR_QEMU_CAPS_HOST_CPU_REPORTED);
if (cpuDef) {
int svm = virCPUCheckFeature(def->os.arch, cpuDef, "svm");
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 26a668d27..07a88a3a7 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -5299,12 +5299,14 @@ qemuProcessUpdateGuestCPU(virDomainDefPtr def,
if (def->cpu->check == VIR_CPU_CHECK_PARTIAL &&
virCPUCompare(caps->host.arch,
- virQEMUCapsGetHostModel(qemuCaps, def->virtType),
+ virQEMUCapsGetHostModel(qemuCaps, def->virtType,
+ VIR_QEMU_CAPS_HOST_CPU_REPORTED),
def->cpu, true) < 0)
return -1;
if (virCPUUpdate(def->os.arch, def->cpu,
- virQEMUCapsGetHostModel(qemuCaps, def->virtType)) < 0)
+ virQEMUCapsGetHostModel(qemuCaps, def->virtType,
+ VIR_QEMU_CAPS_HOST_CPU_REPORTED)) < 0)
goto cleanup;
if (virQEMUCapsGetCPUDefinitions(qemuCaps, def->virtType,
@@ -0,0 +1,210 @@
From: Jiri Denemark <jdenemar@redhat.com>
Date: Wed, 29 Mar 2017 15:31:17 +0200
Subject: [PATCH] qemu: Pass migratable host CPU model to virCPUUpdate
We already know from QEMU which CPU features will block migration. Let's
use this information to make a migratable copy of the host CPU model and
use it for updating guest CPU specification. This will allow us to drop
feature filtering from virCPUUpdate where it was just a hack.
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
(cherry picked from commit 56bd7edcb5dc878beffb80d4e6a9cfb812378ded)
---
src/qemu/qemu_capabilities.c | 57 +++++++++++++++++++++++++++++++++++++-------
src/qemu/qemu_capabilities.h | 2 ++
src/qemu/qemu_process.c | 2 +-
tests/cputest.c | 7 +++++-
4 files changed, 57 insertions(+), 11 deletions(-)
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index a6324a398..7fc577546 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -384,6 +384,8 @@ struct _virQEMUCapsHostCPUData {
qemuMonitorCPUModelInfoPtr info;
/* Host CPU definition reported in domain capabilities. */
virCPUDefPtr reported;
+ /* Migratable host CPU definition used for updating guest CPU. */
+ virCPUDefPtr migratable;
};
/*
@@ -2100,6 +2102,10 @@ virQEMUCapsHostCPUDataCopy(virQEMUCapsHostCPUDataPtr dst,
!(dst->reported = virCPUDefCopy(src->reported)))
return -1;
+ if (src->migratable &&
+ !(dst->migratable = virCPUDefCopy(src->migratable)))
+ return -1;
+
return 0;
}
@@ -2109,6 +2115,7 @@ virQEMUCapsHostCPUDataClear(virQEMUCapsHostCPUDataPtr cpuData)
{
qemuMonitorCPUModelInfoFree(cpuData->info);
virCPUDefFree(cpuData->reported);
+ virCPUDefFree(cpuData->migratable);
memset(cpuData, 0, sizeof(*cpuData));
}
@@ -2447,6 +2454,9 @@ virQEMUCapsGetHostModel(virQEMUCapsPtr qemuCaps,
switch (cpuType) {
case VIR_QEMU_CAPS_HOST_CPU_REPORTED:
return cpuData->reported;
+
+ case VIR_QEMU_CAPS_HOST_CPU_MIGRATABLE:
+ return cpuData->migratable;
}
return NULL;
@@ -2456,11 +2466,13 @@ virQEMUCapsGetHostModel(virQEMUCapsPtr qemuCaps,
static void
virQEMUCapsSetHostModel(virQEMUCapsPtr qemuCaps,
virDomainVirtType type,
- virCPUDefPtr cpu)
+ virCPUDefPtr reported,
+ virCPUDefPtr migratable)
{
virQEMUCapsHostCPUDataPtr cpuData = virQEMUCapsGetHostCPUData(qemuCaps, type);
- cpuData->reported = cpu;
+ cpuData->reported = reported;
+ cpuData->migratable = migratable;
}
@@ -3307,26 +3319,39 @@ virQEMUCapsInitCPUModel(virQEMUCapsPtr qemuCaps,
}
+static virCPUDefPtr
+virQEMUCapsNewHostCPUModel(void)
+{
+ virCPUDefPtr cpu;
+
+ if (VIR_ALLOC(cpu) < 0)
+ return NULL;
+
+ cpu->type = VIR_CPU_TYPE_GUEST;
+ cpu->mode = VIR_CPU_MODE_CUSTOM;
+ cpu->match = VIR_CPU_MATCH_EXACT;
+ cpu->fallback = VIR_CPU_FALLBACK_ALLOW;
+
+ return cpu;
+}
+
+
void
virQEMUCapsInitHostCPUModel(virQEMUCapsPtr qemuCaps,
virCapsPtr caps,
virDomainVirtType type)
{
virCPUDefPtr cpu = NULL;
+ virCPUDefPtr migCPU = NULL;
virCPUDefPtr hostCPU = NULL;
int rc;
if (!caps || !virQEMUCapsGuestIsNative(caps->host.arch, qemuCaps->arch))
return;
- if (VIR_ALLOC(cpu) < 0)
+ if (!(cpu = virQEMUCapsNewHostCPUModel()))
goto error;
- cpu->type = VIR_CPU_TYPE_GUEST;
- cpu->mode = VIR_CPU_MODE_CUSTOM;
- cpu->match = VIR_CPU_MATCH_EXACT;
- cpu->fallback = VIR_CPU_FALLBACK_ALLOW;
-
if ((rc = virQEMUCapsInitCPUModel(qemuCaps, type, cpu, false)) < 0) {
goto error;
} else if (rc == 1) {
@@ -3340,7 +3365,20 @@ virQEMUCapsInitHostCPUModel(virQEMUCapsPtr qemuCaps,
goto error;
}
- virQEMUCapsSetHostModel(qemuCaps, type, cpu);
+ if (!(migCPU = virQEMUCapsNewHostCPUModel()))
+ goto error;
+
+ if ((rc = virQEMUCapsInitCPUModel(qemuCaps, type, migCPU, true)) < 0) {
+ goto error;
+ } else if (rc == 1) {
+ VIR_DEBUG("CPU migratability not provided by QEMU");
+
+ virCPUDefFree(migCPU);
+ if (!(migCPU = virCPUCopyMigratable(qemuCaps->arch, cpu)))
+ goto error;
+ }
+
+ virQEMUCapsSetHostModel(qemuCaps, type, cpu, migCPU);
cleanup:
virCPUDefFree(hostCPU);
@@ -3348,6 +3386,7 @@ virQEMUCapsInitHostCPUModel(virQEMUCapsPtr qemuCaps,
error:
virCPUDefFree(cpu);
+ virCPUDefFree(migCPU);
virResetLastError();
goto cleanup;
}
diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h
index 88e27855b..31818c940 100644
--- a/src/qemu/qemu_capabilities.h
+++ b/src/qemu/qemu_capabilities.h
@@ -453,6 +453,8 @@ int virQEMUCapsGetCPUDefinitions(virQEMUCapsPtr qemuCaps,
typedef enum {
/* Host CPU definition reported in domain capabilities. */
VIR_QEMU_CAPS_HOST_CPU_REPORTED,
+ /* Migratable host CPU definition used for updating guest CPU. */
+ VIR_QEMU_CAPS_HOST_CPU_MIGRATABLE,
} virQEMUCapsHostCPUType;
virCPUDefPtr virQEMUCapsGetHostModel(virQEMUCapsPtr qemuCaps,
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 07a88a3a7..e67736638 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -5306,7 +5306,7 @@ qemuProcessUpdateGuestCPU(virDomainDefPtr def,
if (virCPUUpdate(def->os.arch, def->cpu,
virQEMUCapsGetHostModel(qemuCaps, def->virtType,
- VIR_QEMU_CAPS_HOST_CPU_REPORTED)) < 0)
+ VIR_QEMU_CAPS_HOST_CPU_MIGRATABLE)) < 0)
goto cleanup;
if (virQEMUCapsGetCPUDefinitions(qemuCaps, def->virtType,
diff --git a/tests/cputest.c b/tests/cputest.c
index 8c07cf4f6..efa891dc1 100644
--- a/tests/cputest.c
+++ b/tests/cputest.c
@@ -393,6 +393,7 @@ cpuTestUpdate(const void *arg)
const struct data *data = arg;
int ret = -1;
virCPUDefPtr host = NULL;
+ virCPUDefPtr migHost = NULL;
virCPUDefPtr cpu = NULL;
char *result = NULL;
@@ -400,7 +401,10 @@ cpuTestUpdate(const void *arg)
!(cpu = cpuTestLoadXML(data->arch, data->name)))
goto cleanup;
- if (virCPUUpdate(host->arch, cpu, host) < 0)
+ if (!(migHost = virCPUCopyMigratable(data->arch, host)))
+ goto cleanup;
+
+ if (virCPUUpdate(host->arch, cpu, migHost) < 0)
goto cleanup;
if (virAsprintf(&result, "%s+%s", data->host, data->name) < 0)
@@ -411,6 +415,7 @@ cpuTestUpdate(const void *arg)
cleanup:
virCPUDefFree(host);
virCPUDefFree(cpu);
+ virCPUDefFree(migHost);
VIR_FREE(result);
return ret;
}
@@ -0,0 +1,49 @@
From: Jiri Denemark <jdenemar@redhat.com>
Date: Wed, 29 Mar 2017 15:00:21 +0200
Subject: [PATCH] cpu: Drop feature filtering from virCPUUpdate
Because of the changes done in the previous commit, @host is already a
migratable CPU and there's no need to do any additional filtering.
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
(cherry picked from commit 232d87c7dd081d126a079fb45178e0be096cc680)
---
src/cpu/cpu_x86.c | 9 +++------
1 file changed, 3 insertions(+), 6 deletions(-)
diff --git a/src/cpu/cpu_x86.c b/src/cpu/cpu_x86.c
index a771b251e..53359ff9b 100644
--- a/src/cpu/cpu_x86.c
+++ b/src/cpu/cpu_x86.c
@@ -2549,8 +2549,7 @@ x86Baseline(virCPUDefPtr *cpus,
static int
x86UpdateHostModel(virCPUDefPtr guest,
- const virCPUDef *host,
- virCPUx86MapPtr map)
+ const virCPUDef *host)
{
virCPUDefPtr updated = NULL;
size_t i;
@@ -2559,11 +2558,9 @@ x86UpdateHostModel(virCPUDefPtr guest,
if (!(updated = virCPUDefCopyWithoutModel(host)))
goto cleanup;
- /* Remove non-migratable features by default */
updated->type = VIR_CPU_TYPE_GUEST;
updated->mode = VIR_CPU_MODE_CUSTOM;
- if (virCPUDefCopyModelFilter(updated, host, true,
- x86FeatureIsMigratable, map) < 0)
+ if (virCPUDefCopyModel(updated, host, true) < 0)
goto cleanup;
if (guest->vendor_id) {
@@ -2627,7 +2624,7 @@ virCPUx86Update(virCPUDefPtr guest,
if (guest->mode == VIR_CPU_MODE_HOST_MODEL ||
guest->match == VIR_CPU_MATCH_MINIMUM)
- ret = x86UpdateHostModel(guest, host, map);
+ ret = x86UpdateHostModel(guest, host);
else
ret = 0;
@@ -0,0 +1,74 @@
From: Jiri Denemark <jdenemar@redhat.com>
Date: Tue, 11 Apr 2017 20:45:07 +0200
Subject: [PATCH] cpu: Introduce virCPUGetHostIsSupported
Sometimes we want to call virCPUGetHost only when it is implemented for
a given architecture to avoid logging expected and possibly misleading
errors. The new virCPUGetHostIsSupported API may be used to guard such
calls to virCPUGetHost.
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
(cherry picked from commit bf1a881715c905c67f7d38dcd5bd6c2afbff1f9b)
---
src/cpu/cpu.c | 20 ++++++++++++++++++++
src/cpu/cpu.h | 3 +++
src/libvirt_private.syms | 1 +
3 files changed, 24 insertions(+)
diff --git a/src/cpu/cpu.c b/src/cpu/cpu.c
index 8a407ac18..702b14dbb 100644
--- a/src/cpu/cpu.c
+++ b/src/cpu/cpu.c
@@ -357,6 +357,26 @@ virCPUDataFree(virCPUDataPtr data)
}
+/**
+ * virCPUGetHostIsSupported:
+ *
+ * @arch: CPU architecture
+ *
+ * Check whether virCPUGetHost is supported for @arch.
+ *
+ * Returns true if virCPUGetHost is supported, false otherwise.
+ */
+bool
+virCPUGetHostIsSupported(virArch arch)
+{
+ struct cpuArchDriver *driver;
+
+ VIR_DEBUG("arch=%s", virArchToString(arch));
+
+ return (driver = cpuGetSubDriver(arch)) && driver->getHost;
+}
+
+
/**
* virCPUGetHost:
*
diff --git a/src/cpu/cpu.h b/src/cpu/cpu.h
index 352445c40..c6ca111e9 100644
--- a/src/cpu/cpu.h
+++ b/src/cpu/cpu.h
@@ -183,6 +183,9 @@ virCPUDataNew(virArch arch);
void
virCPUDataFree(virCPUDataPtr data);
+bool
+virCPUGetHostIsSupported(virArch arch);
+
virCPUDefPtr
virCPUGetHost(virArch arch,
virCPUType type,
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index dc6db3b28..2d8a9ddec 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -1024,6 +1024,7 @@ virCPUDataNew;
virCPUDataParse;
virCPUExpandFeatures;
virCPUGetHost;
+virCPUGetHostIsSupported;
virCPUGetModels;
virCPUProbeHost;
virCPUTranslate;
@@ -0,0 +1,164 @@
From: Jiri Denemark <jdenemar@redhat.com>
Date: Tue, 11 Apr 2017 20:46:05 +0200
Subject: [PATCH] qemu: Use more data for comparing CPUs
With QEMU older than 2.9.0 libvirt uses CPUID instruction to determine
what CPU features are supported on the host. This was later used when
checking compatibility of guest CPUs. Since QEMU 2.9.0 we ask QEMU for
the host CPU data. But the two methods we use usually provide disjoint
sets of CPU features because QEMU/KVM does not support all features
provided by the host CPU and on the other hand it can enable some
feature even if the host CPU does not support them.
So if there is a domain which requires a CPU features disabled by
QEMU/KVM, libvirt will refuse to start it with QEMU > 2.9.0 as its guest
CPU is incompatible with the host CPU data we got from QEMU. But such
domain would happily start on older QEMU (of course, the features would
be missing the guest CPU). To fix this regression, we need to combine
both CPU feature sets when checking guest CPU compatibility.
https://bugzilla.redhat.com/show_bug.cgi?id=1439933
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
(cherry picked from commit 5b4a6adb5ca24a6cb91cdc55c31506fb278d3a91)
---
src/qemu/qemu_capabilities.c | 35 +++++++++++++++++++++++++++++++++--
src/qemu/qemu_capabilities.h | 4 ++++
src/qemu/qemu_process.c | 2 +-
3 files changed, 38 insertions(+), 3 deletions(-)
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index 7fc577546..01bd4750c 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -386,6 +386,10 @@ struct _virQEMUCapsHostCPUData {
virCPUDefPtr reported;
/* Migratable host CPU definition used for updating guest CPU. */
virCPUDefPtr migratable;
+ /* CPU definition with features detected by libvirt using virCPUGetHost
+ * combined with features reported by QEMU. This is used for backward
+ * compatible comparison between a guest CPU and a host CPU. */
+ virCPUDefPtr full;
};
/*
@@ -2106,6 +2110,10 @@ virQEMUCapsHostCPUDataCopy(virQEMUCapsHostCPUDataPtr dst,
!(dst->migratable = virCPUDefCopy(src->migratable)))
return -1;
+ if (src->full &&
+ !(dst->full = virCPUDefCopy(src->full)))
+ return -1;
+
return 0;
}
@@ -2116,6 +2124,7 @@ virQEMUCapsHostCPUDataClear(virQEMUCapsHostCPUDataPtr cpuData)
qemuMonitorCPUModelInfoFree(cpuData->info);
virCPUDefFree(cpuData->reported);
virCPUDefFree(cpuData->migratable);
+ virCPUDefFree(cpuData->full);
memset(cpuData, 0, sizeof(*cpuData));
}
@@ -2457,6 +2466,11 @@ virQEMUCapsGetHostModel(virQEMUCapsPtr qemuCaps,
case VIR_QEMU_CAPS_HOST_CPU_MIGRATABLE:
return cpuData->migratable;
+
+ case VIR_QEMU_CAPS_HOST_CPU_FULL:
+ /* 'full' is non-NULL only if we have data from both QEMU and
+ * virCPUGetHost */
+ return cpuData->full ? cpuData->full : cpuData->reported;
}
return NULL;
@@ -2467,12 +2481,14 @@ static void
virQEMUCapsSetHostModel(virQEMUCapsPtr qemuCaps,
virDomainVirtType type,
virCPUDefPtr reported,
- virCPUDefPtr migratable)
+ virCPUDefPtr migratable,
+ virCPUDefPtr full)
{
virQEMUCapsHostCPUDataPtr cpuData = virQEMUCapsGetHostCPUData(qemuCaps, type);
cpuData->reported = reported;
cpuData->migratable = migratable;
+ cpuData->full = full;
}
@@ -3344,6 +3360,8 @@ virQEMUCapsInitHostCPUModel(virQEMUCapsPtr qemuCaps,
virCPUDefPtr cpu = NULL;
virCPUDefPtr migCPU = NULL;
virCPUDefPtr hostCPU = NULL;
+ virCPUDefPtr fullCPU = NULL;
+ size_t i;
int rc;
if (!caps || !virQEMUCapsGuestIsNative(caps->host.arch, qemuCaps->arch))
@@ -3363,6 +3381,18 @@ virQEMUCapsInitHostCPUModel(virQEMUCapsPtr qemuCaps,
virQEMUCapsCPUFilterFeatures,
qemuCaps) < 0)
goto error;
+ } else if (type == VIR_DOMAIN_VIRT_KVM &&
+ virCPUGetHostIsSupported(qemuCaps->arch)) {
+ if (!(fullCPU = virCPUGetHost(qemuCaps->arch, VIR_CPU_TYPE_GUEST,
+ NULL, NULL, 0)))
+ goto error;
+
+ for (i = 0; i < cpu->nfeatures; i++) {
+ if (cpu->features[i].policy == VIR_CPU_FEATURE_REQUIRE &&
+ virCPUDefUpdateFeature(fullCPU, cpu->features[i].name,
+ VIR_CPU_FEATURE_REQUIRE) < 0)
+ goto error;
+ }
}
if (!(migCPU = virQEMUCapsNewHostCPUModel()))
@@ -3378,7 +3408,7 @@ virQEMUCapsInitHostCPUModel(virQEMUCapsPtr qemuCaps,
goto error;
}
- virQEMUCapsSetHostModel(qemuCaps, type, cpu, migCPU);
+ virQEMUCapsSetHostModel(qemuCaps, type, cpu, migCPU, fullCPU);
cleanup:
virCPUDefFree(hostCPU);
@@ -3387,6 +3417,7 @@ virQEMUCapsInitHostCPUModel(virQEMUCapsPtr qemuCaps,
error:
virCPUDefFree(cpu);
virCPUDefFree(migCPU);
+ virCPUDefFree(fullCPU);
virResetLastError();
goto cleanup;
}
diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h
index 31818c940..4e9561c0a 100644
--- a/src/qemu/qemu_capabilities.h
+++ b/src/qemu/qemu_capabilities.h
@@ -455,6 +455,10 @@ typedef enum {
VIR_QEMU_CAPS_HOST_CPU_REPORTED,
/* Migratable host CPU definition used for updating guest CPU. */
VIR_QEMU_CAPS_HOST_CPU_MIGRATABLE,
+ /* CPU definition with features detected by libvirt using virCPUGetHost
+ * combined with features reported by QEMU. This is used for backward
+ * compatible comparison between a guest CPU and a host CPU. */
+ VIR_QEMU_CAPS_HOST_CPU_FULL,
} virQEMUCapsHostCPUType;
virCPUDefPtr virQEMUCapsGetHostModel(virQEMUCapsPtr qemuCaps,
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index e67736638..992a7174b 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -5300,7 +5300,7 @@ qemuProcessUpdateGuestCPU(virDomainDefPtr def,
if (def->cpu->check == VIR_CPU_CHECK_PARTIAL &&
virCPUCompare(caps->host.arch,
virQEMUCapsGetHostModel(qemuCaps, def->virtType,
- VIR_QEMU_CAPS_HOST_CPU_REPORTED),
+ VIR_QEMU_CAPS_HOST_CPU_FULL),
def->cpu, true) < 0)
return -1;
@@ -0,0 +1,123 @@
From: Neal Gompa <ngompa13@gmail.com>
Date: Mon, 17 Jul 2017 11:32:46 -0400
Subject: [PATCH] spec: Add support for building the zfs storage driver
Where it can be supported in Fedora, the driver is built and made
available as a subpackage.
Signed-off-by: Neal Gompa <ngompa13@gmail.com>
(cherry picked from commit 9af764e86aef7dfb0191a9561bf1d1abf941da05)
---
libvirt.spec.in | 50 +++++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 49 insertions(+), 1 deletion(-)
diff --git a/libvirt.spec.in b/libvirt.spec.in
index 079b5f386..46a3e97d1 100644
--- a/libvirt.spec.in
+++ b/libvirt.spec.in
@@ -71,6 +71,13 @@
%define with_storage_gluster 0%{!?_without_storage_gluster:1}
%define with_numactl 0%{!?_without_numactl:1}
+# F25+ has zfs-fuse
+%if 0%{?fedora} >= 25
+ %define with_storage_zfs 0%{!?_without_storage_zfs:1}
+%else
+ %define with_storage_zfs 0
+%endif
+
# A few optional bits off by default, we enable later
%define with_fuse 0%{!?_without_fuse:0}
%define with_cgconfig 0%{!?_without_cgconfig:0}
@@ -115,6 +122,12 @@
%endif
%endif
+# zfs-fuse is not available on some architectures
+%ifarch s390 s390x aarch64
+ %define with_storage_zfs 0
+%endif
+
+
# RHEL doesn't ship OpenVZ, VBox, UML, PowerHypervisor,
# VMware, libxenserver (xenapi), libxenlight (Xen 4.1 and newer),
# or HyperV.
@@ -373,6 +386,12 @@ BuildRequires: glusterfs-devel >= 3.4.1
%if %{with_storage_sheepdog}
BuildRequires: sheepdog
%endif
+%if %{with_storage_zfs}
+# Support any conforming implementation of zfs. On stock Fedora
+# this is zfs-fuse, but could be zfsonlinux upstream RPMs
+BuildRequires: /sbin/zfs
+BuildRequires: /sbin/zpool
+%endif
%if %{with_numactl}
# For QEMU/LXC numa info
BuildRequires: numactl-devel
@@ -705,6 +724,21 @@ sheepdog volumes using.
%endif
+%if %{with_storage_zfs}
+%package daemon-driver-storage-zfs
+Summary: Storage driver plugin for ZFS
+Group: Development/Libraries
+Requires: libvirt-daemon-driver-storage-core = %{version}-%{release}
+# Support any conforming implementation of zfs
+Requires: /sbin/zfs
+Requires: /sbin/zpool
+
+%description daemon-driver-storage-zfs
+The storage driver backend adding implementation of the storage APIs for
+ZFS volumes.
+%endif
+
+
%package daemon-driver-storage
Summary: Storage driver plugin including all backends for the libvirtd daemon
Group: Development/Libraries
@@ -723,6 +757,9 @@ Requires: libvirt-daemon-driver-storage-rbd = %{version}-%{release}
%if %{with_storage_sheepdog}
Requires: libvirt-daemon-driver-storage-sheepdog = %{version}-%{release}
%endif
+%if %{with_storage_zfs}
+Requires: libvirt-daemon-driver-storage-zfs = %{version}-%{release}
+%endif
%description daemon-driver-storage
The storage driver plugin for the libvirtd daemon, providing
@@ -1180,6 +1217,12 @@ rm -rf .git
%define arg_storage_gluster --without-storage-gluster
%endif
+%if %{with_storage_zfs}
+ %define arg_storage_zfs --with-storage-zfs
+%else
+ %define arg_storage_zfs --without-storage-zfs
+%endif
+
%if %{with_numactl}
%define arg_numactl --with-numactl
%else
@@ -1288,7 +1331,7 @@ rm -f po/stamp-po
%{?arg_storage_rbd} \
%{?arg_storage_sheepdog} \
%{?arg_storage_gluster} \
- --without-storage-zfs \
+ %{?arg_storage_zfs} \
--without-storage-vstorage \
%{?arg_numactl} \
%{?arg_numad} \
@@ -1850,6 +1893,11 @@ exit 0
%{_libdir}/%{name}/storage-backend/libvirt_storage_backend_sheepdog.so
%endif
+%if %{with_storage_zfs}
+%files daemon-driver-storage-zfs
+%{_libdir}/%{name}/storage-backend/libvirt_storage_backend_zfs.so
+%endif
+
%if %{with_qemu}
%files daemon-driver-qemu
%dir %attr(0700, root, root) %{_sysconfdir}/libvirt/qemu/
+150
View File
@@ -0,0 +1,150 @@
From: Juan Hernandez <jhernand@redhat.com>
Date: Thu, 6 Jul 2017 17:03:31 +0200
Subject: [PATCH] Avoid hidden cgroup mount points
Currently the scan of the /proc/mounts file used to find cgroup mount
points doesn't take into account that mount points may hidden by other
mount points. For, example in certain Kubernetes environments the
/proc/mounts contains the following lines:
cgroup /sys/fs/cgroup/net_prio,net_cls cgroup ...
tmpfs /sys/fs/cgroup tmpfs ...
cgroup /sys/fs/cgroup/net_cls,net_prio cgroup ...
In this particular environment the first mount point is hidden by the
second one. The correct mount point is the third one, but libvirt will
never process it because it only checks the first mount point for each
controller (net_cls in this case). So libvirt will try to use the first
mount point, which doesn't actually exist, and the complete detection
process will fail.
To avoid that issue this patch changes the virCgroupDetectMountsFromFile
function so that when there are duplicates it takes the information from
the last line in /proc/mounts. This requires removing the previous
explicit condition to skip duplicates, and adding code to free the
memory used by the processing of duplicated lines.
Related-To: https://bugzilla.redhat.com/1468214
Related-To: https://github.com/kubevirt/libvirt/issues/4
Signed-off-by: Juan Hernandez <jhernand@redhat.com>
(cherry picked from commit dacd160d7479e0ec2d8a63f102145fd30636a1c8)
---
src/util/vircgroup.c | 23 ++++++++++++++---------
tests/vircgroupdata/kubevirt.mounts | 25 +++++++++++++++++++++++++
tests/vircgroupdata/kubevirt.parsed | 10 ++++++++++
tests/vircgrouptest.c | 1 +
4 files changed, 50 insertions(+), 9 deletions(-)
create mode 100644 tests/vircgroupdata/kubevirt.mounts
create mode 100644 tests/vircgroupdata/kubevirt.parsed
diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c
index 5aa1db5b1..a53908fc9 100644
--- a/src/util/vircgroup.c
+++ b/src/util/vircgroup.c
@@ -397,6 +397,7 @@ virCgroupDetectMountsFromFile(virCgroupPtr group,
const char *typestr = virCgroupControllerTypeToString(i);
int typelen = strlen(typestr);
char *tmp = entry.mnt_opts;
+ struct virCgroupController *controller = &group->controllers[i];
while (tmp) {
char *next = strchr(tmp, ',');
int len;
@@ -406,18 +407,22 @@ virCgroupDetectMountsFromFile(virCgroupPtr group,
} else {
len = strlen(tmp);
}
- /* NB, the same controller can appear >1 time in mount list
- * due to bind mounts from one location to another. Pick the
- * first entry only
- */
- if (typelen == len && STREQLEN(typestr, tmp, len) &&
- !group->controllers[i].mountPoint) {
+
+ if (typelen == len && STREQLEN(typestr, tmp, len)) {
char *linksrc;
struct stat sb;
char *tmp2;
- if (VIR_STRDUP(group->controllers[i].mountPoint,
- entry.mnt_dir) < 0)
+ /* Note that the lines in /proc/mounts have the same
+ * order than the mount operations, and that there may
+ * be duplicates due to bind mounts. This means
+ * that the same mount point may be processed more than
+ * once. We need to save the results of the last one,
+ * and we need to be careful to release the memory used
+ * by previous processing. */
+ VIR_FREE(controller->mountPoint);
+ VIR_FREE(controller->linkPoint);
+ if (VIR_STRDUP(controller->mountPoint, entry.mnt_dir) < 0)
goto error;
tmp2 = strrchr(entry.mnt_dir, '/');
@@ -453,7 +458,7 @@ virCgroupDetectMountsFromFile(virCgroupPtr group,
VIR_WARN("Expecting a symlink at %s for controller %s",
linksrc, typestr);
} else {
- group->controllers[i].linkPoint = linksrc;
+ controller->linkPoint = linksrc;
}
}
}
diff --git a/tests/vircgroupdata/kubevirt.mounts b/tests/vircgroupdata/kubevirt.mounts
new file mode 100644
index 000000000..ca036196b
--- /dev/null
+++ b/tests/vircgroupdata/kubevirt.mounts
@@ -0,0 +1,25 @@
+rootfs / rootfs rw 0 0
+proc /proc proc rw,nosuid,nodev,noexec,relatime 0 0
+udev /dev devtmpfs rw,nosuid,relatime,size=10240k,nr_inodes=1006404,mode=755 0 0
+devpts /dev/pts devpts rw,relatime,gid=5,mode=620,ptmxmode=000 0 0
+sysfs /sys sysfs rw,nosuid,nodev,noexec,relatime 0 0
+/dev/sda1 / ext4 rw,noatime,data=ordered 0 0
+tmpfs /run tmpfs rw,nodev,relatime,size=812296k,mode=755 0 0
+mqueue /dev/mqueue mqueue rw,nosuid,nodev,noexec,relatime 0 0
+shm /dev/shm tmpfs rw,nosuid,nodev,noexec,relatime 0 0
+debugfs /sys/kernel/debug debugfs rw,nosuid,nodev,noexec,relatime 0 0
+cgroup_root /sys/fs/cgroup tmpfs rw,nosuid,nodev,noexec,relatime,size=10240k,mode=755 0 0
+openrc /sys/fs/cgroup/openrc cgroup rw,nosuid,nodev,noexec,relatime,release_agent=/lib64/rc/sh/cgroup-release-agent.sh,name=openrc 0 0
+cpuset /some/random/location/cpuset cgroup rw,nosuid,nodev,noexec,relatime,cpuset 0 0
+cpuset /sys/fs/cgroup/cpuset cgroup rw,nosuid,nodev,noexec,relatime,cpuset 0 0
+cpu /sys/fs/cgroup/cpu cgroup rw,nosuid,nodev,noexec,relatime,cpu 0 0
+cpuacct /some/random/location/cpuset cgroup rw,nosuid,nodev,noexec,relatime,cpuacct 0 0
+cpuacct /sys/fs/cgroup/cpuacct cgroup rw,nosuid,nodev,noexec,relatime,cpuacct 0 0
+memory /sys/fs/cgroup/memory cgroup rw,nosuid,nodev,noexec,relatime,memory 0 0
+devices /sys/fs/cgroup/devices cgroup rw,nosuid,nodev,noexec,relatime,devices 0 0
+freezer /sys/fs/cgroup/freezer cgroup rw,nosuid,nodev,noexec,relatime,freezer 0 0
+blkio /sys/fs/cgroup/blkio cgroup rw,nosuid,nodev,noexec,relatime,blkio 0 0
+perf_event /sys/fs/cgroup/perf_event cgroup rw,nosuid,nodev,noexec,relatime,perf_event 0 0
+hugetlb /sys/fs/cgroup/hugetlb cgroup rw,nosuid,nodev,noexec,relatime,hugetlb 0 0
+binfmt_misc /proc/sys/fs/binfmt_misc binfmt_misc rw,nosuid,nodev,noexec,relatime 0 0
+freezer /some/random/location/freezer cgroup rw,nosuid,nodev,noexec,relatime,freezer 0 0
diff --git a/tests/vircgroupdata/kubevirt.parsed b/tests/vircgroupdata/kubevirt.parsed
new file mode 100644
index 000000000..694870723
--- /dev/null
+++ b/tests/vircgroupdata/kubevirt.parsed
@@ -0,0 +1,10 @@
+cpu /sys/fs/cgroup/cpu
+cpuacct /sys/fs/cgroup/cpuacct
+cpuset /sys/fs/cgroup/cpuset
+memory /sys/fs/cgroup/memory
+devices /sys/fs/cgroup/devices
+freezer /some/random/location/freezer
+blkio /sys/fs/cgroup/blkio
+net_cls <null>
+perf_event /sys/fs/cgroup/perf_event
+name=systemd <null>
diff --git a/tests/vircgrouptest.c b/tests/vircgrouptest.c
index f55ef74a1..cf0315f16 100644
--- a/tests/vircgrouptest.c
+++ b/tests/vircgrouptest.c
@@ -885,6 +885,7 @@ mymain(void)
DETECT_MOUNTS("cgroups3");
DETECT_MOUNTS("all-in-one");
DETECT_MOUNTS("no-cgroups");
+ DETECT_MOUNTS("kubevirt");
if (virTestRun("New cgroup for self", testCgroupNewForSelf, NULL) < 0)
ret = -1;
@@ -0,0 +1,53 @@
From: Jim Fehlig <jfehlig@suse.com>
Date: Tue, 18 Jul 2017 10:20:35 -0600
Subject: [PATCH] docs: schema: make disk driver name attribute optional
/domain/devices/disk/driver/@name is not a required or mandatory
attribute according to formatdomain, and indeed it was agreed on
IRC that the attribute is "optional for input, recommended (but
not required) for output". Currently the schema requires the
attribute, causing virt-xml-validate to fail on disk config where
the driver name is not explicitly specified. E.g.
# cat test.xml | grep -A 5 cdrom
<disk type='file' device='cdrom'>
<driver type='raw'/>
<target dev='hdb' bus='ide'/>
<readonly/>
<address type='drive' controller='0' bus='0' target='0' unit='1'/>
</disk>
# virt-xml-validate test.xml
Relax-NG validity error : Extra element devices in interleave
test.xml:21: element devices: Relax-NG validity error : Element domain failed to validate content
test.xml fails to validate
Relaxing the name attribute to be optional fixes the validation
# virt-xml-validate test.xml
test.xml validates
(cherry picked from commit b494e09d058f09b48d0fd8855edd557101294671)
---
docs/schemas/domaincommon.rng | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index edc225fe5..dfc7e2470 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -1720,9 +1720,11 @@
</element>
</define>
<define name="driverFormat">
- <attribute name="name">
- <ref name="genericName"/>
- </attribute>
+ <optional>
+ <attribute name="name">
+ <ref name="genericName"/>
+ </attribute>
+ </optional>
<optional>
<attribute name='type'>
<choice>
@@ -0,0 +1,34 @@
From: Stefan Berger <stefanb@linux.vnet.ibm.com>
Date: Thu, 29 Jun 2017 14:01:11 -0400
Subject: [PATCH] tpm: Use /dev/null for cancel path if none was found
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
TPM 2 does not implement sysfs files for cancellation of commands.
We therefore use /dev/null for the cancel path passed to QEMU.
Signed-off-by: Stefan Berger <stefanb@linux.vnet.ibm.com>
Tested-by: Javier Martinez Canillas <javierm@redhat.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
(cherry picked from commit dfbb15b75433e520fb1b905c1c3e28753e53e4a5)
---
src/util/virtpm.c | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/src/util/virtpm.c b/src/util/virtpm.c
index 6d9b0657a..d5c10da38 100644
--- a/src/util/virtpm.c
+++ b/src/util/virtpm.c
@@ -61,9 +61,7 @@ virTPMCreateCancelPath(const char *devpath)
VIR_FREE(path);
}
if (!path)
- virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
- _("No usable sysfs TPM cancel file could be "
- "found"));
+ ignore_value(VIR_STRDUP(path, "/dev/null"));
} else {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("TPM device path %s is invalid"), devpath);
@@ -0,0 +1,108 @@
From: Cole Robinson <crobinso@redhat.com>
Date: Sun, 27 Aug 2017 11:23:47 -0400
Subject: [PATCH] security: add MANAGER_MOUNT_NAMESPACE flag
The VIR_SECURITY_MANAGER_MOUNT_NAMESPACE flag informs the DAC driver
if mount namespaces are in use for the VM. Will be used for future
changes.
Wire it up in the qemu driver
(cherry picked from commit 321031e482425dfeae0f125cdac6df870f079efd)
---
src/qemu/qemu_driver.c | 2 ++
src/security/security_dac.c | 10 ++++++++++
src/security/security_dac.h | 3 +++
src/security/security_manager.c | 4 +++-
src/security/security_manager.h | 1 +
5 files changed, 19 insertions(+), 1 deletion(-)
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index ce844bb04..555a1009b 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -417,6 +417,8 @@ qemuSecurityInit(virQEMUDriverPtr driver)
if (virQEMUDriverIsPrivileged(driver)) {
if (cfg->dynamicOwnership)
flags |= VIR_SECURITY_MANAGER_DYNAMIC_OWNERSHIP;
+ if (virBitmapIsBitSet(cfg->namespaces, QEMU_DOMAIN_NS_MOUNT))
+ flags |= VIR_SECURITY_MANAGER_MOUNT_NAMESPACE;
if (!(mgr = qemuSecurityNewDAC(QEMU_DRIVER_NAME,
cfg->user,
cfg->group,
diff --git a/src/security/security_dac.c b/src/security/security_dac.c
index 922e48494..1f8d279bf 100644
--- a/src/security/security_dac.c
+++ b/src/security/security_dac.c
@@ -57,6 +57,7 @@ struct _virSecurityDACData {
gid_t *groups;
int ngroups;
bool dynamicOwnership;
+ bool mountNamespace;
char *baselabel;
virSecurityManagerDACChownCallback chownCallback;
};
@@ -237,6 +238,15 @@ virSecurityDACSetDynamicOwnership(virSecurityManagerPtr mgr,
priv->dynamicOwnership = dynamicOwnership;
}
+void
+virSecurityDACSetMountNamespace(virSecurityManagerPtr mgr,
+ bool mountNamespace)
+{
+ virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
+ priv->mountNamespace = mountNamespace;
+}
+
+
void
virSecurityDACSetChownCallback(virSecurityManagerPtr mgr,
virSecurityManagerDACChownCallback chownCallback)
diff --git a/src/security/security_dac.h b/src/security/security_dac.h
index 846cefbb5..97681c961 100644
--- a/src/security/security_dac.h
+++ b/src/security/security_dac.h
@@ -32,6 +32,9 @@ int virSecurityDACSetUserAndGroup(virSecurityManagerPtr mgr,
void virSecurityDACSetDynamicOwnership(virSecurityManagerPtr mgr,
bool dynamic);
+void virSecurityDACSetMountNamespace(virSecurityManagerPtr mgr,
+ bool mountNamespace);
+
void virSecurityDACSetChownCallback(virSecurityManagerPtr mgr,
virSecurityManagerDACChownCallback chownCallback);
diff --git a/src/security/security_manager.c b/src/security/security_manager.c
index 6c777db1e..b2d04d4b9 100644
--- a/src/security/security_manager.c
+++ b/src/security/security_manager.c
@@ -146,7 +146,8 @@ virSecurityManagerNewDAC(const char *virtDriver,
virSecurityManagerPtr mgr;
virCheckFlags(VIR_SECURITY_MANAGER_NEW_MASK |
- VIR_SECURITY_MANAGER_DYNAMIC_OWNERSHIP, NULL);
+ VIR_SECURITY_MANAGER_DYNAMIC_OWNERSHIP |
+ VIR_SECURITY_MANAGER_MOUNT_NAMESPACE, NULL);
mgr = virSecurityManagerNewDriver(&virSecurityDriverDAC,
virtDriver,
@@ -161,6 +162,7 @@ virSecurityManagerNewDAC(const char *virtDriver,
}
virSecurityDACSetDynamicOwnership(mgr, flags & VIR_SECURITY_MANAGER_DYNAMIC_OWNERSHIP);
+ virSecurityDACSetMountNamespace(mgr, flags & VIR_SECURITY_MANAGER_MOUNT_NAMESPACE);
virSecurityDACSetChownCallback(mgr, chownCallback);
return mgr;
diff --git a/src/security/security_manager.h b/src/security/security_manager.h
index 238e66cd0..96937a892 100644
--- a/src/security/security_manager.h
+++ b/src/security/security_manager.h
@@ -36,6 +36,7 @@ typedef enum {
VIR_SECURITY_MANAGER_REQUIRE_CONFINED = 1 << 2,
VIR_SECURITY_MANAGER_PRIVILEGED = 1 << 3,
VIR_SECURITY_MANAGER_DYNAMIC_OWNERSHIP = 1 << 4,
+ VIR_SECURITY_MANAGER_MOUNT_NAMESPACE = 1 << 5,
} virSecurityManagerNewFlags;
# define VIR_SECURITY_MANAGER_NEW_MASK \
@@ -0,0 +1,101 @@
From: Cole Robinson <crobinso@redhat.com>
Date: Mon, 17 Jul 2017 08:57:57 -0400
Subject: [PATCH] security: dac: relabel spice rendernode
For a logged in user this a path like /dev/dri/renderD128 will have
default ownership root:video which won't work for the qemu:qemu user,
so we need to chown it.
We only do this when mount namespaces are enabled in the qemu driver,
so the chown'ing doesn't interfere with other users of the shared
render node path
https://bugzilla.redhat.com/show_bug.cgi?id=1460804
(cherry picked from commit 98931187eefdec6f2dea5cb82ab6d23a3ffa6634)
---
src/security/security_dac.c | 58 +++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 58 insertions(+)
diff --git a/src/security/security_dac.c b/src/security/security_dac.c
index 1f8d279bf..5f13bcee8 100644
--- a/src/security/security_dac.c
+++ b/src/security/security_dac.c
@@ -1379,6 +1379,54 @@ virSecurityDACRestoreTPMFileLabel(virSecurityManagerPtr mgr,
}
+static int
+virSecurityDACSetGraphicsLabel(virSecurityManagerPtr mgr,
+ virDomainDefPtr def,
+ virDomainGraphicsDefPtr gfx)
+
+{
+ virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
+ virSecurityLabelDefPtr seclabel;
+ uid_t user;
+ gid_t group;
+
+ /* Skip chowning the shared render file if namespaces are disabled */
+ if (!priv->mountNamespace)
+ return 0;
+
+ seclabel = virDomainDefGetSecurityLabelDef(def, SECURITY_DAC_NAME);
+ if (seclabel && !seclabel->relabel)
+ return 0;
+
+ if (virSecurityDACGetIds(seclabel, priv, &user, &group, NULL, NULL) < 0)
+ return -1;
+
+ if (gfx->type == VIR_DOMAIN_GRAPHICS_TYPE_SPICE &&
+ gfx->data.spice.gl == VIR_TRISTATE_BOOL_YES &&
+ gfx->data.spice.rendernode) {
+ if (virSecurityDACSetOwnership(priv, NULL,
+ gfx->data.spice.rendernode,
+ user, group) < 0)
+ return -1;
+ }
+
+ return 0;
+}
+
+
+static int
+virSecurityDACRestoreGraphicsLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
+ virDomainDefPtr def ATTRIBUTE_UNUSED,
+ virDomainGraphicsDefPtr gfx ATTRIBUTE_UNUSED)
+
+{
+ /* The only graphics labelling we do is dependent on mountNamespaces,
+ in which case 'restoring' the label doesn't actually accomplish
+ anything, so there's nothing to do here */
+ return 0;
+}
+
+
static int
virSecurityDACSetInputLabel(virSecurityManagerPtr mgr,
virDomainDefPtr def,
@@ -1489,6 +1537,11 @@ virSecurityDACRestoreAllLabel(virSecurityManagerPtr mgr,
rc = -1;
}
+ for (i = 0; i < def->ngraphics; i++) {
+ if (virSecurityDACRestoreGraphicsLabel(mgr, def, def->graphics[i]) < 0)
+ return -1;
+ }
+
for (i = 0; i < def->ninputs; i++) {
if (virSecurityDACRestoreInputLabel(mgr, def, def->inputs[i]) < 0)
rc = -1;
@@ -1602,6 +1655,11 @@ virSecurityDACSetAllLabel(virSecurityManagerPtr mgr,
return -1;
}
+ for (i = 0; i < def->ngraphics; i++) {
+ if (virSecurityDACSetGraphicsLabel(mgr, def, def->graphics[i]) < 0)
+ return -1;
+ }
+
for (i = 0; i < def->ninputs; i++) {
if (virSecurityDACSetInputLabel(mgr, def, def->inputs[i]) < 0)
return -1;
+63
View File
@@ -0,0 +1,63 @@
From: Michal Privoznik <mprivozn@redhat.com>
Date: Mon, 31 Jul 2017 16:55:58 +0200
Subject: [PATCH] qemu: Honour <on_reboot/>
https://bugzilla.redhat.com/show_bug.cgi?id=1476866
For some reason, we completely ignore <on_reboot/> setting for
domains. The implementation is simply not there. It never was.
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
(cherry picked from commit 3ee9bdbe351c0b80d4c469571ef31df3f1b148ea)
---
src/qemu/qemu_process.c | 27 ++++++++++++++++++++++++---
1 file changed, 24 insertions(+), 3 deletions(-)
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 992a7174b..7588212ba 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -487,6 +487,7 @@ qemuProcessHandleReset(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
virObjectEventPtr event;
qemuDomainObjPrivatePtr priv;
virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
+ int ret = -1;
virObjectLock(vm);
@@ -498,12 +499,32 @@ qemuProcessHandleReset(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
if (virDomainSaveStatus(driver->xmlopt, cfg->stateDir, vm, driver->caps) < 0)
VIR_WARN("Failed to save status on vm %s", vm->def->name);
- virObjectUnlock(vm);
+ if (vm->def->onReboot == VIR_DOMAIN_LIFECYCLE_DESTROY ||
+ vm->def->onReboot == VIR_DOMAIN_LIFECYCLE_PRESERVE) {
- qemuDomainEventQueue(driver, event);
+ if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_MODIFY) < 0)
+ goto cleanup;
+
+ if (!virDomainObjIsActive(vm)) {
+ VIR_DEBUG("Ignoring RESET event from inactive domain %s",
+ vm->def->name);
+ goto endjob;
+ }
+
+ qemuProcessStop(driver, vm, VIR_DOMAIN_SHUTOFF_DESTROYED,
+ QEMU_ASYNC_JOB_NONE, 0);
+ virDomainAuditStop(vm, "destroyed");
+ qemuDomainRemoveInactive(driver, vm);
+ endjob:
+ qemuDomainObjEndJob(driver, vm);
+ }
+ ret = 0;
+ cleanup:
+ virObjectUnlock(vm);
+ qemuDomainEventQueue(driver, event);
virObjectUnref(cfg);
- return 0;
+ return ret;
}
@@ -0,0 +1,113 @@
From: Michal Privoznik <mprivozn@redhat.com>
Date: Thu, 27 Apr 2017 16:29:21 +0200
Subject: [PATCH] qemuDomainBuildNamespace: Move /dev/* mountpoints later
When setting up mount namespace for a qemu domain the following
steps are executed:
1) get list of mountpoints under /dev/
2) move them to /var/run/libvirt/qemu/$domName.ext
3) start constructing new device tree under /var/run/libvirt/qemu/$domName.dev
4) move the mountpoint of the new device tree to /dev
5) restore original mountpoints from step 2)
Note the problem with this approach is that if some device in step
3) requires access to a mountpoint from step 2) it will fail as
the mountpoint is not there anymore. For instance consider the
following domain disk configuration:
<disk type='file' device='disk'>
<driver name='qemu' type='raw'/>
<source file='/dev/shm/vhostmd0'/>
<target dev='vdb' bus='virtio'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x0a' function='0x0'/>
</disk>
In this case operation fails as we are unable to create vhostmd0
in the new device tree because after step 2) there is no /dev/shm
anymore. Leave aside fact that we shouldn't try to create devices
living in other mountpoints. That's a separate bug that will be
addressed later.
Currently, the order described above is rearranged to:
1) get list of mountpoints under /dev/
2) start constructing new device tree under /var/run/libvirt/qemu/$domName.dev
3) move them to /var/run/libvirt/qemu/$domName.ext
4) move the mountpoint of the new device tree to /dev
5) restore original mountpoints from step 3)
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Cedric Bosdonnat <cbosdonnat@suse.com>
(cherry picked from commit a7cc039dc796f541793955598377807af48341fb)
(cherry picked from commit 469bf7cb7a44a0798c63e4b5e4682d8e38bce66e)
---
src/qemu/qemu_domain.c | 48 ++++++++++++++++++++++++------------------------
1 file changed, 24 insertions(+), 24 deletions(-)
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index 4a127cedf..64f18f493 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -7854,6 +7854,30 @@ qemuDomainBuildNamespace(virQEMUDriverConfigPtr cfg,
if (qemuDomainSetupDev(cfg, mgr, vm, devPath) < 0)
goto cleanup;
+ if (qemuDomainSetupAllDisks(cfg, vm, devPath) < 0)
+ goto cleanup;
+
+ if (qemuDomainSetupAllHostdevs(cfg, vm, devPath) < 0)
+ goto cleanup;
+
+ if (qemuDomainSetupAllMemories(cfg, vm, devPath) < 0)
+ goto cleanup;
+
+ if (qemuDomainSetupAllChardevs(cfg, vm, devPath) < 0)
+ goto cleanup;
+
+ if (qemuDomainSetupTPM(cfg, vm, devPath) < 0)
+ goto cleanup;
+
+ if (qemuDomainSetupAllGraphics(cfg, vm, devPath) < 0)
+ goto cleanup;
+
+ if (qemuDomainSetupAllInputs(cfg, vm, devPath) < 0)
+ goto cleanup;
+
+ if (qemuDomainSetupAllRNGs(cfg, vm, devPath) < 0)
+ goto cleanup;
+
/* Save some mount points because we want to share them with the host */
for (i = 0; i < ndevMountsPath; i++) {
struct stat sb;
@@ -7881,30 +7905,6 @@ qemuDomainBuildNamespace(virQEMUDriverConfigPtr cfg,
goto cleanup;
}
- if (qemuDomainSetupAllDisks(cfg, vm, devPath) < 0)
- goto cleanup;
-
- if (qemuDomainSetupAllHostdevs(cfg, vm, devPath) < 0)
- goto cleanup;
-
- if (qemuDomainSetupAllMemories(cfg, vm, devPath) < 0)
- goto cleanup;
-
- if (qemuDomainSetupAllChardevs(cfg, vm, devPath) < 0)
- goto cleanup;
-
- if (qemuDomainSetupTPM(cfg, vm, devPath) < 0)
- goto cleanup;
-
- if (qemuDomainSetupAllGraphics(cfg, vm, devPath) < 0)
- goto cleanup;
-
- if (qemuDomainSetupAllInputs(cfg, vm, devPath) < 0)
- goto cleanup;
-
- if (qemuDomainSetupAllRNGs(cfg, vm, devPath) < 0)
- goto cleanup;
-
if (virFileMoveMount(devPath, "/dev") < 0)
goto cleanup;
@@ -0,0 +1,71 @@
From: "Daniel P. Berrange" <berrange@redhat.com>
Date: Thu, 5 Oct 2017 17:54:28 +0100
Subject: [PATCH] qemu: ensure TLS clients always verify the server certificate
The default_tls_x509_verify (and related) parameters in qemu.conf
control whether the QEMU TLS servers request & verify certificates
from clients. This works as a simple access control system for
servers by requiring the CA to issue certs to permitted clients.
This use of client certificates is disabled by default, since it
requires extra work to issue client certificates.
Unfortunately the code was using this configuration parameter when
setting up both TLS clients and servers in QEMU. The result was that
TLS clients for character devices and disk devices had verification
turned off, meaning they would ignore errors while validating the
server certificate.
This allows for trivial MITM attacks between client and server,
as any certificate returned by the attacker will be accepted by
the client.
This is assigned CVE-2017-1000256 / LSN-2017-0002
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
(cherry picked from commit 441d3eb6d1be940a67ce45a286602a967601b157)
---
src/qemu/qemu_command.c | 2 +-
tests/qemuxml2argvdata/qemuxml2argv-serial-tcp-tlsx509-chardev.args | 2 +-
.../qemuxml2argv-serial-tcp-tlsx509-secret-chardev.args | 2 +-
3 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 311edd13e..141831635 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -727,7 +727,7 @@ qemuBuildTLSx509BackendProps(const char *tlspath,
if (virJSONValueObjectCreate(propsret,
"s:dir", path,
"s:endpoint", (isListen ? "server": "client"),
- "b:verify-peer", verifypeer,
+ "b:verify-peer", (isListen ? verifypeer : true),
NULL) < 0)
goto cleanup;
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-serial-tcp-tlsx509-chardev.args b/tests/qemuxml2argvdata/qemuxml2argv-serial-tcp-tlsx509-chardev.args
index b456cce30..003d11de7 100644
--- a/tests/qemuxml2argvdata/qemuxml2argv-serial-tcp-tlsx509-chardev.args
+++ b/tests/qemuxml2argvdata/qemuxml2argv-serial-tcp-tlsx509-chardev.args
@@ -26,7 +26,7 @@ server,nowait \
localport=1111 \
-device isa-serial,chardev=charserial0,id=serial0 \
-object tls-creds-x509,id=objcharserial1_tls0,dir=/etc/pki/libvirt-chardev,\
-endpoint=client,verify-peer=no \
+endpoint=client,verify-peer=yes \
-chardev socket,id=charserial1,host=127.0.0.1,port=5555,\
tls-creds=objcharserial1_tls0 \
-device isa-serial,chardev=charserial1,id=serial1 \
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-serial-tcp-tlsx509-secret-chardev.args b/tests/qemuxml2argvdata/qemuxml2argv-serial-tcp-tlsx509-secret-chardev.args
index 7f9fedb6c..a020ff006 100644
--- a/tests/qemuxml2argvdata/qemuxml2argv-serial-tcp-tlsx509-secret-chardev.args
+++ b/tests/qemuxml2argvdata/qemuxml2argv-serial-tcp-tlsx509-secret-chardev.args
@@ -31,7 +31,7 @@ localport=1111 \
data=9eao5F8qtkGt+seB1HYivWIxbtwUu6MQtg1zpj/oDtUsPr1q8wBYM91uEHCn6j/1,\
keyid=masterKey0,iv=AAECAwQFBgcICQoLDA0ODw==,format=base64 \
-object tls-creds-x509,id=objcharserial1_tls0,dir=/etc/pki/libvirt-chardev,\
-endpoint=client,verify-peer=no,passwordid=charserial1-secret0 \
+endpoint=client,verify-peer=yes,passwordid=charserial1-secret0 \
-chardev socket,id=charserial1,host=127.0.0.1,port=5555,\
tls-creds=objcharserial1_tls0 \
-device isa-serial,chardev=charserial1,id=serial1 \
+21
View File
@@ -0,0 +1,21 @@
# Makefile for source rpm: libvirt
# $Id$
NAME := libvirt
SPECFILE = $(firstword $(wildcard *.spec))
define find-makefile-common
for d in common ../common ../../common ; do if [ -f $$d/Makefile.common ] ; then if [ -f $$d/CVS/Root -a -w $$d/Makefile.common ] ; then cd $$d ; cvs -Q update ; fi ; echo "$$d/Makefile.common" ; break ; fi ; done
endef
MAKEFILE_COMMON := $(shell $(find-makefile-common))
ifeq ($(MAKEFILE_COMMON),)
# attempt a checkout
define checkout-makefile-common
test -f CVS/Root && { cvs -Q -d $$(cat CVS/Root) checkout common && echo "common/Makefile.common" ; } || { echo "ERROR: I can't figure out how to checkout the 'common' module." ; exit -1 ; } >&2
endef
MAKEFILE_COMMON := $(shell $(checkout-makefile-common))
endif
include $(MAKEFILE_COMMON)
@@ -1,31 +0,0 @@
From c9056e682a8a67dc29e39eb01392fcf8ee978c31 Mon Sep 17 00:00:00 2001
From: Jonathan Wright <jonathan@almalinux.org>
Date: Wed, 3 Jan 2024 09:26:59 -0600
Subject: [PATCH] conf: Restore setting default bus for input devices
Prior to v9.3.0-rc1~30 we used to set default bus for <input/>
devices, during XML parsing. In the commit this code was moved to
a post parse callback. But somehow the line that sets the bus in
one specific case disappeared. Bring it back.
Resolves: https://gitlab.com/libvirt/libvirt/-/issues/577
Fixes: c4bc4d3b82fbe22e03c986ca896090f481df5c10
Signed-off-by: Jonathan Wright <jonathan@almalinux.org>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
---
src/conf/domain_postparse.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/conf/domain_postparse.c b/src/conf/domain_postparse.c
index e79913b73f..ee27023f3e 100644
--- a/src/conf/domain_postparse.c
+++ b/src/conf/domain_postparse.c
@@ -657,6 +657,7 @@ virDomainInputDefPostParse(virDomainInputDef *input,
if ((input->type == VIR_DOMAIN_INPUT_TYPE_MOUSE ||
input->type == VIR_DOMAIN_INPUT_TYPE_KBD) &&
(ARCH_IS_X86(def->os.arch) || def->os.arch == VIR_ARCH_NONE)) {
+ input->bus = VIR_DOMAIN_INPUT_BUS_PS2;
} else if (ARCH_IS_S390(def->os.arch) ||
input->type == VIR_DOMAIN_INPUT_TYPE_PASSTHROUGH) {
input->bus = VIR_DOMAIN_INPUT_BUS_VIRTIO;
--
+1213 -1535
View File
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -1 +1 @@
SHA512 (libvirt-9.7.0.tar.xz) = dd771822c0fa0861a32cab9d7f82235b101867fa0a4e8cf9a857ddfb2347e41b625b1e6f8791c4b3543fec836a1a23cae1fac4ce4b40debd51f2097bae46c949
SHA512 (libvirt-3.2.1.tar.xz) = 4ec4faceedcad3a5419e91444b0c83adcbed0ff6482fb53c058a75412064de69e09fd096de4a30b8c1149da6ba03287b10e8af925b01d725e655658035e43d9a