]> git.ipfire.org Git - thirdparty/mdadm.git/commitdiff
--wait-clean: shorten timeout
authorDan Williams <dan.j.williams@intel.com>
Sun, 28 Sep 2008 19:12:06 +0000 (12:12 -0700)
committerDan Williams <dan.j.williams@intel.com>
Wed, 15 Oct 2008 21:15:51 +0000 (14:15 -0700)
Set the safemode timeout to a small value to get the array marked clean as
soon as possible.  We don't write 'clean' directly as it may cause mdmon to
miss a 'write-pending' event.

Include a couple fixes to sysfs_set_safemode():
1/ 0 pad the milliseconds field
2/ workaround input truncation in the kernel

Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Monitor.c
sysfs.c

index 3197b42a37b86daeb6856747ea253b38a3fec058..8d8939cef7ad190def2619e6d3f6acb4f51512f2 100644 (file)
--- a/Monitor.c
+++ b/Monitor.c
@@ -675,41 +675,52 @@ int WaitClean(char *dev)
 
        if (rv) {
                int state_fd = sysfs_open(fd2devnum(fd), NULL, "array_state");
-               unsigned long secs;
                char buf[20];
+               fd_set fds;
+               struct timeval tm;
 
-               secs = mdi->safe_mode_delay / 1000;
-               if (mdi->safe_mode_delay - secs * 1000)
-                       secs++;
-               secs *= 2;
+               /* 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);
 
-               for (; secs; secs--) {
+               /* wait for array_state to be clean */
+               while (1) {
                        rv = read(state_fd, buf, sizeof(buf));
                        if (rv < 0)
                                break;
                        if (sysfs_match_word(buf, clean_states) <= 4)
                                break;
-                       sleep(1);
+                       FD_SET(state_fd, &fds);
+                       rv = select(state_fd + 1, &fds, NULL, NULL, &tm);
+                       if (rv < 0 && errno != EINTR)
+                               break;
                        lseek(state_fd, 0, SEEK_SET);
                }
                if (rv < 0)
                        rv = 1;
-               else if (secs) {
+               else if (ping_monitor(mdi->text_version) == 0) {
                        /* we need to ping to close the window between array
                         * state transitioning to clean and the metadata being
                         * marked clean
                         */
-                       if (ping_monitor(mdi->text_version) == 0)
-                               rv = 0;
-               }
+                       rv = 0;
+               } else
+                       rv = 1;
                if (rv)
                        fprintf(stderr, Name ": Error waiting for %s to be clean\n",
                                dev);
 
+               /* restore the original safe_mode_delay */
+               sysfs_set_safemode(mdi, mdi->safe_mode_delay);
                close(state_fd);
        }
 
-       sysfs_free(mdi);                
+       sysfs_free(mdi);
        close(fd);
 
        return rv;
diff --git a/sysfs.c b/sysfs.c
index 291a1dc3467b3ea2e165ac85e640db265e60fa74..23d2f18d87d172fd3e9b5ce8ece71dec71733ae1 100644 (file)
--- a/sysfs.c
+++ b/sysfs.c
@@ -436,9 +436,10 @@ int sysfs_set_safemode(struct mdinfo *sra, unsigned long ms)
        char delay[30];
 
        sec = ms / 1000;
-       msec = ms - (sec * 1000);
+       msec = ms % 1000;
 
-       sprintf(delay, "%ld.%ld", sec, msec);
+       sprintf(delay, "%ld.%03ld\n", sec, msec);
+       /*             this '\n' ^ needed for kernels older than 2.6.28 */
        return sysfs_set_str(sra, NULL, "safe_mode_delay", delay);
 }