#include "mdadm.h"
#include "dlink.h"
+#include <sys/select.h>
void free_mdstat(struct mdstat_ent *ms)
{
}
}
-struct mdstat_ent *mdstat_read()
+static int mdstat_fd = -1;
+struct mdstat_ent *mdstat_read(int hold)
{
FILE *f;
struct mdstat_ent *all, **end;
char *line;
- f = fopen("/proc/mdstat", "r");
+ if (hold && mdstat_fd != -1) {
+ lseek(mdstat_fd, 0L, 0);
+ f = fdopen(dup(mdstat_fd), "r");
+ } else
+ f = fopen("/proc/mdstat", "r");
if (f == NULL)
return NULL;
for (; (line = conf_line(f)) ; free_line(line)) {
struct mdstat_ent *ent;
char *w;
+ int devnum;
+ char *ep;
if (strcmp(line, "Personalities")==0)
continue;
if (strcmp(line, "unused")==0)
continue;
/* Better be an md line.. */
- if (strncmp(line, "md", 2)!= 0
- || atoi(line+2)<0) {
- fprintf(stderr, Name ": bad /proc/mdstat line starts: %s\n", line);
+ if (strncmp(line, "md", 2)!= 0)
+ continue;
+ if (strncmp(line, "md_d", 4) == 0)
+ devnum = -1-strtoul(line+4, &ep, 10);
+ else if (strncmp(line, "md", 2) == 0)
+ devnum = strtoul(line+2, &ep, 10);
+ else
+ continue;
+ if (ep == NULL || *ep ) {
+ /* fprintf(stderr, Name ": bad /proc/mdstat line starts: %s\n", line); */
continue;
}
if (!ent) {
fprintf(stderr, Name ": malloc failed reading /proc/mdstat.\n");
free_line(line);
- fclose(f);
- return all;
+ break;
}
ent->dev = ent->level = ent->pattern= NULL;
ent->next = NULL;
ent->percent = -1;
ent->active = -1;
+ ent->resync = 0;
ent->dev = strdup(line);
- ent->devnum = atoi(line+2);
+ ent->devnum = devnum;
for (w=dl_next(line); w!= line ; w=dl_next(w)) {
int l = strlen(w);
w[l-1] == '%' &&
(eq=strchr(w, '=')) != NULL ) {
ent->percent = atoi(eq+1);
+ if (strncmp(w,"resync", 4)==0)
+ ent->resync = 1;
+ } else if (ent->percent == -1 &&
+ strncmp(w, "resync", 4)==0) {
+ ent->resync = 1;
} else if (ent->percent == -1 &&
w[0] >= '0' &&
w[0] <= '9' &&
*end = ent;
end = &ent->next;
}
+ if (hold && mdstat_fd == -1)
+ mdstat_fd = dup(fileno(f));
fclose(f);
return all;
}
+
+void mdstat_wait(int seconds)
+{
+ fd_set fds;
+ struct timeval tm;
+ FD_ZERO(&fds);
+ if (mdstat_fd >= 0)
+ FD_SET(mdstat_fd, &fds);
+ tm.tv_sec = seconds;
+ tm.tv_usec = 0;
+ select(mdstat_fd >2 ? mdstat_fd+1:3, NULL, NULL, &fds, &tm);
+}