From 101cb20b189a8b7a4f31e42c13e5f36d05c69d6730fc34c04cdcbf2bb1a2f05d Mon Sep 17 00:00:00 2001 From: James Fehlig Date: Wed, 19 Aug 2020 19:39:18 +0000 Subject: [PATCH] - virdevmapper: Handle kernel without device-mapper support 82bb167f-dont-cache-devmapper-major.patch, feb8564a-handle-no-devmapper.patch boo#1175465 OBS-URL: https://build.opensuse.org/package/show/Virtualization/libvirt?expand=0&rev=837 --- 82bb167f-dont-cache-devmapper-major.patch | 86 +++++++++++++++++++++++ feb8564a-handle-no-devmapper.patch | 74 +++++++++++++++++++ libvirt.changes | 8 +++ libvirt.spec | 4 ++ 4 files changed, 172 insertions(+) create mode 100644 82bb167f-dont-cache-devmapper-major.patch create mode 100644 feb8564a-handle-no-devmapper.patch diff --git a/82bb167f-dont-cache-devmapper-major.patch b/82bb167f-dont-cache-devmapper-major.patch new file mode 100644 index 0000000..e4b238f --- /dev/null +++ b/82bb167f-dont-cache-devmapper-major.patch @@ -0,0 +1,86 @@ +commit 82bb167f0d15b733b23931205be3488b83cb9ec6 +Author: Michal Prívozník +Date: Tue Aug 18 11:08:15 2020 +0200 + + 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 + +Index: libvirt-6.6.0/src/util/virdevmapper.c +=================================================================== +--- libvirt-6.6.0.orig/src/util/virdevmapper.c ++++ libvirt-6.6.0/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; diff --git a/feb8564a-handle-no-devmapper.patch b/feb8564a-handle-no-devmapper.patch new file mode 100644 index 0000000..f68ff68 --- /dev/null +++ b/feb8564a-handle-no-devmapper.patch @@ -0,0 +1,74 @@ +commit feb8564a3cc63bc8f68284063d53ec0d2d81a1cc +Author: Michal Prívozník +Date: Tue Aug 18 11:04:24 2020 +0200 + + 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 + +Index: libvirt-6.6.0/src/util/virdevmapper.c +=================================================================== +--- libvirt-6.6.0.orig/src/util/virdevmapper.c ++++ libvirt-6.6.0/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); + } diff --git a/libvirt.changes b/libvirt.changes index 2685827..e57170e 100644 --- a/libvirt.changes +++ b/libvirt.changes @@ -1,3 +1,11 @@ +------------------------------------------------------------------- +Wed Aug 19 19:36:52 UTC 2020 - James Fehlig + +- virdevmapper: Handle kernel without device-mapper support + 82bb167f-dont-cache-devmapper-major.patch, + feb8564a-handle-no-devmapper.patch + boo#1175465 + ------------------------------------------------------------------- Tue Aug 18 21:40:48 UTC 2020 - James Fehlig diff --git a/libvirt.spec b/libvirt.spec index 357d417..8e2f6c2 100644 --- a/libvirt.spec +++ b/libvirt.spec @@ -337,6 +337,8 @@ Source99: baselibs.conf Source100: %{name}-rpmlintrc # Upstream patches Patch0: 2edd63a0-fix-virFileSetCOW-logic.patch +Patch1: 82bb167f-dont-cache-devmapper-major.patch +Patch2: feb8564a-handle-no-devmapper.patch # Patches pending upstream review Patch100: libxl-dom-reset.patch Patch101: network-don-t-use-dhcp-authoritative-on-static-netwo.patch @@ -877,6 +879,8 @@ libvirt plugin for NSS for translating domain names into IP addresses. %prep %setup -q %patch0 -p1 +%patch1 -p1 +%patch2 -p1 %patch100 -p1 %patch101 -p1 %patch150 -p1