mirror of
git://sourceware.org/git/lvm2.git
synced 2024-12-21 13:34:40 +03:00
lvconvert: add segtype raid5_n and conversions to/from it
Add: - support for segment type raid5_n (striped raid with dedicated last parity SubLVs) - conversion support from striped/raid0/raid0_meta/raid4 to/from raid5_n - related tests to lvconvert-raid-takeover.sh Related: rhbz1366296
This commit is contained in:
parent
875ce04c61
commit
60ddd05f16
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
|
||||
* Copyright (C) 2004-2016 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2004-2017 Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This file is part of LVM2.
|
||||
*
|
||||
@ -148,7 +148,8 @@ static void _check_raid1_seg(struct lv_segment *seg, int *error_count)
|
||||
static void _check_raid45610_seg(struct lv_segment *seg, int *error_count)
|
||||
{
|
||||
/* Checks applying to any raid4/5/6/10 */
|
||||
if (!seg->meta_areas)
|
||||
/* Allow raid4 + raid5_n to get activated w/o metadata (mandatory during conversion between them) */
|
||||
if (!(seg_is_raid4(seg) || seg_is_raid5_n(seg)) && !seg->meta_areas)
|
||||
raid_seg_error("no meta areas");
|
||||
if (!seg->stripe_size)
|
||||
raid_seg_error("zero stripe size");
|
||||
@ -610,7 +611,7 @@ int check_lv_segments(struct logical_volume *lv, int complete_vg)
|
||||
continue;
|
||||
if (lv == seg_lv(seg, s))
|
||||
seg_found++;
|
||||
if (seg_is_raid_with_meta(seg) && (lv == seg_metalv(seg, s)))
|
||||
if (seg->meta_areas && seg_is_raid_with_meta(seg) && (lv == seg_metalv(seg, s)))
|
||||
seg_found++;
|
||||
}
|
||||
if (seg_is_replicator_dev(seg)) {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2011-2014 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2011-2017 Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This file is part of LVM2.
|
||||
*
|
||||
@ -2175,6 +2175,7 @@ static int _convert_mirror_to_raid1(struct logical_volume *lv,
|
||||
lv->status &= ~MIRROR;
|
||||
lv->status &= ~MIRRORED;
|
||||
lv->status |= RAID;
|
||||
seg->status |= RAID;
|
||||
|
||||
if (!lv_update_and_reload(lv))
|
||||
return_0;
|
||||
@ -2567,44 +2568,22 @@ static struct possible_takeover_reshape_type _possible_takeover_reshape_types[]
|
||||
.possible_types = SEG_RAID0|SEG_RAID0_META,
|
||||
.current_areas = 1,
|
||||
.options = ALLOW_STRIPE_SIZE },
|
||||
{ .current_types = SEG_STRIPED_TARGET, /* striped -> raid0*, i.e. seg->area_count > 1 */
|
||||
.possible_types = SEG_RAID0|SEG_RAID0_META,
|
||||
.current_areas = ~0U,
|
||||
.options = ALLOW_NONE },
|
||||
{ .current_types = SEG_STRIPED_TARGET, /* striped -> raid4 , i.e. seg->area_count > 1 */
|
||||
.possible_types = SEG_RAID4,
|
||||
.current_areas = ~0U,
|
||||
.options = ALLOW_NONE }, /* FIXME: ALLOW_REGION_SIZE */
|
||||
|
||||
/* raid0* -> */
|
||||
{ .current_types = SEG_RAID0|SEG_RAID0_META, /* seg->area_count = 1 */
|
||||
.possible_types = SEG_RAID1,
|
||||
.current_areas = 1,
|
||||
.options = ALLOW_NONE }, /* FIXME: ALLOW_REGION_SIZE */
|
||||
{ .current_types = SEG_RAID0|SEG_RAID0_META, /* raid0* -> striped, i.e. seg->area_count > 1 */
|
||||
.possible_types = SEG_STRIPED_TARGET,
|
||||
.current_areas = ~0U,
|
||||
.options = ALLOW_NONE },
|
||||
{ .current_types = SEG_RAID0|SEG_RAID0_META, /* raid0* -> raid0*, i.e. seg->area_count > 1 */
|
||||
.possible_types = SEG_RAID0_META|SEG_RAID0,
|
||||
.current_areas = ~0U,
|
||||
.options = ALLOW_NONE },
|
||||
{ .current_types = SEG_RAID0|SEG_RAID0_META, /* raid0* -> raid4, i.e. seg->area_count > 1 */
|
||||
.possible_types = SEG_RAID4,
|
||||
|
||||
/* striped,raid0*,raid4,raid5_n <-> striped,raid0*,raid4,raid5_n */
|
||||
{ .current_types = SEG_STRIPED_TARGET|SEG_RAID0|SEG_RAID0_META|SEG_RAID4|SEG_RAID5_N,
|
||||
.possible_types = SEG_STRIPED_TARGET|SEG_RAID0|SEG_RAID0_META|SEG_RAID4|SEG_RAID5_N,
|
||||
.current_areas = ~0U,
|
||||
.options = ALLOW_NONE }, /* FIXME: ALLOW_REGION_SIZE */
|
||||
/* raid4 -> -> */
|
||||
{ .current_types = SEG_RAID4, /* raid4 ->striped/raid0*, i.e. seg->area_count > 1 */
|
||||
.possible_types = SEG_STRIPED_TARGET|SEG_RAID0|SEG_RAID0_META,
|
||||
.current_areas = ~0U,
|
||||
.options = ALLOW_NONE },
|
||||
/* raid1 -> mirror */
|
||||
{ .current_types = SEG_RAID1,
|
||||
.possible_types = SEG_MIRROR,
|
||||
.current_areas = ~0U,
|
||||
.options = ALLOW_NONE }, /* FIXME: ALLOW_REGION_SIZE */
|
||||
/* mirror -> raid1 with arbitrary number of legs */
|
||||
{ .current_types = SEG_MIRROR,
|
||||
.possible_types = SEG_RAID1,
|
||||
|
||||
/* mirror <-> raid1 with arbitrary number of legs */
|
||||
{ .current_types = SEG_MIRROR|SEG_RAID1,
|
||||
.possible_types = SEG_MIRROR|SEG_RAID1,
|
||||
.current_areas = ~0U,
|
||||
.options = ALLOW_NONE }, /* FIXME: ALLOW_REGION_SIZE */
|
||||
|
||||
@ -2724,6 +2703,15 @@ static const char *_get_segtype_alias(const struct segment_type *segtype)
|
||||
return "";
|
||||
}
|
||||
|
||||
/* Return "linear" for striped segtype with 1 area instead of "striped" */
|
||||
static const char *_get_segtype_name(const struct segment_type *segtype, unsigned new_image_count)
|
||||
{
|
||||
if (!segtype || (segtype_is_striped(segtype) && new_image_count == 1))
|
||||
return "linear";
|
||||
|
||||
return segtype->name;
|
||||
}
|
||||
|
||||
static int _log_possible_conversion_types(const struct logical_volume *lv, const struct segment_type *new_segtype)
|
||||
{
|
||||
unsigned possible_conversions = 0;
|
||||
@ -2744,7 +2732,7 @@ static int _log_possible_conversion_types(const struct logical_volume *lv, const
|
||||
|
||||
log_error("Converting %s from %s%s%s%s is "
|
||||
"directly possible to the following layout%s:",
|
||||
display_lvname(lv), lvseg_name(seg),
|
||||
display_lvname(lv), _get_segtype_name(seg->segtype, seg->area_count),
|
||||
*alias ? " (same as " : "", alias, *alias ? ")" : "",
|
||||
possible_conversions > 1 ? "s" : "");
|
||||
|
||||
@ -2911,6 +2899,8 @@ static int _raid1_to_mirrored_wrapper(TAKEOVER_FN_ARGS)
|
||||
* parity device to lv segment area 0 and thus changing MD
|
||||
* array roles, detach the MetaLVs and reload as raid0 in
|
||||
* order to wipe them then reattach and set back to raid0_meta.
|
||||
*
|
||||
* Same applies to raid4 <-> raid5.
|
||||
*/
|
||||
static int _clear_meta_lvs(struct logical_volume *lv)
|
||||
{
|
||||
@ -2920,16 +2910,18 @@ static int _clear_meta_lvs(struct logical_volume *lv)
|
||||
const struct segment_type *tmp_segtype;
|
||||
struct dm_list meta_lvs;
|
||||
struct lv_list *lvl_array, *lvl;
|
||||
int is_raid4_or_5N = seg_is_raid4(seg) || seg_is_raid5_n(seg);
|
||||
|
||||
/* Reject non-raid0_meta segment types cautiously */
|
||||
if (!seg_is_raid0_meta(seg) ||
|
||||
!seg->meta_areas)
|
||||
/* Reject non-raid0_meta/raid4/raid5_n segment types cautiously */
|
||||
if (!seg->meta_areas ||
|
||||
(!seg_is_raid0_meta(seg) && !is_raid4_or_5N))
|
||||
return_0;
|
||||
|
||||
if (!(lvl_array = dm_pool_alloc(lv->vg->vgmem, seg->area_count * sizeof(*lvl_array))))
|
||||
return_0;
|
||||
|
||||
dm_list_init(&meta_lvs);
|
||||
tmp_segtype = seg->segtype;
|
||||
tmp_areas = seg->meta_areas;
|
||||
|
||||
/* Extract all MetaLVs listing them on @meta_lvs */
|
||||
@ -2940,10 +2932,12 @@ static int _clear_meta_lvs(struct logical_volume *lv)
|
||||
|
||||
/* Memorize meta areas and segtype to set again after initializing. */
|
||||
seg->meta_areas = NULL;
|
||||
tmp_segtype = seg->segtype;
|
||||
|
||||
if (!(seg->segtype = get_segtype_from_flag(lv->vg->cmd, SEG_RAID0)) ||
|
||||
!lv_update_and_reload(lv))
|
||||
if (seg_is_raid0_meta(seg) &&
|
||||
!(seg->segtype = get_segtype_from_flag(lv->vg->cmd, SEG_RAID0)))
|
||||
return_0;
|
||||
|
||||
if (!lv_update_and_reload(lv))
|
||||
return_0;
|
||||
|
||||
/* Note: detached rmeta are NOT renamed */
|
||||
@ -3066,7 +3060,7 @@ static void _shift_area_lvs(struct lv_segment *seg, uint32_t s1, uint32_t s2)
|
||||
*/
|
||||
static int _shift_parity_dev(struct lv_segment *seg)
|
||||
{
|
||||
if (seg_is_raid0_meta(seg))
|
||||
if (seg_is_raid0_meta(seg) || seg_is_raid5_n(seg))
|
||||
_shift_area_lvs(seg, seg->area_count - 1, 0);
|
||||
else if (seg_is_raid4(seg))
|
||||
_shift_area_lvs(seg, 0, seg->area_count - 1);
|
||||
@ -3082,10 +3076,13 @@ static int _raid456_to_raid0_or_striped_wrapper(TAKEOVER_FN_ARGS)
|
||||
int rename_sublvs = 0;
|
||||
struct lv_segment *seg = first_seg(lv);
|
||||
struct dm_list removal_lvs;
|
||||
uint32_t region_size = seg->region_size;
|
||||
|
||||
dm_list_init(&removal_lvs);
|
||||
|
||||
if (!seg_is_raid4(seg) && !seg_is_raid5_n(seg) && !seg_is_raid6_n_6(seg)) {
|
||||
if (!seg_is_raid4(seg) &&
|
||||
!seg_is_raid5_n(seg) &&
|
||||
!seg_is_raid6_n_6(seg)) {
|
||||
log_error("LV %s has to be of type raid4/raid5_n/raid6_n_6 to allow for this conversion.",
|
||||
display_lvname(lv));
|
||||
return 0;
|
||||
@ -3098,7 +3095,7 @@ static int _raid456_to_raid0_or_striped_wrapper(TAKEOVER_FN_ARGS)
|
||||
if (!yes && yes_no_prompt("Are you sure you want to convert \"%s\" LV %s to \"%s\" "
|
||||
"type losing all resilience? [y/n]: ",
|
||||
lvseg_name(seg), display_lvname(lv), new_segtype->name) == 'n') {
|
||||
log_error("Logical volume %s NOT converted to \"%s\".",
|
||||
log_error("Logical volume %s NOT converted to \"%s\"",
|
||||
display_lvname(lv), new_segtype->name);
|
||||
return 0;
|
||||
}
|
||||
@ -3122,22 +3119,23 @@ static int _raid456_to_raid0_or_striped_wrapper(TAKEOVER_FN_ARGS)
|
||||
|
||||
if (segtype_is_any_raid0(new_segtype) &&
|
||||
!(rename_sublvs = _rename_area_lvs(lv, "_"))) {
|
||||
log_error("Failed to rename %s LV %s MetaLVs.",
|
||||
lvseg_name(seg), display_lvname(lv));
|
||||
log_error("Failed to rename %s LV %s MetaLVs.", lvseg_name(seg), display_lvname(lv));
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* Remove meta and data LVs requested */
|
||||
if (!_lv_raid_change_image_count(lv, new_image_count, allocate_pvs, &removal_lvs, 0, 0))
|
||||
return 0;
|
||||
|
||||
/* FIXME Hard-coded raid4/5/6 to striped/raid0 */
|
||||
if (segtype_is_striped_target(new_segtype) || segtype_is_any_raid0(new_segtype)) {
|
||||
seg->area_len = seg->extents_copied = seg->area_len / seg->area_count;
|
||||
if (!(seg->segtype = get_segtype_from_flag(lv->vg->cmd, SEG_RAID0_META)))
|
||||
return_0;
|
||||
|
||||
/* FIXME Hard-coded raid4 to raid0 */
|
||||
seg->area_len = seg->extents_copied = seg->area_len / seg->area_count;
|
||||
region_size = 0;
|
||||
}
|
||||
|
||||
if (segtype_is_striped_target(new_segtype)) {
|
||||
if (!_convert_raid0_to_striped(lv, 0, &removal_lvs))
|
||||
@ -3146,15 +3144,15 @@ static int _raid456_to_raid0_or_striped_wrapper(TAKEOVER_FN_ARGS)
|
||||
!_raid0_add_or_remove_metadata_lvs(lv, 0 /* update_and_reload */, allocate_pvs, &removal_lvs))
|
||||
return_0;
|
||||
|
||||
seg->region_size = 0;
|
||||
seg->region_size = region_size;
|
||||
seg->segtype = new_segtype;
|
||||
|
||||
if (!_lv_update_reload_fns_reset_eliminate_lvs(lv, &removal_lvs))
|
||||
return_0;
|
||||
|
||||
if (rename_sublvs) {
|
||||
if (!_rename_area_lvs(lv, NULL)) {
|
||||
log_error("Failed to rename %s LV %s MetaLVs.",
|
||||
lvseg_name(seg), display_lvname(lv));
|
||||
log_error("Failed to rename %s LV %s MetaLVs.", lvseg_name(seg), display_lvname(lv));
|
||||
return 0;
|
||||
}
|
||||
if (!lv_update_and_reload(lv))
|
||||
@ -3164,6 +3162,79 @@ static int _raid456_to_raid0_or_striped_wrapper(TAKEOVER_FN_ARGS)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* raid4 <-> raid5_n helper
|
||||
*
|
||||
* On conversions between raid4 and raid5_n, the parity SubLVs need
|
||||
* to be switched between beginning and end of the segment areas.
|
||||
*
|
||||
* The metadata devices reflect the previous positions within the RaidLV,
|
||||
* thus need to be cleared in order to allow the kernel to start the new
|
||||
* mapping and recreate metadata with the proper new position stored.
|
||||
*/
|
||||
static int _raid45_to_raid54_wrapper(TAKEOVER_FN_ARGS)
|
||||
{
|
||||
struct lv_segment *seg = first_seg(lv);
|
||||
struct dm_list removal_lvs;
|
||||
uint32_t region_size = seg->region_size;
|
||||
|
||||
dm_list_init(&removal_lvs);
|
||||
|
||||
if (!(seg_is_raid4(seg) && segtype_is_raid5_n(new_segtype)) &&
|
||||
!(seg_is_raid5_n(seg) && segtype_is_raid4(new_segtype))) {
|
||||
log_error("LV %s has to be of type raid4 or raid5_n to allow for this conversion.",
|
||||
display_lvname(lv));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Necessary when convering to raid0/striped w/o redundancy? */
|
||||
if (!_raid_in_sync(lv)) {
|
||||
log_error("Unable to convert %s while it is not in-sync.",
|
||||
display_lvname(lv));
|
||||
return 0;
|
||||
}
|
||||
|
||||
log_debug_metadata("Converting LV %s from %s to %s.", display_lvname(lv),
|
||||
(seg_is_raid4(seg) ? SEG_TYPE_NAME_RAID4 : SEG_TYPE_NAME_RAID5_N),
|
||||
(seg_is_raid4(seg) ? SEG_TYPE_NAME_RAID5_N : SEG_TYPE_NAME_RAID4));
|
||||
|
||||
/* Archive metadata */
|
||||
if (!archive(lv->vg))
|
||||
return_0;
|
||||
|
||||
if (!_rename_area_lvs(lv, "_")) {
|
||||
log_error("Failed to rename %s LV %s MetaLVs.", lvseg_name(seg), display_lvname(lv));
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!_clear_meta_lvs(lv))
|
||||
return_0;
|
||||
|
||||
/* Shift parity SubLV pair "PDD..." <-> "DD...P" on raid4 <-> raid5_n conversion */
|
||||
if( !_shift_parity_dev(seg))
|
||||
return 0;
|
||||
|
||||
/* Don't resync */
|
||||
init_mirror_in_sync(1);
|
||||
seg->region_size = new_region_size ?: region_size;
|
||||
seg->segtype = new_segtype;
|
||||
|
||||
if (!_lv_update_reload_fns_reset_eliminate_lvs(lv, &removal_lvs))
|
||||
return_0;
|
||||
|
||||
init_mirror_in_sync(0);
|
||||
|
||||
if (!_rename_area_lvs(lv, NULL)) {
|
||||
log_error("Failed to rename %s LV %s MetaLVs.", lvseg_name(seg), display_lvname(lv));
|
||||
return 0;
|
||||
}
|
||||
if (!lv_update_and_reload(lv))
|
||||
return_0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int _striped_to_raid0_wrapper(struct logical_volume *lv,
|
||||
const struct segment_type *new_segtype,
|
||||
uint32_t new_stripes,
|
||||
@ -3188,14 +3259,31 @@ static int _striped_to_raid0_wrapper(struct logical_volume *lv,
|
||||
/* Helper: striped/raid0* -> raid4/5/6/10 */
|
||||
static int _striped_or_raid0_to_raid45610_wrapper(TAKEOVER_FN_ARGS)
|
||||
{
|
||||
uint32_t extents_copied, region_size, seg_len, stripe_size;
|
||||
struct lv_segment *seg = first_seg(lv);
|
||||
struct dm_list removal_lvs;
|
||||
|
||||
dm_list_init(&removal_lvs);
|
||||
|
||||
if (!seg_is_striped_target(seg) &&
|
||||
!seg_is_any_raid0(seg) &&
|
||||
!seg_is_raid4(seg) &&
|
||||
!seg_is_any_raid5(seg)) {
|
||||
log_error("Can't convert %s LV %s.", lvseg_name(seg), display_lvname(lv));
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (seg_is_raid10(seg))
|
||||
return _takeover_unsupported_yet(lv, new_stripes, new_segtype);
|
||||
|
||||
if (!segtype_is_raid4(new_segtype) &&
|
||||
!segtype_is_raid5_n(new_segtype) &&
|
||||
!segtype_is_raid6_n_6(new_segtype)) {
|
||||
/* Can't convert to e.g. raid10_offset */
|
||||
log_error("Can't convert %s to %s.", display_lvname(lv), new_segtype->name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (new_data_copies > new_image_count) {
|
||||
log_error("N number of data_copies \"--mirrors N-1\" may not be larger than number of stripes.");
|
||||
return 0;
|
||||
@ -3206,8 +3294,9 @@ static int _striped_or_raid0_to_raid45610_wrapper(TAKEOVER_FN_ARGS)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* FIXME: restricted to raid4 for the time being... */
|
||||
if (!segtype_is_raid4(new_segtype)) {
|
||||
/* FIXME: restricted to raid4 and raid5_n for the time being... */
|
||||
if (!segtype_is_raid4(new_segtype) &&
|
||||
!segtype_is_raid5_n(new_segtype)) {
|
||||
/* Can't convert striped/raid0* to e.g. raid10_offset */
|
||||
log_error("Can't convert %s to %s.", display_lvname(lv), new_segtype->name);
|
||||
return 0;
|
||||
@ -3219,7 +3308,7 @@ static int _striped_or_raid0_to_raid45610_wrapper(TAKEOVER_FN_ARGS)
|
||||
|
||||
/* This helper can be used to convert from striped/raid0* -> raid10 too */
|
||||
if (seg_is_striped_target(seg)) {
|
||||
log_debug_metadata("Converting LV %s from %s to %s",
|
||||
log_debug_metadata("Converting LV %s from %s to %s.",
|
||||
display_lvname(lv), SEG_TYPE_NAME_STRIPED, SEG_TYPE_NAME_RAID0);
|
||||
if (!(seg = _convert_striped_to_raid0(lv, 1 /* alloc_metadata_devs */, 0 /* update_and_reload */, allocate_pvs)))
|
||||
return_0;
|
||||
@ -3229,18 +3318,32 @@ static int _striped_or_raid0_to_raid45610_wrapper(TAKEOVER_FN_ARGS)
|
||||
if (seg_is_raid0(seg)) {
|
||||
log_debug_metadata("Adding metadata LVs to %s.", display_lvname(lv));
|
||||
if (!_raid0_add_or_remove_metadata_lvs(lv, 1 /* update_and_reload */, allocate_pvs, NULL))
|
||||
return_0;
|
||||
/* raid0_meta -> raid4 needs clearing of MetaLVs in order to avoid raid disk role cahnge issues in the kernel */
|
||||
return 0;
|
||||
/* raid0_meta -> raid4 needs clearing of MetaLVs in order to avoid raid disk role change issues in the kernel */
|
||||
} else if (segtype_is_raid4(new_segtype) &&
|
||||
!_clear_meta_lvs(lv))
|
||||
return_0;
|
||||
|
||||
|
||||
/* Add the additional component LV pairs */
|
||||
log_debug_metadata("Adding %" PRIu32 " component LV pair(s) to %s.",
|
||||
new_image_count - lv_raid_image_count(lv),
|
||||
display_lvname(lv));
|
||||
if (!_lv_raid_change_image_count(lv, new_image_count, allocate_pvs, NULL, 0, 1))
|
||||
extents_copied = seg->extents_copied;
|
||||
region_size = seg->region_size;
|
||||
seg_len = seg->len;
|
||||
stripe_size = seg->stripe_size;
|
||||
|
||||
if (seg_is_raid4(seg) || seg_is_any_raid5(seg)) {
|
||||
if (!(seg->segtype = get_segtype_from_flag(lv->vg->cmd, SEG_RAID0_META)))
|
||||
return_0;
|
||||
seg->area_len = seg_lv(seg, 0)->le_count;
|
||||
lv->le_count = seg->len = seg->area_len * seg->area_count;
|
||||
seg->extents_copied = seg->region_size = 0;
|
||||
}
|
||||
|
||||
if (!_lv_raid_change_image_count(lv, new_image_count, allocate_pvs, NULL, 0, 1))
|
||||
return 0;
|
||||
|
||||
if (segtype_is_raid4(new_segtype) &&
|
||||
(!_shift_parity_dev(seg) ||
|
||||
@ -3250,9 +3353,12 @@ static int _striped_or_raid0_to_raid45610_wrapper(TAKEOVER_FN_ARGS)
|
||||
}
|
||||
|
||||
seg->segtype = new_segtype;
|
||||
seg->region_size = new_region_size;
|
||||
/* FIXME Hard-coded raid0 to raid4 */
|
||||
seg->area_len = seg->len;
|
||||
seg->region_size = new_region_size ?: region_size;
|
||||
|
||||
/* FIXME Hard-coded raid0 to raid4/5/6 */
|
||||
seg->stripe_size = stripe_size;
|
||||
lv->le_count = seg->len = seg->area_len = seg_len;
|
||||
seg->extents_copied = extents_copied;
|
||||
|
||||
_check_and_adjust_region_size(lv);
|
||||
|
||||
@ -3262,7 +3368,7 @@ static int _striped_or_raid0_to_raid45610_wrapper(TAKEOVER_FN_ARGS)
|
||||
return_0;
|
||||
|
||||
if (segtype_is_raid4(new_segtype)) {
|
||||
/* We had to rename SubLVs because of collision free sgifting, rename back... */
|
||||
/* We had to rename SubLVs because of collision free shifting, rename back... */
|
||||
if (!_rename_area_lvs(lv, NULL))
|
||||
return_0;
|
||||
if (!lv_update_and_reload(lv))
|
||||
@ -3352,7 +3458,9 @@ static int _takeover_from_raid0_to_raid10(TAKEOVER_FN_ARGS)
|
||||
|
||||
static int _takeover_from_raid0_to_raid45(TAKEOVER_FN_ARGS)
|
||||
{
|
||||
return _striped_or_raid0_to_raid45610_wrapper(lv, new_segtype, yes, force, first_seg(lv)->area_count + 1, 1 /* data_copies */, 0, 0, new_region_size, allocate_pvs);
|
||||
return _striped_or_raid0_to_raid45610_wrapper(lv, new_segtype, yes, force,
|
||||
first_seg(lv)->area_count + 1 /* new_image_count */,
|
||||
2 /* data_copies */, 0, 0, new_region_size, allocate_pvs);
|
||||
}
|
||||
|
||||
static int _takeover_from_raid0_to_raid6(TAKEOVER_FN_ARGS)
|
||||
@ -3398,7 +3506,9 @@ static int _takeover_from_raid0_meta_to_raid10(TAKEOVER_FN_ARGS)
|
||||
|
||||
static int _takeover_from_raid0_meta_to_raid45(TAKEOVER_FN_ARGS)
|
||||
{
|
||||
return _striped_or_raid0_to_raid45610_wrapper(lv, new_segtype, yes, force, first_seg(lv)->area_count + 1, 1 /* data_copies */, 0, 0, new_region_size, allocate_pvs);
|
||||
return _striped_or_raid0_to_raid45610_wrapper(lv, new_segtype, yes, force,
|
||||
first_seg(lv)->area_count + 1 /* new_image_count */,
|
||||
2 /* data_copies */, 0, 0, new_region_size, allocate_pvs);
|
||||
}
|
||||
|
||||
static int _takeover_from_raid0_meta_to_raid6(TAKEOVER_FN_ARGS)
|
||||
@ -3481,7 +3591,7 @@ static int _takeover_from_raid45_to_raid1(TAKEOVER_FN_ARGS)
|
||||
|
||||
static int _takeover_from_raid45_to_raid54(TAKEOVER_FN_ARGS)
|
||||
{
|
||||
return _takeover_unsupported_yet(lv, new_stripes, new_segtype);
|
||||
return _raid45_to_raid54_wrapper(lv, new_segtype, yes, force, first_seg(lv)->area_count, 2 /* data_copies */, 0, 0, 0, allocate_pvs);
|
||||
}
|
||||
|
||||
static int _takeover_from_raid45_to_raid6(TAKEOVER_FN_ARGS)
|
||||
@ -3679,14 +3789,10 @@ static int _set_convenient_raid456_segtype_to(const struct lv_segment *seg_from,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Got to do check for raid5 -> raid6 ... */
|
||||
} else if (seg_is_any_raid5(seg_from) &&
|
||||
segtype_is_any_raid6(*segtype)) {
|
||||
log_error("Conversion not supported.");
|
||||
return 0;
|
||||
|
||||
/* ... and raid6 -> raid5 */
|
||||
} else if (seg_is_any_raid6(seg_from) &&
|
||||
} else if ((seg_is_raid6_zr(seg_from) ||
|
||||
seg_is_raid6_nr(seg_from) ||
|
||||
seg_is_raid6_nc(seg_from)) &&
|
||||
segtype_is_any_raid5(*segtype)) {
|
||||
log_error("Conversion not supported.");
|
||||
return 0;
|
||||
@ -3927,7 +4033,7 @@ static int _lv_raid_rebuild_or_replace(struct logical_volume *lv,
|
||||
const char *action_str = rebuild ? "rebuild" : "replace";
|
||||
|
||||
if (seg_is_any_raid0(raid_seg)) {
|
||||
log_error("Can't replace any devices in %s LV %s",
|
||||
log_error("Can't replace any devices in %s LV %s.",
|
||||
lvseg_name(raid_seg), display_lvname(lv));
|
||||
return 0;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2011-2016 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2011-2017 Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This file is part of LVM2.
|
||||
*
|
||||
@ -87,13 +87,13 @@ static int _raid_text_import_areas(struct lv_segment *seg,
|
||||
}
|
||||
|
||||
/* Metadata device comes first. */
|
||||
if (!seg_is_raid0(seg)) {
|
||||
if (!(lv = find_lv(seg->lv->vg, cv->v.str))) {
|
||||
log_error("Couldn't find volume '%s' for segment '%s'.",
|
||||
cv->v.str ? : "NULL", seg_name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (strstr(lv->name, "_rmeta_")) {
|
||||
if (!set_lv_segment_area_lv(seg, s, lv, 0, RAID_META))
|
||||
return_0;
|
||||
cv = cv->next;
|
||||
@ -537,6 +537,7 @@ static const struct raid_type {
|
||||
{ SEG_TYPE_NAME_RAID10, 0, SEG_RAID10 | SEG_AREAS_MIRRORED },
|
||||
{ SEG_TYPE_NAME_RAID4, 1, SEG_RAID4 },
|
||||
{ SEG_TYPE_NAME_RAID5, 1, SEG_RAID5 },
|
||||
{ SEG_TYPE_NAME_RAID5_N, 1, SEG_RAID5_N },
|
||||
{ SEG_TYPE_NAME_RAID5_LA, 1, SEG_RAID5_LA },
|
||||
{ SEG_TYPE_NAME_RAID5_LS, 1, SEG_RAID5_LS },
|
||||
{ SEG_TYPE_NAME_RAID5_RA, 1, SEG_RAID5_RA },
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2016 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2005-2017 Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This file is part of the device-mapper userspace tools.
|
||||
*
|
||||
@ -47,6 +47,7 @@ enum {
|
||||
SEG_RAID1,
|
||||
SEG_RAID10,
|
||||
SEG_RAID4,
|
||||
SEG_RAID5_N,
|
||||
SEG_RAID5_LA,
|
||||
SEG_RAID5_RA,
|
||||
SEG_RAID5_LS,
|
||||
@ -81,6 +82,7 @@ static const struct {
|
||||
{ SEG_RAID1, "raid1"},
|
||||
{ SEG_RAID10, "raid10"},
|
||||
{ SEG_RAID4, "raid4"},
|
||||
{ SEG_RAID5_N, "raid5_n"},
|
||||
{ SEG_RAID5_LA, "raid5_la"},
|
||||
{ SEG_RAID5_RA, "raid5_ra"},
|
||||
{ SEG_RAID5_LS, "raid5_ls"},
|
||||
@ -2140,6 +2142,7 @@ static int _emit_areas_line(struct dm_task *dmt __attribute__((unused)),
|
||||
case SEG_RAID1:
|
||||
case SEG_RAID10:
|
||||
case SEG_RAID4:
|
||||
case SEG_RAID5_N:
|
||||
case SEG_RAID5_LA:
|
||||
case SEG_RAID5_RA:
|
||||
case SEG_RAID5_LS:
|
||||
@ -2588,6 +2591,7 @@ static int _emit_segment_line(struct dm_task *dmt, uint32_t major,
|
||||
case SEG_RAID1:
|
||||
case SEG_RAID10:
|
||||
case SEG_RAID4:
|
||||
case SEG_RAID5_N:
|
||||
case SEG_RAID5_LA:
|
||||
case SEG_RAID5_RA:
|
||||
case SEG_RAID5_LS:
|
||||
@ -3869,6 +3873,7 @@ int dm_tree_node_add_null_area(struct dm_tree_node *node, uint64_t offset)
|
||||
case SEG_RAID0_META:
|
||||
case SEG_RAID1:
|
||||
case SEG_RAID4:
|
||||
case SEG_RAID5_N:
|
||||
case SEG_RAID5_LA:
|
||||
case SEG_RAID5_RA:
|
||||
case SEG_RAID5_LS:
|
||||
|
@ -1,5 +1,5 @@
|
||||
#!/bin/sh
|
||||
# Copyright (C) 2016 Red Hat, Inc. All rights reserved.
|
||||
# Copyright (C) 2016,2017 Red Hat, Inc. All rights reserved.
|
||||
#
|
||||
# This copyrighted material is made available to anyone wishing to use,
|
||||
# modify, copy, or redistribute it subject to the terms and conditions
|
||||
@ -120,6 +120,7 @@ check lv_field $vg/$lv4 segtype "striped"
|
||||
check lv_field $vg/$lv4 stripes 3
|
||||
fsck -fn /dev/mapper/$vg-$lv4
|
||||
|
||||
|
||||
# Convert striped -> raid4
|
||||
lvconvert -y --ty raid4 $vg/$lv1
|
||||
check lv_field $vg/$lv1 segtype "raid4"
|
||||
@ -128,6 +129,37 @@ fsck -fn /dev/mapper/$vg-$lv1
|
||||
aux wait_for_sync $vg $lv1
|
||||
fsck -fn /dev/mapper/$vg-$lv1
|
||||
|
||||
# Convert raid4 -> raid5_n
|
||||
lvconvert -y --ty raid5_n $vg/$lv1
|
||||
check lv_field $vg/$lv1 segtype "raid5_n"
|
||||
check lv_field $vg/$lv1 stripes 4
|
||||
fsck -fn /dev/mapper/$vg-$lv1
|
||||
aux wait_for_sync $vg $lv1
|
||||
fsck -fn /dev/mapper/$vg-$lv1
|
||||
|
||||
# Convert raid5 -> striped
|
||||
lvconvert -y --ty striped $vg/$lv1
|
||||
check lv_field $vg/$lv1 segtype "striped"
|
||||
check lv_field $vg/$lv1 stripes 3
|
||||
fsck -fn /dev/mapper/$vg-$lv1
|
||||
|
||||
# Convert striped -> raid5_n
|
||||
lvconvert -y --ty raid5_n $vg/$lv1
|
||||
check lv_field $vg/$lv1 segtype "raid5_n"
|
||||
check lv_field $vg/$lv1 stripes 4
|
||||
fsck -fn /dev/mapper/$vg-$lv1
|
||||
aux wait_for_sync $vg $lv1
|
||||
fsck -fn /dev/mapper/$vg-$lv1
|
||||
|
||||
# Convert raid5_n -> raid4
|
||||
lvconvert -y --ty raid4 $vg/$lv1
|
||||
check lv_field $vg/$lv1 segtype "raid4"
|
||||
check lv_field $vg/$lv1 stripes 4
|
||||
fsck -fn /dev/mapper/$vg-$lv1
|
||||
aux wait_for_sync $vg $lv1
|
||||
fsck -fn /dev/mapper/$vg-$lv1
|
||||
|
||||
|
||||
# Convert raid0 -> raid4
|
||||
lvconvert -y --ty raid4 $vg/$lv2
|
||||
check lv_field $vg/$lv2 segtype "raid4"
|
||||
@ -136,6 +168,35 @@ fsck -fn /dev/mapper/$vg-$lv2
|
||||
aux wait_for_sync $vg $lv2
|
||||
fsck -fn /dev/mapper/$vg-$lv2
|
||||
|
||||
# Convert raid4 -> raid0
|
||||
lvconvert -y --ty raid0 $vg/$lv2
|
||||
check lv_field $vg/$lv2 segtype "raid0"
|
||||
check lv_field $vg/$lv2 stripes 3
|
||||
fsck -fn /dev/mapper/$vg-$lv2
|
||||
|
||||
# Convert raid0 -> raid5_n
|
||||
lvconvert -y --ty raid5_n $vg/$lv2
|
||||
check lv_field $vg/$lv2 segtype "raid5_n"
|
||||
check lv_field $vg/$lv2 stripes 4
|
||||
fsck -fn /dev/mapper/$vg-$lv2
|
||||
aux wait_for_sync $vg $lv2
|
||||
fsck -fn /dev/mapper/$vg-$lv2
|
||||
|
||||
# Convert raid5_n -> raid0_meta
|
||||
lvconvert -y --ty raid0_meta $vg/$lv2
|
||||
check lv_field $vg/$lv2 segtype "raid0_meta"
|
||||
check lv_field $vg/$lv2 stripes 3
|
||||
fsck -fn /dev/mapper/$vg-$lv2
|
||||
|
||||
# Convert raid0_meta -> raid5_n
|
||||
lvconvert -y --ty raid5_n $vg/$lv2
|
||||
check lv_field $vg/$lv2 segtype "raid5_n"
|
||||
check lv_field $vg/$lv2 stripes 4
|
||||
fsck -fn /dev/mapper/$vg-$lv2
|
||||
aux wait_for_sync $vg $lv2
|
||||
fsck -fn /dev/mapper/$vg-$lv2
|
||||
|
||||
|
||||
# Convert raid4 -> raid0_meta
|
||||
lvconvert -y --ty raid0_meta $vg/$lv1
|
||||
check lv_field $vg/$lv1 segtype "raid0_meta"
|
||||
|
Loading…
Reference in New Issue
Block a user