]> sourceware.org Git - lvm2.git/commitdiff
Do not scan device if it is part of active multipath.
authorMilan Broz <mbroz@redhat.com>
Fri, 11 Nov 2011 15:11:08 +0000 (15:11 +0000)
committerMilan Broz <mbroz@redhat.com>
Fri, 11 Nov 2011 15:11:08 +0000 (15:11 +0000)
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>
WHATS_NEW
doc/example.conf.in
include/.symlinks.in
lib/Makefile.in
lib/activate/activate.c
lib/activate/activate.h
lib/commands/toolcontext.c
lib/config/defaults.h
lib/filters/filter.c
lib/filters/filter.h

index f893dd0e5e063337da7e60b03e7536b9d48068c0..0ee72716012905be51268ae2009444e01d0e48fa 100644 (file)
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,6 @@
 Version 2.02.89 - 
 ==================================
+  Add filter to avoid scan of device if it is part of active multipath.
   Add missing default $LVM_VG_NAME usage for snapshots.
   Fix extent_count overflow with lvextend.
   Add missing lvrename mirrored log recursion in for_each_sub_lv.
index ed15db6c96203a9adbe0521bb81ca4d31c4e1e70..2dd18089cd2e1bae92399c09abb1f82d71114f46 100644 (file)
@@ -103,6 +103,11 @@ devices {
     # 1 enables; 0 disables.
     sysfs_scan = 1
 
+    # By default, LVM2 will ignore devices used as component paths
+    # of device-mapper multipath devices.
+    # 1 enables; 0 disables.
+    multipath_component_detection = 1
+
     # By default, LVM2 will ignore devices used as components of
     # software RAID (md) devices by looking for md superblocks.
     # 1 enables; 0 disables.
index c16e107d90c9b20aae984d04c4c73036340eb730..00d7d55b4245597612a7a6c73a54083ca12e7e1a 100644 (file)
@@ -16,6 +16,7 @@
 @top_srcdir@/lib/display/display.h
 @top_srcdir@/lib/filters/filter-composite.h
 @top_srcdir@/lib/filters/filter-md.h
+@top_srcdir@/lib/filters/filter-mpath.h
 @top_srcdir@/lib/filters/filter-persistent.h
 @top_srcdir@/lib/filters/filter-regex.h
 @top_srcdir@/lib/filters/filter-sysfs.h
index a46e59603b4f690ccb4ae1e8267bb11dd46dbe83..4e9afd9d4ac1cde95bebbb6b67c3343928cf4095 100644 (file)
@@ -65,6 +65,7 @@ SOURCES =\
        filters/filter-regex.c \
        filters/filter-sysfs.c \
        filters/filter-md.c \
+       filters/filter-mpath.c \
        filters/filter.c \
        format_text/archive.c \
        format_text/archiver.c \
index 2b44b19264d4d59599234e75b271a95d7159f5f4..37c10f586438236d60a5dafc7d1c15082d31b998 100644 (file)
@@ -147,6 +147,10 @@ int target_present(struct cmd_context *cmd, const char *target_name,
 {
        return 0;
 }
+int dm_prefix_check(const char *sysfs_dir, int major, int minor, const char *prefix)
+{
+       return 0;
+}
 int lv_info(struct cmd_context *cmd, const struct logical_volume *lv, unsigned origin_only,
            struct lvinfo *info, int with_open_count, int with_read_ahead)
 {
@@ -439,6 +443,29 @@ int target_version(const char *target_name, uint32_t *maj,
        return r;
 }
 
+int dm_prefix_check(const char *sysfs_dir, int major, int minor, const char *prefix)
+{
+       struct dm_task *dmt;
+       const char *uuid;
+       int r;
+
+       if (!(dmt = dm_task_create(DM_DEVICE_STATUS)))
+               return 0;
+
+       if (!dm_task_set_minor(dmt, minor) ||
+           !dm_task_set_major(dmt, major) ||
+           !dm_task_run(dmt) ||
+           !(uuid = dm_task_get_uuid(dmt))) {
+               dm_task_destroy(dmt);
+               return 0;
+       }
+
+       r = strncasecmp(uuid, prefix, strlen(prefix));
+       dm_task_destroy(dmt);
+
+       return (r == 0) ? 1 : 0;
+}
+
 int module_present(struct cmd_context *cmd, const char *target_name)
 {
        int ret = 0;
index 119211dfc3b9e760133421569a2534568c07fb8e..7de1703c00490845a04cbb52cdef2481a010f50e 100644 (file)
@@ -53,6 +53,7 @@ int target_present(struct cmd_context *cmd, const char *target_name,
                   int use_modprobe);
 int target_version(const char *target_name, uint32_t *maj,
                   uint32_t *min, uint32_t *patchlevel);
+int dm_prefix_check(const char *sysfs_dir, int major, int minor, const char *prefix);
 int list_segment_modules(struct dm_pool *mem, const struct lv_segment *seg,
                         struct dm_list *modules);
 int list_lv_modules(struct dm_pool *mem, const struct logical_volume *lv,
index 4dc4c26604f96e9d9eba15253eea94b22b8907a5..ec6e40011ce1935ed70e19a35577924432a019a1 100644 (file)
@@ -22,6 +22,7 @@
 #include "filter.h"
 #include "filter-composite.h"
 #include "filter-md.h"
+#include "filter-mpath.h"
 #include "filter-persistent.h"
 #include "filter-regex.h"
 #include "filter-sysfs.h"
@@ -714,7 +715,7 @@ static int _init_dev_cache(struct cmd_context *cmd)
        return 1;
 }
 
-#define MAX_FILTERS 4
+#define MAX_FILTERS 5
 
 static struct dev_filter *_init_filter_components(struct cmd_context *cmd)
 {
@@ -766,6 +767,13 @@ static struct dev_filter *_init_filter_components(struct cmd_context *cmd)
                        nr_filt++;
        }
 
+       /* mpath component filter. Optional, non-critical. */
+       if (find_config_tree_bool(cmd, "devices/multipath_component_detection",
+                            DEFAULT_MULTIPATH_COMPONENT_DETECTION)) {
+               if ((filters[nr_filt] = mpath_filter_create(cmd->sysfs_dir)))
+                       nr_filt++;
+       }
+
        /* Only build a composite filter if we really need it. */
        return (nr_filt == 1) ?
            filters[0] : composite_filter_create(nr_filt, filters);
index 6819a9a80f2fd09841e393d6abae0ccca9e582a7..9b91aea51f2eaf5ae106b2fadabbfc852831b27c 100644 (file)
@@ -33,6 +33,7 @@
 #define DEFAULT_SYSFS_SCAN 1
 #define DEFAULT_MD_COMPONENT_DETECTION 1
 #define DEFAULT_MD_CHUNK_ALIGNMENT 1
+#define DEFAULT_MULTIPATH_COMPONENT_DETECTION 1
 #define DEFAULT_IGNORE_SUSPENDED_DEVICES 1
 #define DEFAULT_DISABLE_AFTER_ERROR_COUNT 0
 #define DEFAULT_REQUIRE_RESTOREFILE_WITH_UUID 1
index f2398a1f2ae1350eca1d0935cd315a68e0de3734..68f65a0348d73b072291e6e33efa056f19819b2e 100644 (file)
 
 #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,
index 5c6047a441eefca2e055bcc7eff4e7cec60b6fc6..21cb89bdec1006e2b569155092828c8f5a78fe63 100644 (file)
@@ -39,6 +39,7 @@ int dm_major(void);
 int md_major(void);
 int blkext_major(void);
 int max_partitions(int major);
+int major_is_scsi_device(int major);
 
 int dev_subsystem_part_major(const struct device *dev);
 const char *dev_subsystem_name(const struct device *dev);
This page took 0.053711 seconds and 5 git commands to generate.