Compare commits

...

25 Commits

Author SHA1 Message Date
Mark McLoughlin
68c271bad8 * Thu Oct 29 2009 Mark McLoughlin <markmc@redhat.com> - 0.7.1-15
- Avoid compressing small log files (#531030)
2009-10-29 17:26:12 +00:00
Mark McLoughlin
21a9f1ec41 * Thu Oct 29 2009 Mark McLoughlin <markmc@redhat.com> - 0.7.1-14
- Fix xen driver recounting (#531429)
- Fix crash on virsh error (#531429)
- Fix segfault where XML parsing fails in qemu disk hotplug
- Fix segfault where interface target device name is ommitted (#523418)
2009-10-29 10:40:45 +00:00
Mark McLoughlin
39bacac57d * Thu Oct 29 2009 Mark McLoughlin <markmc@redhat.com> - 0.7.1-14
- Make libvirt-devel require libvirt-client, not libvirt
2009-10-29 10:14:00 +00:00
Mark McLoughlin
7d9775ba12 * Mon Oct 19 2009 Mark McLoughlin <markmc@redhat.com> - 0.7.1-13
- Misc fixes to qemu machine types handling
- A couple of XML formatting fixes
2009-10-19 10:14:07 +00:00
Mark McLoughlin
3cfccddffa Add the second patch for #523158 2009-10-13 15:43:51 +00:00
Mark McLoughlin
1bc3776fdb * Tue Oct 13 2009 Mark McLoughlin <markmc@redhat.com> - 0.7.1-12
- Fix restore of qemu guest using raw save format (#523158)
2009-10-13 15:34:19 +00:00
Mark McLoughlin
3a44160f46 * Fri Oct 9 2009 Mark McLoughlin <markmc@redhat.com> - 0.7.1-11
- Fix libvirtd memory leak during error reply sending (#528162)
- Add several PCI hot-unplug typo fixes from upstream
2009-10-09 14:55:28 +00:00
Mark McLoughlin
5e8ea6c64c * Tue Oct 6 2009 Mark McLoughlin <markmc@redhat.com> - 0.7.1-10
- Create /var/log/libvirt/{lxc,uml} dirs for logrotate
- Make libvirt-python dependon on libvirt-client
- Sync misc minor changes from upstream spec
2009-10-06 12:42:16 +00:00
Mark McLoughlin
00ce651fb8 * Tue Oct 6 2009 Mark McLoughlin <markmc@redhat.com> - 0.7.1-9
- Change logrotate config to weekly (#526769)
2009-10-06 09:43:52 +00:00
Mark McLoughlin
3c684a55ed - Re-label qcow2 backing files (#497131) 2009-10-01 15:17:32 +00:00
Mark McLoughlin
b1ea570e48 * Thu Oct 1 2009 Mark McLoughlin <markmc@redhat.com> - 0.7.1-8
- Disable sound backend, even when selinux is disabled (#524499)
2009-10-01 08:35:16 +00:00
Mark McLoughlin
6ccf4c1a0c * Wed Sep 30 2009 Mark McLoughlin <markmc@redhat.com> - 0.7.1-7
- Fix USB device passthrough (#522683)
2009-09-30 17:57:50 +00:00
Jesse Keating
dbaa6786af Initialize branch F-12 for libvirt 2009-09-29 05:24:04 +00:00
Chris Weyl
288291b795 * Mon Sep 21 2009 Chris Weyl <cweyl@alumni.drew.edu> - 0.7.1-6
- rebuild for libssh2 1.2
2009-09-22 03:52:07 +00:00
Mark McLoughlin
7c2073faca * Mon Sep 21 2009 Mark McLoughlin <markmc@redhat.com> - 0.7.1-5
- Don't set a bogus error in virDrvSupportsFeature()
- Fix raw save format
2009-09-21 15:32:34 +00:00
Mark McLoughlin
5b528ba717 Fix typo 2009-09-17 14:58:55 +00:00
Mark McLoughlin
4f731a7250 Got the wrong bug number 2009-09-17 14:51:05 +00:00
Mark McLoughlin
f1ac0031f5 * Thu Sep 17 2009 Mark McLoughlin <markmc@redhat.com> - 0.7.1-4%
- A couple of hot-unplug memory handling fixes (#523960)
2009-09-17 14:47:51 +00:00
Daniel Veillard
e45b9c9030 Disable numactl on s390[x], Daniel 2009-09-17 13:30:50 +00:00
Daniel Veillard
3cf75c269d Refactoring of spec file by danpb for RHEL 5/6 compat, daniel 2009-09-17 12:32:32 +00:00
Daniel Veillard
585033f372 Release of 0.7.1 upstream, Daniel 2009-09-15 12:50:58 +00:00
Mark McLoughlin
897506e66a * Mon Sep 14 2009 Mark McLoughlin <markmc@redhat.com> - 0.7.1-0.2.gitfac3f4c
- Update to newer snapshot of 0.7.1
- Stop libvirt using untrusted 'info vcpus' PID data (#520864)
- Support relabelling of USB and PCI devices
- Enable multipath storage support
- Restart libvirtd upon RPM upgrade
2009-09-14 18:30:45 +00:00
Mark McLoughlin
e4bf8ffa42 * Sun Sep 6 2009 Mark McLoughlin <markmc@redhat.com> - 0.7.1-0.1.gitg3ef2e05
- Update to pre-release git snapshot of 0.7.1
- Drop upstreamed patches
2009-09-06 13:46:19 +00:00
Mark McLoughlin
20367a58a6 Add URL to source tag 2009-08-21 10:19:53 +00:00
Mark McLoughlin
aa037364ed * Wed Aug 19 2009 Mark McLoughlin <markmc@redhat.com> - 0.7.0-6
- Fix migration completion with newer versions of qemu (#516187)
2009-08-19 17:13:01 +00:00
40 changed files with 4871 additions and 2952 deletions

View File

@@ -9,6 +9,5 @@ libvirt-0.6.2.tar.gz
libvirt-0.6.3.tar.gz
libvirt-0.6.4.tar.gz
libvirt-0.6.5.tar.gz
libvirt-0.7.0-0.1.gitf055724.tar.gz
libvirt-0.7.0-0.6.gite195b43.tar.gz
libvirt-0.7.0.tar.gz
libvirt-0.7.1.tar.gz

1
branch Normal file
View File

@@ -0,0 +1 @@
F-12

View File

@@ -1,51 +0,0 @@
From 1e99b2edee0eb3ca1c600e5bd5c55741cb95a29a Mon Sep 17 00:00:00 2001
From: Daniel P. Berrange <berrange@redhat.com>
Date: Mon, 17 Aug 2009 08:32:08 +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.4-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 6b0b404..53186e0 100644
--- a/src/qemu_conf.c
+++ b/src/qemu_conf.c
@@ -1384,6 +1384,20 @@ int qemudBuildCommandLine(virConnectPtr conn,
char uuid[VIR_UUID_STRING_BUFLEN];
char domid[50];
const char *cpu = NULL;
+ int skipSound = 0;
+
+ if (driver->securityDriver &&
+ driver->securityDriver->name &&
+ STREQ(driver->securityDriver->name, "selinux") &&
+ getuid() == 0) {
+ static int soundWarned = 0;
+ skipSound = 1;
+ if (def->nsounds &&
+ !soundWarned) {
+ soundWarned = 1;
+ VIR_WARN0("Sound cards for VMs are disabled while SELinux security model is active");
+ }
+ }
uname_normalize(&ut);
@@ -2015,7 +2029,8 @@ int qemudBuildCommandLine(virConnectPtr conn,
}
/* Add sound hardware */
- if (def->nsounds) {
+ if (def->nsounds &&
+ !skipSound) {
int size = 100;
char *modstr;
if (VIR_ALLOC_N(modstr, size+1) < 0)
--
1.6.2.5

View File

@@ -1,79 +0,0 @@
From 541cfdf5465ac3bba2c0c0901950547bc6638e47 Mon Sep 17 00:00:00 2001
From: Mark McLoughlin <markmc@redhat.com>
Date: Thu, 6 Aug 2009 15:14:19 +0100
Subject: [PATCH] chown kernel/initrd before spawning qemu
If we're running qemu unprivileged, we need to chown any supplied kernel
or initrd before spawning it.
* src/qemu_driver.c: rename qemuDomainSetDiskOwnership() to
qemuDomainSetFileOwnership(), pass it a path string instead of a disk
definition and use it for chowning the kernel/initrd in
qemuDomainSetAllDeviceOwnership()
(cherry picked from commit c42b39784534930791d1feb3de859d85a7848168)
Fedora-patch: libvirt-0.7.0-chown-kernel-initrd-before-spawning-qemu.patch
---
src/qemu_driver.c | 20 ++++++++++++--------
1 files changed, 12 insertions(+), 8 deletions(-)
diff --git a/src/qemu_driver.c b/src/qemu_driver.c
index 412b68d..bd58435 100644
--- a/src/qemu_driver.c
+++ b/src/qemu_driver.c
@@ -1684,18 +1684,18 @@ static int qemuDomainSetHostdevOwnership(virConnectPtr conn,
}
-static int qemuDomainSetDiskOwnership(virConnectPtr conn,
- virDomainDiskDefPtr def,
+static int qemuDomainSetFileOwnership(virConnectPtr conn,
+ const char *path,
uid_t uid, gid_t gid)
{
- if (!def->src)
+ if (!path)
return 0;
- VIR_DEBUG("Setting ownership on %s to %d:%d", def->src, uid, gid);
- if (chown(def->src, uid, gid) < 0) {
+ VIR_DEBUG("Setting ownership on %s to %d:%d", path, uid, gid);
+ if (chown(path, uid, gid) < 0) {
virReportSystemError(conn, errno, _("cannot set ownership on %s"),
- def->src);
+ path);
return -1;
}
return 0;
@@ -1725,7 +1725,7 @@ static int qemuDomainSetDeviceOwnership(virConnectPtr conn,
(def->data.disk->readonly || def->data.disk->shared))
return 0;
- return qemuDomainSetDiskOwnership(conn, def->data.disk, uid, gid);
+ return qemuDomainSetFileOwnership(conn, def->data.disk->src, uid, gid);
case VIR_DOMAIN_DEVICE_HOSTDEV:
return qemuDomainSetHostdevOwnership(conn, def->data.hostdev, uid, gid);
@@ -1753,12 +1753,16 @@ static int qemuDomainSetAllDeviceOwnership(virConnectPtr conn,
uid = restore ? 0 : driver->user;
gid = restore ? 0 : driver->group;
+ if (qemuDomainSetFileOwnership(conn, def->os.kernel, uid, gid) < 0 ||
+ qemuDomainSetFileOwnership(conn, def->os.initrd, uid, gid) < 0)
+ return -1;
+
for (i = 0 ; i < def->ndisks ; i++) {
if (restore &&
(def->disks[i]->readonly || def->disks[i]->shared))
continue;
- if (qemuDomainSetDiskOwnership(conn, def->disks[i], uid, gid) < 0)
+ if (qemuDomainSetFileOwnership(conn, def->disks[i]->src, uid, gid) < 0)
return -1;
}
--
1.6.2.5

View File

@@ -1,45 +0,0 @@
From ddf0a7cb04debe60825d11186e68cc6de6fd1dd2 Mon Sep 17 00:00:00 2001
From: Mark McLoughlin <markmc@redhat.com>
Date: Mon, 10 Aug 2009 11:16:37 +0100
Subject: [PATCH] Handle kernels with no ipv6 support
If the ipv6 kernel module is not loaded, then we get this when starting
a virtual network:
libvir: Network Config error :
cannot enable /proc/sys/net/ipv6/conf/virbr0/disable_ipv6:
No such file or directory
If disable_ipv6 is not present, we should just merrily continue on our
way.
* src/network_driver.c: make networkDisableIPV6() not fail if the kernel
has no ipv6 support
(cherry picked from commit f5a8f969dd92ec2744e1eec5d35288d5fbcded22)
Fedora-patch: libvirt-0.7.0-handle-kernels-with-no-ipv6-support.patch
---
src/network_driver.c | 6 ++++++
1 files changed, 6 insertions(+), 0 deletions(-)
diff --git a/src/network_driver.c b/src/network_driver.c
index eaea454..84910ab 100644
--- a/src/network_driver.c
+++ b/src/network_driver.c
@@ -801,6 +801,12 @@ static int networkDisableIPV6(virConnectPtr conn,
goto cleanup;
}
+ if (access(field, W_OK) < 0 && errno == ENOENT) {
+ VIR_DEBUG("ipv6 appears to already be disabled on %s", network->def->bridge);
+ ret = 0;
+ goto cleanup;
+ }
+
if (virFileWriteStr(field, "1") < 0) {
virReportSystemError(conn, errno,
_("cannot enable %s"), field);
--
1.6.2.5

View File

@@ -1,96 +0,0 @@
From 663bf081dc6737c7fcc68a7ca1169aca60fbf8e5 Mon Sep 17 00:00:00 2001
From: Daniel P. Berrange <berrange@redhat.com>
Date: Thu, 13 Aug 2009 11:56:31 +0100
Subject: [PATCH] Make LXC / UML drivers robust against NUMA topology brokenness
Some kernel versions expose broken NUMA topology for some machines.
This causes the LXC/UML drivers to fail to start. QEMU driver was
already fixed for this problem
* src/lxc_conf.c: Log and ignore failure to populate NUMA info
* src/uml_conf.c: Log and ignore failure to populate NUMA info
* src/capabilities.c: Reset nnumaCell to 0 after freeing
(cherry picked from commit 19bac57b26c2d46ac8a7601158f210f34acdceac)
Fedora-patch: libvirt-0.7.0-numa-ignore-fail.patch
---
src/capabilities.c | 1 +
src/lxc_conf.c | 12 ++++++++++--
src/uml_conf.c | 11 +++++++++--
3 files changed, 20 insertions(+), 4 deletions(-)
diff --git a/src/capabilities.c b/src/capabilities.c
index c6766b6..193a9fe 100644
--- a/src/capabilities.c
+++ b/src/capabilities.c
@@ -139,6 +139,7 @@ virCapabilitiesFreeNUMAInfo(virCapsPtr caps)
for (i = 0 ; i < caps->host.nnumaCell ; i++)
virCapabilitiesFreeHostNUMACell(caps->host.numaCell[i]);
VIR_FREE(caps->host.numaCell);
+ caps->host.nnumaCell = 0;
}
/**
diff --git a/src/lxc_conf.c b/src/lxc_conf.c
index d06a024..fef60ba 100644
--- a/src/lxc_conf.c
+++ b/src/lxc_conf.c
@@ -30,6 +30,8 @@
#include "lxc_conf.h"
#include "nodeinfo.h"
#include "virterror_internal.h"
+#include "logging.h"
+
#define VIR_FROM_THIS VIR_FROM_LXC
@@ -46,8 +48,14 @@ virCapsPtr lxcCapsInit(void)
0, 0)) == NULL)
goto no_memory;
- if (nodeCapsInitNUMA(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 (nodeCapsInitNUMA(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/uml_conf.c b/src/uml_conf.c
index 48e05a8..4f756d4 100644
--- a/src/uml_conf.c
+++ b/src/uml_conf.c
@@ -45,6 +45,7 @@
#include "nodeinfo.h"
#include "verify.h"
#include "bridge.h"
+#include "logging.h"
#define VIR_FROM_THIS VIR_FROM_UML
@@ -63,8 +64,14 @@ virCapsPtr umlCapsInit(void) {
0, 0)) == NULL)
goto no_memory;
- if (nodeCapsInitNUMA(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 (nodeCapsInitNUMA(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

@@ -1,505 +0,0 @@
From d54fc5008d465d192101a0cb78fd02c437dff736 Mon Sep 17 00:00:00 2001
From: Daniel P. Berrange <berrange@redhat.com>
Date: Mon, 17 Aug 2009 08:32:08 +0100
Subject: [PATCH] Policykit rewrite (bug #499970)
Fedora-patch: libvirt-0.7.0-policy-kit-rewrite.patch
---
configure.in | 73 ++++++++++++++++++++++++++++--------------
qemud/Makefile.am | 11 +++++-
qemud/libvirtd.policy | 42 ------------------------
qemud/libvirtd.policy-0 | 42 ++++++++++++++++++++++++
qemud/libvirtd.policy-1 | 42 ++++++++++++++++++++++++
qemud/qemud.c | 4 +-
qemud/qemud.h | 4 +-
qemud/remote.c | 81 ++++++++++++++++++++++++++++++++++++++++++++--
src/remote_internal.c | 7 ++++
9 files changed, 230 insertions(+), 76 deletions(-)
delete mode 100644 qemud/libvirtd.policy
create mode 100644 qemud/libvirtd.policy-0
create mode 100644 qemud/libvirtd.policy-1
diff --git a/configure.in b/configure.in
index 45fa9ed..d28c44a 100644
--- a/configure.in
+++ b/configure.in
@@ -641,40 +641,61 @@ AC_SUBST([SASL_LIBS])
dnl PolicyKit library
POLKIT_CFLAGS=
POLKIT_LIBS=
+PKCHECK_PATH=
AC_ARG_WITH([polkit],
[ --with-polkit use PolicyKit for UNIX socket access checks],
[],
[with_polkit=check])
+with_polkit0=no
+with_polkit1=no
if test "x$with_polkit" = "xyes" -o "x$with_polkit" = "xcheck"; then
- PKG_CHECK_MODULES(POLKIT, polkit-dbus >= $POLKIT_REQUIRED,
- [with_polkit=yes], [
- if test "x$with_polkit" = "xcheck" ; then
- with_polkit=no
- else
- AC_MSG_ERROR(
- [You must install PolicyKit >= $POLKIT_REQUIRED to compile libvirt])
- fi
- ])
- if test "x$with_polkit" = "xyes" ; then
+ dnl Check for new polkit first - just a binary
+ AC_PATH_PROG([PKCHECK_PATH],[pkcheck], [], [/usr/sbin:$PATH])
+ if test "x$PKCHECK_PATH" != "x" ; then
+ AC_DEFINE_UNQUOTED([PKCHECK_PATH],["$PKCHECK_PATH"],[Location of pkcheck program])
AC_DEFINE_UNQUOTED([HAVE_POLKIT], 1,
- [use PolicyKit for UNIX socket access checks])
-
- old_CFLAGS=$CFLAGS
- old_LDFLAGS=$LDFLAGS
- CFLAGS="$CFLAGS $POLKIT_CFLAGS"
- LDFLAGS="$LDFLAGS $POLKIT_LIBS"
- AC_CHECK_FUNCS([polkit_context_is_caller_authorized])
- CFLAGS="$old_CFLAGS"
- LDFLAGS="$old_LDFLAGS"
-
- AC_PATH_PROG([POLKIT_AUTH], [polkit-auth])
- if test "x$POLKIT_AUTH" != "x"; then
- AC_DEFINE_UNQUOTED([POLKIT_AUTH],["$POLKIT_AUTH"],[Location of polkit-auth program])
+ [use PolicyKit for UNIX socket access checks])
+ AC_DEFINE_UNQUOTED([HAVE_POLKIT1], 1,
+ [use PolicyKit for UNIX socket access checks])
+ with_polkit="yes"
+ with_polkit1="yes"
+ else
+ dnl Check for old polkit second - library + binary
+ PKG_CHECK_MODULES(POLKIT, polkit-dbus >= $POLKIT_REQUIRED,
+ [with_polkit=yes], [
+ if test "x$with_polkit" = "xcheck" ; then
+ with_polkit=no
+ else
+ AC_MSG_ERROR(
+ [You must install PolicyKit >= $POLKIT_REQUIRED to compile libvirt])
+ fi
+ ])
+ if test "x$with_polkit" = "xyes" ; then
+ AC_DEFINE_UNQUOTED([HAVE_POLKIT], 1,
+ [use PolicyKit for UNIX socket access checks])
+ AC_DEFINE_UNQUOTED([HAVE_POLKIT0], 1,
+ [use PolicyKit for UNIX socket access checks])
+
+ old_CFLAGS=$CFLAGS
+ old_LDFLAGS=$LDFLAGS
+ CFLAGS="$CFLAGS $POLKIT_CFLAGS"
+ LDFLAGS="$LDFLAGS $POLKIT_LIBS"
+ AC_CHECK_FUNCS([polkit_context_is_caller_authorized])
+ CFLAGS="$old_CFLAGS"
+ LDFLAGS="$old_LDFLAGS"
+
+ AC_PATH_PROG([POLKIT_AUTH], [polkit-auth])
+ if test "x$POLKIT_AUTH" != "x"; then
+ AC_DEFINE_UNQUOTED([POLKIT_AUTH],["$POLKIT_AUTH"],[Location of polkit-auth program])
+ fi
+ with_polkit0="yes"
fi
fi
fi
AM_CONDITIONAL([HAVE_POLKIT], [test "x$with_polkit" = "xyes"])
+AM_CONDITIONAL([HAVE_POLKIT0], [test "x$with_polkit0" = "xyes"])
+AM_CONDITIONAL([HAVE_POLKIT1], [test "x$with_polkit1" = "xyes"])
AC_SUBST([POLKIT_CFLAGS])
AC_SUBST([POLKIT_LIBS])
@@ -1695,7 +1716,11 @@ else
AC_MSG_NOTICE([ avahi: no])
fi
if test "$with_polkit" = "yes" ; then
-AC_MSG_NOTICE([ polkit: $POLKIT_CFLAGS $POLKIT_LIBS])
+if test "$with_polkit0" = "yes" ; then
+AC_MSG_NOTICE([ polkit: $POLKIT_CFLAGS $POLKIT_LIBS (version 0)])
+else
+AC_MSG_NOTICE([ polkit: $PKCHECK_PATH (version 1)])
+fi
else
AC_MSG_NOTICE([ polkit: no])
fi
diff --git a/qemud/Makefile.am b/qemud/Makefile.am
index 959ff88..3d143da 100644
--- a/qemud/Makefile.am
+++ b/qemud/Makefile.am
@@ -21,7 +21,8 @@ EXTRA_DIST = \
remote_protocol.x \
libvirtd.conf \
libvirtd.init.in \
- libvirtd.policy \
+ libvirtd.policy-0 \
+ libvirtd.policy-1 \
libvirtd.sasl \
libvirtd.sysconf \
libvirtd.aug \
@@ -147,7 +148,13 @@ endif
libvirtd_LDADD += ../src/libvirt.la
if HAVE_POLKIT
+if HAVE_POLKIT0
policydir = $(datadir)/PolicyKit/policy
+policyfile = libvirtd.policy-0
+else
+policydir = $(datadir)/polkit-1/actions
+policyfile = libvirtd.policy-1
+endif
endif
if HAVE_AVAHI
@@ -197,7 +204,7 @@ endif
if HAVE_POLKIT
install-data-polkit:: install-init
mkdir -p $(DESTDIR)$(policydir)
- $(INSTALL_DATA) $(srcdir)/libvirtd.policy $(DESTDIR)$(policydir)/org.libvirt.unix.policy
+ $(INSTALL_DATA) $(srcdir)/$(policyfile) $(DESTDIR)$(policydir)/org.libvirt.unix.policy
uninstall-data-polkit:: install-init
rm -f $(DESTDIR)$(policydir)/org.libvirt.unix.policy
else
diff --git a/qemud/libvirtd.policy b/qemud/libvirtd.policy
deleted file mode 100644
index b6da946..0000000
--- a/qemud/libvirtd.policy
+++ /dev/null
@@ -1,42 +0,0 @@
-<!DOCTYPE policyconfig PUBLIC
- "-//freedesktop//DTD PolicyKit Policy Configuration 1.0//EN"
- "http://www.freedesktop.org/standards/PolicyKit/1.0/policyconfig.dtd">
-
-<!--
-Policy definitions for libvirt daemon
-
-Copyright (c) 2007 Daniel P. Berrange <berrange redhat com>
-
-libvirt is licensed to you under the GNU Lesser General Public License
-version 2. See COPYING for details.
-
-NOTE: If you make changes to this file, make sure to validate the file
-using the polkit-policy-file-validate(1) tool. Changes made to this
-file are instantly applied.
--->
-
-<policyconfig>
- <action id="org.libvirt.unix.monitor">
- <description>Monitor local virtualized systems</description>
- <message>System policy prevents monitoring of local virtualized systems</message>
- <defaults>
- <!-- Any program can use libvirt in read-only mode for monitoring,
- even if not part of a session -->
- <allow_any>yes</allow_any>
- <allow_inactive>yes</allow_inactive>
- <allow_active>yes</allow_active>
- </defaults>
- </action>
-
- <action id="org.libvirt.unix.manage">
- <description>Manage local virtualized systems</description>
- <message>System policy prevents management of local virtualized systems</message>
- <defaults>
- <!-- Only a program in the active host session can use libvirt in
- read-write mode for management, and we require user password -->
- <allow_any>no</allow_any>
- <allow_inactive>no</allow_inactive>
- <allow_active>auth_admin_keep_session</allow_active>
- </defaults>
- </action>
-</policyconfig>
diff --git a/qemud/libvirtd.policy-0 b/qemud/libvirtd.policy-0
new file mode 100644
index 0000000..b6da946
--- /dev/null
+++ b/qemud/libvirtd.policy-0
@@ -0,0 +1,42 @@
+<!DOCTYPE policyconfig PUBLIC
+ "-//freedesktop//DTD PolicyKit Policy Configuration 1.0//EN"
+ "http://www.freedesktop.org/standards/PolicyKit/1.0/policyconfig.dtd">
+
+<!--
+Policy definitions for libvirt daemon
+
+Copyright (c) 2007 Daniel P. Berrange <berrange redhat com>
+
+libvirt is licensed to you under the GNU Lesser General Public License
+version 2. See COPYING for details.
+
+NOTE: If you make changes to this file, make sure to validate the file
+using the polkit-policy-file-validate(1) tool. Changes made to this
+file are instantly applied.
+-->
+
+<policyconfig>
+ <action id="org.libvirt.unix.monitor">
+ <description>Monitor local virtualized systems</description>
+ <message>System policy prevents monitoring of local virtualized systems</message>
+ <defaults>
+ <!-- Any program can use libvirt in read-only mode for monitoring,
+ even if not part of a session -->
+ <allow_any>yes</allow_any>
+ <allow_inactive>yes</allow_inactive>
+ <allow_active>yes</allow_active>
+ </defaults>
+ </action>
+
+ <action id="org.libvirt.unix.manage">
+ <description>Manage local virtualized systems</description>
+ <message>System policy prevents management of local virtualized systems</message>
+ <defaults>
+ <!-- Only a program in the active host session can use libvirt in
+ read-write mode for management, and we require user password -->
+ <allow_any>no</allow_any>
+ <allow_inactive>no</allow_inactive>
+ <allow_active>auth_admin_keep_session</allow_active>
+ </defaults>
+ </action>
+</policyconfig>
diff --git a/qemud/libvirtd.policy-1 b/qemud/libvirtd.policy-1
new file mode 100644
index 0000000..6fa3a5e
--- /dev/null
+++ b/qemud/libvirtd.policy-1
@@ -0,0 +1,42 @@
+<!DOCTYPE policyconfig PUBLIC
+ "-//freedesktop//DTD PolicyKit Policy Configuration 1.0//EN"
+ "http://www.freedesktop.org/standards/PolicyKit/1.0/policyconfig.dtd">
+
+<!--
+Policy definitions for libvirt daemon
+
+Copyright (c) 2007 Daniel P. Berrange <berrange redhat com>
+
+libvirt is licensed to you under the GNU Lesser General Public License
+version 2. See COPYING for details.
+
+NOTE: If you make changes to this file, make sure to validate the file
+using the polkit-policy-file-validate(1) tool. Changes made to this
+file are instantly applied.
+-->
+
+<policyconfig>
+ <action id="org.libvirt.unix.monitor">
+ <description>Monitor local virtualized systems</description>
+ <message>System policy prevents monitoring of local virtualized systems</message>
+ <defaults>
+ <!-- Any program can use libvirt in read-only mode for monitoring,
+ even if not part of a session -->
+ <allow_any>yes</allow_any>
+ <allow_inactive>yes</allow_inactive>
+ <allow_active>yes</allow_active>
+ </defaults>
+ </action>
+
+ <action id="org.libvirt.unix.manage">
+ <description>Manage local virtualized systems</description>
+ <message>System policy prevents management of local virtualized systems</message>
+ <defaults>
+ <!-- Only a program in the active host session can use libvirt in
+ read-write mode for management, and we require user password -->
+ <allow_any>no</allow_any>
+ <allow_inactive>no</allow_inactive>
+ <allow_active>auth_admin_keep</allow_active>
+ </defaults>
+ </action>
+</policyconfig>
diff --git a/qemud/qemud.c b/qemud/qemud.c
index 3e551ca..50b0cdd 100644
--- a/qemud/qemud.c
+++ b/qemud/qemud.c
@@ -895,7 +895,7 @@ static struct qemud_server *qemudNetworkInit(struct qemud_server *server) {
}
#endif
-#ifdef HAVE_POLKIT
+#if HAVE_POLKIT0
if (auth_unix_rw == REMOTE_AUTH_POLKIT ||
auth_unix_ro == REMOTE_AUTH_POLKIT) {
DBusError derr;
@@ -982,7 +982,7 @@ static struct qemud_server *qemudNetworkInit(struct qemud_server *server) {
sock = sock->next;
}
-#ifdef HAVE_POLKIT
+#if HAVE_POLKIT0
if (server->sysbus)
dbus_connection_unref(server->sysbus);
#endif
diff --git a/qemud/qemud.h b/qemud/qemud.h
index 254db44..e8ce209 100644
--- a/qemud/qemud.h
+++ b/qemud/qemud.h
@@ -34,7 +34,7 @@
#include <sasl/sasl.h>
#endif
-#ifdef HAVE_POLKIT
+#if HAVE_POLKIT0
#include <dbus/dbus.h>
#endif
@@ -253,7 +253,7 @@ struct qemud_server {
#if HAVE_SASL
char **saslUsernameWhitelist;
#endif
-#if HAVE_POLKIT
+#if HAVE_POLKIT0
DBusConnection *sysbus;
#endif
};
diff --git a/qemud/remote.c b/qemud/remote.c
index d32d513..490a807 100644
--- a/qemud/remote.c
+++ b/qemud/remote.c
@@ -43,7 +43,7 @@
#include <fnmatch.h>
#include "virterror_internal.h"
-#ifdef HAVE_POLKIT
+#if HAVE_POLKIT0
#include <polkit/polkit.h>
#include <polkit-dbus/polkit-dbus.h>
#endif
@@ -3106,7 +3106,80 @@ remoteDispatchAuthSaslStep (struct qemud_server *server ATTRIBUTE_UNUSED,
#endif /* HAVE_SASL */
-#if HAVE_POLKIT
+#if HAVE_POLKIT1
+static int
+remoteDispatchAuthPolkit (struct qemud_server *server,
+ struct qemud_client *client,
+ virConnectPtr conn ATTRIBUTE_UNUSED,
+ remote_error *rerr,
+ void *args ATTRIBUTE_UNUSED,
+ remote_auth_polkit_ret *ret)
+{
+ pid_t callerPid;
+ uid_t callerUid;
+ const char *action;
+ int status = -1;
+ char pidbuf[50];
+ int rv;
+
+ virMutexLock(&server->lock);
+ virMutexLock(&client->lock);
+ virMutexUnlock(&server->lock);
+
+ action = client->readonly ?
+ "org.libvirt.unix.monitor" :
+ "org.libvirt.unix.manage";
+
+ const char * const pkcheck [] = {
+ PKCHECK_PATH,
+ "--action-id", action,
+ "--process", pidbuf,
+ "--allow-user-interaction",
+ NULL
+ };
+
+ REMOTE_DEBUG("Start PolicyKit auth %d", client->fd);
+ if (client->auth != REMOTE_AUTH_POLKIT) {
+ VIR_ERROR0(_("client tried invalid PolicyKit init request"));
+ goto authfail;
+ }
+
+ if (qemudGetSocketIdentity(client->fd, &callerUid, &callerPid) < 0) {
+ VIR_ERROR0(_("cannot get peer socket identity"));
+ goto authfail;
+ }
+
+ VIR_INFO(_("Checking PID %d running as %d"), callerPid, callerUid);
+
+ rv = snprintf(pidbuf, sizeof pidbuf, "%d", callerPid);
+ if (rv < 0 || rv >= sizeof pidbuf) {
+ VIR_ERROR(_("Caller PID was too large %d"), callerPid);
+ goto authfail;
+ }
+
+ if (virRun(NULL, pkcheck, &status) < 0) {
+ VIR_ERROR(_("Cannot invoke %s"), PKCHECK_PATH);
+ goto authfail;
+ }
+ if (status != 0) {
+ VIR_ERROR(_("Policy kit denied action %s from pid %d, uid %d, result: %d\n"),
+ action, callerPid, callerUid, status);
+ goto authfail;
+ }
+ VIR_INFO(_("Policy allowed action %s from pid %d, uid %d"),
+ action, callerPid, callerUid);
+ ret->complete = 1;
+ client->auth = REMOTE_AUTH_NONE;
+
+ virMutexUnlock(&client->lock);
+ return 0;
+
+authfail:
+ remoteDispatchAuthError(rerr);
+ virMutexUnlock(&client->lock);
+ return -1;
+}
+#elif HAVE_POLKIT0
static int
remoteDispatchAuthPolkit (struct qemud_server *server,
struct qemud_client *client,
@@ -3217,7 +3290,7 @@ authfail:
return -1;
}
-#else /* HAVE_POLKIT */
+#else /* !HAVE_POLKIT0 & !HAVE_POLKIT1*/
static int
remoteDispatchAuthPolkit (struct qemud_server *server ATTRIBUTE_UNUSED,
@@ -3231,7 +3304,7 @@ remoteDispatchAuthPolkit (struct qemud_server *server ATTRIBUTE_UNUSED,
remoteDispatchAuthError(rerr);
return -1;
}
-#endif /* HAVE_POLKIT */
+#endif /* HAVE_POLKIT1 */
/***************************************************************
diff --git a/src/remote_internal.c b/src/remote_internal.c
index a58b768..e98c99b 100644
--- a/src/remote_internal.c
+++ b/src/remote_internal.c
@@ -6201,6 +6201,7 @@ remoteAuthPolkit (virConnectPtr conn, struct private_data *priv, int in_open,
virConnectAuthPtr auth)
{
remote_auth_polkit_ret ret;
+#if HAVE_POLKIT0
int i, allowcb = 0;
virConnectCredential cred = {
VIR_CRED_EXTERNAL,
@@ -6210,8 +6211,10 @@ remoteAuthPolkit (virConnectPtr conn, struct private_data *priv, int in_open,
NULL,
0,
};
+#endif
DEBUG0("Client initialize PolicyKit authentication");
+#if HAVE_POLKIT0
if (auth && auth->cb) {
/* Check if the necessary credential type for PolicyKit is supported */
for (i = 0 ; i < auth->ncredtype ; i++) {
@@ -6220,6 +6223,7 @@ remoteAuthPolkit (virConnectPtr conn, struct private_data *priv, int in_open,
}
if (allowcb) {
+ DEBUG0("Client run callback for PolicyKit authentication");
/* Run the authentication callback */
if ((*(auth->cb))(&cred, 1, auth->cbdata) < 0) {
virRaiseError (in_open ? NULL : conn, NULL, NULL, VIR_FROM_REMOTE,
@@ -6233,6 +6237,9 @@ remoteAuthPolkit (virConnectPtr conn, struct private_data *priv, int in_open,
} else {
DEBUG0("No auth callback provided");
}
+#else
+ DEBUG0("No auth callback required for PolicyKit-1");
+#endif
memset (&ret, 0, sizeof ret);
if (call (conn, priv, in_open, REMOTE_PROC_AUTH_POLKIT,
--
1.6.2.5

View File

@@ -1,465 +0,0 @@
From 332979bb680d833529ab9cecac6828c6ce54d731 Mon Sep 17 00:00:00 2001
From: Mark McLoughlin <markmc@redhat.com>
Date: Fri, 14 Aug 2009 08:31:10 +0100
Subject: [PATCH] Add host PCI device hotplug support
Attaching a host PCI device to a qemu guest is done with a
straightforward 'pci_add pci_addr auto host host=XX:XX.X' command.
Like with NIC and disk hotplug, we need to retain the guest PCI address
assigned by qemu so that we can use it for hot-unplug.
Identifying a device for detach is done using the host PCI address.
Managed mode is handled by detaching/resetting the device before
attaching it to the guest and re-attaching it after detaching it from
the guest.
(cherry picked from commit 7636ef4630fc15c3d559eceb5b5c4fb1524b7c5a)
(cherry picked from commit 0c5b7b93a3cdb197c55d79c2605e9e19e3af43f5)
(cherry picked from commit 60ff07585ca8f7e639fed477e2e2cf79ce1c5c21)
(cherry picked from commit 4e12af5623e4a962a6bb911af06fa29aa85befba)
(cherry picked from commit 4dbecff9fbd5b5d1154bc7a41a5d4dd00533b359)
(cherry picked from commit 12edef9a6aca5bd9a2ea18b73ca862f615684d84)
(cherry picked from commit 457e05062863a35c7efb35470886b9b83a49d04d)
(cherry picked from commit e8ad33931296c67de0538e78d12e21706a826d37)
Fedora-patch: libvirt-add-pci-hostdev-hotplug-support.patch
---
src/domain_conf.c | 33 +++++-
src/domain_conf.h | 13 +++
src/libvirt_private.syms | 2 +
src/qemu_driver.c | 266 ++++++++++++++++++++++++++++++++++++++++++++--
4 files changed, 300 insertions(+), 14 deletions(-)
diff --git a/src/domain_conf.c b/src/domain_conf.c
index 2301a96..bad53f7 100644
--- a/src/domain_conf.c
+++ b/src/domain_conf.c
@@ -1977,7 +1977,8 @@ out:
static int
virDomainHostdevSubsysPciDefParseXML(virConnectPtr conn,
const xmlNodePtr node,
- virDomainHostdevDefPtr def) {
+ virDomainHostdevDefPtr def,
+ int flags) {
int ret = -1;
xmlNodePtr cur;
@@ -2049,6 +2050,20 @@ virDomainHostdevSubsysPciDefParseXML(virConnectPtr conn,
_("pci address needs function id"));
goto out;
}
+ } else if ((flags & VIR_DOMAIN_XML_INTERNAL_STATUS) &&
+ xmlStrEqual(cur->name, BAD_CAST "state")) {
+ char *devaddr = virXMLPropString(cur, "devaddr");
+ if (devaddr &&
+ sscanf(devaddr, "%x:%x:%x",
+ &def->source.subsys.u.pci.guest_addr.domain,
+ &def->source.subsys.u.pci.guest_addr.bus,
+ &def->source.subsys.u.pci.guest_addr.slot) < 3) {
+ virDomainReportError(conn, VIR_ERR_INTERNAL_ERROR,
+ _("Unable to parse devaddr parameter '%s'"),
+ devaddr);
+ VIR_FREE(devaddr);
+ goto out;
+ }
} else {
virDomainReportError(conn, VIR_ERR_INTERNAL_ERROR,
_("unknown pci source type '%s'"),
@@ -2123,7 +2138,7 @@ virDomainHostdevDefParseXML(virConnectPtr conn,
}
if (def->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS &&
def->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI) {
- if (virDomainHostdevSubsysPciDefParseXML(conn, cur, def) < 0)
+ if (virDomainHostdevSubsysPciDefParseXML(conn, cur, def, flags) < 0)
goto error;
}
} else {
@@ -3937,7 +3952,8 @@ virDomainGraphicsDefFormat(virConnectPtr conn,
static int
virDomainHostdevDefFormat(virConnectPtr conn,
virBufferPtr buf,
- virDomainHostdevDefPtr def)
+ virDomainHostdevDefPtr def,
+ int flags)
{
const char *mode = virDomainHostdevModeTypeToString(def->mode);
const char *type;
@@ -3978,6 +3994,15 @@ virDomainHostdevDefFormat(virConnectPtr conn,
def->source.subsys.u.pci.bus,
def->source.subsys.u.pci.slot,
def->source.subsys.u.pci.function);
+ if (flags & VIR_DOMAIN_XML_INTERNAL_STATUS) {
+ virBufferAddLit(buf, " <state");
+ if (virHostdevHasValidGuestAddr(def))
+ virBufferVSprintf(buf, " devaddr='%.4x:%.2x:%.2x'",
+ def->source.subsys.u.pci.guest_addr.domain,
+ def->source.subsys.u.pci.guest_addr.bus,
+ def->source.subsys.u.pci.guest_addr.slot);
+ virBufferAddLit(buf, "/>\n");
+ }
}
virBufferAddLit(buf, " </source>\n");
@@ -4192,7 +4217,7 @@ char *virDomainDefFormat(virConnectPtr conn,
goto cleanup;
for (n = 0 ; n < def->nhostdevs ; n++)
- if (virDomainHostdevDefFormat(conn, &buf, def->hostdevs[n]) < 0)
+ if (virDomainHostdevDefFormat(conn, &buf, def->hostdevs[n], flags) < 0)
goto cleanup;
virBufferAddLit(&buf, " </devices>\n");
diff --git a/src/domain_conf.h b/src/domain_conf.h
index 63fca76..44302be 100644
--- a/src/domain_conf.h
+++ b/src/domain_conf.h
@@ -391,6 +391,11 @@ struct _virDomainHostdevDef {
unsigned bus;
unsigned slot;
unsigned function;
+ struct {
+ unsigned domain;
+ unsigned bus;
+ unsigned slot;
+ } guest_addr;
} pci;
} u;
} subsys;
@@ -404,6 +409,14 @@ struct _virDomainHostdevDef {
char* target;
};
+static inline int
+virHostdevHasValidGuestAddr(virDomainHostdevDefPtr def)
+{
+ return def->source.subsys.u.pci.guest_addr.domain ||
+ def->source.subsys.u.pci.guest_addr.bus ||
+ def->source.subsys.u.pci.guest_addr.slot;
+}
+
/* Flags for the 'type' field in next struct */
enum virDomainDeviceType {
VIR_DOMAIN_DEVICE_DISK,
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 4f1b01f..22131c4 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -88,6 +88,8 @@ virDomainGetRootFilesystem;
virDomainGraphicsTypeFromString;
virDomainGraphicsDefFree;
virDomainHostdevDefFree;
+virDomainHostdevModeTypeToString;
+virDomainHostdevSubsysTypeToString;
virDomainInputDefFree;
virDomainLifecycleTypeFromString;
virDomainLifecycleTypeToString;
diff --git a/src/qemu_driver.c b/src/qemu_driver.c
index cbc27c4..99dac52 100644
--- a/src/qemu_driver.c
+++ b/src/qemu_driver.c
@@ -5258,9 +5258,91 @@ cleanup:
return -1;
}
-static int qemudDomainAttachHostDevice(virConnectPtr conn,
- virDomainObjPtr vm,
- virDomainDeviceDefPtr dev)
+static int qemudDomainAttachHostPciDevice(virConnectPtr conn,
+ struct qemud_driver *driver,
+ virDomainObjPtr vm,
+ virDomainDeviceDefPtr dev)
+{
+ virDomainHostdevDefPtr hostdev = dev->data.hostdev;
+ char *cmd, *reply;
+ unsigned domain, bus, slot;
+ pciDevice *pci;
+
+ if (VIR_REALLOC_N(vm->def->hostdevs, vm->def->nhostdevs+1) < 0) {
+ virReportOOMError(conn);
+ return -1;
+ }
+
+ pci = 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)
+ return -1;
+
+ if ((hostdev->managed && pciDettachDevice(conn, pci) < 0) ||
+ pciResetDevice(conn, pci, driver->activePciHostdevs) < 0) {
+ pciFreeDevice(conn, pci);
+ return -1;
+ }
+
+ if (pciDeviceListAdd(conn, driver->activePciHostdevs, pci) < 0) {
+ pciFreeDevice(conn, pci);
+ return -1;
+ }
+
+ cmd = reply = NULL;
+
+ if (virAsprintf(&cmd, "pci_add pci_addr=auto host host=%.2x:%.2x.%.1x",
+ hostdev->source.subsys.u.pci.bus,
+ hostdev->source.subsys.u.pci.slot,
+ hostdev->source.subsys.u.pci.function) < 0) {
+ virReportOOMError(conn);
+ goto error;
+ }
+
+ if (qemudMonitorCommand(vm, cmd, &reply) < 0) {
+ qemudReportError(conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
+ "%s", _("cannot attach host pci device"));
+ goto error;
+ }
+
+ if (strstr(reply, "invalid type: host")) {
+ qemudReportError(conn, dom, NULL, VIR_ERR_NO_SUPPORT, "%s",
+ _("PCI device assignment is not supported by this version of qemu"));
+ goto error;
+ }
+
+ if (qemudParsePciAddReply(vm, reply, &domain, &bus, &slot) < 0) {
+ qemudReportError(conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
+ _("parsing pci_add reply failed: %s"), reply);
+ goto error;
+ }
+
+ hostdev->source.subsys.u.pci.guest_addr.domain = domain;
+ hostdev->source.subsys.u.pci.guest_addr.bus = bus;
+ hostdev->source.subsys.u.pci.guest_addr.slot = slot;
+
+ vm->def->hostdevs[vm->def->nhostdevs++] = hostdev;
+
+ VIR_FREE(reply);
+ VIR_FREE(cmd);
+
+ return 0;
+
+error:
+ pciDeviceListDel(conn, driver->activePciHostdevs, pci);
+
+ VIR_FREE(reply);
+ VIR_FREE(cmd);
+
+ return -1;
+}
+
+static int qemudDomainAttachHostUsbDevice(virConnectPtr conn,
+ virDomainObjPtr vm,
+ virDomainDeviceDefPtr dev)
{
int ret;
char *cmd, *reply;
@@ -5310,6 +5392,36 @@ static int qemudDomainAttachHostDevice(virConnectPtr conn,
return 0;
}
+static int qemudDomainAttachHostDevice(virConnectPtr conn,
+ struct qemud_driver *driver,
+ virDomainObjPtr vm,
+ virDomainDeviceDefPtr dev)
+{
+ virDomainHostdevDefPtr hostdev = dev->data.hostdev;
+
+ if (hostdev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS) {
+ qemudReportError(conn, dom, NULL, VIR_ERR_NO_SUPPORT,
+ _("hostdev mode '%s' not supported"),
+ virDomainHostdevModeTypeToString(hostdev->mode));
+ return -1;
+ }
+
+ if (qemuDomainSetDeviceOwnership(conn, driver, dev, 0) < 0)
+ return -1;
+
+ switch (hostdev->source.subsys.type) {
+ case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI:
+ return qemudDomainAttachHostPciDevice(conn, driver, vm, dev);
+ case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB:
+ return qemudDomainAttachHostUsbDevice(conn, vm, dev);
+ default:
+ qemudReportError(conn, dom, NULL, VIR_ERR_NO_SUPPORT,
+ _("hostdev subsys type '%s' not supported"),
+ virDomainHostdevSubsysTypeToString(hostdev->source.subsys.type));
+ return -1;
+ }
+}
+
static int qemudDomainAttachDevice(virDomainPtr dom,
const char *xml) {
struct qemud_driver *driver = dom->conn->privateData;
@@ -5411,13 +5523,8 @@ static int qemudDomainAttachDevice(virDomainPtr dom,
}
} else if (dev->type == VIR_DOMAIN_DEVICE_NET) {
ret = qemudDomainAttachNetDevice(dom->conn, driver, vm, dev, qemuCmdFlags);
- } else if (dev->type == VIR_DOMAIN_DEVICE_HOSTDEV &&
- dev->data.hostdev->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS &&
- dev->data.hostdev->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB) {
- if (qemuDomainSetDeviceOwnership(dom->conn, driver, dev, 0) < 0)
- goto cleanup;
-
- ret = qemudDomainAttachHostDevice(dom->conn, vm, dev);
+ } else if (dev->type == VIR_DOMAIN_DEVICE_HOSTDEV) {
+ ret = qemudDomainAttachHostDevice(dom->conn, driver, vm, dev);
} else {
qemudReportError(dom->conn, dom, NULL, VIR_ERR_NO_SUPPORT,
_("device type '%s' cannot be attached"),
@@ -5630,6 +5737,143 @@ cleanup:
return ret;
}
+static int qemudDomainDetachHostPciDevice(virConnectPtr conn,
+ struct qemud_driver *driver,
+ virDomainObjPtr vm,
+ virDomainDeviceDefPtr dev)
+{
+ virDomainHostdevDefPtr detach;
+ char *cmd, *reply;
+ int i, ret;
+ pciDevice *pci;
+
+ for (i = 0 ; i < vm->def->nhostdevs ; i++) {
+ unsigned domain = vm->def->hostdevs[i]->source.subsys.u.pci.domain;
+ unsigned bus = vm->def->hostdevs[i]->source.subsys.u.pci.bus;
+ unsigned slot = vm->def->hostdevs[i]->source.subsys.u.pci.slot;
+ unsigned function = vm->def->hostdevs[i]->source.subsys.u.pci.function;
+
+ if (dev->data.hostdev->source.subsys.u.pci.domain == domain &&
+ dev->data.hostdev->source.subsys.u.pci.bus == bus &&
+ dev->data.hostdev->source.subsys.u.pci.slot == slot &&
+ dev->data.hostdev->source.subsys.u.pci.function == function) {
+ detach = vm->def->hostdevs[i];
+ break;
+ }
+ }
+
+ if (!detach) {
+ qemudReportError(conn, NULL, NULL, VIR_ERR_OPERATION_FAILED,
+ _("host pci device %.4x:%.2x:%.2x.%.1x not found"),
+ dev->data.hostdev->source.subsys.u.pci.domain,
+ dev->data.hostdev->source.subsys.u.pci.bus,
+ dev->data.hostdev->source.subsys.u.pci.slot,
+ dev->data.hostdev->source.subsys.u.pci.function);
+ return -1;
+ }
+
+ if (!virHostdevHasValidGuestAddr(detach)) {
+ qemudReportError(conn, NULL, NULL, VIR_ERR_OPERATION_FAILED,
+ "%s", _("hostdev cannot be detached - device state missing"));
+ return -1;
+ }
+
+ if (virAsprintf(&cmd, "pci_del pci_addr=%.4x:%.2x:%.2x",
+ detach->source.subsys.u.pci.guest_addr.domain,
+ detach->source.subsys.u.pci.guest_addr.bus,
+ detach->source.subsys.u.pci.guest_addr.slot) < 0) {
+ virReportOOMError(conn);
+ return -1;
+ }
+
+ if (qemudMonitorCommand(vm, cmd, &reply) < 0) {
+ qemudReportError(conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
+ "%s", _("cannot detach host pci device"));
+ VIR_FREE(cmd);
+ return -1;
+ }
+
+ DEBUG("%s: pci_del reply: %s", vm->def->name, reply);
+
+ /* If the command fails due to a wrong PCI address qemu prints
+ * 'invalid pci address'; nothing is printed on success */
+ if (strstr(reply, "Invalid pci address")) {
+ qemudReportError(conn, NULL, NULL, VIR_ERR_OPERATION_FAILED,
+ _("failed to detach host pci device: invalid PCI address %.4x:%.2x:%.2x: %s"),
+ detach->source.subsys.u.pci.guest_addr.domain,
+ detach->source.subsys.u.pci.guest_addr.bus,
+ detach->source.subsys.u.pci.guest_addr.slot,
+ reply);
+ VIR_FREE(reply);
+ VIR_FREE(cmd);
+ return -1;
+ }
+
+ VIR_FREE(reply);
+ VIR_FREE(cmd);
+
+ ret = 0;
+
+ pci = pciGetDevice(conn,
+ detach->source.subsys.u.pci.domain,
+ detach->source.subsys.u.pci.bus,
+ detach->source.subsys.u.pci.slot,
+ detach->source.subsys.u.pci.function);
+ if (!pci)
+ ret = -1;
+ else {
+ pciDeviceListDel(conn, driver->activePciHostdevs, pci);
+ if (pciResetDevice(conn, pci, driver->activePciHostdevs) < 0)
+ ret = -1;
+ if (detach->managed && pciReAttachDevice(conn, pci) < 0)
+ ret = -1;
+ pciFreeDevice(conn, pci);
+ }
+
+ if (i != --vm->def->nhostdevs)
+ memmove(&vm->def->hostdevs[i],
+ &vm->def->hostdevs[i+1],
+ sizeof(*vm->def->hostdevs) * (vm->def->nhostdevs-i));
+ if (VIR_REALLOC_N(vm->def->hostdevs, vm->def->nhostdevs) < 0) {
+ virReportOOMError(conn);
+ ret = -1;
+ }
+
+ return ret;
+}
+
+static int qemudDomainDetachHostDevice(virConnectPtr conn,
+ struct qemud_driver *driver,
+ virDomainObjPtr vm,
+ virDomainDeviceDefPtr dev)
+{
+ virDomainHostdevDefPtr hostdev = dev->data.hostdev;
+ int ret;
+
+ if (hostdev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS) {
+ qemudReportError(conn, dom, NULL, VIR_ERR_NO_SUPPORT,
+ _("hostdev mode '%s' not supported"),
+ virDomainHostdevModeTypeToString(hostdev->mode));
+ return -1;
+ }
+
+ switch (hostdev->source.subsys.type) {
+ case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI:
+ ret = qemudDomainDetachHostPciDevice(conn, driver, vm, dev);
+ break;
+ default:
+ qemudReportError(conn, dom, NULL, VIR_ERR_NO_SUPPORT,
+ _("hostdev subsys type '%s' not supported"),
+ virDomainHostdevSubsysTypeToString(hostdev->source.subsys.type));
+ return -1;
+ }
+
+ if (qemuDomainSetDeviceOwnership(conn, driver, dev, 1) < 0)
+ VIR_WARN0("Fail to restore disk device ownership");
+
+ return ret;
+}
+
static int qemudDomainDetachDevice(virDomainPtr dom,
const char *xml) {
struct qemud_driver *driver = dom->conn->privateData;
@@ -5670,6 +5914,8 @@ static int qemudDomainDetachDevice(virDomainPtr dom,
VIR_WARN0("Fail to restore disk device ownership");
} else if (dev->type == VIR_DOMAIN_DEVICE_NET) {
ret = qemudDomainDetachNetDevice(dom->conn, vm, dev);
+ } else if (dev->type == VIR_DOMAIN_DEVICE_HOSTDEV) {
+ ret = qemudDomainDetachHostDevice(dom->conn, driver, vm, dev);
} else
qemudReportError(dom->conn, dom, NULL, VIR_ERR_NO_SUPPORT,
"%s", _("only SCSI or virtio disk device can be detached dynamically"));
--
1.6.2.5

View File

@@ -1,43 +0,0 @@
From 100eb35a80932cd9a162c38ecd2ab8b01894fb61 Mon Sep 17 00:00:00 2001
From: Mark McLoughlin <markmc@redhat.com>
Date: Mon, 17 Aug 2009 15:05:22 +0100
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 097c818bf00b3777778ffc32fea3a6ed1e741e2b)
Fedora-patch: libvirt-add-space-to-nodedev-list-tree.patch
---
src/virsh.c | 4 +++-
1 files changed, 3 insertions(+), 1 deletions(-)
diff --git a/src/virsh.c b/src/virsh.c
index 94c3c4e..2d0cf81 100644
--- a/src/virsh.c
+++ b/src/virsh.c
@@ -5370,6 +5370,8 @@ cmdNodeListDevicesPrint(vshControl *ctl,
if (depth && depth < MAX_DEPTH) {
indentBuf[indentIdx] = '+';
indentBuf[indentIdx+1] = '-';
+ indentBuf[indentIdx+2] = ' ';
+ indentBuf[indentIdx+3] = '\0';
}
/* Print this device */
@@ -5398,7 +5400,7 @@ cmdNodeListDevicesPrint(vshControl *ctl,
/* If there is a child device, then print another blank line */
if (nextlastdev != -1) {
vshPrint(ctl, "%s", indentBuf);
- vshPrint(ctl, " |\n");
+ vshPrint(ctl, " |\n");
}
/* Finally print all children */
--
1.6.2.5

View File

@@ -1,812 +0,0 @@
From 89eefbd116ae74c3a5cfcfc74a31a40b83c726c3 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 bd63692..4f1b01f 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -278,7 +278,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 74f7ef0..96e5d6d 100644
--- a/src/pci.c
+++ b/src/pci.c
@@ -63,6 +63,7 @@ struct _pciDevice {
unsigned pci_pm_cap_pos;
unsigned has_flr : 1;
unsigned has_pm_reset : 1;
+ unsigned managed : 1;
};
/* For virReportOOMError() and virReportSystemError() */
@@ -225,7 +226,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.
@@ -236,7 +237,8 @@ static int
pciIterDevices(virConnectPtr conn,
pciIterPredicate predicate,
pciDevice *dev,
- pciDevice **matched)
+ pciDevice **matched,
+ void *data)
{
DIR *dir;
struct dirent *entry;
@@ -254,7 +256,7 @@ pciIterDevices(virConnectPtr conn,
while ((entry = readdir(dir))) {
unsigned domain, bus, slot, function;
- pciDevice *try;
+ pciDevice *check;
/* Ignore '.' and '..' */
if (entry->d_name[0] == '.')
@@ -266,18 +268,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;
@@ -379,63 +381,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;
}
@@ -443,9 +452,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;
@@ -455,10 +466,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;
}
@@ -572,10 +583,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;
@@ -594,7 +613,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();
@@ -890,8 +909,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 517626a..ab9d5e1 100644
--- a/src/qemu_conf.h
+++ b/src/qemu_conf.h
@@ -35,6 +35,7 @@
#include "threads.h"
#include "security.h"
#include "cgroup.h"
+#include "pci.h"
#define qemudDebug(fmt, ...) do {} while(0)
@@ -107,6 +108,8 @@ struct qemud_driver {
char *securityDriverName;
virSecurityDriverPtr securityDriver;
+
+ pciDeviceList *activePciHostdevs;
};
diff --git a/src/qemu_driver.c b/src/qemu_driver.c
index fd39fc2..cbc27c4 100644
--- a/src/qemu_driver.c
+++ b/src/qemu_driver.c
@@ -128,6 +128,9 @@ static int qemudDomainSetMemoryBalloon(virConnectPtr conn,
static int qemudDetectVcpuPIDs(virConnectPtr conn,
virDomainObjPtr vm);
+static int qemuUpdateActivePciHostdevs(struct qemud_driver *driver,
+ virDomainDefPtr def);
+
static struct qemud_driver *qemu_driver = NULL;
static int qemuCgroupControllerActive(struct qemud_driver *driver,
@@ -320,6 +323,10 @@ qemuReconnectDomain(struct qemud_driver *driver,
goto error;
}
+ if (qemuUpdateActivePciHostdevs(driver, obj->def) < 0) {
+ goto error;
+ }
+
if (obj->def->seclabel.type == VIR_DOMAIN_SECLABEL_DYNAMIC &&
driver->securityDriver &&
driver->securityDriver->domainReserveSecurityLabel &&
@@ -524,6 +531,9 @@ qemudStartup(int privileged) {
if ((qemu_driver->caps = qemudCapsInit(NULL)) == NULL)
goto out_of_memory;
+ if ((qemu_driver->activePciHostdevs = pciDeviceListNew(NULL)) == NULL)
+ goto error;
+
if (qemudLoadDriverConfig(qemu_driver, driverConf) < 0) {
goto error;
}
@@ -648,6 +658,7 @@ qemudShutdown(void) {
return -1;
qemuDriverLock(qemu_driver);
+ pciDeviceListFree(NULL, qemu_driver->activePciHostdevs);
virCapabilitiesFree(qemu_driver->caps);
virDomainObjListFree(&qemu_driver->domains);
@@ -1329,48 +1340,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;
@@ -1385,95 +1364,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 const char *const defaultDeviceACL[] = {
@@ -2001,7 +2036,7 @@ static int qemudStartVMDaemon(virConnectPtr conn,
if (qemuSetupCgroup(conn, driver, vm) < 0)
goto cleanup;
- if (qemuPrepareHostDevices(conn, vm->def) < 0)
+ if (qemuPrepareHostDevices(conn, driver, vm->def) < 0)
goto cleanup;
if (VIR_ALLOC(vm->monitor_chr) < 0) {
@@ -2183,7 +2218,7 @@ static void qemudShutdownVMDaemon(virConnectPtr conn,
VIR_WARN("Failed to restore all device ownership for %s",
vm->def->name);
- qemuDomainReAttachHostDevices(conn, vm->def);
+ qemuDomainReAttachHostDevices(conn, driver, vm->def);
retry:
if ((ret = qemuRemoveCgroup(conn, driver, vm)) < 0) {
@@ -6791,6 +6826,7 @@ out:
static int
qemudNodeDeviceReset (virNodeDevicePtr dev)
{
+ struct qemud_driver *driver = dev->conn->privateData;
pciDevice *pci;
unsigned domain, bus, slot, function;
int ret = -1;
@@ -6802,11 +6838,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 f2ffc25..dfa9ca5 100644
--- a/src/xen_unified.c
+++ b/src/xen_unified.c
@@ -1641,7 +1641,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

@@ -1,121 +0,0 @@
From 5aad00b08cadc4d9da8bffd3d255ffaac98d36dd 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 2dc2e1c..11b3e8b 100644
--- a/src/pci.c
+++ b/src/pci.c
@@ -402,29 +402,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)
@@ -529,7 +506,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;
@@ -537,16 +514,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);
@@ -604,14 +571,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,34 @@
From bcd4180124afa20580d720912e2179b3a2f9295a Mon Sep 17 00:00:00 2001
From: Daniel Veillard <veillard@redhat.com>
Date: Mon, 5 Oct 2009 17:03:14 +0200
Subject: [PATCH] 526769 change logrotate config default to weekly
* daemon/libvirtd.logrotate.in: change to weekly rotation of logs,
keep a month worth of data and also extend to cover LXC and UML
domain logs
(cherry picked from commit 529325bbdd050af89bda5a5c1a01b5553c49a57e)
Fedora-patch: libvirt-change-logrotate-config-to-weekly.patch
---
qemud/libvirtd.logrotate.in | 6 +++---
1 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/qemud/libvirtd.logrotate.in b/qemud/libvirtd.logrotate.in
index 9b42630..093651c 100644
--- a/qemud/libvirtd.logrotate.in
+++ b/qemud/libvirtd.logrotate.in
@@ -1,7 +1,7 @@
-@localstatedir@/log/libvirt/qemu/*.log {
- daily
+@localstatedir@/log/libvirt/qemu/*.log @localstatedir@/log/libvirt/uml/*.log @localstatedir@/log/libvirt/lxc/*.log {
+ weekly
missingok
- rotate 7
+ rotate 4
compress
delaycompress
copytruncate
--
1.6.2.5

View File

@@ -0,0 +1,77 @@
From 4721ceb9b85daabe53804627473b06ced821c695 Mon Sep 17 00:00:00 2001
From: Daniel P. Berrange <berrange@redhat.com>
Date: Mon, 14 Sep 2009 11:23:20 +0100
Subject: [PATCH] Allow control over QEMU audio backend
When using VNC for graphics + keyboard + mouse, we shouldn't
then use the host OS for audio. Audio should go back over
VNC.
When using SDL for graphics, we should use the host OS for
audio since that's where the display is. We need to allow
certain QEMU env variables to be passed through to guest
too to allow choice of QEMU audio backend.
* qemud/libvirtd.sysconf: Mention QEMU/SDL audio env vars
* src/qemu_conf.c: Passthrough QEMU/SDL audio env for SDL display,
disable host audio for VNC display
(cherry picked from commit b08e6d38ae7a0ed70300d7d82107f83fddb60f44)
Fedora-patch: libvirt-disable-audio-backend.patch
---
qemud/libvirtd.sysconf | 8 ++++++++
src/qemu_conf.c | 14 ++++++++++++++
2 files changed, 22 insertions(+), 0 deletions(-)
diff --git a/qemud/libvirtd.sysconf b/qemud/libvirtd.sysconf
index fe4596a..28080a0 100644
--- a/qemud/libvirtd.sysconf
+++ b/qemud/libvirtd.sysconf
@@ -7,3 +7,11 @@
# Override Kerberos service keytab for SASL/GSSAPI
#KRB5_KTNAME=/etc/libvirt/krb5.tab
+
+# Override the QEMU/SDL default audio driver probing when
+# starting virtual machines using SDL graphics
+#
+# NB these have no effect for VMs using VNC
+#QEMU_AUDIO_DRV=sdl
+#
+#SDL_AUDIODRIVER=pulse
diff --git a/src/qemu_conf.c b/src/qemu_conf.c
index f92bcef..0dd0624 100644
--- a/src/qemu_conf.c
+++ b/src/qemu_conf.c
@@ -2109,6 +2109,13 @@ int qemudBuildCommandLine(virConnectPtr conn,
ADD_ARG_LIT("-k");
ADD_ARG_LIT(def->graphics[0]->data.vnc.keymap);
}
+
+ /* QEMU implements a VNC extension for providing audio, so we
+ * set the audio backend to none, to prevent it opening the
+ * host OS audio devices since that causes security issues
+ * and is non-sensical when using VNC.
+ */
+ ADD_ENV_LIT("QEMU_AUDIO_DRV=none");
} else if ((def->ngraphics == 1) &&
def->graphics[0]->type == VIR_DOMAIN_GRAPHICS_TYPE_SDL) {
char *xauth = NULL;
@@ -2131,6 +2138,13 @@ int qemudBuildCommandLine(virConnectPtr conn,
ADD_ENV(display);
if (def->graphics[0]->data.sdl.fullscreen)
ADD_ARG_LIT("-full-screen");
+
+ /* If using SDL for video, then we should just let it
+ * use QEMU's host audio drivers, possibly SDL too
+ * User can set these two before starting libvirtd
+ */
+ ADD_ENV_COPY("QEMU_AUDIO_DRV");
+ ADD_ENV_COPY("SDL_AUDIODRIVER");
}
if (def->nvideos) {
--
1.6.2.5

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,31 @@
From a5fa9f63fcffbf70465386672f24edac439866b9 Mon Sep 17 00:00:00 2001
From: Daniel P. Berrange <berrange@redhat.com>
Date: Thu, 24 Sep 2009 15:42:25 +0100
Subject: [PATCH] Fix crash in device hotplug cleanup code
* src/qemu/qemu_driver.c: Fix crash in scenario where XML
parsing of hotplugged device failed & thus 'dev' is NULL
(cherry picked from commit 879cd8cc2ba00f795913f296556e05f25afa7877)
Fedora-patch: libvirt-fix-crash-on-device-hotplug-parse-error.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 0ce403c..c956258 100644
--- a/src/qemu_driver.c
+++ b/src/qemu_driver.c
@@ -5912,7 +5912,7 @@ cleanup:
if (cgroup)
virCgroupFree(&cgroup);
- if (ret < 0) {
+ if (ret < 0 && dev != NULL) {
if (qemuDomainSetDeviceOwnership(dom->conn, driver, dev, 1) < 0)
VIR_WARN0("Fail to restore disk device ownership");
virDomainDeviceDefFree(dev);
--
1.6.2.5

View File

@@ -0,0 +1,33 @@
From 7bc1491deba6338e514504d1b68fe097e7f2bf19 Mon Sep 17 00:00:00 2001
From: Daniel Veillard <veillard@redhat.com>
Date: Thu, 1 Oct 2009 11:54:38 +0200
Subject: [PATCH] Avoid a libvirtd crash on broken input 523418
* src/conf/domain_conf.c: a simple typo in an XML domain file could lead
to a crash, because we called STRPREFIX() on the looked up value without
checking it was non-null.
(cherry picked from commit 79d233b5ca62f86ab22d271d1f08ec20060eee88)
Fedora-patch: libvirt-fix-crash-on-missing-iface-target-dev.patch
---
src/domain_conf.c | 3 ++-
1 files changed, 2 insertions(+), 1 deletions(-)
diff --git a/src/domain_conf.c b/src/domain_conf.c
index c424c67..476cdd7 100644
--- a/src/domain_conf.c
+++ b/src/domain_conf.c
@@ -1031,7 +1031,8 @@ virDomainNetDefParseXML(virConnectPtr conn,
} else if ((ifname == NULL) &&
xmlStrEqual(cur->name, BAD_CAST "target")) {
ifname = virXMLPropString(cur, "dev");
- if (STRPREFIX((const char*)ifname, "vnet")) {
+ if ((ifname != NULL) &&
+ (STRPREFIX((const char*)ifname, "vnet"))) {
/* An auto-generated target name, blank it out */
VIR_FREE(ifname);
}
--
1.6.2.5

View File

@@ -0,0 +1,29 @@
From 58c38896a67c170063401d8091bae7dca8842923 Mon Sep 17 00:00:00 2001
From: Jiri Denemark <jdenemar@redhat.com>
Date: Wed, 23 Sep 2009 18:46:23 +0200
Subject: [PATCH] Fix a typo in virDiskHasValidPciAddr()
(cherry-picked from commit 3620e3cdcfe56cc4475b5ef1a0a893757240b795)
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
Fedora-patch: libvirt-fix-device-detach-typo1.patch
---
src/domain_conf.h | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/src/domain_conf.h b/src/domain_conf.h
index 09368d9..d494e54 100644
--- a/src/domain_conf.h
+++ b/src/domain_conf.h
@@ -125,7 +125,7 @@ struct _virDomainDiskDef {
static inline int
virDiskHasValidPciAddr(virDomainDiskDefPtr def)
{
- return def->pci_addr.domain || def->pci_addr.domain || def->pci_addr.slot;
+ return def->pci_addr.domain || def->pci_addr.bus || def->pci_addr.slot;
}
--
1.6.2.5

View File

@@ -0,0 +1,30 @@
From 81e967c716ce8c085be8baad9169f7772452d187 Mon Sep 17 00:00:00 2001
From: Mark McLoughlin <markmc@redhat.com>
Date: Thu, 24 Sep 2009 08:55:55 +0100
Subject: [PATCH] Fix a typo in virNetHasValidPciAddr() too
* src/domain_conf.h: check domain/bus/slot, not domain/domain/slot
(cherry-picked from commit 6bfffce91635bb08de601747e94ed1182c0f47eb)
Fedora-patch: libvirt-fix-device-detach-typo2.patch
---
src/domain_conf.h | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/src/domain_conf.h b/src/domain_conf.h
index d494e54..7c918a7 100644
--- a/src/domain_conf.h
+++ b/src/domain_conf.h
@@ -207,7 +207,7 @@ struct _virDomainNetDef {
static inline int
virNetHasValidPciAddr(virDomainNetDefPtr def)
{
- return def->pci_addr.domain || def->pci_addr.domain || def->pci_addr.slot;
+ return def->pci_addr.domain || def->pci_addr.bus || def->pci_addr.slot;
}
enum virDomainChrSrcType {
--
1.6.2.5

View File

@@ -0,0 +1,30 @@
From 3a64779ec5a89d38d64e07bca2b11b19e1882d7a Mon Sep 17 00:00:00 2001
From: Charles Duffy <charles@dyfis.net>
Date: Thu, 24 Sep 2009 09:00:24 +0100
Subject: [PATCH] Fix unitialized variable in qemudDomainDetachHostPciDevice()
* src/qemu_driver.c: initialize detach var
(cherry-picked from commit 580ad29288751234bee47ac9f6c04dac1dc529ea)
Fedora-patch: libvirt-fix-device-detach-typo3.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 7c7b985..550a59c 100644
--- a/src/qemu_driver.c
+++ b/src/qemu_driver.c
@@ -6126,7 +6126,7 @@ static int qemudDomainDetachHostPciDevice(virConnectPtr conn,
virDomainObjPtr vm,
virDomainDeviceDefPtr dev)
{
- virDomainHostdevDefPtr detach;
+ virDomainHostdevDefPtr detach = NULL;
char *cmd, *reply;
int i, ret;
pciDevice *pci;
--
1.6.2.5

View File

@@ -1,79 +0,0 @@
From 165fb333c9d954fec636dc0f1917ba50417478c0 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/network 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 qemudDomainDetachNetDevice() and
qemudDomainDetachPciDiskDevice()
(cherry picked from commit 4e12af5623e4a962a6bb911af06fa29aa85befba)
Fedora-patch: libvirt-fix-device-list-update-after-detach.patch
---
src/qemu_driver.c | 38 ++++++++++++++++++--------------------
1 files changed, 18 insertions(+), 20 deletions(-)
diff --git a/src/qemu_driver.c b/src/qemu_driver.c
index bd58435..2c4fd6f 100644
--- a/src/qemu_driver.c
+++ b/src/qemu_driver.c
@@ -5404,18 +5404,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:
@@ -5503,16 +5502,15 @@ qemudDomainDetachNetDevice(virConnectPtr conn,
DEBUG("%s: host_net_remove reply: %s", vm->def->name, reply);
- if (vm->def->nnets > 1) {
- vm->def->nets[i] = vm->def->nets[--vm->def->nnets];
- if (VIR_REALLOC_N(vm->def->nets, vm->def->nnets) < 0) {
- virReportOOMError(conn);
- goto cleanup;
- }
- } else {
- VIR_FREE(vm->def->nets[0]);
- vm->def->nnets = 0;
+ if (i != --vm->def->nnets)
+ memmove(&vm->def->nets[i],
+ &vm->def->nets[i+1],
+ sizeof(*vm->def->nets) * (vm->def->nnets-i));
+ if (VIR_REALLOC_N(vm->def->nets, vm->def->nnets) < 0) {
+ virReportOOMError(conn);
+ goto cleanup;
}
+
ret = 0;
cleanup:
--
1.6.2.5

View File

@@ -0,0 +1,32 @@
From 7692e1e19487c28454b1e5f6488d5574c70883f2 Mon Sep 17 00:00:00 2001
From: Chris Lalancette <clalance@redhat.com>
Date: Mon, 21 Sep 2009 14:53:31 +0200
Subject: [PATCH] Don't do virSetConnError when virDrvSupportsFeature is successful.
Signed-off-by: Chris Lalancette <clalance@redhat.com>
Fedora-patch: libvirt-fix-drv-supports-feature-bogus-error.patch
---
src/libvirt.c | 7 +++++--
1 files changed, 5 insertions(+), 2 deletions(-)
diff --git a/src/libvirt.c b/src/libvirt.c
index 4a11688..fa59dc7 100644
--- a/src/libvirt.c
+++ b/src/libvirt.c
@@ -1349,8 +1349,11 @@ virDrvSupportsFeature (virConnectPtr conn, int feature)
}
ret = VIR_DRV_SUPPORTS_FEATURE (conn->driver, conn, feature);
- /* Copy to connection error object for back compatability */
- virSetConnError(conn);
+
+ if (ret < 0)
+ /* Copy to connection error object for back compatability */
+ virSetConnError(conn);
+
return ret;
}
--
1.6.2.5

View File

@@ -0,0 +1,79 @@
From 71de8d92f20a9a9ee76d4d5df77ff477f1b7d441 Mon Sep 17 00:00:00 2001
From: Matthias Bolte <matthias.bolte@googlemail.com>
Date: Wed, 30 Sep 2009 02:17:27 +0200
Subject: [PATCH] Fix memory leaks in libvirtd's message processing
Commit 47cab734995fa9521b1df05d37e9978eedd8d3a2 changed the way how
qemud_client_message objects were reused. Before this commit
remoteDispatchClientRequest() reused the received message for normal responses
and to report non-fatal errors. If a fatal error occurred qemudWorker() frees
the message. After this commit non-fatal errors are reported by
remoteSerializeReplyError() using a new qemud_client_message object and the
original message leaks.
To fix this leak the original message has to be freed if
remoteSerializeReplyError() succeeds. If remoteSerializeReplyError()
fails the original message is freed in qemudWorker().
* daemon/dispatch.c: free qemud_client_message objects that will not be reused
and would leak otherwise, also free the allocated qemud_client_message object
in remoteSerializeError() if an error occurs
(cherry-picked from commit c6f1459eb998619ab21a92d9bb87341f26978181)
Fedora-patch: libvirt-fix-libvirtd-leak-in-error-reply.patch
---
qemud/dispatch.c | 15 +++++++++++++--
1 files changed, 13 insertions(+), 2 deletions(-)
diff --git a/qemud/dispatch.c b/qemud/dispatch.c
index a60f2f4..ddb3215 100644
--- a/qemud/dispatch.c
+++ b/qemud/dispatch.c
@@ -191,6 +191,7 @@ remoteSerializeError(struct qemud_client *client,
xdr_error:
xdr_destroy(&xdr);
+ VIR_FREE(msg);
fatal_error:
xdr_free((xdrproc_t)xdr_remote_error, (char *)rerr);
return -1;
@@ -336,6 +337,7 @@ remoteDispatchClientRequest (struct qemud_server *server,
struct qemud_client *client,
struct qemud_client_message *msg)
{
+ int ret;
remote_error rerr;
memset(&rerr, 0, sizeof rerr);
@@ -364,7 +366,12 @@ remoteDispatchClientRequest (struct qemud_server *server,
}
error:
- return remoteSerializeReplyError(client, &rerr, &msg->hdr);
+ ret = remoteSerializeReplyError(client, &rerr, &msg->hdr);
+
+ if (ret >= 0)
+ VIR_FREE(msg);
+
+ return ret;
}
@@ -521,8 +528,12 @@ remoteDispatchClientCall (struct qemud_server *server,
rpc_error:
/* Semi-bad stuff happened, we can still try to send back
* an RPC error message to client */
- return remoteSerializeReplyError(client, &rerr, &msg->hdr);
+ rv = remoteSerializeReplyError(client, &rerr, &msg->hdr);
+
+ if (rv >= 0)
+ VIR_FREE(msg);
+ return rv;
xdr_error:
/* Seriously bad stuff happened, so we'll kill off this client
--
1.6.2.5

View File

@@ -0,0 +1,46 @@
From ba585ed6cff624c6c0f1f9801382fd6846466ee0 Mon Sep 17 00:00:00 2001
From: Mark McLoughlin <markmc@redhat.com>
Date: Thu, 17 Sep 2009 15:31:08 +0100
Subject: [PATCH] Fix net/disk hot-unplug segfault
When we hot-unplug the last device, we're currently double-freeing
the device definition.
Reported by Michal Nowak here:
https://bugzilla.redhat.com/523953
* src/qemu_driver.c: fix double free
(cherry-picked from commit 8881ae1bf8783006777429403cc543c33187175d)
Fedora-patch: libvirt-fix-net-hotunplug-double-free.patch
---
src/qemu_driver.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/qemu_driver.c b/src/qemu_driver.c
index a65334f..de31581 100644
--- a/src/qemu_driver.c
+++ b/src/qemu_driver.c
@@ -5998,7 +5998,7 @@ try_command:
/* ignore, harmless */
}
} else {
- VIR_FREE(vm->def->disks[0]);
+ VIR_FREE(vm->def->disks);
vm->def->ndisks = 0;
}
virDomainDiskDefFree(detach);
@@ -6100,7 +6100,7 @@ qemudDomainDetachNetDevice(virConnectPtr conn,
/* ignore, harmless */
}
} else {
- VIR_FREE(vm->def->nets[0]);
+ VIR_FREE(vm->def->nets);
vm->def->nnets = 0;
}
virDomainNetDefFree(detach);
--
1.6.2.5

View File

@@ -0,0 +1,50 @@
From 17831d20051f8de8f1f7d661e8a23f4fe67c2153 Mon Sep 17 00:00:00 2001
From: Mark McLoughlin <markmc@redhat.com>
Date: Thu, 17 Sep 2009 15:32:45 +0100
Subject: [PATCH] Fix leak in PCI hostdev hot-unplug
* src/qemu_driver.c: sync the hostdev hot-unplug code with the disk/net
code.
(cherry-picked from commit a70da51ff76ed860bfc0cdee2e1d556da997c557)
Fedora-patch: libvirt-fix-pci-hostdev-hotunplug-leak.patch
---
src/qemu_driver.c | 20 +++++++++++++-------
1 files changed, 13 insertions(+), 7 deletions(-)
diff --git a/src/qemu_driver.c b/src/qemu_driver.c
index de31581..2ddcdc0 100644
--- a/src/qemu_driver.c
+++ b/src/qemu_driver.c
@@ -6206,14 +6206,20 @@ static int qemudDomainDetachHostPciDevice(virConnectPtr conn,
pciFreeDevice(conn, pci);
}
- if (i != --vm->def->nhostdevs)
- memmove(&vm->def->hostdevs[i],
- &vm->def->hostdevs[i+1],
- sizeof(*vm->def->hostdevs) * (vm->def->nhostdevs-i));
- if (VIR_REALLOC_N(vm->def->hostdevs, vm->def->nhostdevs) < 0) {
- virReportOOMError(conn);
- ret = -1;
+ if (vm->def->nhostdevs > 1) {
+ memmove(vm->def->hostdevs + i,
+ vm->def->hostdevs + i + 1,
+ sizeof(*vm->def->hostdevs) *
+ (vm->def->nhostdevs - (i + 1)));
+ vm->def->nhostdevs--;
+ if (VIR_REALLOC_N(vm->def->hostdevs, vm->def->nhostdevs) < 0) {
+ /* ignore, harmless */
+ }
+ } else {
+ VIR_FREE(vm->def->hostdevs);
+ vm->def->nhostdevs = 0;
}
+ virDomainHostdevDefFree(detach);
return ret;
}
--
1.6.2.5

View File

@@ -0,0 +1,53 @@
From f1be5a4714e194a84840343e0937fe62463a18dc Mon Sep 17 00:00:00 2001
From: Charles Duffy <Charles_Duffy@dell.com>
Date: Fri, 18 Sep 2009 11:32:35 -0500
Subject: [PATCH] Prevent attempt to call cat -c during virDomainSave to raw
Fedora-patch: libvirt-fix-qemu-raw-format-save.patch
---
src/qemu_driver.c | 28 ++++++++++++++++++----------
1 files changed, 18 insertions(+), 10 deletions(-)
diff --git a/src/qemu_driver.c b/src/qemu_driver.c
index 2ddcdc0..7c7b985 100644
--- a/src/qemu_driver.c
+++ b/src/qemu_driver.c
@@ -3905,17 +3905,25 @@ static int qemudDomainSave(virDomainPtr dom,
goto cleanup;
}
- const char *prog = qemudSaveCompressionTypeToString(header.compressed);
- if (prog == NULL) {
- qemudReportError(dom->conn, dom, NULL, VIR_ERR_INTERNAL_ERROR,
- _("Invalid compress format %d"), header.compressed);
- goto cleanup;
- }
+ {
+ const char *prog = qemudSaveCompressionTypeToString(header.compressed);
+ const char *args;
- if (STREQ (prog, "raw"))
- prog = "cat";
- internalret = virAsprintf(&command, "migrate \"exec:"
- "%s -c >> '%s' 2>/dev/null\"", prog, safe_path);
+ if (prog == NULL) {
+ qemudReportError(dom->conn, dom, NULL, VIR_ERR_INTERNAL_ERROR,
+ _("Invalid compress format %d"), header.compressed);
+ goto cleanup;
+ }
+
+ if (STREQ (prog, "raw")) {
+ prog = "cat";
+ args = "";
+ } else {
+ args = "-c";
+ }
+ internalret = virAsprintf(&command, "migrate \"exec:"
+ "%s %s >> '%s' 2>/dev/null\"", prog, args, safe_path);
+ }
if (internalret < 0) {
virReportOOMError(dom->conn);
--
1.6.2.5

View File

@@ -0,0 +1,38 @@
From 0b846a30468a6b4586407f020ccde7bb51afaf98 Mon Sep 17 00:00:00 2001
From: Daniel P. Berrange <berrange@redhat.com>
Date: Mon, 12 Oct 2009 20:03:50 +0100
Subject: [PATCH] Fix QEMU restore from file in raw format
The logic for running the decompression programs was broken in
commit f238709304f9f6c57204cdd943e542cbae38fa5f, so that for
non-raw formats the decompression program was never run, and
for raw formats, it tried to exec an argv[] with initial NULL
in the program name.
* src/qemu/qemu_driver.c: Fix logic in runing decompression program
(cherry picked from commit 74b379cbd5ba9f472a3a2d5710e497966b1a3a37)
Fedora-patch: libvirt-fix-qemu-restore-from-raw1.patch
---
src/qemu_driver.c | 3 +--
1 files changed, 1 insertions(+), 2 deletions(-)
diff --git a/src/qemu_driver.c b/src/qemu_driver.c
index 550a59c..0ce403c 100644
--- a/src/qemu_driver.c
+++ b/src/qemu_driver.c
@@ -4541,9 +4541,8 @@ static int qemudDomainRestore(virConnectPtr conn,
goto cleanup;
}
- if (header.compressed != QEMUD_SAVE_FORMAT_RAW)
+ if (header.compressed != QEMUD_SAVE_FORMAT_RAW) {
intermediate_argv[0] = prog;
- else {
intermediatefd = fd;
fd = -1;
if (virExec(conn, intermediate_argv, NULL, NULL,
--
1.6.2.5

View File

@@ -0,0 +1,120 @@
From 57d7cc602d14c6b50e2826e427a5de124e479f95 Mon Sep 17 00:00:00 2001
From: Daniel P. Berrange <berrange@redhat.com>
Date: Mon, 12 Oct 2009 20:32:33 +0100
Subject: [PATCH] Fix virFileReadLimFD/virFileReadAll to handle EINTR
The fread_file_lim() function uses fread() but never handles
EINTR results, causing unexpected failures when reading QEMU
help arg info. It was unneccessarily using FILE * instead
of plain UNIX file handles, which prevented use of saferead()
* src/util/util.c: Switch fread_file_lim over to use saferead
instead of fread, remove FILE * use, and rename
(cherry picked from commit 11a36d956cb8a5e439e535bff3e0cfce50a64bca)
Fedora-patch: libvirt-fix-qemu-restore-from-raw2.patch
---
src/util.c | 45 ++++++++++++---------------------------------
1 files changed, 12 insertions(+), 33 deletions(-)
diff --git a/src/util.c b/src/util.c
index 1878e33..7bc3a66 100644
--- a/src/util.c
+++ b/src/util.c
@@ -887,7 +887,7 @@ virExec(virConnectPtr conn,
number of bytes. If the length of the input is <= max_len, and
upon error while reading that data, it works just like fread_file. */
static char *
-fread_file_lim (FILE *stream, size_t max_len, size_t *length)
+saferead_lim (int fd, size_t max_len, size_t *length)
{
char *buf = NULL;
size_t alloc = 0;
@@ -895,8 +895,8 @@ fread_file_lim (FILE *stream, size_t max_len, size_t *length)
int save_errno;
for (;;) {
- size_t count;
- size_t requested;
+ int count;
+ int requested;
if (size + BUFSIZ + 1 > alloc) {
alloc += alloc / 2;
@@ -912,12 +912,12 @@ fread_file_lim (FILE *stream, size_t max_len, size_t *length)
/* Ensure that (size + requested <= max_len); */
requested = MIN (size < max_len ? max_len - size : 0,
alloc - size - 1);
- count = fread (buf + size, 1, requested, stream);
+ count = saferead (fd, buf + size, requested);
size += count;
if (count != requested || requested == 0) {
save_errno = errno;
- if (ferror (stream))
+ if (count < 0)
break;
buf[size] = '\0';
*length = size;
@@ -930,12 +930,12 @@ fread_file_lim (FILE *stream, size_t max_len, size_t *length)
return NULL;
}
-/* A wrapper around fread_file_lim that maps a failure due to
+/* A wrapper around saferead_lim that maps a failure due to
exceeding the maximum size limitation to EOVERFLOW. */
-static int virFileReadLimFP(FILE *fp, int maxlen, char **buf)
+int virFileReadLimFD(int fd, int maxlen, char **buf)
{
size_t len;
- char *s = fread_file_lim (fp, maxlen+1, &len);
+ char *s = saferead_lim (fd, maxlen+1, &len);
if (s == NULL)
return -1;
if (len > maxlen || (int)len != len) {
@@ -949,37 +949,16 @@ static int virFileReadLimFP(FILE *fp, int maxlen, char **buf)
return len;
}
-/* Like virFileReadLimFP, but use a file descriptor rather than a FILE*. */
-int virFileReadLimFD(int fd_arg, int maxlen, char **buf)
-{
- int fd = dup (fd_arg);
- if (fd >= 0) {
- FILE *fp = fdopen (fd, "r");
- if (fp) {
- int len = virFileReadLimFP (fp, maxlen, buf);
- int saved_errno = errno;
- fclose (fp);
- errno = saved_errno;
- return len;
- } else {
- int saved_errno = errno;
- close (fd);
- errno = saved_errno;
- }
- }
- return -1;
-}
-
int virFileReadAll(const char *path, int maxlen, char **buf)
{
- FILE *fh = fopen(path, "r");
- if (fh == NULL) {
+ int fd = open(path, O_RDONLY);
+ if (fd < 0) {
virReportSystemError(NULL, errno, _("Failed to open file '%s'"), path);
return -1;
}
- int len = virFileReadLimFP (fh, maxlen, buf);
- fclose(fh);
+ int len = virFileReadLimFD(fd, maxlen, buf);
+ close(fd);
if (len < 0) {
virReportSystemError(NULL, errno, _("Failed to read file '%s'"), path);
return -1;
--
1.6.2.5

View File

@@ -0,0 +1,41 @@
From 6b12148864cf6a1d22a2cf4e0e9c48e9946331cb Mon Sep 17 00:00:00 2001
From: Mark McLoughlin <markmc@redhat.com>
Date: Wed, 30 Sep 2009 18:37:03 +0100
Subject: [PATCH] Fix USB device re-labelling
A simple misplaced break out of a switch results in:
libvir: error : Failed to open file '/sys/bus/pci/devices/0000:00:54c./vendor': No such file or directory
libvir: error : Failed to open file '/sys/bus/pci/devices/0000:00:54c./device': No such file or directory
libvir: error : this function is not supported by the hypervisor: Failed to read product/vendor ID for 0000:00:54c.
when trying to passthrough a USB host device to qemu.
* src/security_selinux.c: fix a switch/break thinko
Fedora-patch: libvirt-fix-usb-device-passthrough.patch
---
src/security_selinux.c | 3 +--
1 files changed, 1 insertions(+), 2 deletions(-)
diff --git a/src/security_selinux.c b/src/security_selinux.c
index bc295b1..b4dc153 100644
--- a/src/security_selinux.c
+++ b/src/security_selinux.c
@@ -464,12 +464,11 @@ SELinuxSetSecurityHostdevLabel(virConnectPtr conn,
ret = usbDeviceFileIterate(conn, usb, SELinuxSetSecurityUSBLabel, vm);
usbFreeDevice(conn, usb);
-
- break;
} else {
/* XXX deal with product/vendor better */
ret = 0;
}
+ break;
}
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI: {
--
1.6.2.5

View File

@@ -0,0 +1,103 @@
From cab81502320d97dac4c5c12e7496f30896709c49 Mon Sep 17 00:00:00 2001
From: Matthias Bolte <matthias.bolte@googlemail.com>
Date: Tue, 22 Sep 2009 15:12:48 +0200
Subject: [PATCH] Fix xen driver refcounting.
The commit cb51aa48a777ddae6997faa9f28350cb62655ffd "Fix up connection
reference counting." changed the driver closing and virConnectPtr
unref-logic in virConnectClose().
Before this commit virConnectClose() closed all drivers of the given
virConnectPtr and virUnrefConnect()'ed it afterwards. After this
commit the driver-closing is done in virUnrefConnect() if and only if
the ref-count of the virConnectPtr dropped to zero.
This change in execution order leads to a virConnectPtr leak, at least
for connections to Xen.
The relevant call sequences:
virConnectOpen() -> xenUnifiedOpen() ...
... xenInotifyOpen() -> virConnectRef(conn)
... xenStoreOpen() -> xenStoreAddWatch() -> conn->refs++
virConnectClose() -> xenUnifiedClose() ...
... xenInotifyClose() -> virUnrefConnect(conn)
... xenStoreClose() -> xenStoreRemoveWatch() -> virUnrefConnect(conn)
Before the commit this additional virConnectRef/virUnrefConnect calls
where no problem, because virConnectClose() closed the drivers
explicitly and the additional refs added by the Xen subdrivers were
removed properly. After the commit this additional refs result in a
virConnectPtr leak (including a leak of the hypercall file handle;
that's how I noticed this problem), because now the drivers are only
close if and only if the ref-count drops to zero, but this cannot
happen anymore, because the additional refs from the Xen subdrivers
would only be removed if the drivers get closed, but that doesn't
happen because the ref-count cannot drop to zero.
The fix for this problem is simple: remove the
virConnectRef/virUnrefConnect calls from the Xen subdrivers (see
attached patch). Maybe someone could explain why the Xen Inotify and
Xen Store driver do this extra ref-counting, but none of the other Xen
subdrivers. It seems unnecessary to me and can be removed without
problems.
Signed-off-by: Chris Lalancette <clalance@redhat.com>
(cherry picked from commit 6ed7374c5a6c6a2b1b1801d7d041dc7f09748592)
Fedora-patch: libvirt-fix-xen-driver-refcounting.patch
---
src/xen_inotify.c | 2 --
src/xs_internal.c | 3 ---
2 files changed, 0 insertions(+), 5 deletions(-)
diff --git a/src/xen_inotify.c b/src/xen_inotify.c
index e312b9e..ecaefaf 100644
--- a/src/xen_inotify.c
+++ b/src/xen_inotify.c
@@ -463,7 +463,6 @@ xenInotifyOpen(virConnectPtr conn ATTRIBUTE_UNUSED,
DEBUG0("Failed to add inotify handle, disabling events");
}
- virConnectRef(conn);
return 0;
}
@@ -486,7 +485,6 @@ xenInotifyClose(virConnectPtr conn)
if (priv->inotifyWatch != -1)
virEventRemoveHandle(priv->inotifyWatch);
close(priv->inotifyFD);
- virUnrefConnect(conn);
return 0;
}
diff --git a/src/xs_internal.c b/src/xs_internal.c
index 1f54b1f..a18dcad 100644
--- a/src/xs_internal.c
+++ b/src/xs_internal.c
@@ -1139,8 +1139,6 @@ int xenStoreAddWatch(virConnectPtr conn,
list->watches[n] = watch;
list->count++;
- conn->refs++;
-
return xs_watch(priv->xshandle, watch->path, watch->token);
}
@@ -1190,7 +1188,6 @@ int xenStoreRemoveWatch(virConnectPtr conn,
; /* Failure to reduce memory allocation isn't fatal */
}
list->count--;
- virUnrefConnect(conn);
return 0;
}
}
--
1.6.2.5

View File

@@ -1,141 +0,0 @@
From c8a9dbe131713de83bdc67c563c4ab149e32c489 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 11b3e8b..74f7ef0 100644
--- a/src/pci.c
+++ b/src/pci.c
@@ -456,15 +456,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;
}
@@ -475,7 +478,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;
}
@@ -492,9 +497,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);
@@ -516,7 +524,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;
}
@@ -533,8 +543,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;
}
@@ -582,10 +596,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 4ce7a54..fd39fc2 100644
--- a/src/qemu_driver.c
+++ b/src/qemu_driver.c
@@ -1465,9 +1465,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,31 @@
From 918724aa76982224437384d712c182c332fa5ef9 Mon Sep 17 00:00:00 2001
From: Dan Kenigsberg <danken@redhat.com>
Date: Wed, 21 Oct 2009 13:56:04 +0200
Subject: [PATCH] Do not log rotate very small logs
Without this, after few weeks without use, each defined domain grows a
tail of empty gzipped logs, instead of keeping just the last log of
interest.
* daemon/libvirtd.logrotate.in: only rotate when the log is over 100 KBytes
(cherry picked from commit b03fe2d0aefb57a096a102bf23375f0a167ca189)
Fedora-patch: libvirt-logrotate-avoid-compressing-small-logs.patch
---
qemud/libvirtd.logrotate.in | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/qemud/libvirtd.logrotate.in b/qemud/libvirtd.logrotate.in
index 093651c..0c51fd3 100644
--- a/qemud/libvirtd.logrotate.in
+++ b/qemud/libvirtd.logrotate.in
@@ -5,4 +5,5 @@
compress
delaycompress
copytruncate
+ minsize 100k
}
--
1.6.2.5

View File

@@ -0,0 +1,54 @@
From b7e3ac4f23befe67518b57e34691c301820a436c Mon Sep 17 00:00:00 2001
From: Mark McLoughlin <markmc@redhat.com>
Date: Tue, 6 Oct 2009 12:33:17 +0100
Subject: [PATCH] Create /var/log/libvirt/{lxc,uml} dirs
Otherwise logrotate barfs:
error: error accessing /var/log/libvirt/uml: No such file or directory
error: libvirtd:1 glob failed for /var/log/libvirt/uml/*.log
error: found error in /var/log/libvirt/qemu/*.log /var/log/libvirt/uml/*.log /var/log/libvirt/lxc/*.log , skipping
* qemud/Makefile.am: always create /var/log/libvirt/{lxc,uml} when
installing the logrotate conf; not ideal, but easier than making
the logrotate conf depend on which drivers are enabled
Fedora-patch: libvirt-logrotate-create-lxc-uml-dirs.patch
---
qemud/Makefile.am | 6 ++++--
1 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/qemud/Makefile.am b/qemud/Makefile.am
index 3d143da..a7f4bdf 100644
--- a/qemud/Makefile.am
+++ b/qemud/Makefile.am
@@ -176,7 +176,7 @@ install-data-local: install-init install-data-sasl install-data-polkit \
test -e $(DESTDIR)$(sysconfdir)/libvirt/qemu/networks/autostart/default.xml || \
ln -s ../default.xml \
$(DESTDIR)$(sysconfdir)/libvirt/qemu/networks/autostart/default.xml
- mkdir -p $(DESTDIR)$(localstatedir)/log/libvirt/qemu
+ mkdir -p $(DESTDIR)$(localstatedir)/log/libvirt
mkdir -p $(DESTDIR)$(localstatedir)/run/libvirt
mkdir -p $(DESTDIR)$(localstatedir)/lib/libvirt
@@ -184,7 +184,7 @@ uninstall-local:: uninstall-init uninstall-data-sasl install-data-polkit
rm -f $(DESTDIR)$(sysconfdir)/libvirt/qemu/networks/autostart/default.xml
rm -f $(DESTDIR)$(sysconfdir)/$(default_xml_dest)
rmdir $(DESTDIR)$(sysconfdir)/libvirt/qemu/networks/autostart || :
- rmdir $(DESTDIR)$(localstatedir)/log/libvirt/qemu || :
+ rmdir $(DESTDIR)$(localstatedir)/log/libvirt || :
rmdir $(DESTDIR)$(localstatedir)/run/libvirt || :
rmdir $(DESTDIR)$(localstatedir)/lib/libvirt || :
@@ -240,6 +240,8 @@ libvirtd.logrotate: libvirtd.logrotate.in
install-logrotate: libvirtd.logrotate
mkdir -p $(DESTDIR)$(localstatedir)/log/libvirt/qemu/
+ mkdir -p $(DESTDIR)$(localstatedir)/log/libvirt/lxc/
+ mkdir -p $(DESTDIR)$(localstatedir)/log/libvirt/uml/
mkdir -p $(DESTDIR)$(sysconfdir)/logrotate.d/
$(INSTALL_DATA) $< $(DESTDIR)$(sysconfdir)/logrotate.d/libvirtd
--
1.6.2.5

View File

@@ -0,0 +1,32 @@
From ba3bc9b22a21b8e9e110166c98be70e2ad6469cb Mon Sep 17 00:00:00 2001
From: Cole Robinson <crobinso@redhat.com>
Date: Tue, 13 Oct 2009 11:31:27 -0400
Subject: [PATCH] network: Fix printing XML 'delay' attribute
When specifying bridge delay via network XML define, we were looking for
the 'delay' attribute, but would dump the value as 'forwardDelay'. Have
the output match the expected input (and schema).
(cherry picked from commit 3b13aa3db37bf5a692bccfa015a01999043e797b)
Fedora-patch: libvirt-network-delay-attribute-formatting.patch
---
src/network_conf.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/src/network_conf.c b/src/network_conf.c
index 3764bb4..f75c457 100644
--- a/src/network_conf.c
+++ b/src/network_conf.c
@@ -587,7 +587,7 @@ char *virNetworkDefFormat(virConnectPtr conn,
virBufferAddLit(&buf, " <bridge");
if (def->bridge)
virBufferEscapeString(&buf, " name='%s'", def->bridge);
- virBufferVSprintf(&buf, " stp='%s' forwardDelay='%ld' />\n",
+ virBufferVSprintf(&buf, " stp='%s' delay='%ld' />\n",
def->stp ? "on" : "off",
def->delay);
--
1.6.2.5

View File

@@ -0,0 +1,177 @@
From d7722ed1cb04aa8a7b9fbf880882841867b69ab0 Mon Sep 17 00:00:00 2001
From: Mark McLoughlin <markmc@redhat.com>
Date: Mon, 12 Oct 2009 10:52:13 +0100
Subject: [PATCH] Take domain type into account when looking up default machine
If one has e.g.
<guest>
<os_type>hvm</os_type>
<arch name='x86_64'>
<wordsize>64</wordsize>
<emulator>/usr/bin/qemu-system-x86_64</emulator>
<machine>pc-0.11</machine>
<machine canonical='pc-0.11'>pc</machine>
<machine>pc-0.10</machine>
<machine>isapc</machine>
<domain type='qemu'>
</domain>
<domain type='kvm'>
<emulator>/usr/bin/kvm</emulator>
<machine>pc</machine>
<machine>isapc</machine>
</domain>
</arch>
</guest>
and start a guest with:
<domain type='kvm'>
...
<os>
<type arch='x86_64'>hvm</type>
...
</os>
</domain>
then the default machine type should be 'pc' and not 'pc-0.11'
Issue was reported by Anton Protopopov.
* src/capabilities.[ch]: pass the domain type to
virCapabilitiesDefaultGuestArch() and use it to look up the default
machine type from a specific guest domain if needed.
* src/conf/domain_conf.c, src/xen/xm_internal.c: update
* tests/qemuxml2argvdata/qemuxml2argv-machine-aliases2.xml: update
the domain type to 'kvm' and remove the machine type to check
that the default gets looked up correctly
(cherry picked from commit 73c901a8075c09203545fc81164c1e5f11c67c89)
Fedora-patch: libvirt-qemu-machine-type-fixes1.patch
---
src/capabilities.c | 31 ++++++++++++++++---
src/capabilities.h | 3 +-
src/domain_conf.c | 3 +-
src/xm_internal.c | 3 +-
.../qemuxml2argv-machine-aliases2.xml | 4 +-
5 files changed, 34 insertions(+), 10 deletions(-)
diff --git a/src/capabilities.c b/src/capabilities.c
index 38fe7fc..6ebddf5 100644
--- a/src/capabilities.c
+++ b/src/capabilities.c
@@ -549,22 +549,43 @@ virCapabilitiesDefaultGuestArch(virCapsPtr caps,
* @caps: capabilities to query
* @ostype: OS type to search for
* @arch: architecture to search for
+ * @domain: domain type to search for
*
* Returns the first machine variant associated with
- * the requested operating system type and architecture
+ * the requested operating system type, architecture
+ * and domain type
*/
extern const char *
virCapabilitiesDefaultGuestMachine(virCapsPtr caps,
const char *ostype,
- const char *arch)
+ const char *arch,
+ const char *domain)
{
int i;
+
for (i = 0 ; i < caps->nguests ; i++) {
- if (STREQ(caps->guests[i]->ostype, ostype) &&
- STREQ(caps->guests[i]->arch.name, arch) &&
- caps->guests[i]->arch.defaultInfo.nmachines)
+ virCapsGuestPtr guest = caps->guests[i];
+ int j;
+
+ if (!STREQ(guest->ostype, ostype) || !STREQ(guest->arch.name, arch))
+ continue;
+
+ for (j = 0; j < guest->arch.ndomains; j++) {
+ virCapsGuestDomainPtr dom= guest->arch.domains[j];
+
+ if (!STREQ(dom->type, domain))
+ continue;
+
+ if (!dom->info.nmachines)
+ break;
+
+ return dom->info.machines[0]->name;
+ }
+
+ if (guest->arch.defaultInfo.nmachines)
return caps->guests[i]->arch.defaultInfo.machines[0]->name;
}
+
return NULL;
}
diff --git a/src/capabilities.h b/src/capabilities.h
index b958d95..2f24605 100644
--- a/src/capabilities.h
+++ b/src/capabilities.h
@@ -207,7 +207,8 @@ virCapabilitiesDefaultGuestArch(virCapsPtr caps,
extern const char *
virCapabilitiesDefaultGuestMachine(virCapsPtr caps,
const char *ostype,
- const char *arch);
+ const char *arch,
+ const char *domain);
extern const char *
virCapabilitiesDefaultGuestEmulator(virCapsPtr caps,
const char *ostype,
diff --git a/src/domain_conf.c b/src/domain_conf.c
index 5ae0775..c424c67 100644
--- a/src/domain_conf.c
+++ b/src/domain_conf.c
@@ -2664,7 +2664,8 @@ static virDomainDefPtr virDomainDefParseXML(virConnectPtr conn,
if (!def->os.machine) {
const char *defaultMachine = virCapabilitiesDefaultGuestMachine(caps,
def->os.type,
- def->os.arch);
+ def->os.arch,
+ virDomainVirtTypeToString(def->virtType));
if (defaultMachine != NULL) {
if (!(def->os.machine = strdup(defaultMachine))) {
virReportOOMError(conn);
diff --git a/src/xm_internal.c b/src/xm_internal.c
index de3aca9..6d351d4 100644
--- a/src/xm_internal.c
+++ b/src/xm_internal.c
@@ -720,7 +720,8 @@ xenXMDomainConfigParse(virConnectPtr conn, virConfPtr conf) {
defaultMachine = virCapabilitiesDefaultGuestMachine(priv->caps,
def->os.type,
- def->os.arch);
+ def->os.arch,
+ virDomainVirtTypeToString(def->virtType));
if (defaultMachine != NULL) {
if (!(def->os.machine = strdup(defaultMachine)))
goto no_memory;
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-machine-aliases2.xml b/tests/qemuxml2argvdata/qemuxml2argv-machine-aliases2.xml
index 6f62243..a2c6254 100644
--- a/tests/qemuxml2argvdata/qemuxml2argv-machine-aliases2.xml
+++ b/tests/qemuxml2argvdata/qemuxml2argv-machine-aliases2.xml
@@ -1,11 +1,11 @@
-<domain type='qemu'>
+<domain type='kvm'>
<name>QEMUGuest1</name>
<uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
<memory>219200</memory>
<currentMemory>219200</currentMemory>
<vcpu>1</vcpu>
<os>
- <type arch='x86_64' machine='pc'>hvm</type>
+ <type arch='x86_64'>hvm</type>
<boot dev='hd'/>
</os>
<clock offset='utc'/>
--
1.6.2.5

View File

@@ -0,0 +1,42 @@
From bb64cc4cbe5d3c69057f63be2c1acaca72038e5a Mon Sep 17 00:00:00 2001
From: Mark McLoughlin <markmc@redhat.com>
Date: Thu, 15 Oct 2009 12:09:17 +0100
Subject: [PATCH] Don't copy old machines from a domain which has none
If the the qemu and kvm binaries are the same, we don't include machine
types in the kvm domain info.
However, the code which refreshes the machine types info from the
previous capabilities structure first looks at the kvm domain's info,
finds it matches and then copies the empty machine types list over
for the top-level qemu domain.
That doesn't make sense, we shouldn't copy an empty machin types list.
* src/qemu/qemu_conf.c: qemudGetOldMachinesFromInfo(): don't copy an
empty machine types list.
(cherry picked from commit 2210f8a3a8e2774ca4fb8b42e21899e5b85ca913)
Fedora-patch: libvirt-qemu-machine-type-fixes2.patch
---
src/qemu_conf.c | 3 +++
1 files changed, 3 insertions(+), 0 deletions(-)
diff --git a/src/qemu_conf.c b/src/qemu_conf.c
index 0dd0624..34a7fe1 100644
--- a/src/qemu_conf.c
+++ b/src/qemu_conf.c
@@ -505,6 +505,9 @@ qemudGetOldMachinesFromInfo(virCapsGuestDomainInfoPtr info,
virCapsGuestMachinePtr *list;
int i;
+ if (!info->nmachines)
+ return 0;
+
if (!info->emulator || !STREQ(emulator, info->emulator))
return 0;
--
1.6.2.5

View File

@@ -1,124 +0,0 @@
From 8f26acc66ca90eea67fd5e84be5a76e3b8aa7fbf 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 2c4fd6f..4ce7a54 100644
--- a/src/qemu_driver.c
+++ b/src/qemu_driver.c
@@ -1402,6 +1402,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 const char *const defaultDeviceACL[] = {
"/dev/null", "/dev/full", "/dev/zero",
"/dev/random", "/dev/urandom",
@@ -2109,6 +2183,8 @@ static void qemudShutdownVMDaemon(virConnectPtr conn,
VIR_WARN("Failed to restore all device ownership for %s",
vm->def->name);
+ qemuDomainReAttachHostDevices(conn, vm->def);
+
retry:
if ((ret = qemuRemoveCgroup(conn, driver, vm)) < 0) {
if (ret == -EBUSY && (retries++ < 5)) {
--
1.6.2.5

View File

@@ -0,0 +1,30 @@
From a44bce591a8d746a4a00c8609cb0111c76271cab Mon Sep 17 00:00:00 2001
From: Cole Robinson <crobinso@redhat.com>
Date: Thu, 8 Oct 2009 18:05:36 -0400
Subject: [PATCH] storage: Fix generating iscsi 'auth' xml
We were missing a closing tag, so the XML wasn't proper.
(cherry picked from commit 826cbac4591fd5929b497299a90d3a65226b2825)
Fedora-patch: libvirt-storage-iscsi-auth-xml-formatting.patch
---
src/storage_conf.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/src/storage_conf.c b/src/storage_conf.c
index 788de15..1633aac 100644
--- a/src/storage_conf.c
+++ b/src/storage_conf.c
@@ -799,7 +799,7 @@ virStoragePoolSourceFormat(virConnectPtr conn,
if (src->authType == VIR_STORAGE_POOL_AUTH_CHAP)
- virBufferVSprintf(buf," <auth type='chap' login='%s' passwd='%s'>\n",
+ virBufferVSprintf(buf," <auth type='chap' login='%s' passwd='%s'/>\n",
src->auth.chap.login,
src->auth.chap.passwd);
virBufferAddLit(buf," </source>\n");
--
1.6.2.5

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1 +1 @@
8c2c14a7695c9c661004bcfc6468d62d libvirt-0.7.0.tar.gz
f1cd360a5da38b847e166c6482141940 libvirt-0.7.1.tar.gz