master - metadata: cleanup flags definition to be consistent
by Heinz Mauelshagen
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=7126fb13e7d4f9fbdf1...
Commit: 7126fb13e7d4f9fbdf10663a5d04b52a3f5dba0c
Parent: 1810162b510e25d4f07d07f83ba17a8ebc230c9c
Author: Heinz Mauelshagen <heinzm(a)redhat.com>
AuthorDate: Wed Mar 22 00:29:49 2017 +0100
Committer: Heinz Mauelshagen <heinzm(a)redhat.com>
CommitterDate: Wed Mar 22 00:29:49 2017 +0100
metadata: cleanup flags definition to be consistent
Use shift bitops throughout segtype.h.
---
lib/metadata/segtype.h | 76 ++++++++++++++++++++++++------------------------
1 files changed, 38 insertions(+), 38 deletions(-)
diff --git a/lib/metadata/segtype.h b/lib/metadata/segtype.h
index a6093e8..2be9eac 100644
--- a/lib/metadata/segtype.h
+++ b/lib/metadata/segtype.h
@@ -28,50 +28,50 @@ struct dm_config_node;
struct dev_manager;
/* Feature flags */
-#define SEG_CAN_SPLIT 0x0000000000000001ULL
-#define SEG_AREAS_STRIPED 0x0000000000000002ULL
-#define SEG_AREAS_MIRRORED 0x0000000000000004ULL
-#define SEG_SNAPSHOT 0x0000000000000008ULL
-#define SEG_FORMAT1_SUPPORT 0x0000000000000010ULL
-#define SEG_VIRTUAL 0x0000000000000020ULL
-#define SEG_CANNOT_BE_ZEROED 0x0000000000000040ULL
-#define SEG_MONITORED 0x0000000000000080ULL
-#define SEG_REPLICATOR 0x0000000000000100ULL
-#define SEG_REPLICATOR_DEV 0x0000000000000200ULL
-#define SEG_RAID 0x0000000000000400ULL
-#define SEG_THIN_POOL 0x0000000000000800ULL
-#define SEG_THIN_VOLUME 0x0000000000001000ULL
-#define SEG_CACHE 0x0000000000002000ULL
-#define SEG_CACHE_POOL 0x0000000000004000ULL
-#define SEG_MIRROR 0x0000000000008000ULL
-#define SEG_ONLY_EXCLUSIVE 0x0000000000010000ULL /* In cluster only exlusive activation */
-#define SEG_CAN_ERROR_WHEN_FULL 0x0000000000020000ULL
-
-#define SEG_RAID0 0x0000000000040000ULL
-#define SEG_RAID0_META 0x0000000000080000ULL
-#define SEG_RAID1 0x0000000000100000ULL
-#define SEG_RAID10_NEAR 0x0000000000200000ULL
+#define SEG_CAN_SPLIT (1ULL << 0)
+#define SEG_AREAS_STRIPED (1ULL << 1)
+#define SEG_AREAS_MIRRORED (1ULL << 2)
+#define SEG_SNAPSHOT (1ULL << 3)
+#define SEG_FORMAT1_SUPPORT (1ULL << 4)
+#define SEG_VIRTUAL (1ULL << 5)
+#define SEG_CANNOT_BE_ZEROED (1ULL << 6)
+#define SEG_MONITORED (1ULL << 7)
+#define SEG_REPLICATOR (1ULL << 8)
+#define SEG_REPLICATOR_DEV (1ULL << 9)
+#define SEG_RAID (1ULL << 10)
+#define SEG_THIN_POOL (1ULL << 11)
+#define SEG_THIN_VOLUME (1ULL << 12)
+#define SEG_CACHE (1ULL << 13)
+#define SEG_CACHE_POOL (1ULL << 14)
+#define SEG_MIRROR (1ULL << 15)
+#define SEG_ONLY_EXCLUSIVE (1ULL << 16) /* In cluster only exlusive activation */
+#define SEG_CAN_ERROR_WHEN_FULL (1ULL << 17)
+
+#define SEG_RAID0 (1ULL << 18)
+#define SEG_RAID0_META (1ULL << 19)
+#define SEG_RAID1 (1ULL << 20)
+#define SEG_RAID10_NEAR (1ULL << 21)
#define SEG_RAID10 SEG_RAID10_NEAR
-#define SEG_RAID4 0x0000000000400000ULL
-#define SEG_RAID5_N 0x0000000000800000ULL
-#define SEG_RAID5_LA 0x0000000001000000ULL
-#define SEG_RAID5_LS 0x0000000002000000ULL
-#define SEG_RAID5_RA 0x0000000004000000ULL
-#define SEG_RAID5_RS 0x0000000008000000ULL
+#define SEG_RAID4 (1ULL << 22)
+#define SEG_RAID5_N (1ULL << 23)
+#define SEG_RAID5_LA (1ULL << 24)
+#define SEG_RAID5_LS (1ULL << 25)
+#define SEG_RAID5_RA (1ULL << 26)
+#define SEG_RAID5_RS (1ULL << 27)
#define SEG_RAID5 SEG_RAID5_LS
-#define SEG_RAID6_NC 0x0000000010000000ULL
-#define SEG_RAID6_NR 0x0000000020000000ULL
-#define SEG_RAID6_ZR 0x0000000040000000ULL
-#define SEG_RAID6_LA_6 0x0000000080000000ULL
-#define SEG_RAID6_LS_6 0x0000000100000000ULL
-#define SEG_RAID6_RA_6 0x0000000200000000ULL
-#define SEG_RAID6_RS_6 0x0000000400000000ULL
-#define SEG_RAID6_N_6 0x0000000800000000ULL
+#define SEG_RAID6_NC (1ULL << 28)
+#define SEG_RAID6_NR (1ULL << 29)
+#define SEG_RAID6_ZR (1ULL << 30)
+#define SEG_RAID6_LA_6 (1ULL << 31)
+#define SEG_RAID6_LS_6 (1ULL << 32)
+#define SEG_RAID6_RA_6 (1ULL << 33)
+#define SEG_RAID6_RS_6 (1ULL << 34)
+#define SEG_RAID6_N_6 (1ULL << 35)
#define SEG_RAID6 SEG_RAID6_ZR
-#define SEG_STRIPED_TARGET 0x0000008000000000ULL
+#define SEG_STRIPED_TARGET (1ULL << 39)
-#define SEG_UNKNOWN 0x8000000000000000ULL
+#define SEG_UNKNOWN (1ULL << 63)
#define SEG_TYPE_NAME_LINEAR "linear"
#define SEG_TYPE_NAME_STRIPED "striped"
7 years, 2 months
master - WHATS_NEW: adjust to misordered raid parameters
by Heinz Mauelshagen
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=1810162b510e25d4f07...
Commit: 1810162b510e25d4f07d07f83ba17a8ebc230c9c
Parent: 1e4462dbfbd2bbe3590936df24b3ccd83110b158
Author: Heinz Mauelshagen <heinzm(a)redhat.com>
AuthorDate: Tue Mar 21 18:18:58 2017 +0100
Committer: Heinz Mauelshagen <heinzm(a)redhat.com>
CommitterDate: Tue Mar 21 18:18:58 2017 +0100
WHATS_NEW: adjust to misordered raid parameters
---
WHATS_NEW | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/WHATS_NEW b/WHATS_NEW
index daca9e0..99a0bda 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,6 @@
Version 2.02.169 -
=====================================
+ Adjust to misordered raid parameters
Conditionally reject raid convert to striped/raid0* after reshape
Ensure raid6 upconversion restrictions
Adjust mirror+raid DSOs to aforementioned lvconvert --repair
7 years, 2 months
master - raid: adjust to misordered raid table line output
by Heinz Mauelshagen
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=1e4462dbfbd2bbe3590...
Commit: 1e4462dbfbd2bbe3590936df24b3ccd83110b158
Parent: 642d682d8ddcc3152f68b3ec8518902a0ef448ac
Author: Heinz Mauelshagen <heinzm(a)redhat.com>
AuthorDate: Tue Mar 21 18:17:42 2017 +0100
Committer: Heinz Mauelshagen <heinzm(a)redhat.com>
CommitterDate: Tue Mar 21 18:17:42 2017 +0100
raid: adjust to misordered raid table line output
The libdevmapper interface compares existing table line retrieved from
the kernel to new table line created to decide if it can suppress a reload.
Any difference between input and output of the table line is taken to be a
change thus causing a table reload.
The dm-raid target started to misorder the raid parameters (e.g. 'raid10_copies')
starting with dm-raid target version 1.9.0 up to (excluding) 1.11.0. This causes
runtime failures (limited to raid10 as of tests) and needs to be reversed to allow
e.g. old lvm2 uspace to run properly.
Check for the aforementioned version range and adjust creation of the table line
to the respective (mis)ordered sequence inside and correct order outside the range
(as described for the raid target in the kernels Documentation/device-mapper/dm-raid.txt).
---
lib/metadata/segtype.h | 1 +
lib/raid/raid.c | 23 ++++++++++-
libdm/libdevmapper.h | 10 +++++
libdm/libdm-deptree.c | 102 +++++++++++++++++++++++++++++++++---------------
4 files changed, 103 insertions(+), 33 deletions(-)
diff --git a/lib/metadata/segtype.h b/lib/metadata/segtype.h
index 2364db8..a6093e8 100644
--- a/lib/metadata/segtype.h
+++ b/lib/metadata/segtype.h
@@ -288,6 +288,7 @@ struct segment_type *init_unknown_segtype(struct cmd_context *cmd,
#define RAID_FEATURE_RAID4 (1U << 3) /* ! version 1.8 or 1.9.0 */
#define RAID_FEATURE_SHRINK (1U << 4) /* version 1.9.0 */
#define RAID_FEATURE_RESHAPE (1U << 5) /* version 1.10.1 */
+#define RAID_FEATURE_PROPER_TABLE_ORDER (1U << 6) /* version >= 1.9.0 and < 1.11.0 had wrong parameter order */
#ifdef RAID_INTERNAL
int init_raid_segtypes(struct cmd_context *cmd, struct segtype_library *seglib);
diff --git a/lib/raid/raid.c b/lib/raid/raid.c
index df9796d..7e9f0d3 100644
--- a/lib/raid/raid.c
+++ b/lib/raid/raid.c
@@ -228,6 +228,9 @@ static int _raid_text_export(const struct lv_segment *seg, struct formatter *f)
return _raid_text_export_raid(seg, f);
}
+static int _raid_target_present(struct cmd_context *cmd,
+ const struct lv_segment *seg __attribute__((unused)),
+ unsigned *attributes);
static int _raid_add_target_line(struct dev_manager *dm __attribute__((unused)),
struct dm_pool *mem __attribute__((unused)),
struct cmd_context *cmd __attribute__((unused)),
@@ -238,6 +241,7 @@ static int _raid_add_target_line(struct dev_manager *dm __attribute__((unused)),
uint32_t *pvmove_mirror_count __attribute__((unused)))
{
int delta_disks = 0, delta_disks_minus = 0, delta_disks_plus = 0, data_offset = 0;
+ unsigned attrs;
uint32_t s;
uint64_t flags = 0;
uint64_t rebuilds[RAID_BITMAP_SIZE];
@@ -300,6 +304,13 @@ static int _raid_add_target_line(struct dev_manager *dm __attribute__((unused)),
flags = DM_NOSYNC;
}
+ if (!_raid_target_present(seg->lv->vg->cmd, seg, &attrs))
+ return_0;
+
+ /* RAID target line parameters are in kernel documented order */
+ if (attrs & RAID_FEATURE_PROPER_TABLE_ORDER)
+ flags |= DM_RAID_TABLE_ORDERED;
+
params.raid_type = lvseg_name(seg);
if (seg->segtype->parity_devs) {
@@ -479,7 +490,7 @@ static int _raid_target_present(struct cmd_context *cmd,
static int _raid_checked = 0;
static int _raid_present = 0;
- static unsigned _raid_attrs = 0;
+ static unsigned _raid_attrs;
uint32_t maj, min, patchlevel;
unsigned i;
@@ -488,6 +499,7 @@ static int _raid_target_present(struct cmd_context *cmd,
if (!_raid_checked) {
_raid_checked = 1;
+ _raid_attrs = RAID_FEATURE_PROPER_TABLE_ORDER;
if (!(_raid_present = target_present(cmd, TARGET_NAME_RAID, 1)))
return 0;
@@ -514,6 +526,15 @@ static int _raid_target_present(struct cmd_context *cmd,
else
log_very_verbose("Target raid does not support %s.",
SEG_TYPE_NAME_RAID4);
+
+ /*
+ * Target version range check:
+ *
+ * raid target line parameters were misordered (e.g. 'raid10_copies')
+ * in target version >= 1.9.0 and < 1.11.0
+ */
+ if (maj == 1 && min >= 9 && min < 11)
+ _raid_attrs &= ~RAID_FEATURE_PROPER_TABLE_ORDER;
}
if (attributes)
diff --git a/libdm/libdevmapper.h b/libdm/libdevmapper.h
index 4bd32b4..ff84785 100644
--- a/libdm/libdevmapper.h
+++ b/libdm/libdevmapper.h
@@ -1775,6 +1775,16 @@ int dm_tree_node_add_mirror_target(struct dm_tree_node *node,
#define DM_BLOCK_ON_ERROR 0x00000004 /* On error, suspend I/O */
#define DM_CORELOG 0x00000008 /* In-memory log */
+/*
+ * RAID flag: table line is in kernel documented order.
+ *
+ * Target version >= 1.9.0 and < 1.11.0 misordered e.g. 'raid10_copies'
+ *
+ * Keep distinct from mirror log ones above because it
+ * can be passed together with those in load segment flags!
+ */
+#define DM_RAID_TABLE_ORDERED 0x00000010
+
int dm_tree_node_add_mirror_target_log(struct dm_tree_node *node,
uint32_t region_size,
unsigned clustered,
diff --git a/libdm/libdm-deptree.c b/libdm/libdm-deptree.c
index 832d8de..2dced75 100644
--- a/libdm/libdm-deptree.c
+++ b/libdm/libdm-deptree.c
@@ -2432,46 +2432,84 @@ static int _raid_emit_segment_line(struct dm_task *dmt, uint32_t major,
EMIT_PARAMS(pos, " raid10_format offset");
#endif
- if (seg->data_copies > 1 && type == SEG_RAID10)
- EMIT_PARAMS(pos, " raid10_copies %u", seg->data_copies);
+ if (seg->flags & DM_RAID_TABLE_ORDERED) {
+ /* Emit order of paramters as of kernel target documentation */
+ if (seg->flags & DM_NOSYNC)
+ EMIT_PARAMS(pos, " nosync");
+ else if (seg->flags & DM_FORCESYNC)
+ EMIT_PARAMS(pos, " sync");
- if (seg->flags & DM_NOSYNC)
- EMIT_PARAMS(pos, " nosync");
- else if (seg->flags & DM_FORCESYNC)
- EMIT_PARAMS(pos, " sync");
+ for (i = 0; i < area_count; i++)
+ if (seg->rebuilds[i/64] & (1ULL << (i%64)))
+ EMIT_PARAMS(pos, " rebuild %u", i);
- if (seg->region_size)
- EMIT_PARAMS(pos, " region_size %u", seg->region_size);
+ if (seg->min_recovery_rate)
+ EMIT_PARAMS(pos, " min_recovery_rate %u",
+ seg->min_recovery_rate);
- /* If seg-data_offset == 1, kernel needs a zero offset to adjust to it */
- if (seg->data_offset)
- EMIT_PARAMS(pos, " data_offset %d", seg->data_offset == 1 ? 0 : seg->data_offset);
+ if (seg->max_recovery_rate)
+ EMIT_PARAMS(pos, " max_recovery_rate %u",
+ seg->max_recovery_rate);
- if (seg->delta_disks)
- EMIT_PARAMS(pos, " delta_disks %d", seg->delta_disks);
+ for (i = 0; i < area_count; i++)
+ if (seg->writemostly[i/64] & (1ULL << (i%64)))
+ EMIT_PARAMS(pos, " write_mostly %u", i);
- for (i = 0; i < area_count; i++)
- if (seg->rebuilds[i/64] & (1ULL << (i%64)))
- EMIT_PARAMS(pos, " rebuild %u", i);
+ if (seg->writebehind)
+ EMIT_PARAMS(pos, " max_write_behind %u", seg->writebehind);
- for (i = 0; i < area_count; i++)
- if (seg->writemostly[i/64] & (1ULL << (i%64)))
- EMIT_PARAMS(pos, " write_mostly %u", i);
+ if (seg->region_size)
+ EMIT_PARAMS(pos, " region_size %u", seg->region_size);
- if (seg->writebehind)
- EMIT_PARAMS(pos, " max_write_behind %u", seg->writebehind);
+ if (seg->data_copies > 1 && type == SEG_RAID10)
+ EMIT_PARAMS(pos, " raid10_copies %u", seg->data_copies);
- /*
- * Has to be before "min_recovery_rate" or the kernels
- * check will fail when both set and min > previous max
- */
- if (seg->max_recovery_rate)
- EMIT_PARAMS(pos, " max_recovery_rate %u",
- seg->max_recovery_rate);
+ if (seg->delta_disks)
+ EMIT_PARAMS(pos, " delta_disks %d", seg->delta_disks);
+
+ /* If seg-data_offset == 1, kernel needs a zero offset to adjust to it */
+ if (seg->data_offset)
+ EMIT_PARAMS(pos, " data_offset %d", seg->data_offset == 1 ? 0 : seg->data_offset);
+
+ } else {
+ /* Target version >= 1.9.0 && < 1.11.0 had a table line parameter ordering flaw */
+ if (seg->data_copies > 1 && type == SEG_RAID10)
+ EMIT_PARAMS(pos, " raid10_copies %u", seg->data_copies);
+
+ if (seg->flags & DM_NOSYNC)
+ EMIT_PARAMS(pos, " nosync");
+ else if (seg->flags & DM_FORCESYNC)
+ EMIT_PARAMS(pos, " sync");
- if (seg->min_recovery_rate)
- EMIT_PARAMS(pos, " min_recovery_rate %u",
- seg->min_recovery_rate);
+ if (seg->region_size)
+ EMIT_PARAMS(pos, " region_size %u", seg->region_size);
+
+ /* If seg-data_offset == 1, kernel needs a zero offset to adjust to it */
+ if (seg->data_offset)
+ EMIT_PARAMS(pos, " data_offset %d", seg->data_offset == 1 ? 0 : seg->data_offset);
+
+ if (seg->delta_disks)
+ EMIT_PARAMS(pos, " delta_disks %d", seg->delta_disks);
+
+ for (i = 0; i < area_count; i++)
+ if (seg->rebuilds[i/64] & (1ULL << (i%64)))
+ EMIT_PARAMS(pos, " rebuild %u", i);
+
+ for (i = 0; i < area_count; i++)
+ if (seg->writemostly[i/64] & (1ULL << (i%64)))
+ EMIT_PARAMS(pos, " write_mostly %u", i);
+
+ if (seg->writebehind)
+ EMIT_PARAMS(pos, " max_write_behind %u", seg->writebehind);
+
+ if (seg->max_recovery_rate)
+ EMIT_PARAMS(pos, " max_recovery_rate %u",
+ seg->max_recovery_rate);
+
+ if (seg->min_recovery_rate)
+ EMIT_PARAMS(pos, " min_recovery_rate %u",
+ seg->min_recovery_rate);
+ }
/* Print number of metadata/data device pairs */
EMIT_PARAMS(pos, " %u", area_count);
@@ -2742,7 +2780,7 @@ static int _emit_segment(struct dm_task *dmt, uint32_t major, uint32_t minor,
struct load_segment *seg, uint64_t *seg_start)
{
char *params;
- size_t paramsize = 4096;
+ size_t paramsize = 4096; /* FIXME: too small for long RAID lines when > 64 devices supported */
int ret;
do {
7 years, 2 months
master - raid: adjust to misordered raid table line output
by Heinz Mauelshagen
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=4dcc3bd38ca945da8b5...
Commit: 4dcc3bd38ca945da8b5ab9a49c0d03fabc5fdfaa
Parent: 642d682d8ddcc3152f68b3ec8518902a0ef448ac
Author: Heinz Mauelshagen <heinzm(a)redhat.com>
AuthorDate: Tue Mar 21 18:15:59 2017 +0100
Committer: Heinz Mauelshagen <heinzm(a)redhat.com>
CommitterDate: Tue Mar 21 18:15:59 2017 +0100
raid: adjust to misordered raid table line output
the libdevmapper interface compares existing table line retrieved from
the kernel to new table line created to decide if it can suppress a reload.
Any difference between input and output of the table line is taken to be a
change thus causing a table reload.
The dm-raid target started to misorder the raid parameters (e.g. 'raid10_copies')
starting with dm-raid target version 1.9.0 up to (excluding) 1.11.0. This causes
runtime failures (limited to raid10 as of tests) and needs to be reversed to allow
e.g. old lvm2 uspace to run properly.
Check for the aforementioned version range and adjust creation of the table line
to the respective (mis)ordered sequence inside and correct order outside the range
(as described for the raid target in the kernels Documentation/device-mapper/dm-raid.txt).
---
lib/metadata/segtype.h | 1 +
lib/raid/raid.c | 23 ++++++++++-
libdm/libdevmapper.h | 10 +++++
libdm/libdm-deptree.c | 102 +++++++++++++++++++++++++++++++++---------------
4 files changed, 103 insertions(+), 33 deletions(-)
diff --git a/lib/metadata/segtype.h b/lib/metadata/segtype.h
index 2364db8..a6093e8 100644
--- a/lib/metadata/segtype.h
+++ b/lib/metadata/segtype.h
@@ -288,6 +288,7 @@ struct segment_type *init_unknown_segtype(struct cmd_context *cmd,
#define RAID_FEATURE_RAID4 (1U << 3) /* ! version 1.8 or 1.9.0 */
#define RAID_FEATURE_SHRINK (1U << 4) /* version 1.9.0 */
#define RAID_FEATURE_RESHAPE (1U << 5) /* version 1.10.1 */
+#define RAID_FEATURE_PROPER_TABLE_ORDER (1U << 6) /* version >= 1.9.0 and < 1.11.0 had wrong parameter order */
#ifdef RAID_INTERNAL
int init_raid_segtypes(struct cmd_context *cmd, struct segtype_library *seglib);
diff --git a/lib/raid/raid.c b/lib/raid/raid.c
index df9796d..7e9f0d3 100644
--- a/lib/raid/raid.c
+++ b/lib/raid/raid.c
@@ -228,6 +228,9 @@ static int _raid_text_export(const struct lv_segment *seg, struct formatter *f)
return _raid_text_export_raid(seg, f);
}
+static int _raid_target_present(struct cmd_context *cmd,
+ const struct lv_segment *seg __attribute__((unused)),
+ unsigned *attributes);
static int _raid_add_target_line(struct dev_manager *dm __attribute__((unused)),
struct dm_pool *mem __attribute__((unused)),
struct cmd_context *cmd __attribute__((unused)),
@@ -238,6 +241,7 @@ static int _raid_add_target_line(struct dev_manager *dm __attribute__((unused)),
uint32_t *pvmove_mirror_count __attribute__((unused)))
{
int delta_disks = 0, delta_disks_minus = 0, delta_disks_plus = 0, data_offset = 0;
+ unsigned attrs;
uint32_t s;
uint64_t flags = 0;
uint64_t rebuilds[RAID_BITMAP_SIZE];
@@ -300,6 +304,13 @@ static int _raid_add_target_line(struct dev_manager *dm __attribute__((unused)),
flags = DM_NOSYNC;
}
+ if (!_raid_target_present(seg->lv->vg->cmd, seg, &attrs))
+ return_0;
+
+ /* RAID target line parameters are in kernel documented order */
+ if (attrs & RAID_FEATURE_PROPER_TABLE_ORDER)
+ flags |= DM_RAID_TABLE_ORDERED;
+
params.raid_type = lvseg_name(seg);
if (seg->segtype->parity_devs) {
@@ -479,7 +490,7 @@ static int _raid_target_present(struct cmd_context *cmd,
static int _raid_checked = 0;
static int _raid_present = 0;
- static unsigned _raid_attrs = 0;
+ static unsigned _raid_attrs;
uint32_t maj, min, patchlevel;
unsigned i;
@@ -488,6 +499,7 @@ static int _raid_target_present(struct cmd_context *cmd,
if (!_raid_checked) {
_raid_checked = 1;
+ _raid_attrs = RAID_FEATURE_PROPER_TABLE_ORDER;
if (!(_raid_present = target_present(cmd, TARGET_NAME_RAID, 1)))
return 0;
@@ -514,6 +526,15 @@ static int _raid_target_present(struct cmd_context *cmd,
else
log_very_verbose("Target raid does not support %s.",
SEG_TYPE_NAME_RAID4);
+
+ /*
+ * Target version range check:
+ *
+ * raid target line parameters were misordered (e.g. 'raid10_copies')
+ * in target version >= 1.9.0 and < 1.11.0
+ */
+ if (maj == 1 && min >= 9 && min < 11)
+ _raid_attrs &= ~RAID_FEATURE_PROPER_TABLE_ORDER;
}
if (attributes)
diff --git a/libdm/libdevmapper.h b/libdm/libdevmapper.h
index 4bd32b4..ff84785 100644
--- a/libdm/libdevmapper.h
+++ b/libdm/libdevmapper.h
@@ -1775,6 +1775,16 @@ int dm_tree_node_add_mirror_target(struct dm_tree_node *node,
#define DM_BLOCK_ON_ERROR 0x00000004 /* On error, suspend I/O */
#define DM_CORELOG 0x00000008 /* In-memory log */
+/*
+ * RAID flag: table line is in kernel documented order.
+ *
+ * Target version >= 1.9.0 and < 1.11.0 misordered e.g. 'raid10_copies'
+ *
+ * Keep distinct from mirror log ones above because it
+ * can be passed together with those in load segment flags!
+ */
+#define DM_RAID_TABLE_ORDERED 0x00000010
+
int dm_tree_node_add_mirror_target_log(struct dm_tree_node *node,
uint32_t region_size,
unsigned clustered,
diff --git a/libdm/libdm-deptree.c b/libdm/libdm-deptree.c
index 832d8de..2dced75 100644
--- a/libdm/libdm-deptree.c
+++ b/libdm/libdm-deptree.c
@@ -2432,46 +2432,84 @@ static int _raid_emit_segment_line(struct dm_task *dmt, uint32_t major,
EMIT_PARAMS(pos, " raid10_format offset");
#endif
- if (seg->data_copies > 1 && type == SEG_RAID10)
- EMIT_PARAMS(pos, " raid10_copies %u", seg->data_copies);
+ if (seg->flags & DM_RAID_TABLE_ORDERED) {
+ /* Emit order of paramters as of kernel target documentation */
+ if (seg->flags & DM_NOSYNC)
+ EMIT_PARAMS(pos, " nosync");
+ else if (seg->flags & DM_FORCESYNC)
+ EMIT_PARAMS(pos, " sync");
- if (seg->flags & DM_NOSYNC)
- EMIT_PARAMS(pos, " nosync");
- else if (seg->flags & DM_FORCESYNC)
- EMIT_PARAMS(pos, " sync");
+ for (i = 0; i < area_count; i++)
+ if (seg->rebuilds[i/64] & (1ULL << (i%64)))
+ EMIT_PARAMS(pos, " rebuild %u", i);
- if (seg->region_size)
- EMIT_PARAMS(pos, " region_size %u", seg->region_size);
+ if (seg->min_recovery_rate)
+ EMIT_PARAMS(pos, " min_recovery_rate %u",
+ seg->min_recovery_rate);
- /* If seg-data_offset == 1, kernel needs a zero offset to adjust to it */
- if (seg->data_offset)
- EMIT_PARAMS(pos, " data_offset %d", seg->data_offset == 1 ? 0 : seg->data_offset);
+ if (seg->max_recovery_rate)
+ EMIT_PARAMS(pos, " max_recovery_rate %u",
+ seg->max_recovery_rate);
- if (seg->delta_disks)
- EMIT_PARAMS(pos, " delta_disks %d", seg->delta_disks);
+ for (i = 0; i < area_count; i++)
+ if (seg->writemostly[i/64] & (1ULL << (i%64)))
+ EMIT_PARAMS(pos, " write_mostly %u", i);
- for (i = 0; i < area_count; i++)
- if (seg->rebuilds[i/64] & (1ULL << (i%64)))
- EMIT_PARAMS(pos, " rebuild %u", i);
+ if (seg->writebehind)
+ EMIT_PARAMS(pos, " max_write_behind %u", seg->writebehind);
- for (i = 0; i < area_count; i++)
- if (seg->writemostly[i/64] & (1ULL << (i%64)))
- EMIT_PARAMS(pos, " write_mostly %u", i);
+ if (seg->region_size)
+ EMIT_PARAMS(pos, " region_size %u", seg->region_size);
- if (seg->writebehind)
- EMIT_PARAMS(pos, " max_write_behind %u", seg->writebehind);
+ if (seg->data_copies > 1 && type == SEG_RAID10)
+ EMIT_PARAMS(pos, " raid10_copies %u", seg->data_copies);
- /*
- * Has to be before "min_recovery_rate" or the kernels
- * check will fail when both set and min > previous max
- */
- if (seg->max_recovery_rate)
- EMIT_PARAMS(pos, " max_recovery_rate %u",
- seg->max_recovery_rate);
+ if (seg->delta_disks)
+ EMIT_PARAMS(pos, " delta_disks %d", seg->delta_disks);
+
+ /* If seg-data_offset == 1, kernel needs a zero offset to adjust to it */
+ if (seg->data_offset)
+ EMIT_PARAMS(pos, " data_offset %d", seg->data_offset == 1 ? 0 : seg->data_offset);
+
+ } else {
+ /* Target version >= 1.9.0 && < 1.11.0 had a table line parameter ordering flaw */
+ if (seg->data_copies > 1 && type == SEG_RAID10)
+ EMIT_PARAMS(pos, " raid10_copies %u", seg->data_copies);
+
+ if (seg->flags & DM_NOSYNC)
+ EMIT_PARAMS(pos, " nosync");
+ else if (seg->flags & DM_FORCESYNC)
+ EMIT_PARAMS(pos, " sync");
- if (seg->min_recovery_rate)
- EMIT_PARAMS(pos, " min_recovery_rate %u",
- seg->min_recovery_rate);
+ if (seg->region_size)
+ EMIT_PARAMS(pos, " region_size %u", seg->region_size);
+
+ /* If seg-data_offset == 1, kernel needs a zero offset to adjust to it */
+ if (seg->data_offset)
+ EMIT_PARAMS(pos, " data_offset %d", seg->data_offset == 1 ? 0 : seg->data_offset);
+
+ if (seg->delta_disks)
+ EMIT_PARAMS(pos, " delta_disks %d", seg->delta_disks);
+
+ for (i = 0; i < area_count; i++)
+ if (seg->rebuilds[i/64] & (1ULL << (i%64)))
+ EMIT_PARAMS(pos, " rebuild %u", i);
+
+ for (i = 0; i < area_count; i++)
+ if (seg->writemostly[i/64] & (1ULL << (i%64)))
+ EMIT_PARAMS(pos, " write_mostly %u", i);
+
+ if (seg->writebehind)
+ EMIT_PARAMS(pos, " max_write_behind %u", seg->writebehind);
+
+ if (seg->max_recovery_rate)
+ EMIT_PARAMS(pos, " max_recovery_rate %u",
+ seg->max_recovery_rate);
+
+ if (seg->min_recovery_rate)
+ EMIT_PARAMS(pos, " min_recovery_rate %u",
+ seg->min_recovery_rate);
+ }
/* Print number of metadata/data device pairs */
EMIT_PARAMS(pos, " %u", area_count);
@@ -2742,7 +2780,7 @@ static int _emit_segment(struct dm_task *dmt, uint32_t major, uint32_t minor,
struct load_segment *seg, uint64_t *seg_start)
{
char *params;
- size_t paramsize = 4096;
+ size_t paramsize = 4096; /* FIXME: too small for long RAID lines when > 64 devices supported */
int ret;
do {
7 years, 2 months
master - lvcreate: continue to accept --thinpool with -L and -V but not -T
by Alasdair Kergon
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=642d682d8ddcc3152f6...
Commit: 642d682d8ddcc3152f68b3ec8518902a0ef448ac
Parent: b3e833c777f46c0c3b3ef70c94cd0fb808be0a50
Author: Alasdair G Kergon <agk(a)redhat.com>
AuthorDate: Mon Mar 20 21:57:17 2017 +0000
Committer: Alasdair G Kergon <agk(a)redhat.com>
CommitterDate: Mon Mar 20 22:04:37 2017 +0000
lvcreate: continue to accept --thinpool with -L and -V but not -T
lvcreate --thinpool POOL1 -L 100M --virtualsize 100M snapper_thinp
https://bugzilla.redhat.com/1434027
(The general rule is that a command is accepted if it is unambiguous.
The combination -L -V --thinpool uniquely identifies the operation.)
---
tools/command-lines.in | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/tools/command-lines.in b/tools/command-lines.in
index 2fec553..a4d1f38 100644
--- a/tools/command-lines.in
+++ b/tools/command-lines.in
@@ -1056,7 +1056,7 @@ FLAGS: SECONDARY_SYNTAX
---
lvcreate --size SizeMB --virtualsize SizeMB VG
-OO: --type thin, --type snapshot, --thin, --snapshot, OO_LVCREATE_POOL, OO_LVCREATE_THIN, OO_LVCREATE,
+OO: --type thin, --type snapshot, --thin, --snapshot, --thinpool LV_new, OO_LVCREATE_POOL, OO_LVCREATE_THIN, OO_LVCREATE,
--stripes Number, --stripesize SizeKB
OP: PV ...
IO: --mirrors 0
7 years, 2 months
master - man-generator: Remove unused variable.
by Alasdair Kergon
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=b3e833c777f46c0c3b3...
Commit: b3e833c777f46c0c3b3ef70c94cd0fb808be0a50
Parent: 862ca6e8b7754b249e989dba934c32170d8074b9
Author: Alasdair G Kergon <agk(a)redhat.com>
AuthorDate: Mon Mar 20 16:55:30 2017 +0000
Committer: Alasdair G Kergon <agk(a)redhat.com>
CommitterDate: Mon Mar 20 16:55:30 2017 +0000
man-generator: Remove unused variable.
man-generator.c:2976:6: warning: variable "sep" set but not used
---
tools/command.c | 3 ---
1 files changed, 0 insertions(+), 3 deletions(-)
diff --git a/tools/command.c b/tools/command.c
index a344e55..5c0e151 100644
--- a/tools/command.c
+++ b/tools/command.c
@@ -2973,7 +2973,6 @@ static void _print_man_all_options_list(struct command_name *cname)
static void _print_man_all_options_desc(struct command_name *cname)
{
int opt_enum, val_enum;
- int sep = 0;
int i;
for (i = 0; i < ARG_COUNT; i++) {
@@ -3018,8 +3017,6 @@ static void _print_man_all_options_desc(struct command_name *cname)
}
printf(".ad b\n");
-
- sep = 1;
}
}
7 years, 2 months
master - lvmdbusd: Rename ee to got_external_event
by Tony Asleson
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=862ca6e8b7754b249e9...
Commit: 862ca6e8b7754b249e989dba934c32170d8074b9
Parent: b65a9230a359de82cb4b5b2e802a493b72d46c4f
Author: Tony Asleson <tasleson(a)redhat.com>
AuthorDate: Mon Mar 20 09:43:34 2017 -0500
Committer: Tony Asleson <tasleson(a)redhat.com>
CommitterDate: Mon Mar 20 10:08:39 2017 -0500
lvmdbusd: Rename ee to got_external_event
This variable is global, make it more descriptive.
---
daemons/lvmdbusd/cfg.py | 2 +-
daemons/lvmdbusd/manager.py | 2 +-
daemons/lvmdbusd/utils.py | 2 +-
3 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/daemons/lvmdbusd/cfg.py b/daemons/lvmdbusd/cfg.py
index f3eadf1..771909f 100644
--- a/daemons/lvmdbusd/cfg.py
+++ b/daemons/lvmdbusd/cfg.py
@@ -26,7 +26,7 @@ bus = None
args = None
# Set to true if we are depending on external events for updates
-ee = False
+got_external_event = False
# Shared state variable across all processes
run = multiprocessing.Value('i', 1)
diff --git a/daemons/lvmdbusd/manager.py b/daemons/lvmdbusd/manager.py
index 433473f..5bcdbb8 100644
--- a/daemons/lvmdbusd/manager.py
+++ b/daemons/lvmdbusd/manager.py
@@ -206,7 +206,7 @@ class Manager(AutomatedProperties):
utils.log_debug("ExternalEvent received, disabling "
"udev monitoring")
# We are dependent on external events now to stay current!
- cfg.ee = True
+ cfg.got_external_event = True
r = RequestEntry(
-1, Manager._external_event, (command,), None, None, False)
diff --git a/daemons/lvmdbusd/utils.py b/daemons/lvmdbusd/utils.py
index c9a84cc..af9e10a 100644
--- a/daemons/lvmdbusd/utils.py
+++ b/daemons/lvmdbusd/utils.py
@@ -512,7 +512,7 @@ def add_no_notify(cmdline):
# Only after we have seen an external event will be disable lvm from sending
# us one when we call lvm
- if cfg.ee:
+ if cfg.got_external_event:
if 'help' in cmdline:
return cmdline
7 years, 2 months
master - lvmdbusd: Update state during pv move
by Tony Asleson
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=b65a9230a359de82cb4...
Commit: b65a9230a359de82cb4b5b2e802a493b72d46c4f
Parent: 3ead4fb7ac3006a4c4377a88da22c22e6d426035
Author: Tony Asleson <tasleson(a)redhat.com>
AuthorDate: Wed Mar 15 14:19:55 2017 -0500
Committer: Tony Asleson <tasleson(a)redhat.com>
CommitterDate: Mon Mar 20 10:08:39 2017 -0500
lvmdbusd: Update state during pv move
Periodically update the state during pv move so that all the different
dbus objects reflect something close to reality during the process.
---
daemons/lvmdbusd/background.py | 4 ++++
1 files changed, 4 insertions(+), 0 deletions(-)
diff --git a/daemons/lvmdbusd/background.py b/daemons/lvmdbusd/background.py
index e870c05..f7f77d5 100644
--- a/daemons/lvmdbusd/background.py
+++ b/daemons/lvmdbusd/background.py
@@ -64,6 +64,10 @@ def _move_merge(interface_name, command, job_state):
(device, ignore, percentage) = line_str.split(':')
job_state.Percent = round(
float(percentage.strip()[:-1]), 1)
+
+ # While the move is in progress we need to periodically update
+ # the state to reflect where everything is at.
+ cfg.load()
except ValueError:
log_error("Trying to parse percentage which failed for %s" %
line_str)
7 years, 2 months
master - lvmdbusd: Limit state refreshes for udev events
by Tony Asleson
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=3ead4fb7ac3006a4c43...
Commit: 3ead4fb7ac3006a4c4377a88da22c22e6d426035
Parent: 7eeb093fdd314063eff7f14b8b6338523e0dd840
Author: Tony Asleson <tasleson(a)redhat.com>
AuthorDate: Wed Mar 15 13:08:19 2017 -0500
Committer: Tony Asleson <tasleson(a)redhat.com>
CommitterDate: Mon Mar 20 10:08:39 2017 -0500
lvmdbusd: Limit state refreshes for udev events
Udev events can come in like a flood when something changes. It really
doesn't do us any good to refresh the state of the service numerous times
when 1 would suffice. We had something like this before, but it was
removed when we added the refresh thread. However, we have since learned
that we need to sequence events in the correct order and block dbus
operations if we believe the state has been affected, thus udev events are
being processed on the main work queue. This change limits spurious
work items from getting to the queue.
---
daemons/lvmdbusd/udevwatch.py | 29 +++++++++++++++++++++++++----
1 files changed, 25 insertions(+), 4 deletions(-)
diff --git a/daemons/lvmdbusd/udevwatch.py b/daemons/lvmdbusd/udevwatch.py
index eaf31df..b53b180 100644
--- a/daemons/lvmdbusd/udevwatch.py
+++ b/daemons/lvmdbusd/udevwatch.py
@@ -16,9 +16,33 @@ from . import utils
observer = None
observer_lock = threading.RLock()
+_udev_lock = threading.RLock()
+_udev_count = 0
+
+
+def udev_add():
+ global _udev_count
+ with _udev_lock:
+ if _udev_count == 0:
+ _udev_count += 1
+
+ # Place this on the queue so any other operations will sequence
+ # behind it
+ r = RequestEntry(
+ -1, _udev_event, (), None, None, False)
+ cfg.worker_q.put(r)
+
+
+def udev_complete():
+ global _udev_count
+ with _udev_lock:
+ if _udev_count > 0:
+ _udev_count -= 1
+
def _udev_event():
utils.log_debug("Processing udev event")
+ udev_complete()
cfg.load()
@@ -44,10 +68,7 @@ def filter_event(action, device):
refresh = True
if refresh:
- # Place this on the queue so any other operations will sequence behind it
- r = RequestEntry(
- -1, _udev_event, (), None, None, False)
- cfg.worker_q.put(r)
+ udev_add()
def add():
7 years, 2 months
master - lvmdbusd: Call add_no_notify for *move commands
by Tony Asleson
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=7eeb093fdd314063eff...
Commit: 7eeb093fdd314063eff7f14b8b6338523e0dd840
Parent: 2dc71fc291b3ac861298b4dd7b25963dd9325a4d
Author: Tony Asleson <tasleson(a)redhat.com>
AuthorDate: Wed Mar 15 10:58:41 2017 -0500
Committer: Tony Asleson <tasleson(a)redhat.com>
CommitterDate: Mon Mar 20 10:08:38 2017 -0500
lvmdbusd: Call add_no_notify for *move commands
Missed this in change when "add_no_notify" was added. This was causing
extra external events to process when we did moves.
---
daemons/lvmdbusd/background.py | 7 ++++++-
1 files changed, 6 insertions(+), 1 deletions(-)
diff --git a/daemons/lvmdbusd/background.py b/daemons/lvmdbusd/background.py
index 19a2e6c..e870c05 100644
--- a/daemons/lvmdbusd/background.py
+++ b/daemons/lvmdbusd/background.py
@@ -11,7 +11,8 @@ import subprocess
from . import cfg
from .cmdhandler import options_to_cli_args
import dbus
-from .utils import pv_range_append, pv_dest_ranges, log_error, log_debug
+from .utils import pv_range_append, pv_dest_ranges, log_error, log_debug,\
+ add_no_notify
import os
import threading
@@ -42,6 +43,10 @@ def _move_merge(interface_name, command, job_state):
# the command always as we will be getting periodic output from them on
# the status of the long running operation.
command.insert(0, cfg.LVM_CMD)
+
+ # Instruct lvm to not register an event with us
+ command = add_no_notify(command)
+
process = subprocess.Popen(command, stdout=subprocess.PIPE,
env=os.environ,
stderr=subprocess.PIPE, close_fds=True)
7 years, 2 months