From 295646b3d59c7d8d8c389ff320b30e61552ba331 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Mon, 15 Sep 2008 20:58:43 -0700 Subject: [PATCH] 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 --- managemon.c | 8 ++++++++ mdmon.c | 35 ++++++++++++++++++++++++++--------- mdmon.h | 3 +++ mdstat.c | 3 ++- 4 files changed, 39 insertions(+), 10 deletions(-) diff --git a/managemon.c b/managemon.c index fc5da71..779cb23 100644 --- a/managemon.c +++ b/managemon.c @@ -605,6 +605,7 @@ void do_manager(struct supertype *container) sigprocmask(SIG_UNBLOCK, NULL, &set); sigdelset(&set, SIGUSR1); + sigdelset(&set, SIGHUP); do { @@ -622,6 +623,13 @@ void do_manager(struct supertype *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); } remove_old(); diff --git a/mdmon.c b/mdmon.c index 9485757..073d769 100644 --- a/mdmon.c +++ b/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 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); if (fd < 0) - return -1; + return -errno; sprintf(pid, "%d\n", getpid()); write(fd, pid, strlen(pid)); close(fd); @@ -138,7 +138,7 @@ void remove_pidfile(char *devname) unlink(buf); } -static int make_control_sock(char *devname) +int make_control_sock(char *devname) { char path[100]; int sfd; @@ -164,6 +164,12 @@ static int make_control_sock(char *devname) return sfd; } +int socket_hup_requested; +static void hup(int sig) +{ + socket_hup_requested = 1; +} + static void wake_me(int sig) { @@ -245,21 +251,29 @@ int main(int argc, char *argv[]) container->devname); exit(3); } else { + int err; + /* cleanup the old monitor, this one is taking over */ 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", 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); - if (container->sock < 0) { + if (container->sock < 0) fprintf(stderr, "mdmon: Cannot create socket in /var/run/mdadm\n"); - exit(3); - } container->arrays = NULL; mdi = sysfs_read(mdfd, container->devnum, @@ -329,15 +343,18 @@ int main(int argc, char *argv[]) */ sigemptyset(&set); sigaddset(&set, SIGUSR1); + sigaddset(&set, SIGHUP); sigprocmask(SIG_BLOCK, &set, NULL); act.sa_handler = wake_me; act.sa_flags = 0; sigaction(SIGUSR1, &act, NULL); + act.sa_handler = hup; + sigaction(SIGHUP, &act, NULL); act.sa_handler = SIG_IGN; sigaction(SIGPIPE, &act, NULL); 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)); exit(2); } diff --git a/mdmon.h b/mdmon.h index b3f4d6e..e5b2a72 100644 --- a/mdmon.h +++ b/mdmon.h @@ -55,6 +55,9 @@ extern struct md_generic_cmd *active_cmd; void remove_pidfile(char *devname); void do_monitor(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 get_resync_start(struct active_array *a); diff --git a/mdstat.c b/mdstat.c index 00714b4..ebdfc67 100644 --- a/mdstat.c +++ b/mdstat.c @@ -280,7 +280,8 @@ void mdstat_wait_fd(int fd, const sigset_t *sigmask) FD_ZERO(&rfds); if (mdstat_fd >= 0) FD_SET(mdstat_fd, &fds); - FD_SET(fd, &rfds); + if (fd >= 0) + FD_SET(fd, &rfds); if (mdstat_fd > maxfd) maxfd = mdstat_fd;