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@canonical.com>
Reviewed-by: Christian Ehrhardt <christian.ehrhardt@canonical.com>
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
This commit is contained in:
Michal Privoznik 2020-08-19 13:35:55 +02:00
parent e41ac71fca
commit 53d9af1e79

View File

@ -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)) {
@ -309,9 +316,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;
}