* 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
This commit is contained in:
parent
20367a58a6
commit
e4bf8ffa42
@ -3,12 +3,3 @@
|
|||||||
i686
|
i686
|
||||||
x86_64
|
x86_64
|
||||||
libvirt-*.tar.gz
|
libvirt-*.tar.gz
|
||||||
libvirt-0.6.0.tar.gz
|
|
||||||
libvirt-0.6.1.tar.gz
|
|
||||||
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
|
|
||||||
|
@ -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
|
|
||||||
|
|
@ -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
|
|
||||||
|
|
@ -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
|
|
||||||
|
|
@ -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
|
|
||||||
|
|
@ -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
|
|
||||||
|
|
@ -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
|
|
||||||
|
|
@ -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
|
|
||||||
|
|
@ -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
|
|
||||||
|
|
@ -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
|
|
||||||
|
|
@ -1,45 +0,0 @@
|
|||||||
From f2eb2ad5163d5bae2392a8bfc6040c45426c9f5f Mon Sep 17 00:00:00 2001
|
|
||||||
From: Chris Lalancette <clalance@redhat.com>
|
|
||||||
Date: Wed, 5 Aug 2009 13:42:07 +0200
|
|
||||||
Subject: [PATCH] Run 'cont' on successful migration finish.
|
|
||||||
|
|
||||||
https://bugzilla.redhat.com/516187
|
|
||||||
|
|
||||||
As of qemu 0.10.6, qemu now honors the -S flag on incoming migration.
|
|
||||||
That means that when the migration completes, we have to issue a
|
|
||||||
'cont' command to get the VM running again. We do it unconditionally
|
|
||||||
since it won't hurt on older qemu.
|
|
||||||
|
|
||||||
(cherry picked from commit d1ec4d7a5a4f50c9492137eaab4f021caa075f95)
|
|
||||||
|
|
||||||
Fedora-patch: libvirt-fix-migration-completion-with-newer-qemu.patch
|
|
||||||
---
|
|
||||||
src/qemu_driver.c | 11 +++++++++++
|
|
||||||
1 files changed, 11 insertions(+), 0 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/src/qemu_driver.c b/src/qemu_driver.c
|
|
||||||
index 99dac52..bf9a0b2 100644
|
|
||||||
--- a/src/qemu_driver.c
|
|
||||||
+++ b/src/qemu_driver.c
|
|
||||||
@@ -6951,7 +6951,18 @@ qemudDomainMigrateFinish2 (virConnectPtr dconn,
|
|
||||||
*/
|
|
||||||
if (retcode == 0) {
|
|
||||||
dom = virGetDomain (dconn, vm->def->name, vm->def->uuid);
|
|
||||||
+
|
|
||||||
+ /* run 'cont' on the destination, which allows migration on qemu
|
|
||||||
+ * >= 0.10.6 to work properly. This isn't strictly necessary on
|
|
||||||
+ * older qemu's, but it also doesn't hurt anything there
|
|
||||||
+ */
|
|
||||||
+ if (qemudMonitorCommand(vm, "cont", &info) < 0) {
|
|
||||||
+ qemudReportError(dconn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
|
|
||||||
+ "%s", _("resume operation failed"));
|
|
||||||
+ goto cleanup;
|
|
||||||
+ }
|
|
||||||
VIR_FREE(info);
|
|
||||||
+
|
|
||||||
vm->state = VIR_DOMAIN_RUNNING;
|
|
||||||
event = virDomainEventNewFromObj(vm,
|
|
||||||
VIR_DOMAIN_EVENT_RESUMED,
|
|
||||||
--
|
|
||||||
1.6.2.5
|
|
||||||
|
|
@ -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
|
|
||||||
|
|
@ -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
|
|
||||||
|
|
83
libvirt.spec
83
libvirt.spec
@ -12,6 +12,7 @@
|
|||||||
%define with_libvirtd 0%{!?_without_libvirtd:1}
|
%define with_libvirtd 0%{!?_without_libvirtd:1}
|
||||||
%define with_uml 0%{!?_without_uml:1}
|
%define with_uml 0%{!?_without_uml:1}
|
||||||
%define with_one 0%{!?_without_one:1}
|
%define with_one 0%{!?_without_one:1}
|
||||||
|
%define with_phyp 0%{!?_without_phyp:1}
|
||||||
%define with_network 0%{!?_without_network:1}
|
%define with_network 0%{!?_without_network:1}
|
||||||
%define with_storage_fs 0%{!?_without_storage_fs:1}
|
%define with_storage_fs 0%{!?_without_storage_fs:1}
|
||||||
%define with_storage_lvm 0%{!?_without_storage_lvm:1}
|
%define with_storage_lvm 0%{!?_without_storage_lvm:1}
|
||||||
@ -24,9 +25,6 @@
|
|||||||
%define with_capng 0%{!?_without_capng:0}
|
%define with_capng 0%{!?_without_capng:0}
|
||||||
%define with_netcf 0%{!?_without_netcf:0}
|
%define with_netcf 0%{!?_without_netcf:0}
|
||||||
|
|
||||||
# default to off
|
|
||||||
%define with_phyp 0%{!?_without_phyp:0}
|
|
||||||
|
|
||||||
# Xen is available only on i386 x86_64 ia64
|
# Xen is available only on i386 x86_64 ia64
|
||||||
%ifnarch i386 i586 i686 x86_64 ia64
|
%ifnarch i386 i586 i686 x86_64 ia64
|
||||||
%define with_xen 0
|
%define with_xen 0
|
||||||
@ -74,55 +72,19 @@
|
|||||||
%define with_one 0
|
%define with_one 0
|
||||||
%endif
|
%endif
|
||||||
|
|
||||||
|
%define git_snapshot git3ef2e05
|
||||||
|
|
||||||
Summary: Library providing a simple API virtualization
|
Summary: Library providing a simple API virtualization
|
||||||
Name: libvirt
|
Name: libvirt
|
||||||
Version: 0.7.0
|
Version: 0.7.1
|
||||||
Release: 6%{?dist}%{?extra_release}
|
Release: 0.1.%{git_snapshot}%{?dist}%{?extra_release}
|
||||||
License: LGPLv2+
|
License: LGPLv2+
|
||||||
Group: Development/Libraries
|
Group: Development/Libraries
|
||||||
Source: http://libvirt.org/sources/libvirt-%{version}.tar.gz
|
Source: http://libvirt.org/sources/libvirt-%{version}-%{git_snapshot}.tar.gz
|
||||||
|
|
||||||
# Make sure qemu can access kernel/initrd (bug #516034)
|
|
||||||
Patch01: libvirt-0.7.0-chown-kernel-initrd-before-spawning-qemu.patch
|
|
||||||
|
|
||||||
# Don't fail to start network if ipv6 modules is not loaded (bug #516497)
|
|
||||||
Patch02: libvirt-0.7.0-handle-kernels-with-no-ipv6-support.patch
|
|
||||||
|
|
||||||
# Policykit rewrite (bug #499970)
|
|
||||||
# NB remove autoreconf hack & extra BRs when this goes away
|
|
||||||
Patch03: libvirt-0.7.0-policy-kit-rewrite.patch
|
|
||||||
|
|
||||||
# Log and ignore NUMA topology problems (rhbz #506590)
|
|
||||||
Patch04: libvirt-0.7.0-numa-ignore-fail.patch
|
|
||||||
|
|
||||||
# Minor 'virsh nodedev-list --tree' annoyance, fix from upstream
|
|
||||||
Patch05: libvirt-add-space-to-nodedev-list-tree.patch
|
|
||||||
|
|
||||||
# Fixes list corruption after disk hot-unplug
|
|
||||||
Patch06: libvirt-fix-device-list-update-after-detach.patch
|
|
||||||
|
|
||||||
# Re-attach PCI host devices after guest shuts down (bug #499561)
|
|
||||||
Patch07: libvirt-reattach-pci-hostdevs-after-guest-shutdown.patch
|
|
||||||
|
|
||||||
# Allow PM reset on multi-function PCI devices (bug #515689)
|
|
||||||
Patch08: libvirt-allow-pm-reset-on-multi-function-pci-devices.patch
|
|
||||||
|
|
||||||
# Fix stupid PCI reset error message (#499678)
|
|
||||||
Patch09: libvirt-improve-pci-hostdev-reset-error-message.patch
|
|
||||||
|
|
||||||
# Allow PCI bus reset to reset other devices (#499678)
|
|
||||||
Patch10: libvirt-allow-pci-hostdev-reset-to-reset-other-devices.patch
|
|
||||||
|
|
||||||
# Add PCI host device hotplug support
|
|
||||||
Patch11: libvirt-add-pci-hostdev-hotplug-support.patch
|
|
||||||
|
|
||||||
# Fix migration completion with newer versions of qemu (#516187)
|
|
||||||
Patch12: libvirt-fix-migration-completion-with-newer-qemu.patch
|
|
||||||
|
|
||||||
# Temporary hack till PulseAudio autostart problems are sorted
|
# Temporary hack till PulseAudio autostart problems are sorted
|
||||||
# out when SELinux enforcing (bz 486112)
|
# out when SELinux enforcing (bz 486112)
|
||||||
Patch200: libvirt-0.6.4-svirt-sound.patch
|
Patch00: libvirt-0.6.4-svirt-sound.patch
|
||||||
|
|
||||||
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root
|
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root
|
||||||
URL: http://libvirt.org/
|
URL: http://libvirt.org/
|
||||||
@ -150,8 +112,10 @@ BuildRequires: util-linux
|
|||||||
BuildRequires: nfs-utils
|
BuildRequires: nfs-utils
|
||||||
Requires: nfs-utils
|
Requires: nfs-utils
|
||||||
# For glusterfs
|
# For glusterfs
|
||||||
|
%if 0%{?fedora} >= 11
|
||||||
Requires: glusterfs-client >= 2.0.1
|
Requires: glusterfs-client >= 2.0.1
|
||||||
%endif
|
%endif
|
||||||
|
%endif
|
||||||
%if %{with_qemu}
|
%if %{with_qemu}
|
||||||
# From QEMU RPMs
|
# From QEMU RPMs
|
||||||
Requires: /usr/bin/qemu-img
|
Requires: /usr/bin/qemu-img
|
||||||
@ -236,7 +200,7 @@ BuildRequires: numactl-devel
|
|||||||
BuildRequires: libcap-ng-devel >= 0.5.0
|
BuildRequires: libcap-ng-devel >= 0.5.0
|
||||||
%endif
|
%endif
|
||||||
%if %{with_phyp}
|
%if %{with_phyp}
|
||||||
BuildRequires: libssh-devel >= 0.3.1
|
BuildRequires: libssh2-devel
|
||||||
%endif
|
%endif
|
||||||
%if %{with_netcf}
|
%if %{with_netcf}
|
||||||
BuildRequires: netcf-devel
|
BuildRequires: netcf-devel
|
||||||
@ -245,9 +209,6 @@ BuildRequires: netcf-devel
|
|||||||
# Fedora build root suckage
|
# Fedora build root suckage
|
||||||
BuildRequires: gawk
|
BuildRequires: gawk
|
||||||
|
|
||||||
# Temp hack for patch 3
|
|
||||||
BuildRequires: libtool autoconf automake gettext cvs
|
|
||||||
|
|
||||||
%description
|
%description
|
||||||
Libvirt is a C toolkit to interact with the virtualization capabilities
|
Libvirt is a C toolkit to interact with the virtualization capabilities
|
||||||
of recent versions of Linux (and other OSes). The main package includes
|
of recent versions of Linux (and other OSes). The main package includes
|
||||||
@ -301,20 +262,7 @@ of recent versions of Linux (and other OSes).
|
|||||||
%prep
|
%prep
|
||||||
%setup -q
|
%setup -q
|
||||||
|
|
||||||
%patch01 -p1
|
%patch00 -p1
|
||||||
%patch02 -p1
|
|
||||||
%patch03 -p1
|
|
||||||
%patch04 -p1
|
|
||||||
%patch05 -p1
|
|
||||||
%patch06 -p1
|
|
||||||
%patch07 -p1
|
|
||||||
%patch08 -p1
|
|
||||||
%patch09 -p1
|
|
||||||
%patch10 -p1
|
|
||||||
%patch11 -p1
|
|
||||||
%patch12 -p1
|
|
||||||
|
|
||||||
%patch200 -p1
|
|
||||||
|
|
||||||
%build
|
%build
|
||||||
%if ! %{with_xen}
|
%if ! %{with_xen}
|
||||||
@ -405,9 +353,6 @@ of recent versions of Linux (and other OSes).
|
|||||||
%define _without_netcf --without-netcf
|
%define _without_netcf --without-netcf
|
||||||
%endif
|
%endif
|
||||||
|
|
||||||
# Temp hack for patch 3
|
|
||||||
autoreconf -if
|
|
||||||
|
|
||||||
%configure %{?_without_xen} \
|
%configure %{?_without_xen} \
|
||||||
%{?_without_qemu} \
|
%{?_without_qemu} \
|
||||||
%{?_without_openvz} \
|
%{?_without_openvz} \
|
||||||
@ -566,7 +511,7 @@ fi
|
|||||||
%dir %attr(0700, root, root) %{_localstatedir}/cache/libvirt/
|
%dir %attr(0700, root, root) %{_localstatedir}/cache/libvirt/
|
||||||
|
|
||||||
%if %{with_qemu}
|
%if %{with_qemu}
|
||||||
%dir %attr(0700, %{qemu_user}, %{qemu_group}) %{_localstatedir}/run/libvirt/qemu/
|
%dir %attr(0700, root, root) %{_localstatedir}/run/libvirt/qemu/
|
||||||
%dir %attr(0700, %{qemu_user}, %{qemu_group}) %{_localstatedir}/lib/libvirt/qemu/
|
%dir %attr(0700, %{qemu_user}, %{qemu_group}) %{_localstatedir}/lib/libvirt/qemu/
|
||||||
%dir %attr(0700, %{qemu_user}, %{qemu_group}) %{_localstatedir}/cache/libvirt/qemu/
|
%dir %attr(0700, %{qemu_user}, %{qemu_group}) %{_localstatedir}/cache/libvirt/qemu/
|
||||||
%endif
|
%endif
|
||||||
@ -644,6 +589,8 @@ fi
|
|||||||
%{_datadir}/libvirt/schemas/nodedev.rng
|
%{_datadir}/libvirt/schemas/nodedev.rng
|
||||||
%{_datadir}/libvirt/schemas/capability.rng
|
%{_datadir}/libvirt/schemas/capability.rng
|
||||||
%{_datadir}/libvirt/schemas/interface.rng
|
%{_datadir}/libvirt/schemas/interface.rng
|
||||||
|
%{_datadir}/libvirt/schemas/secret.rng
|
||||||
|
%{_datadir}/libvirt/schemas/storageencryption.rng
|
||||||
|
|
||||||
%if %{with_sasl}
|
%if %{with_sasl}
|
||||||
%config(noreplace) %{_sysconfdir}/sasl2/libvirt.conf
|
%config(noreplace) %{_sysconfdir}/sasl2/libvirt.conf
|
||||||
@ -681,6 +628,10 @@ fi
|
|||||||
%endif
|
%endif
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* 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
|
||||||
|
|
||||||
* Wed Aug 19 2009 Mark McLoughlin <markmc@redhat.com> - 0.7.0-6
|
* Wed Aug 19 2009 Mark McLoughlin <markmc@redhat.com> - 0.7.0-6
|
||||||
- Fix migration completion with newer versions of qemu (#516187)
|
- Fix migration completion with newer versions of qemu (#516187)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user