summaryrefslogtreecommitdiff
path: root/libdm/libdm-targets.c
diff options
context:
space:
mode:
authorZdenek Kabelac <zkabelac@redhat.com>2017-06-16 13:20:47 +0200
committerZdenek Kabelac <zkabelac@redhat.com>2017-06-16 17:04:00 +0200
commit529dcaf6a3c4fea4a15baf13cf057d2333860c05 (patch)
tree27e69e1ca90b3fc0e003eae97339e3f5649123a3 /libdm/libdm-targets.c
parent40e0dcf70d5a719671916aa88adf9a8f18e096c6 (diff)
downloadlvm2-529dcaf6a3c4fea4a15baf13cf057d2333860c05.tar.gz
libdm: workarounds reported raid status info
Current existing kernels reports status sometimes in weird form. Instead of showing what is the exact progress, we need to estimate this in-sync state from several surrounding states. Main reason here is to never report 100% sync state for a raid device which will be undergoing i.e. recovery.
Diffstat (limited to 'libdm/libdm-targets.c')
-rw-r--r--libdm/libdm-targets.c18
1 files changed, 18 insertions, 0 deletions
diff --git a/libdm/libdm-targets.c b/libdm/libdm-targets.c
index 1709c2b2c..6577f0744 100644
--- a/libdm/libdm-targets.c
+++ b/libdm/libdm-targets.c
@@ -99,6 +99,7 @@ int dm_get_status_raid(struct dm_pool *mem, const char *params,
unsigned num_fields;
const char *p, *pp, *msg_fields = "";
struct dm_status_raid *s = NULL;
+ unsigned a = 0;
if ((num_fields = _count_fields(params)) < 4)
goto_bad;
@@ -168,6 +169,23 @@ int dm_get_status_raid(struct dm_pool *mem, const char *params,
out:
*status = s;
+ if (s->insync_regions == s->total_regions) {
+ /* FIXME: kernel gives misleading info here
+ * Trying to recognize a true state */
+ while (i-- > 0)
+ if (s->dev_health[i] == 'a')
+ a++; /* Count number of 'a' */
+
+ if (a && a < s->dev_count) {
+ /* SOME legs are in 'a' */
+ if (!strcasecmp(s->sync_action, "recover")
+ || !strcasecmp(s->sync_action, "idle"))
+ /* Kernel may possibly start some action
+ * in near-by future, do not report 100% */
+ s->insync_regions--;
+ }
+ }
+
return 1;
bad: