From 2eff6e19740c5b2ef30effc2fdb0df8899b75ce1 Mon Sep 17 00:00:00 2001 From: Zdenek Kabelac Date: Sun, 24 Mar 2024 22:42:16 +0100 Subject: [PATCH] raid: update dm_get_status_raid Handle mismatch of reported 'dm raid' status, where the active raid LV can be actually showing higher numebr of raid leg devices, that the number of shown status characters. This can happen if the raid leg is dropped during initial resynchronization. --- WHATS_NEW_DM | 1 + device_mapper/libdm-targets.c | 11 ++++++++++- libdm/libdm-targets.c | 11 ++++++++++- 3 files changed, 21 insertions(+), 2 deletions(-) diff --git a/WHATS_NEW_DM b/WHATS_NEW_DM index 05afe5d84..d27faf183 100644 --- a/WHATS_NEW_DM +++ b/WHATS_NEW_DM @@ -1,5 +1,6 @@ Version 1.02.198 - =================== + Enhance dm_get_status_raid to handle mismatching status or reported legs. Create /dev/disk/by-label symlinks for DM devs that have crypto as next layer. Persist udev db for DM devs on cleanup used in initrd to rootfs transition. Process synthetic udev events other than 'add/change' as 'change' events. diff --git a/device_mapper/libdm-targets.c b/device_mapper/libdm-targets.c index 43fe88d4c..c0a8f6669 100644 --- a/device_mapper/libdm-targets.c +++ b/device_mapper/libdm-targets.c @@ -117,9 +117,18 @@ int dm_get_status_raid(struct dm_pool *mem, const char *params, if (!(s->raid_type = dm_pool_strndup(mem, params, pp - params - 1))) goto_bad; /* memory is freed when pool is destroyed */ - if (!(s->dev_health = dm_pool_strndup(mem, p, i)) || !(p = _skip_fields(p, 1))) /* health chars */ + if (!(pp = _skip_fields(p, 1))) goto_bad; + /* Raid target can actually report more then real number of legs in a case + * raid legs have been removed during initial raid array resynchronization */ + if (i > (pp - p - 1)) + i = pp - p - 1; + + if (!(s->dev_health = dm_pool_strndup(mem, p, i))) /* health chars */ + goto_bad; + p = pp; + s->dev_count = i; if (sscanf(p, FMTu64 "/" FMTu64, &s->insync_regions, &s->total_regions) != 2) goto_bad; diff --git a/libdm/libdm-targets.c b/libdm/libdm-targets.c index d94480b64..a2f838f98 100644 --- a/libdm/libdm-targets.c +++ b/libdm/libdm-targets.c @@ -117,9 +117,18 @@ int dm_get_status_raid(struct dm_pool *mem, const char *params, if (!(s->raid_type = dm_pool_strndup(mem, params, pp - params - 1))) goto_bad; /* memory is freed when pool is destroyed */ - if (!(s->dev_health = dm_pool_strndup(mem, p, i)) || !(p = _skip_fields(p, 1))) /* health chars */ + if (!(pp = _skip_fields(p, 1))) goto_bad; + /* Raid target can actually report more then real number of legs in a case + * raid legs have been removed during initial raid array resynchronization */ + if (i > (pp - p - 1)) + i = pp - p - 1; + + if (!(s->dev_health = dm_pool_strndup(mem, p, i))) /* health chars */ + goto_bad; + p = pp; + s->dev_count = i; if (sscanf(p, FMTu64 "/" FMTu64, &s->insync_regions, &s->total_regions) != 2) goto_bad;