mirror of
https://github.com/samba-team/samba.git
synced 2025-03-20 22:50:26 +03:00
merge from tridge
(This used to be ctdb commit a84e9b47a87fc7d4756b4a179aa2ea0bc7c54c78)
This commit is contained in:
commit
f67a79ad8e
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
@ -594,50 +590,12 @@ 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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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"
|
||||
|
@ -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,22 +96,60 @@ 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
|
||||
*/
|
||||
@ -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;
|
||||
|
||||
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++) {
|
||||
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) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user