]> git.ipfire.org Git - thirdparty/mdadm.git/blobdiff - mdstat.c
Support external metadata recovery-resume
[thirdparty/mdadm.git] / mdstat.c
index 040df150c74cec0eb5b64597ad604d0c80129fcb..4d2f473eb09a5b4714dda91fad6c222609c866b2 100644 (file)
--- a/mdstat.c
+++ b/mdstat.c
@@ -2,7 +2,7 @@
  * mdstat - parse /proc/mdstat file. Part of:
  * mdadm - manage Linux "md" devices aka RAID arrays.
  *
- * Copyright (C) 2002-2006 Neil Brown <neilb@suse.de>
+ * Copyright (C) 2002-2009 Neil Brown <neilb@suse.de>
  *
  *
  *    This program is free software; you can redistribute it and/or modify
  *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
  *    Author: Neil Brown
- *    Email: <neilb@cse.unsw.edu.au>
- *    Paper: Neil Brown
- *           School of Computer Science and Engineering
- *           The University of New South Wales
- *           Sydney, 2052
- *           Australia
+ *    Email: <neilb@suse.de>
  */
 
 /*
@@ -191,11 +186,7 @@ struct mdstat_ent *mdstat_read(int hold, int start)
                                         * 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);
+                                       int dn2 = devname2devnum(w);
                                        ih = &all;
                                        while (ih != insert_here && *ih &&
                                               (*ih)->devnum != dn2)
@@ -264,25 +255,42 @@ 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);
-       FD_SET(fd, &rfds);
+       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(mdstat_fd >2 ? mdstat_fd+1:3, &rfds, NULL, &fds,
+       pselect(maxfd + 1, &rfds, NULL, &fds,
                NULL, sigmask);
 }