Compare commits

...

7 Commits

Author SHA1 Message Date
Mark McLoughlin
e8eadea9cd * Wed Sep 30 2009 Mark McLoughlin <markmc@redhat.com> - 0.6.2-18
- Fix qemu-kvm version detection so GSO is enabled for virtio_net (#526472)
2009-09-30 14:20:16 +00:00
Mark McLoughlin
5d42cf83f8 Add URL to source tag 2009-08-21 10:20:12 +00:00
Mark McLoughlin
36d6c9d752 * Wed Aug 19 2009 Mark McLoughlin <markmc@redhat.com> - 0.6.2-17
- Fix migration completion with newer versions of qemu (#516187)
- Fix dumpxml segfault with newer versions of Xen (#518091)
2009-08-19 17:08:59 +00:00
Mark McLoughlin
529d097d28 * Wed Aug 19 2009 Mark McLoughlin <markmc@redhat.com> - 0.6.2-16.fc11
- Allow PCI bus reset to reset other devices (#499678)
- Fix stupid PCI reset error message (bug #499678)
- Allow PM reset on multi-function PCI devices (bug #515689)
- Re-attach PCI host devices after guest shuts down (bug #499561)
- Fixes list corruption after disk hot-unplug
- Fix minor 'virsh nodedev-list --tree' annoyance
2009-08-19 16:15:46 +00:00
Mark McLoughlin
3eb78ffd37 Sync patches from git 2009-08-17 08:08:56 +00:00
Daniel P. Berrange
8841355697 Log and ignore NUMA topology problems (rhbz #506590) 2009-08-13 16:07:23 +00:00
Daniel P. Berrange
40a867daeb Misc important fixes from BZ
- Fix crash when attaching/detaching non-existant PCI device (rhbz #510907)
- Fix QEMU guest name/uuid uniqueness checks (rhbz #507405)
- Fix to use correct pci_add/del syntax for QEMU (rhbz #499669)
- Relabel disks before hotplugging them to guest (rhbz #496442)
- Correctly handle 8-bit high bytes when escaping XML (rhbz #479517)
2009-08-05 15:48:14 +00:00
37 changed files with 2791 additions and 143 deletions

View File

@@ -1,14 +1,17 @@
From 934b71abf1b908f720811a44ad5411cfc1a4ca37 Mon Sep 17 00:00:00 2001
From 6e80c60b89728de28267242f7373ecf553e40bc1 Mon Sep 17 00:00:00 2001
From: Daniel P. Berrange <berrange@redhat.com>
Date: Thu, 28 May 2009 13:15:57 +0000
Subject: [PATCH 1/1] Avoid broken networking with new QEMU/KVM >= 86
Subject: [PATCH] Avoid broken networking with new QEMU/KVM >= 86
(cherry picked from commit 2afc3bfd8b779ddba974da9d66d6ea337fc91c01)
Fedora-patch: libvirt-0.6.2-avoid-broken-networking-with-newer-qemu.patch
---
src/qemu_conf.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/qemu_conf.c b/src/qemu_conf.c
index 93dc0b7..a04d216 100644
index fc0e772..99f13c6 100644
--- a/src/qemu_conf.c
+++ b/src/qemu_conf.c
@@ -658,8 +658,8 @@ qemudNetworkIfaceConnect(virConnectPtr conn,
@@ -23,5 +26,5 @@ index 93dc0b7..a04d216 100644
if (!(retval = strdup(tapfdstr)))
goto no_memory;
--
1.6.0.6
1.6.2.5

View File

@@ -1,10 +1,11 @@
From 4db7474b0c1907e877d7206edeb4d73962971096 Mon Sep 17 00:00:00 2001
From 6635abc3bbe54e6b0168182805de92cd70d125e4 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
Subject: [PATCH] * src/network_driver.c: enable bridges which are not up without an IP address, patch by Ludwig Nussel
(cherry picked from commit e978774ec67f4b062b1f65e5c76a13193a9430eb)
Fedora-patch: libvirt-0.6.2-bring-up-ipless-bridge.patch
---
src/network_driver.c | 9 +++------
1 files changed, 3 insertions(+), 6 deletions(-)
@@ -44,5 +45,5 @@ index a17a769..a163b15 100644
network->def->bridge, virStrerror(err, ebuf, sizeof ebuf));
}
--
1.6.0.6
1.6.2.5

View File

@@ -0,0 +1,33 @@
From f793cd9b7220145b6df8086d77db4fdc035d680b Mon Sep 17 00:00:00 2001
From: Daniel P. Berrange <berrange@redhat.com>
Date: Tue, 4 Aug 2009 18:13:09 +0100
Subject: [PATCH] Fix escaping of 8-bit high characters
Fix https://bugzilla.redhat.com/show_bug.cgi?id=479517
* src/buf.c: Cast to 'unsigned char' before doing compare to
avoid rejecting 8-bit high characters
(cherry picked from commit 8feb499ba2c3625632210c997b49f5df515c05d4)
Fedora-patch: libvirt-0.6.2-buf-locale-escape.patch
---
src/buf.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/src/buf.c b/src/buf.c
index 259175d..c802aa2 100644
--- a/src/buf.c
+++ b/src/buf.c
@@ -304,7 +304,7 @@ virBufferEscapeString(const virBufferPtr buf, const char *format, const char *st
*out++ = 'o';
*out++ = 's';
*out++ = ';';
- } else if ((*cur >= 0x20) || (*cur == '\n') || (*cur == '\t') ||
+ } else if (((unsigned char)*cur >= 0x20) || (*cur == '\n') || (*cur == '\t') ||
(*cur == '\r')) {
/*
* default case, just copy !
--
1.6.2.5

View File

@@ -0,0 +1,170 @@
From fe3cb2edefceacc76d0dc9c98b8d3b677a495c32 Mon Sep 17 00:00:00 2001
From: Mark McLoughlin <markmc@redhat.com>
Date: Thu, 11 Jun 2009 14:15:49 +0000
Subject: [PATCH] Detect newer qemu-kvm versions
The KVM version string can be one of the following:
- qemu-kvm-x.y.z in stable releases
- kvm-XX for kvm versions up to kvm-85
- qemu-kvm-devel-XX for kvm version kvm-86 and later
There are only a few of places where we need to detect
differences between KVM versions based on 0.9.1:
1) VNET_HDR introduced in kvm-74
2) -incoming tcp introduced in kvm-79
3) -incoming exec introduced in kvm-80
4) -incoming stdio in all earlier kvm versions
With qemu-kvm-0.10.x, we can now assume that (1) is available
if it's a KVM release, (2) and (3) is always available and
(4) is never available.
So, from now on we should only need to check the qemu version
number and the "is_kvm" flag for detecting feature availability.
We only need the KVM version number for older releases.
(cherry picked from commit 04cbe687974b3b46c96fa20180bbb07ffeff69da)
Signed-off-by: Mark McLoughlin <markmc@redhat.com>
Fedora-patch: libvirt-0.6.2-detect-newer-qemu-kvm-versions.patch
---
src/qemu_conf.c | 44 +++++++++++++++++++++++++++++++-------------
1 files changed, 31 insertions(+), 13 deletions(-)
diff --git a/src/qemu_conf.c b/src/qemu_conf.c
index e488d74..d76b2b6 100644
--- a/src/qemu_conf.c
+++ b/src/qemu_conf.c
@@ -416,6 +416,7 @@ virCapsPtr qemudCapsInit(void) {
static unsigned int qemudComputeCmdFlags(const char *help,
unsigned int version,
+ unsigned int is_kvm,
unsigned int kvm_version)
{
unsigned int flags = 0;
@@ -441,7 +442,8 @@ static unsigned int qemudComputeCmdFlags(const char *help,
flags |= QEMUD_CMD_FLAG_DRIVE_BOOT;
if (version >= 9000)
flags |= QEMUD_CMD_FLAG_VNC_COLON;
- if (kvm_version >= 74)
+
+ if (is_kvm && (version >= 10000 || kvm_version >= 74))
flags |= QEMUD_CMD_FLAG_VNET_HDR;
/*
@@ -454,15 +456,15 @@ static unsigned int qemudComputeCmdFlags(const char *help,
* was broken, because it blocked the monitor console
* while waiting for data, so pretend it doesn't exist
*/
- if (kvm_version >= 79) {
+ if (version >= 10000) {
+ flags |= QEMUD_CMD_FLAG_MIGRATE_QEMU_TCP;
+ flags |= QEMUD_CMD_FLAG_MIGRATE_QEMU_EXEC;
+ } else if (kvm_version >= 79) {
flags |= QEMUD_CMD_FLAG_MIGRATE_QEMU_TCP;
if (kvm_version >= 80)
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;
}
return flags;
@@ -472,10 +474,19 @@ static unsigned int qemudComputeCmdFlags(const char *help,
* version number. The first bit is easy, just parse
* 'QEMU PC emulator version x.y.z'.
*
- * With qemu-kvm, however, that is followed by a kvm-XX
- * string in parenthesis.
+ * With qemu-kvm, however, that is followed by a string
+ * in parenthesis as follows:
+ * - qemu-kvm-x.y.z in stable releases
+ * - kvm-XX for kvm versions up to kvm-85
+ * - qemu-kvm-devel-XX for kvm version kvm-86 and later
+ *
+ * For qemu-kvm versions before 0.10.z, we need to detect
+ * the KVM version number for some features. With 0.10.z
+ * and later, we just need the QEMU version number and
+ * whether it is KVM QEMU or mainline QEMU.
*/
#define QEMU_VERSION_STR "QEMU PC emulator version"
+#define QEMU_KVM_VER_PREFIX "(qemu-kvm-"
#define KVM_VER_PREFIX "(kvm-"
#define SKIP_BLANKS(p) do { while ((*(p) == ' ') || (*(p) == '\t')) (p)++; } while (0)
@@ -483,12 +494,13 @@ static unsigned int qemudComputeCmdFlags(const char *help,
static int qemudParseHelpStr(const char *help,
unsigned int *flags,
unsigned int *version,
+ unsigned int *is_kvm,
unsigned int *kvm_version)
{
unsigned major, minor, micro;
const char *p = help;
- *flags = *version = *kvm_version = 0;
+ *flags = *version = *is_kvm = *kvm_version = 0;
if (!STRPREFIX(p, QEMU_VERSION_STR))
goto fail;
@@ -515,9 +527,13 @@ static int qemudParseHelpStr(const char *help,
SKIP_BLANKS(p);
- if (STRPREFIX(p, KVM_VER_PREFIX)) {
+ if (STRPREFIX(p, QEMU_KVM_VER_PREFIX)) {
+ *is_kvm = 1;
+ p += strlen(QEMU_KVM_VER_PREFIX);
+ } else if (STRPREFIX(p, KVM_VER_PREFIX)) {
int ret;
+ *is_kvm = 1;
p += strlen(KVM_VER_PREFIX);
ret = virParseNumber(&p);
@@ -529,12 +545,14 @@ static int qemudParseHelpStr(const char *help,
*version = (major * 1000 * 1000) + (minor * 1000) + micro;
- *flags = qemudComputeCmdFlags(help, *version, *kvm_version);
+ *flags = qemudComputeCmdFlags(help, *version, *is_kvm, *kvm_version);
qemudDebug("Version %u.%u.%u, cooked version %u, flags %u",
major, minor, micro, *version, *flags);
if (*kvm_version)
- qemudDebug("KVM version %u detected", *kvm_version);
+ qemudDebug("KVM version %d detected", *kvm_version);
+ else if (*is_kvm)
+ qemudDebug("qemu-kvm version %u.%u.%u detected", major, minor, micro);
return 0;
@@ -560,7 +578,7 @@ int qemudExtractVersionInfo(const char *qemu,
pid_t child;
int newstdout = -1;
int ret = -1, status;
- unsigned int version, kvm_version;
+ unsigned int version, is_kvm, kvm_version;
unsigned int flags = 0;
if (retflags)
@@ -581,7 +599,7 @@ int qemudExtractVersionInfo(const char *qemu,
goto cleanup2;
}
- if (qemudParseHelpStr(help, &flags, &version, &kvm_version) == -1)
+ if (qemudParseHelpStr(help, &flags, &version, &is_kvm, &kvm_version) == -1)
goto cleanup2;
if (retversion)
--
1.6.2.5

View File

@@ -1,19 +1,23 @@
From fbd16cecc72494e8a9450f38197221f2f50c9d0e Mon Sep 17 00:00:00 2001
From 182a3cac2b4339e988802eb02279e7ab4c883c67 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.
Subject: [PATCH] Don't log monitor output to domain log file.
It's logged via the logging system already. Prefix monitor debug output with vm
name.
(cherry picked from commit 5caa1e0eb050a12fe8ed02cf635bb672a56cdb6f)
Fedora-patch: libvirt-0.6.2-do-not-log-monitor-output.patch
---
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
index 5ca3d20..cb738b2 100644
--- a/src/qemu_driver.c
+++ b/src/qemu_driver.c
@@ -1710,27 +1710,11 @@ qemudMonitorCommandExtra(const virDomainObjPtr vm,
@@ -1706,27 +1706,11 @@ qemudMonitorCommandExtra(const virDomainObjPtr vm,
goto error;
}
}
@@ -42,7 +46,7 @@ index 79ee072..f5b5fa5 100644
return -1;
}
@@ -2463,7 +2447,7 @@ static int qemudDomainGetMemoryBalloon(virConnectPtr conn,
@@ -2461,7 +2445,7 @@ static int qemudDomainGetMemoryBalloon(virConnectPtr conn,
goto cleanup;
}
@@ -51,7 +55,7 @@ index 79ee072..f5b5fa5 100644
if ((offset = strstr(reply, BALLOON_PREFIX)) != NULL) {
unsigned int memMB;
char *end;
@@ -2517,7 +2501,7 @@ static int qemudDomainSetMemoryBalloon(virConnectPtr conn,
@@ -2515,7 +2499,7 @@ static int qemudDomainSetMemoryBalloon(virConnectPtr conn,
/* If the command failed qemu prints: 'unknown command'
* No message is printed on success it seems */
@@ -60,7 +64,7 @@ index 79ee072..f5b5fa5 100644
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,
@@ -2810,7 +2794,7 @@ static int qemudDomainSave(virDomainPtr dom,
goto cleanup;
}
@@ -69,7 +73,7 @@ index 79ee072..f5b5fa5 100644
/* If the command isn't supported then qemu prints:
* unknown command: migrate" */
@@ -3658,7 +3642,7 @@ static int qemudDomainChangeEjectableMedia(virConnectPtr conn,
@@ -3662,7 +3646,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 */
@@ -78,7 +82,7 @@ index 79ee072..f5b5fa5 100644
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,
@@ -3723,7 +3707,7 @@ static int qemudDomainAttachPciDiskDevice(virConnectPtr conn,
return -1;
}
@@ -87,7 +91,7 @@ index 79ee072..f5b5fa5 100644
/* 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,
@@ -3791,7 +3775,7 @@ static int qemudDomainAttachUsbMassstorageDevice(virConnectPtr conn,
return -1;
}
@@ -96,7 +100,7 @@ index 79ee072..f5b5fa5 100644
/* If the command failed qemu prints:
* Could not add ... */
if (strstr(reply, "Could not add ")) {
@@ -3841,7 +3825,7 @@ static int qemudDomainAttachHostDevice(virConnectPtr conn,
@@ -3845,7 +3829,7 @@ static int qemudDomainAttachHostDevice(virConnectPtr conn,
return -1;
}
@@ -105,7 +109,7 @@ index 79ee072..f5b5fa5 100644
/* If the command failed qemu prints:
* Could not add ... */
if (strstr(reply, "Could not add ")) {
@@ -3980,7 +3964,7 @@ static int qemudDomainDetachPciDiskDevice(virConnectPtr conn,
@@ -3984,7 +3968,7 @@ static int qemudDomainDetachPciDiskDevice(virConnectPtr conn,
goto cleanup;
}
@@ -114,7 +118,7 @@ index 79ee072..f5b5fa5 100644
/* 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,
@@ -4214,7 +4198,7 @@ qemudDomainBlockStats (virDomainPtr dom,
"%s", _("'info blockstats' command failed"));
goto cleanup;
}
@@ -123,7 +127,7 @@ index 79ee072..f5b5fa5 100644
/* 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,
@@ -4255,21 +4239,25 @@ qemudDomainBlockStats (virDomainPtr dom,
if (STRPREFIX (p, "rd_bytes=")) {
p += 9;
if (virStrToLong_ll (p, &dummy, 10, &stats->rd_bytes) == -1)
@@ -154,7 +158,7 @@ index 79ee072..f5b5fa5 100644
/* Skip to next label. */
p = strchr (p, ' ');
@@ -4477,7 +4465,7 @@ qemudDomainMemoryPeek (virDomainPtr dom,
@@ -4481,7 +4469,7 @@ qemudDomainMemoryPeek (virDomainPtr dom,
goto cleanup;
}
@@ -163,7 +167,7 @@ index 79ee072..f5b5fa5 100644
/* Read the memory file into buffer. */
if (saferead (fd, buffer, size) == (ssize_t) -1) {
@@ -4794,7 +4782,7 @@ qemudDomainMigratePerform (virDomainPtr dom,
@@ -4798,7 +4786,7 @@ qemudDomainMigratePerform (virDomainPtr dom,
"%s", _("off-line migration specified, but suspend operation failed"));
goto cleanup;
}
@@ -172,7 +176,7 @@ index 79ee072..f5b5fa5 100644
VIR_FREE(info);
paused = 1;
@@ -4811,7 +4799,7 @@ qemudDomainMigratePerform (virDomainPtr dom,
@@ -4815,7 +4803,7 @@ qemudDomainMigratePerform (virDomainPtr dom,
snprintf (cmd, sizeof cmd, "migrate_set_speed %lum", resource);
qemudMonitorCommand (vm, cmd, &info);
@@ -181,7 +185,7 @@ index 79ee072..f5b5fa5 100644
VIR_FREE (info);
}
@@ -4830,7 +4818,7 @@ qemudDomainMigratePerform (virDomainPtr dom,
@@ -4834,7 +4822,7 @@ qemudDomainMigratePerform (virDomainPtr dom,
goto cleanup;
}
@@ -190,7 +194,7 @@ index 79ee072..f5b5fa5 100644
/* Now check for "fail" in the output string */
if (strstr(info, "fail") != NULL) {
@@ -4869,7 +4857,7 @@ cleanup:
@@ -4873,7 +4861,7 @@ cleanup:
vm->def->name);
}
else {
@@ -200,5 +204,5 @@ index 79ee072..f5b5fa5 100644
}
--
1.6.0.6
1.6.2.5

View File

@@ -1,7 +1,7 @@
From ae4523336ac06e3ff7cc7b416fad9e57998c6b54 Mon Sep 17 00:00:00 2001
From: Tim Waugh <twaugh@redhat.com>
Date: Fri, 3 Jul 2009 10:29:01 +0100
Subject: [PATCH 2/3] Don't unnecessarily try to change a file context
From 2d299525f5de29d11c6dc4810aa41e893535695b Mon Sep 17 00:00:00 2001
From: Mark McLoughlin <markmc@redhat.com>
Date: Fri, 3 Jul 2009 10:27:46 +0000
Subject: [PATCH] Don't unnecessarily try to change a file context
As pointed out by Tim Waugh here:
@@ -12,13 +12,15 @@ matches what we want.
(Fixed to use STREQ() and not use tabs, as pointed out by danpb)
Signed-off-by: Mark McLoughlin <markmc@redhat.com>
(cherry picked from commit add254feeaa830dd5af1118c141cb140bf55b5a7)
Fedora-patch: libvirt-0.6.2-do-not-unnecessarily-try-to-change-a-file-context.patch
---
src/security_selinux.c | 11 ++++++++++-
1 files changed, 10 insertions(+), 1 deletions(-)
diff --git a/src/security_selinux.c b/src/security_selinux.c
index db1c27d..c2015a1 100644
index 450fce2..8ebe1fe 100644
--- a/src/security_selinux.c
+++ b/src/security_selinux.c
@@ -280,10 +280,19 @@ static int

View File

@@ -1,17 +1,20 @@
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
From 9b41d6550b6bf8d4450bb5b86550eb605cc1fd91 Mon Sep 17 00:00:00 2001
From: Daniel P. Berrange <berrange@redhat.com>
Date: Fri, 8 May 2009 10:07:15 +0000
Subject: [PATCH] Enable save/restore/migrate for 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.
(cherry picked from commit 88e22e4e8cb7fc7e1fa1d132778aa1994f4b55b6)
Daniel
Fedora-patch: libvirt-0.6.2-enable-qemu-0-10-migration.patch
---
src/qemu_conf.c | 10 +++++-----
1 files changed, 5 insertions(+), 5 deletions(-)
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 *
diff --git a/src/qemu_conf.c b/src/qemu_conf.c
index 6f9e610..929fe00 100644
--- a/src/qemu_conf.c
+++ b/src/qemu_conf.c
@@ -472,16 +472,13 @@ int qemudExtractVersionInfo(const char *qemu,
/*
* Handling of -incoming arg with varying features
@@ -30,7 +33,7 @@ diff -r be7993675e07 src/qemu_conf.c
*/
if (kvm_version >= 79) {
flags |= QEMUD_CMD_FLAG_MIGRATE_QEMU_TCP;
@@ -489,6 +486,9 @@ int qemudExtractVersionInfo(const char *
@@ -489,6 +486,9 @@ int qemudExtractVersionInfo(const char *qemu,
flags |= QEMUD_CMD_FLAG_MIGRATE_QEMU_EXEC;
} else if (kvm_version > 0) {
flags |= QEMUD_CMD_FLAG_MIGRATE_KVM_STDIO;
@@ -40,6 +43,6 @@ diff -r be7993675e07 src/qemu_conf.c
}
if (retversion)
--
1.6.2.5

View File

@@ -1,17 +1,20 @@
From e7be6cc841a5652b73ddd2ccd3769c7f8bbad13d Mon Sep 17 00:00:00 2001
From 261ec2c9597b2eb6c7d91589fc66e203f60b6735 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
Subject: [PATCH] Fix interrupting of main event thread & protect against accidental uniniitalized variables
(cherry picked from commit 0a31be6ba243066378c344882cc1a32802774edb)
Fedora-patch: libvirt-0.6.2-event-handling-1.patch
---
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
index 0887008..4dc1020 100644
--- a/qemud/event.c
+++ b/qemud/event.c
@@ -84,10 +84,10 @@ struct virEventLoop {
@@ -83,10 +83,10 @@ struct virEventLoop {
static struct virEventLoop eventLoop;
/* Unique ID for the next FD watch to be registered */
@@ -24,7 +27,7 @@ index 65f548e..754f2b1 100644
static void virEventLock(void)
{
@@ -143,15 +143,22 @@ int virEventAddHandleImpl(int fd, int events,
@@ -142,15 +142,22 @@ int virEventAddHandleImpl(int fd, int events,
void virEventUpdateHandleImpl(int watch, int events) {
int i;
@@ -48,7 +51,7 @@ index 65f548e..754f2b1 100644
virEventUnlock();
}
@@ -164,6 +171,12 @@ void virEventUpdateHandleImpl(int watch, int events) {
@@ -163,6 +170,12 @@ void virEventUpdateHandleImpl(int watch, int events) {
int virEventRemoveHandleImpl(int watch) {
int i;
EVENT_DEBUG("Remove handle %d", watch);
@@ -61,7 +64,7 @@ index 65f548e..754f2b1 100644
virEventLock();
for (i = 0 ; i < eventLoop.handlesCount ; i++) {
if (eventLoop.handles[i].deleted)
@@ -172,11 +185,11 @@ int virEventRemoveHandleImpl(int watch) {
@@ -171,11 +184,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;
@@ -74,7 +77,7 @@ index 65f548e..754f2b1 100644
virEventUnlock();
return -1;
}
@@ -232,6 +245,12 @@ void virEventUpdateTimeoutImpl(int timer, int frequency) {
@@ -231,6 +244,12 @@ void virEventUpdateTimeoutImpl(int timer, int frequency) {
struct timeval tv;
int i;
EVENT_DEBUG("Updating timer %d timeout with %d ms freq", timer, frequency);
@@ -87,7 +90,7 @@ index 65f548e..754f2b1 100644
if (gettimeofday(&tv, NULL) < 0) {
return;
}
@@ -244,10 +263,10 @@ void virEventUpdateTimeoutImpl(int timer, int frequency) {
@@ -243,10 +262,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;
@@ -99,7 +102,7 @@ index 65f548e..754f2b1 100644
virEventUnlock();
}
@@ -260,6 +279,12 @@ void virEventUpdateTimeoutImpl(int timer, int frequency) {
@@ -259,6 +278,12 @@ void virEventUpdateTimeoutImpl(int timer, int frequency) {
int virEventRemoveTimeoutImpl(int timer) {
int i;
EVENT_DEBUG("Remove timer %d", timer);
@@ -112,7 +115,7 @@ index 65f548e..754f2b1 100644
virEventLock();
for (i = 0 ; i < eventLoop.timeoutsCount ; i++) {
if (eventLoop.timeouts[i].deleted)
@@ -267,11 +292,11 @@ int virEventRemoveTimeoutImpl(int timer) {
@@ -266,11 +291,11 @@ int virEventRemoveTimeoutImpl(int timer) {
if (eventLoop.timeouts[i].timer == timer) {
eventLoop.timeouts[i].deleted = 1;
@@ -125,7 +128,7 @@ index 65f548e..754f2b1 100644
virEventUnlock();
return -1;
}
@@ -617,9 +642,12 @@ static int virEventInterruptLocked(void)
@@ -616,9 +641,12 @@ static int virEventInterruptLocked(void)
char c = '\0';
if (!eventLoop.running ||
@@ -140,5 +143,5 @@ index 65f548e..754f2b1 100644
return -1;
return 0;
--
1.6.0.6
1.6.2.5

View File

@@ -1,17 +1,20 @@
From 6483ee77ed12f037d68a6adc690624fa1b508dc0 Mon Sep 17 00:00:00 2001
From ef1a3eaa58d83c3367a1addff6c8132f27aa09dd 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
Subject: [PATCH] Fix watch/timer event deletion
(cherry picked from commit 470317f5c71cbcc6b6d8d83d0978aea3510d3698)
Fedora-patch: libvirt-0.6.2-event-handling-2.patch
---
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
index 4dc1020..8bc7c34 100644
--- a/qemud/event.c
+++ b/qemud/event.c
@@ -313,7 +313,7 @@ static int virEventCalculateTimeout(int *timeout) {
@@ -312,7 +312,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++) {
@@ -20,7 +23,7 @@ index 754f2b1..a57d967 100644
continue;
EVENT_DEBUG("Got a timeout scheduled for %llu", eventLoop.timeouts[i].expiresAt);
@@ -350,32 +350,26 @@ static int virEventCalculateTimeout(int *timeout) {
@@ -349,32 +349,26 @@ static int virEventCalculateTimeout(int *timeout) {
* file handles. The caller must free the returned data struct
* returns: the pollfd array, or NULL on error
*/
@@ -66,7 +69,7 @@ index 754f2b1..a57d967 100644
}
@@ -435,26 +429,30 @@ static int virEventDispatchTimeouts(void) {
@@ -434,26 +428,30 @@ static int virEventDispatchTimeouts(void) {
* Returns 0 upon success, -1 if an error occurred
*/
static int virEventDispatchHandles(int nfds, struct pollfd *fds) {
@@ -106,7 +109,7 @@ index 754f2b1..a57d967 100644
}
return 0;
@@ -545,22 +543,21 @@ static int virEventCleanupHandles(void) {
@@ -544,22 +542,21 @@ static int virEventCleanupHandles(void) {
* at least one file handle has an event, or a timer expires
*/
int virEventRunOnce(void) {
@@ -138,7 +141,7 @@ index 754f2b1..a57d967 100644
virEventUnlock();
@@ -572,38 +569,31 @@ int virEventRunOnce(void) {
@@ -571,38 +568,31 @@ int virEventRunOnce(void) {
if (errno == EINTR) {
goto retry;
}
@@ -193,5 +196,5 @@ index 754f2b1..a57d967 100644
static void virEventHandleWakeup(int watch ATTRIBUTE_UNUSED,
--
1.6.0.6
1.6.2.5

View File

@@ -1,15 +1,19 @@
From 80965bff6d46dea1808c8bbf02f50f0e289a0e65 Mon Sep 17 00:00:00 2001
From d8bd0cff27c0572e9305e7fdbc6b843f74d9e30f Mon Sep 17 00:00:00 2001
From: Daniel P. Berrange <berrange@redhat.com>
Date: Mon, 29 Jun 2009 10:41:56 +0000
Subject: [PATCH] Fix crash in QEMU driver with bad capabilities data
(cherry picked from commit 39c7e7a6b79bbdfa36928a430d56fa88a204e8fd)
Fedora-patch: libvirt-0.6.2-fix-libvirtd-crash-with-bad-capabilities-data.patch
---
src/qemu_driver.c | 80 +++++++++++++++++++++++++++++++++++-----------------
1 files changed, 54 insertions(+), 26 deletions(-)
diff -up libvirt-0.6.2/src/qemu_driver.c.bad-caps libvirt-0.6.2/src/qemu_driver.c
--- libvirt-0.6.2/src/qemu_driver.c.bad-caps 2009-07-03 10:07:03.275252815 +0100
+++ libvirt-0.6.2/src/qemu_driver.c 2009-07-03 10:08:52.143502961 +0100
diff --git a/src/qemu_driver.c b/src/qemu_driver.c
index cb738b2..3d3675c 100644
--- a/src/qemu_driver.c
+++ b/src/qemu_driver.c
@@ -360,12 +360,43 @@ next:
return 0;
}
@@ -56,7 +60,7 @@ diff -up libvirt-0.6.2/src/qemu_driver.c.bad-caps libvirt-0.6.2/src/qemu_driver.
virSecurityDriverPtr security_drv;
ret = virSecurityDriverStartup(&security_drv,
@@ -381,36 +412,17 @@ qemudSecurityInit(struct qemud_driver *q
@@ -381,36 +412,17 @@ qemudSecurityInit(struct qemud_driver *qemud_drv)
}
qemud_drv->securityDriver = security_drv;
@@ -96,7 +100,7 @@ diff -up libvirt-0.6.2/src/qemu_driver.c.bad-caps libvirt-0.6.2/src/qemu_driver.
/**
* qemudStartup:
@@ -1852,13 +1864,29 @@ static int qemudGetNodeInfo(virConnectPt
@@ -1852,13 +1864,29 @@ static int qemudGetNodeInfo(virConnectPtr conn,
static char *qemudGetCapabilities(virConnectPtr conn) {
struct qemud_driver *driver = conn->privateData;
@@ -128,3 +132,6 @@ diff -up libvirt-0.6.2/src/qemu_driver.c.bad-caps libvirt-0.6.2/src/qemu_driver.
qemuDriverUnlock(driver);
return xml;
--
1.6.2.5

View File

@@ -1,7 +1,28 @@
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
From 99c018831379f23e65860ad4f3628a6d5f1a7d5a Mon Sep 17 00:00:00 2001
From: Mark McLoughlin <markmc@redhat.com>
Date: Fri, 3 Jul 2009 10:29:09 +0000
Subject: [PATCH] Skip labelling if no src path present
Fixes startup of guest's with sourceless cdrom devices.
Patch from Cole Robinson originally posted here:
https://bugzilla.redhat.com/499569
but never sent upstream.
(cherry picked from commit 67d0c6eb9410d5101f4820a7286deacb6398afde)
Fedora-patch: libvirt-0.6.2-fix-nosource-label.patch
---
src/security_selinux.c | 3 +++
1 files changed, 3 insertions(+), 0 deletions(-)
diff --git a/src/security_selinux.c b/src/security_selinux.c
index 95fa0a6..450fce2 100644
--- a/src/security_selinux.c
+++ b/src/security_selinux.c
@@ -338,6 +338,9 @@ SELinuxSetSecurityImageLabel(virConnectPtr conn,
{
const virSecurityLabelDefPtr secdef = &vm->def->seclabel;
@@ -11,3 +32,6 @@ diff -rup libvirt-0.6.2/src/security_selinux.c new/src/security_selinux.c
if (disk->shared) {
return SELinuxSetFilecon(conn, disk->src, default_image_context);
} else if (disk->readonly) {
--
1.6.2.5

View File

@@ -1,15 +1,18 @@
From 2b3fcdc378e7bec5c1a78b81632756e92930fd24 Mon Sep 17 00:00:00 2001
From 9f6a5f50aee13575331f79f5d93635f701646eb7 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
Subject: [PATCH] Fix QEMU ARGV detection with kvm >= 85
(cherry picked from commit 426f9772b84752b4901b72fd382ff6e28e258efd)
Fedora-patch: libvirt-0.6.2-fix-qemu-argv-detection-with-kvm-85.patch
---
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
index 929fe00..3e7e32d 100644
--- a/src/qemu_conf.c
+++ b/src/qemu_conf.c
@@ -431,18 +431,28 @@ int qemudExtractVersionInfo(const char *qemu,
@@ -46,10 +49,10 @@ index 9cb71eb..a57d3ab 100644
version = (major * 1000 * 1000) + (minor * 1000) + micro;
diff --git a/src/qemu_driver.c b/src/qemu_driver.c
index 30642d5..bd60b29 100644
index 4752a64..5ca3d20 100644
--- a/src/qemu_driver.c
+++ b/src/qemu_driver.c
@@ -1391,12 +1391,8 @@ static int qemudStartVMDaemon(virConnectPtr conn,
@@ -1379,12 +1379,8 @@ static int qemudStartVMDaemon(virConnectPtr conn,
if (qemudExtractVersionInfo(emulator,
NULL,
@@ -63,7 +66,7 @@ index 30642d5..bd60b29 100644
if (qemuPrepareHostDevices(conn, vm->def) < 0)
goto cleanup;
@@ -3715,12 +3711,8 @@ static int qemudDomainChangeEjectableMedia(virConnectPtr conn,
@@ -3606,12 +3602,8 @@ static int qemudDomainChangeEjectableMedia(virConnectPtr conn,
if (qemudExtractVersionInfo(vm->def->emulator,
NULL,
@@ -78,5 +81,5 @@ index 30642d5..bd60b29 100644
if (qemuCmdFlags & QEMUD_CMD_FLAG_DRIVE) {
if (!(devname = qemudDiskDeviceName(conn, newdisk)))
--
1.6.0.6
1.6.2.5

View File

@@ -0,0 +1,46 @@
From 0aac99f8e13dfc74b87986908165ae7f44662153 Mon Sep 17 00:00:00 2001
From: Daniel P. Berrange <berrange@redhat.com>
Date: Mon, 6 Jul 2009 16:01:55 +0100
Subject: [PATCH] Fix SELinux denial during hotplug
* src/qemu_driver.c: Relabel disk images *before* running QEMU
hotplug monitor commands
(cherry picked from commit 1795bfe4a177a5eff1b3b0a16d56df6f371c0f8e)
Fedora-patch: libvirt-0.6.2-hotplug-labelling.patch
---
src/qemu_driver.c | 6 ++++--
1 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/src/qemu_driver.c b/src/qemu_driver.c
index 5fc21a1..f3661f8 100644
--- a/src/qemu_driver.c
+++ b/src/qemu_driver.c
@@ -3934,10 +3934,14 @@ static int qemudDomainAttachDevice(virDomainPtr dom,
switch (dev->data.disk->device) {
case VIR_DOMAIN_DISK_DEVICE_CDROM:
case VIR_DOMAIN_DISK_DEVICE_FLOPPY:
+ if (driver->securityDriver)
+ driver->securityDriver->domainSetSecurityImageLabel(dom->conn, vm, dev->data.disk);
ret = qemudDomainChangeEjectableMedia(dom->conn, vm, dev);
break;
case VIR_DOMAIN_DISK_DEVICE_DISK:
+ if (driver->securityDriver)
+ driver->securityDriver->domainSetSecurityImageLabel(dom->conn, vm, dev->data.disk);
if (dev->data.disk->bus == VIR_DOMAIN_DISK_BUS_USB) {
ret = qemudDomainAttachUsbMassstorageDevice(dom->conn, vm, dev);
} else if (dev->data.disk->bus == VIR_DOMAIN_DISK_BUS_SCSI ||
@@ -3949,8 +3953,6 @@ static int qemudDomainAttachDevice(virDomainPtr dom,
virDomainDiskBusTypeToString(dev->data.disk->bus));
goto cleanup;
}
- if (driver->securityDriver)
- driver->securityDriver->domainSetSecurityImageLabel(dom->conn, vm, dev->data.disk);
break;
default:
--
1.6.2.5

View File

@@ -0,0 +1,134 @@
From ae80f9ec15b03d9d3ab6cfa2d48529b459a64fb2 Mon Sep 17 00:00:00 2001
From: Daniel P. Berrange <berrange@redhat.com>
Date: Mon, 6 Jul 2009 15:58:55 +0100
Subject: [PATCH] Fix PCI device hotplug/unplug with newer QEMU
* src/qemu_driver.c: Try new monitor syntax for hotplug first. If
that fails fallback to old KVM specific syntax
(cherry picked from commit 326ecb78145cfeb7706ef0dcd521b19d934950e7)
Fedora-patch: libvirt-0.6.2-hotplug-monitor-syntax.patch
---
src/qemu_driver.c | 56 +++++++++++++++++++++++++++++++++++++++-------------
1 files changed, 42 insertions(+), 14 deletions(-)
diff --git a/src/qemu_driver.c b/src/qemu_driver.c
index f3661f8..8473616 100644
--- a/src/qemu_driver.c
+++ b/src/qemu_driver.c
@@ -3724,6 +3724,7 @@ static int qemudDomainAttachPciDiskDevice(virConnectPtr conn,
char *cmd, *reply, *s;
char *safe_path;
const char* type = virDomainDiskBusTypeToString(dev->data.disk->bus);
+ int tryOldSyntax = 0;
for (i = 0 ; i < vm->def->ndisks ; i++) {
if (STREQ(vm->def->disks[i]->dst, dev->data.disk->dst)) {
@@ -3738,14 +3739,15 @@ static int qemudDomainAttachPciDiskDevice(virConnectPtr conn,
return -1;
}
+try_command:
safe_path = qemudEscapeMonitorArg(dev->data.disk->src);
if (!safe_path) {
virReportOOMError(conn);
return -1;
}
- ret = virAsprintf(&cmd, "pci_add 0 storage file=%s,if=%s",
- safe_path, type);
+ ret = virAsprintf(&cmd, "pci_add %s storage file=%s,if=%s",
+ (tryOldSyntax ? "0": "pci_addr=auto"), safe_path, type);
VIR_FREE(safe_path);
if (ret == -1) {
virReportOOMError(conn);
@@ -3761,17 +3763,27 @@ static int qemudDomainAttachPciDiskDevice(virConnectPtr conn,
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 "
- if ((s=strstr(reply, PCI_ATTACH_OK_MSG))) {
- char* dummy = s;
- s += strlen(PCI_ATTACH_OK_MSG);
+ * OK bus 0, slot XXX...
+ * or
+ * OK domain 0, bus 0, slot XXX
+ */
+ if ((s = strstr(reply, "OK ")) &&
+ (s = strstr(s, "slot "))) {
+ char *dummy = s;
+ s += strlen("slot ");
if (virStrToLong_i ((const char*)s, &dummy, 10, &dev->data.disk->slotnum) == -1)
VIR_WARN("%s", _("Unable to parse slot number\n"));
+ /* XXX not neccessarily always going to end up in domain 0 / bus 0 :-( */
+ /* XXX this slotnum is not persistant across restarts :-( */
+ } else if (!tryOldSyntax && strstr(reply, "invalid char in expression")) {
+ VIR_FREE(reply);
+ VIR_FREE(cmd);
+ tryOldSyntax = 1;
+ goto try_command;
} else {
qemudReportError (conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
- _("adding %s disk failed"), type);
+ _("adding %s disk failed: %s"), type, reply);
VIR_FREE(reply);
VIR_FREE(cmd);
return -1;
@@ -3990,6 +4002,7 @@ static int qemudDomainDetachPciDiskDevice(virConnectPtr conn,
char *cmd = NULL;
char *reply = NULL;
virDomainDiskDefPtr detach = NULL;
+ int tryOldSyntax = 0;
for (i = 0 ; i < vm->def->ndisks ; i++) {
if (STREQ(vm->def->disks[i]->dst, dev->data.disk->dst)) {
@@ -4011,9 +4024,17 @@ static int qemudDomainDetachPciDiskDevice(virConnectPtr conn,
goto cleanup;
}
- if (virAsprintf(&cmd, "pci_del 0 %d", detach->slotnum) < 0) {
- virReportOOMError(conn);
- goto cleanup;
+try_command:
+ if (tryOldSyntax) {
+ if (virAsprintf(&cmd, "pci_del 0 %d", detach->slotnum) < 0) {
+ virReportOOMError(conn);
+ goto cleanup;
+ }
+ } else {
+ if (virAsprintf(&cmd, "pci_del pci_addr=0:0:%d", detach->slotnum) < 0) {
+ virReportOOMError(conn);
+ goto cleanup;
+ }
}
if (qemudMonitorCommand(vm, cmd, &reply) < 0) {
@@ -4023,12 +4044,19 @@ static int qemudDomainDetachPciDiskDevice(virConnectPtr conn,
}
DEBUG ("%s: pci_del reply: %s",vm->def->name, reply);
+
+ if (!tryOldSyntax &&
+ strstr(reply, "extraneous characters")) {
+ tryOldSyntax = 1;
+ goto try_command;
+ }
/* If the command fails due to a wrong slot qemu prints: invalid slot,
* nothing is printed on success */
- if (strstr(reply, "invalid slot")) {
+ if (strstr(reply, "invalid slot") ||
+ strstr(reply, "Invalid pci address")) {
qemudReportError (conn, NULL, NULL, VIR_ERR_OPERATION_FAILED,
- _("failed to detach disk %s: invalid slot %d"),
- detach->dst, detach->slotnum);
+ _("failed to detach disk %s: invalid slot %d: %s"),
+ detach->dst, detach->slotnum, reply);
goto cleanup;
}
--
1.6.2.5

View File

@@ -1,14 +1,17 @@
From c3b3f6005d45552d01823504925eb587889cf25a Mon Sep 17 00:00:00 2001
From 2c42e4c96efd390fa7a6957692a5863d30a10828 Mon Sep 17 00:00:00 2001
From: Daniel P. Berrange <berrange@redhat.com>
Date: Fri, 29 May 2009 14:34:35 +0000
Subject: [PATCH 1/1] Avoid double-free in daemon client cleanup code
Subject: [PATCH] Avoid double-free in daemon client cleanup code
(cherry picked from commit 6c3ef350649b959215cfc5ccfdaba35bf9560066)
Fedora-patch: libvirt-0.6.2-libvirtd-double-free.patch
---
qemud/qemud.c | 22 +++++++++++++++++-----
1 files changed, 17 insertions(+), 5 deletions(-)
diff --git a/qemud/qemud.c b/qemud/qemud.c
index 1375560..783dc69 100644
index 4f04355..e299a67 100644
--- a/qemud/qemud.c
+++ b/qemud/qemud.c
@@ -1397,7 +1397,10 @@ static int qemudDispatchServer(struct qemud_server *server, struct qemud_socket
@@ -23,7 +26,7 @@ index 1375560..783dc69 100644
/* Deregister event delivery callback */
if(client->conn) {
@@ -1406,12 +1406,21 @@ void qemudDispatchClientFailure(struct qemud_client *client) {
@@ -1406,12 +1409,21 @@ void qemudDispatchClientFailure(struct qemud_client *client) {
}
#if HAVE_SASL
@@ -50,5 +53,5 @@ index 1375560..783dc69 100644
--
1.6.0.6
1.6.2.5

View File

@@ -0,0 +1,60 @@
From eb2fad7e94ba9bf48787e24542931688b9926ca1 Mon Sep 17 00:00:00 2001
From: Daniel P. Berrange <berrange@redhat.com>
Date: Mon, 6 Jul 2009 15:45:04 +0100
Subject: [PATCH] Fix problem with QEMU monitor welcome prompt confusing libvirt after a libvirtd daemon restart with active guests
* src/qemu_driver: Read and dicard pending monitor data
before issuing new monitor commands.
(cherry picked from commit 2d1f2e706c8b13571e1227df1c69b2302da35d5a)
Fedora-patch: libvirt-0.6.2-monitor-prompt-discard.patch
---
src/qemu_driver.c | 24 ++++++++++++++++++++++++
1 files changed, 24 insertions(+), 0 deletions(-)
diff --git a/src/qemu_driver.c b/src/qemu_driver.c
index 3d3675c..5fc21a1 100644
--- a/src/qemu_driver.c
+++ b/src/qemu_driver.c
@@ -1636,6 +1636,28 @@ cleanup:
qemuDriverUnlock(driver);
}
+
+/* Throw away any data available on the monitor
+ * This is done before executing a command, in order
+ * to allow re-synchronization if something went badly
+ * wrong in the past. it also deals with problem of
+ * QEMU *sometimes* re-printing its initial greeting
+ * when we reconnect to the monitor after restarts.
+ */
+static void
+qemuMonitorDiscardPendingData(virDomainObjPtr vm) {
+ char buf[1024];
+ int ret = 0;
+
+ /* Monitor is non-blocking, so just loop till we
+ * get -1 or 0. Don't bother with detecting
+ * errors, since we'll deal with that better later */
+ do {
+ ret = read(vm->monitor, buf, sizeof (buf)-1);
+ } while (ret > 0);
+}
+
+
static int
qemudMonitorCommandExtra(const virDomainObjPtr vm,
const char *cmd,
@@ -1647,6 +1669,8 @@ qemudMonitorCommandExtra(const virDomainObjPtr vm,
size_t cmdlen = strlen(cmd);
size_t extralen = extra ? strlen(extra) : 0;
+ qemuMonitorDiscardPendingData(vm);
+
if (safewrite(vm->monitor, cmd, cmdlen) != cmdlen)
return -1;
if (safewrite(vm->monitor, "\r", 1) != 1)
--
1.6.2.5

View File

@@ -0,0 +1,159 @@
From 3cf2f90a4747547f9877b15c1f573f8a771098e8 Mon Sep 17 00:00:00 2001
From: Daniel P. Berrange <berrange@redhat.com>
Date: Mon, 29 Jun 2009 10:41:56 +0000
Subject: [PATCH] Fix crash in QEMU driver with bad capabilities data
(cherry picked from commit 39c7e7a6b79bbdfa36928a430d56fa88a204e8fd)
Fedora-patch: libvirt-0.6.2-numa-ignore-fail.patch
---
src/capabilities.c | 16 +++++++++++++---
src/capabilities.h | 3 +++
src/libvirt_private.syms | 1 +
src/lxc_conf.c | 11 +++++++++--
src/qemu_conf.c | 10 ++++++++--
src/uml_conf.c | 11 +++++++++--
6 files changed, 43 insertions(+), 9 deletions(-)
diff --git a/src/capabilities.c b/src/capabilities.c
index d6e3478..8dc32a1 100644
--- a/src/capabilities.c
+++ b/src/capabilities.c
@@ -122,6 +122,18 @@ virCapabilitiesFreeGuest(virCapsGuestPtr guest)
}
+void
+virCapabilitiesFreeNUMAInfo(virCapsPtr caps)
+{
+ int i;
+
+ for (i = 0 ; i < caps->host.nnumaCell ; i++)
+ virCapabilitiesFreeHostNUMACell(caps->host.numaCell[i]);
+ VIR_FREE(caps->host.numaCell);
+ caps->host.nnumaCell = 0;
+}
+
+
/**
* virCapabilitiesFree:
* @caps: object to free
@@ -141,9 +153,7 @@ virCapabilitiesFree(virCapsPtr caps) {
for (i = 0 ; i < caps->host.nfeatures ; i++)
VIR_FREE(caps->host.features[i]);
VIR_FREE(caps->host.features);
- for (i = 0 ; i < caps->host.nnumaCell ; i++)
- virCapabilitiesFreeHostNUMACell(caps->host.numaCell[i]);
- VIR_FREE(caps->host.numaCell);
+ virCapabilitiesFreeNUMAInfo(caps);
for (i = 0 ; i < caps->host.nmigrateTrans ; i++)
VIR_FREE(caps->host.migrateTrans[i]);
diff --git a/src/capabilities.h b/src/capabilities.h
index 5b0bbab..1b49666 100644
--- a/src/capabilities.h
+++ b/src/capabilities.h
@@ -118,6 +118,9 @@ extern void
virCapabilitiesFree(virCapsPtr caps);
extern void
+virCapabilitiesFreeNUMAInfo(virCapsPtr caps);
+
+extern void
virCapabilitiesSetMacPrefix(virCapsPtr caps,
unsigned char *prefix);
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 350a931..9249a1a 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -24,6 +24,7 @@ virCapabilitiesDefaultGuestEmulator;
virCapabilitiesDefaultGuestMachine;
virCapabilitiesFormatXML;
virCapabilitiesFree;
+virCapabilitiesFreeNUMAInfo;
virCapabilitiesNew;
virCapabilitiesSetMacPrefix;
virCapabilitiesGenerateMac;
diff --git a/src/lxc_conf.c b/src/lxc_conf.c
index 34c8aea..fe721e3 100644
--- a/src/lxc_conf.c
+++ b/src/lxc_conf.c
@@ -30,6 +30,7 @@
#include "lxc_conf.h"
#include "nodeinfo.h"
#include "virterror_internal.h"
+#include "logging.h"
#define VIR_FROM_THIS VIR_FROM_LXC
@@ -46,8 +47,14 @@ virCapsPtr lxcCapsInit(void)
0, 0)) == NULL)
goto no_memory;
- if (virCapsInitNUMA(caps) < 0)
- goto no_memory;
+ /* Some machines have problematic NUMA toplogy causing
+ * unexpected failures. We don't want to break the QEMU
+ * driver in this scenario, so log errors & carry on
+ */
+ if (virCapsInitNUMA(caps) < 0) {
+ virCapabilitiesFreeNUMAInfo(caps);
+ VIR_WARN0("Failed to query host NUMA topology, disabling NUMA capabilities");
+ }
/* XXX shouldn't 'borrow' KVM's prefix */
virCapabilitiesSetMacPrefix(caps, (unsigned char []){ 0x52, 0x54, 0x00 });
diff --git a/src/qemu_conf.c b/src/qemu_conf.c
index 99f13c6..1194e36 100644
--- a/src/qemu_conf.c
+++ b/src/qemu_conf.c
@@ -376,8 +376,14 @@ virCapsPtr qemudCapsInit(void) {
/* Using KVM's mac prefix for QEMU too */
virCapabilitiesSetMacPrefix(caps, (unsigned char[]){ 0x52, 0x54, 0x00 });
- if (virCapsInitNUMA(caps) < 0)
- goto no_memory;
+ /* Some machines have problematic NUMA toplogy causing
+ * unexpected failures. We don't want to break the QEMU
+ * driver in this scenario, so log errors & carry on
+ */
+ if (virCapsInitNUMA(caps) < 0) {
+ virCapabilitiesFreeNUMAInfo(caps);
+ VIR_WARN0("Failed to query host NUMA topology, disabling NUMA capabilities");
+ }
/* First the pure HVM guests */
for (i = 0 ; i < ARRAY_CARDINALITY(arch_info_hvm) ; i++)
diff --git a/src/uml_conf.c b/src/uml_conf.c
index c0d086e..9dd4967 100644
--- a/src/uml_conf.c
+++ b/src/uml_conf.c
@@ -44,6 +44,7 @@
#include "memory.h"
#include "nodeinfo.h"
#include "verify.h"
+#include "logging.h"
#define VIR_FROM_THIS VIR_FROM_UML
@@ -62,8 +63,14 @@ virCapsPtr umlCapsInit(void) {
0, 0)) == NULL)
goto no_memory;
- if (virCapsInitNUMA(caps) < 0)
- goto no_memory;
+ /* Some machines have problematic NUMA toplogy causing
+ * unexpected failures. We don't want to break the QEMU
+ * driver in this scenario, so log errors & carry on
+ */
+ if (virCapsInitNUMA(caps) < 0) {
+ virCapabilitiesFreeNUMAInfo(caps);
+ VIR_WARN0("Failed to query host NUMA topology, disabling NUMA capabilities");
+ }
if ((guest = virCapabilitiesAddGuest(caps,
"uml",
--
1.6.2.5

View File

@@ -0,0 +1,31 @@
From d5d67ea357d92759d4a9ecb213e577835f961eed Mon Sep 17 00:00:00 2001
From: Daniel P. Berrange <berrange@redhat.com>
Date: Thu, 16 Jul 2009 13:23:32 +0100
Subject: [PATCH] Fix free of unitialized data upon PCI open fail
(cherry picked from commit 4a7acedd3c59a6a750576cb8680bc3f08fe0b52c)
Fedora-patch: libvirt-0.6.2-pci-device-crash.patch
---
src/pci.c | 4 +---
1 files changed, 1 insertions(+), 3 deletions(-)
diff --git a/src/pci.c b/src/pci.c
index ed64d68..68a380d 100644
--- a/src/pci.c
+++ b/src/pci.c
@@ -829,10 +829,8 @@ pciReadDeviceID(pciDevice *dev, const char *id_name)
dev->name, id_name);
/* ID string is '0xNNNN\n' ... i.e. 7 bytes */
- if (virFileReadAll(path, 7, &id_str) < 7) {
- VIR_FREE(id_str);
+ if (virFileReadAll(path, 7, &id_str) < 0)
return NULL;
- }
/* Check for 0x suffix */
if (id_str[0] != '0' || id_str[1] != 'x') {
--
1.6.2.5

View File

@@ -1,15 +1,17 @@
From 0ae4c67ff5f1d24698c5cfc8a9719d333c892644 Mon Sep 17 00:00:00 2001
From bf7b58a2471a07111f8022c0176f45ee5dc5fe71 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=
Date: Thu, 16 Apr 2009 14:21:35 +0000
Subject: [PATCH] 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>
(cherry picked from commit 9fa79000ecc883c699a6cb1ce7f00c34881bc8fe)
Fedora-patch: libvirt-0.6.2-qemu-drive-format.patch
---
src/qemu_conf.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
src/qemu_conf.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/src/qemu_conf.c b/src/qemu_conf.c
index f36c927..6f9e610 100644
@@ -24,3 +26,6 @@ index f36c927..6f9e610 100644
if (disk->cachemode) {
const char *mode =
--
1.6.2.5

View File

@@ -0,0 +1,176 @@
From 1f1a0ca63c5492c7d41a0cdbd452a2743f314ebc Mon Sep 17 00:00:00 2001
From: Daniel P. Berrange <berrange@redhat.com>
Date: Fri, 8 May 2009 10:11:14 +0000
Subject: [PATCH] Improve name & UUID uniqueness checking in QEMU driver
(cherry picked from commit 54ebbde1e18ec831ff2fddb44ec27ed5dde7874a)
Fedora-patch: libvirt-0.6.2-qemu-name-uniqueness.patch
---
src/qemu_driver.c | 103 ++++++++++++++++++++++++++++++++++++++++++----------
1 files changed, 83 insertions(+), 20 deletions(-)
diff --git a/src/qemu_driver.c b/src/qemu_driver.c
index 8473616..dfd19c5 100644
--- a/src/qemu_driver.c
+++ b/src/qemu_driver.c
@@ -2174,22 +2174,37 @@ static virDomainPtr qemudDomainCreate(virConnectPtr conn, const char *xml,
if (virSecurityDriverVerify(conn, def) < 0)
goto cleanup;
- vm = virDomainFindByName(&driver->domains, def->name);
- if (vm) {
- qemudReportError(conn, NULL, NULL, VIR_ERR_OPERATION_FAILED,
- _("domain '%s' is already defined"),
- def->name);
- goto cleanup;
- }
+ /* See if a VM with matching UUID already exists */
vm = virDomainFindByUUID(&driver->domains, def->uuid);
if (vm) {
- char uuidstr[VIR_UUID_STRING_BUFLEN];
+ /* UUID matches, but if names don't match, refuse it */
+ if (STRNEQ(vm->def->name, def->name)) {
+ char uuidstr[VIR_UUID_STRING_BUFLEN];
+ virUUIDFormat(vm->def->uuid, uuidstr);
+ qemudReportError(conn, NULL, NULL, VIR_ERR_OPERATION_FAILED,
+ _("domain '%s' is already defined with uuid %s"),
+ vm->def->name, uuidstr);
+ goto cleanup;
+ }
- virUUIDFormat(def->uuid, uuidstr);
- qemudReportError(conn, NULL, NULL, VIR_ERR_OPERATION_FAILED,
- _("domain with uuid '%s' is already defined"),
- uuidstr);
- goto cleanup;
+ /* UUID & name match, but if VM is already active, refuse it */
+ if (virDomainIsActive(vm)) {
+ qemudReportError(conn, NULL, NULL, VIR_ERR_OPERATION_FAILED,
+ _("domain is already active as '%s'"), vm->def->name);
+ goto cleanup;
+ }
+ virDomainObjUnlock(vm);
+ } else {
+ /* UUID does not match, but if a name matches, refuse it */
+ vm = virDomainFindByName(&driver->domains, def->name);
+ if (vm) {
+ char uuidstr[VIR_UUID_STRING_BUFLEN];
+ virUUIDFormat(vm->def->uuid, uuidstr);
+ qemudReportError(conn, NULL, NULL, VIR_ERR_OPERATION_FAILED,
+ _("domain '%s' is already defined with uuid %s"),
+ def->name, uuidstr);
+ goto cleanup;
+ }
}
if (!(vm = virDomainAssignDef(conn,
@@ -2368,6 +2383,11 @@ static int qemudDomainDestroy(virDomainPtr dom) {
_("no domain with matching id %d"), dom->id);
goto cleanup;
}
+ if (!virDomainIsActive(vm)) {
+ qemudReportError(dom->conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
+ "%s", _("domain is not running"));
+ goto cleanup;
+ }
qemudShutdownVMDaemon(dom->conn, driver, vm);
event = virDomainEventNewFromObj(vm,
@@ -3272,17 +3292,36 @@ static int qemudDomainRestore(virConnectPtr conn,
goto cleanup;
}
- /* Ensure the name and UUID don't already exist in an active VM */
+ /* See if a VM with matching UUID already exists */
vm = virDomainFindByUUID(&driver->domains, def->uuid);
- if (!vm)
- vm = virDomainFindByName(&driver->domains, def->name);
if (vm) {
+ /* UUID matches, but if names don't match, refuse it */
+ if (STRNEQ(vm->def->name, def->name)) {
+ char uuidstr[VIR_UUID_STRING_BUFLEN];
+ virUUIDFormat(vm->def->uuid, uuidstr);
+ qemudReportError(conn, NULL, NULL, VIR_ERR_OPERATION_FAILED,
+ _("domain '%s' is already defined with uuid %s"),
+ vm->def->name, uuidstr);
+ goto cleanup;
+ }
+
+ /* UUID & name match, but if VM is already active, refuse it */
if (virDomainIsActive(vm)) {
qemudReportError(conn, NULL, NULL, VIR_ERR_OPERATION_FAILED,
_("domain is already active as '%s'"), vm->def->name);
goto cleanup;
- } else {
- virDomainObjUnlock(vm);
+ }
+ virDomainObjUnlock(vm);
+ } else {
+ /* UUID does not match, but if a name matches, refuse it */
+ vm = virDomainFindByName(&driver->domains, def->name);
+ if (vm) {
+ char uuidstr[VIR_UUID_STRING_BUFLEN];
+ virUUIDFormat(vm->def->uuid, uuidstr);
+ qemudReportError(conn, NULL, NULL, VIR_ERR_OPERATION_FAILED,
+ _("domain '%s' is already defined with uuid %s"),
+ def->name, uuidstr);
+ goto cleanup;
}
}
@@ -3470,18 +3509,41 @@ static virDomainPtr qemudDomainDefine(virConnectPtr conn, const char *xml) {
if (virSecurityDriverVerify(conn, def) < 0)
goto cleanup;
- vm = virDomainFindByName(&driver->domains, def->name);
+ /* See if a VM with matching UUID already exists */
+ vm = virDomainFindByUUID(&driver->domains, def->uuid);
if (vm) {
+ /* UUID matches, but if names don't match, refuse it */
+ if (STRNEQ(vm->def->name, def->name)) {
+ char uuidstr[VIR_UUID_STRING_BUFLEN];
+ virUUIDFormat(vm->def->uuid, uuidstr);
+ qemudReportError(conn, NULL, NULL, VIR_ERR_OPERATION_FAILED,
+ _("domain '%s' is already defined with uuid %s"),
+ vm->def->name, uuidstr);
+ goto cleanup;
+ }
+
+ /* UUID & name match */
virDomainObjUnlock(vm);
newVM = 0;
+ } else {
+ /* UUID does not match, but if a name matches, refuse it */
+ vm = virDomainFindByName(&driver->domains, def->name);
+ if (vm) {
+ char uuidstr[VIR_UUID_STRING_BUFLEN];
+ virUUIDFormat(vm->def->uuid, uuidstr);
+ qemudReportError(conn, NULL, NULL, VIR_ERR_OPERATION_FAILED,
+ _("domain '%s' is already defined with uuid %s"),
+ def->name, uuidstr);
+ goto cleanup;
+ }
}
if (!(vm = virDomainAssignDef(conn,
&driver->domains,
def))) {
- virDomainDefFree(def);
goto cleanup;
}
+ def = NULL;
vm->persistent = 1;
if (virDomainSaveConfig(conn,
@@ -3503,6 +3565,7 @@ static virDomainPtr qemudDomainDefine(virConnectPtr conn, const char *xml) {
if (dom) dom->id = vm->def->id;
cleanup:
+ virDomainDefFree(def);
if (vm)
virDomainObjUnlock(vm);
if (event)
--
1.6.2.5

View File

@@ -1,12 +1,11 @@
From daf3db93457427c25325781af684758c0341a6aa Mon Sep 17 00:00:00 2001
From 5c1ff776a3194bcc5d593aedd36cd676f1fcab64 Mon Sep 17 00:00:00 2001
From: Daniel Veillard <veillard@redhat.com>
Date: Fri, 29 May 2009 13:32:06 +0000
Subject: [PATCH 1/1] PPC Qemu Machine Type update
* src/qemu_conf.c docs/schemas/domain.rng
tests/capabilityschemadata/caps-qemu-kvm.xml: PPC Qemu Machine Type
changed from g3bw to g3beige some time ago, patch by Thomas Baker
Daniel
Subject: [PATCH] PPC Qemu Machine Type update * src/qemu_conf.c docs/schemas/domain.rng tests/capabilityschemadata/caps-qemu-kvm.xml: PPC Qemu Machine Type changed from g3bw to g3beige some time ago, patch by Thomas Baker
(cherry picked from commit 525c3d40a97a1ccce7c4dc314d2dd9e780b50d41)
Fedora-patch: libvirt-0.6.2-qemu-ppc-machine-type.patch
---
docs/schemas/domain.rng | 2 +-
src/qemu_conf.c | 2 +-
@@ -14,7 +13,7 @@ Subject: [PATCH 1/1] PPC Qemu Machine Type update
3 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/docs/schemas/domain.rng b/docs/schemas/domain.rng
index 204c633..11cf04a 100644
index 2f784e1..b29079a 100644
--- a/docs/schemas/domain.rng
+++ b/docs/schemas/domain.rng
@@ -184,7 +184,7 @@
@@ -27,7 +26,7 @@ index 204c633..11cf04a 100644
<value>prep</value>
</choice>
diff --git a/src/qemu_conf.c b/src/qemu_conf.c
index 18156cd..d54f2ca 100644
index 3e7e32d..fc0e772 100644
--- a/src/qemu_conf.c
+++ b/src/qemu_conf.c
@@ -192,7 +192,7 @@ static const char *const arch_info_hvm_sparc_machines[] = {
@@ -53,5 +52,5 @@ index fd8523e..893f9ed 100644
<machine>prep</machine>
<domain type='qemu'>
--
1.6.0.6
1.6.2.5

View File

@@ -0,0 +1,224 @@
From 266df161bfd87220bac68918613a2ce9323c8238 Mon Sep 17 00:00:00 2001
From: Mark McLoughlin <markmc@redhat.com>
Date: Thu, 11 Jun 2009 14:12:30 +0000
Subject: [PATCH] Re-factor qemu version parsing
This patch is purely re-factoring without any functional changes
to make way for the next patch.
The main thing achieved by the refactoring is that we now have
easier access to the parenthesised string that KVM folks seem
to delight in changing.
(cherry picked from commit 56ecebf22dd5a235503028e20bf936229037664b)
Signed-off-by: Mark McLoughlin <markmc@redhat.com>
Fedora-patch: libvirt-0.6.2-refactor-qemu-version-parsing.patch
---
src/qemu_conf.c | 174 +++++++++++++++++++++++++++++++++++++++----------------
1 files changed, 123 insertions(+), 51 deletions(-)
diff --git a/src/qemu_conf.c b/src/qemu_conf.c
index 1194e36..e488d74 100644
--- a/src/qemu_conf.c
+++ b/src/qemu_conf.c
@@ -414,54 +414,12 @@ virCapsPtr qemudCapsInit(void) {
return NULL;
}
-
-int qemudExtractVersionInfo(const char *qemu,
- unsigned int *retversion,
- unsigned int *retflags) {
- const char *const qemuarg[] = { qemu, "-help", NULL };
- const char *const qemuenv[] = { "LC_ALL=C", NULL };
- pid_t child;
- int newstdout = -1;
- int ret = -1, status;
- unsigned int major, minor, micro;
- unsigned int version, kvm_version;
+static unsigned int qemudComputeCmdFlags(const char *help,
+ unsigned int version,
+ unsigned int kvm_version)
+{
unsigned int flags = 0;
- if (retflags)
- *retflags = 0;
- if (retversion)
- *retversion = 0;
-
- if (virExec(NULL, qemuarg, qemuenv, NULL,
- &child, -1, &newstdout, NULL, VIR_EXEC_NONE) < 0)
- return -1;
-
- char *help = NULL;
- enum { MAX_HELP_OUTPUT_SIZE = 1024*64 };
- int len = virFileReadLimFD(newstdout, MAX_HELP_OUTPUT_SIZE, &help);
- 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) {
- 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;
-
if (strstr(help, "-no-kqemu"))
flags |= QEMUD_CMD_FLAG_KQEMU;
if (strstr(help, "-no-kvm"))
@@ -507,6 +465,125 @@ int qemudExtractVersionInfo(const char *qemu,
flags |= QEMUD_CMD_FLAG_MIGRATE_QEMU_EXEC;
}
+ return flags;
+}
+
+/* We parse the output of 'qemu -help' to get the QEMU
+ * version number. The first bit is easy, just parse
+ * 'QEMU PC emulator version x.y.z'.
+ *
+ * With qemu-kvm, however, that is followed by a kvm-XX
+ * string in parenthesis.
+ */
+#define QEMU_VERSION_STR "QEMU PC emulator version"
+#define KVM_VER_PREFIX "(kvm-"
+
+#define SKIP_BLANKS(p) do { while ((*(p) == ' ') || (*(p) == '\t')) (p)++; } while (0)
+
+static int qemudParseHelpStr(const char *help,
+ unsigned int *flags,
+ unsigned int *version,
+ unsigned int *kvm_version)
+{
+ unsigned major, minor, micro;
+ const char *p = help;
+
+ *flags = *version = *kvm_version = 0;
+
+ if (!STRPREFIX(p, QEMU_VERSION_STR))
+ goto fail;
+
+ p += strlen(QEMU_VERSION_STR);
+
+ SKIP_BLANKS(p);
+
+ major = virParseNumber(&p);
+ if (major == -1 || *p != '.')
+ goto fail;
+
+ ++p;
+
+ minor = virParseNumber(&p);
+ if (major == -1 || *p != '.')
+ goto fail;
+
+ ++p;
+
+ micro = virParseNumber(&p);
+ if (major == -1)
+ goto fail;
+
+ SKIP_BLANKS(p);
+
+ if (STRPREFIX(p, KVM_VER_PREFIX)) {
+ int ret;
+
+ p += strlen(KVM_VER_PREFIX);
+
+ ret = virParseNumber(&p);
+ if (ret == -1)
+ goto fail;
+
+ *kvm_version = ret;
+ }
+
+ *version = (major * 1000 * 1000) + (minor * 1000) + micro;
+
+ *flags = qemudComputeCmdFlags(help, *version, *kvm_version);
+
+ qemudDebug("Version %u.%u.%u, cooked version %u, flags %u",
+ major, minor, micro, *version, *flags);
+ if (*kvm_version)
+ qemudDebug("KVM version %u detected", *kvm_version);
+
+ return 0;
+
+fail:
+ p = strchr(help, '\n');
+ if (p)
+ p = strndup(help, p - help);
+
+ qemudReportError(NULL, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
+ _("cannot parse QEMU version number in '%s'"),
+ p ? p : help);
+
+ VIR_FREE(p);
+
+ return -1;
+}
+
+int qemudExtractVersionInfo(const char *qemu,
+ unsigned int *retversion,
+ unsigned int *retflags) {
+ const char *const qemuarg[] = { qemu, "-help", NULL };
+ const char *const qemuenv[] = { "LC_ALL=C", NULL };
+ pid_t child;
+ int newstdout = -1;
+ int ret = -1, status;
+ unsigned int version, kvm_version;
+ unsigned int flags = 0;
+
+ if (retflags)
+ *retflags = 0;
+ if (retversion)
+ *retversion = 0;
+
+ if (virExec(NULL, qemuarg, qemuenv, NULL,
+ &child, -1, &newstdout, NULL, VIR_EXEC_NONE) < 0)
+ return -1;
+
+ char *help = NULL;
+ enum { MAX_HELP_OUTPUT_SIZE = 1024*64 };
+ int len = virFileReadLimFD(newstdout, MAX_HELP_OUTPUT_SIZE, &help);
+ if (len < 0) {
+ virReportSystemError(NULL, errno, "%s",
+ _("Unable to read QEMU help output"));
+ goto cleanup2;
+ }
+
+ if (qemudParseHelpStr(help, &flags, &version, &kvm_version) == -1)
+ goto cleanup2;
+
if (retversion)
*retversion = version;
if (retflags)
@@ -514,11 +591,6 @@ int qemudExtractVersionInfo(const char *qemu,
ret = 0;
- qemudDebug("Version %d %d %d Cooked version: %d, with flags ? %d",
- major, minor, micro, version, flags);
- if (kvm_version)
- qemudDebug("KVM version %d detected", kvm_version);
-
cleanup2:
VIR_FREE(help);
if (close(newstdout) < 0)
--
1.6.2.5

View File

@@ -1,6 +1,27 @@
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
From 36cf92efa2b22f275bdc56411d9704e530cdb3fa Mon Sep 17 00:00:00 2001
From: Mark McLoughlin <markmc@redhat.com>
Date: Fri, 3 Jul 2009 10:26:37 +0000
Subject: [PATCH] Re-label shared and readonly images
This patch was posted ages ago here:
https://bugzilla.redhat.com/493692
But was never posted upstream AFAICT.
Patch from Dan Berrange
(cherry picked from commit 547147084d03ebf30d09d242a5a721a4df664ffe)
Fedora-patch: libvirt-0.6.2-shared-readonly-label.patch
---
src/security_selinux.c | 26 +++++++++++++++++++-------
1 files changed, 19 insertions(+), 7 deletions(-)
diff --git a/src/security_selinux.c b/src/security_selinux.c
index ac317d7..95fa0a6 100644
--- a/src/security_selinux.c
+++ b/src/security_selinux.c
@@ -24,11 +24,12 @@
#include "virterror_internal.h"
#include "util.h"
@@ -31,7 +52,7 @@ diff -rup libvirt-0.6.2/src/security_selinux.c libvirt-0.6.2.new/src/security_se
return 0;
}
@@ -275,6 +281,8 @@ SELinuxSetFilecon(virConnectPtr conn, co
@@ -275,6 +281,8 @@ SELinuxSetFilecon(virConnectPtr conn, const char *path, char *tcon)
{
char ebuf[1024];
@@ -40,7 +61,7 @@ diff -rup libvirt-0.6.2/src/security_selinux.c libvirt-0.6.2.new/src/security_se
if(setfilecon(path, tcon) < 0) {
virSecurityReportError(conn, VIR_ERR_ERROR,
_("%s: unable to set security context "
@@ -299,6 +307,8 @@ SELinuxRestoreSecurityImageLabel(virConn
@@ -299,6 +307,8 @@ SELinuxRestoreSecurityImageLabel(virConnectPtr conn,
char *newpath = NULL;
const char *path = disk->src;
@@ -49,7 +70,7 @@ diff -rup libvirt-0.6.2/src/security_selinux.c libvirt-0.6.2.new/src/security_se
if (disk->readonly || disk->shared)
return 0;
@@ -328,8 +338,13 @@ SELinuxSetSecurityImageLabel(virConnectP
@@ -328,8 +338,13 @@ SELinuxSetSecurityImageLabel(virConnectPtr conn,
{
const virSecurityLabelDefPtr secdef = &vm->def->seclabel;
@@ -64,7 +85,7 @@ diff -rup libvirt-0.6.2/src/security_selinux.c libvirt-0.6.2.new/src/security_se
return 0;
}
@@ -403,9 +418,6 @@ SELinuxSetSecurityLabel(virConnectPtr co
@@ -403,9 +418,6 @@ SELinuxSetSecurityLabel(virConnectPtr conn,
if (secdef->imagelabel) {
for (i = 0 ; i < vm->def->ndisks ; i++) {
@@ -74,3 +95,6 @@ diff -rup libvirt-0.6.2/src/security_selinux.c libvirt-0.6.2.new/src/security_se
if (SELinuxSetSecurityImageLabel(conn, vm, vm->def->disks[i]) < 0)
return -1;
}
--
1.6.2.5

View File

@@ -1,6 +1,21 @@
--- 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
From 6096cb19d6b05707ca32f52b905c53818ecfc84b Mon Sep 17 00:00:00 2001
From: Daniel P. Berrange <berrange@redhat.com>
Date: Mon, 17 Aug 2009 08:52:30 +0100
Subject: [PATCH] Disable sound cards when running sVirt
Temporary hack till PulseAudio autostart problems are sorted out when
SELinux enforcing (bz 486112)
Fedora-patch: libvirt-0.6.2-svirt-sound.patch
---
src/qemu_conf.c | 17 ++++++++++++++++-
1 files changed, 16 insertions(+), 1 deletions(-)
diff --git a/src/qemu_conf.c b/src/qemu_conf.c
index d76b2b6..22c5363 100644
--- a/src/qemu_conf.c
+++ b/src/qemu_conf.c
@@ -885,6 +885,20 @@ int qemudBuildCommandLine(virConnectPtr conn,
char domid[50];
char *pidfile;
const char *cpu = NULL;
@@ -10,7 +25,7 @@
+ driver->securityDriver->name &&
+ STREQ(driver->securityDriver->name, "selinux") &&
+ getuid() == 0) {
+ static int soundWarned = 0;
+ static int soundWarned = 0;
+ skipSound = 1;
+ if (vm->def->nsounds &&
+ !soundWarned) {
@@ -21,7 +36,7 @@
uname_normalize(&ut);
@@ -1425,7 +1439,8 @@ int qemudBuildCommandLine(virConnectPtr
@@ -1531,7 +1545,8 @@ int qemudBuildCommandLine(virConnectPtr conn,
}
/* Add sound hardware */
@@ -31,3 +46,6 @@
int size = 100;
char *modstr;
if (VIR_ALLOC_N(modstr, size+1) < 0)
--
1.6.2.5

View File

@@ -1,9 +1,11 @@
From 7f7a4403860f56d5a1ad65bfd16f5bf97a971d45 Mon Sep 17 00:00:00 2001
From a7d81a2f9e80942c9951c1d16ad69c66b9a47bbb 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
Subject: [PATCH] * src/buf.c: avoid an XML attribute escaping bug #499791 daniel
(cherry picked from commit 7afe94e7e236ec465d838e7d60e961975c526ab2)
Fedora-patch: libvirt-0.6.2-xml-attribute-escaping.patch
---
src/buf.c | 16 +++++++++++++++-
1 files changed, 15 insertions(+), 1 deletions(-)
@@ -43,5 +45,5 @@ index cdcdac9..259175d 100644
(*cur == '\r')) {
/*
--
1.6.0.6
1.6.2.5

View File

@@ -1,6 +1,6 @@
From 3d7771e0570e09096ad9391a857dad48b150bc0c Mon Sep 17 00:00:00 2001
From b3f02d5528c121bcf7b9ac5c4284517e71a5e2f2 Mon Sep 17 00:00:00 2001
From: Mark McLoughlin <markmc@redhat.com>
Date: Wed, 6 May 2009 16:33:28 +0100
Date: Wed, 6 May 2009 15:56:20 +0000
Subject: [PATCH] Fix qemu driver's interpretation of <hostdev managed='yes'/>
This change:
@@ -22,13 +22,15 @@ accidentally did this:
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>
(cherry picked from commit 1d6c713b18741f1a0e3d0ccd094275a11aef138c)
Fedora-patch: libvirt-0.6.3-hostdev-managed.patch
---
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
index 79ee072..162d072 100644
--- a/src/qemu_driver.c
+++ b/src/qemu_driver.c
@@ -1215,7 +1215,7 @@ static int qemuPrepareHostDevices(virConnectPtr conn,
@@ -41,5 +43,5 @@ index 5898026..59312c0 100644
hostdev->source.subsys.u.pci.domain,
hostdev->source.subsys.u.pci.bus,
--
1.6.0.6
1.6.2.5

View File

@@ -1,17 +1,23 @@
commit 0e51348cb9aeafe5e2fd6469a4bde0baa1eb8720
Author: Cole Robinson <crobinso@redhat.com>
Date: Mon May 4 15:06:03 2009 -0400
From a521796bac21f0c8af38a8551a420d87b61c7a9a Mon Sep 17 00:00:00 2001
From: Cole Robinson <crobinso@redhat.com>
Date: Wed, 6 May 2009 14:20:34 +0000
Subject: [PATCH] Refresh QEMU driver capabilities for each getCapabilities call.
Refresh QEMU driver capabilities for each getCapabilities call.
Also fix up a couple issues where caps are accessed without locking
the driver structure.
Also fix up a couple issues where caps are accessed without locking
the driver structure.
(cherry picked from commit 4f107590243631869677ddea2bb667db4a1282a6)
Fedora-patch: libvirt-0.6.3-refresh-qemu-caps.patch
---
src/qemu_driver.c | 28 ++++++++++++++++++++--------
1 files changed, 20 insertions(+), 8 deletions(-)
diff --git a/src/qemu_driver.c b/src/qemu_driver.c
index 23ea961..790dac6 100644
index 162d072..4752a64 100644
--- a/src/qemu_driver.c
+++ b/src/qemu_driver.c
@@ -1885,10 +1885,12 @@ static int qemudGetNodeInfo(virConnectPtr conn,
@@ -1872,10 +1872,12 @@ static int qemudGetNodeInfo(virConnectPtr conn,
static char *qemudGetCapabilities(virConnectPtr conn) {
struct qemud_driver *driver = conn->privateData;
@@ -26,7 +32,7 @@ index 23ea961..790dac6 100644
virReportOOMError(conn);
qemuDriverUnlock(driver);
@@ -3169,20 +3171,26 @@ cleanup:
@@ -3142,20 +3144,26 @@ cleanup:
return ret;
}
@@ -57,7 +63,7 @@ index 23ea961..790dac6 100644
}
strcpy(secmodel->model, p);
@@ -3191,10 +3199,14 @@ static int qemudNodeGetSecurityModel(virConnectPtr conn, virSecurityModelPtr sec
@@ -3164,10 +3172,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);
@@ -74,3 +80,6 @@ index 23ea961..790dac6 100644
}
/* TODO: check seclabel restore */
--
1.6.2.5

View File

@@ -0,0 +1,60 @@
From b77d11b221862343d304e11ed878e2f176101f24 Mon Sep 17 00:00:00 2001
From: Daniel P. Berrange <berrange@redhat.com>
Date: Tue, 28 Apr 2009 10:55:45 +0000
Subject: [PATCH] Cosmetic change to 'virsh nodedev-list --tree' output
Maybe it's just me, but I try to select an item from the tree using
double-click and get annoyed when "+-" gets included in the selection.
* src/virsh.c: add a space between "+-" and the node device name
in 'virsh nodedev-list --tree'
(cherry picked from commit cb4a6614fae48d05f09b7b15328ea6ef4071ccb3)
(cherry picked from commit 097c818bf00b3777778ffc32fea3a6ed1e741e2b)
Fedora-patch: libvirt-add-space-to-nodedev-list-tree.patch
---
src/virsh.c | 10 ++++++----
1 files changed, 6 insertions(+), 4 deletions(-)
diff --git a/src/virsh.c b/src/virsh.c
index 26764a7..c92bb8f 100644
--- a/src/virsh.c
+++ b/src/virsh.c
@@ -4460,10 +4460,12 @@ cmdNodeListDevicesPrint(vshControl *ctl,
if (depth && depth < MAX_DEPTH) {
indentBuf[indentIdx] = '+';
indentBuf[indentIdx+1] = '-';
+ indentBuf[indentIdx+2] = ' ';
+ indentBuf[indentIdx+3] = '\0';
}
/* Print this device */
- vshPrint(ctl, indentBuf);
+ vshPrint(ctl, "%s", indentBuf);
vshPrint(ctl, "%s\n", devices[devid]);
@@ -4487,8 +4489,8 @@ cmdNodeListDevicesPrint(vshControl *ctl,
/* If there is a child device, then print another blank line */
if (nextlastdev != -1) {
- vshPrint(ctl, indentBuf);
- vshPrint(ctl, " |\n");
+ vshPrint(ctl, "%s", indentBuf);
+ vshPrint(ctl, " |\n");
}
/* Finally print all children */
@@ -4511,7 +4513,7 @@ cmdNodeListDevicesPrint(vshControl *ctl,
/* If there was no child device, and we're the last in
* a list of devices, then print another blank line */
if (nextlastdev == -1 && devid == lastdev) {
- vshPrint(ctl, indentBuf);
+ vshPrint(ctl, "%s", indentBuf);
vshPrint(ctl, "\n");
}
}
--
1.6.2.5

View File

@@ -0,0 +1,812 @@
From 6878a049e27f2eaea7bd3d5c266a2d2b39e444f1 Mon Sep 17 00:00:00 2001
From: Mark McLoughlin <markmc@redhat.com>
Date: Mon, 17 Aug 2009 15:05:23 +0100
Subject: [PATCH] Maintain a list of active PCI hostdevs and use it in pciResetDevice()
https://bugzilla.redhat.com/499678
First we add a pciDeviceList type and add a qemuGetPciHostDeviceList()
function to build a list from a domain definition. Use this in
prepare/re-attach to simplify things and eliminate the multiple
pciGetDevice() calls.
Then, as we start/shutdown guests we can add or delete devices as
appropriate from a list of active devices.
Finally, in pciReset(), we can use this to determine whether its safe to
reset a device as a side effect of resetting another device.
(cherry picked from commit 78675b228b76a83f83d64856bfb63b9e14c103a0)
(cherry picked from commit e8ad33931296c67de0538e78d12e21706a826d37)
Fedora-patch: libvirt-allow-pci-hostdev-reset-to-reset-other-devices.patch
---
src/libvirt_private.syms | 7 +-
src/pci.c | 211 +++++++++++++++++++++++++++++++++--------
src/pci.h | 23 +++++-
src/qemu_conf.h | 3 +
src/qemu_driver.c | 237 +++++++++++++++++++++++++++-------------------
src/xen_unified.c | 2 +-
6 files changed, 339 insertions(+), 144 deletions(-)
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 9249a1a..75ddda8 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -240,7 +240,12 @@ pciFreeDevice;
pciDettachDevice;
pciReAttachDevice;
pciResetDevice;
-
+pciDeviceSetManaged;
+pciDeviceGetManaged;
+pciDeviceListNew;
+pciDeviceListFree;
+pciDeviceListAdd;
+pciDeviceListDel;
# qparams.h
qparam_get_query;
diff --git a/src/pci.c b/src/pci.c
index 1dddb08..1e68261 100644
--- a/src/pci.c
+++ b/src/pci.c
@@ -58,6 +58,7 @@ struct _pciDevice {
unsigned pci_pm_cap_pos;
unsigned has_flr : 1;
unsigned has_pm_reset : 1;
+ unsigned managed : 1;
};
/* For virReportOOMError() and virReportSystemError() */
@@ -220,7 +221,7 @@ pciWrite32(pciDevice *dev, unsigned pos, uint32_t val)
pciWrite(dev, pos, &buf[0], sizeof(buf));
}
-typedef int (*pciIterPredicate)(pciDevice *, pciDevice *);
+typedef int (*pciIterPredicate)(pciDevice *, pciDevice *, void *);
/* Iterate over available PCI devices calling @predicate
* to compare each one to @dev.
@@ -231,7 +232,8 @@ static int
pciIterDevices(virConnectPtr conn,
pciIterPredicate predicate,
pciDevice *dev,
- pciDevice **matched)
+ pciDevice **matched,
+ void *data)
{
DIR *dir;
struct dirent *entry;
@@ -249,7 +251,7 @@ pciIterDevices(virConnectPtr conn,
while ((entry = readdir(dir))) {
unsigned domain, bus, slot, function;
- pciDevice *try;
+ pciDevice *check;
/* Ignore '.' and '..' */
if (entry->d_name[0] == '.')
@@ -261,18 +263,18 @@ pciIterDevices(virConnectPtr conn,
continue;
}
- try = pciGetDevice(conn, domain, bus, slot, function);
- if (!try) {
+ check = pciGetDevice(conn, domain, bus, slot, function);
+ if (!check) {
ret = -1;
break;
}
- if (predicate(try, dev)) {
- VIR_DEBUG("%s %s: iter matched on %s", dev->id, dev->name, try->name);
- *matched = try;
+ if (predicate(dev, check, data)) {
+ VIR_DEBUG("%s %s: iter matched on %s", dev->id, dev->name, check->name);
+ *matched = check;
break;
}
- pciFreeDevice(conn, try);
+ pciFreeDevice(conn, check);
}
closedir(dir);
return ret;
@@ -374,63 +376,70 @@ pciDetectPowerManagementReset(pciDevice *dev)
return 0;
}
-/* Any devices other than the one supplied on the same domain/bus ? */
+/* Any active devices other than the one supplied on the same domain/bus ? */
static int
-pciSharesBus(pciDevice *a, pciDevice *b)
+pciSharesBusWithActive(pciDevice *dev, pciDevice *check, void *data)
{
- return
- a->domain == b->domain &&
- a->bus == b->bus &&
- (a->slot != b->slot ||
- a->function != b->function);
-}
+ pciDeviceList *activeDevs = data;
-static int
-pciBusContainsOtherDevices(virConnectPtr conn, pciDevice *dev)
-{
- pciDevice *matched = NULL;
- if (pciIterDevices(conn, pciSharesBus, dev, &matched) < 0)
- return 1;
- if (!matched)
+ if (dev->domain != check->domain ||
+ dev->bus != check->bus ||
+ (check->slot == check->slot &&
+ check->function == check->function))
+ return 0;
+
+ if (activeDevs && !pciDeviceListFind(activeDevs, check))
return 0;
- pciFreeDevice(conn, matched);
+
return 1;
}
-/* Is @a the parent of @b ? */
+static pciDevice *
+pciBusContainsActiveDevices(virConnectPtr conn,
+ pciDevice *dev,
+ pciDeviceList *activeDevs)
+{
+ pciDevice *active = NULL;
+ if (pciIterDevices(conn, pciSharesBusWithActive,
+ dev, &active, activeDevs) < 0)
+ return NULL;
+ return active;
+}
+
+/* Is @check the parent of @dev ? */
static int
-pciIsParent(pciDevice *a, pciDevice *b)
+pciIsParent(pciDevice *dev, pciDevice *check, void *data ATTRIBUTE_UNUSED)
{
uint16_t device_class;
uint8_t header_type, secondary, subordinate;
- if (a->domain != b->domain)
+ if (dev->domain != check->domain)
return 0;
/* Is it a bridge? */
- device_class = pciRead16(a, PCI_CLASS_DEVICE);
+ device_class = pciRead16(check, PCI_CLASS_DEVICE);
if (device_class != PCI_CLASS_BRIDGE_PCI)
return 0;
/* Is it a plane? */
- header_type = pciRead8(a, PCI_HEADER_TYPE);
+ header_type = pciRead8(check, PCI_HEADER_TYPE);
if ((header_type & PCI_HEADER_TYPE_MASK) != PCI_HEADER_TYPE_BRIDGE)
return 0;
- secondary = pciRead8(a, PCI_SECONDARY_BUS);
- subordinate = pciRead8(a, PCI_SUBORDINATE_BUS);
+ secondary = pciRead8(check, PCI_SECONDARY_BUS);
+ subordinate = pciRead8(check, PCI_SUBORDINATE_BUS);
- VIR_DEBUG("%s %s: found parent device %s\n", b->id, b->name, a->name);
+ VIR_DEBUG("%s %s: found parent device %s\n", dev->id, dev->name, check->name);
/* No, it's superman! */
- return (b->bus >= secondary && b->bus <= subordinate);
+ return (dev->bus >= secondary && dev->bus <= subordinate);
}
static pciDevice *
pciGetParentDevice(virConnectPtr conn, pciDevice *dev)
{
pciDevice *parent = NULL;
- pciIterDevices(conn, pciIsParent, dev, &parent);
+ pciIterDevices(conn, pciIsParent, dev, &parent, NULL);
return parent;
}
@@ -438,9 +447,11 @@ pciGetParentDevice(virConnectPtr conn, pciDevice *dev)
* devices behind a bus.
*/
static int
-pciTrySecondaryBusReset(virConnectPtr conn, pciDevice *dev)
+pciTrySecondaryBusReset(virConnectPtr conn,
+ pciDevice *dev,
+ pciDeviceList *activeDevs)
{
- pciDevice *parent;
+ pciDevice *parent, *conflict;
uint8_t config_space[PCI_CONF_LEN];
uint16_t ctl;
int ret = -1;
@@ -450,10 +461,10 @@ pciTrySecondaryBusReset(virConnectPtr conn, pciDevice *dev)
* In future, we could allow it so long as those devices
* are not in use by the host or other guests.
*/
- if (pciBusContainsOtherDevices(conn, dev)) {
+ if ((conflict = pciBusContainsActiveDevices(conn, dev, activeDevs))) {
pciReportError(conn, VIR_ERR_NO_SUPPORT,
- _("Other devices on bus with %s, not doing bus reset"),
- dev->name);
+ _("Active %s devices on bus with %s, not doing bus reset"),
+ conflict->name, dev->name);
return -1;
}
@@ -567,10 +578,18 @@ pciInitDevice(virConnectPtr conn, pciDevice *dev)
}
int
-pciResetDevice(virConnectPtr conn, pciDevice *dev)
+pciResetDevice(virConnectPtr conn,
+ pciDevice *dev,
+ pciDeviceList *activeDevs)
{
int ret = -1;
+ if (activeDevs && pciDeviceListFind(activeDevs, dev)) {
+ pciReportError(conn, VIR_ERR_INTERNAL_ERROR,
+ _("Not resetting active device %s"), dev->name);
+ return -1;
+ }
+
if (!dev->initted && pciInitDevice(conn, dev) < 0)
return -1;
@@ -589,7 +608,7 @@ pciResetDevice(virConnectPtr conn, pciDevice *dev)
/* Bus reset is not an option with the root bus */
if (ret < 0 && dev->bus != 0)
- ret = pciTrySecondaryBusReset(conn, dev);
+ ret = pciTrySecondaryBusReset(conn, dev, activeDevs);
if (ret < 0) {
virErrorPtr err = virGetLastError();
@@ -885,8 +904,116 @@ pciGetDevice(virConnectPtr conn,
void
pciFreeDevice(virConnectPtr conn ATTRIBUTE_UNUSED, pciDevice *dev)
{
+ if (!dev)
+ return;
VIR_DEBUG("%s %s: freeing", dev->id, dev->name);
if (dev->fd >= 0)
close(dev->fd);
VIR_FREE(dev);
}
+
+void pciDeviceSetManaged(pciDevice *dev, unsigned managed)
+{
+ dev->managed = !!managed;
+}
+
+unsigned pciDeviceGetManaged(pciDevice *dev)
+{
+ return dev->managed;
+}
+
+pciDeviceList *
+pciDeviceListNew(virConnectPtr conn)
+{
+ pciDeviceList *list;
+
+ if (VIR_ALLOC(list) < 0) {
+ virReportOOMError(conn);
+ return NULL;
+ }
+
+ return list;
+}
+
+void
+pciDeviceListFree(virConnectPtr conn,
+ pciDeviceList *list)
+{
+ int i;
+
+ if (!list)
+ return;
+
+ for (i = 0; i < list->count; i++) {
+ pciFreeDevice(conn, list->devs[i]);
+ list->devs[i] = NULL;
+ }
+
+ list->count = 0;
+ VIR_FREE(list->devs);
+ VIR_FREE(list);
+}
+
+int
+pciDeviceListAdd(virConnectPtr conn,
+ pciDeviceList *list,
+ pciDevice *dev)
+{
+ if (pciDeviceListFind(list, dev)) {
+ pciReportError(conn, VIR_ERR_INTERNAL_ERROR,
+ _("Device %s is already in use"), dev->name);
+ return -1;
+ }
+
+ if (VIR_REALLOC_N(list->devs, list->count+1) < 0) {
+ virReportOOMError(conn);
+ return -1;
+ }
+
+ list->devs[list->count++] = dev;
+
+ return 0;
+}
+
+void
+pciDeviceListDel(virConnectPtr conn ATTRIBUTE_UNUSED,
+ pciDeviceList *list,
+ pciDevice *dev)
+{
+ int i;
+
+ for (i = 0; i < list->count; i++) {
+ if (list->devs[i]->domain != dev->domain ||
+ list->devs[i]->bus != dev->bus ||
+ list->devs[i]->slot != dev->slot ||
+ list->devs[i]->function != dev->function)
+ continue;
+
+ pciFreeDevice(conn, list->devs[i]);
+
+ if (i != --list->count)
+ memmove(&list->devs[i],
+ &list->devs[i+1],
+ sizeof(*list->devs) * (list->count-i));
+
+ if (VIR_REALLOC_N(list->devs, list->count) < 0) {
+ ; /* not fatal */
+ }
+
+ break;
+ }
+}
+
+pciDevice *
+pciDeviceListFind(pciDeviceList *list, pciDevice *dev)
+{
+ int i;
+
+ for (i = 0; i < list->count; i++)
+ if (list->devs[i]->domain == dev->domain &&
+ list->devs[i]->bus == dev->bus &&
+ list->devs[i]->slot == dev->slot &&
+ list->devs[i]->function == dev->function)
+ return list->devs[i];
+ return NULL;
+}
diff --git a/src/pci.h b/src/pci.h
index 47882ef..685b0af 100644
--- a/src/pci.h
+++ b/src/pci.h
@@ -27,6 +27,11 @@
typedef struct _pciDevice pciDevice;
+typedef struct {
+ unsigned count;
+ pciDevice **devs;
+} pciDeviceList;
+
pciDevice *pciGetDevice (virConnectPtr conn,
unsigned domain,
unsigned bus,
@@ -39,6 +44,22 @@ int pciDettachDevice (virConnectPtr conn,
int pciReAttachDevice (virConnectPtr conn,
pciDevice *dev);
int pciResetDevice (virConnectPtr conn,
- pciDevice *dev);
+ pciDevice *dev,
+ pciDeviceList *activeDevs);
+void pciDeviceSetManaged(pciDevice *dev,
+ unsigned managed);
+unsigned pciDeviceGetManaged(pciDevice *dev);
+
+pciDeviceList *pciDeviceListNew (virConnectPtr conn);
+void pciDeviceListFree (virConnectPtr conn,
+ pciDeviceList *list);
+int pciDeviceListAdd (virConnectPtr conn,
+ pciDeviceList *list,
+ pciDevice *dev);
+void pciDeviceListDel (virConnectPtr conn,
+ pciDeviceList *list,
+ pciDevice *dev);
+pciDevice * pciDeviceListFind (pciDeviceList *list,
+ pciDevice *dev);
#endif /* __VIR_PCI_H__ */
diff --git a/src/qemu_conf.h b/src/qemu_conf.h
index 70fe9c8..cde326d 100644
--- a/src/qemu_conf.h
+++ b/src/qemu_conf.h
@@ -34,6 +34,7 @@
#include "domain_event.h"
#include "threads.h"
#include "security.h"
+#include "pci.h"
#define qemudDebug(fmt, ...) do {} while(0)
@@ -90,6 +91,8 @@ struct qemud_driver {
char *securityDriverName;
virSecurityDriverPtr securityDriver;
+
+ pciDeviceList *activePciHostdevs;
};
/* Status needed to reconenct to running VMs */
diff --git a/src/qemu_driver.c b/src/qemu_driver.c
index 9f87d2a..7dbf4a2 100644
--- a/src/qemu_driver.c
+++ b/src/qemu_driver.c
@@ -126,6 +126,9 @@ static int qemudDomainSetMemoryBalloon(virConnectPtr conn,
virDomainObjPtr vm,
unsigned long newmem);
+static int qemuUpdateActivePciHostdevs(struct qemud_driver *driver,
+ virDomainDefPtr def);
+
static struct qemud_driver *qemu_driver = NULL;
@@ -334,6 +337,10 @@ qemudReconnectVMs(struct qemud_driver *driver)
if ((vm->logfile = qemudLogFD(NULL, driver->logDir, vm->def->name)) < 0)
goto next_error;
+ if (qemuUpdateActivePciHostdevs(driver, vm->def) < 0) {
+ goto next_error;
+ }
+
if (vm->def->id >= driver->nextvmid)
driver->nextvmid = vm->def->id + 1;
@@ -515,6 +522,9 @@ qemudStartup(void) {
if ((qemu_driver->caps = qemudCapsInit()) == NULL)
goto out_of_memory;
+ if ((qemu_driver->activePciHostdevs = pciDeviceListNew(NULL)) == NULL)
+ goto error;
+
if (qemudLoadDriverConfig(qemu_driver, driverConf) < 0) {
goto error;
}
@@ -627,6 +637,7 @@ qemudShutdown(void) {
return -1;
qemuDriverLock(qemu_driver);
+ pciDeviceListFree(NULL, qemu_driver->activePciHostdevs);
virCapabilitiesFree(qemu_driver->caps);
virDomainObjListFree(&qemu_driver->domains);
@@ -1209,48 +1220,16 @@ static int qemudNextFreeVNCPort(struct qemud_driver *driver ATTRIBUTE_UNUSED) {
return -1;
}
-static int qemuPrepareHostDevices(virConnectPtr conn,
- virDomainDefPtr def) {
+static pciDeviceList *
+qemuGetPciHostDeviceList(virConnectPtr conn,
+ virDomainDefPtr def)
+{
+ pciDeviceList *list;
int i;
- /* We have to use 2 loops here. *All* devices must
- * be detached before we reset any of them, because
- * in some cases you have to reset the whole PCI,
- * which impacts all devices on it
- */
-
- for (i = 0 ; i < def->nhostdevs ; i++) {
- virDomainHostdevDefPtr hostdev = def->hostdevs[i];
-
- if (hostdev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS)
- continue;
- if (hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI)
- continue;
-
- if (hostdev->managed) {
- pciDevice *dev = pciGetDevice(conn,
- hostdev->source.subsys.u.pci.domain,
- hostdev->source.subsys.u.pci.bus,
- hostdev->source.subsys.u.pci.slot,
- hostdev->source.subsys.u.pci.function);
- if (!dev)
- goto error;
-
- if (pciDettachDevice(conn, dev) < 0) {
- pciFreeDevice(conn, dev);
- goto error;
- }
-
- pciFreeDevice(conn, dev);
- } /* else {
- XXX validate that non-managed device isn't in use, eg
- by checking that device is either un-bound, or bound
- to pci-stub.ko
- } */
- }
+ if (!(list = pciDeviceListNew(conn)))
+ return NULL;
- /* Now that all the PCI hostdevs have be dettached, we can safely
- * reset them */
for (i = 0 ; i < def->nhostdevs ; i++) {
virDomainHostdevDefPtr hostdev = def->hostdevs[i];
pciDevice *dev;
@@ -1265,95 +1244,151 @@ static int qemuPrepareHostDevices(virConnectPtr conn,
hostdev->source.subsys.u.pci.bus,
hostdev->source.subsys.u.pci.slot,
hostdev->source.subsys.u.pci.function);
- if (!dev)
- goto error;
+ if (!dev) {
+ pciDeviceListFree(conn, list);
+ return NULL;
+ }
- if (pciResetDevice(conn, dev) < 0) {
+ if (pciDeviceListAdd(conn, list, dev) < 0) {
pciFreeDevice(conn, dev);
- goto error;
+ pciDeviceListFree(conn, list);
+ return NULL;
}
- pciFreeDevice(conn, dev);
+ pciDeviceSetManaged(dev, hostdev->managed);
}
- return 0;
+ return list;
+}
-error:
- return -1;
+static int
+qemuUpdateActivePciHostdevs(struct qemud_driver *driver,
+ virDomainDefPtr def)
+{
+ pciDeviceList *pcidevs;
+ int i, ret;
+
+ if (!def->nhostdevs)
+ return 0;
+
+ if (!(pcidevs = qemuGetPciHostDeviceList(NULL, def)))
+ return -1;
+
+ ret = 0;
+
+ for (i = 0; i < pcidevs->count; i++) {
+ if (pciDeviceListAdd(NULL,
+ driver->activePciHostdevs,
+ pcidevs->devs[i]) < 0) {
+ ret = -1;
+ break;
+ }
+ pcidevs->devs[i] = NULL;
+ }
+
+ pciDeviceListFree(NULL, pcidevs);
+ return ret;
}
-static void
-qemuDomainReAttachHostDevices(virConnectPtr conn, virDomainDefPtr def)
+static int
+qemuPrepareHostDevices(virConnectPtr conn,
+ struct qemud_driver *driver,
+ virDomainDefPtr def)
{
+ pciDeviceList *pcidevs;
int i;
- /* Again 2 loops; reset all the devices before re-attach */
+ if (!def->nhostdevs)
+ return 0;
- for (i = 0 ; i < def->nhostdevs ; i++) {
- virDomainHostdevDefPtr hostdev = def->hostdevs[i];
- pciDevice *dev;
+ if (!(pcidevs = qemuGetPciHostDeviceList(conn, def)))
+ return -1;
- if (hostdev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS)
- continue;
- if (hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI)
- continue;
+ /* We have to use 3 loops here. *All* devices must
+ * be detached before we reset any of them, because
+ * in some cases you have to reset the whole PCI,
+ * which impacts all devices on it. Also, all devices
+ * must be reset before being marked as active.
+ */
- dev = pciGetDevice(conn,
- hostdev->source.subsys.u.pci.domain,
- hostdev->source.subsys.u.pci.bus,
- hostdev->source.subsys.u.pci.slot,
- hostdev->source.subsys.u.pci.function);
- if (!dev) {
- virErrorPtr err = virGetLastError();
- VIR_ERROR(_("Failed to allocate pciDevice: %s\n"),
- err ? err->message : "");
- virResetError(err);
- continue;
- }
+ /* XXX validate that non-managed device isn't in use, eg
+ * by checking that device is either un-bound, or bound
+ * to pci-stub.ko
+ */
- if (pciResetDevice(conn, dev) < 0) {
- virErrorPtr err = virGetLastError();
- VIR_ERROR(_("Failed to reset PCI device: %s\n"),
- err ? err->message : "");
- virResetError(err);
- }
+ for (i = 0; i < pcidevs->count; i++)
+ if (pciDeviceGetManaged(pcidevs->devs[i]) &&
+ pciDettachDevice(conn, pcidevs->devs[i]) < 0)
+ goto error;
+
+ /* Now that all the PCI hostdevs have be dettached, we can safely
+ * reset them */
+ for (i = 0; i < pcidevs->count; i++)
+ if (pciResetDevice(conn, pcidevs->devs[i],
+ driver->activePciHostdevs) < 0)
+ goto error;
- pciFreeDevice(conn, dev);
+ /* Now mark all the devices as active */
+ for (i = 0; i < pcidevs->count; i++) {
+ if (pciDeviceListAdd(conn,
+ driver->activePciHostdevs,
+ pcidevs->devs[i]) < 0)
+ goto error;
+ pcidevs->devs[i] = NULL;
}
- for (i = 0 ; i < def->nhostdevs ; i++) {
- virDomainHostdevDefPtr hostdev = def->hostdevs[i];
- pciDevice *dev;
+ pciDeviceListFree(conn, pcidevs);
+ return 0;
- if (hostdev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS)
- continue;
- if (hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI)
- continue;
- if (!hostdev->managed)
- continue;
+error:
+ pciDeviceListFree(conn, pcidevs);
+ return -1;
+}
- dev = pciGetDevice(conn,
- hostdev->source.subsys.u.pci.domain,
- hostdev->source.subsys.u.pci.bus,
- hostdev->source.subsys.u.pci.slot,
- hostdev->source.subsys.u.pci.function);
- if (!dev) {
+static void
+qemuDomainReAttachHostDevices(virConnectPtr conn,
+ struct qemud_driver *driver,
+ virDomainDefPtr def)
+{
+ pciDeviceList *pcidevs;
+ int i;
+
+ if (!def->nhostdevs)
+ return;
+
+ if (!(pcidevs = qemuGetPciHostDeviceList(conn, def))) {
+ virErrorPtr err = virGetLastError();
+ VIR_ERROR(_("Failed to allocate pciDeviceList: %s\n"),
+ err ? err->message : "");
+ virResetError(err);
+ return;
+ }
+
+ /* Again 3 loops; mark all devices as inactive before reset
+ * them and reset all the devices before re-attach */
+
+ for (i = 0; i < pcidevs->count; i++)
+ pciDeviceListDel(conn, driver->activePciHostdevs, pcidevs->devs[i]);
+
+ for (i = 0; i < pcidevs->count; i++)
+ if (pciResetDevice(conn, pcidevs->devs[i],
+ driver->activePciHostdevs) < 0) {
virErrorPtr err = virGetLastError();
- VIR_ERROR(_("Failed to allocate pciDevice: %s\n"),
+ VIR_ERROR(_("Failed to reset PCI device: %s\n"),
err ? err->message : "");
virResetError(err);
- continue;
}
- if (pciReAttachDevice(conn, dev) < 0) {
+ for (i = 0; i < pcidevs->count; i++)
+ if (pciDeviceGetManaged(pcidevs->devs[i]) &&
+ pciReAttachDevice(conn, pcidevs->devs[i]) < 0) {
virErrorPtr err = virGetLastError();
VIR_ERROR(_("Failed to re-attach PCI device: %s\n"),
err ? err->message : "");
virResetError(err);
}
- pciFreeDevice(conn, dev);
- }
+ pciDeviceListFree(conn, pcidevs);
}
static int qemudDomainSetSecurityLabel(virConnectPtr conn, struct qemud_driver *driver, virDomainObjPtr vm)
@@ -1468,7 +1503,7 @@ static int qemudStartVMDaemon(virConnectPtr conn,
&qemuCmdFlags) < 0)
goto cleanup;
- if (qemuPrepareHostDevices(conn, vm->def) < 0)
+ if (qemuPrepareHostDevices(conn, driver, vm->def) < 0)
goto cleanup;
vm->def->id = driver->nextvmid++;
@@ -1634,7 +1669,7 @@ static void qemudShutdownVMDaemon(virConnectPtr conn ATTRIBUTE_UNUSED,
VIR_FREE(vm->def->seclabel.imagelabel);
}
- qemuDomainReAttachHostDevices(conn, vm->def);
+ qemuDomainReAttachHostDevices(conn, driver, vm->def);
if (qemudRemoveDomainStatus(conn, driver, vm) < 0) {
VIR_WARN(_("Failed to remove domain status for %s"),
@@ -5247,6 +5282,7 @@ out:
static int
qemudNodeDeviceReset (virNodeDevicePtr dev)
{
+ struct qemud_driver *driver = dev->conn->privateData;
pciDevice *pci;
unsigned domain, bus, slot, function;
int ret = -1;
@@ -5258,11 +5294,14 @@ qemudNodeDeviceReset (virNodeDevicePtr dev)
if (!pci)
return -1;
- if (pciResetDevice(dev->conn, pci) < 0)
+ qemuDriverLock(driver);
+
+ if (pciResetDevice(dev->conn, pci, driver->activePciHostdevs) < 0)
goto out;
ret = 0;
out:
+ qemuDriverUnlock(driver);
pciFreeDevice(dev->conn, pci);
return ret;
}
diff --git a/src/xen_unified.c b/src/xen_unified.c
index e708980..ba8c769 100644
--- a/src/xen_unified.c
+++ b/src/xen_unified.c
@@ -1529,7 +1529,7 @@ xenUnifiedNodeDeviceReset (virNodeDevicePtr dev)
if (!pci)
return -1;
- if (pciResetDevice(dev->conn, pci) < 0)
+ if (pciResetDevice(dev->conn, pci, NULL) < 0)
goto out;
ret = 0;
--
1.6.2.5

View File

@@ -0,0 +1,121 @@
From d79f35fbd4eaf610972621b042993d00f3247d5c Mon Sep 17 00:00:00 2001
From: Mark McLoughlin <markmc@redhat.com>
Date: Fri, 14 Aug 2009 08:31:11 +0100
Subject: [PATCH] Allow PM reset on multi-function PCI devices
https://bugzilla.redhat.com/515689
It turns out that a PCI Power Management reset only affects individual
functions, and not the whole device.
The PCI Power Management spec talks about resetting the 'device' rather
than the 'function', but Intel's Dexuan Cui informs me that it is
actually a per-function reset.
Also, Yu Zhao has added pci_pm_reset() to the kernel, and it doesn't
reject multi-function devices, so it must be true! :-)
(A side issue is that we could defer the PM reset to the kernel if we
could detect that the kernel has PM reset support, but barring version
number checks we don't have a way to detect that support)
* src/pci.c: remove the pciDeviceContainsOtherFunctions() check from
pciTryPowerManagementReset() and prefer PM reset over bus reset
where both are available
Cc: Cui, Dexuan <dexuan.cui@intel.com>
Cc: Yu Zhao <yu.zhao@intel.com>
(cherry picked from commit 64a6682b93a2a8aa38067a43979c9eaf993d2b41)
Fedora-patch: libvirt-allow-pm-reset-on-multi-function-pci-devices.patch
---
src/pci.c | 48 +++++++++---------------------------------------
1 files changed, 9 insertions(+), 39 deletions(-)
diff --git a/src/pci.c b/src/pci.c
index 68a380d..f78ab9f 100644
--- a/src/pci.c
+++ b/src/pci.c
@@ -397,29 +397,6 @@ pciBusContainsOtherDevices(virConnectPtr conn, pciDevice *dev)
return 1;
}
-/* Any other functions on this device ? */
-static int
-pciSharesDevice(pciDevice *a, pciDevice *b)
-{
- return
- a->domain == b->domain &&
- a->bus == b->bus &&
- a->slot == b->slot &&
- a->function != b->function;
-}
-
-static int
-pciDeviceContainsOtherFunctions(virConnectPtr conn, pciDevice *dev)
-{
- pciDevice *matched = NULL;
- if (pciIterDevices(conn, pciSharesDevice, dev, &matched) < 0)
- return 1;
- if (!matched)
- return 0;
- pciFreeDevice(conn, matched);
- return 1;
-}
-
/* Is @a the parent of @b ? */
static int
pciIsParent(pciDevice *a, pciDevice *b)
@@ -524,7 +501,7 @@ out:
* above we require the device supports a full internal reset.
*/
static int
-pciTryPowerManagementReset(virConnectPtr conn, pciDevice *dev)
+pciTryPowerManagementReset(virConnectPtr conn ATTRIBUTE_UNUSED, pciDevice *dev)
{
uint8_t config_space[PCI_CONF_LEN];
uint32_t ctl;
@@ -532,16 +509,6 @@ pciTryPowerManagementReset(virConnectPtr conn, pciDevice *dev)
if (!dev->pci_pm_cap_pos)
return -1;
- /* For now, we just refuse to do a power management reset
- * if there are other functions on this device.
- * In future, we could allow it so long as those functions
- * are not in use by the host or other guests.
- */
- if (pciDeviceContainsOtherFunctions(conn, dev)) {
- VIR_WARN("%s contains other functions, not resetting", dev->name);
- return -1;
- }
-
/* Save and restore the device's config space. */
if (pciRead(dev, 0, &config_space[0], PCI_CONF_LEN) < 0) {
VIR_WARN("Failed to save PCI config space for %s", dev->name);
@@ -599,14 +566,17 @@ pciResetDevice(virConnectPtr conn, pciDevice *dev)
if (dev->has_flr)
return 0;
+ /* If the device supports PCI power management reset,
+ * that's the next best thing because it only resets
+ * the function, not the whole device.
+ */
+ if (dev->has_pm_reset)
+ ret = pciTryPowerManagementReset(conn, dev);
+
/* Bus reset is not an option with the root bus */
- if (dev->bus != 0)
+ if (ret < 0 && dev->bus != 0)
ret = pciTrySecondaryBusReset(conn, dev);
- /* Next best option is a PCI power management reset */
- if (ret < 0 && dev->has_pm_reset)
- ret = pciTryPowerManagementReset(conn, dev);
-
if (ret < 0)
pciReportError(conn, VIR_ERR_NO_SUPPORT,
_("No PCI reset capability available for %s"),
--
1.6.2.5

View File

@@ -0,0 +1,31 @@
From 1319852c443c432d44a2e73508f3be742027f780 Mon Sep 17 00:00:00 2001
From: Mark McLoughlin <markmc@redhat.com>
Date: Wed, 19 Aug 2009 11:28:02 +0100
Subject: [PATCH] Don't overwrite error in qemudWaitForMonitor()
May help diagnose https://bugzilla.redhat.com/515054
Fedora-patch: libvirt-do-not-overwrite-error-in-wait-for-monitor.patch
---
src/qemu_driver.c | 5 +++--
1 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/src/qemu_driver.c b/src/qemu_driver.c
index dfd19c5..74e106a 100644
--- a/src/qemu_driver.c
+++ b/src/qemu_driver.c
@@ -985,8 +985,9 @@ static int qemudWaitForMonitor(virConnectPtr conn,
return 0;
/* Unexpected end of file - inform user of QEMU log data */
- qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
- _("unable to start guest: %s"), buf);
+ if (!virGetLastError())
+ qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
+ _("unable to start guest: %s"), buf);
return -1;
}
--
1.6.2.5

View File

@@ -0,0 +1,53 @@
From 2754da03d65f216271c81ece791b96a19272c812 Mon Sep 17 00:00:00 2001
From: Mark McLoughlin <markmc@redhat.com>
Date: Sat, 15 Aug 2009 19:38:15 +0100
Subject: [PATCH] Fix list updating after disk hot-unplug
The current code makes a poor effort at updating the device arrays after
hot-unplug. Fix that and combine the two code paths into one.
* src/qemu_driver.c: fix list updating in qemudDomainDetachPciDiskDevice()
(cherry picked from commit 4e12af5623e4a962a6bb911af06fa29aa85befba)
Fedora-patch: libvirt-fix-device-list-update-after-detach.patch
---
src/qemu_driver.c | 21 ++++++++++-----------
1 files changed, 10 insertions(+), 11 deletions(-)
diff --git a/src/qemu_driver.c b/src/qemu_driver.c
index dfd19c5..ce04beb 100644
--- a/src/qemu_driver.c
+++ b/src/qemu_driver.c
@@ -4123,18 +4123,17 @@ try_command:
goto cleanup;
}
- if (vm->def->ndisks > 1) {
- vm->def->disks[i] = vm->def->disks[--vm->def->ndisks];
- if (VIR_REALLOC_N(vm->def->disks, vm->def->ndisks) < 0) {
- virReportOOMError(conn);
- goto cleanup;
- }
- qsort(vm->def->disks, vm->def->ndisks, sizeof(*vm->def->disks),
- virDomainDiskQSort);
- } else {
- VIR_FREE(vm->def->disks[0]);
- vm->def->ndisks = 0;
+ if (i != --vm->def->ndisks)
+ memmove(&vm->def->disks[i],
+ &vm->def->disks[i+1],
+ sizeof(*vm->def->disks) * (vm->def->ndisks-i));
+ if (VIR_REALLOC_N(vm->def->disks, vm->def->ndisks) < 0) {
+ virReportOOMError(conn);
+ goto cleanup;
}
+ qsort(vm->def->disks, vm->def->ndisks, sizeof(*vm->def->disks),
+ virDomainDiskQSort);
+
ret = 0;
cleanup:
--
1.6.2.5

View File

@@ -0,0 +1,45 @@
From 21ef933dfdd64c754d184d41d87ecd94eaddf697 Mon Sep 17 00:00:00 2001
From: Chris Lalancette <clalance@redhat.com>
Date: Wed, 5 Aug 2009 13:42:07 +0200
Subject: [PATCH] Run 'cont' on successful migration finish.
https://bugzilla.redhat.com/516187
As of qemu 0.10.6, qemu now honors the -S flag on incoming migration.
That means that when the migration completes, we have to issue a
'cont' command to get the VM running again. We do it unconditionally
since it won't hurt on older qemu.
(cherry picked from commit d1ec4d7a5a4f50c9492137eaab4f021caa075f95)
Fedora-patch: libvirt-fix-migration-completion-with-newer-qemu.patch
---
src/qemu_driver.c | 11 +++++++++++
1 files changed, 11 insertions(+), 0 deletions(-)
diff --git a/src/qemu_driver.c b/src/qemu_driver.c
index 7dbf4a2..ff56f61 100644
--- a/src/qemu_driver.c
+++ b/src/qemu_driver.c
@@ -5162,7 +5162,18 @@ qemudDomainMigrateFinish2 (virConnectPtr dconn,
*/
if (retcode == 0) {
dom = virGetDomain (dconn, vm->def->name, vm->def->uuid);
+
+ /* run 'cont' on the destination, which allows migration on qemu
+ * >= 0.10.6 to work properly. This isn't strictly necessary on
+ * older qemu's, but it also doesn't hurt anything there
+ */
+ if (qemudMonitorCommand(vm, "cont", &info) < 0) {
+ qemudReportError(dconn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
+ "%s", _("resume operation failed"));
+ goto cleanup;
+ }
VIR_FREE(info);
+
vm->state = VIR_DOMAIN_RUNNING;
event = virDomainEventNewFromObj(vm,
VIR_DOMAIN_EVENT_RESUMED,
--
1.6.2.5

View File

@@ -0,0 +1,38 @@
From 0878a15ad937449b5dfc4cf49888cc7753473e33 Mon Sep 17 00:00:00 2001
From: Daniel Veillard <veillard@redhat.com>
Date: Fri, 26 Jun 2009 18:14:16 +0000
Subject: [PATCH] Fix xen driver segfault with newer Xen
https://bugzilla.redhat.com/518091
(cherry picked from commit 14435163a086c0bcdff04308077fa46a5fa08bb0)
Fedora-patch: libvirt-fix-xen-driver-segfault-with-newer-xen.patch
---
src/xend_internal.c | 10 +++++++++-
1 files changed, 9 insertions(+), 1 deletions(-)
diff --git a/src/xend_internal.c b/src/xend_internal.c
index 2e2fd21..c3a9836 100644
--- a/src/xend_internal.c
+++ b/src/xend_internal.c
@@ -2077,7 +2077,15 @@ xenDaemonParseSxprGraphicsNew(virConnectPtr conn,
if (sexpr_lookup(node, "device/vfb")) {
/* New style graphics config for PV guests in >= 3.0.4,
* or for HVM guests in >= 3.0.5 */
- tmp = sexpr_node(node, "device/vfb/type");
+ if (sexpr_node(node, "device/vfb/type")) {
+ tmp = sexpr_node(node, "device/vfb/type");
+ } else if (sexpr_node(node, "device/vfb/vnc")) {
+ tmp = "vnc";
+ } else if (sexpr_node(node, "device/vfb/sdl")) {
+ tmp = "sdl";
+ } else {
+ tmp = "unknown";
+ }
if (VIR_ALLOC(graphics) < 0)
goto no_memory;
--
1.6.2.5

View File

@@ -0,0 +1,141 @@
From 9f80bab3829b97ac2802c15b9f3e4a6bbbb24627 Mon Sep 17 00:00:00 2001
From: Mark McLoughlin <markmc@redhat.com>
Date: Fri, 14 Aug 2009 08:31:11 +0100
Subject: [PATCH] Improve PCI host device reset error message
https://bugzilla.redhat.com/499678
Currently, if we are unable to reset a PCI device we return a fairly
generic 'No PCI reset capability available' error message.
Fix that by returning an error from the individual reset messages and
using that error to construct the higher level error mesage.
* src/pci.c: set errors in pciTryPowerManagementReset() and
pciTrySecondaryBusReset() on failure; use those error messages
in pciResetDevice(), or explain that no reset support is available
(cherry picked from commit ebea34185612c3b96d7d3bbd8b7c2ce6c9f4fe6f)
Fedora-patch: libvirt-improve-pci-hostdev-reset-error-message.patch
---
src/pci.c | 44 +++++++++++++++++++++++++++++++-------------
src/qemu_driver.c | 4 ++--
2 files changed, 33 insertions(+), 15 deletions(-)
diff --git a/src/pci.c b/src/pci.c
index f78ab9f..1dddb08 100644
--- a/src/pci.c
+++ b/src/pci.c
@@ -451,15 +451,18 @@ pciTrySecondaryBusReset(virConnectPtr conn, pciDevice *dev)
* are not in use by the host or other guests.
*/
if (pciBusContainsOtherDevices(conn, dev)) {
- VIR_WARN("Other devices on bus with %s, not doing bus reset",
- dev->name);
+ pciReportError(conn, VIR_ERR_NO_SUPPORT,
+ _("Other devices on bus with %s, not doing bus reset"),
+ dev->name);
return -1;
}
/* Find the parent bus */
parent = pciGetParentDevice(conn, dev);
if (!parent) {
- VIR_WARN("Failed to find parent device for %s", dev->name);
+ pciReportError(conn, VIR_ERR_NO_SUPPORT,
+ _("Failed to find parent device for %s"),
+ dev->name);
return -1;
}
@@ -470,7 +473,9 @@ pciTrySecondaryBusReset(virConnectPtr conn, pciDevice *dev)
* are multiple devices/functions
*/
if (pciRead(dev, 0, config_space, PCI_CONF_LEN) < 0) {
- VIR_WARN("Failed to save PCI config space for %s", dev->name);
+ pciReportError(conn, VIR_ERR_NO_SUPPORT,
+ _("Failed to save PCI config space for %s"),
+ dev->name);
goto out;
}
@@ -487,9 +492,12 @@ pciTrySecondaryBusReset(virConnectPtr conn, pciDevice *dev)
usleep(200 * 1000); /* sleep 200ms */
- if (pciWrite(dev, 0, config_space, PCI_CONF_LEN) < 0)
- VIR_WARN("Failed to restore PCI config space for %s", dev->name);
-
+ if (pciWrite(dev, 0, config_space, PCI_CONF_LEN) < 0) {
+ pciReportError(conn, VIR_ERR_NO_SUPPORT,
+ _("Failed to restore PCI config space for %s"),
+ dev->name);
+ goto out;
+ }
ret = 0;
out:
pciFreeDevice(conn, parent);
@@ -511,7 +519,9 @@ pciTryPowerManagementReset(virConnectPtr conn ATTRIBUTE_UNUSED, pciDevice *dev)
/* Save and restore the device's config space. */
if (pciRead(dev, 0, &config_space[0], PCI_CONF_LEN) < 0) {
- VIR_WARN("Failed to save PCI config space for %s", dev->name);
+ pciReportError(conn, VIR_ERR_NO_SUPPORT,
+ _("Failed to save PCI config space for %s"),
+ dev->name);
return -1;
}
@@ -528,8 +538,12 @@ pciTryPowerManagementReset(virConnectPtr conn ATTRIBUTE_UNUSED, pciDevice *dev)
usleep(10 * 1000); /* sleep 10ms */
- if (pciWrite(dev, 0, &config_space[0], PCI_CONF_LEN) < 0)
- VIR_WARN("Failed to restore PCI config space for %s", dev->name);
+ if (pciWrite(dev, 0, &config_space[0], PCI_CONF_LEN) < 0) {
+ pciReportError(conn, VIR_ERR_NO_SUPPORT,
+ _("Failed to restore PCI config space for %s"),
+ dev->name);
+ return -1;
+ }
return 0;
}
@@ -577,10 +591,14 @@ pciResetDevice(virConnectPtr conn, pciDevice *dev)
if (ret < 0 && dev->bus != 0)
ret = pciTrySecondaryBusReset(conn, dev);
- if (ret < 0)
+ if (ret < 0) {
+ virErrorPtr err = virGetLastError();
pciReportError(conn, VIR_ERR_NO_SUPPORT,
- _("No PCI reset capability available for %s"),
- dev->name);
+ _("Unable to reset PCI device %s: %s"),
+ dev->name,
+ err ? err->message : _("no FLR, PM reset or bus reset available"));
+ }
+
return ret;
}
diff --git a/src/qemu_driver.c b/src/qemu_driver.c
index ddd3693..9f87d2a 100644
--- a/src/qemu_driver.c
+++ b/src/qemu_driver.c
@@ -1345,9 +1345,9 @@ qemuDomainReAttachHostDevices(virConnectPtr conn, virDomainDefPtr def)
continue;
}
- if (pciDettachDevice(conn, dev) < 0) {
+ if (pciReAttachDevice(conn, dev) < 0) {
virErrorPtr err = virGetLastError();
- VIR_ERROR(_("Failed to reset PCI device: %s\n"),
+ VIR_ERROR(_("Failed to re-attach PCI device: %s\n"),
err ? err->message : "");
virResetError(err);
}
--
1.6.2.5

View File

@@ -0,0 +1,124 @@
From 1e44604c0d4c2d4c1347c2a1027f1ea02a6499f9 Mon Sep 17 00:00:00 2001
From: Mark McLoughlin <markmc@redhat.com>
Date: Fri, 14 Aug 2009 08:31:11 +0100
Subject: [PATCH] Reset and re-attach PCI host devices on guest shutdown
https://bugzilla.redhat.com/499561
When the guest shuts down, we should attempt to restore all PCI host
devices to a sane state.
In the case of managed hostdevs, we should reset and re-attach the
devices. In the case of unmanaged hostdevs, we should just reset them.
Note, KVM will already reset assigned devices when the guest shuts
down using whatever means it can, so we are only doing it to cover the
cases the kernel can't handle.
* src/qemu_driver.c: add qemuDomainReAttachHostDevices() and call
it from qemudShutdownVMDaemon()
(cherry picked from commit 4035152a8767e72fd4e26a91cb4d5afa75b72e61)
Fedora-patch: libvirt-reattach-pci-hostdevs-after-guest-shutdown.patch
---
src/qemu_driver.c | 76 +++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 76 insertions(+), 0 deletions(-)
diff --git a/src/qemu_driver.c b/src/qemu_driver.c
index ce04beb..ddd3693 100644
--- a/src/qemu_driver.c
+++ b/src/qemu_driver.c
@@ -1282,6 +1282,80 @@ error:
return -1;
}
+static void
+qemuDomainReAttachHostDevices(virConnectPtr conn, virDomainDefPtr def)
+{
+ int i;
+
+ /* Again 2 loops; reset all the devices before re-attach */
+
+ for (i = 0 ; i < def->nhostdevs ; i++) {
+ virDomainHostdevDefPtr hostdev = def->hostdevs[i];
+ pciDevice *dev;
+
+ if (hostdev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS)
+ continue;
+ if (hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI)
+ continue;
+
+ dev = pciGetDevice(conn,
+ hostdev->source.subsys.u.pci.domain,
+ hostdev->source.subsys.u.pci.bus,
+ hostdev->source.subsys.u.pci.slot,
+ hostdev->source.subsys.u.pci.function);
+ if (!dev) {
+ virErrorPtr err = virGetLastError();
+ VIR_ERROR(_("Failed to allocate pciDevice: %s\n"),
+ err ? err->message : "");
+ virResetError(err);
+ continue;
+ }
+
+ if (pciResetDevice(conn, dev) < 0) {
+ virErrorPtr err = virGetLastError();
+ VIR_ERROR(_("Failed to reset PCI device: %s\n"),
+ err ? err->message : "");
+ virResetError(err);
+ }
+
+ pciFreeDevice(conn, dev);
+ }
+
+ for (i = 0 ; i < def->nhostdevs ; i++) {
+ virDomainHostdevDefPtr hostdev = def->hostdevs[i];
+ pciDevice *dev;
+
+ if (hostdev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS)
+ continue;
+ if (hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI)
+ continue;
+ if (!hostdev->managed)
+ continue;
+
+ dev = pciGetDevice(conn,
+ hostdev->source.subsys.u.pci.domain,
+ hostdev->source.subsys.u.pci.bus,
+ hostdev->source.subsys.u.pci.slot,
+ hostdev->source.subsys.u.pci.function);
+ if (!dev) {
+ virErrorPtr err = virGetLastError();
+ VIR_ERROR(_("Failed to allocate pciDevice: %s\n"),
+ err ? err->message : "");
+ virResetError(err);
+ continue;
+ }
+
+ if (pciDettachDevice(conn, dev) < 0) {
+ virErrorPtr err = virGetLastError();
+ VIR_ERROR(_("Failed to reset PCI device: %s\n"),
+ err ? err->message : "");
+ virResetError(err);
+ }
+
+ pciFreeDevice(conn, dev);
+ }
+}
+
static int qemudDomainSetSecurityLabel(virConnectPtr conn, struct qemud_driver *driver, virDomainObjPtr vm)
{
if (vm->def->seclabel.label != NULL)
@@ -1560,6 +1634,8 @@ static void qemudShutdownVMDaemon(virConnectPtr conn ATTRIBUTE_UNUSED,
VIR_FREE(vm->def->seclabel.imagelabel);
}
+ qemuDomainReAttachHostDevices(conn, vm->def);
+
if (qemudRemoveDomainStatus(conn, driver, vm) < 0) {
VIR_WARN(_("Failed to remove domain status for %s"),
vm->def->name);
--
1.6.2.5

View File

@@ -66,10 +66,10 @@
Summary: Library providing a simple API virtualization
Name: libvirt
Version: 0.6.2
Release: 13%{?dist}%{?extra_release}
Release: 18%{?dist}%{?extra_release}
License: LGPLv2+
Group: Development/Libraries
Source: libvirt-%{version}.tar.gz
Source: http://libvirt.org/sources/libvirt-%{version}.tar.gz
# Patches cherry-picked from upstream
Patch0: libvirt-0.6.2-qemu-drive-format.patch
@@ -104,6 +104,39 @@ Patch14: libvirt-0.6.2-avoid-broken-networking-with-newer-qemu.patch
Patch15: libvirt-0.6.2-fix-libvirtd-crash-with-bad-capabilities-data.patch
# Don't unnecessarily try to change a file context (bug #507555)
Patch16: libvirt-0.6.2-do-not-unnecessarily-try-to-change-a-file-context.patch
# Misc useful fix
Patch17: libvirt-0.6.2-monitor-prompt-discard.patch
# rhbz #496442
Patch18: libvirt-0.6.2-hotplug-labelling.patch
# rhbz 499669
Patch19: libvirt-0.6.2-hotplug-monitor-syntax.patch
# rhbz #510907
Patch20: libvirt-0.6.2-pci-device-crash.patch
# rhbz #507405
Patch21: libvirt-0.6.2-qemu-name-uniqueness.patch
# rhbz #479517
Patch22: libvirt-0.6.2-buf-locale-escape.patch
# rhbz #506590
Patch23: libvirt-0.6.2-numa-ignore-fail.patch
# Minor 'virsh nodedev-list --tree' annoyance, fix from upstream
Patch24: libvirt-add-space-to-nodedev-list-tree.patch
# Fixes list corruption after disk hot-unplug
Patch25: libvirt-fix-device-list-update-after-detach.patch
# Re-attach PCI host devices after guest shuts down (bug #499561)
Patch26: libvirt-reattach-pci-hostdevs-after-guest-shutdown.patch
# Allow PM reset on multi-function PCI devices (bug #515689)
Patch27: libvirt-allow-pm-reset-on-multi-function-pci-devices.patch
# Fix stupid PCI reset error message (#499678)
Patch28: libvirt-improve-pci-hostdev-reset-error-message.patch
# Allow PCI bus reset to reset other devices (#499678)
Patch29: libvirt-allow-pci-hostdev-reset-to-reset-other-devices.patch
# Fix migration completion with newer versions of qemu (#516187)
Patch30: libvirt-fix-migration-completion-with-newer-qemu.patch
# Fix dumpxml segfault with newer versions of Xen (#518091)
Patch31: libvirt-fix-xen-driver-segfault-with-newer-xen.patch
# Fix qemu-kvm version detection so GSO is enabled
Patch32: libvirt-0.6.2-refactor-qemu-version-parsing.patch
Patch33: libvirt-0.6.2-detect-newer-qemu-kvm-versions.patch
# Not for upstream. Temporary hack till PulseAudio autostart
# problems are sorted out when SELinux enforcing
@@ -272,8 +305,25 @@ of recent versions of Linux (and other OSes).
%patch14 -p1
%patch15 -p1
%patch16 -p1
%patch17 -p1
%patch18 -p1
%patch19 -p1
%patch20 -p1
%patch21 -p1
%patch22 -p1
%patch23 -p1
%patch24 -p1
%patch25 -p1
%patch26 -p1
%patch27 -p1
%patch28 -p1
%patch29 -p1
%patch30 -p1
%patch31 -p1
%patch32 -p1
%patch33 -p1
%patch200 -p0
%patch200 -p1
mv NEWS NEWS.old
iconv -f ISO-8859-1 -t UTF-8 < NEWS.old > NEWS
@@ -595,6 +645,31 @@ fi
%endif
%changelog
* Wed Sep 30 2009 Mark McLoughlin <markmc@redhat.com> - 0.6.2-18
- Fix qemu-kvm version detection so GSO is enabled for virtio_net (#526472)
* Wed Aug 19 2009 Mark McLoughlin <markmc@redhat.com> - 0.6.2-17
- Fix migration completion with newer versions of qemu (#516187)
- Fix dumpxml segfault with newer versions of Xen (#518091)
* Wed Aug 19 2009 Mark McLoughlin <markmc@redhat.com> - 0.6.2-16.fc11
- Allow PCI bus reset to reset other devices (#499678)
- Fix stupid PCI reset error message (bug #499678)
- Allow PM reset on multi-function PCI devices (bug #515689)
- Re-attach PCI host devices after guest shuts down (bug #499561)
- Fixes list corruption after disk hot-unplug
- Fix minor 'virsh nodedev-list --tree' annoyance
* Thu Aug 13 2009 Daniel P. Berrange <berrange@redhat.com> - 0.6.2-15.fc11
- Log and ignore NUMA topology problems (rhbz #506590)
* Wed Aug 5 2009 Daniel P. Berrange <berrange@redhat.com> - 0.6.2-14.fc11
- Fix crash when attaching/detaching non-existant PCI device (rhbz #510907)
- Fix QEMU guest name/uuid uniqueness checks (rhbz #507405)
- Fix to use correct pci_add/del syntax for QEMU (rhbz #499669)
- Relabel disks before hotplugging them to guest (rhbz #496442)
- Correctly handle 8-bit high bytes when escaping XML (rhbz #479517)
* Fri Jul 3 2009 Mark McLoughlin <markmc@redhat.com> - 0.6.2-13.fc11
- Fix libvirtd crash with bad capabilities data (bug #505635)
- Don't unnecessarily try to change a file context (bug #507555)