mdmon: recreate socket/pid file on SIGHUP
Allow mdmon to start while /var/run/mdadm is readonly. Later a SIGHUP can trigger mdmon to drop its pid and socket once /var/run/mdadm is writable. Of course one needs the pid to send a HUP, that can be stored in a distribution specific rw-init directory... For now, rely on a killall -HUP mdmon to get the files dumped. Signed-off-by: Dan Williams <dan.j.williams@intel.com>
This commit is contained in:
parent
313a4a82f1
commit
295646b3d5
|
@ -605,6 +605,7 @@ void do_manager(struct supertype *container)
|
||||||
|
|
||||||
sigprocmask(SIG_UNBLOCK, NULL, &set);
|
sigprocmask(SIG_UNBLOCK, NULL, &set);
|
||||||
sigdelset(&set, SIGUSR1);
|
sigdelset(&set, SIGUSR1);
|
||||||
|
sigdelset(&set, SIGHUP);
|
||||||
|
|
||||||
do {
|
do {
|
||||||
|
|
||||||
|
@ -622,6 +623,13 @@ void do_manager(struct supertype *container)
|
||||||
|
|
||||||
read_sock(container);
|
read_sock(container);
|
||||||
|
|
||||||
|
if (socket_hup_requested) {
|
||||||
|
close(container->sock);
|
||||||
|
container->sock = make_control_sock(container->devname);
|
||||||
|
make_pidfile(container->devname, 0);
|
||||||
|
socket_hup_requested = 0;
|
||||||
|
}
|
||||||
|
|
||||||
free_mdstat(mdstat);
|
free_mdstat(mdstat);
|
||||||
}
|
}
|
||||||
remove_old();
|
remove_old();
|
||||||
|
|
35
mdmon.c
35
mdmon.c
|
@ -80,7 +80,7 @@ static struct superswitch *find_metadata_methods(char *vers)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int make_pidfile(char *devname, int o_excl)
|
int make_pidfile(char *devname, int o_excl)
|
||||||
{
|
{
|
||||||
char path[100];
|
char path[100];
|
||||||
char pid[10];
|
char pid[10];
|
||||||
|
@ -89,7 +89,7 @@ static int make_pidfile(char *devname, int o_excl)
|
||||||
|
|
||||||
fd = open(path, O_RDWR|O_CREAT|o_excl, 0600);
|
fd = open(path, O_RDWR|O_CREAT|o_excl, 0600);
|
||||||
if (fd < 0)
|
if (fd < 0)
|
||||||
return -1;
|
return -errno;
|
||||||
sprintf(pid, "%d\n", getpid());
|
sprintf(pid, "%d\n", getpid());
|
||||||
write(fd, pid, strlen(pid));
|
write(fd, pid, strlen(pid));
|
||||||
close(fd);
|
close(fd);
|
||||||
|
@ -138,7 +138,7 @@ void remove_pidfile(char *devname)
|
||||||
unlink(buf);
|
unlink(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int make_control_sock(char *devname)
|
int make_control_sock(char *devname)
|
||||||
{
|
{
|
||||||
char path[100];
|
char path[100];
|
||||||
int sfd;
|
int sfd;
|
||||||
|
@ -164,6 +164,12 @@ static int make_control_sock(char *devname)
|
||||||
return sfd;
|
return sfd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int socket_hup_requested;
|
||||||
|
static void hup(int sig)
|
||||||
|
{
|
||||||
|
socket_hup_requested = 1;
|
||||||
|
}
|
||||||
|
|
||||||
static void wake_me(int sig)
|
static void wake_me(int sig)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -245,21 +251,29 @@ int main(int argc, char *argv[])
|
||||||
container->devname);
|
container->devname);
|
||||||
exit(3);
|
exit(3);
|
||||||
} else {
|
} else {
|
||||||
|
int err;
|
||||||
|
|
||||||
/* cleanup the old monitor, this one is taking over */
|
/* cleanup the old monitor, this one is taking over */
|
||||||
try_kill_monitor(container->devname);
|
try_kill_monitor(container->devname);
|
||||||
if (make_pidfile(container->devname, 0) < 0) {
|
err = make_pidfile(container->devname, 0);
|
||||||
|
if (err < 0) {
|
||||||
fprintf(stderr, "mdmon: %s Cannot create pidfile\n",
|
fprintf(stderr, "mdmon: %s Cannot create pidfile\n",
|
||||||
container->devname);
|
container->devname);
|
||||||
exit(3);
|
if (err == -EROFS) {
|
||||||
|
/* FIXME implement a mechanism to
|
||||||
|
* prevent duplicate monitor instances
|
||||||
|
*/
|
||||||
|
fprintf(stderr,
|
||||||
|
"mdmon: continuing on read-only file system\n");
|
||||||
|
} else
|
||||||
|
exit(3);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
container->sock = make_control_sock(container->devname);
|
container->sock = make_control_sock(container->devname);
|
||||||
if (container->sock < 0) {
|
if (container->sock < 0)
|
||||||
fprintf(stderr, "mdmon: Cannot create socket in /var/run/mdadm\n");
|
fprintf(stderr, "mdmon: Cannot create socket in /var/run/mdadm\n");
|
||||||
exit(3);
|
|
||||||
}
|
|
||||||
container->arrays = NULL;
|
container->arrays = NULL;
|
||||||
|
|
||||||
mdi = sysfs_read(mdfd, container->devnum,
|
mdi = sysfs_read(mdfd, container->devnum,
|
||||||
|
@ -329,15 +343,18 @@ int main(int argc, char *argv[])
|
||||||
*/
|
*/
|
||||||
sigemptyset(&set);
|
sigemptyset(&set);
|
||||||
sigaddset(&set, SIGUSR1);
|
sigaddset(&set, SIGUSR1);
|
||||||
|
sigaddset(&set, SIGHUP);
|
||||||
sigprocmask(SIG_BLOCK, &set, NULL);
|
sigprocmask(SIG_BLOCK, &set, NULL);
|
||||||
act.sa_handler = wake_me;
|
act.sa_handler = wake_me;
|
||||||
act.sa_flags = 0;
|
act.sa_flags = 0;
|
||||||
sigaction(SIGUSR1, &act, NULL);
|
sigaction(SIGUSR1, &act, NULL);
|
||||||
|
act.sa_handler = hup;
|
||||||
|
sigaction(SIGHUP, &act, NULL);
|
||||||
act.sa_handler = SIG_IGN;
|
act.sa_handler = SIG_IGN;
|
||||||
sigaction(SIGPIPE, &act, NULL);
|
sigaction(SIGPIPE, &act, NULL);
|
||||||
|
|
||||||
if (clone_monitor(container) < 0) {
|
if (clone_monitor(container) < 0) {
|
||||||
fprintf(stderr, "md-manage: failed to start monitor process: %s\n",
|
fprintf(stderr, "mdmon: failed to start monitor process: %s\n",
|
||||||
strerror(errno));
|
strerror(errno));
|
||||||
exit(2);
|
exit(2);
|
||||||
}
|
}
|
||||||
|
|
3
mdmon.h
3
mdmon.h
|
@ -55,6 +55,9 @@ extern struct md_generic_cmd *active_cmd;
|
||||||
void remove_pidfile(char *devname);
|
void remove_pidfile(char *devname);
|
||||||
void do_monitor(struct supertype *container);
|
void do_monitor(struct supertype *container);
|
||||||
void do_manager(struct supertype *container);
|
void do_manager(struct supertype *container);
|
||||||
|
int make_control_sock(char *devname);
|
||||||
|
int make_pidfile(char *devname, int o_excl);
|
||||||
|
extern int socket_hup_requested;
|
||||||
|
|
||||||
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);
|
||||||
|
|
3
mdstat.c
3
mdstat.c
|
@ -280,7 +280,8 @@ void mdstat_wait_fd(int fd, const sigset_t *sigmask)
|
||||||
FD_ZERO(&rfds);
|
FD_ZERO(&rfds);
|
||||||
if (mdstat_fd >= 0)
|
if (mdstat_fd >= 0)
|
||||||
FD_SET(mdstat_fd, &fds);
|
FD_SET(mdstat_fd, &fds);
|
||||||
FD_SET(fd, &rfds);
|
if (fd >= 0)
|
||||||
|
FD_SET(fd, &rfds);
|
||||||
if (mdstat_fd > maxfd)
|
if (mdstat_fd > maxfd)
|
||||||
maxfd = mdstat_fd;
|
maxfd = mdstat_fd;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue