#include "md_p.h"
#include "md_u.h"
#include <sys/wait.h>
-#include <sys/signal.h>
+#include <signal.h>
#include <values.h>
#include <syslog.h>
mdstat = mdstat_read(oneshot?0:1, 0);
for (st=statelist; st; st=st->next) {
+ struct { int state, major, minor; } info[MaxDisks];
mdu_array_info_t array;
struct mdstat_ent *mse = NULL, *mse2;
char *dev = st->devname;
*/ st->err=1;
continue;
}
+ fcntl(fd, F_SETFD, FD_CLOEXEC);
if (ioctl(fd, GET_ARRAY_INFO, &array)<0) {
if (!st->err)
alert("DeviceDisappeared", dev, NULL,
close(fd);
continue;
}
- if (array.level != 1 && array.level != 5 && array.level != -4 &&
- array.level != 6 && array.level != 10) {
+ /* It's much easier to list what array levels can't
+ * have a device disappear than all of them that can
+ */
+ if (array.level == 0 || array.level == -1) {
if (!st->err)
alert("DeviceDisappeared", dev, "Wrong-Level",
mailaddr, mailfrom, alert_cmd, dosyslog);
if (mse)
st->percent = mse->percent;
- for (i=0; i<MaxDisks; i++) {
+
+ for (i=0; i<MaxDisks && i <= array.raid_disks + array.nr_disks;
+ i++) {
mdu_disk_info_t disc;
+ disc.number = i;
+ if (ioctl(fd, GET_DISK_INFO, &disc) >= 0) {
+ info[i].state = disc.state;
+ info[i].major = disc.major;
+ info[i].minor = disc.minor;
+ } else
+ info[i].major = info[i].minor = 0;
+ }
+ close(fd);
+
+ for (i=0; i<MaxDisks; i++) {
+ mdu_disk_info_t disc = {0};
int newstate=0;
int change;
char *dv = NULL;
if (i > array.raid_disks + array.nr_disks) {
newstate = 0;
disc.major = disc.minor = 0;
- } else if (ioctl(fd, GET_DISK_INFO, &disc)>= 0) {
- newstate = disc.state;
- dv = map_dev(disc.major, disc.minor, 1);
+ } else if (info[i].major || info[i].minor) {
+ newstate = info[i].state;
+ dv = map_dev(info[i].major, info[i].minor, 1);
+ disc.state = newstate;
+ disc.major = info[i].major;
+ disc.minor = info[i].minor;
} else if (mse && mse->pattern && i < strlen(mse->pattern)) {
switch(mse->pattern[i]) {
case 'U': newstate = 6 /* ACTIVE/SYNC */; break;
)
alert("SpareActive", dev, dv, mailaddr, mailfrom, alert_cmd, dosyslog);
}
- st->devstate[i] = disc.state;
+ st->devstate[i] = newstate;
st->devid[i] = makedev(disc.major, disc.minor);
}
- close(fd);
st->active = array.active_disks;
st->working = array.working_disks;
st->spare = array.spare_disks;
struct mdstat_ent *mse;
for (mse=mdstat; mse; mse=mse->next)
if (mse->devnum != MAXINT &&
- (strcmp(mse->level, "raid1")==0 ||
- strcmp(mse->level, "raid5")==0 ||
- strcmp(mse->level, "multipath")==0)
+ (strcmp(mse->level, "raid0")!=0 &&
+ strcmp(mse->level, "linear")!=0)
) {
struct state *st = malloc(sizeof *st);
mdu_array_info_t array;
if (major(stb.st_rdev) == MD_MAJOR)
devnum = minor(stb.st_rdev);
else
- devnum = -minor(stb.st_rdev)/16;
+ devnum = -1-(minor(stb.st_rdev)/64);
while(1) {
struct mdstat_ent *ms = mdstat_read(1, 0);