diff options
Diffstat (limited to 'mdstat.c')
-rw-r--r-- | mdstat.c | 79 |
1 files changed, 61 insertions, 18 deletions
@@ -86,6 +86,7 @@ #include "mdadm.h" #include "dlink.h" #include <sys/select.h> +#include <ctype.h> void free_mdstat(struct mdstat_ent *ms) { @@ -94,6 +95,7 @@ void free_mdstat(struct mdstat_ent *ms) if (ms->dev) free(ms->dev); if (ms->level) free(ms->level); if (ms->pattern) free(ms->pattern); + if (ms->metadata_version) free(ms->metadata_version); t = ms; ms = ms->next; free(t); @@ -158,6 +160,10 @@ struct mdstat_ent *mdstat_read(int hold, int start) ent->percent = -1; ent->active = -1; ent->resync = 0; + ent->metadata_version = NULL; + ent->raid_disks = 0; + ent->chunk_size = 0; + ent->devcnt = 0; ent->dev = strdup(line); ent->devnum = devnum; @@ -176,22 +182,28 @@ struct mdstat_ent *mdstat_read(int hold, int start) in_devs = 1; } else if (in_devs && strcmp(w, "blocks")==0) in_devs = 0; - else if (in_devs && strncmp(w, "md", 2)==0) { - /* This has an md device as a component. - * If that device is already in the list, - * make sure we insert before there. - */ - struct mdstat_ent **ih; - int dn2; - if (strncmp(w, "md_d", 4)==0) - dn2 = -1-strtoul(w+4, &ep, 10); - else - dn2 = strtoul(w+2, &ep, 10); - ih = &all; - while (ih != insert_here && *ih && - (*ih)->devnum != dn2) - ih = & (*ih)->next; - insert_here = ih; + else if (in_devs) { + ent->devcnt++; + if (strncmp(w, "md", 2)==0) { + /* This has an md device as a component. + * If that device is already in the + * list, make sure we insert before + * there. + */ + struct mdstat_ent **ih; + int dn2 = devname2devnum(w); + ih = &all; + while (ih != insert_here && *ih && + (*ih)->devnum != dn2) + ih = & (*ih)->next; + insert_here = ih; + } + } else if (strcmp(w, "super") == 0 && + dl_next(w) != line) { + w = dl_next(w); + ent->metadata_version = strdup(w); + } else if (w[0] == '[' && isdigit(w[1])) { + ent->raid_disks = atoi(w+1); } else if (!ent->pattern && w[0] == '[' && (w[1] == 'U' || w[1] == '_')) { @@ -248,12 +260,43 @@ void mdstat_wait(int seconds) { fd_set fds; struct timeval tm; + int maxfd = 0; FD_ZERO(&fds); - if (mdstat_fd >= 0) + if (mdstat_fd >= 0) { FD_SET(mdstat_fd, &fds); + maxfd = mdstat_fd; + } tm.tv_sec = seconds; tm.tv_usec = 0; - select(mdstat_fd >2 ? mdstat_fd+1:3, NULL, NULL, &fds, &tm); + select(maxfd + 1, NULL, NULL, &fds, &tm); +} + +void mdstat_wait_fd(int fd, const sigset_t *sigmask) +{ + fd_set fds, rfds; + int maxfd = fd; + + FD_ZERO(&fds); + FD_ZERO(&rfds); + if (mdstat_fd >= 0) + FD_SET(mdstat_fd, &fds); + if (fd >= 0) { + struct stat stb; + fstat(fd, &stb); + if ((stb.st_mode & S_IFMT) == S_IFREG) + /* Must be a /proc or /sys fd, so expect + * POLLPRI + * i.e. an 'exceptional' event. + */ + FD_SET(fd, &fds); + else + FD_SET(fd, &rfds); + } + if (mdstat_fd > maxfd) + maxfd = mdstat_fd; + + pselect(maxfd + 1, &rfds, NULL, &fds, + NULL, sigmask); } int mddev_busy(int devnum) |