summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile2
-rw-r--r--managemon.c8
-rw-r--r--mdmon.c69
-rw-r--r--mdmon.h1
4 files changed, 50 insertions, 30 deletions
diff --git a/Makefile b/Makefile
index f26eeace..89427774 100644
--- 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
diff --git a/managemon.c b/managemon.c
index a8af614a..02343127 100644
--- a/managemon.c
+++ b/managemon.c
@@ -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 7ef0c80f..d40adb26 100644
--- 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 2ce1fe69..8a5cd4a8 100644
--- 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);