1
0
mirror of git://sourceware.org/git/lvm2.git synced 2025-01-03 05:18:29 +03:00

raid_manip: report index of tracking LV back; activate added striped image pairs

This commit is contained in:
Heinz Mauelshagen 2016-02-04 13:31:37 +01:00
parent ebda5f8a65
commit 10f5c83851
2 changed files with 63 additions and 55 deletions

View File

@ -295,8 +295,7 @@ static int is_same_level(const struct segment_type *t1, const struct segment_typ
return _cmp_level(t1, t2);
}
static int _lv_is_raid_with_tracking(const struct logical_volume *lv,
struct logical_volume **tracking)
static int _lv_is_raid_with_tracking(const struct logical_volume *lv, uint32_t *ss)
{
uint32_t s;
const struct lv_segment *seg;
@ -307,7 +306,9 @@ static int _lv_is_raid_with_tracking(const struct logical_volume *lv,
for (s = 0; s < seg->area_count; s++)
if (lv_is_visible(seg_lv(seg, s))) {
if (!(seg_lv(seg, s)->status & LVM_WRITE)) {
*tracking = seg_lv(seg, s);
if (ss)
*ss = s;
return 1;
}
@ -320,9 +321,7 @@ static int _lv_is_raid_with_tracking(const struct logical_volume *lv,
/* API function to check for @lv to be a tracking one */
int lv_is_raid_with_tracking(const struct logical_volume *lv)
{
struct logical_volume *tracking;
return _lv_is_raid_with_tracking(lv, &tracking);
return _lv_is_raid_with_tracking(lv, NULL);
}
/* HM Helper: return true in case this is a raid1 top-level LV inserted to do synchronization of 2 given sub LVs */
@ -3230,7 +3229,7 @@ int lv_raid_split(struct logical_volume *lv, int yes,
const char *split_name, uint32_t new_image_count,
struct dm_list *splittable_pvs)
{
uint32_t split_count;
uint32_t split_count, s;
struct lv_list *lvl;
struct dm_list meta_lvs, data_lvs;
struct cmd_context *cmd;
@ -3274,11 +3273,11 @@ int lv_raid_split(struct logical_volume *lv, int yes,
* complete the split of the tracking sub-LV
*/
log_debug_metadata("Check if LV %s is tracking changes", display_lvname(lv));
if (_lv_is_raid_with_tracking(lv, &tracking)) {
if (!lv_is_on_pvs(tracking, splittable_pvs)) {
if (_lv_is_raid_with_tracking(lv, &s)) {
if (!lv_is_on_pvs((tracking = seg_lv(seg, s)), splittable_pvs)) {
log_error("Unable to split additional image from %s "
"while tracking changes for %s",
lv->name, tracking->name);
"while tracking changes for %s",
lv->name, tracking->name);
return 0;
}
@ -3407,10 +3406,12 @@ int lv_raid_split_and_track(struct logical_volume *lv,
int s;
struct logical_volume *split_lv;
struct lv_segment *seg;
struct volume_group *vg;
RETURN_IF_LV_SEG_ZERO(lv, (seg = first_seg(lv)));
RETURN_IF_NONZERO(!seg_is_mirrored(seg) && !seg_is_raid01(seg),
"mirrored/raid10 segment to split off");
vg = lv->vg;
if (!_raid_in_sync(lv)) {
log_error("Unable to split image from %s while not in-sync",
@ -3498,19 +3499,18 @@ int lv_raid_split_and_track(struct logical_volume *lv,
return 0;
}
if (!lv_update_and_reload(lv))
if (!vg_write(vg) || !vg_commit(vg) || !backup(vg))
return_0;
log_print_unless_silent("%s split from %s for read-only purposes.",
split_lv->name, lv->name);
/* Suspend+resume the tracking LV to create its devnode */
if (!suspend_lv(lv->vg->cmd, split_lv) || !resume_lv(lv->vg->cmd, split_lv)) {
if (!suspend_lv(vg->cmd, split_lv) || !resume_lv(vg->cmd, split_lv)) {
log_error("Failed to suspend+resume %s after committing changes",
display_lvname(split_lv));
return 0;
}
log_print_unless_silent("%s split from %s for read-only purposes.",
split_lv->name, lv->name);
log_print_unless_silent("Use 'lvconvert --merge %s' to merge back into %s",
display_lvname(split_lv), display_lvname(lv));
return 1;
@ -3589,13 +3589,12 @@ int lv_raid_merge(struct logical_volume *image_lv)
"mirrored/raid10 to merge into, rejecting request");
RETURN_IF_ZERO(seg->meta_areas, "metadata LV areas");
if (!_lv_is_raid_with_tracking(lv, &tracking)) {
log_error("%s is not a tracking LV.",
display_lvname(lv));
if (!_lv_is_raid_with_tracking(lv, &s)) {
log_error("%s is not a tracking LV.", display_lvname(lv));
return 0;
}
if (tracking != image_lv) {
if ((tracking = seg_lv(seg, s)) != image_lv) {
log_error("%s is not the tracking LV of %s but %s is.",
display_lvname(image_lv), display_lvname(lv), display_lvname(tracking));
return 0;
@ -3614,13 +3613,7 @@ int lv_raid_merge(struct logical_volume *image_lv)
display_lvname(image_lv));
}
for (s = 0; s < seg->area_count; s++)
if (seg_lv(seg, s) == image_lv) {
meta_lv = seg_metalv(seg, s);
break;
}
if (!meta_lv) {
if (!(meta_lv = seg_metalv(seg, s))) {
log_error("Failed to find metadata LV for %s in %s.",
display_lvname(image_lv), display_lvname(lv));
return 0;
@ -3641,7 +3634,7 @@ int lv_raid_merge(struct logical_volume *image_lv)
log_print_unless_silent("LV %s successfully merged back into %s",
display_lvname(image_lv), display_lvname(lv));
return _lv_cond_repair(lv);
return 1;
}
/*
@ -4351,23 +4344,27 @@ PFLA("lv->size=%s seg->len=%u seg->area_len=%u seg->area_count=%u old_image_coun
* Reshape: add disks to existing raid lv
*
*/
static int _raid_reshape_add_disks(struct logical_volume *lv,
const struct segment_type *new_segtype,
int yes, int force,
uint32_t old_image_count, uint32_t new_image_count,
const unsigned new_stripes, const unsigned new_stripe_size,
struct dm_list *allocate_pvs)
static int _raid_reshape_add_images(struct logical_volume *lv,
const struct segment_type *new_segtype,
int yes, int force,
uint32_t old_image_count, uint32_t new_image_count,
const unsigned new_stripes, const unsigned new_stripe_size,
struct dm_list *allocate_pvs)
{
uint32_t grown_le_count, current_le_count, s;
struct volume_group *vg;
struct logical_volume *slv;
struct lv_segment *seg;
struct lvinfo info = { 0 };
RETURN_IF_LV_SEG_SEGTYPE_ZERO(lv, (seg = first_seg(lv)), new_segtype);
vg = lv->vg;
if (!lv_info(lv->vg->cmd, lv, 0, &info, 1, 0) && driver_version(NULL, 0)) {
if (!lv_info(vg->cmd, lv, 0, &info, 1, 0) && driver_version(NULL, 0)) {
log_error("lv_info failed: aborting");
return 0;
}
if (seg->segtype != new_segtype)
log_print_unless_silent("Ignoring layout change on device adding reshape");
PFL();
@ -4404,7 +4401,7 @@ PFL();
if (!_lv_alloc_reshape_space(lv, alloc_begin, NULL, allocate_pvs))
return 0;
PFLA("lv->size=%s", display_size(lv->vg->cmd, lv->size));
PFLA("lv->size=%s", display_size(vg->cmd, lv->size));
PFLA("lv->le_count=%u", lv->le_count);
PFLA("seg->len=%u", first_seg(lv)->len);
/*
@ -4415,10 +4412,21 @@ PFLA("seg->len=%u", first_seg(lv)->len);
*/
log_debug_metadata("Setting delta disk flag on new data LVs of %s",
display_lvname(lv));
for (s = old_image_count; s < seg->area_count; s++) {
PFLA("seg_lv(seg, %u)=%s", s, seg_lv(seg, s)->name);
seg_lv(seg, s)->status &= ~LV_REBUILD;
seg_lv(seg, s)->status |= LV_RESHAPE_DELTA_DISKS_PLUS;
if (old_image_count < seg->area_count) {
if (!vg_write(vg) || !vg_commit(vg) || !backup(vg)) {
log_error("metadata commit/backup failed");
return 0;
}
for (s = old_image_count; s < seg->area_count; s++) {
slv = seg_lv(seg, s);
PFLA("seg_lv(seg, %u)=%s", s, slv);
slv->status &= ~LV_REBUILD;
slv->status |= LV_RESHAPE_DELTA_DISKS_PLUS;
if (!activate_lv_excl_local(vg->cmd, slv) ||
!activate_lv_excl_local(vg->cmd, seg_metalv(seg, s)))
return_0;
}
}
return 1;
@ -4430,12 +4438,12 @@ PFLA("seg_lv(seg, %u)=%s", s, seg_lv(seg, s)->name);
* Reshape: remove disks from existing raid lv
*
*/
static int _raid_reshape_remove_disks(struct logical_volume *lv,
const struct segment_type *new_segtype,
int yes, int force,
uint32_t old_image_count, uint32_t new_image_count,
const unsigned new_stripes, const unsigned new_stripe_size,
struct dm_list *allocate_pvs, struct dm_list *removal_lvs)
static int _raid_reshape_remove_images(struct logical_volume *lv,
const struct segment_type *new_segtype,
int yes, int force,
uint32_t old_image_count, uint32_t new_image_count,
const unsigned new_stripes, const unsigned new_stripe_size,
struct dm_list *allocate_pvs, struct dm_list *removal_lvs)
{
uint32_t active_lvs, current_le_count, reduced_le_count, removed_lvs, s;
uint64_t extend_le_count;
@ -4928,17 +4936,17 @@ PFLA("devs_in_sync=%u old_image_count=%u new_image_count=%u", devs_in_sync,old_i
/* Handle disk addition reshaping */
if (old_image_count < new_image_count) {
PFL();
if (!_raid_reshape_add_disks(lv, new_segtype, yes, force,
old_image_count, new_image_count,
new_stripes, new_stripe_size, allocate_pvs))
if (!_raid_reshape_add_images(lv, new_segtype, yes, force,
old_image_count, new_image_count,
new_stripes, new_stripe_size, allocate_pvs))
return 0;
/* Handle disk removal reshaping */
} else if (old_image_count > new_image_count) {
if (!_raid_reshape_remove_disks(lv, new_segtype, yes, force,
old_image_count, new_image_count,
new_stripes, new_stripe_size,
allocate_pvs, &removal_lvs))
if (!_raid_reshape_remove_images(lv, new_segtype, yes, force,
old_image_count, new_image_count,
new_stripes, new_stripe_size,
allocate_pvs, &removal_lvs))
return 0;
/*
@ -9120,7 +9128,7 @@ static int _raid_convert_define_parms(const struct lv_segment *seg,
!segtype_is_raid1(*segtype) &&
!segtype_is_raid01(*segtype)) {
if (!segtype_is_any_raid6(*segtype) && *data_copies > *stripes) {
log_error("Number of data copies %u is larger than number of stripes %u!",
log_error("Number of data copies %u is larger than number of stripes %u",
*data_copies, *stripes);
return 0;
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2005-2014 Red Hat, Inc. All rights reserved.
* Copyright (C) 2005-2016 Red Hat, Inc. All rights reserved.
*
* This file is part of the device-mapper userspace tools.
*