]> git.ipfire.org Git - thirdparty/mdadm.git/commitdiff
Exit when there are no more arrays to manage.
authorNeil Brown <neilb@suse.de>
Mon, 26 May 2008 23:18:41 +0000 (09:18 +1000)
committerNeil Brown <neilb@suse.de>
Mon, 26 May 2008 23:18:41 +0000 (09:18 +1000)
managemon.c
mdadm.h
mdmon.c
mdmon.h
monitor.c

index aa10a9930f3372ef3ff3676010d7dcdeec447944..971dcd1d54aa66149eafeae7d1ef6a236ca4c88c 100644 (file)
@@ -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 7b11ffb1bb93710f75ccbaf547a2731902e1d6f1..5586dce47b593088b9a967e1fa99daf5a2f2dada 100644 (file)
--- 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 2919a02f4e98f73fa5a8e9993ba95abfdacd6d4a..323ee62ee56ed37617dbda90a330d18813815490 100644 (file)
--- 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 29349b7a8024c8c5cfb460c206f99e2b1df0e8ba..b84e270bcfd27e966c8298173e8a7b34e1cf3124 100644 (file)
--- 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;
index ead96d9d0f74afcfdeafc64ff7d29287572f0dd6..a7e530801dd03006441acb2722d473bbb878e1d2 100644 (file)
--- 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);