mdmon: wait after trying to kill
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>
This commit is contained in:
parent
6144ed4414
commit
883a6142e6
2
Makefile
2
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 \
|
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 \
|
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
|
STATICSRC = pwgr.c
|
||||||
|
|
|
@ -504,13 +504,7 @@ void manage(struct mdstat_ent *mdstat, struct supertype *container)
|
||||||
manage_container(mdstat, container);
|
manage_container(mdstat, container);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (mdstat->metadata_version == NULL ||
|
if (!is_container_member(mdstat, container->devname))
|
||||||
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)]
|
|
||||||
!= '/')
|
|
||||||
/* Not for this array */
|
/* Not for this array */
|
||||||
continue;
|
continue;
|
||||||
/* Looks like a member of this container */
|
/* Looks like a member of this container */
|
||||||
|
|
69
mdmon.c
69
mdmon.c
|
@ -105,11 +105,25 @@ int make_pidfile(char *devname, int o_excl)
|
||||||
return 0;
|
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)
|
static void try_kill_monitor(char *devname)
|
||||||
{
|
{
|
||||||
char buf[100];
|
char buf[100];
|
||||||
int fd;
|
int fd;
|
||||||
pid_t pid;
|
pid_t pid;
|
||||||
|
struct mdstat_ent *mdstat;
|
||||||
|
|
||||||
sprintf(buf, "/var/run/mdadm/%s.pid", devname);
|
sprintf(buf, "/var/run/mdadm/%s.pid", devname);
|
||||||
fd = open(buf, O_RDONLY);
|
fd = open(buf, O_RDONLY);
|
||||||
|
@ -135,8 +149,19 @@ static void try_kill_monitor(char *devname)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strstr(buf, "mdmon") != NULL)
|
if (!strstr(buf, "mdmon"))
|
||||||
kill(pid, SIGTERM);
|
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)
|
void remove_pidfile(char *devname)
|
||||||
|
@ -268,6 +293,26 @@ int main(int argc, char *argv[])
|
||||||
container->devname = devnum2devname(container->devnum);
|
container->devname = devnum2devname(container->devnum);
|
||||||
container->device_name = argv[1];
|
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 */
|
/* If this fails, we hope it already exists */
|
||||||
mkdir("/var/run/mdadm", 0600);
|
mkdir("/var/run/mdadm", 0600);
|
||||||
/* pid file lives in /var/run/mdadm/mdXX.pid */
|
/* pid file lives in /var/run/mdadm/mdXX.pid */
|
||||||
|
@ -364,26 +409,6 @@ int main(int argc, char *argv[])
|
||||||
|
|
||||||
mlockall(MCL_FUTURE);
|
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) {
|
if (clone_monitor(container) < 0) {
|
||||||
fprintf(stderr, "mdmon: failed to start monitor process: %s\n",
|
fprintf(stderr, "mdmon: failed to start monitor process: %s\n",
|
||||||
strerror(errno));
|
strerror(errno));
|
||||||
|
|
1
mdmon.h
1
mdmon.h
|
@ -54,6 +54,7 @@ extern int sigterm;
|
||||||
|
|
||||||
int read_dev_state(int fd);
|
int read_dev_state(int fd);
|
||||||
int get_resync_start(struct active_array *a);
|
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);
|
struct mdstat_ent *mdstat_read(int hold, int start);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue