]> git.ipfire.org Git - thirdparty/mdadm.git/commitdiff
start fleshing out socket code, ping monitor to see if it is alive
authorDan Williams <dan.j.williams@intel.com>
Thu, 15 May 2008 06:48:52 +0000 (16:48 +1000)
committerNeil Brown <neilb@suse.de>
Thu, 15 May 2008 06:48:52 +0000 (16:48 +1000)
From: Dan Williams <dan.j.williams@intel.com>

Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Makefile
managemon.c
mdmon.c
msg.h

index b2087d0c693e5bb27a69a050428a732bbbf8ae30..68b3891870fe601c4ed283f420e85852fdd3a2b9 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -79,7 +79,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 \
        Kill.o sg_io.o dlink.o ReadMe.o super0.o super1.o super-intel.o \
-       super-ddf.o sha1.o crc32.o
+       super-ddf.o sha1.o crc32.o msg.o
 
 
 STATICSRC = pwgr.c
@@ -125,6 +125,7 @@ mdadm.O2 : $(SRCS) mdadm.h
 
 mdmon : $(MON_OBJS)
        $(CC) $(LDFLAGS) -o mdmon $(MON_OBJS) $(LDLIBS)
+msg.o: msg.c msg.h
 
 test_stripe : restripe.c mdadm.h
        $(CC) $(CXFLAGS) $(LDFLAGS) -o test_stripe -DMAIN restripe.c
index 43c731fa819fe7054759d79ee0d72f93e0b9f893..f8123d0efd974210889ca6bcac8f2be890638e42 100644 (file)
@@ -74,6 +74,7 @@
 #endif
 #include       "mdadm.h"
 #include       "mdmon.h"
+#include       "msg.h"
 #include       <sys/socket.h>
 
 
@@ -302,12 +303,35 @@ void manage(struct mdstat_ent *mdstat, struct active_array *aa,
 void read_sock(int pfd)
 {
        int fd;
+       struct md_message msg;
+       int terminate = 0;
+       long fl;
+       int tmo = 3; /* 3 second timeout before hanging up the socket */
 
-       // FIXME set non-blocking
        fd = accept(pfd, NULL, NULL);
        if (fd < 0)
                return;
-       // FIXME do something useful
+
+       fl = fcntl(fd, F_GETFL, 0);
+       fl |= O_NONBLOCK;
+       fcntl(fd, F_SETFL, fl);
+
+       do {
+               msg.buf = NULL;
+
+               /* read and validate the message */
+               if (receive_message(fd, &msg, tmo) == 0) {
+                       // FIXME: handle message contents
+                       ack(fd, msg.seq, tmo);
+               } else {
+                       terminate = 1;
+                       nack(fd, -1, tmo);
+               }
+
+               if (msg.buf)
+                       free(msg.buf);
+       } while (!terminate);
+
        close(fd);
 }
 void do_manager(struct supertype *container)
diff --git a/mdmon.c b/mdmon.c
index 1284a1249b9e22aedc7f0e1b59d710f61038768b..2cce760fccfcb8e33ba09db807c18dc16d070b3d 100644 (file)
--- a/mdmon.c
+++ b/mdmon.c
@@ -34,6 +34,7 @@
 #include       <errno.h>
 #include       <string.h>
 #include       <fcntl.h>
+#include       <signal.h>
 
 #include       <sched.h>
 
@@ -76,14 +77,14 @@ static struct superswitch *find_metadata_methods(char *vers)
 }
 
 
-static int make_pidfile(char *devname)
+static int make_pidfile(char *devname, int o_excl)
 {
        char path[100];
        char pid[10];
        int fd;
        sprintf(path, "/var/run/mdadm/%s.pid", devname);
 
-       fd = open(path, O_RDWR|O_CREAT|O_EXCL, 0600);
+       fd = open(path, O_RDWR|O_CREAT|o_excl, 0600);
        if (fd < 0)
                return -1;
        sprintf(pid, "%d\n", getpid());
@@ -92,6 +93,40 @@ static int make_pidfile(char *devname)
        return 0;
 }
 
+static void try_kill_monitor(char *devname)
+{
+       char buf[100];
+       int fd;
+       pid_t pid;
+
+       sprintf(buf, "/var/run/mdadm/%s.pid", devname);
+       fd = open(buf, O_RDONLY);
+       if (fd < 0)
+               return;
+
+       if (read(fd, buf, sizeof(buf)) < 0) {
+               close(fd);
+               return;
+       }
+
+       close(fd);
+       pid = strtoul(buf, NULL, 10);
+
+       /* kill this process if it is mdmon */
+       sprintf(buf, "/proc/%lu/cmdline", (unsigned long) pid);
+       fd = open(buf, O_RDONLY);
+       if (fd < 0)
+               return;
+
+       if (read(fd, buf, sizeof(buf)) < 0) {
+               close(fd);
+               return;
+       }
+
+       if (strstr(buf, "mdmon") != NULL)
+               kill(pid, SIGTERM);
+}
+
 static int make_control_sock(char *devname)
 {
        char path[100];
@@ -150,10 +185,20 @@ int main(int argc, char *argv[])
        /* If this fails, we hope it already exists */
        mkdir("/var/run/mdadm", 0600);
        /* pid file lives in /var/run/mdadm/mdXX.pid */
-       if (make_pidfile(container->devname) < 0) {
-               fprintf(stderr, "md-manage: %s already managed\n",
-                       container->devname);
-               exit(3);
+       if (make_pidfile(container->devname, O_EXCL) < 0) {
+               if (ping_monitor(container->devname) == 0) {
+                       fprintf(stderr, "mdmon: %s already managed\n",
+                               container->devname);
+                       exit(3);
+               } else {
+                       /* cleanup the old monitor, this one is taking over */
+                       try_kill_monitor(container->devname);
+                       if (make_pidfile(container->devname, 0) < 0) {
+                               fprintf(stderr, "mdmon: %s Cannot create pidfile\n",
+                                       container->devname);
+                               exit(3);
+                       }
+               }
        }
 
        container->sock = make_control_sock(container->devname);
diff --git a/msg.h b/msg.h
index 84ee9b3a88531a1d36f2f412909d4569d4679700..6f0d9c1656847febf4bf5b6bc26babc4292d09e0 100644 (file)
--- a/msg.h
+++ b/msg.h
@@ -17,6 +17,9 @@
  * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
  */
 
+#ifndef _MSG_H
+#define _MSG_H
+
 struct mdinfo;
 struct md_message {
        int seq;
@@ -57,3 +60,4 @@ extern int connect_monitor(char *devname);
 extern int ping_monitor(char *devname);
 extern int send_remove_device(int fd, dev_t rdev, int seq, int tmo);
 
+#endif