Compare commits

..

11 Commits

Author SHA1 Message Date
Mark McLoughlin bda88aaa38 * Mon May 25 2009 Mark McLoughlin <markmc@redhat.com> - 0.6.2-11.fc11
- Bring up the bridge, even if it doesn't have an IP address (bug #501912)
2009-05-25 15:23:17 +00:00
Mark McLoughlin ca4d795c85 * Fri May 22 2009 Mark McLoughlin <markmc@redhat.com> - 0.6.2-10.fc11
- Don't log monitor output to domain log file (bug #499584)
2009-05-22 09:24:30 +00:00
Mark McLoughlin e2e196d813 * Thu May 21 2009 Mark McLoughlin <markmc@redhat.com> - 0.6.2-9.fc11
- Fix qemu argv detection with latest qemu (bug #501923)
- Fix XML attribute escaping (bug #499791)
- Fix serious event handling issues causing guests to be destroyed (bug #499698)
2009-05-21 12:07:19 +00:00
Cole Robinson a5a2a38a5e Don't try to label a disk with no path (e.g. empty cdrom) (bug #499569) 2009-05-11 02:28:23 +00:00
Mark McLoughlin 30f098460c * Thu May 7 2009 Mark McLoughlin <markmc@redhat.com> - 0.6.2-7.fc11
- Enable migration for qemu 0.10 (bug #499704)
2009-05-07 19:08:42 +00:00
Cole Robinson 7017c99a1e Refresh qemu caps when getCapabilities is called (bug #460649) 2009-05-06 16:32:34 +00:00
Mark McLoughlin 1c41ce6f30 * Wed May 6 2009 Mark McLoughlin <markmc@redhat.com> - 0.6.2-5.fc11
- Fix handling of <hostdev managed='yes'> (bug #499386)
2009-05-06 15:51:47 +00:00
Daniel P. Berrange c6db79d97f Fix labelling of shared/readonly disks (rhbz #493692) 2009-05-05 13:01:15 +00:00
Daniel Veillard 7b7f8cc27f - Fix missing directories in spec (#496945 and gtk-doc)
Daniel
2009-04-28 10:57:59 +00:00
Mark McLoughlin a9cc41b082 * Thu Apr 16 2009 Mark McLoughlin <markmc@redhat.com> - 0.6.2-2.fc11
- Fix qemu drive format specification (#496092)
2009-04-16 15:26:45 +00:00
Jesse Keating ce1593f88f Initialize branch F-11 for libvirt 2009-04-15 07:13:06 +00:00
44 changed files with 1838 additions and 4884 deletions
+8
View File
@@ -0,0 +1,8 @@
.build*.log
*.rpm
i686
x86_64
libvirt-*.tar.gz
libvirt-0.6.0.tar.gz
libvirt-0.6.1.tar.gz
libvirt-0.6.2.tar.gz
-5
View File
@@ -1,5 +0,0 @@
.build*.log
*.rpm
i686
x86_64
libvirt-*.tar.xz
@@ -1,122 +0,0 @@
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);
@@ -1,85 +0,0 @@
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>
@@ -1,67 +0,0 @@
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),
@@ -1,198 +0,0 @@
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,
@@ -1,145 +0,0 @@
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;
@@ -1,78 +0,0 @@
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;
@@ -1,139 +0,0 @@
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);
@@ -1,47 +0,0 @@
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);
@@ -1,70 +0,0 @@
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)
@@ -1,67 +0,0 @@
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);
}
@@ -1,342 +0,0 @@
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);
}
@@ -1,119 +0,0 @@
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,
@@ -1,210 +0,0 @@
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;
}
@@ -1,49 +0,0 @@
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;
@@ -1,74 +0,0 @@
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;
@@ -1,164 +0,0 @@
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;
@@ -1,123 +0,0 @@
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
@@ -1,150 +0,0 @@
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;
@@ -1,53 +0,0 @@
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>
@@ -1,34 +0,0 @@
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);
@@ -1,108 +0,0 @@
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 \
@@ -1,101 +0,0 @@
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
@@ -1,63 +0,0 @@
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;
}
@@ -1,113 +0,0 @@
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;
@@ -1,71 +0,0 @@
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 \
+1 -1
View File
@@ -4,7 +4,7 @@ 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
for d in common ../common ../../common ; do if [ -f $$d/Makefile.common ] ; then if [ -f $$d/CVS/Root -a -w $$/Makefile.common ] ; then cd $$d ; cvs -Q update ; fi ; echo "$$d/Makefile.common" ; break ; fi ; done
endef
MAKEFILE_COMMON := $(shell $(find-makefile-common))
+1
View File
@@ -0,0 +1 @@
F-11
@@ -0,0 +1,48 @@
From 4db7474b0c1907e877d7206edeb4d73962971096 Mon Sep 17 00:00:00 2001
From: Daniel Veillard <veillard@redhat.com>
Date: Tue, 12 May 2009 15:31:22 +0000
Subject: [PATCH 1/1] * src/network_driver.c: enable bridges which are not up
without an IP address, patch by Ludwig Nussel
Daniel
---
src/network_driver.c | 9 +++------
1 files changed, 3 insertions(+), 6 deletions(-)
diff --git a/src/network_driver.c b/src/network_driver.c
index a17a769..a163b15 100644
--- a/src/network_driver.c
+++ b/src/network_driver.c
@@ -836,8 +836,7 @@ static int networkStartNetworkDaemon(virConnectPtr conn,
goto err_delbr;
}
- if (network->def->ipAddress &&
- (err = brSetInterfaceUp(driver->brctl, network->def->bridge, 1))) {
+ if ((err = brSetInterfaceUp(driver->brctl, network->def->bridge, 1))) {
virReportSystemError(conn, err,
_("failed to bring the bridge '%s' up"),
network->def->bridge);
@@ -878,8 +877,7 @@ static int networkStartNetworkDaemon(virConnectPtr conn,
networkRemoveIptablesRules(driver, network);
err_delbr1:
- if (network->def->ipAddress &&
- (err = brSetInterfaceUp(driver->brctl, network->def->bridge, 0))) {
+ if ((err = brSetInterfaceUp(driver->brctl, network->def->bridge, 0))) {
char ebuf[1024];
networkLog(NETWORK_WARN, _("Failed to bring down bridge '%s' : %s\n"),
network->def->bridge, virStrerror(err, ebuf, sizeof ebuf));
@@ -920,8 +918,7 @@ static int networkShutdownNetworkDaemon(virConnectPtr conn,
networkRemoveIptablesRules(driver, network);
char ebuf[1024];
- if (network->def->ipAddress &&
- (err = brSetInterfaceUp(driver->brctl, network->def->bridge, 0))) {
+ if ((err = brSetInterfaceUp(driver->brctl, network->def->bridge, 0))) {
networkLog(NETWORK_WARN, _("Failed to bring down bridge '%s' : %s\n"),
network->def->bridge, virStrerror(err, ebuf, sizeof ebuf));
}
--
1.6.0.6
@@ -0,0 +1,204 @@
From fbd16cecc72494e8a9450f38197221f2f50c9d0e Mon Sep 17 00:00:00 2001
From: =?utf-8?q?Guido=20G=C3=BCnther?= <agx@sigxcpu.org>
Date: Thu, 16 Apr 2009 15:56:27 +0000
Subject: [PATCH 1/1] Don't log monitor output to domain log file.
It's logged via the logging system already. Prefix monitor debug output with vm
name.
---
src/qemu_driver.c | 60 +++++++++++++++++++++-------------------------------
1 files changed, 24 insertions(+), 36 deletions(-)
diff --git a/src/qemu_driver.c b/src/qemu_driver.c
index 79ee072..f5b5fa5 100644
--- a/src/qemu_driver.c
+++ b/src/qemu_driver.c
@@ -1710,27 +1710,11 @@ qemudMonitorCommandExtra(const virDomainObjPtr vm,
goto error;
}
}
-
- /* Log, but ignore failures to write logfile for VM */
- if (safewrite(vm->logfile, buf, strlen(buf)) < 0) {
- char ebuf[1024];
- VIR_WARN(_("Unable to log VM console data: %s\n"),
- virStrerror(errno, ebuf, sizeof ebuf));
- }
-
*reply = buf;
return 0;
error:
- if (buf) {
- /* Log, but ignore failures to write logfile for VM */
- if (safewrite(vm->logfile, buf, strlen(buf)) < 0) {
- char ebuf[1024];
- VIR_WARN(_("Unable to log VM console data: %s\n"),
- virStrerror(errno, ebuf, sizeof ebuf));
- }
- VIR_FREE(buf);
- }
+ VIR_FREE(buf);
return -1;
}
@@ -2463,7 +2447,7 @@ static int qemudDomainGetMemoryBalloon(virConnectPtr conn,
goto cleanup;
}
- DEBUG ("balloon reply: '%s'", reply);
+ DEBUG ("%s: balloon reply: '%s'", vm->def->name, reply);
if ((offset = strstr(reply, BALLOON_PREFIX)) != NULL) {
unsigned int memMB;
char *end;
@@ -2517,7 +2501,7 @@ static int qemudDomainSetMemoryBalloon(virConnectPtr conn,
/* If the command failed qemu prints: 'unknown command'
* No message is printed on success it seems */
- DEBUG ("balloon reply: %s", reply);
+ DEBUG ("%s: balloon reply: %s",vm->def->name, reply);
if (strstr(reply, "\nunknown command:")) {
/* Don't set error - it is expected memory balloon fails on many qemu */
ret = 0;
@@ -2812,7 +2796,7 @@ static int qemudDomainSave(virDomainPtr dom,
goto cleanup;
}
- DEBUG ("migrate reply: %s", info);
+ DEBUG ("%s: migrate reply: %s", vm->def->name, info);
/* If the command isn't supported then qemu prints:
* unknown command: migrate" */
@@ -3658,7 +3642,7 @@ static int qemudDomainChangeEjectableMedia(virConnectPtr conn,
/* If the command failed qemu prints:
* device not found, device is locked ...
* No message is printed on success it seems */
- DEBUG ("ejectable media change reply: %s", reply);
+ DEBUG ("%s: ejectable media change reply: %s", vm->def->name, reply);
if (strstr(reply, "\ndevice ")) {
qemudReportError (conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
_("changing cdrom media failed: %s"), reply);
@@ -3719,7 +3703,7 @@ static int qemudDomainAttachPciDiskDevice(virConnectPtr conn,
return -1;
}
- DEBUG ("pci_add reply: %s", reply);
+ DEBUG ("%s: pci_add reply: %s", vm->def->name, reply);
/* If the command succeeds qemu prints:
* OK bus 0... */
#define PCI_ATTACH_OK_MSG "OK bus 0, slot "
@@ -3787,7 +3771,7 @@ static int qemudDomainAttachUsbMassstorageDevice(virConnectPtr conn,
return -1;
}
- DEBUG ("attach_usb reply: %s", reply);
+ DEBUG ("%s: attach_usb reply: %s",vm->def->name, reply);
/* If the command failed qemu prints:
* Could not add ... */
if (strstr(reply, "Could not add ")) {
@@ -3841,7 +3825,7 @@ static int qemudDomainAttachHostDevice(virConnectPtr conn,
return -1;
}
- DEBUG ("attach_usb reply: %s", reply);
+ DEBUG ("%s: attach_usb reply: %s", vm->def->name, reply);
/* If the command failed qemu prints:
* Could not add ... */
if (strstr(reply, "Could not add ")) {
@@ -3980,7 +3964,7 @@ static int qemudDomainDetachPciDiskDevice(virConnectPtr conn,
goto cleanup;
}
- DEBUG ("pci_del reply: %s", reply);
+ DEBUG ("%s: pci_del reply: %s",vm->def->name, reply);
/* If the command fails due to a wrong slot qemu prints: invalid slot,
* nothing is printed on success */
if (strstr(reply, "invalid slot")) {
@@ -4210,7 +4194,7 @@ qemudDomainBlockStats (virDomainPtr dom,
"%s", _("'info blockstats' command failed"));
goto cleanup;
}
- DEBUG ("info blockstats reply: %s", info);
+ DEBUG ("%s: info blockstats reply: %s", vm->def->name, info);
/* If the command isn't supported then qemu prints the supported
* info commands, so the output starts "info ". Since this is
@@ -4251,21 +4235,25 @@ qemudDomainBlockStats (virDomainPtr dom,
if (STRPREFIX (p, "rd_bytes=")) {
p += 9;
if (virStrToLong_ll (p, &dummy, 10, &stats->rd_bytes) == -1)
- DEBUG ("error reading rd_bytes: %s", p);
+ DEBUG ("%s: error reading rd_bytes: %s",
+ vm->def->name, p);
} else if (STRPREFIX (p, "wr_bytes=")) {
p += 9;
if (virStrToLong_ll (p, &dummy, 10, &stats->wr_bytes) == -1)
- DEBUG ("error reading wr_bytes: %s", p);
+ DEBUG ("%s: error reading wr_bytes: %s",
+ vm->def->name, p);
} else if (STRPREFIX (p, "rd_operations=")) {
p += 14;
if (virStrToLong_ll (p, &dummy, 10, &stats->rd_req) == -1)
- DEBUG ("error reading rd_req: %s", p);
+ DEBUG ("%s: error reading rd_req: %s",
+ vm->def->name, p);
} else if (STRPREFIX (p, "wr_operations=")) {
p += 14;
if (virStrToLong_ll (p, &dummy, 10, &stats->wr_req) == -1)
- DEBUG ("error reading wr_req: %s", p);
+ DEBUG ("%s: error reading wr_req: %s",
+ vm->def->name, p);
} else
- DEBUG ("unknown block stat near %s", p);
+ DEBUG ("%s: unknown block stat near %s", vm->def->name, p);
/* Skip to next label. */
p = strchr (p, ' ');
@@ -4477,7 +4465,7 @@ qemudDomainMemoryPeek (virDomainPtr dom,
goto cleanup;
}
- DEBUG ("memsave reply: %s", info);
+ DEBUG ("%s: memsave reply: %s", vm->def->name, info);
/* Read the memory file into buffer. */
if (saferead (fd, buffer, size) == (ssize_t) -1) {
@@ -4794,7 +4782,7 @@ qemudDomainMigratePerform (virDomainPtr dom,
"%s", _("off-line migration specified, but suspend operation failed"));
goto cleanup;
}
- DEBUG ("stop reply: %s", info);
+ DEBUG ("%s: stop reply: %s", vm->def->name, info);
VIR_FREE(info);
paused = 1;
@@ -4811,7 +4799,7 @@ qemudDomainMigratePerform (virDomainPtr dom,
snprintf (cmd, sizeof cmd, "migrate_set_speed %lum", resource);
qemudMonitorCommand (vm, cmd, &info);
- DEBUG ("migrate_set_speed reply: %s", info);
+ DEBUG ("%s: migrate_set_speed reply: %s", vm->def->name, info);
VIR_FREE (info);
}
@@ -4830,7 +4818,7 @@ qemudDomainMigratePerform (virDomainPtr dom,
goto cleanup;
}
- DEBUG ("migrate reply: %s", info);
+ DEBUG ("%s: migrate reply: %s", vm->def->name, info);
/* Now check for "fail" in the output string */
if (strstr(info, "fail") != NULL) {
@@ -4869,7 +4857,7 @@ cleanup:
vm->def->name);
}
else {
- DEBUG ("cont reply: %s", info);
+ DEBUG ("%s: cont reply: %s", vm->def->name, info);
VIR_FREE(info);
}
--
1.6.0.6
@@ -0,0 +1,45 @@
From: "Daniel P. Berrange" <berrange@redhat.com>
To: libvir-list@redhat.com
Date: Thu, 30 Apr 2009 15:09:05 +0100
Subject: [libvirt] PATCH: Enable migration with QEMU >= 0.10.0
The KVM migration code was added to QEMU for the 0.10.0 release, so we
should enable this in libvirt now.
Daniel
diff -r be7993675e07 src/qemu_conf.c
--- a/src/qemu_conf.c Thu Apr 30 14:49:27 2009 +0100
+++ b/src/qemu_conf.c Thu Apr 30 15:08:45 2009 +0100
@@ -472,16 +472,13 @@ int qemudExtractVersionInfo(const char *
/*
* Handling of -incoming arg with varying features
- * -incoming tcp (kvm >= 79)
- * -incoming exec (kvm >= 80)
+ * -incoming tcp (kvm >= 79, qemu >= 0.10.0)
+ * -incoming exec (kvm >= 80, qemu >= 0.10.0)
* -incoming stdio (all earlier kvm)
*
* NB, there was a pre-kvm-79 'tcp' support, but it
* was broken, because it blocked the monitor console
* while waiting for data, so pretend it doesn't exist
- *
- * XXX when next QEMU release after 0.9.1 arrives,
- * we'll need to add MIGRATE_QEMU_TCP/EXEC here too
*/
if (kvm_version >= 79) {
flags |= QEMUD_CMD_FLAG_MIGRATE_QEMU_TCP;
@@ -489,6 +486,9 @@ int qemudExtractVersionInfo(const char *
flags |= QEMUD_CMD_FLAG_MIGRATE_QEMU_EXEC;
} else if (kvm_version > 0) {
flags |= QEMUD_CMD_FLAG_MIGRATE_KVM_STDIO;
+ } else if (version >= 10000) {
+ flags |= QEMUD_CMD_FLAG_MIGRATE_QEMU_TCP;
+ flags |= QEMUD_CMD_FLAG_MIGRATE_QEMU_EXEC;
}
if (retversion)
--
+144
View File
@@ -0,0 +1,144 @@
From e7be6cc841a5652b73ddd2ccd3769c7f8bbad13d Mon Sep 17 00:00:00 2001
From: Daniel P. Berrange <berrange@redhat.com>
Date: Tue, 12 May 2009 16:41:49 +0000
Subject: [PATCH 1/2] Fix interrupting of main event thread & protect against accidental uniniitalized variables
---
qemud/event.c | 42 +++++++++++++++++++++++++++++++++++-------
1 files changed, 35 insertions(+), 7 deletions(-)
diff --git a/qemud/event.c b/qemud/event.c
index 65f548e..754f2b1 100644
--- a/qemud/event.c
+++ b/qemud/event.c
@@ -84,10 +84,10 @@ struct virEventLoop {
static struct virEventLoop eventLoop;
/* Unique ID for the next FD watch to be registered */
-static int nextWatch = 0;
+static int nextWatch = 1;
/* Unique ID for the next timer to be registered */
-static int nextTimer = 0;
+static int nextTimer = 1;
static void virEventLock(void)
{
@@ -143,15 +143,22 @@ int virEventAddHandleImpl(int fd, int events,
void virEventUpdateHandleImpl(int watch, int events) {
int i;
+ EVENT_DEBUG("Update handle w=%d e=%d", watch, events);
+
+ if (watch <= 0) {
+ VIR_WARN("Ignoring invalid update watch %d", watch);
+ return;
+ }
+
virEventLock();
for (i = 0 ; i < eventLoop.handlesCount ; i++) {
if (eventLoop.handles[i].watch == watch) {
eventLoop.handles[i].events =
virEventHandleTypeToPollEvent(events);
+ virEventInterruptLocked();
break;
}
}
- virEventInterruptLocked();
virEventUnlock();
}
@@ -164,6 +171,12 @@ void virEventUpdateHandleImpl(int watch, int events) {
int virEventRemoveHandleImpl(int watch) {
int i;
EVENT_DEBUG("Remove handle %d", watch);
+
+ if (watch <= 0) {
+ VIR_WARN("Ignoring invalid remove watch %d", watch);
+ return -1;
+ }
+
virEventLock();
for (i = 0 ; i < eventLoop.handlesCount ; i++) {
if (eventLoop.handles[i].deleted)
@@ -172,11 +185,11 @@ int virEventRemoveHandleImpl(int watch) {
if (eventLoop.handles[i].watch == watch) {
EVENT_DEBUG("mark delete %d %d", i, eventLoop.handles[i].fd);
eventLoop.handles[i].deleted = 1;
+ virEventInterruptLocked();
virEventUnlock();
return 0;
}
}
- virEventInterruptLocked();
virEventUnlock();
return -1;
}
@@ -232,6 +245,12 @@ void virEventUpdateTimeoutImpl(int timer, int frequency) {
struct timeval tv;
int i;
EVENT_DEBUG("Updating timer %d timeout with %d ms freq", timer, frequency);
+
+ if (timer <= 0) {
+ VIR_WARN("Ignoring invalid update timer %d", timer);
+ return;
+ }
+
if (gettimeofday(&tv, NULL) < 0) {
return;
}
@@ -244,10 +263,10 @@ void virEventUpdateTimeoutImpl(int timer, int frequency) {
frequency >= 0 ? frequency +
(((unsigned long long)tv.tv_sec)*1000) +
(((unsigned long long)tv.tv_usec)/1000) : 0;
+ virEventInterruptLocked();
break;
}
}
- virEventInterruptLocked();
virEventUnlock();
}
@@ -260,6 +279,12 @@ void virEventUpdateTimeoutImpl(int timer, int frequency) {
int virEventRemoveTimeoutImpl(int timer) {
int i;
EVENT_DEBUG("Remove timer %d", timer);
+
+ if (timer <= 0) {
+ VIR_WARN("Ignoring invalid remove timer %d", timer);
+ return -1;
+ }
+
virEventLock();
for (i = 0 ; i < eventLoop.timeoutsCount ; i++) {
if (eventLoop.timeouts[i].deleted)
@@ -267,11 +292,11 @@ int virEventRemoveTimeoutImpl(int timer) {
if (eventLoop.timeouts[i].timer == timer) {
eventLoop.timeouts[i].deleted = 1;
+ virEventInterruptLocked();
virEventUnlock();
return 0;
}
}
- virEventInterruptLocked();
virEventUnlock();
return -1;
}
@@ -617,9 +642,12 @@ static int virEventInterruptLocked(void)
char c = '\0';
if (!eventLoop.running ||
- pthread_self() == eventLoop.leader)
+ pthread_self() == eventLoop.leader) {
+ VIR_DEBUG("Skip interrupt, %d %d", eventLoop.running, (int)eventLoop.leader);
return 0;
+ }
+ VIR_DEBUG0("Interrupting");
if (safewrite(eventLoop.wakeupfd[1], &c, sizeof(c)) != sizeof(c))
return -1;
return 0;
--
1.6.0.6
+197
View File
@@ -0,0 +1,197 @@
From 6483ee77ed12f037d68a6adc690624fa1b508dc0 Mon Sep 17 00:00:00 2001
From: Daniel P. Berrange <berrange@redhat.com>
Date: Tue, 12 May 2009 16:43:04 +0000
Subject: [PATCH 2/2] Fix watch/timer event deletion
---
qemud/event.c | 112 ++++++++++++++++++++++++++-------------------------------
1 files changed, 51 insertions(+), 61 deletions(-)
diff --git a/qemud/event.c b/qemud/event.c
index 754f2b1..a57d967 100644
--- a/qemud/event.c
+++ b/qemud/event.c
@@ -313,7 +313,7 @@ static int virEventCalculateTimeout(int *timeout) {
EVENT_DEBUG("Calculate expiry of %d timers", eventLoop.timeoutsCount);
/* Figure out if we need a timeout */
for (i = 0 ; i < eventLoop.timeoutsCount ; i++) {
- if (eventLoop.timeouts[i].deleted || eventLoop.timeouts[i].frequency < 0)
+ if (eventLoop.timeouts[i].frequency < 0)
continue;
EVENT_DEBUG("Got a timeout scheduled for %llu", eventLoop.timeouts[i].expiresAt);
@@ -350,32 +350,26 @@ static int virEventCalculateTimeout(int *timeout) {
* file handles. The caller must free the returned data struct
* returns: the pollfd array, or NULL on error
*/
-static int virEventMakePollFDs(struct pollfd **retfds) {
+static struct pollfd *virEventMakePollFDs(void) {
struct pollfd *fds;
- int i, nfds = 0;
+ int i;
- for (i = 0 ; i < eventLoop.handlesCount ; i++) {
- if (eventLoop.handles[i].deleted)
- continue;
- nfds++;
- }
- *retfds = NULL;
/* Setup the poll file handle data structs */
- if (VIR_ALLOC_N(fds, nfds) < 0)
- return -1;
+ if (VIR_ALLOC_N(fds, eventLoop.handlesCount) < 0)
+ return NULL;
- for (i = 0, nfds = 0 ; i < eventLoop.handlesCount ; i++) {
- if (eventLoop.handles[i].deleted)
- continue;
- fds[nfds].fd = eventLoop.handles[i].fd;
- fds[nfds].events = eventLoop.handles[i].events;
- fds[nfds].revents = 0;
+ for (i = 0 ; i < eventLoop.handlesCount ; i++) {
+ EVENT_DEBUG("Prepare n=%d w=%d, f=%d e=%d", i,
+ eventLoop.handles[i].watch,
+ eventLoop.handles[i].fd,
+ eventLoop.handles[i].events);
+ fds[i].fd = eventLoop.handles[i].fd;
+ fds[i].events = eventLoop.handles[i].events;
+ fds[i].revents = 0;
//EVENT_DEBUG("Wait for %d %d", eventLoop.handles[i].fd, eventLoop.handles[i].events);
- nfds++;
}
- *retfds = fds;
- return nfds;
+ return fds;
}
@@ -435,26 +429,30 @@ static int virEventDispatchTimeouts(void) {
* Returns 0 upon success, -1 if an error occurred
*/
static int virEventDispatchHandles(int nfds, struct pollfd *fds) {
- int i, n;
+ int i;
- for (i = 0, n = 0 ; i < eventLoop.handlesCount && n < nfds ; i++) {
+ /* NB, use nfds not eventLoop.handlesCount, because new
+ * fds might be added on end of list, and they're not
+ * in the fds array we've got */
+ for (i = 0 ; i < nfds ; i++) {
if (eventLoop.handles[i].deleted) {
- EVENT_DEBUG("Skip deleted %d", eventLoop.handles[i].fd);
+ EVENT_DEBUG("Skip deleted n=%d w=%d f=%d", i,
+ eventLoop.handles[i].watch, eventLoop.handles[i].fd);
continue;
}
- if (fds[n].revents) {
+ if (fds[i].revents) {
virEventHandleCallback cb = eventLoop.handles[i].cb;
void *opaque = eventLoop.handles[i].opaque;
- int hEvents = virPollEventToEventHandleType(fds[n].revents);
- EVENT_DEBUG("Dispatch %d %d %p", fds[n].fd,
- fds[n].revents, eventLoop.handles[i].opaque);
+ int hEvents = virPollEventToEventHandleType(fds[i].revents);
+ EVENT_DEBUG("Dispatch n=%d f=%d w=%d e=%d %p", i,
+ fds[i].fd, eventLoop.handles[i].watch,
+ fds[i].revents, eventLoop.handles[i].opaque);
virEventUnlock();
(cb)(eventLoop.handles[i].watch,
- fds[n].fd, hEvents, opaque);
+ fds[i].fd, hEvents, opaque);
virEventLock();
}
- n++;
}
return 0;
@@ -545,22 +543,21 @@ static int virEventCleanupHandles(void) {
* at least one file handle has an event, or a timer expires
*/
int virEventRunOnce(void) {
- struct pollfd *fds;
+ struct pollfd *fds = NULL;
int ret, timeout, nfds;
virEventLock();
eventLoop.running = 1;
eventLoop.leader = pthread_self();
- if ((nfds = virEventMakePollFDs(&fds)) < 0) {
- virEventUnlock();
- return -1;
- }
- if (virEventCalculateTimeout(&timeout) < 0) {
- VIR_FREE(fds);
- virEventUnlock();
- return -1;
- }
+ if (virEventCleanupTimeouts() < 0 ||
+ virEventCleanupHandles() < 0)
+ goto error;
+
+ if (!(fds = virEventMakePollFDs()) ||
+ virEventCalculateTimeout(&timeout) < 0)
+ goto error;
+ nfds = eventLoop.handlesCount;
virEventUnlock();
@@ -572,38 +569,31 @@ int virEventRunOnce(void) {
if (errno == EINTR) {
goto retry;
}
- VIR_FREE(fds);
- return -1;
+ goto error_unlocked;
}
virEventLock();
- if (virEventDispatchTimeouts() < 0) {
- VIR_FREE(fds);
- virEventUnlock();
- return -1;
- }
+ if (virEventDispatchTimeouts() < 0)
+ goto error;
if (ret > 0 &&
- virEventDispatchHandles(nfds, fds) < 0) {
- VIR_FREE(fds);
- virEventUnlock();
- return -1;
- }
- VIR_FREE(fds);
-
- if (virEventCleanupTimeouts() < 0) {
- virEventUnlock();
- return -1;
- }
+ virEventDispatchHandles(nfds, fds) < 0)
+ goto error;
- if (virEventCleanupHandles() < 0) {
- virEventUnlock();
- return -1;
- }
+ if (virEventCleanupTimeouts() < 0 ||
+ virEventCleanupHandles() < 0)
+ goto error;
eventLoop.running = 0;
virEventUnlock();
+ VIR_FREE(fds);
return 0;
+
+error:
+ virEventUnlock();
+error_unlocked:
+ VIR_FREE(fds);
+ return -1;
}
static void virEventHandleWakeup(int watch ATTRIBUTE_UNUSED,
--
1.6.0.6
+13
View File
@@ -0,0 +1,13 @@
diff -rup libvirt-0.6.2/src/security_selinux.c new/src/security_selinux.c
--- libvirt-0.6.2/src/security_selinux.c 2009-05-10 22:04:25.000000000 -0400
+++ new/src/security_selinux.c 2009-05-10 22:06:09.000000000 -0400
@@ -338,6 +338,9 @@ SELinuxSetSecurityImageLabel(virConnectP
{
const virSecurityLabelDefPtr secdef = &vm->def->seclabel;
+ if (!disk->src)
+ return 0;
+
if (disk->shared) {
return SELinuxSetFilecon(conn, disk->src, default_image_context);
} else if (disk->readonly) {
@@ -0,0 +1,82 @@
From 2b3fcdc378e7bec5c1a78b81632756e92930fd24 Mon Sep 17 00:00:00 2001
From: Daniel P. Berrange <berrange@redhat.com>
Date: Mon, 11 May 2009 15:14:24 +0000
Subject: [PATCH 1/1] Fix QEMU ARGV detection with kvm >= 85
---
src/qemu_conf.c | 18 ++++++++++++++----
src/qemu_driver.c | 12 ++----------
2 files changed, 16 insertions(+), 14 deletions(-)
diff --git a/src/qemu_conf.c b/src/qemu_conf.c
index 9cb71eb..a57d3ab 100644
--- a/src/qemu_conf.c
+++ b/src/qemu_conf.c
@@ -431,18 +431,28 @@ int qemudExtractVersionInfo(const char *qemu,
return -1;
char *help = NULL;
- enum { MAX_HELP_OUTPUT_SIZE = 8192 };
+ enum { MAX_HELP_OUTPUT_SIZE = 1024*64 };
int len = virFileReadLimFD(newstdout, MAX_HELP_OUTPUT_SIZE, &help);
- if (len < 0)
+ if (len < 0) {
+ virReportSystemError(NULL, errno, "%s",
+ _("Unable to read QEMU help output"));
goto cleanup2;
+ }
if (sscanf(help, "QEMU PC emulator version %u.%u.%u (kvm-%u)",
&major, &minor, &micro, &kvm_version) != 4)
kvm_version = 0;
- if (!kvm_version && sscanf(help, "QEMU PC emulator version %u.%u.%u",
- &major, &minor, &micro) != 3)
+ if (!kvm_version &&
+ sscanf(help, "QEMU PC emulator version %u.%u.%u",
+ &major, &minor, &micro) != 3) {
+ char *eol = strchr(help, '\n');
+ if (eol) *eol = '\0';
+ qemudReportError(NULL, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
+ _("cannot parse QEMU version number in '%s'"),
+ help);
goto cleanup2;
+ }
version = (major * 1000 * 1000) + (minor * 1000) + micro;
diff --git a/src/qemu_driver.c b/src/qemu_driver.c
index 30642d5..bd60b29 100644
--- a/src/qemu_driver.c
+++ b/src/qemu_driver.c
@@ -1391,12 +1391,8 @@ static int qemudStartVMDaemon(virConnectPtr conn,
if (qemudExtractVersionInfo(emulator,
NULL,
- &qemuCmdFlags) < 0) {
- qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
- _("Cannot determine QEMU argv syntax %s"),
- emulator);
+ &qemuCmdFlags) < 0)
goto cleanup;
- }
if (qemuPrepareHostDevices(conn, vm->def) < 0)
goto cleanup;
@@ -3715,12 +3711,8 @@ static int qemudDomainChangeEjectableMedia(virConnectPtr conn,
if (qemudExtractVersionInfo(vm->def->emulator,
NULL,
- &qemuCmdFlags) < 0) {
- qemudReportError(conn, dom, NULL, VIR_ERR_INTERNAL_ERROR,
- _("Cannot determine QEMU argv syntax %s"),
- vm->def->emulator);
+ &qemuCmdFlags) < 0)
return -1;
- }
if (qemuCmdFlags & QEMUD_CMD_FLAG_DRIVE) {
if (!(devname = qemudDiskDeviceName(conn, newdisk)))
--
1.6.0.6
+26
View File
@@ -0,0 +1,26 @@
From 0ae4c67ff5f1d24698c5cfc8a9719d333c892644 Mon Sep 17 00:00:00 2001
From: Mark McLoughlin <markmc@redhat.com>
Date: Thu, 16 Apr 2009 11:23:55 +0100
Subject: [PATCH 1/3] qemu -drive takes format= not fmt=
Seems like a simple typo - it has been "format=" since the flag
was introduced, but we added it as "fmt=".
Signed-off-by: Mark McLoughlin <markmc@redhat.com>
---
src/qemu_conf.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/qemu_conf.c b/src/qemu_conf.c
index f36c927..6f9e610 100644
--- a/src/qemu_conf.c
+++ b/src/qemu_conf.c
@@ -1135,7 +1135,7 @@ int qemudBuildCommandLine(virConnectPtr conn,
disk->device == VIR_DOMAIN_DISK_DEVICE_DISK)
virBufferAddLit(&opt, ",boot=on");
if (disk->driverType)
- virBufferVSprintf(&opt, ",fmt=%s", disk->driverType);
+ virBufferVSprintf(&opt, ",format=%s", disk->driverType);
if (disk->cachemode) {
const char *mode =
+76
View File
@@ -0,0 +1,76 @@
diff -rup libvirt-0.6.2/src/security_selinux.c libvirt-0.6.2.new/src/security_selinux.c
--- libvirt-0.6.2/src/security_selinux.c 2009-04-03 15:36:56.000000000 +0100
+++ libvirt-0.6.2.new/src/security_selinux.c 2009-05-05 13:39:42.000000000 +0100
@@ -24,11 +24,12 @@
#include "virterror_internal.h"
#include "util.h"
#include "memory.h"
-
+#include "logging.h"
#define VIR_FROM_THIS VIR_FROM_SECURITY
static char default_domain_context[1024];
+static char default_content_context[1024];
static char default_image_context[1024];
#define SECURITY_SELINUX_VOID_DOI "0"
#define SECURITY_SELINUX_NAME "selinux"
@@ -148,8 +149,13 @@ SELinuxInitialize(virConnectPtr conn)
close(fd);
ptr = strchrnul(default_image_context, '\n');
- *ptr = '\0';
-
+ if (*ptr == '\n') {
+ *ptr = '\0';
+ strcpy(default_content_context, ptr+1);
+ ptr = strchrnul(default_content_context, '\n');
+ if (*ptr == '\n')
+ *ptr = '\0';
+ }
return 0;
}
@@ -275,6 +281,8 @@ SELinuxSetFilecon(virConnectPtr conn, co
{
char ebuf[1024];
+ VIR_INFO("Setting SELinux context on '%s' to '%s'", path, tcon);
+
if(setfilecon(path, tcon) < 0) {
virSecurityReportError(conn, VIR_ERR_ERROR,
_("%s: unable to set security context "
@@ -299,6 +307,8 @@ SELinuxRestoreSecurityImageLabel(virConn
char *newpath = NULL;
const char *path = disk->src;
+ /* Don't restore labels on readoly/shared disks, because
+ * other VMs may still be accessing these */
if (disk->readonly || disk->shared)
return 0;
@@ -328,8 +338,13 @@ SELinuxSetSecurityImageLabel(virConnectP
{
const virSecurityLabelDefPtr secdef = &vm->def->seclabel;
- if (secdef->imagelabel)
+ if (disk->shared) {
+ return SELinuxSetFilecon(conn, disk->src, default_image_context);
+ } else if (disk->readonly) {
+ return SELinuxSetFilecon(conn, disk->src, default_content_context);
+ } else if (secdef->imagelabel) {
return SELinuxSetFilecon(conn, disk->src, secdef->imagelabel);
+ }
return 0;
}
@@ -403,9 +418,6 @@ SELinuxSetSecurityLabel(virConnectPtr co
if (secdef->imagelabel) {
for (i = 0 ; i < vm->def->ndisks ; i++) {
- if (vm->def->disks[i]->readonly ||
- vm->def->disks[i]->shared) continue;
-
if (SELinuxSetSecurityImageLabel(conn, vm, vm->def->disks[i]) < 0)
return -1;
}
+33
View File
@@ -0,0 +1,33 @@
--- src/qemu_conf.c.orig 2009-04-02 11:50:10.000000000 +0200
+++ src/qemu_conf.c 2009-04-03 17:46:59.000000000 +0200
@@ -779,6 +779,20 @@ int qemudBuildCommandLine(virConnectPtr
char domid[50];
char *pidfile;
const char *cpu = NULL;
+ int skipSound = 0;
+
+ if (driver->securityDriver &&
+ driver->securityDriver->name &&
+ STREQ(driver->securityDriver->name, "selinux") &&
+ getuid() == 0) {
+ static int soundWarned = 0;
+ skipSound = 1;
+ if (vm->def->nsounds &&
+ !soundWarned) {
+ soundWarned = 1;
+ VIR_WARN0("Sound cards for VMs are disabled while SELinux security model is active");
+ }
+ }
uname_normalize(&ut);
@@ -1425,7 +1439,8 @@ int qemudBuildCommandLine(virConnectPtr
}
/* Add sound hardware */
- if (vm->def->nsounds) {
+ if (vm->def->nsounds &&
+ !skipSound) {
int size = 100;
char *modstr;
if (VIR_ALLOC_N(modstr, size+1) < 0)
@@ -0,0 +1,47 @@
From 7f7a4403860f56d5a1ad65bfd16f5bf97a971d45 Mon Sep 17 00:00:00 2001
From: Daniel Veillard <veillard@redhat.com>
Date: Wed, 13 May 2009 16:19:59 +0000
Subject: [PATCH 1/1] * src/buf.c: avoid an XML attribute escaping bug #499791
daniel
---
src/buf.c | 16 +++++++++++++++-
1 files changed, 15 insertions(+), 1 deletions(-)
diff --git a/src/buf.c b/src/buf.c
index cdcdac9..259175d 100644
--- a/src/buf.c
+++ b/src/buf.c
@@ -266,7 +266,7 @@ virBufferEscapeString(const virBufferPtr buf, const char *format, const char *st
return;
len = strlen(str);
- if (VIR_ALLOC_N(escaped, 5 * len + 1) < 0) {
+ if (VIR_ALLOC_N(escaped, 6 * len + 1) < 0) {
virBufferNoMemory(buf);
return;
}
@@ -290,6 +290,20 @@ virBufferEscapeString(const virBufferPtr buf, const char *format, const char *st
*out++ = 'm';
*out++ = 'p';
*out++ = ';';
+ } else if (*cur == '"') {
+ *out++ = '&';
+ *out++ = 'q';
+ *out++ = 'u';
+ *out++ = 'o';
+ *out++ = 't';
+ *out++ = ';';
+ } else if (*cur == '\'') {
+ *out++ = '&';
+ *out++ = 'a';
+ *out++ = 'p';
+ *out++ = 'o';
+ *out++ = 's';
+ *out++ = ';';
} else if ((*cur >= 0x20) || (*cur == '\n') || (*cur == '\t') ||
(*cur == '\r')) {
/*
--
1.6.0.6
+45
View File
@@ -0,0 +1,45 @@
From 3d7771e0570e09096ad9391a857dad48b150bc0c Mon Sep 17 00:00:00 2001
From: Mark McLoughlin <markmc@redhat.com>
Date: Wed, 6 May 2009 16:33:28 +0100
Subject: [PATCH] Fix qemu driver's interpretation of <hostdev managed='yes'/>
This change:
Tue Mar 3 08:55:13 GMT 2009 Daniel P. Berrange <berrange@redhat.com>
Don't try to detach & reset PCI devices while running test
suite for XML-> ARGV conversion.
* src/qemu_driver.c: Add qemuPrepareHostDevices() helper to
detach and reset PCI devices.
* src/qemu_conf.c: Don't detach & reset PCI devices while
building the command line argv
accidentally did this:
- if (hostdev->managed) {
+ if (!hostdev->managed) {
Which results in managed='yes' not causing the device to be
detached when the guest is starting.
Signed-off-by: Mark McLoughlin <markmc@redhat.com>
---
src/qemu_driver.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/src/qemu_driver.c b/src/qemu_driver.c
index 5898026..59312c0 100644
--- a/src/qemu_driver.c
+++ b/src/qemu_driver.c
@@ -1215,7 +1215,7 @@ static int qemuPrepareHostDevices(virConnectPtr conn,
if (hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI)
continue;
- if (!hostdev->managed) {
+ if (hostdev->managed) {
pciDevice *dev = pciGetDevice(conn,
hostdev->source.subsys.u.pci.domain,
hostdev->source.subsys.u.pci.bus,
--
1.6.0.6
+76
View File
@@ -0,0 +1,76 @@
commit 0e51348cb9aeafe5e2fd6469a4bde0baa1eb8720
Author: Cole Robinson <crobinso@redhat.com>
Date: Mon May 4 15:06:03 2009 -0400
Refresh QEMU driver capabilities for each getCapabilities call.
Also fix up a couple issues where caps are accessed without locking
the driver structure.
diff --git a/src/qemu_driver.c b/src/qemu_driver.c
index 23ea961..790dac6 100644
--- a/src/qemu_driver.c
+++ b/src/qemu_driver.c
@@ -1885,10 +1885,12 @@ static int qemudGetNodeInfo(virConnectPtr conn,
static char *qemudGetCapabilities(virConnectPtr conn) {
struct qemud_driver *driver = conn->privateData;
- char *xml;
+ char *xml = NULL;
qemuDriverLock(driver);
- if ((xml = virCapabilitiesFormatXML(driver->caps)) == NULL)
+ virCapabilitiesFree(qemu_driver->caps);
+ if ((qemu_driver->caps = qemudCapsInit()) == NULL ||
+ (xml = virCapabilitiesFormatXML(driver->caps)) == NULL)
virReportOOMError(conn);
qemuDriverUnlock(driver);
@@ -3169,20 +3171,26 @@ cleanup:
return ret;
}
-static int qemudNodeGetSecurityModel(virConnectPtr conn, virSecurityModelPtr secmodel)
+static int qemudNodeGetSecurityModel(virConnectPtr conn,
+ virSecurityModelPtr secmodel)
{
struct qemud_driver *driver = (struct qemud_driver *)conn->privateData;
char *p;
+ int ret = 0;
- if (!driver->securityDriver)
- return -2;
+ qemuDriverLock(driver);
+ if (!driver->securityDriver) {
+ ret = -2;
+ goto cleanup;
+ }
p = driver->caps->host.secModel.model;
if (strlen(p) >= VIR_SECURITY_MODEL_BUFLEN-1) {
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
_("security model string exceeds max %d bytes"),
VIR_SECURITY_MODEL_BUFLEN-1);
- return -1;
+ ret = -1;
+ goto cleanup;
}
strcpy(secmodel->model, p);
@@ -3191,10 +3199,14 @@ static int qemudNodeGetSecurityModel(virConnectPtr conn, virSecurityModelPtr sec
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
_("security DOI string exceeds max %d bytes"),
VIR_SECURITY_DOI_BUFLEN-1);
- return -1;
+ ret = -1;
+ goto cleanup;
}
strcpy(secmodel->doi, p);
- return 0;
+
+cleanup:
+ qemuDriverUnlock(driver);
+ return ret;
}
/* TODO: check seclabel restore */
+791 -2085
View File
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -1 +1 @@
SHA512 (libvirt-3.2.1.tar.xz) = 4ec4faceedcad3a5419e91444b0c83adcbed0ff6482fb53c058a75412064de69e09fd096de4a30b8c1149da6ba03287b10e8af925b01d725e655658035e43d9a
3035b484861516a1cd425acef1e760e3 libvirt-0.6.2.tar.gz