mirror of
git://sourceware.org/git/lvm2.git
synced 2025-03-11 20:58:50 +03:00
lvchange/vgchange/lvconvert: prevent raid4 creation/activation/conversion on non-supporting raid targets
Check for dm-raid target version with non-standard raid4 mapping expecting the dedicated parity device in the last rather than the first slot and prohibit to create, activate or convert to such LVs from striped/raid0* or vice-versa in order to avoid data corruption. Add related tests to lvconvert-raid-takeover.sh Resolves: rhbz1388962
This commit is contained in:
parent
e84f527cd3
commit
ff05ed7afd
@ -1,5 +1,6 @@
|
|||||||
Version 2.02.167 -
|
Version 2.02.167 -
|
||||||
======================================
|
======================================
|
||||||
|
Prevent raid4 creation/conversion on non-supporting kernels
|
||||||
Add direct striped -> raid4 conversion
|
Add direct striped -> raid4 conversion
|
||||||
Fix raid4 parity image pair position on conversions from striped/raid0*
|
Fix raid4 parity image pair position on conversions from striped/raid0*
|
||||||
Fix a few unconverted return code values for some lvconvert error path.
|
Fix a few unconverted return code values for some lvconvert error path.
|
||||||
|
@ -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)
|
int lv_is_active(const struct logical_volume *lv)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
@ -1489,6 +1494,26 @@ out:
|
|||||||
return r || l;
|
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)
|
int lv_is_active(const struct logical_volume *lv)
|
||||||
{
|
{
|
||||||
return _lv_is_active(lv, NULL, NULL, NULL);
|
return _lv_is_active(lv, NULL, NULL, NULL);
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
|
* 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.
|
* 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 use_modprobe);
|
||||||
int target_version(const char *target_name, uint32_t *maj,
|
int target_version(const char *target_name, uint32_t *maj,
|
||||||
uint32_t *min, uint32_t *patchlevel);
|
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 lvm_dm_prefix_check(int major, int minor, const char *prefix);
|
||||||
int list_segment_modules(struct dm_pool *mem, const struct lv_segment *seg,
|
int list_segment_modules(struct dm_pool *mem, const struct lv_segment *seg,
|
||||||
struct dm_list *modules);
|
struct dm_list *modules);
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
|
* 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.
|
* This file is part of LVM2.
|
||||||
*
|
*
|
||||||
@ -1418,6 +1418,7 @@ int lv_active_change(struct cmd_context *cmd, struct logical_volume *lv,
|
|||||||
enum activation_change activate, int needs_exclusive)
|
enum activation_change activate, int needs_exclusive)
|
||||||
{
|
{
|
||||||
const char *ay_with_mode = NULL;
|
const char *ay_with_mode = NULL;
|
||||||
|
struct lv_segment *seg = first_seg(lv);
|
||||||
|
|
||||||
if (activate == CHANGE_ASY)
|
if (activate == CHANGE_ASY)
|
||||||
ay_with_mode = "sh";
|
ay_with_mode = "sh";
|
||||||
@ -1454,6 +1455,9 @@ deactivate:
|
|||||||
break;
|
break;
|
||||||
case CHANGE_ALY:
|
case CHANGE_ALY:
|
||||||
case CHANGE_AAY:
|
case CHANGE_AAY:
|
||||||
|
if (!raid4_is_supported(cmd, seg->segtype))
|
||||||
|
goto no_raid4;
|
||||||
|
|
||||||
if (needs_exclusive || _lv_is_exclusive(lv)) {
|
if (needs_exclusive || _lv_is_exclusive(lv)) {
|
||||||
log_verbose("Activating logical volume %s exclusively locally.",
|
log_verbose("Activating logical volume %s exclusively locally.",
|
||||||
display_lvname(lv));
|
display_lvname(lv));
|
||||||
@ -1468,6 +1472,9 @@ deactivate:
|
|||||||
break;
|
break;
|
||||||
case CHANGE_AEY:
|
case CHANGE_AEY:
|
||||||
exclusive:
|
exclusive:
|
||||||
|
if (!raid4_is_supported(cmd, seg->segtype))
|
||||||
|
goto no_raid4;
|
||||||
|
|
||||||
log_verbose("Activating logical volume %s exclusively.",
|
log_verbose("Activating logical volume %s exclusively.",
|
||||||
display_lvname(lv));
|
display_lvname(lv));
|
||||||
if (!activate_lv_excl(cmd, lv))
|
if (!activate_lv_excl(cmd, lv))
|
||||||
@ -1476,6 +1483,9 @@ exclusive:
|
|||||||
case CHANGE_ASY:
|
case CHANGE_ASY:
|
||||||
case CHANGE_AY:
|
case CHANGE_AY:
|
||||||
default:
|
default:
|
||||||
|
if (!raid4_is_supported(cmd, seg->segtype))
|
||||||
|
goto no_raid4;
|
||||||
|
|
||||||
if (needs_exclusive || _lv_is_exclusive(lv))
|
if (needs_exclusive || _lv_is_exclusive(lv))
|
||||||
goto exclusive;
|
goto exclusive;
|
||||||
log_verbose("Activating logical volume %s.", display_lvname(lv));
|
log_verbose("Activating logical volume %s.", display_lvname(lv));
|
||||||
@ -1488,6 +1498,10 @@ exclusive:
|
|||||||
log_error("Failed to unlock logical volume %s.", display_lvname(lv));
|
log_error("Failed to unlock logical volume %s.", display_lvname(lv));
|
||||||
|
|
||||||
return 1;
|
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)
|
char *lv_active_dup(struct dm_pool *mem, const struct logical_volume *lv)
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
|
* 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.
|
* 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_RAID10 (1U << 0) /* version 1.3 */
|
||||||
#define RAID_FEATURE_RAID0 (1U << 1) /* version 1.7 */
|
#define RAID_FEATURE_RAID0 (1U << 1) /* version 1.7 */
|
||||||
#define RAID_FEATURE_RESHAPING (1U << 2) /* version 1.8 */
|
#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
|
#ifdef RAID_INTERNAL
|
||||||
int init_raid_segtypes(struct cmd_context *cmd, struct segtype_library *seglib);
|
int init_raid_segtypes(struct cmd_context *cmd, struct segtype_library *seglib);
|
||||||
|
@ -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.
|
* 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_checked = 0;
|
||||||
static int _raid_present = 0;
|
static int _raid_present = 0;
|
||||||
static int _raid_attrs = 0;
|
static unsigned _raid_attrs = 0;
|
||||||
uint32_t maj, min, patchlevel;
|
uint32_t maj, min, patchlevel;
|
||||||
unsigned i;
|
unsigned i;
|
||||||
|
|
||||||
@ -389,6 +389,12 @@ static int _raid_target_present(struct cmd_context *cmd,
|
|||||||
else
|
else
|
||||||
log_very_verbose("Target raid does not support %s.",
|
log_very_verbose("Target raid does not support %s.",
|
||||||
_features[i].feature);
|
_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)
|
if (attributes)
|
||||||
|
@ -16,6 +16,8 @@ SKIP_WITH_LVMPOLLD=1
|
|||||||
|
|
||||||
aux have_raid 1 9 0 || skip
|
aux have_raid 1 9 0 || skip
|
||||||
|
|
||||||
|
[ `aux have_raid 1.9.1` ] && correct_raid4_layout=1
|
||||||
|
|
||||||
aux prepare_vg 9 288
|
aux prepare_vg 9 288
|
||||||
|
|
||||||
# Delay 1st leg so that rebuilding status characters
|
# 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
|
echo y | mkfs -t ext4 /dev/mapper/$vg-$lv3
|
||||||
fsck -fn /dev/mapper/$vg-$lv3
|
fsck -fn /dev/mapper/$vg-$lv3
|
||||||
|
|
||||||
|
if [ $correct_raid4_layout -eq 1 ]
|
||||||
|
then
|
||||||
|
|
||||||
# Create 3-way raid4
|
# Create 3-way raid4
|
||||||
lvcreate -y -aey --type raid4 -i 3 -L 64M -n $lv4 $vg
|
lvcreate -y -aey --type raid4 -i 3 -L 64M -n $lv4 $vg
|
||||||
check lv_field $vg/$lv4 segtype "raid4"
|
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
|
check lv_field $vg/$lv1 stripes 3
|
||||||
fsck -fn /dev/mapper/$vg-$lv1
|
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
|
vgremove -ff $vg
|
||||||
|
@ -1828,6 +1828,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)
|
static int _lvconvert_raid(struct logical_volume *lv, struct lvconvert_params *lp)
|
||||||
{
|
{
|
||||||
int replace = 0, image_count = 0;
|
int replace = 0, image_count = 0;
|
||||||
@ -1951,6 +1970,9 @@ static int _lvconvert_raid(struct logical_volume *lv, struct lvconvert_params *l
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!_raid4_conversion_supported(lv, lp))
|
||||||
|
return 0;
|
||||||
|
|
||||||
if (!arg_is_set(cmd, stripes_long_ARG))
|
if (!arg_is_set(cmd, stripes_long_ARG))
|
||||||
lp->stripes = 0;
|
lp->stripes = 0;
|
||||||
|
|
||||||
@ -2008,6 +2030,9 @@ static int _lvconvert_raid(struct logical_volume *lv, struct lvconvert_params *l
|
|||||||
|
|
||||||
try_new_takeover_or_reshape:
|
try_new_takeover_or_reshape:
|
||||||
|
|
||||||
|
if (!_raid4_conversion_supported(lv, lp))
|
||||||
|
return 0;
|
||||||
|
|
||||||
/* FIXME This needs changing globally. */
|
/* FIXME This needs changing globally. */
|
||||||
if (!arg_is_set(cmd, stripes_long_ARG))
|
if (!arg_is_set(cmd, stripes_long_ARG))
|
||||||
lp->stripes = 0;
|
lp->stripes = 0;
|
||||||
|
@ -1054,6 +1054,12 @@ static int _lvcreate_params(struct cmd_context *cmd,
|
|||||||
return 0;
|
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)) {
|
if (segtype_is_raid10(lp->segtype) && !(lp->target_attr & RAID_FEATURE_RAID10)) {
|
||||||
log_error("RAID module does not support RAID10.");
|
log_error("RAID module does not support RAID10.");
|
||||||
return 0;
|
return 0;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user