diff --git a/libvirt.spec b/libvirt.spec index fc972c4f32351390c9020d943247f0c0a71c8b1c..1b7ad02f0d24443f564327e8878412eedf076d82 100644 --- a/libvirt.spec +++ b/libvirt.spec @@ -99,7 +99,7 @@ Summary: Library providing a simple virtualization API Name: libvirt Version: 6.2.0 -Release: 15 +Release: 16 License: LGPLv2+ URL: https://libvirt.org/ @@ -147,6 +147,9 @@ Patch0036: conf-domain_conf-pin-the-retry_interval-and-retry_ti.patch Patch0037: storage_driver-Unlock-object-on-ACL-fail-in-storageP.patch Patch0038: security-fix-SELinux-label-generation-logic.patch Patch0039: add-phytium-2000plus-and-s2500-support-on-arm-archit.patch +Patch0040: virDevMapperGetTargets-Don-t-ignore-EBADF.patch +Patch0041: virdevmapper-Don-t-cache-device-mapper-major.patch +Patch0042: virdevmapper-Handle-kernel-without-device-mapper-sup.patch Requires: libvirt-daemon = %{version}-%{release} Requires: libvirt-daemon-config-network = %{version}-%{release} @@ -1879,6 +1882,11 @@ exit 0 %changelog +* Wed Dec 08 2021 Euler Robot +- virDevMapperGetTargets: Don't ignore EBADF +- virdevmapper: Don't cache device-mapper major +- virdevmapper: Handle kernel without device-mapper support + * Wed Dec 08 2021 Euler Robot - add phytium 2000plus and s2500 support on arm architecture for capability diff --git a/virDevMapperGetTargets-Don-t-ignore-EBADF.patch b/virDevMapperGetTargets-Don-t-ignore-EBADF.patch new file mode 100644 index 0000000000000000000000000000000000000000..30cc2214d9e81970f9da99b4def4f43bc7d3705f --- /dev/null +++ b/virDevMapperGetTargets-Don-t-ignore-EBADF.patch @@ -0,0 +1,53 @@ +From 63a6d2b325f4cad831a3bd349bb33359273093f7 Mon Sep 17 00:00:00 2001 +From: Michal Privoznik +Date: Thu, 23 Jul 2020 17:08:46 +0200 +Subject: [PATCH] virDevMapperGetTargets: Don't ignore EBADF +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Michal Privoznik +Reviewed-by: Daniel P. Berrangé +--- + src/qemu/qemu_cgroup.c | 2 +- + src/qemu/qemu_domain.c | 4 ++-- + 2 files changed, 3 insertions(+), 3 deletions(-) + +diff --git a/src/qemu/qemu_cgroup.c b/src/qemu/qemu_cgroup.c +index 057f87124c..aa721df100 100644 +--- a/src/qemu/qemu_cgroup.c ++++ b/src/qemu/qemu_cgroup.c +@@ -91,7 +91,7 @@ qemuSetupImagePathCgroup(virDomainObjPtr vm, + } + + if (virDevMapperGetTargets(path, &targetPaths) < 0 && +- errno != ENOSYS && errno != EBADF) { ++ errno != ENOSYS) { + virReportSystemError(errno, + _("Unable to get devmapper targets for %s"), + path); +diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c +index daab7ebec3..adae36db0e 100644 +--- a/src/qemu/qemu_domain.c ++++ b/src/qemu/qemu_domain.c +@@ -14923,7 +14923,7 @@ qemuDomainSetupDisk(virQEMUDriverConfigPtr cfg G_GNUC_UNUSED, + return -1; + + if (virDevMapperGetTargets(next->path, &targetPaths) < 0 && +- errno != ENOSYS && errno != EBADF) { ++ errno != ENOSYS) { + virReportSystemError(errno, + _("Unable to get devmapper targets for %s"), + next->path); +@@ -15976,7 +15976,7 @@ qemuDomainNamespaceSetupDisk(virDomainObjPtr vm, + tmpPath = g_strdup(next->path); + + if (virDevMapperGetTargets(next->path, &targetPaths) < 0 && +- errno != ENOSYS && errno != EBADF) { ++ errno != ENOSYS) { + virReportSystemError(errno, + _("Unable to get devmapper targets for %s"), + next->path); +-- +2.27.0 + diff --git a/virdevmapper-Don-t-cache-device-mapper-major.patch b/virdevmapper-Don-t-cache-device-mapper-major.patch new file mode 100644 index 0000000000000000000000000000000000000000..b080043bb44ced1096a40336d38494486b0500b9 --- /dev/null +++ b/virdevmapper-Don-t-cache-device-mapper-major.patch @@ -0,0 +1,91 @@ +From fb5ac9b0db25984b0d54149dc15b87f513523430 Mon Sep 17 00:00:00 2001 +From: Michal Privoznik +Date: Tue, 18 Aug 2020 11:08:15 +0200 +Subject: [PATCH] virdevmapper: Don't cache device-mapper major + +The device mapper major is needed in virIsDevMapperDevice() which +determines whether given device is managed by device-mapper. This +number is obtained by parsing /proc/devices and then stored in a +global variable so that the file doesn't have to be parsed again. +However, as it turns out this logic is flawed - the major number +is not static and can change as it can be specified as a +parameter when loading the dm-mod module. + +Unfortunately, I was not able to come up with a good solution and +thus the /proc/devices file is being parsed every time we need +the device mapper major. + +Signed-off-by: Michal Privoznik +Reviewed-by: Peter Krempa +Reviewed-by: Christian Ehrhardt +Tested-by: Christian Ehrhardt +--- + src/util/virdevmapper.c | 17 +++++------------ + 1 file changed, 5 insertions(+), 12 deletions(-) + +diff --git a/src/util/virdevmapper.c b/src/util/virdevmapper.c +index a471504176..b43dbefa9a 100644 +--- a/src/util/virdevmapper.c ++++ b/src/util/virdevmapper.c +@@ -46,11 +46,9 @@ + + G_STATIC_ASSERT(BUF_SIZE > sizeof(struct dm_ioctl)); + +-static unsigned int virDMMajor; +- + + static int +-virDevMapperOnceInit(void) ++virDevMapperGetMajor(unsigned int *major) + { + g_autofree char *buf = NULL; + VIR_AUTOSTRINGLIST lines = NULL; +@@ -69,7 +67,7 @@ virDevMapperOnceInit(void) + + if (sscanf(lines[i], "%u %ms\n", &maj, &dev) == 2 && + STREQ(dev, DM_NAME)) { +- virDMMajor = maj; ++ *major = maj; + break; + } + } +@@ -85,9 +83,6 @@ virDevMapperOnceInit(void) + } + + +-VIR_ONCE_GLOBAL_INIT(virDevMapper); +- +- + static void * + virDMIoctl(int controlFD, int cmd, struct dm_ioctl *dm, char **buf) + { +@@ -305,9 +300,6 @@ virDevMapperGetTargets(const char *path, + * consist of devices or yet another targets. If that's the + * case, we have to stop recursion somewhere. */ + +- if (virDevMapperInitialize() < 0) +- return -1; +- + if ((controlFD = virDMOpen()) < 0) + return -1; + +@@ -319,13 +311,14 @@ bool + virIsDevMapperDevice(const char *dev_name) + { + struct stat buf; ++ unsigned int major; + +- if (virDevMapperInitialize() < 0) ++ if (virDevMapperGetMajor(&major) < 0) + return false; + + if (!stat(dev_name, &buf) && + S_ISBLK(buf.st_mode) && +- major(buf.st_rdev) == virDMMajor) ++ major(buf.st_rdev) == major) + return true; + + return false; +-- +2.27.0 + diff --git a/virdevmapper-Handle-kernel-without-device-mapper-sup.patch b/virdevmapper-Handle-kernel-without-device-mapper-sup.patch new file mode 100644 index 0000000000000000000000000000000000000000..ba256260898c50d33969378f8f5b73a6df118ad0 --- /dev/null +++ b/virdevmapper-Handle-kernel-without-device-mapper-sup.patch @@ -0,0 +1,79 @@ +From 83298f3086380c9b3b3ec39a2d6bf7b33592683b Mon Sep 17 00:00:00 2001 +From: Michal Privoznik +Date: Tue, 18 Aug 2020 11:04:24 +0200 +Subject: [PATCH] virdevmapper: Handle kernel without device-mapper support + +In one of my latest patch (v6.6.0~30) I was trying to remove +libdevmapper use in favor of our own implementation. However, the +code did not take into account that device mapper can be not +compiled into the kernel (e.g. be a separate module that's not +loaded) in which case /proc/devices won't have the device-mapper +major number and thus virDevMapperGetTargets() and/or +virIsDevMapperDevice() fails. + +However, such failure is safe to ignore, because if device mapper +is missing then there can't be any multipath devices and thus we +don't need to allow the deps in CGroups, nor create them in the +domain private namespace, etc. + +Fixes: 22494556542c676d1b9e7f1c1f2ea13ac17e1e3e +Reported-by: Andrea Bolognani +Reported-by: Christian Ehrhardt +Signed-off-by: Michal Privoznik +Reviewed-by: Peter Krempa +Reviewed-by: Christian Ehrhardt +Tested-by: Christian Ehrhardt +--- + src/util/virdevmapper.c | 20 ++++++++++++++++++-- + 1 file changed, 18 insertions(+), 2 deletions(-) + +diff --git a/src/util/virdevmapper.c b/src/util/virdevmapper.c +index b43dbefa9a..a81e2edee4 100644 +--- a/src/util/virdevmapper.c ++++ b/src/util/virdevmapper.c +@@ -54,6 +54,9 @@ virDevMapperGetMajor(unsigned int *major) + VIR_AUTOSTRINGLIST lines = NULL; + size_t i; + ++ if (!virFileExists(CONTROL_PATH)) ++ return -2; ++ + if (virFileReadAll(PROC_DEVICES, BUF_SIZE, &buf) < 0) + return -1; + +@@ -126,8 +129,13 @@ virDMOpen(void) + + memset(&dm, 0, sizeof(dm)); + +- if ((controlFD = open(CONTROL_PATH, O_RDWR)) < 0) ++ if ((controlFD = open(CONTROL_PATH, O_RDWR)) < 0) { ++ if (errno == ENOENT) ++ return -2; ++ ++ virReportSystemError(errno, _("Unable to open %s"), CONTROL_PATH); + return -1; ++ } + + if (!virDMIoctl(controlFD, DM_VERSION, &dm, &tmp)) { + virReportSystemError(errno, "%s", +@@ -300,8 +308,16 @@ virDevMapperGetTargets(const char *path, + * consist of devices or yet another targets. If that's the + * case, we have to stop recursion somewhere. */ + +- if ((controlFD = virDMOpen()) < 0) ++ if ((controlFD = virDMOpen()) < 0) { ++ if (controlFD == -2) { ++ /* The CONTROL_PATH doesn't exist. Probably the ++ * module isn't loaded, yet. Don't error out, just ++ * exit. */ ++ return 0; ++ } ++ + return -1; ++ } + + return virDevMapperGetTargetsImpl(controlFD, path, devPaths, ttl); + } +-- +2.27.0 +