You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
303 lines
9.3 KiB
303 lines
9.3 KiB
WHATS_NEW | 1 + |
|
lib/activate/activate.c | 25 +++++++++++++++++++++++++ |
|
lib/activate/activate.h | 3 ++- |
|
lib/metadata/lv.c | 16 +++++++++++++++- |
|
lib/metadata/segtype.h | 3 ++- |
|
lib/raid/raid.c | 10 ++++++++-- |
|
test/shell/lvconvert-raid-takeover.sh | 13 +++++++++++++ |
|
tools/lvconvert.c | 26 ++++++++++++++++++++++++++ |
|
tools/lvcreate.c | 6 ++++++ |
|
9 files changed, 98 insertions(+), 5 deletions(-) |
|
|
|
diff --git a/WHATS_NEW b/WHATS_NEW |
|
index 6a0c311..519bbc9 100644 |
|
--- a/WHATS_NEW |
|
+++ b/WHATS_NEW |
|
@@ -1,5 +1,6 @@ |
|
Version 2.02.167 - |
|
====================================== |
|
+ Prevent raid4 creation/conversion on non-supporting kernels |
|
Add direct striped -> raid4 conversion |
|
Fix raid4 parity image pair position on conversions from striped/raid0* |
|
Disable lvconvert of thin pool to raid while active. |
|
diff --git a/lib/activate/activate.c b/lib/activate/activate.c |
|
index 5550955..571f2b2 100644 |
|
--- a/lib/activate/activate.c |
|
+++ b/lib/activate/activate.c |
|
@@ -370,6 +370,11 @@ void activation_exit(void) |
|
{ |
|
} |
|
|
|
+int raid4_is_supported(struct cmd_context *cmd, const struct segment_type *segtype) |
|
+{ |
|
+ return 1; |
|
+} |
|
+ |
|
int lv_is_active(const struct logical_volume *lv) |
|
{ |
|
return 0; |
|
@@ -1489,6 +1494,26 @@ out: |
|
return r || l; |
|
} |
|
|
|
+/* |
|
+ * Check if "raid4" @segtype is supported by kernel. |
|
+ * |
|
+ * if segment type is not raid4, return 1. |
|
+ */ |
|
+int raid4_is_supported(struct cmd_context *cmd, const struct segment_type *segtype) |
|
+{ |
|
+ unsigned attrs; |
|
+ |
|
+ if (segtype_is_raid4(segtype) && |
|
+ (!segtype->ops->target_present || |
|
+ !segtype->ops->target_present(cmd, NULL, &attrs) || |
|
+ !(attrs & RAID_FEATURE_RAID4))) { |
|
+ log_error("RAID module does not support RAID4."); |
|
+ return 0; |
|
+ } |
|
+ |
|
+ return 1; |
|
+} |
|
+ |
|
int lv_is_active(const struct logical_volume *lv) |
|
{ |
|
return _lv_is_active(lv, NULL, NULL, NULL); |
|
diff --git a/lib/activate/activate.h b/lib/activate/activate.h |
|
index 1e8d7a8..3922d78 100644 |
|
--- a/lib/activate/activate.h |
|
+++ b/lib/activate/activate.h |
|
@@ -1,6 +1,6 @@ |
|
/* |
|
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved. |
|
- * Copyright (C) 2004-2012 Red Hat, Inc. All rights reserved. |
|
+ * Copyright (C) 2004-2016 Red Hat, Inc. All rights reserved. |
|
* |
|
* This file is part of LVM2. |
|
* |
|
@@ -99,6 +99,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 raid4_is_supported(struct cmd_context *cmd, const struct segment_type *segtype); |
|
int lvm_dm_prefix_check(int major, int minor, const char *prefix); |
|
int list_segment_modules(struct dm_pool *mem, const struct lv_segment *seg, |
|
struct dm_list *modules); |
|
diff --git a/lib/metadata/lv.c b/lib/metadata/lv.c |
|
index 53a1044..0f1b6e7 100644 |
|
--- a/lib/metadata/lv.c |
|
+++ b/lib/metadata/lv.c |
|
@@ -1,6 +1,6 @@ |
|
/* |
|
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved. |
|
- * Copyright (C) 2004-2013 Red Hat, Inc. All rights reserved. |
|
+ * Copyright (C) 2004-2016 Red Hat, Inc. All rights reserved. |
|
* |
|
* This file is part of LVM2. |
|
* |
|
@@ -1425,6 +1425,7 @@ int lv_active_change(struct cmd_context *cmd, struct logical_volume *lv, |
|
enum activation_change activate, int needs_exclusive) |
|
{ |
|
const char *ay_with_mode = NULL; |
|
+ struct lv_segment *seg = first_seg(lv); |
|
|
|
if (activate == CHANGE_ASY) |
|
ay_with_mode = "sh"; |
|
@@ -1461,6 +1462,9 @@ deactivate: |
|
break; |
|
case CHANGE_ALY: |
|
case CHANGE_AAY: |
|
+ if (!raid4_is_supported(cmd, seg->segtype)) |
|
+ goto no_raid4; |
|
+ |
|
if (needs_exclusive || _lv_is_exclusive(lv)) { |
|
log_verbose("Activating logical volume %s exclusively locally.", |
|
display_lvname(lv)); |
|
@@ -1475,6 +1479,9 @@ deactivate: |
|
break; |
|
case CHANGE_AEY: |
|
exclusive: |
|
+ if (!raid4_is_supported(cmd, seg->segtype)) |
|
+ goto no_raid4; |
|
+ |
|
log_verbose("Activating logical volume %s exclusively.", |
|
display_lvname(lv)); |
|
if (!activate_lv_excl(cmd, lv)) |
|
@@ -1483,6 +1490,9 @@ exclusive: |
|
case CHANGE_ASY: |
|
case CHANGE_AY: |
|
default: |
|
+ if (!raid4_is_supported(cmd, seg->segtype)) |
|
+ goto no_raid4; |
|
+ |
|
if (needs_exclusive || _lv_is_exclusive(lv)) |
|
goto exclusive; |
|
log_verbose("Activating logical volume %s.", display_lvname(lv)); |
|
@@ -1495,6 +1505,10 @@ exclusive: |
|
log_error("Failed to unlock logical volume %s.", display_lvname(lv)); |
|
|
|
return 1; |
|
+ |
|
+no_raid4: |
|
+ log_error("Failed to activate %s LV %s", lvseg_name(seg), display_lvname(lv)); |
|
+ return 0; |
|
} |
|
|
|
char *lv_active_dup(struct dm_pool *mem, const struct logical_volume *lv) |
|
diff --git a/lib/metadata/segtype.h b/lib/metadata/segtype.h |
|
index 9ca740d..292b8b6 100644 |
|
--- a/lib/metadata/segtype.h |
|
+++ b/lib/metadata/segtype.h |
|
@@ -1,6 +1,6 @@ |
|
/* |
|
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved. |
|
- * Copyright (C) 2004-2015 Red Hat, Inc. All rights reserved. |
|
+ * Copyright (C) 2004-2016 Red Hat, Inc. All rights reserved. |
|
* |
|
* This file is part of LVM2. |
|
* |
|
@@ -268,6 +268,7 @@ struct segment_type *init_unknown_segtype(struct cmd_context *cmd, |
|
#define RAID_FEATURE_RAID10 (1U << 0) /* version 1.3 */ |
|
#define RAID_FEATURE_RAID0 (1U << 1) /* version 1.7 */ |
|
#define RAID_FEATURE_RESHAPING (1U << 2) /* version 1.8 */ |
|
+#define RAID_FEATURE_RAID4 (1U << 3) /* ! version 1.8 or 1.9.0 */ |
|
|
|
#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 3bc3c75..92a96a3 100644 |
|
--- a/lib/raid/raid.c |
|
+++ b/lib/raid/raid.c |
|
@@ -1,5 +1,5 @@ |
|
/* |
|
- * Copyright (C) 2011-2013 Red Hat, Inc. All rights reserved. |
|
+ * Copyright (C) 2011-2016 Red Hat, Inc. All rights reserved. |
|
* |
|
* This file is part of LVM2. |
|
* |
|
@@ -366,7 +366,7 @@ static int _raid_target_present(struct cmd_context *cmd, |
|
|
|
static int _raid_checked = 0; |
|
static int _raid_present = 0; |
|
- static int _raid_attrs = 0; |
|
+ static unsigned _raid_attrs = 0; |
|
uint32_t maj, min, patchlevel; |
|
unsigned i; |
|
|
|
@@ -389,6 +389,12 @@ static int _raid_target_present(struct cmd_context *cmd, |
|
else |
|
log_very_verbose("Target raid does not support %s.", |
|
_features[i].feature); |
|
+ |
|
+ if (!(maj == 1 && (min == 8 || (min == 9 && patchlevel == 0)))) |
|
+ _raid_attrs |= RAID_FEATURE_RAID4; |
|
+ else |
|
+ log_very_verbose("Target raid does not support %s.", |
|
+ SEG_TYPE_NAME_RAID4); |
|
} |
|
|
|
if (attributes) |
|
diff --git a/test/shell/lvconvert-raid-takeover.sh b/test/shell/lvconvert-raid-takeover.sh |
|
index 0140e22..332786d 100644 |
|
--- a/test/shell/lvconvert-raid-takeover.sh |
|
+++ b/test/shell/lvconvert-raid-takeover.sh |
|
@@ -16,6 +16,8 @@ SKIP_WITH_LVMPOLLD=1 |
|
|
|
aux have_raid 1 9 0 || skip |
|
|
|
+[ `aux have_raid 1.9.1` ] && correct_raid4_layout=1 |
|
+ |
|
aux prepare_vg 9 288 |
|
|
|
# Delay 1st leg so that rebuilding status characters |
|
@@ -99,6 +101,9 @@ check lv_field $vg/$lv3 stripes 3 |
|
echo y | mkfs -t ext4 /dev/mapper/$vg-$lv3 |
|
fsck -fn /dev/mapper/$vg-$lv3 |
|
|
|
+if [ $correct_raid4_layout -eq 1 ] |
|
+then |
|
+ |
|
# Create 3-way raid4 |
|
lvcreate -y -aey --type raid4 -i 3 -L 64M -n $lv4 $vg |
|
check lv_field $vg/$lv4 segtype "raid4" |
|
@@ -164,4 +169,12 @@ check lv_field $vg/$lv1 segtype "striped" |
|
check lv_field $vg/$lv1 stripes 3 |
|
fsck -fn /dev/mapper/$vg-$lv1 |
|
|
|
+else |
|
+ |
|
+not lvcreate -y -aey --type raid4 -i 3 -L 64M -n $lv4 $vg |
|
+not lvconvert -y --ty raid4 $vg/$lv1 |
|
+not lvconvert -y --ty raid4 $vg/$lv2 |
|
+ |
|
+fi |
|
+ |
|
vgremove -ff $vg |
|
diff --git a/tools/lvconvert.c b/tools/lvconvert.c |
|
index 541df72..7a4215a 100644 |
|
--- a/tools/lvconvert.c |
|
+++ b/tools/lvconvert.c |
|
@@ -1821,6 +1821,25 @@ static void _lvconvert_raid_repair_ask(struct cmd_context *cmd, |
|
} |
|
} |
|
|
|
+/* Check for dm-raid target supporting raid4 conversion properly. */ |
|
+static int _raid4_conversion_supported(struct logical_volume *lv, struct lvconvert_params *lp) |
|
+{ |
|
+ int ret = 1; |
|
+ struct lv_segment *seg = first_seg(lv); |
|
+ |
|
+ if (seg_is_raid4(seg)) |
|
+ ret = raid4_is_supported(lv->vg->cmd, seg->segtype); |
|
+ else if (segtype_is_raid4(lp->segtype)) |
|
+ ret = raid4_is_supported(lv->vg->cmd, lp->segtype); |
|
+ |
|
+ if (ret) |
|
+ return 1; |
|
+ |
|
+ log_error("Cannot convert %s LV %s to %s.", |
|
+ lvseg_name(seg), display_lvname(lv), lp->segtype->name); |
|
+ return 0; |
|
+} |
|
+ |
|
static int _lvconvert_raid(struct logical_volume *lv, struct lvconvert_params *lp) |
|
{ |
|
int replace = 0, image_count = 0; |
|
@@ -1945,6 +1964,9 @@ static int _lvconvert_raid(struct logical_volume *lv, struct lvconvert_params *l |
|
return 0; |
|
} |
|
|
|
+ if (!_raid4_conversion_supported(lv, lp)) |
|
+ return 0; |
|
+ |
|
if (!arg_is_set(cmd, stripes_long_ARG)) |
|
lp->stripes = 0; |
|
|
|
@@ -2018,6 +2040,10 @@ static int _lvconvert_raid(struct logical_volume *lv, struct lvconvert_params *l |
|
} |
|
|
|
try_new_takeover_or_reshape: |
|
+ |
|
+ if (!_raid4_conversion_supported(lv, lp)) |
|
+ return 0; |
|
+ |
|
/* FIXME This needs changing globally. */ |
|
if (!arg_is_set(cmd, stripes_long_ARG)) |
|
lp->stripes = 0; |
|
diff --git a/tools/lvcreate.c b/tools/lvcreate.c |
|
index 387c8d4..dbc0708 100644 |
|
--- a/tools/lvcreate.c |
|
+++ b/tools/lvcreate.c |
|
@@ -1054,6 +1054,12 @@ static int _lvcreate_params(struct cmd_context *cmd, |
|
return 0; |
|
} |
|
|
|
+ if (segtype_is_raid4(lp->segtype) && |
|
+ !(lp->target_attr & RAID_FEATURE_RAID4)) { |
|
+ log_error("RAID module does not support RAID4."); |
|
+ return 0; |
|
+ } |
|
+ |
|
if (segtype_is_raid10(lp->segtype) && !(lp->target_attr & RAID_FEATURE_RAID10)) { |
|
log_error("RAID module does not support RAID10."); |
|
return 0;
|
|
|