1
0
mirror of git://sourceware.org/git/lvm2.git synced 2025-10-20 11:33:15 +03:00

pvmove: prohibit non-resilient collocation of RAID SubLVs

'pvmove -n name pv1 pv2' allows to collocate multiple RAID SubLVs
on pv2 (e.g. results in collocated raidlv_rimage_0 and raidlv_rimage_1),
thus causing loss of resilence and/or performance of the RaidLV.

Fix this pvmove flaw leading to potential data loss in case of PV failure
by preventing any SubLVs from collocation on any PVs of the RaidLV.
Still allow to collocate any DataLVs of a RaidLV with their sibling MetaLVs
and vice-versa though (e.g. raidlv_rmeta_0 on pv1 may still be moved to pv2
already holding raidlv_rimage_0).

Because access to the top-level RaidLV name is needed,
promote local _top_level_lv_name() from raid_manip.c
to global top_level_lv_name().

- resolves rhbz1202497
This commit is contained in:
Heinz Mauelshagen
2016-08-15 18:22:32 +02:00
parent c7bd33d951
commit 8e9d5d12ae
4 changed files with 88 additions and 8 deletions

View File

@@ -109,16 +109,17 @@ static void _check_and_adjust_region_size(const struct logical_volume *lv)
}
/* Strip any raid suffix off LV name */
static char *_top_level_raid_lv_name(struct logical_volume *lv)
char *top_level_lv_name(struct volume_group *vg, const char *lv_name)
{
char *new_lv_name, *suffix;
if (!(new_lv_name = dm_pool_strdup(lv->vg->vgmem, lv->name))) {
if (!(new_lv_name = dm_pool_strdup(vg->vgmem, lv_name))) {
log_error("Failed to allocate string for new LV name.");
return NULL;
}
if ((suffix = first_substring(new_lv_name, "_rimage_", "_mimage_", NULL)))
if ((suffix = first_substring(new_lv_name, "_rimage_", "_rmeta_",
"_mimage_", "_mlog_", NULL)))
*suffix = '\0';
return new_lv_name;
@@ -731,7 +732,7 @@ static int _alloc_rmeta_for_lv(struct logical_volume *data_lv,
return 0;
}
if (!(base_name = _top_level_raid_lv_name(data_lv)))
if (!(base_name = top_level_lv_name(data_lv->vg, data_lv->name)))
return_0;
if (!(ah = allocate_extents(data_lv->vg, NULL, seg->segtype, 0, 1, 0,