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@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Christian Ehrhardt <christian.ehrhardt@canonical.com>
Tested-by: Christian Ehrhardt <christian.ehrhardt@canonical.com>
This commit is contained in:
Michal Privoznik 2020-08-18 11:08:15 +02:00
parent cbce7a12b7
commit 82bb167f0d

View File

@ -46,11 +46,9 @@
G_STATIC_ASSERT(BUF_SIZE > sizeof(struct dm_ioctl)); G_STATIC_ASSERT(BUF_SIZE > sizeof(struct dm_ioctl));
static unsigned int virDMMajor;
static int static int
virDevMapperOnceInit(void) virDevMapperGetMajor(unsigned int *major)
{ {
g_autofree char *buf = NULL; g_autofree char *buf = NULL;
VIR_AUTOSTRINGLIST lines = NULL; VIR_AUTOSTRINGLIST lines = NULL;
@ -69,7 +67,7 @@ virDevMapperOnceInit(void)
if (sscanf(lines[i], "%u %ms\n", &maj, &dev) == 2 && if (sscanf(lines[i], "%u %ms\n", &maj, &dev) == 2 &&
STREQ(dev, DM_NAME)) { STREQ(dev, DM_NAME)) {
virDMMajor = maj; *major = maj;
break; break;
} }
} }
@ -85,9 +83,6 @@ virDevMapperOnceInit(void)
} }
VIR_ONCE_GLOBAL_INIT(virDevMapper);
static void * static void *
virDMIoctl(int controlFD, int cmd, struct dm_ioctl *dm, char **buf) virDMIoctl(int controlFD, int cmd, struct dm_ioctl *dm, char **buf)
{ {
@ -304,9 +299,6 @@ virDevMapperGetTargets(const char *path,
* consist of devices or yet another targets. If that's the * consist of devices or yet another targets. If that's the
* case, we have to stop recursion somewhere. */ * case, we have to stop recursion somewhere. */
if (virDevMapperInitialize() < 0)
return -1;
if ((controlFD = virDMOpen()) < 0) if ((controlFD = virDMOpen()) < 0)
return -1; return -1;
@ -318,13 +310,14 @@ bool
virIsDevMapperDevice(const char *dev_name) virIsDevMapperDevice(const char *dev_name)
{ {
struct stat buf; struct stat buf;
unsigned int major;
if (virDevMapperInitialize() < 0) if (virDevMapperGetMajor(&major) < 0)
return false; return false;
if (!stat(dev_name, &buf) && if (!stat(dev_name, &buf) &&
S_ISBLK(buf.st_mode) && S_ISBLK(buf.st_mode) &&
major(buf.st_rdev) == virDMMajor) major(buf.st_rdev) == major)
return true; return true;
return false; return false;