summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.de>2013-07-01 13:28:13 +1000
committerNeilBrown <neilb@suse.de>2013-07-01 13:28:13 +1000
commitefc67e8e9fe430d5833236f16ea287ef363dadc5 (patch)
tree4da51e5aa6580aa3ae63eaf318fe16d93ad59163
parenta2836f12c4c45738b495403a91a0f0db2e88e0cb (diff)
New function: sysfs_wait
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>
-rw-r--r--Grow.c28
-rw-r--r--Monitor.c10
-rw-r--r--mdadm.h1
-rw-r--r--super-intel.c5
-rw-r--r--sysfs.c29
5 files changed, 41 insertions, 32 deletions
diff --git a/Grow.c b/Grow.c
index 1d0c7ce2..0e20b240 100644
--- 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;
}
}
diff --git a/Monitor.c b/Monitor.c
index 86df18c2..c1a5d60d 100644
--- 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 2633b89e..13ea26a0 100644
--- 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,
diff --git a/super-intel.c b/super-intel.c
index 7a4260cb..27c725fc 100644
--- a/super-intel.c
+++ b/super-intel.c
@@ -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 cde8f197..b7d41a57 100644
--- 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;
+}