]> git.ipfire.org Git - thirdparty/mdadm.git/commitdiff
mdmon: recreate socket/pid file on SIGHUP
authorDan Williams <dan.j.williams@intel.com>
Tue, 16 Sep 2008 03:58:43 +0000 (20:58 -0700)
committerDan Williams <dan.j.williams@intel.com>
Tue, 16 Sep 2008 03:58:43 +0000 (20:58 -0700)
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>
managemon.c
mdmon.c
mdmon.h
mdstat.c

index fc5da713feffc5f61d23980cb63157fb0aebf4ad..779cb237e77308a91c58f33e7ec635d05216d309 100644 (file)
@@ -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 9485757a3d6d2de68f33752840d51b638ce36c1d..073d7698952f0aaaa6c47c5895d4d60a777e81a0 100644 (file)
--- 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 b3f4d6e709ffb62666bc751041343ebe3e62b38e..e5b2a727ee233fa5ee6009d9251a92d83b9200df 100644 (file)
--- 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);
index 00714b485905be156fb33ce2d009b02171cd8154..ebdfc67bf6d46705e1ebcb74212299b2aa47b66c 100644 (file)
--- 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;