summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDan Williams <dan.j.williams@intel.com>2008-09-28 12:12:06 -0700
committerDan Williams <dan.j.williams@intel.com>2008-10-15 14:15:51 -0700
commit0dd3ba30aa1fbab2d7e62fca5169789ceb62b3f1 (patch)
tree9eafafde61587a4635c9cb8bbfa3d9d26c7c2a86
parent593add1b56877a6881419c2496eb26dd1f82d39b (diff)
downloadmdadm-0dd3ba30aa1fbab2d7e62fca5169789ceb62b3f1.tar.gz
mdadm-0dd3ba30aa1fbab2d7e62fca5169789ceb62b3f1.tar.xz
mdadm-0dd3ba30aa1fbab2d7e62fca5169789ceb62b3f1.zip
--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 <dan.j.williams@intel.com>
-rw-r--r--Monitor.c35
-rw-r--r--sysfs.c5
2 files changed, 26 insertions, 14 deletions
diff --git a/Monitor.c b/Monitor.c
index 3197b42..8d8939c 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 291a1dc..23d2f18 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);
}