summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.de>2011-03-22 16:10:22 +1100
committerNeilBrown <neilb@suse.de>2011-03-22 16:10:22 +1100
commitd998b738f5b91e6058659b459e5b9e3717d085f6 (patch)
tree18a7e8eeff84004a86e0c37753acc8da9dcfc9f0
parent4e2c1a9a32c8e4c85bc699ff425a75bd5c594f8e (diff)
downloadmdadm-d998b738f5b91e6058659b459e5b9e3717d085f6.tar.gz
mdmon: don't wait for O_EXCL when shutting down.
If mdmon is shutting down because there are no devices left to look at, then don't wait 5 seconds for an O_EXCL open, and that can block progress of --grow. Only wait for O_EXCL if we received a signal. Signed-off-by: NeilBrown <neilb@suse.de>
-rw-r--r--mdadm.h1
-rw-r--r--monitor.c16
-rw-r--r--util.c9
3 files changed, 22 insertions, 4 deletions
diff --git a/mdadm.h b/mdadm.h
index d3ed50a..fa5af3a 100644
--- a/mdadm.h
+++ b/mdadm.h
@@ -1086,6 +1086,7 @@ extern int check_partitions(int fd, char *dname,
extern int get_mdp_major(void);
extern int dev_open(char *dev, int flags);
extern int open_dev(int devnum);
+extern int open_dev_flags(int devnum, int flags);
extern int open_dev_excl(int devnum);
extern int is_standard(char *dev, int *nump);
extern int same_dev(char *one, char *two);
diff --git a/monitor.c b/monitor.c
index 8e0f1b7..69026ca 100644
--- a/monitor.c
+++ b/monitor.c
@@ -563,7 +563,11 @@ static int wait_and_act(struct supertype *container, int nowait)
* problem as there are no active arrays, there is
* nothing that we need to be ready to do.
*/
- int fd = open_dev_excl(container->devnum);
+ int fd;
+ if (sigterm)
+ fd = open_dev_excl(container->devnum);
+ else
+ fd = open_dev_flags(container->devnum, O_RDONLY|O_EXCL);
if (fd >= 0 || errno != EBUSY) {
/* OK, we are safe to leave */
if (sigterm && !dirty_arrays)
@@ -584,10 +588,18 @@ static int wait_and_act(struct supertype *container, int nowait)
if (!nowait) {
sigset_t set;
+ struct timespec ts;
+ ts.tv_sec = 24*3600;
+ ts.tv_nsec = 0;
+ if (*aap == NULL) {
+ /* just waiting to get O_EXCL access */
+ ts.tv_sec = 0;
+ ts.tv_nsec = 20000000ULL;
+ }
sigprocmask(SIG_UNBLOCK, NULL, &set);
sigdelset(&set, SIGUSR1);
monitor_loop_cnt |= 1;
- rv = pselect(maxfd+1, NULL, NULL, &rfds, NULL, &set);
+ rv = pselect(maxfd+1, NULL, NULL, &rfds, &ts, &set);
monitor_loop_cnt += 1;
if (rv == -1 && errno == EINTR)
rv = 0;
diff --git a/util.c b/util.c
index cc6ccb4..8e1b737 100644
--- a/util.c
+++ b/util.c
@@ -998,12 +998,17 @@ int dev_open(char *dev, int flags)
return fd;
}
-int open_dev(int devnum)
+int open_dev_flags(int devnum, int flags)
{
char buf[20];
sprintf(buf, "%d:%d", dev2major(devnum), dev2minor(devnum));
- return dev_open(buf, O_RDONLY);
+ return dev_open(buf, flags);
+}
+
+int open_dev(int devnum)
+{
+ return open_dev_flags(devnum, O_RDONLY);
}
int open_dev_excl(int devnum)