summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Williams <dan.j.williams@intel.com>2008-05-15 16:48:52 +1000
committerNeil Brown <neilb@suse.de>2008-05-15 16:48:52 +1000
commitb109d92863bfa319d140b305132ca41bfb8d1194 (patch)
tree77e038600e1a454443f1ff37d28b21f27ead8336
parent0af73f61a25904edc7da24e2da9786b48bb8bec6 (diff)
start fleshing out socket code, ping monitor to see if it is alive
From: Dan Williams <dan.j.williams@intel.com> Signed-off-by: Dan Williams <dan.j.williams@intel.com>
-rw-r--r--Makefile3
-rw-r--r--managemon.c28
-rw-r--r--mdmon.c57
-rw-r--r--msg.h4
4 files changed, 83 insertions, 9 deletions
diff --git a/Makefile b/Makefile
index b2087d0c..68b38918 100644
--- 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
diff --git a/managemon.c b/managemon.c
index 43c731fa..f8123d0e 100644
--- a/managemon.c
+++ b/managemon.c
@@ -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 1284a124..2cce760f 100644
--- 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 84ee9b3a..6f0d9c16 100644
--- 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