- neaten up the command line for killtcp
authorAndrew Tridgell <tridge@samba.org>
Wed, 4 Jul 2007 06:51:13 +0000 (16:51 +1000)
committerAndrew Tridgell <tridge@samba.org>
Wed, 4 Jul 2007 06:51:13 +0000 (16:51 +1000)
- split out the event script code into a separate module
- get rid of the separate takeover directory

Makefile.in
common/ctdb_util.c
common/system.c [moved from takeover/system.c with 71% similarity]
include/ctdb_private.h
server/ctdb_takeover.c [moved from takeover/ctdb_takeover.c with 100% similarity]
tools/ctdb.c

index 322cec1b6aed83d5f0c7b495be18c64fb2859838..32a6fa11d355012369e429f1410151468a27db5e 100644 (file)
@@ -35,7 +35,7 @@ UTIL_OBJ = lib/util/idtree.o lib/util/db_wrap.o lib/util/strlist.o lib/util/util
 
 CTDB_COMMON_OBJ =  common/ctdb_io.o common/ctdb_util.o \
        common/ctdb_ltdb.o common/ctdb_message.o common/cmdline.o  \
-       lib/util/debug.o 
+       lib/util/debug.o common/system.o
 
 CTDB_TCP_OBJ = tcp/tcp_connect.o tcp/tcp_io.o tcp/tcp_init.o
 
@@ -43,14 +43,14 @@ CTDB_CLIENT_OBJ = client/ctdb_client.o \
        $(CTDB_COMMON_OBJ) $(POPT_OBJ) $(UTIL_OBJ) @TALLOC_OBJ@ @TDB_OBJ@ \
        @LIBREPLACEOBJ@ $(EXTRA_OBJ) @EVENTS_OBJ@ 
 
-CTDB_TAKEOVER_OBJ = takeover/system.o takeover/ctdb_takeover.o
+CTDB_TAKEOVER_OBJ = 
 
 CTDB_SERVER_OBJ = server/ctdbd.o server/ctdb_daemon.o server/ctdb_lockwait.o \
        server/ctdb_recoverd.o server/ctdb_recover.o server/ctdb_freeze.o \
        server/ctdb_tunables.o server/ctdb_monitor.o server/ctdb_server.o \
        server/ctdb_control.o server/ctdb_call.o server/ctdb_ltdb_server.o \
-       server/ctdb_traverse.o $(CTDB_CLIENT_OBJ) \
-       $(CTDB_TAKEOVER_OBJ) $(CTDB_TCP_OBJ) @INFINIBAND_WRAPPER_OBJ@
+       server/ctdb_traverse.o server/eventscript.o server/ctdb_takeover.o \
+       $(CTDB_CLIENT_OBJ) $(CTDB_TAKEOVER_OBJ) $(CTDB_TCP_OBJ) @INFINIBAND_WRAPPER_OBJ@
 
 TEST_BINS=bin/ctdb_bench bin/ctdb_fetch bin/ctdb_store @INFINIBAND_BINS@
 BINS = bin/ctdb bin/scsi_io
@@ -79,13 +79,13 @@ bin/ctdbd: $(CTDB_SERVER_OBJ)
        @echo Linking $@
        @$(CC) $(CFLAGS) -o $@ $(CTDB_SERVER_OBJ) $(LIB_FLAGS)
 
-bin/scsi_io: $(CLIENT_OBJS) scsi/scsi_io.o 
+bin/scsi_io: $(CTDB_CLIENT_OBJ) scsi/scsi_io.o 
        @echo Linking $@
        @$(CC) $(CFLAGS) -o $@ scsi/scsi_io.o $(CTDB_CLIENT_OBJ) $(LIB_FLAGS)
 
-bin/ctdb: $(CLIENT_OBJS) tools/ctdb.o takeover/system.o 
+bin/ctdb: $(CTDB_CLIENT_OBJ) tools/ctdb.o 
        @echo Linking $@
-       @$(CC) $(CFLAGS) -o $@ tools/ctdb.o takeover/system.o $(CTDB_CLIENT_OBJ) $(LIB_FLAGS)
+       @$(CC) $(CFLAGS) -o $@ tools/ctdb.o $(CTDB_CLIENT_OBJ) $(LIB_FLAGS)
 
 bin/ctdb_bench: $(CTDB_CLIENT_OBJ) tests/ctdb_bench.o 
        @echo Linking $@
index 821ae79b3b74bf291144d82b807aa85a5a707950..0f1b76925a2a9e779ca1635c7e7dc49cefc4f1c1 100644 (file)
@@ -225,3 +225,40 @@ void set_close_on_exec(int fd)
         fcntl(fd, F_SETFD, v | FD_CLOEXEC);
 }
 
+
+/*
+  parse a ip:port pair
+ */
+bool parse_ip_port(const char *s, struct sockaddr_in *ip)
+{
+       const char *p;
+       char *endp = NULL;
+       unsigned port;
+       char buf[16];
+
+       ip->sin_family = AF_INET;
+
+       p = strchr(s, ':');
+       if (p == NULL) {
+               return false;
+       }
+
+       if (p - s > 15) {
+               return false;
+       }
+
+       port = strtoul(p+1, &endp, 10);
+       if (endp == NULL || *endp != 0) {
+               /* trailing garbage */
+               return false;
+       }
+       ip->sin_port = htons(port);
+
+       strlcpy(buf, s, 1+p-s);
+
+       if (inet_aton(buf, &ip->sin_addr) == 0) {
+               return false;
+       }
+
+       return true;
+}
similarity index 71%
rename from takeover/system.c
rename to common/system.c
index 2259cff36d66adb6bb33ace9c3e36784ab513025..04adf35fed59ef03a959172b2cf09bb7e7271420 100644 (file)
@@ -274,172 +274,6 @@ bool ctdb_sys_have_ip(const char *ip)
        return ret == 0;
 }
 
-/*
-  run the event script - varargs version
- */
-static int ctdb_event_script_v(struct ctdb_context *ctdb, const char *fmt, va_list ap)
-{
-       char *options, *cmdstr;
-       int ret;
-       va_list ap2;
-       struct stat st;
-
-       if (stat(ctdb->takeover.event_script, &st) != 0 && 
-           errno == ENOENT) {
-               DEBUG(0,("No event script found at '%s'\n", ctdb->takeover.event_script));
-               return 0;
-       }
-
-       va_copy(ap2, ap);
-       options  = talloc_vasprintf(ctdb, fmt, ap2);
-       va_end(ap2);
-       CTDB_NO_MEMORY(ctdb, options);
-
-       cmdstr = talloc_asprintf(ctdb, "%s %s", ctdb->takeover.event_script, options);
-       CTDB_NO_MEMORY(ctdb, cmdstr);
-
-       ret = system(cmdstr);
-       if (ret != -1) {
-               ret = WEXITSTATUS(ret);
-       }
-
-       talloc_free(cmdstr);
-       talloc_free(options);
-
-       return ret;
-}
-
-/*
-  run the event script
- */
-int ctdb_event_script(struct ctdb_context *ctdb, const char *fmt, ...)
-{
-       va_list ap;
-       int ret;
-
-       va_start(ap, fmt);
-       ret = ctdb_event_script_v(ctdb, fmt, ap);
-       va_end(ap);
-
-       return ret;
-}
-
-
-struct ctdb_event_script_state {
-       struct ctdb_context *ctdb;
-       pid_t child;
-       void (*callback)(struct ctdb_context *, int, void *);
-       int fd[2];
-       void *private_data;
-};
-
-/* called when child is finished */
-static void ctdb_event_script_handler(struct event_context *ev, struct fd_event *fde, 
-                                     uint16_t flags, void *p)
-{
-       struct ctdb_event_script_state *state = 
-               talloc_get_type(p, struct ctdb_event_script_state);
-       int status = -1;
-       void (*callback)(struct ctdb_context *, int, void *) = state->callback;
-       void *private_data = state->private_data;
-       struct ctdb_context *ctdb = state->ctdb;
-
-       waitpid(state->child, &status, 0);
-       if (status != -1) {
-               status = WEXITSTATUS(status);
-       }
-       talloc_set_destructor(state, NULL);
-       talloc_free(state);
-       callback(ctdb, status, private_data);
-}
-
-
-/* called when child times out */
-static void ctdb_event_script_timeout(struct event_context *ev, struct timed_event *te, 
-                                     struct timeval t, void *p)
-{
-       struct ctdb_event_script_state *state = talloc_get_type(p, struct ctdb_event_script_state);
-       void (*callback)(struct ctdb_context *, int, void *) = state->callback;
-       void *private_data = state->private_data;
-       struct ctdb_context *ctdb = state->ctdb;
-
-       DEBUG(0,("event script timed out\n"));
-       talloc_free(state);
-       callback(ctdb, -1, private_data);
-}
-
-/*
-  destroy a running event script
- */
-static int event_script_destructor(struct ctdb_event_script_state *state)
-{
-       kill(state->child, SIGKILL);
-       waitpid(state->child, NULL, 0);
-       return 0;
-}
-
-/*
-  run the event script in the background, calling the callback when 
-  finished
- */
-int ctdb_event_script_callback(struct ctdb_context *ctdb, 
-                              struct timeval timeout,
-                              TALLOC_CTX *mem_ctx,
-                              void (*callback)(struct ctdb_context *, int, void *),
-                              void *private_data,
-                              const char *fmt, ...)
-{
-       struct ctdb_event_script_state *state;
-       va_list ap;
-       int ret;
-
-       state = talloc(mem_ctx, struct ctdb_event_script_state);
-       CTDB_NO_MEMORY(ctdb, state);
-
-       state->ctdb = ctdb;
-       state->callback = callback;
-       state->private_data = private_data;
-       
-       ret = pipe(state->fd);
-       if (ret != 0) {
-               talloc_free(state);
-               return -1;
-       }
-
-       state->child = fork();
-
-       if (state->child == (pid_t)-1) {
-               close(state->fd[0]);
-               close(state->fd[1]);
-               talloc_free(state);
-               return -1;
-       }
-
-       if (state->child == 0) {
-               close(state->fd[0]);
-               ctdb_set_realtime(false);
-               set_close_on_exec(state->fd[1]);
-               va_start(ap, fmt);
-               ret = ctdb_event_script_v(ctdb, fmt, ap);
-               va_end(ap);
-               _exit(ret);
-       }
-
-       talloc_set_destructor(state, event_script_destructor);
-
-       close(state->fd[1]);
-
-       event_add_fd(ctdb->ev, state, state->fd[0], EVENT_FD_READ|EVENT_FD_AUTOCLOSE,
-                    ctdb_event_script_handler, state);
-
-       if (!timeval_is_zero(&timeout)) {
-               event_add_timed(ctdb->ev, state, timeout, ctdb_event_script_timeout, state);
-       }
-
-       return 0;
-}
-
-
 static void ctdb_wait_handler(struct event_context *ev, struct timed_event *te, 
                              struct timeval yt, void *p)
 {
index 053a0fcf2a7468ceb6ab60d90fb52e5ad23db6f6..01aa629afa37f5103ac96fae99a3e27ac75eb215 100644 (file)
@@ -1031,4 +1031,6 @@ int ctdb_ctrl_get_all_tunables(struct ctdb_context *ctdb,
 
 void ctdb_start_freeze(struct ctdb_context *ctdb);
 
+bool parse_ip_port(const char *s, struct sockaddr_in *ip);
+
 #endif
index b283789103566faef215115f76ac3026d10e6ebc..7f44f45d3774cd39b06077e00f040233005d2024 100644 (file)
@@ -311,17 +311,19 @@ static int kill_tcp(struct ctdb_context *ctdb, int argc, const char **argv)
        int i, ret;
        struct sockaddr_in src, dst;
 
-       if (argc < 4) {
+       if (argc < 2) {
                usage();
        }
 
-       src.sin_family=AF_INET;
-       src.sin_port=htons(atoi(argv[1]));
-       inet_aton(argv[0], &src.sin_addr);
+       if (!parse_ip_port(argv[0], &src)) {
+               printf("Bad IP:port '%s'\n", argv[1]);
+               return -1;
+       }
 
-       dst.sin_family=AF_INET;
-       dst.sin_port=htons(atoi(argv[3]));
-       inet_aton(argv[2], &dst.sin_addr);
+       if (!parse_ip_port(argv[1], &dst)) {
+               printf("Bad IP:port '%s'\n", argv[1]);
+               return -1;
+       }
 
        for (i=0;i<5;i++) {
                ret = ctdb_sys_kill_tcp(ctdb->ev, &src, &dst);
@@ -856,7 +858,7 @@ static const struct {
        { "recover",         control_recover,           true,  "force recovery" },
        { "freeze",          control_freeze,            true,  "freeze all databases" },
        { "thaw",            control_thaw,              true,  "thaw all databases" },
-       { "killtcp",         kill_tcp,                  false, "kill a tcp connection", "<srcip> <srcport> <dstip> <dstport>" },
+       { "killtcp",         kill_tcp,                  false, "kill a tcp connection", "<srcip:port> <dstip:port>" },
 };
 
 /*