diff options
author | Xiao Ni <xni@redhat.com> | 2021-10-27 14:23:14 +0200 |
---|---|---|
committer | Jes Sorensen <jsorensen@fb.com> | 2021-11-02 17:09:51 +0100 |
commit | 8e1a258ecbc239c04052b3f36ed57e62da71a19e (patch) | |
tree | 027d4a8090ec1e8b34dad19e9718dc40b03ef404 | |
parent | mdadm/lib: Define a new helper function is_dev_alived (diff) | |
download | mdadm-8e1a258ecbc239c04052b3f36ed57e62da71a19e.tar.xz mdadm-8e1a258ecbc239c04052b3f36ed57e62da71a19e.zip |
mdadm/Detail: Can't show container name correctly when unpluging disks
The test case is:
1. create one imsm container
2. create a raid5 device from the container
3. unplug two disks
4. mdadm --detail /dev/md126
[root@rhel85 ~]# mdadm -D /dev/md126
/dev/md126:
Container : ��, member 0
The Detail function first gets container name by function
map_dev_preferred. Then it tries to find which disks are
available. In patch db5377883fef(It should be FAILED..)
uses map_dev_preferred to find which disks are under /dev.
But now, the major/minor information comes from kernel space.
map_dev_preferred malloc memory and init a device list when
first be called by Detail. It can't find the device in the
list by the major/minor. It free the memory and reinit the
list.
The container name now points to an area tha has been freed.
So the containt is a mess.
This patch replaces map_dev_preferred with access.
Fixes: db5377883fef (It should be FAILED when raid has)
Signed-off-by: Xiao Ni <xni@redhat.com>
Reported-by: Fine Fan <ffan@redhat.com>
Acked-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
Signed-off-by: Jes Sorensen <jsorensen@fb.com>
-rw-r--r-- | Detail.c | 16 |
1 files changed, 8 insertions, 8 deletions
@@ -351,14 +351,14 @@ int Detail(char *dev, struct context *c) avail = xcalloc(array.raid_disks, 1); for (d = 0; d < array.raid_disks; d++) { - char *dv, *dv_rep; - dv = map_dev_preferred(disks[d*2].major, - disks[d*2].minor, 0, c->prefer); - dv_rep = map_dev_preferred(disks[d*2+1].major, - disks[d*2+1].minor, 0, c->prefer); - - if ((dv && (disks[d*2].state & (1<<MD_DISK_SYNC))) || - (dv_rep && (disks[d*2+1].state & (1<<MD_DISK_SYNC)))) { + char dv[PATH_MAX], dv_rep[PATH_MAX]; + snprintf(dv, PATH_MAX, "/sys/dev/block/%d:%d", + disks[d*2].major, disks[d*2].minor); + snprintf(dv_rep, PATH_MAX, "/sys/dev/block/%d:%d", + disks[d*2+1].major, disks[d*2+1].minor); + + if ((is_dev_alive(dv) && (disks[d*2].state & (1<<MD_DISK_SYNC))) || + (is_dev_alive(dv_rep) && (disks[d*2+1].state & (1<<MD_DISK_SYNC)))) { avail_disks ++; avail[d] = 1; } else |