From 23809379babf96459ae7135114b9c6302c9a014e Mon Sep 17 00:00:00 2001 From: Zdenek Kabelac Date: Mon, 21 Nov 2016 12:43:18 +0100 Subject: [PATCH] raid: implement transient status check Take into acount reported state from 'raid' targets. When raid leg is marked with 'D' - take it as missing leg. --- WHATS_NEW | 1 + lib/raid/raid.c | 57 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+) diff --git a/WHATS_NEW b/WHATS_NEW index 7f8801ac0..9414b0393 100644 --- a/WHATS_NEW +++ b/WHATS_NEW @@ -1,5 +1,6 @@ Version 2.02.168 - ==================================== + Implement transient status check for raid volumes. Only log msg as debug if lvm2-lvmdbusd unit missing for D-Bus notification. Missing stripe filler now could be also 'zero'. lvconvert --repair accepts --interval and --background option. diff --git a/lib/raid/raid.c b/lib/raid/raid.c index 92a96a3e9..80af61e06 100644 --- a/lib/raid/raid.c +++ b/lib/raid/raid.c @@ -349,6 +349,62 @@ static int _raid_target_percent(void **target_state, return 1; } +static int _raid_transient_status(struct dm_pool *mem, + struct lv_segment *seg, + char *params) +{ + int failed = 0, r = 0; + unsigned i; + struct lvinfo info; + struct logical_volume *lv; + struct dm_status_raid *sr; + + log_debug("Raid transient status %s.", params); + + if (!dm_get_status_raid(mem, params, &sr)) + return_0; + + if (sr->dev_count != seg->area_count) { + log_error("Active raid has a wrong number of raid images!"); + log_error("Metadata says %u, kernel says %u.", + seg->area_count, sr->dev_count); + goto out; + } + + if (seg->meta_areas) + for (i = 0; i < seg->area_count; ++i) { + lv = seg_metalv(seg, i); + if (!lv_info(lv->vg->cmd, lv, 0, &info, 0, 0)) { + log_error("Check for existence of raid meta %s failed.", + display_lvname(lv)); + goto out; + } + } + + for (i = 0; i < seg->area_count; ++i) { + lv = seg_lv(seg, i); + if (!lv_info(lv->vg->cmd, lv, 0, &info, 0, 0)) { + log_error("Check for existence of raid image %s failed.", + display_lvname(lv)); + goto out; + } + if (sr->dev_health[i] == 'D') { + lv->status |= PARTIAL_LV; + ++failed; + } + } + + /* Update PARTIAL_LV flags across the VG */ + if (failed) + vg_mark_partial_lvs(lv->vg, 0); + + r = 1; +out: + dm_pool_free(mem, sr); + + return r; +} + static int _raid_target_present(struct cmd_context *cmd, const struct lv_segment *seg __attribute__((unused)), unsigned *attributes) @@ -460,6 +516,7 @@ static struct segtype_handler _raid_ops = { #ifdef DEVMAPPER_SUPPORT .target_percent = _raid_target_percent, .target_present = _raid_target_present, + .check_transient_status = _raid_transient_status, .modules_needed = _raid_modules_needed, # ifdef DMEVENTD .target_monitored = _raid_target_monitored,