summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--conf/example.conf.in8
-rw-r--r--lib/Makefile.in1
-rw-r--r--lib/commands/toolcontext.c13
-rw-r--r--lib/config/config_settings.h1
-rw-r--r--lib/config/defaults.h1
-rw-r--r--lib/filters/filter-fwraid.c121
-rw-r--r--lib/filters/filter.h1
-rw-r--r--lib/misc/lvm-globals.c11
-rw-r--r--lib/misc/lvm-globals.h2
9 files changed, 156 insertions, 3 deletions
diff --git a/conf/example.conf.in b/conf/example.conf.in
index 67800cd09..caffc988e 100644
--- a/conf/example.conf.in
+++ b/conf/example.conf.in
@@ -179,6 +179,14 @@ devices {
# 1 enables; 0 disables.
md_component_detection = 1
+ # By default, LVM2 will not ignore devices used as components of
+ # firmware RAID devices. Set to 1 to enable this detection.
+ # N.B. LVM2 itself is not detecting firmware RAID - an
+ # auxiliary_device_status_source other than "native" must
+ # be used for this detection to be successful.
+ # 1 enables; 0 disables
+ fw_raid_component_detection = 0
+
# By default, if a PV is placed directly upon an md device, LVM2
# will align its data blocks with the md device's stripe-width.
# 1 enables; 0 disables.
diff --git a/lib/Makefile.in b/lib/Makefile.in
index bad5d8cd3..abd37a1db 100644
--- a/lib/Makefile.in
+++ b/lib/Makefile.in
@@ -69,6 +69,7 @@ SOURCES =\
filters/filter-regex.c \
filters/filter-sysfs.c \
filters/filter-md.c \
+ filters/filter-fwraid.c \
filters/filter-mpath.c \
filters/filter-partitioned.c \
filters/filter-type.c \
diff --git a/lib/commands/toolcontext.c b/lib/commands/toolcontext.c
index 9ce75e4d7..441904b3d 100644
--- a/lib/commands/toolcontext.c
+++ b/lib/commands/toolcontext.c
@@ -851,7 +851,7 @@ static int _init_dev_cache(struct cmd_context *cmd)
return 1;
}
-#define MAX_FILTERS 7
+#define MAX_FILTERS 8
static struct dev_filter *_init_lvmetad_filter_chain(struct cmd_context *cmd)
{
@@ -921,6 +921,13 @@ static struct dev_filter *_init_lvmetad_filter_chain(struct cmd_context *cmd)
nr_filt++;
}
+ /* firmware raid filter. Optional, non-critical. */
+ if (find_config_tree_bool(cmd, devices_fw_raid_component_detection_CFG, NULL)) {
+ init_fwraid_filtering(1);
+ if ((filters[nr_filt] = fwraid_filter_create(cmd->dev_types)))
+ nr_filt++;
+ }
+
if (!(composite = composite_filter_create(nr_filt, filters)))
goto_bad;
@@ -942,7 +949,7 @@ bad:
* sysfs filter -> global regex filter -> type filter ->
* usable device filter(FILTER_MODE_PRE_LVMETAD) ->
* mpath component filter -> partitioned filter ->
- * md component filter
+ * md component filter -> fw raid filter
*
* - cmd->filter - the filter chain used for lvmetad responses:
* persistent filter -> usable device filter(FILTER_MODE_POST_LVMETAD) ->
@@ -958,7 +965,7 @@ bad:
* global regex filter -> type filter ->
* usable device filter(FILTER_MODE_NO_LVMETAD) ->
* mpath component filter -> partitioned filter ->
- * md component filter
+ * md component filter -> fw raid filter
*
*/
static int _init_filters(struct cmd_context *cmd, unsigned load_persistent_cache)
diff --git a/lib/config/config_settings.h b/lib/config/config_settings.h
index 87d0e37d5..4d7c56a27 100644
--- a/lib/config/config_settings.h
+++ b/lib/config/config_settings.h
@@ -103,6 +103,7 @@ cfg_array(devices_types_CFG, "types", devices_CFG_SECTION, CFG_DEFAULT_UNDEFINED
cfg(devices_sysfs_scan_CFG, "sysfs_scan", devices_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_SYSFS_SCAN, vsn(1, 0, 8), NULL)
cfg(devices_multipath_component_detection_CFG, "multipath_component_detection", devices_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_MULTIPATH_COMPONENT_DETECTION, vsn(2, 2, 89), NULL)
cfg(devices_md_component_detection_CFG, "md_component_detection", devices_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_MD_COMPONENT_DETECTION, vsn(1, 0, 18), NULL)
+cfg(devices_fw_raid_component_detection_CFG, "fw_raid_component_detection", devices_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_FW_RAID_COMPONENT_DETECTION, vsn(2, 2, 112), NULL)
cfg(devices_md_chunk_alignment_CFG, "md_chunk_alignment", devices_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_MD_CHUNK_ALIGNMENT, vsn(2, 2, 48), NULL)
cfg(devices_default_data_alignment_CFG, "default_data_alignment", devices_CFG_SECTION, 0, CFG_TYPE_INT, DEFAULT_DATA_ALIGNMENT, vsn(2, 2, 75), NULL)
cfg(devices_data_alignment_detection_CFG, "data_alignment_detection", devices_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_DATA_ALIGNMENT_DETECTION, vsn(2, 2, 51), NULL)
diff --git a/lib/config/defaults.h b/lib/config/defaults.h
index 25972f635..de6642bbf 100644
--- a/lib/config/defaults.h
+++ b/lib/config/defaults.h
@@ -33,6 +33,7 @@
#define DEFAULT_AUXILIARY_DEVICE_STATUS_SOURCE "native"
#define DEFAULT_SYSFS_SCAN 1
#define DEFAULT_MD_COMPONENT_DETECTION 1
+#define DEFAULT_FW_RAID_COMPONENT_DETECTION 0
#define DEFAULT_MD_CHUNK_ALIGNMENT 1
#define DEFAULT_IGNORE_LVM_MIRRORS 1
#define DEFAULT_MULTIPATH_COMPONENT_DETECTION 1
diff --git a/lib/filters/filter-fwraid.c b/lib/filters/filter-fwraid.c
new file mode 100644
index 000000000..1d1ef6d01
--- /dev/null
+++ b/lib/filters/filter-fwraid.c
@@ -0,0 +1,121 @@
+/*
+ * Copyright (C) 2014 Red Hat, Inc. All rights reserved.
+ *
+ * This file is part of LVM2.
+ *
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU Lesser General Public License v.2.1.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "lib.h"
+#include "filter.h"
+
+#ifdef __linux__
+
+#ifdef UDEV_SYNC_SUPPORT
+static int _udev_dev_is_fwraid(struct device *dev)
+{
+ const char *value;
+
+ value = udev_device_get_property_value((struct udev_device *)dev->aux_status.handle, "ID_FS_TYPE");
+ if (value && strcmp(value, "linux_raid_member") && strstr(value, "_raid_member"))
+ return 1;
+
+ return 0;
+}
+#else
+static int _udev_dev_is_fwraid(struct device *dev)
+{
+ return 0;
+}
+#endif
+
+static int _native_dev_is_fwraid(struct device *dev)
+{
+ log_verbose("%s: Firmware RAID detection is not supported by LVM natively. "
+ "Skipping firmware raid detection. ", dev_name(dev));
+ return 0;
+}
+
+static int _dev_is_fwraid(struct device *dev)
+{
+ if (dev_aux_status_use_native(&dev->aux_status, dev_name(dev)))
+ return _native_dev_is_fwraid(dev);
+
+ if (dev->aux_status.source == DEV_AUX_STATUS_SRC_UDEV)
+ return _udev_dev_is_fwraid(dev);
+
+ log_error(INTERNAL_ERROR "Missing hook for firmware RAID recognition "
+ "using auxiliary device status source %s",
+ dev_aux_status_source_name(dev->aux_status.source));
+
+ return 0;
+}
+
+static int _ignore_fwraid(struct dev_filter *f __attribute__((unused)),
+ struct device *dev)
+{
+ int ret;
+
+ if (!fwraid_filtering())
+ return 1;
+
+ ret = _dev_is_fwraid(dev);
+
+ if (ret == 1) {
+ log_debug_devs("%s: Skipping firmware RAID component device [aux:%s/%p]",
+ dev_name(dev),
+ dev_aux_status_source_name_used(&dev->aux_status),
+ dev->aux_status.handle);
+ return 0;
+ }
+
+ if (ret < 0) {
+ log_debug_devs("%s: Skipping: error in firmware RAID component detection",
+ dev_name(dev));
+ return 0;
+ }
+
+ return 1;
+}
+
+static void _destroy(struct dev_filter *f)
+{
+ if (f->use_count)
+ log_error(INTERNAL_ERROR "Destroying firmware RAID filter while in use %u times.", f->use_count);
+
+ dm_free(f);
+}
+
+struct dev_filter *fwraid_filter_create(struct dev_types *dt __attribute__((unused)))
+{
+ struct dev_filter *f;
+
+ if (!(f = dm_zalloc(sizeof(*f)))) {
+ log_error("Firmware RAID filter allocation failed");
+ return NULL;
+ }
+
+ f->passes_filter = _ignore_fwraid;
+ f->destroy = _destroy;
+ f->use_count = 0;
+ f->private = NULL;
+
+ log_debug_devs("Firmware RAID filter initialised.");
+
+ return f;
+}
+
+#else
+
+struct dev_filter *fwraid_filter_create(struct dev_types *dt __attribute__((unused)))
+{
+ return NULL;
+}
+
+#endif
diff --git a/lib/filters/filter.h b/lib/filters/filter.h
index 0519439e9..873ae6d19 100644
--- a/lib/filters/filter.h
+++ b/lib/filters/filter.h
@@ -23,6 +23,7 @@
struct dev_filter *composite_filter_create(int n, struct dev_filter **filters);
struct dev_filter *lvm_type_filter_create(struct dev_types *dt);
struct dev_filter *md_filter_create(struct dev_types *dt);
+struct dev_filter *fwraid_filter_create(struct dev_types *dt);
struct dev_filter *mpath_filter_create(struct dev_types *dt);
struct dev_filter *partitioned_filter_create(struct dev_types *dt);
struct dev_filter *persistent_filter_create(struct dev_types *dt,
diff --git a/lib/misc/lvm-globals.c b/lib/misc/lvm-globals.c
index 92672bb8a..3e5e409ff 100644
--- a/lib/misc/lvm-globals.c
+++ b/lib/misc/lvm-globals.c
@@ -26,6 +26,7 @@ static int _verbose_level = VERBOSE_BASE_LEVEL;
static int _silent = 0;
static int _test = 0;
static int _md_filtering = 0;
+static int _fwraid_filtering = 0;
static int _pvmove = 0;
static int _full_scan_done = 0; /* Restrict to one full scan during each cmd */
static int _obtain_device_list_from_udev = DEFAULT_OBTAIN_DEVICE_LIST_FROM_UDEV;
@@ -75,6 +76,11 @@ void init_md_filtering(int level)
_md_filtering = level;
}
+void init_fwraid_filtering(int level)
+{
+ _fwraid_filtering = level;
+}
+
void init_pvmove(int level)
{
_pvmove = level;
@@ -221,6 +227,11 @@ int md_filtering(void)
return _md_filtering;
}
+int fwraid_filtering(void)
+{
+ return _fwraid_filtering;
+}
+
int pvmove_mode(void)
{
return _pvmove;
diff --git a/lib/misc/lvm-globals.h b/lib/misc/lvm-globals.h
index a0fb458dd..2ce0de547 100644
--- a/lib/misc/lvm-globals.h
+++ b/lib/misc/lvm-globals.h
@@ -26,6 +26,7 @@ void init_verbose(int level);
void init_silent(int silent);
void init_test(int level);
void init_md_filtering(int level);
+void init_fwraid_filtering(int level);
void init_pvmove(int level);
void init_full_scan_done(int level);
void init_obtain_device_list_from_udev(int device_list_from_udev);
@@ -56,6 +57,7 @@ void set_sysfs_dir_path(const char *path);
int test_mode(void);
int md_filtering(void);
+int fwraid_filtering(void);
int pvmove_mode(void);
int full_scan_done(void);
int obtain_device_list_from_udev(void);