Hello community, here is the log from the commit of package libvirt for openSUSE:Leap:15.2 checked in at 2020-03-23 17:26:28 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Leap:15.2/libvirt (Old) and /work/SRC/openSUSE:Leap:15.2/.libvirt.new.3160 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "libvirt" Mon Mar 23 17:26:28 2020 rev:112 rq:787275 version:6.0.0 Changes: -------- --- /work/SRC/openSUSE:Leap:15.2/libvirt/libvirt.changes 2020-03-13 10:56:29.324396757 +0100 +++ /work/SRC/openSUSE:Leap:15.2/.libvirt.new.3160/libvirt.changes 2020-03-23 17:26:29.442152466 +0100 @@ -1,0 +2,8 @@ +Tue Mar 17 19:50:01 UTC 2020 - James Fehlig <[email protected]> + +- qemu: Create multipath targets for PRs + a30078cb-qemu-create-mp-target.patch, + aeb909bf-qemu-multipath-fix.patch + bsc#1161883 + +------------------------------------------------------------------- New: ---- a30078cb-qemu-create-mp-target.patch aeb909bf-qemu-multipath-fix.patch ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ libvirt.spec ++++++ --- /var/tmp/diff_new_pack.9qgzzc/_old 2020-03-23 17:26:32.058154527 +0100 +++ /var/tmp/diff_new_pack.9qgzzc/_new 2020-03-23 17:26:32.062154530 +0100 @@ -343,6 +343,8 @@ Patch2: 72ed254b-drop-exec-perms-bashcompletion.patch Patch3: e092daac-prohib-parallel-tunneled-mig.patch Patch4: ae9e6c2a-qemu-allow-cond-format-probe.patch +Patch5: a30078cb-qemu-create-mp-target.patch +Patch6: aeb909bf-qemu-multipath-fix.patch # Patches pending upstream review Patch100: libxl-dom-reset.patch Patch101: network-don-t-use-dhcp-authoritative-on-static-netwo.patch @@ -881,6 +883,8 @@ %patch2 -p1 %patch3 -p1 %patch4 -p1 +%patch5 -p1 +%patch6 -p1 %patch100 -p1 %patch101 -p1 %patch150 -p1 ++++++ a30078cb-qemu-create-mp-target.patch ++++++ commit a30078cb832646177defd256e77c632905f1e6d0 Author: Michal Prívozník <[email protected]> Date: Wed Nov 13 15:34:50 2019 +0100 qemu: Create multipath targets for PRs If a disk has persistent reservations enabled, qemu-pr-helper might open not only /dev/mapper/control but also individual targets of the multipath device. We are already querying for them in CGroups, but now we have to create them in the namespace too. This was brought up in [1]. 1: https://bugzilla.redhat.com/show_bug.cgi?id=1711045#c61 Signed-off-by: Michal Privoznik <[email protected]> Tested-by: Lin Ma <[email protected]> Reviewed-by: Jim Fehlig <[email protected]> Index: libvirt-6.0.0/src/qemu/qemu_domain.c =================================================================== --- libvirt-6.0.0.orig/src/qemu/qemu_domain.c +++ libvirt-6.0.0/src/qemu/qemu_domain.c @@ -62,6 +62,7 @@ #include "virdomainsnapshotobjlist.h" #include "virdomaincheckpointobjlist.h" #include "backup_conf.h" +#include "virdevmapper.h" #ifdef MAJOR_IN_MKDEV # include <sys/mkdev.h> @@ -14559,6 +14560,9 @@ qemuDomainSetupDisk(virQEMUDriverConfigP int ret = -1; for (next = disk->src; virStorageSourceIsBacking(next); next = next->backingStore) { + VIR_AUTOSTRINGLIST targetPaths = NULL; + size_t i; + if (next->type == VIR_STORAGE_TYPE_NVME) { g_autofree char *nvmePath = NULL; @@ -14577,6 +14581,19 @@ qemuDomainSetupDisk(virQEMUDriverConfigP if (qemuDomainCreateDevice(next->path, data, false) < 0) goto cleanup; + + if (virDevMapperGetTargets(next->path, &targetPaths) < 0 && + errno != ENOSYS && errno != EBADF) { + virReportSystemError(errno, + _("Unable to get devmapper targets for %s"), + next->path); + goto cleanup; + } + + for (i = 0; targetPaths && targetPaths[i]; i++) { + if (qemuDomainCreateDevice(targetPaths[i], data, false) < 0) + goto cleanup; + } } } @@ -15603,21 +15620,19 @@ qemuDomainNamespaceSetupDisk(virDomainOb virStorageSourcePtr src) { virStorageSourcePtr next; - char **paths = NULL; + VIR_AUTOSTRINGLIST paths = NULL; size_t npaths = 0; bool hasNVMe = false; - g_autofree char *dmPath = NULL; - g_autofree char *vfioPath = NULL; - int ret = -1; for (next = src; virStorageSourceIsBacking(next); next = next->backingStore) { + VIR_AUTOSTRINGLIST targetPaths = NULL; g_autofree char *tmpPath = NULL; if (next->type == VIR_STORAGE_TYPE_NVME) { hasNVMe = true; if (!(tmpPath = virPCIDeviceAddressGetIOMMUGroupDev(&next->nvme->pciAddr))) - goto cleanup; + return -1; } else { if (virStorageSourceIsEmpty(next) || !virStorageSourceIsLocalStorage(next)) { @@ -15628,30 +15643,35 @@ qemuDomainNamespaceSetupDisk(virDomainOb tmpPath = g_strdup(next->path); } - if (VIR_APPEND_ELEMENT(paths, npaths, tmpPath) < 0) - goto cleanup; + if (virStringListAdd(&paths, tmpPath) < 0) + return -1; + + if (virDevMapperGetTargets(next->path, &targetPaths) < 0 && + errno != ENOSYS && errno != EBADF) { + virReportSystemError(errno, + _("Unable to get devmapper targets for %s"), + next->path); + return -1; + } + + if (virStringListMerge(&paths, &targetPaths) < 0) + return -1; } /* qemu-pr-helper might require access to /dev/mapper/control. */ - if (src->pr) { - dmPath = g_strdup(QEMU_DEVICE_MAPPER_CONTROL_PATH); - if (VIR_APPEND_ELEMENT_COPY(paths, npaths, dmPath) < 0) - goto cleanup; - } + if (src->pr && + virStringListAdd(&paths, QEMU_DEVICE_MAPPER_CONTROL_PATH) < 0) + return -1; - if (hasNVMe) { - vfioPath = g_strdup(QEMU_DEV_VFIO); - if (VIR_APPEND_ELEMENT(paths, npaths, vfioPath) < 0) - goto cleanup; - } + if (hasNVMe && + virStringListAdd(&paths, QEMU_DEV_VFIO) < 0) + return -1; + npaths = virStringListLength((const char **) paths); if (qemuDomainNamespaceMknodPaths(vm, (const char **) paths, npaths) < 0) - goto cleanup; + return -1; - ret = 0; - cleanup: - virStringListFreeCount(paths, npaths); - return ret; + return 0; } Index: libvirt-6.0.0/src/util/virdevmapper.h =================================================================== --- libvirt-6.0.0.orig/src/util/virdevmapper.h +++ libvirt-6.0.0/src/util/virdevmapper.h @@ -20,6 +20,8 @@ #pragma once +#include "internal.h" + int virDevMapperGetTargets(const char *path, - char ***devPaths); + char ***devPaths) G_GNUC_NO_INLINE; Index: libvirt-6.0.0/src/util/virutil.h =================================================================== --- libvirt-6.0.0.orig/src/util/virutil.h +++ libvirt-6.0.0/src/util/virutil.h @@ -122,7 +122,7 @@ bool virValidateWWN(const char *wwn); int virGetDeviceID(const char *path, int *maj, - int *min); + int *min) G_GNUC_NO_INLINE; int virSetDeviceUnprivSGIO(const char *path, const char *sysfs_dir, int unpriv_sgio); Index: libvirt-6.0.0/tests/qemuhotplugmock.c =================================================================== --- libvirt-6.0.0.orig/tests/qemuhotplugmock.c +++ libvirt-6.0.0/tests/qemuhotplugmock.c @@ -19,7 +19,24 @@ #include <config.h> #include "qemu/qemu_hotplug.h" +#include "qemu/qemu_process.h" #include "conf/domain_conf.h" +#include "virdevmapper.h" +#include "virutil.h" +#include "virmock.h" + +static int (*real_virGetDeviceID)(const char *path, int *maj, int *min); +static bool (*real_virFileExists)(const char *path); + +static void +init_syms(void) +{ + if (real_virFileExists) + return; + + VIR_MOCK_REAL_INIT(virGetDeviceID); + VIR_MOCK_REAL_INIT(virFileExists); +} unsigned long long qemuDomainGetUnplugTimeout(virDomainObjPtr vm G_GNUC_UNUSED) @@ -31,3 +48,61 @@ qemuDomainGetUnplugTimeout(virDomainObjP return 200; return 100; } + + +int +virDevMapperGetTargets(const char *path, + char ***devPaths) +{ + *devPaths = NULL; + + if (STREQ(path, "/dev/mapper/virt")) { + *devPaths = g_new(char *, 4); + (*devPaths)[0] = g_strdup("/dev/block/8:0"); /* /dev/sda */ + (*devPaths)[1] = g_strdup("/dev/block/8:16"); /* /dev/sdb */ + (*devPaths)[2] = g_strdup("/dev/block/8:32"); /* /dev/sdc */ + (*devPaths)[3] = NULL; + } + + return 0; +} + + +int +virGetDeviceID(const char *path, int *maj, int *min) +{ + init_syms(); + + if (STREQ(path, "/dev/mapper/virt")) { + *maj = 254; + *min = 0; + return 0; + } + + return real_virGetDeviceID(path, maj, min); +} + + +bool +virFileExists(const char *path) +{ + init_syms(); + + if (STREQ(path, "/dev/mapper/virt")) + return true; + + return real_virFileExists(path); +} + + +int +qemuProcessStartManagedPRDaemon(virDomainObjPtr vm G_GNUC_UNUSED) +{ + return 0; +} + + +void +qemuProcessKillManagedPRDaemon(virDomainObjPtr vm G_GNUC_UNUSED) +{ +} Index: libvirt-6.0.0/tests/qemuhotplugtest.c =================================================================== --- libvirt-6.0.0.orig/tests/qemuhotplugtest.c +++ libvirt-6.0.0/tests/qemuhotplugtest.c @@ -87,6 +87,8 @@ qemuHotplugCreateObjects(virDomainXMLOpt virQEMUCapsSet(priv->qemuCaps, QEMU_CAPS_VNC); virQEMUCapsSet(priv->qemuCaps, QEMU_CAPS_SPICE); virQEMUCapsSet(priv->qemuCaps, QEMU_CAPS_SPICE_FILE_XFER_DISABLE); + virQEMUCapsSet(priv->qemuCaps, QEMU_CAPS_PR_MANAGER_HELPER); + virQEMUCapsSet(priv->qemuCaps, QEMU_CAPS_SCSI_BLOCK); if (qemuTestCapsCacheInsert(driver.qemuCapsCache, priv->qemuCaps) < 0) return -1; @@ -743,6 +745,17 @@ mymain(void) "device_del", QMP_DEVICE_DELETED("scsi3-0-5-6") QMP_OK, "human-monitor-command", HMP("")); + DO_TEST_ATTACH("base-live", "disk-scsi-multipath", false, true, + "object-add", QMP_OK, + "human-monitor-command", HMP("OK\\r\\n"), + "device_add", QMP_OK); + DO_TEST_DETACH("base-live", "disk-scsi-multipath", true, true, + "device_del", QMP_OK, + "human-monitor-command", HMP("")); + DO_TEST_DETACH("base-live", "disk-scsi-multipath", false, false, + "device_del", QMP_DEVICE_DELETED("scsi0-0-0-0") QMP_OK, + "human-monitor-command", HMP("")); + DO_TEST_ATTACH("base-live", "qemu-agent", false, true, "chardev-add", QMP_OK, "device_add", QMP_OK); Index: libvirt-6.0.0/tests/qemuhotplugtestdevices/qemuhotplug-disk-scsi-multipath.xml =================================================================== --- /dev/null +++ libvirt-6.0.0/tests/qemuhotplugtestdevices/qemuhotplug-disk-scsi-multipath.xml @@ -0,0 +1,8 @@ +<disk type='block' device='lun'> + <driver name='qemu' type='raw'/> + <source dev='/dev/mapper/virt'> + <reservations managed='yes'/> + </source> + <target dev='sda' bus='scsi'/> + <address type='drive' controller='0' bus='0' target='0' unit='0'/> +</disk> Index: libvirt-6.0.0/tests/qemuhotplugtestdomains/qemuhotplug-base-live+disk-scsi-multipath.xml =================================================================== --- /dev/null +++ libvirt-6.0.0/tests/qemuhotplugtestdomains/qemuhotplug-base-live+disk-scsi-multipath.xml @@ -0,0 +1,62 @@ +<domain type='kvm' id='7'> + <name>hotplug</name> + <uuid>d091ea82-29e6-2e34-3005-f02617b36e87</uuid> + <memory unit='KiB'>4194304</memory> + <currentMemory unit='KiB'>4194304</currentMemory> + <vcpu placement='static'>4</vcpu> + <os> + <type arch='x86_64' machine='pc'>hvm</type> + <boot dev='hd'/> + </os> + <features> + <acpi/> + <apic/> + <pae/> + </features> + <clock offset='utc'/> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>restart</on_crash> + <devices> + <emulator>/usr/bin/qemu-system-x86_64</emulator> + <disk type='block' device='lun'> + <driver name='qemu' type='raw'/> + <source dev='/dev/mapper/virt'> + <reservations managed='yes'> + <source type='unix' path='/tmp/lib/domain-7-hotplug/pr-helper0.sock' mode='client'/> + </reservations> + </source> + <backingStore/> + <target dev='sda' bus='scsi'/> + <alias name='scsi0-0-0-0'/> + <address type='drive' controller='0' bus='0' target='0' unit='0'/> + </disk> + <controller type='usb' index='0'> + <alias name='usb'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/> + </controller> + <controller type='ide' index='0'> + <alias name='ide'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/> + </controller> + <controller type='scsi' index='0' model='virtio-scsi'> + <alias name='scsi0'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/> + </controller> + <controller type='pci' index='0' model='pci-root'> + <alias name='pci'/> + </controller> + <controller type='virtio-serial' index='0'> + <alias name='virtio-serial0'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/> + </controller> + <input type='mouse' bus='ps2'> + <alias name='input0'/> + </input> + <input type='keyboard' bus='ps2'> + <alias name='input1'/> + </input> + <memballoon model='none'/> + </devices> + <seclabel type='none' model='none'/> +</domain> ++++++ aeb909bf-qemu-multipath-fix.patch ++++++ commit aeb909bf9b4c3fa48d017475545df94f7c5d3b3a Author: Michal Prívozník <[email protected]> Date: Thu Mar 19 12:51:55 2020 +0100 qemu: Don't crash when getting targets for a multipath In one of my previous commits I've introduced code that creates all devices for given (possible) multipath target. But I've made a mistake there - the code accesses 'next->path' without checking if the disk source is local. Note that the 'next->path' is NULL/doesn't make sense for VIR_STORAGE_TYPE_NVME. Fixes: a30078cb832646177defd256e77c632905f1e6d0 Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1814947 Signed-off-by: Michal Privoznik <[email protected]> Reviewed-by: Peter Krempa <[email protected]> Reviewed-by: Ján Tomko <[email protected]> Index: libvirt-6.0.0/src/qemu/qemu_domain.c =================================================================== --- libvirt-6.0.0.orig/src/qemu/qemu_domain.c +++ libvirt-6.0.0/src/qemu/qemu_domain.c @@ -15625,7 +15625,6 @@ qemuDomainNamespaceSetupDisk(virDomainOb bool hasNVMe = false; for (next = src; virStorageSourceIsBacking(next); next = next->backingStore) { - VIR_AUTOSTRINGLIST targetPaths = NULL; g_autofree char *tmpPath = NULL; if (next->type == VIR_STORAGE_TYPE_NVME) { @@ -15634,6 +15633,8 @@ qemuDomainNamespaceSetupDisk(virDomainOb if (!(tmpPath = virPCIDeviceAddressGetIOMMUGroupDev(&next->nvme->pciAddr))) return -1; } else { + VIR_AUTOSTRINGLIST targetPaths = NULL; + if (virStorageSourceIsEmpty(next) || !virStorageSourceIsLocalStorage(next)) { /* Not creating device. Just continue. */ @@ -15641,20 +15642,20 @@ qemuDomainNamespaceSetupDisk(virDomainOb } tmpPath = g_strdup(next->path); - } - if (virStringListAdd(&paths, tmpPath) < 0) - return -1; + if (virDevMapperGetTargets(next->path, &targetPaths) < 0 && + errno != ENOSYS && errno != EBADF) { + virReportSystemError(errno, + _("Unable to get devmapper targets for %s"), + next->path); + return -1; + } - if (virDevMapperGetTargets(next->path, &targetPaths) < 0 && - errno != ENOSYS && errno != EBADF) { - virReportSystemError(errno, - _("Unable to get devmapper targets for %s"), - next->path); - return -1; + if (virStringListMerge(&paths, &targetPaths) < 0) + return -1; } - if (virStringListMerge(&paths, &targetPaths) < 0) + if (virStringListAdd(&paths, tmpPath) < 0) return -1; }
