From: NeilBrown Date: Tue, 14 Apr 2009 04:59:24 +0000 (+1000) Subject: Wait for POLLPRI on /proc or /sys files. X-Git-Tag: mdadm-3.0-rc1~27 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2800528713cd32a4d12d7e17c14eba34eb8a4ec2;p=thirdparty%2Fmdadm.git Wait for POLLPRI on /proc or /sys files. From 2.6.30, /proc/mounts and various /sys files will probably always returns 'readable' to select, so we will need to wait on POLLPRI to get the 'new data is available' signal. When using select, this corresponds to an 'exception', so adjust calls to select accordingly. In one case we sometimes wait on a socket and sometime on /proc/mounts, so we need to test which. Signed-off-by: NeilBrown --- diff --git a/Monitor.c b/Monitor.c index af531294..2677f7bf 100644 --- a/Monitor.c +++ b/Monitor.c @@ -706,7 +706,7 @@ int WaitClean(char *dev, int verbose) if (sysfs_match_word(buf, clean_states) <= 4) break; FD_SET(state_fd, &fds); - rv = select(state_fd + 1, &fds, NULL, NULL, &tm); + rv = select(state_fd + 1, NULL, NULL, &fds, &tm); if (rv < 0 && errno != EINTR) break; lseek(state_fd, 0, SEEK_SET); diff --git a/mdstat.c b/mdstat.c index ebdfc67b..8de51cf7 100644 --- a/mdstat.c +++ b/mdstat.c @@ -280,8 +280,18 @@ void mdstat_wait_fd(int fd, const sigset_t *sigmask) FD_ZERO(&rfds); if (mdstat_fd >= 0) FD_SET(mdstat_fd, &fds); - if (fd >= 0) - FD_SET(fd, &rfds); + if (fd >= 0) { + struct stat stb; + fstat(fd, &stb); + if ((stb.st_mode & S_IFMT) == S_IFREG) + /* Must be a /proc or /sys fd, so expect + * POLLPRI + * i.e. an 'exceptional' event. + */ + FD_SET(fd, &fds); + else + FD_SET(fd, &rfds); + } if (mdstat_fd > maxfd) maxfd = mdstat_fd; diff --git a/monitor.c b/monitor.c index 3388d31c..66fea80e 100644 --- a/monitor.c +++ b/monitor.c @@ -498,7 +498,7 @@ static int wait_and_act(struct supertype *container, int nowait) sigprocmask(SIG_UNBLOCK, NULL, &set); sigdelset(&set, SIGUSR1); monitor_loop_cnt |= 1; - rv = pselect(maxfd+1, &rfds, NULL, NULL, NULL, &set); + rv = pselect(maxfd+1, NULL, NULL, &rfds, NULL, &set); monitor_loop_cnt += 1; if (rv == -1 && errno == EINTR) rv = 0;