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:
Dan Williams 2008-09-15 20:58:43 -07:00
parent 313a4a82f1
commit 295646b3d5
4 changed files with 39 additions and 10 deletions

View File

@ -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
View File

@ -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);
} }

View File

@ -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);

View File

@ -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;