From 8ea2c923a3e2464200ff79bf2c3f1f89e6a93ad4 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 4 Jul 2007 16:51:13 +1000 Subject: [PATCH] - neaten up the command line for killtcp - split out the event script code into a separate module - get rid of the separate takeover directory --- Makefile.in | 14 +-- common/ctdb_util.c | 37 ++++++ {takeover => common}/system.c | 166 --------------------------- include/ctdb_private.h | 2 + {takeover => server}/ctdb_takeover.c | 0 tools/ctdb.c | 18 +-- 6 files changed, 56 insertions(+), 181 deletions(-) rename {takeover => common}/system.c (71%) rename {takeover => server}/ctdb_takeover.c (100%) diff --git a/Makefile.in b/Makefile.in index 322cec1b..32a6fa11 100644 --- a/Makefile.in +++ b/Makefile.in @@ -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 $@ diff --git a/common/ctdb_util.c b/common/ctdb_util.c index 821ae79b..0f1b7692 100644 --- a/common/ctdb_util.c +++ b/common/ctdb_util.c @@ -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; +} diff --git a/takeover/system.c b/common/system.c similarity index 71% rename from takeover/system.c rename to common/system.c index 2259cff3..04adf35f 100644 --- a/takeover/system.c +++ b/common/system.c @@ -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) { diff --git a/include/ctdb_private.h b/include/ctdb_private.h index 053a0fcf..01aa629a 100644 --- a/include/ctdb_private.h +++ b/include/ctdb_private.h @@ -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 diff --git a/takeover/ctdb_takeover.c b/server/ctdb_takeover.c similarity index 100% rename from takeover/ctdb_takeover.c rename to server/ctdb_takeover.c diff --git a/tools/ctdb.c b/tools/ctdb.c index b2837891..7f44f45d 100644 --- a/tools/ctdb.c +++ b/tools/ctdb.c @@ -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", " " }, + { "killtcp", kill_tcp, false, "kill a tcp connection", " " }, }; /* -- 2.34.1