diff --git a/WHATS_NEW b/WHATS_NEW index 66a7ed192..2d0f07c09 100644 --- a/WHATS_NEW +++ b/WHATS_NEW @@ -1,5 +1,6 @@ Version 2.02.45 - =================================== + No longer require kernel and metadata major numbers to match. Add a fully-functional get_cluster_name() to clvmd corosync interface. Remove duplicate cpg_initialize from clvmd startup. Add option to /etc/sysconfig/cluster to select cluster type for clvmd. diff --git a/WHATS_NEW_DM b/WHATS_NEW_DM index 83c88ab40..4435b00a7 100644 --- a/WHATS_NEW_DM +++ b/WHATS_NEW_DM @@ -1,5 +1,6 @@ Version 1.02.31 - ==================================== + If kernel supports only one dm major number, use in place of any supplied. Version 1.02.30 - 26th January 2009 ==================================== diff --git a/lib/activate/dev_manager.c b/lib/activate/dev_manager.c index ef827adc4..cd580e66c 100644 --- a/lib/activate/dev_manager.c +++ b/lib/activate/dev_manager.c @@ -640,7 +640,10 @@ 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)) { + /* + * FIXME compare info.major with lv->major if multiple major support + */ + 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 0c5a73047..fe864946b 100644 --- a/libdm/ioctl/libdm-iface.c +++ b/libdm/ioctl/libdm-iface.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #ifdef linux @@ -63,12 +64,22 @@ static unsigned _dm_version_minor = 0; static unsigned _dm_version_patchlevel = 0; static int _log_suppress = 0; +/* + * If the kernel dm driver only supports one major number + * we store it in _dm_device_major. Otherwise we indicate + * which major numbers have been claimed by device-mapper + * in _dm_bitset. + */ +static unsigned _dm_multiple_major_support = 1; static dm_bitset_t _dm_bitset = NULL; +static uint32_t _dm_device_major = 0; + static int _control_fd = -1; static int _version_checked = 0; static int _version_ok = 1; static unsigned _ioctl_buffer_double_factor = 0; + /* * Support both old and new major numbers to ease the transition. * Clumsy, but only temporary. @@ -249,12 +260,35 @@ static int _create_control(const char *control, uint32_t major, uint32_t minor) } #endif +/* + * FIXME Update bitset in long-running process if dm claims new major numbers. + */ static int _create_dm_bitset(void) { #ifdef DM_IOCTLS - if (_dm_bitset) + struct utsname uts; + + if (_dm_bitset || _dm_device_major) return 1; + if (uname(&uts)) + return 0; + + /* + * 2.6 kernels are limited to one major number. + * Assume 2.4 kernels are patched not to. + * FIXME Check _dm_version and _dm_version_minor if 2.6 changes this. + */ + if (!strncmp(uts.release, "2.6.", 4)) + _dm_multiple_major_support = 0; + + if (!_dm_multiple_major_support) { + if (!_get_proc_number(PROC_DEVICES, DM_NAME, &_dm_device_major)) + return 0; + return 1; + } + + /* Multiple major numbers supported */ if (!(_dm_bitset = dm_bitset_create(NULL, NUMBER_OF_MAJORS))) return 0; @@ -275,7 +309,10 @@ int dm_is_dm_major(uint32_t major) if (!_create_dm_bitset()) return 0; - return dm_bit(_dm_bitset, major) ? 1 : 0; + if (_dm_multiple_major_support) + return dm_bit(_dm_bitset, major) ? 1 : 0; + else + return (major == _dm_device_major) ? 1 : 0; } static int _open_control(void) @@ -1297,6 +1334,14 @@ static struct dm_ioctl *_flatten(struct dm_task *dmt, unsigned repeat_count) log_error("Missing major number for persistent device."); goto bad; } + + if (!_dm_multiple_major_support && dmt->major != _dm_device_major) { + log_verbose("Overriding major number of %" PRIu32 + " with %" PRIu32 " for persistent device.", + dmt->major, _dm_device_major); + dmt->major = _dm_device_major; + } + dmi->flags |= DM_PERSISTENT_DEV_FLAG; dmi->dev = MKDEV(dmt->major, dmt->minor); }