From 0e4fd4485fa3dd5b85886a1f4d85e7d477dd1c3a Mon Sep 17 00:00:00 2001 From: David Teigland Date: Fri, 17 Nov 2023 11:04:22 -0600 Subject: [PATCH] lvs: set first attr flag for raid integrity images The first lv_attr flag is 'i' or 'I' for a raid image. (i: raid image, I: out of sync raid image) For integrity raid images (_iorig), the flag was not being set. --- lib/metadata/integrity_manip.c | 1 + lib/metadata/lv.c | 75 ++++++++++++++++++++++++++++++++++ 2 files changed, 76 insertions(+) diff --git a/lib/metadata/integrity_manip.c b/lib/metadata/integrity_manip.c index 635059e20..8bdbeeee9 100644 --- a/lib/metadata/integrity_manip.c +++ b/lib/metadata/integrity_manip.c @@ -672,6 +672,7 @@ int lv_add_integrity_to_raid(struct logical_volume *lv, struct integrity_setting log_debug("Adding integrity to raid image %s", lv_image->name); /* + * lv_iorig returned by insert_layer_for_lv() (but unused here) * "lv_iorig" is a new LV with new id, but with the segments * from "lv_image". "lv_image" keeps the existing name and id, * but gets a new integrity segment, in place of the segments diff --git a/lib/metadata/lv.c b/lib/metadata/lv.c index ceacfa917..d7d8a78a4 100644 --- a/lib/metadata/lv.c +++ b/lib/metadata/lv.c @@ -1152,6 +1152,79 @@ int lv_raid_image_in_sync(const struct logical_volume *lv) return 0; } +static int lv_raid_integrity_image_in_sync(const struct logical_volume *lv_iorig) +{ + struct logical_volume *lv_image = NULL; + struct logical_volume *lv_raid = NULL; + struct lv_segment *raid_seg = NULL; + const struct seg_list *sl; + char *raid_health; + unsigned int s; + int found = 0; + + if (!lv_is_active(lv_iorig)) + return 0; /* Assume not in-sync */ + + /* Get top level raid LV from lv_iorig. */ + + /* step 1: get lv_image from lv_iorig */ + dm_list_iterate_items(sl, &lv_iorig->segs_using_this_lv) { + if (!sl->seg || !sl->seg->lv || !sl->seg->origin) + continue; + if (lv_is_integrity(sl->seg->lv) && (sl->seg->origin == lv_iorig)) { + lv_image = sl->seg->lv; + break; + } + } + + if (!lv_image) { + log_error("No lv_image found for lv_iorig %s", lv_iorig->name); + return 0; + } + + /* step 2: get lv_raid from lv_image */ + if ((raid_seg = get_only_segment_using_this_lv(lv_image))) + lv_raid = raid_seg->lv; + + if (!lv_raid) { + log_error("No lv_raid found for lv_image %s lv_iorig %s", lv_image->name, lv_iorig->name); + return 0; + } + + /* Figure out which image number this is in lv_raid. */ + if (!(raid_seg = first_seg(lv_raid))) { + log_error("No raid seg found for lv_raid %s lv_image %s lv_iorig %s", + lv_raid->name, lv_image->name, lv_iorig->name); + return 0; + } + for (s = 0; s < raid_seg->area_count; s++) { + if (seg_lv(raid_seg, s) == lv_image) { + found = 1; + break; + } + } + + if (!found) { + log_error("No seg area found for lv_raid %s lv_image %s lv_iorig %s", + lv_raid->name, lv_image->name, lv_iorig->name); + return 0; + } + + if (!lv_raid_dev_health(lv_raid, &raid_health)) { + log_error("No raid health for seg area %u lv_raid %s lv_image %s lv_iorig %s", + s, lv_raid->name, lv_image->name, lv_iorig->name); + return 0; + } + + log_debug("raid health %c for seg area %u lv_raid %s lv_image %s lv_iorig %s", + raid_health[s], s, lv_raid->name, lv_image->name, lv_iorig->name); + + if (raid_health[s] == 'A') + return 1; + + return 0; +} + /* * _lv_raid_healthy * @lv: A RAID_IMAGE, RAID_META, or RAID logical volume. @@ -1258,6 +1331,8 @@ char *lv_attr_dup_with_info_and_seg_status(struct dm_pool *mem, const struct lv_ repstr[0] = 'e'; else if (lv_is_cache_type(lv) || lv_is_writecache(lv)) repstr[0] = 'C'; + else if (lv_is_integrity_origin(lv)) + repstr[0] = lv_raid_integrity_image_in_sync(lv) ? 'i' : 'I'; else if (lv_is_integrity(lv)) repstr[0] = 'g'; else if (lv_is_raid(lv))