[lvm-devel] [PATCH] Workaround for problems with persistent device major number
Milan Broz
mbroz at redhat.com
Wed Feb 4 13:52:00 UTC 2009
Workaround for problems with persistent device major number.
We have support in LVM metadata for storing arbitrary major:minor
number for LV.
This used to work with LVM1 and 2.4 kernel.
Unfortunately, 2.6 kernel device-mapper have no support for arbitrary
major number for dm device (yet).
(One major number is allocated in dm_mod constructor now.)
- the major number is ignored during device creation
- but status query request that major:minor pair match
LVM2 need to check that requested persistent major:minor pair is not
used - but this check can fail now, because used major number changed.
# lvcreate -n tst -My --major 200 --minor 33 -l 1 vg_test
Volume tst (200:33) differs from already active device (254:33)
Until the major number setting is reinstated in kernel, the patch
uses this workaround:
- it stores allocated major number from kernel device-mapper
(parsing /proc/devices)
- it replaces this major number in all ioctl calls if persistent
number is requested
- it removes validation for major number in LVM device_manager,
(major:minor collision check still applies for non-LVM devices)
Patch fixes regression bug
https://bugzilla.redhat.com/show_bug.cgi?id=480838
Signed-off-by: Milan Broz <mbroz at redhat.com>
---
lib/activate/dev_manager.c | 2 +-
libdm/ioctl/libdm-iface.c | 15 +++++++++++++++
2 files changed, 16 insertions(+), 1 deletions(-)
diff --git a/lib/activate/dev_manager.c b/lib/activate/dev_manager.c
index ef827ad..a0b3bbe 100644
--- a/lib/activate/dev_manager.c
+++ b/lib/activate/dev_manager.c
@@ -640,7 +640,7 @@ static int _add_dev_to_dtree(struct dev_manager *dm, struct dm_tree *dtree,
* requested major/minor and that major/minor pair is available for use
*/
if (!layer && lv->major != -1 && lv->minor != -1) {
- if (info.exists && (info.major != lv->major || info.minor != lv->minor)) {
+ if (info.exists && (info.minor != lv->minor)) {
log_error("Volume %s (%" PRIu32 ":%" PRIu32")"
" differs from already active device "
"(%" PRIu32 ":%" PRIu32")",
diff --git a/libdm/ioctl/libdm-iface.c b/libdm/ioctl/libdm-iface.c
index 0c5a730..96aceb1 100644
--- a/libdm/ioctl/libdm-iface.c
+++ b/libdm/ioctl/libdm-iface.c
@@ -69,6 +69,8 @@ static int _version_checked = 0;
static int _version_ok = 1;
static unsigned _ioctl_buffer_double_factor = 0;
+static uint32_t _dm_device_major = 0;
+
/*
* Support both old and new major numbers to ease the transition.
* Clumsy, but only temporary.
@@ -255,6 +257,12 @@ static int _create_dm_bitset(void)
if (_dm_bitset)
return 1;
+ /* FIXME: when reinstated multiple major number support in kernel
+ * if (_dm_version >= 4 && _dm_version_minor >= 20)
+ */
+ if (!_get_proc_number(PROC_DEVICES, DM_NAME, &_dm_device_major))
+ return 0;
+
if (!(_dm_bitset = dm_bitset_create(NULL, NUMBER_OF_MAJORS)))
return 0;
@@ -1297,6 +1305,13 @@ static struct dm_ioctl *_flatten(struct dm_task *dmt, unsigned repeat_count)
log_error("Missing major number for persistent device.");
goto bad;
}
+
+ if (_dm_device_major && dmt->major != _dm_device_major) {
+ log_verbose("Fixing major number for persistent device to %u.",
+ _dm_device_major);
+ dmt->major = _dm_device_major;
+ }
+
dmi->flags |= DM_PERSISTENT_DEV_FLAG;
dmi->dev = MKDEV(dmt->major, dmt->minor);
}
More information about the lvm-devel
mailing list