diff --git a/Makefile b/Makefile index f26eeac..8942777 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 a8af614..0234312 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 7ef0c80..d40adb2 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 2ce1fe6..8a5cd4a 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);