summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorHeinz Mauelshagen <heinzm@redhat.com>2018-05-03 18:00:21 +0200
committerHeinz Mauelshagen <heinzm@redhat.com>2018-05-03 18:48:00 +0200
commit4ebfd8e8eb68442efc334b35bc1f22eda3e4dd3d (patch)
tree9bb57652d1ee374b3a84588131fa8e1b51446e5f /lib
parentb393fbec00bbe1fb8d546ee3f360f8d2eb19540e (diff)
downloadlvm2-4ebfd8e8eb68442efc334b35bc1f22eda3e4dd3d.tar.gz
lvconvert: don't return success on degraded -m raid1 conversion
In case "lvconvert -mN RaidLV" was used on a degraded raid1 LV, success was returned instead of an error. Provide message to inform about the need to repair first before changing number of mirrors and exit with error. Add new lvconvert-m-raid1-degraded.sh test. Resolves: rhbz1573960
Diffstat (limited to 'lib')
-rw-r--r--lib/metadata/raid_manip.c36
1 files changed, 35 insertions, 1 deletions
diff --git a/lib/metadata/raid_manip.c b/lib/metadata/raid_manip.c
index 7d82a24b8..1b9ebcf94 100644
--- a/lib/metadata/raid_manip.c
+++ b/lib/metadata/raid_manip.c
@@ -3200,6 +3200,27 @@ static int _raid_remove_images(struct logical_volume *lv, int yes,
return 1;
}
+/* Check if single SubLV @slv is degraded. */
+static int _sublv_is_degraded(const struct logical_volume *slv)
+{
+ return !slv || lv_is_partial(slv) || lv_is_virtual(slv);
+}
+
+/* Return failed component SubLV count for @lv. */
+static uint32_t _lv_get_nr_failed_components(const struct logical_volume *lv)
+{
+ uint32_t r = 0, s;
+ struct lv_segment *seg = first_seg(lv);
+
+ for (s = 0; s < seg->area_count; s++)
+ if (_sublv_is_degraded(seg_lv(seg, s)) ||
+ (seg->meta_areas &&
+ _sublv_is_degraded(seg_metalv(seg, s))))
+ r++;
+
+ return r;
+}
+
/*
* _lv_raid_change_image_count
* new_count: The absolute count of images (e.g. '2' for a 2-way mirror)
@@ -3215,12 +3236,25 @@ static int _lv_raid_change_image_count(struct logical_volume *lv, int yes, uint3
struct dm_list *allocate_pvs, struct dm_list *removal_lvs,
int commit, int use_existing_area_len)
{
+ int r;
uint32_t old_count = lv_raid_image_count(lv);
+ /* If there's failed component SubLVs, require repair first! */
+ if (lv_is_raid(lv) &&
+ _lv_get_nr_failed_components(lv) &&
+ new_count >= old_count) {
+ log_error("Can't change number of mirrors of degraded %s.",
+ display_lvname(lv));
+ log_error("Please run \"lvconvert --repair %s\" first.",
+ display_lvname(lv));
+ r = 0;
+ } else
+ r = 1;
+
if (old_count == new_count) {
log_warn("WARNING: %s already has image count of %d.",
display_lvname(lv), new_count);
- return 1;
+ return r;
}
/*