diff --git a/apparmor-qemu-bridge-helper.patch b/apparmor-qemu-bridge-helper.patch new file mode 100644 index 0000000..c472caa --- /dev/null +++ b/apparmor-qemu-bridge-helper.patch @@ -0,0 +1,69 @@ +From 430cd5a72cf1f5c3e56cf1b4b40385812477aef3 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?C=C3=A9dric=20Bosdonnat?= +Date: Fri, 5 Aug 2016 09:32:54 +0200 +Subject: [PATCH] apparmor: move qemu-bridge-helper to libvirtd profile + +qemu-bridge-helper is only called from libvirtd, it has to be moved +from the qemu domain abstraction to the usr.sbin.libvirtd profile. +--- + examples/apparmor/libvirt-qemu | 19 ------------------- + examples/apparmor/usr.sbin.libvirtd | 18 ++++++++++++++++++ + 2 files changed, 18 insertions(+), 19 deletions(-) + +diff --git a/examples/apparmor/libvirt-qemu b/examples/apparmor/libvirt-qemu +index efb4873..11381d4 100644 +--- a/examples/apparmor/libvirt-qemu ++++ b/examples/apparmor/libvirt-qemu +@@ -148,22 +148,3 @@ + /etc/udev/udev.conf r, + /sys/bus/ r, + /sys/class/ r, +- +- /usr/{lib,libexec}/qemu-bridge-helper Cx -> qemu_bridge_helper, +- # child profile for bridge helper process +- profile qemu_bridge_helper { +- #include +- +- capability setuid, +- capability setgid, +- capability setpcap, +- capability net_admin, +- +- network inet stream, +- +- /dev/net/tun rw, +- /etc/qemu/** r, +- owner @{PROC}/*/status r, +- +- /usr/{lib,libexec}/qemu-bridge-helper rmix, +- } +diff --git a/examples/apparmor/usr.sbin.libvirtd b/examples/apparmor/usr.sbin.libvirtd +index 23f70f5..48651b2 100644 +--- a/examples/apparmor/usr.sbin.libvirtd ++++ b/examples/apparmor/usr.sbin.libvirtd +@@ -67,4 +67,22 @@ + # allow changing to our UUID-based named profiles + change_profile -> @{LIBVIRT}-[0-9a-f]*-[0-9a-f]*-[0-9a-f]*-[0-9a-f]*-[0-9a-f]*, + ++ /usr/{lib,libexec}/qemu-bridge-helper Cx -> qemu_bridge_helper, ++ # child profile for bridge helper process ++ profile qemu_bridge_helper { ++ #include ++ ++ capability setuid, ++ capability setgid, ++ capability setpcap, ++ capability net_admin, ++ ++ network inet stream, ++ ++ /dev/net/tun rw, ++ /etc/qemu/** r, ++ owner @{PROC}/*/status r, ++ ++ /usr/{lib,libexec}/qemu-bridge-helper rmix, ++ } + } +-- +2.6.6 + diff --git a/cpumodel-vendor-crash-fix.patch b/cpumodel-vendor-crash-fix.patch new file mode 100644 index 0000000..51aab51 --- /dev/null +++ b/cpumodel-vendor-crash-fix.patch @@ -0,0 +1,56 @@ +From 341445ce85d91a105f8183f22226d9d90853b27b Mon Sep 17 00:00:00 2001 +From: Jim Fehlig +Date: Fri, 5 Aug 2016 15:23:47 -0600 +Subject: [PATCH] cpu_x86: fix libvirtd crash when host cpu is 'qemu64' + +When starting an L2 nested VM with on an +L1 VM with cpu 'qemu64', libvirtd crashes with + +Program received signal SIGSEGV, Segmentation fault. +0x00007ffff739bf33 in x86DataCpuid (cpuid=0x8, cpuid=0x8, + data=data@entry=0x7fffb800ee78) at cpu/cpu_x86.c:287 +287 for (i = 0; i < data->len; i++) { +(gdb) bt +f0 0x00007ffff739bf33 in x86DataCpuid (cpuid=0x8, cpuid=0x8, + data=data@entry=0x7fffb800ee78) at cpu/cpu_x86.c:287 +f1 virCPUx86DataAddCPUID (data=data@entry=0x7fffb800ee78, cpuid=0x8) + at cpu/cpu_x86.c:355 +f2 0x00007ffff739ef47 in x86Compute (host=, cpu=0x7fffb8000cc0, + guest=0x7fffecca7348, message=) at cpu/cpu_x86.c:1580 +f3 0x00007fffd2b38e53 in qemuBuildCpuModelArgStr (migrating=false, + hasHwVirt=, qemuCaps=0x7fffb8001040, buf=0x7fffecca7360, + def=0x7fffc400ce20, driver=0x1c) at qemu/qemu_command.c:6283 +f4 qemuBuildCpuCommandLine (cmd=cmd@entry=0x7fffb8002f60, + driver=driver@entry=0x7fffc80882c0, def=def@entry=0x7fffc400ce20, + qemuCaps=qemuCaps@entry=0x7fffb8001040, migrating=) + at qemu/qemu_command.c:6445 + +In frame 2, &host_model->vendor->cpuid is passed to virCPUx86DataAddCPUID(), +but + +(gdb) p *host_model +$23 = {name = 0x7fffb800ec50 "qemu64", vendor = 0x0, signature = 0, data = { + len = 2, data = 0x7fffb800e720}} + +With vendor = 0x0, &host_model->vendor->cpuid evaluates to 8, which +is not a nice value to pass to virCPUx86DataAddCPUID(). Check for a +non-null host_model->vendor before calling virCPUx86DataAddCPUID(). + +Signed-off-by: Jim Fehlig +--- + src/cpu/cpu_x86.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +Index: libvirt-2.0.0/src/cpu/cpu_x86.c +=================================================================== +--- libvirt-2.0.0.orig/src/cpu/cpu_x86.c ++++ libvirt-2.0.0/src/cpu/cpu_x86.c +@@ -1576,7 +1576,7 @@ x86Compute(virCPUDefPtr host, + if (!(guest_model = x86ModelCopy(host_model))) + goto error; + +- if (cpu->vendor && ++ if (cpu->vendor && host_model->vendor && + virCPUx86DataAddCPUID(&guest_model->data, + &host_model->vendor->cpuid) < 0) + goto error; diff --git a/libvirt.changes b/libvirt.changes index 1c5e4a7..0460a11 100644 --- a/libvirt.changes +++ b/libvirt.changes @@ -1,3 +1,39 @@ +------------------------------------------------------------------- +Fri Aug 5 22:27:44 UTC 2016 - jfehlig@suse.com + +- cpu_x86: fix libvirtd segfault when host cpu is 'qemu64' + cpumodel-vendor-crash-fix.patch + bsc#992425 + +------------------------------------------------------------------- +Fri Aug 5 08:05:39 UTC 2016 - cbosdonnat@suse.com + +- bsc#988279. Move the qemu-bridge-helper apparmor profile from the + qemu abstraction to the usr.sbin.libvirtd profile. + apparmor-qemu-bridge-helper.patch + +------------------------------------------------------------------- +Wed Aug 3 19:31:11 UTC 2016 - jfehlig@suse.com + +- spec: minor improvements to logic enabling numactl and numad + support and fix nested if indentation + FATE#319979 + +------------------------------------------------------------------- +Tue Aug 2 17:17:25 UTC 2016 - jfehlig@suse.com + +- Update patches providing support for driver_override sysfs + interface with latest upstream variant. Dropped + pci-simplify-stub.patch and updated + pci-use-driver-override-sysfs.patch + bsc#986718 + +------------------------------------------------------------------- +Sat Jul 30 17:25:38 UTC 2016 - jfehlig@suse.com + +- spec: enable numactl and numad support for aarch64 + FATE#319979, bsc#991377 + ------------------------------------------------------------------- Fri Jul 15 14:57:40 UTC 2016 - jfehlig@suse.com diff --git a/libvirt.spec b/libvirt.spec index fcb67c1..de2575d 100644 --- a/libvirt.spec +++ b/libvirt.spec @@ -41,10 +41,9 @@ %define with_hyperv 0%{!?_without_hyperv:0} # Then the secondary host drivers, which run inside libvirtd -%define with_storage_rbd 0 +%define with_storage_rbd 0%{!?_without_storage_rbd:0} %define with_storage_sheepdog 0 %define with_storage_gluster 0 -%define with_numactl 0%{!?_without_numactl:1} %define with_apparmor 0%{!?_without_apparmor:1} # Optional bits on by default @@ -54,6 +53,7 @@ # A few optional bits off by default, we enable later %define with_cgconfig 0%{!?_without_cgconfig:0} %define with_systemd 0%{!?_without_systemd:0} +%define with_numactl 0%{!?_without_numactl:0} %define with_numad 0%{!?_without_numad:0} %define with_firewalld 0%{!?_without_firewalld:0} %define with_wireshark 0%{!?_without_wireshark:0} @@ -77,10 +77,17 @@ %endif %endif -# numactl package has "ExclusiveArch: ia64 x86_64 ppc64 ppc64le ppc %sparc" -# We'll only use it on x86_64 ppc64 ppc64le -%ifnarch x86_64 ppc64 ppc64le - %define with_numactl 0 +# Enable numactl for most architectures. Handle aarch64 separately +%ifnarch s390 s390x %arm %ix86 aarch64 + %define with_numactl 0%{!?_without_numactl:1} +%endif + +# For aarch64, numactl is only available on newer than 1320, or SLE12 +# family newer than 120100 +%ifarch aarch64 + %if 0%{?suse_version} > 1320 || ( 0%{?suse_version} == 1315 && ( 0%{?sle_version} > 120100 ) ) + %define with_numactl 0%{!?_without_numactl:1} + %endif %endif # vbox is available only on i386 x86_64 @@ -106,26 +113,26 @@ %ifarch x86_64 # enable on anything newer than 1320, or SLE12 family newer than 120100 # use librbd-devel as build dependency -%if 0%{?suse_version} > 1320 || ( 0%{?suse_version} == 1315 && ( 0%{?sle_version} > 120100 ) ) -%define with_storage_rbd 1 -%define with_rbd_lib librbd-devel -%endif -# enable for SLE12 family <= 120100 (SLE12ga/sp1, Leap 42.1) + %if 0%{?suse_version} > 1320 || ( 0%{?suse_version} == 1315 && ( 0%{?sle_version} > 120100 ) ) + %define with_storage_rbd 0%{!?_without_storage_rbd:1} + %define with_rbd_lib librbd-devel + %endif +# enable for SLE12 family <= 120100 (SLE12GA/SP1, Leap 42.1) # use ceph-devel as build dependency -%if 0%{?suse_version} == 1315 && 0%{?sle_version} <= 120100 -%define with_storage_rbd 1 -%define with_rbd_lib ceph-devel -%endif + %if 0%{?suse_version} == 1315 && 0%{?sle_version} <= 120100 + %define with_storage_rbd 0%{!?_without_storage_rbd:1} + %define with_rbd_lib ceph-devel + %endif %endif # For arm %ifarch aarch64 # enable on anything newer than 1320, or SLE12 family newer than 120100 # use librbd-devel as build dependency -%if 0%{?suse_version} > 1320 || ( 0%{?is_opensuse} == 0 && 0%{?sle_version} > 120100 ) -%define with_storage_rbd 1 -%define with_rbd_lib librbd-devel -%endif + %if 0%{?suse_version} > 1320 || ( 0%{?is_opensuse} == 0 && 0%{?sle_version} > 120100 ) + %define with_storage_rbd 0%{!?_without_storage_rbd:1} + %define with_rbd_lib librbd-devel + %endif %endif # Support systemd on 12.1 and later @@ -139,11 +146,19 @@ %define with_wireshark 0 # numad is used to manage the CPU and memory placement dynamically for -# qemu, lxc, and uml drivers. We'll only use in on x86_64 +# qemu, lxc, and uml drivers %if %{with_qemu} || %{with_lxc} || %{with_uml} - %ifarch x86_64 +# Enable numad for most architectures. Handle aarch64 separately + %ifnarch s390 s390x %arm %ix86 aarch64 %define with_numad 0%{!?_without_numad:1} %endif +# For aarch64, enable on anything newer than 1320, or SLE12 family newer +# than 120100 + %ifarch aarch64 + %if 0%{?suse_version} > 1320 || ( 0%{?suse_version} == 1315 && 0%{?sle_version} > 120100 ) + %define with_numad 0%{!?_without_numad:1} + %endif + %endif %endif # Force QEMU to run as qemu:qemu @@ -301,8 +316,8 @@ Source100: %{name}-rpmlintrc Patch0: c8f08e48-systemd-notify-fix.patch # Patches pending upstream review Patch100: libxl-dom-reset.patch -Patch101: pci-simplify-stub.patch -Patch102: pci-use-driver-override-sysfs.patch +Patch101: pci-use-driver-override-sysfs.patch +Patch102: cpumodel-vendor-crash-fix.patch # Need to go upstream Patch150: xen-pv-cdrom.patch Patch151: blockcopy-check-dst-identical-device.patch @@ -311,6 +326,7 @@ Patch153: ppc64le-canonical-name.patch Patch154: libxl-set-migration-constraints.patch Patch155: libxl-set-cach-mode.patch Patch156: apparmor-fixes.patch +Patch157: apparmor-qemu-bridge-helper.patch # Our patches Patch200: libvirtd-defaults.patch Patch201: libvirtd-init-script.patch @@ -763,6 +779,7 @@ libvirt plugin for NSS for translating domain names into IP addresses. %patch154 -p1 %patch155 -p1 %patch156 -p1 +%patch157 -p1 %patch200 -p1 %patch201 -p1 %patch202 -p1 diff --git a/pci-simplify-stub.patch b/pci-simplify-stub.patch deleted file mode 100644 index 42c03d8..0000000 --- a/pci-simplify-stub.patch +++ /dev/null @@ -1,118 +0,0 @@ -commit caba00f00fb18d8ffc388f4fc8b82527ef98d3b0 -Author: Jim Fehlig -Date: Wed Jul 6 14:06:37 2016 -0600 - - virpci: simplify virPCIDeviceBindToStub - - Early in virPCIDeviceBindToStub, there is a check to see if the - stub is already bound to the device, returning success with no - further actions if that is the case. - - The same condition is unnecessarily checked later in the function. - Remove the unneeded checks to simplify the logic a bit. - - Signed-off-by: Jim Fehlig - -Index: libvirt-2.0.0/src/util/virpci.c -=================================================================== ---- libvirt-2.0.0.orig/src/util/virpci.c -+++ libvirt-2.0.0/src/util/virpci.c -@@ -1196,7 +1196,6 @@ static int - virPCIDeviceBindToStub(virPCIDevicePtr dev) - { - int result = -1; -- bool reprobe = false; - char *stubDriverPath = NULL; - char *driverLink = NULL; - char *path = NULL; /* reused for different purposes */ -@@ -1225,10 +1224,16 @@ virPCIDeviceBindToStub(virPCIDevicePtr d - /* The device is already bound to the correct driver */ - VIR_DEBUG("Device %s is already bound to %s", - dev->name, stubDriverName); -+ dev->unbind_from_stub = true; -+ dev->remove_slot = true; - result = 0; - goto cleanup; - } -- reprobe = true; -+ /* -+ * If the device is bound to a driver that is not the stub, we'll -+ * need to reprobe later -+ */ -+ dev->reprobe = true; - } - - /* Add the PCI device ID to the stub's dynamic ID table; -@@ -1249,51 +1254,34 @@ virPCIDeviceBindToStub(virPCIDevicePtr d - goto cleanup; - } - -- /* check whether the device is bound to pci-stub when we write dev->id to -- * ${stubDriver}/new_id. -- */ -- if (virFileLinkPointsTo(driverLink, stubDriverPath)) { -- dev->unbind_from_stub = true; -- dev->remove_slot = true; -- result = 0; -+ if (virPCIDeviceUnbind(dev) < 0) - goto remove_id; -- } - -- if (virPCIDeviceUnbind(dev) < 0) -+ /* Xen's pciback.ko wants you to use new_slot first */ -+ VIR_FREE(path); -+ if (!(path = virPCIDriverFile(stubDriverName, "new_slot"))) - goto remove_id; - -- /* If the device was bound to a driver we'll need to reprobe later */ -- dev->reprobe = reprobe; -+ if (virFileExists(path) && virFileWriteStr(path, dev->name, 0) < 0) { -+ virReportSystemError(errno, -+ _("Failed to add slot for " -+ "PCI device '%s' to %s"), -+ dev->name, stubDriverName); -+ goto remove_id; -+ } -+ dev->remove_slot = true; - -- /* If the device isn't already bound to pci-stub, try binding it now. -- */ -- if (!virFileLinkPointsTo(driverLink, stubDriverPath)) { -- /* Xen's pciback.ko wants you to use new_slot first */ -- VIR_FREE(path); -- if (!(path = virPCIDriverFile(stubDriverName, "new_slot"))) -- goto remove_id; -- -- if (virFileExists(path) && virFileWriteStr(path, dev->name, 0) < 0) { -- virReportSystemError(errno, -- _("Failed to add slot for " -- "PCI device '%s' to %s"), -- dev->name, stubDriverName); -- goto remove_id; -- } -- dev->remove_slot = true; -+ VIR_FREE(path); -+ if (!(path = virPCIDriverFile(stubDriverName, "bind"))) -+ goto remove_id; - -- VIR_FREE(path); -- if (!(path = virPCIDriverFile(stubDriverName, "bind"))) -- goto remove_id; -- -- if (virFileWriteStr(path, dev->name, 0) < 0) { -- virReportSystemError(errno, -- _("Failed to bind PCI device '%s' to %s"), -- dev->name, stubDriverName); -- goto remove_id; -- } -- dev->unbind_from_stub = true; -+ if (virFileWriteStr(path, dev->name, 0) < 0) { -+ virReportSystemError(errno, -+ _("Failed to bind PCI device '%s' to %s"), -+ dev->name, stubDriverName); -+ goto remove_id; - } -+ dev->unbind_from_stub = true; - - result = 0; - diff --git a/pci-use-driver-override-sysfs.patch b/pci-use-driver-override-sysfs.patch index 89b9563..445e7a4 100644 --- a/pci-use-driver-override-sysfs.patch +++ b/pci-use-driver-override-sysfs.patch @@ -1,191 +1,81 @@ -commit 1de627810eaba897705cf32c9f025023e34ce73a -Author: Jim Fehlig -Date: Fri Jul 8 16:25:03 2016 -0600 +From 9bd9a05b8b64489598ca4e0d241247cb99406d20 Mon Sep 17 00:00:00 2001 +From: Jim Fehlig +Date: Mon, 1 Aug 2016 21:16:43 -0600 +Subject: [PATCH] virpci: support driver_override sysfs interface - virpci: support driver_override sysfs interface - - Currently, libvirt uses the new_id PCI sysfs interface to bind a PCI - stub driver to a PCI device. The new_id interface is known to be - buggy and racey, hence a more deterministic interface was introduced - in the 3.12 kernel - driver_override. For more details see - - https://www.redhat.com/archives/libvir-list/2016-June/msg02124.html - - This patch changes the stub binding/unbinding code to use the - driver_override interface if present. If not present, the new_id - interface will be used to provide compatibility with older kernels - lacking driver_override. - - Signed-off-by: Jim Fehlig +libvirt uses the new_id PCI sysfs interface to bind a PCI stub driver +to a PCI device. The new_id interface is known to be buggy and racey, +hence a more deterministic interface was introduced in the 3.12 kernel: +driver_override. For more details see + +https://www.redhat.com/archives/libvir-list/2016-June/msg02124.html + +This patch adds support for the driver_override interface by + +- adding new virPCIDevice{BindTo,UnbindFrom}StubWithOverride functions + that use the driver_override interface +- renames the existing virPCIDevice{BindTo,UnbindFrom}Stub functions + to virPCIDevice{BindTo,UnbindFrom}StubWithNewid to perserve existing + behavior on new_id interface +- changes virPCIDevice{BindTo,UnbindFrom}Stub function to call one of + the above depending on availability of driver_override + +The patch includes a bit of duplicate code, but allows for easily +dropping the new_id code once support for older kernels is no +longer desired. + +Signed-off-by: Jim Fehlig +--- + src/util/virpci.c | 151 +++++++++++++++++++++++++++++++++++++++++++++++++++++- + 1 file changed, 149 insertions(+), 2 deletions(-) Index: libvirt-2.0.0/src/util/virpci.c =================================================================== --- libvirt-2.0.0.orig/src/util/virpci.c +++ libvirt-2.0.0/src/util/virpci.c -@@ -1158,6 +1158,19 @@ virPCIDeviceUnbindFromStub(virPCIDeviceP - - VIR_DEBUG("Reprobing for PCI device %s", dev->name); - -+ /* Remove driver_override if it exists */ -+ VIR_FREE(path); -+ if (!(path = virPCIFile(dev->name, "driver_override"))) -+ goto cleanup; -+ -+ if (virFileExists(path) && virFileWriteStr(path, "\n", 0) < 0) { -+ virReportSystemError(errno, -+ _("Failed to remove stub driver from " -+ "driver_override interface of PCI device '%s'"), -+ dev->name); -+ goto cleanup; -+ } -+ - /* Trigger a re-probe of the device is not in the stub's dynamic - * ID table. If the stub is available, but 'remove_id' isn't - * available, then re-probing would just cause the device to be -@@ -1193,49 +1206,13 @@ virPCIDeviceUnbindFromStub(virPCIDeviceP - +@@ -1089,8 +1089,54 @@ virPCIDeviceUnbind(virPCIDevicePtr dev) + return ret; + } ++/* ++ * Bind a PCI device to a driver using driver_override sysfs interface. ++ * E.g. ++ * ++ * echo driver-name > /sys/bus/pci/devices/0000:03:00.0/driver_override ++ * echo 0000:03:00.0 > /sys/bus/pci/devices/0000:03:00.0/driver/unbind ++ * echo 0000:03:00.0 > /sys/bus/pci/drivers_probe ++ * ++ * An empty driverName will cause the device to be bound to its ++ * preferred driver. ++ */ static int --virPCIDeviceBindToStub(virPCIDevicePtr dev) -+virPCIDeviceBindToStubWithNewid(virPCIDevicePtr dev, -+ const char *stubDriverName) - { -- int result = -1; -- char *stubDriverPath = NULL; -- char *driverLink = NULL; -- char *path = NULL; /* reused for different purposes */ -- const char *stubDriverName = NULL; -+ int ret = -1; -+ char *path = NULL; - virErrorPtr err = NULL; - -- /* Check the device is configured to use one of the known stub drivers */ -- if (dev->stubDriver == VIR_PCI_STUB_DRIVER_NONE) { -- virReportError(VIR_ERR_INTERNAL_ERROR, -- _("No stub driver configured for PCI device %s"), -- dev->name); -- return -1; -- } else if (!(stubDriverName = virPCIStubDriverTypeToString(dev->stubDriver))) { -- virReportError(VIR_ERR_INTERNAL_ERROR, -- _("Unknown stub driver configured for PCI device %s"), -- dev->name); -- return -1; -- } -- -- if (!(stubDriverPath = virPCIDriverDir(stubDriverName)) || -- !(driverLink = virPCIFile(dev->name, "driver"))) -- goto cleanup; -- -- if (virFileExists(driverLink)) { -- if (virFileLinkPointsTo(driverLink, stubDriverPath)) { -- /* The device is already bound to the correct driver */ -- VIR_DEBUG("Device %s is already bound to %s", -- dev->name, stubDriverName); -- dev->unbind_from_stub = true; -- dev->remove_slot = true; -- result = 0; -- goto cleanup; -- } -- /* -- * If the device is bound to a driver that is not the stub, we'll -- * need to reprobe later -- */ -- dev->reprobe = true; -- } -- - /* Add the PCI device ID to the stub's dynamic ID table; - * this is needed to allow us to bind the device to the stub. - * Note: if the device is not currently bound to any driver, -@@ -1283,7 +1260,7 @@ virPCIDeviceBindToStub(virPCIDevicePtr d - } - dev->unbind_from_stub = true; - -- result = 0; -+ ret = 0; - - remove_id: - err = virSaveLastError(); -@@ -1299,7 +1276,7 @@ virPCIDeviceBindToStub(virPCIDevicePtr d - "cannot be probed again.", dev->id, stubDriverName); - } - dev->reprobe = false; -- result = -1; -+ ret = -1; - goto cleanup; - } - -@@ -1314,10 +1291,142 @@ virPCIDeviceBindToStub(virPCIDevicePtr d - "cannot be probed again.", dev->id, stubDriverName); - } - dev->reprobe = false; -- result = -1; -+ ret = -1; -+ goto cleanup; -+ } -+ -+ cleanup: -+ VIR_FREE(path); -+ -+ if (err) -+ virSetError(err); -+ virFreeError(err); -+ -+ return ret; -+} -+ -+ -+static int -+virPCIDeviceBindToStubWithOverride(virPCIDevicePtr dev, -+ const char *stubDriverName) +-virPCIDeviceUnbindFromStub(virPCIDevicePtr dev) ++virPCIDeviceBindWithDriverOverride(virPCIDevicePtr dev, ++ const char *driverName) +{ + int ret = -1; -+ char *path = NULL; ++ char *path; + -+ /* -+ * Add stub to the device's driver_override, falling back to -+ * adding the device ID to the stub's dynamic ID table. -+ */ + if (!(path = virPCIFile(dev->name, "driver_override"))) + return -1; + -+ if (virFileWriteStr(path, stubDriverName, 0) < 0) { ++ if (virFileWriteStr(path, driverName, 0) < 0) { + virReportSystemError(errno, -+ _("Failed to add stub driver '%s' to " -+ "driver_override interface of PCI device '%s'"), -+ stubDriverName, dev->name); ++ _("Failed to add driver '%s' to driver_override " ++ " interface of PCI device '%s'"), ++ driverName, dev->name); + goto cleanup; + } + + if (virPCIDeviceUnbind(dev) < 0) + goto cleanup; + -+ /* Xen's pciback.ko wants you to use new_slot first */ -+ VIR_FREE(path); -+ if (!(path = virPCIDriverFile(stubDriverName, "new_slot"))) -+ goto cleanup; -+ -+ if (virFileExists(path) && virFileWriteStr(path, dev->name, 0) < 0) { -+ virReportSystemError(errno, -+ _("Failed to add slot for " -+ "PCI device '%s' to %s"), -+ dev->name, stubDriverName); -+ goto cleanup; -+ } -+ dev->remove_slot = true; -+ + if (virFileWriteStr(PCI_SYSFS "drivers_probe", dev->name, 0) < 0) { + virReportSystemError(errno, -+ _("Failed to trigger a re-probe for PCI device '%s'"), ++ _("Failed to trigger a probe for PCI device '%s'"), + dev->name); - goto cleanup; - } - -+ /* -+ * Device is now bound to the stub. Set reprobe so it will be re-bound -+ * when unbinding from the stub. -+ */ -+ dev->reprobe = true; -+ dev->unbind_from_stub = true; ++ goto cleanup; ++ } + + ret = 0; + @@ -194,15 +84,65 @@ Index: libvirt-2.0.0/src/util/virpci.c + return ret; +} + ++static int ++virPCIDeviceUnbindFromStubWithNewid(virPCIDevicePtr dev) + { + int result = -1; + char *drvdir = NULL; +@@ -1191,9 +1237,41 @@ virPCIDeviceUnbindFromStub(virPCIDeviceP + return result; + } + ++static int ++virPCIDeviceUnbindFromStubWithOverride(virPCIDevicePtr dev) ++{ ++ if (!dev->unbind_from_stub) { ++ VIR_DEBUG("Unbind from stub skipped for PCI device %s", dev->name); ++ return 0; ++ } ++ ++ return virPCIDeviceBindWithDriverOverride(dev, "\n"); ++} + +static int -+virPCIDeviceBindToStub(virPCIDevicePtr dev) ++virPCIDeviceUnbindFromStub(virPCIDevicePtr dev) +{ -+ int result = -1; ++ int ret; ++ char *path; ++ ++ /* ++ * Prefer using the device's driver_override interface, falling back ++ * to the unpleasant new_id interface. ++ */ ++ if (!(path = virPCIFile(dev->name, "driver_override"))) ++ return -1; ++ ++ if (virFileExists(path)) ++ ret = virPCIDeviceUnbindFromStubWithOverride(dev); ++ else ++ ret = virPCIDeviceUnbindFromStubWithNewid(dev); ++ ++ VIR_FREE(path); ++ return ret; ++} + + static int +-virPCIDeviceBindToStub(virPCIDevicePtr dev) ++virPCIDeviceBindToStubWithNewid(virPCIDevicePtr dev) + { + int result = -1; + bool reprobe = false; +@@ -1345,6 +1423,75 @@ virPCIDeviceBindToStub(virPCIDevicePtr d + return result; + } + ++static int ++virPCIDeviceBindToStubWithOverride(virPCIDevicePtr dev) ++{ ++ int ret = -1; ++ const char *stubDriverName; + char *stubDriverPath = NULL; + char *driverLink = NULL; -+ char *path = NULL; /* reused for different purposes */ -+ const char *stubDriverName = NULL; + + /* Check the device is configured to use one of the known stub drivers */ + if (dev->stubDriver == VIR_PCI_STUB_DRIVER_NONE) { @@ -226,46 +166,45 @@ Index: libvirt-2.0.0/src/util/virpci.c + /* The device is already bound to the correct driver */ + VIR_DEBUG("Device %s is already bound to %s", + dev->name, stubDriverName); -+ dev->unbind_from_stub = true; -+ dev->remove_slot = true; -+ result = 0; ++ ret = 0; + goto cleanup; + } -+ /* -+ * If the device is bound to a driver that is not the stub, we'll -+ * need to reprobe later -+ */ -+ dev->reprobe = true; + } + -+ /* -+ * Add stub to the device's driver_override, falling back to -+ * adding the device ID to the stub's dynamic ID table. -+ */ -+ if (!(path = virPCIFile(dev->name, "driver_override"))) ++ if (virPCIDeviceBindWithDriverOverride(dev, stubDriverName) < 0) + goto cleanup; + -+ if (virFileExists(path)) { -+ if (virPCIDeviceBindToStubWithOverride(dev, stubDriverName) < 0) -+ goto cleanup; -+ } else { -+ if (virPCIDeviceBindToStubWithNewid(dev, stubDriverName) < 0) -+ goto cleanup; -+ } ++ dev->unbind_from_stub = true; ++ ret = 0; + -+ result = 0; ++ cleanup: ++ VIR_FREE(stubDriverPath); ++ VIR_FREE(driverLink); ++ return ret; ++} + - cleanup: - VIR_FREE(stubDriverPath); - VIR_FREE(driverLink); -@@ -1326,10 +1435,6 @@ virPCIDeviceBindToStub(virPCIDevicePtr d - if (result < 0) - virPCIDeviceUnbindFromStub(dev); - -- if (err) -- virSetError(err); -- virFreeError(err); -- - return result; - } - ++static int ++virPCIDeviceBindToStub(virPCIDevicePtr dev) ++{ ++ int ret; ++ char *path; ++ ++ /* ++ * Prefer using the device's driver_override interface, falling back ++ * to the unpleasant new_id interface. ++ */ ++ if (!(path = virPCIFile(dev->name, "driver_override"))) ++ return -1; ++ ++ if (virFileExists(path)) ++ ret = virPCIDeviceBindToStubWithOverride(dev); ++ else ++ ret = virPCIDeviceBindToStubWithNewid(dev); ++ ++ VIR_FREE(path); ++ return ret; ++} ++ + /* virPCIDeviceDetach: + * + * Detach this device from the host driver, attach it to the stub diff --git a/qemu-apparmor-screenshot.patch b/qemu-apparmor-screenshot.patch index 582493c..8dc46f6 100644 --- a/qemu-apparmor-screenshot.patch +++ b/qemu-apparmor-screenshot.patch @@ -2,13 +2,10 @@ Index: libvirt-2.0.0/examples/apparmor/libvirt-qemu =================================================================== --- libvirt-2.0.0.orig/examples/apparmor/libvirt-qemu +++ libvirt-2.0.0/examples/apparmor/libvirt-qemu -@@ -152,6 +152,9 @@ +@@ -151,3 +151,6 @@ + /etc/udev/udev.conf r, /sys/bus/ r, /sys/class/ r, - ++ + # Temporary screendump rule -- See bsc#904426 + /var/cache/libvirt/qemu/qemu.screendump.* rw, -+ - /usr/{lib,libexec}/qemu-bridge-helper Cx -> qemu_bridge_helper, - # child profile for bridge helper process - profile qemu_bridge_helper {