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;