]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
- renamed ctdb_control utility to ctdb
authorAndrew Tridgell <tridge@samba.org>
Tue, 29 May 2007 02:16:59 +0000 (12:16 +1000)
committerAndrew Tridgell <tridge@samba.org>
Tue, 29 May 2007 02:16:59 +0000 (12:16 +1000)
- use -n to specify node number in ctdb utility

- change 'ctdb status' to 'ctdb statistics'

- added 'ctdb status' which shows status

- added netmask to public IPs, so you don't try a takeover on a
  foreign network

- cleaned up tools/ctdb_control.c a lot

- generate usage message at runtime

(This used to be ctdb commit 28de71c03ace7d32a9fd9882fabbd5d668b97656)

14 files changed:
ctdb/Makefile.in
ctdb/common/ctdb.c
ctdb/common/ctdb_call.c
ctdb/common/ctdb_client.c
ctdb/common/ctdb_control.c
ctdb/common/ctdb_daemon.c
ctdb/common/ctdb_lockwait.c
ctdb/common/ctdb_traverse.c
ctdb/include/ctdb.h
ctdb/include/ctdb_private.h
ctdb/takeover/ctdb_takeover.c
ctdb/tests/ctdbd.sh
ctdb/tools/ctdb_control.c
ctdb/tools/monitor_recovery.sh

index d4fbc95edeac3510121065bc50e9305c135a13eb..a0e693876b7b0c1241359d0c40f5bc5445c9b3ae 100644 (file)
@@ -41,7 +41,7 @@ CTDB_OBJ = $(CTDB_COMMON_OBJ) $(CTDB_TAKEOVER_OBJ) $(CTDB_TCP_OBJ) $(POPT_OBJ)
 
 OBJS = @TDB_OBJ@ @TALLOC_OBJ@ @LIBREPLACEOBJ@ @INFINIBAND_WRAPPER_OBJ@ $(EXTRA_OBJ) @EVENTS_OBJ@ $(CTDB_OBJ) $(UTIL_OBJ)
 
-BINS = bin/ctdbd bin/ctdbd_test bin/ctdb_test bin/ctdb_bench bin/ctdb_messaging bin/ctdb_fetch bin/ctdb_fetch1 bin/lockwait bin/ctdb_control @INFINIBAND_BINS@
+BINS = bin/ctdbd bin/ctdbd_test bin/ctdb_test bin/ctdb_bench bin/ctdb_messaging bin/ctdb_fetch bin/ctdb_fetch1 bin/lockwait bin/ctdb @INFINIBAND_BINS@
 
 DIRS = lib bin
 
index 2f0c21b5ba63d0fe7ca8659ac3f9399df60fd88b..1f43a95b11e84b76375c8f178375f43092c41a85 100644 (file)
@@ -279,52 +279,52 @@ void ctdb_input_pkt(struct ctdb_context *ctdb, struct ctdb_req_header *hdr)
 
        switch (hdr->operation) {
        case CTDB_REQ_CALL:
-               ctdb->status.node.req_call++;
+               ctdb->statistics.node.req_call++;
                ctdb_request_call(ctdb, hdr);
                break;
 
        case CTDB_REPLY_CALL:
-               ctdb->status.node.reply_call++;
+               ctdb->statistics.node.reply_call++;
                ctdb_reply_call(ctdb, hdr);
                break;
 
        case CTDB_REPLY_ERROR:
-               ctdb->status.node.reply_error++;
+               ctdb->statistics.node.reply_error++;
                ctdb_reply_error(ctdb, hdr);
                break;
 
        case CTDB_REQ_DMASTER:
-               ctdb->status.node.req_dmaster++;
+               ctdb->statistics.node.req_dmaster++;
                ctdb_request_dmaster(ctdb, hdr);
                break;
 
        case CTDB_REPLY_DMASTER:
-               ctdb->status.node.reply_dmaster++;
+               ctdb->statistics.node.reply_dmaster++;
                ctdb_reply_dmaster(ctdb, hdr);
                break;
 
        case CTDB_REQ_MESSAGE:
-               ctdb->status.node.req_message++;
+               ctdb->statistics.node.req_message++;
                ctdb_request_message(ctdb, hdr);
                break;
 
        case CTDB_REQ_FINISHED:
-               ctdb->status.node.req_finished++;
+               ctdb->statistics.node.req_finished++;
                ctdb_request_finished(ctdb, hdr);
                break;
 
        case CTDB_REQ_CONTROL:
-               ctdb->status.node.req_control++;
+               ctdb->statistics.node.req_control++;
                ctdb_request_control(ctdb, hdr);
                break;
 
        case CTDB_REPLY_CONTROL:
-               ctdb->status.node.reply_control++;
+               ctdb->statistics.node.reply_control++;
                ctdb_reply_control(ctdb, hdr);
                break;
 
        case CTDB_REQ_KEEPALIVE:
-               ctdb->status.keepalive_packets_recv++;
+               ctdb->statistics.keepalive_packets_recv++;
                break;
 
        default:
@@ -345,7 +345,7 @@ static void ctdb_recv_pkt(struct ctdb_context *ctdb, uint8_t *data, uint32_t len
 {
        struct ctdb_req_header *hdr = (struct ctdb_req_header *)data;
 
-       ctdb->status.node_packets_recv++;
+       ctdb->statistics.node_packets_recv++;
 
        /* up the counter for this source node, so we know its alive */
        if (ctdb_validate_vnn(ctdb, hdr->srcnode)) {
@@ -487,7 +487,7 @@ void ctdb_queue_packet(struct ctdb_context *ctdb, struct ctdb_req_header *hdr)
                return;
        }
 
-       ctdb->status.node_packets_sent++;
+       ctdb->statistics.node_packets_sent++;
 
        if (!ctdb_validate_vnn(ctdb, hdr->destnode)) {
                DEBUG(0,(__location__ " cant send to node %u that does not exist\n", 
index c4194e3835de7ee612b727a94441ddf179f54400..22f21b33e76bb226ad2cf6cab10c096f540091b1 100644 (file)
@@ -465,8 +465,8 @@ void ctdb_request_call(struct ctdb_context *ctdb, struct ctdb_req_header *hdr)
                return;
        }
 
-       if (c->hopcount > ctdb->status.max_hop_count) {
-               ctdb->status.max_hop_count = c->hopcount;
+       if (c->hopcount > ctdb->statistics.max_hop_count) {
+               ctdb->statistics.max_hop_count = c->hopcount;
        }
 
        /* if this nodes has done enough consecutive calls on the same record
@@ -801,7 +801,7 @@ void ctdb_send_keepalive(struct ctdb_context *ctdb, uint32_t destnode)
        r->hdr.destnode  = destnode;
        r->hdr.reqid     = 0;
        
-       ctdb->status.keepalive_packets_sent++;
+       ctdb->statistics.keepalive_packets_sent++;
 
        ctdb_queue_packet(ctdb, &r->hdr);
 
index ada67fc06540d1caa16a3aa501539c9d024e2bba..c384fb3bda53e6de13f360a0205ab0249d829a97 100644 (file)
@@ -805,29 +805,29 @@ int ctdb_ctrl_process_exists(struct ctdb_context *ctdb, uint32_t destnode, pid_t
 }
 
 /*
-  get remote status
+  get remote statistics
  */
-int ctdb_ctrl_status(struct ctdb_context *ctdb, uint32_t destnode, struct ctdb_status *status)
+int ctdb_ctrl_statistics(struct ctdb_context *ctdb, uint32_t destnode, struct ctdb_statistics *status)
 {
        int ret;
        TDB_DATA data;
        int32_t res;
 
        ret = ctdb_control(ctdb, destnode, 0, 
-                          CTDB_CONTROL_STATUS, 0, tdb_null, 
+                          CTDB_CONTROL_STATISTICS, 0, tdb_null, 
                           ctdb, &data, &res, NULL, NULL);
        if (ret != 0 || res != 0) {
-               DEBUG(0,(__location__ " ctdb_control for status failed\n"));
+               DEBUG(0,(__location__ " ctdb_control for statistics failed\n"));
                return -1;
        }
 
-       if (data.dsize != sizeof(struct ctdb_status)) {
-               DEBUG(0,(__location__ " Wrong status size %u - expected %u\n",
-                        data.dsize, sizeof(struct ctdb_status)));
+       if (data.dsize != sizeof(struct ctdb_statistics)) {
+               DEBUG(0,(__location__ " Wrong statistics size %u - expected %u\n",
+                        data.dsize, sizeof(struct ctdb_statistics)));
                      return -1;
        }
 
-       *status = *(struct ctdb_status *)data.dptr;
+       *status = *(struct ctdb_statistics *)data.dptr;
        talloc_free(data.dptr);
                        
        return 0;
@@ -1397,16 +1397,16 @@ uint32_t *ctdb_get_connected_nodes(struct ctdb_context *ctdb,
 /*
   reset remote status
  */
-int ctdb_status_reset(struct ctdb_context *ctdb, uint32_t destnode)
+int ctdb_statistics_reset(struct ctdb_context *ctdb, uint32_t destnode)
 {
        int ret;
        int32_t res;
 
        ret = ctdb_control(ctdb, destnode, 0, 
-                          CTDB_CONTROL_STATUS_RESET, 0, tdb_null, 
+                          CTDB_CONTROL_STATISTICS_RESET, 0, tdb_null, 
                           NULL, NULL, &res, NULL, NULL);
        if (ret != 0 || res != 0) {
-               DEBUG(0,(__location__ " ctdb_control for reset status failed\n"));
+               DEBUG(0,(__location__ " ctdb_control for reset statistics failed\n"));
                return -1;
        }
        return 0;
index 5b9e6904f9a6535c6c325049a747c7be18ec6e37..a1885c1078a46da77410ee093ece0162c555a0f5 100644 (file)
@@ -52,7 +52,7 @@ static int32_t ctdb_control_dispatch(struct ctdb_context *ctdb,
        switch (opcode) {
        case CTDB_CONTROL_PROCESS_EXISTS: {
                CHECK_CONTROL_DATA_SIZE(sizeof(pid_t));
-               ctdb->status.controls.process_exists++;
+               ctdb->statistics.controls.process_exists++;
                return kill(*(pid_t *)indata.dptr, 0);
        }
 
@@ -69,14 +69,14 @@ static int32_t ctdb_control_dispatch(struct ctdb_context *ctdb,
                return 0;
        }
 
-       case CTDB_CONTROL_STATUS: {
+       case CTDB_CONTROL_STATISTICS: {
                CHECK_CONTROL_DATA_SIZE(0);
-               ctdb->status.controls.status++;
-               ctdb->status.memory_used = talloc_total_size(ctdb);
-               ctdb->status.frozen = (ctdb->freeze_mode == CTDB_FREEZE_FROZEN);
-               ctdb->status.recovering = (ctdb->recovery_mode == CTDB_RECOVERY_ACTIVE);
-               outdata->dptr = (uint8_t *)&ctdb->status;
-               outdata->dsize = sizeof(ctdb->status);
+               ctdb->statistics.controls.statistics++;
+               ctdb->statistics.memory_used = talloc_total_size(ctdb);
+               ctdb->statistics.frozen = (ctdb->freeze_mode == CTDB_FREEZE_FROZEN);
+               ctdb->statistics.recovering = (ctdb->recovery_mode == CTDB_RECOVERY_ACTIVE);
+               outdata->dptr = (uint8_t *)&ctdb->statistics;
+               outdata->dsize = sizeof(ctdb->statistics);
                return 0;
        }
 
@@ -86,9 +86,9 @@ static int32_t ctdb_control_dispatch(struct ctdb_context *ctdb,
                return 0;
        }
 
-       case CTDB_CONTROL_STATUS_RESET: {
+       case CTDB_CONTROL_STATISTICS_RESET: {
                CHECK_CONTROL_DATA_SIZE(0);
-               ZERO_STRUCT(ctdb->status);
+               ZERO_STRUCT(ctdb->statistics);
                return 0;
        }
 
@@ -144,7 +144,7 @@ static int32_t ctdb_control_dispatch(struct ctdb_context *ctdb,
 
        case CTDB_CONTROL_CONFIG: {
                CHECK_CONTROL_DATA_SIZE(0);
-               ctdb->status.controls.get_config++;
+               ctdb->statistics.controls.get_config++;
                outdata->dptr = (uint8_t *)ctdb;
                outdata->dsize = sizeof(*ctdb);
                return 0;
@@ -152,8 +152,8 @@ static int32_t ctdb_control_dispatch(struct ctdb_context *ctdb,
 
        case CTDB_CONTROL_PING:
                CHECK_CONTROL_DATA_SIZE(0);
-               ctdb->status.controls.ping++;
-               return ctdb->status.num_clients;
+               ctdb->statistics.controls.ping++;
+               return ctdb->statistics.num_clients;
 
        case CTDB_CONTROL_GET_DBNAME: {
                uint32_t db_id;
@@ -182,50 +182,50 @@ static int32_t ctdb_control_dispatch(struct ctdb_context *ctdb,
        }
 
        case CTDB_CONTROL_DB_ATTACH:
-               ctdb->status.controls.attach++;
+               ctdb->statistics.controls.attach++;
                return ctdb_control_db_attach(ctdb, indata, outdata);
 
        case CTDB_CONTROL_SET_CALL: {
                struct ctdb_control_set_call *sc = 
                        (struct ctdb_control_set_call *)indata.dptr;
-               ctdb->status.controls.set_call++;
+               ctdb->statistics.controls.set_call++;
                CHECK_CONTROL_DATA_SIZE(sizeof(struct ctdb_control_set_call));
                return ctdb_daemon_set_call(ctdb, sc->db_id, sc->fn, sc->id);
        }
 
        case CTDB_CONTROL_TRAVERSE_START:
                CHECK_CONTROL_DATA_SIZE(sizeof(struct ctdb_traverse_start));
-               ctdb->status.controls.traverse_start++;
+               ctdb->statistics.controls.traverse_start++;
                return ctdb_control_traverse_start(ctdb, indata, outdata, srcnode);
 
        case CTDB_CONTROL_TRAVERSE_ALL:
-               ctdb->status.controls.traverse_all++;
+               ctdb->statistics.controls.traverse_all++;
                return ctdb_control_traverse_all(ctdb, indata, outdata);
 
        case CTDB_CONTROL_TRAVERSE_DATA:
-               ctdb->status.controls.traverse_data++;
+               ctdb->statistics.controls.traverse_data++;
                return ctdb_control_traverse_data(ctdb, indata, outdata);
 
        case CTDB_CONTROL_REGISTER_SRVID:
-               ctdb->status.controls.register_srvid++;
+               ctdb->statistics.controls.register_srvid++;
                return daemon_register_message_handler(ctdb, client_id, srvid);
 
        case CTDB_CONTROL_DEREGISTER_SRVID:
-               ctdb->status.controls.deregister_srvid++;
+               ctdb->statistics.controls.deregister_srvid++;
                return daemon_deregister_message_handler(ctdb, client_id, srvid);
 
        case CTDB_CONTROL_ENABLE_SEQNUM:
-               ctdb->status.controls.enable_seqnum++;
+               ctdb->statistics.controls.enable_seqnum++;
                CHECK_CONTROL_DATA_SIZE(sizeof(uint32_t));
                return ctdb_ltdb_enable_seqnum(ctdb, *(uint32_t *)indata.dptr);
 
        case CTDB_CONTROL_UPDATE_SEQNUM:
-               ctdb->status.controls.update_seqnum++;
+               ctdb->statistics.controls.update_seqnum++;
                CHECK_CONTROL_DATA_SIZE(sizeof(uint32_t));              
                return ctdb_ltdb_update_seqnum(ctdb, *(uint32_t *)indata.dptr, srcnode);
 
        case CTDB_CONTROL_SET_SEQNUM_FREQUENCY:
-               ctdb->status.controls.set_seqnum_frequency++;
+               ctdb->statistics.controls.set_seqnum_frequency++;
                CHECK_CONTROL_DATA_SIZE(sizeof(uint32_t));              
                return ctdb_ltdb_set_seqnum_frequency(ctdb, *(uint32_t *)indata.dptr);
 
@@ -409,7 +409,7 @@ static void ctdb_control_timeout(struct event_context *ev, struct timed_event *t
        struct ctdb_control_state *state = talloc_get_type(private_data, struct ctdb_control_state);
        TALLOC_CTX *tmp_ctx = talloc_new(ev);
 
-       state->ctdb->status.timeouts.control++;
+       state->ctdb->statistics.timeouts.control++;
 
        talloc_steal(tmp_ctx, state);
 
index a420f4613d34b977a6fe63700ec0e289e085cdd4..435c1b1ea3ca2e85356069d80351ca79c59b8992 100644 (file)
@@ -95,7 +95,7 @@ static void block_signal(int signum)
  */
 static int daemon_queue_send(struct ctdb_client *client, struct ctdb_req_header *hdr)
 {
-       client->ctdb->status.client_packets_sent++;
+       client->ctdb->statistics.client_packets_sent++;
        return ctdb_queue_send(client->queue, (uint8_t *)hdr, hdr->length);
 }
 
@@ -247,7 +247,7 @@ static int ctdb_client_destructor(struct ctdb_client *client)
 {
        ctdb_takeover_client_destructor_hook(client);
        ctdb_reqid_remove(client->ctdb, client->client_id);
-       client->ctdb->status.num_clients--;
+       client->ctdb->statistics.num_clients--;
        return 0;
 }
 
@@ -305,8 +305,8 @@ static void daemon_call_from_client_callback(struct ctdb_call_state *state)
        res = ctdb_daemon_call_recv(state, dstate->call);
        if (res != 0) {
                DEBUG(0, (__location__ " ctdbd_call_recv() returned error\n"));
-               client->ctdb->status.pending_calls--;
-               ctdb_latency(&client->ctdb->status.max_call_latency, dstate->start_time);
+               client->ctdb->statistics.pending_calls--;
+               ctdb_latency(&client->ctdb->statistics.max_call_latency, dstate->start_time);
                return;
        }
 
@@ -315,8 +315,8 @@ static void daemon_call_from_client_callback(struct ctdb_call_state *state)
                               length, struct ctdb_reply_call);
        if (r == NULL) {
                DEBUG(0, (__location__ " Failed to allocate reply_call in ctdb daemon\n"));
-               client->ctdb->status.pending_calls--;
-               ctdb_latency(&client->ctdb->status.max_call_latency, dstate->start_time);
+               client->ctdb->statistics.pending_calls--;
+               ctdb_latency(&client->ctdb->statistics.max_call_latency, dstate->start_time);
                return;
        }
        r->hdr.reqid        = dstate->reqid;
@@ -327,9 +327,9 @@ static void daemon_call_from_client_callback(struct ctdb_call_state *state)
        if (res != 0) {
                DEBUG(0, (__location__ " Failed to queue packet from daemon to client\n"));
        }
-       ctdb_latency(&client->ctdb->status.max_call_latency, dstate->start_time);
+       ctdb_latency(&client->ctdb->statistics.max_call_latency, dstate->start_time);
        talloc_free(dstate);
-       client->ctdb->status.pending_calls--;
+       client->ctdb->statistics.pending_calls--;
 }
 
 
@@ -352,14 +352,14 @@ static void daemon_request_call_from_client(struct ctdb_client *client,
        int ret;
        struct ctdb_context *ctdb = client->ctdb;
 
-       ctdb->status.total_calls++;
-       ctdb->status.pending_calls++;
+       ctdb->statistics.total_calls++;
+       ctdb->statistics.pending_calls++;
 
        ctdb_db = find_ctdb_db(client->ctdb, c->db_id);
        if (!ctdb_db) {
                DEBUG(0, (__location__ " Unknown database in request. db_id==0x%08x",
                          c->db_id));
-               ctdb->status.pending_calls--;
+               ctdb->statistics.pending_calls--;
                return;
        }
 
@@ -371,13 +371,13 @@ static void daemon_request_call_from_client(struct ctdb_client *client,
                                           daemon_incoming_packet, client, True);
        if (ret == -2) {
                /* will retry later */
-               ctdb->status.pending_calls--;
+               ctdb->statistics.pending_calls--;
                return;
        }
 
        if (ret != 0) {
                DEBUG(0,(__location__ " Unable to fetch record\n"));
-               ctdb->status.pending_calls--;
+               ctdb->statistics.pending_calls--;
                return;
        }
 
@@ -385,7 +385,7 @@ static void daemon_request_call_from_client(struct ctdb_client *client,
        if (dstate == NULL) {
                ctdb_ltdb_unlock(ctdb_db, key);
                DEBUG(0,(__location__ " Unable to allocate dstate\n"));
-               ctdb->status.pending_calls--;
+               ctdb->statistics.pending_calls--;
                return;
        }
        dstate->start_time = timeval_current();
@@ -397,8 +397,8 @@ static void daemon_request_call_from_client(struct ctdb_client *client,
        if (call == NULL) {
                ctdb_ltdb_unlock(ctdb_db, key);
                DEBUG(0,(__location__ " Unable to allocate call\n"));
-               ctdb->status.pending_calls--;
-               ctdb_latency(&ctdb->status.max_call_latency, dstate->start_time);
+               ctdb->statistics.pending_calls--;
+               ctdb_latency(&ctdb->statistics.max_call_latency, dstate->start_time);
                return;
        }
 
@@ -418,8 +418,8 @@ static void daemon_request_call_from_client(struct ctdb_client *client,
 
        if (state == NULL) {
                DEBUG(0,(__location__ " Unable to setup call send\n"));
-               ctdb->status.pending_calls--;
-               ctdb_latency(&ctdb->status.max_call_latency, dstate->start_time);
+               ctdb->statistics.pending_calls--;
+               ctdb_latency(&ctdb->statistics.max_call_latency, dstate->start_time);
                return;
        }
        talloc_steal(state, dstate);
@@ -459,27 +459,27 @@ static void daemon_incoming_packet(void *p, struct ctdb_req_header *hdr)
 
        switch (hdr->operation) {
        case CTDB_REQ_CALL:
-               ctdb->status.client.req_call++;
+               ctdb->statistics.client.req_call++;
                daemon_request_call_from_client(client, (struct ctdb_req_call *)hdr);
                break;
 
        case CTDB_REQ_MESSAGE:
-               ctdb->status.client.req_message++;
+               ctdb->statistics.client.req_message++;
                daemon_request_message_from_client(client, (struct ctdb_req_message *)hdr);
                break;
 
        case CTDB_REQ_CONNECT_WAIT:
-               ctdb->status.client.req_connect_wait++;
+               ctdb->statistics.client.req_connect_wait++;
                daemon_request_connect_wait(client, (struct ctdb_req_connect_wait *)hdr);
                break;
 
        case CTDB_REQ_SHUTDOWN:
-               ctdb->status.client.req_shutdown++;
+               ctdb->statistics.client.req_shutdown++;
                daemon_request_shutdown(client, (struct ctdb_req_shutdown *)hdr);
                break;
 
        case CTDB_REQ_CONTROL:
-               ctdb->status.client.req_control++;
+               ctdb->statistics.client.req_control++;
                daemon_request_control_from_client(client, (struct ctdb_req_control *)hdr);
                break;
 
@@ -505,7 +505,7 @@ static void ctdb_daemon_read_cb(uint8_t *data, size_t cnt, void *args)
                return;
        }
 
-       client->ctdb->status.client_packets_recv++;
+       client->ctdb->statistics.client_packets_recv++;
 
        if (cnt < sizeof(*hdr)) {
                ctdb_set_error(client->ctdb, "Bad packet length %u in daemon\n", 
@@ -558,7 +558,7 @@ static void ctdb_accept_client(struct event_context *ev, struct fd_event *fde,
        client->ctdb = ctdb;
        client->fd = fd;
        client->client_id = ctdb_reqid_new(ctdb, client);
-       ctdb->status.num_clients++;
+       ctdb->statistics.num_clients++;
 
        client->queue = ctdb_queue_setup(ctdb, client, fd, CTDB_DS_ALIGNMENT, 
                                         ctdb_daemon_read_cb, client);
index f281433e066bc3e7e22c4cb1cdbb20d2a03af712..3655bef976c0a672fd617815e59d30b028b90483 100644 (file)
@@ -54,8 +54,8 @@ static void lockwait_handler(struct event_context *ev, struct fd_event *fde,
        key.dptr = talloc_memdup(tmp_ctx, key.dptr, key.dsize);
 
        talloc_set_destructor(h, NULL);
-       ctdb_latency(&h->ctdb->status.max_lockwait_latency, h->start_time);
-       h->ctdb->status.pending_lockwait_calls--;
+       ctdb_latency(&h->ctdb->statistics.max_lockwait_latency, h->start_time);
+       h->ctdb->statistics.pending_lockwait_calls--;
 
        /* the handle needs to go away when the context is gone - when
           the handle goes away this implicitly closes the pipe, which
@@ -79,7 +79,7 @@ static void lockwait_handler(struct event_context *ev, struct fd_event *fde,
 
 static int lockwait_destructor(struct lockwait_handle *h)
 {
-       h->ctdb->status.pending_lockwait_calls--;
+       h->ctdb->statistics.pending_lockwait_calls--;
        kill(h->child, SIGKILL);
        waitpid(h->child, NULL, 0);
        return 0;
@@ -104,11 +104,11 @@ struct lockwait_handle *ctdb_lockwait(struct ctdb_db_context *ctdb_db,
        int ret;
        pid_t parent = getpid();
 
-       ctdb_db->ctdb->status.lockwait_calls++;
-       ctdb_db->ctdb->status.pending_lockwait_calls++;
+       ctdb_db->ctdb->statistics.lockwait_calls++;
+       ctdb_db->ctdb->statistics.pending_lockwait_calls++;
 
        if (!(result = talloc_zero(private_data, struct lockwait_handle))) {
-               ctdb_db->ctdb->status.pending_lockwait_calls--;
+               ctdb_db->ctdb->statistics.pending_lockwait_calls--;
                return NULL;
        }
 
@@ -116,7 +116,7 @@ struct lockwait_handle *ctdb_lockwait(struct ctdb_db_context *ctdb_db,
 
        if (ret != 0) {
                talloc_free(result);
-               ctdb_db->ctdb->status.pending_lockwait_calls--;
+               ctdb_db->ctdb->statistics.pending_lockwait_calls--;
                return NULL;
        }
 
@@ -126,7 +126,7 @@ struct lockwait_handle *ctdb_lockwait(struct ctdb_db_context *ctdb_db,
                close(result->fd[0]);
                close(result->fd[1]);
                talloc_free(result);
-               ctdb_db->ctdb->status.pending_lockwait_calls--;
+               ctdb_db->ctdb->statistics.pending_lockwait_calls--;
                return NULL;
        }
 
@@ -156,7 +156,7 @@ struct lockwait_handle *ctdb_lockwait(struct ctdb_db_context *ctdb_db,
                                   (void *)result);
        if (result->fde == NULL) {
                talloc_free(result);
-               ctdb_db->ctdb->status.pending_lockwait_calls--;
+               ctdb_db->ctdb->statistics.pending_lockwait_calls--;
                return NULL;
        }
 
index a89ddc3eb9561482dbe0b127d0830eacd3b39ecd..8b41abcc007f1a23cedbe222adc19cb7e0fc8ccd 100644 (file)
@@ -203,7 +203,7 @@ static void ctdb_traverse_all_timeout(struct event_context *ev, struct timed_eve
 {
        struct ctdb_traverse_all_handle *state = talloc_get_type(private_data, struct ctdb_traverse_all_handle);
 
-       state->ctdb->status.timeouts.traverse++;
+       state->ctdb->statistics.timeouts.traverse++;
 
        state->callback(state->private_data, tdb_null, tdb_null);
        talloc_free(state);
index a82effda235ee12c5e2448f61f5ba0f27ff38763..987b64a3fd9530f796150ecb22b16fa1e5a670c2 100644 (file)
@@ -211,8 +211,8 @@ struct ctdb_db_context *find_ctdb_db(struct ctdb_context *ctdb, uint32_t id);
 
 struct ctdb_context *ctdb_cmdline_client(struct event_context *ev);
 
-struct ctdb_status;
-int ctdb_ctrl_status(struct ctdb_context *ctdb, uint32_t destnode, struct ctdb_status *status);
+struct ctdb_statistics;
+int ctdb_ctrl_statistics(struct ctdb_context *ctdb, uint32_t destnode, struct ctdb_statistics *status);
 
 int ctdb_ctrl_shutdown(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode);
 
@@ -327,7 +327,7 @@ 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);
+int ctdb_statistics_reset(struct ctdb_context *ctdb, uint32_t destnode);
 
 int ctdb_set_logfile(struct ctdb_context *ctdb, const char *logfile);
 
index ab2d529f694f6d7d349a449512a25c61e0e6492a..c6d514fae50cce3072aee1a2cfeaf53859d740b3 100644 (file)
@@ -115,6 +115,7 @@ struct ctdb_node {
 
        /* the public address of this node, if known */
        const char *public_address;
+       uint8_t public_netmask_bits;
 
        /* the node number that has taken over this nodes public address, if any. 
           If not taken over, then set to -1 */
@@ -165,7 +166,7 @@ struct ctdb_daemon_data {
 /*
   ctdb status information
  */
-struct ctdb_status {
+struct ctdb_statistics {
        uint32_t num_clients;
        uint32_t frozen;
        uint32_t recovering;
@@ -195,7 +196,7 @@ struct ctdb_status {
                uint32_t req_control;
        } client;
        struct {
-               uint32_t status;
+               uint32_t statistics;
                uint32_t get_config;
                uint32_t ping;
                uint32_t attach;
@@ -220,7 +221,7 @@ struct ctdb_status {
        uint32_t lockwait_calls;
        uint32_t pending_lockwait_calls;
        uint32_t memory_used;
-       uint32_t __last_counter; /* hack for control_status_all */
+       uint32_t __last_counter; /* hack for control_statistics_all */
        uint32_t max_hop_count;
        double max_call_latency;
        double max_lockwait_latency;
@@ -296,7 +297,7 @@ struct ctdb_context {
        struct ctdb_db_context *db_list;
        struct ctdb_message_list *message_list;
        struct ctdb_daemon_data daemon;
-       struct ctdb_status status;
+       struct ctdb_statistics statistics;
        struct ctdb_vnn_map *vnn_map;
        uint32_t num_clients;
        uint32_t seqnum_frequency;
@@ -368,7 +369,7 @@ struct ctdb_ltdb_header {
 };
 
 enum ctdb_controls {CTDB_CONTROL_PROCESS_EXISTS, 
-                   CTDB_CONTROL_STATUS, 
+                   CTDB_CONTROL_STATISTICS, 
                    CTDB_CONTROL_CONFIG,
                    CTDB_CONTROL_PING,
                    CTDB_CONTROL_GETDBPATH,
@@ -384,7 +385,7 @@ enum ctdb_controls {CTDB_CONTROL_PROCESS_EXISTS,
                    CTDB_CONTROL_PUSH_DB,
                    CTDB_CONTROL_GET_RECMODE,
                    CTDB_CONTROL_SET_RECMODE,
-                   CTDB_CONTROL_STATUS_RESET,
+                   CTDB_CONTROL_STATISTICS_RESET,
                    CTDB_CONTROL_DB_ATTACH,
                    CTDB_CONTROL_SET_CALL,
                    CTDB_CONTROL_TRAVERSE_START,
index f4a9540ba0d442de8c9d48d4d209380450be3d52..1058588e91a993f818c36b80ee9ce2301aff4973 100644 (file)
@@ -225,15 +225,57 @@ int ctdb_set_public_addresses(struct ctdb_context *ctdb, const char *alist)
        }
 
        for (i=0;i<nlines;i++) {
+               char *p;
+               struct in_addr in;
+
                ctdb->nodes[i]->public_address = talloc_strdup(ctdb->nodes[i], lines[i]);
                CTDB_NO_MEMORY(ctdb, ctdb->nodes[i]->public_address);
                ctdb->nodes[i]->takeover_vnn = -1;
+
+               /* see if they supplied a netmask length */
+               p = strchr(ctdb->nodes[i]->public_address, '/');
+               if (!p) {
+                       DEBUG(0,("You must supply a netmask for public address %s\n",
+                                ctdb->nodes[i]->public_address));
+                       return -1;
+               }
+               *p = 0;
+               ctdb->nodes[i]->public_netmask_bits = atoi(p+1);
+
+               if (ctdb->nodes[i]->public_netmask_bits > 32) {
+                       DEBUG(0, ("Illegal netmask for IP %s\n", ctdb->nodes[i]->public_address));
+                       return -1;
+               }
+
+               if (inet_aton(ctdb->nodes[i]->public_address, &in) != 0) {
+                       DEBUG(0,("Badly formed IP '%s' in public address list\n", ctdb->nodes[i]->public_address));
+                       return -1;
+               }
        }
 
        talloc_free(lines);
        return 0;
 }
 
+/*
+  see if two IPs are on the same subnet
+ */
+static bool ctdb_same_subnet(const char *ip1, const char *ip2, uint8_t netmask_bits)
+{
+       struct in_addr in1, in2;
+       uint32_t mask;
+
+       inet_aton(ip1, &in1);
+       inet_aton(ip2, &in2);
+
+       mask = ~((1LL<<(32-netmask_bits))-1);
+
+       if ((ntohl(in1.s_addr) & mask) != (ntohl(in2.s_addr) & mask)) {
+               return false;
+       }
+
+       return true;
+}
 
 /*
   make any IP alias changes for public addresses that are necessary 
@@ -252,16 +294,16 @@ int ctdb_takeover_run(struct ctdb_context *ctdb, struct ctdb_node_map *nodemap)
                        for (j=(i+1)%nodemap->num;
                             j != i;
                             j=(j+1)%nodemap->num) {
-                               if ((nodemap->nodes[j].flags & NODE_FLAGS_CONNECTED) && 
-                                   same_subnet(nodemap->nodes[j]->public_address, nodemap->nodes[i]->public_address, 
-                                               nodemap->nodes[i]->public_netmask)) {
+                               if ((nodemap->nodes[j].flags & NODE_FLAGS_CONNECTED) &&
+                                   ctdb_same_subnet(ctdb->nodes[j]->public_address, ctdb->nodes[i]->public_address, 
+                                                    ctdb->nodes[i]->public_netmask_bits)) {
                                        ctdb->nodes[i]->takeover_vnn = nodemap->nodes[j].vnn;
                                        break;
                                }
                        }
                        if (j == i) {
                                DEBUG(0,(__location__ " No node available on same network to take %s\n",
-                                        nodemap->nodes[i]->public_address));
+                                        ctdb->nodes[i]->public_address));
                                ctdb->nodes[i]->takeover_vnn = -1;      
                        }
                }
index 104bb71787711be83d7d801f16eb4bdf5abd2a2c..72bd47eb604cada050e194debaea5d39b70aa4c0 100755 (executable)
@@ -7,29 +7,29 @@ $VALGRIND bin/ctdbd --nlist direct/nodes.txt
 $VALGRIND bin/ctdbd --nlist direct/nodes.txt
 
 echo "Testing ping"
-$VALGRIND bin/ctdb_control ping || exit 1
+$VALGRIND bin/ctdb ping || exit 1
 
 echo "Testing status"
-$VALGRIND bin/ctdb_control status all || exit 1
+$VALGRIND bin/ctdb status || exit 1
 
-echo "Testing statusreset"
-$VALGRIND bin/ctdb_control statusreset all || exit 1
+echo "Testing statistics"
+$VALGRIND bin/ctdb -n all statistics || exit 1
 
-echo "Testing debug"
-$VALGRIND bin/ctdb_control debug all 5 || exit 1
-$VALGRIND bin/ctdb_control debuglevel || exit 1
-$VALGRIND bin/ctdb_control debug all 0 || exit 1
-$VALGRIND bin/ctdb_control debuglevel || exit 1
+echo "Testing statisticsreset"
+$VALGRIND bin/ctdb -n all statisticsreset || exit 1
 
-echo "Testing map calls"
-$VALGRIND bin/ctdb_control getvnnmap 0 || exit 1
+echo "Testing debug"
+$VALGRIND bin/ctdb -n all setdebug 5 || exit 1
+$VALGRIND bin/ctdb -n all getdebug || exit 1
+$VALGRIND bin/ctdb -n all setdebug 0 || exit 1
+$VALGRIND bin/ctdb -n all getdebug || exit 1
 
 echo "Attaching to some databases"
-$VALGRIND bin/ctdb_control attach test1.tdb || exit 1
-$VALGRIND bin/ctdb_control attach test2.tdb || exit 1
+$VALGRIND bin/ctdb attach test1.tdb || exit 1
+$VALGRIND bin/ctdb attach test2.tdb || exit 1
 
 echo "Testing getdbmap"
-$VALGRIND bin/ctdb_control getdbmap 0 || exit 1
+$VALGRIND bin/ctdb getdbmap || exit 1
 
 echo "All done"
 
index 0a6580985df7e63eb7266ea6d31120450883d055..8deb55bf639610a7bcd8547ce07077a86aef0e7a 100644 (file)
 #include "../include/ctdb_private.h"
 #include <arpa/inet.h>
 
-static int timelimit = 3;
+static void usage(void);
 
-/*
-  show usage message
- */
-static void usage(void)
-{
-       printf(
-               "Usage: ctdb_control [options] <control>\n"
-               "\nControls:\n"
-               "  ping\n"
-               "  process-exists <vnn:pid>           see if a process exists\n"
-               "  status <vnn|all>                   show ctdb status on a node\n"
-               "  statusreset <vnn|all>              reset status on a node\n"
-               "  debug <vnn|all> <level>            set ctdb debug level on a node\n"
-               "  debuglevel                         display ctdb debug levels\n"
-               "  getvnnmap <vnn>                    display ctdb vnnmap\n"
-               "  setvnnmap <vnn> <generation> <numslots> <lmaster>*\n"
-               "  getdbmap <vnn>                     lists databases on a node\n"
-               "  getnodemap <vnn>                   lists nodes known to a ctdb daemon\n"
-               "  createdb <vnn> <dbname>            create a database\n"
-               "  catdb <dbname> [vnn]               lists all keys/data in a db\n"
-               "  cpdb <fromvnn> <tovnn> <dbid>      lists all keys in a remote tdb\n"
-               "  setdmaster <vnn> <dbid> <dmaster>  sets new dmaster for all records in the database\n"
-               "  cleardb <vnn> <dbid>               deletes all records in a db\n"
-               "  getrecmode <vnn>                   get recovery mode\n"
-               "  setrecmode <vnn> <mode>            set recovery mode\n"
-               "  getrecmaster <vnn>                 get recovery master\n"
-               "  setrecmaster <vnn> <master_vnn>    set recovery master\n"
-               "  getmonmode <vnn>                   get monitoring mode\n"
-               "  setmonmode <vnn> <mode>            set monitoring mode\n"
-               "  attach <dbname>                    attach a database\n"
-               "  getpid <vnn>                       get the pid of a ctdb daemon\n"
-               "  dumpmemory <vnn|all>               dump memory map to log\n"
-               "  shutdown <vnn>                     shutdown a remote ctdb\n"
-               "  recovery <vnn>                     trigger a recovery\n"
-               "  takeoverip <vnn> <ip> <iface>      take over an ip address\n"
-               "  releaseip <vnn> <ip> <iface>       release an ip address\n"
-               "  freeze <vnn|all>                   freeze a node\n"
-               "  thaw <vnn|all>                     thaw a node\n"
-       );
-       exit(1);
-}
+static struct {
+       int timelimit;
+       uint32_t vnn;
+} options;
+
+#define TIMELIMIT() timeval_current_ofs(options.timelimit, 0)
 
 /*
   see if a process exists
@@ -97,9 +62,9 @@ static int control_process_exists(struct ctdb_context *ctdb, int argc, const cha
 }
 
 /*
-  display status structure
+  display statistics structure
  */
-static void show_status(struct ctdb_status *s)
+static void show_statistics(struct ctdb_statistics *s)
 {
        TALLOC_CTX *tmp_ctx = talloc_new(NULL);
        int i;
@@ -109,54 +74,54 @@ static void show_status(struct ctdb_status *s)
                const char *name;
                uint32_t offset;
        } fields[] = {
-#define STATUS_FIELD(n) { #n, offsetof(struct ctdb_status, n) }
-               STATUS_FIELD(num_clients),
-               STATUS_FIELD(frozen),
-               STATUS_FIELD(recovering),
-               STATUS_FIELD(client_packets_sent),
-               STATUS_FIELD(client_packets_recv),
-               STATUS_FIELD(node_packets_sent),
-               STATUS_FIELD(node_packets_recv),
-               STATUS_FIELD(keepalive_packets_sent),
-               STATUS_FIELD(keepalive_packets_recv),
-               STATUS_FIELD(node.req_call),
-               STATUS_FIELD(node.reply_call),
-               STATUS_FIELD(node.req_dmaster),
-               STATUS_FIELD(node.reply_dmaster),
-               STATUS_FIELD(node.reply_error),
-               STATUS_FIELD(node.req_message),
-               STATUS_FIELD(node.req_finished),
-               STATUS_FIELD(node.req_control),
-               STATUS_FIELD(node.reply_control),
-               STATUS_FIELD(client.req_call),
-               STATUS_FIELD(client.req_message),
-               STATUS_FIELD(client.req_finished),
-               STATUS_FIELD(client.req_connect_wait),
-               STATUS_FIELD(client.req_shutdown),
-               STATUS_FIELD(client.req_control),
-               STATUS_FIELD(controls.status),
-               STATUS_FIELD(controls.get_config),
-               STATUS_FIELD(controls.ping),
-               STATUS_FIELD(controls.attach),
-               STATUS_FIELD(controls.set_call),
-               STATUS_FIELD(controls.process_exists),
-               STATUS_FIELD(controls.traverse_start),
-               STATUS_FIELD(controls.traverse_all),
-               STATUS_FIELD(controls.traverse_data),
-               STATUS_FIELD(controls.update_seqnum),
-               STATUS_FIELD(controls.enable_seqnum),
-               STATUS_FIELD(controls.set_seqnum_frequency),
-               STATUS_FIELD(controls.register_srvid),
-               STATUS_FIELD(controls.deregister_srvid),
-               STATUS_FIELD(timeouts.call),
-               STATUS_FIELD(timeouts.control),
-               STATUS_FIELD(timeouts.traverse),
-               STATUS_FIELD(total_calls),
-               STATUS_FIELD(pending_calls),
-               STATUS_FIELD(lockwait_calls),
-               STATUS_FIELD(pending_lockwait_calls),
-               STATUS_FIELD(memory_used),
-               STATUS_FIELD(max_hop_count),
+#define STATISTICS_FIELD(n) { #n, offsetof(struct ctdb_statistics, n) }
+               STATISTICS_FIELD(num_clients),
+               STATISTICS_FIELD(frozen),
+               STATISTICS_FIELD(recovering),
+               STATISTICS_FIELD(client_packets_sent),
+               STATISTICS_FIELD(client_packets_recv),
+               STATISTICS_FIELD(node_packets_sent),
+               STATISTICS_FIELD(node_packets_recv),
+               STATISTICS_FIELD(keepalive_packets_sent),
+               STATISTICS_FIELD(keepalive_packets_recv),
+               STATISTICS_FIELD(node.req_call),
+               STATISTICS_FIELD(node.reply_call),
+               STATISTICS_FIELD(node.req_dmaster),
+               STATISTICS_FIELD(node.reply_dmaster),
+               STATISTICS_FIELD(node.reply_error),
+               STATISTICS_FIELD(node.req_message),
+               STATISTICS_FIELD(node.req_finished),
+               STATISTICS_FIELD(node.req_control),
+               STATISTICS_FIELD(node.reply_control),
+               STATISTICS_FIELD(client.req_call),
+               STATISTICS_FIELD(client.req_message),
+               STATISTICS_FIELD(client.req_finished),
+               STATISTICS_FIELD(client.req_connect_wait),
+               STATISTICS_FIELD(client.req_shutdown),
+               STATISTICS_FIELD(client.req_control),
+               STATISTICS_FIELD(controls.statistics),
+               STATISTICS_FIELD(controls.get_config),
+               STATISTICS_FIELD(controls.ping),
+               STATISTICS_FIELD(controls.attach),
+               STATISTICS_FIELD(controls.set_call),
+               STATISTICS_FIELD(controls.process_exists),
+               STATISTICS_FIELD(controls.traverse_start),
+               STATISTICS_FIELD(controls.traverse_all),
+               STATISTICS_FIELD(controls.traverse_data),
+               STATISTICS_FIELD(controls.update_seqnum),
+               STATISTICS_FIELD(controls.enable_seqnum),
+               STATISTICS_FIELD(controls.set_seqnum_frequency),
+               STATISTICS_FIELD(controls.register_srvid),
+               STATISTICS_FIELD(controls.deregister_srvid),
+               STATISTICS_FIELD(timeouts.call),
+               STATISTICS_FIELD(timeouts.control),
+               STATISTICS_FIELD(timeouts.traverse),
+               STATISTICS_FIELD(total_calls),
+               STATISTICS_FIELD(pending_calls),
+               STATISTICS_FIELD(lockwait_calls),
+               STATISTICS_FIELD(pending_lockwait_calls),
+               STATISTICS_FIELD(memory_used),
+               STATISTICS_FIELD(max_hop_count),
        };
        printf("CTDB version %u\n", CTDB_VERSION);
        for (i=0;i<ARRAY_SIZE(fields);i++) {
@@ -181,92 +146,86 @@ static void show_status(struct ctdb_status *s)
 }
 
 /*
-  display remote ctdb status combined from all nodes
+  display remote ctdb statistics combined from all nodes
  */
-static int control_status_all(struct ctdb_context *ctdb)
+static int control_statistics_all(struct ctdb_context *ctdb)
 {
        int ret, i;
-       struct ctdb_status status;
+       struct ctdb_statistics statistics;
        uint32_t *nodes;
        uint32_t num_nodes;
 
-       nodes = ctdb_get_connected_nodes(ctdb, timeval_current_ofs(timelimit, 0), ctdb, &num_nodes);
+       nodes = ctdb_get_connected_nodes(ctdb, TIMELIMIT(), ctdb, &num_nodes);
        CTDB_NO_MEMORY(ctdb, nodes);
        
-       ZERO_STRUCT(status);
+       ZERO_STRUCT(statistics);
 
        for (i=0;i<num_nodes;i++) {
-               struct ctdb_status s1;
+               struct ctdb_statistics s1;
                int j;
                uint32_t *v1 = (uint32_t *)&s1;
-               uint32_t *v2 = (uint32_t *)&status;
+               uint32_t *v2 = (uint32_t *)&statistics;
                uint32_t num_ints = 
-                       offsetof(struct ctdb_status, __last_counter) / sizeof(uint32_t);
-               ret = ctdb_ctrl_status(ctdb, nodes[i], &s1);
+                       offsetof(struct ctdb_statistics, __last_counter) / sizeof(uint32_t);
+               ret = ctdb_ctrl_statistics(ctdb, nodes[i], &s1);
                if (ret != 0) {
-                       printf("Unable to get status from node %u\n", nodes[i]);
+                       printf("Unable to get statistics from node %u\n", nodes[i]);
                        return ret;
                }
                for (j=0;j<num_ints;j++) {
                        v2[j] += v1[j];
                }
-               status.max_hop_count = 
-                       MAX(status.max_hop_count, s1.max_hop_count);
-               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);
+               statistics.max_hop_count = 
+                       MAX(statistics.max_hop_count, s1.max_hop_count);
+               statistics.max_call_latency = 
+                       MAX(statistics.max_call_latency, s1.max_call_latency);
+               statistics.max_lockwait_latency = 
+                       MAX(statistics.max_lockwait_latency, s1.max_lockwait_latency);
        }
        talloc_free(nodes);
-       printf("Gathered status for %u nodes\n", num_nodes);
-       show_status(&status);
+       printf("Gathered statistics for %u nodes\n", num_nodes);
+       show_statistics(&statistics);
        return 0;
 }
 
 /*
-  display remote ctdb status
+  display remote ctdb statistics
  */
-static int control_status(struct ctdb_context *ctdb, int argc, const char **argv)
+static int control_statistics(struct ctdb_context *ctdb, int argc, const char **argv)
 {
-       uint32_t vnn;
        int ret;
-       struct ctdb_status status;
-       if (argc < 1) {
-               usage();
-       }
+       struct ctdb_statistics statistics;
 
-       if (strcmp(argv[0], "all") == 0) {
-               return control_status_all(ctdb);
+       if (options.vnn == CTDB_BROADCAST_ALL) {
+               return control_statistics_all(ctdb);
        }
 
-       vnn = strtoul(argv[0], NULL, 0);
-
-       ret = ctdb_ctrl_status(ctdb, vnn, &status);
+       ret = ctdb_ctrl_statistics(ctdb, options.vnn, &statistics);
        if (ret != 0) {
-               printf("Unable to get status from node %u\n", vnn);
+               printf("Unable to get statistics from node %u\n", options.vnn);
                return ret;
        }
-       show_status(&status);
+       show_statistics(&statistics);
        return 0;
 }
 
 
 /*
-  reset status on all nodes
+  reset statistics on all nodes
  */
-static int control_status_reset_all(struct ctdb_context *ctdb)
+static int control_statistics_reset_all(struct ctdb_context *ctdb)
 {
        int ret, i;
        uint32_t *nodes;
        uint32_t num_nodes;
 
-       nodes = ctdb_get_connected_nodes(ctdb, timeval_current_ofs(timelimit, 0), ctdb, &num_nodes);
+       nodes = ctdb_get_connected_nodes(ctdb, TIMELIMIT(), ctdb, &num_nodes);
        CTDB_NO_MEMORY(ctdb, nodes);
        
        for (i=0;i<num_nodes;i++) {
-               ret = ctdb_status_reset(ctdb, nodes[i]);
+               ret = ctdb_statistics_reset(ctdb, nodes[i]);
                if (ret != 0) {
-                       printf("Unable to reset status on node %u\n", nodes[i]);
+                       printf("Unable to reset statistics on node %u\n", nodes[i]);
                        return ret;
                }
        }
@@ -276,25 +235,19 @@ static int control_status_reset_all(struct ctdb_context *ctdb)
 
 
 /*
-  reset remote ctdb status
+  reset remote ctdb statistics
  */
-static int control_status_reset(struct ctdb_context *ctdb, int argc, const char **argv)
+static int control_statistics_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);
+       if (options.vnn == CTDB_BROADCAST_ALL) {
+               return control_statistics_reset_all(ctdb);
        }
 
-       vnn = strtoul(argv[0], NULL, 0);
-
-       ret = ctdb_status_reset(ctdb, vnn);
+       ret = ctdb_statistics_reset(ctdb, options.vnn);
        if (ret != 0) {
-               printf("Unable to reset status on node %u\n", vnn);
+               printf("Unable to reset statistics on node %u\n", options.vnn);
                return ret;
        }
        return 0;
@@ -302,125 +255,88 @@ static int control_status_reset(struct ctdb_context *ctdb, int argc, const char
 
 
 /*
-  display remote ctdb vnn map
+  display remote ctdb status
  */
-static int control_getvnnmap(struct ctdb_context *ctdb, int argc, const char **argv)
+static int control_status(struct ctdb_context *ctdb, int argc, const char **argv)
 {
-       uint32_t vnn;
        int i, ret;
        struct ctdb_vnn_map *vnnmap=NULL;
-       if (argc < 1) {
-               usage();
+       struct ctdb_node_map *nodemap=NULL;
+       uint32_t recmode, recmaster;
+       uint32_t myvnn;
+
+       myvnn = ctdb_ctrl_getvnn(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE);
+
+       ret = ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), options.vnn, ctdb, &nodemap);
+       if (ret != 0) {
+               printf("Unable to get nodemap from node %u\n", options.vnn);
+               return ret;
        }
 
-       vnn = strtoul(argv[0], NULL, 0);
+       printf("Number of nodes:%d\n", nodemap->num);
+       for(i=0;i<nodemap->num;i++){
+               printf("vnn:%d %s%s\n", nodemap->nodes[i].vnn,
+                       nodemap->nodes[i].flags&NODE_FLAGS_CONNECTED?
+                               "CONNECTED":"UNAVAILABLE",
+                       nodemap->nodes[i].vnn == myvnn?" (THIS NODE)":"");
+       }
 
-       ret = ctdb_ctrl_getvnnmap(ctdb, timeval_current_ofs(timelimit, 0), vnn, ctdb, &vnnmap);
+       ret = ctdb_ctrl_getvnnmap(ctdb, TIMELIMIT(), options.vnn, ctdb, &vnnmap);
        if (ret != 0) {
-               printf("Unable to get vnnmap from node %u\n", vnn);
+               printf("Unable to get vnnmap from node %u\n", options.vnn);
                return ret;
        }
        printf("Generation:%d\n",vnnmap->generation);
        printf("Size:%d\n",vnnmap->size);
        for(i=0;i<vnnmap->size;i++){
-               printf("hash:%d lmaster:%d\n",i,vnnmap->map[i]);
-       }
-       return 0;
-}
-
-/*
-  display pid of a ctdb daemon
- */
-static int control_getpid(struct ctdb_context *ctdb, int argc, const char **argv)
-{
-       uint32_t vnn, pid;
-       int ret;
-
-
-       if (argc < 1) {
-               usage();
+               printf("hash:%d lmaster:%d\n", i, vnnmap->map[i]);
        }
 
-       vnn     = strtoul(argv[0], NULL, 0);
-
-       ret = ctdb_ctrl_getpid(ctdb, timeval_current_ofs(timelimit, 0), vnn, &pid);
+       ret = ctdb_ctrl_getrecmode(ctdb, TIMELIMIT(), options.vnn, &recmode);
        if (ret != 0) {
-               printf("Unable to get daemon pid from node %u\n", vnn);
+               printf("Unable to get recmode from node %u\n", options.vnn);
                return ret;
        }
-       printf("Pid:%d\n",pid);
-
-       return 0;
-}
-
-/*
-  shutdown a daemon
- */
-static int control_shutdown(struct ctdb_context *ctdb, int argc, const char **argv)
-{
-       uint32_t vnn;
-       int ret;
-
-
-       if (argc < 1) {
-               usage();
-       }
-
-       vnn     = strtoul(argv[0], NULL, 0);
+       printf("Recovery mode:%s (%d)\n",recmode==CTDB_RECOVERY_NORMAL?"NORMAL":"RECOVERY",recmode);
 
-       ret = ctdb_ctrl_shutdown(ctdb, timeval_current_ofs(1, 0), vnn);
+       ret = ctdb_ctrl_getrecmaster(ctdb, TIMELIMIT(), options.vnn, &recmaster);
        if (ret != 0) {
-               printf("Unable to shutdown node %u\n", vnn);
+               printf("Unable to get recmaster from node %u\n", options.vnn);
                return ret;
        }
+       printf("Recovery master:%d\n",recmaster);
 
        return 0;
 }
 
 /*
-  take over an ip address
+  display pid of a ctdb daemon
  */
-static int control_takeoverip(struct ctdb_context *ctdb, int argc, const char **argv)
+static int control_getpid(struct ctdb_context *ctdb, int argc, const char **argv)
 {
-       uint32_t vnn;
+       uint32_t pid;
        int ret;
-       const char *ip;
-
-       if (argc < 2) {
-               usage();
-       }
 
-       vnn  = strtoul(argv[0], NULL, 0);
-       ip   = argv[1];
-
-       ret = ctdb_ctrl_takeover_ip(ctdb, timeval_current_ofs(1, 0), vnn, ip);
+       ret = ctdb_ctrl_getpid(ctdb, TIMELIMIT(), options.vnn, &pid);
        if (ret != 0) {
-               printf("Unable to takeoverip node %u ip %s\n", vnn, ip);
+               printf("Unable to get daemon pid from node %u\n", options.vnn);
                return ret;
        }
+       printf("Pid:%d\n", pid);
 
        return 0;
 }
 
 /*
-  release an ip address
+  shutdown a daemon
  */
-static int control_releaseip(struct ctdb_context *ctdb, int argc, const char **argv)
+static int control_shutdown(struct ctdb_context *ctdb, int argc, const char **argv)
 {
-       uint32_t vnn;
        int ret;
-       const char *ip;
 
-       if (argc < 2) {
-               usage();
-       }
-
-       vnn     = strtoul(argv[0], NULL, 0);
-       ip      = argv[1];
-
-       ret = ctdb_ctrl_release_ip(ctdb, timeval_current_ofs(1, 0), vnn, ip);
+       ret = ctdb_ctrl_shutdown(ctdb, timeval_current_ofs(1, 0), options.vnn);
        if (ret != 0) {
-               printf("Unable to releaseip node %u ip %s\n", vnn, ip);
+               printf("Unable to shutdown node %u\n", options.vnn);
                return ret;
        }
 
@@ -430,93 +346,37 @@ static int control_releaseip(struct ctdb_context *ctdb, int argc, const char **a
 /*
   trigger a recovery
  */
-static int control_recovery(struct ctdb_context *ctdb, int argc, const char **argv)
+static int control_recover(struct ctdb_context *ctdb, int argc, const char **argv)
 {
        int ret;
 
-
-       ret = ctdb_ctrl_freeze(ctdb, timeval_current_ofs(timelimit, 0), CTDB_CURRENT_NODE);
+       ret = ctdb_ctrl_freeze(ctdb, TIMELIMIT(), options.vnn);
        if (ret != 0) {
                printf("Unable to freeze node\n");
                return ret;
        }
-       ret = ctdb_ctrl_setrecmode(ctdb, timeval_current_ofs(timelimit, 0), CTDB_CURRENT_NODE, CTDB_RECOVERY_ACTIVE);
-       if (ret != 0) {
-               printf("Unable to set recovery mode\n");
-               return ret;
-       }
-
-       return 0;
-}
-
-/*
-  display recovery mode of a remote node
- */
-static int control_getrecmode(struct ctdb_context *ctdb, int argc, const char **argv)
-{
-       uint32_t vnn, recmode;
-       int ret;
-
-
-       if (argc < 1) {
-               usage();
-       }
 
-       vnn     = strtoul(argv[0], NULL, 0);
-
-       ret = ctdb_ctrl_getrecmode(ctdb, timeval_current_ofs(timelimit, 0), vnn, &recmode);
+       ret = ctdb_ctrl_setrecmode(ctdb, TIMELIMIT(), options.vnn, CTDB_RECOVERY_ACTIVE);
        if (ret != 0) {
-               printf("Unable to get recmode from node %u\n", vnn);
+               printf("Unable to set recovery mode\n");
                return ret;
        }
-       printf("Recovery mode:%s (%d)\n",recmode==CTDB_RECOVERY_NORMAL?"NORMAL":"RECOVERY",recmode);
 
        return 0;
 }
 
-/*
-  set recovery mode of a remote node
- */
-static int control_setrecmode(struct ctdb_context *ctdb, int argc, const char **argv)
-{
-       uint32_t vnn, recmode;
-       int ret;
-
-
-       if (argc < 2) {
-               usage();
-       }
-
-       vnn     = strtoul(argv[0], NULL, 0);
-       recmode = strtoul(argv[1], NULL, 0);
-
-       ret = ctdb_ctrl_setrecmode(ctdb, timeval_current_ofs(timelimit, 0), vnn, recmode);
-       if (ret != 0) {
-               printf("Unable to set recmode on node %u\n", vnn);
-               return ret;
-       }
-
-       return 0;
-}
 
 /*
   display monitoring mode of a remote node
  */
 static int control_getmonmode(struct ctdb_context *ctdb, int argc, const char **argv)
 {
-       uint32_t vnn, monmode;
+       uint32_t monmode;
        int ret;
 
-
-       if (argc < 1) {
-               usage();
-       }
-
-       vnn     = strtoul(argv[0], NULL, 0);
-
-       ret = ctdb_ctrl_getmonmode(ctdb, timeval_current_ofs(timelimit, 0), vnn, &monmode);
+       ret = ctdb_ctrl_getmonmode(ctdb, TIMELIMIT(), options.vnn, &monmode);
        if (ret != 0) {
-               printf("Unable to get monmode from node %u\n", vnn);
+               printf("Unable to get monmode from node %u\n", options.vnn);
                return ret;
        }
        printf("Monitoring mode:%s (%d)\n",monmode==CTDB_MONITORING_ACTIVE?"ACTIVE":"DISABLED",monmode);
@@ -529,70 +389,18 @@ static int control_getmonmode(struct ctdb_context *ctdb, int argc, const char **
  */
 static int control_setmonmode(struct ctdb_context *ctdb, int argc, const char **argv)
 {
-       uint32_t vnn, monmode;
-       int ret;
-
-
-       if (argc < 2) {
-               usage();
-       }
-
-       vnn     = strtoul(argv[0], NULL, 0);
-       monmode = strtoul(argv[1], NULL, 0);
-
-       ret = ctdb_ctrl_setmonmode(ctdb, timeval_current_ofs(timelimit, 0), vnn, monmode);
-       if (ret != 0) {
-               printf("Unable to set monmode on node %u\n", vnn);
-               return ret;
-       }
-
-       return 0;
-}
-
-/*
-  display recovery master of a remote node
- */
-static int control_getrecmaster(struct ctdb_context *ctdb, int argc, const char **argv)
-{
-       uint32_t vnn, recmaster;
+       uint32_t monmode;
        int ret;
 
-
        if (argc < 1) {
                usage();
        }
 
-       vnn     = strtoul(argv[0], NULL, 0);
-
-       ret = ctdb_ctrl_getrecmaster(ctdb, timeval_current_ofs(timelimit, 0), vnn, &recmaster);
-       if (ret != 0) {
-               printf("Unable to get recmaster from node %u\n", vnn);
-               return ret;
-       }
-       printf("Recovery master:%d\n",recmaster);
-
-       return 0;
-}
-
-/*
-  set recovery master of a remote node
- */
-static int control_setrecmaster(struct ctdb_context *ctdb, int argc, const char **argv)
-{
-       uint32_t vnn, recmaster;
-       int ret;
-
-
-       if (argc < 2) {
-               usage();
-       }
-
-       vnn       = strtoul(argv[0], NULL, 0);
-       recmaster = strtoul(argv[1], NULL, 0);
+       monmode = strtoul(argv[0], NULL, 0);
 
-       ret = ctdb_ctrl_setrecmaster(ctdb, timeval_current_ofs(timelimit, 0), vnn, recmaster);
+       ret = ctdb_ctrl_setmonmode(ctdb, TIMELIMIT(), options.vnn, monmode);
        if (ret != 0) {
-               printf("Unable to set recmaster on node %u\n", vnn);
+               printf("Unable to set monmode on node %u\n", options.vnn);
                return ret;
        }
 
@@ -606,7 +414,6 @@ static int control_catdb(struct ctdb_context *ctdb, int argc, const char **argv)
 {
        const char *db_name;
        struct ctdb_db_context *ctdb_db;
-       uint32_t vnn;
        int ret;
 
        if (argc < 1) {
@@ -615,94 +422,36 @@ static int control_catdb(struct ctdb_context *ctdb, int argc, const char **argv)
 
        db_name = argv[0];
        ctdb_db = ctdb_attach(ctdb, db_name);
+
        if (ctdb_db == NULL) {
                DEBUG(0,("Unable to attach to database '%s'\n", db_name));
                return -1;
        }
 
-       if (argc==1) {
-               /* traverse and dump the cluster tdb */
-               ret = ctdb_dump_db(ctdb_db, stdout);
-               if (ret == -1) {
-                       printf("Unable to dump database\n");
-                       return -1;
-               }
-       } else {
-               struct ctdb_key_list keys;
-               int i;
-
-               /* dump only the local tdb of a specific node */
-               vnn     = strtoul(argv[1], NULL, 0);
-               ret = ctdb_ctrl_pulldb(ctdb, vnn, ctdb_db->db_id, CTDB_LMASTER_ANY, ctdb, &keys);
-               if (ret == -1) {
-                       printf("Unable to pull remote database\n");
-                       return -1;
-               }
-               for(i=0;i<keys.num;i++){
-                       char *keystr, *datastr;
-
-                       keystr  = hex_encode(ctdb, keys.keys[i].dptr, keys.keys[i].dsize);
-                       datastr = hex_encode(ctdb, keys.data[i].dptr, keys.data[i].dsize);
-
-                       printf("rsn:%llu dmaster:%d key:%s data:%s\n", 
-                              (unsigned long long)keys.headers[i].rsn,  
-                              keys.headers[i].dmaster, keystr, datastr); 
-                       ret++;
-               }
+       /* traverse and dump the cluster tdb */
+       ret = ctdb_dump_db(ctdb_db, stdout);
+       if (ret == -1) {
+               printf("Unable to dump database\n");
+               return -1;
        }
-       
        talloc_free(ctdb_db);
 
        printf("Dumped %d records\n", ret);
        return 0;
 }
 
-/*
-  copy a db from one node to another
- */
-static int control_cpdb(struct ctdb_context *ctdb, int argc, const char **argv)
-{
-       uint32_t fromvnn, tovnn, dbid;
-       int ret;
-       TALLOC_CTX *mem_ctx;
-
-       if (argc < 3) {
-               usage();
-       }
-
-       fromvnn  = strtoul(argv[0], NULL, 0);
-       tovnn    = strtoul(argv[1], NULL, 0);
-       dbid     = strtoul(argv[2], NULL, 0);
-
-       mem_ctx = talloc_new(ctdb);
-       ret = ctdb_ctrl_copydb(ctdb, timeval_current_ofs(timelimit, 0), fromvnn, tovnn, dbid, CTDB_LMASTER_ANY, mem_ctx);
-       if (ret != 0) {
-               printf("Unable to copy db from node %u to node %u\n", fromvnn, tovnn);
-               return ret;
-       }
-
-       talloc_free(mem_ctx);
-       return 0;
-}
 
 /*
   display a list of the databases on a remote ctdb
  */
 static int control_getdbmap(struct ctdb_context *ctdb, int argc, const char **argv)
 {
-       uint32_t vnn;
        int i, ret;
        struct ctdb_dbid_map *dbmap=NULL;
 
-       if (argc < 1) {
-               usage();
-       }
-
-       vnn = strtoul(argv[0], NULL, 0);
-
-       ret = ctdb_ctrl_getdbmap(ctdb, timeval_current_ofs(timelimit, 0), vnn, ctdb, &dbmap);
+       ret = ctdb_ctrl_getdbmap(ctdb, TIMELIMIT(), options.vnn, ctdb, &dbmap);
        if (ret != 0) {
-               printf("Unable to get dbids from node %u\n", vnn);
+               printf("Unable to get dbids from node %u\n", options.vnn);
                return ret;
        }
 
@@ -711,8 +460,8 @@ static int control_getdbmap(struct ctdb_context *ctdb, int argc, const char **ar
                const char *path;
                const char *name;
 
-               ctdb_ctrl_getdbpath(ctdb, timeval_current_ofs(timelimit, 0), CTDB_CURRENT_NODE, dbmap->dbids[i], ctdb, &path);
-               ctdb_ctrl_getdbname(ctdb, timeval_current_ofs(timelimit, 0), CTDB_CURRENT_NODE, dbmap->dbids[i], ctdb, &name);
+               ctdb_ctrl_getdbpath(ctdb, TIMELIMIT(), options.vnn, dbmap->dbids[i], ctdb, &path);
+               ctdb_ctrl_getdbname(ctdb, TIMELIMIT(), options.vnn, dbmap->dbids[i], ctdb, &name);
                printf("dbid:0x%08x name:%s path:%s\n", dbmap->dbids[i], name, path);
        }
 
@@ -720,157 +469,7 @@ static int control_getdbmap(struct ctdb_context *ctdb, int argc, const char **ar
 }
 
 /*
-  display a list nodes known to a remote ctdb
- */
-static int control_getnodemap(struct ctdb_context *ctdb, int argc, const char **argv)
-{
-       uint32_t vnn;
-       int i, ret;
-       struct ctdb_node_map *nodemap=NULL;
-
-       if (argc < 1) {
-               usage();
-       }
-
-       vnn = strtoul(argv[0], NULL, 0);
-
-       ret = ctdb_ctrl_getnodemap(ctdb, timeval_current_ofs(timelimit, 0), vnn, ctdb, &nodemap);
-       if (ret != 0) {
-               printf("Unable to get nodemap from node %u\n", vnn);
-               return ret;
-       }
-
-       printf("Number of nodes:%d\n", nodemap->num);
-       for(i=0;i<nodemap->num;i++){
-               printf("vnn:%d %s%s\n", nodemap->nodes[i].vnn,
-                       nodemap->nodes[i].flags&NODE_FLAGS_CONNECTED?
-                               "CONNECTED":"UNAVAILABLE",
-                       nodemap->nodes[i].vnn==vnn?" (THIS NODE)":"");
-       }
-
-       return 0;
-}
-
-/*
-  set remote ctdb vnn map
- */
-static int control_setvnnmap(struct ctdb_context *ctdb, int argc, const char **argv)
-{
-       uint32_t vnn, num_nodes, generation;
-       struct ctdb_vnn_map *vnnmap;
-       int i, ret;
-       if (argc < 3) {
-               usage();
-       }
-
-       vnn        = strtoul(argv[0], NULL, 0);
-       generation = strtoul(argv[1], NULL, 0);
-       num_nodes  = strtoul(argv[2], NULL, 0);
-
-       vnnmap = talloc(ctdb, struct ctdb_vnn_map);
-       CTDB_NO_MEMORY(ctdb, vnnmap);
-
-       vnnmap->generation = generation;
-       vnnmap->size       = num_nodes;
-       vnnmap->map        = talloc_array(vnnmap, uint32_t, vnnmap->size);
-       CTDB_NO_MEMORY(ctdb, vnnmap->map);
-
-       for (i=0;i<vnnmap->size;i++) {
-               vnnmap->map[i] = strtoul(argv[3+i], NULL, 0);
-       }
-
-       ret = ctdb_ctrl_setvnnmap(ctdb, timeval_current_ofs(timelimit, 0), vnn, ctdb, vnnmap);
-       if (ret != 0) {
-               printf("Unable to set vnnmap for node %u\n", vnn);
-               return ret;
-       }
-       return 0;
-}
-
-
-/*
-  set the dmaster for all records in a database
- */
-static int control_setdmaster(struct ctdb_context *ctdb, int argc, const char **argv)
-{
-       uint32_t vnn, dbid, dmaster;
-       int ret;
-
-       if (argc < 3) {
-               usage();
-       }
-
-       vnn     = strtoul(argv[0], NULL, 0);
-       dbid    = strtoul(argv[1], NULL, 0);
-       dmaster = strtoul(argv[2], NULL, 0);
-
-       ret = ctdb_ctrl_setdmaster(ctdb, timeval_current_ofs(timelimit, 0), vnn, ctdb, dbid, dmaster);
-       if (ret != 0) {
-               printf("Unable to set dmaster for node %u db:0x%08x\n", vnn, dbid);
-               return ret;
-       }
-       return 0;
-}
-
-/*
-  clears a database
- */
-static int control_cleardb(struct ctdb_context *ctdb, int argc, const char **argv)
-{
-       uint32_t vnn, dbid;
-       int ret;
-
-       if (argc < 2) {
-               usage();
-       }
-
-       vnn     = strtoul(argv[0], NULL, 0);
-       dbid    = strtoul(argv[1], NULL, 0);
-
-       ret = ctdb_ctrl_cleardb(ctdb, vnn, ctdb, dbid);
-       if (ret != 0) {
-               printf("Unable to clear db for node %u db:0x%08x\n", vnn, dbid);
-               return ret;
-       }
-       return 0;
-}
-
-/*
-  create a database
- */
-static int control_createdb(struct ctdb_context *ctdb, int argc, const char **argv)
-{
-       uint32_t vnn;
-       const char *dbname;
-       int ret;
-       int32_t res;
-       TDB_DATA data;
-       struct timeval timeout;
-
-       if (argc < 2) {
-               usage();
-       }
-
-       vnn     = strtoul(argv[0], NULL, 0);
-       dbname  = argv[1];
-
-       /* tell ctdb daemon to attach */
-       data.dptr = discard_const(dbname);
-       data.dsize = strlen(dbname)+1;
-       timeout = timeval_current_ofs(timelimit, 0);
-       ret = ctdb_control(ctdb, vnn, 0, CTDB_CONTROL_DB_ATTACH,
-                          0, data, ctdb, &data, &res, 
-                          &timeout, NULL);
-       if (ret != 0 || res != 0 || data.dsize != sizeof(uint32_t)) {
-               DEBUG(0,("Failed to attach to database '%s'\n", dbname));
-               return -1;
-       }
-
-       return 0;
-}
-
-/*
-  ping all node
+  ping a node
  */
 static int control_ping(struct ctdb_context *ctdb, int argc, const char **argv)
 {
@@ -878,7 +477,7 @@ static int control_ping(struct ctdb_context *ctdb, int argc, const char **argv)
        uint32_t *nodes;
        uint32_t num_nodes;
 
-       nodes = ctdb_get_connected_nodes(ctdb, timeval_current_ofs(timelimit, 0), ctdb, &num_nodes);
+       nodes = ctdb_get_connected_nodes(ctdb, TIMELIMIT(), ctdb, &num_nodes);
        CTDB_NO_MEMORY(ctdb, nodes);
 
        for (i=0;i<num_nodes;i++) {
@@ -897,19 +496,30 @@ static int control_ping(struct ctdb_context *ctdb, int argc, const char **argv)
 
 
 /*
-  display debug level on all node
+  display debug level on a node
  */
-static int control_debuglevel(struct ctdb_context *ctdb, int argc, const char **argv)
+static int control_getdebug(struct ctdb_context *ctdb, int argc, const char **argv)
 {
        int ret, i;
        uint32_t *nodes;
        uint32_t num_nodes;
+       uint32_t level;
 
-       nodes = ctdb_get_connected_nodes(ctdb, timeval_current_ofs(timelimit, 0), ctdb, &num_nodes);
-       CTDB_NO_MEMORY(ctdb, nodes);
+       if (options.vnn != CTDB_BROADCAST_ALL) {
+               ret = ctdb_ctrl_get_debuglevel(ctdb, options.vnn, &level);
+               if (ret != 0) {
+                       printf("Unable to get debuglevel response from node %u\n", 
+                               options.vnn);
+               } else {
+                       printf("Node %u is at debug level %u\n", options.vnn, level);
+               }
+               return 0;
+       }
 
+       nodes = ctdb_get_connected_nodes(ctdb, TIMELIMIT(), ctdb, &num_nodes);
+       CTDB_NO_MEMORY(ctdb, nodes);
+       
        for (i=0;i<num_nodes;i++) {
-               uint32_t level;
                ret = ctdb_ctrl_get_debuglevel(ctdb, nodes[i], &level);
                if (ret != 0) {
                        printf("Unable to get debuglevel response from node %u\n", 
@@ -922,33 +532,32 @@ static int control_debuglevel(struct ctdb_context *ctdb, int argc, const char **
        return 0;
 }
 
+
 /*
-  set debug level on a node
+  set debug level on a node or all nodes
  */
-static int control_debug(struct ctdb_context *ctdb, int argc, const char **argv)
+static int control_setdebug(struct ctdb_context *ctdb, int argc, const char **argv)
 {
        int ret;
-       uint32_t vnn, level, i;
+       uint32_t level, i;
        uint32_t *nodes;
        uint32_t num_nodes;
 
-       if (argc < 2) {
+       if (argc < 1) {
                usage();
        }
 
-       level = strtoul(argv[1], NULL, 0);
+       level = strtoul(argv[0], NULL, 0);
 
-       if (strcmp(argv[0], "all") != 0) {
-               vnn = strtoul(argv[0], NULL, 0);
-               ret = ctdb_ctrl_set_debuglevel(ctdb, vnn, level);
+       if (options.vnn != CTDB_BROADCAST_ALL) {
+               ret = ctdb_ctrl_set_debuglevel(ctdb, options.vnn, level);
                if (ret != 0) {
-                       printf("Unable to set debug level on node %u\n", vnn);
+                       printf("Unable to set debug level on node %u\n", options.vnn);
                }
-               
                return 0;
        }
 
-       nodes = ctdb_get_connected_nodes(ctdb, timeval_current_ofs(timelimit, 0), ctdb, &num_nodes);
+       nodes = ctdb_get_connected_nodes(ctdb, TIMELIMIT(), ctdb, &num_nodes);
        CTDB_NO_MEMORY(ctdb, nodes);
        for (i=0;i<num_nodes;i++) {
                ret = ctdb_ctrl_set_debuglevel(ctdb, nodes[i], level);
@@ -968,27 +577,22 @@ static int control_debug(struct ctdb_context *ctdb, int argc, const char **argv)
 static int control_freeze(struct ctdb_context *ctdb, int argc, const char **argv)
 {
        int ret=0, count=0;
-       uint32_t vnn, i;
+       uint32_t i;
        uint32_t *nodes;
        uint32_t num_nodes;
 
-       if (argc < 1) {
-               usage();
-       }
-
-       if (strcmp(argv[0], "all") != 0) {
-               vnn = strtoul(argv[0], NULL, 0);
-               ret = ctdb_ctrl_freeze(ctdb, timeval_current_ofs(timelimit, 0), vnn);
+       if (options.vnn != CTDB_BROADCAST_ALL) {
+               ret = ctdb_ctrl_freeze(ctdb, TIMELIMIT(), options.vnn);
                if (ret != 0) {
-                       printf("Unable to freeze node %u\n", vnn);
+                       printf("Unable to freeze node %u\n", options.vnn);
                }               
                return 0;
        }
 
-       nodes = ctdb_get_connected_nodes(ctdb, timeval_current_ofs(timelimit, 0), ctdb, &num_nodes);
+       nodes = ctdb_get_connected_nodes(ctdb, TIMELIMIT(), ctdb, &num_nodes);
        CTDB_NO_MEMORY(ctdb, nodes);
        for (i=0;i<num_nodes;i++) {
-               int res = ctdb_ctrl_freeze(ctdb, timeval_current_ofs(timelimit, 0), nodes[i]);
+               int res = ctdb_ctrl_freeze(ctdb, TIMELIMIT(), nodes[i]);
                if (res != 0) {
                        printf("Warning: Unable to freeze node %u\n", nodes[i]);
                } else {
@@ -1007,27 +611,22 @@ static int control_freeze(struct ctdb_context *ctdb, int argc, const char **argv
 static int control_thaw(struct ctdb_context *ctdb, int argc, const char **argv)
 {
        int ret=0, count=0;
-       uint32_t vnn, i;
+       uint32_t i;
        uint32_t *nodes;
        uint32_t num_nodes;
 
-       if (argc < 1) {
-               usage();
-       }
-
-       if (strcmp(argv[0], "all") != 0) {
-               vnn = strtoul(argv[0], NULL, 0);
-               ret = ctdb_ctrl_thaw(ctdb, timeval_current_ofs(timelimit, 0), vnn);
+       if (options.vnn != CTDB_BROADCAST_ALL) {
+               ret = ctdb_ctrl_thaw(ctdb, TIMELIMIT(), options.vnn);
                if (ret != 0) {
-                       printf("Unable to thaw node %u\n", vnn);
+                       printf("Unable to thaw node %u\n", options.vnn);
                }               
                return 0;
        }
 
-       nodes = ctdb_get_connected_nodes(ctdb, timeval_current_ofs(timelimit, 0), ctdb, &num_nodes);
+       nodes = ctdb_get_connected_nodes(ctdb, TIMELIMIT(), ctdb, &num_nodes);
        CTDB_NO_MEMORY(ctdb, nodes);
        for (i=0;i<num_nodes;i++) {
-               int res = ctdb_ctrl_thaw(ctdb, timeval_current_ofs(timelimit, 0), nodes[i]);
+               int res = ctdb_ctrl_thaw(ctdb, TIMELIMIT(), nodes[i]);
                if (res != 0) {
                        printf("Warning: Unable to thaw node %u\n", nodes[i]);
                } else {
@@ -1048,6 +647,7 @@ static int control_attach(struct ctdb_context *ctdb, int argc, const char **argv
 {
        const char *db_name;
        struct ctdb_db_context *ctdb_db;
+
        if (argc < 1) {
                usage();
        }
@@ -1067,33 +667,71 @@ static int control_attach(struct ctdb_context *ctdb, int argc, const char **argv
  */
 static int control_dumpmemory(struct ctdb_context *ctdb, int argc, const char **argv)
 {
+       return ctdb_control(ctdb, options.vnn, 0, CTDB_CONTROL_DUMP_MEMORY,
+                           CTDB_CTRL_FLAG_NOREPLY, tdb_null, NULL, NULL, NULL, NULL, NULL);
+}
+
+
+static const struct {
+       const char *name;
+       int (*fn)(struct ctdb_context *, int, const char **);
+       const char *msg;
+       const char *args;
+} ctdb_commands[] = {
+       { "status",          control_status,            "show node status" },
+       { "ping",            control_ping,              "ping all nodes" },
+       { "statistics",      control_statistics,        "show statistics" },
+       { "statisticsreset", control_statistics_reset,  "reset statistics"},
+       { "process-exists",  control_process_exists,    "check if a process exists on a node",  "<pid>"},
+       { "getdbmap",        control_getdbmap,          "show the database map" },
+       { "catdb",           control_catdb,             "dump a database" ,                     "<dbname>"},
+       { "getmonmode",      control_getmonmode,        "show monitoring mode" },
+       { "setmonmode",      control_setmonmode,        "set monitoring mode" },
+       { "setdebug",        control_setdebug,          "set debug level",                      "<debuglevel>" },
+       { "getdebug",        control_getdebug,          "get debug level" },
+       { "attach",          control_attach,            "attach to a database",                 "<dbname>" },
+       { "dumpmemory",      control_dumpmemory,        "dump memory map to logs" },
+       { "getpid",          control_getpid,            "get ctdbd process ID" },
+       { "shutdown",        control_shutdown,          "shutdown ctdbd" },
+       { "recover",         control_recover,           "force recovery" },
+       { "freeze",          control_freeze,            "freeze all databases" },
+       { "thaw",            control_thaw,              "thaw all databases" },
+};
 
-       uint32_t vnn;
-       if (argc < 1) {
-               usage();
-       }
-       if (strcmp(argv[0], "all") == 0) {
-               vnn = CTDB_BROADCAST_ALL;
-       } else {
-               vnn = strtoul(argv[0], NULL, 0);
+/*
+  show usage message
+ */
+static void usage(void)
+{
+       int i;
+       printf(
+"Usage: ctdb [options] <control>\n" \
+"Options:\n" \
+"   -n <node>          choose node number, or 'all' (defaults to local node)\n"
+"   -t <timelimit>     set timelimit for control in seconds (default %u)\n", options.timelimit);
+       printf("Controls:\n");
+       for (i=0;i<ARRAY_SIZE(ctdb_commands);i++) {
+               printf("  %-15s %-20s  %s\n", 
+                      ctdb_commands[i].name, 
+                      ctdb_commands[i].args?ctdb_commands[i].args:"",
+                      ctdb_commands[i].msg);
        }
-
-       ctdb_control(ctdb, vnn, 0, CTDB_CONTROL_DUMP_MEMORY,
-                    CTDB_CTRL_FLAG_NOREPLY, tdb_null, NULL, NULL, NULL, NULL, NULL);
-
-       return 0;
+       exit(1);
 }
 
+
 /*
   main program
 */
 int main(int argc, const char *argv[])
 {
        struct ctdb_context *ctdb;
+       char *nodestring = NULL;
        struct poptOption popt_options[] = {
                POPT_AUTOHELP
                POPT_CTDB_CMDLINE
-               { "timelimit", 't', POPT_ARG_INT, &timelimit, 0, "timelimit", "integer" },
+               { "timelimit", 't', POPT_ARG_INT, &options.timelimit, 0, "timelimit", "integer" },
+               { "node",      'n', POPT_ARG_STRING, &nodestring, 0, "node", "integer|all" },
                POPT_TABLEEND
        };
        int opt;
@@ -1103,41 +741,10 @@ int main(int argc, const char *argv[])
        poptContext pc;
        struct event_context *ev;
        const char *control;
-       static struct {
-               const char *name;
-               int (*fn)(struct ctdb_context *, int, const char **);
-       } commands[] = {
-               { "process-exists", control_process_exists },
-               { "status", control_status },
-               { "statusreset", control_status_reset },
-               { "getvnnmap", control_getvnnmap },
-               { "getdbmap", control_getdbmap },
-               { "getnodemap", control_getnodemap },
-               { "catdb", control_catdb },
-               { "cpdb", control_cpdb },
-               { "setvnnmap", control_setvnnmap },
-               { "setdmaster", control_setdmaster },
-               { "createdb", control_createdb },
-               { "cleardb", control_cleardb },
-               { "getrecmode", control_getrecmode },
-               { "setrecmode", control_setrecmode },
-               { "getrecmaster", control_getrecmaster },
-               { "setrecmaster", control_setrecmaster },
-               { "getmonmode", control_getmonmode },
-               { "setmonmode", control_setmonmode },
-               { "ping", control_ping },
-               { "debug", control_debug },
-               { "debuglevel", control_debuglevel },
-               { "attach", control_attach },
-               { "dumpmemory", control_dumpmemory },
-               { "getpid", control_getpid },
-               { "shutdown", control_shutdown },
-               { "recovery", control_recovery },
-               { "takeoverip", control_takeoverip },
-               { "releaseip", control_releaseip },
-               { "freeze", control_freeze },
-               { "thaw", control_thaw },
-       };
+
+       /* set some defaults */
+       options.timelimit = 3;
+       options.vnn = CTDB_CURRENT_NODE;
 
        pc = poptGetContext(argv[0], argc, argv, popt_options, POPT_CONTEXT_KEEP_FIRST);
 
@@ -1161,6 +768,15 @@ int main(int argc, const char *argv[])
                usage();
        }
 
+       /* setup the node number to contact */
+       if (nodestring != NULL) {
+               if (strcmp(nodestring, "all") == 0) {
+                       options.vnn = CTDB_BROADCAST_ALL;
+               } else {
+                       options.vnn = strtoul(nodestring, NULL, 0);
+               }
+       }
+
        control = extra_argv[0];
 
        ev = event_context_init(NULL);
@@ -1172,14 +788,14 @@ int main(int argc, const char *argv[])
                exit(1);
        }
 
-       for (i=0;i<ARRAY_SIZE(commands);i++) {
-               if (strcmp(control, commands[i].name) == 0) {
-                       ret = commands[i].fn(ctdb, extra_argc-1, extra_argv+1);
+       for (i=0;i<ARRAY_SIZE(ctdb_commands);i++) {
+               if (strcmp(control, ctdb_commands[i].name) == 0) {
+                       ret = ctdb_commands[i].fn(ctdb, extra_argc-1, extra_argv+1);
                        break;
                }
        }
 
-       if (i == ARRAY_SIZE(commands)) {
+       if (i == ARRAY_SIZE(ctdb_commands)) {
                printf("Unknown control '%s'\n", control);
                exit(1);
        }
index c21e95333b2139ab12b0882a03184b2e8fd98710..dcd2123b3451c38c79bbc32a4028158132dd7b65 100755 (executable)
@@ -1,12 +1,9 @@
 #!/bin/sh
 
-CTDB_CONTROL="./bin/ctdb_control"
-export CTDB_CONTROL
-
-$CTDB_CONTROL getnodemap 0 | egrep "^vnn:" | sed -e "s/^vnn://" -e "s/ .*$//" | while read NODE; do
-       xterm -geometry 30x25 -e "watch -n1 \"$CTDB_CONTROL getnodemap $NODE; $CTDB_CONTROL getvnnmap $NODE; $CTDB_CONTROL getrecmode $NODE; $CTDB_CONTROL getrecmaster $NODE\"" &
+CTDB="./bin/ctdb"
+export CTDB
 
+$CTDB status | egrep "^vnn:" | sed -e "s/^vnn://" -e "s/ .*$//" | while read NODE; do
+       xterm -geometry 30x25 -e "watch -n1 \"$CTDB -n $NODE status\"" &
 done
 
-
-