diff options
| author | Ronnie Sahlberg <sahlberg@ronnie> | 2007-04-29 23:49:27 +1000 |
|---|---|---|
| committer | Ronnie Sahlberg <sahlberg@ronnie> | 2007-04-29 23:49:27 +1000 |
| commit | f67a79ad8ef6ce21aaefa75ecf04d447c92d11bc (patch) | |
| tree | ed87d2dc821af1896700dc2d422b62c7d6d2acaf | |
| parent | 77ce5750b2a18c1b4a82f3bc982fbb3ea465b60c (diff) | |
| parent | 10910f52eb1e62bf5393952f4c3a7380bf2dc548 (diff) | |
merge from tridge
(This used to be ctdb commit a84e9b47a87fc7d4756b4a179aa2ea0bc7c54c78)
| -rw-r--r-- | ctdb/Makefile.in | 10 | ||||
| -rw-r--r-- | ctdb/common/ctdb.c | 6 | ||||
| -rw-r--r-- | ctdb/common/ctdb_call.c | 82 | ||||
| -rw-r--r-- | ctdb/common/ctdb_client.c | 82 | ||||
| -rw-r--r-- | ctdb/common/ctdb_control.c | 8 | ||||
| -rw-r--r-- | ctdb/common/ctdb_daemon.c | 2 | ||||
| -rw-r--r-- | ctdb/include/ctdb.h | 8 | ||||
| -rw-r--r-- | ctdb/include/ctdb_private.h | 41 | ||||
| -rwxr-xr-x | ctdb/tests/run_tests.sh | 4 | ||||
| -rw-r--r-- | ctdb/tools/ctdb_control.c | 167 |
10 files changed, 277 insertions, 133 deletions
diff --git a/ctdb/Makefile.in b/ctdb/Makefile.in index a80908c638..ff53535c90 100644 --- a/ctdb/Makefile.in +++ b/ctdb/Makefile.in @@ -108,8 +108,14 @@ distclean: clean install: all mkdir -p $(bindir) mkdir -p $(includedir) - cp $(BINS) $(bindir) - cp $(srcdir)/include/ctdb.h $(includedir) + rsync $(BINS) $(bindir) + rsync $(srcdir)/include/ctdb.h $(includedir) + +test: + tests/run_tests.sh + +valgrindtest: + VALGRIND="valgrind -q --trace-children=yes" tests/run_tests.sh test: tests/run_tests.sh diff --git a/ctdb/common/ctdb.c b/ctdb/common/ctdb.c index d2cf41f647..6ae32f5a0f 100644 --- a/ctdb/common/ctdb.c +++ b/ctdb/common/ctdb.c @@ -105,6 +105,7 @@ static int ctdb_add_node(struct ctdb_context *ctdb, char *nstr) if (ctdb_same_address(&ctdb->address, &node->address)) { ctdb->vnn = node->vnn; + node->flags |= NODE_FLAGS_CONNECTED; } ctdb->num_nodes++; @@ -278,11 +279,6 @@ void ctdb_recv_pkt(struct ctdb_context *ctdb, uint8_t *data, uint32_t length) ctdb_reply_error(ctdb, hdr); break; - case CTDB_REPLY_REDIRECT: - ctdb->status.count.reply_redirect++; - ctdb_reply_redirect(ctdb, hdr); - break; - case CTDB_REQ_DMASTER: ctdb->status.count.req_dmaster++; ctdb_request_dmaster(ctdb, hdr); diff --git a/ctdb/common/ctdb_call.c b/ctdb/common/ctdb_call.c index 18172996ca..012e6758a5 100644 --- a/ctdb/common/ctdb_call.c +++ b/ctdb/common/ctdb_call.c @@ -162,22 +162,18 @@ static void ctdb_send_error(struct ctdb_context *ctdb, send a redirect reply */ static void ctdb_call_send_redirect(struct ctdb_context *ctdb, + TDB_DATA key, struct ctdb_req_call *c, struct ctdb_ltdb_header *header) { - struct ctdb_reply_redirect *r; - - r = ctdb_transport_allocate(ctdb, ctdb, CTDB_REPLY_REDIRECT, sizeof(*r), - struct ctdb_reply_redirect); - CTDB_NO_MEMORY_FATAL(ctdb, r); - - r->hdr.destnode = c->hdr.srcnode; - r->hdr.reqid = c->hdr.reqid; - r->dmaster = header->dmaster; - - ctdb_queue_packet(ctdb, &r->hdr); - - talloc_free(r); + + uint32_t lmaster = ctdb_lmaster(ctdb, &key); + if (ctdb->vnn == lmaster) { + c->hdr.destnode = header->dmaster; + } else { + c->hdr.destnode = lmaster; + } + ctdb_queue_packet(ctdb, &c->hdr); } @@ -438,8 +434,8 @@ void ctdb_request_call(struct ctdb_context *ctdb, struct ctdb_req_header *hdr) /* if we are not the dmaster, then send a redirect to the requesting node */ if (header.dmaster != ctdb->vnn) { - ctdb_call_send_redirect(ctdb, c, &header); talloc_free(data.dptr); + ctdb_call_send_redirect(ctdb, call.key, c, &header); ctdb_ltdb_unlock(ctdb_db, call.key); return; } @@ -595,49 +591,11 @@ void ctdb_reply_error(struct ctdb_context *ctdb, struct ctdb_req_header *hdr) /* - called when a CTDB_REPLY_REDIRECT packet comes in - - This packet arrives when we have sent a CTDB_REQ_CALL request and - the node that received it is not the dmaster for the given key. We - are given a hint as to what node to try next. -*/ -void ctdb_reply_redirect(struct ctdb_context *ctdb, struct ctdb_req_header *hdr) -{ - struct ctdb_reply_redirect *c = (struct ctdb_reply_redirect *)hdr; - struct ctdb_call_state *state; - - state = ctdb_reqid_find(ctdb, hdr->reqid, struct ctdb_call_state); - if (state == NULL) { - return; - } - - if (hdr->reqid != state->reqid) { - /* we found a record but it was the wrong one */ - DEBUG(0, ("Dropped orphaned dmaster reply with reqid:%d\n",hdr->reqid)); - return; - } - - /* don't allow for too many redirects */ - if ((++state->redirect_count) % CTDB_MAX_REDIRECT == 0) { - c->dmaster = ctdb_lmaster(ctdb, &state->call.key); - if (state->redirect_count > ctdb->status.max_redirect_count) { - ctdb->status.max_redirect_count = state->redirect_count; - } - } - - /* send it off again */ - state->node = ctdb->nodes[c->dmaster]; - state->c->hdr.destnode = c->dmaster; - - ctdb_queue_packet(ctdb, &state->c->hdr); -} - -/* destroy a ctdb_call */ static int ctdb_call_destructor(struct ctdb_call_state *state) { - ctdb_reqid_remove(state->node->ctdb, state->reqid); + ctdb_reqid_remove(state->ctdb_db->ctdb, state->reqid); return 0; } @@ -651,7 +609,7 @@ void ctdb_call_timeout(struct event_context *ev, struct timed_event *te, struct ctdb_call_state *state = talloc_get_type(private_data, struct ctdb_call_state); DEBUG(0,(__location__ " call timeout for reqid %d\n", state->c->hdr.reqid)); state->state = CTDB_CALL_ERROR; - ctdb_set_error(state->node->ctdb, "ctdb_call %u timed out", + ctdb_set_error(state->ctdb_db->ctdb, "ctdb_call %u timed out", state->c->hdr.reqid); if (state->async.fn) { state->async.fn(state); @@ -692,7 +650,6 @@ struct ctdb_call_state *ctdb_call_local_send(struct ctdb_db_context *ctdb_db, talloc_steal(state, data->dptr); state->state = CTDB_CALL_DONE; - state->node = ctdb->nodes[ctdb->vnn]; state->call = *call; state->ctdb_db = ctdb_db; @@ -729,12 +686,14 @@ struct ctdb_call_state *ctdb_daemon_call_send_remote(struct ctdb_db_context *ctd struct ctdb_req_call); CTDB_NO_MEMORY_NULL(ctdb, state->c); state->c->hdr.destnode = header->dmaster; - /* - always sending the remote call straight to the lmaster + +#if 0 + /*always sending the remote call straight to the lmaster improved performance slightly in some tests. worth investigating further in the future - state->c->hdr.destnode = ctdb_lmaster(ctdb_db->ctdb, &(call->key)); */ + state->c->hdr.destnode = ctdb_lmaster(ctdb_db->ctdb, &(call->key)); +#endif /* this limits us to 16k outstanding messages - not unreasonable */ @@ -751,7 +710,6 @@ struct ctdb_call_state *ctdb_daemon_call_send_remote(struct ctdb_db_context *ctd state->call.call_data.dptr = &state->c->data[call->key.dsize]; state->call.key.dptr = &state->c->data[0]; - state->node = ctdb->nodes[header->dmaster]; state->state = CTDB_CALL_WAIT; state->header = *header; state->ctdb_db = ctdb_db; @@ -774,16 +732,16 @@ struct ctdb_call_state *ctdb_daemon_call_send_remote(struct ctdb_db_context *ctd int ctdb_daemon_call_recv(struct ctdb_call_state *state, struct ctdb_call *call) { while (state->state < CTDB_CALL_DONE) { - event_loop_once(state->node->ctdb->ev); + event_loop_once(state->ctdb_db->ctdb->ev); } if (state->state != CTDB_CALL_DONE) { - ctdb_set_error(state->node->ctdb, "%s", state->errmsg); + ctdb_set_error(state->ctdb_db->ctdb, "%s", state->errmsg); talloc_free(state); return -1; } if (state->call.reply_data.dsize) { - call->reply_data.dptr = talloc_memdup(state->node->ctdb, + call->reply_data.dptr = talloc_memdup(state->ctdb_db->ctdb, state->call.reply_data.dptr, state->call.reply_data.dsize); call->reply_data.dsize = state->call.reply_data.dsize; diff --git a/ctdb/common/ctdb_client.c b/ctdb/common/ctdb_client.c index d7dc7be54d..d11bab6fc4 100644 --- a/ctdb/common/ctdb_client.c +++ b/ctdb/common/ctdb_client.c @@ -879,13 +879,15 @@ int ctdb_getdbmap(struct ctdb_context *ctdb, uint32_t destnode, struct ctdb_dbid /* get a list of nodes (vnn and flags ) from a remote node */ -int ctdb_getnodemap(struct ctdb_context *ctdb, uint32_t destnode, struct ctdb_node_map *nodemap) +int ctdb_getnodemap(struct ctdb_context *ctdb, uint32_t destnode, + TALLOC_CTX *mem_ctx, struct ctdb_node_map *nodemap) { int ret; TDB_DATA data, outdata; int32_t i, res; ZERO_STRUCT(data); + ZERO_STRUCT(*nodemap); ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_GET_NODEMAP, data, ctdb, &outdata, &res); @@ -895,15 +897,9 @@ int ctdb_getnodemap(struct ctdb_context *ctdb, uint32_t destnode, struct ctdb_no } nodemap->num = ((uint32_t *)outdata.dptr)[0]; - if (nodemap->nodes) { - talloc_free(nodemap->nodes); - nodemap->nodes=NULL; - } - nodemap->nodes=talloc_array(nodemap, struct ctdb_node_and_flags, nodemap->num); - if (!nodemap->nodes) { - DEBUG(0,(__location__ " failed to talloc nodemap\n")); - return -1; - } + nodemap->nodes=talloc_array(mem_ctx, struct ctdb_node_and_flags, nodemap->num); + CTDB_NO_MEMORY(ctdb, nodemap->nodes); + for (i=0;i<nodemap->num;i++) { nodemap->nodes[i].vnn = ((uint32_t *)outdata.dptr)[2*i+1]; nodemap->nodes[i].flags = ((uint32_t *)outdata.dptr)[2*i+2]; @@ -1083,7 +1079,7 @@ int ctdb_pulldb(struct ctdb_context *ctdb, uint32_t destnode, TALLOC_CTX *mem_ct } /* - ping a node + ping a node, return number of clients connected */ int ctdb_ping(struct ctdb_context *ctdb, uint32_t destnode) { @@ -1093,10 +1089,10 @@ int ctdb_ping(struct ctdb_context *ctdb, uint32_t destnode) ZERO_STRUCT(data); ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_PING, data, NULL, NULL, &res); - if (ret != 0 || res != 0) { + if (ret != 0) { return -1; } - return 0; + return res; } /* @@ -1205,3 +1201,63 @@ int ctdb_set_debuglevel(struct ctdb_context *ctdb, uint32_t destnode, uint32_t l } return 0; } + + +/* + get a list of connected nodes + */ +uint32_t *ctdb_get_connected_nodes(struct ctdb_context *ctdb, TALLOC_CTX *mem_ctx, + uint32_t *num_nodes) +{ + struct ctdb_node_map *map; + int ret, i; + uint32_t *nodes; + + *num_nodes = 0; + + map = talloc(mem_ctx, struct ctdb_node_map); + CTDB_NO_MEMORY_VOID(ctdb, map); + + ret = ctdb_getnodemap(ctdb, CTDB_CURRENT_NODE, map, map); + if (ret != 0) { + talloc_free(map); + return NULL; + } + + nodes = talloc_array(mem_ctx, uint32_t, map->num); + if (nodes == NULL) { + talloc_free(map); + return NULL; + } + + for (i=0;i<map->num;i++) { + if (map->nodes[i].flags & NODE_FLAGS_CONNECTED) { + nodes[*num_nodes] = map->nodes[i].vnn; + (*num_nodes)++; + } + } + + talloc_free(map); + return nodes; +} + + +/* + reset remote status + */ +int ctdb_status_reset(struct ctdb_context *ctdb, uint32_t destnode) +{ + int ret; + TDB_DATA data; + int32_t res; + + ZERO_STRUCT(data); + ret = ctdb_control(ctdb, destnode, 0, + CTDB_CONTROL_STATUS_RESET, data, + NULL, NULL, &res); + if (ret != 0 || res != 0) { + DEBUG(0,(__location__ " ctdb_control for reset status failed\n")); + return -1; + } + return 0; +} diff --git a/ctdb/common/ctdb_control.c b/ctdb/common/ctdb_control.c index 102d0debb3..2fb299f44e 100644 --- a/ctdb/common/ctdb_control.c +++ b/ctdb/common/ctdb_control.c @@ -160,6 +160,12 @@ static int32_t ctdb_control_dispatch(struct ctdb_context *ctdb, return 0; } + case CTDB_CONTROL_STATUS_RESET: { + CHECK_CONTROL_DATA_SIZE(0); + ZERO_STRUCT(ctdb->status); + return 0; + } + case CTDB_CONTROL_GETVNNMAP: { uint32_t i, len; CHECK_CONTROL_DATA_SIZE(0); @@ -377,7 +383,7 @@ static int32_t ctdb_control_dispatch(struct ctdb_context *ctdb, case CTDB_CONTROL_PING: CHECK_CONTROL_DATA_SIZE(0); - return 0; + return ctdb->num_clients; case CTDB_CONTROL_GETDBPATH: { uint32_t db_id; diff --git a/ctdb/common/ctdb_daemon.c b/ctdb/common/ctdb_daemon.c index d305718575..d0d2c1a46d 100644 --- a/ctdb/common/ctdb_daemon.c +++ b/ctdb/common/ctdb_daemon.c @@ -232,6 +232,7 @@ static void daemon_request_connect_wait(struct ctdb_client *client, */ static int ctdb_client_destructor(struct ctdb_client *client) { + client->ctdb->num_clients--; close(client->fd); client->fd = -1; return 0; @@ -547,6 +548,7 @@ static void ctdb_accept_client(struct event_context *ev, struct fd_event *fde, client = talloc_zero(ctdb, struct ctdb_client); client->ctdb = ctdb; client->fd = fd; + ctdb->num_clients++; client->queue = ctdb_queue_setup(ctdb, client, fd, CTDB_DS_ALIGNMENT, ctdb_daemon_read_cb, client); diff --git a/ctdb/include/ctdb.h b/ctdb/include/ctdb.h index aa2f31fa34..1e382b4b8c 100644 --- a/ctdb/include/ctdb.h +++ b/ctdb/include/ctdb.h @@ -239,7 +239,8 @@ struct ctdb_node_map { uint32_t num; struct ctdb_node_and_flags *nodes; }; -int ctdb_getnodemap(struct ctdb_context *ctdb, uint32_t destnode, struct ctdb_node_map *nodemap); +int ctdb_getnodemap(struct ctdb_context *ctdb, uint32_t destnode, + TALLOC_CTX *mem_ctx, struct ctdb_node_map *nodemap); struct ctdb_key_list { uint32_t num; @@ -288,4 +289,9 @@ int ctdb_getrecmode(struct ctdb_context *ctdb, uint32_t destnode, uint32_t *recm */ int ctdb_setrecmode(struct ctdb_context *ctdb, uint32_t destnode, uint32_t recmode); +uint32_t *ctdb_get_connected_nodes(struct ctdb_context *ctdb, TALLOC_CTX *mem_ctx, + uint32_t *num_nodes); + +int ctdb_status_reset(struct ctdb_context *ctdb, uint32_t destnode); + #endif diff --git a/ctdb/include/ctdb_private.h b/ctdb/include/ctdb_private.h index 73de824f33..e3b33ff6bf 100644 --- a/ctdb/include/ctdb_private.h +++ b/ctdb/include/ctdb_private.h @@ -135,7 +135,6 @@ struct ctdb_status { struct { uint32_t req_call; uint32_t reply_call; - uint32_t reply_redirect; uint32_t req_dmaster; uint32_t reply_dmaster; uint32_t reply_error; @@ -157,7 +156,7 @@ struct ctdb_status { uint32_t pending_calls; uint32_t lockwait_calls; uint32_t pending_lockwait_calls; - uint32_t max_redirect_count; + uint32_t __last_counter; /* hack for control_status_all */ double max_call_latency; double max_lockwait_latency; }; @@ -196,6 +195,7 @@ struct ctdb_context { struct ctdb_daemon_data daemon; struct ctdb_status status; struct ctdb_vnn_map *vnn_map; + uint32_t num_clients; }; struct ctdb_db_context { @@ -228,9 +228,6 @@ struct ctdb_db_context { /* arbitrary maximum timeout for ctdb operations */ #define CTDB_REQ_TIMEOUT 0 -/* max number of redirects before we ask the lmaster */ -#define CTDB_MAX_REDIRECT 2 - /* number of consecutive calls from the same node before we give them the record */ #define CTDB_DEFAULT_MAX_LACOUNT 7 @@ -261,7 +258,8 @@ enum ctdb_controls {CTDB_CONTROL_PROCESS_EXISTS, CTDB_CONTROL_CLEAR_DB, CTDB_CONTROL_PULL_DB, CTDB_CONTROL_GET_RECMODE, - CTDB_CONTROL_SET_RECMODE}; + CTDB_CONTROL_SET_RECMODE, + CTDB_CONTROL_STATUS_RESET}; enum call_state {CTDB_CALL_WAIT, CTDB_CALL_DONE, CTDB_CALL_ERROR}; @@ -273,10 +271,8 @@ struct ctdb_call_state { uint32_t reqid; struct ctdb_req_call *c; struct ctdb_db_context *ctdb_db; - struct ctdb_node *node; const char *errmsg; struct ctdb_call call; - int redirect_count; struct ctdb_ltdb_header header; struct { void (*fn)(struct ctdb_call_state *); @@ -298,21 +294,20 @@ struct ctdb_fetch_handle { */ enum ctdb_operation { CTDB_REQ_CALL = 0, - CTDB_REPLY_CALL = 1, - CTDB_REPLY_REDIRECT = 2, - CTDB_REQ_DMASTER = 3, - CTDB_REPLY_DMASTER = 4, - CTDB_REPLY_ERROR = 5, - CTDB_REQ_MESSAGE = 6, - CTDB_REQ_FINISHED = 7, - CTDB_REQ_CONTROL = 8, - CTDB_REPLY_CONTROL = 9, + CTDB_REPLY_CALL, + CTDB_REQ_DMASTER, + CTDB_REPLY_DMASTER, + CTDB_REPLY_ERROR, + CTDB_REQ_MESSAGE, + CTDB_REQ_FINISHED, + CTDB_REQ_CONTROL, + CTDB_REPLY_CONTROL, /* only used on the domain socket */ CTDB_REQ_REGISTER = 1000, - CTDB_REQ_CONNECT_WAIT = 1001, - CTDB_REPLY_CONNECT_WAIT = 1002, - CTDB_REQ_SHUTDOWN = 1003 + CTDB_REQ_CONNECT_WAIT, + CTDB_REPLY_CONNECT_WAIT, + CTDB_REQ_SHUTDOWN }; #define CTDB_MAGIC 0x43544442 /* CTDB */ @@ -356,11 +351,6 @@ struct ctdb_reply_error { uint8_t msg[1]; }; -struct ctdb_reply_redirect { - struct ctdb_req_header hdr; - uint32_t dmaster; -}; - struct ctdb_req_dmaster { struct ctdb_req_header hdr; uint32_t db_id; @@ -447,7 +437,6 @@ void ctdb_request_message(struct ctdb_context *ctdb, struct ctdb_req_header *hdr void ctdb_reply_dmaster(struct ctdb_context *ctdb, struct ctdb_req_header *hdr); void ctdb_reply_call(struct ctdb_context *ctdb, struct ctdb_req_header *hdr); void ctdb_reply_error(struct ctdb_context *ctdb, struct ctdb_req_header *hdr); -void ctdb_reply_redirect(struct ctdb_context *ctdb, struct ctdb_req_header *hdr); uint32_t ctdb_lmaster(struct ctdb_context *ctdb, const TDB_DATA *key); int ctdb_ltdb_fetch(struct ctdb_db_context *ctdb_db, diff --git a/ctdb/tests/run_tests.sh b/ctdb/tests/run_tests.sh index 983afa0adb..e628bad800 100755 --- a/ctdb/tests/run_tests.sh +++ b/ctdb/tests/run_tests.sh @@ -1,7 +1,7 @@ #!/bin/sh -tests/fetch.sh || exit 1 -tests/bench.sh || exit 1 +tests/fetch.sh 4 || exit 1 +tests/bench.sh 4 || exit 1 tests/test.sh || exit 1 echo "All OK" diff --git a/ctdb/tools/ctdb_control.c b/ctdb/tools/ctdb_control.c index d2fa2a4308..469914da87 100644 --- a/ctdb/tools/ctdb_control.c +++ b/ctdb/tools/ctdb_control.c @@ -35,8 +35,9 @@ static void usage(void) printf("\nControls:\n"); printf(" ping\n"); printf(" process-exists <vnn:pid> see if a process exists\n"); - printf(" status <vnn> show ctdb status on a node\n"); - printf(" debug <vnn> <level> set ctdb debug level on a node\n"); + printf(" status <vnn|all> show ctdb status on a node\n"); + printf(" statusreset <vnn|all> reset status on a node\n"); + printf(" debug <vnn|all> <level> set ctdb debug level on a node\n"); printf(" debuglevel display ctdb debug levels\n"); printf(" getvnnmap <vnn> display ctdb vnnmap\n"); printf(" setvnnmap <vnn> <generation> <numslots> <lmaster>*\n"); @@ -95,23 +96,61 @@ static void show_status(struct ctdb_status *s) printf(" node_packets_recv %u\n", s->node_packets_recv); printf(" req_call %u\n", s->count.req_call); printf(" reply_call %u\n", s->count.reply_call); - printf(" reply_redirect %u\n", s->count.reply_redirect); printf(" req_dmaster %u\n", s->count.req_dmaster); printf(" reply_dmaster %u\n", s->count.reply_dmaster); printf(" reply_error %u\n", s->count.reply_error); - printf(" reply_redirect %u\n", s->count.reply_redirect); printf(" req_message %u\n", s->count.req_message); printf(" req_finished %u\n", s->count.req_finished); printf(" total_calls %u\n", s->total_calls); printf(" pending_calls %u\n", s->pending_calls); printf(" lockwait_calls %u\n", s->lockwait_calls); printf(" pending_lockwait_calls %u\n", s->pending_lockwait_calls); - printf(" max_redirect_count %u\n", s->max_redirect_count); printf(" max_call_latency %.6f sec\n", s->max_call_latency); printf(" max_lockwait_latency %.6f sec\n", s->max_lockwait_latency); } /* + display remote ctdb status combined from all nodes + */ +static int control_status_all(struct ctdb_context *ctdb) +{ + int ret, i; + struct ctdb_status status; + uint32_t *nodes; + uint32_t num_nodes; + + nodes = ctdb_get_connected_nodes(ctdb, ctdb, &num_nodes); + CTDB_NO_MEMORY(ctdb, nodes); + + ZERO_STRUCT(status); + + for (i=0;i<num_nodes;i++) { + struct ctdb_status s1; + int j; + uint32_t *v1 = (uint32_t *)&s1; + uint32_t *v2 = (uint32_t *)&status; + uint32_t num_ints = + offsetof(struct ctdb_status, __last_counter) / sizeof(uint32_t); + ret = ctdb_status(ctdb, nodes[i], &s1); + if (ret != 0) { + printf("Unable to get status from node %u\n", nodes[i]); + return ret; + } + for (j=0;j<num_ints;j++) { + v2[j] += v1[j]; + } + status.max_call_latency = + MAX(status.max_call_latency, s1.max_call_latency); + status.max_lockwait_latency = + MAX(status.max_lockwait_latency, s1.max_lockwait_latency); + } + talloc_free(nodes); + printf("Gathered status for %u nodes\n", num_nodes); + show_status(&status); + return 0; +} + +/* display remote ctdb status */ static int control_status(struct ctdb_context *ctdb, int argc, const char **argv) @@ -123,6 +162,10 @@ static int control_status(struct ctdb_context *ctdb, int argc, const char **argv usage(); } + if (strcmp(argv[0], "all") == 0) { + return control_status_all(ctdb); + } + vnn = strtoul(argv[0], NULL, 0); ret = ctdb_status(ctdb, vnn, &status); @@ -134,6 +177,56 @@ static int control_status(struct ctdb_context *ctdb, int argc, const char **argv return 0; } + +/* + reset status on all nodes + */ +static int control_status_reset_all(struct ctdb_context *ctdb) +{ + int ret, i; + uint32_t *nodes; + uint32_t num_nodes; + + nodes = ctdb_get_connected_nodes(ctdb, ctdb, &num_nodes); + CTDB_NO_MEMORY(ctdb, nodes); + + for (i=0;i<num_nodes;i++) { + ret = ctdb_status_reset(ctdb, nodes[i]); + if (ret != 0) { + printf("Unable to reset status on node %u\n", nodes[i]); + return ret; + } + } + talloc_free(nodes); + return 0; +} + + +/* + reset remote ctdb status + */ +static int control_status_reset(struct ctdb_context *ctdb, int argc, const char **argv) +{ + uint32_t vnn; + int ret; + if (argc < 1) { + usage(); + } + + if (strcmp(argv[0], "all") == 0) { + return control_status_reset_all(ctdb); + } + + vnn = strtoul(argv[0], NULL, 0); + + ret = ctdb_status_reset(ctdb, vnn); + if (ret != 0) { + printf("Unable to reset status on node %u\n", vnn); + return ret; + } + return 0; +} + /* display remote ctdb vnn map */ @@ -303,7 +396,7 @@ static int control_getnodemap(struct ctdb_context *ctdb, int argc, const char ** vnn = strtoul(argv[0], NULL, 0); nodemap = talloc_zero(ctdb, struct ctdb_node_map); - ret = ctdb_getnodemap(ctdb, vnn, nodemap); + ret = ctdb_getnodemap(ctdb, vnn, nodemap, nodemap); if (ret != 0) { printf("Unable to get nodemap from node %u\n", vnn); talloc_free(nodemap); @@ -428,17 +521,23 @@ static int control_pulldb(struct ctdb_context *ctdb, int argc, const char **argv static int control_ping(struct ctdb_context *ctdb, int argc, const char **argv) { int ret, i; + uint32_t *nodes; + uint32_t num_nodes; - for (i=0;i<ctdb->num_nodes;i++) { + nodes = ctdb_get_connected_nodes(ctdb, ctdb, &num_nodes); + CTDB_NO_MEMORY(ctdb, nodes); + + for (i=0;i<num_nodes;i++) { struct timeval tv = timeval_current(); - ret = ctdb_ping(ctdb, i); - if (ret != 0) { - printf("Unable to get ping response from node %u\n", i); + ret = ctdb_ping(ctdb, nodes[i]); + if (ret == -1) { + printf("Unable to get ping response from node %u\n", nodes[i]); } else { - printf("response from %u time=%.6f sec\n", - i, timeval_elapsed(&tv)); + printf("response from %u time=%.6f sec (%d clients)\n", + nodes[i], timeval_elapsed(&tv), ret); } } + talloc_free(nodes); return 0; } @@ -449,16 +548,23 @@ static int control_ping(struct ctdb_context *ctdb, int argc, const char **argv) static int control_debuglevel(struct ctdb_context *ctdb, int argc, const char **argv) { int ret, i; + uint32_t *nodes; + uint32_t num_nodes; + + nodes = ctdb_get_connected_nodes(ctdb, ctdb, &num_nodes); + CTDB_NO_MEMORY(ctdb, nodes); - for (i=0;i<ctdb->num_nodes;i++) { + for (i=0;i<num_nodes;i++) { uint32_t level; - ret = ctdb_get_debuglevel(ctdb, i, &level); + ret = ctdb_get_debuglevel(ctdb, nodes[i], &level); if (ret != 0) { - printf("Unable to get debuglevel response from node %u\n", i); + printf("Unable to get debuglevel response from node %u\n", + nodes[i]); } else { - printf("Node %u is at debug level %u\n", i, level); + printf("Node %u is at debug level %u\n", nodes[i], level); } } + talloc_free(nodes); return 0; } @@ -468,19 +574,36 @@ static int control_debuglevel(struct ctdb_context *ctdb, int argc, const char ** static int control_debug(struct ctdb_context *ctdb, int argc, const char **argv) { int ret; - uint32_t vnn, level; + uint32_t vnn, level, i; + uint32_t *nodes; + uint32_t num_nodes; if (argc < 2) { usage(); } - vnn = strtoul(argv[0], NULL, 0); level = strtoul(argv[1], NULL, 0); - ret = ctdb_set_debuglevel(ctdb, vnn, level); - if (ret != 0) { - printf("Unable to set debug level on node %u\n", vnn); + if (strcmp(argv[0], "all") != 0) { + vnn = strtoul(argv[0], NULL, 0); + ret = ctdb_set_debuglevel(ctdb, vnn, level); + if (ret != 0) { + printf("Unable to set debug level on node %u\n", vnn); + } + + return 0; + } + + nodes = ctdb_get_connected_nodes(ctdb, ctdb, &num_nodes); + CTDB_NO_MEMORY(ctdb, nodes); + for (i=0;i<num_nodes;i++) { + ret = ctdb_set_debuglevel(ctdb, nodes[i], level); + if (ret != 0) { + printf("Unable to set debug level on node %u\n", nodes[i]); + break; + } } + talloc_free(nodes); return 0; } @@ -540,6 +663,8 @@ int main(int argc, const char *argv[]) ret = control_process_exists(ctdb, extra_argc-1, extra_argv+1); } else if (strcmp(control, "status") == 0) { ret = control_status(ctdb, extra_argc-1, extra_argv+1); + } else if (strcmp(control, "statusreset") == 0) { + ret = control_status_reset(ctdb, extra_argc-1, extra_argv+1); } else if (strcmp(control, "getvnnmap") == 0) { ret = control_getvnnmap(ctdb, extra_argc-1, extra_argv+1); } else if (strcmp(control, "getdbmap") == 0) { |
