Accepting request 786023 from home:jfehlig:branches:Virtualization
- qemu: Create multipath targets for PRs a30078cb-qemu-create-mp-target.patch bsc#1161883 OBS-URL: https://build.opensuse.org/request/show/786023 OBS-URL: https://build.opensuse.org/package/show/Virtualization/libvirt?expand=0&rev=813
This commit is contained in:
parent
fb13d95c01
commit
770cfbf6c2
367
a30078cb-qemu-create-mp-target.patch
Normal file
367
a30078cb-qemu-create-mp-target.patch
Normal file
@ -0,0 +1,367 @@
|
||||
commit a30078cb832646177defd256e77c632905f1e6d0
|
||||
Author: Michal Prívozník <mprivozn@redhat.com>
|
||||
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 <mprivozn@redhat.com>
|
||||
Tested-by: Lin Ma <LMa@suse.com>
|
||||
Reviewed-by: Jim Fehlig <jfehlig@suse.com>
|
||||
|
||||
Index: libvirt-6.1.0/src/qemu/qemu_domain.c
|
||||
===================================================================
|
||||
--- libvirt-6.1.0.orig/src/qemu/qemu_domain.c
|
||||
+++ libvirt-6.1.0/src/qemu/qemu_domain.c
|
||||
@@ -62,6 +62,7 @@
|
||||
#include "virdomaincheckpointobjlist.h"
|
||||
#include "backup_conf.h"
|
||||
#include "virutil.h"
|
||||
+#include "virdevmapper.h"
|
||||
|
||||
#ifdef __linux__
|
||||
# include <sys/sysmacros.h>
|
||||
@@ -14495,6 +14496,9 @@ qemuDomainSetupDisk(virQEMUDriverConfigP
|
||||
bool hasNVMe = false;
|
||||
|
||||
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;
|
||||
|
||||
@@ -14513,6 +14517,19 @@ qemuDomainSetupDisk(virQEMUDriverConfigP
|
||||
|
||||
if (qemuDomainCreateDevice(next->path, data, false) < 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;
|
||||
+ }
|
||||
+
|
||||
+ for (i = 0; targetPaths && targetPaths[i]; i++) {
|
||||
+ if (qemuDomainCreateDevice(targetPaths[i], data, false) < 0)
|
||||
+ return -1;
|
||||
+ }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15528,21 +15545,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)) {
|
||||
@@ -15553,30 +15568,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.1.0/src/util/virdevmapper.h
|
||||
===================================================================
|
||||
--- libvirt-6.1.0.orig/src/util/virdevmapper.h
|
||||
+++ libvirt-6.1.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.1.0/src/util/virutil.h
|
||||
===================================================================
|
||||
--- libvirt-6.1.0.orig/src/util/virutil.h
|
||||
+++ libvirt-6.1.0/src/util/virutil.h
|
||||
@@ -120,7 +120,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.1.0/tests/qemuhotplugmock.c
|
||||
===================================================================
|
||||
--- libvirt-6.1.0.orig/tests/qemuhotplugmock.c
|
||||
+++ libvirt-6.1.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.1.0/tests/qemuhotplugtest.c
|
||||
===================================================================
|
||||
--- libvirt-6.1.0.orig/tests/qemuhotplugtest.c
|
||||
+++ libvirt-6.1.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;
|
||||
@@ -748,6 +750,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.1.0/tests/qemuhotplugtestdevices/qemuhotplug-disk-scsi-multipath.xml
|
||||
===================================================================
|
||||
--- /dev/null
|
||||
+++ libvirt-6.1.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.1.0/tests/qemuhotplugtestdomains/qemuhotplug-base-live+disk-scsi-multipath.xml
|
||||
===================================================================
|
||||
--- /dev/null
|
||||
+++ libvirt-6.1.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>
|
@ -1,3 +1,10 @@
|
||||
-------------------------------------------------------------------
|
||||
Tue Mar 17 19:50:01 UTC 2020 - James Fehlig <jfehlig@suse.com>
|
||||
|
||||
- qemu: Create multipath targets for PRs
|
||||
a30078cb-qemu-create-mp-target.patch
|
||||
bsc#1161883
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Mon Mar 16 08:42:10 UTC 2020 - Guillaume GARDET <guillaume.gardet@opensuse.org>
|
||||
|
||||
|
@ -338,6 +338,7 @@ Source6: libvirtd-relocation-server.xml
|
||||
Source99: baselibs.conf
|
||||
Source100: %{name}-rpmlintrc
|
||||
# Upstream patches
|
||||
Patch0: a30078cb-qemu-create-mp-target.patch
|
||||
# Patches pending upstream review
|
||||
Patch100: libxl-dom-reset.patch
|
||||
Patch101: network-don-t-use-dhcp-authoritative-on-static-netwo.patch
|
||||
@ -871,6 +872,7 @@ libvirt plugin for NSS for translating domain names into IP addresses.
|
||||
|
||||
%prep
|
||||
%setup -q
|
||||
%patch0 -p1
|
||||
%patch100 -p1
|
||||
%patch101 -p1
|
||||
%patch150 -p1
|
||||
|
Loading…
Reference in New Issue
Block a user