]> git.ipfire.org Git - thirdparty/mdadm.git/commitdiff
mdmon: wait after trying to kill
authorDan Williams <dan.j.williams@intel.com>
Thu, 2 Oct 2008 22:42:57 +0000 (15:42 -0700)
committerDan Williams <dan.j.williams@intel.com>
Wed, 15 Oct 2008 21:43:57 +0000 (14:43 -0700)
Now that mdmon handles sigterm if another monitor wants to take over it
should wait until all managed arrays are clean.  So make WaitClean()
available to mdmon and teach try_kill_monitor() to wait on each subarray
in the container.

...since we may be communicating with a dieing process, we need to
block SIGPIPE earlier.

Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Makefile
managemon.c
mdmon.c
mdmon.h

index f26eeaceb0946d62802999b9505c8fb4f8042d1b..89427774bda00558d5f1f4121799befc6c535afb 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -85,7 +85,7 @@ SRCS =  mdadm.c config.c mdstat.c  ReadMe.c util.c Manage.c Assemble.c Build.c \
 
 MON_OBJS = mdmon.o monitor.o managemon.o util.o mdstat.o sysfs.o config.o \
        Kill.o sg_io.o dlink.o ReadMe.o super0.o super1.o super-intel.o \
-       super-ddf.o sha1.o crc32.o msg.o
+       super-ddf.o sha1.o crc32.o msg.o Monitor.o
 
 
 STATICSRC = pwgr.c
index a8af614af0be5304b9349b95eaa80226a59aeb7d..023431276db99ee5b859eda1877cfc52961c7a9f 100644 (file)
@@ -504,13 +504,7 @@ void manage(struct mdstat_ent *mdstat, struct supertype *container)
                        manage_container(mdstat, container);
                        continue;
                }
-               if (mdstat->metadata_version == NULL ||
-                   strncmp(mdstat->metadata_version, "external:", 9) != 0 ||
-                   !is_subarray(mdstat->metadata_version+9) ||
-                   strncmp(mdstat->metadata_version+10, container->devname,
-                           strlen(container->devname)) != 0 ||
-                   mdstat->metadata_version[10+strlen(container->devname)]
-                     != '/')
+               if (!is_container_member(mdstat, container->devname))
                        /* Not for this array */
                        continue;
                /* Looks like a member of this container */
diff --git a/mdmon.c b/mdmon.c
index 7ef0c80f5b38568c7f1ecfda04fe0bcd79bb4ed5..d40adb26706ae732075f591eacd540fc1c99bc3c 100644 (file)
--- a/mdmon.c
+++ b/mdmon.c
@@ -105,11 +105,25 @@ int make_pidfile(char *devname, int o_excl)
        return 0;
 }
 
+int is_container_member(struct mdstat_ent *mdstat, char *container)
+{
+       if (mdstat->metadata_version == NULL ||
+           strncmp(mdstat->metadata_version, "external:", 9) != 0 ||
+           !is_subarray(mdstat->metadata_version+9) ||
+           strncmp(mdstat->metadata_version+10, container, strlen(container)) != 0 ||
+           mdstat->metadata_version[10+strlen(container)] != '/')
+               return 0;
+
+       return 1;
+}
+
+void remove_pidfile(char *devname);
 static void try_kill_monitor(char *devname)
 {
        char buf[100];
        int fd;
        pid_t pid;
+       struct mdstat_ent *mdstat;
 
        sprintf(buf, "/var/run/mdadm/%s.pid", devname);
        fd = open(buf, O_RDONLY);
@@ -135,8 +149,19 @@ static void try_kill_monitor(char *devname)
                return;
        }
 
-       if (strstr(buf, "mdmon") != NULL)
-               kill(pid, SIGTERM);
+       if (!strstr(buf, "mdmon"))
+               return;
+
+       kill(pid, SIGTERM);
+
+       mdstat = mdstat_read(0, 0);
+       for ( ; mdstat; mdstat = mdstat->next)
+               if (is_container_member(mdstat, devname)) {
+                       sprintf(buf, "/dev/%s", mdstat->dev);
+                       WaitClean(buf);
+               }
+       free_mdstat(mdstat);
+       remove_pidfile(devname);
 }
 
 void remove_pidfile(char *devname)
@@ -268,6 +293,26 @@ int main(int argc, char *argv[])
        container->devname = devnum2devname(container->devnum);
        container->device_name = argv[1];
 
+       /* SIGUSR is sent between parent and child.  So both block it
+        * and enable it only with pselect.
+        */
+       sigemptyset(&set);
+       sigaddset(&set, SIGUSR1);
+       sigaddset(&set, SIGHUP);
+       sigaddset(&set, SIGALRM);
+       sigaddset(&set, SIGTERM);
+       sigprocmask(SIG_BLOCK, &set, NULL);
+       act.sa_handler = wake_me;
+       act.sa_flags = 0;
+       sigaction(SIGUSR1, &act, NULL);
+       sigaction(SIGALRM, &act, NULL);
+       act.sa_handler = hup;
+       sigaction(SIGHUP, &act, NULL);
+       act.sa_handler = term;
+       sigaction(SIGTERM, &act, NULL);
+       act.sa_handler = SIG_IGN;
+       sigaction(SIGPIPE, &act, NULL);
+
        /* If this fails, we hope it already exists */
        mkdir("/var/run/mdadm", 0600);
        /* pid file lives in /var/run/mdadm/mdXX.pid */
@@ -364,26 +409,6 @@ int main(int argc, char *argv[])
 
        mlockall(MCL_FUTURE);
 
-       /* SIGUSR is sent between parent and child.  So both block it
-        * and enable it only with pselect.
-        */
-       sigemptyset(&set);
-       sigaddset(&set, SIGUSR1);
-       sigaddset(&set, SIGHUP);
-       sigaddset(&set, SIGALRM);
-       sigaddset(&set, SIGTERM);
-       sigprocmask(SIG_BLOCK, &set, NULL);
-       act.sa_handler = wake_me;
-       act.sa_flags = 0;
-       sigaction(SIGUSR1, &act, NULL);
-       sigaction(SIGALRM, &act, NULL);
-       act.sa_handler = hup;
-       sigaction(SIGHUP, &act, NULL);
-       act.sa_handler = term;
-       sigaction(SIGTERM, &act, NULL);
-       act.sa_handler = SIG_IGN;
-       sigaction(SIGPIPE, &act, NULL);
-
        if (clone_monitor(container) < 0) {
                fprintf(stderr, "mdmon: failed to start monitor process: %s\n",
                        strerror(errno));
diff --git a/mdmon.h b/mdmon.h
index 2ce1fe6924790e53267d6a4be5225d2048973693..8a5cd4a8af6c8948a2605f89d4d16e7b4e8d260e 100644 (file)
--- a/mdmon.h
+++ b/mdmon.h
@@ -54,6 +54,7 @@ extern int sigterm;
 
 int read_dev_state(int fd);
 int get_resync_start(struct active_array *a);
+int is_container_member(struct mdstat_ent *mdstat, char *container);
 
 struct mdstat_ent *mdstat_read(int hold, int start);