summaryrefslogtreecommitdiffstats
path: root/lib/filters/filter.c
diff options
context:
space:
mode:
authorMilan Broz <mbroz@redhat.com>2011-11-11 15:11:08 +0000
committerMilan Broz <mbroz@redhat.com>2011-11-11 15:11:08 +0000
commit07113beea3c9ef6405fb66b4ae710553f59a45ca (patch)
tree7851b1461bb2e55c88662705ee85fb830d02dd76 /lib/filters/filter.c
parent7891cead1174829900b1779d4dfaa6423883fb97 (diff)
downloadlvm2-07113beea3c9ef6405fb66b4ae710553f59a45ca.tar.gz
lvm2-07113beea3c9ef6405fb66b4ae710553f59a45ca.tar.xz
lvm2-07113beea3c9ef6405fb66b4ae710553f59a45ca.zip
Do not scan device if it is part of active multipath.
Add filter which tries to check if scanned device is part of active multipath. Firstly, only SCSI major number devices are handled in filter. Then it checks if device has exactly one holder (in sysfs) and if it is device-mapper device and DM-UUID is prefixed by "MPATH-". If so, this device is filtered out. The whole filter can be switched off by setting mpath_component_detection in lvm.conf. https://bugzilla.redhat.com/show_bug.cgi?id=597010 Signed-off-by: Milan Broz <mbroz@redhat.com>
Diffstat (limited to 'lib/filters/filter.c')
-rw-r--r--lib/filters/filter.c34
1 files changed, 26 insertions, 8 deletions
diff --git a/lib/filters/filter.c b/lib/filters/filter.c
index f2398a1f..68f65a03 100644
--- a/lib/filters/filter.c
+++ b/lib/filters/filter.c
@@ -29,8 +29,11 @@
#define NUMBER_OF_MAJORS 4096
-/* 0 means LVM won't use this major number. */
-static int _max_partitions_by_major[NUMBER_OF_MAJORS];
+#define PARTITION_SCSI_DEVICE (1 << 0)
+static struct {
+ int max_partitions; /* 0 means LVM won't use this major number. */
+ int flags;
+} _partitions[NUMBER_OF_MAJORS];
typedef struct {
const char *name;
@@ -140,7 +143,7 @@ static int _passes_lvm_type_device_filter(struct dev_filter *f __attribute__((un
uint64_t size;
/* Is this a recognised device type? */
- if (!_max_partitions_by_major[MAJOR(dev->dev)]) {
+ if (!_partitions[MAJOR(dev->dev)].max_partitions) {
log_debug("%s: Skipping: Unrecognised LVM device type %"
PRIu64, name, (uint64_t) MAJOR(dev->dev));
return 0;
@@ -194,12 +197,12 @@ static int _scan_proc_dev(const char *proc, const struct dm_config_node *cn)
log_verbose("No proc filesystem found: using all block device "
"types");
for (i = 0; i < NUMBER_OF_MAJORS; i++)
- _max_partitions_by_major[i] = 1;
+ _partitions[i].max_partitions = 1;
return 1;
}
/* All types unrecognised initially */
- memset(_max_partitions_by_major, 0, sizeof(int) * NUMBER_OF_MAJORS);
+ memset(_partitions, 0, sizeof(_partitions));
if (dm_snprintf(proc_devices, sizeof(proc_devices),
"%s/devices", proc) < 0) {
@@ -251,6 +254,10 @@ static int _scan_proc_dev(const char *proc, const struct dm_config_node *cn)
if (!strncmp("device-mapper", line + i, 13) && isspace(*(line + i + 13)))
_device_mapper_major = line_maj;
+ /* Major is SCSI device */
+ if (!strncmp("sd", line + i, 2) && isspace(*(line + i + 2)))
+ _partitions[line_maj].flags |= PARTITION_SCSI_DEVICE;
+
/* Go through the valid device names and if there is a
match store max number of partitions */
for (j = 0; device_info[j].name != NULL; j++) {
@@ -258,7 +265,7 @@ static int _scan_proc_dev(const char *proc, const struct dm_config_node *cn)
if (dev_len <= strlen(line + i) &&
!strncmp(device_info[j].name, line + i, dev_len) &&
(line_maj < NUMBER_OF_MAJORS)) {
- _max_partitions_by_major[line_maj] =
+ _partitions[line_maj].max_partitions =
device_info[j].max_partitions;
break;
}
@@ -298,7 +305,7 @@ static int _scan_proc_dev(const char *proc, const struct dm_config_node *cn)
if (dev_len <= strlen(line + i) &&
!strncmp(name, line + i, dev_len) &&
(line_maj < NUMBER_OF_MAJORS)) {
- _max_partitions_by_major[line_maj] = cv->v.i;
+ _partitions[line_maj].max_partitions = cv->v.i;
break;
}
}
@@ -312,7 +319,18 @@ static int _scan_proc_dev(const char *proc, const struct dm_config_node *cn)
int max_partitions(int major)
{
- return _max_partitions_by_major[major];
+ if (major > NUMBER_OF_MAJORS)
+ return 0;
+
+ return _partitions[major].max_partitions;
+}
+
+int major_is_scsi_device(int major)
+{
+ if (major > NUMBER_OF_MAJORS)
+ return 0;
+
+ return (_partitions[major].flags & PARTITION_SCSI_DEVICE) ? 1 : 0;
}
struct dev_filter *lvm_type_filter_create(const char *proc,