diff --git a/ctdb/ctdb.h b/ctdb/ctdb.h index 90be2d103d4..7d2b8235d9f 100644 --- a/ctdb/ctdb.h +++ b/ctdb/ctdb.h @@ -39,12 +39,21 @@ struct ctdb_call { */ struct ctdb_context *ctdb_init(TALLOC_CTX *mem_ctx); +/* + tell ctdb what address to listen on, in transport specific format +*/ +int ctdb_set_address(struct ctdb_context *ctdb, const char *address); + /* tell ctdb what nodes are available. This takes a filename, which will contain 1 node address per line, in a transport specific format */ int ctdb_set_nlist(struct ctdb_context *ctdb, const char *nlist); +/* + start the ctdb protocol +*/ +int ctdb_start(struct ctdb_context *ctdb); /* error string for last ctdb error diff --git a/ctdb/ctdb_private.h b/ctdb/ctdb_private.h index b4056d788eb..c126798abdd 100644 --- a/ctdb/ctdb_private.h +++ b/ctdb/ctdb_private.h @@ -35,20 +35,25 @@ struct ctdb_registered_call { ctdb_fn_t fn; }; +struct ctdb_address { + const char *address; + int port; +}; + /* state associated with one node */ struct ctdb_node { struct ctdb_context *ctdb; struct ctdb_node *next, *prev; - const char *address; - int port; + struct ctdb_address address; int fd; }; /* main state of the ctdb daemon */ struct ctdb_context { struct event_context *ev; + struct ctdb_address address; struct ctdb_node *nodes; /* list of nodes in the cluster */ struct ctdb_registered_call *calls; /* list of registered calls */ char *err_msg; diff --git a/ctdb/ctdb_tcp.c b/ctdb/ctdb_tcp.c index 85f2599d71b..01477f38b9e 100644 --- a/ctdb/ctdb_tcp.c +++ b/ctdb/ctdb_tcp.c @@ -67,7 +67,8 @@ static void ctdb_node_read(struct event_context *ev, struct fd_event *fde, uint16_t flags, void *private) { struct ctdb_node *node = talloc_get_type(private, struct ctdb_node); - printf("connection to node %s:%u is readable\n", node->address, node->port); + printf("connection to node %s:%u is readable\n", + node->address.address, node->address.port); event_set_fd_flags(fde, 0); } @@ -93,7 +94,8 @@ static void ctdb_node_connect_write(struct event_context *ev, struct fd_event *f return; } - printf("Established connection to %s:%u\n", node->address, node->port); + printf("Established connection to %s:%u\n", + node->address.address, node->address.port); talloc_free(fde); event_add_fd(node->ctdb->ev, node, node->fd, EVENT_FD_READ, ctdb_node_read, node); @@ -115,8 +117,8 @@ static void ctdb_node_connect(struct event_context *ev, struct timed_event *te, v = fcntl(node->fd, F_GETFL, 0); fcntl(node->fd, F_SETFL, v | O_NONBLOCK); - inet_pton(AF_INET, node->address, &sock_out.sin_addr); - sock_out.sin_port = htons(node->port); + inet_pton(AF_INET, node->address.address, &sock_out.sin_addr); + sock_out.sin_port = htons(node->address.port); sock_out.sin_family = PF_INET; if (connect(node->fd, &sock_out, sizeof(sock_out)) != 0 && @@ -133,6 +135,25 @@ static void ctdb_node_connect(struct event_context *ev, struct timed_event *te, ctdb_node_connect_write, node); } +/* + parse a IP:port pair +*/ +static int ctdb_parse_address(struct ctdb_context *ctdb, + TALLOC_CTX *mem_ctx, const char *str, + struct ctdb_address *address) +{ + char *p; + p = strchr(str, ':'); + if (p == NULL) { + ctdb_set_error(ctdb, "Badly formed node '%s'\n", str); + return -1; + } + + address->address = talloc_strndup(mem_ctx, str, p-str); + address->port = strtoul(p+1, NULL, 0); + return 0; +} + /* add a node to the list of active nodes @@ -141,23 +162,14 @@ static int ctdb_add_node(struct ctdb_context *ctdb, char *nstr) { struct ctdb_node *node; - /* expected to be in IP:port format */ - char *p; - p = strchr(nstr, ':'); - if (p == NULL) { - ctdb_set_error(ctdb, "Badly formed node '%s'\n", nstr); + node = talloc(ctdb, struct ctdb_node); + if (ctdb_parse_address(ctdb, node, nstr, &node->address) != 0) { return -1; } - *p++ = 0; - - node = talloc(ctdb, struct ctdb_node); - node->address = talloc_strdup(node, nstr); - node->port = strtoul(p, NULL, 0); node->fd = -1; node->ctdb = ctdb; DLIST_ADD(ctdb->nodes, node); - event_add_timed(ctdb->ev, node, timeval_zero(), ctdb_node_connect, node); return 0; } @@ -187,6 +199,14 @@ int ctdb_set_nlist(struct ctdb_context *ctdb, const char *nlist) return 0; } +/* + setup the node list from a file +*/ +int ctdb_set_address(struct ctdb_context *ctdb, const char *address) +{ + return ctdb_parse_address(ctdb, ctdb, address, &ctdb->address); +} + /* add a node to the list of active nodes */ diff --git a/ctdb/ctdb_test.c b/ctdb/ctdb_test.c index 9fa49fe7901..df16d1f432c 100644 --- a/ctdb/ctdb_test.c +++ b/ctdb/ctdb_test.c @@ -75,9 +75,12 @@ int main(int argc, const char *argv[]) { struct ctdb_context *ctdb; const char *nlist = NULL; + const char *myaddress = NULL; + struct poptOption popt_options[] = { POPT_AUTOHELP { "nlist", 0, POPT_ARG_STRING, &nlist, 0, "node list file", "filename" }, + { "listen", 0, POPT_ARG_STRING, &myaddress, 0, "address to listen on", "address" }, }; int opt; const char **extra_argv; @@ -104,8 +107,8 @@ int main(int argc, const char *argv[]) while (extra_argv[extra_argc]) extra_argc++; } - if (nlist == NULL) { - printf("You must provide a node list with --nlist\n"); + if (nlist == NULL || myaddress == NULL) { + printf("You must provide a node list with --nlist and an address with --listen\n"); exit(1); } @@ -116,6 +119,13 @@ int main(int argc, const char *argv[]) exit(1); } + /* tell ctdb what address to listen on */ + ret = ctdb_set_address(ctdb, myaddress); + if (ret == -1) { + printf("ctdb_set_address failed - %s\n", ctdb_errstr(ctdb)); + exit(1); + } + /* tell ctdb what nodes are available */ ret = ctdb_set_nlist(ctdb, nlist); if (ret == -1) { @@ -126,7 +136,7 @@ int main(int argc, const char *argv[]) /* setup a ctdb call function */ ret = ctdb_set_call(ctdb, sort_func, FUNC_SORT); ret = ctdb_set_call(ctdb, fetch_func, FUNC_FETCH); - + /* attach to a specific database */ ret = ctdb_attach(ctdb, "test.tdb", TDB_DEFAULT, O_RDWR|O_CREAT|O_TRUNC, 0666); if (ret == -1) { @@ -134,6 +144,9 @@ int main(int argc, const char *argv[]) exit(1); } + /* start the protocol running */ + ret = ctdb_start(ctdb); + key.dptr = "test"; key.dsize = strlen("test")+1;