[Pkg-libvirt-commits] [Git][libvirt-team/libvirt][debian/experimental] fix device mapper issues

Andrea Bolognani gitlab at salsa.debian.org
Thu Aug 20 08:28:30 BST 2020



Andrea Bolognani pushed to branch debian/experimental at Libvirt Packaging Team / libvirt


Commits:
d31eba58 by Christian Ehrhardt at 2020-08-20T07:19:40+02:00
fix device mapper issues

As reported on:
https://www.redhat.com/archives/libvir-list/2020-August/msg00236.html
https://www.redhat.com/archives/libvir-list/2020-August/msg00592.html
- virdevmapper-Don-t-cache-device-mapper-major.patch
- virdevmapper-Ignore-all-errors-when-opening-dev-mapper-co.patch
- virdevmapper-Handle-kernel-without-device-mapper-support.patch

- - - - -


4 changed files:

- debian/patches/series
- + debian/patches/virdevmapper-Don-t-cache-device-mapper-major.patch
- + debian/patches/virdevmapper-Handle-kernel-without-device-mapper-support.patch
- + debian/patches/virdevmapper-Ignore-all-errors-when-opening-dev-mapper-co.patch


Changes:

=====================================
debian/patches/series
=====================================
@@ -11,3 +11,6 @@ Pass-GPG_TTY-env-var-to-the-ssh-binary.patch
 debian/Prefer-sbin-over-usr-sbin.patch
 Include-etc-pki-qemu-in-apparmor.patch
 apparmor-Allow-run-pygrub.patch
+virdevmapper-Don-t-cache-device-mapper-major.patch
+virdevmapper-Handle-kernel-without-device-mapper-support.patch
+virdevmapper-Ignore-all-errors-when-opening-dev-mapper-co.patch


=====================================
debian/patches/virdevmapper-Don-t-cache-device-mapper-major.patch
=====================================
@@ -0,0 +1,88 @@
+From: Michal Privoznik <mprivozn at redhat.com>
+Date: Tue, 18 Aug 2020 11:08:15 +0200
+Subject: 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 <mprivozn at redhat.com>
+Reviewed-by: Peter Krempa <pkrempa at redhat.com>
+Reviewed-by: Christian Ehrhardt <christian.ehrhardt at canonical.com>
+Tested-by: Christian Ehrhardt <christian.ehrhardt at canonical.com>
+(cherry picked from commit 82bb167f0d15b733b23931205be3488b83cb9ec6)
+---
+ 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 a471504..b43dbef 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;


=====================================
debian/patches/virdevmapper-Handle-kernel-without-device-mapper-support.patch
=====================================
@@ -0,0 +1,76 @@
+From: Michal Privoznik <mprivozn at redhat.com>
+Date: Tue, 18 Aug 2020 11:04:24 +0200
+Subject: 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 <abologna at redhat.com>
+Reported-by: Christian Ehrhardt <christian.ehrhardt at canonical.com>
+Signed-off-by: Michal Privoznik <mprivozn at redhat.com>
+Reviewed-by: Peter Krempa <pkrempa at redhat.com>
+Reviewed-by: Christian Ehrhardt <christian.ehrhardt at canonical.com>
+Tested-by: Christian Ehrhardt <christian.ehrhardt at canonical.com>
+(cherry picked from commit feb8564a3cc63bc8f68284063d53ec0d2d81a1cc)
+---
+ 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 b43dbef..a81e2ed 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);
+ }


=====================================
debian/patches/virdevmapper-Ignore-all-errors-when-opening-dev-mapper-co.patch
=====================================
@@ -0,0 +1,76 @@
+From: Michal Privoznik <mprivozn at redhat.com>
+Date: Wed, 19 Aug 2020 13:35:55 +0200
+Subject: virdevmapper: Ignore all errors when opening /dev/mapper/control
+
+So far, only ENOENT is ignored (to deal with kernels without
+devmapper). However, as reported on the list, under certain
+scenarios a different error can occur. For instance, when libvirt
+is running inside a container which doesn't have permissions to
+talk to the devmapper. If this is the case, then open() returns
+-1 and sets errno=EPERM.
+
+Assuming that multipath devices are fairly narrow use case and
+using them in a restricted container is even more narrow the best
+fix seems to be to ignore all open errors BUT produce a warning
+on failure. To avoid flooding logs with warnings on kernels
+without devmapper the level is reduced to a plain debug message.
+
+Reported-by: Christian Ehrhardt <christian.ehrhardt at canonical.com>
+Reviewed-by: Christian Ehrhardt <christian.ehrhardt at canonical.com>
+Signed-off-by: Michal Privoznik <mprivozn at redhat.com>
+(cherry picked from commit 53d9af1e7924757e3b5f661131dd707d7110d094)
+---
+ src/util/virdevmapper.c | 23 +++++++++++++++--------
+ 1 file changed, 15 insertions(+), 8 deletions(-)
+
+diff --git a/src/util/virdevmapper.c b/src/util/virdevmapper.c
+index a81e2ed..ee2fab5 100644
+--- a/src/util/virdevmapper.c
++++ b/src/util/virdevmapper.c
+@@ -35,9 +35,12 @@
+ # include "viralloc.h"
+ # include "virstring.h"
+ # include "virfile.h"
++# include "virlog.h"
+ 
+ # define VIR_FROM_THIS VIR_FROM_STORAGE
+ 
++VIR_LOG_INIT("util.virdevmapper");
++
+ # define PROC_DEVICES "/proc/devices"
+ # define DM_NAME "device-mapper"
+ # define DEV_DM_DIR "/dev/" DM_DIR
+@@ -130,11 +133,15 @@ virDMOpen(void)
+     memset(&dm, 0, sizeof(dm));
+ 
+     if ((controlFD = open(CONTROL_PATH, O_RDWR)) < 0) {
+-        if (errno == ENOENT)
+-            return -2;
+-
+-        virReportSystemError(errno, _("Unable to open %s"), CONTROL_PATH);
+-        return -1;
++        /* We can't talk to devmapper. Produce a warning and let
++         * the caller decide what to do next. */
++        if (errno == ENOENT) {
++            VIR_DEBUG("device mapper not available");
++        } else {
++            VIR_WARN("unable to open %s: %s",
++                     CONTROL_PATH, g_strerror(errno));
++        }
++        return -2;
+     }
+ 
+     if (!virDMIoctl(controlFD, DM_VERSION, &dm, &tmp)) {
+@@ -310,9 +317,9 @@ virDevMapperGetTargets(const char *path,
+ 
+     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. */
++            /* The CONTROL_PATH doesn't exist or is unusable.
++             * Probably the module isn't loaded, yet. Don't error
++             * out, just exit. */
+             return 0;
+         }
+ 



View it on GitLab: https://salsa.debian.org/libvirt-team/libvirt/-/commit/d31eba58b2553876b5cea7eafdd666d18c82c593

-- 
View it on GitLab: https://salsa.debian.org/libvirt-team/libvirt/-/commit/d31eba58b2553876b5cea7eafdd666d18c82c593
You're receiving this email because of your account on salsa.debian.org.


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://alioth-lists.debian.net/pipermail/pkg-libvirt-commits/attachments/20200820/2baa789b/attachment-0001.html>


More information about the Pkg-libvirt-commits mailing list