Version 2.02.104
===================================
+ Add ignore_lvm_mirrors to config file to read/ignore labels on mirrors.
Add internal flag for temporary LVs to properly direct udev to not interfere.
Fix endless loop in blkdeactivate <device>... if unable to umount/deactivate.
Add dev-block-<major>:<minor>.device systemd alias for complete PV tracking.
# in recovery situations.
ignore_suspended_devices = 0
+ # ignore_lvm_mirrors: Introduced in version 2.02.104
+ # This setting determines whether logical volumes of "mirror" segment
+ # type are scanned for LVM labels. This affects the ability of
+ # mirrors to be used as physical volumes. If 'ignore_lvm_mirrors'
+ # is set to '1', it becomes impossible to create volume groups on top
+ # of mirror logical volumes - i.e. to stack volume groups on mirrors.
+ #
+ # Allowing mirror logical volumes to be scanned (setting the value to '0')
+ # can potentially cause LVM processes and I/O to the mirror to become
+ # blocked. This is due to the way that the "mirror" segment type handles
+ # failures. In order for the hang to manifest itself, an LVM command must
+ # be run just after a failure and before the automatic LVM repair process
+ # takes place OR there must be failures in multiple mirrors in the same
+ # volume group at the same time with write failures occurring moments
+ # before a scan of the mirror's labels.
+ #
+ # Note that these scanning limitations do not apply to the LVM RAID
+ # types, like "raid1". The RAID segment types handle failures in a
+ # different way and are not subject to possible process or I/O blocking.
+ #
+ # It is encouraged that users set 'ignore_lvm_mirrors' to 1 if they
+ # are using the "mirror" segment type. Users that require volume group
+ # stacking on mirrored logical volumes should consider using the "raid1"
+ # segment type. The "raid1" segment type is not available for
+ # active/active clustered volume groups.
+ #
+ # Set to 1 to disallow stacking and thereby avoid a possible deadlock.
+ ignore_lvm_mirrors = 1
+
# During each LVM operation errors received from each device are counted.
# If the counter of a particular device exceeds the limit set here, no
# further I/O is sent to that device for the remainder of the respective
next = dm_get_next_target(dmt, next, &start, &length,
&target_type, ¶ms);
- if (target_type && !strcmp(target_type, "mirror") &&
- !_ignore_blocked_mirror_devices(dev, start, length, params)) {
- log_debug_activation("%s: Mirror device %s not usable.",
- dev_name(dev), name);
- goto out;
+ if (target_type && !strcmp(target_type, "mirror")) {
+ if (ignore_lvm_mirrors()) {
+ log_debug_activation("%s: Scanning mirror devices is disabled.", dev_name(dev));
+ goto out;
+ }
+ if (!_ignore_blocked_mirror_devices(dev, start,
+ length, params)) {
+ log_debug_activation("%s: Mirror device %s not usable.",
+ dev_name(dev), name);
+ goto out;
+ }
}
/*
goto_bad;
init_ignore_suspended_devices(find_config_tree_bool(cmd, devices_ignore_suspended_devices_CFG, NULL));
+ init_ignore_lvm_mirrors(find_config_tree_bool(cmd, devices_ignore_lvm_mirrors_CFG, NULL));
/*
* If 'cache_dir' or 'cache_file_prefix' is set, ignore 'cache'.
cfg(devices_data_alignment_CFG, "data_alignment", devices_CFG_SECTION, 0, CFG_TYPE_INT, 0, vsn(2, 2, 45), NULL)
cfg(devices_data_alignment_offset_detection_CFG, "data_alignment_offset_detection", devices_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_DATA_ALIGNMENT_OFFSET_DETECTION, vsn(2, 2, 50), NULL)
cfg(devices_ignore_suspended_devices_CFG, "ignore_suspended_devices", devices_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_IGNORE_SUSPENDED_DEVICES, vsn(1, 2, 19), NULL)
+cfg(devices_ignore_lvm_mirrors_CFG, "ignore_lvm_mirrors", devices_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_IGNORE_LVM_MIRRORS, vsn(2, 2, 104), NULL)
cfg(devices_disable_after_error_count_CFG, "disable_after_error_count", devices_CFG_SECTION, 0, CFG_TYPE_INT, DEFAULT_DISABLE_AFTER_ERROR_COUNT, vsn(2, 2, 75), NULL)
cfg(devices_require_restorefile_with_uuid_CFG, "require_restorefile_with_uuid", devices_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_REQUIRE_RESTOREFILE_WITH_UUID, vsn(2, 2, 73), NULL)
cfg(devices_pv_min_size_CFG, "pv_min_size", devices_CFG_SECTION, 0, CFG_TYPE_INT, DEFAULT_PV_MIN_SIZE_KB, vsn(2, 2, 85), NULL)
#define DEFAULT_SYSFS_SCAN 1
#define DEFAULT_MD_COMPONENT_DETECTION 1
#define DEFAULT_MD_CHUNK_ALIGNMENT 1
+#define DEFAULT_IGNORE_LVM_MIRRORS 1
#define DEFAULT_MULTIPATH_COMPONENT_DETECTION 1
#define DEFAULT_IGNORE_SUSPENDED_DEVICES 1
#define DEFAULT_DISABLE_AFTER_ERROR_COUNT 0
static int _dmeventd_monitor = DEFAULT_DMEVENTD_MONITOR;
static int _background_polling = DEFAULT_BACKGROUND_POLLING;
static int _ignore_suspended_devices = 0;
+static int _ignore_lvm_mirrors = DEFAULT_IGNORE_LVM_MIRRORS;
static int _error_message_produced = 0;
static unsigned _is_static = 0;
static int _udev_checking = 1;
_ignore_suspended_devices = ignore;
}
+void init_ignore_lvm_mirrors(int scan)
+{
+ _ignore_lvm_mirrors = scan;
+}
+
void init_cmd_name(int status)
{
_log_cmd_name = status;
return _ignore_suspended_devices;
}
+int ignore_lvm_mirrors(void)
+{
+ return _ignore_lvm_mirrors;
+}
+
void init_debug(int level)
{
_debug_level = level;
void init_dmeventd_monitor(int reg);
void init_background_polling(int polling);
void init_ignore_suspended_devices(int ignore);
+void init_ignore_lvm_mirrors(int scan);
void init_error_message_produced(int produced);
void init_is_static(unsigned value);
void init_udev_checking(int checking);
int mirror_in_sync(void);
int background_polling(void);
int ignore_suspended_devices(void);
+int ignore_lvm_mirrors(void);
const char *log_command_name(void);
unsigned is_static(void);
int udev_checking(void);