summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNeil Brown <neilb@suse.de>2008-05-27 09:18:41 +1000
committerNeil Brown <neilb@suse.de>2008-05-27 09:18:41 +1000
commite0d6609fe6b0fe6a74705d1f1c1cf4a0d3a71db8 (patch)
tree4e1a2f6c44d2ae2a943de26178edab3462e723c9
parent5869a76c90aa0725e665d3c7bd6c7ab021d24fd4 (diff)
Exit when there are no more arrays to manage.
-rw-r--r--managemon.c6
-rw-r--r--mdadm.h1
-rw-r--r--mdmon.c11
-rw-r--r--mdmon.h3
-rw-r--r--monitor.c21
5 files changed, 39 insertions, 3 deletions
diff --git a/managemon.c b/managemon.c
index aa10a993..971dcd1d 100644
--- a/managemon.c
+++ b/managemon.c
@@ -382,6 +382,8 @@ void wake_me(int sig)
woke = 1;
}
+int exit_now = 0;
+int manager_ready = 0;
void do_manager(struct supertype *container)
{
struct mdstat_ent *mdstat;
@@ -395,6 +397,9 @@ void do_manager(struct supertype *container)
do {
woke = 0;
+ if (exit_now)
+ exit(0);
+
mdstat = mdstat_read(1, 0);
manage(mdstat, container);
@@ -405,6 +410,7 @@ void do_manager(struct supertype *container)
remove_old();
+ manager_ready = 1;
sigprocmask(SIG_SETMASK, &block, &orig);
if (woke == 0)
mdstat_wait_fd(container->sock, &orig);
diff --git a/mdadm.h b/mdadm.h
index 7b11ffb1..5586dce4 100644
--- a/mdadm.h
+++ b/mdadm.h
@@ -460,6 +460,7 @@ struct supertype {
* external:/md0/12
*/
int devcnt;
+ char *device_name; /* e.g. /dev/md/whatever */
struct mdinfo *devs;
diff --git a/mdmon.c b/mdmon.c
index 2919a02f..323ee62e 100644
--- a/mdmon.c
+++ b/mdmon.c
@@ -146,6 +146,14 @@ static void try_kill_monitor(char *devname)
kill(pid, SIGTERM);
}
+void remove_pidfile(char *devname)
+{
+ char buf[100];
+
+ sprintf(buf, "/var/run/mdadm/%s.pid", devname);
+ unlink(buf);
+}
+
static int make_control_sock(char *devname)
{
char path[100];
@@ -198,6 +206,7 @@ int main(int argc, char *argv[])
container = malloc(sizeof(*container));
container->devnum = fd2devnum(mdfd);
container->devname = devnum2devname(container->devnum);
+ container->device_name = argv[1];
/* If this fails, we hope it already exists */
mkdir("/var/run/mdadm", 0600);
@@ -267,7 +276,7 @@ int main(int argc, char *argv[])
argv[1]);
exit(3);
}
-
+ close(mdfd);
close(mdfd);
mlockall(MCL_FUTURE);
diff --git a/mdmon.h b/mdmon.h
index 29349b7a..b84e270b 100644
--- a/mdmon.h
+++ b/mdmon.h
@@ -33,6 +33,7 @@ extern struct active_array *pending_discard;
extern struct md_generic_cmd *active_cmd;
+void remove_pidfile(char *devname);
void do_monitor(struct supertype *container);
void do_manager(struct supertype *container);
@@ -41,3 +42,5 @@ int read_dev_state(int fd);
struct mdstat_ent *mdstat_read(int hold, int start);
extern struct superswitch super_ddf, super_ddf_bvd, super_ddf_svd;
+
+extern int exit_now, manager_ready;
diff --git a/monitor.c b/monitor.c
index ead96d9d..a7e53080 100644
--- a/monitor.c
+++ b/monitor.c
@@ -436,11 +436,12 @@ static int handle_pipe(struct md_generic_cmd *cmd, struct active_array *aa)
return -1;
}
-static int wait_and_act(struct active_array **aap, int pfd,
+static int wait_and_act(struct supertype *container, int pfd,
int monfd, int nowait)
{
fd_set rfds;
int maxfd = 0;
+ struct active_array **aap = &container->arrays;
struct active_array *a, **ap;
int rv;
struct mdinfo *mdi;
@@ -473,6 +474,22 @@ static int wait_and_act(struct active_array **aap, int pfd,
ap = &(*ap)->next;
}
+ if (manager_ready && *aap == NULL) {
+ /* No interesting arrays. Lets see about exiting.
+ * Note that blocking at this point is not a problem
+ * as there are no active arrays, there is nothing that
+ * we need to be ready to do.
+ */
+ int fd = open(container->device_name, O_RDONLY|O_EXCL);
+ if (fd >= 0 || errno != EBUSY) {
+ /* OK, we are safe to leave */
+ exit_now = 1;
+ signal_manager();
+ remove_pidfile(container->devname);
+ exit(0);
+ }
+ }
+
if (!nowait) {
rv = select(maxfd+1, &rfds, NULL, NULL, NULL);
@@ -521,7 +538,7 @@ void do_monitor(struct supertype *container)
int rv;
int first = 1;
do {
- rv = wait_and_act(&container->arrays, container->mgr_pipe[0],
+ rv = wait_and_act(container, container->mgr_pipe[0],
container->mon_pipe[1], first);
first = 0;
} while (rv >= 0);