diff options
-rw-r--r-- | conf/example.conf.in | 8 | ||||
-rw-r--r-- | lib/Makefile.in | 1 | ||||
-rw-r--r-- | lib/commands/toolcontext.c | 13 | ||||
-rw-r--r-- | lib/config/config_settings.h | 1 | ||||
-rw-r--r-- | lib/config/defaults.h | 1 | ||||
-rw-r--r-- | lib/filters/filter-fwraid.c | 121 | ||||
-rw-r--r-- | lib/filters/filter.h | 1 | ||||
-rw-r--r-- | lib/misc/lvm-globals.c | 11 | ||||
-rw-r--r-- | lib/misc/lvm-globals.h | 2 |
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); |