diff options
author | NeilBrown <neilb@suse.de> | 2010-01-29 15:45:36 +1100 |
---|---|---|
committer | NeilBrown <neilb@suse.de> | 2010-01-29 15:46:23 +1100 |
commit | d998adc316299efc44cb6e70ecc2e04bffb76d17 (patch) | |
tree | d1dd39b203d2af87adb1b3df5081a8da09f4e22d /Detail.c | |
parent | a1331cc4068d4c0723dd46f3a170ed100adba000 (diff) |
Detail: Report state of FAILED when an array has too few devices to work.
We already have a call to 'enough' in Detail which is the check for
"do we have enough devices". We just need to calculate the required
data a bit earlier, then use the same 'enough' call to possibly
print FAILED.
This is motivated by Debian bug 495755.
The other request in that bug is not practical.
It would be very nice if output of `mdadm' is more clear in case of a
broken array.
Currently the only hint you get from `mdadm' that your array is broken
is this:
# mdadm -A /dev/md0 /dev/sdc1 /dev/sdd1 /dev/sde1 /dev/sdf1
mdadm: /dev/md0 assembled from 1 drive and 3 spares - not enough to start the
array.
It could say something like `Your array is broken, you can't use it anymore'
It is not valid to report that array as 'broken' if the user hasn't
listed all the devices, which could be the case here.
Resolves-Debian-Bug: 495755
Signed-off-by: NeilBrown <neilb@suse.de>
Diffstat (limited to 'Detail.c')
-rw-r--r-- | Detail.c | 80 |
1 files changed, 48 insertions, 32 deletions
@@ -207,6 +207,42 @@ int Detail(char *dev, int brief, int export, int test, char *homehost) goto out; } + disks = malloc(max_disks * sizeof(mdu_disk_info_t)); + for (d=0; d<max_disks; d++) { + disks[d].state = (1<<MD_DISK_REMOVED); + disks[d].major = disks[d].minor = 0; + disks[d].number = disks[d].raid_disk = d; + } + + next = array.raid_disks; + for (d=0; d < max_disks; d++) { + mdu_disk_info_t disk; + disk.number = d; + if (ioctl(fd, GET_DISK_INFO, &disk) < 0) { + if (d < array.raid_disks) + fprintf(stderr, Name ": cannot get device detail for device %d: %s\n", + d, strerror(errno)); + continue; + } + if (disk.major == 0 && disk.minor == 0) + continue; + if (disk.raid_disk >= 0 && disk.raid_disk < array.raid_disks) + disks[disk.raid_disk] = disk; + else if (next < max_disks) + disks[next++] = disk; + } + + avail = calloc(array.raid_disks, 1); + + for (d= 0; d < array.raid_disks; d++) { + mdu_disk_info_t disk = disks[d]; + + if ((disk.state & (1<<MD_DISK_SYNC))) { + avail_disks ++; + avail[d] = 1; + } + } + if (brief) { mdu_bitmap_file_t bmf; printf("ARRAY %s", dev); @@ -306,13 +342,23 @@ int Detail(char *dev, int brief, int export, int test, char *homehost) atime = array.utime; if (atime) printf(" Update Time : %.24s\n", ctime(&atime)); - if (array.raid_disks) + if (array.raid_disks) { + char *st; + if (avail_disks == array.raid_disks) + st = ""; + else if (!enough(array.level, array.raid_disks, + array.layout, 1, avail, avail_disks)) + st = ", FAILED"; + else + st = ", degraded"; + printf(" State : %s%s%s%s\n", (array.state&(1<<MD_SB_CLEAN))?"clean":"active", - array.active_disks < array.raid_disks? ", degraded":"", + st, (!e || e->percent < 0) ? "" : (e->resync) ? ", resyncing": ", recovering", larray_size ? "": ", Not Started"); + } if (array.raid_disks) printf(" Active Devices : %d\n", array.active_disks); printf("Working Devices : %d\n", array.working_disks); @@ -442,32 +488,7 @@ This is pretty boring else printf(" Number Major Minor RaidDevice\n"); } - disks = malloc(max_disks * sizeof(mdu_disk_info_t)); - for (d=0; d<max_disks; d++) { - disks[d].state = (1<<MD_DISK_REMOVED); - disks[d].major = disks[d].minor = 0; - disks[d].number = disks[d].raid_disk = d; - } - next = array.raid_disks; - for (d=0; d < max_disks; d++) { - mdu_disk_info_t disk; - disk.number = d; - if (ioctl(fd, GET_DISK_INFO, &disk) < 0) { - if (d < array.raid_disks) - fprintf(stderr, Name ": cannot get device detail for device %d: %s\n", - d, strerror(errno)); - continue; - } - if (disk.major == 0 && disk.minor == 0) - continue; - if (disk.raid_disk >= 0 && disk.raid_disk < array.raid_disks) - disks[disk.raid_disk] = disk; - else if (next < max_disks) - disks[next++] = disk; - } - - avail = calloc(array.raid_disks, 1); for (d= 0; d < max_disks; d++) { char *dv; mdu_disk_info_t disk = disks[d]; @@ -520,11 +541,6 @@ This is pretty boring if (test && d < array.raid_disks && !(disk.state & (1<<MD_DISK_SYNC))) rv |= 1; - if (d < array.raid_disks - && (disk.state & (1<<MD_DISK_SYNC))) { - avail_disks ++; - avail[d] = 1; - } if ((dv=map_dev(disk.major, disk.minor, 0))) { if (brief) { if (devices) { |