summaryrefslogtreecommitdiff
path: root/Detail.c
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.de>2010-01-29 15:45:36 +1100
committerNeilBrown <neilb@suse.de>2010-01-29 15:46:23 +1100
commitd998adc316299efc44cb6e70ecc2e04bffb76d17 (patch)
treed1dd39b203d2af87adb1b3df5081a8da09f4e22d /Detail.c
parenta1331cc4068d4c0723dd46f3a170ed100adba000 (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.c80
1 files changed, 48 insertions, 32 deletions
diff --git a/Detail.c b/Detail.c
index ba07c83d..3d6b10fd 100644
--- a/Detail.c
+++ b/Detail.c
@@ -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) {