]> git.ipfire.org Git - thirdparty/mdadm.git/commitdiff
New function: sysfs_wait
authorNeilBrown <neilb@suse.de>
Mon, 1 Jul 2013 03:28:13 +0000 (13:28 +1000)
committerNeilBrown <neilb@suse.de>
Mon, 1 Jul 2013 03:28:13 +0000 (13:28 +1000)
We have several places that wait for activity on a sysfs
file.  Combine most of these into a single 'sysfs_wait' function.

Signed-off-by: NeilBrown <neilb@suse.de>
Grow.c
Monitor.c
mdadm.h
super-intel.c
sysfs.c

diff --git a/Grow.c b/Grow.c
index 1d0c7ce2b2d1db9a480f12ab5af36622a13620b8..0e20b240df61cf211e3fd3263cfc3de2c87e0f78 100644 (file)
--- a/Grow.c
+++ b/Grow.c
@@ -626,13 +626,9 @@ static void wait_reshape(struct mdinfo *sra)
        if (fd < 0)
                return;
 
-       while  (sysfs_fd_get_str(fd, action, 20) > 0 &&
-               strncmp(action, "reshape", 7) == 0) {
-               fd_set rfds;
-               FD_ZERO(&rfds);
-               FD_SET(fd, &rfds);
-               select(fd+1, NULL, NULL, &rfds, NULL);
-       }
+       while (sysfs_fd_get_str(fd, action, 20) > 0 &&
+              strncmp(action, "reshape", 7) == 0)
+               sysfs_wait(fd, NULL);
        close(fd);
 }
 
@@ -3777,7 +3773,6 @@ int progress_reshape(struct mdinfo *info, struct reshape *reshape,
                 * waiting forever on a dead array
                 */
                char action[20];
-               fd_set rfds;
                if (sysfs_get_str(info, NULL, "sync_action",
                                  action, 20) <= 0 ||
                    strncmp(action, "reshape", 7) != 0)
@@ -3793,9 +3788,7 @@ int progress_reshape(struct mdinfo *info, struct reshape *reshape,
                    && info->reshape_progress < (info->component_size
                                                 * reshape->after.data_disks))
                        break;
-               FD_ZERO(&rfds);
-               FD_SET(fd, &rfds);
-               select(fd+1, NULL, NULL, &rfds, NULL);
+               sysfs_wait(fd, NULL);
                if (sysfs_fd_get_ll(fd, &completed) < 0)
                        goto check_progress;
        }
@@ -3840,15 +3833,10 @@ check_progress:
                /* The abort might only be temporary.  Wait up to 10
                 * seconds for fd to contain a valid number again.
                 */
-               struct timeval tv;
+               int wait = 10000;
                int rv = -2;
-               tv.tv_sec = 10;
-               tv.tv_usec = 0;
-               while (fd >= 0 && rv < 0 && tv.tv_sec > 0) {
-                       fd_set rfds;
-                       FD_ZERO(&rfds);
-                       FD_SET(fd, &rfds);
-                       if (select(fd+1, NULL, NULL, &rfds, &tv) != 1)
+               while (fd >= 0 && rv < 0 && wait > 0) {
+                       if (sysfs_wait(fd, &wait) != 1)
                                break;
                        switch (sysfs_fd_get_ll(fd, &completed)) {
                        case 0:
@@ -3856,7 +3844,7 @@ check_progress:
                                rv = 1;
                                break;
                        case -2: /* read error - abort */
-                               tv.tv_sec = 0;
+                               wait = 0;
                                break;
                        }
                }
index 86df18c264caf20e5a5f342ba0e45d5938ac754b..c1a5d60d91f671d164fa010d3c6d25a6dd4542ca 100644 (file)
--- a/Monitor.c
+++ b/Monitor.c
@@ -1050,17 +1050,12 @@ int WaitClean(char *dev, int sock, int verbose)
        if (rv) {
                int state_fd = sysfs_open(fd2devnm(fd), NULL, "array_state");
                char buf[20];
-               fd_set fds;
-               struct timeval tm;
+               int delay = 5000;
 
                /* minimize the safe_mode_delay and prepare to wait up to 5s
                 * for writes to quiesce
                 */
                sysfs_set_safemode(mdi, 1);
-               tm.tv_sec = 5;
-               tm.tv_usec = 0;
-
-               FD_ZERO(&fds);
 
                /* wait for array_state to be clean */
                while (1) {
@@ -1069,8 +1064,7 @@ int WaitClean(char *dev, int sock, int verbose)
                                break;
                        if (sysfs_match_word(buf, clean_states) <= 4)
                                break;
-                       FD_SET(state_fd, &fds);
-                       rv = select(state_fd + 1, NULL, NULL, &fds, &tm);
+                       rv = sysfs_wait(state_fd, &delay);
                        if (rv < 0 && errno != EINTR)
                                break;
                        lseek(state_fd, 0, SEEK_SET);
diff --git a/mdadm.h b/mdadm.h
index 2633b89e6c1b276cfa9b6bb1313109ac81a1df08..13ea26a0bda45f49be101817236c72355bf4d7a6 100644 (file)
--- a/mdadm.h
+++ b/mdadm.h
@@ -549,6 +549,7 @@ extern int sysfs_add_disk(struct mdinfo *sra, struct mdinfo *sd, int resume);
 extern int sysfs_disk_to_scsi_id(int fd, __u32 *id);
 extern int sysfs_unique_holder(char *devnm, long rdev);
 extern int sysfs_freeze_array(struct mdinfo *sra);
+extern int sysfs_wait(int fd, int *msec);
 extern int load_sys(char *path, char *buf);
 extern int reshape_prepare_fdlist(char *devname,
                                  struct mdinfo *sra,
index 7a4260cb6bbe54b9308a1462d0084aa4584c702c..27c725fcfa62d942f8eff8e572b2bab30a170d67 100644 (file)
@@ -10163,10 +10163,7 @@ int wait_for_reshape_imsm(struct mdinfo *sra, int ndata)
 
        do {
                char action[20];
-               fd_set rfds;
-               FD_ZERO(&rfds);
-               FD_SET(fd, &rfds);
-               select(fd+1, &rfds, NULL, NULL, NULL);
+               sysfs_wait(fd, NULL);
                if (sysfs_get_str(sra, NULL, "sync_action",
                                  action, 20) > 0 &&
                                strncmp(action, "reshape", 7) != 0)
diff --git a/sysfs.c b/sysfs.c
index cde8f1970de6c4e98002ea940727dec7f4cdc82c..b7d41a579902d1dba3be49604336a391c1a068c5 100644 (file)
--- a/sysfs.c
+++ b/sysfs.c
@@ -844,3 +844,32 @@ int sysfs_freeze_array(struct mdinfo *sra)
                return 0;
        return 1;
 }
+
+int sysfs_wait(int fd, int *msec)
+{
+       /* Wait up to '*msec' for fd to have an exception condition.
+        * if msec == NULL, wait indefinitely.
+        */
+       fd_set fds;
+       int n;
+       FD_ZERO(&fds);
+       FD_SET(fd, &fds);
+       if (msec == NULL)
+               n = select(fd+1, NULL, NULL, &fds, NULL);
+       else if (*msec < 0)
+               n = 0;
+       else {
+               struct timeval start, end, tv;
+               gettimeofday(&start, NULL);
+               if (*msec < 1000)
+                       tv.tv_usec = (*msec)*1000;
+               else
+                       tv.tv_sec = (*msec)/1000;
+               n = select(fd+1, NULL, NULL, &fds, &tv);
+               gettimeofday(&end, NULL);
+               end.tv_sec -= start.tv_sec;
+               *msec -= (end.tv_sec * 1000 + end.tv_usec/1000
+                         - start.tv_usec/100) + 1;
+       }
+       return n;
+}