From 0dd3ba30aa1fbab2d7e62fca5169789ceb62b3f1 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Sun, 28 Sep 2008 12:12:06 -0700 Subject: [PATCH] --wait-clean: shorten timeout 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 --- Monitor.c | 35 +++++++++++++++++++++++------------ sysfs.c | 5 +++-- 2 files changed, 26 insertions(+), 14 deletions(-) diff --git a/Monitor.c b/Monitor.c index 3197b42a..8d8939ce 100644 --- 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 291a1dc3..23d2f18d 100644 --- 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); } -- 2.39.2