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.
# 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.
@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
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 \
{
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)
{
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;
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,
#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"
return 1;
}
-#define MAX_FILTERS 4
+#define MAX_FILTERS 5
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);
#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
#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;
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;
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) {
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++) {
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;
}
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;
}
}
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,
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);